x86: correct cpu_arch_isa_flags maintenance
authorJan Beulich <jbeulich@suse.com>
Wed, 27 Sep 2023 14:51:46 +0000 (16:51 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 27 Sep 2023 14:51:46 +0000 (16:51 +0200)
These may not be set from a value derived from cpu_arch_flags: That
starts with (almost) all functionality enabled, while cpu_arch_isa_flags
is supposed to track features that were explicitly enabled (and perhaps
later disabled) by the user.

To avoid needing to do any such adjustment in two places (each),
introduce helper functions used by both command line handling and
directive processing.

gas/config/tc-i386.c
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/nops-9.d [new file with mode: 0644]
gas/testsuite/gas/i386/nops-9.s [new file with mode: 0644]

index fa813aa80cba515a30055563bb678d7c9b10f4b2..9f5522b7a3f14e56d366fec442e54c024cec05cc 100644 (file)
@@ -2808,13 +2808,41 @@ check_cpu_arch_compatible (const char *name ATTRIBUTE_UNUSED,
 }
 
 static void
-extend_cpu_sub_arch_name (const char *name)
+extend_cpu_sub_arch_name (const char *pfx, const char *name)
 {
   if (cpu_sub_arch_name)
     cpu_sub_arch_name = reconcat (cpu_sub_arch_name, cpu_sub_arch_name,
-                                 ".", name, (const char *) NULL);
+                                 pfx, name, (const char *) NULL);
   else
-    cpu_sub_arch_name = concat (".", name, (const char *) NULL);
+    cpu_sub_arch_name = concat (pfx, name, (const char *) NULL);
+}
+
+static void isa_enable (unsigned int idx)
+{
+  i386_cpu_flags flags = cpu_flags_or (cpu_arch_flags, cpu_arch[idx].enable);
+
+  if (!cpu_flags_equal (&flags, &cpu_arch_flags))
+    {
+      extend_cpu_sub_arch_name (".", cpu_arch[idx].name);
+      cpu_arch_flags = flags;
+    }
+
+  cpu_arch_isa_flags = cpu_flags_or (cpu_arch_isa_flags, cpu_arch[idx].enable);
+}
+
+static void isa_disable (unsigned int idx)
+{
+  i386_cpu_flags flags
+    = cpu_flags_and_not (cpu_arch_flags, cpu_arch[idx].disable);
+
+  if (!cpu_flags_equal (&flags, &cpu_arch_flags))
+    {
+      extend_cpu_sub_arch_name (".no", cpu_arch[idx].name);
+      cpu_arch_flags = flags;
+    }
+
+  cpu_arch_isa_flags
+    = cpu_flags_and_not (cpu_arch_isa_flags, cpu_arch[idx].disable);
 }
 
 static void
@@ -2838,7 +2866,6 @@ set_cpu_arch (int dummy ATTRIBUTE_UNUSED)
   int e;
   const char *string;
   unsigned int j = 0;
-  i386_cpu_flags flags;
 
   SKIP_WHITESPACE ();
 
@@ -2991,17 +3018,7 @@ set_cpu_arch (int dummy ATTRIBUTE_UNUSED)
          if (cpu_flags_all_zero (&cpu_arch[j].enable))
            continue;
 
-         flags = cpu_flags_or (cpu_arch_flags, cpu_arch[j].enable);
-
-         if (!cpu_flags_equal (&flags, &cpu_arch_flags))
-           {
-             extend_cpu_sub_arch_name (string + 1);
-             cpu_arch_flags = flags;
-             cpu_arch_isa_flags = flags;
-           }
-         else
-           cpu_arch_isa_flags
-             = cpu_flags_or (cpu_arch_isa_flags, cpu_arch[j].enable);
+         isa_enable (j);
 
          (void) restore_line_pointer (e);
 
@@ -3048,13 +3065,7 @@ set_cpu_arch (int dummy ATTRIBUTE_UNUSED)
        if (cpu_arch[j].type == PROCESSOR_NONE
            && strcmp (string + 3, cpu_arch[j].name) == 0)
          {
-           flags = cpu_flags_and_not (cpu_arch_flags, cpu_arch[j].disable);
-           if (!cpu_flags_equal (&flags, &cpu_arch_flags))
-             {
-               extend_cpu_sub_arch_name (string + 1);
-               cpu_arch_flags = flags;
-               cpu_arch_isa_flags = flags;
-             }
+           isa_disable (j);
 
            if (cpu_arch[j].vsz == vsz_set)
              vector_size = VSZ_DEFAULT;
@@ -14611,21 +14622,7 @@ md_parse_option (int c, const char *arg)
                       && !cpu_flags_all_zero (&cpu_arch[j].enable))
                {
                  /* ISA extension.  */
-                 i386_cpu_flags flags;
-
-                 flags = cpu_flags_or (cpu_arch_flags,
-                                       cpu_arch[j].enable);
-
-                 if (!cpu_flags_equal (&flags, &cpu_arch_flags))
-                   {
-                     extend_cpu_sub_arch_name (arch);
-                     cpu_arch_flags = flags;
-                     cpu_arch_isa_flags = flags;
-                   }
-                 else
-                   cpu_arch_isa_flags
-                     = cpu_flags_or (cpu_arch_isa_flags,
-                                     cpu_arch[j].enable);
+                 isa_enable (j);
 
                  switch (cpu_arch[j].vsz)
                    {
@@ -14668,16 +14665,7 @@ md_parse_option (int c, const char *arg)
                if (cpu_arch[j].type == PROCESSOR_NONE
                    && strcmp (arch + 2, cpu_arch[j].name) == 0)
                  {
-                   i386_cpu_flags flags;
-
-                   flags = cpu_flags_and_not (cpu_arch_flags,
-                                              cpu_arch[j].disable);
-                   if (!cpu_flags_equal (&flags, &cpu_arch_flags))
-                     {
-                       extend_cpu_sub_arch_name (arch);
-                       cpu_arch_flags = flags;
-                       cpu_arch_isa_flags = flags;
-                     }
+                   isa_disable (j);
                    if (cpu_arch[j].vsz == vsz_set)
                      vector_size = VSZ_DEFAULT;
                    break;
index d16eb888f244e17c053ef06cac6045f0475a75d3..aa9f9a466bb5d64a40ee14bfd1ceb050c6f613d3 100644 (file)
@@ -147,6 +147,7 @@ if [gas_32_check] then {
     run_dump_test "nops-6"
     run_dump_test "nops-7"
     run_dump_test "nops-8"
+    run_dump_test "nops-9"
     run_dump_test "noreg16"
     run_list_test "noreg16"
     run_dump_test "noreg16-data32"
diff --git a/gas/testsuite/gas/i386/nops-9.d b/gas/testsuite/gas/i386/nops-9.d
new file mode 100644 (file)
index 0000000..a073a58
--- /dev/null
@@ -0,0 +1,28 @@
+#objdump: -drw
+#name: i386 nops 9
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <default>:
+[      ]*[a-f0-9]+:    0f be f0                movsbl %al,%esi
+[      ]*[a-f0-9]+:    8d b4 26 00 00 00 00    lea    0x0\(%esi,%eiz,1\),%esi
+[      ]*[a-f0-9]+:    8d b6 00 00 00 00       lea    0x0\(%esi\),%esi
+
+0+10 <nopopcnt>:
+[      ]*[a-f0-9]+:    0f be f0                movsbl %al,%esi
+[      ]*[a-f0-9]+:    8d b4 26 00 00 00 00    lea    0x0\(%esi,%eiz,1\),%esi
+[      ]*[a-f0-9]+:    8d b6 00 00 00 00       lea    0x0\(%esi\),%esi
+
+0+20 <popcnt>:
+[      ]*[a-f0-9]+:    f3 0f b8 f0             popcnt %eax,%esi
+[      ]*[a-f0-9]+:    8d b4 26 00 00 00 00    lea    0x0\(%esi,%eiz,1\),%esi
+[      ]*[a-f0-9]+:    8d 74 26 00             lea    0x0\(%esi,%eiz,1\),%esi
+[      ]*[a-f0-9]+:    90                      nop
+
+0+30 <nop>:
+[      ]*[a-f0-9]+:    0f be f0                movsbl %al,%esi
+[      ]*[a-f0-9]+:    66 66 2e 0f 1f 84 00 00 00 00 00        data16 nopw %cs:0x0\(%eax,%eax,1\)
+[      ]*[a-f0-9]+:    66 90                   xchg   %ax,%ax
+#pass
diff --git a/gas/testsuite/gas/i386/nops-9.s b/gas/testsuite/gas/i386/nops-9.s
new file mode 100644 (file)
index 0000000..db2eebb
--- /dev/null
@@ -0,0 +1,19 @@
+       .text
+default:
+       movsbl %al,%esi
+       .p2align 4
+
+       .arch .nopopcnt
+nopopcnt:
+       movsbl %al,%esi
+       .p2align 4
+
+       .arch .popcnt
+popcnt:
+       popcnt %eax,%esi
+       .p2align 4
+
+       .arch .nop
+nop:
+       movsbl %al,%esi
+       .p2align 4