diff options
Diffstat (limited to 'utils/TableGen')
| -rw-r--r-- | utils/TableGen/ARMDecoderEmitter.cpp | 22 | ||||
| -rw-r--r-- | utils/TableGen/AsmMatcherEmitter.cpp | 25 | ||||
| -rw-r--r-- | utils/TableGen/AsmWriterEmitter.cpp | 116 | ||||
| -rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 27 | ||||
| -rw-r--r-- | utils/TableGen/CodeGenInstruction.cpp | 7 | ||||
| -rw-r--r-- | utils/TableGen/CodeGenTarget.cpp | 5 | ||||
| -rw-r--r-- | utils/TableGen/CodeGenTarget.h | 7 | ||||
| -rw-r--r-- | utils/TableGen/DAGISelMatcherGen.cpp | 18 | ||||
| -rw-r--r-- | utils/TableGen/EDEmitter.cpp | 1 | ||||
| -rw-r--r-- | utils/TableGen/FastISelEmitter.cpp | 4 | ||||
| -rw-r--r-- | utils/TableGen/FixedLenDecoderEmitter.cpp | 4 | ||||
| -rw-r--r-- | utils/TableGen/InstrInfoEmitter.cpp | 209 | ||||
| -rw-r--r-- | utils/TableGen/InstrInfoEmitter.h | 10 | ||||
| -rw-r--r-- | utils/TableGen/Record.cpp | 19 | ||||
| -rw-r--r-- | utils/TableGen/Record.h | 6 | ||||
| -rw-r--r-- | utils/TableGen/RegisterInfoEmitter.cpp | 305 | ||||
| -rw-r--r-- | utils/TableGen/RegisterInfoEmitter.h | 23 | ||||
| -rw-r--r-- | utils/TableGen/SubtargetEmitter.cpp | 16 | ||||
| -rw-r--r-- | utils/TableGen/SubtargetEmitter.h | 2 | ||||
| -rw-r--r-- | utils/TableGen/TableGen.cpp | 33 |
20 files changed, 550 insertions, 309 deletions
diff --git a/utils/TableGen/ARMDecoderEmitter.cpp b/utils/TableGen/ARMDecoderEmitter.cpp index 62bd1c6..a7cbbcd 100644 --- a/utils/TableGen/ARMDecoderEmitter.cpp +++ b/utils/TableGen/ARMDecoderEmitter.cpp @@ -1592,10 +1592,6 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction &CGI, // The following special cases are for conflict resolutions. // - // RSCSri and RSCSrs set the 's' bit, but are not predicated. We are - // better off using the generic RSCri and RSCrs instructions. - if (Name == "RSCSri" || Name == "RSCSrs") return false; - // A8-598: VEXT // Vector Extract extracts elements from the bottom end of the second // operand vector and the top end of the first, concatenates them and @@ -1628,10 +1624,6 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction &CGI, if (Name == "tBX_RET" || Name == "tBX_RET_vararg") return false; - // Ignore the TPsoft (TLS) instructions, which conflict with tBLr9. - if (Name == "tTPsoft" || Name == "t2TPsoft") - return false; - // Ignore tADR, prefer tADDrPCi. if (Name == "tADR") return false; @@ -1644,12 +1636,8 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction &CGI, // Ignore tADDrSP, tADDspr, and tPICADD, prefer the generic tADDhirr. // Ignore t2SUBrSPs, prefer the t2SUB[S]r[r|s]. // Ignore t2ADDrSPs, prefer the t2ADD[S]r[r|s]. - // Ignore t2ADDrSPi/t2SUBrSPi, which have more generic couterparts. - // Ignore t2ADDrSPi12/t2SUBrSPi12, which have more generic couterparts if (Name == "tADDrSP" || Name == "tADDspr" || Name == "tPICADD" || - Name == "t2SUBrSPs" || Name == "t2ADDrSPs" || - Name == "t2ADDrSPi" || Name == "t2SUBrSPi" || - Name == "t2ADDrSPi12" || Name == "t2SUBrSPi12") + Name == "t2SUBrSPs" || Name == "t2ADDrSPs") return false; // FIXME: Use ldr.n to work around a Darwin assembler bug. @@ -1664,17 +1652,15 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction &CGI, // Resolve conflicts: // // tBfar conflicts with tBLr9 - // tPOP_RET/t2LDMIA_RET conflict with tPOP/t2LDM (ditto) + // t2LDMIA_RET conflict with t2LDM (ditto) // tMOVCCi conflicts with tMOVi8 // tMOVCCr conflicts with tMOVgpr2gpr - // tSpill conflicts with tSTRspi // tLDRcp conflicts with tLDRspi - // tRestore conflicts with tLDRspi // t2MOVCCi16 conflicts with tMOVi16 if (Name == "tBfar" || - Name == "tPOP_RET" || Name == "t2LDMIA_RET" || + Name == "t2LDMIA_RET" || Name == "tMOVCCi" || Name == "tMOVCCr" || - Name == "tSpill" || Name == "tLDRcp" || Name == "tRestore" || + Name == "tLDRcp" || Name == "t2MOVCCi16") return false; } diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index a05867b..1fb92ee 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -871,6 +871,31 @@ AsmMatcherInfo::getOperandClass(const CGIOperandList::OperandInfo &OI, if (SubOpIdx != -1) Rec = dynamic_cast<DefInit*>(OI.MIOperandInfo->getArg(SubOpIdx))->getDef(); + if (Rec->isSubClassOf("RegisterOperand")) { + // RegisterOperand may have an associated ParserMatchClass. If it does, + // use it, else just fall back to the underlying register class. + const RecordVal *R = Rec->getValue("ParserMatchClass"); + if (R == 0 || R->getValue() == 0) + throw "Record `" + Rec->getName() + + "' does not have a ParserMatchClass!\n"; + + if (DefInit *DI= dynamic_cast<DefInit*>(R->getValue())) { + Record *MatchClass = DI->getDef(); + if (ClassInfo *CI = AsmOperandClasses[MatchClass]) + return CI; + } + + // No custom match class. Just use the register class. + Record *ClassRec = Rec->getValueAsDef("RegClass"); + if (!ClassRec) + throw TGError(Rec->getLoc(), "RegisterOperand `" + Rec->getName() + + "' has no associated register class!\n"); + if (ClassInfo *CI = RegisterClassClasses[ClassRec]) + return CI; + throw TGError(Rec->getLoc(), "register class has no class info!"); + } + + if (Rec->isSubClassOf("RegisterClass")) { if (ClassInfo *CI = RegisterClassClasses[Rec]) return CI; diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index 066e03d..b77d2e4 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -18,6 +18,7 @@ #include "CodeGenTarget.h" #include "Record.h" #include "StringToOffsetTable.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" #include <algorithm> @@ -458,6 +459,58 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { O << "}\n"; } +static void +emitRegisterNameString(raw_ostream &O, StringRef AltName, + const std::vector<CodeGenRegister*> &Registers) { + StringToOffsetTable StringTable; + O << " static const unsigned RegAsmOffset" << AltName << "[] = {\n "; + for (unsigned i = 0, e = Registers.size(); i != e; ++i) { + const CodeGenRegister &Reg = *Registers[i]; + + std::string AsmName; + // "NoRegAltName" is special. We don't need to do a lookup for that, + // as it's just a reference to the default register name. + if (AltName == "" || AltName == "NoRegAltName") { + AsmName = Reg.TheDef->getValueAsString("AsmName"); + if (AsmName.empty()) + AsmName = Reg.getName(); + } else { + // Make sure the register has an alternate name for this index. + std::vector<Record*> AltNameList = + Reg.TheDef->getValueAsListOfDefs("RegAltNameIndices"); + unsigned Idx = 0, e; + for (e = AltNameList.size(); + Idx < e && (AltNameList[Idx]->getName() != AltName); + ++Idx) + ; + // If the register has an alternate name for this index, use it. + // Otherwise, leave it empty as an error flag. + if (Idx < e) { + std::vector<std::string> AltNames = + Reg.TheDef->getValueAsListOfStrings("AltNames"); + if (AltNames.size() <= Idx) + throw TGError(Reg.TheDef->getLoc(), + (Twine("Register definition missing alt name for '") + + AltName + "'.").str()); + AsmName = AltNames[Idx]; + } + } + + O << StringTable.GetOrAddStringOffset(AsmName); + if (((i + 1) % 14) == 0) + O << ",\n "; + else + O << ", "; + + } + O << "0\n" + << " };\n" + << "\n"; + + O << " const char *AsmStrs" << AltName << " =\n"; + StringTable.EmitString(O); + O << ";\n"; +} void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { CodeGenTarget Target(Records); @@ -465,40 +518,48 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); const std::vector<CodeGenRegister*> &Registers = Target.getRegBank().getRegisters(); + std::vector<Record*> AltNameIndices = Target.getRegAltNameIndices(); + bool hasAltNames = AltNameIndices.size() > 1; - StringToOffsetTable StringTable; O << "\n\n/// getRegisterName - This method is automatically generated by tblgen\n" "/// from the register set description. This returns the assembler name\n" "/// for the specified register.\n" - "const char *" << Target.getName() << ClassName - << "::getRegisterName(unsigned RegNo) {\n" - << " assert(RegNo && RegNo < " << (Registers.size()+1) - << " && \"Invalid register number!\");\n" - << "\n" - << " static const unsigned RegAsmOffset[] = {"; - for (unsigned i = 0, e = Registers.size(); i != e; ++i) { - const CodeGenRegister &Reg = *Registers[i]; - - std::string AsmName = Reg.TheDef->getValueAsString("AsmName"); - if (AsmName.empty()) - AsmName = Reg.getName(); - - - if ((i % 14) == 0) - O << "\n "; - - O << StringTable.GetOrAddStringOffset(AsmName) << ", "; - } - O << "0\n" - << " };\n" + "const char *" << Target.getName() << ClassName << "::"; + if (hasAltNames) + O << "\ngetRegisterName(unsigned RegNo, unsigned AltIdx) {\n"; + else + O << "getRegisterName(unsigned RegNo) {\n"; + O << " assert(RegNo && RegNo < " << (Registers.size()+1) + << " && \"Invalid register number!\");\n" << "\n"; - O << " const char *AsmStrs =\n"; - StringTable.EmitString(O); - O << ";\n"; + if (hasAltNames) { + for (unsigned i = 0, e = AltNameIndices.size(); i < e; ++i) + emitRegisterNameString(O, AltNameIndices[i]->getName(), Registers); + } else + emitRegisterNameString(O, "", Registers); + + if (hasAltNames) { + O << " const unsigned *RegAsmOffset;\n" + << " const char *AsmStrs;\n" + << " switch(AltIdx) {\n" + << " default: assert(0 && \"Invalid register alt name index!\");\n"; + for (unsigned i = 0, e = AltNameIndices.size(); i < e; ++i) { + StringRef Namespace = AltNameIndices[1]->getValueAsString("Namespace"); + StringRef AltName(AltNameIndices[i]->getName()); + O << " case " << Namespace << "::" << AltName + << ":\n" + << " AsmStrs = AsmStrs" << AltName << ";\n" + << " RegAsmOffset = RegAsmOffset" << AltName << ";\n" + << " break;\n"; + } + O << "}\n"; + } - O << " return AsmStrs+RegAsmOffset[RegNo-1];\n" + O << " assert (*(AsmStrs+RegAsmOffset[RegNo-1]) &&\n" + << " \"Invalid alt name index for register!\");\n" + << " return AsmStrs+RegAsmOffset[RegNo-1];\n" << "}\n"; } @@ -936,6 +997,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { const Record *Rec = RO.getRecord(); StringRef ROName = RO.getName(); + + if (Rec->isSubClassOf("RegisterOperand")) + Rec = Rec->getValueAsDef("RegClass"); if (Rec->isSubClassOf("RegisterClass")) { Cond = std::string("MI->getOperand(")+llvm::utostr(i)+").isReg()"; IAP->addCond(Cond); diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 1930a96..0fe5d05 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -1242,6 +1242,16 @@ TreePatternNode *TreePatternNode::InlinePatternFragments(TreePattern &TP) { /// static EEVT::TypeSet getImplicitType(Record *R, unsigned ResNo, bool NotRegisters, TreePattern &TP) { + // Check to see if this is a register operand. + if (R->isSubClassOf("RegisterOperand")) { + assert(ResNo == 0 && "Regoperand ref only has one result!"); + if (NotRegisters) + return EEVT::TypeSet(); // Unknown. + Record *RegClass = R->getValueAsDef("RegClass"); + const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo(); + return EEVT::TypeSet(T.getRegisterClass(RegClass).getValueTypes()); + } + // Check to see if this is a register or a register class. if (R->isSubClassOf("RegisterClass")) { assert(ResNo == 0 && "Regclass ref only has one result!"); @@ -1524,6 +1534,11 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { if (ResultNode->isSubClassOf("PointerLikeRegClass")) { MadeChange |= UpdateNodeType(ResNo, MVT::iPTR, TP); + } else if (ResultNode->isSubClassOf("RegisterOperand")) { + Record *RegClass = ResultNode->getValueAsDef("RegClass"); + const CodeGenRegisterClass &RC = + CDP.getTargetInfo().getRegisterClass(RegClass); + MadeChange |= UpdateNodeType(ResNo, RC.getValueTypes(), TP); } else if (ResultNode->getName() == "unknown") { // Nothing to do. } else { @@ -1582,6 +1597,11 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { const CodeGenRegisterClass &RC = CDP.getTargetInfo().getRegisterClass(OperandNode); MadeChange |= Child->UpdateNodeType(ChildResNo, RC.getValueTypes(), TP); + } else if (OperandNode->isSubClassOf("RegisterOperand")) { + Record *RegClass = OperandNode->getValueAsDef("RegClass"); + const CodeGenRegisterClass &RC = + CDP.getTargetInfo().getRegisterClass(RegClass); + MadeChange |= Child->UpdateNodeType(ChildResNo, RC.getValueTypes(), TP); } else if (OperandNode->isSubClassOf("Operand")) { VT = getValueType(OperandNode->getValueAsDef("Type")); MadeChange |= Child->UpdateNodeType(ChildResNo, VT, TP); @@ -1928,7 +1948,8 @@ InferAllTypes(const StringMap<SmallVector<TreePatternNode*,1> > *InNamedTypes) { // def : Pat<(v1i64 (bitconvert(v2i32 DPR:$src))), (v1i64 DPR:$src)>; if (Nodes[i] == Trees[0] && Nodes[i]->isLeaf()) { DefInit *DI = dynamic_cast<DefInit*>(Nodes[i]->getLeafValue()); - if (DI && DI->getDef()->isSubClassOf("RegisterClass")) + if (DI && (DI->getDef()->isSubClassOf("RegisterClass") || + DI->getDef()->isSubClassOf("RegisterOperand"))) continue; } @@ -2211,7 +2232,8 @@ static bool HandleUse(TreePattern *I, TreePatternNode *Pat, if (Pat->getName().empty()) { if (Pat->isLeaf()) { DefInit *DI = dynamic_cast<DefInit*>(Pat->getLeafValue()); - if (DI && DI->getDef()->isSubClassOf("RegisterClass")) + if (DI && (DI->getDef()->isSubClassOf("RegisterClass") || + DI->getDef()->isSubClassOf("RegisterOperand"))) I->error("Input " + DI->getDef()->getName() + " must be named!"); } return false; @@ -2318,6 +2340,7 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat, I->error("set destination should be a register!"); if (Val->getDef()->isSubClassOf("RegisterClass") || + Val->getDef()->isSubClassOf("RegisterOperand") || Val->getDef()->isSubClassOf("PointerLikeRegClass")) { if (Dest->getName().empty()) I->error("set destination must have a name!"); diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index e9557d2..5fa91be 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -69,7 +69,9 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) { std::string EncoderMethod; unsigned NumOps = 1; DagInit *MIOpInfo = 0; - if (Rec->isSubClassOf("Operand")) { + if (Rec->isSubClassOf("RegisterOperand")) { + PrintMethod = Rec->getValueAsString("PrintMethod"); + } else if (Rec->isSubClassOf("Operand")) { PrintMethod = Rec->getValueAsString("PrintMethod"); // If there is an explicit encoder method, use it. EncoderMethod = Rec->getValueAsString("EncoderMethod"); @@ -415,6 +417,9 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, // Handle explicit registers. if (ADI && ADI->getDef()->isSubClassOf("Register")) { + if (InstOpRec->isSubClassOf("RegisterOperand")) + InstOpRec = InstOpRec->getValueAsDef("RegClass"); + if (!InstOpRec->isSubClassOf("RegisterClass")) return false; diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index 5b0b315..929791c 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -164,6 +164,11 @@ CodeGenRegBank &CodeGenTarget::getRegBank() const { return *RegBank; } +void CodeGenTarget::ReadRegAltNameIndices() const { + RegAltNameIndices = Records.getAllDerivedDefinitions("RegAltNameIndex"); + std::sort(RegAltNameIndices.begin(), RegAltNameIndices.end(), LessRecord()); +} + /// getRegisterByName - If there is a register with the specific AsmName, /// return it. const CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const { diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h index 9bedb9c..143daed 100644 --- a/utils/TableGen/CodeGenTarget.h +++ b/utils/TableGen/CodeGenTarget.h @@ -66,7 +66,9 @@ class CodeGenTarget { mutable DenseMap<const Record*, CodeGenInstruction*> Instructions; mutable CodeGenRegBank *RegBank; + mutable std::vector<Record*> RegAltNameIndices; mutable std::vector<MVT::SimpleValueType> LegalValueTypes; + void ReadRegAltNameIndices() const; void ReadInstructions() const; void ReadLegalValueTypes() const; @@ -100,6 +102,11 @@ public: /// return it. const CodeGenRegister *getRegisterByName(StringRef Name) const; + const std::vector<Record*> &getRegAltNameIndices() const { + if (RegAltNameIndices.empty()) ReadRegAltNameIndices(); + return RegAltNameIndices; + } + const std::vector<CodeGenRegisterClass> &getRegisterClasses() const { return getRegBank().getRegClasses(); } diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp index 54553a8..c5897c7 100644 --- a/utils/TableGen/DAGISelMatcherGen.cpp +++ b/utils/TableGen/DAGISelMatcherGen.cpp @@ -224,6 +224,7 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) { Record *LeafRec = DI->getDef(); if (// Handle register references. Nothing to do here, they always match. LeafRec->isSubClassOf("RegisterClass") || + LeafRec->isSubClassOf("RegisterOperand") || LeafRec->isSubClassOf("PointerLikeRegClass") || LeafRec->isSubClassOf("SubRegIndex") || // Place holder for SRCVALUE nodes. Nothing to do here. @@ -579,15 +580,16 @@ void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N, // If this is an explicit register reference, handle it. if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) { - if (DI->getDef()->isSubClassOf("Register")) { + Record *Def = DI->getDef(); + if (Def->isSubClassOf("Register")) { const CodeGenRegister *Reg = - CGP.getTargetInfo().getRegBank().getReg(DI->getDef()); + CGP.getTargetInfo().getRegBank().getReg(Def); AddMatcher(new EmitRegisterMatcher(Reg, N->getType(0))); ResultOps.push_back(NextRecordedOperandNo++); return; } - if (DI->getDef()->getName() == "zero_reg") { + if (Def->getName() == "zero_reg") { AddMatcher(new EmitRegisterMatcher(0, N->getType(0))); ResultOps.push_back(NextRecordedOperandNo++); return; @@ -595,16 +597,18 @@ void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N, // Handle a reference to a register class. This is used // in COPY_TO_SUBREG instructions. - if (DI->getDef()->isSubClassOf("RegisterClass")) { - std::string Value = getQualifiedName(DI->getDef()) + "RegClassID"; + if (Def->isSubClassOf("RegisterOperand")) + Def = Def->getValueAsDef("RegClass"); + if (Def->isSubClassOf("RegisterClass")) { + std::string Value = getQualifiedName(Def) + "RegClassID"; AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32)); ResultOps.push_back(NextRecordedOperandNo++); return; } // Handle a subregister index. This is used for INSERT_SUBREG etc. - if (DI->getDef()->isSubClassOf("SubRegIndex")) { - std::string Value = getQualifiedName(DI->getDef()); + if (Def->isSubClassOf("SubRegIndex")) { + std::string Value = getQualifiedName(Def); AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32)); ResultOps.push_back(NextRecordedOperandNo++); return; diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index daf9617..4c0d385 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -588,6 +588,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, IMM("imm0_31"); IMM("imm0_31_m1"); IMM("nModImm"); + IMM("imm0_255"); IMM("imm0_4095"); IMM("jt2block_operand"); IMM("t_imm_s4"); diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp index f946ac7..f54e8df 100644 --- a/utils/TableGen/FastISelEmitter.cpp +++ b/utils/TableGen/FastISelEmitter.cpp @@ -248,6 +248,8 @@ struct OperandsSignature { // For now, the only other thing we accept is register operands. const CodeGenRegisterClass *RC = 0; + if (OpLeafRec->isSubClassOf("RegisterOperand")) + OpLeafRec = OpLeafRec->getValueAsDef("RegClass"); if (OpLeafRec->isSubClassOf("RegisterClass")) RC = &Target.getRegisterClass(OpLeafRec); else if (OpLeafRec->isSubClassOf("Register")) @@ -454,6 +456,8 @@ void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) { std::string SubRegNo; if (Op->getName() != "EXTRACT_SUBREG") { Record *Op0Rec = II.Operands[0].Rec; + if (Op0Rec->isSubClassOf("RegisterOperand")) + Op0Rec = Op0Rec->getValueAsDef("RegClass"); if (!Op0Rec->isSubClassOf("RegisterClass")) continue; DstRC = &Target.getRegisterClass(Op0Rec); diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp index 9312fe8..ba6cd86 100644 --- a/utils/TableGen/FixedLenDecoderEmitter.cpp +++ b/utils/TableGen/FixedLenDecoderEmitter.cpp @@ -1305,8 +1305,10 @@ bool FixedLenDecoderEmitter::populateInstruction(const CodeGenInstruction &CGI, RecordRecTy *Type = dynamic_cast<RecordRecTy*>(TI->getType()); Record *TypeRecord = Type->getRecord(); bool isReg = false; + if (TypeRecord->isSubClassOf("RegisterOperand")) + TypeRecord = TypeRecord->getValueAsDef("RegClass"); if (TypeRecord->isSubClassOf("RegisterClass")) { - Decoder = "Decode" + Type->getRecord()->getName() + "RegisterClass"; + Decoder = "Decode" + TypeRecord->getName() + "RegisterClass"; isReg = true; } diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index fc544ee..7b90663 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -27,14 +27,6 @@ static void PrintDefList(const std::vector<Record*> &Uses, OS << "0 };\n"; } -static void PrintBarriers(std::vector<Record*> &Barriers, - unsigned Num, raw_ostream &OS) { - OS << "static const TargetRegisterClass* Barriers" << Num << "[] = { "; - for (unsigned i = 0, e = Barriers.size(); i != e; ++i) - OS << "&" << getQualifiedName(Barriers[i]) << "RegClass, "; - OS << "NULL };\n"; -} - //===----------------------------------------------------------------------===// // Instruction Itinerary Information. //===----------------------------------------------------------------------===// @@ -43,10 +35,10 @@ void InstrInfoEmitter::GatherItinClasses() { std::vector<Record*> DefList = Records.getAllDerivedDefinitions("InstrItinClass"); std::sort(DefList.begin(), DefList.end(), LessRecord()); - + for (unsigned i = 0, N = DefList.size(); i < N; i++) ItinClassMap[DefList[i]->getName()] = i; -} +} unsigned InstrInfoEmitter::getItinClassNumber(const Record *InstRec) { return ItinClassMap[InstRec->getValueAsDef("Itinerary")->getName()]; @@ -59,7 +51,7 @@ unsigned InstrInfoEmitter::getItinClassNumber(const Record *InstRec) { std::vector<std::string> InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { std::vector<std::string> Result; - + for (unsigned i = 0, e = Inst.Operands.size(); i != e; ++i) { // Handle aggregate operands and normal operands the same way by expanding // either case into a list of operands for this op. @@ -70,7 +62,7 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { // operand, which has a single operand, but no declared class for the // operand. DagInit *MIOI = Inst.Operands[i].MIOperandInfo; - + if (!MIOI || MIOI->getNumArgs() == 0) { // Single, anonymous, operand. OperandList.push_back(Inst.Operands[i]); @@ -86,7 +78,9 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { for (unsigned j = 0, e = OperandList.size(); j != e; ++j) { Record *OpR = OperandList[j].Rec; std::string Res; - + + if (OpR->isSubClassOf("RegisterOperand")) + OpR = OpR->getValueAsDef("RegClass"); if (OpR->isSubClassOf("RegisterClass")) Res += getQualifiedName(OpR) + "RegClassID, "; else if (OpR->isSubClassOf("PointerLikeRegClass")) @@ -94,39 +88,39 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { else // -1 means the operand does not have a fixed register class. Res += "-1, "; - + // Fill in applicable flags. Res += "0"; - + // Ptr value whose register class is resolved via callback. if (OpR->isSubClassOf("PointerLikeRegClass")) - Res += "|(1<<TOI::LookupPtrRegClass)"; + Res += "|(1<<MCOI::LookupPtrRegClass)"; // Predicate operands. Check to see if the original unexpanded operand // was of type PredicateOperand. if (Inst.Operands[i].Rec->isSubClassOf("PredicateOperand")) - Res += "|(1<<TOI::Predicate)"; - + Res += "|(1<<MCOI::Predicate)"; + // Optional def operands. Check to see if the original unexpanded operand // was of type OptionalDefOperand. if (Inst.Operands[i].Rec->isSubClassOf("OptionalDefOperand")) - Res += "|(1<<TOI::OptionalDef)"; + Res += "|(1<<MCOI::OptionalDef)"; // Fill in constraint info. Res += ", "; - + const CGIOperandList::ConstraintInfo &Constraint = Inst.Operands[i].Constraints[j]; if (Constraint.isNone()) Res += "0"; else if (Constraint.isEarlyClobber()) - Res += "(1 << TOI::EARLY_CLOBBER)"; + Res += "(1 << MCOI::EARLY_CLOBBER)"; else { assert(Constraint.isTied()); Res += "((" + utostr(Constraint.getTiedOperand()) + - " << 16) | (1 << TOI::TIED_TO))"; + " << 16) | (1 << MCOI::TIED_TO))"; } - + Result.push_back(Res); } } @@ -134,12 +128,12 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { return Result; } -void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, +void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs) { // ID #0 is for no operand info. unsigned OperandListNum = 0; OperandInfoIDs[std::vector<std::string>()] = ++OperandListNum; - + OS << "\n"; const CodeGenTarget &Target = CDP.getTargetInfo(); for (CodeGenTarget::inst_iterator II = Target.inst_begin(), @@ -147,65 +141,40 @@ void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS, std::vector<std::string> OperandInfo = GetOperandInfo(**II); unsigned &N = OperandInfoIDs[OperandInfo]; if (N != 0) continue; - + N = ++OperandListNum; - OS << "static const TargetOperandInfo OperandInfo" << N << "[] = { "; + OS << "static const MCOperandInfo OperandInfo" << N << "[] = { "; for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) OS << "{ " << OperandInfo[i] << " }, "; OS << "};\n"; } } -void InstrInfoEmitter::DetectRegisterClassBarriers(std::vector<Record*> &Defs, - const std::vector<CodeGenRegisterClass> &RCs, - std::vector<Record*> &Barriers) { - std::set<Record*> DefSet; - unsigned NumDefs = Defs.size(); - for (unsigned i = 0; i < NumDefs; ++i) - DefSet.insert(Defs[i]); - - for (unsigned i = 0, e = RCs.size(); i != e; ++i) { - const CodeGenRegisterClass &RC = RCs[i]; - ArrayRef<Record*> Order = RC.getOrder(); - if (Order.size() > NumDefs) - continue; // Can't possibly clobber this RC. - - bool Clobber = true; - for (unsigned j = 0; j < Order.size(); ++j) { - Record *Reg = Order[j]; - if (!DefSet.count(Reg)) { - Clobber = false; - break; - } - } - if (Clobber) - Barriers.push_back(RC.TheDef); - } -} - //===----------------------------------------------------------------------===// // Main Output. //===----------------------------------------------------------------------===// // run - Emit the main instruction description records for the target... void InstrInfoEmitter::run(raw_ostream &OS) { + emitEnums(OS); + GatherItinClasses(); EmitSourceFileHeader("Target Instruction Descriptors", OS); + + OS << "\n#ifdef GET_INSTRINFO_MC_DESC\n"; + OS << "#undef GET_INSTRINFO_MC_DESC\n"; + OS << "namespace llvm {\n\n"; CodeGenTarget &Target = CDP.getTargetInfo(); const std::string &TargetName = Target.getName(); Record *InstrInfo = Target.getInstructionSet(); - const std::vector<CodeGenRegisterClass> &RCs = Target.getRegisterClasses(); // Keep track of all of the def lists we have emitted already. std::map<std::vector<Record*>, unsigned> EmittedLists; unsigned ListNumber = 0; - std::map<std::vector<Record*>, unsigned> EmittedBarriers; - unsigned BarrierNumber = 0; - std::map<Record*, unsigned> BarriersMap; - + // Emit all of the instruction's implicit uses and defs. for (CodeGenTarget::inst_iterator II = Target.inst_begin(), E = Target.inst_end(); II != E; ++II) { @@ -217,42 +186,43 @@ void InstrInfoEmitter::run(raw_ostream &OS) { } std::vector<Record*> Defs = Inst->getValueAsListOfDefs("Defs"); if (!Defs.empty()) { - std::vector<Record*> RCBarriers; - DetectRegisterClassBarriers(Defs, RCs, RCBarriers); - if (!RCBarriers.empty()) { - unsigned &IB = EmittedBarriers[RCBarriers]; - if (!IB) PrintBarriers(RCBarriers, IB = ++BarrierNumber, OS); - BarriersMap.insert(std::make_pair(Inst, IB)); - } - unsigned &IL = EmittedLists[Defs]; if (!IL) PrintDefList(Defs, IL = ++ListNumber, OS); } } OperandInfoMapTy OperandInfoIDs; - + // Emit all of the operand info records. EmitOperandInfo(OS, OperandInfoIDs); - - // Emit all of the TargetInstrDesc records in their ENUM ordering. + + // Emit all of the MCInstrDesc records in their ENUM ordering. // - OS << "\nstatic const TargetInstrDesc " << TargetName + OS << "\nstatic const MCInstrDesc " << TargetName << "Insts[] = {\n"; const std::vector<const CodeGenInstruction*> &NumberedInstructions = Target.getInstructionsByEnumValue(); for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) emitRecord(*NumberedInstructions[i], i, InstrInfo, EmittedLists, - BarriersMap, OperandInfoIDs, OS); - OS << "};\n"; + OperandInfoIDs, OS); + OS << "};\n\n"; + + + // MCInstrInfo initialization routine. + OS << "static inline void Init" << TargetName + << "MCInstrInfo(MCInstrInfo *II) {\n"; + OS << " II->InitMCInstrInfo(" << TargetName << "Insts, " + << NumberedInstructions.size() << ");\n}\n\n"; + OS << "} // End llvm namespace \n"; + + OS << "#endif // GET_INSTRINFO_MC_DESC\n\n"; } void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, std::map<std::vector<Record*>, unsigned> &EmittedLists, - std::map<Record*, unsigned> &BarriersMap, const OperandInfoMapTy &OpInfo, raw_ostream &OS) { int MinOperands = 0; @@ -267,31 +237,31 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, << ",\t\"" << Inst.TheDef->getName() << "\", 0"; // Emit all of the target indepedent flags... - if (Inst.isReturn) OS << "|(1<<TID::Return)"; - if (Inst.isBranch) OS << "|(1<<TID::Branch)"; - if (Inst.isIndirectBranch) OS << "|(1<<TID::IndirectBranch)"; - if (Inst.isCompare) OS << "|(1<<TID::Compare)"; - if (Inst.isMoveImm) OS << "|(1<<TID::MoveImm)"; - if (Inst.isBitcast) OS << "|(1<<TID::Bitcast)"; - if (Inst.isBarrier) OS << "|(1<<TID::Barrier)"; - if (Inst.hasDelaySlot) OS << "|(1<<TID::DelaySlot)"; - if (Inst.isCall) OS << "|(1<<TID::Call)"; - if (Inst.canFoldAsLoad) OS << "|(1<<TID::FoldableAsLoad)"; - if (Inst.mayLoad) OS << "|(1<<TID::MayLoad)"; - if (Inst.mayStore) OS << "|(1<<TID::MayStore)"; - if (Inst.isPredicable) OS << "|(1<<TID::Predicable)"; - if (Inst.isConvertibleToThreeAddress) OS << "|(1<<TID::ConvertibleTo3Addr)"; - if (Inst.isCommutable) OS << "|(1<<TID::Commutable)"; - if (Inst.isTerminator) OS << "|(1<<TID::Terminator)"; - if (Inst.isReMaterializable) OS << "|(1<<TID::Rematerializable)"; - if (Inst.isNotDuplicable) OS << "|(1<<TID::NotDuplicable)"; - if (Inst.Operands.hasOptionalDef) OS << "|(1<<TID::HasOptionalDef)"; - if (Inst.usesCustomInserter) OS << "|(1<<TID::UsesCustomInserter)"; - if (Inst.Operands.isVariadic)OS << "|(1<<TID::Variadic)"; - if (Inst.hasSideEffects) OS << "|(1<<TID::UnmodeledSideEffects)"; - if (Inst.isAsCheapAsAMove) OS << "|(1<<TID::CheapAsAMove)"; - if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<TID::ExtraSrcRegAllocReq)"; - if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<TID::ExtraDefRegAllocReq)"; + if (Inst.isReturn) OS << "|(1<<MCID::Return)"; + if (Inst.isBranch) OS << "|(1<<MCID::Branch)"; + if (Inst.isIndirectBranch) OS << "|(1<<MCID::IndirectBranch)"; + if (Inst.isCompare) OS << "|(1<<MCID::Compare)"; + if (Inst.isMoveImm) OS << "|(1<<MCID::MoveImm)"; + if (Inst.isBitcast) OS << "|(1<<MCID::Bitcast)"; + if (Inst.isBarrier) OS << "|(1<<MCID::Barrier)"; + if (Inst.hasDelaySlot) OS << "|(1<<MCID::DelaySlot)"; + if (Inst.isCall) OS << "|(1<<MCID::Call)"; + if (Inst.canFoldAsLoad) OS << "|(1<<MCID::FoldableAsLoad)"; + if (Inst.mayLoad) OS << "|(1<<MCID::MayLoad)"; + if (Inst.mayStore) OS << "|(1<<MCID::MayStore)"; + if (Inst.isPredicable) OS << "|(1<<MCID::Predicable)"; + if (Inst.isConvertibleToThreeAddress) OS << "|(1<<MCID::ConvertibleTo3Addr)"; + if (Inst.isCommutable) OS << "|(1<<MCID::Commutable)"; + if (Inst.isTerminator) OS << "|(1<<MCID::Terminator)"; + if (Inst.isReMaterializable) OS << "|(1<<MCID::Rematerializable)"; + if (Inst.isNotDuplicable) OS << "|(1<<MCID::NotDuplicable)"; + if (Inst.Operands.hasOptionalDef) OS << "|(1<<MCID::HasOptionalDef)"; + if (Inst.usesCustomInserter) OS << "|(1<<MCID::UsesCustomInserter)"; + if (Inst.Operands.isVariadic)OS << "|(1<<MCID::Variadic)"; + if (Inst.hasSideEffects) OS << "|(1<<MCID::UnmodeledSideEffects)"; + if (Inst.isAsCheapAsAMove) OS << "|(1<<MCID::CheapAsAMove)"; + if (Inst.hasExtraSrcRegAllocReq) OS << "|(1<<MCID::ExtraSrcRegAllocReq)"; + if (Inst.hasExtraDefRegAllocReq) OS << "|(1<<MCID::ExtraDefRegAllocReq)"; // Emit all of the target-specific flags... BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags"); @@ -320,12 +290,6 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, else OS << "ImplicitList" << EmittedLists[DefList] << ", "; - std::map<Record*, unsigned>::iterator BI = BarriersMap.find(Inst.TheDef); - if (BI == BarriersMap.end()) - OS << "NULL, "; - else - OS << "Barriers" << BI->second << ", "; - // Emit the operand info. std::vector<std::string> OperandInfo = GetOperandInfo(Inst); if (OperandInfo.empty()) @@ -335,3 +299,38 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; } + +// emitEnums - Print out enum values for all of the instructions. +void InstrInfoEmitter::emitEnums(raw_ostream &OS) { + EmitSourceFileHeader("Target Instruction Enum Values", OS); + + OS << "\n#ifdef GET_INSTRINFO_ENUM\n"; + OS << "#undef GET_INSTRINFO_ENUM\n"; + + OS << "namespace llvm {\n\n"; + + CodeGenTarget Target(Records); + + // We must emit the PHI opcode first... + std::string Namespace = Target.getInstNamespace(); + + if (Namespace.empty()) { + fprintf(stderr, "No instructions defined!\n"); + exit(1); + } + + const std::vector<const CodeGenInstruction*> &NumberedInstructions = + Target.getInstructionsByEnumValue(); + + OS << "namespace " << Namespace << " {\n"; + OS << " enum {\n"; + for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { + OS << " " << NumberedInstructions[i]->TheDef->getName() + << "\t= " << i << ",\n"; + } + OS << " INSTRUCTION_LIST_END = " << NumberedInstructions.size() << "\n"; + OS << " };\n}\n"; + OS << "} // End llvm namespace \n"; + + OS << "#endif // GET_INSTRINFO_ENUM\n\n"; +} diff --git a/utils/TableGen/InstrInfoEmitter.h b/utils/TableGen/InstrInfoEmitter.h index abb1c6b..165ce42 100644 --- a/utils/TableGen/InstrInfoEmitter.h +++ b/utils/TableGen/InstrInfoEmitter.h @@ -39,12 +39,12 @@ public: void run(raw_ostream &OS); private: - typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy; - + void emitEnums(raw_ostream &OS); + + typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy; void emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, std::map<std::vector<Record*>, unsigned> &EL, - std::map<Record*, unsigned> &BM, const OperandInfoMapTy &OpInfo, raw_ostream &OS); @@ -55,10 +55,6 @@ private: // Operand information. void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs); std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst); - - void DetectRegisterClassBarriers(std::vector<Record*> &Defs, - const std::vector<CodeGenRegisterClass> &RCs, - std::vector<Record*> &Barriers); }; } // End llvm namespace diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp index 3c750da..730eca1 100644 --- a/utils/TableGen/Record.cpp +++ b/utils/TableGen/Record.cpp @@ -1443,6 +1443,25 @@ Record::getValueAsListOfInts(StringRef FieldName) const { return Ints; } +/// getValueAsListOfStrings - This method looks up the specified field and +/// returns its value as a vector of strings, throwing an exception if the +/// field does not exist or if the value is not the right type. +/// +std::vector<std::string> +Record::getValueAsListOfStrings(StringRef FieldName) const { + ListInit *List = getValueAsListInit(FieldName); + std::vector<std::string> Strings; + for (unsigned i = 0; i < List->getSize(); i++) { + if (StringInit *II = dynamic_cast<StringInit*>(List->getElement(i))) { + Strings.push_back(II->getValue()); + } else { + throw "Record `" + getName() + "', field `" + FieldName.str() + + "' does not have a list of strings initializer!"; + } + } + return Strings; +} + /// getValueAsDef - This method looks up the specified field and returns its /// value as a Record, throwing an exception if the field does not exist or if /// the value is not the right type. diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h index c8905cc..f24f5e6 100644 --- a/utils/TableGen/Record.h +++ b/utils/TableGen/Record.h @@ -1368,6 +1368,12 @@ public: /// std::vector<int64_t> getValueAsListOfInts(StringRef FieldName) const; + /// getValueAsListOfStrings - This method looks up the specified field and + /// returns its value as a vector of strings, throwing an exception if the + /// field does not exist or if the value is not the right type. + /// + std::vector<std::string> getValueAsListOfStrings(StringRef FieldName) const; + /// getValueAsDef - This method looks up the specified field and returns its /// value as a Record, throwing an exception if the field does not exist or if /// the value is not the right type. diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 991f34c..abb8624 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -25,14 +25,18 @@ using namespace llvm; // runEnums - Print out enum values for all of the registers. -void RegisterInfoEmitter::runEnums(raw_ostream &OS) { - CodeGenTarget Target(Records); - CodeGenRegBank &Bank = Target.getRegBank(); +void +RegisterInfoEmitter::runEnums(raw_ostream &OS, + CodeGenTarget &Target, CodeGenRegBank &Bank) { const std::vector<CodeGenRegister*> &Registers = Bank.getRegisters(); std::string Namespace = Registers[0]->TheDef->getValueAsString("Namespace"); EmitSourceFileHeader("Target Register Enum Values", OS); + + OS << "\n#ifdef GET_REGINFO_ENUM\n"; + OS << "#undef GET_REGINFO_ENUM\n"; + OS << "namespace llvm {\n\n"; if (!Namespace.empty()) @@ -49,26 +53,158 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS) { if (!Namespace.empty()) OS << "}\n"; - const std::vector<Record*> &SubRegIndices = Bank.getSubRegIndices(); - if (!SubRegIndices.empty()) { - OS << "\n// Subregister indices\n"; - Namespace = SubRegIndices[0]->getValueAsString("Namespace"); + const std::vector<CodeGenRegisterClass> &RegisterClasses = + Target.getRegisterClasses(); + if (!RegisterClasses.empty()) { + OS << "\n// Register classes\n"; if (!Namespace.empty()) OS << "namespace " << Namespace << " {\n"; - OS << "enum {\n NoSubRegister,\n"; - for (unsigned i = 0, e = Bank.getNumNamedIndices(); i != e; ++i) - OS << " " << SubRegIndices[i]->getName() << ",\t// " << i+1 << "\n"; - OS << " NUM_TARGET_NAMED_SUBREGS = " << SubRegIndices.size()+1 << "\n"; + OS << "enum {\n"; + for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) { + if (i) OS << ",\n"; + OS << " " << RegisterClasses[i].getName() << "RegClassID"; + OS << " = " << i; + } + OS << "\n };\n"; + if (!Namespace.empty()) + OS << "}\n"; + } + + const std::vector<Record*> RegAltNameIndices = Target.getRegAltNameIndices(); + // If the only definition is the default NoRegAltName, we don't need to + // emit anything. + if (RegAltNameIndices.size() > 1) { + OS << "\n// Register alternate name indices\n"; + if (!Namespace.empty()) + OS << "namespace " << Namespace << " {\n"; + OS << "enum {\n"; + for (unsigned i = 0, e = RegAltNameIndices.size(); i != e; ++i) + OS << " " << RegAltNameIndices[i]->getName() << ",\t// " << i << "\n"; + OS << " NUM_TARGET_REG_ALT_NAMES = " << RegAltNameIndices.size() << "\n"; OS << "};\n"; if (!Namespace.empty()) OS << "}\n"; } + + + OS << "} // End llvm namespace \n"; + OS << "#endif // GET_REGINFO_ENUM\n\n"; +} + +// +// runMCDesc - Print out MC register descriptions. +// +void +RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, + CodeGenRegBank &RegBank) { + EmitSourceFileHeader("MC Register Information", OS); + + OS << "\n#ifdef GET_REGINFO_MC_DESC\n"; + OS << "#undef GET_REGINFO_MC_DESC\n"; + + std::map<const CodeGenRegister*, CodeGenRegister::Set> Overlaps; + RegBank.computeOverlaps(Overlaps); + + OS << "namespace llvm {\n\n"; + + const std::string &TargetName = Target.getName(); + std::string ClassName = TargetName + "GenMCRegisterInfo"; + OS << "struct " << ClassName << " : public MCRegisterInfo {\n" + << " explicit " << ClassName << "(const MCRegisterDesc *D);\n"; + OS << "};\n"; + + OS << "\nnamespace {\n"; + + const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters(); + + // Emit an overlap list for all registers. + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + const CodeGenRegister *Reg = Regs[i]; + const CodeGenRegister::Set &O = Overlaps[Reg]; + // Move Reg to the front so TRI::getAliasSet can share the list. + OS << " const unsigned " << Reg->getName() << "_Overlaps[] = { " + << getQualifiedName(Reg->TheDef) << ", "; + for (CodeGenRegister::Set::const_iterator I = O.begin(), E = O.end(); + I != E; ++I) + if (*I != Reg) + OS << getQualifiedName((*I)->TheDef) << ", "; + OS << "0 };\n"; + } + + // Emit the empty sub-registers list + OS << " const unsigned Empty_SubRegsSet[] = { 0 };\n"; + // Loop over all of the registers which have sub-registers, emitting the + // sub-registers list to memory. + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + const CodeGenRegister &Reg = *Regs[i]; + if (Reg.getSubRegs().empty()) + continue; + // getSubRegs() orders by SubRegIndex. We want a topological order. + SetVector<CodeGenRegister*> SR; + Reg.addSubRegsPreOrder(SR); + OS << " const unsigned " << Reg.getName() << "_SubRegsSet[] = { "; + for (unsigned j = 0, je = SR.size(); j != je; ++j) + OS << getQualifiedName(SR[j]->TheDef) << ", "; + OS << "0 };\n"; + } + + // Emit the empty super-registers list + OS << " const unsigned Empty_SuperRegsSet[] = { 0 };\n"; + // Loop over all of the registers which have super-registers, emitting the + // super-registers list to memory. + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + const CodeGenRegister &Reg = *Regs[i]; + const CodeGenRegister::SuperRegList &SR = Reg.getSuperRegs(); + if (SR.empty()) + continue; + OS << " const unsigned " << Reg.getName() << "_SuperRegsSet[] = { "; + for (unsigned j = 0, je = SR.size(); j != je; ++j) + OS << getQualifiedName(SR[j]->TheDef) << ", "; + OS << "0 };\n"; + } + + OS << "\n const MCRegisterDesc " << TargetName + << "RegDesc[] = { // Descriptors\n"; + OS << " { \"NOREG\",\t0,\t0,\t0 },\n"; + + // Now that register alias and sub-registers sets have been emitted, emit the + // register descriptors now. + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + const CodeGenRegister &Reg = *Regs[i]; + OS << " { \""; + OS << Reg.getName() << "\",\t" << Reg.getName() << "_Overlaps,\t"; + if (!Reg.getSubRegs().empty()) + OS << Reg.getName() << "_SubRegsSet,\t"; + else + OS << "Empty_SubRegsSet,\t"; + if (!Reg.getSuperRegs().empty()) + OS << Reg.getName() << "_SuperRegsSet"; + else + OS << "Empty_SuperRegsSet"; + OS << " },\n"; + } + OS << " };\n"; // End of register descriptors... + + OS << "}\n\n"; // End of anonymous namespace... + + // MCRegisterInfo initialization routine. + OS << "static inline void Init" << TargetName + << "MCRegisterInfo(MCRegisterInfo *RI) {\n"; + OS << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, " + << Regs.size()+1 << ");\n}\n\n"; + OS << "} // End llvm namespace \n"; + OS << "#endif // GET_REGINFO_MC_DESC\n\n"; } -void RegisterInfoEmitter::runHeader(raw_ostream &OS) { +void +RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target, + CodeGenRegBank &RegBank) { EmitSourceFileHeader("Register Information Header Fragment", OS); - CodeGenTarget Target(Records); + + OS << "\n#ifdef GET_REGINFO_HEADER\n"; + OS << "#undef GET_REGINFO_HEADER\n"; + const std::string &TargetName = Target.getName(); std::string ClassName = TargetName + "GenRegisterInfo"; @@ -78,8 +214,7 @@ void RegisterInfoEmitter::runHeader(raw_ostream &OS) { OS << "namespace llvm {\n\n"; OS << "struct " << ClassName << " : public TargetRegisterInfo {\n" - << " explicit " << ClassName - << "(int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1);\n" + << " explicit " << ClassName << "();\n" << " virtual int getDwarfRegNumFull(unsigned RegNum, " << "unsigned Flavour) const;\n" << " virtual int getLLVMRegNumFull(unsigned DwarfRegNum, " @@ -92,6 +227,21 @@ void RegisterInfoEmitter::runHeader(raw_ostream &OS) { << " unsigned composeSubRegIndices(unsigned, unsigned) const;\n" << "};\n\n"; + const std::vector<Record*> &SubRegIndices = RegBank.getSubRegIndices(); + if (!SubRegIndices.empty()) { + OS << "\n// Subregister indices\n"; + std::string Namespace = SubRegIndices[0]->getValueAsString("Namespace"); + if (!Namespace.empty()) + OS << "namespace " << Namespace << " {\n"; + OS << "enum {\n NoSubRegister,\n"; + for (unsigned i = 0, e = RegBank.getNumNamedIndices(); i != e; ++i) + OS << " " << SubRegIndices[i]->getName() << ",\t// " << i+1 << "\n"; + OS << " NUM_TARGET_NAMED_SUBREGS = " << SubRegIndices.size()+1 << "\n"; + OS << "};\n"; + if (!Namespace.empty()) + OS << "}\n"; + } + const std::vector<CodeGenRegisterClass> &RegisterClasses = Target.getRegisterClasses(); @@ -99,14 +249,6 @@ void RegisterInfoEmitter::runHeader(raw_ostream &OS) { OS << "namespace " << RegisterClasses[0].Namespace << " { // Register classes\n"; - OS << " enum {\n"; - for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) { - if (i) OS << ",\n"; - OS << " " << RegisterClasses[i].getName() << "RegClassID"; - OS << " = " << i; - } - OS << "\n };\n\n"; - for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) { const CodeGenRegisterClass &RC = RegisterClasses[i]; const std::string &Name = RC.getName(); @@ -128,22 +270,19 @@ void RegisterInfoEmitter::runHeader(raw_ostream &OS) { OS << "} // end of namespace " << TargetName << "\n\n"; } OS << "} // End llvm namespace \n"; + OS << "#endif // GET_REGINFO_HEADER\n\n"; } -typedef std::pair<unsigned, unsigned> UUPair; -typedef std::vector<UUPair> UUVector; - // -// RegisterInfoEmitter::run - Main register file description emitter. +// runTargetDesc - Output the target register and register file descriptions. // -void RegisterInfoEmitter::run(raw_ostream &OS) { - CodeGenTarget Target(Records); - CodeGenRegBank &RegBank = Target.getRegBank(); - RegBank.computeDerivedInfo(); - std::map<const CodeGenRegister*, CodeGenRegister::Set> Overlaps; - RegBank.computeOverlaps(Overlaps); +void +RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, + CodeGenRegBank &RegBank){ + EmitSourceFileHeader("Target Register and Register Classes Information", OS); - EmitSourceFileHeader("Register Information Source Fragment", OS); + OS << "\n#ifdef GET_REGINFO_TARGET_DESC\n"; + OS << "#undef GET_REGINFO_TARGET_DESC\n"; OS << "namespace llvm {\n\n"; @@ -407,78 +546,23 @@ void RegisterInfoEmitter::run(raw_ostream &OS) { << "RegClass,\n"; OS << " };\n"; - typedef std::map<Record*, std::vector<int64_t>, LessRecord> DwarfRegNumsMapTy; - DwarfRegNumsMapTy DwarfRegNums; - const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters(); - - // Emit an overlap list for all registers. - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - const CodeGenRegister *Reg = Regs[i]; - const CodeGenRegister::Set &O = Overlaps[Reg]; - // Move Reg to the front so TRI::getAliasSet can share the list. - OS << " const unsigned " << Reg->getName() << "_Overlaps[] = { " - << getQualifiedName(Reg->TheDef) << ", "; - for (CodeGenRegister::Set::const_iterator I = O.begin(), E = O.end(); - I != E; ++I) - if (*I != Reg) - OS << getQualifiedName((*I)->TheDef) << ", "; - OS << "0 };\n"; - } - - // Emit the empty sub-registers list - OS << " const unsigned Empty_SubRegsSet[] = { 0 };\n"; - // Loop over all of the registers which have sub-registers, emitting the - // sub-registers list to memory. - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - const CodeGenRegister &Reg = *Regs[i]; - if (Reg.getSubRegs().empty()) - continue; - // getSubRegs() orders by SubRegIndex. We want a topological order. - SetVector<CodeGenRegister*> SR; - Reg.addSubRegsPreOrder(SR); - OS << " const unsigned " << Reg.getName() << "_SubRegsSet[] = { "; - for (unsigned j = 0, je = SR.size(); j != je; ++j) - OS << getQualifiedName(SR[j]->TheDef) << ", "; - OS << "0 };\n"; - } - - // Emit the empty super-registers list - OS << " const unsigned Empty_SuperRegsSet[] = { 0 };\n"; - // Loop over all of the registers which have super-registers, emitting the - // super-registers list to memory. - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - const CodeGenRegister &Reg = *Regs[i]; - const CodeGenRegister::SuperRegList &SR = Reg.getSuperRegs(); - if (SR.empty()) - continue; - OS << " const unsigned " << Reg.getName() << "_SuperRegsSet[] = { "; - for (unsigned j = 0, je = SR.size(); j != je; ++j) - OS << getQualifiedName(SR[j]->TheDef) << ", "; - OS << "0 };\n"; - } - - OS<<"\n const TargetRegisterDesc RegisterDescriptors[] = { // Descriptors\n"; - OS << " { \"NOREG\",\t0,\t0,\t0,\t0,\t0 },\n"; + // Emit extra information about registers. + const std::string &TargetName = Target.getName(); + OS << "\n static const TargetRegisterInfoDesc " + << TargetName << "RegInfoDesc[] = " + << "{ // Extra Descriptors\n"; + OS << " { 0, 0 },\n"; - // Now that register alias and sub-registers sets have been emitted, emit the - // register descriptors now. + const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters(); for (unsigned i = 0, e = Regs.size(); i != e; ++i) { const CodeGenRegister &Reg = *Regs[i]; - OS << " { \""; - OS << Reg.getName() << "\",\t" << Reg.getName() << "_Overlaps,\t"; - if (!Reg.getSubRegs().empty()) - OS << Reg.getName() << "_SubRegsSet,\t"; - else - OS << "Empty_SubRegsSet,\t"; - if (!Reg.getSuperRegs().empty()) - OS << Reg.getName() << "_SuperRegsSet,\t"; - else - OS << "Empty_SuperRegsSet,\t"; - OS << Reg.CostPerUse << ",\t" + OS << " { "; + OS << Reg.CostPerUse << ", " << int(AllocatableRegs.count(Reg.TheDef)) << " },\n"; } OS << " };\n"; // End of register descriptors... + // Calculate the mapping of subregister+index pairs to physical registers. // This will also create further anonymous indexes. unsigned NamedIndices = RegBank.getNumNamedIndices(); @@ -575,14 +659,17 @@ void RegisterInfoEmitter::run(raw_ostream &OS) { // Emit the constructor of the class... OS << ClassName << "::" << ClassName - << "(int CallFrameSetupOpcode, int CallFrameDestroyOpcode)\n" - << " : TargetRegisterInfo(RegisterDescriptors, " << Regs.size()+1 + << "()\n" + << " : TargetRegisterInfo(" << TargetName << "RegInfoDesc" << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n" - << " SubRegIndexTable,\n" - << " CallFrameSetupOpcode, CallFrameDestroyOpcode) {\n" + << " SubRegIndexTable) {\n" + << " InitMCRegisterInfo(" << TargetName << "RegDesc, " + << Regs.size()+1 << ");\n" << "}\n\n"; // Collect all information about dwarf register numbers + typedef std::map<Record*, std::vector<int64_t>, LessRecord> DwarfRegNumsMapTy; + DwarfRegNumsMapTy DwarfRegNums; // First, just pull all provided information to the map unsigned maxLength = 0; @@ -670,4 +757,16 @@ void RegisterInfoEmitter::run(raw_ostream &OS) { OS << " };\n}\n\n"; OS << "} // End llvm namespace \n"; + OS << "#endif // GET_REGINFO_TARGET_DESC\n\n"; +} + +void RegisterInfoEmitter::run(raw_ostream &OS) { + CodeGenTarget Target(Records); + CodeGenRegBank &RegBank = Target.getRegBank(); + RegBank.computeDerivedInfo(); + + runEnums(OS, Target, RegBank); + runMCDesc(OS, Target, RegBank); + runTargetHeader(OS, Target, RegBank); + runTargetDesc(OS, Target, RegBank); } diff --git a/utils/TableGen/RegisterInfoEmitter.h b/utils/TableGen/RegisterInfoEmitter.h index 1456b4f..2c01b5c 100644 --- a/utils/TableGen/RegisterInfoEmitter.h +++ b/utils/TableGen/RegisterInfoEmitter.h @@ -20,19 +20,30 @@ namespace llvm { +class CodeGenRegBank; +class CodeGenTarget; + class RegisterInfoEmitter : public TableGenBackend { RecordKeeper &Records; public: RegisterInfoEmitter(RecordKeeper &R) : Records(R) {} - // run - Output the register file description, returning true on failure. - void run(raw_ostream &o); + // runEnums - Print out enum values for all of the registers. + void runEnums(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank); - // runHeader - Emit a header fragment for the register info emitter. - void runHeader(raw_ostream &o); + // runMCDesc - Print out MC register descriptions. + void runMCDesc(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank); - // runEnums - Print out enum values for all of the registers. - void runEnums(raw_ostream &o); + // runTargetHeader - Emit a header fragment for the register info emitter. + void runTargetHeader(raw_ostream &o, CodeGenTarget &Target, + CodeGenRegBank &Bank); + + // runTargetDesc - Output the target register and register file descriptions. + void runTargetDesc(raw_ostream &o, CodeGenTarget &Target, + CodeGenRegBank &Bank); + + // run - Output the register file description. + void run(raw_ostream &o); }; } // End llvm namespace diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp index 928fa4b..c823cb1 100644 --- a/utils/TableGen/SubtargetEmitter.cpp +++ b/utils/TableGen/SubtargetEmitter.cpp @@ -606,15 +606,15 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) { OS << "// ParseSubtargetFeatures - Parses features string setting specified\n" << "// subtarget options.\n" - << "std::string llvm::"; + << "void llvm::"; OS << Target; OS << "Subtarget::ParseSubtargetFeatures(const std::string &FS,\n" << " const std::string &CPU) {\n" << " DEBUG(dbgs() << \"\\nFeatures:\" << FS);\n" << " DEBUG(dbgs() << \"\\nCPU:\" << CPU);\n" << " SubtargetFeatures Features(FS);\n" - << " Features.setCPUIfNone(CPU);\n" - << " uint64_t Bits = Features.getBits(SubTypeKV, SubTypeKVSize,\n" + << " uint64_t Bits = Features.getFeatureBits(CPU, " + << "SubTypeKV, SubTypeKVSize,\n" << " FeatureKV, FeatureKVSize);\n"; for (unsigned i = 0; i < Features.size(); i++) { @@ -635,13 +635,13 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS) { if (HasItineraries) { OS << "\n" << " InstrItinerary *Itinerary = (InstrItinerary *)" - << "Features.getInfo(ProcItinKV, ProcItinKVSize);\n" + << "Features.getItinerary(CPU, " + << "ProcItinKV, ProcItinKVSize);\n" << " InstrItins = InstrItineraryData(Stages, OperandCycles, " << "ForwardingPathes, Itinerary);\n"; } - OS << " return Features.getCPU();\n" - << "}\n"; + OS << "}\n"; } // @@ -654,8 +654,8 @@ void SubtargetEmitter::run(raw_ostream &OS) { OS << "#include \"llvm/Support/Debug.h\"\n"; OS << "#include \"llvm/Support/raw_ostream.h\"\n"; - OS << "#include \"llvm/Target/SubtargetFeature.h\"\n"; - OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n"; + OS << "#include \"llvm/MC/SubtargetFeature.h\"\n"; + OS << "#include \"llvm/MC/MCInstrItineraries.h\"\n\n"; // Enumeration(OS, "FuncUnit", true); // OS<<"\n"; diff --git a/utils/TableGen/SubtargetEmitter.h b/utils/TableGen/SubtargetEmitter.h index 93055b7..cf793c8 100644 --- a/utils/TableGen/SubtargetEmitter.h +++ b/utils/TableGen/SubtargetEmitter.h @@ -15,7 +15,7 @@ #define SUBTARGET_EMITTER_H #include "TableGenBackend.h" -#include "llvm/Target/TargetInstrItineraries.h" +#include "llvm/MC/MCInstrItineraries.h" #include <vector> #include <map> #include <string> diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp index 39fe993..ce16c9a 100644 --- a/utils/TableGen/TableGen.cpp +++ b/utils/TableGen/TableGen.cpp @@ -28,7 +28,6 @@ #include "EDEmitter.h" #include "Error.h" #include "FastISelEmitter.h" -#include "InstrEnumEmitter.h" #include "InstrInfoEmitter.h" #include "IntrinsicEmitter.h" #include "LLVMCConfigurationEmitter.h" @@ -54,8 +53,10 @@ using namespace llvm; enum ActionType { PrintRecords, GenEmitter, - GenRegisterEnums, GenRegister, GenRegisterHeader, - GenInstrEnums, GenInstrs, GenAsmWriter, GenAsmMatcher, + GenRegisterInfo, + GenInstrInfo, + GenAsmWriter, + GenAsmMatcher, GenARMDecoder, GenDisassembler, GenCallingConv, @@ -93,15 +94,9 @@ namespace { "Print all records to stdout (default)"), clEnumValN(GenEmitter, "gen-emitter", "Generate machine code emitter"), - clEnumValN(GenRegisterEnums, "gen-register-enums", - "Generate enum values for registers"), - clEnumValN(GenRegister, "gen-register-desc", - "Generate a register info description"), - clEnumValN(GenRegisterHeader, "gen-register-desc-header", - "Generate a register info description header"), - clEnumValN(GenInstrEnums, "gen-instr-enums", - "Generate enum values for instructions"), - clEnumValN(GenInstrs, "gen-instr-desc", + clEnumValN(GenRegisterInfo, "gen-register-info", + "Generate registers and register classes info"), + clEnumValN(GenInstrInfo, "gen-instr-info", "Generate instruction descriptions"), clEnumValN(GenCallingConv, "gen-callingconv", "Generate calling convention descriptions"), @@ -261,20 +256,10 @@ int main(int argc, char **argv) { case GenEmitter: CodeEmitterGen(Records).run(Out.os()); break; - - case GenRegisterEnums: - RegisterInfoEmitter(Records).runEnums(Out.os()); - break; - case GenRegister: + case GenRegisterInfo: RegisterInfoEmitter(Records).run(Out.os()); break; - case GenRegisterHeader: - RegisterInfoEmitter(Records).runHeader(Out.os()); - break; - case GenInstrEnums: - InstrEnumEmitter(Records).run(Out.os()); - break; - case GenInstrs: + case GenInstrInfo: InstrInfoEmitter(Records).run(Out.os()); break; case GenCallingConv: |
