Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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
/// \code{.operation}
43
///   UIF := 0
44
/// \endcode
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
/// \code{.operation}
64
///   UIF := 1
65
/// \endcode
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
/// \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
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
/// \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
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 */