summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorDavid Greene <greened@obbligato.org>2009-04-23 21:25:15 +0000
committerDavid Greene <greened@obbligato.org>2009-04-23 21:25:15 +0000
commite8cf21e8e3db64dd49777d6bf6c867d47e9f5407 (patch)
tree5dc8b12e071de2abba651968b6bc3ed1b955fb2d /utils
parentaa809fbde12dda27943bafb631fbad22130814e2 (diff)
downloadllvm-e8cf21e8e3db64dd49777d6bf6c867d47e9f5407.tar.gz
llvm-e8cf21e8e3db64dd49777d6bf6c867d47e9f5407.tar.bz2
llvm-e8cf21e8e3db64dd49777d6bf6c867d47e9f5407.tar.xz
Make BinOps typed and require a type specifier for !nameconcat. This
allows binops to be used in typed contexts such as when passing arguments to classes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69921 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/CodeGenInstruction.cpp2
-rw-r--r--utils/TableGen/Record.cpp78
-rw-r--r--utils/TableGen/Record.h83
-rw-r--r--utils/TableGen/TGParser.cpp81
4 files changed, 190 insertions, 54 deletions
diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp
index b505871dee..4650b88fd5 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(R, 0);
+ DI = (DagInit*)(new BinOpInit(BinOpInit::CONCAT, DI, IDI, new DagRecTy))->Fold(R, 0);
unsigned MIOperandNo = 0;
std::set<std::string> OperandNames;
diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp
index b244219995..9ce645de34 100644
--- a/utils/TableGen/Record.cpp
+++ b/utils/TableGen/Record.cpp
@@ -138,10 +138,21 @@ Init *StringRecTy::convertValue(BinOpInit *BO) {
Init *R = BO->getRHS()->convertInitializerTo(this);
if (L == 0 || R == 0) return 0;
if (L != BO->getLHS() || R != BO->getRHS())
- return new BinOpInit(BinOpInit::STRCONCAT, L, R);
+ return new BinOpInit(BinOpInit::STRCONCAT, L, R, new StringRecTy);
return BO;
}
- return 0;
+ if (BO->getOpcode() == BinOpInit::NAMECONCAT) {
+ if (BO->getType()->getAsString() == getAsString()) {
+ Init *L = BO->getLHS()->convertInitializerTo(this);
+ Init *R = BO->getRHS()->convertInitializerTo(this);
+ if (L == 0 || R == 0) return 0;
+ if (L != BO->getLHS() || R != BO->getRHS())
+ return new BinOpInit(BinOpInit::NAMECONCAT, L, R, new StringRecTy);
+ return BO;
+ }
+ }
+
+ return convertValue((TypedInit*)BO);
}
@@ -195,9 +206,19 @@ Init *DagRecTy::convertValue(BinOpInit *BO) {
Init *R = BO->getRHS()->convertInitializerTo(this);
if (L == 0 || R == 0) return 0;
if (L != BO->getLHS() || R != BO->getRHS())
- return new BinOpInit(BinOpInit::CONCAT, L, R);
+ return new BinOpInit(BinOpInit::CONCAT, L, R, new DagRecTy);
return BO;
}
+ if (BO->getOpcode() == BinOpInit::NAMECONCAT) {
+ if (BO->getType()->getAsString() == getAsString()) {
+ Init *L = BO->getLHS()->convertInitializerTo(this);
+ Init *R = BO->getRHS()->convertInitializerTo(this);
+ if (L == 0 || R == 0) return 0;
+ if (L != BO->getLHS() || R != BO->getRHS())
+ return new BinOpInit(BinOpInit::CONCAT, L, R, new DagRecTy);
+ return BO;
+ }
+ }
return 0;
}
@@ -445,13 +466,22 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
// From TGParser::ParseIDValue
if (CurRec) {
- if (const RecordVal *RV = CurRec->getValue(Name))
+ if (const RecordVal *RV = CurRec->getValue(Name)) {
+ if (RV->getType() != getType()) {
+ throw "type mismatch in nameconcat";
+ }
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??");
+
+ if (RV->getType() != getType()) {
+ throw "type mismatch in nameconcat";
+ }
+
return new VarInit(TemplateArgName, RV->getType());
}
}
@@ -461,6 +491,11 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
if (CurMultiClass->Rec.isTemplateArg(MCName)) {
const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
assert(RV && "Template arg doesn't exist??");
+
+ if (RV->getType() != getType()) {
+ throw "type mismatch in nameconcat";
+ }
+
return new VarInit(MCName, RV->getType());
}
}
@@ -501,7 +536,7 @@ 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(&R, 0);
+ return (new BinOpInit(getOpcode(), lhs, rhs, getType()))->Fold(&R, 0);
return Fold(&R, 0);
}
@@ -513,11 +548,40 @@ 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;
+ case NAMECONCAT:
+ Result = "!nameconcat<" + getType()->getAsString() + ">"; break;
}
return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
}
+Init *BinOpInit::resolveBitReference(Record &R, const RecordVal *IRV,
+ unsigned Bit) {
+ Init *Folded = Fold(&R, 0);
+
+ if (Folded != this) {
+ TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
+ if (Typed) {
+ return Typed->resolveBitReference(R, IRV, Bit);
+ }
+ }
+
+ return 0;
+}
+
+Init *BinOpInit::resolveListElementReference(Record &R, const RecordVal *IRV,
+ unsigned Elt) {
+ Init *Folded = Fold(&R, 0);
+
+ if (Folded != this) {
+ TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
+ if (Typed) {
+ return Typed->resolveListElementReference(R, IRV, Elt);
+ }
+ }
+
+ return 0;
+}
+
Init *TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
if (T == 0) return 0; // Cannot subscript a non-bits variable...
diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h
index b408452f3d..4aec3320a2 100644
--- a/utils/TableGen/Record.h
+++ b/utils/TableGen/Record.h
@@ -77,7 +77,9 @@ public: // These methods should only be called from subclasses of Init
virtual Init *convertValue( IntInit *II) { return 0; }
virtual Init *convertValue(StringInit *SI) { return 0; }
virtual Init *convertValue( ListInit *LI) { return 0; }
- virtual Init *convertValue( BinOpInit *UI) { return 0; }
+ virtual Init *convertValue( BinOpInit *UI) {
+ return convertValue((TypedInit*)UI);
+ }
virtual Init *convertValue( CodeInit *CI) { return 0; }
virtual Init *convertValue(VarBitInit *VB) { return 0; }
virtual Init *convertValue( DefInit *DI) { return 0; }
@@ -123,7 +125,7 @@ public:
virtual Init *convertValue(VarBitInit *VB) { return (Init*)VB; }
virtual Init *convertValue( DefInit *DI) { return 0; }
virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( BinOpInit *UI) { return 0; }
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( TypedInit *TI);
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -165,7 +167,7 @@ public:
virtual Init *convertValue(VarBitInit *VB) { return 0; }
virtual Init *convertValue( DefInit *DI) { return 0; }
virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( BinOpInit *UI) { return 0; }
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( TypedInit *TI);
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -203,7 +205,7 @@ public:
virtual Init *convertValue(VarBitInit *VB) { return 0; }
virtual Init *convertValue( DefInit *DI) { return 0; }
virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( BinOpInit *UI) { return 0; }
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( TypedInit *TI);
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -282,7 +284,7 @@ public:
virtual Init *convertValue(VarBitInit *VB) { return 0; }
virtual Init *convertValue( DefInit *DI) { return 0; }
virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( BinOpInit *UI) { return 0; }
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( TypedInit *TI);
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -319,7 +321,7 @@ public:
virtual Init *convertValue(VarBitInit *VB) { return 0; }
virtual Init *convertValue( DefInit *DI) { return 0; }
virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( BinOpInit *UI) { return 0; }
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( TypedInit *TI);
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
@@ -393,7 +395,7 @@ public:
virtual Init *convertValue( ListInit *LI) { return 0; }
virtual Init *convertValue( CodeInit *CI) { return 0; }
virtual Init *convertValue(VarBitInit *VB) { return 0; }
- virtual Init *convertValue( BinOpInit *UI) { return 0; }
+ virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( DefInit *DI);
virtual Init *convertValue( DagInit *DI) { return 0; }
virtual Init *convertValue( TypedInit *VI);
@@ -656,36 +658,6 @@ public:
inline bool empty() const { return Values.empty(); }
};
-/// BinOpInit - !op (X, Y) - Combine two inits.
-///
-class BinOpInit : public Init {
-public:
- enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, NAMECONCAT };
-private:
- BinaryOp Opc;
- Init *LHS, *RHS;
-public:
- BinOpInit(BinaryOp opc, Init *lhs, Init *rhs) : Opc(opc), LHS(lhs), RHS(rhs) {
- }
-
- BinaryOp getOpcode() const { return Opc; }
- Init *getLHS() const { return LHS; }
- Init *getRHS() const { return RHS; }
-
- // Fold - If possible, fold this to a simpler init. Return this if not
- // possible to fold.
- Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
-
- virtual Init *convertInitializerTo(RecTy *Ty) {
- return Ty->convertValue(this);
- }
-
- virtual Init *resolveReferences(Record &R, const RecordVal *RV);
-
- virtual std::string getAsString() const;
-};
-
-
/// TypedInit - This is the common super-class of types that have a specific,
/// explicit, type.
@@ -714,6 +686,43 @@ public:
unsigned Elt) = 0;
};
+
+/// BinOpInit - !op (X, Y) - Combine two inits.
+///
+class BinOpInit : public TypedInit {
+public:
+ enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, NAMECONCAT };
+private:
+ BinaryOp Opc;
+ Init *LHS, *RHS;
+public:
+ BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
+ TypedInit(Type), Opc(opc), LHS(lhs), RHS(rhs) {
+ }
+
+ BinaryOp getOpcode() const { return Opc; }
+ Init *getLHS() const { return LHS; }
+ Init *getRHS() const { return RHS; }
+
+ // Fold - If possible, fold this to a simpler init. Return this if not
+ // possible to fold.
+ Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
+
+ virtual Init *convertInitializerTo(RecTy *Ty) {
+ return Ty->convertValue(this);
+ }
+
+ virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+ unsigned Bit);
+ virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt);
+
+ virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
+ virtual std::string getAsString() const;
+};
+
+
/// VarInit - 'Opcode' - Represent a reference to an entire variable object.
///
class VarInit : public TypedInit {
diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp
index d7feb98d2a..c3b17ac603 100644
--- a/utils/TableGen/TGParser.cpp
+++ b/utils/TableGen/TGParser.cpp
@@ -784,6 +784,26 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
BinOpInit::BinaryOp Code = BinOpInit::NAMECONCAT;
Lex.Lex(); // eat the operation
+
+ if (Lex.getCode() != tgtok::less) {
+ TokError("expected type name for nameconcat");
+ return 0;
+ }
+ Lex.Lex(); // eat the <
+
+ RecTy *Type = ParseType();
+
+ if (Type == 0) {
+ TokError("expected type name for nameconcat");
+ return 0;
+ }
+
+ if (Lex.getCode() != tgtok::greater) {
+ TokError("expected type name for nameconcat");
+ return 0;
+ }
+ Lex.Lex(); // eat the >
+
if (Lex.getCode() != tgtok::l_paren) {
TokError("expected '(' after binary operator");
return 0;
@@ -807,7 +827,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
return 0;
}
Lex.Lex(); // eat the ')'
- Operator = (new BinOpInit(Code, LHS, RHS))->Fold(CurRec, CurMultiClass);
+ Operator = (new BinOpInit(Code, LHS, RHS, Type))->Fold(CurRec, CurMultiClass);
}
// If the operator name is present, parse it.
@@ -842,16 +862,59 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
case tgtok::XStrConcat:
case tgtok::XNameConcat: { // Value ::= !binop '(' Value ',' Value ')'
BinOpInit::BinaryOp Code;
+ RecTy *Type = 0;
+
+
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::XNameConcat: Code = BinOpInit::NAMECONCAT; break;
+ case tgtok::XConcat:
+ Lex.Lex(); // eat the operation
+ Code = BinOpInit::CONCAT;
+ Type = new DagRecTy();
+ break;
+ case tgtok::XSRA:
+ Lex.Lex(); // eat the operation
+ Code = BinOpInit::SRA;
+ Type = new IntRecTy();
+ break;
+ case tgtok::XSRL:
+ Lex.Lex(); // eat the operation
+ Code = BinOpInit::SRL;
+ Type = new IntRecTy();
+ break;
+ case tgtok::XSHL:
+ Lex.Lex(); // eat the operation
+ Code = BinOpInit::SHL;
+ Type = new IntRecTy();
+ break;
+ case tgtok::XStrConcat:
+ Lex.Lex(); // eat the operation
+ Code = BinOpInit::STRCONCAT;
+ Type = new StringRecTy();
+ break;
+ case tgtok::XNameConcat:
+ Lex.Lex(); // eat the operation
+ Code = BinOpInit::NAMECONCAT;
+ if (Lex.getCode() != tgtok::less) {
+ TokError("expected type name for nameconcat");
+ return 0;
+ }
+ Lex.Lex(); // eat the <
+
+ Type = ParseType();
+
+ if (Type == 0) {
+ TokError("expected type name for nameconcat");
+ return 0;
+ }
+
+ if (Lex.getCode() != tgtok::greater) {
+ TokError("expected type name for nameconcat");
+ return 0;
+ }
+ Lex.Lex(); // eat the >
+ break;
}
- Lex.Lex(); // eat the operation
if (Lex.getCode() != tgtok::l_paren) {
TokError("expected '(' after binary operator");
return 0;
@@ -875,7 +938,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
return 0;
}
Lex.Lex(); // eat the ')'
- return (new BinOpInit(Code, LHS, RHS))->Fold(CurRec, CurMultiClass);
+ return (new BinOpInit(Code, LHS, RHS, Type))->Fold(CurRec, CurMultiClass);
}
}