diff --git a/llvm/lib/Target/X86/AsmParser/X86Operand.h b/llvm/lib/Target/X86/AsmParser/X86Operand.h --- a/llvm/lib/Target/X86/AsmParser/X86Operand.h +++ b/llvm/lib/Target/X86/AsmParser/X86Operand.h @@ -380,6 +380,40 @@ bool isMem512_RC512() const { return isMem512() && isMemIndexReg(X86::ZMM0, X86::ZMM31); } + bool isMem512_GR16() const { + if (!isMem512()) + return false; + if (getMemBaseReg() && + !X86MCRegisterClasses[X86::GR16RegClassID].contains(getMemBaseReg())) + return false; + return true; + } + bool isMem512_GR32() const { + if (!isMem512()) + return false; + if (getMemBaseReg() && + !X86MCRegisterClasses[X86::GR32RegClassID].contains(getMemBaseReg()) && + getMemBaseReg() != X86::EIP) + return false; + if (getMemIndexReg() && + !X86MCRegisterClasses[X86::GR32RegClassID].contains(getMemIndexReg()) && + getMemIndexReg() != X86::EIZ) + return false; + return true; + } + bool isMem512_GR64() const { + if (!isMem512()) + return false; + if (getMemBaseReg() && + !X86MCRegisterClasses[X86::GR64RegClassID].contains(getMemBaseReg()) && + getMemBaseReg() != X86::RIP) + return false; + if (getMemIndexReg() && + !X86MCRegisterClasses[X86::GR64RegClassID].contains(getMemIndexReg()) && + getMemIndexReg() != X86::RIZ) + return false; + return true; + } bool isAbsMem() const { return Kind == Memory && !getMemSegReg() && !getMemBaseReg() && diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -380,6 +380,9 @@ def X86Mem512_RC256XOperand : AsmOperandClass { let Name = "Mem512_RC256X"; } def X86Mem256_RC512Operand : AsmOperandClass { let Name = "Mem256_RC512"; } def X86Mem512_RC512Operand : AsmOperandClass { let Name = "Mem512_RC512"; } + def X86Mem512_GR16Operand : AsmOperandClass { let Name = "Mem512_GR16"; } + def X86Mem512_GR32Operand : AsmOperandClass { let Name = "Mem512_GR32"; } + def X86Mem512_GR64Operand : AsmOperandClass { let Name = "Mem512_GR64"; } def X86SibMemOperand : AsmOperandClass { let Name = "SibMem"; } } @@ -432,6 +435,11 @@ def f256mem : X86MemOperand<"printymmwordmem", X86Mem256AsmOperand, 256>; def f512mem : X86MemOperand<"printzmmwordmem", X86Mem512AsmOperand, 512>; +// 32/64 mode specific mem operands +def i512mem_GR16 : X86MemOperand<"printzmmwordmem", X86Mem512_GR16Operand, 512>; +def i512mem_GR32 : X86MemOperand<"printzmmwordmem", X86Mem512_GR32Operand, 512>; +def i512mem_GR64 : X86MemOperand<"printzmmwordmem", X86Mem512_GR64Operand, 512>; + // Gather mem operands def vx64mem : X86VMemOperand; def vx128mem : X86VMemOperand; diff --git a/llvm/lib/Target/X86/X86InstrMisc.td b/llvm/lib/Target/X86/X86InstrMisc.td --- a/llvm/lib/Target/X86/X86InstrMisc.td +++ b/llvm/lib/Target/X86/X86InstrMisc.td @@ -1521,14 +1521,14 @@ // MOVDIR64B - Move 64 bytes as direct store // let SchedRW = [WriteStore] in { -def MOVDIR64B16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src), +def MOVDIR64B16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem_GR16:$src), "movdir64b\t{$src, $dst|$dst, $src}", []>, T8PD, AdSize16, Requires<[HasMOVDIR64B, Not64BitMode]>; -def MOVDIR64B32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src), +def MOVDIR64B32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem_GR32:$src), "movdir64b\t{$src, $dst|$dst, $src}", [(int_x86_movdir64b GR32:$dst, addr:$src)]>, T8PD, AdSize32, Requires<[HasMOVDIR64B]>; -def MOVDIR64B64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src), +def MOVDIR64B64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem_GR64:$src), "movdir64b\t{$src, $dst|$dst, $src}", [(int_x86_movdir64b GR64:$dst, addr:$src)]>, T8PD, AdSize64, Requires<[HasMOVDIR64B, In64BitMode]>; diff --git a/llvm/test/MC/X86/index-operations.s b/llvm/test/MC/X86/index-operations.s --- a/llvm/test/MC/X86/index-operations.s +++ b/llvm/test/MC/X86/index-operations.s @@ -160,3 +160,29 @@ // ERR32: 64-bit // ERR16: 64-bit +movdir64b 291(%si), %ecx +// ERR32: invalid operand +// ERR16: invalid operand + +movdir64b 291(%esi), %cx +// ERR32: invalid operand +// ERR16: invalid operand + +movdir64b (%rdx), %r15d +// ERR64: invalid operand + +movdir64b (%edx), %r15 +// ERR64: invalid operand + +movdir64b (%eip), %ebx +// 64: movdir64b (%eip), %ebx # encoding: [0x67,0x66,0x0f,0x38,0xf8,0x1d,0x00,0x00,0x00,0x00] + +movdir64b (%rip), %rbx +// 64: movdir64b (%rip), %rbx # encoding: [0x66,0x0f,0x38,0xf8,0x1d,0x00,0x00,0x00,0x00] + +movdir64b 291(%esi, %eiz, 4), %ebx +// 64: movdir64b 291(%esi,%eiz,4), %ebx # encoding: [0x67,0x66,0x0f,0x38,0xf8,0x9c,0xa6,0x23,0x01,0x00,0x00] +// 32: movdir64b 291(%esi,%eiz,4), %ebx # encoding: [0x66,0x0f,0x38,0xf8,0x9c,0xa6,0x23,0x01,0x00,0x00] + +movdir64b 291(%rsi, %riz, 4), %rbx +// 64: movdir64b 291(%rsi,%riz,4), %rbx # encoding: [0x66,0x0f,0x38,0xf8,0x9c,0xa6,0x23,0x01,0x00,0x00] \ No newline at end of file diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp --- a/llvm/utils/TableGen/X86RecognizableInstr.cpp +++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp @@ -955,6 +955,9 @@ TYPE("i128mem", TYPE_M) TYPE("i256mem", TYPE_M) TYPE("i512mem", TYPE_M) + TYPE("i512mem_GR16", TYPE_M) + TYPE("i512mem_GR32", TYPE_M) + TYPE("i512mem_GR64", TYPE_M) TYPE("i64i32imm_brtarget", TYPE_REL) TYPE("i16imm_brtarget", TYPE_REL) TYPE("i32imm_brtarget", TYPE_REL) @@ -1221,6 +1224,9 @@ ENCODING("i128mem", ENCODING_RM) ENCODING("i256mem", ENCODING_RM) ENCODING("i512mem", ENCODING_RM) + ENCODING("i512mem_GR16", ENCODING_RM) + ENCODING("i512mem_GR32", ENCODING_RM) + ENCODING("i512mem_GR64", ENCODING_RM) ENCODING("f80mem", ENCODING_RM) ENCODING("lea64_32mem", ENCODING_RM) ENCODING("lea64mem", ENCODING_RM)