xref: /freebsd/contrib/llvm-project/clang/lib/Headers/ia32intrin.h (revision a7dea1671b87c07d2d266f836bfa8b58efc7c134)
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 
170b57cec5SDimitry Andric /** Find the first set bit starting from the lsb. Result is undefined if
180b57cec5SDimitry Andric  *  input is 0.
190b57cec5SDimitry Andric  *
200b57cec5SDimitry Andric  *  \headerfile <x86intrin.h>
210b57cec5SDimitry Andric  *
220b57cec5SDimitry Andric  *  This intrinsic corresponds to the <c> BSF </c> instruction or the
230b57cec5SDimitry Andric  *  <c> TZCNT </c> instruction.
240b57cec5SDimitry Andric  *
250b57cec5SDimitry Andric  *  \param __A
260b57cec5SDimitry Andric  *     A 32-bit integer operand.
270b57cec5SDimitry Andric  *  \returns A 32-bit integer containing the bit number.
280b57cec5SDimitry Andric  */
290b57cec5SDimitry Andric static __inline__ int __attribute__((__always_inline__, __nodebug__))
300b57cec5SDimitry Andric __bsfd(int __A) {
310b57cec5SDimitry Andric   return __builtin_ctz(__A);
320b57cec5SDimitry Andric }
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric /** Find the first set bit starting from the msb. Result is undefined if
350b57cec5SDimitry Andric  *  input is 0.
360b57cec5SDimitry Andric  *
370b57cec5SDimitry Andric  *  \headerfile <x86intrin.h>
380b57cec5SDimitry Andric  *
390b57cec5SDimitry Andric  *  This intrinsic corresponds to the <c> BSR </c> instruction or the
400b57cec5SDimitry Andric  *  <c> LZCNT </c> instruction and an <c> XOR </c>.
410b57cec5SDimitry Andric  *
420b57cec5SDimitry Andric  *  \param __A
430b57cec5SDimitry Andric  *     A 32-bit integer operand.
440b57cec5SDimitry Andric  *  \returns A 32-bit integer containing the bit number.
450b57cec5SDimitry Andric  */
460b57cec5SDimitry Andric static __inline__ int __attribute__((__always_inline__, __nodebug__))
470b57cec5SDimitry Andric __bsrd(int __A) {
480b57cec5SDimitry Andric   return 31 - __builtin_clz(__A);
490b57cec5SDimitry Andric }
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric /** Swaps the bytes in the input. Converting little endian to big endian or
520b57cec5SDimitry Andric  *  vice versa.
530b57cec5SDimitry Andric  *
540b57cec5SDimitry Andric  *  \headerfile <x86intrin.h>
550b57cec5SDimitry Andric  *
560b57cec5SDimitry Andric  *  This intrinsic corresponds to the <c> BSWAP </c> instruction.
570b57cec5SDimitry Andric  *
580b57cec5SDimitry Andric  *  \param __A
590b57cec5SDimitry Andric  *     A 32-bit integer operand.
600b57cec5SDimitry Andric  *  \returns A 32-bit integer containing the swapped bytes.
610b57cec5SDimitry Andric  */
620b57cec5SDimitry Andric static __inline__ int __attribute__((__always_inline__, __nodebug__))
630b57cec5SDimitry Andric __bswapd(int __A) {
640b57cec5SDimitry Andric   return __builtin_bswap32(__A);
650b57cec5SDimitry Andric }
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric static __inline__ int __attribute__((__always_inline__, __nodebug__))
680b57cec5SDimitry Andric _bswap(int __A) {
690b57cec5SDimitry Andric   return __builtin_bswap32(__A);
700b57cec5SDimitry Andric }
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric #define _bit_scan_forward(A) __bsfd((A))
730b57cec5SDimitry Andric #define _bit_scan_reverse(A) __bsrd((A))
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric #ifdef __x86_64__
760b57cec5SDimitry Andric /** Find the first set bit starting from the lsb. Result is undefined if
770b57cec5SDimitry Andric  *  input is 0.
780b57cec5SDimitry Andric  *
790b57cec5SDimitry Andric  *  \headerfile <x86intrin.h>
800b57cec5SDimitry Andric  *
810b57cec5SDimitry Andric  *  This intrinsic corresponds to the <c> BSF </c> instruction or the
820b57cec5SDimitry Andric  *  <c> TZCNT </c> instruction.
830b57cec5SDimitry Andric  *
840b57cec5SDimitry Andric  *  \param __A
850b57cec5SDimitry Andric  *     A 64-bit integer operand.
860b57cec5SDimitry Andric  *  \returns A 32-bit integer containing the bit number.
870b57cec5SDimitry Andric  */
880b57cec5SDimitry Andric static __inline__ int __attribute__((__always_inline__, __nodebug__))
890b57cec5SDimitry Andric __bsfq(long long __A) {
900b57cec5SDimitry Andric   return __builtin_ctzll(__A);
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric /** Find the first set bit starting from the msb. Result is undefined if
940b57cec5SDimitry Andric  *  input is 0.
950b57cec5SDimitry Andric  *
960b57cec5SDimitry Andric  *  \headerfile <x86intrin.h>
970b57cec5SDimitry Andric  *
980b57cec5SDimitry Andric  *  This intrinsic corresponds to the <c> BSR </c> instruction or the
990b57cec5SDimitry Andric  *  <c> LZCNT </c> instruction and an <c> XOR </c>.
1000b57cec5SDimitry Andric  *
1010b57cec5SDimitry Andric  *  \param __A
1020b57cec5SDimitry Andric  *     A 64-bit integer operand.
1030b57cec5SDimitry Andric  *  \returns A 32-bit integer containing the bit number.
1040b57cec5SDimitry Andric  */
1050b57cec5SDimitry Andric static __inline__ int __attribute__((__always_inline__, __nodebug__))
1060b57cec5SDimitry Andric __bsrq(long long __A) {
1070b57cec5SDimitry Andric   return 63 - __builtin_clzll(__A);
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric /** Swaps the bytes in the input. Converting little endian to big endian or
1110b57cec5SDimitry Andric  *  vice versa.
1120b57cec5SDimitry Andric  *
1130b57cec5SDimitry Andric  *  \headerfile <x86intrin.h>
1140b57cec5SDimitry Andric  *
1150b57cec5SDimitry Andric  *  This intrinsic corresponds to the <c> BSWAP </c> instruction.
1160b57cec5SDimitry Andric  *
1170b57cec5SDimitry Andric  *  \param __A
1180b57cec5SDimitry Andric  *     A 64-bit integer operand.
1190b57cec5SDimitry Andric  *  \returns A 64-bit integer containing the swapped bytes.
1200b57cec5SDimitry Andric  */
1210b57cec5SDimitry Andric static __inline__ long long __attribute__((__always_inline__, __nodebug__))
1220b57cec5SDimitry Andric __bswapq(long long __A) {
1230b57cec5SDimitry Andric   return __builtin_bswap64(__A);
1240b57cec5SDimitry Andric }
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric #define _bswap64(A) __bswapq((A))
1270b57cec5SDimitry Andric #endif
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric /** Counts the number of bits in the source operand having a value of 1.
1300b57cec5SDimitry Andric  *
1310b57cec5SDimitry Andric  *  \headerfile <x86intrin.h>
1320b57cec5SDimitry Andric  *
1330b57cec5SDimitry Andric  *  This intrinsic corresponds to the <c> POPCNT </c> instruction or a
1340b57cec5SDimitry Andric  *  a sequence of arithmetic and logic ops to calculate it.
1350b57cec5SDimitry Andric  *
1360b57cec5SDimitry Andric  *  \param __A
1370b57cec5SDimitry Andric  *     An unsigned 32-bit integer operand.
1380b57cec5SDimitry Andric  *  \returns A 32-bit integer containing the number of bits with value 1 in the
1390b57cec5SDimitry Andric  *     source operand.
1400b57cec5SDimitry Andric  */
1410b57cec5SDimitry Andric static __inline__ int __attribute__((__always_inline__, __nodebug__))
1420b57cec5SDimitry Andric __popcntd(unsigned int __A)
1430b57cec5SDimitry Andric {
1440b57cec5SDimitry Andric   return __builtin_popcount(__A);
1450b57cec5SDimitry Andric }
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric #define _popcnt32(A) __popcntd((A))
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric #ifdef __x86_64__
1500b57cec5SDimitry Andric /** Counts the number of bits in the source operand having a value of 1.
1510b57cec5SDimitry Andric  *
1520b57cec5SDimitry Andric  *  \headerfile <x86intrin.h>
1530b57cec5SDimitry Andric  *
1540b57cec5SDimitry Andric  *  This intrinsic corresponds to the <c> POPCNT </c> instruction or a
1550b57cec5SDimitry Andric  *  a sequence of arithmetic and logic ops to calculate it.
1560b57cec5SDimitry Andric  *
1570b57cec5SDimitry Andric  *  \param __A
1580b57cec5SDimitry Andric  *     An unsigned 64-bit integer operand.
1590b57cec5SDimitry Andric  *  \returns A 64-bit integer containing the number of bits with value 1 in the
1600b57cec5SDimitry Andric  *     source operand.
1610b57cec5SDimitry Andric  */
1620b57cec5SDimitry Andric static __inline__ long long __attribute__((__always_inline__, __nodebug__))
1630b57cec5SDimitry Andric __popcntq(unsigned long long __A)
1640b57cec5SDimitry Andric {
1650b57cec5SDimitry Andric   return __builtin_popcountll(__A);
1660b57cec5SDimitry Andric }
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric #define _popcnt64(A) __popcntq((A))
1690b57cec5SDimitry Andric #endif /* __x86_64__ */
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric #ifdef __x86_64__
1720b57cec5SDimitry Andric static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
1730b57cec5SDimitry Andric __readeflags(void)
1740b57cec5SDimitry Andric {
1750b57cec5SDimitry Andric   return __builtin_ia32_readeflags_u64();
1760b57cec5SDimitry Andric }
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric static __inline__ void __attribute__((__always_inline__, __nodebug__))
1790b57cec5SDimitry Andric __writeeflags(unsigned long long __f)
1800b57cec5SDimitry Andric {
1810b57cec5SDimitry Andric   __builtin_ia32_writeeflags_u64(__f);
1820b57cec5SDimitry Andric }
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric #else /* !__x86_64__ */
1850b57cec5SDimitry Andric static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
1860b57cec5SDimitry Andric __readeflags(void)
1870b57cec5SDimitry Andric {
1880b57cec5SDimitry Andric   return __builtin_ia32_readeflags_u32();
1890b57cec5SDimitry Andric }
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric static __inline__ void __attribute__((__always_inline__, __nodebug__))
1920b57cec5SDimitry Andric __writeeflags(unsigned int __f)
1930b57cec5SDimitry Andric {
1940b57cec5SDimitry Andric   __builtin_ia32_writeeflags_u32(__f);
1950b57cec5SDimitry Andric }
1960b57cec5SDimitry Andric #endif /* !__x86_64__ */
1970b57cec5SDimitry Andric 
198*a7dea167SDimitry Andric /** Cast a 32-bit float value to a 32-bit unsigned integer value
199*a7dea167SDimitry Andric  *
200*a7dea167SDimitry Andric  *  \headerfile <x86intrin.h>
201*a7dea167SDimitry Andric  *  This intrinsic corresponds to the <c> VMOVD / MOVD </c> instruction in x86_64,
202*a7dea167SDimitry Andric  *  and corresponds to the <c> VMOVL / MOVL </c> instruction in ia32.
203*a7dea167SDimitry Andric  *
204*a7dea167SDimitry Andric  *  \param __A
205*a7dea167SDimitry Andric  *     A 32-bit float value.
206*a7dea167SDimitry Andric  *  \returns a 32-bit unsigned integer containing the converted value.
207*a7dea167SDimitry Andric  */
208*a7dea167SDimitry Andric static __inline__ unsigned int __attribute__((__always_inline__))
209*a7dea167SDimitry Andric _castf32_u32(float __A) {
210*a7dea167SDimitry Andric   unsigned int D;
211*a7dea167SDimitry Andric   __builtin_memcpy(&D, &__A, sizeof(__A));
212*a7dea167SDimitry Andric   return D;
213*a7dea167SDimitry Andric }
214*a7dea167SDimitry Andric 
215*a7dea167SDimitry Andric /** Cast a 64-bit float value to a 64-bit unsigned integer value
216*a7dea167SDimitry Andric  *
217*a7dea167SDimitry Andric  *  \headerfile <x86intrin.h>
218*a7dea167SDimitry Andric  *  This intrinsic corresponds to the <c> VMOVQ / MOVQ </c> instruction in x86_64,
219*a7dea167SDimitry Andric  *  and corresponds to the <c> VMOVL / MOVL </c> instruction in ia32.
220*a7dea167SDimitry Andric  *
221*a7dea167SDimitry Andric  *  \param __A
222*a7dea167SDimitry Andric  *     A 64-bit float value.
223*a7dea167SDimitry Andric  *  \returns a 64-bit unsigned integer containing the converted value.
224*a7dea167SDimitry Andric  */
225*a7dea167SDimitry Andric static __inline__ unsigned long long __attribute__((__always_inline__))
226*a7dea167SDimitry Andric _castf64_u64(double __A) {
227*a7dea167SDimitry Andric   unsigned long long D;
228*a7dea167SDimitry Andric   __builtin_memcpy(&D, &__A, sizeof(__A));
229*a7dea167SDimitry Andric   return D;
230*a7dea167SDimitry Andric }
231*a7dea167SDimitry Andric 
232*a7dea167SDimitry Andric /** Cast a 32-bit unsigned integer value to a 32-bit float value
233*a7dea167SDimitry Andric  *
234*a7dea167SDimitry Andric  *  \headerfile <x86intrin.h>
235*a7dea167SDimitry Andric  *  This intrinsic corresponds to the <c> VMOVQ / MOVQ </c> instruction in x86_64,
236*a7dea167SDimitry Andric  *  and corresponds to the <c> FLDS </c> instruction in ia32.
237*a7dea167SDimitry Andric  *
238*a7dea167SDimitry Andric  *  \param __A
239*a7dea167SDimitry Andric  *     A 32-bit unsigned integer value.
240*a7dea167SDimitry Andric  *  \returns a 32-bit float value containing the converted value.
241*a7dea167SDimitry Andric  */
242*a7dea167SDimitry Andric static __inline__ float __attribute__((__always_inline__))
243*a7dea167SDimitry Andric _castu32_f32(unsigned int __A) {
244*a7dea167SDimitry Andric   float D;
245*a7dea167SDimitry Andric   __builtin_memcpy(&D, &__A, sizeof(__A));
246*a7dea167SDimitry Andric   return D;
247*a7dea167SDimitry Andric }
248*a7dea167SDimitry Andric 
249*a7dea167SDimitry Andric /** Cast a 64-bit unsigned integer value to a 64-bit float value
250*a7dea167SDimitry Andric  *
251*a7dea167SDimitry Andric  *  \headerfile <x86intrin.h>
252*a7dea167SDimitry Andric  *  This intrinsic corresponds to the <c> VMOVQ / MOVQ </c> instruction in x86_64,
253*a7dea167SDimitry Andric  *  and corresponds to the <c> FLDL </c> instruction in ia32.
254*a7dea167SDimitry Andric  *
255*a7dea167SDimitry Andric  *  \param __A
256*a7dea167SDimitry Andric  *     A 64-bit unsigned integer value.
257*a7dea167SDimitry Andric  *  \returns a 64-bit float value containing the converted value.
258*a7dea167SDimitry Andric  */
259*a7dea167SDimitry Andric static __inline__ double __attribute__((__always_inline__))
260*a7dea167SDimitry Andric _castu64_f64(unsigned long long __A) {
261*a7dea167SDimitry Andric   double D;
262*a7dea167SDimitry Andric   __builtin_memcpy(&D, &__A, sizeof(__A));
263*a7dea167SDimitry Andric   return D;
264*a7dea167SDimitry Andric }
265*a7dea167SDimitry Andric 
2660b57cec5SDimitry Andric /** Adds the unsigned integer operand to the CRC-32C checksum of the
2670b57cec5SDimitry Andric  *     unsigned char operand.
2680b57cec5SDimitry Andric  *
2690b57cec5SDimitry Andric  *  \headerfile <x86intrin.h>
2700b57cec5SDimitry Andric  *
2710b57cec5SDimitry Andric  *  This intrinsic corresponds to the <c> CRC32B </c> instruction.
2720b57cec5SDimitry Andric  *
2730b57cec5SDimitry Andric  *  \param __C
2740b57cec5SDimitry Andric  *     An unsigned integer operand to add to the CRC-32C checksum of operand
2750b57cec5SDimitry Andric  *     \a  __D.
2760b57cec5SDimitry Andric  *  \param __D
2770b57cec5SDimitry Andric  *     An unsigned 8-bit integer operand used to compute the CRC-32C checksum.
2780b57cec5SDimitry Andric  *  \returns The result of adding operand \a __C to the CRC-32C checksum of
2790b57cec5SDimitry Andric  *     operand \a __D.
2800b57cec5SDimitry Andric  */
2810b57cec5SDimitry Andric static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("sse4.2")))
2820b57cec5SDimitry Andric __crc32b(unsigned int __C, unsigned char __D)
2830b57cec5SDimitry Andric {
2840b57cec5SDimitry Andric   return __builtin_ia32_crc32qi(__C, __D);
2850b57cec5SDimitry Andric }
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric /** Adds the unsigned integer operand to the CRC-32C checksum of the
2880b57cec5SDimitry Andric  *     unsigned short operand.
2890b57cec5SDimitry Andric  *
2900b57cec5SDimitry Andric  *  \headerfile <x86intrin.h>
2910b57cec5SDimitry Andric  *
2920b57cec5SDimitry Andric  *  This intrinsic corresponds to the <c> CRC32W </c> instruction.
2930b57cec5SDimitry Andric  *
2940b57cec5SDimitry Andric  *  \param __C
2950b57cec5SDimitry Andric  *     An unsigned integer operand to add to the CRC-32C checksum of operand
2960b57cec5SDimitry Andric  *     \a  __D.
2970b57cec5SDimitry Andric  *  \param __D
2980b57cec5SDimitry Andric  *     An unsigned 16-bit integer operand used to compute the CRC-32C checksum.
2990b57cec5SDimitry Andric  *  \returns The result of adding operand \a __C to the CRC-32C checksum of
3000b57cec5SDimitry Andric  *     operand \a __D.
3010b57cec5SDimitry Andric  */
3020b57cec5SDimitry Andric static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("sse4.2")))
3030b57cec5SDimitry Andric __crc32w(unsigned int __C, unsigned short __D)
3040b57cec5SDimitry Andric {
3050b57cec5SDimitry Andric   return __builtin_ia32_crc32hi(__C, __D);
3060b57cec5SDimitry Andric }
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric /** Adds the unsigned integer operand to the CRC-32C checksum of the
3090b57cec5SDimitry Andric  *     second unsigned integer operand.
3100b57cec5SDimitry Andric  *
3110b57cec5SDimitry Andric  *  \headerfile <x86intrin.h>
3120b57cec5SDimitry Andric  *
3130b57cec5SDimitry Andric  *  This intrinsic corresponds to the <c> CRC32D </c> instruction.
3140b57cec5SDimitry Andric  *
3150b57cec5SDimitry Andric  *  \param __C
3160b57cec5SDimitry Andric  *     An unsigned integer operand to add to the CRC-32C checksum of operand
3170b57cec5SDimitry Andric  *     \a  __D.
3180b57cec5SDimitry Andric  *  \param __D
3190b57cec5SDimitry Andric  *     An unsigned 32-bit integer operand used to compute the CRC-32C checksum.
3200b57cec5SDimitry Andric  *  \returns The result of adding operand \a __C to the CRC-32C checksum of
3210b57cec5SDimitry Andric  *     operand \a __D.
3220b57cec5SDimitry Andric  */
3230b57cec5SDimitry Andric static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("sse4.2")))
3240b57cec5SDimitry Andric __crc32d(unsigned int __C, unsigned int __D)
3250b57cec5SDimitry Andric {
3260b57cec5SDimitry Andric   return __builtin_ia32_crc32si(__C, __D);
3270b57cec5SDimitry Andric }
3280b57cec5SDimitry Andric 
3290b57cec5SDimitry Andric #ifdef __x86_64__
3300b57cec5SDimitry Andric /** Adds the unsigned integer operand to the CRC-32C checksum of the
3310b57cec5SDimitry Andric  *     unsigned 64-bit integer operand.
3320b57cec5SDimitry Andric  *
3330b57cec5SDimitry Andric  *  \headerfile <x86intrin.h>
3340b57cec5SDimitry Andric  *
3350b57cec5SDimitry Andric  *  This intrinsic corresponds to the <c> CRC32Q </c> instruction.
3360b57cec5SDimitry Andric  *
3370b57cec5SDimitry Andric  *  \param __C
3380b57cec5SDimitry Andric  *     An unsigned integer operand to add to the CRC-32C checksum of operand
3390b57cec5SDimitry Andric  *     \a  __D.
3400b57cec5SDimitry Andric  *  \param __D
3410b57cec5SDimitry Andric  *     An unsigned 64-bit integer operand used to compute the CRC-32C checksum.
3420b57cec5SDimitry Andric  *  \returns The result of adding operand \a __C to the CRC-32C checksum of
3430b57cec5SDimitry Andric  *     operand \a __D.
3440b57cec5SDimitry Andric  */
3450b57cec5SDimitry Andric static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__, __target__("sse4.2")))
3460b57cec5SDimitry Andric __crc32q(unsigned long long __C, unsigned long long __D)
3470b57cec5SDimitry Andric {
3480b57cec5SDimitry Andric   return __builtin_ia32_crc32di(__C, __D);
3490b57cec5SDimitry Andric }
3500b57cec5SDimitry Andric #endif /* __x86_64__ */
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
3530b57cec5SDimitry Andric __rdpmc(int __A) {
3540b57cec5SDimitry Andric   return __builtin_ia32_rdpmc(__A);
3550b57cec5SDimitry Andric }
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric /* __rdtscp */
3580b57cec5SDimitry Andric static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
3590b57cec5SDimitry Andric __rdtscp(unsigned int *__A) {
3600b57cec5SDimitry Andric   return __builtin_ia32_rdtscp(__A);
3610b57cec5SDimitry Andric }
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric #define _rdtsc() __rdtsc()
3640b57cec5SDimitry Andric 
3650b57cec5SDimitry Andric #define _rdpmc(A) __rdpmc(A)
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric static __inline__ void __attribute__((__always_inline__, __nodebug__))
3680b57cec5SDimitry Andric _wbinvd(void) {
3690b57cec5SDimitry Andric   __builtin_ia32_wbinvd();
3700b57cec5SDimitry Andric }
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
3730b57cec5SDimitry Andric __rolb(unsigned char __X, int __C) {
3740b57cec5SDimitry Andric   return __builtin_rotateleft8(__X, __C);
3750b57cec5SDimitry Andric }
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
3780b57cec5SDimitry Andric __rorb(unsigned char __X, int __C) {
3790b57cec5SDimitry Andric   return __builtin_rotateright8(__X, __C);
3800b57cec5SDimitry Andric }
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
3830b57cec5SDimitry Andric __rolw(unsigned short __X, int __C) {
3840b57cec5SDimitry Andric   return __builtin_rotateleft16(__X, __C);
3850b57cec5SDimitry Andric }
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
3880b57cec5SDimitry Andric __rorw(unsigned short __X, int __C) {
3890b57cec5SDimitry Andric   return __builtin_rotateright16(__X, __C);
3900b57cec5SDimitry Andric }
3910b57cec5SDimitry Andric 
3920b57cec5SDimitry Andric static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
3930b57cec5SDimitry Andric __rold(unsigned int __X, int __C) {
3940b57cec5SDimitry Andric   return __builtin_rotateleft32(__X, __C);
3950b57cec5SDimitry Andric }
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
3980b57cec5SDimitry Andric __rord(unsigned int __X, int __C) {
3990b57cec5SDimitry Andric   return __builtin_rotateright32(__X, __C);
4000b57cec5SDimitry Andric }
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric #ifdef __x86_64__
4030b57cec5SDimitry Andric static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
4040b57cec5SDimitry Andric __rolq(unsigned long long __X, int __C) {
4050b57cec5SDimitry Andric   return __builtin_rotateleft64(__X, __C);
4060b57cec5SDimitry Andric }
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
4090b57cec5SDimitry Andric __rorq(unsigned long long __X, int __C) {
4100b57cec5SDimitry Andric   return __builtin_rotateright64(__X, __C);
4110b57cec5SDimitry Andric }
4120b57cec5SDimitry Andric #endif /* __x86_64__ */
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric #ifndef _MSC_VER
4150b57cec5SDimitry Andric /* These are already provided as builtins for MSVC. */
4160b57cec5SDimitry Andric /* Select the correct function based on the size of long. */
4170b57cec5SDimitry Andric #ifdef __LP64__
4180b57cec5SDimitry Andric #define _lrotl(a,b) __rolq((a), (b))
4190b57cec5SDimitry Andric #define _lrotr(a,b) __rorq((a), (b))
4200b57cec5SDimitry Andric #else
4210b57cec5SDimitry Andric #define _lrotl(a,b) __rold((a), (b))
4220b57cec5SDimitry Andric #define _lrotr(a,b) __rord((a), (b))
4230b57cec5SDimitry Andric #endif
4240b57cec5SDimitry Andric #define _rotl(a,b) __rold((a), (b))
4250b57cec5SDimitry Andric #define _rotr(a,b) __rord((a), (b))
4260b57cec5SDimitry Andric #endif // _MSC_VER
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric /* These are not builtins so need to be provided in all modes. */
4290b57cec5SDimitry Andric #define _rotwl(a,b) __rolw((a), (b))
4300b57cec5SDimitry Andric #define _rotwr(a,b) __rorw((a), (b))
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric #endif /* __IA32INTRIN_H */
433