xref: /freebsd/contrib/llvm-project/clang/lib/Headers/ia32intrin.h (revision 297eecfb02bb25902531dbb5c3b9a88caf8adf29)
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