x86: make sure all PUSH/POP honor DefaultSize
authorJan Beulich <jbeulich@suse.com>
Wed, 4 Dec 2019 09:40:40 +0000 (10:40 +0100)
committerJan Beulich <jbeulich@suse.com>
Wed, 4 Dec 2019 09:40:40 +0000 (10:40 +0100)
While segment registers are registers, their use doesn't allow sizing
of insns without suffix / explicit operand size specifier. Prevent
PUSH and POP of segment registers from entering that path, instead
allowing them to observe the stackop_size setting just like other
PUSH/POP and alike do.

gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/gas/i386/general.l
gas/testsuite/gas/i386/general.s

index 7307dc8e44457d4a1a33f0e6e245c9bfe7ef7955..411d66fd94d7f9726546b70dc644167c3c9c9b24 100644 (file)
@@ -1,3 +1,13 @@
+2019-12-04  Jan Beulich  <jbeulich@suse.com>
+
+       * config/tc-i386.c (process_suffix): Arrange for insns with a
+       single non-GPR register operand to not have its suffix guessed
+       from GPR operands. Extend DefaultSize handling to cover PUSH/POP
+       of segment registers.
+       * testsuite/gas/i386/general.s: Add PUSH/POP sreg to .code16gcc
+       set of insns.
+       * testsuite/gas/i386/general.l: Adjust expectations.
+
 2019-12-04  Jan Beulich  <jbeulich@suse.com>
 
        * config/tc-i386.c (process_suffix): Exclude SYSRET alongside
index 64312d27ab0bee014b9716aa2490aaa741333810..b8babed68ba0b96c6df9530582f47f8a4dffe1af 100644 (file)
@@ -6207,10 +6207,11 @@ process_suffix (void)
     i.suffix = LONG_MNEM_SUFFIX;
   else if (i.tm.opcode_modifier.size == SIZE64)
     i.suffix = QWORD_MNEM_SUFFIX;
-  else if (i.reg_operands)
+  else if (i.reg_operands
+          && (i.operands > 1 || i.types[0].bitfield.class == Reg))
     {
       /* If there's no instruction mnemonic suffix we try to invent one
-        based on register operands.  */
+        based on GPR operands.  */
       if (!i.suffix)
        {
          /* We take i.suffix from the last register operand specified,
@@ -6315,19 +6316,24 @@ process_suffix (void)
           /* exclude sysret */
           && i.tm.base_opcode != 0x0f07)
     {
-      if (stackop_size == LONG_MNEM_SUFFIX
-         && i.tm.base_opcode == 0xcf)
+      i.suffix = stackop_size;
+      if (stackop_size == LONG_MNEM_SUFFIX)
        {
          /* stackop_size is set to LONG_MNEM_SUFFIX for the
             .code16gcc directive to support 16-bit mode with
             32-bit address.  For IRET without a suffix, generate
             16-bit IRET (opcode 0xcf) to return from an interrupt
             handler.  */
-         i.suffix = WORD_MNEM_SUFFIX;
-         as_warn (_("generating 16-bit `iret' for .code16gcc directive"));
+         if (i.tm.base_opcode == 0xcf)
+           {
+             i.suffix = WORD_MNEM_SUFFIX;
+             as_warn (_("generating 16-bit `iret' for .code16gcc directive"));
+           }
+         /* Warn about changed behavior for segment register push/pop.  */
+         else if ((i.tm.base_opcode | 1) == 0x07)
+           as_warn (_("generating 32-bit `%s', unlike earlier gas versions"),
+                    i.tm.name);
        }
-      else
-       i.suffix = stackop_size;
     }
   else if (intel_syntax
           && !i.suffix
index d5f74d11a63240b96afb822f75a3a0560f98a0af..acd44403ee48dc4de8a33f83e584fe9db7801527 100644 (file)
 .*:144: Warning:.*
 .*:178: Warning:.*
 .*:224: Warning:.*
+.*:233: Warning:.*
+.*:234: Warning:.*
+.*:238: Warning:.*
+.*:239: Warning:.*
    1                           .psize 0
    2                           .text
    3                           #test jumps and calls
 [      ]*[1-9][0-9]*[  ]+[0-9a-f]*[    ]+666A00[       ]+push  \$0
 [      ]*[1-9][0-9]*[  ]+[0-9a-f]*[    ]+66683412 0000[        ]+push  \$0x1234
 [      ]*[1-9][0-9]*[  ]+[0-9a-f]*[    ]+66FF37[       ]+push  \(%bx\)
+[      ]*[1-9][0-9]*[  ]+[0-9a-f]*[    ]+6606[         ]+push  %es
+.*Warning:.*32-bit.*push.*
+[      ]*[1-9][0-9]*[  ]+[0-9a-f]*[    ]+660FA0[       ]+push  %fs
+.*Warning:.*32-bit.*push.*
 [      ]*[1-9][0-9]*[  ]+[0-9a-f]*[    ]+6660[         ]+pusha
 [      ]*[1-9][0-9]*[  ]+[0-9a-f]*[    ]+669C[         ]+pushf
 [      ]*[1-9][0-9]*[  ]+[0-9a-f]*[    ]+668F07[       ]+pop   \(%bx\)
+[      ]*[1-9][0-9]*[  ]+[0-9a-f]*[    ]+6607[         ]+pop   %es
+.*Warning:.*32-bit.*pop.*
+[      ]*[1-9][0-9]*[  ]+[0-9a-f]*[    ]+660FA1[       ]+pop   %fs
+.*Warning:.*32-bit.*pop.*
 [      ]*[1-9][0-9]*[  ]+[0-9a-f]*[    ]+6661[         ]+popa
 [      ]*[1-9][0-9]*[  ]+[0-9a-f]*[    ]+669D[         ]+popf
 [      ]*[1-9][0-9]*[  ]+[0-9a-f]*[    ]+66C3[         ]+ret
index add14fd3f2d06f6bfa285a2a11b14f1b23d7ed2c..39bbfe3e0b57e2072537eddd65ee87ca97739433 100644 (file)
        push    $0
        push    $0x1234
        push    (%bx)
+       push    %es
+       push    %fs
        pusha
        pushf
        pop     (%bx)
+       pop     %es
+       pop     %fs
        popa
        popf
        ret