1 /*===------------------ uintrintrin.h - UINTR intrinsics -------------------===
3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 * See https://llvm.org/LICENSE.txt for license information.
5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 *===-----------------------------------------------------------------------===
10 #ifndef __X86GPRINTRIN_H
11 #error "Never use <uintrintrin.h> directly; include <x86gprintrin.h> instead."
14 #ifndef __UINTRINTRIN_H
15 #define __UINTRINTRIN_H
17 /* Define the default attributes for the functions in this file */
18 #define __DEFAULT_FN_ATTRS \
19 __attribute__((__always_inline__, __nodebug__, __target__("uintr")))
25 unsigned long long rip
;
26 unsigned long long rflags
;
27 unsigned long long rsp
;
30 /// Clears the user interrupt flag (UIF). Its effect takes place immediately: a
31 /// user interrupt cannot be delivered on the instruction boundary following
32 /// CLUI. Can be executed only if CR4.UINT = 1, the logical processor is in
33 /// 64-bit mode, and software is not executing inside an enclave; otherwise,
34 /// each causes an invalid-opcode exception. Causes a transactional abort if
35 /// executed inside a transactional region; the abort loads EAX as it would
36 /// had it been due to an execution of CLI.
38 /// \headerfile <x86gprintrin.h>
40 /// This intrinsic corresponds to the <c> CLUI </c> instruction.
45 static __inline__
void __DEFAULT_FN_ATTRS
48 __builtin_ia32_clui();
51 /// Sets the user interrupt flag (UIF). Its effect takes place immediately; a
52 /// user interrupt may be delivered on the instruction boundary following
53 /// STUI. Can be executed only if CR4.UINT = 1, the logical processor is in
54 /// 64-bit mode, and software is not executing inside an enclave; otherwise,
55 /// each causes an invalid-opcode exception. Causes a transactional abort if
56 /// executed inside a transactional region; the abort loads EAX as it would
57 /// had it been due to an execution of STI.
59 /// \headerfile <x86gprintrin.h>
61 /// This intrinsic corresponds to the <c> STUI </c> instruction.
66 static __inline__
void __DEFAULT_FN_ATTRS
69 __builtin_ia32_stui();
72 /// Get the current value of the user interrupt flag (UIF). Can be executed
73 /// regardless of CPL and inside a transactional region. Can be executed only
74 /// if CR4.UINT = 1, the logical processor is in 64-bit mode, and software is
75 /// not executing inside an enclave; otherwise, it causes an invalid-opcode
78 /// \headerfile <x86gprintrin.h>
80 /// This intrinsic corresponds to the <c> TESTUI </c> instruction.
82 /// \returns The current value of the user interrupt flag (UIF).
93 static __inline__
unsigned char __DEFAULT_FN_ATTRS
96 return __builtin_ia32_testui();
99 /// Send interprocessor user interrupt. Can be executed only if
100 /// CR4.UINT = IA32_UINT_TT[0] = 1, the logical processor is in 64-bit mode,
101 /// and software is not executing inside an enclave; otherwise, it causes an
102 /// invalid-opcode exception. May be executed at any privilege level, all of
103 /// its memory accesses are performed with supervisor privilege.
105 /// \headerfile <x86gprintrin.h>
107 /// This intrinsic corresponds to the <c> SENDUIPI </c> instruction
110 /// Index of user-interrupt target table entry in user-interrupt target
113 /// \code{.operation}
117 /// tempUITTE := MEM[UITTADDR + (a<<4)]
118 /// // tempUITTE must be valid, and can't have any reserved bit set
119 /// IF (tempUITTE.V == 0 OR tempUITTE[7:1] != 0)
122 /// tempUPID := MEM[tempUITTE.UPIDADDR] // under lock
123 /// // tempUPID can't have any reserved bit set
124 /// IF (tempUPID[15:2] != 0 OR tempUPID[31:24] != 0)
125 /// GP (0) // release lock
127 /// tempUPID.PIR[tempUITTE.UV] := 1;
128 /// IF (tempUPID.SN == 0 AND tempUPID.ON == 0)
134 /// MEM[tempUITTE.UPIDADDR] := tempUPID // release lock
135 /// IF sendNotify == 1
136 /// IF IA32_APIC_BASE[10] == 1 // local APIC is in x2APIC mode
137 /// // send ordinary IPI with vector tempUPID.NV to 32-bit physical APIC
138 /// // ID tempUPID.NDST
139 /// SendOrdinaryIPI(tempUPID.NV, tempUPID.NDST)
141 /// // send ordinary IPI with vector tempUPID.NV to 8-bit physical APIC
142 /// // ID tempUPID.NDST[15:8]
143 /// SendOrdinaryIPI(tempUPID.NV, tempUPID.NDST[15:8])
147 static __inline__
void __DEFAULT_FN_ATTRS
148 _senduipi (unsigned long long __a
)
150 __builtin_ia32_senduipi(__a
);
153 #endif /* __x86_64__ */
155 #undef __DEFAULT_FN_ATTRS
157 #endif /* __UINTRINTRIN_H */