x86-64: fix handling of PUSH/POP of segment register
authorJan Beulich <jbeulich@suse.com>
Fri, 20 Sep 2019 08:18:15 +0000 (10:18 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 20 Sep 2019 08:18:15 +0000 (10:18 +0200)
Commit 21df382b91 ("x86: fold SReg{2,3}") went too far: Folding 64-bit
PUSH/POP templates into non-64-bit ones isn't correct, due to the
different operand widths, and hence suffixes permitted. Restore the
separate templates.

Add tests of PUSH/POP with q suffix and %fs/%gs operands to the
testsuite. While doing so also add PUSHF/POPF ones _without_ suffix.

gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/gas/i386/x86-64-opcode.d
gas/testsuite/gas/i386/x86-64-opcode.s
opcodes/ChangeLog
opcodes/i386-opc.tbl
opcodes/i386-tbl.h

index b4234f09c0dce7faa001d6346b38cb5d32c6566a..bcd2f9af3571c7c6b8352878b674c1959b733ec4 100644 (file)
@@ -1,3 +1,12 @@
+2018-09-20  Jan Beulich  <jbeulich@suse.com>
+
+       PR gas/25012
+       * config/tc-i386.c (process_operands): Adjust handling of
+       PUSH/POP of segment registers.
+       * testsuite/gas/i386/x86-64-opcode.s: Add PUSHq/POPq case with
+       %fs/%gs operands. Add PUSHF/POPF case without suffix.
+       * testsuite/gas/i386/x86-64-opcode.d: Adjust expectations.
+
 2019-09-19  Matthew Malcomson  <matthew.malcomson@arm.com>
 
        * NEWS: Add SVE2 and TME entries.
index fec69c1397df7bd60587f7765cd728d241d8c8c1..349b36da5d755213896485f68de27abb5edfdbfb 100644 (file)
@@ -7010,14 +7010,14 @@ duplicate:
          if (flag_code != CODE_64BIT
              ? i.tm.base_opcode == POP_SEG_SHORT
                && i.op[0].regs->reg_num == 1
-             : (i.tm.base_opcode | 1) == POP_SEG_SHORT
+             : (i.tm.base_opcode | 1) == POP_SEG386_SHORT
                && i.op[0].regs->reg_num < 4)
            {
              as_bad (_("you can't `%s %s%s'"),
                      i.tm.name, register_prefix, i.op[0].regs->reg_name);
              return 0;
            }
-         if ( i.op[0].regs->reg_num > 3 )
+         if ( i.op[0].regs->reg_num > 3 && i.tm.opcode_length == 1 )
            {
              i.tm.base_opcode ^= POP_SEG_SHORT ^ POP_SEG386_SHORT;
              i.tm.opcode_length = 2;
index 35829f4f8470075acfa387159d507381410ae454..d8a1e44a4511c1606605312fbc807ed0848af317 100644 (file)
@@ -255,13 +255,19 @@ Disassembly of section .text:
 [      ]*[a-f0-9]+:    41 8f 00                popq   \(%r8\)
 [      ]*[a-f0-9]+:    8f 00                   popq   \(%rax\)
 [      ]*[a-f0-9]+:    0f a1                   popq   %fs
+[      ]*[a-f0-9]+:    0f a1                   popq   %fs
+[      ]*[a-f0-9]+:    0f a9                   popq   %gs
 [      ]*[a-f0-9]+:    0f a9                   popq   %gs
 [      ]*[a-f0-9]+:    9d                      popfq  
+[      ]*[a-f0-9]+:    9d                      popfq  
 [      ]*[a-f0-9]+:    41 ff 30                pushq  \(%r8\)
 [      ]*[a-f0-9]+:    ff 30                   pushq  \(%rax\)
 [      ]*[a-f0-9]+:    0f a0                   pushq  %fs
+[      ]*[a-f0-9]+:    0f a0                   pushq  %fs
+[      ]*[a-f0-9]+:    0f a8                   pushq  %gs
 [      ]*[a-f0-9]+:    0f a8                   pushq  %gs
 [      ]*[a-f0-9]+:    9c                      pushfq 
+[      ]*[a-f0-9]+:    9c                      pushfq 
 [      ]*[a-f0-9]+:    0f 77                   emms   
 [      ]*[a-f0-9]+:    0f 0e                   femms  
 [      ]*[a-f0-9]+:    0f 08                   invd   
index 8d4a6ed9b2af5400a585e4ef55630565dfe0898e..caee124d160f742fd8c8be602eb2cffaa520a42c 100644 (file)
        POPq (%r8)                    #  --  --  -- 41   8F 00                           ; REX to access upper reg.
        POPq (%rax)                   #  --  --  -- --   8F 00
        POP %fs                       #  --  --  -- --   0F A1
+       POPq %fs                      #  --  --  -- --   0F A1
        POP %gs                       #  --  --  -- --   0F A9
-       POPFQ                         #  --  --  -- --   9D
+       POPq %gs                      #  --  --  -- --   0F A9
+       POPF                          #  --  --  -- --   9D
+       POPFq                         #  --  --  -- --   9D
 
        # PUSH
        PUSHq (%r8)                   #  --  --  -- 41   FF 30                           ; REX to access upper reg.
        PUSHq (%rax)                  #  --  --  -- --   FF 30
        PUSH %fs                      #  --  --  -- --   0F A0
+       PUSHq %fs                     #  --  --  -- --   0F A0
        PUSH %gs                      #  --  --  -- --   0F A8
-       PUSHFQ                        #  --  --  -- --   9C
+       PUSHq %gs                     #  --  --  -- --   0F A8
+       PUSHF                         #  --  --  -- --   9C
+       PUSHFq                        #  --  --  -- --   9C
 
 
 
index 0d8abcd7ff2017c7f2427a9bd3952417ac5aeeb3..0043d4eb167cb101cb023e1fda94348546a77f0f 100644 (file)
@@ -1,3 +1,10 @@
+2018-09-20  Jan Beulich  <jbeulich@suse.com>
+
+       PR gas/25012
+       * i386-opc.tbl (push, pop): Re-instate distinct Cpu64 templates
+       with SReg operand.
+       * i386-tbl.h: Re-generate.
+
 2019-09-18  Alan Modra  <amodra@gmail.com>
 
        * arc-ext.c: Update throughout for bfd section macro changes.
index af2b600ba1e26e2183729d53009df768ae178ab9..256ff04360c9ccc3c14a139d325bcd1dea1a63eb 100644 (file)
@@ -116,22 +116,24 @@ push, 1, 0x50, None, 1, CpuNo64, ShortForm|DefaultSize|No_bSuf|No_sSuf|No_qSuf|N
 push, 1, 0xff, 0x6, 1, CpuNo64, Modrm|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg16|Reg32|Word|Dword|Unspecified|BaseIndex }
 push, 1, 0x6a, None, 1, Cpu186|CpuNo64, DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm8S }
 push, 1, 0x68, None, 1, Cpu186|CpuNo64, DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Imm16|Imm32 }
-push, 1, 0x6, None, 1, 0, ShortForm|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { SReg }
+push, 1, 0x6, None, 1, CpuNo64, ShortForm|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { SReg }
 // In 64bit mode, the operand size is implicitly 64bit.
 push, 1, 0x50, None, 1, Cpu64, ShortForm|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64, { Reg16|Reg64 }
 push, 1, 0xff, 0x6, 1, Cpu64, Modrm|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64, { Reg16|Reg64|Word|Qword|Unspecified|BaseIndex }
 push, 1, 0x6a, None, 1, Cpu64, DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64, { Imm8S }
 push, 1, 0x68, None, 1, Cpu64, DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64, { Imm16|Imm32S }
+push, 1, 0xfa0, None, 2, Cpu64, ShortForm|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64, { SReg }
 
 pusha, 0, 0x60, None, 1, Cpu186|CpuNo64, DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
 
 // Pop instructions.
 pop, 1, 0x58, None, 1, CpuNo64, ShortForm|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg16|Reg32 }
 pop, 1, 0x8f, 0x0, 1, CpuNo64, Modrm|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg16|Reg32|Word|Dword|Unspecified|BaseIndex }
-pop, 1, 0x7, None, 1, 0, ShortForm|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { SReg }
+pop, 1, 0x7, None, 1, CpuNo64, ShortForm|DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { SReg }
 // In 64bit mode, the operand size is implicitly 64bit.
 pop, 1, 0x58, None, 1, Cpu64, ShortForm|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64, { Reg16|Reg64 }
 pop, 1, 0x8f, 0x0, 1, Cpu64, Modrm|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64, { Reg16|Reg64|Word|Qword|Unspecified|BaseIndex }
+pop, 1, 0xfa1, None, 2, Cpu64, ShortForm|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64, { SReg }
 
 popa, 0, 0x61, None, 1, Cpu186|CpuNo64, DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
 
index 307415e8ca4a638ed9d47ea0db4f855c153fe7c8..89c752e826e8a9843c1f49c5bedbd09c572376ed 100644 (file)
@@ -635,7 +635,7 @@ const insn_template i386_optab[] =
         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, 0, 0, 0, 0, 0, 1, 0 } },
     { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1,
       1, 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,
@@ -694,6 +694,19 @@ const insn_template i386_optab[] =
       0 },
     { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 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 } } } },
+  { "push", 1, 0xfa0, None, 2,
+    { { 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, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0,
+      1, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } } },
   { "pusha", 0, 0x60, None, 1,
     { { 1, 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,
@@ -739,7 +752,7 @@ const insn_template i386_optab[] =
         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, 0, 0, 0, 0, 0, 1, 0 } },
     { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1,
       1, 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,
@@ -772,6 +785,19 @@ const insn_template i386_optab[] =
       0 },
     { { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0,
          0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0 } } } },
+  { "pop", 1, 0xfa1, None, 2,
+    { { 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, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0,
+      1, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } } },
   { "popa", 0, 0x61, None, 1,
     { { 1, 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,
This page took 0.057189 seconds and 4 git commands to generate.