]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
x86/APX: correct .insn opcode space determination when REX2 is needed
authorJan Beulich <jbeulich@suse.com>
Fri, 1 Mar 2024 08:20:56 +0000 (09:20 +0100)
committerJan Beulich <jbeulich@suse.com>
Fri, 1 Mar 2024 08:20:56 +0000 (09:20 +0100)
In this case spaces 0f38 and 0f3a may not be put in place. To achieve
the intended effect, operand parsing (but not operand processing) needs
pulling ahead, so we know whether eGRP-s are in use.

gas/config/tc-i386.c
gas/testsuite/gas/i386/insn-rex2.l [new file with mode: 0644]
gas/testsuite/gas/i386/insn-rex2.s [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64.exp

index 9da95c3c9b371937748c04e110a660a6b4de4882..d1692742c6262f9eb4e66fdbac50384407e08e8a 100644 (file)
@@ -12922,13 +12922,43 @@ s_insn (int dummy ATTRIBUTE_UNUSED)
        }
     }
 
+  /* Parse operands, if any, before evaluating encoding space.  */
+  if (*line == ',')
+    {
+      i.memshift = -1;
+
+      ptr = parse_operands (line + 1, &i386_mnemonics[MN__insn]);
+      this_operand = -1;
+      if (!ptr)
+       goto bad;
+      line = ptr;
+
+      if (!i.operands)
+       {
+         as_bad (_("expecting operand after ','; got nothing"));
+         goto done;
+       }
+
+      if (i.mem_operands > 1)
+       {
+         as_bad (_("too many memory references for `%s'"),
+                 &i386_mnemonics[MN__insn]);
+         goto done;
+       }
+
+      /* No need to distinguish encoding_evex and encoding_evex512.  */
+      if (i.encoding == encoding_evex512)
+       i.encoding = encoding_evex;
+    }
+
   /* Trim off encoding space.  */
   if (j > 1 && !i.insn_opcode_space && (val >> ((j - 1) * 8)) == 0x0f)
     {
       uint8_t byte = val >> ((--j - 1) * 8);
 
       i.insn_opcode_space = SPACE_0F;
-      switch (byte & -(j > 1))
+      switch (byte & -(j > 1 && !i.rex2_encoding
+                      && (i.encoding != encoding_egpr || evex)))
        {
        case 0x38:
          i.insn_opcode_space = SPACE_0F38;
@@ -12951,42 +12981,17 @@ s_insn (int dummy ATTRIBUTE_UNUSED)
   if (j > 2)
     {
       as_bad (_("opcode residual (%#"PRIx64") too wide"), (uint64_t) val);
-      goto bad;
+      goto done;
     }
   i.opcode_length = j;
 
   /* Handle operands, if any.  */
-  if (*line == ',')
+  if (i.operands)
     {
       i386_operand_type combined;
       expressionS *disp_exp = NULL;
       bool changed;
 
-      i.memshift = -1;
-
-      ptr = parse_operands (line + 1, &i386_mnemonics[MN__insn]);
-      this_operand = -1;
-      if (!ptr)
-       goto bad;
-      line = ptr;
-
-      if (!i.operands)
-       {
-         as_bad (_("expecting operand after ','; got nothing"));
-         goto done;
-       }
-
-      if (i.mem_operands > 1)
-       {
-         as_bad (_("too many memory references for `%s'"),
-                 &i386_mnemonics[MN__insn]);
-         goto done;
-       }
-
-      /* No need to distinguish encoding_evex and encoding_evex512.  */
-      if (i.encoding == encoding_evex512)
-       i.encoding = encoding_evex;
-
       if (i.encoding == encoding_egpr)
        {
          if (vex || xop)
diff --git a/gas/testsuite/gas/i386/insn-rex2.l b/gas/testsuite/gas/i386/insn-rex2.l
new file mode 100644 (file)
index 0000000..d9e31bb
--- /dev/null
@@ -0,0 +1,38 @@
+[      ]*[0-9]+[       ]+\.text
+[      ]*[0-9]+[       ]+insn_rex2:
+[      ]*[0-9]+ .... D58001C0[         ]+\.insn \{rex2\} 0x0f01/0, %eax
+[      ]*[0-9]+ .... D58038C0[         ]+\.insn \{rex2\} 0x0f38/0, %eax
+[      ]*[0-9]+ .... D5803801[         ]+\.insn \{rex2\} 0x0f3801/0, %eax
+[      ]*[0-9]+ +C0
+[      ]*[0-9]+ .... D5803901[         ]+\.insn \{rex2\} 0x0f3901/0, %eax
+[      ]*[0-9]+ +C0
+[      ]*[0-9]+ .... D5803A01[         ]+\.insn \{rex2\} 0x0f3a01/0, \$0xCC, %eax
+[      ]*[0-9]+ +C0CC
+[      ]*[0-9]+[       ]+
+[      ]*[0-9]+ .... D58801C0[         ]+\.insn \{rex2\} 0x0f01/0, %rax
+[      ]*[0-9]+ .... D58838C0[         ]+\.insn \{rex2\} 0x0f38/0, %rax
+[      ]*[0-9]+ .... D5883801[         ]+\.insn \{rex2\} 0x0f3801/0, %rax
+[      ]*[0-9]+ +C0
+[      ]*[0-9]+ .... D5883901[         ]+\.insn \{rex2\} 0x0f3901/0, %rax
+[      ]*[0-9]+ +C0
+[      ]*[0-9]+ .... D5883A01[         ]+\.insn \{rex2\} 0x0f3a01/0, \$0xCC, %rax
+[      ]*[0-9]+ +C0CC
+[      ]*[0-9]+[       ]+
+[      ]*[0-9]+ .... D58901C0[         ]+\.insn \{rex2\} 0x0f01/0, %r8
+[      ]*[0-9]+ .... D58938C0[         ]+\.insn \{rex2\} 0x0f38/0, %r8
+[      ]*[0-9]+ .... D5893801[         ]+\.insn \{rex2\} 0x0f3801/0, %r8
+[      ]*[0-9]+ +C0
+[      ]*[0-9]+ .... D5893901[         ]+\.insn \{rex2\} 0x0f3901/0, %r8
+[      ]*[0-9]+ +C0
+[      ]*[0-9]+ .... D5893A01[         ]+\.insn \{rex2\} 0x0f3a01/0, \$0xCC, %r8
+[      ]*[0-9]+ +C0CC
+[      ]*[0-9]+[       ]+
+[      ]*[0-9]+ .... D59801C0[         ]+\.insn 0x0f01/0, %r16
+[      ]*[0-9]+ .... D59838C0[         ]+\.insn 0x0f38/0, %r16
+[      ]*[0-9]+ .... D5983801[         ]+\.insn 0x0f3801/0, %r16
+[      ]*[0-9]+ +C0
+[      ]*[0-9]+ .... D5983901[         ]+\.insn 0x0f3901/0, %r16
+[      ]*[0-9]+ +C0
+[      ]*[0-9]+ .... D5983A01[         ]+\.insn 0x0f3a01/0, \$0xCC, %r16
+[      ]*[0-9]+[       ]+C0CC
+#pass
diff --git a/gas/testsuite/gas/i386/insn-rex2.s b/gas/testsuite/gas/i386/insn-rex2.s
new file mode 100644 (file)
index 0000000..b93159a
--- /dev/null
@@ -0,0 +1,25 @@
+       .text
+insn_rex2:
+       .insn {rex2} 0x0f01/0, %eax
+       .insn {rex2} 0x0f38/0, %eax
+       .insn {rex2} 0x0f3801/0, %eax
+       .insn {rex2} 0x0f3901/0, %eax
+       .insn {rex2} 0x0f3a01/0, $0xCC, %eax
+
+       .insn {rex2} 0x0f01/0, %rax
+       .insn {rex2} 0x0f38/0, %rax
+       .insn {rex2} 0x0f3801/0, %rax
+       .insn {rex2} 0x0f3901/0, %rax
+       .insn {rex2} 0x0f3a01/0, $0xCC, %rax
+
+       .insn {rex2} 0x0f01/0, %r8
+       .insn {rex2} 0x0f38/0, %r8
+       .insn {rex2} 0x0f3801/0, %r8
+       .insn {rex2} 0x0f3901/0, %r8
+       .insn {rex2} 0x0f3a01/0, $0xCC, %r8
+
+       .insn 0x0f01/0, %r16
+       .insn 0x0f38/0, %r16
+       .insn 0x0f3801/0, %r16
+       .insn 0x0f3901/0, %r16
+       .insn 0x0f3a01/0, $0xCC, %r16
index f0ca846a2a32ec265f1e5eb7b16e27e550d9e4b7..e53c135dbcb3cfbf968a871ac3373daf4e2e5a18 100644 (file)
@@ -126,6 +126,7 @@ run_dump_test "x86-64-sysenter-mixed"
 run_dump_test "x86-64-sysenter-amd"
 run_list_test "x86-64-sysenter-amd" "-mamd64"
 run_dump_test "insn-64"
+run_list_test "insn-rex2" "-aln --divide"
 run_dump_test "noreg64"
 run_list_test "noreg64"
 run_dump_test "noreg64-data16"