[PATCH] Allow setting CpuVRex bit in .arch directive

Jakub Jelinek jakub@redhat.com
Sat May 21 16:54:00 GMT 2016


Hi!

I've tried today to check for the various AVX512* ISA issues in GCC
using assembly .arch support.  Seems by default all flags (but l10m/k10m)
are set, but if I want to allow all insns but say AVX512DQ ISA instructions
or something similar, there is no way to do it - there is no way except
for explicit no* flags to remove ISA bits from the default, so one has to
set some CPU and then add all the ISA flags one wants.  Seems most of them
can be added, except for one very important one - the CpuVRex bit.

Here is a patch to add support for .arch .vrex to set that, another option
might be to set CpuVRex whenever CpuAVX512F is set in 64-bit mode.
Any preferences?

Attached is then the hack I've been using on the GCC side, plus another hack
to try to use XMM16+ regs more often.

2016-05-21  Jakub Jelinek  <jakub@redhat.com>

	* config/tc-i386.c (cpu_arch): Add .vrex entry.

	* i386-gen.c (cpu_flag_init): Add CPU_VREX_FLAGS.
	* i386-init.h: Regenerated.

diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 8a4d987..212796a 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -963,6 +963,8 @@ static const arch_entry cpu_arch[] =
     CPU_OSPKE_FLAGS, 0, 0 },
   { STRING_COMMA_LEN (".rdpid"), PROCESSOR_UNKNOWN,
     CPU_RDPID_FLAGS, 0, 0 },
+  { STRING_COMMA_LEN (".vrex"), PROCESSOR_UNKNOWN,
+    CPU_VREX_FLAGS, 0, 0 }
 };
 
 #ifdef I386COFF
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index 5b997f9..8042bee 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -258,7 +258,9 @@ static initializer cpu_flag_init[] =
   { "CPU_OSPKE_FLAGS",
     "CpuOSPKE" },
   { "CPU_RDPID_FLAGS",
-    "CpuRDPID" }
+    "CpuRDPID" },
+  { "CPU_VREX_FLAGS",
+    "CpuVRex" }
 };
 
 static initializer operand_type_init[] =
diff --git a/opcodes/i386-init.h b/opcodes/i386-init.h
index de68c22..f5d6c64 100644
--- a/opcodes/i386-init.h
+++ b/opcodes/i386-init.h
@@ -781,6 +781,13 @@
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
       0, 0, 0, 0, 1, 0, 0, 0, 0, 0 } }
 
+#define CPU_VREX_FLAGS \
+  { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, \
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
+
 
 #define OPERAND_TYPE_NONE \
   { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \

	Jakub
-------------- next part --------------
--- gcc/config/i386/i386.c.jj	2016-05-20 20:48:23.000000000 +0200
+++ gcc/config/i386/i386.c	2016-05-21 16:10:39.689599317 +0200
@@ -7910,6 +7910,8 @@ ix86_function_ms_hook_prologue (const_tr
   return false;
 }
 
+static int prev_avx512 = -1;
+
 /* Write the extra assembler code needed to declare a function properly.  */
 
 void
@@ -7918,6 +7920,59 @@ ix86_asm_output_function_label (FILE *as
 {
   bool is_ms_hook = ix86_function_ms_hook_prologue (decl);
 
+  int cur_avx512 = ((TARGET_AVX512F ? 1 : 0)
+		    | (TARGET_AVX512PF ? 2 : 0)
+		    | (TARGET_AVX512ER ? 4 : 0)
+		    | (TARGET_AVX512CD ? 8 : 0)
+		    | (TARGET_AVX512DQ ? 16 : 0)
+		    | (TARGET_AVX512BW ? 32 : 0)
+		    | (TARGET_AVX512VL ? 64 : 0)
+		    | (TARGET_AVX512VBMI ? 128 : 0)
+		    | (TARGET_AVX512IFMA ? 256 : 0));
+  if (cur_avx512 != prev_avx512)
+    {
+      fprintf (asm_out_file,
+	       "\t.arch\tbdver4\n"
+	       "\t.arch\t.8087\n"
+	       "\t.arch\t.287\n"
+	       "\t.arch\t.3dnow\n"
+	       "\t.arch\t.3dnowa\n"
+	       "\t.arch\t.padlock\n"
+	       "\t.arch\t.vmx\n"
+	       "\t.arch\t.smx\n"
+	       "\t.arch\t.ept\n"
+	       "\t.arch\t.hle\n"
+	       "\t.arch\t.rtm\n"
+	       "\t.arch\t.invpcid\n"
+	       "\t.arch\t.vmfunc\n"
+	       "\t.arch\t.prefetchwt1\n"
+	       "\t.arch\t.se1\n"
+	       "\t.arch\t.clwb\n"
+	       "\t.arch\t.pcommit\n"
+	       "\t.arch\t.mpx\n"
+	       "\t.arch\t.adx\n"
+	       "\t.arch\t.rdseed\n"
+	       "\t.arch\t.smap\n"
+	       "\t.arch\t.sha\n"
+	       "\t.arch\t.xsavec\n"
+	       "\t.arch\t.xsaves\n"
+	       "\t.arch\t.clflushopt\n"
+	       "\t.arch\t.clzero\n"
+	       "\t.arch\t.ospke\n"
+	       "\t.arch\t.rdpid\n%s%s%s%s%s%s%s%s%s%s",
+	       (TARGET_64BIT && TARGET_AVX512F) ? "\t.arch\t.vrex\n" : "",
+	       TARGET_AVX512F ? "\t.arch\t.avx512f\n" : "",
+	       TARGET_AVX512PF ? "\t.arch\t.avx512pf\n" : "",
+	       TARGET_AVX512ER ? "\t.arch\t.avx512er\n" : "",
+	       TARGET_AVX512CD ? "\t.arch\t.avx512cd\n" : "",
+	       TARGET_AVX512DQ ? "\t.arch\t.avx512dq\n" : "",
+	       TARGET_AVX512BW ? "\t.arch\t.avx512bw\n" : "",
+	       TARGET_AVX512VL ? "\t.arch\t.avx512vl\n" : "",
+	       TARGET_AVX512VBMI ? "\t.arch\t.avx512vbmi\n" : "",
+	       TARGET_AVX512IFMA ? "\t.arch\t.avx512ifma\n" : "");
+      prev_avx512 = cur_avx512;
+    }
+
   if (is_ms_hook)
     {
       int i, filler_count = (TARGET_64BIT ? 32 : 16);
-------------- next part --------------
--- gcc/config/i386/i386.h.jj	2016-05-12 10:29:41.000000000 +0200
+++ gcc/config/i386/i386.h	2016-05-21 17:50:01.923718417 +0200
@@ -1064,10 +1064,10 @@ extern const char *host_detect_local_cpu
 
 #define REG_ALLOC_ORDER 					\
 {  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,\
-   18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,	\
-   33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,  \
-   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,	\
-   63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,  \
+   18, 19, 20, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 	\
+   65, 66, 67, 68, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,	\
+   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,	\
+   47, 48, 49, 50, 51, 52, 69, 70, 71, 72, 73, 74, 75, 76, 77,  \
    78, 79, 80 }
 
 /* ADJUST_REG_ALLOC_ORDER is a macro which permits reg_alloc_order


More information about the Binutils mailing list