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