Skip to content

Commit

Permalink
[Headers][X86] Add macro descriptions to ia32intrin.h (#78613)
Browse files Browse the repository at this point in the history
These are largely copy-pasted from the corresponding function
descriptions. Updated _rdtsc definition because it was just plain wrong.
  • Loading branch information
pogo59 committed Jan 22, 2024
1 parent 69fedaf commit d9cb37c
Showing 1 changed file with 269 additions and 3 deletions.
272 changes: 269 additions & 3 deletions clang/lib/Headers/ia32intrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
/// \param __A
/// A 32-bit integer operand.
/// \returns A 32-bit integer containing the bit number.
/// \see _bit_scan_forward
static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
__bsfd(int __A) {
return __builtin_ctz((unsigned int)__A);
Expand All @@ -53,6 +54,7 @@ __bsfd(int __A) {
/// \param __A
/// A 32-bit integer operand.
/// \returns A 32-bit integer containing the bit number.
/// \see _bit_scan_reverse
static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
__bsrd(int __A) {
return 31 - __builtin_clz((unsigned int)__A);
Expand Down Expand Up @@ -88,7 +90,40 @@ _bswap(int __A) {
return (int)__builtin_bswap32((unsigned int)__A);
}

/// Find the first set bit starting from the lsb. Result is undefined if
/// input is 0.
///
/// \headerfile <x86intrin.h>
///
/// \code
/// int _bit_scan_forward(int A);
/// \endcode
///
/// This intrinsic corresponds to the \c BSF instruction or the
/// \c TZCNT instruction.
///
/// \param A
/// A 32-bit integer operand.
/// \returns A 32-bit integer containing the bit number.
/// \see __bsfd
#define _bit_scan_forward(A) __bsfd((A))

/// Find the first set bit starting from the msb. Result is undefined if
/// input is 0.
///
/// \headerfile <x86intrin.h>
///
/// \code
/// int _bit_scan_reverse(int A);
/// \endcode
///
/// This intrinsic corresponds to the \c BSR instruction or the
/// \c LZCNT instruction and an \c XOR.
///
/// \param A
/// A 32-bit integer operand.
/// \returns A 32-bit integer containing the bit number.
/// \see __bsrd
#define _bit_scan_reverse(A) __bsrd((A))

#ifdef __x86_64__
Expand Down Expand Up @@ -134,13 +169,29 @@ __bsrq(long long __A) {
/// \param __A
/// A 64-bit integer operand.
/// \returns A 64-bit integer containing the swapped bytes.
/// \see _bswap64
static __inline__ long long __DEFAULT_FN_ATTRS_CONSTEXPR
__bswapq(long long __A) {
return (long long)__builtin_bswap64((unsigned long long)__A);
}

/// Swaps the bytes in the input. Converting little endian to big endian or
/// vice versa.
///
/// \headerfile <x86intrin.h>
///
/// \code
/// long long _bswap64(long long A);
/// \endcode
///
/// This intrinsic corresponds to the \c BSWAP instruction.
///
/// \param A
/// A 64-bit integer operand.
/// \returns A 64-bit integer containing the swapped bytes.
/// \see __bswapq
#define _bswap64(A) __bswapq((A))
#endif
#endif /* __x86_64__ */

/// Counts the number of bits in the source operand having a value of 1.
///
Expand All @@ -153,12 +204,29 @@ __bswapq(long long __A) {
/// An unsigned 32-bit integer operand.
/// \returns A 32-bit integer containing the number of bits with value 1 in the
/// source operand.
/// \see _popcnt32
static __inline__ int __DEFAULT_FN_ATTRS_CONSTEXPR
__popcntd(unsigned int __A)
{
return __builtin_popcount(__A);
}

/// Counts the number of bits in the source operand having a value of 1.
///
/// \headerfile <x86intrin.h>
///
/// \code
/// int _popcnt32(int A);
/// \endcode
///
/// This intrinsic corresponds to the \c POPCNT instruction or a
/// a sequence of arithmetic and logic ops to calculate it.
///
/// \param A
/// An unsigned 32-bit integer operand.
/// \returns A 32-bit integer containing the number of bits with value 1 in the
/// source operand.
/// \see __popcntd
#define _popcnt32(A) __popcntd((A))

#ifdef __x86_64__
Expand All @@ -173,12 +241,29 @@ __popcntd(unsigned int __A)
/// An unsigned 64-bit integer operand.
/// \returns A 64-bit integer containing the number of bits with value 1 in the
/// source operand.
/// \see _popcnt64
static __inline__ long long __DEFAULT_FN_ATTRS_CONSTEXPR
__popcntq(unsigned long long __A)
{
return __builtin_popcountll(__A);
}

/// Counts the number of bits in the source operand having a value of 1.
///
/// \headerfile <x86intrin.h>
///
/// \code
/// long long _popcnt64(unsigned long long A);
/// \endcode
///
/// This intrinsic corresponds to the \c POPCNT instruction or a
/// a sequence of arithmetic and logic ops to calculate it.
///
/// \param A
/// An unsigned 64-bit integer operand.
/// \returns A 64-bit integer containing the number of bits with value 1 in the
/// source operand.
/// \see __popcntq
#define _popcnt64(A) __popcntq((A))
#endif /* __x86_64__ */

Expand Down Expand Up @@ -396,6 +481,7 @@ __crc32q(unsigned long long __C, unsigned long long __D)
/// \param __A
/// The performance counter to read.
/// \returns The 64-bit value read from the performance counter.
/// \see _rdpmc
static __inline__ unsigned long long __DEFAULT_FN_ATTRS
__rdpmc(int __A) {
return __builtin_ia32_rdpmc(__A);
Expand All @@ -416,8 +502,35 @@ __rdtscp(unsigned int *__A) {
return __builtin_ia32_rdtscp(__A);
}

/// Reads the processor's time stamp counter.
///
/// \headerfile <x86intrin.h>
///
/// \code
/// unsigned long long _rdtsc();
/// \endcode
///
/// This intrinsic corresponds to the \c RDTSC instruction.
///
/// \returns The 64-bit value of the time stamp counter.
#define _rdtsc() __rdtsc()

/// Reads the specified performance monitoring counter. Refer to your
/// processor's documentation to determine which performance counters are
/// supported.
///
/// \headerfile <x86intrin.h>
///
/// \code
/// unsigned long long _rdpmc(int A);
/// \endcode
///
/// This intrinsic corresponds to the \c RDPMC instruction.
///
/// \param A
/// The performance counter to read.
/// \returns The 64-bit value read from the performance counter.
/// \see __rdpmc
#define _rdpmc(A) __rdpmc(A)

static __inline__ void __DEFAULT_FN_ATTRS
Expand Down Expand Up @@ -474,6 +587,7 @@ __rorb(unsigned char __X, int __C) {
/// \param __C
/// The number of bits to rotate the value.
/// \returns The rotated value.
/// \see _rotwl
static __inline__ unsigned short __DEFAULT_FN_ATTRS_CONSTEXPR
__rolw(unsigned short __X, int __C) {
return __builtin_rotateleft16(__X, __C);
Expand All @@ -492,6 +606,7 @@ __rolw(unsigned short __X, int __C) {
/// \param __C
/// The number of bits to rotate the value.
/// \returns The rotated value.
/// \see _rotwr
static __inline__ unsigned short __DEFAULT_FN_ATTRS_CONSTEXPR
__rorw(unsigned short __X, int __C) {
return __builtin_rotateright16(__X, __C);
Expand All @@ -510,6 +625,7 @@ __rorw(unsigned short __X, int __C) {
/// \param __C
/// The number of bits to rotate the value.
/// \returns The rotated value.
/// \see _rotl
static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
__rold(unsigned int __X, int __C) {
return __builtin_rotateleft32(__X, (unsigned int)__C);
Expand All @@ -528,6 +644,7 @@ __rold(unsigned int __X, int __C) {
/// \param __C
/// The number of bits to rotate the value.
/// \returns The rotated value.
/// \see _rotr
static __inline__ unsigned int __DEFAULT_FN_ATTRS_CONSTEXPR
__rord(unsigned int __X, int __C) {
return __builtin_rotateright32(__X, (unsigned int)__C);
Expand Down Expand Up @@ -575,18 +692,167 @@ __rorq(unsigned long long __X, int __C) {
/* These are already provided as builtins for MSVC. */
/* Select the correct function based on the size of long. */
#ifdef __LP64__
/// Rotates a 64-bit value to the left by the specified number of bits.
/// This operation is undefined if the number of bits exceeds the size of
/// the value.
///
/// \headerfile <x86intrin.h>
///
/// \code
/// unsigned long long _lrotl(unsigned long long a, int b);
/// \endcode
///
/// This intrinsic corresponds to the \c ROL instruction.
///
/// \param a
/// The unsigned 64-bit value to be rotated.
/// \param b
/// The number of bits to rotate the value.
/// \returns The rotated value.
/// \see __rolq
#define _lrotl(a,b) __rolq((a), (b))

/// Rotates a 64-bit value to the right by the specified number of bits.
/// This operation is undefined if the number of bits exceeds the size of
/// the value.
///
/// \headerfile <x86intrin.h>
///
/// \code
/// unsigned long long _lrotr(unsigned long long a, int b);
/// \endcode
///
/// This intrinsic corresponds to the \c ROR instruction.
///
/// \param a
/// The unsigned 64-bit value to be rotated.
/// \param b
/// The number of bits to rotate the value.
/// \returns The rotated value.
/// \see __rorq
#define _lrotr(a,b) __rorq((a), (b))
#else
#else // __LP64__
/// Rotates a 32-bit value to the left by the specified number of bits.
/// This operation is undefined if the number of bits exceeds the size of
/// the value.
///
/// \headerfile <x86intrin.h>
///
/// \code
/// unsigned int _lrotl(unsigned int a, int b);
/// \endcode
///
/// This intrinsic corresponds to the \c ROL instruction.
///
/// \param a
/// The unsigned 32-bit value to be rotated.
/// \param b
/// The number of bits to rotate the value.
/// \returns The rotated value.
/// \see __rold
#define _lrotl(a,b) __rold((a), (b))

/// Rotates a 32-bit value to the right by the specified number of bits.
/// This operation is undefined if the number of bits exceeds the size of
/// the value.
///
/// \headerfile <x86intrin.h>
///
/// \code
/// unsigned int _lrotr(unsigned int a, int b);
/// \endcode
///
/// This intrinsic corresponds to the \c ROR instruction.
///
/// \param a
/// The unsigned 32-bit value to be rotated.
/// \param b
/// The number of bits to rotate the value.
/// \returns The rotated value.
/// \see __rord
#define _lrotr(a,b) __rord((a), (b))
#endif
#endif // __LP64__

/// Rotates a 32-bit value to the left by the specified number of bits.
/// This operation is undefined if the number of bits exceeds the size of
/// the value.
///
/// \headerfile <x86intrin.h>
///
/// \code
/// unsigned int _rotl(unsigned int a, int b);
/// \endcode
///
/// This intrinsic corresponds to the \c ROL instruction.
///
/// \param a
/// The unsigned 32-bit value to be rotated.
/// \param b
/// The number of bits to rotate the value.
/// \returns The rotated value.
/// \see __rold
#define _rotl(a,b) __rold((a), (b))

/// Rotates a 32-bit value to the right by the specified number of bits.
/// This operation is undefined if the number of bits exceeds the size of
/// the value.
///
/// \headerfile <x86intrin.h>
///
/// \code
/// unsigned int _rotr(unsigned int a, int b);
/// \endcode
///
/// This intrinsic corresponds to the \c ROR instruction.
///
/// \param a
/// The unsigned 32-bit value to be rotated.
/// \param b
/// The number of bits to rotate the value.
/// \returns The rotated value.
/// \see __rord
#define _rotr(a,b) __rord((a), (b))
#endif // _MSC_VER

/* These are not builtins so need to be provided in all modes. */
/// Rotates a 16-bit value to the left by the specified number of bits.
/// This operation is undefined if the number of bits exceeds the size of
/// the value.
///
/// \headerfile <x86intrin.h>
///
/// \code
/// unsigned short _rotwl(unsigned short a, int b);
/// \endcode
///
/// This intrinsic corresponds to the \c ROL instruction.
///
/// \param a
/// The unsigned 16-bit value to be rotated.
/// \param b
/// The number of bits to rotate the value.
/// \returns The rotated value.
/// \see __rolw
#define _rotwl(a,b) __rolw((a), (b))

/// Rotates a 16-bit value to the right by the specified number of bits.
/// This operation is undefined if the number of bits exceeds the size of
/// the value.
///
/// \headerfile <x86intrin.h>
///
/// \code
/// unsigned short _rotwr(unsigned short a, int b);
/// \endcode
///
/// This intrinsic corresponds to the \c ROR instruction.
///
/// \param a
/// The unsigned 16-bit value to be rotated.
/// \param b
/// The number of bits to rotate the value.
/// \returns The rotated value.
/// \see __rorw
#define _rotwr(a,b) __rorw((a), (b))

#undef __DEFAULT_FN_ATTRS
Expand Down

0 comments on commit d9cb37c

Please sign in to comment.