[clang] [Headers][X86] Add macro descriptions to ia32intrin.h (PR #78613)

Paul T Robinson via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 19 07:54:11 PST 2024


https://github.com/pogo59 updated https://github.com/llvm/llvm-project/pull/78613

>From e4c9272ee9cbb918347a23d2dce14c9c12765009 Mon Sep 17 00:00:00 2001
From: Paul Robinson <paul.robinson at sony.com>
Date: Thu, 18 Jan 2024 10:50:21 -0800
Subject: [PATCH 1/3] [Headers][X86] Add macro descriptions to ia32intrin.h

These are largely copy-pasted from the corresponding function descriptions.
Updated _rdtsc definition because it was just plain wrong.
---
 clang/lib/Headers/ia32intrin.h | 253 ++++++++++++++++++++++++++++++++-
 1 file changed, 249 insertions(+), 4 deletions(-)

diff --git a/clang/lib/Headers/ia32intrin.h b/clang/lib/Headers/ia32intrin.h
index 7d5fede61ce8590..5d8d02ea14200fa 100644
--- a/clang/lib/Headers/ia32intrin.h
+++ b/clang/lib/Headers/ia32intrin.h
@@ -88,7 +88,38 @@ _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.
 #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.
 #define _bit_scan_reverse(A) __bsrd((A))
 
 #ifdef __x86_64__
@@ -139,8 +170,22 @@ __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.
 #define _bswap64(A) __bswapq((A))
-#endif
+#endif /* __x86_64__ */
 
 /// Counts the number of bits in the source operand having a value of 1.
 ///
@@ -159,6 +204,21 @@ __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.
 #define _popcnt32(A) __popcntd((A))
 
 #ifdef __x86_64__
@@ -179,6 +239,21 @@ __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.
 #define _popcnt64(A) __popcntq((A))
 #endif /* __x86_64__ */
 
@@ -416,8 +491,37 @@ __rdtscp(unsigned int *__A) {
   return __builtin_ia32_rdtscp(__A);
 }
 
-#define _rdtsc() __rdtsc()
+/// Reads the processor's time stamp counter and the \c IA32_TSC_AUX MSR
+///    \c (0xc0000103).
+///
+/// \headerfile <x86intrin.h>
+///
+/// \code
+/// unsigned long long _rdtsc(unsigned int *A);
+/// \endcode
+///
+/// This intrinsic corresponds to the \c RDTSCP instruction.
+///
+/// \param A
+///    Address of where to store the 32-bit \c IA32_TSC_AUX value.
+/// \returns The 64-bit value of the time stamp counter.
+#define _rdtsc(A) __rdtscp(A)
 
+/// 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.
 #define _rdpmc(A) __rdpmc(A)
 
 static __inline__ void __DEFAULT_FN_ATTRS
@@ -575,18 +679,159 @@ __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.
 #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.
 #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.
 #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.
 #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.
 #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.
 #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.
 #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.
 #define _rotwr(a,b) __rorw((a), (b))
 
 #undef __DEFAULT_FN_ATTRS

>From ddb4e3d173df4637895f0e0c648f59a2f620c440 Mon Sep 17 00:00:00 2001
From: Paul Robinson <paul.robinson at sony.com>
Date: Thu, 18 Jan 2024 14:06:11 -0800
Subject: [PATCH 2/3] Add cross-references

---
 clang/lib/Headers/ia32intrin.h | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/clang/lib/Headers/ia32intrin.h b/clang/lib/Headers/ia32intrin.h
index 5d8d02ea14200fa..fadbff031922f2a 100644
--- a/clang/lib/Headers/ia32intrin.h
+++ b/clang/lib/Headers/ia32intrin.h
@@ -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);
@@ -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);
@@ -103,6 +105,7 @@ _bswap(int __A) {
 /// \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
@@ -120,6 +123,7 @@ _bswap(int __A) {
 /// \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__
@@ -165,6 +169,7 @@ __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);
@@ -184,6 +189,7 @@ __bswapq(long long __A) {
 /// \param A
 ///    A 64-bit integer operand.
 /// \returns A 64-bit integer containing the swapped bytes.
+/// \see __bswapq
 #define _bswap64(A) __bswapq((A))
 #endif /* __x86_64__ */
 
@@ -198,6 +204,7 @@ __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)
 {
@@ -219,6 +226,7 @@ __popcntd(unsigned int __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__
@@ -233,6 +241,7 @@ __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)
 {
@@ -254,6 +263,7 @@ __popcntq(unsigned long long __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__ */
 
@@ -471,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);
@@ -486,6 +497,7 @@ __rdpmc(int __A) {
 /// \param __A
 ///    Address of where to store the 32-bit \c IA32_TSC_AUX value.
 /// \returns The 64-bit value of the time stamp counter.
+/// \see _rdtsc
 static __inline__ unsigned long long __DEFAULT_FN_ATTRS
 __rdtscp(unsigned int *__A) {
   return __builtin_ia32_rdtscp(__A);
@@ -505,6 +517,7 @@ __rdtscp(unsigned int *__A) {
 /// \param A
 ///    Address of where to store the 32-bit \c IA32_TSC_AUX value.
 /// \returns The 64-bit value of the time stamp counter.
+/// \see __rdtscp
 #define _rdtsc(A) __rdtscp(A)
 
 /// Reads the specified performance monitoring counter. Refer to your
@@ -522,6 +535,7 @@ __rdtscp(unsigned int *__A) {
 /// \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
@@ -578,6 +592,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);
@@ -596,6 +611,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);
@@ -614,6 +630,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);
@@ -632,6 +649,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);
@@ -696,6 +714,7 @@ __rorq(unsigned long long __X, int __C) {
 /// \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.
@@ -715,6 +734,7 @@ __rorq(unsigned long long __X, int __C) {
 /// \param b
 ///    The number of bits to rotate the value.
 /// \returns The rotated value.
+/// \see __rorq
 #define _lrotr(a,b) __rorq((a), (b))
 #else // __LP64__
 /// Rotates a 32-bit value to the left by the specified number of bits.
@@ -734,6 +754,7 @@ __rorq(unsigned long long __X, int __C) {
 /// \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.
@@ -753,6 +774,7 @@ __rorq(unsigned long long __X, int __C) {
 /// \param b
 ///    The number of bits to rotate the value.
 /// \returns The rotated value.
+/// \see __rord
 #define _lrotr(a,b) __rord((a), (b))
 #endif // __LP64__
 
@@ -773,6 +795,7 @@ __rorq(unsigned long long __X, int __C) {
 /// \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.
@@ -792,6 +815,7 @@ __rorq(unsigned long long __X, int __C) {
 /// \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
 
@@ -813,6 +837,7 @@ __rorq(unsigned long long __X, int __C) {
 /// \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.
@@ -832,6 +857,7 @@ __rorq(unsigned long long __X, int __C) {
 /// \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

>From d2d52369ed5c7bfe0fb03ab329e0c702ab342cae Mon Sep 17 00:00:00 2001
From: Paul Robinson <paul.robinson at sony.com>
Date: Fri, 19 Jan 2024 07:53:58 -0800
Subject: [PATCH 3/3] Revert change to _rdtsc macro and correct description

---
 clang/lib/Headers/ia32intrin.h | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/clang/lib/Headers/ia32intrin.h b/clang/lib/Headers/ia32intrin.h
index fadbff031922f2a..1b979770e196233 100644
--- a/clang/lib/Headers/ia32intrin.h
+++ b/clang/lib/Headers/ia32intrin.h
@@ -497,28 +497,23 @@ __rdpmc(int __A) {
 /// \param __A
 ///    Address of where to store the 32-bit \c IA32_TSC_AUX value.
 /// \returns The 64-bit value of the time stamp counter.
-/// \see _rdtsc
 static __inline__ unsigned long long __DEFAULT_FN_ATTRS
 __rdtscp(unsigned int *__A) {
   return __builtin_ia32_rdtscp(__A);
 }
 
-/// Reads the processor's time stamp counter and the \c IA32_TSC_AUX MSR
-///    \c (0xc0000103).
+/// Reads the processor's time stamp counter.
 ///
 /// \headerfile <x86intrin.h>
 ///
 /// \code
-/// unsigned long long _rdtsc(unsigned int *A);
+/// unsigned long long _rdtsc();
 /// \endcode
 ///
-/// This intrinsic corresponds to the \c RDTSCP instruction.
+/// This intrinsic corresponds to the \c RDTSC instruction.
 ///
-/// \param A
-///    Address of where to store the 32-bit \c IA32_TSC_AUX value.
 /// \returns The 64-bit value of the time stamp counter.
-/// \see __rdtscp
-#define _rdtsc(A) __rdtscp(A)
+#define _rdtsc() __rdtsc()
 
 /// Reads the specified performance monitoring counter. Refer to your
 ///    processor's documentation to determine which performance counters are



More information about the cfe-commits mailing list