[llvm] c012854 - [TableGen][X86] Add Size field to X86MemOperand class
Amir Ayupov via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 19 11:47:02 PDT 2022
Author: Amir Ayupov
Date: 2022-06-19T11:46:56-07:00
New Revision: c0128549b00f8dbe3ed1b5519e9b89f1370ae5e8
URL: https://github.com/llvm/llvm-project/commit/c0128549b00f8dbe3ed1b5519e9b89f1370ae5e8
DIFF: https://github.com/llvm/llvm-project/commit/c0128549b00f8dbe3ed1b5519e9b89f1370ae5e8.diff
LOG: [TableGen][X86] Add Size field to X86MemOperand class
Set Size appropriately in operand definitions and query it for dumping memory
operand size table `getMemOperandSize` (follow-up use D126116) and
`X86Disassembler::getMemOperandSize`.
Excerpt from a produced `getMemOperandSize` table for X86:
```
static int getMemOperandSize(int OpType) {
switch (OpType) {
default: return 0;
case OpTypes::i8mem:
case OpTypes::i8mem_NOREX:
return 8;
case OpTypes::f16mem:
case OpTypes::i16mem:
return 16;
case OpTypes::f32mem:
case OpTypes::i32mem:
return 32;
...
```
Reviewed By: skan, pengfei
Differential Revision: https://reviews.llvm.org/D127787
Added:
Modified:
llvm/lib/Target/X86/X86InstrInfo.td
llvm/utils/TableGen/InstrInfoEmitter.cpp
llvm/utils/TableGen/X86RecognizableInstr.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td
index fab6ccd108a6..7f6ef3479d40 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.td
+++ b/llvm/lib/Target/X86/X86InstrInfo.td
@@ -388,17 +388,19 @@ def X86AbsMemAsmOperand : AsmOperandClass {
}
class X86MemOperand<string printMethod,
- AsmOperandClass parserMatchClass = X86MemAsmOperand> : Operand<iPTR> {
+ AsmOperandClass parserMatchClass = X86MemAsmOperand,
+ int size = 0> : Operand<iPTR> {
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<RegisterClass RC, string printMethod,
- AsmOperandClass parserMatchClass>
- : X86MemOperand<printMethod, parserMatchClass> {
+ AsmOperandClass parserMatchClass, int size = 0>
+ : X86MemOperand<printMethod, parserMatchClass, size> {
let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, SEGMENT_REG);
}
@@ -413,48 +415,45 @@ def opaquemem : X86MemOperand<"printMemReference">;
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<VR128, "printqwordmem", X86Mem64_RC128Operand>;
-def vx128mem : X86VMemOperand<VR128, "printxmmwordmem", X86Mem128_RC128Operand>;
-def vx256mem : X86VMemOperand<VR128, "printymmwordmem", X86Mem256_RC128Operand>;
-def vy128mem : X86VMemOperand<VR256, "printxmmwordmem", X86Mem128_RC256Operand>;
-def vy256mem : X86VMemOperand<VR256, "printymmwordmem", X86Mem256_RC256Operand>;
-
-def vx64xmem : X86VMemOperand<VR128X, "printqwordmem", X86Mem64_RC128XOperand>;
-def vx128xmem : X86VMemOperand<VR128X, "printxmmwordmem", X86Mem128_RC128XOperand>;
-def vx256xmem : X86VMemOperand<VR128X, "printymmwordmem", X86Mem256_RC128XOperand>;
-def vy128xmem : X86VMemOperand<VR256X, "printxmmwordmem", X86Mem128_RC256XOperand>;
-def vy256xmem : X86VMemOperand<VR256X, "printymmwordmem", X86Mem256_RC256XOperand>;
-def vy512xmem : X86VMemOperand<VR256X, "printzmmwordmem", X86Mem512_RC256XOperand>;
-def vz256mem : X86VMemOperand<VR512, "printymmwordmem", X86Mem256_RC512Operand>;
-def vz512mem : X86VMemOperand<VR512, "printzmmwordmem", X86Mem512_RC512Operand>;
+def vx64mem : X86VMemOperand<VR128, "printqwordmem", X86Mem64_RC128Operand, 64>;
+def vx128mem : X86VMemOperand<VR128, "printxmmwordmem", X86Mem128_RC128Operand, 128>;
+def vx256mem : X86VMemOperand<VR128, "printymmwordmem", X86Mem256_RC128Operand, 256>;
+def vy128mem : X86VMemOperand<VR256, "printxmmwordmem", X86Mem128_RC256Operand, 128>;
+def vy256mem : X86VMemOperand<VR256, "printymmwordmem", X86Mem256_RC256Operand, 256>;
+
+def vx64xmem : X86VMemOperand<VR128X, "printqwordmem", X86Mem64_RC128XOperand, 64>;
+def vx128xmem : X86VMemOperand<VR128X, "printxmmwordmem", X86Mem128_RC128XOperand, 128>;
+def vx256xmem : X86VMemOperand<VR128X, "printymmwordmem", X86Mem256_RC128XOperand, 256>;
+def vy128xmem : X86VMemOperand<VR256X, "printxmmwordmem", X86Mem128_RC256XOperand, 128>;
+def vy256xmem : X86VMemOperand<VR256X, "printymmwordmem", X86Mem256_RC256XOperand, 256>;
+def vy512xmem : X86VMemOperand<VR256X, "printzmmwordmem", X86Mem512_RC256XOperand, 512>;
+def vz256mem : X86VMemOperand<VR512, "printymmwordmem", X86Mem256_RC512Operand, 256>;
+def vz512mem : X86VMemOperand<VR512, "printzmmwordmem", X86Mem512_RC512Operand, 512>;
// 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<iPTR> {
- 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
index 4cf8e8500e0d..56252f0b69cc 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -449,6 +449,31 @@ void InstrInfoEmitter::emitOperandTypeMappings(
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<int, std::vector<StringRef>> 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
index 155450d77da2..9afde66fe6f3 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -63,26 +63,8 @@ unsigned X86Disassembler::getRegOperandSize(const Record *RegRec) {
}
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!");
}
More information about the llvm-commits
mailing list