Home | History | Annotate | Download | only in psdk_inc
      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.
    158 It 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 
    163 Parameters: (IntNum)
    164 IntNum: 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.
    168 Note that on i386, xchg performs an implicit lock. */
    169 #define __buildmemorybarrier() \
    170 { \
    171 unsigned 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 
    178 Parameters: (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 
    196 Parameters: (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 
    211 Parameters: (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 
    244 Parameters: (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 
    264 Parameters: (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 
    283 Parameters: (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 
    298 Parameters: (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 
    311 Parameters: (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 
    326 Parameters: (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 
    342 Parameters: (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 
    357 Parameters: (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 
    372 Parameters: (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
    390 supports 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
    544 extern "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)
    552 unsigned long _lrotl(unsigned long __X, int __C);
    553 __INTRINSICS_USEINLINE
    554 unsigned 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)
    562 unsigned long _lrotr(unsigned long __X, int __C);
    563 __INTRINSICS_USEINLINE
    564 unsigned 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)
    574 void __faststorefence(void);
    575 __INTRINSICS_USEINLINE
    576 void __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)
    691 unsigned 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)
    698 unsigned 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)
    705 unsigned __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)
    719 void __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)
    726 void __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)
    733 void __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)
    859 unsigned __int64 _umul128(unsigned __int64, unsigned __int64, unsigned __int64 *);
    860 __INTRINSICS_USEINLINE
    861 unsigned __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)
    887 unsigned __int64 __shiftleft128(unsigned __int64  LowPart, unsigned __int64 HighPart, unsigned char Shift);
    888 __INTRINSICS_USEINLINE
    889 unsigned __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)
    904 unsigned __int64 __shiftright128 (unsigned __int64  LowPart, unsigned __int64 HighPart, unsigned char Shift);
    905 __INTRINSICS_USEINLINE
    906 unsigned __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)
    927 unsigned 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)
    934 unsigned 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)
    941 unsigned 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)
    948 unsigned 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)
    955 unsigned 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)
    962 unsigned 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)
    996 short _InterlockedIncrement16(short volatile *Addend);
    997 __INTRINSICS_USEINLINE
    998 short _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)
   1005 short _InterlockedDecrement16(short volatile *Addend);
   1006 __INTRINSICS_USEINLINE
   1007 short _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)
   1014 short _InterlockedCompareExchange16(short volatile *Destination, short ExChange, short Comperand);
   1015 __INTRINSICS_USEINLINE
   1016 short _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)
   1105 void *_InterlockedCompareExchangePointer(void * volatile *Destination, void *ExChange, void *Comperand);
   1106 #if !__has_builtin(_InterlockedCompareExchangePointer)
   1107 __INTRINSICS_USEINLINE
   1108 void *_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)
   1116 void *_InterlockedExchangePointer(void *volatile *Target,void *Value);
   1117 #if !__has_builtin(_InterlockedExchangePointer)
   1118 __INTRINSICS_USEINLINE
   1119 void *_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)
   1131 void __int2c(void);
   1132 __INTRINSICS_USEINLINE
   1133 void __int2c(void) {
   1134     __buildint(0x2c);
   1135 }
   1136 #define __INTRINSIC_DEFINED___int2c
   1137 #endif /* __INTRINSIC_PROLOG */
   1138 
   1139 #if __INTRINSIC_PROLOG(__stosb)
   1140 void __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)
   1147 void __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)
   1154 void __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)
   1161 unsigned 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)
   1168 unsigned 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)
   1175 unsigned 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)
   1182 unsigned 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)
   1189 unsigned 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)
   1196 unsigned 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)
   1203 unsigned 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)
   1210 unsigned 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)
   1217 unsigned 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)
   1224 unsigned 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)
   1231 unsigned 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)
   1238 unsigned 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)
   1245 unsigned 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)
   1252 unsigned 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)
   1259 unsigned __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)
   1266 void __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)
   1273 void __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)
   1280 void __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)
   1287 void __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)
   1294 void __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)
   1301 void __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)
   1308 void __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)
   1315 void __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)
   1322 void __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)
   1329 void __cpuid(int CPUInfo[4], int InfoType);
   1330 __INTRINSICS_USEINLINE
   1331 void __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)
   1341 void __cpuidex(int CPUInfo[4], int, int);
   1342 __INTRINSICS_USEINLINE
   1343 void __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
   1355 unsigned __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
   1376 void __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)
   1388 void __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)
   1395 void __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)
   1402 void __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)
   1410 unsigned __int64 _xgetbv(unsigned int);
   1411 __INTRINSICS_USEINLINE
   1412 unsigned __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)
   1437 unsigned 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)
   1444 unsigned 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)
   1451 unsigned __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)
   1460 void __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)
   1467 void __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)
   1474 void __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)
   1481 unsigned __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)
   1488 unsigned __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)
   1495 unsigned __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)
   1502 unsigned __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)
   1509 unsigned __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)
   1516 void __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)
   1523 void __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)
   1530 void __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)
   1537 void __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