aboutsummaryrefslogtreecommitdiff
path: root/utils/TableGen
diff options
context:
space:
mode:
authorDavid Greene <greened@obbligato.org>2009-04-22 20:18:10 +0000
committerDavid Greene <greened@obbligato.org>2009-04-22 20:18:10 +0000
commitc7cafcd815519b06318629b424abe746437e1389 (patch)
treecb53439bdde7bbb4e94db441f65f2b420ca48052 /utils/TableGen
parentd7b2f7ffcecee2809cf75d71374319dc0e73a71b (diff)
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
Diffstat (limited to 'utils/TableGen')
-rw-r--r--utils/TableGen/CodeGenInstruction.cpp2
-rw-r--r--utils/TableGen/Record.cpp44
-rw-r--r--utils/TableGen/Record.h13
-rw-r--r--utils/TableGen/TGLexer.cpp11
-rw-r--r--utils/TableGen/TGLexer.h4
-rw-r--r--utils/TableGen/TGParser.cpp68
6 files changed, 108 insertions, 34 deletions
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<std::string> 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<StringInit*>(LHS);
+ StringInit *RHSs = dynamic_cast<StringInit*>(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<Record*> RecordVector;
+ RecordVector DefPrototypes;
+
+ MultiClass(const std::string &Name, TGLoc Loc) : Rec(Name, Loc) {}
+};
+
class RecordKeeper {
std::map<std::string, Record*> 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<Record*> 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<std::pair<llvm::Init*, std::string> > 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);
}
}