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 | |
parent | e3696f67abfc46dcac6c9bbe47f8e25e34b17be5 (diff) | |
download | fsf-binutils-gdb-bc31405ebb2c4297ae815ab59f59165014347528.zip fsf-binutils-gdb-bc31405ebb2c4297ae815ab59f59165014347528.tar.gz fsf-binutils-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.
-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 | ||||
-rw-r--r-- | opcodes/ChangeLog | 15 | ||||
-rw-r--r-- | opcodes/i386-dis.c | 61 | ||||
-rw-r--r-- | opcodes/i386-opc.tbl | 4 | ||||
-rw-r--r-- | opcodes/i386-tbl.h | 34 |
18 files changed, 378 insertions, 7 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] diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 585ba1f..3076dac 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,18 @@ +2020-01-27 H.J. Lu <hongjiu.lu@intel.com> + Jan Beulich <jbeulich@suse.com> + + 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 <tamar.christina@arm.com> PR 25403 diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index c73e964..e6f73bf 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]); @@ -16564,6 +16582,45 @@ skip: } 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) { int reg; diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl index 2acb76b..19793fd 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 c8fa7e9..d1a6c09 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, |