x86-64: Properly encode and decode movsxd
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 27 Jan 2020 12:38:10 +0000 (04:38 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Mon, 27 Jan 2020 12:38:29 +0000 (04:38 -0800)
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.

18 files changed:
gas/ChangeLog
gas/config/tc-i386.c
gas/doc/c-i386.texi
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/x86-64-movsxd-intel.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-movsxd-intel64-intel.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-movsxd-intel64-inval.l [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-movsxd-intel64-inval.s [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-movsxd-intel64.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-movsxd-intel64.s [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-movsxd-inval.l [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-movsxd-inval.s [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-movsxd.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-movsxd.s [new file with mode: 0644]
opcodes/ChangeLog
opcodes/i386-dis.c
opcodes/i386-opc.tbl
opcodes/i386-tbl.h

index 6c182f59e1915a2bd5563bf4ee631236805a46f3..91097845d467c6b8209bf7f38b2e84533924ff76 100644 (file)
@@ -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
index 34778ae7605d353769db07a1c73eb8de3824266c..e3c971ca499885876d939c0dbfdd493649e51ef8 100644 (file)
@@ -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. */
index 6d556a01a10ab6f50d601d25529cd19495ad10fa..9fb681e87297bbae848238139d1dd063846df461 100644 (file)
@@ -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
 
index aedcf147380ae1400bfbd88ccdcb2a27d0ef806e..feab8c2be95cff1eb6566a0071b025d4709f91f9 100644 (file)
@@ -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 (file)
index 0000000..b7f55d4
--- /dev/null
@@ -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 (file)
index 0000000..1145df2
--- /dev/null
@@ -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 (file)
index 0000000..b3219e0
--- /dev/null
@@ -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 (file)
index 0000000..2edcaf8
--- /dev/null
@@ -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 (file)
index 0000000..afd26d9
--- /dev/null
@@ -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 (file)
index 0000000..842cdef
--- /dev/null
@@ -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 (file)
index 0000000..7db46d6
--- /dev/null
@@ -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 (file)
index 0000000..84bf520
--- /dev/null
@@ -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 (file)
index 0000000..1881fe2
--- /dev/null
@@ -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 (file)
index 0000000..f0efd59
--- /dev/null
@@ -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]
index 585ba1f6f9516541945b2b6a779f9a78c645a33c..3076dac9f54d8cd3e4ef656e9d794ced84d4f603 100644 (file)
@@ -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
index c73e964b5469b6f43c6a54f2a3227ad37dd71960..e6f73bff20676b7c224e716f7bcccb2feb500c80 100644 (file)
@@ -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)
 {
index 2acb76bfa151d6d2e0905b10af5fe033c9eb09b7..19793fdcd45ee9261ad3fb63d4087fb79f9003c4 100644 (file)
@@ -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 }
index c8fa7e95a0063854c3b34c7fb807309080522850..d1a6c0915a9fd76f4987de22651bef249b5da33a 100644 (file)
@@ -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,