From 947e122241d6ad326ff841ca2179da43d01331cd Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Mon, 24 May 2010 14:48:12 +0000 Subject: Add the SubRegIndex TableGen class. This is the beginning of purely symbolic subregister indices, but we need a bit of jiggling before the explicit numeric indices can be completely removed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104492 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenDAGPatterns.cpp | 5 +++++ utils/TableGen/DAGISelMatcherGen.cpp | 9 +++++++++ utils/TableGen/FastISelEmitter.cpp | 19 +++++++++++-------- utils/TableGen/RegisterInfoEmitter.cpp | 25 +++++++++++++++++++++---- 4 files changed, 46 insertions(+), 12 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index a0bccfc..878ed09 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -1057,6 +1057,11 @@ static EEVT::TypeSet getImplicitType(Record *R, unsigned ResNo, const CodeGenTarget &T = TP.getDAGPatterns().getTargetInfo(); return EEVT::TypeSet(T.getRegisterVTs(R)); } + + if (R->isSubClassOf("SubRegIndex")) { + assert(ResNo == 0 && "SubRegisterIndices only produce one result!"); + return EEVT::TypeSet(); + } if (R->isSubClassOf("ValueType") || R->isSubClassOf("CondCode")) { assert(ResNo == 0 && "This node only has one result!"); diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp index 9d469a9..eb528eb 100644 --- a/utils/TableGen/DAGISelMatcherGen.cpp +++ b/utils/TableGen/DAGISelMatcherGen.cpp @@ -224,6 +224,7 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) { if (// Handle register references. Nothing to do here, they always match. LeafRec->isSubClassOf("RegisterClass") || LeafRec->isSubClassOf("PointerLikeRegClass") || + LeafRec->isSubClassOf("SubRegIndex") || // Place holder for SRCVALUE nodes. Nothing to do here. LeafRec->getName() == "srcvalue") return; @@ -597,6 +598,14 @@ void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N, 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()); + AddMatcher(new EmitStringIntegerMatcher(Value, MVT::i32)); + ResultOps.push_back(NextRecordedOperandNo++); + return; + } } errs() << "unhandled leaf node: \n"; diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp index ce9d97b..9ec9e08 100644 --- a/utils/TableGen/FastISelEmitter.cpp +++ b/utils/TableGen/FastISelEmitter.cpp @@ -31,7 +31,7 @@ namespace { struct InstructionMemo { std::string Name; const CodeGenRegisterClass *RC; - unsigned char SubRegNo; + std::string SubRegNo; std::vector* PhysRegs; }; @@ -278,7 +278,7 @@ void FastISelMap::CollectPatterns(CodeGenDAGPatterns &CGP) { // For now, ignore instructions where the first operand is not an // output register. const CodeGenRegisterClass *DstRC = 0; - unsigned SubRegNo = ~0; + std::string SubRegNo; if (Op->getName() != "EXTRACT_SUBREG") { Record *Op0Rec = II.OperandList[0].Rec; if (!Op0Rec->isSubClassOf("RegisterClass")) @@ -287,8 +287,11 @@ void FastISelMap::CollectPatterns(CodeGenDAGPatterns &CGP) { if (!DstRC) continue; } else { - SubRegNo = static_cast( - Dst->getChild(1)->getLeafValue())->getValue(); + DefInit *SR = dynamic_cast(Dst->getChild(1)->getLeafValue()); + if (SR) + SubRegNo = getQualifiedName(SR->getDef()); + else + SubRegNo = Dst->getChild(1)->getLeafValue()->getAsString(); } // Inspect the pattern. @@ -437,7 +440,7 @@ void FastISelMap::PrintFunctionDefinitions(raw_ostream &OS) { } OS << " return FastEmitInst_"; - if (Memo.SubRegNo == (unsigned char)~0) { + if (Memo.SubRegNo.empty()) { Operands.PrintManglingSuffix(OS, *Memo.PhysRegs); OS << "(" << InstNS << Memo.Name << ", "; OS << InstNS << Memo.RC->getName() << "RegisterClass"; @@ -448,7 +451,7 @@ void FastISelMap::PrintFunctionDefinitions(raw_ostream &OS) { } else { OS << "extractsubreg(" << getName(RetVT); OS << ", Op0, Op0IsKill, "; - OS << (unsigned)Memo.SubRegNo; + OS << Memo.SubRegNo; OS << ");\n"; } @@ -532,7 +535,7 @@ void FastISelMap::PrintFunctionDefinitions(raw_ostream &OS) { OS << " return FastEmitInst_"; - if (Memo.SubRegNo == (unsigned char)~0) { + if (Memo.SubRegNo.empty()) { Operands.PrintManglingSuffix(OS, *Memo.PhysRegs); OS << "(" << InstNS << Memo.Name << ", "; OS << InstNS << Memo.RC->getName() << "RegisterClass"; @@ -542,7 +545,7 @@ void FastISelMap::PrintFunctionDefinitions(raw_ostream &OS) { OS << ");\n"; } else { OS << "extractsubreg(RetVT, Op0, Op0IsKill, "; - OS << (unsigned)Memo.SubRegNo; + OS << Memo.SubRegNo; OS << ");\n"; } diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index fcf4123..a5fabea 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -35,14 +35,31 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS) { if (!Namespace.empty()) OS << "namespace " << Namespace << " {\n"; - OS << " enum {\n NoRegister,\n"; + OS << "enum {\n NoRegister,\n"; for (unsigned i = 0, e = Registers.size(); i != e; ++i) - OS << " " << Registers[i].getName() << ", \t// " << i+1 << "\n"; - OS << " NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n"; - OS << " };\n"; + OS << " " << Registers[i].getName() << ", \t// " << i+1 << "\n"; + OS << " NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n"; + OS << "};\n"; if (!Namespace.empty()) OS << "}\n"; + + const std::vector SubRegIndices = + Records.getAllDerivedDefinitions("SubRegIndex"); + if (!SubRegIndices.empty()) { + OS << "\n// Subregister indices\n"; + Namespace = SubRegIndices[0]->getValueAsString("Namespace"); + if (!Namespace.empty()) + OS << "namespace " << Namespace << " {\n"; + OS << "enum {\n NoSubRegister,\n"; + for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) + OS << " " << SubRegIndices[i]->getName() << " = " + << SubRegIndices[i]->getValueAsInt("NumberHack") << ",\n"; + OS << " NUM_TARGET_SUBREGS = " << SubRegIndices.size()+1 << "\n"; + OS << "};\n"; + if (!Namespace.empty()) + OS << "}\n"; + } OS << "} // End llvm namespace \n"; } -- cgit v1.1