10b57cec5SDimitry Andric /* ===-------- ia32intrin.h ---------------------------------------------------=== 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 __X86INTRIN_H 110b57cec5SDimitry Andric #error "Never use <ia32intrin.h> directly; include <x86intrin.h> instead." 120b57cec5SDimitry Andric #endif 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef __IA32INTRIN_H 150b57cec5SDimitry Andric #define __IA32INTRIN_H 160b57cec5SDimitry Andric 17e8d8bef9SDimitry Andric /* Define the default attributes for the functions in this file. */ 18e8d8bef9SDimitry Andric #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) 19349cc55cSDimitry Andric #define __DEFAULT_FN_ATTRS_CRC32 __attribute__((__always_inline__, __nodebug__, __target__("crc32"))) 20e8d8bef9SDimitry Andric 21e8d8bef9SDimitry Andric #if defined(__cplusplus) && (__cplusplus >= 201103L) 22e8d8bef9SDimitry Andric #define __DEFAULT_FN_ATTRS_CAST __attribute__((__always_inline__)) constexpr 23e8d8bef9SDimitry Andric #define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS constexpr 24e8d8bef9SDimitry Andric #else 25e8d8bef9SDimitry Andric #define __DEFAULT_FN_ATTRS_CAST __attribute__((__always_inline__)) 26e8d8bef9SDimitry Andric #define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS 27e8d8bef9SDimitry Andric #endif 28e8d8bef9SDimitry Andric 29*297eecfbSDimitry Andric /// Find the first set bit starting from the lsb. Result is undefined if 30*297eecfbSDimitry Andric /// input is 0. 31*297eecfbSDimitry Andric /// 32*297eecfbSDimitry Andric /// \headerfile <x86intrin.h> 33*297eecfbSDimitry Andric /// 34*297eecfbSDimitry Andric /// This intrinsic corresponds to the \c BSF instruction or the 35*297eecfbSDimitry Andric /// \c TZCNT instruction. 36*297eecfbSDimitry Andric /// 37*297eecfbSDimitry Andric /// \param __A 38*297eecfbSDimitry Andric /// A 32-bit integer operand. 39*297eecfbSDimitry Andric /// \returns A 32-bit integer containing the bit number. 40e8d8bef9SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR 410b57cec5SDimitry Andric __bsfd(int __A) { 4281ad6265SDimitry Andric return __builtin_ctz((unsigned int)__A); 430b57cec5SDimitry Andric } 440b57cec5SDimitry Andric 45*297eecfbSDimitry Andric /// Find the first set bit starting from the msb. Result is undefined if 46*297eecfbSDimitry Andric /// input is 0. 47*297eecfbSDimitry Andric /// 48*297eecfbSDimitry Andric /// \headerfile <x86intrin.h> 49*297eecfbSDimitry Andric /// 50*297eecfbSDimitry Andric /// This intrinsic corresponds to the \c BSR instruction or the 51*297eecfbSDimitry Andric /// \c LZCNT instruction and an \c XOR. 52*297eecfbSDimitry Andric /// 53*297eecfbSDimitry Andric /// \param __A 54*297eecfbSDimitry Andric /// A 32-bit integer operand. 55*297eecfbSDimitry Andric /// \returns A 32-bit integer containing the bit number. 56e8d8bef9SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR 570b57cec5SDimitry Andric __bsrd(int __A) { 5881ad6265SDimitry Andric return 31 - __builtin_clz((unsigned int)__A); 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric 61*297eecfbSDimitry Andric /// Swaps the bytes in the input. Converting little endian to big endian or 62*297eecfbSDimitry Andric /// vice versa. 63*297eecfbSDimitry Andric /// 64*297eecfbSDimitry Andric /// \headerfile <x86intrin.h> 65*297eecfbSDimitry Andric /// 66*297eecfbSDimitry Andric /// This intrinsic corresponds to the \c BSWAP instruction. 67*297eecfbSDimitry Andric /// 68*297eecfbSDimitry Andric /// \param __A 69*297eecfbSDimitry Andric /// A 32-bit integer operand. 70*297eecfbSDimitry Andric /// \returns A 32-bit integer containing the swapped bytes. 71e8d8bef9SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR 720b57cec5SDimitry Andric __bswapd(int __A) { 7381ad6265SDimitry Andric return (int)__builtin_bswap32((unsigned int)__A); 740b57cec5SDimitry Andric } 750b57cec5SDimitry Andric 76e8d8bef9SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR 770b57cec5SDimitry Andric _bswap(int __A) { 7881ad6265SDimitry Andric return (int)__builtin_bswap32((unsigned int)__A); 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric #define _bit_scan_forward(A) __bsfd((A)) 820b57cec5SDimitry Andric #define _bit_scan_reverse(A) __bsrd((A)) 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric #ifdef __x86_64__ 85*297eecfbSDimitry Andric /// Find the first set bit starting from the lsb. Result is undefined if 86*297eecfbSDimitry Andric /// input is 0. 87*297eecfbSDimitry Andric /// 88*297eecfbSDimitry Andric /// \headerfile <x86intrin.h> 89*297eecfbSDimitry Andric /// 90*297eecfbSDimitry Andric /// This intrinsic corresponds to the \c BSF instruction or the 91*297eecfbSDimitry Andric /// \c TZCNT instruction. 92*297eecfbSDimitry Andric /// 93*297eecfbSDimitry Andric /// \param __A 94*297eecfbSDimitry Andric /// A 64-bit integer operand. 95*297eecfbSDimitry Andric /// \returns A 32-bit integer containing the bit number. 96e8d8bef9SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR 970b57cec5SDimitry Andric __bsfq(long long __A) { 9881ad6265SDimitry Andric return (long long)__builtin_ctzll((unsigned long long)__A); 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric 101*297eecfbSDimitry Andric /// Find the first set bit starting from the msb. Result is undefined if 102*297eecfbSDimitry Andric /// input is 0. 103*297eecfbSDimitry Andric /// 104*297eecfbSDimitry Andric /// \headerfile <x86intrin.h> 105*297eecfbSDimitry Andric /// 106*297eecfbSDimitry Andric /// This intrinsic corresponds to the \c BSR instruction or the 107*297eecfbSDimitry Andric /// \c LZCNT instruction and an \c XOR. 108*297eecfbSDimitry Andric /// 109*297eecfbSDimitry Andric /// \param __A 110*297eecfbSDimitry Andric /// A 64-bit integer operand. 111*297eecfbSDimitry Andric /// \returns A 32-bit integer containing the bit number. 112e8d8bef9SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR 1130b57cec5SDimitry Andric __bsrq(long long __A) { 11481ad6265SDimitry Andric return 63 - __builtin_clzll((unsigned long long)__A); 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric 117*297eecfbSDimitry Andric /// Swaps the bytes in the input. Converting little endian to big endian or 118*297eecfbSDimitry Andric /// vice versa. 119*297eecfbSDimitry Andric /// 120*297eecfbSDimitry Andric /// \headerfile <x86intrin.h> 121*297eecfbSDimitry Andric /// 122*297eecfbSDimitry Andric /// This intrinsic corresponds to the \c BSWAP instruction. 123*297eecfbSDimitry Andric /// 124*297eecfbSDimitry Andric /// \param __A 125*297eecfbSDimitry Andric /// A 64-bit integer operand. 126*297eecfbSDimitry Andric /// \returns A 64-bit integer containing the swapped bytes. 127e8d8bef9SDimitry Andric static __inline__ long long __DEFAULT_FN_ATTRS_CONSTEXPR 1280b57cec5SDimitry Andric __bswapq(long long __A) { 12981ad6265SDimitry Andric return (long long)__builtin_bswap64((unsigned long long)__A); 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric #define _bswap64(A) __bswapq((A)) 1330b57cec5SDimitry Andric #endif 1340b57cec5SDimitry Andric 135*297eecfbSDimitry Andric /// Counts the number of bits in the source operand having a value of 1. 136*297eecfbSDimitry Andric /// 137*297eecfbSDimitry Andric /// \headerfile <x86intrin.h> 138*297eecfbSDimitry Andric /// 139*297eecfbSDimitry Andric /// This intrinsic corresponds to the \c POPCNT instruction or a 140*297eecfbSDimitry Andric /// a sequence of arithmetic and logic ops to calculate it. 141*297eecfbSDimitry Andric /// 142*297eecfbSDimitry Andric /// \param __A 143*297eecfbSDimitry Andric /// An unsigned 32-bit integer operand. 144*297eecfbSDimitry Andric /// \returns A 32-bit integer containing the number of bits with value 1 in the 145*297eecfbSDimitry Andric /// source operand. 146e8d8bef9SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR 1470b57cec5SDimitry Andric __popcntd(unsigned int __A) 1480b57cec5SDimitry Andric { 1490b57cec5SDimitry Andric return __builtin_popcount(__A); 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric #define _popcnt32(A) __popcntd((A)) 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric #ifdef __x86_64__ 155*297eecfbSDimitry Andric /// Counts the number of bits in the source operand having a value of 1. 156*297eecfbSDimitry Andric /// 157*297eecfbSDimitry Andric /// \headerfile <x86intrin.h> 158*297eecfbSDimitry Andric /// 159*297eecfbSDimitry Andric /// This intrinsic corresponds to the \c POPCNT instruction or a 160*297eecfbSDimitry Andric /// a sequence of arithmetic and logic ops to calculate it. 161*297eecfbSDimitry Andric /// 162*297eecfbSDimitry Andric /// \param __A 163*297eecfbSDimitry Andric /// An unsigned 64-bit integer operand. 164*297eecfbSDimitry Andric /// \returns A 64-bit integer containing the number of bits with value 1 in the 165*297eecfbSDimitry Andric /// source operand. 166e8d8bef9SDimitry Andric static __inline__ long long __DEFAULT_FN_ATTRS_CONSTEXPR 1670b57cec5SDimitry Andric __popcntq(unsigned long long __A) 1680b57cec5SDimitry Andric { 1690b57cec5SDimitry Andric return __builtin_popcountll(__A); 1700b57cec5SDimitry Andric } 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric #define _popcnt64(A) __popcntq((A)) 1730b57cec5SDimitry Andric #endif /* __x86_64__ */ 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric #ifdef __x86_64__ 176e8d8bef9SDimitry Andric static __inline__ unsigned long long __DEFAULT_FN_ATTRS 1770b57cec5SDimitry Andric __readeflags(void) 1780b57cec5SDimitry Andric { 1790b57cec5SDimitry Andric return __builtin_ia32_readeflags_u64(); 1800b57cec5SDimitry Andric } 1810b57cec5SDimitry Andric 182e8d8bef9SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS 1830b57cec5SDimitry Andric __writeeflags(unsigned long long __f) 1840b57cec5SDimitry Andric { 1850b57cec5SDimitry Andric __builtin_ia32_writeeflags_u64(__f); 1860b57cec5SDimitry Andric } 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric #else /* !__x86_64__ */ 189e8d8bef9SDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS 1900b57cec5SDimitry Andric __readeflags(void) 1910b57cec5SDimitry Andric { 1920b57cec5SDimitry Andric return __builtin_ia32_readeflags_u32(); 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 195e8d8bef9SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS 1960b57cec5SDimitry Andric __writeeflags(unsigned int __f) 1970b57cec5SDimitry Andric { 1980b57cec5SDimitry Andric __builtin_ia32_writeeflags_u32(__f); 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric #endif /* !__x86_64__ */ 2010b57cec5SDimitry Andric 202*297eecfbSDimitry Andric /// Cast a 32-bit float value to a 32-bit unsigned integer value. 203*297eecfbSDimitry Andric /// 204*297eecfbSDimitry Andric /// \headerfile <x86intrin.h> 205*297eecfbSDimitry Andric /// 206*297eecfbSDimitry Andric /// This intrinsic corresponds to the \c VMOVD / \c MOVD instruction in x86_64, 207*297eecfbSDimitry Andric /// and corresponds to the \c VMOVL / \c MOVL instruction in ia32. 208*297eecfbSDimitry Andric /// 209*297eecfbSDimitry Andric /// \param __A 210*297eecfbSDimitry Andric /// A 32-bit float value. 211*297eecfbSDimitry Andric /// \returns a 32-bit unsigned integer containing the converted value. 212e8d8bef9SDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS_CAST 213a7dea167SDimitry Andric _castf32_u32(float __A) { 214e8d8bef9SDimitry Andric return __builtin_bit_cast(unsigned int, __A); 215a7dea167SDimitry Andric } 216a7dea167SDimitry Andric 217*297eecfbSDimitry Andric /// Cast a 64-bit float value to a 64-bit unsigned integer value. 218*297eecfbSDimitry Andric /// 219*297eecfbSDimitry Andric /// \headerfile <x86intrin.h> 220*297eecfbSDimitry Andric /// 221*297eecfbSDimitry Andric /// This intrinsic corresponds to the \c VMOVQ / \c MOVQ instruction in x86_64, 222*297eecfbSDimitry Andric /// and corresponds to the \c VMOVL / \c MOVL instruction in ia32. 223*297eecfbSDimitry Andric /// 224*297eecfbSDimitry Andric /// \param __A 225*297eecfbSDimitry Andric /// A 64-bit float value. 226*297eecfbSDimitry Andric /// \returns a 64-bit unsigned integer containing the converted value. 227e8d8bef9SDimitry Andric static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CAST 228a7dea167SDimitry Andric _castf64_u64(double __A) { 229e8d8bef9SDimitry Andric return __builtin_bit_cast(unsigned long long, __A); 230a7dea167SDimitry Andric } 231a7dea167SDimitry Andric 232*297eecfbSDimitry Andric /// Cast a 32-bit unsigned integer value to a 32-bit float value. 233*297eecfbSDimitry Andric /// 234*297eecfbSDimitry Andric /// \headerfile <x86intrin.h> 235*297eecfbSDimitry Andric /// 236*297eecfbSDimitry Andric /// This intrinsic corresponds to the \c VMOVQ / \c MOVQ instruction in x86_64, 237*297eecfbSDimitry Andric /// and corresponds to the \c FLDS instruction in ia32. 238*297eecfbSDimitry Andric /// 239*297eecfbSDimitry Andric /// \param __A 240*297eecfbSDimitry Andric /// A 32-bit unsigned integer value. 241*297eecfbSDimitry Andric /// \returns a 32-bit float value containing the converted value. 242e8d8bef9SDimitry Andric static __inline__ float __DEFAULT_FN_ATTRS_CAST 243a7dea167SDimitry Andric _castu32_f32(unsigned int __A) { 244e8d8bef9SDimitry Andric return __builtin_bit_cast(float, __A); 245a7dea167SDimitry Andric } 246a7dea167SDimitry Andric 247*297eecfbSDimitry Andric /// Cast a 64-bit unsigned integer value to a 64-bit float value. 248*297eecfbSDimitry Andric /// 249*297eecfbSDimitry Andric /// \headerfile <x86intrin.h> 250*297eecfbSDimitry Andric /// 251*297eecfbSDimitry Andric /// This intrinsic corresponds to the \c VMOVQ / \c MOVQ instruction in x86_64, 252*297eecfbSDimitry Andric /// and corresponds to the \c FLDL instruction in ia32. 253*297eecfbSDimitry Andric /// 254*297eecfbSDimitry Andric /// \param __A 255*297eecfbSDimitry Andric /// A 64-bit unsigned integer value. 256*297eecfbSDimitry Andric /// \returns a 64-bit float value containing the converted value. 257e8d8bef9SDimitry Andric static __inline__ double __DEFAULT_FN_ATTRS_CAST 258a7dea167SDimitry Andric _castu64_f64(unsigned long long __A) { 259e8d8bef9SDimitry Andric return __builtin_bit_cast(double, __A); 260a7dea167SDimitry Andric } 261a7dea167SDimitry Andric 262*297eecfbSDimitry Andric /// Adds the unsigned integer operand to the CRC-32C checksum of the 263*297eecfbSDimitry Andric /// unsigned char operand. 264*297eecfbSDimitry Andric /// 265*297eecfbSDimitry Andric /// \headerfile <x86intrin.h> 266*297eecfbSDimitry Andric /// 267*297eecfbSDimitry Andric /// This intrinsic corresponds to the \c CRC32B instruction. 268*297eecfbSDimitry Andric /// 269*297eecfbSDimitry Andric /// \param __C 270*297eecfbSDimitry Andric /// An unsigned integer operand to add to the CRC-32C checksum of operand 271*297eecfbSDimitry Andric /// \a __D. 272*297eecfbSDimitry Andric /// \param __D 273*297eecfbSDimitry Andric /// An unsigned 8-bit integer operand used to compute the CRC-32C checksum. 274*297eecfbSDimitry Andric /// \returns The result of adding operand \a __C to the CRC-32C checksum of 275*297eecfbSDimitry Andric /// operand \a __D. 276349cc55cSDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS_CRC32 2770b57cec5SDimitry Andric __crc32b(unsigned int __C, unsigned char __D) 2780b57cec5SDimitry Andric { 2790b57cec5SDimitry Andric return __builtin_ia32_crc32qi(__C, __D); 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric 282*297eecfbSDimitry Andric /// Adds the unsigned integer operand to the CRC-32C checksum of the 283*297eecfbSDimitry Andric /// unsigned short operand. 284*297eecfbSDimitry Andric /// 285*297eecfbSDimitry Andric /// \headerfile <x86intrin.h> 286*297eecfbSDimitry Andric /// 287*297eecfbSDimitry Andric /// This intrinsic corresponds to the \c CRC32W instruction. 288*297eecfbSDimitry Andric /// 289*297eecfbSDimitry Andric /// \param __C 290*297eecfbSDimitry Andric /// An unsigned integer operand to add to the CRC-32C checksum of operand 291*297eecfbSDimitry Andric /// \a __D. 292*297eecfbSDimitry Andric /// \param __D 293*297eecfbSDimitry Andric /// An unsigned 16-bit integer operand used to compute the CRC-32C checksum. 294*297eecfbSDimitry Andric /// \returns The result of adding operand \a __C to the CRC-32C checksum of 295*297eecfbSDimitry Andric /// operand \a __D. 296349cc55cSDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS_CRC32 2970b57cec5SDimitry Andric __crc32w(unsigned int __C, unsigned short __D) 2980b57cec5SDimitry Andric { 2990b57cec5SDimitry Andric return __builtin_ia32_crc32hi(__C, __D); 3000b57cec5SDimitry Andric } 3010b57cec5SDimitry Andric 302*297eecfbSDimitry Andric /// Adds the unsigned integer operand to the CRC-32C checksum of the 303*297eecfbSDimitry Andric /// second unsigned integer operand. 304*297eecfbSDimitry Andric /// 305*297eecfbSDimitry Andric /// \headerfile <x86intrin.h> 306*297eecfbSDimitry Andric /// 307*297eecfbSDimitry Andric /// This intrinsic corresponds to the \c CRC32D instruction. 308*297eecfbSDimitry Andric /// 309*297eecfbSDimitry Andric /// \param __C 310*297eecfbSDimitry Andric /// An unsigned integer operand to add to the CRC-32C checksum of operand 311*297eecfbSDimitry Andric /// \a __D. 312*297eecfbSDimitry Andric /// \param __D 313*297eecfbSDimitry Andric /// An unsigned 32-bit integer operand used to compute the CRC-32C checksum. 314*297eecfbSDimitry Andric /// \returns The result of adding operand \a __C to the CRC-32C checksum of 315*297eecfbSDimitry Andric /// operand \a __D. 316349cc55cSDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS_CRC32 3170b57cec5SDimitry Andric __crc32d(unsigned int __C, unsigned int __D) 3180b57cec5SDimitry Andric { 3190b57cec5SDimitry Andric return __builtin_ia32_crc32si(__C, __D); 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric #ifdef __x86_64__ 323*297eecfbSDimitry Andric /// Adds the unsigned integer operand to the CRC-32C checksum of the 324*297eecfbSDimitry Andric /// unsigned 64-bit integer operand. 325*297eecfbSDimitry Andric /// 326*297eecfbSDimitry Andric /// \headerfile <x86intrin.h> 327*297eecfbSDimitry Andric /// 328*297eecfbSDimitry Andric /// This intrinsic corresponds to the \c CRC32Q instruction. 329*297eecfbSDimitry Andric /// 330*297eecfbSDimitry Andric /// \param __C 331*297eecfbSDimitry Andric /// An unsigned integer operand to add to the CRC-32C checksum of operand 332*297eecfbSDimitry Andric /// \a __D. 333*297eecfbSDimitry Andric /// \param __D 334*297eecfbSDimitry Andric /// An unsigned 64-bit integer operand used to compute the CRC-32C checksum. 335*297eecfbSDimitry Andric /// \returns The result of adding operand \a __C to the CRC-32C checksum of 336*297eecfbSDimitry Andric /// operand \a __D. 337349cc55cSDimitry Andric static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CRC32 3380b57cec5SDimitry Andric __crc32q(unsigned long long __C, unsigned long long __D) 3390b57cec5SDimitry Andric { 3400b57cec5SDimitry Andric return __builtin_ia32_crc32di(__C, __D); 3410b57cec5SDimitry Andric } 3420b57cec5SDimitry Andric #endif /* __x86_64__ */ 3430b57cec5SDimitry Andric 344e8d8bef9SDimitry Andric static __inline__ unsigned long long __DEFAULT_FN_ATTRS 3450b57cec5SDimitry Andric __rdpmc(int __A) { 3460b57cec5SDimitry Andric return __builtin_ia32_rdpmc(__A); 3470b57cec5SDimitry Andric } 3480b57cec5SDimitry Andric 3490b57cec5SDimitry Andric /* __rdtscp */ 350e8d8bef9SDimitry Andric static __inline__ unsigned long long __DEFAULT_FN_ATTRS 3510b57cec5SDimitry Andric __rdtscp(unsigned int *__A) { 3520b57cec5SDimitry Andric return __builtin_ia32_rdtscp(__A); 3530b57cec5SDimitry Andric } 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric #define _rdtsc() __rdtsc() 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric #define _rdpmc(A) __rdpmc(A) 3580b57cec5SDimitry Andric 359e8d8bef9SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS 3600b57cec5SDimitry Andric _wbinvd(void) { 3610b57cec5SDimitry Andric __builtin_ia32_wbinvd(); 3620b57cec5SDimitry Andric } 3630b57cec5SDimitry Andric 364e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS_CONSTEXPR 3650b57cec5SDimitry Andric __rolb(unsigned char __X, int __C) { 3660b57cec5SDimitry Andric return __builtin_rotateleft8(__X, __C); 3670b57cec5SDimitry Andric } 3680b57cec5SDimitry Andric 369e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS_CONSTEXPR 3700b57cec5SDimitry Andric __rorb(unsigned char __X, int __C) { 3710b57cec5SDimitry Andric return __builtin_rotateright8(__X, __C); 3720b57cec5SDimitry Andric } 3730b57cec5SDimitry Andric 374e8d8bef9SDimitry Andric static __inline__ unsigned short __DEFAULT_FN_ATTRS_CONSTEXPR 3750b57cec5SDimitry Andric __rolw(unsigned short __X, int __C) { 3760b57cec5SDimitry Andric return __builtin_rotateleft16(__X, __C); 3770b57cec5SDimitry Andric } 3780b57cec5SDimitry Andric 379e8d8bef9SDimitry Andric static __inline__ unsigned short __DEFAULT_FN_ATTRS_CONSTEXPR 3800b57cec5SDimitry Andric __rorw(unsigned short __X, int __C) { 3810b57cec5SDimitry Andric return __builtin_rotateright16(__X, __C); 3820b57cec5SDimitry Andric } 3830b57cec5SDimitry Andric 384e8d8bef9SDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR 3850b57cec5SDimitry Andric __rold(unsigned int __X, int __C) { 38681ad6265SDimitry Andric return __builtin_rotateleft32(__X, (unsigned int)__C); 3870b57cec5SDimitry Andric } 3880b57cec5SDimitry Andric 389e8d8bef9SDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR 3900b57cec5SDimitry Andric __rord(unsigned int __X, int __C) { 39181ad6265SDimitry Andric return __builtin_rotateright32(__X, (unsigned int)__C); 3920b57cec5SDimitry Andric } 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric #ifdef __x86_64__ 395e8d8bef9SDimitry Andric static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR 3960b57cec5SDimitry Andric __rolq(unsigned long long __X, int __C) { 39781ad6265SDimitry Andric return __builtin_rotateleft64(__X, (unsigned long long)__C); 3980b57cec5SDimitry Andric } 3990b57cec5SDimitry Andric 400e8d8bef9SDimitry Andric static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR 4010b57cec5SDimitry Andric __rorq(unsigned long long __X, int __C) { 40281ad6265SDimitry Andric return __builtin_rotateright64(__X, (unsigned long long)__C); 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric #endif /* __x86_64__ */ 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric #ifndef _MSC_VER 4070b57cec5SDimitry Andric /* These are already provided as builtins for MSVC. */ 4080b57cec5SDimitry Andric /* Select the correct function based on the size of long. */ 4090b57cec5SDimitry Andric #ifdef __LP64__ 4100b57cec5SDimitry Andric #define _lrotl(a,b) __rolq((a), (b)) 4110b57cec5SDimitry Andric #define _lrotr(a,b) __rorq((a), (b)) 4120b57cec5SDimitry Andric #else 4130b57cec5SDimitry Andric #define _lrotl(a,b) __rold((a), (b)) 4140b57cec5SDimitry Andric #define _lrotr(a,b) __rord((a), (b)) 4150b57cec5SDimitry Andric #endif 4160b57cec5SDimitry Andric #define _rotl(a,b) __rold((a), (b)) 4170b57cec5SDimitry Andric #define _rotr(a,b) __rord((a), (b)) 4180b57cec5SDimitry Andric #endif // _MSC_VER 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric /* These are not builtins so need to be provided in all modes. */ 4210b57cec5SDimitry Andric #define _rotwl(a,b) __rolw((a), (b)) 4220b57cec5SDimitry Andric #define _rotwr(a,b) __rorw((a), (b)) 4230b57cec5SDimitry Andric 424e8d8bef9SDimitry Andric #undef __DEFAULT_FN_ATTRS 425e8d8bef9SDimitry Andric #undef __DEFAULT_FN_ATTRS_CAST 426349cc55cSDimitry Andric #undef __DEFAULT_FN_ATTRS_CRC32 427e8d8bef9SDimitry Andric #undef __DEFAULT_FN_ATTRS_CONSTEXPR 428e8d8bef9SDimitry Andric 4290b57cec5SDimitry Andric #endif /* __IA32INTRIN_H */ 430