diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2020-01-27 04:38:10 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2020-01-27 04:38:29 -0800 |
commit | bc31405ebb2c4297ae815ab59f59165014347528 (patch) | |
tree | 4298be1f20f511497e961d2e672f38b0d2e75bf6 /gas | |
parent | e3696f67abfc46dcac6c9bbe47f8e25e34b17be5 (diff) | |
download | gdb-bc31405ebb2c4297ae815ab59f59165014347528.zip gdb-bc31405ebb2c4297ae815ab59f59165014347528.tar.gz gdb-bc31405ebb2c4297ae815ab59f59165014347528.tar.bz2 |
x86-64: Properly encode and decode movsxd
movsxd is a 64-bit only instruction. It supports both 16-bit and 32-bit
destination registers. Its AT&T mnemonic is movslq which only supports
64-bit destination register. There is also a discrepancy between AMD64
and Intel64 on movsxd with 16-bit destination register. AMD64 supports
32-bit source operand and Intel64 supports 16-bit source operand.
This patch updates movsxd encoding and decoding to alow 16-bit and 32-bit
destination registers. It also handles movsxd with 16-bit destination
register for AMD64 and Intel 64.
gas/
PR binutils/25445
* config/tc-i386.c (check_long_reg): Also convert to QWORD for
movsxd.
* doc/c-i386.texi: Add a node for AMD64 vs. Intel64 ISA
differences. Document movslq and movsxd.
* testsuite/gas/i386/i386.exp: Run PR binutils/25445 tests.
* testsuite/gas/i386/x86-64-movsxd-intel.d: New file.
* testsuite/gas/i386/x86-64-movsxd-intel64-intel.d: Likewise.
* testsuite/gas/i386/x86-64-movsxd-intel64-inval.l: Likewise.
* testsuite/gas/i386/x86-64-movsxd-intel64-inval.s: Likewise.
* testsuite/gas/i386/x86-64-movsxd-intel64.d: Likewise.
* testsuite/gas/i386/x86-64-movsxd-intel64.s: Likewise.
* testsuite/gas/i386/x86-64-movsxd-inval.l: Likewise.
* testsuite/gas/i386/x86-64-movsxd-inval.s: Likewise.
* testsuite/gas/i386/x86-64-movsxd.d: Likewise.
* testsuite/gas/i386/x86-64-movsxd.s: Likewise.
opcodes/
PR binutils/25445
* i386-dis.c (MOVSXD_Fixup): New function.
(movsxd_mode): New enum.
(x86_64_table): Use MOVSXD_Fixup and movsxd_mode on movsxd.
(intel_operand_size): Handle movsxd_mode.
(OP_E_register): Likewise.
(OP_G): Likewise.
* i386-opc.tbl: Remove Rex64 and allow 32-bit destination
register on movsxd. Add movsxd with 16-bit destination register
for AMD64 and Intel64 ISAs.
* i386-tbl.h: Regenerated.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 19 | ||||
-rw-r--r-- | gas/config/tc-i386.c | 4 | ||||
-rw-r--r-- | gas/doc/c-i386.texi | 18 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/i386.exp | 6 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-movsxd-intel.d | 26 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-movsxd-intel64-intel.d | 26 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-movsxd-intel64-inval.l | 27 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-movsxd-intel64-inval.s | 14 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-movsxd-intel64.d | 25 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-movsxd-intel64.s | 20 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-movsxd-inval.l | 27 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-movsxd-inval.s | 14 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-movsxd.d | 25 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/x86-64-movsxd.s | 20 |
14 files changed, 270 insertions, 1 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 6c182f5..9109784 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,22 @@ +2020-01-27 H.J. Lu <hongjiu.lu@intel.com> + + PR binutils/25445 + * config/tc-i386.c (check_long_reg): Also convert to QWORD for + movsxd. + * doc/c-i386.texi: Add a node for AMD64 vs. Intel64 ISA + differences. Document movslq and movsxd. + * testsuite/gas/i386/i386.exp: Run PR binutils/25445 tests. + * testsuite/gas/i386/x86-64-movsxd-intel.d: New file. + * testsuite/gas/i386/x86-64-movsxd-intel64-intel.d: Likewise. + * testsuite/gas/i386/x86-64-movsxd-intel64-inval.l: Likewise. + * testsuite/gas/i386/x86-64-movsxd-intel64-inval.s: Likewise. + * testsuite/gas/i386/x86-64-movsxd-intel64.d: Likewise. + * testsuite/gas/i386/x86-64-movsxd-intel64.s: Likewise. + * testsuite/gas/i386/x86-64-movsxd-inval.l: Likewise. + * testsuite/gas/i386/x86-64-movsxd-inval.s: Likewise. + * testsuite/gas/i386/x86-64-movsxd.d: Likewise. + * testsuite/gas/i386/x86-64-movsxd.s: Likewise. + 2020-01-27 Alan Modra <amodra@gmail.com> * testsuite/gas/all/gas.exp: Replace case statements with switch diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 34778ae..e3c971c 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -6690,7 +6690,9 @@ check_long_reg (void) && i.tm.operand_types[op].bitfield.dword) { if (intel_syntax - && i.tm.opcode_modifier.toqword + && (i.tm.opcode_modifier.toqword + /* Also convert to QWORD for MOVSXD. */ + || i.tm.base_opcode == 0x63) && i.types[0].bitfield.class != RegSIMD) { /* Convert to QWORD. We want REX byte. */ diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi index 6d556a0..9fb681e 100644 --- a/gas/doc/c-i386.texi +++ b/gas/doc/c-i386.texi @@ -37,6 +37,7 @@ extending the Intel architecture to 64-bits. * i386-TBM:: AMD's Trailing Bit Manipulation Instructions * i386-16bit:: Writing 16-bit Code * i386-Arch:: Specifying an x86 CPU architecture +* i386-ISA:: AMD64 ISA vs. Intel64 ISA * i386-Bugs:: AT&T Syntax bugs * i386-Notes:: Notes @end menu @@ -856,6 +857,12 @@ Several x87 instructions, @samp{fadd}, @samp{fdiv}, @samp{fdivp}, assembler with different mnemonics from those in Intel IA32 specification. @code{@value{GCC}} generates those instructions with AT&T mnemonic. +@itemize @bullet +@item @samp{movslq} with AT&T mnemonic only accepts 64-bit destination +register. @samp{movsxd} should be used to encode 16-bit or 32-bit +destination register with both AT&T and Intel mnemonics. +@end itemize + @node i386-Regs @section Register Naming @@ -1438,6 +1445,17 @@ For example .arch i8086,nojumps @end smallexample +@node i386-ISA +@section AMD64 ISA vs. Intel64 ISA + +There are some discrepancies between AMD64 and Intel64 ISAs. + +@itemize @bullet +@item For @samp{movsxd} with 16-bit destination register, AMD64 +supports 32-bit source operand and Intel64 supports 16-bit source +operand. +@end itemize + @node i386-Bugs @section AT&T Syntax bugs diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index aedcf14..feab8c2 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -1050,6 +1050,12 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t run_dump_test "x86-64-movd-intel" run_dump_test "x86-64-nop-1" run_dump_test "x86-64-nop-2" + run_dump_test "x86-64-movsxd" + run_dump_test "x86-64-movsxd-intel" + run_list_test "x86-64-movsxd-inval" "-al" + run_dump_test "x86-64-movsxd-intel64" + run_dump_test "x86-64-movsxd-intel64-intel" + run_list_test "x86-64-movsxd-intel64-inval" "-mintel64 -al" run_dump_test "x86-64-optimize-1" run_dump_test "x86-64-optimize-2" run_dump_test "x86-64-optimize-2a" diff --git a/gas/testsuite/gas/i386/x86-64-movsxd-intel.d b/gas/testsuite/gas/i386/x86-64-movsxd-intel.d new file mode 100644 index 0000000..b7f55d4 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-movsxd-intel.d @@ -0,0 +1,26 @@ +#source: x86-64-movsxd.s +#as: +#objdump: -dw -Mintel +#name: x86-64 movsxd (AMD64) (Intel mode) + +.*: +file format .* + +Disassembly of section .text: + +0+ <_start>: + +[a-f0-9]+: 48 63 c8 movsxd rcx,eax + +[a-f0-9]+: 48 63 08 movsxd rcx,DWORD PTR \[rax\] + +[a-f0-9]+: 63 c8 movsxd ecx,eax + +[a-f0-9]+: 63 08 movsxd ecx,DWORD PTR \[rax\] + +[a-f0-9]+: 66 63 c8 movsxd cx,eax + +[a-f0-9]+: 66 63 08 movsxd cx,DWORD PTR \[rax\] + +[a-f0-9]+: 48 63 c8 movsxd rcx,eax + +[a-f0-9]+: 48 63 08 movsxd rcx,DWORD PTR \[rax\] + +[a-f0-9]+: 48 63 08 movsxd rcx,DWORD PTR \[rax\] + +[a-f0-9]+: 63 c8 movsxd ecx,eax + +[a-f0-9]+: 63 08 movsxd ecx,DWORD PTR \[rax\] + +[a-f0-9]+: 63 08 movsxd ecx,DWORD PTR \[rax\] + +[a-f0-9]+: 66 63 c8 movsxd cx,eax + +[a-f0-9]+: 63 08 movsxd ecx,DWORD PTR \[rax\] + +[a-f0-9]+: 66 63 08 movsxd cx,DWORD PTR \[rax\] +#pass diff --git a/gas/testsuite/gas/i386/x86-64-movsxd-intel64-intel.d b/gas/testsuite/gas/i386/x86-64-movsxd-intel64-intel.d new file mode 100644 index 0000000..1145df2 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-movsxd-intel64-intel.d @@ -0,0 +1,26 @@ +#source: x86-64-movsxd-intel64.s +#as: -mintel64 +#objdump: -dw -Mintel -Mintel64 +#name: x86-64 movsxd (Intel64) (Intel mode) + +.*: +file format .* + +Disassembly of section .text: + +0+ <_start>: + +[a-f0-9]+: 48 63 c8 movsxd rcx,eax + +[a-f0-9]+: 48 63 08 movsxd rcx,DWORD PTR \[rax\] + +[a-f0-9]+: 63 c8 movsxd ecx,eax + +[a-f0-9]+: 63 08 movsxd ecx,DWORD PTR \[rax\] + +[a-f0-9]+: 66 63 c8 movsxd cx,ax + +[a-f0-9]+: 66 63 08 movsxd cx,WORD PTR \[rax\] + +[a-f0-9]+: 48 63 c8 movsxd rcx,eax + +[a-f0-9]+: 48 63 08 movsxd rcx,DWORD PTR \[rax\] + +[a-f0-9]+: 48 63 08 movsxd rcx,DWORD PTR \[rax\] + +[a-f0-9]+: 63 c8 movsxd ecx,eax + +[a-f0-9]+: 63 08 movsxd ecx,DWORD PTR \[rax\] + +[a-f0-9]+: 63 08 movsxd ecx,DWORD PTR \[rax\] + +[a-f0-9]+: 66 63 c8 movsxd cx,ax + +[a-f0-9]+: 66 63 08 movsxd cx,WORD PTR \[rax\] + +[a-f0-9]+: 66 63 08 movsxd cx,WORD PTR \[rax\] +#pass diff --git a/gas/testsuite/gas/i386/x86-64-movsxd-intel64-inval.l b/gas/testsuite/gas/i386/x86-64-movsxd-intel64-inval.l new file mode 100644 index 0000000..b3219e0 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-movsxd-intel64-inval.l @@ -0,0 +1,27 @@ +.*: Assembler messages: +.*:4: Error: .* +.*:5: Error: .* +.*:6: Error: .* +.*:7: Error: .* +.*:10: Error: .* +.*:11: Error: .* +.*:12: Error: .* +.*:13: Error: .* +.*:14: Error: .* +GAS LISTING .* + + +[ ]*1[ ]+\# 64-bit only invalid MOVSXD with Intel64 ISA +[ ]*2[ ]+\.text +[ ]*3[ ]+_start: +[ ]*4[ ]+movslq %eax, %cx +[ ]*5[ ]+movslq %eax, %ecx +[ ]*6[ ]+movslq \(%rax\), %ecx +[ ]*7[ ]+movsxd %ax, %ecx +[ ]*8[ ]+ +[ ]*9[ ]+\.intel_syntax noprefix +[ ]*10[ ]+movslq cx, ax +[ ]*11[ ]+movslq ecx, eax +[ ]*12[ ]+movslq ecx, \[rax\] +[ ]*13[ ]+movsxd cx, eax +[ ]*14[ ]+movsxd cx, DWORD PTR \[rax\] diff --git a/gas/testsuite/gas/i386/x86-64-movsxd-intel64-inval.s b/gas/testsuite/gas/i386/x86-64-movsxd-intel64-inval.s new file mode 100644 index 0000000..2edcaf8 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-movsxd-intel64-inval.s @@ -0,0 +1,14 @@ +# 64-bit only invalid MOVSXD with Intel64 ISA + .text +_start: + movslq %eax, %cx + movslq %eax, %ecx + movslq (%rax), %ecx + movsxd %ax, %ecx + + .intel_syntax noprefix + movslq cx, ax + movslq ecx, eax + movslq ecx, [rax] + movsxd cx, eax + movsxd cx, DWORD PTR [rax] diff --git a/gas/testsuite/gas/i386/x86-64-movsxd-intel64.d b/gas/testsuite/gas/i386/x86-64-movsxd-intel64.d new file mode 100644 index 0000000..afd26d9 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-movsxd-intel64.d @@ -0,0 +1,25 @@ +#as: -mintel64 +#objdump: -dw -Mintel64 +#name: x86-64 movsxd (Intel64) + +.*: +file format .* + +Disassembly of section .text: + +0+ <_start>: + +[a-f0-9]+: 48 63 c8 movslq %eax,%rcx + +[a-f0-9]+: 48 63 08 movslq \(%rax\),%rcx + +[a-f0-9]+: 63 c8 movsxd %eax,%ecx + +[a-f0-9]+: 63 08 movsxd \(%rax\),%ecx + +[a-f0-9]+: 66 63 c8 movsxd %ax,%cx + +[a-f0-9]+: 66 63 08 movsxd \(%rax\),%cx + +[a-f0-9]+: 48 63 c8 movslq %eax,%rcx + +[a-f0-9]+: 48 63 08 movslq \(%rax\),%rcx + +[a-f0-9]+: 48 63 08 movslq \(%rax\),%rcx + +[a-f0-9]+: 63 c8 movsxd %eax,%ecx + +[a-f0-9]+: 63 08 movsxd \(%rax\),%ecx + +[a-f0-9]+: 63 08 movsxd \(%rax\),%ecx + +[a-f0-9]+: 66 63 c8 movsxd %ax,%cx + +[a-f0-9]+: 66 63 08 movsxd \(%rax\),%cx + +[a-f0-9]+: 66 63 08 movsxd \(%rax\),%cx +#pass diff --git a/gas/testsuite/gas/i386/x86-64-movsxd-intel64.s b/gas/testsuite/gas/i386/x86-64-movsxd-intel64.s new file mode 100644 index 0000000..842cdef --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-movsxd-intel64.s @@ -0,0 +1,20 @@ +# 64-bit only MOVSXD with Intel64 ISA + .text +_start: + movslq %eax, %rcx + movslq (%rax), %rcx + movsxd %eax, %ecx + movsxd (%rax), %ecx + movsxd %ax, %cx + movsxd (%rax), %cx + + .intel_syntax noprefix + movsxd rcx, eax + movsxd rcx, DWORD PTR [rax] + movsxd rcx, [rax] + movsxd ecx, eax + movsxd ecx, DWORD PTR [rax] + movsxd ecx, [rax] + movsxd cx, ax + movsxd cx, WORD PTR [rax] + movsxd cx, [rax] diff --git a/gas/testsuite/gas/i386/x86-64-movsxd-inval.l b/gas/testsuite/gas/i386/x86-64-movsxd-inval.l new file mode 100644 index 0000000..7db46d6 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-movsxd-inval.l @@ -0,0 +1,27 @@ +.*: Assembler messages: +.*:4: Error: .* +.*:5: Error: .* +.*:6: Error: .* +.*:7: Error: .* +.*:10: Error: .* +.*:11: Error: .* +.*:12: Error: .* +.*:13: Error: .* +.*:14: Error: .* +GAS LISTING .* + + +[ ]*1[ ]+\# 64-bit only invalid MOVSXD with AMD64 ISA +[ ]*2[ ]+\.text +[ ]*3[ ]+_start: +[ ]*4[ ]+movslq %ax, %cx +[ ]*5[ ]+movslq %eax, %ecx +[ ]*6[ ]+movslq \(%rax\), %ecx +[ ]*7[ ]+movsxd %ax, %cx +[ ]*8[ ]+ +[ ]*9[ ]+\.intel_syntax noprefix +[ ]*10[ ]+movslq cx, eax +[ ]*11[ ]+movslq ecx, eax +[ ]*12[ ]+movslq ecx, \[rax\] +[ ]*13[ ]+movsxd cx, ax +[ ]*14[ ]+movsxd cx, WORD PTR \[rax\] diff --git a/gas/testsuite/gas/i386/x86-64-movsxd-inval.s b/gas/testsuite/gas/i386/x86-64-movsxd-inval.s new file mode 100644 index 0000000..84bf520 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-movsxd-inval.s @@ -0,0 +1,14 @@ +# 64-bit only invalid MOVSXD with AMD64 ISA + .text +_start: + movslq %ax, %cx + movslq %eax, %ecx + movslq (%rax), %ecx + movsxd %ax, %cx + + .intel_syntax noprefix + movslq cx, eax + movslq ecx, eax + movslq ecx, [rax] + movsxd cx, ax + movsxd cx, WORD PTR [rax] diff --git a/gas/testsuite/gas/i386/x86-64-movsxd.d b/gas/testsuite/gas/i386/x86-64-movsxd.d new file mode 100644 index 0000000..1881fe2 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-movsxd.d @@ -0,0 +1,25 @@ +#as: +#objdump: -dw +#name: x86-64 movsxd (AMD64) + +.*: +file format .* + +Disassembly of section .text: + +0+ <_start>: + +[a-f0-9]+: 48 63 c8 movslq %eax,%rcx + +[a-f0-9]+: 48 63 08 movslq \(%rax\),%rcx + +[a-f0-9]+: 63 c8 movsxd %eax,%ecx + +[a-f0-9]+: 63 08 movsxd \(%rax\),%ecx + +[a-f0-9]+: 66 63 c8 movsxd %eax,%cx + +[a-f0-9]+: 66 63 08 movsxd \(%rax\),%cx + +[a-f0-9]+: 48 63 c8 movslq %eax,%rcx + +[a-f0-9]+: 48 63 08 movslq \(%rax\),%rcx + +[a-f0-9]+: 48 63 08 movslq \(%rax\),%rcx + +[a-f0-9]+: 63 c8 movsxd %eax,%ecx + +[a-f0-9]+: 63 08 movsxd \(%rax\),%ecx + +[a-f0-9]+: 63 08 movsxd \(%rax\),%ecx + +[a-f0-9]+: 66 63 c8 movsxd %eax,%cx + +[a-f0-9]+: 63 08 movsxd \(%rax\),%ecx + +[a-f0-9]+: 66 63 08 movsxd \(%rax\),%cx +#pass diff --git a/gas/testsuite/gas/i386/x86-64-movsxd.s b/gas/testsuite/gas/i386/x86-64-movsxd.s new file mode 100644 index 0000000..f0efd59 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-movsxd.s @@ -0,0 +1,20 @@ +# 64-bit only MOVSXD with AMD64 ISA + .text +_start: + movslq %eax, %rcx + movslq (%rax), %rcx + movsxd %eax, %ecx + movsxd (%rax), %ecx + movsxd %eax, %cx + movsxd (%rax), %cx + + .intel_syntax noprefix + movsxd rcx, eax + movsxd rcx, DWORD PTR [rax] + movsxd rcx, [rax] + movsxd ecx, eax + movsxd ecx, DWORD PTR [rax] + movsxd ecx, [rax] + movsxd cx, eax + movsxd cx, DWORD PTR [rax] + movsxd cx, [rax] |