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 
29297eecfbSDimitry Andric /// Find the first set bit starting from the lsb. Result is undefined if
30297eecfbSDimitry Andric ///    input is 0.
31297eecfbSDimitry Andric ///
32297eecfbSDimitry Andric /// \headerfile <x86intrin.h>
33297eecfbSDimitry Andric ///
34297eecfbSDimitry Andric /// This intrinsic corresponds to the \c BSF instruction or the
35297eecfbSDimitry Andric ///    \c TZCNT instruction.
36297eecfbSDimitry Andric ///
37297eecfbSDimitry Andric /// \param __A
38297eecfbSDimitry Andric ///    A 32-bit integer operand.
39297eecfbSDimitry Andric /// \returns A 32-bit integer containing the bit number.
407a6dacacSDimitry Andric /// \see _bit_scan_forward
41e8d8bef9SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
__bsfd(int __A)420b57cec5SDimitry Andric __bsfd(int __A) {
4381ad6265SDimitry Andric   return __builtin_ctz((unsigned int)__A);
440b57cec5SDimitry Andric }
450b57cec5SDimitry Andric 
46297eecfbSDimitry Andric /// Find the first set bit starting from the msb. Result is undefined if
47297eecfbSDimitry Andric ///    input is 0.
48297eecfbSDimitry Andric ///
49297eecfbSDimitry Andric /// \headerfile <x86intrin.h>
50297eecfbSDimitry Andric ///
51297eecfbSDimitry Andric /// This intrinsic corresponds to the \c BSR instruction or the
52297eecfbSDimitry Andric ///    \c LZCNT instruction and an \c XOR.
53297eecfbSDimitry Andric ///
54297eecfbSDimitry Andric /// \param __A
55297eecfbSDimitry Andric ///    A 32-bit integer operand.
56297eecfbSDimitry Andric /// \returns A 32-bit integer containing the bit number.
577a6dacacSDimitry Andric /// \see _bit_scan_reverse
58e8d8bef9SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
__bsrd(int __A)590b57cec5SDimitry Andric __bsrd(int __A) {
6081ad6265SDimitry Andric   return 31 - __builtin_clz((unsigned int)__A);
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric 
637a6dacacSDimitry Andric /// Swaps the bytes in the input, converting little endian to big endian or
64297eecfbSDimitry Andric ///    vice versa.
65297eecfbSDimitry Andric ///
66297eecfbSDimitry Andric /// \headerfile <x86intrin.h>
67297eecfbSDimitry Andric ///
68297eecfbSDimitry Andric /// This intrinsic corresponds to the \c BSWAP instruction.
69297eecfbSDimitry Andric ///
70297eecfbSDimitry Andric /// \param __A
71297eecfbSDimitry Andric ///    A 32-bit integer operand.
72297eecfbSDimitry Andric /// \returns A 32-bit integer containing the swapped bytes.
73e8d8bef9SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
__bswapd(int __A)740b57cec5SDimitry Andric __bswapd(int __A) {
7581ad6265SDimitry Andric   return (int)__builtin_bswap32((unsigned int)__A);
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric 
787a6dacacSDimitry Andric /// Swaps the bytes in the input, converting little endian to big endian or
797a6dacacSDimitry Andric ///    vice versa.
807a6dacacSDimitry Andric ///
817a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
827a6dacacSDimitry Andric ///
837a6dacacSDimitry Andric /// This intrinsic corresponds to the \c BSWAP instruction.
847a6dacacSDimitry Andric ///
857a6dacacSDimitry Andric /// \param __A
867a6dacacSDimitry Andric ///    A 32-bit integer operand.
877a6dacacSDimitry Andric /// \returns A 32-bit integer containing the swapped bytes.
88e8d8bef9SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
_bswap(int __A)890b57cec5SDimitry Andric _bswap(int __A) {
9081ad6265SDimitry Andric   return (int)__builtin_bswap32((unsigned int)__A);
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric 
937a6dacacSDimitry Andric /// Find the first set bit starting from the lsb. Result is undefined if
947a6dacacSDimitry Andric ///    input is 0.
957a6dacacSDimitry Andric ///
967a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
977a6dacacSDimitry Andric ///
987a6dacacSDimitry Andric /// \code
997a6dacacSDimitry Andric /// int _bit_scan_forward(int A);
1007a6dacacSDimitry Andric /// \endcode
1017a6dacacSDimitry Andric ///
1027a6dacacSDimitry Andric /// This intrinsic corresponds to the \c BSF instruction or the
1037a6dacacSDimitry Andric ///    \c TZCNT instruction.
1047a6dacacSDimitry Andric ///
1057a6dacacSDimitry Andric /// \param A
1067a6dacacSDimitry Andric ///    A 32-bit integer operand.
1077a6dacacSDimitry Andric /// \returns A 32-bit integer containing the bit number.
1087a6dacacSDimitry Andric /// \see __bsfd
1090b57cec5SDimitry Andric #define _bit_scan_forward(A) __bsfd((A))
1107a6dacacSDimitry Andric 
1117a6dacacSDimitry Andric /// Find the first set bit starting from the msb. Result is undefined if
1127a6dacacSDimitry Andric ///    input is 0.
1137a6dacacSDimitry Andric ///
1147a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
1157a6dacacSDimitry Andric ///
1167a6dacacSDimitry Andric /// \code
1177a6dacacSDimitry Andric /// int _bit_scan_reverse(int A);
1187a6dacacSDimitry Andric /// \endcode
1197a6dacacSDimitry Andric ///
1207a6dacacSDimitry Andric /// This intrinsic corresponds to the \c BSR instruction or the
1217a6dacacSDimitry Andric ///    \c LZCNT instruction and an \c XOR.
1227a6dacacSDimitry Andric ///
1237a6dacacSDimitry Andric /// \param A
1247a6dacacSDimitry Andric ///    A 32-bit integer operand.
1257a6dacacSDimitry Andric /// \returns A 32-bit integer containing the bit number.
1267a6dacacSDimitry Andric /// \see __bsrd
1270b57cec5SDimitry Andric #define _bit_scan_reverse(A) __bsrd((A))
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric #ifdef __x86_64__
130297eecfbSDimitry Andric /// Find the first set bit starting from the lsb. Result is undefined if
131297eecfbSDimitry Andric ///    input is 0.
132297eecfbSDimitry Andric ///
133297eecfbSDimitry Andric /// \headerfile <x86intrin.h>
134297eecfbSDimitry Andric ///
135297eecfbSDimitry Andric /// This intrinsic corresponds to the \c BSF instruction or the
136297eecfbSDimitry Andric ///    \c TZCNT instruction.
137297eecfbSDimitry Andric ///
138297eecfbSDimitry Andric /// \param __A
139297eecfbSDimitry Andric ///    A 64-bit integer operand.
140297eecfbSDimitry Andric /// \returns A 32-bit integer containing the bit number.
141e8d8bef9SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
__bsfq(long long __A)1420b57cec5SDimitry Andric __bsfq(long long __A) {
14381ad6265SDimitry Andric   return (long long)__builtin_ctzll((unsigned long long)__A);
1440b57cec5SDimitry Andric }
1450b57cec5SDimitry Andric 
146297eecfbSDimitry Andric /// Find the first set bit starting from the msb. Result is undefined if
147297eecfbSDimitry Andric ///    input is 0.
148297eecfbSDimitry Andric ///
149297eecfbSDimitry Andric /// \headerfile <x86intrin.h>
150297eecfbSDimitry Andric ///
151297eecfbSDimitry Andric /// This intrinsic corresponds to the \c BSR instruction or the
152297eecfbSDimitry Andric ///    \c LZCNT instruction and an \c XOR.
153297eecfbSDimitry Andric ///
154297eecfbSDimitry Andric /// \param __A
155297eecfbSDimitry Andric ///    A 64-bit integer operand.
156297eecfbSDimitry Andric /// \returns A 32-bit integer containing the bit number.
157e8d8bef9SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
__bsrq(long long __A)1580b57cec5SDimitry Andric __bsrq(long long __A) {
15981ad6265SDimitry Andric   return 63 - __builtin_clzll((unsigned long long)__A);
1600b57cec5SDimitry Andric }
1610b57cec5SDimitry Andric 
162297eecfbSDimitry Andric /// Swaps the bytes in the input. Converting little endian to big endian or
163297eecfbSDimitry Andric ///    vice versa.
164297eecfbSDimitry Andric ///
165297eecfbSDimitry Andric /// \headerfile <x86intrin.h>
166297eecfbSDimitry Andric ///
167297eecfbSDimitry Andric /// This intrinsic corresponds to the \c BSWAP instruction.
168297eecfbSDimitry Andric ///
169297eecfbSDimitry Andric /// \param __A
170297eecfbSDimitry Andric ///    A 64-bit integer operand.
171297eecfbSDimitry Andric /// \returns A 64-bit integer containing the swapped bytes.
1727a6dacacSDimitry Andric /// \see _bswap64
173e8d8bef9SDimitry Andric static __inline__ long long __DEFAULT_FN_ATTRS_CONSTEXPR
__bswapq(long long __A)1740b57cec5SDimitry Andric __bswapq(long long __A) {
17581ad6265SDimitry Andric   return (long long)__builtin_bswap64((unsigned long long)__A);
1760b57cec5SDimitry Andric }
1770b57cec5SDimitry Andric 
1787a6dacacSDimitry Andric /// Swaps the bytes in the input. Converting little endian to big endian or
1797a6dacacSDimitry Andric ///    vice versa.
1807a6dacacSDimitry Andric ///
1817a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
1827a6dacacSDimitry Andric ///
1837a6dacacSDimitry Andric /// \code
1847a6dacacSDimitry Andric /// long long _bswap64(long long A);
1857a6dacacSDimitry Andric /// \endcode
1867a6dacacSDimitry Andric ///
1877a6dacacSDimitry Andric /// This intrinsic corresponds to the \c BSWAP instruction.
1887a6dacacSDimitry Andric ///
1897a6dacacSDimitry Andric /// \param A
1907a6dacacSDimitry Andric ///    A 64-bit integer operand.
1917a6dacacSDimitry Andric /// \returns A 64-bit integer containing the swapped bytes.
1927a6dacacSDimitry Andric /// \see __bswapq
1930b57cec5SDimitry Andric #define _bswap64(A) __bswapq((A))
1947a6dacacSDimitry Andric #endif /* __x86_64__ */
1950b57cec5SDimitry Andric 
196297eecfbSDimitry Andric /// Counts the number of bits in the source operand having a value of 1.
197297eecfbSDimitry Andric ///
198297eecfbSDimitry Andric /// \headerfile <x86intrin.h>
199297eecfbSDimitry Andric ///
200297eecfbSDimitry Andric /// This intrinsic corresponds to the \c POPCNT instruction or a
201297eecfbSDimitry Andric ///    a sequence of arithmetic and logic ops to calculate it.
202297eecfbSDimitry Andric ///
203297eecfbSDimitry Andric /// \param __A
204297eecfbSDimitry Andric ///    An unsigned 32-bit integer operand.
205297eecfbSDimitry Andric /// \returns A 32-bit integer containing the number of bits with value 1 in the
206297eecfbSDimitry Andric ///    source operand.
2077a6dacacSDimitry Andric /// \see _popcnt32
208e8d8bef9SDimitry Andric static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
__popcntd(unsigned int __A)2090b57cec5SDimitry Andric __popcntd(unsigned int __A)
2100b57cec5SDimitry Andric {
2110b57cec5SDimitry Andric   return __builtin_popcount(__A);
2120b57cec5SDimitry Andric }
2130b57cec5SDimitry Andric 
2147a6dacacSDimitry Andric /// Counts the number of bits in the source operand having a value of 1.
2157a6dacacSDimitry Andric ///
2167a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
2177a6dacacSDimitry Andric ///
2187a6dacacSDimitry Andric /// \code
2197a6dacacSDimitry Andric /// int _popcnt32(int A);
2207a6dacacSDimitry Andric /// \endcode
2217a6dacacSDimitry Andric ///
2227a6dacacSDimitry Andric /// This intrinsic corresponds to the \c POPCNT instruction or a
2237a6dacacSDimitry Andric ///    a sequence of arithmetic and logic ops to calculate it.
2247a6dacacSDimitry Andric ///
2257a6dacacSDimitry Andric /// \param A
2267a6dacacSDimitry Andric ///    An unsigned 32-bit integer operand.
2277a6dacacSDimitry Andric /// \returns A 32-bit integer containing the number of bits with value 1 in the
2287a6dacacSDimitry Andric ///    source operand.
2297a6dacacSDimitry Andric /// \see __popcntd
2300b57cec5SDimitry Andric #define _popcnt32(A) __popcntd((A))
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric #ifdef __x86_64__
233297eecfbSDimitry Andric /// Counts the number of bits in the source operand having a value of 1.
234297eecfbSDimitry Andric ///
235297eecfbSDimitry Andric /// \headerfile <x86intrin.h>
236297eecfbSDimitry Andric ///
237297eecfbSDimitry Andric /// This intrinsic corresponds to the \c POPCNT instruction or a
238297eecfbSDimitry Andric ///    a sequence of arithmetic and logic ops to calculate it.
239297eecfbSDimitry Andric ///
240297eecfbSDimitry Andric /// \param __A
241297eecfbSDimitry Andric ///    An unsigned 64-bit integer operand.
242297eecfbSDimitry Andric /// \returns A 64-bit integer containing the number of bits with value 1 in the
243297eecfbSDimitry Andric ///    source operand.
2447a6dacacSDimitry Andric /// \see _popcnt64
245e8d8bef9SDimitry Andric static __inline__ long long __DEFAULT_FN_ATTRS_CONSTEXPR
__popcntq(unsigned long long __A)2460b57cec5SDimitry Andric __popcntq(unsigned long long __A)
2470b57cec5SDimitry Andric {
2480b57cec5SDimitry Andric   return __builtin_popcountll(__A);
2490b57cec5SDimitry Andric }
2500b57cec5SDimitry Andric 
2517a6dacacSDimitry Andric /// Counts the number of bits in the source operand having a value of 1.
2527a6dacacSDimitry Andric ///
2537a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
2547a6dacacSDimitry Andric ///
2557a6dacacSDimitry Andric /// \code
2567a6dacacSDimitry Andric /// long long _popcnt64(unsigned long long A);
2577a6dacacSDimitry Andric /// \endcode
2587a6dacacSDimitry Andric ///
2597a6dacacSDimitry Andric /// This intrinsic corresponds to the \c POPCNT instruction or a
2607a6dacacSDimitry Andric ///    a sequence of arithmetic and logic ops to calculate it.
2617a6dacacSDimitry Andric ///
2627a6dacacSDimitry Andric /// \param A
2637a6dacacSDimitry Andric ///    An unsigned 64-bit integer operand.
2647a6dacacSDimitry Andric /// \returns A 64-bit integer containing the number of bits with value 1 in the
2657a6dacacSDimitry Andric ///    source operand.
2667a6dacacSDimitry Andric /// \see __popcntq
2670b57cec5SDimitry Andric #define _popcnt64(A) __popcntq((A))
2680b57cec5SDimitry Andric #endif /* __x86_64__ */
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric #ifdef __x86_64__
2717a6dacacSDimitry Andric /// Returns the program status and control \c RFLAGS register with the \c VM
2727a6dacacSDimitry Andric ///    and \c RF flags cleared.
2737a6dacacSDimitry Andric ///
2747a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
2757a6dacacSDimitry Andric ///
2767a6dacacSDimitry Andric /// This intrinsic corresponds to the \c PUSHFQ + \c POP instruction sequence.
2777a6dacacSDimitry Andric ///
2787a6dacacSDimitry Andric /// \returns The 64-bit value of the RFLAGS register.
279e8d8bef9SDimitry Andric static __inline__ unsigned long long __DEFAULT_FN_ATTRS
__readeflags(void)2800b57cec5SDimitry Andric __readeflags(void)
2810b57cec5SDimitry Andric {
2820b57cec5SDimitry Andric   return __builtin_ia32_readeflags_u64();
2830b57cec5SDimitry Andric }
2840b57cec5SDimitry Andric 
2857a6dacacSDimitry Andric /// Writes the specified value to the program status and control \c RFLAGS
2867a6dacacSDimitry Andric ///    register. Reserved bits are not affected.
2877a6dacacSDimitry Andric ///
2887a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
2897a6dacacSDimitry Andric ///
2907a6dacacSDimitry Andric /// This intrinsic corresponds to the \c PUSH + \c POPFQ instruction sequence.
2917a6dacacSDimitry Andric ///
2927a6dacacSDimitry Andric /// \param __f
2937a6dacacSDimitry Andric ///    The 64-bit value to write to \c RFLAGS.
294e8d8bef9SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
__writeeflags(unsigned long long __f)2950b57cec5SDimitry Andric __writeeflags(unsigned long long __f)
2960b57cec5SDimitry Andric {
2970b57cec5SDimitry Andric   __builtin_ia32_writeeflags_u64(__f);
2980b57cec5SDimitry Andric }
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric #else /* !__x86_64__ */
3017a6dacacSDimitry Andric /// Returns the program status and control \c EFLAGS register with the \c VM
3027a6dacacSDimitry Andric ///    and \c RF flags cleared.
3037a6dacacSDimitry Andric ///
3047a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
3057a6dacacSDimitry Andric ///
3067a6dacacSDimitry Andric /// This intrinsic corresponds to the \c PUSHFD + \c POP instruction sequence.
3077a6dacacSDimitry Andric ///
3087a6dacacSDimitry Andric /// \returns The 32-bit value of the EFLAGS register.
309e8d8bef9SDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS
__readeflags(void)3100b57cec5SDimitry Andric __readeflags(void)
3110b57cec5SDimitry Andric {
3120b57cec5SDimitry Andric   return __builtin_ia32_readeflags_u32();
3130b57cec5SDimitry Andric }
3140b57cec5SDimitry Andric 
3157a6dacacSDimitry Andric /// Writes the specified value to the program status and control \c EFLAGS
3167a6dacacSDimitry Andric ///    register. Reserved bits are not affected.
3177a6dacacSDimitry Andric ///
3187a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
3197a6dacacSDimitry Andric ///
3207a6dacacSDimitry Andric /// This intrinsic corresponds to the \c PUSH + \c POPFD instruction sequence.
3217a6dacacSDimitry Andric ///
3227a6dacacSDimitry Andric /// \param __f
3237a6dacacSDimitry Andric ///    The 32-bit value to write to \c EFLAGS.
324e8d8bef9SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
__writeeflags(unsigned int __f)3250b57cec5SDimitry Andric __writeeflags(unsigned int __f)
3260b57cec5SDimitry Andric {
3270b57cec5SDimitry Andric   __builtin_ia32_writeeflags_u32(__f);
3280b57cec5SDimitry Andric }
3290b57cec5SDimitry Andric #endif /* !__x86_64__ */
3300b57cec5SDimitry Andric 
331297eecfbSDimitry Andric /// Cast a 32-bit float value to a 32-bit unsigned integer value.
332297eecfbSDimitry Andric ///
333297eecfbSDimitry Andric /// \headerfile <x86intrin.h>
334297eecfbSDimitry Andric ///
335297eecfbSDimitry Andric /// This intrinsic corresponds to the \c VMOVD / \c MOVD instruction in x86_64,
336297eecfbSDimitry Andric ///    and corresponds to the \c VMOVL / \c MOVL instruction in ia32.
337297eecfbSDimitry Andric ///
338297eecfbSDimitry Andric /// \param __A
339297eecfbSDimitry Andric ///    A 32-bit float value.
340297eecfbSDimitry Andric /// \returns a 32-bit unsigned integer containing the converted value.
341e8d8bef9SDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS_CAST
_castf32_u32(float __A)342a7dea167SDimitry Andric _castf32_u32(float __A) {
343e8d8bef9SDimitry Andric   return __builtin_bit_cast(unsigned int, __A);
344a7dea167SDimitry Andric }
345a7dea167SDimitry Andric 
346297eecfbSDimitry Andric /// Cast a 64-bit float value to a 64-bit unsigned integer value.
347297eecfbSDimitry Andric ///
348297eecfbSDimitry Andric /// \headerfile <x86intrin.h>
349297eecfbSDimitry Andric ///
350297eecfbSDimitry Andric /// This intrinsic corresponds to the \c VMOVQ / \c MOVQ instruction in x86_64,
351297eecfbSDimitry Andric ///    and corresponds to the \c VMOVL / \c MOVL instruction in ia32.
352297eecfbSDimitry Andric ///
353297eecfbSDimitry Andric /// \param __A
354297eecfbSDimitry Andric ///    A 64-bit float value.
355297eecfbSDimitry Andric /// \returns a 64-bit unsigned integer containing the converted value.
356e8d8bef9SDimitry Andric static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CAST
_castf64_u64(double __A)357a7dea167SDimitry Andric _castf64_u64(double __A) {
358e8d8bef9SDimitry Andric   return __builtin_bit_cast(unsigned long long, __A);
359a7dea167SDimitry Andric }
360a7dea167SDimitry Andric 
361297eecfbSDimitry Andric /// Cast a 32-bit unsigned integer value to a 32-bit float value.
362297eecfbSDimitry Andric ///
363297eecfbSDimitry Andric /// \headerfile <x86intrin.h>
364297eecfbSDimitry Andric ///
365297eecfbSDimitry Andric /// This intrinsic corresponds to the \c VMOVQ / \c MOVQ instruction in x86_64,
366297eecfbSDimitry Andric ///    and corresponds to the \c FLDS instruction in ia32.
367297eecfbSDimitry Andric ///
368297eecfbSDimitry Andric /// \param __A
369297eecfbSDimitry Andric ///    A 32-bit unsigned integer value.
370297eecfbSDimitry Andric /// \returns a 32-bit float value containing the converted value.
371e8d8bef9SDimitry Andric static __inline__ float __DEFAULT_FN_ATTRS_CAST
_castu32_f32(unsigned int __A)372a7dea167SDimitry Andric _castu32_f32(unsigned int __A) {
373e8d8bef9SDimitry Andric   return __builtin_bit_cast(float, __A);
374a7dea167SDimitry Andric }
375a7dea167SDimitry Andric 
376297eecfbSDimitry Andric /// Cast a 64-bit unsigned integer value to a 64-bit float value.
377297eecfbSDimitry Andric ///
378297eecfbSDimitry Andric /// \headerfile <x86intrin.h>
379297eecfbSDimitry Andric ///
380297eecfbSDimitry Andric /// This intrinsic corresponds to the \c VMOVQ / \c MOVQ instruction in x86_64,
381297eecfbSDimitry Andric ///    and corresponds to the \c FLDL instruction in ia32.
382297eecfbSDimitry Andric ///
383297eecfbSDimitry Andric /// \param __A
384297eecfbSDimitry Andric ///    A 64-bit unsigned integer value.
385297eecfbSDimitry Andric /// \returns a 64-bit float value containing the converted value.
386e8d8bef9SDimitry Andric static __inline__ double __DEFAULT_FN_ATTRS_CAST
_castu64_f64(unsigned long long __A)387a7dea167SDimitry Andric _castu64_f64(unsigned long long __A) {
388e8d8bef9SDimitry Andric   return __builtin_bit_cast(double, __A);
389a7dea167SDimitry Andric }
390a7dea167SDimitry Andric 
391297eecfbSDimitry Andric /// Adds the unsigned integer operand to the CRC-32C checksum of the
392297eecfbSDimitry Andric ///     unsigned char operand.
393297eecfbSDimitry Andric ///
394297eecfbSDimitry Andric /// \headerfile <x86intrin.h>
395297eecfbSDimitry Andric ///
396297eecfbSDimitry Andric /// This intrinsic corresponds to the \c CRC32B instruction.
397297eecfbSDimitry Andric ///
398297eecfbSDimitry Andric /// \param __C
399297eecfbSDimitry Andric ///    An unsigned integer operand to add to the CRC-32C checksum of operand
400297eecfbSDimitry Andric ///    \a  __D.
401297eecfbSDimitry Andric /// \param __D
402297eecfbSDimitry Andric ///    An unsigned 8-bit integer operand used to compute the CRC-32C checksum.
403297eecfbSDimitry Andric /// \returns The result of adding operand \a __C to the CRC-32C checksum of
404297eecfbSDimitry Andric ///    operand \a __D.
405349cc55cSDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS_CRC32
__crc32b(unsigned int __C,unsigned char __D)4060b57cec5SDimitry Andric __crc32b(unsigned int __C, unsigned char __D)
4070b57cec5SDimitry Andric {
4080b57cec5SDimitry Andric   return __builtin_ia32_crc32qi(__C, __D);
4090b57cec5SDimitry Andric }
4100b57cec5SDimitry Andric 
411297eecfbSDimitry Andric /// Adds the unsigned integer operand to the CRC-32C checksum of the
412297eecfbSDimitry Andric ///    unsigned short operand.
413297eecfbSDimitry Andric ///
414297eecfbSDimitry Andric /// \headerfile <x86intrin.h>
415297eecfbSDimitry Andric ///
416297eecfbSDimitry Andric /// This intrinsic corresponds to the \c CRC32W instruction.
417297eecfbSDimitry Andric ///
418297eecfbSDimitry Andric /// \param __C
419297eecfbSDimitry Andric ///    An unsigned integer operand to add to the CRC-32C checksum of operand
420297eecfbSDimitry Andric ///    \a  __D.
421297eecfbSDimitry Andric /// \param __D
422297eecfbSDimitry Andric ///    An unsigned 16-bit integer operand used to compute the CRC-32C checksum.
423297eecfbSDimitry Andric /// \returns The result of adding operand \a __C to the CRC-32C checksum of
424297eecfbSDimitry Andric ///    operand \a __D.
425349cc55cSDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS_CRC32
__crc32w(unsigned int __C,unsigned short __D)4260b57cec5SDimitry Andric __crc32w(unsigned int __C, unsigned short __D)
4270b57cec5SDimitry Andric {
4280b57cec5SDimitry Andric   return __builtin_ia32_crc32hi(__C, __D);
4290b57cec5SDimitry Andric }
4300b57cec5SDimitry Andric 
431297eecfbSDimitry Andric /// Adds the unsigned integer operand to the CRC-32C checksum of the
432297eecfbSDimitry Andric ///    second unsigned integer operand.
433297eecfbSDimitry Andric ///
434297eecfbSDimitry Andric /// \headerfile <x86intrin.h>
435297eecfbSDimitry Andric ///
436297eecfbSDimitry Andric /// This intrinsic corresponds to the \c CRC32D instruction.
437297eecfbSDimitry Andric ///
438297eecfbSDimitry Andric /// \param __C
439297eecfbSDimitry Andric ///    An unsigned integer operand to add to the CRC-32C checksum of operand
440297eecfbSDimitry Andric ///    \a  __D.
441297eecfbSDimitry Andric /// \param __D
442297eecfbSDimitry Andric ///    An unsigned 32-bit integer operand used to compute the CRC-32C checksum.
443297eecfbSDimitry Andric /// \returns The result of adding operand \a __C to the CRC-32C checksum of
444297eecfbSDimitry Andric ///    operand \a __D.
445349cc55cSDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS_CRC32
__crc32d(unsigned int __C,unsigned int __D)4460b57cec5SDimitry Andric __crc32d(unsigned int __C, unsigned int __D)
4470b57cec5SDimitry Andric {
4480b57cec5SDimitry Andric   return __builtin_ia32_crc32si(__C, __D);
4490b57cec5SDimitry Andric }
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric #ifdef __x86_64__
452297eecfbSDimitry Andric /// Adds the unsigned integer operand to the CRC-32C checksum of the
453297eecfbSDimitry Andric ///    unsigned 64-bit integer operand.
454297eecfbSDimitry Andric ///
455297eecfbSDimitry Andric /// \headerfile <x86intrin.h>
456297eecfbSDimitry Andric ///
457297eecfbSDimitry Andric /// This intrinsic corresponds to the \c CRC32Q instruction.
458297eecfbSDimitry Andric ///
459297eecfbSDimitry Andric /// \param __C
460297eecfbSDimitry Andric ///    An unsigned integer operand to add to the CRC-32C checksum of operand
461297eecfbSDimitry Andric ///    \a  __D.
462297eecfbSDimitry Andric /// \param __D
463297eecfbSDimitry Andric ///    An unsigned 64-bit integer operand used to compute the CRC-32C checksum.
464297eecfbSDimitry Andric /// \returns The result of adding operand \a __C to the CRC-32C checksum of
465297eecfbSDimitry Andric ///    operand \a __D.
466349cc55cSDimitry Andric static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CRC32
__crc32q(unsigned long long __C,unsigned long long __D)4670b57cec5SDimitry Andric __crc32q(unsigned long long __C, unsigned long long __D)
4680b57cec5SDimitry Andric {
4690b57cec5SDimitry Andric   return __builtin_ia32_crc32di(__C, __D);
4700b57cec5SDimitry Andric }
4710b57cec5SDimitry Andric #endif /* __x86_64__ */
4720b57cec5SDimitry Andric 
4737a6dacacSDimitry Andric /// Reads the specified performance monitoring counter. Refer to your
4747a6dacacSDimitry Andric ///    processor's documentation to determine which performance counters are
4757a6dacacSDimitry Andric ///    supported.
4767a6dacacSDimitry Andric ///
4777a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
4787a6dacacSDimitry Andric ///
4797a6dacacSDimitry Andric /// This intrinsic corresponds to the \c RDPMC instruction.
4807a6dacacSDimitry Andric ///
4817a6dacacSDimitry Andric /// \param __A
4827a6dacacSDimitry Andric ///    The performance counter to read.
4837a6dacacSDimitry Andric /// \returns The 64-bit value read from the performance counter.
4847a6dacacSDimitry Andric /// \see _rdpmc
485e8d8bef9SDimitry Andric static __inline__ unsigned long long __DEFAULT_FN_ATTRS
__rdpmc(int __A)4860b57cec5SDimitry Andric __rdpmc(int __A) {
4870b57cec5SDimitry Andric   return __builtin_ia32_rdpmc(__A);
4880b57cec5SDimitry Andric }
4890b57cec5SDimitry Andric 
4907a6dacacSDimitry Andric /// Reads the processor's time stamp counter and the \c IA32_TSC_AUX MSR
4917a6dacacSDimitry Andric ///    \c (0xc0000103).
4927a6dacacSDimitry Andric ///
4937a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
4947a6dacacSDimitry Andric ///
4957a6dacacSDimitry Andric /// This intrinsic corresponds to the \c RDTSCP instruction.
4967a6dacacSDimitry Andric ///
4977a6dacacSDimitry Andric /// \param __A
4987a6dacacSDimitry Andric ///    Address of where to store the 32-bit \c IA32_TSC_AUX value.
4997a6dacacSDimitry Andric /// \returns The 64-bit value of the time stamp counter.
500e8d8bef9SDimitry Andric static __inline__ unsigned long long __DEFAULT_FN_ATTRS
__rdtscp(unsigned int * __A)5010b57cec5SDimitry Andric __rdtscp(unsigned int *__A) {
5020b57cec5SDimitry Andric   return __builtin_ia32_rdtscp(__A);
5030b57cec5SDimitry Andric }
5040b57cec5SDimitry Andric 
5057a6dacacSDimitry Andric /// Reads the processor's time stamp counter.
5067a6dacacSDimitry Andric ///
5077a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
5087a6dacacSDimitry Andric ///
5097a6dacacSDimitry Andric /// \code
5107a6dacacSDimitry Andric /// unsigned long long _rdtsc();
5117a6dacacSDimitry Andric /// \endcode
5127a6dacacSDimitry Andric ///
5137a6dacacSDimitry Andric /// This intrinsic corresponds to the \c RDTSC instruction.
5147a6dacacSDimitry Andric ///
5157a6dacacSDimitry Andric /// \returns The 64-bit value of the time stamp counter.
5160b57cec5SDimitry Andric #define _rdtsc() __rdtsc()
5170b57cec5SDimitry Andric 
5187a6dacacSDimitry Andric /// Reads the specified performance monitoring counter. Refer to your
5197a6dacacSDimitry Andric ///    processor's documentation to determine which performance counters are
5207a6dacacSDimitry Andric ///    supported.
5217a6dacacSDimitry Andric ///
5227a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
5237a6dacacSDimitry Andric ///
5247a6dacacSDimitry Andric /// \code
5257a6dacacSDimitry Andric /// unsigned long long _rdpmc(int A);
5267a6dacacSDimitry Andric /// \endcode
5277a6dacacSDimitry Andric ///
5287a6dacacSDimitry Andric /// This intrinsic corresponds to the \c RDPMC instruction.
5297a6dacacSDimitry Andric ///
5307a6dacacSDimitry Andric /// \param A
5317a6dacacSDimitry Andric ///    The performance counter to read.
5327a6dacacSDimitry Andric /// \returns The 64-bit value read from the performance counter.
5337a6dacacSDimitry Andric /// \see __rdpmc
5340b57cec5SDimitry Andric #define _rdpmc(A) __rdpmc(A)
5350b57cec5SDimitry Andric 
536e8d8bef9SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
_wbinvd(void)5370b57cec5SDimitry Andric _wbinvd(void) {
5380b57cec5SDimitry Andric   __builtin_ia32_wbinvd();
5390b57cec5SDimitry Andric }
5400b57cec5SDimitry Andric 
5417a6dacacSDimitry Andric /// Rotates an 8-bit value to the left by the specified number of bits.
5427a6dacacSDimitry Andric ///    This operation is undefined if the number of bits exceeds the size of
5437a6dacacSDimitry Andric ///    the value.
5447a6dacacSDimitry Andric ///
5457a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
5467a6dacacSDimitry Andric ///
5477a6dacacSDimitry Andric /// This intrinsic corresponds to the \c ROL instruction.
5487a6dacacSDimitry Andric ///
5497a6dacacSDimitry Andric /// \param __X
5507a6dacacSDimitry Andric ///    The unsigned 8-bit value to be rotated.
5517a6dacacSDimitry Andric /// \param __C
5527a6dacacSDimitry Andric ///    The number of bits to rotate the value.
5537a6dacacSDimitry Andric /// \returns The rotated value.
554e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS_CONSTEXPR
__rolb(unsigned char __X,int __C)5550b57cec5SDimitry Andric __rolb(unsigned char __X, int __C) {
5560b57cec5SDimitry Andric   return __builtin_rotateleft8(__X, __C);
5570b57cec5SDimitry Andric }
5580b57cec5SDimitry Andric 
5597a6dacacSDimitry Andric /// Rotates an 8-bit value to the right by the specified number of bits.
5607a6dacacSDimitry Andric ///    This operation is undefined if the number of bits exceeds the size of
5617a6dacacSDimitry Andric ///    the value.
5627a6dacacSDimitry Andric ///
5637a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
5647a6dacacSDimitry Andric ///
5657a6dacacSDimitry Andric /// This intrinsic corresponds to the \c ROR instruction.
5667a6dacacSDimitry Andric ///
5677a6dacacSDimitry Andric /// \param __X
5687a6dacacSDimitry Andric ///    The unsigned 8-bit value to be rotated.
5697a6dacacSDimitry Andric /// \param __C
5707a6dacacSDimitry Andric ///    The number of bits to rotate the value.
5717a6dacacSDimitry Andric /// \returns The rotated value.
572e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS_CONSTEXPR
__rorb(unsigned char __X,int __C)5730b57cec5SDimitry Andric __rorb(unsigned char __X, int __C) {
5740b57cec5SDimitry Andric   return __builtin_rotateright8(__X, __C);
5750b57cec5SDimitry Andric }
5760b57cec5SDimitry Andric 
5777a6dacacSDimitry Andric /// Rotates a 16-bit value to the left by the specified number of bits.
5787a6dacacSDimitry Andric ///    This operation is undefined if the number of bits exceeds the size of
5797a6dacacSDimitry Andric ///    the value.
5807a6dacacSDimitry Andric ///
5817a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
5827a6dacacSDimitry Andric ///
5837a6dacacSDimitry Andric /// This intrinsic corresponds to the \c ROL instruction.
5847a6dacacSDimitry Andric ///
5857a6dacacSDimitry Andric /// \param __X
5867a6dacacSDimitry Andric ///    The unsigned 16-bit value to be rotated.
5877a6dacacSDimitry Andric /// \param __C
5887a6dacacSDimitry Andric ///    The number of bits to rotate the value.
5897a6dacacSDimitry Andric /// \returns The rotated value.
5907a6dacacSDimitry Andric /// \see _rotwl
591e8d8bef9SDimitry Andric static __inline__ unsigned short __DEFAULT_FN_ATTRS_CONSTEXPR
__rolw(unsigned short __X,int __C)5920b57cec5SDimitry Andric __rolw(unsigned short __X, int __C) {
5930b57cec5SDimitry Andric   return __builtin_rotateleft16(__X, __C);
5940b57cec5SDimitry Andric }
5950b57cec5SDimitry Andric 
5967a6dacacSDimitry Andric /// Rotates a 16-bit value to the right by the specified number of bits.
5977a6dacacSDimitry Andric ///    This operation is undefined if the number of bits exceeds the size of
5987a6dacacSDimitry Andric ///    the value.
5997a6dacacSDimitry Andric ///
6007a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
6017a6dacacSDimitry Andric ///
6027a6dacacSDimitry Andric /// This intrinsic corresponds to the \c ROR instruction.
6037a6dacacSDimitry Andric ///
6047a6dacacSDimitry Andric /// \param __X
6057a6dacacSDimitry Andric ///    The unsigned 16-bit value to be rotated.
6067a6dacacSDimitry Andric /// \param __C
6077a6dacacSDimitry Andric ///    The number of bits to rotate the value.
6087a6dacacSDimitry Andric /// \returns The rotated value.
6097a6dacacSDimitry Andric /// \see _rotwr
610e8d8bef9SDimitry Andric static __inline__ unsigned short __DEFAULT_FN_ATTRS_CONSTEXPR
__rorw(unsigned short __X,int __C)6110b57cec5SDimitry Andric __rorw(unsigned short __X, int __C) {
6120b57cec5SDimitry Andric   return __builtin_rotateright16(__X, __C);
6130b57cec5SDimitry Andric }
6140b57cec5SDimitry Andric 
6157a6dacacSDimitry Andric /// Rotates a 32-bit value to the left by the specified number of bits.
6167a6dacacSDimitry Andric ///    This operation is undefined if the number of bits exceeds the size of
6177a6dacacSDimitry Andric ///    the value.
6187a6dacacSDimitry Andric ///
6197a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
6207a6dacacSDimitry Andric ///
6217a6dacacSDimitry Andric /// This intrinsic corresponds to the \c ROL instruction.
6227a6dacacSDimitry Andric ///
6237a6dacacSDimitry Andric /// \param __X
6247a6dacacSDimitry Andric ///    The unsigned 32-bit value to be rotated.
6257a6dacacSDimitry Andric /// \param __C
6267a6dacacSDimitry Andric ///    The number of bits to rotate the value.
6277a6dacacSDimitry Andric /// \returns The rotated value.
6287a6dacacSDimitry Andric /// \see _rotl
629e8d8bef9SDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
__rold(unsigned int __X,int __C)6300b57cec5SDimitry Andric __rold(unsigned int __X, int __C) {
63181ad6265SDimitry Andric   return __builtin_rotateleft32(__X, (unsigned int)__C);
6320b57cec5SDimitry Andric }
6330b57cec5SDimitry Andric 
6347a6dacacSDimitry Andric /// Rotates a 32-bit value to the right by the specified number of bits.
6357a6dacacSDimitry Andric ///    This operation is undefined if the number of bits exceeds the size of
6367a6dacacSDimitry Andric ///    the value.
6377a6dacacSDimitry Andric ///
6387a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
6397a6dacacSDimitry Andric ///
6407a6dacacSDimitry Andric /// This intrinsic corresponds to the \c ROR instruction.
6417a6dacacSDimitry Andric ///
6427a6dacacSDimitry Andric /// \param __X
6437a6dacacSDimitry Andric ///    The unsigned 32-bit value to be rotated.
6447a6dacacSDimitry Andric /// \param __C
6457a6dacacSDimitry Andric ///    The number of bits to rotate the value.
6467a6dacacSDimitry Andric /// \returns The rotated value.
6477a6dacacSDimitry Andric /// \see _rotr
648e8d8bef9SDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
__rord(unsigned int __X,int __C)6490b57cec5SDimitry Andric __rord(unsigned int __X, int __C) {
65081ad6265SDimitry Andric   return __builtin_rotateright32(__X, (unsigned int)__C);
6510b57cec5SDimitry Andric }
6520b57cec5SDimitry Andric 
6530b57cec5SDimitry Andric #ifdef __x86_64__
6547a6dacacSDimitry Andric /// Rotates a 64-bit value to the left by the specified number of bits.
6557a6dacacSDimitry Andric ///    This operation is undefined if the number of bits exceeds the size of
6567a6dacacSDimitry Andric ///    the value.
6577a6dacacSDimitry Andric ///
6587a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
6597a6dacacSDimitry Andric ///
6607a6dacacSDimitry Andric /// This intrinsic corresponds to the \c ROL instruction.
6617a6dacacSDimitry Andric ///
6627a6dacacSDimitry Andric /// \param __X
6637a6dacacSDimitry Andric ///    The unsigned 64-bit value to be rotated.
6647a6dacacSDimitry Andric /// \param __C
6657a6dacacSDimitry Andric ///    The number of bits to rotate the value.
6667a6dacacSDimitry Andric /// \returns The rotated value.
667e8d8bef9SDimitry Andric static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
__rolq(unsigned long long __X,int __C)6680b57cec5SDimitry Andric __rolq(unsigned long long __X, int __C) {
66981ad6265SDimitry Andric   return __builtin_rotateleft64(__X, (unsigned long long)__C);
6700b57cec5SDimitry Andric }
6710b57cec5SDimitry Andric 
6727a6dacacSDimitry Andric /// Rotates a 64-bit value to the right by the specified number of bits.
6737a6dacacSDimitry Andric ///    This operation is undefined if the number of bits exceeds the size of
6747a6dacacSDimitry Andric ///    the value.
6757a6dacacSDimitry Andric ///
6767a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
6777a6dacacSDimitry Andric ///
6787a6dacacSDimitry Andric /// This intrinsic corresponds to the \c ROR instruction.
6797a6dacacSDimitry Andric ///
6807a6dacacSDimitry Andric /// \param __X
6817a6dacacSDimitry Andric ///    The unsigned 64-bit value to be rotated.
6827a6dacacSDimitry Andric /// \param __C
6837a6dacacSDimitry Andric ///    The number of bits to rotate the value.
6847a6dacacSDimitry Andric /// \returns The rotated value.
685e8d8bef9SDimitry Andric static __inline__ unsigned long long __DEFAULT_FN_ATTRS_CONSTEXPR
__rorq(unsigned long long __X,int __C)6860b57cec5SDimitry Andric __rorq(unsigned long long __X, int __C) {
68781ad6265SDimitry Andric   return __builtin_rotateright64(__X, (unsigned long long)__C);
6880b57cec5SDimitry Andric }
6890b57cec5SDimitry Andric #endif /* __x86_64__ */
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric #ifndef _MSC_VER
6920b57cec5SDimitry Andric /* These are already provided as builtins for MSVC. */
6930b57cec5SDimitry Andric /* Select the correct function based on the size of long. */
6940b57cec5SDimitry Andric #ifdef __LP64__
6957a6dacacSDimitry Andric /// Rotates a 64-bit value to the left by the specified number of bits.
6967a6dacacSDimitry Andric ///    This operation is undefined if the number of bits exceeds the size of
6977a6dacacSDimitry Andric ///    the value.
6987a6dacacSDimitry Andric ///
6997a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
7007a6dacacSDimitry Andric ///
7017a6dacacSDimitry Andric /// \code
7027a6dacacSDimitry Andric /// unsigned long long _lrotl(unsigned long long a, int b);
7037a6dacacSDimitry Andric /// \endcode
7047a6dacacSDimitry Andric ///
7057a6dacacSDimitry Andric /// This intrinsic corresponds to the \c ROL instruction.
7067a6dacacSDimitry Andric ///
7077a6dacacSDimitry Andric /// \param a
7087a6dacacSDimitry Andric ///    The unsigned 64-bit value to be rotated.
7097a6dacacSDimitry Andric /// \param b
7107a6dacacSDimitry Andric ///    The number of bits to rotate the value.
7117a6dacacSDimitry Andric /// \returns The rotated value.
7127a6dacacSDimitry Andric /// \see __rolq
7130b57cec5SDimitry Andric #define _lrotl(a,b) __rolq((a), (b))
7147a6dacacSDimitry Andric 
7157a6dacacSDimitry Andric /// Rotates a 64-bit value to the right by the specified number of bits.
7167a6dacacSDimitry Andric ///    This operation is undefined if the number of bits exceeds the size of
7177a6dacacSDimitry Andric ///    the value.
7187a6dacacSDimitry Andric ///
7197a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
7207a6dacacSDimitry Andric ///
7217a6dacacSDimitry Andric /// \code
7227a6dacacSDimitry Andric /// unsigned long long _lrotr(unsigned long long a, int b);
7237a6dacacSDimitry Andric /// \endcode
7247a6dacacSDimitry Andric ///
7257a6dacacSDimitry Andric /// This intrinsic corresponds to the \c ROR instruction.
7267a6dacacSDimitry Andric ///
7277a6dacacSDimitry Andric /// \param a
7287a6dacacSDimitry Andric ///    The unsigned 64-bit value to be rotated.
7297a6dacacSDimitry Andric /// \param b
7307a6dacacSDimitry Andric ///    The number of bits to rotate the value.
7317a6dacacSDimitry Andric /// \returns The rotated value.
7327a6dacacSDimitry Andric /// \see __rorq
7330b57cec5SDimitry Andric #define _lrotr(a,b) __rorq((a), (b))
7347a6dacacSDimitry Andric #else // __LP64__
7357a6dacacSDimitry Andric /// Rotates a 32-bit value to the left by the specified number of bits.
7367a6dacacSDimitry Andric ///    This operation is undefined if the number of bits exceeds the size of
7377a6dacacSDimitry Andric ///    the value.
7387a6dacacSDimitry Andric ///
7397a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
7407a6dacacSDimitry Andric ///
7417a6dacacSDimitry Andric /// \code
7427a6dacacSDimitry Andric /// unsigned int _lrotl(unsigned int a, int b);
7437a6dacacSDimitry Andric /// \endcode
7447a6dacacSDimitry Andric ///
7457a6dacacSDimitry Andric /// This intrinsic corresponds to the \c ROL instruction.
7467a6dacacSDimitry Andric ///
7477a6dacacSDimitry Andric /// \param a
7487a6dacacSDimitry Andric ///    The unsigned 32-bit value to be rotated.
7497a6dacacSDimitry Andric /// \param b
7507a6dacacSDimitry Andric ///    The number of bits to rotate the value.
7517a6dacacSDimitry Andric /// \returns The rotated value.
7527a6dacacSDimitry Andric /// \see __rold
7530b57cec5SDimitry Andric #define _lrotl(a,b) __rold((a), (b))
7547a6dacacSDimitry Andric 
7557a6dacacSDimitry Andric /// Rotates a 32-bit value to the right by the specified number of bits.
7567a6dacacSDimitry Andric ///    This operation is undefined if the number of bits exceeds the size of
7577a6dacacSDimitry Andric ///    the value.
7587a6dacacSDimitry Andric ///
7597a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
7607a6dacacSDimitry Andric ///
7617a6dacacSDimitry Andric /// \code
7627a6dacacSDimitry Andric /// unsigned int _lrotr(unsigned int a, int b);
7637a6dacacSDimitry Andric /// \endcode
7647a6dacacSDimitry Andric ///
7657a6dacacSDimitry Andric /// This intrinsic corresponds to the \c ROR instruction.
7667a6dacacSDimitry Andric ///
7677a6dacacSDimitry Andric /// \param a
7687a6dacacSDimitry Andric ///    The unsigned 32-bit value to be rotated.
7697a6dacacSDimitry Andric /// \param b
7707a6dacacSDimitry Andric ///    The number of bits to rotate the value.
7717a6dacacSDimitry Andric /// \returns The rotated value.
7727a6dacacSDimitry Andric /// \see __rord
7730b57cec5SDimitry Andric #define _lrotr(a,b) __rord((a), (b))
7747a6dacacSDimitry Andric #endif // __LP64__
7757a6dacacSDimitry Andric 
7767a6dacacSDimitry Andric /// Rotates a 32-bit value to the left by the specified number of bits.
7777a6dacacSDimitry Andric ///    This operation is undefined if the number of bits exceeds the size of
7787a6dacacSDimitry Andric ///    the value.
7797a6dacacSDimitry Andric ///
7807a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
7817a6dacacSDimitry Andric ///
7827a6dacacSDimitry Andric /// \code
7837a6dacacSDimitry Andric /// unsigned int _rotl(unsigned int a, int b);
7847a6dacacSDimitry Andric /// \endcode
7857a6dacacSDimitry Andric ///
7867a6dacacSDimitry Andric /// This intrinsic corresponds to the \c ROL instruction.
7877a6dacacSDimitry Andric ///
7887a6dacacSDimitry Andric /// \param a
7897a6dacacSDimitry Andric ///    The unsigned 32-bit value to be rotated.
7907a6dacacSDimitry Andric /// \param b
7917a6dacacSDimitry Andric ///    The number of bits to rotate the value.
7927a6dacacSDimitry Andric /// \returns The rotated value.
7937a6dacacSDimitry Andric /// \see __rold
7940b57cec5SDimitry Andric #define _rotl(a,b) __rold((a), (b))
7957a6dacacSDimitry Andric 
7967a6dacacSDimitry Andric /// Rotates a 32-bit value to the right by the specified number of bits.
7977a6dacacSDimitry Andric ///    This operation is undefined if the number of bits exceeds the size of
7987a6dacacSDimitry Andric ///    the value.
7997a6dacacSDimitry Andric ///
8007a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
8017a6dacacSDimitry Andric ///
8027a6dacacSDimitry Andric /// \code
8037a6dacacSDimitry Andric /// unsigned int _rotr(unsigned int a, int b);
8047a6dacacSDimitry Andric /// \endcode
8057a6dacacSDimitry Andric ///
8067a6dacacSDimitry Andric /// This intrinsic corresponds to the \c ROR instruction.
8077a6dacacSDimitry Andric ///
8087a6dacacSDimitry Andric /// \param a
8097a6dacacSDimitry Andric ///    The unsigned 32-bit value to be rotated.
8107a6dacacSDimitry Andric /// \param b
8117a6dacacSDimitry Andric ///    The number of bits to rotate the value.
8127a6dacacSDimitry Andric /// \returns The rotated value.
8137a6dacacSDimitry Andric /// \see __rord
8140b57cec5SDimitry Andric #define _rotr(a,b) __rord((a), (b))
8150b57cec5SDimitry Andric #endif // _MSC_VER
8160b57cec5SDimitry Andric 
8170b57cec5SDimitry Andric /* These are not builtins so need to be provided in all modes. */
8187a6dacacSDimitry Andric /// Rotates a 16-bit value to the left by the specified number of bits.
8197a6dacacSDimitry Andric ///    This operation is undefined if the number of bits exceeds the size of
8207a6dacacSDimitry Andric ///    the value.
8217a6dacacSDimitry Andric ///
8227a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
8237a6dacacSDimitry Andric ///
8247a6dacacSDimitry Andric /// \code
8257a6dacacSDimitry Andric /// unsigned short _rotwl(unsigned short a, int b);
8267a6dacacSDimitry Andric /// \endcode
8277a6dacacSDimitry Andric ///
8287a6dacacSDimitry Andric /// This intrinsic corresponds to the \c ROL instruction.
8297a6dacacSDimitry Andric ///
8307a6dacacSDimitry Andric /// \param a
8317a6dacacSDimitry Andric ///    The unsigned 16-bit value to be rotated.
8327a6dacacSDimitry Andric /// \param b
8337a6dacacSDimitry Andric ///    The number of bits to rotate the value.
8347a6dacacSDimitry Andric /// \returns The rotated value.
8357a6dacacSDimitry Andric /// \see __rolw
8360b57cec5SDimitry Andric #define _rotwl(a,b) __rolw((a), (b))
8377a6dacacSDimitry Andric 
8387a6dacacSDimitry Andric /// Rotates a 16-bit value to the right by the specified number of bits.
8397a6dacacSDimitry Andric ///    This operation is undefined if the number of bits exceeds the size of
8407a6dacacSDimitry Andric ///    the value.
8417a6dacacSDimitry Andric ///
8427a6dacacSDimitry Andric /// \headerfile <x86intrin.h>
8437a6dacacSDimitry Andric ///
8447a6dacacSDimitry Andric /// \code
8457a6dacacSDimitry Andric /// unsigned short _rotwr(unsigned short a, int b);
8467a6dacacSDimitry Andric /// \endcode
8477a6dacacSDimitry Andric ///
8487a6dacacSDimitry Andric /// This intrinsic corresponds to the \c ROR instruction.
8497a6dacacSDimitry Andric ///
8507a6dacacSDimitry Andric /// \param a
8517a6dacacSDimitry Andric ///    The unsigned 16-bit value to be rotated.
8527a6dacacSDimitry Andric /// \param b
8537a6dacacSDimitry Andric ///    The number of bits to rotate the value.
8547a6dacacSDimitry Andric /// \returns The rotated value.
8557a6dacacSDimitry Andric /// \see __rorw
8560b57cec5SDimitry Andric #define _rotwr(a,b) __rorw((a), (b))
8570b57cec5SDimitry Andric 
858e8d8bef9SDimitry Andric #undef __DEFAULT_FN_ATTRS
859e8d8bef9SDimitry Andric #undef __DEFAULT_FN_ATTRS_CAST
860349cc55cSDimitry Andric #undef __DEFAULT_FN_ATTRS_CRC32
861e8d8bef9SDimitry Andric #undef __DEFAULT_FN_ATTRS_CONSTEXPR
862e8d8bef9SDimitry Andric 
8630b57cec5SDimitry Andric #endif /* __IA32INTRIN_H */
864