[llvm] bf11ed2 - [X86][tablgen] Add class RecognizableInstrBase to simplify X86 code, NFCI
Shengchen Kan via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 25 22:03:35 PDT 2022
Author: Shengchen Kan
Date: 2022-03-26T13:03:06+08:00
New Revision: bf11ed293abf4dcb2bcd37be3a027a786132e695
URL: https://github.com/llvm/llvm-project/commit/bf11ed293abf4dcb2bcd37be3a027a786132e695
DIFF: https://github.com/llvm/llvm-project/commit/bf11ed293abf4dcb2bcd37be3a027a786132e695.diff
LOG: [X86][tablgen] Add class RecognizableInstrBase to simplify X86 code, NFCI
Added:
Modified:
llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp
llvm/utils/TableGen/X86FoldTablesEmitter.cpp
llvm/utils/TableGen/X86MnemonicTables.cpp
llvm/utils/TableGen/X86RecognizableInstr.cpp
llvm/utils/TableGen/X86RecognizableInstr.h
Removed:
################################################################################
diff --git a/llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp b/llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp
index 740bd63f2aa90..6f82dfea8d5ce 100644
--- a/llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp
+++ b/llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp
@@ -13,6 +13,7 @@
#include "CodeGenInstruction.h"
#include "CodeGenTarget.h"
+#include "X86RecognizableInstr.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/TableGenBackend.h"
@@ -109,28 +110,25 @@ class IsMatch {
IsMatch(const CodeGenInstruction *EVEXInst) : EVEXInst(EVEXInst) {}
bool operator()(const CodeGenInstruction *VEXInst) {
- Record *RecE = EVEXInst->TheDef;
- Record *RecV = VEXInst->TheDef;
- bool EVEX_W = RecE->getValueAsBit("HasVEX_W");
- bool VEX_W = RecV->getValueAsBit("HasVEX_W");
- bool VEX_WIG = RecV->getValueAsBit("IgnoresVEX_W");
- bool EVEX_WIG = RecE->getValueAsBit("IgnoresVEX_W");
- bool EVEX_W1_VEX_W0 = RecE->getValueAsBit("EVEX_W1_VEX_W0");
-
- if (RecV->getValueAsDef("OpEnc")->getName().str() != "EncVEX" ||
- RecV->getValueAsBit("isCodeGenOnly") != RecE->getValueAsBit("isCodeGenOnly") ||
+ X86Disassembler::RecognizableInstrBase VEXRI(*VEXInst);
+ X86Disassembler::RecognizableInstrBase EVEXRI(*EVEXInst);
+ bool VEX_W = VEXRI.HasVEX_W;
+ bool EVEX_W = EVEXRI.HasVEX_W;
+ bool VEX_WIG = VEXRI.IgnoresVEX_W;
+ bool EVEX_WIG = EVEXRI.IgnoresVEX_W;
+ bool EVEX_W1_VEX_W0 = EVEXRI.Rec->getValueAsBit("EVEX_W1_VEX_W0");
+
+ if (VEXRI.IsCodeGenOnly != EVEXRI.IsCodeGenOnly ||
// VEX/EVEX fields
- RecV->getValueAsDef("OpPrefix") != RecE->getValueAsDef("OpPrefix") ||
- RecV->getValueAsDef("OpMap") != RecE->getValueAsDef("OpMap") ||
- RecV->getValueAsBit("hasVEX_4V") != RecE->getValueAsBit("hasVEX_4V") ||
- RecV->getValueAsBit("hasEVEX_L2") != RecE->getValueAsBit("hasEVEX_L2") ||
- RecV->getValueAsBit("hasVEX_L") != RecE->getValueAsBit("hasVEX_L") ||
+ VEXRI.OpPrefix != EVEXRI.OpPrefix || VEXRI.OpMap != EVEXRI.OpMap ||
+ VEXRI.HasVEX_4V != EVEXRI.HasVEX_4V ||
+ VEXRI.HasVEX_LPrefix != EVEXRI.HasVEX_LPrefix ||
// Match is allowed if either is VEX_WIG, or they match, or EVEX
// is VEX_W1X and VEX is VEX_W0.
(!(VEX_WIG || (!EVEX_WIG && EVEX_W == VEX_W) ||
(EVEX_W1_VEX_W0 && EVEX_W && !VEX_W))) ||
// Instruction's format
- RecV->getValueAsDef("Form") != RecE->getValueAsDef("Form"))
+ VEXRI.Form != EVEXRI.Form)
return false;
// This is needed for instructions with intrinsic version (_Int).
@@ -207,23 +205,19 @@ void X86EVEX2VEXTablesEmitter::run(raw_ostream &OS) {
Target.getInstructionsByEnumValue();
for (const CodeGenInstruction *Inst : NumberedInstructions) {
+ X86Disassembler::RecognizableInstrBase RI(*Inst);
+ const Record *Def = RI.Rec;
// Filter non-X86 instructions.
- if (!Inst->TheDef->isSubClassOf("X86Inst"))
+ if (!Def->isSubClassOf("X86Inst"))
continue;
// Add VEX encoded instructions to one of VEXInsts vectors according to
// it's opcode.
- if (Inst->TheDef->getValueAsDef("OpEnc")->getName() == "EncVEX") {
- uint64_t Opcode = getValueFromBitsInit(Inst->TheDef->
- getValueAsBitsInit("Opcode"));
- VEXInsts[Opcode].push_back(Inst);
- }
+ if (RI.Encoding == X86Local::VEX)
+ VEXInsts[RI.Opcode].push_back(Inst);
// Add relevant EVEX encoded instructions to EVEXInsts
- else if (Inst->TheDef->getValueAsDef("OpEnc")->getName() == "EncEVEX" &&
- !Inst->TheDef->getValueAsBit("hasEVEX_K") &&
- !Inst->TheDef->getValueAsBit("hasEVEX_B") &&
- !Inst->TheDef->getValueAsBit("hasEVEX_L2") &&
- !Inst->TheDef->getValueAsBit("notEVEX2VEXConvertible"))
+ else if (RI.Encoding == X86Local::EVEX && !RI.HasEVEX_K && !RI.HasEVEX_B &&
+ !RI.HasEVEX_L2Prefix && !Def->getValueAsBit("notEVEX2VEXConvertible"))
EVEXInsts.push_back(Inst);
}
diff --git a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
index 6b3b8ae84ba65..c5f5ed8e084dc 100644
--- a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
+++ b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
@@ -212,20 +212,6 @@ static inline uint64_t getValueFromBitsInit(const BitsInit *B) {
return Value;
}
-// Returns true if the two given BitsInits represent the same integer value
-static inline bool equalBitsInits(const BitsInit *B1, const BitsInit *B2) {
- if (B1->getNumBits() != B2->getNumBits())
- PrintFatalError("Comparing two BitsInits with
diff erent sizes!");
-
- for (unsigned i = 0, e = B1->getNumBits(); i != e; ++i) {
- BitInit *Bit1 = cast<BitInit>(B1->getBit(i));
- BitInit *Bit2 = cast<BitInit>(B2->getBit(i));
- if (Bit1->getValue() != Bit2->getValue())
- return false;
- }
- return true;
-}
-
// Return the size of the register operand
static inline unsigned int getRegOperandSize(const Record *RegRec) {
if (RegRec->isSubClassOf("RegisterOperand"))
@@ -323,53 +309,42 @@ class IsMatch {
: MemInst(Inst) {}
bool operator()(const CodeGenInstruction *RegInst) {
- Record *MemRec = MemInst->TheDef;
- Record *RegRec = RegInst->TheDef;
+ X86Disassembler::RecognizableInstrBase RegRI(*RegInst);
+ X86Disassembler::RecognizableInstrBase MemRI(*MemInst);
+ const Record *RegRec = RegRI.Rec;
+ const Record *MemRec = MemRI.Rec;
+
+ // EVEX_B means
diff erent things for memory and register forms.
+ if (RegRI.HasEVEX_B != 0 || MemRI.HasEVEX_B != 0)
+ return false;
+
+ // Instruction's format - The register form's "Form" field should be
+ // the opposite of the memory form's "Form" field.
+ if (!areOppositeForms(RegRI.Form, MemRI.Form))
+ return false;
// Return false if one (at least) of the encoding fields of both
// instructions do not match.
- if (RegRec->getValueAsDef("OpEnc") != MemRec->getValueAsDef("OpEnc") ||
- !equalBitsInits(RegRec->getValueAsBitsInit("Opcode"),
- MemRec->getValueAsBitsInit("Opcode")) ||
- // VEX/EVEX fields
- RegRec->getValueAsDef("OpPrefix") !=
- MemRec->getValueAsDef("OpPrefix") ||
- RegRec->getValueAsDef("OpMap") != MemRec->getValueAsDef("OpMap") ||
- RegRec->getValueAsDef("OpSize") != MemRec->getValueAsDef("OpSize") ||
- RegRec->getValueAsDef("AdSize") != MemRec->getValueAsDef("AdSize") ||
- RegRec->getValueAsBit("hasVEX_4V") !=
- MemRec->getValueAsBit("hasVEX_4V") ||
- RegRec->getValueAsBit("hasEVEX_K") !=
- MemRec->getValueAsBit("hasEVEX_K") ||
- RegRec->getValueAsBit("hasEVEX_Z") !=
- MemRec->getValueAsBit("hasEVEX_Z") ||
- // EVEX_B means
diff erent things for memory and register forms.
- RegRec->getValueAsBit("hasEVEX_B") != 0 ||
- MemRec->getValueAsBit("hasEVEX_B") != 0 ||
+ if (RegRI.Encoding != MemRI.Encoding || RegRI.Opcode != MemRI.Opcode ||
+ RegRI.OpPrefix != MemRI.OpPrefix || RegRI.OpMap != MemRI.OpMap ||
+ RegRI.OpSize != MemRI.OpSize || RegRI.AdSize != MemRI.AdSize ||
+ RegRI.HasREX_WPrefix != MemRI.HasREX_WPrefix ||
+ RegRI.HasVEX_4V != MemRI.HasVEX_4V ||
+ RegRI.HasVEX_LPrefix != MemRI.HasVEX_LPrefix ||
+ RegRI.HasVEX_W != MemRI.HasVEX_W ||
+ RegRI.IgnoresVEX_L != MemRI.IgnoresVEX_L ||
+ RegRI.IgnoresVEX_W != MemRI.IgnoresVEX_W ||
+ RegRI.HasEVEX_K != MemRI.HasEVEX_K ||
+ RegRI.HasEVEX_KZ != MemRI.HasEVEX_KZ ||
+ RegRI.HasEVEX_L2Prefix != MemRI.HasEVEX_L2Prefix ||
RegRec->getValueAsBit("hasEVEX_RC") !=
MemRec->getValueAsBit("hasEVEX_RC") ||
- RegRec->getValueAsBit("hasREX_WPrefix") !=
- MemRec->getValueAsBit("hasREX_WPrefix") ||
RegRec->getValueAsBit("hasLockPrefix") !=
MemRec->getValueAsBit("hasLockPrefix") ||
RegRec->getValueAsBit("hasNoTrackPrefix") !=
MemRec->getValueAsBit("hasNoTrackPrefix") ||
- RegRec->getValueAsBit("hasVEX_L") !=
- MemRec->getValueAsBit("hasVEX_L") ||
- RegRec->getValueAsBit("hasEVEX_L2") !=
- MemRec->getValueAsBit("hasEVEX_L2") ||
- RegRec->getValueAsBit("ignoresVEX_L") !=
- MemRec->getValueAsBit("ignoresVEX_L") ||
- RegRec->getValueAsBit("HasVEX_W") !=
- MemRec->getValueAsBit("HasVEX_W") ||
- RegRec->getValueAsBit("IgnoresVEX_W") !=
- MemRec->getValueAsBit("IgnoresVEX_W") ||
RegRec->getValueAsBit("EVEX_W1_VEX_W0") !=
MemRec->getValueAsBit("EVEX_W1_VEX_W0") ||
- // Instruction's format - The register form's "Form" field should be
- // the opposite of the memory form's "Form" field.
- !areOppositeForms(RegRec->getValueAsBitsInit("FormBits"),
- MemRec->getValueAsBitsInit("FormBits")) ||
RegRec->getValueAsBit("isAsmParserOnly") !=
MemRec->getValueAsBit("isAsmParserOnly"))
return false;
@@ -424,31 +399,24 @@ class IsMatch {
private:
// Return true of the 2 given forms are the opposite of each other.
- bool areOppositeForms(const BitsInit *RegFormBits,
- const BitsInit *MemFormBits) {
- uint64_t MemFormNum = getValueFromBitsInit(MemFormBits);
- uint64_t RegFormNum = getValueFromBitsInit(RegFormBits);
-
- if ((MemFormNum == X86Local::MRM0m && RegFormNum == X86Local::MRM0r) ||
- (MemFormNum == X86Local::MRM1m && RegFormNum == X86Local::MRM1r) ||
- (MemFormNum == X86Local::MRM2m && RegFormNum == X86Local::MRM2r) ||
- (MemFormNum == X86Local::MRM3m && RegFormNum == X86Local::MRM3r) ||
- (MemFormNum == X86Local::MRM4m && RegFormNum == X86Local::MRM4r) ||
- (MemFormNum == X86Local::MRM5m && RegFormNum == X86Local::MRM5r) ||
- (MemFormNum == X86Local::MRM6m && RegFormNum == X86Local::MRM6r) ||
- (MemFormNum == X86Local::MRM7m && RegFormNum == X86Local::MRM7r) ||
- (MemFormNum == X86Local::MRMXm && RegFormNum == X86Local::MRMXr) ||
- (MemFormNum == X86Local::MRMXmCC && RegFormNum == X86Local::MRMXrCC) ||
- (MemFormNum == X86Local::MRMDestMem &&
- RegFormNum == X86Local::MRMDestReg) ||
- (MemFormNum == X86Local::MRMSrcMem &&
- RegFormNum == X86Local::MRMSrcReg) ||
- (MemFormNum == X86Local::MRMSrcMem4VOp3 &&
- RegFormNum == X86Local::MRMSrcReg4VOp3) ||
- (MemFormNum == X86Local::MRMSrcMemOp4 &&
- RegFormNum == X86Local::MRMSrcRegOp4) ||
- (MemFormNum == X86Local::MRMSrcMemCC &&
- RegFormNum == X86Local::MRMSrcRegCC))
+ bool areOppositeForms(unsigned RegForm, unsigned MemForm) {
+ if ((MemForm == X86Local::MRM0m && RegForm == X86Local::MRM0r) ||
+ (MemForm == X86Local::MRM1m && RegForm == X86Local::MRM1r) ||
+ (MemForm == X86Local::MRM2m && RegForm == X86Local::MRM2r) ||
+ (MemForm == X86Local::MRM3m && RegForm == X86Local::MRM3r) ||
+ (MemForm == X86Local::MRM4m && RegForm == X86Local::MRM4r) ||
+ (MemForm == X86Local::MRM5m && RegForm == X86Local::MRM5r) ||
+ (MemForm == X86Local::MRM6m && RegForm == X86Local::MRM6r) ||
+ (MemForm == X86Local::MRM7m && RegForm == X86Local::MRM7r) ||
+ (MemForm == X86Local::MRMXm && RegForm == X86Local::MRMXr) ||
+ (MemForm == X86Local::MRMXmCC && RegForm == X86Local::MRMXrCC) ||
+ (MemForm == X86Local::MRMDestMem && RegForm == X86Local::MRMDestReg) ||
+ (MemForm == X86Local::MRMSrcMem && RegForm == X86Local::MRMSrcReg) ||
+ (MemForm == X86Local::MRMSrcMem4VOp3 &&
+ RegForm == X86Local::MRMSrcReg4VOp3) ||
+ (MemForm == X86Local::MRMSrcMemOp4 &&
+ RegForm == X86Local::MRMSrcRegOp4) ||
+ (MemForm == X86Local::MRMSrcMemCC && RegForm == X86Local::MRMSrcRegCC))
return true;
return false;
diff --git a/llvm/utils/TableGen/X86MnemonicTables.cpp b/llvm/utils/TableGen/X86MnemonicTables.cpp
index 8c899a3e57c13..9faa3664739f4 100644
--- a/llvm/utils/TableGen/X86MnemonicTables.cpp
+++ b/llvm/utils/TableGen/X86MnemonicTables.cpp
@@ -13,7 +13,6 @@
#include "CodeGenInstruction.h"
#include "CodeGenTarget.h"
-#include "X86DisassemblerTables.h"
#include "X86RecognizableInstr.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/TableGenBackend.h"
@@ -41,23 +40,17 @@ void X86MnemonicTablesEmitter::run(raw_ostream &OS) {
// Hold all instructions grouped by mnemonic
StringMap<SmallVector<const CodeGenInstruction *, 0>> MnemonicToCGInstrMap;
- // Unused
- X86Disassembler::DisassemblerTables Tables;
ArrayRef<const CodeGenInstruction *> NumberedInstructions =
Target.getInstructionsByEnumValue();
- for (unsigned II = 0, IE = NumberedInstructions.size(); II != IE; ++II) {
- const CodeGenInstruction *I = NumberedInstructions[II];
- X86Disassembler::RecognizableInstr RI(Tables, *I, II);
- Record *Def = I->TheDef;
- if ( // Filter non-X86 instructions
- !Def->isSubClassOf("X86Inst") ||
- // Skip pseudo instructions as they may contain non-alnum characters in
- // mnemonic
- (RI.IsCodeGenOnly && !RI.ForceDisassemble) ||
- // Non-parsable instruction defs contain prefix as part of AsmString
+ for (const CodeGenInstruction *I : NumberedInstructions) {
+ X86Disassembler::RecognizableInstrBase RI(*I);
+ const Record *Def = RI.Rec;
+ if (!RI.ShouldBeEmitted)
+ continue;
+ if ( // Non-parsable instruction defs contain prefix as part of AsmString
Def->getValueAsString("AsmVariantName") == "NonParsable" ||
- // Skip CodeGenInstructions that are not real standalone instructions
- RI.Form == X86Local::PrefixByte || RI.Form == X86Local::Pseudo)
+ // Skip prefix byte
+ RI.Form == X86Local::PrefixByte)
continue;
std::string Mnemonic = X86Disassembler::getMnemonic(I, Variant);
MnemonicToCGInstrMap[Mnemonic].push_back(I);
diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp
index e9a9f8faf4233..6d857f6883763 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -75,14 +75,9 @@ static uint8_t byteFromRec(const Record* rec, StringRef name) {
return byteFromBitsInit(*bits);
}
-RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
- const CodeGenInstruction &insn,
- InstrUID uid) {
- UID = uid;
-
+RecognizableInstrBase::RecognizableInstrBase(const CodeGenInstruction &insn) {
Rec = insn.TheDef;
Name = std::string(Rec->getName());
- Spec = &tables.specForUID(UID);
if (!Rec->isSubClassOf("X86Inst")) {
ShouldBeEmitted = false;
@@ -144,6 +139,14 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
ShouldBeEmitted = true;
}
+RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
+ const CodeGenInstruction &insn,
+ InstrUID uid)
+ : RecognizableInstrBase(insn) {
+ UID = uid;
+ Spec = &tables.specForUID(UID);
+}
+
void RecognizableInstr::processInstr(DisassemblerTables &tables,
const CodeGenInstruction &insn,
InstrUID uid)
diff --git a/llvm/utils/TableGen/X86RecognizableInstr.h b/llvm/utils/TableGen/X86RecognizableInstr.h
index 1c151511f4b5c..bef4024d1d358 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.h
+++ b/llvm/utils/TableGen/X86RecognizableInstr.h
@@ -158,14 +158,8 @@ namespace X86Disassembler {
class DisassemblerTables;
-/// RecognizableInstr - Encapsulates all information required to decode a single
-/// instruction, as extracted from the LLVM instruction tables. Has methods
-/// to interpret the information available in the LLVM tables, and to emit the
-/// instruction into DisassemblerTables.
-class RecognizableInstr {
-public:
- /// The opcode of the instruction, as used in an MCInst
- InstrUID UID;
+/// Extract common fields of a single X86 instruction from a CodeGenInstruction
+struct RecognizableInstrBase {
/// The record from the .td files corresponding to this instruction
const Record* Rec;
/// The OpPrefix field from the record
@@ -228,6 +222,18 @@ class RecognizableInstr {
/// memory operands expand to 5 operands in the MCInst
const std::vector<CGIOperandList::OperandInfo>* Operands;
+ /// \param insn The CodeGenInstruction to extract information from.
+ RecognizableInstrBase(const CodeGenInstruction &insn);
+};
+
+/// RecognizableInstr - Encapsulates all information required to decode a single
+/// instruction, as extracted from the LLVM instruction tables. Has methods
+/// to interpret the information available in the LLVM tables, and to emit the
+/// instruction into DisassemblerTables.
+class RecognizableInstr : public RecognizableInstrBase {
+public:
+ /// The opcode of the instruction, as used in an MCInst
+ InstrUID UID;
/// The description of the instruction that is emitted into the instruction
/// info table
InstructionSpecifier* Spec;
More information about the llvm-commits
mailing list