Blob Blame History Raw
From 6b7c58474df3b416b1acb8b58e73b7edf73b8c43 Mon Sep 17 00:00:00 2001
From: Fabian Vogt <fvogt@suse.de>
Date: Mon, 6 Mar 2023 17:50:42 +0100
Subject: [PATCH] The bit for LZCNT is in CPUID 0x80000001, not 1

The GCC headers put bit_LZCNT into the list for CPUID 1 %ecx values, but that
corresponds to VMX. LZCNT is actually advertised in CPUID 0x80000001 %ecx,
which is also referred to as "ABM" by AMD and some other places.
---
 lib/rpmrc.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git lib/rpmrc.c lib/rpmrc.c
index fc2ed5fe2..66ce947ae 100644
--- lib/rpmrc.c
+++ lib/rpmrc.c
@@ -747,7 +747,6 @@ static inline void cpuid(uint32_t op, uint32_t op2, uint32_t *eax, uint32_t *ebx
 /* Features (%eax == 1) */
 /* %ecx */
 #define bit_SSE3	(1 << 0)
-#define bit_LZCNT	(1 << 5)
 #define bit_SSSE3	(1 << 9)
 #define bit_FMA		(1 << 12)
 #define bit_CMPXCHG16B	(1 << 13)
@@ -762,6 +761,7 @@ static inline void cpuid(uint32_t op, uint32_t op2, uint32_t *eax, uint32_t *ebx
 /* Extended Features (%eax == 0x80000001) */
 /* %ecx */
 #define bit_LAHF_LM	(1 << 0)
+#define bit_LZCNT	(1 << 5)
 
 /* Extended Features (%eax == 7) */
 /* %ebx */
@@ -787,9 +787,10 @@ static int get_x86_64_level(void)
     if ((op_1_ecx & op_1_ecx_lv2) == op_1_ecx_lv2 && (op_80000001_ecx & bit_LAHF_LM))
 	level = 2;
 
-    const unsigned int op_1_ecx_lv3 = bit_LZCNT | bit_FMA | bit_MOVBE | bit_OSXSAVE | bit_AVX | bit_F16C;
+    const unsigned int op_1_ecx_lv3 = bit_FMA | bit_MOVBE | bit_OSXSAVE | bit_AVX | bit_F16C;
     const unsigned int op_7_ebx_lv3 = bit_BMI | bit_AVX2 | bit_BMI2;
-    if (level == 2 && (op_1_ecx & op_1_ecx_lv3) == op_1_ecx_lv3 && (op_7_ebx & op_7_ebx_lv3) == op_7_ebx_lv3)
+    if (level == 2 && (op_1_ecx & op_1_ecx_lv3) == op_1_ecx_lv3 && (op_7_ebx & op_7_ebx_lv3) == op_7_ebx_lv3
+        && (op_80000001_ecx & bit_LZCNT))
         level = 3;
 
     const unsigned int op_7_ebx_lv4 = bit_AVX512F | bit_AVX512DQ | bit_AVX512CD | bit_AVX512BW | bit_AVX512VL;
-- 
2.39.2