From 848930b2ba6024409e18d93f52fbdc206c4904c4 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 7 Aug 2012 16:57:49 +0000 Subject: [PATCH] Despite them being ignored by the CPU, gas issues segment override prefixes for other than FS/GS in 64-bit mode. If doing so at all, it should clearly do this correctly. Determining the default segment, however, requires to take into consideration RegRex (so far, RSP, RBP, R12, and R13 were all treated equally here). gas/ 2012-08-07 Jan Beulich * config/tc-i386-intel.c (build_modrm_byte): Split determining default segment from figuring out encoding. Honor RegRex for the former. gas/testsuite/ 2012-08-07 Jan Beulich * gas/i386/x86-64-segovr.{s,l}: New. * gas/i386/i386.exp: Run new test. --- gas/ChangeLog | 6 ++++ gas/config/tc-i386.c | 16 ++++------ gas/testsuite/ChangeLog | 5 ++++ gas/testsuite/gas/i386/i386.exp | 1 + gas/testsuite/gas/i386/x86-64-segovr.d | 41 ++++++++++++++++++++++++++ gas/testsuite/gas/i386/x86-64-segovr.s | 9 ++++++ 6 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 gas/testsuite/gas/i386/x86-64-segovr.d create mode 100644 gas/testsuite/gas/i386/x86-64-segovr.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 2c6dfd2296..72116dde77 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2012-08-07 Jan Beulich + + * config/tc-i386-intel.c (build_modrm_byte): Split determining + default segment from figuring out encoding. Honor RegRex for + the former. + 2012-08-07 Jan Beulich * config/tc-i386.c (set_check): Renamed from set_sse_check. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 7cc6fa71e0..171749e08b 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -5770,18 +5770,14 @@ build_modrm_byte (void) i.sib.base = i.base_reg->reg_num; /* x86-64 ignores REX prefix bit here to avoid decoder complications. */ - if ((i.base_reg->reg_num & 7) == EBP_REG_NUM) - { + if (!(i.base_reg->reg_flags & RegRex) + && (i.base_reg->reg_num == EBP_REG_NUM + || i.base_reg->reg_num == ESP_REG_NUM)) default_seg = &ss; - if (i.disp_operands == 0) - { - fake_zero_displacement = 1; - i.types[op].bitfield.disp8 = 1; - } - } - else if (i.base_reg->reg_num == ESP_REG_NUM) + if (i.base_reg->reg_num == 5 && i.disp_operands == 0) { - default_seg = &ss; + fake_zero_displacement = 1; + i.types[op].bitfield.disp8 = 1; } i.sib.scale = i.log2_scale_factor; if (i.index_reg == 0) diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 8225b2327b..56a01d8fd3 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-08-07 Jan Beulich + + * gas/i386/x86-64-segovr.{s,l}: New. + * gas/i386/i386.exp: Run new test. + 2012-08-07 Jan Beulich * gas/i386/vgather-check-error.{s,l}: New. diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index fb36423061..82cef63ab9 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -315,6 +315,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t run_dump_test "x86-64-stack-suffix" run_list_test "x86-64-inval" "-al" run_list_test "x86-64-segment" "-al" + run_dump_test "x86-64-segovr" run_list_test "x86-64-inval-seg" "-al" run_dump_test "x86-64-branch" run_dump_test "x86-64-relax-1" diff --git a/gas/testsuite/gas/i386/x86-64-segovr.d b/gas/testsuite/gas/i386/x86-64-segovr.d new file mode 100644 index 0000000000..76f85948ac --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-segovr.d @@ -0,0 +1,41 @@ +#objdump: -dw +#name: x86-64 segment overrides + +.*: +file format .* + +Disassembly of section .text: + +0+ : +[ ]*[a-f0-9]+: 8b 00[ ]+mov[ ]+\(%rax\),%eax +[ ]*[a-f0-9]+: 8b 01[ ]+mov[ ]+\(%rcx\),%eax +[ ]*[a-f0-9]+: 8b 02[ ]+mov[ ]+\(%rdx\),%eax +[ ]*[a-f0-9]+: 8b 03[ ]+mov[ ]+\(%rbx\),%eax +[ ]*[a-f0-9]+: 3e 8b 04 24[ ]+mov[ ]+%ds:\(%rsp\),%eax +[ ]*[a-f0-9]+: 3e 8b 45 00[ ]+mov[ ]+%ds:((0x)?0)?\(%rbp\),%eax +[ ]*[a-f0-9]+: 8b 06[ ]+mov[ ]+\(%rsi\),%eax +[ ]*[a-f0-9]+: 8b 07[ ]+mov[ ]+\(%rdi\),%eax +[ ]*[a-f0-9]+: 41 8b 00[ ]+mov[ ]+\(%r8\),%eax +[ ]*[a-f0-9]+: 41 8b 01[ ]+mov[ ]+\(%r9\),%eax +[ ]*[a-f0-9]+: 41 8b 02[ ]+mov[ ]+\(%r10\),%eax +[ ]*[a-f0-9]+: 41 8b 03[ ]+mov[ ]+\(%r11\),%eax +[ ]*[a-f0-9]+: 41 8b 04 24[ ]+mov[ ]+\(%r12\),%eax +[ ]*[a-f0-9]+: 41 8b 45 00[ ]+mov[ ]+((0x)?0)?\(%r13\),%eax +[ ]*[a-f0-9]+: 41 8b 06[ ]+mov[ ]+\(%r14\),%eax +[ ]*[a-f0-9]+: 41 8b 07[ ]+mov[ ]+\(%r15\),%eax +[ ]*[a-f0-9]+: 36 8b 00[ ]+mov[ ]+%ss:\(%rax\),%eax +[ ]*[a-f0-9]+: 36 8b 01[ ]+mov[ ]+%ss:\(%rcx\),%eax +[ ]*[a-f0-9]+: 36 8b 02[ ]+mov[ ]+%ss:\(%rdx\),%eax +[ ]*[a-f0-9]+: 36 8b 03[ ]+mov[ ]+%ss:\(%rbx\),%eax +[ ]*[a-f0-9]+: 8b 04 24[ ]+mov[ ]+\(%rsp\),%eax +[ ]*[a-f0-9]+: 8b 45 00[ ]+mov[ ]+((0x)?0)?\(%rbp\),%eax +[ ]*[a-f0-9]+: 36 8b 06[ ]+mov[ ]+%ss:\(%rsi\),%eax +[ ]*[a-f0-9]+: 36 8b 07[ ]+mov[ ]+%ss:\(%rdi\),%eax +[ ]*[a-f0-9]+: 36 41 8b 00[ ]+mov[ ]+%ss:\(%r8\),%eax +[ ]*[a-f0-9]+: 36 41 8b 01[ ]+mov[ ]+%ss:\(%r9\),%eax +[ ]*[a-f0-9]+: 36 41 8b 02[ ]+mov[ ]+%ss:\(%r10\),%eax +[ ]*[a-f0-9]+: 36 41 8b 03[ ]+mov[ ]+%ss:\(%r11\),%eax +[ ]*[a-f0-9]+: 36 41 8b 04 24[ ]+mov[ ]+%ss:\(%r12\),%eax +[ ]*[a-f0-9]+: 36 41 8b 45 00[ ]+mov[ ]+%ss:((0x)?0)?\(%r13\),%eax +[ ]*[a-f0-9]+: 36 41 8b 06[ ]+mov[ ]+%ss:\(%r14\),%eax +[ ]*[a-f0-9]+: 36 41 8b 07[ ]+mov[ ]+%ss:\(%r15\),%eax +#pass diff --git a/gas/testsuite/gas/i386/x86-64-segovr.s b/gas/testsuite/gas/i386/x86-64-segovr.s new file mode 100644 index 0000000000..08c045f231 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-segovr.s @@ -0,0 +1,9 @@ +# 64bit segment overrides + + .text +segovr: +.irp seg, ds, ss + .irp reg, ax, cx, dx, bx, sp, bp, si, di, 8, 9, 10, 11, 12, 13, 14, 15 + mov %\seg:(%r\reg), %eax + .endr +.endr