1/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7/* There are 3 separate ways this file is intended to be used:
8
9   1) Included from intrin.h.  In this case, all intrinsics in this file get declarations and
10      implementations.  No special #defines are needed for this case.
11
12   2) Included from the library versions of these functions (ie mingw-w64-crt\intrincs\*.c).  All
13      intrinsics in this file must also be included in the library.  In this case, only the
14      specific functions requested will get defined, and they will not be defined as inline.  If
15      you have followed the instructions (below) for adding functions to this file, then all you
16      need to have in the .c file is the following:
17
18      #define __INTRINSIC_ONLYSPECIAL
19      #define __INTRINSIC_SPECIAL___stosb // Causes code generation in intrin-impl.h
20
21      #include <intrin.h>
22
23   3) Included from various platform sdk headers.  Some platform sdk headers (such as winnt.h)
24      define a subset of intrinsics.  To avoid potential conflicts, this file is designed to
25      allow for specific subsets of functions to be defined.  This is done by defining the
26      appropriate variable before including this file:
27
28      #define __INTRINSIC_GROUP_WINNT
29      #include <psdk_inc/intrin-impl.h>
30
31   In all cases, it is acceptable to include this file multiple times in any order (ie include
32   winnt.h to get its subset, then include intrin.h to get everything, or vice versa).
33
34   See also the comments at the top of intrin.h.
35*/
36
37/* To add an implementation for a new intrinsic to this file, you should comment out the current prototype in intrin.h.
38   If the function you are adding is not in intrin.h, you should not be adding it to this file.  This file is only
39   for MSVC intrinsics.
40
41   Make sure you put your definition in the right section (x86 vs x64), and use this outline when adding definitions
42   to this file:
43
44#if __INTRINSIC_PROLOG(__int2c)
45
46<prototype goes here>
47
48__INTRINSICS_USEINLINE
49<code goes here>
50
51#define __INTRINSIC_DEFINED___int2c
52#endif
53*/
54
55/* Note that there is no file-wide #if to prevent intrin-impl.h from being
56   included multiple times.  This is because this file might be included multiple
57   times to define various subsets of the functions it contains. */
58
59/* However we do check for __MINGW_INTRIN_INLINE.  In theory this means we
60   can work with other compilers.  */
61
62#ifdef __MINGW_INTRIN_INLINE
63
64/* These macros are used by the routines below.  While this file may be included
65   multiple times, these macros only need to be defined once. */
66#ifndef _INTRIN_MAC_
67#define _INTRIN_MAC_
68
69/* GCC v6 added support for outputting flags.  This allows better code to be
70   produced for a number of intrinsics. */
71#ifndef __GCC_ASM_FLAG_OUTPUTS__
72#define __FLAGCONSTRAINT "=qm"
73#define __FLAGSET "\n\tsetc %[old]"
74#define __FLAGCLOBBER1 , "cc"
75#define __FLAGCLOBBER2 "cc"
76#else
77#define __FLAGCONSTRAINT "=@ccc"
78#define __FLAGSET
79#define __FLAGCLOBBER1
80#define __FLAGCLOBBER2
81#endif
82
83/* Clang has support for MSVC builtins, GCC doesn't */
84#pragma push_macro("__has_builtin")
85#ifndef __has_builtin
86  #define __has_builtin(x) 0
87#endif
88
89/* This macro is used by __stosb, __stosw, __stosd, __stosq */
90
91/* Parameters: (FunctionName, DataType, Operator)
92   FunctionName: Any valid function name
93   DataType: BYTE, WORD, DWORD or DWORD64
94   InstructionSize: b|b, w|w, l|d, q|q */
95
96/* While we don't need the output values for Dest or Count, we
97   must still inform the compiler the asm changes them. */
98#define __buildstos(x, y, z) void x(y *Dest, y Data, size_t Count) \
99{ \
100   __asm__ __volatile__ ("rep stos{" z "}" \
101      : "+D" (Dest), "+c" (Count) \
102      : [Data] "a" (Data) \
103      : "memory"); \
104}
105
106/* This macro is used by InterlockedAnd, InterlockedOr, InterlockedXor, InterlockedAnd64, InterlockedOr64, InterlockedXor64 */
107
108/* Parameters: (FunctionName, DataType, Operator)
109   FunctionName: Any valid function name
110   DataType: __LONG32 or __int64
111   Operator: One of xor, or, and */
112#define __buildlogicali(x, y, o) y x(volatile y *Destination, y Value) \
113{ \
114    return __sync_fetch_and_ ## o(Destination, Value); \
115}
116
117/* This macro is used by InterlockedBitTestAndSet, InterlockedBitTestAndReset, InterlockedBitTestAndComplement,
118   InterlockedBitTestAndSet64, InterlockedBitTestAndReset64, InterlockedBitTestAndComplement64
119   _interlockedbittestandset, _interlockedbittestandreset, _interlockedbittestandcomplement
120   _interlockedbittestandset64, _interlockedbittestandreset64, _interlockedbittestandcomplement64 */
121
122/* Parameters: (FunctionName, DataType, AsmCode, OffsetConstraint, Volatile)
123   FunctionName: Any valid function name
124   DataType: __LONG32 or __int64
125   OffsetConstraint: either "I" for 32bit data types or "J" for 64.
126   Volatile: either volatile or blank. */
127#if defined(__x86_64__) || defined(_AMD64_) || defined(__i386__) || defined(_X86_)
128#define __buildbittesti(x, y, z, a, b) unsigned char x(y *Base, b Offset) \
129{ \
130   unsigned char old; \
131   __asm__ __volatile__ (z \
132      : [old] __FLAGCONSTRAINT (old), [Base] "+m" (*Base) \
133      : [Offset] a "r" (Offset) \
134      : "memory" __FLAGCLOBBER1); \
135   return old; \
136}
137#elif defined(__arm__) || defined(_ARM_)
138#define __buildbittesti(x, y, z, a, b) unsigned char x(b y *Base, y Offset) \
139{ \
140   unsigned char old, tmp1, tmp2; \
141   Offset = 1 << Offset; \
142   __asm__ __volatile__ ("dmb	sy\n\t" \
143        "1: ldrex	%[old], %[Base]\n\t" \
144        "mov	%[tmp1], %[old]\n\t" \
145        z "	%[tmp1], %[tmp1], %[Offset]\n\t" \
146        "strex	%[tmp2], %[tmp1], %[Base]\n\t" \
147        "cmp	%[tmp2], #0\n\t" \
148        "bne	1b\n\t" \
149        "dmb	sy" \
150      : [old] "=r" (old), [tmp1] "=r" (tmp1), [tmp2] "=r" (tmp2), [Base] "+m" (*Base) \
151      : [Offset] a "r" (Offset) \
152      : "memory", "cc"); \
153   return old; \
154}
155#endif /* defined(__x86_64__) || defined(_AMD64_) || defined(__i386__) || defined(_X86_) */
156
157/* This macro is used by YieldProcessor when compiling x86 w/o SSE2.
158It generates the same opcodes as _mm_pause.  */
159#define __buildpause() __asm__ __volatile__("rep nop")
160
161/* This macro is used by DbgRaiseAssertionFailure and __int2c
162
163Parameters: (IntNum)
164IntNum: Interrupt number in hex */
165#define __buildint(a) __asm__ __volatile__("int {$}" #a :)
166
167/* This macro is used by MemoryBarrier when compiling x86 w/o SSE2.
168Note that on i386, xchg performs an implicit lock. */
169#define __buildmemorybarrier() \
170{ \
171unsigned char Barrier; \
172__asm__ __volatile__("xchg{b %%| }al, %0" :"=m" (Barrier) : /* no inputs */ : "eax", "memory"); \
173}
174
175/* This macro is used by __readfsbyte, __readfsword, __readfsdword
176                         __readgsbyte, __readgsword, __readgsdword, __readgsqword
177
178Parameters: (FunctionName, DataType, Segment)
179   FunctionName: Any valid function name
180   DataType: char, short, __LONG32 or __int64
181   Segment: fs or gs
182   Type: b, w, l, q
183   */
184
185#define __buildreadseg(x, y, z, a) y x(unsigned __LONG32 Offset) { \
186    y ret; \
187    __asm__ ("mov{" a " %%" z ":%[offset], %[ret] | %[ret], %%" z ":%[offset]}" \
188        : [ret] "=r" (ret) \
189        : [offset] "m" ((*(y *) (size_t) Offset))); \
190    return ret; \
191}
192
193/* This macro is used by __writefsbyte, __writefsword, __writefsdword
194                         __writegsbyte, __writegsword, __writegsdword, __writegsqword
195
196Parameters: (FunctionName, DataType, Segment)
197   FunctionName: Any valid function name
198   DataType: char, short, __LONG32 or __int64
199   Segment: fs or gs
200   Type: b, w, l, q
201   */
202
203#define __buildwriteseg(x, y, z, a) void x(unsigned __LONG32 Offset, y Data) { \
204    __asm__ ("mov{" a " %[Data], %%" z ":%[offset] | %%" z ":%[offset], %[Data]}" \
205        : [offset] "=m" ((*(y *) (size_t) Offset)) \
206        : [Data] "ri" (Data)); \
207}
208
209/* This macro is used by _BitScanForward, _BitScanForward64, _BitScanReverse _BitScanReverse64
210
211Parameters: (FunctionName, DataType, Segment)
212   FunctionName: Any valid function name
213   DataType: unsigned __LONG32 or unsigned __int64
214   Statement: BSF or BSR */
215
216/* GCC v6 added support for outputting flags.  This allows better code to be
217   produced for a number of intrinsics. */
218#ifndef __GCC_ASM_FLAG_OUTPUTS__
219#define __buildbitscan(x, y, z) unsigned char x(unsigned __LONG32 *Index, y Mask) \
220{ \
221   y n; \
222   __asm__ (z \
223      : [Index] "=r" (n) \
224      : [Mask] "r" (Mask) \
225      : "cc"); \
226   *Index = n; \
227   return Mask!=0; \
228}
229#else
230#define __buildbitscan(x, y, z) unsigned char x(unsigned __LONG32 *Index, y Mask) \
231{ \
232   y n; \
233   unsigned char old; \
234   __asm__ (z \
235      : "=@ccnz" (old), [Index] "=r" (n) \
236      : [Mask] "r" (Mask)); \
237   *Index = n; \
238   return old; \
239}
240#endif
241
242/* This macro is used by _bittest & _bittest64
243
244Parameters: (FunctionName, DataType, OffsetConstraint)
245   FunctionName: Any valid function name
246   DataType: __LONG32 or __int64
247   Type: l, q
248   OffsetConstraint: either "I" for 32bit data types or "J" for 64.
249
250   */
251#define __buildbittest(x, y, z, a) unsigned char x(const y *Base, y Offset) \
252{ \
253   unsigned char old; \
254   __asm__ ("bt{" z " %[Offset],%[Base] | %[Base],%[Offset]}" __FLAGSET \
255      : [old] __FLAGCONSTRAINT (old) \
256      : [Offset] a "r" (Offset), [Base] "rm" (*Base) \
257      : __FLAGCLOBBER2); \
258   return old; \
259}
260
261/* This macro is used by _bittestandset, _bittestandreset, _bittestandcomplement,
262   _bittestandset64, _bittestandreset64, _bittestandcomplement64
263
264Parameters: (FunctionName, DataType, Statement, OffsetConstraint)
265   FunctionName: Any valid function name
266   DataType: __LONG32 or __int64
267   Statement: asm statement (bts, btr, btc)
268   OffsetConstraint: either "I" for 32bit data types or "J" for 64.
269   Type: l, q
270   */
271#define __buildbittestand(x, y, z, a, b) unsigned char x(y *Base, y Offset) \
272{ \
273   unsigned char old; \
274   __asm__ (z "{" b " %[Offset],%[Base] | %[Base],%[Offset]}" __FLAGSET \
275      : [old] __FLAGCONSTRAINT (old), [Base] "+rm" (*Base) \
276      : [Offset] a "r" (Offset) \
277      : __FLAGCLOBBER2); \
278   return old; \
279}
280
281/* This macro is used by __inbyte, __inword, __indword
282
283Parameters: (FunctionName, DataType)
284   FunctionName: Any valid function name
285   DataType: unsigned char, unsigned short, unsigned __LONG32
286   Type: b, w, l
287   */
288#define __build_inport(x, y, z) y x(unsigned short Port) { \
289   y value; \
290      __asm__ __volatile__ ("in{" z " %w[port],%[value]| %[value],%w[port]}" \
291          : [value] "=a" (value) \
292          : [port] "Nd" (Port)); \
293      return value; \
294   }
295
296/* This macro is used by __outbyte, __outword, __outdword
297
298Parameters: (FunctionName, DataType)
299   FunctionName: Any valid function name
300   DataType: unsigned char, unsigned short, unsigned __LONG32
301   Type: b, w, l
302   */
303#define __build_outport(x, y, z) void x(unsigned short Port, y Data) { \
304      __asm__ __volatile__ ("out{" z " %[data],%w[port]| %w[port],%[data]}" \
305          : \
306          : [data] "a" (Data), [port] "Nd" (Port)); \
307   }
308
309/* This macro is used by __inbytestring, __inwordstring, __indwordstring
310
311Parameters: (FunctionName, DataType, InstructionSizeAtt, InstructionSizeIntel)
312   FunctionName: Any valid function name
313   DataType: unsigned char, unsigned short, unsigned __LONG32
314   InstructionSizeAtt: b, w, l
315   InstructionSizeIntel: b, w, d (not b,w,l)
316   */
317#define __build_inportstring(x, y, z, a) void x(unsigned short Port, y *Buffer, unsigned __LONG32 Count) { \
318   __asm__ __volatile__ ("cld ; rep ins{" z "|" a "}" \
319      : "=D" (Buffer), "=c" (Count) \
320      : "d"(Port), "0"(Buffer), "1" (Count) \
321      : "memory"); \
322   }
323
324/* This macro is used by __outbytestring, __outwordstring, __outdwordstring
325
326Parameters: (FunctionName, DataType, InstructionSizeAtt, InstructionSizeIntel)
327   FunctionName: Any valid function name
328   DataType: unsigned char, unsigned short, unsigned __LONG32
329   InstructionSizeAtt: b, w, l
330   InstructionSizeIntel: b, w, d (not b,w,l)
331
332   */
333#define __build_outportstring(x, y, z, a) void x(unsigned short Port, y *Buffer, unsigned __LONG32 Count) { \
334   __asm__ __volatile__ ("cld ; rep outs{" z "|" a "}" \
335      : "=S" (Buffer), "=c" (Count) \
336      : "d"(Port), "0"(Buffer), "1" (Count) \
337      : "memory"); \
338  }
339
340/* This macro is used by __readcr0, __readcr2, __readcr3, __readcr4, __readcr8
341
342Parameters: (FunctionName, DataType, RegisterNumber)
343   FunctionName: Any valid function name
344   DataType: unsigned __LONG32, unsigned __int64
345   RegisterNumber: 0, 2, 3, 4, 8
346
347   */
348#define __build_readcr(x, y, z) y x(void) { \
349      y value; \
350      __asm__ __volatile__ ("mov {%%cr" z ", %[value] | %[value], %%cr" z "}" \
351          : [value] "=q" (value)); \
352      return value; \
353  }
354
355/* This macro is used by __writecr0, __writecr2, __writecr3, __writecr4, __writecr8
356
357Parameters: (FunctionName, DataType, RegisterNumber)
358   FunctionName: Any valid function name
359   DataType: unsigned __LONG32, unsigned __int64
360   RegisterNumber: 0, 2, 3, 4, 8
361
362   */
363#define __build_writecr(x, y, z) void x(y Data) { \
364   __asm__ __volatile__ ("mov {%[Data], %%cr" z "|%%cr" z ", %[Data]}" \
365       : \
366       : [Data] "q" (Data) \
367       : "memory"); \
368   }
369
370/* This macro is used by __movsb, __movsd, __movsq, __movsw
371
372Parameters: (FunctionName, DataType, RegisterNumber)
373   FunctionName: Any valid function name
374   DataType: unsigned char, unsigned short, unsigned __LONG32, unsigned __int64
375   InstructionSize: b, w, d, q
376
377   */
378#define __buildmov(x, y, z) void x(y *Destination, y const *Source, size_t Count) \
379{ \
380  __asm__ __volatile__ ( \
381    "rep movs" z \
382       : "=D" (Destination), "=S" (Source), "=c" (Count) \
383       : "0" (Destination), "1" (Source), "2" (Count) \
384       : "memory"); \
385}
386
387#endif /* _INTRIN_MAC_ */
388
389/* The Barrier functions can never be in the library.  Since gcc only
390supports ReadWriteBarrier, map all 3 to do the same. */
391#ifndef _ReadWriteBarrier
392
393#define _ReadWriteBarrier() __asm__ __volatile__ ("" ::: "memory")
394#define _ReadBarrier _ReadWriteBarrier
395#define _WriteBarrier _ReadWriteBarrier
396
397#endif
398
399/* The logic for this macro is:
400   if the function is not yet defined AND
401   (
402       (if we are not just defining special OR
403           (we are defining special AND this is one of the ones we are defining)
404       )
405   )
406*/
407#define __INTRINSIC_PROLOG(name) (!defined(__INTRINSIC_DEFINED_ ## name)) && ((!defined (__INTRINSIC_ONLYSPECIAL)) || (defined (__INTRINSIC_ONLYSPECIAL) && defined(__INTRINSIC_SPECIAL_ ## name)))
408
409#ifdef __INTRINSIC_ONLYSPECIAL
410#define __INTRINSICS_USEINLINE
411#else
412#define __INTRINSICS_USEINLINE __MINGW_INTRIN_INLINE
413#endif
414
415/* Normally __INTRINSIC_ONLYSPECIAL is used to indicate that we are
416   being included in the library version of the intrinsic (case 2).  However,
417   that really only affects the definition of __INTRINSICS_USEINLINE.
418   So here we are letting it serve an additional purpose of only defining
419   the intrinsics for a certain file (case 3).  For example, to create the
420   intrinsics for the functions in winnt.h, define __INTRINSIC_GROUP_WINNT.
421
422   Note that this file can be included multiple times, and as a result
423   there can be overlap (definitions that appear in more than one
424   file).  This is handled by __INTRINSIC_DEFINED_*
425
426   If no groups are defined (such as what happens when including intrin.h),
427   all intrinsics are defined.   */
428
429/* If __INTRINSIC_ONLYSPECIAL is defined at this point, we are processing case 2.  In
430   that case, don't go looking for groups */
431#ifndef __INTRINSIC_ONLYSPECIAL
432
433#ifdef __INTRINSIC_GROUP_WINNT
434#undef __INTRINSIC_GROUP_WINNT /* Remove this for efficiency if intrin-impl.h is included again */
435
436/* Note that this gets undefined at the end of this file */
437#define __INTRINSIC_ONLYSPECIAL
438
439#define __INTRINSIC_SPECIAL___faststorefence
440#define __INTRINSIC_SPECIAL___int2c
441#define __INTRINSIC_SPECIAL___stosb
442#define __INTRINSIC_SPECIAL___stosd
443#define __INTRINSIC_SPECIAL___stosq
444#define __INTRINSIC_SPECIAL___stosw
445#define __INTRINSIC_SPECIAL__InterlockedAnd
446#define __INTRINSIC_SPECIAL__InterlockedAnd64
447#define __INTRINSIC_SPECIAL__interlockedbittestandcomplement
448#define __INTRINSIC_SPECIAL__interlockedbittestandcomplement64
449#define __INTRINSIC_SPECIAL__interlockedbittestandreset
450#define __INTRINSIC_SPECIAL__interlockedbittestandreset64
451#define __INTRINSIC_SPECIAL__interlockedbittestandset
452#define __INTRINSIC_SPECIAL__interlockedbittestandset64
453#define __INTRINSIC_SPECIAL__InterlockedOr
454#define __INTRINSIC_SPECIAL__InterlockedOr64
455#define __INTRINSIC_SPECIAL__InterlockedXor
456#define __INTRINSIC_SPECIAL__InterlockedXor64
457#define __INTRINSIC_SPECIAL_InterlockedBitTestAndComplement
458#define __INTRINSIC_SPECIAL_InterlockedBitTestAndComplement64
459#define __INTRINSIC_SPECIAL_InterlockedBitTestAndReset
460#define __INTRINSIC_SPECIAL_InterlockedBitTestAndReset64
461#define __INTRINSIC_SPECIAL_InterlockedBitTestAndSet
462#define __INTRINSIC_SPECIAL_InterlockedBitTestAndSet64
463#define __INTRINSIC_SPECIAL__InterlockedIncrement16
464#define __INTRINSIC_SPECIAL__InterlockedDecrement16
465#define __INTRINSIC_SPECIAL__InterlockedCompareExchange16
466#define __INTRINSIC_SPECIAL__InterlockedIncrement
467#define __INTRINSIC_SPECIAL__InterlockedDecrement
468#define __INTRINSIC_SPECIAL__InterlockedAdd
469#define __INTRINSIC_SPECIAL__InterlockedExchange
470#define __INTRINSIC_SPECIAL__InterlockedExchangeAdd
471#define __INTRINSIC_SPECIAL__InterlockedCompareExchange
472#define __INTRINSIC_SPECIAL__InterlockedIncrement64
473#define __INTRINSIC_SPECIAL__InterlockedDecrement64
474#define __INTRINSIC_SPECIAL__InterlockedAdd64
475#define __INTRINSIC_SPECIAL__InterlockedExchangeAdd64
476#define __INTRINSIC_SPECIAL__InterlockedExchange64
477#define __INTRINSIC_SPECIAL__InterlockedCompareExchange64
478#define __INTRINSIC_SPECIAL__InterlockedExchangePointer
479#define __INTRINSIC_SPECIAL__InterlockedCompareExchangePointer
480#define __INTRINSIC_SPECIAL___readgsbyte
481#define __INTRINSIC_SPECIAL___readgsword
482#define __INTRINSIC_SPECIAL___readgsdword
483#define __INTRINSIC_SPECIAL___readgsqword
484#define __INTRINSIC_SPECIAL___writegsbyte
485#define __INTRINSIC_SPECIAL___writegsword
486#define __INTRINSIC_SPECIAL___writegsdword
487#define __INTRINSIC_SPECIAL___writegsqword
488#define __INTRINSIC_SPECIAL___readfsbyte
489#define __INTRINSIC_SPECIAL___readfsword
490#define __INTRINSIC_SPECIAL___readfsdword
491#define __INTRINSIC_SPECIAL___writefsbyte
492#define __INTRINSIC_SPECIAL___writefsword
493#define __INTRINSIC_SPECIAL___writefsdword
494#define __INTRINSIC_SPECIAL__BitScanForward
495#define __INTRINSIC_SPECIAL__BitScanForward64
496#define __INTRINSIC_SPECIAL__BitScanReverse
497#define __INTRINSIC_SPECIAL__BitScanReverse64
498#define __INTRINSIC_SPECIAL__bittest
499#define __INTRINSIC_SPECIAL__bittestandset
500#define __INTRINSIC_SPECIAL__bittestandreset
501#define __INTRINSIC_SPECIAL__bittestandcomplement
502#define __INTRINSIC_SPECIAL__bittest64
503#define __INTRINSIC_SPECIAL__bittestandset64
504#define __INTRINSIC_SPECIAL__bittestandreset64
505#define __INTRINSIC_SPECIAL__bittestandcomplement64
506#define __INTRINSIC_SPECIAL___movsb
507#define __INTRINSIC_SPECIAL___movsw
508#define __INTRINSIC_SPECIAL___movsd
509#define __INTRINSIC_SPECIAL___movsq
510
511#endif /* __INTRINSIC_GROUP_WINNT */
512
513#ifdef __INTRINSIC_GROUP_WINBASE
514#undef __INTRINSIC_GROUP_WINBASE /* Remove this for efficiency if intrin-impl.h is included again */
515
516/* Note that this gets undefined at the end of this file */
517#define __INTRINSIC_ONLYSPECIAL
518
519#define __INTRINSIC_SPECIAL__InterlockedIncrement
520#define __INTRINSIC_SPECIAL__InterlockedDecrement
521#define __INTRINSIC_SPECIAL__InterlockedAdd
522#define __INTRINSIC_SPECIAL__InterlockedExchange
523#define __INTRINSIC_SPECIAL__InterlockedExchangeAdd
524#define __INTRINSIC_SPECIAL__InterlockedCompareExchange
525#define __INTRINSIC_SPECIAL__InterlockedCompareExchangePointer
526#define __INTRINSIC_SPECIAL__InterlockedExchangePointer
527#define __INTRINSIC_SPECIAL__InterlockedAnd64
528#define __INTRINSIC_SPECIAL__InterlockedOr64
529#define __INTRINSIC_SPECIAL__InterlockedXor64
530#define __INTRINSIC_SPECIAL__InterlockedIncrement64
531#define __INTRINSIC_SPECIAL__InterlockedDecrement64
532#define __INTRINSIC_SPECIAL__InterlockedAdd64
533#define __INTRINSIC_SPECIAL__InterlockedExchange64
534#define __INTRINSIC_SPECIAL__InterlockedExchangeAdd64
535#define __INTRINSIC_SPECIAL__InterlockedCompareExchange64
536
537#endif /* __INTRINSIC_GROUP_WINBASE */
538
539/* To add an additional group, put the #ifdef and definitions here. */
540
541#endif /* __INTRINSIC_ONLYSPECIAL */
542
543#ifdef __cplusplus
544extern "C" {
545#endif
546
547/* Before 4.9.2, ia32intrin.h had broken versions of these. */
548#undef _lrotl
549#undef _lrotr
550
551#if __INTRINSIC_PROLOG(_lrotl)
552unsigned long _lrotl(unsigned long __X, int __C);
553__INTRINSICS_USEINLINE
554unsigned long _lrotl(unsigned long __X, int __C)
555{
556  return (__X << __C) | (__X >> ((sizeof(long) * 8) - __C));
557}
558#define __INTRINSIC_DEFINED__lrotl
559#endif /* __INTRINSIC_PROLOG */
560
561#if __INTRINSIC_PROLOG(_lrotr)
562unsigned long _lrotr(unsigned long __X, int __C);
563__INTRINSICS_USEINLINE
564unsigned long _lrotr(unsigned long __X, int __C)
565{
566  return (__X >> __C) | (__X << ((sizeof(long) * 8) - __C));
567}
568#define __INTRINSIC_DEFINED__lrotr
569#endif /* __INTRINSIC_PROLOG */
570
571#if defined(__x86_64__) || defined(_AMD64_)
572
573#if __INTRINSIC_PROLOG(__faststorefence)
574void __faststorefence(void);
575__INTRINSICS_USEINLINE
576void __faststorefence(void) {
577    /* Turns out this is actually faster than MS's "trick" on newer cpus.  Note
578    that this builtin performs an implicit ReadWriteBarrier. */
579    __builtin_ia32_sfence();
580}
581#define __INTRINSIC_DEFINED___faststorefence
582#endif /* __INTRINSIC_PROLOG */
583
584#if __INTRINSIC_PROLOG(__stosq)
585__MINGW_EXTENSION void __stosq(unsigned __int64 *, unsigned __int64, size_t);
586__INTRINSICS_USEINLINE
587__buildstos(__stosq, unsigned __int64, "q|q")
588#define __INTRINSIC_DEFINED___stosq
589#endif /* __INTRINSIC_PROLOG */
590
591#if __INTRINSIC_PROLOG(_interlockedbittestandset64)
592__MINGW_EXTENSION unsigned char _interlockedbittestandset64(__int64 *a, __int64 b);
593__INTRINSICS_USEINLINE
594__buildbittesti(_interlockedbittestandset64, __int64, "lock bts{q %[Offset],%[Base] | %[Base],%[Offset]}" __FLAGSET, "J", __int64)
595#define __INTRINSIC_DEFINED__interlockedbittestandset64
596#endif /* __INTRINSIC_PROLOG */
597
598#if __INTRINSIC_PROLOG(_interlockedbittestandreset64)
599__MINGW_EXTENSION unsigned char _interlockedbittestandreset64(__int64 *a, __int64 b);
600__INTRINSICS_USEINLINE
601__buildbittesti(_interlockedbittestandreset64, __int64, "lock btr{q %[Offset],%[Base] | %[Base],%[Offset]}" __FLAGSET, "J", __int64)
602#define __INTRINSIC_DEFINED__interlockedbittestandreset64
603#endif /* __INTRINSIC_PROLOG */
604
605#if __INTRINSIC_PROLOG(_interlockedbittestandcomplement64)
606__MINGW_EXTENSION unsigned char _interlockedbittestandcomplement64(__int64 *a, __int64 b);
607__INTRINSICS_USEINLINE
608__buildbittesti(_interlockedbittestandcomplement64, __int64, "lock btc{q %[Offset],%[Base] | %[Base],%[Offset]}" __FLAGSET, "J", __int64)
609#define __INTRINSIC_DEFINED__interlockedbittestandcomplement64
610#endif /* __INTRINSIC_PROLOG */
611
612#if __INTRINSIC_PROLOG(InterlockedBitTestAndSet64)
613__MINGW_EXTENSION unsigned char InterlockedBitTestAndSet64(volatile __int64 *a, __int64 b);
614__INTRINSICS_USEINLINE
615__buildbittesti(InterlockedBitTestAndSet64, volatile __int64, "lock bts{q %[Offset],%[Base] | %[Base],%[Offset]}" __FLAGSET, "J", __int64)
616#define __INTRINSIC_DEFINED_InterlockedBitTestAndSet64
617#endif /* __INTRINSIC_PROLOG */
618
619#if __INTRINSIC_PROLOG(InterlockedBitTestAndReset64)
620__MINGW_EXTENSION unsigned char InterlockedBitTestAndReset64(volatile __int64 *a, __int64 b);
621__INTRINSICS_USEINLINE
622__buildbittesti(InterlockedBitTestAndReset64, volatile __int64, "lock btr{q %[Offset],%[Base] | %[Base],%[Offset]}" __FLAGSET, "J", __int64)
623#define __INTRINSIC_DEFINED_InterlockedBitTestAndReset64
624#endif /* __INTRINSIC_PROLOG */
625
626#if __INTRINSIC_PROLOG(InterlockedBitTestAndComplement64)
627__MINGW_EXTENSION unsigned char InterlockedBitTestAndComplement64(volatile __int64 *a, __int64 b);
628__INTRINSICS_USEINLINE
629__buildbittesti(InterlockedBitTestAndComplement64, volatile __int64, "lock btc{q %[Offset],%[Base] | %[Base],%[Offset]}" __FLAGSET, "J", __int64)
630#define __INTRINSIC_DEFINED_InterlockedBitTestAndComplement64
631#endif /* __INTRINSIC_PROLOG */
632
633#if __INTRINSIC_PROLOG(_InterlockedAnd64)
634__MINGW_EXTENSION __int64 _InterlockedAnd64(__int64 volatile *, __int64);
635__INTRINSICS_USEINLINE
636__buildlogicali(_InterlockedAnd64, __int64, and)
637#define __INTRINSIC_DEFINED__InterlockedAnd64
638#endif /* __INTRINSIC_PROLOG */
639
640#if __INTRINSIC_PROLOG(_InterlockedOr64)
641__MINGW_EXTENSION __int64 _InterlockedOr64(__int64 volatile *, __int64);
642__INTRINSICS_USEINLINE
643__buildlogicali(_InterlockedOr64, __int64, or)
644#define __INTRINSIC_DEFINED__InterlockedOr64
645#endif /* __INTRINSIC_PROLOG */
646
647#if __INTRINSIC_PROLOG(_InterlockedXor64)
648__MINGW_EXTENSION __int64 _InterlockedXor64(__int64 volatile *, __int64);
649__INTRINSICS_USEINLINE
650__buildlogicali(_InterlockedXor64, __int64, xor)
651#define __INTRINSIC_DEFINED__InterlockedXor64
652#endif /* __INTRINSIC_PROLOG */
653
654#if __INTRINSIC_PROLOG(_InterlockedIncrement64)
655__MINGW_EXTENSION __int64 _InterlockedIncrement64(__int64 volatile *Addend);
656__MINGW_EXTENSION __INTRINSICS_USEINLINE
657__int64 _InterlockedIncrement64(__int64 volatile *Addend) {
658    return __sync_add_and_fetch(Addend, 1);
659}
660#define __INTRINSIC_DEFINED__InterlockedIncrement64
661#endif /* __INTRINSIC_PROLOG */
662
663#if __INTRINSIC_PROLOG(_InterlockedDecrement64)
664__MINGW_EXTENSION __int64 _InterlockedDecrement64(__int64 volatile *Addend);
665__MINGW_EXTENSION __INTRINSICS_USEINLINE
666__int64 _InterlockedDecrement64(__int64 volatile *Addend) {
667    return __sync_sub_and_fetch(Addend, 1);
668}
669#define __INTRINSIC_DEFINED__InterlockedDecrement64
670#endif /* __INTRINSIC_PROLOG */
671
672#if __INTRINSIC_PROLOG(_InterlockedExchange64)
673__MINGW_EXTENSION __int64 _InterlockedExchange64(__int64 volatile *Target, __int64 Value);
674__MINGW_EXTENSION __INTRINSICS_USEINLINE
675__int64 _InterlockedExchange64(__int64 volatile *Target, __int64 Value) {
676    return __sync_lock_test_and_set(Target, Value);
677}
678#define __INTRINSIC_DEFINED__InterlockedExchange64
679#endif /* __INTRINSIC_PROLOG */
680
681#if __INTRINSIC_PROLOG(_InterlockedExchangeAdd64)
682__MINGW_EXTENSION __int64 _InterlockedExchangeAdd64(__int64 volatile *Addend, __int64 Value);
683__MINGW_EXTENSION __INTRINSICS_USEINLINE
684__int64 _InterlockedExchangeAdd64(__int64 volatile *Addend, __int64 Value) {
685    return __sync_fetch_and_add(Addend, Value);
686}
687#define __INTRINSIC_DEFINED__InterlockedExchangeAdd64
688#endif /* __INTRINSIC_PROLOG */
689
690#if __INTRINSIC_PROLOG(__readgsbyte)
691unsigned char __readgsbyte(unsigned __LONG32 Offset);
692__INTRINSICS_USEINLINE
693__buildreadseg(__readgsbyte, unsigned char, "gs", "b")
694#define __INTRINSIC_DEFINED___readgsbyte
695#endif /* __INTRINSIC_PROLOG */
696
697#if __INTRINSIC_PROLOG(__readgsword)
698unsigned short __readgsword(unsigned __LONG32 Offset);
699__INTRINSICS_USEINLINE
700__buildreadseg(__readgsword, unsigned short, "gs", "w")
701#define __INTRINSIC_DEFINED___readgsword
702#endif /* __INTRINSIC_PROLOG */
703
704#if __INTRINSIC_PROLOG(__readgsdword)
705unsigned __LONG32 __readgsdword(unsigned __LONG32 Offset);
706__INTRINSICS_USEINLINE
707__buildreadseg(__readgsdword, unsigned __LONG32, "gs", "l")
708#define __INTRINSIC_DEFINED___readgsdword
709#endif /* __INTRINSIC_PROLOG */
710
711#if __INTRINSIC_PROLOG(__readgsqword)
712__MINGW_EXTENSION unsigned __int64 __readgsqword(unsigned __LONG32 Offset);
713__MINGW_EXTENSION __INTRINSICS_USEINLINE
714__buildreadseg(__readgsqword, unsigned __int64, "gs", "q")
715#define __INTRINSIC_DEFINED___readgsqword
716#endif /* __INTRINSIC_PROLOG */
717
718#if __INTRINSIC_PROLOG(__writegsbyte)
719void __writegsbyte(unsigned __LONG32 Offset,unsigned char Data);
720__INTRINSICS_USEINLINE
721__buildwriteseg(__writegsbyte, unsigned char, "gs", "b")
722#define __INTRINSIC_DEFINED___writegsbyte
723#endif /* __INTRINSIC_PROLOG */
724
725#if __INTRINSIC_PROLOG(__writegsword)
726void __writegsword(unsigned __LONG32 Offset,unsigned short Data);
727__INTRINSICS_USEINLINE
728__buildwriteseg(__writegsword, unsigned short, "gs", "w")
729#define __INTRINSIC_DEFINED___writegsword
730#endif /* __INTRINSIC_PROLOG */
731
732#if __INTRINSIC_PROLOG(__writegsdword)
733void __writegsdword(unsigned __LONG32 Offset,unsigned __LONG32 Data);
734__INTRINSICS_USEINLINE
735__buildwriteseg(__writegsdword, unsigned __LONG32, "gs", "l")
736#define __INTRINSIC_DEFINED___writegsdword
737#endif /* __INTRINSIC_PROLOG */
738
739#if __INTRINSIC_PROLOG(__writegsqword)
740__MINGW_EXTENSION void __writegsqword(unsigned __LONG32 Offset,unsigned __int64 Data);
741__MINGW_EXTENSION __INTRINSICS_USEINLINE
742__buildwriteseg(__writegsqword, unsigned __int64, "gs", "q")
743#define __INTRINSIC_DEFINED___writegsqword
744#endif /* __INTRINSIC_PROLOG */
745
746#if __INTRINSIC_PROLOG(_BitScanForward64)
747__MINGW_EXTENSION unsigned char _BitScanForward64(unsigned __LONG32 *Index, unsigned __int64 Mask);
748__MINGW_EXTENSION __INTRINSICS_USEINLINE
749__buildbitscan(_BitScanForward64, unsigned __int64, "bsf{q %[Mask],%[Index] | %[Index],%[Mask]}")
750#define __INTRINSIC_DEFINED__BitScanForward64
751#endif /* __INTRINSIC_PROLOG */
752
753#if __INTRINSIC_PROLOG(_BitScanReverse64)
754__MINGW_EXTENSION unsigned char _BitScanReverse64(unsigned __LONG32 *Index, unsigned __int64 Mask);
755__MINGW_EXTENSION __INTRINSICS_USEINLINE
756__buildbitscan(_BitScanReverse64, unsigned __int64, "bsr{q %[Mask],%[Index] | %[Index],%[Mask]}")
757#define __INTRINSIC_DEFINED__BitScanReverse64
758#endif /* __INTRINSIC_PROLOG */
759
760#if __INTRINSIC_PROLOG(_bittest64)
761__MINGW_EXTENSION unsigned char _bittest64(__int64 const *a, __int64 b);
762__MINGW_EXTENSION __INTRINSICS_USEINLINE
763__buildbittest(_bittest64, __int64, "q", "J")
764#define __INTRINSIC_DEFINED__bittest64
765#endif /* __INTRINSIC_PROLOG */
766
767#if __INTRINSIC_PROLOG(_bittestandset64)
768__MINGW_EXTENSION unsigned char _bittestandset64(__int64 *a, __int64 b);
769__MINGW_EXTENSION __INTRINSICS_USEINLINE
770__buildbittestand(_bittestandset64, __int64, "bts", "J", "q")
771#define __INTRINSIC_DEFINED__bittestandset64
772#endif /* __INTRINSIC_PROLOG */
773
774#if __INTRINSIC_PROLOG(_bittestandreset64)
775__MINGW_EXTENSION unsigned char _bittestandreset64(__int64 *a, __int64 b);
776__MINGW_EXTENSION __INTRINSICS_USEINLINE
777__buildbittestand(_bittestandreset64, __int64, "btr", "J", "q")
778#define __INTRINSIC_DEFINED__bittestandreset64
779#endif /* __INTRINSIC_PROLOG */
780
781#if __INTRINSIC_PROLOG(_bittestandcomplement64)
782__MINGW_EXTENSION unsigned char _bittestandcomplement64(__int64 *a, __int64 b);
783__MINGW_EXTENSION __INTRINSICS_USEINLINE
784__buildbittestand(_bittestandcomplement64, __int64, "btc", "J", "q")
785#define __INTRINSIC_DEFINED__bittestandcomplement64
786#endif /* __INTRINSIC_PROLOG */
787
788#if __INTRINSIC_PROLOG(__readcr0)
789__MINGW_EXTENSION unsigned __int64 __readcr0(void);
790__INTRINSICS_USEINLINE
791__build_readcr(__readcr0, unsigned __int64, "0")
792#define __INTRINSIC_DEFINED___readcr0
793#endif /* __INTRINSIC_PROLOG */
794
795#if __INTRINSIC_PROLOG(__readcr2)
796__MINGW_EXTENSION unsigned __int64 __readcr2(void);
797__INTRINSICS_USEINLINE
798__build_readcr(__readcr2, unsigned __int64, "2")
799#define __INTRINSIC_DEFINED___readcr2
800#endif /* __INTRINSIC_PROLOG */
801
802#if __INTRINSIC_PROLOG(__readcr3)
803__MINGW_EXTENSION unsigned __int64 __readcr3(void);
804__INTRINSICS_USEINLINE
805__build_readcr(__readcr3, unsigned __int64, "3")
806#define __INTRINSIC_DEFINED___readcr3
807#endif /* __INTRINSIC_PROLOG */
808
809#if __INTRINSIC_PROLOG(__readcr4)
810__MINGW_EXTENSION unsigned __int64 __readcr4(void);
811__INTRINSICS_USEINLINE
812__build_readcr(__readcr4, unsigned __int64, "4")
813#define __INTRINSIC_DEFINED___readcr4
814#endif /* __INTRINSIC_PROLOG */
815
816#if __INTRINSIC_PROLOG(__readcr8)
817__MINGW_EXTENSION unsigned __int64 __readcr8(void);
818__INTRINSICS_USEINLINE
819__build_readcr(__readcr8, unsigned __int64, "8")
820#define __INTRINSIC_DEFINED___readcr8
821#endif /* __INTRINSIC_PROLOG */
822
823#if __INTRINSIC_PROLOG(__writecr0)
824__MINGW_EXTENSION void __writecr0(unsigned __int64);
825__INTRINSICS_USEINLINE
826__build_writecr(__writecr0, unsigned __int64, "0")
827#define __INTRINSIC_DEFINED___writecr0
828#endif /* __INTRINSIC_PROLOG */
829
830#if __INTRINSIC_PROLOG(__writecr3)
831__MINGW_EXTENSION void __writecr3(unsigned __int64);
832__INTRINSICS_USEINLINE
833__build_writecr(__writecr3, unsigned __int64, "3")
834#define __INTRINSIC_DEFINED___writecr3
835#endif /* __INTRINSIC_PROLOG */
836
837#if __INTRINSIC_PROLOG(__writecr4)
838__MINGW_EXTENSION void __writecr4(unsigned __int64);
839__INTRINSICS_USEINLINE
840__build_writecr(__writecr4, unsigned __int64, "4")
841#define __INTRINSIC_DEFINED___writecr4
842#endif /* __INTRINSIC_PROLOG */
843
844#if __INTRINSIC_PROLOG(__writecr8)
845__MINGW_EXTENSION void __writecr8(unsigned __int64);
846__INTRINSICS_USEINLINE
847__build_writecr(__writecr8, unsigned __int64, "8")
848#define __INTRINSIC_DEFINED___writecr8
849#endif /* __INTRINSIC_PROLOG */
850
851#if __INTRINSIC_PROLOG(__movsq)
852__MINGW_EXTENSION void __movsq(unsigned __int64 *Dest, unsigned __int64 const *Source, size_t Count);
853__MINGW_EXTENSION __INTRINSICS_USEINLINE
854__buildmov(__movsq, unsigned __int64, "q")
855#define __INTRINSIC_DEFINED___movsq
856#endif /* __INTRINSIC_PROLOG */
857
858#if __INTRINSIC_PROLOG(_umul128)
859unsigned __int64 _umul128(unsigned __int64, unsigned __int64, unsigned __int64 *);
860__INTRINSICS_USEINLINE
861unsigned __int64 _umul128(unsigned __int64 a, unsigned __int64 b, unsigned __int64 *hi)
862{
863   __MINGW_EXTENSION union { unsigned __int128 v; unsigned __int64 sv[2]; } var;
864   var.v = a;
865   var.v *= b;
866   if (hi) *hi = var.sv[1];
867   return var.sv[0];
868}
869#define __INTRINSIC_DEFINED__umul128
870#endif /* __INTRINSIC_PROLOG */
871
872#if __INTRINSIC_PROLOG(_mul128)
873__int64 _mul128(__int64, __int64, __int64 *);
874__INTRINSICS_USEINLINE
875__int64 _mul128(__int64 a, __int64 b, __int64 *hi)
876{
877   __MINGW_EXTENSION union { __int128 v; __int64 sv[2]; } var;
878   var.v = a;
879   var.v *= b;
880   if (hi) *hi = var.sv[1];
881   return var.sv[0];
882}
883#define __INTRINSIC_DEFINED__mul128
884#endif /* __INTRINSIC_PROLOG */
885
886#if __INTRINSIC_PROLOG(__shiftleft128)
887unsigned __int64 __shiftleft128(unsigned __int64  LowPart, unsigned __int64 HighPart, unsigned char Shift);
888__INTRINSICS_USEINLINE
889unsigned __int64 __shiftleft128 (unsigned __int64  LowPart, unsigned __int64 HighPart, unsigned char Shift)
890{
891   unsigned __int64 ret;
892
893   __asm__ ("shld {%[Shift],%[LowPart],%[HighPart]|%[HighPart], %[LowPart], %[Shift]}"
894      : [ret] "=r" (ret)
895      : [LowPart] "r" (LowPart), [HighPart] "0" (HighPart), [Shift] "Jc" (Shift)
896      : "cc");
897
898   return ret;
899}
900#define __INTRINSIC_DEFINED___shiftleft128
901#endif /* __INTRINSIC_PROLOG */
902
903#if __INTRINSIC_PROLOG(__shiftright128)
904unsigned __int64 __shiftright128 (unsigned __int64  LowPart, unsigned __int64 HighPart, unsigned char Shift);
905__INTRINSICS_USEINLINE
906unsigned __int64 __shiftright128 (unsigned __int64  LowPart, unsigned __int64 HighPart, unsigned char Shift)
907{
908   unsigned __int64 ret;
909
910   __asm__ ("shrd {%[Shift],%[HighPart],%[LowPart]|%[LowPart], %[HighPart], %[Shift]}"
911      : [ret] "=r" (ret)
912      : [LowPart] "0" (LowPart), [HighPart] "r" (HighPart), [Shift] "Jc" (Shift)
913      : "cc");
914
915   return ret;
916}
917#define __INTRINSIC_DEFINED___shiftright128
918#endif /* __INTRINSIC_PROLOG */
919
920#endif /* defined(__x86_64__) || defined(_AMD64_) */
921
922/* ***************************************************** */
923
924#if defined(__arm__) || defined(_ARM_)
925
926#if __INTRINSIC_PROLOG(_interlockedbittestandset)
927unsigned char _interlockedbittestandset(__LONG32 *a, __LONG32 b);
928__INTRINSICS_USEINLINE
929__buildbittesti(_interlockedbittestandset, __LONG32, "orr", "M", /* unused param */)
930#define __INTRINSIC_DEFINED__interlockedbittestandset
931#endif /* __INTRINSIC_PROLOG */
932
933#if __INTRINSIC_PROLOG(_interlockedbittestandreset)
934unsigned char _interlockedbittestandreset(__LONG32 *a, __LONG32 b);
935__INTRINSICS_USEINLINE
936__buildbittesti(_interlockedbittestandreset, __LONG32, "bic", "M", /* unused param */)
937#define __INTRINSIC_DEFINED__interlockedbittestandreset
938#endif /* __INTRINSIC_PROLOG */
939
940#if __INTRINSIC_PROLOG(_interlockedbittestandcomplement)
941unsigned char _interlockedbittestandcomplement(__LONG32 *a, __LONG32 b);
942__INTRINSICS_USEINLINE
943__buildbittesti(_interlockedbittestandcomplement, __LONG32, "eor", "M", /* unused param */)
944#define __INTRINSIC_DEFINED__interlockedbittestandcomplement
945#endif /* __INTRINSIC_PROLOG */
946
947#if __INTRINSIC_PROLOG(InterlockedBitTestAndSet)
948unsigned char InterlockedBitTestAndSet(volatile __LONG32 *a, __LONG32 b);
949__INTRINSICS_USEINLINE
950__buildbittesti(InterlockedBitTestAndSet, __LONG32, "orr", "M", volatile)
951#define __INTRINSIC_DEFINED_InterlockedBitTestAndSet
952#endif /* __INTRINSIC_PROLOG */
953
954#if __INTRINSIC_PROLOG(InterlockedBitTestAndReset)
955unsigned char InterlockedBitTestAndReset(volatile __LONG32 *a, __LONG32 b);
956__INTRINSICS_USEINLINE
957__buildbittesti(InterlockedBitTestAndReset, __LONG32, "bic", "M", volatile)
958#define __INTRINSIC_DEFINED_InterlockedBitTestAndReset
959#endif /* __INTRINSIC_PROLOG */
960
961#if __INTRINSIC_PROLOG(InterlockedBitTestAndComplement)
962unsigned char InterlockedBitTestAndComplement(volatile __LONG32 *a, __LONG32 b);
963__INTRINSICS_USEINLINE
964__buildbittesti(InterlockedBitTestAndComplement, __LONG32, "eor", "M", volatile)
965#define __INTRINSIC_DEFINED_InterlockedBitTestAndComplement
966#endif /* __INTRINSIC_PROLOG */
967
968#endif /* defined(__arm__) || defined(_ARM_) */
969
970/* ***************************************************** */
971
972#if defined(__x86_64__) || defined(_AMD64_) || defined(__i386__) || defined(_X86_) || defined(__arm__) || defined(_ARM_)
973
974#if __INTRINSIC_PROLOG(_InterlockedAnd)
975__LONG32 _InterlockedAnd(__LONG32 volatile *, __LONG32);
976__INTRINSICS_USEINLINE
977__buildlogicali(_InterlockedAnd, __LONG32, and)
978#define __INTRINSIC_DEFINED__InterlockedAnd
979#endif /* __INTRINSIC_PROLOG */
980
981#if __INTRINSIC_PROLOG(_InterlockedOr)
982__LONG32 _InterlockedOr(__LONG32 volatile *, __LONG32);
983__INTRINSICS_USEINLINE
984__buildlogicali(_InterlockedOr, __LONG32, or)
985#define __INTRINSIC_DEFINED__InterlockedOr
986#endif /* __INTRINSIC_PROLOG */
987
988#if __INTRINSIC_PROLOG(_InterlockedXor)
989__LONG32 _InterlockedXor(__LONG32 volatile *, __LONG32);
990__INTRINSICS_USEINLINE
991__buildlogicali(_InterlockedXor, __LONG32, xor)
992#define __INTRINSIC_DEFINED__InterlockedXor
993#endif /* __INTRINSIC_PROLOG */
994
995#if __INTRINSIC_PROLOG(_InterlockedIncrement16)
996short _InterlockedIncrement16(short volatile *Addend);
997__INTRINSICS_USEINLINE
998short _InterlockedIncrement16(short volatile *Addend) {
999    return __sync_add_and_fetch(Addend, 1);
1000}
1001#define __INTRINSIC_DEFINED__InterlockedIncrement16
1002#endif /* __INTRINSIC_PROLOG */
1003
1004#if __INTRINSIC_PROLOG(_InterlockedDecrement16)
1005short _InterlockedDecrement16(short volatile *Addend);
1006__INTRINSICS_USEINLINE
1007short _InterlockedDecrement16(short volatile *Addend) {
1008    return __sync_sub_and_fetch(Addend, 1);
1009}
1010#define __INTRINSIC_DEFINED__InterlockedDecrement16
1011#endif /* __INTRINSIC_PROLOG */
1012
1013#if __INTRINSIC_PROLOG(_InterlockedCompareExchange16)
1014short _InterlockedCompareExchange16(short volatile *Destination, short ExChange, short Comperand);
1015__INTRINSICS_USEINLINE
1016short _InterlockedCompareExchange16(short volatile *Destination, short ExChange, short Comperand) {
1017    return __sync_val_compare_and_swap(Destination, Comperand, ExChange);
1018}
1019#define __INTRINSIC_DEFINED__InterlockedCompareExchange16
1020#endif /* __INTRINSIC_PROLOG */
1021
1022#if __INTRINSIC_PROLOG(_InterlockedExchangeAdd)
1023__LONG32 _InterlockedExchangeAdd(__LONG32 volatile *Addend, __LONG32 Value);
1024#if !__has_builtin(_InterlockedExchangeAdd)
1025__INTRINSICS_USEINLINE
1026__LONG32 _InterlockedExchangeAdd(__LONG32 volatile *Addend, __LONG32 Value) {
1027    return __sync_fetch_and_add(Addend, Value);
1028}
1029#endif
1030#define __INTRINSIC_DEFINED__InterlockedExchangeAdd
1031#endif /* __INTRINSIC_PROLOG */
1032
1033#if __INTRINSIC_PROLOG(_InterlockedCompareExchange)
1034__LONG32 _InterlockedCompareExchange(__LONG32 volatile *Destination, __LONG32 ExChange, __LONG32 Comperand);
1035#if !__has_builtin(_InterlockedCompareExchange)
1036__INTRINSICS_USEINLINE
1037__LONG32 _InterlockedCompareExchange(__LONG32 volatile *Destination, __LONG32 ExChange, __LONG32 Comperand) {
1038    return __sync_val_compare_and_swap(Destination, Comperand, ExChange);
1039}
1040#endif
1041#define __INTRINSIC_DEFINED__InterlockedCompareExchange
1042#endif /* __INTRINSIC_PROLOG */
1043
1044#if __INTRINSIC_PROLOG(_InterlockedIncrement)
1045__LONG32 _InterlockedIncrement(__LONG32 volatile *Addend);
1046#if !__has_builtin(_InterlockedIncrement)
1047__INTRINSICS_USEINLINE
1048__LONG32 _InterlockedIncrement(__LONG32 volatile *Addend) {
1049   return __sync_add_and_fetch(Addend, 1);
1050}
1051#endif
1052#define __INTRINSIC_DEFINED__InterlockedIncrement
1053#endif /* __INTRINSIC_PROLOG */
1054
1055#if __INTRINSIC_PROLOG(_InterlockedDecrement)
1056__LONG32 _InterlockedDecrement(__LONG32 volatile *Addend);
1057#if !__has_builtin(_InterlockedDecrement)
1058__INTRINSICS_USEINLINE
1059__LONG32 _InterlockedDecrement(__LONG32 volatile *Addend) {
1060   return __sync_sub_and_fetch(Addend, 1);
1061}
1062#endif
1063#define __INTRINSIC_DEFINED__InterlockedDecrement
1064#endif /* __INTRINSIC_PROLOG */
1065
1066#if __INTRINSIC_PROLOG(_InterlockedAdd)
1067__LONG32 _InterlockedAdd(__LONG32 volatile *Addend, __LONG32 Value);
1068__INTRINSICS_USEINLINE
1069__LONG32 _InterlockedAdd(__LONG32 volatile *Addend, __LONG32 Value) {
1070    return __sync_add_and_fetch(Addend, Value);
1071}
1072#define __INTRINSIC_DEFINED__InterlockedAdd
1073#endif /* __INTRINSIC_PROLOG */
1074
1075#if __INTRINSIC_PROLOG(_InterlockedAdd64)
1076__MINGW_EXTENSION __int64 _InterlockedAdd64(__int64 volatile *Addend, __int64 Value);
1077__MINGW_EXTENSION __INTRINSICS_USEINLINE
1078__int64 _InterlockedAdd64(__int64 volatile *Addend, __int64 Value) {
1079    return __sync_add_and_fetch(Addend, Value);
1080}
1081#define __INTRINSIC_DEFINED__InterlockedAdd64
1082#endif /* __INTRINSIC_PROLOG */
1083
1084#if __INTRINSIC_PROLOG(_InterlockedExchange)
1085__LONG32 _InterlockedExchange(__LONG32 volatile *Target, __LONG32 Value);
1086#if !__has_builtin(_InterlockedExchange)
1087__INTRINSICS_USEINLINE
1088__LONG32 _InterlockedExchange(__LONG32 volatile *Target, __LONG32 Value) {
1089    return __sync_lock_test_and_set(Target, Value);
1090}
1091#endif
1092#define __INTRINSIC_DEFINED__InterlockedExchange
1093#endif /* __INTRINSIC_PROLOG */
1094
1095#if __INTRINSIC_PROLOG(_InterlockedCompareExchange64)
1096__MINGW_EXTENSION __int64 _InterlockedCompareExchange64(__int64 volatile *Destination, __int64 ExChange, __int64 Comperand);
1097__MINGW_EXTENSION __INTRINSICS_USEINLINE
1098__int64 _InterlockedCompareExchange64(__int64 volatile *Destination, __int64 ExChange, __int64 Comperand) {
1099    return __sync_val_compare_and_swap(Destination, Comperand, ExChange);
1100}
1101#define __INTRINSIC_DEFINED__InterlockedCompareExchange64
1102#endif /* __INTRINSIC_PROLOG */
1103
1104#if __INTRINSIC_PROLOG(_InterlockedCompareExchangePointer)
1105void *_InterlockedCompareExchangePointer(void * volatile *Destination, void *ExChange, void *Comperand);
1106#if !__has_builtin(_InterlockedCompareExchangePointer)
1107__INTRINSICS_USEINLINE
1108void *_InterlockedCompareExchangePointer(void *volatile *Destination, void *ExChange, void *Comperand) {
1109    return __sync_val_compare_and_swap(Destination, Comperand, ExChange);
1110}
1111#endif
1112#define __INTRINSIC_DEFINED__InterlockedCompareExchangePointer
1113#endif /* __INTRINSIC_PROLOG */
1114
1115#if __INTRINSIC_PROLOG(_InterlockedExchangePointer)
1116void *_InterlockedExchangePointer(void *volatile *Target,void *Value);
1117#if !__has_builtin(_InterlockedExchangePointer)
1118__INTRINSICS_USEINLINE
1119void *_InterlockedExchangePointer(void *volatile *Target,void *Value) {
1120    return __sync_lock_test_and_set(Target, Value);
1121}
1122#endif
1123#define __INTRINSIC_DEFINED__InterlockedExchangePointer
1124#endif /* __INTRINSIC_PROLOG */
1125
1126#endif /* defined(__x86_64__) || defined(_AMD64_) || defined(__i386__) || defined(_X86_) || defined(__arm__) || defined(_ARM_) */
1127
1128#if defined(__x86_64__) || defined(_AMD64_) || defined(__i386__) || defined(_X86_)
1129
1130#if __INTRINSIC_PROLOG(__int2c)
1131void __int2c(void);
1132__INTRINSICS_USEINLINE
1133void __int2c(void) {
1134    __buildint(0x2c);
1135}
1136#define __INTRINSIC_DEFINED___int2c
1137#endif /* __INTRINSIC_PROLOG */
1138
1139#if __INTRINSIC_PROLOG(__stosb)
1140void __stosb(unsigned char *, unsigned char, size_t);
1141__INTRINSICS_USEINLINE
1142__buildstos(__stosb, unsigned char, "b|b")
1143#define __INTRINSIC_DEFINED___stosb
1144#endif /* __INTRINSIC_PROLOG */
1145
1146#if __INTRINSIC_PROLOG(__stosw)
1147void __stosw(unsigned short *, unsigned short, size_t);
1148__INTRINSICS_USEINLINE
1149__buildstos(__stosw, unsigned short, "w|w")
1150#define __INTRINSIC_DEFINED___stosw
1151#endif /* __INTRINSIC_PROLOG */
1152
1153#if __INTRINSIC_PROLOG(__stosd)
1154void __stosd(unsigned __LONG32 *, unsigned __LONG32, size_t);
1155__INTRINSICS_USEINLINE
1156__buildstos(__stosd, unsigned __LONG32, "l|d")
1157#define __INTRINSIC_DEFINED___stosd
1158#endif /* __INTRINSIC_PROLOG */
1159
1160#if __INTRINSIC_PROLOG(_interlockedbittestandset)
1161unsigned char _interlockedbittestandset(__LONG32 *a, __LONG32 b);
1162__INTRINSICS_USEINLINE
1163__buildbittesti(_interlockedbittestandset, __LONG32, "lock bts{l %[Offset],%[Base] | %[Base],%[Offset]}" __FLAGSET, "I", __LONG32)
1164#define __INTRINSIC_DEFINED__interlockedbittestandset
1165#endif /* __INTRINSIC_PROLOG */
1166
1167#if __INTRINSIC_PROLOG(_interlockedbittestandreset)
1168unsigned char _interlockedbittestandreset(__LONG32 *a, __LONG32 b);
1169__INTRINSICS_USEINLINE
1170__buildbittesti(_interlockedbittestandreset, __LONG32, "lock btr{l %[Offset],%[Base] | %[Base],%[Offset]}" __FLAGSET, "I", __LONG32)
1171#define __INTRINSIC_DEFINED__interlockedbittestandreset
1172#endif /* __INTRINSIC_PROLOG */
1173
1174#if __INTRINSIC_PROLOG(_interlockedbittestandcomplement)
1175unsigned char _interlockedbittestandcomplement(__LONG32 *a, __LONG32 b);
1176__INTRINSICS_USEINLINE
1177__buildbittesti(_interlockedbittestandcomplement, __LONG32, "lock btc{l %[Offset],%[Base] | %[Base],%[Offset]}" __FLAGSET, "I", __LONG32)
1178#define __INTRINSIC_DEFINED__interlockedbittestandcomplement
1179#endif /* __INTRINSIC_PROLOG */
1180
1181#if __INTRINSIC_PROLOG(InterlockedBitTestAndSet)
1182unsigned char InterlockedBitTestAndSet(volatile __LONG32 *a, __LONG32 b);
1183__INTRINSICS_USEINLINE
1184__buildbittesti(InterlockedBitTestAndSet, volatile __LONG32, "lock bts{l %[Offset],%[Base] | %[Base],%[Offset]}" __FLAGSET, "I", __LONG32)
1185#define __INTRINSIC_DEFINED_InterlockedBitTestAndSet
1186#endif /* __INTRINSIC_PROLOG */
1187
1188#if __INTRINSIC_PROLOG(InterlockedBitTestAndReset)
1189unsigned char InterlockedBitTestAndReset(volatile __LONG32 *a, __LONG32 b);
1190__INTRINSICS_USEINLINE
1191__buildbittesti(InterlockedBitTestAndReset, volatile __LONG32, "lock btr{l %[Offset],%[Base] | %[Base],%[Offset]}" __FLAGSET, "I", __LONG32)
1192#define __INTRINSIC_DEFINED_InterlockedBitTestAndReset
1193#endif /* __INTRINSIC_PROLOG */
1194
1195#if __INTRINSIC_PROLOG(InterlockedBitTestAndComplement)
1196unsigned char InterlockedBitTestAndComplement(volatile __LONG32 *a, __LONG32 b);
1197__INTRINSICS_USEINLINE
1198__buildbittesti(InterlockedBitTestAndComplement, volatile __LONG32, "lock btc{l %[Offset],%[Base] | %[Base],%[Offset]}" __FLAGSET, "I", __LONG32)
1199#define __INTRINSIC_DEFINED_InterlockedBitTestAndComplement
1200#endif /* __INTRINSIC_PROLOG */
1201
1202#if __INTRINSIC_PROLOG(_BitScanForward)
1203unsigned char _BitScanForward(unsigned __LONG32 *Index, unsigned __LONG32 Mask);
1204__INTRINSICS_USEINLINE
1205__buildbitscan(_BitScanForward, unsigned __LONG32, "bsf{l %[Mask],%[Index] | %[Index],%[Mask]}")
1206#define __INTRINSIC_DEFINED__BitScanForward
1207#endif /* __INTRINSIC_PROLOG */
1208
1209#if __INTRINSIC_PROLOG(_BitScanReverse)
1210unsigned char _BitScanReverse(unsigned __LONG32 *Index, unsigned __LONG32 Mask);
1211__INTRINSICS_USEINLINE
1212__buildbitscan(_BitScanReverse, unsigned __LONG32, "bsr{l %[Mask],%[Index] | %[Index],%[Mask]}")
1213#define __INTRINSIC_DEFINED__BitScanReverse
1214#endif /* __INTRINSIC_PROLOG */
1215
1216#if __INTRINSIC_PROLOG(_bittest)
1217unsigned char _bittest(__LONG32 const *a, __LONG32 b);
1218__INTRINSICS_USEINLINE
1219__buildbittest(_bittest, __LONG32, "l", "I")
1220#define __INTRINSIC_DEFINED__bittest
1221#endif /* __INTRINSIC_PROLOG */
1222
1223#if __INTRINSIC_PROLOG(_bittestandset)
1224unsigned char _bittestandset(__LONG32 *a, __LONG32 b);
1225__INTRINSICS_USEINLINE
1226__buildbittestand(_bittestandset, __LONG32, "bts", "I", "l")
1227#define __INTRINSIC_DEFINED__bittestandset
1228#endif /* __INTRINSIC_PROLOG */
1229
1230#if __INTRINSIC_PROLOG(_bittestandreset)
1231unsigned char _bittestandreset(__LONG32 *a, __LONG32 b);
1232__INTRINSICS_USEINLINE
1233__buildbittestand(_bittestandreset, __LONG32, "btr", "I", "l")
1234#define __INTRINSIC_DEFINED__bittestandreset
1235#endif /* __INTRINSIC_PROLOG */
1236
1237#if __INTRINSIC_PROLOG(_bittestandcomplement)
1238unsigned char _bittestandcomplement(__LONG32 *a, __LONG32 b);
1239__INTRINSICS_USEINLINE
1240__buildbittestand(_bittestandcomplement, __LONG32, "btc", "I", "l")
1241#define __INTRINSIC_DEFINED__bittestandcomplement
1242#endif /* __INTRINSIC_PROLOG */
1243
1244#if __INTRINSIC_PROLOG(__inbyte)
1245unsigned char __inbyte(unsigned short Port);
1246__INTRINSICS_USEINLINE
1247__build_inport(__inbyte, unsigned char, "b")
1248#define __INTRINSIC_DEFINED___inbyte
1249#endif /* __INTRINSIC_PROLOG */
1250
1251#if __INTRINSIC_PROLOG(__inword)
1252unsigned short __inword(unsigned short Port);
1253__INTRINSICS_USEINLINE
1254__build_inport(__inword, unsigned short, "w")
1255#define __INTRINSIC_DEFINED___inword
1256#endif /* __INTRINSIC_PROLOG */
1257
1258#if __INTRINSIC_PROLOG(__indword)
1259unsigned __LONG32 __indword(unsigned short Port);
1260__INTRINSICS_USEINLINE
1261__build_inport(__indword, unsigned __LONG32, "l")
1262#define __INTRINSIC_DEFINED___indword
1263#endif /* __INTRINSIC_PROLOG */
1264
1265#if __INTRINSIC_PROLOG(__outbyte)
1266void __outbyte(unsigned short Port, unsigned char Data);
1267__INTRINSICS_USEINLINE
1268__build_outport(__outbyte, unsigned char, "b")
1269#define __INTRINSIC_DEFINED___outbyte
1270#endif /* __INTRINSIC_PROLOG */
1271
1272#if __INTRINSIC_PROLOG(__outword)
1273void __outword(unsigned short Port, unsigned short Data);
1274__INTRINSICS_USEINLINE
1275__build_outport(__outword, unsigned short, "w")
1276#define __INTRINSIC_DEFINED___outword
1277#endif /* __INTRINSIC_PROLOG */
1278
1279#if __INTRINSIC_PROLOG(__outdword)
1280void __outdword(unsigned short Port, unsigned __LONG32 Data);
1281__INTRINSICS_USEINLINE
1282__build_outport(__outdword, unsigned __LONG32, "l")
1283#define __INTRINSIC_DEFINED___outdword
1284#endif /* __INTRINSIC_PROLOG */
1285
1286#if __INTRINSIC_PROLOG(__inbytestring)
1287void __inbytestring(unsigned short Port, unsigned char *Buffer, unsigned __LONG32 Count);
1288__INTRINSICS_USEINLINE
1289__build_inportstring(__inbytestring, unsigned char, "b", "b")
1290#define __INTRINSIC_DEFINED___inbytestring
1291#endif /* __INTRINSIC_PROLOG */
1292
1293#if __INTRINSIC_PROLOG(__inwordstring)
1294void __inwordstring(unsigned short Port, unsigned short *Buffer, unsigned __LONG32 Count);
1295__INTRINSICS_USEINLINE
1296__build_inportstring(__inwordstring, unsigned short, "w", "w")
1297#define __INTRINSIC_DEFINED___inwordstring
1298#endif /* __INTRINSIC_PROLOG */
1299
1300#if __INTRINSIC_PROLOG(__indwordstring)
1301void __indwordstring(unsigned short Port, unsigned __LONG32 *Buffer, unsigned __LONG32 Count);
1302__INTRINSICS_USEINLINE
1303__build_inportstring(__indwordstring, unsigned __LONG32, "l", "d")
1304#define __INTRINSIC_DEFINED___indwordstring
1305#endif /* __INTRINSIC_PROLOG */
1306
1307#if __INTRINSIC_PROLOG(__outbytestring)
1308void __outbytestring(unsigned short Port, unsigned char *Buffer, unsigned __LONG32 Count);
1309__INTRINSICS_USEINLINE
1310__build_outportstring(__outbytestring, unsigned char, "b", "b")
1311#define __INTRINSIC_DEFINED___outbytestring
1312#endif /* __INTRINSIC_PROLOG */
1313
1314#if __INTRINSIC_PROLOG(__outwordstring)
1315void __outwordstring(unsigned short Port, unsigned short *Buffer, unsigned __LONG32 Count);
1316__INTRINSICS_USEINLINE
1317__build_outportstring(__outwordstring, unsigned short, "w", "w")
1318#define __INTRINSIC_DEFINED___outwordstring
1319#endif /* __INTRINSIC_PROLOG */
1320
1321#if __INTRINSIC_PROLOG(__outdwordstring)
1322void __outdwordstring(unsigned short Port, unsigned __LONG32 *Buffer, unsigned __LONG32 Count);
1323__INTRINSICS_USEINLINE
1324__build_outportstring(__outdwordstring, unsigned __LONG32, "l", "d")
1325#define __INTRINSIC_DEFINED___outdwordstring
1326#endif /* __INTRINSIC_PROLOG */
1327
1328#if __INTRINSIC_PROLOG(__cpuid)
1329void __cpuid(int CPUInfo[4], int InfoType);
1330__INTRINSICS_USEINLINE
1331void __cpuid(int CPUInfo[4], int InfoType) {
1332   __asm__ __volatile__ (
1333      "cpuid"
1334      : "=a" (CPUInfo [0]), "=b" (CPUInfo [1]), "=c" (CPUInfo [2]), "=d" (CPUInfo [3])
1335      : "a" (InfoType));
1336}
1337#define __INTRINSIC_DEFINED___cpuid
1338#endif /* __INTRINSIC_PROLOG */
1339
1340#if __INTRINSIC_PROLOG(__cpuidex)
1341void __cpuidex(int CPUInfo[4], int, int);
1342__INTRINSICS_USEINLINE
1343void __cpuidex(int CPUInfo[4], int function_id, int subfunction_id) {
1344   __asm__ __volatile__ (
1345      "cpuid"
1346      : "=a" (CPUInfo [0]), "=b" (CPUInfo [1]), "=c" (CPUInfo [2]), "=d" (CPUInfo [3])
1347      : "a" (function_id), "c" (subfunction_id));
1348}
1349#define __INTRINSIC_DEFINED___cpuidex
1350#endif /* __INTRINSIC_PROLOG */
1351
1352#if __INTRINSIC_PROLOG(__readmsr)
1353__MINGW_EXTENSION unsigned __int64 __readmsr(unsigned __LONG32);
1354__INTRINSICS_USEINLINE
1355unsigned __int64 __readmsr(unsigned __LONG32 msr)
1356{
1357#if defined(__x86_64__) || defined(_AMD64_)
1358   unsigned __int64 val1, val2;
1359#else
1360   unsigned __LONG32 val1, val2;
1361#endif /* defined(__x86_64__) || defined(_AMD64_) */
1362
1363   __asm__ __volatile__(
1364      "rdmsr"
1365      : "=a" (val1), "=d" (val2)
1366      : "c" (msr));
1367
1368   return ((unsigned __int64) val1) | (((unsigned __int64)val2) << 32);
1369}
1370#define __INTRINSIC_DEFINED___readmsr
1371#endif /* __INTRINSIC_PROLOG */
1372
1373#if __INTRINSIC_PROLOG(__writemsr)
1374__MINGW_EXTENSION void __writemsr(unsigned __LONG32, unsigned __int64);
1375__INTRINSICS_USEINLINE
1376void __writemsr(unsigned __LONG32 msr, unsigned __int64 Value)
1377{
1378   unsigned __LONG32 val1 = Value, val2 = Value >> 32;
1379   __asm__ __volatile__ (
1380      "wrmsr"
1381      :
1382      : "c" (msr), "a" (val1), "d" (val2));
1383}
1384#define __INTRINSIC_DEFINED___writemsr
1385#endif /* __INTRINSIC_PROLOG */
1386
1387#if __INTRINSIC_PROLOG(__movsb)
1388void __movsb(unsigned char *Destination, unsigned char const *Source, size_t Count);
1389__INTRINSICS_USEINLINE
1390__buildmov(__movsb, unsigned char, "b")
1391#define __INTRINSIC_DEFINED___movsb
1392#endif /* __INTRINSIC_PROLOG */
1393
1394#if __INTRINSIC_PROLOG(__movsw)
1395void __movsw(unsigned short *Dest, unsigned short const *Source, size_t Count);
1396__INTRINSICS_USEINLINE
1397__buildmov(__movsw, unsigned short, "w")
1398#define __INTRINSIC_DEFINED___movsw
1399#endif /* __INTRINSIC_PROLOG */
1400
1401#if __INTRINSIC_PROLOG(__movsd)
1402void __movsd(unsigned __LONG32 *Dest, unsigned __LONG32 const *Source, size_t Count);
1403__INTRINSICS_USEINLINE
1404__buildmov(__movsd, unsigned __LONG32, "d")
1405#define __INTRINSIC_DEFINED___movsd
1406#endif /* __INTRINSIC_PROLOG */
1407
1408/* NOTE: This should be in immintrin.h */
1409#if __INTRINSIC_PROLOG(_xgetbv)
1410unsigned __int64 _xgetbv(unsigned int);
1411__INTRINSICS_USEINLINE
1412unsigned __int64 _xgetbv(unsigned int index)
1413{
1414#if defined(__x86_64__) || defined(_AMD64_)
1415   unsigned __int64 val1, val2;
1416#else
1417   unsigned __LONG32 val1, val2;
1418#endif /* defined(__x86_64__) || defined(_AMD64_) */
1419
1420   __asm__ __volatile__(
1421      "xgetbv"
1422      : "=a" (val1), "=d" (val2)
1423      : "c" (index));
1424
1425   return (((unsigned __int64)val2) << 32) | val1;
1426}
1427#define __INTRINSIC_DEFINED__xgetbv
1428#endif /* __INTRINSIC_PROLOG */
1429
1430#endif /* defined(__x86_64__) || defined(_AMD64_) || defined(__i386__) || defined(_X86_) */
1431
1432/* ***************************************************** */
1433
1434#if defined(__i386__) || defined(_X86_)
1435
1436#if __INTRINSIC_PROLOG(__readfsbyte)
1437unsigned char __readfsbyte(unsigned __LONG32 Offset);
1438__INTRINSICS_USEINLINE
1439__buildreadseg(__readfsbyte, unsigned char, "fs", "b")
1440#define __INTRINSIC_DEFINED___readfsbyte
1441#endif /* __INTRINSIC_PROLOG */
1442
1443#if __INTRINSIC_PROLOG(__readfsword)
1444unsigned short __readfsword(unsigned __LONG32 Offset);
1445__INTRINSICS_USEINLINE
1446__buildreadseg(__readfsword, unsigned short, "fs", "w")
1447#define __INTRINSIC_DEFINED___readfsword
1448#endif /* __INTRINSIC_PROLOG */
1449
1450#if __INTRINSIC_PROLOG(__readfsdword)
1451unsigned __LONG32 __readfsdword(unsigned __LONG32 Offset);
1452#if !__has_builtin(__readfsdword)
1453__INTRINSICS_USEINLINE
1454__buildreadseg(__readfsdword, unsigned __LONG32, "fs", "l")
1455#define __INTRINSIC_DEFINED___readfsdword
1456#endif
1457#endif /* __INTRINSIC_PROLOG */
1458
1459#if __INTRINSIC_PROLOG(__writefsbyte)
1460void __writefsbyte(unsigned __LONG32 Offset,unsigned char Data);
1461__INTRINSICS_USEINLINE
1462__buildwriteseg(__writefsbyte, unsigned char, "fs", "b")
1463#define __INTRINSIC_DEFINED___writefsbyte
1464#endif /* __INTRINSIC_PROLOG */
1465
1466#if __INTRINSIC_PROLOG(__writefsword)
1467void __writefsword(unsigned __LONG32 Offset,unsigned short Data);
1468__INTRINSICS_USEINLINE
1469__buildwriteseg(__writefsword, unsigned short, "fs", "w")
1470#define __INTRINSIC_DEFINED___writefsword
1471#endif /* __INTRINSIC_PROLOG */
1472
1473#if __INTRINSIC_PROLOG(__writefsdword)
1474void __writefsdword(unsigned __LONG32 Offset,unsigned __LONG32 Data);
1475__INTRINSICS_USEINLINE
1476__buildwriteseg(__writefsdword, unsigned __LONG32, "fs", "l")
1477#define __INTRINSIC_DEFINED___writefsdword
1478#endif /* __INTRINSIC_PROLOG */
1479
1480#if __INTRINSIC_PROLOG(__readcr0)
1481unsigned __LONG32 __readcr0(void);
1482__INTRINSICS_USEINLINE
1483__build_readcr(__readcr0, unsigned __LONG32, "0")
1484#define __INTRINSIC_DEFINED___readcr0
1485#endif /* __INTRINSIC_PROLOG */
1486
1487#if __INTRINSIC_PROLOG(__readcr2)
1488unsigned __LONG32 __readcr2(void);
1489__INTRINSICS_USEINLINE
1490__build_readcr(__readcr2, unsigned __LONG32, "2")
1491#define __INTRINSIC_DEFINED___readcr2
1492#endif /* __INTRINSIC_PROLOG */
1493
1494#if __INTRINSIC_PROLOG(__readcr3)
1495unsigned __LONG32 __readcr3(void);
1496__INTRINSICS_USEINLINE
1497__build_readcr(__readcr3, unsigned __LONG32, "3")
1498#define __INTRINSIC_DEFINED___readcr3
1499#endif /* __INTRINSIC_PROLOG */
1500
1501#if __INTRINSIC_PROLOG(__readcr4)
1502unsigned __LONG32 __readcr4(void);
1503__INTRINSICS_USEINLINE
1504__build_readcr(__readcr4, unsigned __LONG32, "4")
1505#define __INTRINSIC_DEFINED___readcr4
1506#endif /* __INTRINSIC_PROLOG */
1507
1508#if __INTRINSIC_PROLOG(__readcr8)
1509unsigned __LONG32 __readcr8(void);
1510__INTRINSICS_USEINLINE
1511__build_readcr(__readcr8, unsigned __LONG32, "8")
1512#define __INTRINSIC_DEFINED___readcr8
1513#endif /* __INTRINSIC_PROLOG */
1514
1515#if __INTRINSIC_PROLOG(__writecr0)
1516void __writecr0(unsigned __LONG32);
1517__INTRINSICS_USEINLINE
1518__build_writecr(__writecr0, unsigned __LONG32, "0")
1519#define __INTRINSIC_DEFINED___writecr0
1520#endif /* __INTRINSIC_PROLOG */
1521
1522#if __INTRINSIC_PROLOG(__writecr3)
1523void __writecr3(unsigned __LONG32);
1524__INTRINSICS_USEINLINE
1525__build_writecr(__writecr3, unsigned __LONG32, "3")
1526#define __INTRINSIC_DEFINED___writecr3
1527#endif /* __INTRINSIC_PROLOG */
1528
1529#if __INTRINSIC_PROLOG(__writecr4)
1530void __writecr4(unsigned __LONG32);
1531__INTRINSICS_USEINLINE
1532__build_writecr(__writecr4, unsigned __LONG32, "4")
1533#define __INTRINSIC_DEFINED___writecr4
1534#endif /* __INTRINSIC_PROLOG */
1535
1536#if __INTRINSIC_PROLOG(__writecr8)
1537void __writecr8(unsigned __LONG32);
1538__INTRINSICS_USEINLINE
1539__build_writecr(__writecr8, unsigned __LONG32, "8")
1540#define __INTRINSIC_DEFINED___writecr8
1541#endif /* __INTRINSIC_PROLOG */
1542
1543#endif /* defined(__i386__) || defined(_X86_) */
1544
1545#ifdef __cplusplus
1546}
1547#endif
1548
1549#undef __INTRINSIC_ONLYSPECIAL
1550#undef __INTRINSIC_PROLOG
1551#undef __INTRINSIC_EPILOG
1552#undef __INTRINSICS_USEINLINE
1553#undef __FLAGCONSTRAINT
1554#undef __FLAGSET
1555#undef __FLAGCLOBBER1
1556#undef __FLAGCLOBBER2
1557
1558#pragma pop_macro("__has_builtin")
1559
1560#endif /* __MINGW_INTRIN_INLINE */
1561