Clang Project

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