[PATCH] x86-64: Properly encode and decode movsxd
H.J. Lu
hjl.tools@gmail.com
Thu Jan 23 20:25:00 GMT 2020
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.
(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/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/i386-dis.c | 61 ++++++++++++++++++-
opcodes/i386-opc.tbl | 4 +-
opcodes/i386-tbl.h | 34 ++++++++++-
16 files changed, 344 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/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/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.24.1
More information about the Binutils
mailing list