diff --git a/llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp b/llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp index 740bd63f2aa905..6f82dfea8d5ce6 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 6b3b8ae84ba659..c5f5ed8e084dca 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 different sizes!"); - - for (unsigned i = 0, e = B1->getNumBits(); i != e; ++i) { - BitInit *Bit1 = cast(B1->getBit(i)); - BitInit *Bit2 = cast(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 different 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 different 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 8c899a3e57c135..9faa3664739f46 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> MnemonicToCGInstrMap; - // Unused - X86Disassembler::DisassemblerTables Tables; ArrayRef 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 e9a9f8faf4233a..6d857f6883763a 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 1c151511f4b5cf..bef4024d1d3583 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* 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;