This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 2/3] x86-64: correct / adjust prefix emission
- From: Jan Beulich <jbeulich at suse dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Cc: "H.J. Lu" <hjl dot tools at gmail dot com>
- Date: Fri, 20 Dec 2019 11:39:34 +0100
- Subject: [PATCH 2/3] x86-64: correct / adjust prefix emission
- References: <e6cb32e1-eb85-5f93-7e0a-e19e8363afbd@suse.com>
First and foremost REX must come last. Next JumpInterSegment branches
can't possibly have a REX prefix, as they're consistently CpuNo64. And
finally make BND prefix handling in output_branch() consistent with that
of other prefixes in the same function, and make its placement among
prefixes consistent with output_jump() (which, oddly enough, still isn't
the supposedly canonical order specified by the *_PREFIX definitions).
gas/
2019-12-XX Jan Beulich <jbeulich@suse.com>
* config/tc-i386-intel.c (output_branch): Handle BND prefix the
same way as other prefixes. Emit it last before REX.
(output_jump): Emit BND before REX.
(output_interseg_jump): Don't emit REX.
* testsuite/gas/i386/x86-64-branch-2.s,
testsuite/gas/i386/x86-64-branch-3.s,
testsuite/gas/i386/x86-64-mpx-branch-1.s,
testsuite/gas/i386/x86-64-mpx-branch-2.s: Add REX.W cases.
* testsuite/gas/i386/x86-64-mpx-branch-2.d: Match output against
x86-64-mpx-branch-1.d.
* testsuite/gas/i386/x86-64-branch-2.d,
testsuite/gas/i386/x86-64-branch-3.d,
testsuite/gas/i386/x86-64-mpx-branch-1.d: Adjust expectations.
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -7912,8 +7912,8 @@ output_branch (void)
/* BND prefixed jump. */
if (i.prefix[BND_PREFIX] != 0)
{
- FRAG_APPEND_1_CHAR (i.prefix[BND_PREFIX]);
- i.prefixes -= 1;
+ prefix++;
+ i.prefixes--;
}
if (i.prefixes != 0 && !intel_syntax)
@@ -7932,6 +7932,8 @@ output_branch (void)
if (i.prefix[SEG_PREFIX] == CS_PREFIX_OPCODE
|| i.prefix[SEG_PREFIX] == DS_PREFIX_OPCODE)
*p++ = i.prefix[SEG_PREFIX];
+ if (i.prefix[BND_PREFIX] != 0)
+ *p++ = BND_PREFIX_OPCODE;
if (i.prefix[REX_PREFIX] != 0)
*p++ = i.prefix[REX_PREFIX];
*p = i.tm.base_opcode;
@@ -8044,16 +8046,16 @@ output_jump (void)
size = 2;
}
- if (i.prefix[REX_PREFIX] != 0)
+ /* BND prefixed jump. */
+ if (i.prefix[BND_PREFIX] != 0)
{
- FRAG_APPEND_1_CHAR (i.prefix[REX_PREFIX]);
+ FRAG_APPEND_1_CHAR (i.prefix[BND_PREFIX]);
i.prefixes -= 1;
}
- /* BND prefixed jump. */
- if (i.prefix[BND_PREFIX] != 0)
+ if (i.prefix[REX_PREFIX] != 0)
{
- FRAG_APPEND_1_CHAR (i.prefix[BND_PREFIX]);
+ FRAG_APPEND_1_CHAR (i.prefix[REX_PREFIX]);
i.prefixes -= 1;
}
@@ -8111,11 +8113,8 @@ output_interseg_jump (void)
i.prefixes -= 1;
code16 ^= CODE16;
}
- if (i.prefix[REX_PREFIX] != 0)
- {
- prefix++;
- i.prefixes -= 1;
- }
+
+ gas_assert (!i.prefix[REX_PREFIX]);
size = 4;
if (code16)
--- a/gas/testsuite/gas/i386/x86-64-branch-2.d
+++ b/gas/testsuite/gas/i386/x86-64-branch-2.d
@@ -6,10 +6,12 @@
Disassembly of section .text:
-0+ <bar-0x4>:
-[ ]*[a-f0-9]+: 66 e9 00 00 jmpw 4 <bar> 2: R_X86_64_PC16 foo-0x2
+0+ <bar-0xb>:
+[ ]*[a-f0-9]+: 66 e9 00 00 jmpw 4 <bar-0x7> 2: R_X86_64_PC16 foo-0x2
+[ ]*[a-f0-9]+: 66 48 e9 00 00 00 00 data16 jmpq b <bar> 7: R_X86_64_PLT32 foo-0x4
-0+4 <bar>:
+0+b <bar>:
[ ]*[a-f0-9]+: 89 c3 mov %eax,%ebx
-[ ]*[a-f0-9]+: 66 e8 00 00 callw a <bar\+0x6> 8: R_X86_64_PC16 foo-0x2
+[ ]*[a-f0-9]+: 66 e8 00 00 callw 11 <bar\+0x6> f: R_X86_64_PC16 foo-0x2
+[ ]*[a-f0-9]+: 66 48 e8 00 00 00 00 data16 callq 18 <bar\+0xd> 14: R_X86_64_PLT32 foo-0x4
#pass
--- a/gas/testsuite/gas/i386/x86-64-branch-2.s
+++ b/gas/testsuite/gas/i386/x86-64-branch-2.s
@@ -1,7 +1,9 @@
.text
data16 jmp foo
+ data16 rex.w jmp foo
bar:
mov %eax, %ebx
data16 call foo
+ data16 rex.w call foo
--- a/gas/testsuite/gas/i386/x86-64-branch-3.d
+++ b/gas/testsuite/gas/i386/x86-64-branch-3.d
@@ -6,11 +6,14 @@
Disassembly of section .text:
-0+ <bar-0x6>:
-[ ]*[a-f0-9]+: 66 e9 00 00 00 00 data16 jmpq 6 <bar> 2: R_X86_64_PLT32 foo-0x4
+0+ <bar-0xd>:
+[ ]*[a-f0-9]+: 66 e9 00 00 00 00 data16 jmpq 6 <bar-0x7> 2: R_X86_64_PLT32 foo-0x4
+[ ]*[a-f0-9]+: 66 48 e9 00 00 00 00 data16 rex\.W jmpq d <bar> 9: R_X86_64_PLT32 foo-0x4
-0+6 <bar>:
+0+d <bar>:
[ ]*[a-f0-9]+: 89 c3 mov %eax,%ebx
-[ ]*[a-f0-9]+: 66 e8 00 00 00 00 data16 callq e <bar\+0x8> a: R_X86_64_PLT32 foo-0x4
-[ ]*[a-f0-9]+: 66 c7 f8 00 00 xbeginw 13 <bar\+0xd> 11: R_X86_64_PC16 foo-0x2
+[ ]*[a-f0-9]+: 66 e8 00 00 00 00 data16 callq 15 <bar\+0x8> 11: R_X86_64_PLT32 foo-0x4
+[ ]*[a-f0-9]+: 66 48 e8 00 00 00 00 data16 rex\.W callq 1c <bar\+0xf> 18: R_X86_64_PLT32 foo-0x4
+[ ]*[a-f0-9]+: 66 c7 f8 00 00 xbeginw 21 <bar\+0x14> 1f: R_X86_64_PC16 foo-0x2
+[ ]*[a-f0-9]+: 66 48 c7 f8 00 00 00 00 data16 xbeginq 29 <bar\+0x1c> 25: R_X86_64_PLT32 foo-0x4
#pass
--- a/gas/testsuite/gas/i386/x86-64-branch-3.s
+++ b/gas/testsuite/gas/i386/x86-64-branch-3.s
@@ -1,9 +1,12 @@
.text
data16 jmp foo
+ data16 rex.w jmp foo
bar:
mov %eax, %ebx
data16 call foo
+ data16 rex.w call foo
data16 xbegin foo
+ data16 rex.w xbegin foo
--- a/gas/testsuite/gas/i386/x86-64-mpx-branch-1.d
+++ b/gas/testsuite/gas/i386/x86-64-mpx-branch-1.d
@@ -8,22 +8,24 @@
Disassembly of section .text:
-0+ <foo1-0xc>:
-[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 6 <foo1-0x6> 2: R_X86_64_PC32 \*ABS\*\+0x10003c
-[ ]*[a-f0-9]+: f2 e9 00 00 00 00 bnd jmpq c <foo1> 8: R_X86_64_PC32 \*ABS\*\+0x10003c
+0+ <foo1-0x1c>:
+[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 6 <foo1-0x16> 2: R_X86_64_PC32 \*ABS\*\+0x10003c
+[ ]*[a-f0-9]+: f2 e9 00 00 00 00 bnd jmpq c <foo1-0x10> 8: R_X86_64_PC32 \*ABS\*\+0x10003c
+[ ]*[a-f0-9]+: 66 f2 48 e8 00 00 00 00 data16 bnd callq 14 <foo1-0x8> 10: R_X86_64_PC32 \*ABS\*\+0x10003c
+[ ]*[a-f0-9]+: 66 f2 48 e9 00 00 00 00 data16 bnd jmpq 1c <foo1> 18: R_X86_64_PC32 \*ABS\*\+0x10003c
-0+c <foo1>:
-[ ]*[a-f0-9]+: f2 eb fd bnd jmp c <foo1>
-[ ]*[a-f0-9]+: f2 72 fa bnd jb c <foo1>
-[ ]*[a-f0-9]+: f2 e8 f4 ff ff ff bnd callq c <foo1>
-[ ]*[a-f0-9]+: f2 eb 09 bnd jmp 24 <foo2>
-[ ]*[a-f0-9]+: f2 72 06 bnd jb 24 <foo2>
-[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 24 <foo2>
+0+1c <foo1>:
+[ ]*[a-f0-9]+: f2 eb fd bnd jmp 1c <foo1>
+[ ]*[a-f0-9]+: f2 72 fa bnd jb 1c <foo1>
+[ ]*[a-f0-9]+: f2 e8 f4 ff ff ff bnd callq 1c <foo1>
+[ ]*[a-f0-9]+: f2 eb 09 bnd jmp 34 <foo2>
+[ ]*[a-f0-9]+: f2 72 06 bnd jb 34 <foo2>
+[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 34 <foo2>
-0+24 <foo2>:
-[ ]*[a-f0-9]+: f2 e9 00 00 00 00 bnd jmpq 2a <foo2\+0x6> 26: R_X86_64_PLT32 foo-0x4
-[ ]*[a-f0-9]+: f2 0f 82 00 00 00 00 bnd jb 31 <foo2\+0xd> 2d: R_X86_64_PLT32 foo-0x4
-[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 37 <foo2\+0x13> 33: R_X86_64_PLT32 foo-0x4
-[ ]*[a-f0-9]+: f2 e9 00 00 00 00 bnd jmpq 3d <foo2\+0x19> 39: R_X86_64_PLT32 foo-0x4
-[ ]*[a-f0-9]+: f2 0f 82 00 00 00 00 bnd jb 44 <foo2\+0x20> 40: R_X86_64_PLT32 foo-0x4
-[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 4a <foo2\+0x26> 46: R_X86_64_PLT32 foo-0x4
+0+34 <foo2>:
+[ ]*[a-f0-9]+: f2 e9 00 00 00 00 bnd jmpq 3a <foo2\+0x6> 36: R_X86_64_PLT32 foo-0x4
+[ ]*[a-f0-9]+: f2 0f 82 00 00 00 00 bnd jb 41 <foo2\+0xd> 3d: R_X86_64_PLT32 foo-0x4
+[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 47 <foo2\+0x13> 43: R_X86_64_PLT32 foo-0x4
+[ ]*[a-f0-9]+: f2 e9 00 00 00 00 bnd jmpq 4d <foo2\+0x19> 49: R_X86_64_PLT32 foo-0x4
+[ ]*[a-f0-9]+: f2 0f 82 00 00 00 00 bnd jb 54 <foo2\+0x20> 50: R_X86_64_PLT32 foo-0x4
+[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 5a <foo2\+0x26> 56: R_X86_64_PLT32 foo-0x4
--- a/gas/testsuite/gas/i386/x86-64-mpx-branch-1.s
+++ b/gas/testsuite/gas/i386/x86-64-mpx-branch-1.s
@@ -2,6 +2,9 @@
bnd call 0x100040
bnd jmp 0x100040
+ bnd data16 rex.w call 0x100040
+ bnd data16 rex.w jmp 0x100040
+
foo1:
bnd jmp foo1
bnd jb foo1
--- a/gas/testsuite/gas/i386/x86-64-mpx-branch-2.d
+++ b/gas/testsuite/gas/i386/x86-64-mpx-branch-2.d
@@ -1,29 +1,5 @@
#as: -J -madd-bnd-prefix
#objdump: -dwr
#name: x86-64 branch with BND prefix
+#dump: x86-64-mpx-branch-1.d
#notarget: *-*-solaris*
-
-.*: +file format .*
-
-
-Disassembly of section .text:
-
-0+ <foo1-0xc>:
-[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 6 <foo1-0x6> 2: R_X86_64_PC32 \*ABS\*\+0x10003c
-[ ]*[a-f0-9]+: f2 e9 00 00 00 00 bnd jmpq c <foo1> 8: R_X86_64_PC32 \*ABS\*\+0x10003c
-
-0+c <foo1>:
-[ ]*[a-f0-9]+: f2 eb fd bnd jmp c <foo1>
-[ ]*[a-f0-9]+: f2 72 fa bnd jb c <foo1>
-[ ]*[a-f0-9]+: f2 e8 f4 ff ff ff bnd callq c <foo1>
-[ ]*[a-f0-9]+: f2 eb 09 bnd jmp 24 <foo2>
-[ ]*[a-f0-9]+: f2 72 06 bnd jb 24 <foo2>
-[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 24 <foo2>
-
-0+24 <foo2>:
-[ ]*[a-f0-9]+: f2 e9 00 00 00 00 bnd jmpq 2a <foo2\+0x6> 26: R_X86_64_PLT32 foo-0x4
-[ ]*[a-f0-9]+: f2 0f 82 00 00 00 00 bnd jb 31 <foo2\+0xd> 2d: R_X86_64_PLT32 foo-0x4
-[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 37 <foo2\+0x13> 33: R_X86_64_PLT32 foo-0x4
-[ ]*[a-f0-9]+: f2 e9 00 00 00 00 bnd jmpq 3d <foo2\+0x19> 39: R_X86_64_PLT32 foo-0x4
-[ ]*[a-f0-9]+: f2 0f 82 00 00 00 00 bnd jb 44 <foo2\+0x20> 40: R_X86_64_PLT32 foo-0x4
-[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 4a <foo2\+0x26> 46: R_X86_64_PLT32 foo-0x4
--- a/gas/testsuite/gas/i386/x86-64-mpx-branch-2.s
+++ b/gas/testsuite/gas/i386/x86-64-mpx-branch-2.s
@@ -2,6 +2,9 @@
call 0x100040
jmp 0x100040
+ data16 rex.w call 0x100040
+ data16 rex.w jmp 0x100040
+
foo1:
jmp foo1
jb foo1