10b57cec5SDimitry Andric /*===---- immintrin.h - Intel intrinsics -----------------------------------===
20b57cec5SDimitry Andric *
30b57cec5SDimitry Andric * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric * See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric *
70b57cec5SDimitry Andric *===-----------------------------------------------------------------------===
80b57cec5SDimitry Andric */
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric #ifndef __IMMINTRIN_H
110b57cec5SDimitry Andric #define __IMMINTRIN_H
120b57cec5SDimitry Andric
13349cc55cSDimitry Andric #if !defined(__i386__) && !defined(__x86_64__)
14349cc55cSDimitry Andric #error "This header is only meant to be used on x86 and x64 architecture"
15349cc55cSDimitry Andric #endif
16349cc55cSDimitry Andric
17e8d8bef9SDimitry Andric #include <x86gprintrin.h>
18e8d8bef9SDimitry Andric
19*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__MMX__)
200b57cec5SDimitry Andric #include <mmintrin.h>
210b57cec5SDimitry Andric #endif
220b57cec5SDimitry Andric
23*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__SSE__)
240b57cec5SDimitry Andric #include <xmmintrin.h>
250b57cec5SDimitry Andric #endif
260b57cec5SDimitry Andric
27*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__SSE2__)
280b57cec5SDimitry Andric #include <emmintrin.h>
290b57cec5SDimitry Andric #endif
300b57cec5SDimitry Andric
31*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__SSE3__)
320b57cec5SDimitry Andric #include <pmmintrin.h>
330b57cec5SDimitry Andric #endif
340b57cec5SDimitry Andric
35*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__SSSE3__)
360b57cec5SDimitry Andric #include <tmmintrin.h>
370b57cec5SDimitry Andric #endif
380b57cec5SDimitry Andric
39*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || \
400b57cec5SDimitry Andric (defined(__SSE4_2__) || defined(__SSE4_1__))
410b57cec5SDimitry Andric #include <smmintrin.h>
420b57cec5SDimitry Andric #endif
430b57cec5SDimitry Andric
44*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || \
450b57cec5SDimitry Andric (defined(__AES__) || defined(__PCLMUL__))
460b57cec5SDimitry Andric #include <wmmintrin.h>
470b57cec5SDimitry Andric #endif
480b57cec5SDimitry Andric
49*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__CLFLUSHOPT__)
500b57cec5SDimitry Andric #include <clflushoptintrin.h>
510b57cec5SDimitry Andric #endif
520b57cec5SDimitry Andric
53*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__CLWB__)
540b57cec5SDimitry Andric #include <clwbintrin.h>
550b57cec5SDimitry Andric #endif
560b57cec5SDimitry Andric
57*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX__)
580b57cec5SDimitry Andric #include <avxintrin.h>
590b57cec5SDimitry Andric #endif
600b57cec5SDimitry Andric
61*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX2__)
620b57cec5SDimitry Andric #include <avx2intrin.h>
630b57cec5SDimitry Andric #endif
640b57cec5SDimitry Andric
65*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__F16C__)
660b57cec5SDimitry Andric #include <f16cintrin.h>
670b57cec5SDimitry Andric #endif
680b57cec5SDimitry Andric
69a7dea167SDimitry Andric /* No feature check desired due to internal checks */
700b57cec5SDimitry Andric #include <bmiintrin.h>
710b57cec5SDimitry Andric
72*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__BMI2__)
730b57cec5SDimitry Andric #include <bmi2intrin.h>
740b57cec5SDimitry Andric #endif
750b57cec5SDimitry Andric
76*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__LZCNT__)
770b57cec5SDimitry Andric #include <lzcntintrin.h>
780b57cec5SDimitry Andric #endif
790b57cec5SDimitry Andric
80*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__POPCNT__)
810b57cec5SDimitry Andric #include <popcntintrin.h>
820b57cec5SDimitry Andric #endif
830b57cec5SDimitry Andric
84*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__FMA__)
850b57cec5SDimitry Andric #include <fmaintrin.h>
860b57cec5SDimitry Andric #endif
870b57cec5SDimitry Andric
88*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512F__)
890b57cec5SDimitry Andric #include <avx512fintrin.h>
900b57cec5SDimitry Andric #endif
910b57cec5SDimitry Andric
92*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512VL__)
930b57cec5SDimitry Andric #include <avx512vlintrin.h>
940b57cec5SDimitry Andric #endif
950b57cec5SDimitry Andric
96*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512BW__)
970b57cec5SDimitry Andric #include <avx512bwintrin.h>
980b57cec5SDimitry Andric #endif
990b57cec5SDimitry Andric
100*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512BITALG__)
1010b57cec5SDimitry Andric #include <avx512bitalgintrin.h>
1020b57cec5SDimitry Andric #endif
1030b57cec5SDimitry Andric
104*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512CD__)
1050b57cec5SDimitry Andric #include <avx512cdintrin.h>
1060b57cec5SDimitry Andric #endif
1070b57cec5SDimitry Andric
108*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512VPOPCNTDQ__)
1090b57cec5SDimitry Andric #include <avx512vpopcntdqintrin.h>
1100b57cec5SDimitry Andric #endif
1110b57cec5SDimitry Andric
112*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || \
1130b57cec5SDimitry Andric (defined(__AVX512VL__) && defined(__AVX512VPOPCNTDQ__))
1140b57cec5SDimitry Andric #include <avx512vpopcntdqvlintrin.h>
1150b57cec5SDimitry Andric #endif
1160b57cec5SDimitry Andric
117*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512VNNI__)
1180b57cec5SDimitry Andric #include <avx512vnniintrin.h>
1190b57cec5SDimitry Andric #endif
1200b57cec5SDimitry Andric
121*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || \
1220b57cec5SDimitry Andric (defined(__AVX512VL__) && defined(__AVX512VNNI__))
1230b57cec5SDimitry Andric #include <avx512vlvnniintrin.h>
1240b57cec5SDimitry Andric #endif
1250b57cec5SDimitry Andric
126*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVXVNNI__)
127e8d8bef9SDimitry Andric #include <avxvnniintrin.h>
128e8d8bef9SDimitry Andric #endif
129e8d8bef9SDimitry Andric
130*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512DQ__)
1310b57cec5SDimitry Andric #include <avx512dqintrin.h>
1320b57cec5SDimitry Andric #endif
1330b57cec5SDimitry Andric
134*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || \
1350b57cec5SDimitry Andric (defined(__AVX512VL__) && defined(__AVX512BITALG__))
1360b57cec5SDimitry Andric #include <avx512vlbitalgintrin.h>
1370b57cec5SDimitry Andric #endif
1380b57cec5SDimitry Andric
139*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || \
1400b57cec5SDimitry Andric (defined(__AVX512VL__) && defined(__AVX512BW__))
1410b57cec5SDimitry Andric #include <avx512vlbwintrin.h>
1420b57cec5SDimitry Andric #endif
1430b57cec5SDimitry Andric
144*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || \
1450b57cec5SDimitry Andric (defined(__AVX512VL__) && defined(__AVX512CD__))
1460b57cec5SDimitry Andric #include <avx512vlcdintrin.h>
1470b57cec5SDimitry Andric #endif
1480b57cec5SDimitry Andric
149*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || \
1500b57cec5SDimitry Andric (defined(__AVX512VL__) && defined(__AVX512DQ__))
1510b57cec5SDimitry Andric #include <avx512vldqintrin.h>
1520b57cec5SDimitry Andric #endif
1530b57cec5SDimitry Andric
154*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512IFMA__)
1550b57cec5SDimitry Andric #include <avx512ifmaintrin.h>
1560b57cec5SDimitry Andric #endif
1570b57cec5SDimitry Andric
158*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || \
1590b57cec5SDimitry Andric (defined(__AVX512IFMA__) && defined(__AVX512VL__))
1600b57cec5SDimitry Andric #include <avx512ifmavlintrin.h>
1610b57cec5SDimitry Andric #endif
1620b57cec5SDimitry Andric
163*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVXIFMA__)
164bdd1243dSDimitry Andric #include <avxifmaintrin.h>
165bdd1243dSDimitry Andric #endif
166bdd1243dSDimitry Andric
167*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512VBMI__)
1680b57cec5SDimitry Andric #include <avx512vbmiintrin.h>
1690b57cec5SDimitry Andric #endif
1700b57cec5SDimitry Andric
171*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || \
1720b57cec5SDimitry Andric (defined(__AVX512VBMI__) && defined(__AVX512VL__))
1730b57cec5SDimitry Andric #include <avx512vbmivlintrin.h>
1740b57cec5SDimitry Andric #endif
1750b57cec5SDimitry Andric
176*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512VBMI2__)
1770b57cec5SDimitry Andric #include <avx512vbmi2intrin.h>
1780b57cec5SDimitry Andric #endif
1790b57cec5SDimitry Andric
180*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || \
1810b57cec5SDimitry Andric (defined(__AVX512VBMI2__) && defined(__AVX512VL__))
1820b57cec5SDimitry Andric #include <avx512vlvbmi2intrin.h>
1830b57cec5SDimitry Andric #endif
1840b57cec5SDimitry Andric
185*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512FP16__)
186349cc55cSDimitry Andric #include <avx512fp16intrin.h>
187349cc55cSDimitry Andric #endif
188349cc55cSDimitry Andric
189*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || \
190bdd1243dSDimitry Andric (defined(__AVX512VL__) && defined(__AVX512FP16__))
191349cc55cSDimitry Andric #include <avx512vlfp16intrin.h>
192349cc55cSDimitry Andric #endif
193349cc55cSDimitry Andric
194*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVX512BF16__)
1950b57cec5SDimitry Andric #include <avx512bf16intrin.h>
1960b57cec5SDimitry Andric #endif
1970b57cec5SDimitry Andric
198*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || \
1990b57cec5SDimitry Andric (defined(__AVX512VL__) && defined(__AVX512BF16__))
2000b57cec5SDimitry Andric #include <avx512vlbf16intrin.h>
2010b57cec5SDimitry Andric #endif
2020b57cec5SDimitry Andric
203*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__PKU__)
2040b57cec5SDimitry Andric #include <pkuintrin.h>
2050b57cec5SDimitry Andric #endif
2060b57cec5SDimitry Andric
207*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__VPCLMULQDQ__)
208fe6060f1SDimitry Andric #include <vpclmulqdqintrin.h>
209fe6060f1SDimitry Andric #endif
210fe6060f1SDimitry Andric
211*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__VAES__)
2120b57cec5SDimitry Andric #include <vaesintrin.h>
2130b57cec5SDimitry Andric #endif
2140b57cec5SDimitry Andric
215*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__GFNI__)
2160b57cec5SDimitry Andric #include <gfniintrin.h>
2170b57cec5SDimitry Andric #endif
2180b57cec5SDimitry Andric
219*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVXVNNIINT8__)
220bdd1243dSDimitry Andric #include <avxvnniint8intrin.h>
221bdd1243dSDimitry Andric #endif
222bdd1243dSDimitry Andric
223*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVXNECONVERT__)
224bdd1243dSDimitry Andric #include <avxneconvertintrin.h>
225bdd1243dSDimitry Andric #endif
226bdd1243dSDimitry Andric
227*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__SHA512__)
22806c3fb27SDimitry Andric #include <sha512intrin.h>
22906c3fb27SDimitry Andric #endif
23006c3fb27SDimitry Andric
231*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__SM3__)
23206c3fb27SDimitry Andric #include <sm3intrin.h>
23306c3fb27SDimitry Andric #endif
23406c3fb27SDimitry Andric
235*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__SM4__)
23606c3fb27SDimitry Andric #include <sm4intrin.h>
23706c3fb27SDimitry Andric #endif
23806c3fb27SDimitry Andric
239*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AVXVNNIINT16__)
24006c3fb27SDimitry Andric #include <avxvnniint16intrin.h>
24106c3fb27SDimitry Andric #endif
24206c3fb27SDimitry Andric
243*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__RDPID__)
2445f757f3fSDimitry Andric /// Reads the value of the IA32_TSC_AUX MSR (0xc0000103).
2450b57cec5SDimitry Andric ///
2460b57cec5SDimitry Andric /// \headerfile <immintrin.h>
2470b57cec5SDimitry Andric ///
2480b57cec5SDimitry Andric /// This intrinsic corresponds to the <c> RDPID </c> instruction.
2495f757f3fSDimitry Andric ///
2505f757f3fSDimitry Andric /// \returns The 32-bit contents of the MSR.
2510b57cec5SDimitry Andric static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("rdpid")))
_rdpid_u32(void)2520b57cec5SDimitry Andric _rdpid_u32(void) {
2530b57cec5SDimitry Andric return __builtin_ia32_rdpid();
2540b57cec5SDimitry Andric }
2550b57cec5SDimitry Andric #endif // __RDPID__
2560b57cec5SDimitry Andric
257*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__RDRND__)
25806c3fb27SDimitry Andric /// Returns a 16-bit hardware-generated random value.
25906c3fb27SDimitry Andric ///
26006c3fb27SDimitry Andric /// \headerfile <immintrin.h>
26106c3fb27SDimitry Andric ///
26206c3fb27SDimitry Andric /// This intrinsic corresponds to the <c> RDRAND </c> instruction.
26306c3fb27SDimitry Andric ///
26406c3fb27SDimitry Andric /// \param __p
26506c3fb27SDimitry Andric /// A pointer to a 16-bit memory location to place the random value.
26606c3fb27SDimitry Andric /// \returns 1 if the value was successfully generated, 0 otherwise.
2670b57cec5SDimitry Andric static __inline__ int __attribute__((__always_inline__, __nodebug__, __target__("rdrnd")))
_rdrand16_step(unsigned short * __p)2680b57cec5SDimitry Andric _rdrand16_step(unsigned short *__p)
2690b57cec5SDimitry Andric {
27081ad6265SDimitry Andric return (int)__builtin_ia32_rdrand16_step(__p);
2710b57cec5SDimitry Andric }
2720b57cec5SDimitry Andric
27306c3fb27SDimitry Andric /// Returns a 32-bit hardware-generated random value.
27406c3fb27SDimitry Andric ///
27506c3fb27SDimitry Andric /// \headerfile <immintrin.h>
27606c3fb27SDimitry Andric ///
27706c3fb27SDimitry Andric /// This intrinsic corresponds to the <c> RDRAND </c> instruction.
27806c3fb27SDimitry Andric ///
27906c3fb27SDimitry Andric /// \param __p
28006c3fb27SDimitry Andric /// A pointer to a 32-bit memory location to place the random value.
28106c3fb27SDimitry Andric /// \returns 1 if the value was successfully generated, 0 otherwise.
2820b57cec5SDimitry Andric static __inline__ int __attribute__((__always_inline__, __nodebug__, __target__("rdrnd")))
_rdrand32_step(unsigned int * __p)2830b57cec5SDimitry Andric _rdrand32_step(unsigned int *__p)
2840b57cec5SDimitry Andric {
28581ad6265SDimitry Andric return (int)__builtin_ia32_rdrand32_step(__p);
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric
28806c3fb27SDimitry Andric /// Returns a 64-bit hardware-generated random value.
28906c3fb27SDimitry Andric ///
29006c3fb27SDimitry Andric /// \headerfile <immintrin.h>
29106c3fb27SDimitry Andric ///
29206c3fb27SDimitry Andric /// This intrinsic corresponds to the <c> RDRAND </c> instruction.
29306c3fb27SDimitry Andric ///
29406c3fb27SDimitry Andric /// \param __p
29506c3fb27SDimitry Andric /// A pointer to a 64-bit memory location to place the random value.
29606c3fb27SDimitry Andric /// \returns 1 if the value was successfully generated, 0 otherwise.
2970b57cec5SDimitry Andric static __inline__ int __attribute__((__always_inline__, __nodebug__, __target__("rdrnd")))
_rdrand64_step(unsigned long long * __p)2980b57cec5SDimitry Andric _rdrand64_step(unsigned long long *__p)
2990b57cec5SDimitry Andric {
30006c3fb27SDimitry Andric #ifdef __x86_64__
30181ad6265SDimitry Andric return (int)__builtin_ia32_rdrand64_step(__p);
302bdd1243dSDimitry Andric #else
303bdd1243dSDimitry Andric // We need to emulate the functionality of 64-bit rdrand with 2 32-bit
304bdd1243dSDimitry Andric // rdrand instructions.
305bdd1243dSDimitry Andric unsigned int __lo, __hi;
306bdd1243dSDimitry Andric unsigned int __res_lo = __builtin_ia32_rdrand32_step(&__lo);
307bdd1243dSDimitry Andric unsigned int __res_hi = __builtin_ia32_rdrand32_step(&__hi);
308bdd1243dSDimitry Andric if (__res_lo && __res_hi) {
309bdd1243dSDimitry Andric *__p = ((unsigned long long)__hi << 32) | (unsigned long long)__lo;
310bdd1243dSDimitry Andric return 1;
311bdd1243dSDimitry Andric } else {
312bdd1243dSDimitry Andric *__p = 0;
313bdd1243dSDimitry Andric return 0;
314bdd1243dSDimitry Andric }
3150b57cec5SDimitry Andric #endif
31606c3fb27SDimitry Andric }
3170b57cec5SDimitry Andric #endif /* __RDRND__ */
3180b57cec5SDimitry Andric
319*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__FSGSBASE__)
3200b57cec5SDimitry Andric #ifdef __x86_64__
32106c3fb27SDimitry Andric /// Reads the FS base register.
32206c3fb27SDimitry Andric ///
32306c3fb27SDimitry Andric /// \headerfile <immintrin.h>
32406c3fb27SDimitry Andric ///
32506c3fb27SDimitry Andric /// This intrinsic corresponds to the <c> RDFSBASE </c> instruction.
32606c3fb27SDimitry Andric ///
32706c3fb27SDimitry Andric /// \returns The lower 32 bits of the FS base register.
3280b57cec5SDimitry Andric static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
_readfsbase_u32(void)3290b57cec5SDimitry Andric _readfsbase_u32(void)
3300b57cec5SDimitry Andric {
3310b57cec5SDimitry Andric return __builtin_ia32_rdfsbase32();
3320b57cec5SDimitry Andric }
3330b57cec5SDimitry Andric
33406c3fb27SDimitry Andric /// Reads the FS base register.
33506c3fb27SDimitry Andric ///
33606c3fb27SDimitry Andric /// \headerfile <immintrin.h>
33706c3fb27SDimitry Andric ///
33806c3fb27SDimitry Andric /// This intrinsic corresponds to the <c> RDFSBASE </c> instruction.
33906c3fb27SDimitry Andric ///
34006c3fb27SDimitry Andric /// \returns The contents of the FS base register.
3410b57cec5SDimitry Andric static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
_readfsbase_u64(void)3420b57cec5SDimitry Andric _readfsbase_u64(void)
3430b57cec5SDimitry Andric {
3440b57cec5SDimitry Andric return __builtin_ia32_rdfsbase64();
3450b57cec5SDimitry Andric }
3460b57cec5SDimitry Andric
34706c3fb27SDimitry Andric /// Reads the GS base register.
34806c3fb27SDimitry Andric ///
34906c3fb27SDimitry Andric /// \headerfile <immintrin.h>
35006c3fb27SDimitry Andric ///
35106c3fb27SDimitry Andric /// This intrinsic corresponds to the <c> RDGSBASE </c> instruction.
35206c3fb27SDimitry Andric ///
35306c3fb27SDimitry Andric /// \returns The lower 32 bits of the GS base register.
3540b57cec5SDimitry Andric static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
_readgsbase_u32(void)3550b57cec5SDimitry Andric _readgsbase_u32(void)
3560b57cec5SDimitry Andric {
3570b57cec5SDimitry Andric return __builtin_ia32_rdgsbase32();
3580b57cec5SDimitry Andric }
3590b57cec5SDimitry Andric
36006c3fb27SDimitry Andric /// Reads the GS base register.
36106c3fb27SDimitry Andric ///
36206c3fb27SDimitry Andric /// \headerfile <immintrin.h>
36306c3fb27SDimitry Andric ///
36406c3fb27SDimitry Andric /// This intrinsic corresponds to the <c> RDGSBASE </c> instruction.
36506c3fb27SDimitry Andric ///
36606c3fb27SDimitry Andric /// \returns The contents of the GS base register.
3670b57cec5SDimitry Andric static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
_readgsbase_u64(void)3680b57cec5SDimitry Andric _readgsbase_u64(void)
3690b57cec5SDimitry Andric {
3700b57cec5SDimitry Andric return __builtin_ia32_rdgsbase64();
3710b57cec5SDimitry Andric }
3720b57cec5SDimitry Andric
37306c3fb27SDimitry Andric /// Modifies the FS base register.
37406c3fb27SDimitry Andric ///
37506c3fb27SDimitry Andric /// \headerfile <immintrin.h>
37606c3fb27SDimitry Andric ///
37706c3fb27SDimitry Andric /// This intrinsic corresponds to the <c> WRFSBASE </c> instruction.
37806c3fb27SDimitry Andric ///
37906c3fb27SDimitry Andric /// \param __V
38006c3fb27SDimitry Andric /// Value to use for the lower 32 bits of the FS base register.
3810b57cec5SDimitry Andric static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
_writefsbase_u32(unsigned int __V)3820b57cec5SDimitry Andric _writefsbase_u32(unsigned int __V)
3830b57cec5SDimitry Andric {
3840b57cec5SDimitry Andric __builtin_ia32_wrfsbase32(__V);
3850b57cec5SDimitry Andric }
3860b57cec5SDimitry Andric
38706c3fb27SDimitry Andric /// Modifies the FS base register.
38806c3fb27SDimitry Andric ///
38906c3fb27SDimitry Andric /// \headerfile <immintrin.h>
39006c3fb27SDimitry Andric ///
39106c3fb27SDimitry Andric /// This intrinsic corresponds to the <c> WRFSBASE </c> instruction.
39206c3fb27SDimitry Andric ///
39306c3fb27SDimitry Andric /// \param __V
39406c3fb27SDimitry Andric /// Value to use for the FS base register.
3950b57cec5SDimitry Andric static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
_writefsbase_u64(unsigned long long __V)3960b57cec5SDimitry Andric _writefsbase_u64(unsigned long long __V)
3970b57cec5SDimitry Andric {
3980b57cec5SDimitry Andric __builtin_ia32_wrfsbase64(__V);
3990b57cec5SDimitry Andric }
4000b57cec5SDimitry Andric
40106c3fb27SDimitry Andric /// Modifies the GS base register.
40206c3fb27SDimitry Andric ///
40306c3fb27SDimitry Andric /// \headerfile <immintrin.h>
40406c3fb27SDimitry Andric ///
40506c3fb27SDimitry Andric /// This intrinsic corresponds to the <c> WRGSBASE </c> instruction.
40606c3fb27SDimitry Andric ///
40706c3fb27SDimitry Andric /// \param __V
40806c3fb27SDimitry Andric /// Value to use for the lower 32 bits of the GS base register.
4090b57cec5SDimitry Andric static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
_writegsbase_u32(unsigned int __V)4100b57cec5SDimitry Andric _writegsbase_u32(unsigned int __V)
4110b57cec5SDimitry Andric {
4120b57cec5SDimitry Andric __builtin_ia32_wrgsbase32(__V);
4130b57cec5SDimitry Andric }
4140b57cec5SDimitry Andric
41506c3fb27SDimitry Andric /// Modifies the GS base register.
41606c3fb27SDimitry Andric ///
41706c3fb27SDimitry Andric /// \headerfile <immintrin.h>
41806c3fb27SDimitry Andric ///
41906c3fb27SDimitry Andric /// This intrinsic corresponds to the <c> WRFSBASE </c> instruction.
42006c3fb27SDimitry Andric ///
42106c3fb27SDimitry Andric /// \param __V
42206c3fb27SDimitry Andric /// Value to use for GS base register.
4230b57cec5SDimitry Andric static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("fsgsbase")))
_writegsbase_u64(unsigned long long __V)4240b57cec5SDimitry Andric _writegsbase_u64(unsigned long long __V)
4250b57cec5SDimitry Andric {
4260b57cec5SDimitry Andric __builtin_ia32_wrgsbase64(__V);
4270b57cec5SDimitry Andric }
4280b57cec5SDimitry Andric
4290b57cec5SDimitry Andric #endif
4300b57cec5SDimitry Andric #endif /* __FSGSBASE__ */
4310b57cec5SDimitry Andric
432*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__MOVBE__)
4330b57cec5SDimitry Andric
4340b57cec5SDimitry Andric /* The structs used below are to force the load/store to be unaligned. This
4350b57cec5SDimitry Andric * is accomplished with the __packed__ attribute. The __may_alias__ prevents
4360b57cec5SDimitry Andric * tbaa metadata from being generated based on the struct and the type of the
4370b57cec5SDimitry Andric * field inside of it.
4380b57cec5SDimitry Andric */
4390b57cec5SDimitry Andric
4407a6dacacSDimitry Andric /// Load a 16-bit value from memory and swap its bytes.
4417a6dacacSDimitry Andric ///
4427a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
4437a6dacacSDimitry Andric ///
4447a6dacacSDimitry Andric /// This intrinsic corresponds to the MOVBE instruction.
4457a6dacacSDimitry Andric ///
4467a6dacacSDimitry Andric /// \param __P
4477a6dacacSDimitry Andric /// A pointer to the 16-bit value to load.
4487a6dacacSDimitry Andric /// \returns The byte-swapped value.
4490b57cec5SDimitry Andric static __inline__ short __attribute__((__always_inline__, __nodebug__, __target__("movbe")))
_loadbe_i16(void const * __P)4500b57cec5SDimitry Andric _loadbe_i16(void const * __P) {
4510b57cec5SDimitry Andric struct __loadu_i16 {
45281ad6265SDimitry Andric unsigned short __v;
4530b57cec5SDimitry Andric } __attribute__((__packed__, __may_alias__));
45481ad6265SDimitry Andric return (short)__builtin_bswap16(((const struct __loadu_i16*)__P)->__v);
4550b57cec5SDimitry Andric }
4560b57cec5SDimitry Andric
4577a6dacacSDimitry Andric /// Swap the bytes of a 16-bit value and store it to memory.
4587a6dacacSDimitry Andric ///
4597a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
4607a6dacacSDimitry Andric ///
4617a6dacacSDimitry Andric /// This intrinsic corresponds to the MOVBE instruction.
4627a6dacacSDimitry Andric ///
4637a6dacacSDimitry Andric /// \param __P
4647a6dacacSDimitry Andric /// A pointer to the memory for storing the swapped value.
4657a6dacacSDimitry Andric /// \param __D
4667a6dacacSDimitry Andric /// The 16-bit value to be byte-swapped.
4670b57cec5SDimitry Andric static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("movbe")))
_storebe_i16(void * __P,short __D)4680b57cec5SDimitry Andric _storebe_i16(void * __P, short __D) {
4690b57cec5SDimitry Andric struct __storeu_i16 {
47081ad6265SDimitry Andric unsigned short __v;
4710b57cec5SDimitry Andric } __attribute__((__packed__, __may_alias__));
47281ad6265SDimitry Andric ((struct __storeu_i16*)__P)->__v = __builtin_bswap16((unsigned short)__D);
4730b57cec5SDimitry Andric }
4740b57cec5SDimitry Andric
4757a6dacacSDimitry Andric /// Load a 32-bit value from memory and swap its bytes.
4767a6dacacSDimitry Andric ///
4777a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
4787a6dacacSDimitry Andric ///
4797a6dacacSDimitry Andric /// This intrinsic corresponds to the MOVBE instruction.
4807a6dacacSDimitry Andric ///
4817a6dacacSDimitry Andric /// \param __P
4827a6dacacSDimitry Andric /// A pointer to the 32-bit value to load.
4837a6dacacSDimitry Andric /// \returns The byte-swapped value.
4840b57cec5SDimitry Andric static __inline__ int __attribute__((__always_inline__, __nodebug__, __target__("movbe")))
_loadbe_i32(void const * __P)4850b57cec5SDimitry Andric _loadbe_i32(void const * __P) {
4860b57cec5SDimitry Andric struct __loadu_i32 {
48781ad6265SDimitry Andric unsigned int __v;
4880b57cec5SDimitry Andric } __attribute__((__packed__, __may_alias__));
48981ad6265SDimitry Andric return (int)__builtin_bswap32(((const struct __loadu_i32*)__P)->__v);
4900b57cec5SDimitry Andric }
4910b57cec5SDimitry Andric
4927a6dacacSDimitry Andric /// Swap the bytes of a 32-bit value and store it to memory.
4937a6dacacSDimitry Andric ///
4947a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
4957a6dacacSDimitry Andric ///
4967a6dacacSDimitry Andric /// This intrinsic corresponds to the MOVBE instruction.
4977a6dacacSDimitry Andric ///
4987a6dacacSDimitry Andric /// \param __P
4997a6dacacSDimitry Andric /// A pointer to the memory for storing the swapped value.
5007a6dacacSDimitry Andric /// \param __D
5017a6dacacSDimitry Andric /// The 32-bit value to be byte-swapped.
5020b57cec5SDimitry Andric static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("movbe")))
_storebe_i32(void * __P,int __D)5030b57cec5SDimitry Andric _storebe_i32(void * __P, int __D) {
5040b57cec5SDimitry Andric struct __storeu_i32 {
50581ad6265SDimitry Andric unsigned int __v;
5060b57cec5SDimitry Andric } __attribute__((__packed__, __may_alias__));
50781ad6265SDimitry Andric ((struct __storeu_i32*)__P)->__v = __builtin_bswap32((unsigned int)__D);
5080b57cec5SDimitry Andric }
5090b57cec5SDimitry Andric
5100b57cec5SDimitry Andric #ifdef __x86_64__
5117a6dacacSDimitry Andric /// Load a 64-bit value from memory and swap its bytes.
5127a6dacacSDimitry Andric ///
5137a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
5147a6dacacSDimitry Andric ///
5157a6dacacSDimitry Andric /// This intrinsic corresponds to the MOVBE instruction.
5167a6dacacSDimitry Andric ///
5177a6dacacSDimitry Andric /// \param __P
5187a6dacacSDimitry Andric /// A pointer to the 64-bit value to load.
5197a6dacacSDimitry Andric /// \returns The byte-swapped value.
5200b57cec5SDimitry Andric static __inline__ long long __attribute__((__always_inline__, __nodebug__, __target__("movbe")))
_loadbe_i64(void const * __P)5210b57cec5SDimitry Andric _loadbe_i64(void const * __P) {
5220b57cec5SDimitry Andric struct __loadu_i64 {
52381ad6265SDimitry Andric unsigned long long __v;
5240b57cec5SDimitry Andric } __attribute__((__packed__, __may_alias__));
52581ad6265SDimitry Andric return (long long)__builtin_bswap64(((const struct __loadu_i64*)__P)->__v);
5260b57cec5SDimitry Andric }
5270b57cec5SDimitry Andric
5287a6dacacSDimitry Andric /// Swap the bytes of a 64-bit value and store it to memory.
5297a6dacacSDimitry Andric ///
5307a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
5317a6dacacSDimitry Andric ///
5327a6dacacSDimitry Andric /// This intrinsic corresponds to the MOVBE instruction.
5337a6dacacSDimitry Andric ///
5347a6dacacSDimitry Andric /// \param __P
5357a6dacacSDimitry Andric /// A pointer to the memory for storing the swapped value.
5367a6dacacSDimitry Andric /// \param __D
5377a6dacacSDimitry Andric /// The 64-bit value to be byte-swapped.
5380b57cec5SDimitry Andric static __inline__ void __attribute__((__always_inline__, __nodebug__, __target__("movbe")))
_storebe_i64(void * __P,long long __D)5390b57cec5SDimitry Andric _storebe_i64(void * __P, long long __D) {
5400b57cec5SDimitry Andric struct __storeu_i64 {
54181ad6265SDimitry Andric unsigned long long __v;
5420b57cec5SDimitry Andric } __attribute__((__packed__, __may_alias__));
54381ad6265SDimitry Andric ((struct __storeu_i64*)__P)->__v = __builtin_bswap64((unsigned long long)__D);
5440b57cec5SDimitry Andric }
5450b57cec5SDimitry Andric #endif
5460b57cec5SDimitry Andric #endif /* __MOVBE */
5470b57cec5SDimitry Andric
548*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__RTM__)
5490b57cec5SDimitry Andric #include <rtmintrin.h>
5500b57cec5SDimitry Andric #include <xtestintrin.h>
5510b57cec5SDimitry Andric #endif
5520b57cec5SDimitry Andric
553*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__SHA__)
5540b57cec5SDimitry Andric #include <shaintrin.h>
5550b57cec5SDimitry Andric #endif
5560b57cec5SDimitry Andric
557*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__FXSR__)
5580b57cec5SDimitry Andric #include <fxsrintrin.h>
5590b57cec5SDimitry Andric #endif
5600b57cec5SDimitry Andric
5610b57cec5SDimitry Andric /* No feature check desired due to internal MSC_VER checks */
5620b57cec5SDimitry Andric #include <xsaveintrin.h>
5630b57cec5SDimitry Andric
564*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__XSAVEOPT__)
5650b57cec5SDimitry Andric #include <xsaveoptintrin.h>
5660b57cec5SDimitry Andric #endif
5670b57cec5SDimitry Andric
568*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__XSAVEC__)
5690b57cec5SDimitry Andric #include <xsavecintrin.h>
5700b57cec5SDimitry Andric #endif
5710b57cec5SDimitry Andric
572*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__XSAVES__)
5730b57cec5SDimitry Andric #include <xsavesintrin.h>
5740b57cec5SDimitry Andric #endif
5750b57cec5SDimitry Andric
576*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__SHSTK__)
5770b57cec5SDimitry Andric #include <cetintrin.h>
5780b57cec5SDimitry Andric #endif
5790b57cec5SDimitry Andric
580cb14a3feSDimitry Andric /* Intrinsics inside adcintrin.h are available at all times. */
581cb14a3feSDimitry Andric #include <adcintrin.h>
582cb14a3feSDimitry Andric
583*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__ADX__)
5840b57cec5SDimitry Andric #include <adxintrin.h>
585cb14a3feSDimitry Andric #endif
5860b57cec5SDimitry Andric
587*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__RDSEED__)
5880b57cec5SDimitry Andric #include <rdseedintrin.h>
5890b57cec5SDimitry Andric #endif
5900b57cec5SDimitry Andric
591*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__WBNOINVD__)
5920b57cec5SDimitry Andric #include <wbnoinvdintrin.h>
5930b57cec5SDimitry Andric #endif
5940b57cec5SDimitry Andric
595*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__CLDEMOTE__)
5960b57cec5SDimitry Andric #include <cldemoteintrin.h>
5970b57cec5SDimitry Andric #endif
5980b57cec5SDimitry Andric
599*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__WAITPKG__)
6000b57cec5SDimitry Andric #include <waitpkgintrin.h>
6010b57cec5SDimitry Andric #endif
6020b57cec5SDimitry Andric
603*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__MOVDIRI__) || \
604*0fca6ea1SDimitry Andric defined(__MOVDIR64B__)
6050b57cec5SDimitry Andric #include <movdirintrin.h>
6060b57cec5SDimitry Andric #endif
6070b57cec5SDimitry Andric
608*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__PCONFIG__)
6090b57cec5SDimitry Andric #include <pconfigintrin.h>
6100b57cec5SDimitry Andric #endif
6110b57cec5SDimitry Andric
612*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__SGX__)
6130b57cec5SDimitry Andric #include <sgxintrin.h>
6140b57cec5SDimitry Andric #endif
6150b57cec5SDimitry Andric
616*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__PTWRITE__)
6170b57cec5SDimitry Andric #include <ptwriteintrin.h>
6180b57cec5SDimitry Andric #endif
6190b57cec5SDimitry Andric
620*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__INVPCID__)
6210b57cec5SDimitry Andric #include <invpcidintrin.h>
6220b57cec5SDimitry Andric #endif
623*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AMX_FP16__)
624bdd1243dSDimitry Andric #include <amxfp16intrin.h>
625bdd1243dSDimitry Andric #endif
6260b57cec5SDimitry Andric
627*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__KL__) || \
628*0fca6ea1SDimitry Andric defined(__WIDEKL__)
629e8d8bef9SDimitry Andric #include <keylockerintrin.h>
630e8d8bef9SDimitry Andric #endif
631e8d8bef9SDimitry Andric
632*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AMX_TILE__) || \
633*0fca6ea1SDimitry Andric defined(__AMX_INT8__) || defined(__AMX_BF16__)
6345ffd83dbSDimitry Andric #include <amxintrin.h>
6355ffd83dbSDimitry Andric #endif
6365ffd83dbSDimitry Andric
637*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__AMX_COMPLEX__)
63806c3fb27SDimitry Andric #include <amxcomplexintrin.h>
63906c3fb27SDimitry Andric #endif
64006c3fb27SDimitry Andric
641*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || \
6420b57cec5SDimitry Andric defined(__AVX512VP2INTERSECT__)
6430b57cec5SDimitry Andric #include <avx512vp2intersectintrin.h>
6440b57cec5SDimitry Andric #endif
6450b57cec5SDimitry Andric
646*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || \
6470b57cec5SDimitry Andric (defined(__AVX512VL__) && defined(__AVX512VP2INTERSECT__))
6480b57cec5SDimitry Andric #include <avx512vlvp2intersectintrin.h>
6490b57cec5SDimitry Andric #endif
6500b57cec5SDimitry Andric
651*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__ENQCMD__)
6520b57cec5SDimitry Andric #include <enqcmdintrin.h>
6530b57cec5SDimitry Andric #endif
6540b57cec5SDimitry Andric
655*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__SERIALIZE__)
6565ffd83dbSDimitry Andric #include <serializeintrin.h>
6575ffd83dbSDimitry Andric #endif
6585ffd83dbSDimitry Andric
659*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__TSXLDTRK__)
6605ffd83dbSDimitry Andric #include <tsxldtrkintrin.h>
6615ffd83dbSDimitry Andric #endif
6625ffd83dbSDimitry Andric
6630b57cec5SDimitry Andric #if defined(_MSC_VER) && __has_extension(gnu_asm)
6640b57cec5SDimitry Andric /* Define the default attributes for these intrinsics */
6650b57cec5SDimitry Andric #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
6660b57cec5SDimitry Andric #ifdef __cplusplus
6670b57cec5SDimitry Andric extern "C" {
6680b57cec5SDimitry Andric #endif
6690b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
6700b57cec5SDimitry Andric |* Interlocked Exchange HLE
6710b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
6720b57cec5SDimitry Andric #if defined(__i386__) || defined(__x86_64__)
6730b57cec5SDimitry Andric static __inline__ long __DEFAULT_FN_ATTRS
_InterlockedExchange_HLEAcquire(long volatile * _Target,long _Value)6740b57cec5SDimitry Andric _InterlockedExchange_HLEAcquire(long volatile *_Target, long _Value) {
675349cc55cSDimitry Andric __asm__ __volatile__(".byte 0xf2 ; lock ; xchg {%0, %1|%1, %0}"
6760b57cec5SDimitry Andric : "+r" (_Value), "+m" (*_Target) :: "memory");
6770b57cec5SDimitry Andric return _Value;
6780b57cec5SDimitry Andric }
6790b57cec5SDimitry Andric static __inline__ long __DEFAULT_FN_ATTRS
_InterlockedExchange_HLERelease(long volatile * _Target,long _Value)6800b57cec5SDimitry Andric _InterlockedExchange_HLERelease(long volatile *_Target, long _Value) {
681349cc55cSDimitry Andric __asm__ __volatile__(".byte 0xf3 ; lock ; xchg {%0, %1|%1, %0}"
6820b57cec5SDimitry Andric : "+r" (_Value), "+m" (*_Target) :: "memory");
6830b57cec5SDimitry Andric return _Value;
6840b57cec5SDimitry Andric }
6850b57cec5SDimitry Andric #endif
6860b57cec5SDimitry Andric #if defined(__x86_64__)
6870b57cec5SDimitry Andric static __inline__ __int64 __DEFAULT_FN_ATTRS
_InterlockedExchange64_HLEAcquire(__int64 volatile * _Target,__int64 _Value)6880b57cec5SDimitry Andric _InterlockedExchange64_HLEAcquire(__int64 volatile *_Target, __int64 _Value) {
689349cc55cSDimitry Andric __asm__ __volatile__(".byte 0xf2 ; lock ; xchg {%0, %1|%1, %0}"
6900b57cec5SDimitry Andric : "+r" (_Value), "+m" (*_Target) :: "memory");
6910b57cec5SDimitry Andric return _Value;
6920b57cec5SDimitry Andric }
6930b57cec5SDimitry Andric static __inline__ __int64 __DEFAULT_FN_ATTRS
_InterlockedExchange64_HLERelease(__int64 volatile * _Target,__int64 _Value)6940b57cec5SDimitry Andric _InterlockedExchange64_HLERelease(__int64 volatile *_Target, __int64 _Value) {
695349cc55cSDimitry Andric __asm__ __volatile__(".byte 0xf3 ; lock ; xchg {%0, %1|%1, %0}"
6960b57cec5SDimitry Andric : "+r" (_Value), "+m" (*_Target) :: "memory");
6970b57cec5SDimitry Andric return _Value;
6980b57cec5SDimitry Andric }
6990b57cec5SDimitry Andric #endif
7000b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
7010b57cec5SDimitry Andric |* Interlocked Compare Exchange HLE
7020b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
7030b57cec5SDimitry Andric #if defined(__i386__) || defined(__x86_64__)
7040b57cec5SDimitry Andric static __inline__ long __DEFAULT_FN_ATTRS
_InterlockedCompareExchange_HLEAcquire(long volatile * _Destination,long _Exchange,long _Comparand)7050b57cec5SDimitry Andric _InterlockedCompareExchange_HLEAcquire(long volatile *_Destination,
7060b57cec5SDimitry Andric long _Exchange, long _Comparand) {
707349cc55cSDimitry Andric __asm__ __volatile__(".byte 0xf2 ; lock ; cmpxchg {%2, %1|%1, %2}"
7080b57cec5SDimitry Andric : "+a" (_Comparand), "+m" (*_Destination)
7090b57cec5SDimitry Andric : "r" (_Exchange) : "memory");
7100b57cec5SDimitry Andric return _Comparand;
7110b57cec5SDimitry Andric }
7120b57cec5SDimitry Andric static __inline__ long __DEFAULT_FN_ATTRS
_InterlockedCompareExchange_HLERelease(long volatile * _Destination,long _Exchange,long _Comparand)7130b57cec5SDimitry Andric _InterlockedCompareExchange_HLERelease(long volatile *_Destination,
7140b57cec5SDimitry Andric long _Exchange, long _Comparand) {
715349cc55cSDimitry Andric __asm__ __volatile__(".byte 0xf3 ; lock ; cmpxchg {%2, %1|%1, %2}"
7160b57cec5SDimitry Andric : "+a" (_Comparand), "+m" (*_Destination)
7170b57cec5SDimitry Andric : "r" (_Exchange) : "memory");
7180b57cec5SDimitry Andric return _Comparand;
7190b57cec5SDimitry Andric }
7200b57cec5SDimitry Andric #endif
7210b57cec5SDimitry Andric #if defined(__x86_64__)
7220b57cec5SDimitry Andric static __inline__ __int64 __DEFAULT_FN_ATTRS
_InterlockedCompareExchange64_HLEAcquire(__int64 volatile * _Destination,__int64 _Exchange,__int64 _Comparand)7230b57cec5SDimitry Andric _InterlockedCompareExchange64_HLEAcquire(__int64 volatile *_Destination,
7240b57cec5SDimitry Andric __int64 _Exchange, __int64 _Comparand) {
725349cc55cSDimitry Andric __asm__ __volatile__(".byte 0xf2 ; lock ; cmpxchg {%2, %1|%1, %2}"
7260b57cec5SDimitry Andric : "+a" (_Comparand), "+m" (*_Destination)
7270b57cec5SDimitry Andric : "r" (_Exchange) : "memory");
7280b57cec5SDimitry Andric return _Comparand;
7290b57cec5SDimitry Andric }
7300b57cec5SDimitry Andric static __inline__ __int64 __DEFAULT_FN_ATTRS
_InterlockedCompareExchange64_HLERelease(__int64 volatile * _Destination,__int64 _Exchange,__int64 _Comparand)7310b57cec5SDimitry Andric _InterlockedCompareExchange64_HLERelease(__int64 volatile *_Destination,
7320b57cec5SDimitry Andric __int64 _Exchange, __int64 _Comparand) {
733349cc55cSDimitry Andric __asm__ __volatile__(".byte 0xf3 ; lock ; cmpxchg {%2, %1|%1, %2}"
7340b57cec5SDimitry Andric : "+a" (_Comparand), "+m" (*_Destination)
7350b57cec5SDimitry Andric : "r" (_Exchange) : "memory");
7360b57cec5SDimitry Andric return _Comparand;
7370b57cec5SDimitry Andric }
7380b57cec5SDimitry Andric #endif
7390b57cec5SDimitry Andric #ifdef __cplusplus
7400b57cec5SDimitry Andric }
7410b57cec5SDimitry Andric #endif
7420b57cec5SDimitry Andric
7430b57cec5SDimitry Andric #undef __DEFAULT_FN_ATTRS
7440b57cec5SDimitry Andric
7450b57cec5SDimitry Andric #endif /* defined(_MSC_VER) && __has_extension(gnu_asm) */
7460b57cec5SDimitry Andric
7470b57cec5SDimitry Andric #endif /* __IMMINTRIN_H */
748