diff options
author | Jan Beulich <jbeulich@suse.com> | 2019-09-20 10:18:15 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2019-09-20 10:18:15 +0200 |
commit | 3f9aad111cea2f25877d0a6b404956769c14faee (patch) | |
tree | 710516f16c6e7652447adce60a180cdd6f9e2362 | |
parent | 4c51dacacf8a97194a1241ad5e1cbf7be00a59a3 (diff) | |
download | gdb-3f9aad111cea2f25877d0a6b404956769c14faee.zip gdb-3f9aad111cea2f25877d0a6b404956769c14faee.tar.gz gdb-3f9aad111cea2f25877d0a6b404956769c14faee.tar.bz2 |
x86-64: fix handling of PUSH/POP of segment register
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.
-rw-r--r-- | gas/ChangeLog | 9 | ||||
-rw-r--r-- | gas/config/tc-i386.c | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-opcode.d | 6 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-opcode.s | 10 | ||||
-rw-r--r-- | opcodes/ChangeLog | 7 | ||||
-rw-r--r-- | opcodes/i386-opc.tbl | 6 | ||||
-rw-r--r-- | opcodes/i386-tbl.h | 30 |
7 files changed, 64 insertions, 8 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index b4234f0..bcd2f9a 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index fec69c1..349b36d 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -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; diff --git a/gas/testsuite/gas/i386/x86-64-opcode.d b/gas/testsuite/gas/i386/x86-64-opcode.d index 35829f4..d8a1e44 100644 --- a/gas/testsuite/gas/i386/x86-64-opcode.d +++ b/gas/testsuite/gas/i386/x86-64-opcode.d @@ -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 diff --git a/gas/testsuite/gas/i386/x86-64-opcode.s b/gas/testsuite/gas/i386/x86-64-opcode.s index 8d4a6ed..caee124 100644 --- a/gas/testsuite/gas/i386/x86-64-opcode.s +++ b/gas/testsuite/gas/i386/x86-64-opcode.s @@ -323,15 +323,21 @@ 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 diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 0d8abcd..0043d4e 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -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. diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl index af2b600..256ff04 100644 --- a/opcodes/i386-opc.tbl +++ b/opcodes/i386-opc.tbl @@ -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 } diff --git a/opcodes/i386-tbl.h b/opcodes/i386-tbl.h index 307415e..89c752e 100644 --- a/opcodes/i386-tbl.h +++ b/opcodes/i386-tbl.h @@ -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, |