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