master
  1/*===------------------ uintrintrin.h - UINTR intrinsics -------------------===
  2 *
  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
  6 *
  7 *===-----------------------------------------------------------------------===
  8 */
  9
 10#ifndef __X86GPRINTRIN_H
 11#error "Never use <uintrintrin.h> directly; include <x86gprintrin.h> instead."
 12#endif
 13
 14#ifndef __UINTRINTRIN_H
 15#define __UINTRINTRIN_H
 16
 17/* Define the default attributes for the functions in this file */
 18#define __DEFAULT_FN_ATTRS \
 19  __attribute__((__always_inline__, __nodebug__, __target__("uintr")))
 20
 21#ifdef __x86_64__
 22
 23struct __uintr_frame
 24{
 25  unsigned long long rip;
 26  unsigned long long rflags;
 27  unsigned long long rsp;
 28};
 29
 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.
 37///
 38/// \headerfile <x86gprintrin.h>
 39///
 40/// This intrinsic corresponds to the <c> CLUI </c> instruction.
 41///
 42/// \code{.operation}
 43///   UIF := 0
 44/// \endcode
 45static __inline__ void __DEFAULT_FN_ATTRS
 46_clui (void)
 47{
 48  __builtin_ia32_clui();
 49}
 50
 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.
 58///
 59/// \headerfile <x86gprintrin.h>
 60///
 61/// This intrinsic corresponds to the <c> STUI </c> instruction.
 62///
 63/// \code{.operation}
 64///   UIF := 1
 65/// \endcode
 66static __inline__ void __DEFAULT_FN_ATTRS
 67_stui (void)
 68{
 69  __builtin_ia32_stui();
 70}
 71
 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
 76///    exception.
 77///
 78/// \headerfile <x86gprintrin.h>
 79///
 80/// This intrinsic corresponds to the <c> TESTUI </c> instruction.
 81///
 82/// \returns The current value of the user interrupt flag (UIF).
 83///
 84/// \code{.operation}
 85///   CF := UIF
 86///   ZF := 0
 87///   AF := 0
 88///   OF := 0
 89///   PF := 0
 90///   SF := 0
 91///   dst := CF
 92/// \endcode
 93static __inline__ unsigned char __DEFAULT_FN_ATTRS
 94_testui (void)
 95{
 96  return __builtin_ia32_testui();
 97}
 98
 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.
104///
105/// \headerfile <x86gprintrin.h>
106///
107/// This intrinsic corresponds to the <c> SENDUIPI </c> instruction
108///
109/// \param __a
110///    Index of user-interrupt target table entry in user-interrupt target
111///    table.
112///
113/// \code{.operation}
114///   IF __a > UITTSZ
115///     GP (0)
116///   FI
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)
120///     GP (0)
121///   FI
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
126///   FI
127///   tempUPID.PIR[tempUITTE.UV] := 1;
128///   IF (tempUPID.SN == 0 AND tempUPID.ON == 0)
129///     tempUPID.ON := 1
130///     sendNotify := 1
131///   ELSE
132///     sendNotify := 0
133///   FI
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)
140///     ELSE
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])
144///     FI
145///   FI
146/// \endcode
147static __inline__ void __DEFAULT_FN_ATTRS
148_senduipi (unsigned long long __a)
149{
150  __builtin_ia32_senduipi(__a);
151}
152
153#endif /* __x86_64__ */
154
155#undef __DEFAULT_FN_ATTRS
156
157#endif /* __UINTRINTRIN_H */