]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
x86: don't suppress errors when optimizing
authorJan Beulich <jbeulich@suse.com>
Fri, 21 Jun 2024 06:33:57 +0000 (08:33 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 21 Jun 2024 06:33:57 +0000 (08:33 +0200)
Blindly ignoring any mnemonic suffix can't be quite right: Bad suffix /
operand combinations still want flagging. Simply avoid optimizing in
such situations.

gas/config/tc-i386.c
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/optimize-8.l [new file with mode: 0644]
gas/testsuite/gas/i386/optimize-8.s [new file with mode: 0644]

index b8fc3c438196c7d16c67b858bda0ef114247c22a..b8911c04436e1186577fb27e4f0fdcf427f45d7a 100644 (file)
@@ -4573,6 +4573,20 @@ check_hle (void)
     }
 }
 
+/* Helper for optimization (running ahead of process_suffix()), to make sure we
+   convert only well-formed insns.  @OP is the sized operand to cross check
+   against (typically a register).  Checking against a single operand typically
+   suffices, as match_template() has already honored CheckOperandSize.  */
+
+static bool is_plausible_suffix (unsigned int op)
+{
+  return !i.suffix
+        || (i.suffix == BYTE_MNEM_SUFFIX && i.types[op].bitfield.byte)
+        || (i.suffix == WORD_MNEM_SUFFIX && i.types[op].bitfield.word)
+        || (i.suffix == LONG_MNEM_SUFFIX && i.types[op].bitfield.dword)
+        || (i.suffix == QWORD_MNEM_SUFFIX && i.types[op].bitfield.qword);
+}
+
 /* Encode aligned vector move as unaligned vector move.  */
 
 static void
@@ -4758,6 +4772,7 @@ optimize_encoding (void)
       && i.reg_operands == 1
       && i.imm_operands == 1
       && !i.types[1].bitfield.byte
+      && is_plausible_suffix (1)
       && i.op[0].imms->X_op == O_constant
       && fits_in_imm7 (i.op[0].imms->X_add_number))
     {
@@ -4768,7 +4783,7 @@ optimize_encoding (void)
       if (flag_code == CODE_64BIT || base_regnum < 4)
        {
          i.types[1].bitfield.byte = 1;
-         /* Ignore the suffix.  */
+         /* Squash the suffix.  */
          i.suffix = 0;
          /* Convert to byte registers. 8-bit registers are special,
             RegRex64 and non-RegRex64 each have 8 registers.  */
index 2584c69bddc5bcf7918b7abde3a82419b31c9b17..e40b45fe990e3a77fb80247f064cb7bc9582a979 100644 (file)
@@ -615,6 +615,7 @@ if [gas_32_check] then {
     run_list_test "optimize-6a" "-I${srcdir}/$subdir -march=+noavx -al"
     run_dump_test "optimize-6b"
     run_list_test "optimize-7" "-I${srcdir}/$subdir -march=+noavx2 -al"
+    run_list_test "optimize-8" "-Os"
     run_dump_test "noopt"
     run_dump_test "lea-optimize"
     run_dump_test "lea16-optimize"
diff --git a/gas/testsuite/gas/i386/optimize-8.l b/gas/testsuite/gas/i386/optimize-8.l
new file mode 100644 (file)
index 0000000..af97d73
--- /dev/null
@@ -0,0 +1,4 @@
+.*: Assembler messages:
+.*:5: Error: .* `%ecx' .* suffix
+.*:6: Error: .* `%cx' .* suffix
+#pass
diff --git a/gas/testsuite/gas/i386/optimize-8.s b/gas/testsuite/gas/i386/optimize-8.s
new file mode 100644 (file)
index 0000000..9b68189
--- /dev/null
@@ -0,0 +1,6 @@
+# Check bogus instructions are still rejected when optimizing
+
+       .text
+_start:
+       testw   $4, %ecx
+       testl   $4, %cx