From 9b20fece812ff8f745a2772c414f285fcb810695 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 22 Aug 2016 07:38:45 +0000 Subject: [PATCH] [X86] Create a new instruction format to handle MemOp4 encoding. This saves one bit in TSFlags and simplifies MRMSrcMem/MRMSrcReg format handling. llvm-svn: 279423 --- llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h | 24 ++++--- .../Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp | 80 +++++++++++++++++----- llvm/lib/Target/X86/X86InstrFMA.td | 32 ++++----- llvm/lib/Target/X86/X86InstrFormats.td | 15 ++-- llvm/lib/Target/X86/X86InstrXOP.td | 40 +++++------ llvm/utils/TableGen/X86RecognizableInstr.cpp | 43 ++++++++---- llvm/utils/TableGen/X86RecognizableInstr.h | 2 - 7 files changed, 151 insertions(+), 85 deletions(-) diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index 0493ccb..2751b6a 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -277,6 +277,11 @@ namespace X86II { /// MRMSrcMem = 33, + /// MRMSrcMemOp4 - This form is used for instructions that use the Mod/RM + /// byte to specify the fourth source, which in this case is memory. + /// + MRMSrcMemOp4 = 34, + /// MRMXm - This form is used for instructions that use the Mod/RM byte /// to specify a memory source, but doesn't use the middle field. /// @@ -296,6 +301,11 @@ namespace X86II { /// MRMSrcReg = 49, + /// MRMSrcRegOp4 - This form is used for instructions that use the Mod/RM + /// byte to specify the fourth source, which in this case is a register. + /// + MRMSrcRegOp4 = 50, + /// MRMXr - This form is used for instructions that use the Mod/RM byte /// to specify a register source, but doesn't use the middle field. /// @@ -536,13 +546,8 @@ namespace X86II { Has3DNow0F0FOpcodeShift = CD8_Scale_Shift + 7, Has3DNow0F0FOpcode = 1ULL << Has3DNow0F0FOpcodeShift, - /// MemOp4 - Used to indicate swapping of operand 3 and 4 to be encoded in - /// ModRM or I8IMM. This is used for FMA4 and XOP instructions. - MemOp4Shift = Has3DNow0F0FOpcodeShift + 1, - MemOp4 = 1ULL << MemOp4Shift, - /// Explicitly specified rounding control - EVEX_RCShift = MemOp4Shift + 1, + EVEX_RCShift = Has3DNow0F0FOpcodeShift + 1, EVEX_RC = 1ULL << EVEX_RCShift }; @@ -649,7 +654,6 @@ namespace X86II { /// inline int getMemoryOperandNo(uint64_t TSFlags) { bool HasVEX_4V = TSFlags & X86II::VEX_4V; - bool HasMemOp4 = TSFlags & X86II::MemOp4; bool HasEVEX_K = TSFlags & X86II::EVEX_K; switch (TSFlags & X86II::FormMask) { @@ -669,9 +673,13 @@ namespace X86II { case X86II::MRMSrcMem: // Start from 1, skip any registers encoded in VEX_VVVV or I8IMM, or a // mask register. - return 1 + HasVEX_4V + HasMemOp4 + HasEVEX_K; + return 1 + HasVEX_4V + HasEVEX_K; + case X86II::MRMSrcMemOp4: + // Skip registers encoded in reg, VEX_VVVV, and I8IMM. + return 3; case X86II::MRMDestReg: case X86II::MRMSrcReg: + case X86II::MRMSrcRegOp4: case X86II::MRMXr: case X86II::MRM0r: case X86II::MRM1r: case X86II::MRM2r: case X86II::MRM3r: diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index 4128c4fb..05b905f 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -603,7 +603,6 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, bool HasEVEX_K = TSFlags & X86II::EVEX_K; bool HasVEX_4V = TSFlags & X86II::VEX_4V; bool HasVEX_4VOp3 = TSFlags & X86II::VEX_4VOp3; - bool HasMemOp4 = TSFlags & X86II::MemOp4; bool HasEVEX_RC = TSFlags & X86II::EVEX_RC; // VEX_R: opcode externsion equivalent to REX.R in @@ -749,7 +748,6 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, // // FMA4: // dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(Imm[7:4]) - // dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M), unsigned RegEnc = getX86RegEncoding(MI, CurOp++); VEX_R = ~(RegEnc >> 3) & 1; EVEX_R2 = ~(RegEnc >> 4) & 1; @@ -779,6 +777,20 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, VEX_4V = ~getX86RegEncoding(MI, CurOp + X86::AddrNumOperands) & 0xf; break; } + case X86II::MRMSrcMemOp4: { + // dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M), + unsigned RegEnc = getX86RegEncoding(MI, CurOp++); + VEX_R = ~(RegEnc >> 3) & 1; + + unsigned VRegEnc = getX86RegEncoding(MI, CurOp++); + VEX_4V = ~VRegEnc & 0xf; + + unsigned BaseRegEnc = getX86RegEncoding(MI, MemOperand + X86::AddrBaseReg); + VEX_B = ~(BaseRegEnc >> 3) & 1; + unsigned IndexRegEnc = getX86RegEncoding(MI, MemOperand+X86::AddrIndexReg); + VEX_X = ~(IndexRegEnc >> 3) & 1; + break; + } case X86II::MRM0m: case X86II::MRM1m: case X86II::MRM2m: case X86II::MRM3m: case X86II::MRM4m: case X86II::MRM5m: @@ -808,7 +820,6 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, // dst(ModR/M), src1(ModR/M), imm8 // // FMA4: - // dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(Imm[7:4]) // dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M), unsigned RegEnc = getX86RegEncoding(MI, CurOp++); VEX_R = ~(RegEnc >> 3) & 1; @@ -823,9 +834,6 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, EVEX_V2 = ~(VRegEnc >> 4) & 1; } - if (HasMemOp4) // Skip second register source (encoded in Imm[7:4]) - CurOp++; - RegEnc = getX86RegEncoding(MI, CurOp++); VEX_B = ~(RegEnc >> 3) & 1; VEX_X = ~(RegEnc >> 4) & 1; @@ -841,6 +849,22 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, } break; } + case X86II::MRMSrcRegOp4: { + // dst(ModR/M.reg), src1(VEX_4V), src2(Imm[7:4]), src3(ModR/M), + unsigned RegEnc = getX86RegEncoding(MI, CurOp++); + VEX_R = ~(RegEnc >> 3) & 1; + + unsigned VRegEnc = getX86RegEncoding(MI, CurOp++); + VEX_4V = ~VRegEnc & 0xf; + + // Skip second register source (encoded in Imm[7:4]) + ++CurOp; + + RegEnc = getX86RegEncoding(MI, CurOp++); + VEX_B = ~(RegEnc >> 3) & 1; + VEX_X = ~(RegEnc >> 4) & 1; + break; + } case X86II::MRMDestReg: { // MRMDestReg instructions forms: // dst(ModR/M), src(ModR/M) @@ -1134,9 +1158,7 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS, // It uses the VEX.VVVV field? bool HasVEX_4V = TSFlags & X86II::VEX_4V; bool HasVEX_4VOp3 = TSFlags & X86II::VEX_4VOp3; - bool HasMemOp4 = TSFlags & X86II::MemOp4; bool HasVEX_I8Reg = (TSFlags & X86II::ImmMask) == X86II::Imm8Reg; - assert((!HasMemOp4 || HasVEX_I8Reg) && "MemOp4 should imply VEX_I8Reg"); // It uses the EVEX.aaa field? bool HasEVEX_K = TSFlags & X86II::EVEX_K; @@ -1312,21 +1334,34 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS, if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV) ++SrcRegNum; - if (HasMemOp4) // Capture 2nd src (which is encoded in Imm[7:4]) - I8RegNum = getX86RegEncoding(MI, SrcRegNum++); - EmitRegModRMByte(MI.getOperand(SrcRegNum), GetX86RegNum(MI.getOperand(CurOp)), CurByte, OS); CurOp = SrcRegNum + 1; if (HasVEX_4VOp3) ++CurOp; - if (!HasMemOp4 && HasVEX_I8Reg) + if (HasVEX_I8Reg) I8RegNum = getX86RegEncoding(MI, CurOp++); // do not count the rounding control operand if (HasEVEX_RC) --NumOps; break; } + case X86II::MRMSrcRegOp4: { + EmitByte(BaseOpcode, CurByte, OS); + unsigned SrcRegNum = CurOp + 1; + + // Skip 1st src (which is encoded in VEX_VVVV) + ++SrcRegNum; + + // Capture 2nd src (which is encoded in Imm[7:4]) + assert(HasVEX_I8Reg && "MRMSrcRegOp4 should imply VEX_I8Reg"); + I8RegNum = getX86RegEncoding(MI, SrcRegNum++); + + EmitRegModRMByte(MI.getOperand(SrcRegNum), + GetX86RegNum(MI.getOperand(CurOp)), CurByte, OS); + CurOp = SrcRegNum + 1; + break; + } case X86II::MRMSrcMem: { unsigned FirstMemOp = CurOp+1; @@ -1336,9 +1371,6 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS, if (HasVEX_4V) ++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV). - if (HasMemOp4) // Capture second register source (encoded in Imm[7:4]) - I8RegNum = getX86RegEncoding(MI, FirstMemOp++); - EmitByte(BaseOpcode, CurByte, OS); emitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)), @@ -1346,10 +1378,26 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS, CurOp = FirstMemOp + X86::AddrNumOperands; if (HasVEX_4VOp3) ++CurOp; - if (!HasMemOp4 && HasVEX_I8Reg) + if (HasVEX_I8Reg) I8RegNum = getX86RegEncoding(MI, CurOp++); break; } + case X86II::MRMSrcMemOp4: { + unsigned FirstMemOp = CurOp+1; + + ++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV). + + // Capture second register source (encoded in Imm[7:4]) + assert(HasVEX_I8Reg && "MRMSrcRegOp4 should imply VEX_I8Reg"); + I8RegNum = getX86RegEncoding(MI, FirstMemOp++); + + EmitByte(BaseOpcode, CurByte, OS); + + emitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)), + TSFlags, Rex, CurByte, OS, Fixups, STI); + CurOp = FirstMemOp + X86::AddrNumOperands; + break; + } case X86II::MRMXr: case X86II::MRM0r: case X86II::MRM1r: diff --git a/llvm/lib/Target/X86/X86InstrFMA.td b/llvm/lib/Target/X86/X86InstrFMA.td index 49cf6dc..cbf60d8 100644 --- a/llvm/lib/Target/X86/X86InstrFMA.td +++ b/llvm/lib/Target/X86/X86InstrFMA.td @@ -269,18 +269,18 @@ multiclass fma4s opc, string OpcodeStr, RegisterClass RC, X86MemOperand x86memop, ValueType OpVT, SDNode OpNode, PatFrag mem_frag> { let isCommutable = 1 in - def rr : FMA4, VEX_W, VEX_LIG, MemOp4; - def rm : FMA4, VEX_W, VEX_LIG; + def rm : FMA4, VEX_W, VEX_LIG, MemOp4; + (mem_frag addr:$src3)))]>, VEX_W, VEX_LIG; def mr : FMA4 opc, string OpcodeStr, Operand memop, ComplexPattern mem_cpat, Intrinsic Int> { let isCodeGenOnly = 1 in { let isCommutable = 1 in - def rr_Int : FMA4, VEX_W, VEX_LIG, MemOp4; - def rm_Int : FMA4, VEX_W, VEX_LIG; + def rm_Int : FMA4, VEX_W, VEX_LIG, MemOp4; + mem_cpat:$src3))]>, VEX_W, VEX_LIG; def mr_Int : FMA4 opc, string OpcodeStr, SDNode OpNode, ValueType OpVT128, ValueType OpVT256, PatFrag ld_frag128, PatFrag ld_frag256> { let isCommutable = 1 in - def rr : FMA4, - VEX_W, MemOp4; - def rm : FMA4, VEX_W, MemOp4; + (ld_frag128 addr:$src3)))]>, VEX_W; def mr : FMA4 opc, string OpcodeStr, SDNode OpNode, [(set VR128:$dst, (OpNode VR128:$src1, (ld_frag128 addr:$src2), VR128:$src3))]>; let isCommutable = 1 in - def Yrr : FMA4, - VEX_W, MemOp4, VEX_L; - def Yrm : FMA4, VEX_W, MemOp4, VEX_L; + (ld_frag256 addr:$src3)))]>, VEX_W, VEX_L; def Ymr : FMA4; def RawFrmDstSrc : Format<6>; def RawFrmImm8 : Format<7>; def RawFrmImm16 : Format<8>; -def MRMDestMem : Format<32>; -def MRMSrcMem : Format<33>; +def MRMDestMem : Format<32>; +def MRMSrcMem : Format<33>; +def MRMSrcMemOp4 : Format<34>; def MRMXm : Format<39>; def MRM0m : Format<40>; def MRM1m : Format<41>; def MRM2m : Format<42>; def MRM3m : Format<43>; def MRM4m : Format<44>; def MRM5m : Format<45>; def MRM6m : Format<46>; def MRM7m : Format<47>; -def MRMDestReg : Format<48>; -def MRMSrcReg : Format<49>; +def MRMDestReg : Format<48>; +def MRMSrcReg : Format<49>; +def MRMSrcRegOp4 : Format<50>; def MRMXr : Format<55>; def MRM0r : Format<56>; def MRM1r : Format<57>; def MRM2r : Format<58>; def MRM3r : Format<59>; def MRM4r : Format<60>; def MRM5r : Format<61>; @@ -218,7 +220,6 @@ class EVEX_CD8 { } class Has3DNow0F0FOpcode { bit has3DNow0F0FOpcode = 1; } -class MemOp4 { bit hasMemOp4Prefix = 1; } class XOP { Encoding OpEnc = EncXOP; } class XOP_4V : XOP { bit hasVEX_4V = 1; } class XOP_4VOp3 : XOP { bit hasVEX_4VOp3 = 1; } @@ -284,7 +285,6 @@ class X86Inst opcod, Format f, ImmType i, dag outs, dag ins, // assigning to bits<7>. int CD8_EltSize = 0; // Compressed disp8 form - element-size in bytes. bit has3DNow0F0FOpcode =0;// Wacky 3dNow! encoding? - bit hasMemOp4Prefix = 0; // Same bit as VEX_W, but used for swapping operands bit hasEVEX_RC = 0; // Explicitly specified rounding control in FP instruction. bits<2> EVEX_LL; @@ -330,8 +330,7 @@ class X86Inst opcod, Format f, ImmType i, dag outs, dag ins, // If we run out of TSFlags bits, it's possible to encode this in 3 bits. let TSFlags{53-47} = CD8_Scale; let TSFlags{54} = has3DNow0F0FOpcode; - let TSFlags{55} = hasMemOp4Prefix; - let TSFlags{56} = hasEVEX_RC; + let TSFlags{55} = hasEVEX_RC; } class PseudoI pattern> diff --git a/llvm/lib/Target/X86/X86InstrXOP.td b/llvm/lib/Target/X86/X86InstrXOP.td index 1834780..d498797 100644 --- a/llvm/lib/Target/X86/X86InstrXOP.td +++ b/llvm/lib/Target/X86/X86InstrXOP.td @@ -232,14 +232,14 @@ multiclass xop4op opc, string OpcodeStr, SDNode OpNode, (vt128 (OpNode (vt128 VR128:$src1), (vt128 VR128:$src2), (vt128 VR128:$src3))))]>, XOP_4V; - def rrm : IXOPi8Reg, - XOP_4V, VEX_W, MemOp4; + XOP_4V, VEX_W; def rmr : IXOPi8Reg opc, string OpcodeStr, SDNode OpNode, XOP_4V; // For disassembler let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in - def rrr_REV : IXOPi8Reg, XOP_4V, VEX_W, MemOp4; + []>, XOP_4V, VEX_W; } let ExeDomain = SSEPackedInt in { @@ -271,14 +271,14 @@ multiclass xop4op_int opc, string OpcodeStr, "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), [(set VR128:$dst, (Int128 VR128:$src1, VR128:$src2, VR128:$src3))]>, XOP_4V; - def rrm : IXOPi8Reg, - XOP_4V, VEX_W, MemOp4; + XOP_4V, VEX_W; def rmr : IXOPi8Reg opc, string OpcodeStr, XOP_4V; // For disassembler let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in - def rrr_REV : IXOPi8Reg, XOP_4V, VEX_W, MemOp4; + []>, XOP_4V, VEX_W; // 256-bit Instruction def rrrY : IXOPi8Reg opc, string OpcodeStr, "\t{$src3, $src2, $src1, $dst|$dst, $src1, $src2, $src3}"), [(set VR256:$dst, (Int256 VR256:$src1, VR256:$src2, VR256:$src3))]>, XOP_4V, VEX_L; - def rrmY : IXOPi8Reg, - XOP_4V, VEX_W, MemOp4, VEX_L; + XOP_4V, VEX_W, VEX_L; def rmrY : IXOPi8Reg opc, string OpcodeStr, XOP_4V, VEX_L; // For disassembler let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in - def rrrY_REV : IXOPi8Reg, XOP_4V, VEX_W, MemOp4, VEX_L; + []>, XOP_4V, VEX_W, VEX_L; } let ExeDomain = SSEPackedInt in { @@ -353,7 +353,7 @@ multiclass xop5op opc, string OpcodeStr, SDNode OpNode, [(set VR128:$dst, (vt128 (OpNode (vt128 VR128:$src1), (vt128 VR128:$src2), (id128 VR128:$src3), (i8 imm:$src4))))]>; - def rm : IXOP5 opc, string OpcodeStr, SDNode OpNode, (vt128 (OpNode (vt128 VR128:$src1), (vt128 VR128:$src2), (id128 (bitconvert (loadv2i64 addr:$src3))), (i8 imm:$src4))))]>, - VEX_W, MemOp4; + VEX_W; def mr : IXOP5 opc, string OpcodeStr, SDNode OpNode, (id128 VR128:$src3), (i8 imm:$src4))))]>; // For disassembler let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in - def rr_REV : IXOP5, VEX_W, MemOp4; + []>, VEX_W; def rrY : IXOP5 opc, string OpcodeStr, SDNode OpNode, [(set VR256:$dst, (vt256 (OpNode (vt256 VR256:$src1), (vt256 VR256:$src2), (id256 VR256:$src3), (i8 imm:$src4))))]>, VEX_L; - def rmY : IXOP5, VEX_W, MemOp4, VEX_L; + (i8 imm:$src4))))]>, VEX_W, VEX_L; def mrY : IXOP5 opc, string OpcodeStr, SDNode OpNode, (id256 VR256:$src3), (i8 imm:$src4))))]>, VEX_L; // For disassembler let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in - def rrY_REV : IXOP5, VEX_W, MemOp4, VEX_L; + []>, VEX_W, VEX_L; } let ExeDomain = SSEPackedDouble in diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp index b337a7c..c30ef65 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.cpp +++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp @@ -100,13 +100,15 @@ namespace X86Local { RawFrmDstSrc = 6, RawFrmImm8 = 7, RawFrmImm16 = 8, - MRMDestMem = 32, - MRMSrcMem = 33, + MRMDestMem = 32, + MRMSrcMem = 33, + MRMSrcMemOp4 = 34, MRMXm = 39, MRM0m = 40, MRM1m = 41, MRM2m = 42, MRM3m = 43, MRM4m = 44, MRM5m = 45, MRM6m = 46, MRM7m = 47, - MRMDestReg = 48, - MRMSrcReg = 49, + MRMDestReg = 48, + MRMSrcReg = 49, + MRMSrcRegOp4 = 50, MRMXr = 55, MRM0r = 56, MRM1r = 57, MRM2r = 58, MRM3r = 59, MRM4r = 60, MRM5r = 61, MRM6r = 62, MRM7r = 63, @@ -201,7 +203,6 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables, HasVEX_4V = Rec->getValueAsBit("hasVEX_4V"); HasVEX_4VOp3 = Rec->getValueAsBit("hasVEX_4VOp3"); HasVEX_WPrefix = Rec->getValueAsBit("hasVEX_WPrefix"); - HasMemOp4Prefix = Rec->getValueAsBit("hasMemOp4Prefix"); IgnoresVEX_L = Rec->getValueAsBit("ignoresVEX_L"); HasEVEX_L2Prefix = Rec->getValueAsBit("hasEVEX_L2"); HasEVEX_K = Rec->getValueAsBit("hasEVEX_K"); @@ -653,19 +654,24 @@ void RecognizableInstr::emitInstructionSpecifier() { // in ModRMVEX and the one above the one in the VEX.VVVV field HANDLE_OPERAND(vvvvRegister) - if (HasMemOp4Prefix) - HANDLE_OPERAND(immediate) - HANDLE_OPERAND(rmRegister) if (HasVEX_4VOp3) HANDLE_OPERAND(vvvvRegister) - if (!HasMemOp4Prefix) - HANDLE_OPTIONAL(immediate) + HANDLE_OPTIONAL(immediate) HANDLE_OPTIONAL(immediate) // above might be a register in 7:4 HANDLE_OPTIONAL(immediate) break; + case X86Local::MRMSrcRegOp4: + assert(numPhysicalOperands >= 4 && numPhysicalOperands <= 5 && + "Unexpected number of operands for MRMSrcRegOp4Frm"); + HANDLE_OPERAND(roRegister) + HANDLE_OPERAND(vvvvRegister) + HANDLE_OPERAND(immediate) // Register in imm[7:4] + HANDLE_OPERAND(rmRegister) + HANDLE_OPTIONAL(immediate) + break; case X86Local::MRMSrcMem: // Operand 1 is a register operand in the Reg/Opcode field. // Operand 2 is a memory operand (possibly SIB-extended) @@ -686,18 +692,23 @@ void RecognizableInstr::emitInstructionSpecifier() { // in ModRMVEX and the one above the one in the VEX.VVVV field HANDLE_OPERAND(vvvvRegister) - if (HasMemOp4Prefix) - HANDLE_OPERAND(immediate) - HANDLE_OPERAND(memory) if (HasVEX_4VOp3) HANDLE_OPERAND(vvvvRegister) - if (!HasMemOp4Prefix) - HANDLE_OPTIONAL(immediate) + HANDLE_OPTIONAL(immediate) HANDLE_OPTIONAL(immediate) // above might be a register in 7:4 break; + case X86Local::MRMSrcMemOp4: + assert(numPhysicalOperands >= 4 && numPhysicalOperands <= 5 && + "Unexpected number of operands for MRMSrcMemOp4Frm"); + HANDLE_OPERAND(roRegister) + HANDLE_OPERAND(vvvvRegister) + HANDLE_OPERAND(immediate) // Register in imm[7:4] + HANDLE_OPERAND(memory) + HANDLE_OPTIONAL(immediate) + break; case X86Local::MRMXr: case X86Local::MRM0r: case X86Local::MRM1r: @@ -842,11 +853,13 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { break; case X86Local::MRMDestReg: case X86Local::MRMSrcReg: + case X86Local::MRMSrcRegOp4: case X86Local::MRMXr: filter = new ModFilter(true); break; case X86Local::MRMDestMem: case X86Local::MRMSrcMem: + case X86Local::MRMSrcMemOp4: case X86Local::MRMXm: filter = new ModFilter(false); break; diff --git a/llvm/utils/TableGen/X86RecognizableInstr.h b/llvm/utils/TableGen/X86RecognizableInstr.h index f6f5006..402fd86 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.h +++ b/llvm/utils/TableGen/X86RecognizableInstr.h @@ -61,8 +61,6 @@ private: bool HasVEX_WPrefix; /// Inferred from the operands; indicates whether the L bit in the VEX prefix is set bool HasVEX_LPrefix; - /// The hasMemOp4Prefix field from the record - bool HasMemOp4Prefix; /// The ignoreVEX_L field from the record bool IgnoresVEX_L; /// The hasEVEX_L2Prefix field from the record -- 2.7.4