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 @@ -388,17 +388,19 @@ } class X86MemOperand : Operand { + AsmOperandClass parserMatchClass = X86MemAsmOperand, + int size = 0> : Operand { let PrintMethod = printMethod; let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG); let ParserMatchClass = parserMatchClass; let OperandType = "OPERAND_MEMORY"; + int Size = size; } // Gather mem operands class X86VMemOperand - : X86MemOperand { + AsmOperandClass parserMatchClass, int size = 0> + : X86MemOperand { let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, SEGMENT_REG); } @@ -413,48 +415,45 @@ def sibmem: X86MemOperand<"printMemReference", X86SibMemOperand>; -def i8mem : X86MemOperand<"printbytemem", X86Mem8AsmOperand>; -def i16mem : X86MemOperand<"printwordmem", X86Mem16AsmOperand>; -def i32mem : X86MemOperand<"printdwordmem", X86Mem32AsmOperand>; -def i64mem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand>; -def i128mem : X86MemOperand<"printxmmwordmem", X86Mem128AsmOperand>; -def i256mem : X86MemOperand<"printymmwordmem", X86Mem256AsmOperand>; -def i512mem : X86MemOperand<"printzmmwordmem", X86Mem512AsmOperand>; -def f16mem : X86MemOperand<"printwordmem", X86Mem16AsmOperand>; -def f32mem : X86MemOperand<"printdwordmem", X86Mem32AsmOperand>; -def f64mem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand>; -def f80mem : X86MemOperand<"printtbytemem", X86Mem80AsmOperand>; -def f128mem : X86MemOperand<"printxmmwordmem", X86Mem128AsmOperand>; -def f256mem : X86MemOperand<"printymmwordmem", X86Mem256AsmOperand>; -def f512mem : X86MemOperand<"printzmmwordmem", X86Mem512AsmOperand>; +def i8mem : X86MemOperand<"printbytemem", X86Mem8AsmOperand, 8>; +def i16mem : X86MemOperand<"printwordmem", X86Mem16AsmOperand, 16>; +def i32mem : X86MemOperand<"printdwordmem", X86Mem32AsmOperand, 32>; +def i64mem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand, 64>; +def i128mem : X86MemOperand<"printxmmwordmem", X86Mem128AsmOperand, 128>; +def i256mem : X86MemOperand<"printymmwordmem", X86Mem256AsmOperand, 256>; +def i512mem : X86MemOperand<"printzmmwordmem", X86Mem512AsmOperand, 512>; +def f16mem : X86MemOperand<"printwordmem", X86Mem16AsmOperand, 16>; +def f32mem : X86MemOperand<"printdwordmem", X86Mem32AsmOperand, 32>; +def f64mem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand, 64>; +def f80mem : X86MemOperand<"printtbytemem", X86Mem80AsmOperand, 80>; +def f128mem : X86MemOperand<"printxmmwordmem", X86Mem128AsmOperand, 128>; +def f256mem : X86MemOperand<"printymmwordmem", X86Mem256AsmOperand, 256>; +def f512mem : X86MemOperand<"printzmmwordmem", X86Mem512AsmOperand, 512>; // Gather mem operands -def vx64mem : X86VMemOperand; -def vx128mem : X86VMemOperand; -def vx256mem : X86VMemOperand; -def vy128mem : X86VMemOperand; -def vy256mem : X86VMemOperand; - -def vx64xmem : X86VMemOperand; -def vx128xmem : X86VMemOperand; -def vx256xmem : X86VMemOperand; -def vy128xmem : X86VMemOperand; -def vy256xmem : X86VMemOperand; -def vy512xmem : X86VMemOperand; -def vz256mem : X86VMemOperand; -def vz512mem : X86VMemOperand; +def vx64mem : X86VMemOperand; +def vx128mem : X86VMemOperand; +def vx256mem : X86VMemOperand; +def vy128mem : X86VMemOperand; +def vy256mem : X86VMemOperand; + +def vx64xmem : X86VMemOperand; +def vx128xmem : X86VMemOperand; +def vx256xmem : X86VMemOperand; +def vy128xmem : X86VMemOperand; +def vy256xmem : X86VMemOperand; +def vy512xmem : X86VMemOperand; +def vz256mem : X86VMemOperand; +def vz512mem : X86VMemOperand; // A version of i8mem for use on x86-64 and x32 that uses a NOREX GPR instead // of a plain GPR, so that it doesn't potentially require a REX prefix. def ptr_rc_norex : PointerLikeRegClass<2>; def ptr_rc_norex_nosp : PointerLikeRegClass<3>; -def i8mem_NOREX : Operand { - let PrintMethod = "printbytemem"; +def i8mem_NOREX : X86MemOperand<"printbytemem", X86Mem8AsmOperand, 8> { let MIOperandInfo = (ops ptr_rc_norex, i8imm, ptr_rc_norex_nosp, i32imm, SEGMENT_REG); - let ParserMatchClass = X86Mem8AsmOperand; - let OperandType = "OPERAND_MEMORY"; } // GPRs available for tailcall. diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp --- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp @@ -449,6 +449,31 @@ OS << "} // end namespace " << Namespace << "\n"; OS << "} // end namespace llvm\n"; OS << "#endif // GET_INSTRINFO_OPERAND_TYPE\n\n"; + + OS << "#ifdef GET_INSTRINFO_MEM_OPERAND_SIZE\n"; + OS << "#undef GET_INSTRINFO_MEM_OPERAND_SIZE\n"; + OS << "namespace llvm {\n"; + OS << "namespace " << Namespace << " {\n"; + OS << "LLVM_READONLY\n"; + OS << "static int getMemOperandSize(int OpType) {\n"; + OS << " switch (OpType) {\n"; + std::map> SizeToOperandName; + for (const Record *Op : Operands) { + if (!Op->isSubClassOf("X86MemOperand")) + continue; + if (int Size = Op->getValueAsInt("Size")) + SizeToOperandName[Size].push_back(Op->getName()); + } + OS << " default: return 0;\n"; + for (auto KV : SizeToOperandName) { + for (const StringRef &OperandName : KV.second) + OS << " case OpTypes::" << OperandName << ":\n"; + OS << " return " << KV.first << ";\n\n"; + } + OS << " }\n}\n"; + OS << "} // end namespace " << Namespace << "\n"; + OS << "} // end namespace llvm\n"; + OS << "#endif // GET_INSTRINFO_MEM_OPERAND_SIZE\n\n"; } void InstrInfoEmitter::emitLogicalOperandSizeMappings( 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 @@ -63,26 +63,8 @@ } unsigned X86Disassembler::getMemOperandSize(const Record *MemRec) { - if (MemRec->isSubClassOf("Operand")) { - StringRef Name = - MemRec->getValueAsDef("ParserMatchClass")->getValueAsString("Name"); - if (Name == "Mem8") - return 8; - if (Name == "Mem16") - return 16; - if (Name == "Mem32") - return 32; - if (Name == "Mem64") - return 64; - if (Name == "Mem80") - return 80; - if (Name == "Mem128") - return 128; - if (Name == "Mem256") - return 256; - if (Name == "Mem512") - return 512; - } + if (MemRec->isSubClassOf("X86MemOperand")) + return MemRec->getValueAsInt("Size"); llvm_unreachable("Memory operand's size not known!"); }