Home | History | Annotate | Line # | Download | only in Headers
      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 
     23 struct __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 /// \operation
     43 ///   UIF := 0
     44 /// \endoperation
     45 static __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 /// \operation
     64 ///   UIF := 1
     65 /// \endoperation
     66 static __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 /// \operation
     85 ///   CF := UIF
     86 ///   ZF := 0
     87 ///   AF := 0
     88 ///   OF := 0
     89 ///   PF := 0
     90 ///   SF := 0
     91 ///   dst := CF
     92 /// \endoperation
     93 static __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 /// \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 /// \endoperation
    147 static __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 */
    158