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