From c7cafcd815519b06318629b424abe746437e1389 Mon Sep 17 00:00:00 2001 From: David Greene Date: Wed, 22 Apr 2009 20:18:10 +0000 Subject: Implement !nameconcat to concatenate strings and look up the resulting name in the symbol table, returning an object. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69822 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenInstruction.cpp | 2 +- utils/TableGen/Record.cpp | 44 +++++++++++++++++++++-- utils/TableGen/Record.h | 13 +++++-- utils/TableGen/TGLexer.cpp | 11 +++--- utils/TableGen/TGLexer.h | 4 +-- utils/TableGen/TGParser.cpp | 68 ++++++++++++++++++++++++----------- 6 files changed, 108 insertions(+), 34 deletions(-) (limited to 'utils/TableGen') diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index 185db01418..b505871dee 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -127,7 +127,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr) OperandList.clear(); return; } - DI = (DagInit*)(new BinOpInit(BinOpInit::CONCAT, DI, IDI))->Fold(); + DI = (DagInit*)(new BinOpInit(BinOpInit::CONCAT, DI, IDI))->Fold(R, 0); unsigned MIOperandNo = 0; std::set OperandNames; diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp index e2d9657c4d..b244219995 100644 --- a/utils/TableGen/Record.cpp +++ b/utils/TableGen/Record.cpp @@ -395,7 +395,7 @@ std::string ListInit::getAsString() const { return Result + "]"; } -Init *BinOpInit::Fold() { +Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { switch (getOpcode()) { default: assert(0 && "Unknown binop"); case CONCAT: { @@ -437,6 +437,43 @@ Init *BinOpInit::Fold() { return new StringInit(LHSs->getValue() + RHSs->getValue()); break; } + case NAMECONCAT: { + StringInit *LHSs = dynamic_cast(LHS); + StringInit *RHSs = dynamic_cast(RHS); + if (LHSs && RHSs) { + std::string Name(LHSs->getValue() + RHSs->getValue()); + + // From TGParser::ParseIDValue + if (CurRec) { + if (const RecordVal *RV = CurRec->getValue(Name)) + return new VarInit(Name, RV->getType()); + + std::string TemplateArgName = CurRec->getName()+":"+Name; + if (CurRec->isTemplateArg(TemplateArgName)) { + const RecordVal *RV = CurRec->getValue(TemplateArgName); + assert(RV && "Template arg doesn't exist??"); + return new VarInit(TemplateArgName, RV->getType()); + } + } + + if (CurMultiClass) { + std::string MCName = CurMultiClass->Rec.getName()+"::"+Name; + if (CurMultiClass->Rec.isTemplateArg(MCName)) { + const RecordVal *RV = CurMultiClass->Rec.getValue(MCName); + assert(RV && "Template arg doesn't exist??"); + return new VarInit(MCName, RV->getType()); + } + } + + if (Record *D = Records.getDef(Name)) + return new DefInit(D); + + cerr << "Variable not defined: '" + Name + "'\n"; + assert(0 && "Variable not found"); + return 0; + } + break; + } case SHL: case SRA: case SRL: { @@ -464,8 +501,8 @@ Init *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) { Init *rhs = RHS->resolveReferences(R, RV); if (LHS != lhs || RHS != rhs) - return (new BinOpInit(getOpcode(), lhs, rhs))->Fold(); - return Fold(); + return (new BinOpInit(getOpcode(), lhs, rhs))->Fold(&R, 0); + return Fold(&R, 0); } std::string BinOpInit::getAsString() const { @@ -476,6 +513,7 @@ std::string BinOpInit::getAsString() const { case SRA: Result = "!sra"; break; case SRL: Result = "!srl"; break; case STRCONCAT: Result = "!strconcat"; break; + case NAMECONCAT: Result = "!nameconcat"; break; } return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")"; } diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h index 32172ef12a..b408452f3d 100644 --- a/utils/TableGen/Record.h +++ b/utils/TableGen/Record.h @@ -53,6 +53,7 @@ class VarListElementInit; // Other classes. class Record; class RecordVal; +class MultiClass; //===----------------------------------------------------------------------===// // Type Classes @@ -659,7 +660,7 @@ public: /// class BinOpInit : public Init { public: - enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT }; + enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, NAMECONCAT }; private: BinaryOp Opc; Init *LHS, *RHS; @@ -673,7 +674,7 @@ public: // Fold - If possible, fold this to a simpler init. Return this if not // possible to fold. - Init *Fold(); + Init *Fold(Record *CurRec, MultiClass *CurMultiClass); virtual Init *convertInitializerTo(RecTy *Ty) { return Ty->convertValue(this); @@ -1124,6 +1125,14 @@ public: std::ostream &operator<<(std::ostream &OS, const Record &R); +struct MultiClass { + Record Rec; // Placeholder for template args and Name. + typedef std::vector RecordVector; + RecordVector DefPrototypes; + + MultiClass(const std::string &Name, TGLoc Loc) : Rec(Name, Loc) {} +}; + class RecordKeeper { std::map Classes, Defs; public: diff --git a/utils/TableGen/TGLexer.cpp b/utils/TableGen/TGLexer.cpp index 79982aa05f..f2ea7a1517 100644 --- a/utils/TableGen/TGLexer.cpp +++ b/utils/TableGen/TGLexer.cpp @@ -429,11 +429,12 @@ tgtok::TokKind TGLexer::LexExclaim() { // Check to see which operator this is. unsigned Len = CurPtr-Start; - if (Len == 3 && !memcmp(Start, "con", 3)) return tgtok::XConcat; - if (Len == 3 && !memcmp(Start, "sra", 3)) return tgtok::XSRA; - if (Len == 3 && !memcmp(Start, "srl", 3)) return tgtok::XSRL; - if (Len == 3 && !memcmp(Start, "shl", 3)) return tgtok::XSHL; - if (Len == 9 && !memcmp(Start, "strconcat", 9)) return tgtok::XStrConcat; + if (Len == 3 && !memcmp(Start, "con", 3)) return tgtok::XConcat; + if (Len == 3 && !memcmp(Start, "sra", 3)) return tgtok::XSRA; + if (Len == 3 && !memcmp(Start, "srl", 3)) return tgtok::XSRL; + if (Len == 3 && !memcmp(Start, "shl", 3)) return tgtok::XSHL; + if (Len == 9 && !memcmp(Start, "strconcat", 9)) return tgtok::XStrConcat; + if (Len == 10 && !memcmp(Start, "nameconcat", 10)) return tgtok::XNameConcat; return ReturnError(Start-1, "Unknown operator"); } diff --git a/utils/TableGen/TGLexer.h b/utils/TableGen/TGLexer.h index 245dd41461..734dc2651e 100644 --- a/utils/TableGen/TGLexer.h +++ b/utils/TableGen/TGLexer.h @@ -45,8 +45,8 @@ namespace tgtok { MultiClass, String, // !keywords. - XConcat, XSRA, XSRL, XSHL, XStrConcat, - + XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, + // Integer value. IntVal, diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp index ddaf55803f..45ad5792f9 100644 --- a/utils/TableGen/TGParser.cpp +++ b/utils/TableGen/TGParser.cpp @@ -23,14 +23,6 @@ using namespace llvm; //===----------------------------------------------------------------------===// namespace llvm { -struct MultiClass { - Record Rec; // Placeholder for template args and Name. - typedef std::vector RecordVector; - RecordVector DefPrototypes; - - MultiClass(const std::string &Name, TGLoc Loc) : Rec(Name, Loc) {} -}; - struct SubClassReference { TGLoc RefLoc; Record *Rec; @@ -777,14 +769,47 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) { } case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')' Lex.Lex(); // eat the '(' - if (Lex.getCode() != tgtok::Id) { + if (Lex.getCode() != tgtok::Id + && Lex.getCode() != tgtok::XNameConcat) { TokError("expected identifier in dag init"); return 0; } - Init *Operator = ParseIDValue(CurRec); - if (Operator == 0) return 0; - + Init *Operator = 0; + if (Lex.getCode() == tgtok::Id) { + Operator = ParseIDValue(CurRec); + if (Operator == 0) return 0; + } + else { + BinOpInit::BinaryOp Code = BinOpInit::NAMECONCAT; + + Lex.Lex(); // eat the operation + if (Lex.getCode() != tgtok::l_paren) { + TokError("expected '(' after binary operator"); + return 0; + } + Lex.Lex(); // eat the '(' + + Init *LHS = ParseValue(CurRec); + if (LHS == 0) return 0; + + if (Lex.getCode() != tgtok::comma) { + TokError("expected ',' in binary operator"); + return 0; + } + Lex.Lex(); // eat the ',' + + Init *RHS = ParseValue(CurRec); + if (RHS == 0) return 0; + + if (Lex.getCode() != tgtok::r_paren) { + TokError("expected ')' in binary operator"); + return 0; + } + Lex.Lex(); // eat the ')' + Operator = (new BinOpInit(Code, LHS, RHS))->Fold(CurRec, CurMultiClass); + } + // If the operator name is present, parse it. std::string OperatorName; if (Lex.getCode() == tgtok::colon) { @@ -796,7 +821,6 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) { Lex.Lex(); // eat the VarName. } - std::vector > DagArgs; if (Lex.getCode() != tgtok::r_paren) { DagArgs = ParseDagArgList(CurRec); @@ -815,15 +839,17 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) { case tgtok::XSRA: case tgtok::XSRL: case tgtok::XSHL: - case tgtok::XStrConcat: { // Value ::= !binop '(' Value ',' Value ')' + case tgtok::XStrConcat: + case tgtok::XNameConcat: { // Value ::= !binop '(' Value ',' Value ')' BinOpInit::BinaryOp Code; switch (Lex.getCode()) { default: assert(0 && "Unhandled code!"); - case tgtok::XConcat: Code = BinOpInit::CONCAT; break; - case tgtok::XSRA: Code = BinOpInit::SRA; break; - case tgtok::XSRL: Code = BinOpInit::SRL; break; - case tgtok::XSHL: Code = BinOpInit::SHL; break; - case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break; + case tgtok::XConcat: Code = BinOpInit::CONCAT; break; + case tgtok::XSRA: Code = BinOpInit::SRA; break; + case tgtok::XSRL: Code = BinOpInit::SRL; break; + case tgtok::XSHL: Code = BinOpInit::SHL; break; + case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break; + case tgtok::XNameConcat: Code = BinOpInit::NAMECONCAT; break; } Lex.Lex(); // eat the operation if (Lex.getCode() != tgtok::l_paren) { @@ -831,7 +857,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) { return 0; } Lex.Lex(); // eat the '(' - + Init *LHS = ParseValue(CurRec); if (LHS == 0) return 0; @@ -849,7 +875,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) { return 0; } Lex.Lex(); // eat the ')' - return (new BinOpInit(Code, LHS, RHS))->Fold(); + return (new BinOpInit(Code, LHS, RHS))->Fold(CurRec, CurMultiClass); } } -- cgit v1.2.3-18-g5258