Skip to content

[Headers][X86] Add macro descriptions to ia32intrin.h #78613

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 22, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the old code is correct. The __rdtsc is a built in, and we have documented in Intrinsic Guide.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I will revise the description, and make a note to add __rdtsc to our guide. (We have __builtin_readcyclecounter but not that one.)


/// 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