aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2020-01-27 04:38:10 -0800
committerH.J. Lu <hjl.tools@gmail.com>2020-01-27 04:38:29 -0800
commitbc31405ebb2c4297ae815ab59f59165014347528 (patch)
tree4298be1f20f511497e961d2e672f38b0d2e75bf6
parente3696f67abfc46dcac6c9bbe47f8e25e34b17be5 (diff)
downloadbinutils-bc31405ebb2c4297ae815ab59f59165014347528.zip
binutils-bc31405ebb2c4297ae815ab59f59165014347528.tar.gz
binutils-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/ChangeLog19
-rw-r--r--gas/config/tc-i386.c4
-rw-r--r--gas/doc/c-i386.texi18
-rw-r--r--gas/testsuite/gas/i386/i386.exp6
-rw-r--r--gas/testsuite/gas/i386/x86-64-movsxd-intel.d26
-rw-r--r--gas/testsuite/gas/i386/x86-64-movsxd-intel64-intel.d26
-rw-r--r--gas/testsuite/gas/i386/x86-64-movsxd-intel64-inval.l27
-rw-r--r--gas/testsuite/gas/i386/x86-64-movsxd-intel64-inval.s14
-rw-r--r--gas/testsuite/gas/i386/x86-64-movsxd-intel64.d25
-rw-r--r--gas/testsuite/gas/i386/x86-64-movsxd-intel64.s20
-rw-r--r--gas/testsuite/gas/i386/x86-64-movsxd-inval.l27
-rw-r--r--gas/testsuite/gas/i386/x86-64-movsxd-inval.s14
-rw-r--r--gas/testsuite/gas/i386/x86-64-movsxd.d25
-rw-r--r--gas/testsuite/gas/i386/x86-64-movsxd.s20
-rw-r--r--opcodes/ChangeLog15
-rw-r--r--opcodes/i386-dis.c61
-rw-r--r--opcodes/i386-opc.tbl4
-rw-r--r--opcodes/i386-tbl.h34
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,