diff options
author | Manjunath Matti <mmatti@linux.ibm.com> | 2024-03-19 15:29:48 -0500 |
---|---|---|
committer | Peter Bergner <bergner@linux.ibm.com> | 2024-03-19 17:19:27 -0500 |
commit | 3ab9b88e2ac91062b6d493fe32bd101a55006c6a (patch) | |
tree | a13cf4a7a73bb6f77748d2bfefedce381591be56 /sysdeps/powerpc | |
parent | 3d53d18fc71c5d9ef4773b8bce04d54b80181926 (diff) | |
download | glibc-3ab9b88e2ac91062b6d493fe32bd101a55006c6a.tar.gz glibc-3ab9b88e2ac91062b6d493fe32bd101a55006c6a.tar.xz glibc-3ab9b88e2ac91062b6d493fe32bd101a55006c6a.zip |
powerpc: Add HWCAP3/HWCAP4 data to TCB for Power Architecture.
This patch adds a new feature for powerpc. In order to get faster access to the HWCAP3/HWCAP4 masks, similar to HWCAP/HWCAP2 (i.e. for implementing __builtin_cpu_supports() in GCC) without the overhead of reading them from the auxiliary vector, we now reserve space for them in the TCB. This is an ABI change for GLIBC 2.39. Suggested-by: Peter Bergner <bergner@linux.ibm.com> Reviewed-by: Peter Bergner <bergner@linux.ibm.com>
Diffstat (limited to 'sysdeps/powerpc')
-rw-r--r-- | sysdeps/powerpc/dl-procinfo.c | 6 | ||||
-rw-r--r-- | sysdeps/powerpc/dl-procinfo.h | 52 | ||||
-rw-r--r-- | sysdeps/powerpc/hwcapinfo.c | 11 |
3 files changed, 50 insertions, 19 deletions
diff --git a/sysdeps/powerpc/dl-procinfo.c b/sysdeps/powerpc/dl-procinfo.c index a76bb6e5b0..8cf00aa7e3 100644 --- a/sysdeps/powerpc/dl-procinfo.c +++ b/sysdeps/powerpc/dl-procinfo.c @@ -38,6 +38,10 @@ needed. */ +/* The total number of available bits (including those prior to + _DL_HWCAP_FIRST). Some of these bits might not be used. */ +#define _DL_HWCAP_COUNT 128 + #ifndef PROCINFO_CLASS # define PROCINFO_CLASS #endif @@ -61,7 +65,7 @@ PROCINFO_CLASS struct cpu_features _dl_powerpc_cpu_features #if !defined PROCINFO_DECL && defined SHARED ._dl_powerpc_cap_flags #else -PROCINFO_CLASS const char _dl_powerpc_cap_flags[64][15] +PROCINFO_CLASS const char _dl_powerpc_cap_flags[_DL_HWCAP_COUNT][15] #endif #ifndef PROCINFO_DECL = { diff --git a/sysdeps/powerpc/dl-procinfo.h b/sysdeps/powerpc/dl-procinfo.h index 68f4241095..f8cb343877 100644 --- a/sysdeps/powerpc/dl-procinfo.h +++ b/sysdeps/powerpc/dl-procinfo.h @@ -22,16 +22,17 @@ #include <ldsodefs.h> #include <sysdep.h> /* This defines the PPC_FEATURE[2]_* macros. */ -/* The total number of available bits (including those prior to - _DL_HWCAP_FIRST). Some of these bits might not be used. */ -#define _DL_HWCAP_COUNT 64 +/* Feature masks are all 32-bits in size. */ +#define _DL_HWCAP_SIZE 32 -/* Features started at bit 31 and decremented as new features were added. */ -#define _DL_HWCAP_LAST 31 +/* AT_HWCAP2 feature strings follow the AT_HWCAP feature strings. */ +#define _DL_HWCAP2_OFFSET _DL_HWCAP_SIZE -/* AT_HWCAP2 features started at bit 31 and decremented as new features were - added. HWCAP2 feature bits start at bit 0. */ -#define _DL_HWCAP2_LAST 31 +/* AT_HWCAP3 feature strings follow the AT_HWCAP2 feature strings. */ +#define _DL_HWCAP3_OFFSET (_DL_HWCAP2_OFFSET + _DL_HWCAP_SIZE) + +/* AT_HWCAP4 feature strings follow the AT_HWCAP3 feature strings. */ +#define _DL_HWCAP4_OFFSET (_DL_HWCAP3_OFFSET + _DL_HWCAP_SIZE) /* These bits influence library search. */ #define HWCAP_IMPORTANT (PPC_FEATURE_HAS_ALTIVEC \ @@ -187,21 +188,42 @@ _dl_procinfo (unsigned int type, unsigned long int word) case AT_HWCAP: _dl_printf ("AT_HWCAP: "); - for (int i = 0; i <= _DL_HWCAP_LAST; ++i) + for (int i = 0; i < _DL_HWCAP_SIZE; ++i) if (word & (1 << i)) _dl_printf (" %s", _dl_hwcap_string (i)); break; case AT_HWCAP2: { - unsigned int offset = _DL_HWCAP_LAST + 1; _dl_printf ("AT_HWCAP2: "); - /* We have to go through them all because the kernel added the - AT_HWCAP2 features starting with the high bits. */ - for (int i = 0; i <= _DL_HWCAP2_LAST; ++i) - if (word & (1 << i)) - _dl_printf (" %s", _dl_hwcap_string (offset + i)); + /* We have to go through them all because the kernel added the + AT_HWCAP2 features starting with the high bits. */ + for (int i = 0; i < _DL_HWCAP_SIZE; ++i) + if (word & (1 << i)) + _dl_printf (" %s", _dl_hwcap_string (_DL_HWCAP2_OFFSET + i)); + break; + } + case AT_HWCAP3: + { + _dl_printf ("AT_HWCAP3: "); + + /* We have to go through them all because the kernel added the + AT_HWCAP3 features starting with the high bits. */ + for (int i = 0; i < _DL_HWCAP_SIZE; ++i) + if (word & (1 << i)) + _dl_printf (" %s", _dl_hwcap_string (_DL_HWCAP3_OFFSET + i)); + break; + } + case AT_HWCAP4: + { + _dl_printf ("AT_HWCAP4: "); + + /* We have to go through them all because the kernel added the + AT_HWCAP4 features starting with the high bits. */ + for (int i = 0; i <= _DL_HWCAP_SIZE; ++i) + if (word & (1 << i)) + _dl_printf (" %s", _dl_hwcap_string (_DL_HWCAP4_OFFSET + i)); break; } case AT_L1I_CACHEGEOMETRY: diff --git a/sysdeps/powerpc/hwcapinfo.c b/sysdeps/powerpc/hwcapinfo.c index 76344f285a..f6fede15a7 100644 --- a/sysdeps/powerpc/hwcapinfo.c +++ b/sysdeps/powerpc/hwcapinfo.c @@ -31,7 +31,7 @@ void __tcb_parse_hwcap_and_convert_at_platform (void) { - uint64_t h1, h2; + uint64_t h1, h2, h3, h4; /* Read AT_PLATFORM string from auxv and convert it to a number. */ __tcb.at_platform = _dl_string_platform (GLRO (dl_platform)); @@ -39,6 +39,8 @@ __tcb_parse_hwcap_and_convert_at_platform (void) /* Read HWCAP and HWCAP2 from auxv. */ h1 = GLRO (dl_hwcap); h2 = GLRO (dl_hwcap2); + h3 = GLRO (dl_hwcap3); + h4 = GLRO (dl_hwcap4); /* hwcap contains only the latest supported ISA, the code checks which is and fills the previous supported ones. */ @@ -64,13 +66,16 @@ __tcb_parse_hwcap_and_convert_at_platform (void) else if (h1 & PPC_FEATURE_POWER5) h1 |= PPC_FEATURE_POWER4; - uint64_t array_hwcaps[] = { h1, h2 }; + uint64_t array_hwcaps[] = { h1, h2, h3, h4 }; init_cpu_features (&GLRO(dl_powerpc_cpu_features), array_hwcaps); /* Consolidate both HWCAP and HWCAP2 into a single doubleword so that we can read both in a single load later. */ __tcb.hwcap = (h1 << 32) | (h2 & 0xffffffff); - __tcb.hwcap_extn = 0x0; + + /* Consolidate both HWCAP3 and HWCAP4 into a single doubleword so that + we can read both in a single load later. */ + __tcb.hwcap_extn = (h3 << 32) | (h4 & 0xffffffff); } #if IS_IN (rtld) |