xref: /freebsd/contrib/llvm-project/clang/lib/Headers/intrin.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric /* ===-------- intrin.h ---------------------------------------------------===
2*0b57cec5SDimitry Andric  *
3*0b57cec5SDimitry Andric  * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric  * See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric  *
7*0b57cec5SDimitry Andric  *===-----------------------------------------------------------------------===
8*0b57cec5SDimitry Andric  */
9*0b57cec5SDimitry Andric 
10*0b57cec5SDimitry Andric /* Only include this if we're compiling for the windows platform. */
11*0b57cec5SDimitry Andric #ifndef _MSC_VER
12*0b57cec5SDimitry Andric #include_next <intrin.h>
13*0b57cec5SDimitry Andric #else
14*0b57cec5SDimitry Andric 
15*0b57cec5SDimitry Andric #ifndef __INTRIN_H
16*0b57cec5SDimitry Andric #define __INTRIN_H
17*0b57cec5SDimitry Andric 
18*0b57cec5SDimitry Andric /* First include the standard intrinsics. */
19*0b57cec5SDimitry Andric #if defined(__i386__) || defined(__x86_64__)
20*0b57cec5SDimitry Andric #include <x86intrin.h>
21*0b57cec5SDimitry Andric #endif
22*0b57cec5SDimitry Andric 
23*0b57cec5SDimitry Andric #if defined(__arm__)
24*0b57cec5SDimitry Andric #include <armintr.h>
25*0b57cec5SDimitry Andric #endif
26*0b57cec5SDimitry Andric 
27*0b57cec5SDimitry Andric #if defined(__aarch64__)
28*0b57cec5SDimitry Andric #include <arm64intr.h>
29*0b57cec5SDimitry Andric #endif
30*0b57cec5SDimitry Andric 
31*0b57cec5SDimitry Andric /* For the definition of jmp_buf. */
32*0b57cec5SDimitry Andric #if __STDC_HOSTED__
33*0b57cec5SDimitry Andric #include <setjmp.h>
34*0b57cec5SDimitry Andric #endif
35*0b57cec5SDimitry Andric 
36*0b57cec5SDimitry Andric /* Define the default attributes for the functions in this file. */
37*0b57cec5SDimitry Andric #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
38*0b57cec5SDimitry Andric 
39*0b57cec5SDimitry Andric #ifdef __cplusplus
40*0b57cec5SDimitry Andric extern "C" {
41*0b57cec5SDimitry Andric #endif
42*0b57cec5SDimitry Andric 
43*0b57cec5SDimitry Andric #if defined(__MMX__)
44*0b57cec5SDimitry Andric /* And the random ones that aren't in those files. */
45*0b57cec5SDimitry Andric __m64 _m_from_float(float);
46*0b57cec5SDimitry Andric float _m_to_float(__m64);
47*0b57cec5SDimitry Andric #endif
48*0b57cec5SDimitry Andric 
49*0b57cec5SDimitry Andric /* Other assorted instruction intrinsics. */
50*0b57cec5SDimitry Andric void __addfsbyte(unsigned long, unsigned char);
51*0b57cec5SDimitry Andric void __addfsdword(unsigned long, unsigned long);
52*0b57cec5SDimitry Andric void __addfsword(unsigned long, unsigned short);
53*0b57cec5SDimitry Andric void __code_seg(const char *);
54*0b57cec5SDimitry Andric static __inline__
55*0b57cec5SDimitry Andric void __cpuid(int[4], int);
56*0b57cec5SDimitry Andric static __inline__
57*0b57cec5SDimitry Andric void __cpuidex(int[4], int, int);
58*0b57cec5SDimitry Andric static __inline__
59*0b57cec5SDimitry Andric __int64 __emul(int, int);
60*0b57cec5SDimitry Andric static __inline__
61*0b57cec5SDimitry Andric unsigned __int64 __emulu(unsigned int, unsigned int);
62*0b57cec5SDimitry Andric unsigned int __getcallerseflags(void);
63*0b57cec5SDimitry Andric static __inline__
64*0b57cec5SDimitry Andric void __halt(void);
65*0b57cec5SDimitry Andric unsigned char __inbyte(unsigned short);
66*0b57cec5SDimitry Andric void __inbytestring(unsigned short, unsigned char *, unsigned long);
67*0b57cec5SDimitry Andric void __incfsbyte(unsigned long);
68*0b57cec5SDimitry Andric void __incfsdword(unsigned long);
69*0b57cec5SDimitry Andric void __incfsword(unsigned long);
70*0b57cec5SDimitry Andric unsigned long __indword(unsigned short);
71*0b57cec5SDimitry Andric void __indwordstring(unsigned short, unsigned long *, unsigned long);
72*0b57cec5SDimitry Andric void __int2c(void);
73*0b57cec5SDimitry Andric void __invlpg(void *);
74*0b57cec5SDimitry Andric unsigned short __inword(unsigned short);
75*0b57cec5SDimitry Andric void __inwordstring(unsigned short, unsigned short *, unsigned long);
76*0b57cec5SDimitry Andric void __lidt(void *);
77*0b57cec5SDimitry Andric unsigned __int64 __ll_lshift(unsigned __int64, int);
78*0b57cec5SDimitry Andric __int64 __ll_rshift(__int64, int);
79*0b57cec5SDimitry Andric static __inline__
80*0b57cec5SDimitry Andric void __movsb(unsigned char *, unsigned char const *, size_t);
81*0b57cec5SDimitry Andric static __inline__
82*0b57cec5SDimitry Andric void __movsd(unsigned long *, unsigned long const *, size_t);
83*0b57cec5SDimitry Andric static __inline__
84*0b57cec5SDimitry Andric void __movsw(unsigned short *, unsigned short const *, size_t);
85*0b57cec5SDimitry Andric static __inline__
86*0b57cec5SDimitry Andric void __nop(void);
87*0b57cec5SDimitry Andric void __nvreg_restore_fence(void);
88*0b57cec5SDimitry Andric void __nvreg_save_fence(void);
89*0b57cec5SDimitry Andric void __outbyte(unsigned short, unsigned char);
90*0b57cec5SDimitry Andric void __outbytestring(unsigned short, unsigned char *, unsigned long);
91*0b57cec5SDimitry Andric void __outdword(unsigned short, unsigned long);
92*0b57cec5SDimitry Andric void __outdwordstring(unsigned short, unsigned long *, unsigned long);
93*0b57cec5SDimitry Andric void __outword(unsigned short, unsigned short);
94*0b57cec5SDimitry Andric void __outwordstring(unsigned short, unsigned short *, unsigned long);
95*0b57cec5SDimitry Andric unsigned long __readcr0(void);
96*0b57cec5SDimitry Andric unsigned long __readcr2(void);
97*0b57cec5SDimitry Andric static __inline__
98*0b57cec5SDimitry Andric unsigned long __readcr3(void);
99*0b57cec5SDimitry Andric unsigned long __readcr4(void);
100*0b57cec5SDimitry Andric unsigned long __readcr8(void);
101*0b57cec5SDimitry Andric unsigned int __readdr(unsigned int);
102*0b57cec5SDimitry Andric #ifdef __i386__
103*0b57cec5SDimitry Andric static __inline__
104*0b57cec5SDimitry Andric unsigned char __readfsbyte(unsigned long);
105*0b57cec5SDimitry Andric static __inline__
106*0b57cec5SDimitry Andric unsigned __int64 __readfsqword(unsigned long);
107*0b57cec5SDimitry Andric static __inline__
108*0b57cec5SDimitry Andric unsigned short __readfsword(unsigned long);
109*0b57cec5SDimitry Andric #endif
110*0b57cec5SDimitry Andric static __inline__
111*0b57cec5SDimitry Andric unsigned __int64 __readmsr(unsigned long);
112*0b57cec5SDimitry Andric unsigned __int64 __readpmc(unsigned long);
113*0b57cec5SDimitry Andric unsigned long __segmentlimit(unsigned long);
114*0b57cec5SDimitry Andric void __sidt(void *);
115*0b57cec5SDimitry Andric static __inline__
116*0b57cec5SDimitry Andric void __stosb(unsigned char *, unsigned char, size_t);
117*0b57cec5SDimitry Andric static __inline__
118*0b57cec5SDimitry Andric void __stosd(unsigned long *, unsigned long, size_t);
119*0b57cec5SDimitry Andric static __inline__
120*0b57cec5SDimitry Andric void __stosw(unsigned short *, unsigned short, size_t);
121*0b57cec5SDimitry Andric void __svm_clgi(void);
122*0b57cec5SDimitry Andric void __svm_invlpga(void *, int);
123*0b57cec5SDimitry Andric void __svm_skinit(int);
124*0b57cec5SDimitry Andric void __svm_stgi(void);
125*0b57cec5SDimitry Andric void __svm_vmload(size_t);
126*0b57cec5SDimitry Andric void __svm_vmrun(size_t);
127*0b57cec5SDimitry Andric void __svm_vmsave(size_t);
128*0b57cec5SDimitry Andric void __ud2(void);
129*0b57cec5SDimitry Andric unsigned __int64 __ull_rshift(unsigned __int64, int);
130*0b57cec5SDimitry Andric void __vmx_off(void);
131*0b57cec5SDimitry Andric void __vmx_vmptrst(unsigned __int64 *);
132*0b57cec5SDimitry Andric void __wbinvd(void);
133*0b57cec5SDimitry Andric void __writecr0(unsigned int);
134*0b57cec5SDimitry Andric static __inline__
135*0b57cec5SDimitry Andric void __writecr3(unsigned int);
136*0b57cec5SDimitry Andric void __writecr4(unsigned int);
137*0b57cec5SDimitry Andric void __writecr8(unsigned int);
138*0b57cec5SDimitry Andric void __writedr(unsigned int, unsigned int);
139*0b57cec5SDimitry Andric void __writefsbyte(unsigned long, unsigned char);
140*0b57cec5SDimitry Andric void __writefsdword(unsigned long, unsigned long);
141*0b57cec5SDimitry Andric void __writefsqword(unsigned long, unsigned __int64);
142*0b57cec5SDimitry Andric void __writefsword(unsigned long, unsigned short);
143*0b57cec5SDimitry Andric void __writemsr(unsigned long, unsigned __int64);
144*0b57cec5SDimitry Andric static __inline__
145*0b57cec5SDimitry Andric void *_AddressOfReturnAddress(void);
146*0b57cec5SDimitry Andric static __inline__
147*0b57cec5SDimitry Andric unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask);
148*0b57cec5SDimitry Andric static __inline__
149*0b57cec5SDimitry Andric unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask);
150*0b57cec5SDimitry Andric unsigned char _bittest(long const *, long);
151*0b57cec5SDimitry Andric unsigned char _bittestandcomplement(long *, long);
152*0b57cec5SDimitry Andric unsigned char _bittestandreset(long *, long);
153*0b57cec5SDimitry Andric unsigned char _bittestandset(long *, long);
154*0b57cec5SDimitry Andric void __cdecl _disable(void);
155*0b57cec5SDimitry Andric void __cdecl _enable(void);
156*0b57cec5SDimitry Andric long _InterlockedAddLargeStatistic(__int64 volatile *_Addend, long _Value);
157*0b57cec5SDimitry Andric unsigned char _interlockedbittestandreset(long volatile *, long);
158*0b57cec5SDimitry Andric unsigned char _interlockedbittestandset(long volatile *, long);
159*0b57cec5SDimitry Andric void *_InterlockedCompareExchangePointer_HLEAcquire(void *volatile *, void *,
160*0b57cec5SDimitry Andric                                                     void *);
161*0b57cec5SDimitry Andric void *_InterlockedCompareExchangePointer_HLERelease(void *volatile *, void *,
162*0b57cec5SDimitry Andric                                                     void *);
163*0b57cec5SDimitry Andric long _InterlockedExchangeAdd_HLEAcquire(long volatile *, long);
164*0b57cec5SDimitry Andric long _InterlockedExchangeAdd_HLERelease(long volatile *, long);
165*0b57cec5SDimitry Andric __int64 _InterlockedExchangeAdd64_HLEAcquire(__int64 volatile *, __int64);
166*0b57cec5SDimitry Andric __int64 _InterlockedExchangeAdd64_HLERelease(__int64 volatile *, __int64);
167*0b57cec5SDimitry Andric void __cdecl _invpcid(unsigned int, void *);
168*0b57cec5SDimitry Andric static __inline__ void
169*0b57cec5SDimitry Andric __attribute__((__deprecated__("use other intrinsics or C++11 atomics instead")))
170*0b57cec5SDimitry Andric _ReadBarrier(void);
171*0b57cec5SDimitry Andric static __inline__ void
172*0b57cec5SDimitry Andric __attribute__((__deprecated__("use other intrinsics or C++11 atomics instead")))
173*0b57cec5SDimitry Andric _ReadWriteBarrier(void);
174*0b57cec5SDimitry Andric unsigned int _rorx_u32(unsigned int, const unsigned int);
175*0b57cec5SDimitry Andric int _sarx_i32(int, unsigned int);
176*0b57cec5SDimitry Andric #if __STDC_HOSTED__
177*0b57cec5SDimitry Andric int __cdecl _setjmp(jmp_buf);
178*0b57cec5SDimitry Andric #endif
179*0b57cec5SDimitry Andric unsigned int _shlx_u32(unsigned int, unsigned int);
180*0b57cec5SDimitry Andric unsigned int _shrx_u32(unsigned int, unsigned int);
181*0b57cec5SDimitry Andric void _Store_HLERelease(long volatile *, long);
182*0b57cec5SDimitry Andric void _Store64_HLERelease(__int64 volatile *, __int64);
183*0b57cec5SDimitry Andric void _StorePointer_HLERelease(void *volatile *, void *);
184*0b57cec5SDimitry Andric static __inline__ void
185*0b57cec5SDimitry Andric __attribute__((__deprecated__("use other intrinsics or C++11 atomics instead")))
186*0b57cec5SDimitry Andric _WriteBarrier(void);
187*0b57cec5SDimitry Andric unsigned __int32 xbegin(void);
188*0b57cec5SDimitry Andric void _xend(void);
189*0b57cec5SDimitry Andric 
190*0b57cec5SDimitry Andric /* These additional intrinsics are turned on in x64/amd64/x86_64 mode. */
191*0b57cec5SDimitry Andric #ifdef __x86_64__
192*0b57cec5SDimitry Andric void __addgsbyte(unsigned long, unsigned char);
193*0b57cec5SDimitry Andric void __addgsdword(unsigned long, unsigned long);
194*0b57cec5SDimitry Andric void __addgsqword(unsigned long, unsigned __int64);
195*0b57cec5SDimitry Andric void __addgsword(unsigned long, unsigned short);
196*0b57cec5SDimitry Andric static __inline__
197*0b57cec5SDimitry Andric void __faststorefence(void);
198*0b57cec5SDimitry Andric void __incgsbyte(unsigned long);
199*0b57cec5SDimitry Andric void __incgsdword(unsigned long);
200*0b57cec5SDimitry Andric void __incgsqword(unsigned long);
201*0b57cec5SDimitry Andric void __incgsword(unsigned long);
202*0b57cec5SDimitry Andric static __inline__
203*0b57cec5SDimitry Andric void __movsq(unsigned long long *, unsigned long long const *, size_t);
204*0b57cec5SDimitry Andric static __inline__
205*0b57cec5SDimitry Andric unsigned char __readgsbyte(unsigned long);
206*0b57cec5SDimitry Andric static __inline__
207*0b57cec5SDimitry Andric unsigned long __readgsdword(unsigned long);
208*0b57cec5SDimitry Andric static __inline__
209*0b57cec5SDimitry Andric unsigned __int64 __readgsqword(unsigned long);
210*0b57cec5SDimitry Andric unsigned short __readgsword(unsigned long);
211*0b57cec5SDimitry Andric unsigned __int64 __shiftleft128(unsigned __int64 _LowPart,
212*0b57cec5SDimitry Andric                                 unsigned __int64 _HighPart,
213*0b57cec5SDimitry Andric                                 unsigned char _Shift);
214*0b57cec5SDimitry Andric unsigned __int64 __shiftright128(unsigned __int64 _LowPart,
215*0b57cec5SDimitry Andric                                  unsigned __int64 _HighPart,
216*0b57cec5SDimitry Andric                                  unsigned char _Shift);
217*0b57cec5SDimitry Andric static __inline__
218*0b57cec5SDimitry Andric void __stosq(unsigned __int64 *, unsigned __int64, size_t);
219*0b57cec5SDimitry Andric unsigned char __vmx_on(unsigned __int64 *);
220*0b57cec5SDimitry Andric unsigned char __vmx_vmclear(unsigned __int64 *);
221*0b57cec5SDimitry Andric unsigned char __vmx_vmlaunch(void);
222*0b57cec5SDimitry Andric unsigned char __vmx_vmptrld(unsigned __int64 *);
223*0b57cec5SDimitry Andric unsigned char __vmx_vmread(size_t, size_t *);
224*0b57cec5SDimitry Andric unsigned char __vmx_vmresume(void);
225*0b57cec5SDimitry Andric unsigned char __vmx_vmwrite(size_t, size_t);
226*0b57cec5SDimitry Andric void __writegsbyte(unsigned long, unsigned char);
227*0b57cec5SDimitry Andric void __writegsdword(unsigned long, unsigned long);
228*0b57cec5SDimitry Andric void __writegsqword(unsigned long, unsigned __int64);
229*0b57cec5SDimitry Andric void __writegsword(unsigned long, unsigned short);
230*0b57cec5SDimitry Andric unsigned char _bittest64(__int64 const *, __int64);
231*0b57cec5SDimitry Andric unsigned char _bittestandcomplement64(__int64 *, __int64);
232*0b57cec5SDimitry Andric unsigned char _bittestandreset64(__int64 *, __int64);
233*0b57cec5SDimitry Andric unsigned char _bittestandset64(__int64 *, __int64);
234*0b57cec5SDimitry Andric long _InterlockedAnd_np(long volatile *_Value, long _Mask);
235*0b57cec5SDimitry Andric short _InterlockedAnd16_np(short volatile *_Value, short _Mask);
236*0b57cec5SDimitry Andric __int64 _InterlockedAnd64_np(__int64 volatile *_Value, __int64 _Mask);
237*0b57cec5SDimitry Andric char _InterlockedAnd8_np(char volatile *_Value, char _Mask);
238*0b57cec5SDimitry Andric unsigned char _interlockedbittestandreset64(__int64 volatile *, __int64);
239*0b57cec5SDimitry Andric unsigned char _interlockedbittestandset64(__int64 volatile *, __int64);
240*0b57cec5SDimitry Andric long _InterlockedCompareExchange_np(long volatile *_Destination, long _Exchange,
241*0b57cec5SDimitry Andric                                     long _Comparand);
242*0b57cec5SDimitry Andric unsigned char _InterlockedCompareExchange128(__int64 volatile *_Destination,
243*0b57cec5SDimitry Andric                                              __int64 _ExchangeHigh,
244*0b57cec5SDimitry Andric                                              __int64 _ExchangeLow,
245*0b57cec5SDimitry Andric                                              __int64 *_CompareandResult);
246*0b57cec5SDimitry Andric unsigned char _InterlockedCompareExchange128_np(__int64 volatile *_Destination,
247*0b57cec5SDimitry Andric                                                 __int64 _ExchangeHigh,
248*0b57cec5SDimitry Andric                                                 __int64 _ExchangeLow,
249*0b57cec5SDimitry Andric                                                 __int64 *_ComparandResult);
250*0b57cec5SDimitry Andric short _InterlockedCompareExchange16_np(short volatile *_Destination,
251*0b57cec5SDimitry Andric                                        short _Exchange, short _Comparand);
252*0b57cec5SDimitry Andric __int64 _InterlockedCompareExchange64_np(__int64 volatile *_Destination,
253*0b57cec5SDimitry Andric                                          __int64 _Exchange, __int64 _Comparand);
254*0b57cec5SDimitry Andric void *_InterlockedCompareExchangePointer_np(void *volatile *_Destination,
255*0b57cec5SDimitry Andric                                             void *_Exchange, void *_Comparand);
256*0b57cec5SDimitry Andric long _InterlockedOr_np(long volatile *_Value, long _Mask);
257*0b57cec5SDimitry Andric short _InterlockedOr16_np(short volatile *_Value, short _Mask);
258*0b57cec5SDimitry Andric __int64 _InterlockedOr64_np(__int64 volatile *_Value, __int64 _Mask);
259*0b57cec5SDimitry Andric char _InterlockedOr8_np(char volatile *_Value, char _Mask);
260*0b57cec5SDimitry Andric long _InterlockedXor_np(long volatile *_Value, long _Mask);
261*0b57cec5SDimitry Andric short _InterlockedXor16_np(short volatile *_Value, short _Mask);
262*0b57cec5SDimitry Andric __int64 _InterlockedXor64_np(__int64 volatile *_Value, __int64 _Mask);
263*0b57cec5SDimitry Andric char _InterlockedXor8_np(char volatile *_Value, char _Mask);
264*0b57cec5SDimitry Andric unsigned __int64 _rorx_u64(unsigned __int64, const unsigned int);
265*0b57cec5SDimitry Andric __int64 _sarx_i64(__int64, unsigned int);
266*0b57cec5SDimitry Andric unsigned __int64 _shlx_u64(unsigned __int64, unsigned int);
267*0b57cec5SDimitry Andric unsigned __int64 _shrx_u64(unsigned __int64, unsigned int);
268*0b57cec5SDimitry Andric static __inline__
269*0b57cec5SDimitry Andric __int64 __mulh(__int64, __int64);
270*0b57cec5SDimitry Andric static __inline__
271*0b57cec5SDimitry Andric unsigned __int64 __umulh(unsigned __int64, unsigned __int64);
272*0b57cec5SDimitry Andric static __inline__
273*0b57cec5SDimitry Andric __int64 _mul128(__int64, __int64, __int64*);
274*0b57cec5SDimitry Andric static __inline__
275*0b57cec5SDimitry Andric unsigned __int64 _umul128(unsigned __int64,
276*0b57cec5SDimitry Andric                           unsigned __int64,
277*0b57cec5SDimitry Andric                           unsigned __int64*);
278*0b57cec5SDimitry Andric 
279*0b57cec5SDimitry Andric #endif /* __x86_64__ */
280*0b57cec5SDimitry Andric 
281*0b57cec5SDimitry Andric #if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
282*0b57cec5SDimitry Andric 
283*0b57cec5SDimitry Andric static __inline__
284*0b57cec5SDimitry Andric unsigned char _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask);
285*0b57cec5SDimitry Andric static __inline__
286*0b57cec5SDimitry Andric unsigned char _BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask);
287*0b57cec5SDimitry Andric 
288*0b57cec5SDimitry Andric static __inline__
289*0b57cec5SDimitry Andric __int64 _InterlockedDecrement64(__int64 volatile *_Addend);
290*0b57cec5SDimitry Andric static __inline__
291*0b57cec5SDimitry Andric __int64 _InterlockedExchange64(__int64 volatile *_Target, __int64 _Value);
292*0b57cec5SDimitry Andric static __inline__
293*0b57cec5SDimitry Andric __int64 _InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value);
294*0b57cec5SDimitry Andric static __inline__
295*0b57cec5SDimitry Andric __int64 _InterlockedExchangeSub64(__int64 volatile *_Subend, __int64 _Value);
296*0b57cec5SDimitry Andric static __inline__
297*0b57cec5SDimitry Andric __int64 _InterlockedIncrement64(__int64 volatile *_Addend);
298*0b57cec5SDimitry Andric static __inline__
299*0b57cec5SDimitry Andric __int64 _InterlockedOr64(__int64 volatile *_Value, __int64 _Mask);
300*0b57cec5SDimitry Andric static __inline__
301*0b57cec5SDimitry Andric __int64 _InterlockedXor64(__int64 volatile *_Value, __int64 _Mask);
302*0b57cec5SDimitry Andric static __inline__
303*0b57cec5SDimitry Andric __int64 _InterlockedAnd64(__int64 volatile *_Value, __int64 _Mask);
304*0b57cec5SDimitry Andric 
305*0b57cec5SDimitry Andric #endif
306*0b57cec5SDimitry Andric 
307*0b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
308*0b57cec5SDimitry Andric |* Interlocked Exchange Add
309*0b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
310*0b57cec5SDimitry Andric #if defined(__arm__) || defined(__aarch64__)
311*0b57cec5SDimitry Andric char _InterlockedExchangeAdd8_acq(char volatile *_Addend, char _Value);
312*0b57cec5SDimitry Andric char _InterlockedExchangeAdd8_nf(char volatile *_Addend, char _Value);
313*0b57cec5SDimitry Andric char _InterlockedExchangeAdd8_rel(char volatile *_Addend, char _Value);
314*0b57cec5SDimitry Andric short _InterlockedExchangeAdd16_acq(short volatile *_Addend, short _Value);
315*0b57cec5SDimitry Andric short _InterlockedExchangeAdd16_nf(short volatile *_Addend, short _Value);
316*0b57cec5SDimitry Andric short _InterlockedExchangeAdd16_rel(short volatile *_Addend, short _Value);
317*0b57cec5SDimitry Andric long _InterlockedExchangeAdd_acq(long volatile *_Addend, long _Value);
318*0b57cec5SDimitry Andric long _InterlockedExchangeAdd_nf(long volatile *_Addend, long _Value);
319*0b57cec5SDimitry Andric long _InterlockedExchangeAdd_rel(long volatile *_Addend, long _Value);
320*0b57cec5SDimitry Andric __int64 _InterlockedExchangeAdd64_acq(__int64 volatile *_Addend, __int64 _Value);
321*0b57cec5SDimitry Andric __int64 _InterlockedExchangeAdd64_nf(__int64 volatile *_Addend, __int64 _Value);
322*0b57cec5SDimitry Andric __int64 _InterlockedExchangeAdd64_rel(__int64 volatile *_Addend, __int64 _Value);
323*0b57cec5SDimitry Andric #endif
324*0b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
325*0b57cec5SDimitry Andric |* Interlocked Increment
326*0b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
327*0b57cec5SDimitry Andric #if defined(__arm__) || defined(__aarch64__)
328*0b57cec5SDimitry Andric short _InterlockedIncrement16_acq(short volatile *_Value);
329*0b57cec5SDimitry Andric short _InterlockedIncrement16_nf(short volatile *_Value);
330*0b57cec5SDimitry Andric short _InterlockedIncrement16_rel(short volatile *_Value);
331*0b57cec5SDimitry Andric long _InterlockedIncrement_acq(long volatile *_Value);
332*0b57cec5SDimitry Andric long _InterlockedIncrement_nf(long volatile *_Value);
333*0b57cec5SDimitry Andric long _InterlockedIncrement_rel(long volatile *_Value);
334*0b57cec5SDimitry Andric __int64 _InterlockedIncrement64_acq(__int64 volatile *_Value);
335*0b57cec5SDimitry Andric __int64 _InterlockedIncrement64_nf(__int64 volatile *_Value);
336*0b57cec5SDimitry Andric __int64 _InterlockedIncrement64_rel(__int64 volatile *_Value);
337*0b57cec5SDimitry Andric #endif
338*0b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
339*0b57cec5SDimitry Andric |* Interlocked Decrement
340*0b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
341*0b57cec5SDimitry Andric #if defined(__arm__) || defined(__aarch64__)
342*0b57cec5SDimitry Andric short _InterlockedDecrement16_acq(short volatile *_Value);
343*0b57cec5SDimitry Andric short _InterlockedDecrement16_nf(short volatile *_Value);
344*0b57cec5SDimitry Andric short _InterlockedDecrement16_rel(short volatile *_Value);
345*0b57cec5SDimitry Andric long _InterlockedDecrement_acq(long volatile *_Value);
346*0b57cec5SDimitry Andric long _InterlockedDecrement_nf(long volatile *_Value);
347*0b57cec5SDimitry Andric long _InterlockedDecrement_rel(long volatile *_Value);
348*0b57cec5SDimitry Andric __int64 _InterlockedDecrement64_acq(__int64 volatile *_Value);
349*0b57cec5SDimitry Andric __int64 _InterlockedDecrement64_nf(__int64 volatile *_Value);
350*0b57cec5SDimitry Andric __int64 _InterlockedDecrement64_rel(__int64 volatile *_Value);
351*0b57cec5SDimitry Andric #endif
352*0b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
353*0b57cec5SDimitry Andric |* Interlocked And
354*0b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
355*0b57cec5SDimitry Andric #if defined(__arm__) || defined(__aarch64__)
356*0b57cec5SDimitry Andric char _InterlockedAnd8_acq(char volatile *_Value, char _Mask);
357*0b57cec5SDimitry Andric char _InterlockedAnd8_nf(char volatile *_Value, char _Mask);
358*0b57cec5SDimitry Andric char _InterlockedAnd8_rel(char volatile *_Value, char _Mask);
359*0b57cec5SDimitry Andric short _InterlockedAnd16_acq(short volatile *_Value, short _Mask);
360*0b57cec5SDimitry Andric short _InterlockedAnd16_nf(short volatile *_Value, short _Mask);
361*0b57cec5SDimitry Andric short _InterlockedAnd16_rel(short volatile *_Value, short _Mask);
362*0b57cec5SDimitry Andric long _InterlockedAnd_acq(long volatile *_Value, long _Mask);
363*0b57cec5SDimitry Andric long _InterlockedAnd_nf(long volatile *_Value, long _Mask);
364*0b57cec5SDimitry Andric long _InterlockedAnd_rel(long volatile *_Value, long _Mask);
365*0b57cec5SDimitry Andric __int64 _InterlockedAnd64_acq(__int64 volatile *_Value, __int64 _Mask);
366*0b57cec5SDimitry Andric __int64 _InterlockedAnd64_nf(__int64 volatile *_Value, __int64 _Mask);
367*0b57cec5SDimitry Andric __int64 _InterlockedAnd64_rel(__int64 volatile *_Value, __int64 _Mask);
368*0b57cec5SDimitry Andric #endif
369*0b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
370*0b57cec5SDimitry Andric |* Bit Counting and Testing
371*0b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
372*0b57cec5SDimitry Andric #if defined(__arm__) || defined(__aarch64__)
373*0b57cec5SDimitry Andric unsigned char _interlockedbittestandset_acq(long volatile *_BitBase,
374*0b57cec5SDimitry Andric                                             long _BitPos);
375*0b57cec5SDimitry Andric unsigned char _interlockedbittestandset_nf(long volatile *_BitBase,
376*0b57cec5SDimitry Andric                                            long _BitPos);
377*0b57cec5SDimitry Andric unsigned char _interlockedbittestandset_rel(long volatile *_BitBase,
378*0b57cec5SDimitry Andric                                             long _BitPos);
379*0b57cec5SDimitry Andric unsigned char _interlockedbittestandreset_acq(long volatile *_BitBase,
380*0b57cec5SDimitry Andric                                               long _BitPos);
381*0b57cec5SDimitry Andric unsigned char _interlockedbittestandreset_nf(long volatile *_BitBase,
382*0b57cec5SDimitry Andric                                              long _BitPos);
383*0b57cec5SDimitry Andric unsigned char _interlockedbittestandreset_rel(long volatile *_BitBase,
384*0b57cec5SDimitry Andric                                               long _BitPos);
385*0b57cec5SDimitry Andric #endif
386*0b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
387*0b57cec5SDimitry Andric |* Interlocked Or
388*0b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
389*0b57cec5SDimitry Andric #if defined(__arm__) || defined(__aarch64__)
390*0b57cec5SDimitry Andric char _InterlockedOr8_acq(char volatile *_Value, char _Mask);
391*0b57cec5SDimitry Andric char _InterlockedOr8_nf(char volatile *_Value, char _Mask);
392*0b57cec5SDimitry Andric char _InterlockedOr8_rel(char volatile *_Value, char _Mask);
393*0b57cec5SDimitry Andric short _InterlockedOr16_acq(short volatile *_Value, short _Mask);
394*0b57cec5SDimitry Andric short _InterlockedOr16_nf(short volatile *_Value, short _Mask);
395*0b57cec5SDimitry Andric short _InterlockedOr16_rel(short volatile *_Value, short _Mask);
396*0b57cec5SDimitry Andric long _InterlockedOr_acq(long volatile *_Value, long _Mask);
397*0b57cec5SDimitry Andric long _InterlockedOr_nf(long volatile *_Value, long _Mask);
398*0b57cec5SDimitry Andric long _InterlockedOr_rel(long volatile *_Value, long _Mask);
399*0b57cec5SDimitry Andric __int64 _InterlockedOr64_acq(__int64 volatile *_Value, __int64 _Mask);
400*0b57cec5SDimitry Andric __int64 _InterlockedOr64_nf(__int64 volatile *_Value, __int64 _Mask);
401*0b57cec5SDimitry Andric __int64 _InterlockedOr64_rel(__int64 volatile *_Value, __int64 _Mask);
402*0b57cec5SDimitry Andric #endif
403*0b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
404*0b57cec5SDimitry Andric |* Interlocked Xor
405*0b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
406*0b57cec5SDimitry Andric #if defined(__arm__) || defined(__aarch64__)
407*0b57cec5SDimitry Andric char _InterlockedXor8_acq(char volatile *_Value, char _Mask);
408*0b57cec5SDimitry Andric char _InterlockedXor8_nf(char volatile *_Value, char _Mask);
409*0b57cec5SDimitry Andric char _InterlockedXor8_rel(char volatile *_Value, char _Mask);
410*0b57cec5SDimitry Andric short _InterlockedXor16_acq(short volatile *_Value, short _Mask);
411*0b57cec5SDimitry Andric short _InterlockedXor16_nf(short volatile *_Value, short _Mask);
412*0b57cec5SDimitry Andric short _InterlockedXor16_rel(short volatile *_Value, short _Mask);
413*0b57cec5SDimitry Andric long _InterlockedXor_acq(long volatile *_Value, long _Mask);
414*0b57cec5SDimitry Andric long _InterlockedXor_nf(long volatile *_Value, long _Mask);
415*0b57cec5SDimitry Andric long _InterlockedXor_rel(long volatile *_Value, long _Mask);
416*0b57cec5SDimitry Andric __int64 _InterlockedXor64_acq(__int64 volatile *_Value, __int64 _Mask);
417*0b57cec5SDimitry Andric __int64 _InterlockedXor64_nf(__int64 volatile *_Value, __int64 _Mask);
418*0b57cec5SDimitry Andric __int64 _InterlockedXor64_rel(__int64 volatile *_Value, __int64 _Mask);
419*0b57cec5SDimitry Andric #endif
420*0b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
421*0b57cec5SDimitry Andric |* Interlocked Exchange
422*0b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
423*0b57cec5SDimitry Andric #if defined(__arm__) || defined(__aarch64__)
424*0b57cec5SDimitry Andric char _InterlockedExchange8_acq(char volatile *_Target, char _Value);
425*0b57cec5SDimitry Andric char _InterlockedExchange8_nf(char volatile *_Target, char _Value);
426*0b57cec5SDimitry Andric char _InterlockedExchange8_rel(char volatile *_Target, char _Value);
427*0b57cec5SDimitry Andric short _InterlockedExchange16_acq(short volatile *_Target, short _Value);
428*0b57cec5SDimitry Andric short _InterlockedExchange16_nf(short volatile *_Target, short _Value);
429*0b57cec5SDimitry Andric short _InterlockedExchange16_rel(short volatile *_Target, short _Value);
430*0b57cec5SDimitry Andric long _InterlockedExchange_acq(long volatile *_Target, long _Value);
431*0b57cec5SDimitry Andric long _InterlockedExchange_nf(long volatile *_Target, long _Value);
432*0b57cec5SDimitry Andric long _InterlockedExchange_rel(long volatile *_Target, long _Value);
433*0b57cec5SDimitry Andric __int64 _InterlockedExchange64_acq(__int64 volatile *_Target, __int64 _Value);
434*0b57cec5SDimitry Andric __int64 _InterlockedExchange64_nf(__int64 volatile *_Target, __int64 _Value);
435*0b57cec5SDimitry Andric __int64 _InterlockedExchange64_rel(__int64 volatile *_Target, __int64 _Value);
436*0b57cec5SDimitry Andric #endif
437*0b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
438*0b57cec5SDimitry Andric |* Interlocked Compare Exchange
439*0b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
440*0b57cec5SDimitry Andric #if defined(__arm__) || defined(__aarch64__)
441*0b57cec5SDimitry Andric char _InterlockedCompareExchange8_acq(char volatile *_Destination,
442*0b57cec5SDimitry Andric                              char _Exchange, char _Comparand);
443*0b57cec5SDimitry Andric char _InterlockedCompareExchange8_nf(char volatile *_Destination,
444*0b57cec5SDimitry Andric                              char _Exchange, char _Comparand);
445*0b57cec5SDimitry Andric char _InterlockedCompareExchange8_rel(char volatile *_Destination,
446*0b57cec5SDimitry Andric                              char _Exchange, char _Comparand);
447*0b57cec5SDimitry Andric short _InterlockedCompareExchange16_acq(short volatile *_Destination,
448*0b57cec5SDimitry Andric                               short _Exchange, short _Comparand);
449*0b57cec5SDimitry Andric short _InterlockedCompareExchange16_nf(short volatile *_Destination,
450*0b57cec5SDimitry Andric                               short _Exchange, short _Comparand);
451*0b57cec5SDimitry Andric short _InterlockedCompareExchange16_rel(short volatile *_Destination,
452*0b57cec5SDimitry Andric                               short _Exchange, short _Comparand);
453*0b57cec5SDimitry Andric long _InterlockedCompareExchange_acq(long volatile *_Destination,
454*0b57cec5SDimitry Andric                               long _Exchange, long _Comparand);
455*0b57cec5SDimitry Andric long _InterlockedCompareExchange_nf(long volatile *_Destination,
456*0b57cec5SDimitry Andric                               long _Exchange, long _Comparand);
457*0b57cec5SDimitry Andric long _InterlockedCompareExchange_rel(long volatile *_Destination,
458*0b57cec5SDimitry Andric                               long _Exchange, long _Comparand);
459*0b57cec5SDimitry Andric __int64 _InterlockedCompareExchange64_acq(__int64 volatile *_Destination,
460*0b57cec5SDimitry Andric                               __int64 _Exchange, __int64 _Comparand);
461*0b57cec5SDimitry Andric __int64 _InterlockedCompareExchange64_nf(__int64 volatile *_Destination,
462*0b57cec5SDimitry Andric                               __int64 _Exchange, __int64 _Comparand);
463*0b57cec5SDimitry Andric __int64 _InterlockedCompareExchange64_rel(__int64 volatile *_Destination,
464*0b57cec5SDimitry Andric                               __int64 _Exchange, __int64 _Comparand);
465*0b57cec5SDimitry Andric #endif
466*0b57cec5SDimitry Andric 
467*0b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
468*0b57cec5SDimitry Andric |* movs, stos
469*0b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
470*0b57cec5SDimitry Andric #if defined(__i386__) || defined(__x86_64__)
471*0b57cec5SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
472*0b57cec5SDimitry Andric __movsb(unsigned char *__dst, unsigned char const *__src, size_t __n) {
473*0b57cec5SDimitry Andric   __asm__ __volatile__("rep movsb" : "+D"(__dst), "+S"(__src), "+c"(__n)
474*0b57cec5SDimitry Andric                        : : "memory");
475*0b57cec5SDimitry Andric }
476*0b57cec5SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
477*0b57cec5SDimitry Andric __movsd(unsigned long *__dst, unsigned long const *__src, size_t __n) {
478*0b57cec5SDimitry Andric   __asm__ __volatile__("rep movsl" : "+D"(__dst), "+S"(__src), "+c"(__n)
479*0b57cec5SDimitry Andric                        : : "memory");
480*0b57cec5SDimitry Andric }
481*0b57cec5SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
482*0b57cec5SDimitry Andric __movsw(unsigned short *__dst, unsigned short const *__src, size_t __n) {
483*0b57cec5SDimitry Andric   __asm__ __volatile__("rep movsw" : "+D"(__dst), "+S"(__src), "+c"(__n)
484*0b57cec5SDimitry Andric                        : : "memory");
485*0b57cec5SDimitry Andric }
486*0b57cec5SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
487*0b57cec5SDimitry Andric __stosd(unsigned long *__dst, unsigned long __x, size_t __n) {
488*0b57cec5SDimitry Andric   __asm__ __volatile__("rep stosl" : "+D"(__dst), "+c"(__n) : "a"(__x)
489*0b57cec5SDimitry Andric                        : "memory");
490*0b57cec5SDimitry Andric }
491*0b57cec5SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
492*0b57cec5SDimitry Andric __stosw(unsigned short *__dst, unsigned short __x, size_t __n) {
493*0b57cec5SDimitry Andric   __asm__ __volatile__("rep stosw" : "+D"(__dst), "+c"(__n) : "a"(__x)
494*0b57cec5SDimitry Andric                        : "memory");
495*0b57cec5SDimitry Andric }
496*0b57cec5SDimitry Andric #endif
497*0b57cec5SDimitry Andric #ifdef __x86_64__
498*0b57cec5SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
499*0b57cec5SDimitry Andric __movsq(unsigned long long *__dst, unsigned long long const *__src, size_t __n) {
500*0b57cec5SDimitry Andric   __asm__ __volatile__("rep movsq" : "+D"(__dst), "+S"(__src), "+c"(__n)
501*0b57cec5SDimitry Andric                        : : "memory");
502*0b57cec5SDimitry Andric }
503*0b57cec5SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
504*0b57cec5SDimitry Andric __stosq(unsigned __int64 *__dst, unsigned __int64 __x, size_t __n) {
505*0b57cec5SDimitry Andric   __asm__ __volatile__("rep stosq" : "+D"(__dst), "+c"(__n) : "a"(__x)
506*0b57cec5SDimitry Andric                        : "memory");
507*0b57cec5SDimitry Andric }
508*0b57cec5SDimitry Andric #endif
509*0b57cec5SDimitry Andric 
510*0b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
511*0b57cec5SDimitry Andric |* Misc
512*0b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
513*0b57cec5SDimitry Andric #if defined(__i386__) || defined(__x86_64__)
514*0b57cec5SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
515*0b57cec5SDimitry Andric __cpuid(int __info[4], int __level) {
516*0b57cec5SDimitry Andric   __asm__ ("cpuid" : "=a"(__info[0]), "=b" (__info[1]), "=c"(__info[2]), "=d"(__info[3])
517*0b57cec5SDimitry Andric                    : "a"(__level), "c"(0));
518*0b57cec5SDimitry Andric }
519*0b57cec5SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
520*0b57cec5SDimitry Andric __cpuidex(int __info[4], int __level, int __ecx) {
521*0b57cec5SDimitry Andric   __asm__ ("cpuid" : "=a"(__info[0]), "=b" (__info[1]), "=c"(__info[2]), "=d"(__info[3])
522*0b57cec5SDimitry Andric                    : "a"(__level), "c"(__ecx));
523*0b57cec5SDimitry Andric }
524*0b57cec5SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
525*0b57cec5SDimitry Andric __halt(void) {
526*0b57cec5SDimitry Andric   __asm__ volatile ("hlt");
527*0b57cec5SDimitry Andric }
528*0b57cec5SDimitry Andric #endif
529*0b57cec5SDimitry Andric 
530*0b57cec5SDimitry Andric #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
531*0b57cec5SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
532*0b57cec5SDimitry Andric __nop(void) {
533*0b57cec5SDimitry Andric   __asm__ volatile ("nop");
534*0b57cec5SDimitry Andric }
535*0b57cec5SDimitry Andric #endif
536*0b57cec5SDimitry Andric 
537*0b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
538*0b57cec5SDimitry Andric |* MS AArch64 specific
539*0b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
540*0b57cec5SDimitry Andric #if defined(__aarch64__)
541*0b57cec5SDimitry Andric unsigned __int64 __getReg(int);
542*0b57cec5SDimitry Andric long _InterlockedAdd(long volatile *Addend, long Value);
543*0b57cec5SDimitry Andric __int64 _ReadStatusReg(int);
544*0b57cec5SDimitry Andric void _WriteStatusReg(int, __int64);
545*0b57cec5SDimitry Andric 
546*0b57cec5SDimitry Andric unsigned short __cdecl _byteswap_ushort(unsigned short val);
547*0b57cec5SDimitry Andric unsigned long __cdecl _byteswap_ulong (unsigned long val);
548*0b57cec5SDimitry Andric unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64 val);
549*0b57cec5SDimitry Andric #endif
550*0b57cec5SDimitry Andric 
551*0b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
552*0b57cec5SDimitry Andric |* Privileged intrinsics
553*0b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
554*0b57cec5SDimitry Andric #if defined(__i386__) || defined(__x86_64__)
555*0b57cec5SDimitry Andric static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS
556*0b57cec5SDimitry Andric __readmsr(unsigned long __register) {
557*0b57cec5SDimitry Andric   // Loads the contents of a 64-bit model specific register (MSR) specified in
558*0b57cec5SDimitry Andric   // the ECX register into registers EDX:EAX. The EDX register is loaded with
559*0b57cec5SDimitry Andric   // the high-order 32 bits of the MSR and the EAX register is loaded with the
560*0b57cec5SDimitry Andric   // low-order 32 bits. If less than 64 bits are implemented in the MSR being
561*0b57cec5SDimitry Andric   // read, the values returned to EDX:EAX in unimplemented bit locations are
562*0b57cec5SDimitry Andric   // undefined.
563*0b57cec5SDimitry Andric   unsigned long __edx;
564*0b57cec5SDimitry Andric   unsigned long __eax;
565*0b57cec5SDimitry Andric   __asm__ ("rdmsr" : "=d"(__edx), "=a"(__eax) : "c"(__register));
566*0b57cec5SDimitry Andric   return (((unsigned __int64)__edx) << 32) | (unsigned __int64)__eax;
567*0b57cec5SDimitry Andric }
568*0b57cec5SDimitry Andric 
569*0b57cec5SDimitry Andric static __inline__ unsigned long __DEFAULT_FN_ATTRS
570*0b57cec5SDimitry Andric __readcr3(void) {
571*0b57cec5SDimitry Andric   unsigned long __cr3_val;
572*0b57cec5SDimitry Andric   __asm__ __volatile__ ("mov %%cr3, %0" : "=q"(__cr3_val) : : "memory");
573*0b57cec5SDimitry Andric   return __cr3_val;
574*0b57cec5SDimitry Andric }
575*0b57cec5SDimitry Andric 
576*0b57cec5SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
577*0b57cec5SDimitry Andric __writecr3(unsigned int __cr3_val) {
578*0b57cec5SDimitry Andric   __asm__ ("mov %0, %%cr3" : : "q"(__cr3_val) : "memory");
579*0b57cec5SDimitry Andric }
580*0b57cec5SDimitry Andric #endif
581*0b57cec5SDimitry Andric 
582*0b57cec5SDimitry Andric #ifdef __cplusplus
583*0b57cec5SDimitry Andric }
584*0b57cec5SDimitry Andric #endif
585*0b57cec5SDimitry Andric 
586*0b57cec5SDimitry Andric #undef __DEFAULT_FN_ATTRS
587*0b57cec5SDimitry Andric 
588*0b57cec5SDimitry Andric #endif /* __INTRIN_H */
589*0b57cec5SDimitry Andric #endif /* _MSC_VER */
590