aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Headers/uintrintrin.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Headers/uintrintrin.h')
-rw-r--r--clang/lib/Headers/uintrintrin.h150
1 files changed, 150 insertions, 0 deletions
diff --git a/clang/lib/Headers/uintrintrin.h b/clang/lib/Headers/uintrintrin.h
new file mode 100644
index 000000000000..78aa8779c325
--- /dev/null
+++ b/clang/lib/Headers/uintrintrin.h
@@ -0,0 +1,150 @@
+/*===------------------ uintrintrin.h - UINTR intrinsics -------------------===
+ *
+ * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+ * See https://llvm.org/LICENSE.txt for license information.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __X86GPRINTRIN_H
+#error "Never use <uintrintrin.h> directly; include <x86gprintrin.h> instead."
+#endif
+
+#ifndef __UINTRINTRIN_H
+#define __UINTRINTRIN_H
+
+/* Define the default attributes for the functions in this file */
+#define __DEFAULT_FN_ATTRS \
+ __attribute__((__always_inline__, __nodebug__, __target__("uintr")))
+
+#ifdef __x86_64__
+
+/// Clears the user interrupt flag (UIF). Its effect takes place immediately: a
+/// user interrupt cannot be delivered on the instruction boundary following
+/// CLUI. Can be executed only if CR4.UINT = 1, the logical processor is in
+/// 64-bit mode, and software is not executing inside an enclave; otherwise,
+/// each causes an invalid-opcode exception. Causes a transactional abort if
+/// executed inside a transactional region; the abort loads EAX as it would
+/// had it been due to an execution of CLI.
+///
+/// \headerfile <x86gprintrin.h>
+///
+/// This intrinsic corresponds to the <c> CLUI </c> instruction.
+///
+/// \operation
+/// UIF := 0
+/// \endoperation
+static __inline__ void __DEFAULT_FN_ATTRS
+_clui (void)
+{
+ __builtin_ia32_clui();
+}
+
+/// Sets the user interrupt flag (UIF). Its effect takes place immediately; a
+/// user interrupt may be delivered on the instruction boundary following
+/// STUI. Can be executed only if CR4.UINT = 1, the logical processor is in
+/// 64-bit mode, and software is not executing inside an enclave; otherwise,
+/// each causes an invalid-opcode exception. Causes a transactional abort if
+/// executed inside a transactional region; the abort loads EAX as it would
+/// had it been due to an execution of STI.
+///
+/// \headerfile <x86gprintrin.h>
+///
+/// This intrinsic corresponds to the <c> STUI </c> instruction.
+///
+/// \operation
+/// UIF := 1
+/// \endoperation
+static __inline__ void __DEFAULT_FN_ATTRS
+_stui (void)
+{
+ __builtin_ia32_stui();
+}
+
+/// Get the current value of the user interrupt flag (UIF). Can be executed
+/// regardless of CPL and inside a transactional region. Can be executed only
+/// if CR4.UINT = 1, the logical processor is in 64-bit mode, and software is
+/// not executing inside an enclave; otherwise, it causes an invalid-opcode
+/// exception.
+///
+/// \headerfile <x86gprintrin.h>
+///
+/// This intrinsic corresponds to the <c> TESTUI </c> instruction.
+///
+/// \returns The current value of the user interrupt flag (UIF).
+///
+/// \operation
+/// CF := UIF
+/// ZF := 0
+/// AF := 0
+/// OF := 0
+/// PF := 0
+/// SF := 0
+/// dst := CF
+/// \endoperation
+static __inline__ unsigned char __DEFAULT_FN_ATTRS
+_testui (void)
+{
+ return __builtin_ia32_testui();
+}
+
+/// Send interprocessor user interrupt. Can be executed only if
+/// CR4.UINT = IA32_UINT_TT[0] = 1, the logical processor is in 64-bit mode,
+/// and software is not executing inside an enclave; otherwise, it causes an
+/// invalid-opcode exception. May be executed at any privilege level, all of
+/// its memory accesses are performed with supervisor privilege.
+///
+/// \headerfile <x86gprintrin.h>
+///
+/// This intrinsic corresponds to the <c> SENDUIPI </c> instruction
+///
+/// \param __a
+/// Index of user-interrupt target table entry in user-interrupt target
+/// table.
+///
+/// \operation
+/// IF __a > UITTSZ
+/// GP (0)
+/// FI
+/// tempUITTE := MEM[UITTADDR + (a<<4)]
+/// // tempUITTE must be valid, and can't have any reserved bit set
+/// IF (tempUITTE.V == 0 OR tempUITTE[7:1] != 0)
+/// GP (0)
+/// FI
+/// tempUPID := MEM[tempUITTE.UPIDADDR] // under lock
+/// // tempUPID can't have any reserved bit set
+/// IF (tempUPID[15:2] != 0 OR tempUPID[31:24] != 0)
+/// GP (0) // release lock
+/// FI
+/// tempUPID.PIR[tempUITTE.UV] := 1;
+/// IF (tempUPID.SN == 0 AND tempUPID.ON == 0)
+/// tempUPID.ON := 1
+/// sendNotify := 1
+/// ELSE
+/// sendNotify := 0
+/// FI
+/// MEM[tempUITTE.UPIDADDR] := tempUPID // release lock
+/// IF sendNotify == 1
+/// IF IA32_APIC_BASE[10] == 1 // local APIC is in x2APIC mode
+/// // send ordinary IPI with vector tempUPID.NV to 32-bit physical APIC
+/// // ID tempUPID.NDST
+/// SendOrdinaryIPI(tempUPID.NV, tempUPID.NDST)
+/// ELSE
+/// // send ordinary IPI with vector tempUPID.NV to 8-bit physical APIC
+/// // ID tempUPID.NDST[15:8]
+/// SendOrdinaryIPI(tempUPID.NV, tempUPID.NDST[15:8])
+/// FI
+/// FI
+/// \endoperation
+static __inline__ void __DEFAULT_FN_ATTRS
+_senduipi (unsigned long long __a)
+{
+ __builtin_ia32_senduipi(__a);
+}
+
+#endif /* __x86_64__ */
+
+#undef __DEFAULT_FN_ATTRS
+
+#endif /* __UINTRINTRIN_H */