From 4e511d4c19d2e6664f9631977c8722becdf9cb2a Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 2 Oct 2018 18:16:19 +0000 Subject: [PATCH] [X86][Disassembler] Add bizarro versions of the MOVSXD instruction that sign extend from a GR32 to GR32 or GR16. The 0x63 opcodes in 64-bit mode have a fixed source size of 32-bits, but the destination size is controlled by REX.W and the 0x66 opsize prefix. This instruction is normally used with a REX.W prefix which provides desired behavior. The other encodings are interpretted as valid by the processor, but aren't useful. This patch makes us recognize them for the disassembler to match objdump. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343614 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86InstrExtension.td | 20 ++++++++++++++++++++ test/MC/Disassembler/X86/x86-64.txt | 9 +++++++++ 2 files changed, 29 insertions(+) diff --git a/lib/Target/X86/X86InstrExtension.td b/lib/Target/X86/X86InstrExtension.td index 421792c5599..c24d6d5b8df 100644 --- a/lib/Target/X86/X86InstrExtension.td +++ b/lib/Target/X86/X86InstrExtension.td @@ -163,6 +163,26 @@ def MOVSX64rm32: RI<0x63, MRMSrcMem, (outs GR64:$dst), (ins i32mem:$src), [(set GR64:$dst, (sextloadi64i32 addr:$src))]>, Sched<[WriteALULd]>, Requires<[In64BitMode]>; +// These instructions exist as a consequence of operand size prefix having +// control of the destination size, but not the input size. Only support them +// for the disassembler. +let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in { +def MOVSX16rr32: I<0x63, MRMSrcReg, (outs GR16:$dst), (ins GR32:$src), + "movs{lq|xd}\t{$src, $dst|$dst, $src}", []>, + Sched<[WriteALU]>, OpSize16, Requires<[In64BitMode]>; +def MOVSX32rr32: I<0x63, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), + "movs{lq|xd}\t{$src, $dst|$dst, $src}", []>, + Sched<[WriteALU]>, OpSize32, Requires<[In64BitMode]>; +let mayLoad = 1 in { +def MOVSX16rm32: I<0x63, MRMSrcMem, (outs GR16:$dst), (ins i32mem:$src), + "movs{lq|xd}\t{$src, $dst|$dst, $src}", []>, + Sched<[WriteALULd]>, OpSize16, Requires<[In64BitMode]>; +def MOVSX32rm32: I<0x63, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), + "movs{lq|xd}\t{$src, $dst|$dst, $src}", []>, + Sched<[WriteALULd]>, OpSize32, Requires<[In64BitMode]>; +} // mayLoad = 1 +} // isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 + // movzbq and movzwq encodings for the disassembler let hasSideEffects = 0 in { def MOVZX64rr8 : RI<0xB6, MRMSrcReg, (outs GR64:$dst), (ins GR8:$src), diff --git a/test/MC/Disassembler/X86/x86-64.txt b/test/MC/Disassembler/X86/x86-64.txt index ae0e95a5095..dcf9e7b923b 100644 --- a/test/MC/Disassembler/X86/x86-64.txt +++ b/test/MC/Disassembler/X86/x86-64.txt @@ -622,3 +622,12 @@ # 0x67 prefix prints %eip instead of %rip #CHECK: addb %al, (%eip) 0x67,0x00,0x05,0x00,0x00,0x00,0x00 + +# CHECK: movslq %eax, %eax +0x63 0xc0 +# CHECK: movslq %eax, %ax +0x66 0x63 0xc0 +# CHECK: movslq (%rax), %ecx +0x63 0x08 +# CHECK: movslq (%rax), %cx +0x66 0x63 0x08