Blame x86_64-microarchitectures.patch

8b86e1
From 282f75e33f93e46854345598f576d052d5cfe390 Mon Sep 17 00:00:00 2001
8b86e1
From: Fabian Vogt <fvogt@suse.de>
8b86e1
Date: Thu, 8 Dec 2022 12:50:12 +0100
8b86e1
Subject: [PATCH] Add x86-64 architecture levels (v2-v4) as architectures
8b86e1
8b86e1
The x86_64 SysV psABI defines four levels of x86_64 with certain CPU features
8b86e1
required for each level. Those definitions are meant to be generically useful
8b86e1
and recognized as such by glibc and gcc as well.
8b86e1
8b86e1
For backward-compatibility and to avoid surprises, default to building x86_64
8b86e1
even on v2+ capable machines.
8b86e1
---
8b86e1
 installplatform |  2 +-
8b86e1
 lib/rpmrc.c     | 75 +++++++++++++++++++++++++++++++++++++++++++++++++
8b86e1
 macros.in       |  4 +++
8b86e1
 rpmrc.in        | 18 ++++++++++++
8b86e1
 4 files changed, 98 insertions(+), 1 deletion(-)
8b86e1
8b86e1
--- installplatform
8b86e1
+++ installplatform
8b86e1
@@ -78,7 +78,7 @@ for ARCH in noarch `grep ^arch_canon $RP
8b86e1
 	CANONARCH=i386
8b86e1
 	CANONCOLOR=0
8b86e1
 	;;
8b86e1
-    x86_64|amd64|ia32e)
8b86e1
+    x86_64*|amd64|ia32e)
8b86e1
 	ISANAME=x86
8b86e1
 	ISABITS=64
8b86e1
 	CANONARCH=x86_64
8b86e1
--- lib/rpmrc.c
8b86e1
+++ lib/rpmrc.c
8b86e1
@@ -735,6 +735,71 @@ exit:
8b86e1
     return rc;
8b86e1
 }
8b86e1
 
8b86e1
+#	if defined(__linux__) && defined(__x86_64__)
8b86e1
+static inline void cpuid(uint32_t op, uint32_t op2, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
8b86e1
+{
8b86e1
+    asm volatile (
8b86e1
+	"cpuid\n"
8b86e1
+    : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
8b86e1
+    : "a" (op), "c" (op2));
8b86e1
+}
8b86e1
+
8b86e1
+/* From gcc's gcc/config/i386/cpuid.h */
8b86e1
+/* Features (%eax == 1) */
8b86e1
+/* %ecx */
8b86e1
+#define bit_SSE3	(1 << 0)
8b86e1
+#define bit_LZCNT	(1 << 5)
8b86e1
+#define bit_SSSE3	(1 << 9)
8b86e1
+#define bit_FMA		(1 << 12)
8b86e1
+#define bit_CMPXCHG16B	(1 << 13)
8b86e1
+#define bit_SSE4_1	(1 << 19)
8b86e1
+#define bit_SSE4_2	(1 << 20)
8b86e1
+#define bit_MOVBE	(1 << 22)
8b86e1
+#define bit_POPCNT	(1 << 23)
8b86e1
+#define bit_OSXSAVE	(1 << 27)
8b86e1
+#define bit_AVX		(1 << 28)
8b86e1
+#define bit_F16C	(1 << 29)
8b86e1
+
8b86e1
+/* Extended Features (%eax == 0x80000001) */
8b86e1
+/* %ecx */
8b86e1
+#define bit_LAHF_LM	(1 << 0)
8b86e1
+
8b86e1
+/* Extended Features (%eax == 7) */
8b86e1
+/* %ebx */
8b86e1
+#define bit_BMI		(1 << 3)
8b86e1
+#define bit_AVX2	(1 << 5)
8b86e1
+#define bit_BMI2	(1 << 8)
8b86e1
+#define bit_AVX512F	(1 << 16)
8b86e1
+#define bit_AVX512DQ	(1 << 17)
8b86e1
+#define bit_AVX512CD	(1 << 28)
8b86e1
+#define bit_AVX512BW	(1 << 30)
8b86e1
+#define bit_AVX512VL	(1u << 31)
8b86e1
+
8b86e1
+static int get_x86_64_level(void)
8b86e1
+{
8b86e1
+    int level = 1;
8b86e1
+
8b86e1
+    unsigned int op_1_ecx = 0, op_80000001_ecx = 0, op_7_ebx = 0, unused;
8b86e1
+    cpuid(1, 0, &unused, &unused, &op_1_ecx, &unused);
8b86e1
+    cpuid(0x80000001, 0, &unused, &unused, &op_80000001_ecx, &unused);
8b86e1
+    cpuid(7, 0, &unused, &op_7_ebx, &unused, &unused);
8b86e1
+
8b86e1
+    const unsigned int op_1_ecx_lv2 = bit_SSE3 | bit_SSSE3 | bit_CMPXCHG16B | bit_SSE4_1 | bit_SSE4_2 | bit_POPCNT;
8b86e1
+    if ((op_1_ecx & op_1_ecx_lv2) == op_1_ecx_lv2 && (op_80000001_ecx & bit_LAHF_LM))
8b86e1
+	level = 2;
8b86e1
+
8b86e1
+    const unsigned int op_1_ecx_lv3 = bit_LZCNT | bit_FMA | bit_MOVBE | bit_OSXSAVE | bit_AVX | bit_F16C;
8b86e1
+    const unsigned int op_7_ebx_lv3 = bit_BMI | bit_AVX2 | bit_BMI2;
8b86e1
+    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)
8b86e1
+        level = 3;
8b86e1
+
8b86e1
+    const unsigned int op_7_ebx_lv4 = bit_AVX512F | bit_AVX512DQ | bit_AVX512CD | bit_AVX512BW | bit_AVX512VL;
8b86e1
+    if (level == 3 && (op_7_ebx & op_7_ebx_lv4) == op_7_ebx_lv4)
8b86e1
+        level = 4;
8b86e1
+
8b86e1
+    return level;
8b86e1
+}
8b86e1
+#	endif
8b86e1
 
8b86e1
 #	if defined(__linux__) && defined(__i386__)
8b86e1
 #include <setjmp.h>
8b86e1
@@ -1287,6 +1352,16 @@ static void defaultMachine(rpmrcCtx ctx,
8b86e1
 	}
8b86e1
 #	endif
8b86e1
 
8b86e1
+# if defined(__linux__) && defined(__x86_64__)
8b86e1
+	{
8b86e1
+	    int x86_64_level = get_x86_64_level();
8b86e1
+	    if (x86_64_level > 1) {
8b86e1
+	        strcpy(un.machine, "x86_64_vX");
8b86e1
+	        un.machine[8] = '0' + x86_64_level;
8b86e1
+	    }
8b86e1
+	}
8b86e1
+#endif
8b86e1
+
8b86e1
 	/* the uname() result goes through the arch_canon table */
8b86e1
 	canon = lookupInCanonTable(un.machine,
8b86e1
 			   ctx->tables[RPM_MACHTABLE_INSTARCH].canons,
8b86e1
--- macros.in
8b86e1
+++ macros.in
8b86e1
@@ -1064,6 +1064,10 @@ package or when debugging this package.\
8b86e1
 %ix86   i386 i486 i586 i686 pentium3 pentium4 athlon geode
8b86e1
 
8b86e1
 #------------------------------------------------------------------------------
8b86e1
+# arch macro for all supported x86_64 processors
8b86e1
+%x86_64	x86_64 x86_64_v2 x86_64_v3 x86_64_v4 amd64 em64t
8b86e1
+
8b86e1
+#------------------------------------------------------------------------------
8b86e1
 # arch macro for all supported 32-bit ARM processors
8b86e1
 %arm32	armv3l armv4b armv4l armv4tl armv5b armv5l armv5teb armv5tel armv5tejl armv6l armv6hl armv7l armv7hl armv7hnl armv8l armv8hl armv8hnl armv8hcnl
8b86e1
 
8b86e1
--- rpmrc.in
8b86e1
+++ rpmrc.in
8b86e1
@@ -22,6 +22,10 @@ optflags: athlon -O2 -g -m32 -march=athl
8b86e1
 optflags: geode -Os -g -m32 -march=geode
8b86e1
 optflags: ia64 -O2 -g -fmessage-length=0 -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables
8b86e1
 optflags: x86_64 -O2 -g -m64 -fmessage-length=0 -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables
8b86e1
+optflags: x86_64_v2 -O2 -g -march=x86-64-v2 -m64 -fmessage-length=0 -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables
8b86e1
+optflags: x86_64_v3 -O2 -g -march=x86-64-v3 -m64 -fmessage-length=0 -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables
8b86e1
+optflags: x86_64_v4 -O2 -g -march=x86-64-v4 -m64 -fmessage-length=0 -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables
8b86e1
+
8b86e1
 optflags: amd64 -O2 -g
8b86e1
 optflags: ia32e -O2 -g
8b86e1
 
8b86e1
@@ -148,6 +152,9 @@ archcolor: s390x 2
8b86e1
 archcolor: ia64 2
8b86e1
 
8b86e1
 archcolor: x86_64 2
8b86e1
+archcolor: x86_64_v2 2
8b86e1
+archcolor: x86_64_v3 2
8b86e1
+archcolor: x86_64_v4 2
8b86e1
 
8b86e1
 archcolor: sh3 1
8b86e1
 archcolor: sh4 1
8b86e1
@@ -168,6 +175,9 @@ arch_canon:	i586:	i586	1
8b86e1
 arch_canon:	i486:	i486	1
8b86e1
 arch_canon:	i386:	i386	1
8b86e1
 arch_canon:	x86_64:	x86_64	1
8b86e1
+arch_canon:	x86_64_v2:	x86_64_v2	1
8b86e1
+arch_canon:	x86_64_v3:	x86_64_v3	1
8b86e1
+arch_canon:	x86_64_v4:	x86_64_v4	1
8b86e1
 arch_canon:	amd64:	amd64	1
8b86e1
 arch_canon:	ia32e:	ia32e	1
8b86e1
 arch_canon:	em64t:	em64t	1
8b86e1
@@ -378,6 +388,9 @@ buildarchtranslate: s390x: s390x
8b86e1
 buildarchtranslate: ia64: ia64
8b86e1
 
8b86e1
 buildarchtranslate: x86_64: x86_64
8b86e1
+buildarchtranslate: x86_64_v2: x86_64
8b86e1
+buildarchtranslate: x86_64_v3: x86_64
8b86e1
+buildarchtranslate: x86_64_v4: x86_64
8b86e1
 buildarchtranslate: amd64: x86_64
8b86e1
 buildarchtranslate: ia32e: x86_64
8b86e1
 
8b86e1
@@ -504,6 +517,9 @@ arch_compat: ia64: i686 noarch
8b86e1
 arch_compat: x86_64: amd64 em64t athlon noarch
8b86e1
 arch_compat: amd64: x86_64 em64t athlon noarch
8b86e1
 arch_compat: ia32e: x86_64 em64t athlon noarch
8b86e1
+arch_compat: x86_64_v2: x86_64 amd64 em64t athlon noarch
8b86e1
+arch_compat: x86_64_v3: x86_64_v2 x86_64 amd64 em64t athlon noarch
8b86e1
+arch_compat: x86_64_v4: x86_64_v3 x86_64_v2 x86_64 amd64 em64t athlon noarch
8b86e1
 
8b86e1
 arch_compat: sh3: noarch
8b86e1
 arch_compat: sh4: noarch
8b86e1
@@ -640,6 +656,9 @@ buildarch_compat: s390x: noarch
8b86e1
 
8b86e1
 buildarch_compat: ia64: noarch
8b86e1
 
8b86e1
+buildarch_compat: x86_64_v4: x86_64_v3
8b86e1
+buildarch_compat: x86_64_v3: x86_64_v2
8b86e1
+buildarch_compat: x86_64_v2: x86_64
8b86e1
 buildarch_compat: x86_64: noarch
8b86e1
 buildarch_compat: amd64: x86_64
8b86e1
 buildarch_compat: ia32e: x86_64