From bc31405ebb2c4297ae815ab59f59165014347528 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 27 Jan 2020 04:38:10 -0800 Subject: [PATCH] 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. --- gas/ChangeLog | 19 ++++++ gas/config/tc-i386.c | 4 +- gas/doc/c-i386.texi | 18 ++++++ gas/testsuite/gas/i386/i386.exp | 6 ++ gas/testsuite/gas/i386/x86-64-movsxd-intel.d | 26 ++++++++ .../gas/i386/x86-64-movsxd-intel64-intel.d | 26 ++++++++ .../gas/i386/x86-64-movsxd-intel64-inval.l | 27 ++++++++ .../gas/i386/x86-64-movsxd-intel64-inval.s | 14 +++++ .../gas/i386/x86-64-movsxd-intel64.d | 25 ++++++++ .../gas/i386/x86-64-movsxd-intel64.s | 20 ++++++ gas/testsuite/gas/i386/x86-64-movsxd-inval.l | 27 ++++++++ gas/testsuite/gas/i386/x86-64-movsxd-inval.s | 14 +++++ gas/testsuite/gas/i386/x86-64-movsxd.d | 25 ++++++++ gas/testsuite/gas/i386/x86-64-movsxd.s | 20 ++++++ opcodes/ChangeLog | 15 +++++ opcodes/i386-dis.c | 61 ++++++++++++++++++- opcodes/i386-opc.tbl | 4 +- opcodes/i386-tbl.h | 34 ++++++++++- 18 files changed, 378 insertions(+), 7 deletions(-) create mode 100644 gas/testsuite/gas/i386/x86-64-movsxd-intel.d create mode 100644 gas/testsuite/gas/i386/x86-64-movsxd-intel64-intel.d create mode 100644 gas/testsuite/gas/i386/x86-64-movsxd-intel64-inval.l create mode 100644 gas/testsuite/gas/i386/x86-64-movsxd-intel64-inval.s create mode 100644 gas/testsuite/gas/i386/x86-64-movsxd-intel64.d create mode 100644 gas/testsuite/gas/i386/x86-64-movsxd-intel64.s create mode 100644 gas/testsuite/gas/i386/x86-64-movsxd-inval.l create mode 100644 gas/testsuite/gas/i386/x86-64-movsxd-inval.s create mode 100644 gas/testsuite/gas/i386/x86-64-movsxd.d create mode 100644 gas/testsuite/gas/i386/x86-64-movsxd.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 6c182f59e19..91097845d46 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,22 @@ +2020-01-27 H.J. Lu + + 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 * 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 34778ae7605..e3c971ca499 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 6d556a01a10..9fb681e8729 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 aedcf147380..feab8c2be95 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 00000000000..b7f55d41681 --- /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 00000000000..1145df2971f --- /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 00000000000..b3219e0c671 --- /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 00000000000..2edcaf83302 --- /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 00000000000..afd26d93a51 --- /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 00000000000..842cdef42f5 --- /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 00000000000..7db46d6af39 --- /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 00000000000..84bf5209057 --- /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 00000000000..1881fe2e313 --- /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 00000000000..f0efd59319a --- /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] diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 585ba1f6f95..3076dac9f54 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,18 @@ +2020-01-27 H.J. Lu + Jan Beulich + + 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. + 2020-01-27 Tamar Christina PR 25403 diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index c73e964b546..e6f73bff206 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -124,6 +124,7 @@ static void OP_Vex_2src_1 (int, int); static void OP_Vex_2src_2 (int, int); static void MOVBE_Fixup (int, int); +static void MOVSXD_Fixup (int, int); static void OP_Mask (int, int); @@ -556,6 +557,7 @@ enum a_mode, cond_jump_mode, loop_jcxz_mode, + movsxd_mode, v_bnd_mode, /* like v_bnd_mode in 32bit, no RIP-rel in 64bit mode. */ v_bndmk_mode, @@ -6873,7 +6875,7 @@ static const struct dis386 x86_64_table[][2] = { /* X86_64_63 */ { { "arpl", { Ew, Gw }, 0 }, - { "movs{lq|xd}", { Gv, Ed }, 0 }, + { "movs", { { OP_G, movsxd_mode }, { MOVSXD_Fixup, movsxd_mode } }, 0 }, }, /* X86_64_6D */ @@ -13536,6 +13538,13 @@ intel_operand_size (int bytemode, int sizeflag) oappend ("DWORD PTR "); used_prefixes |= (prefixes & PREFIX_DATA); break; + case movsxd_mode: + if (!(sizeflag & DFLAG) && isa64 == intel64) + oappend ("WORD PTR "); + else + oappend ("DWORD PTR "); + used_prefixes |= (prefixes & PREFIX_DATA); + break; case d_mode: case d_scalar_mode: case d_scalar_swap_mode: @@ -13921,6 +13930,13 @@ OP_E_register (int bytemode, int sizeflag) used_prefixes |= (prefixes & PREFIX_DATA); } break; + case movsxd_mode: + if (!(sizeflag & DFLAG) && isa64 == intel64) + names = names16; + else + names = names32; + used_prefixes |= (prefixes & PREFIX_DATA); + break; case va_mode: names = (address_mode == mode_64bit ? names64 : names32); @@ -14492,12 +14508,14 @@ OP_G (int bytemode, int sizeflag) case dqb_mode: case dqd_mode: case dqw_mode: + case movsxd_mode: USED_REX (REX_W); if (rex & REX_W) oappend (names64[modrm.reg + add]); else { - if ((sizeflag & DFLAG) || bytemode != v_mode) + if ((sizeflag & DFLAG) + || (bytemode != v_mode && bytemode != movsxd_mode)) oappend (names32[modrm.reg + add]); else oappend (names16[modrm.reg + add]); @@ -16563,6 +16581,45 @@ skip: OP_M (bytemode, sizeflag); } +static void +MOVSXD_Fixup (int bytemode, int sizeflag) +{ + /* Add proper suffix to "movsxd". */ + char *p = mnemonicendp; + + switch (bytemode) + { + case movsxd_mode: + if (intel_syntax) + { + *p++ = 'x'; + *p++ = 'd'; + goto skip; + } + + USED_REX (REX_W); + if (rex & REX_W) + { + *p++ = 'l'; + *p++ = 'q'; + } + else + { + *p++ = 'x'; + *p++ = 'd'; + } + break; + default: + oappend (INTERNAL_DISASSEMBLER_ERROR); + break; + } + +skip: + mnemonicendp = p; + *p = '\0'; + OP_E (bytemode, sizeflag); +} + static void OP_LWPCB_E (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) { diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl index 2acb76bfa15..19793fdcd45 100644 --- a/opcodes/i386-opc.tbl +++ b/opcodes/i386-opc.tbl @@ -135,7 +135,9 @@ movsx, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf|R movsx, 2, 0xfbe, None, 2, Cpu386, Modrm|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IntelSyntax, { Reg8|Byte|BaseIndex, Reg16|Reg32|Reg64 } movsx, 2, 0xfbf, None, 2, Cpu386, Modrm|No_bSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf|IntelSyntax, { Reg16|Word|BaseIndex, Reg32|Reg64 } movsx, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64|IntelSyntax, { Reg32|Dword|BaseIndex, Reg64 } -movsxd, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_qSuf|No_ldSuf|Rex64, { Reg32|Dword|Unspecified|BaseIndex, Reg64 } +movsxd, 2, 0x63, None, 1, Cpu64, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg32|Reg64 } +movsxd, 2, 0x63, None, 1, Cpu64, AMD64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg32|Unspecified|BaseIndex, Reg16 } +movsxd, 2, 0x63, None, 1, Cpu64, Intel64|Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { Reg16|Unspecified|BaseIndex, Reg16 } // Move with zero extend. movzb, 2, 0xfb6, None, 2, Cpu386, Modrm|No_bSuf|No_sSuf|No_ldSuf, { Reg8|Byte|Unspecified|BaseIndex, Reg16|Reg32|Reg64 } diff --git a/opcodes/i386-tbl.h b/opcodes/i386-tbl.h index c8fa7e95a00..d1a6c0915a9 100644 --- a/opcodes/i386-tbl.h +++ b/opcodes/i386-tbl.h @@ -435,12 +435,40 @@ 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, 1, 0, 0 } }, - { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 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, 0 }, { { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 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, 1, + { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, + 0, 0, 0, 0, 0, 0 } } } }, + { "movsxd", 0x63, None, 1, 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, 0, 0, 1, 0, 0 } }, + { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 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, 1, 0 }, + { { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 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 } } } }, + { "movsxd", 0x63, None, 1, 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, 0, 0, 1, 0, 0 } }, + { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 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, 1 }, + { { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } } }, { "movzb", 0xfb6, None, 2, 2, { { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 2.30.2