summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorDavid Greene <greened@obbligato.org>2009-05-14 20:54:48 +0000
committerDavid Greene <greened@obbligato.org>2009-05-14 20:54:48 +0000
commitd418c1b768b5ff26afe05a5ce84d920bbbc99583 (patch)
treea353f9555d0b125cbeaed9fc9d727545061e65a0 /utils
parentccf85ded583167cbdbc20043e698eda8a7c2ed7d (diff)
downloadllvm-d418c1b768b5ff26afe05a5ce84d920bbbc99583.tar.gz
llvm-d418c1b768b5ff26afe05a5ce84d920bbbc99583.tar.bz2
llvm-d418c1b768b5ff26afe05a5ce84d920bbbc99583.tar.xz
Operation Enhancements
Create an OpInit class to serve as a base for all operation Inits. Move parsing of operation constructs to separate functions and reference from multiple places. Add some commented out new operations. Coming soon. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71789 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/Record.cpp374
-rw-r--r--utils/TableGen/Record.h165
-rw-r--r--utils/TableGen/TGLexer.cpp5
-rw-r--r--utils/TableGen/TGLexer.h3
-rw-r--r--utils/TableGen/TGParser.cpp367
-rw-r--r--utils/TableGen/TGParser.h2
6 files changed, 751 insertions, 165 deletions
diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp
index d420e6338c..0f31861269 100644
--- a/utils/TableGen/Record.cpp
+++ b/utils/TableGen/Record.cpp
@@ -132,6 +132,18 @@ Init *IntRecTy::convertValue(TypedInit *TI) {
return 0;
}
+// Init *StringRecTy::convertValue(UnOpInit *BO) {
+// if (BO->getOpcode() == UnOpInit::CAST) {
+// Init *L = BO->getOperand()->convertInitializerTo(this);
+// if (L == 0) return 0;
+// if (L != BO->getOperand())
+// return new UnOpInit(UnOpInit::CAST, L, new StringRecTy);
+// return BO;
+// }
+
+// return convertValue((TypedInit*)BO);
+// }
+
Init *StringRecTy::convertValue(BinOpInit *BO) {
if (BO->getOpcode() == BinOpInit::STRCONCAT) {
Init *L = BO->getLHS()->convertInitializerTo(this);
@@ -200,6 +212,17 @@ Init *DagRecTy::convertValue(TypedInit *TI) {
return 0;
}
+// Init *DagRecTy::convertValue(UnOpInit *BO) {
+// if (BO->getOpcode() == UnOpInit::CAST) {
+// Init *L = BO->getOperand()->convertInitializerTo(this);
+// if (L == 0) return 0;
+// if (L != BO->getOperand())
+// return new UnOpInit(UnOpInit::CAST, L, new DagRecTy);
+// return BO;
+// }
+// return 0;
+// }
+
Init *DagRecTy::convertValue(BinOpInit *BO) {
if (BO->getOpcode() == BinOpInit::CONCAT) {
Init *L = BO->getLHS()->convertInitializerTo(this);
@@ -416,6 +439,107 @@ std::string ListInit::getAsString() const {
return Result + "]";
}
+Init *OpInit::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 *OpInit::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 *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
+// switch (getOpcode()) {
+// default: assert(0 && "Unknown unop");
+// case CAST: {
+// StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+// if (LHSs) {
+// std::string Name = LHSs->getValue();
+
+// // From TGParser::ParseIDValue
+// if (CurRec) {
+// 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());
+// }
+// }
+
+// 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??");
+
+// if (RV->getType() != getType()) {
+// throw "type mismatch in nameconcat";
+// }
+
+// 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;
+// }
+// }
+// return this;
+// }
+
+// Init *UnOpInit::resolveReferences(Record &R, const RecordVal *RV) {
+// Init *lhs = LHS->resolveReferences(R, RV);
+
+// if (LHS != lhs)
+// return (new UnOpInit(getOpcode(), lhs, getType()))->Fold(&R, 0);
+// return Fold(&R, 0);
+// }
+
+// std::string UnOpInit::getAsString() const {
+// std::string Result;
+// switch (Opc) {
+// case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break;
+// }
+// return Result + "(" + LHS->getAsString() + ")";
+// }
+
Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
switch (getOpcode()) {
default: assert(0 && "Unknown binop");
@@ -554,33 +678,231 @@ std::string BinOpInit::getAsString() const {
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);
- }
- }
+// Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
+// switch (getOpcode()) {
+// default: assert(0 && "Unknown binop");
+// case SUBST: {
+// DefInit *LHSd = dynamic_cast<DefInit*>(LHS);
+// VarInit *LHSv = dynamic_cast<VarInit*>(LHS);
+// StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+
+// DefInit *MHSd = dynamic_cast<DefInit*>(MHS);
+// VarInit *MHSv = dynamic_cast<VarInit*>(MHS);
+// StringInit *MHSs = dynamic_cast<StringInit*>(MHS);
+
+// DagInit *RHSd = dynamic_cast<DagInit*>(RHS);
+// ListInit *RHSl = dynamic_cast<ListInit*>(RHS);
+
+// DagRecTy *DagType = dynamic_cast<DagRecTy*>(getType());
+// ListRecTy *ListType = dynamic_cast<ListRecTy*>(getType());
+
+// if ((DagType && RHSd || ListType && RHSl)
+// && (LHSd && MHSd || LHSv && MHSv || LHSs && MHSs)) {
+// if (RHSd) {
+// Init *Val = RHSd->getOperator();
+// if (Val->getAsString() == LHS->getAsString()) {
+// Val = MHS;
+// }
+// std::vector<std::pair<Init *, std::string> > args;
+// for (int i = 0; i < RHSd->getNumArgs(); ++i) {
+// Init *Arg;
+// std::string ArgName;
+// Arg = RHSd->getArg(i);
+// ArgName = RHSd->getArgName(i);
+// if (Arg->getAsString() == LHS->getAsString()) {
+// Arg = MHS;
+// }
+// if (ArgName == LHS->getAsString()) {
+// ArgName = MHS->getAsString();
+// }
+// args.push_back(std::make_pair(Arg, ArgName));
+// }
+
+// return new DagInit(Val, args);
+// }
+// if (RHSl) {
+// std::vector<Init *> NewList(RHSl->begin(), RHSl->end());
+
+// for (ListInit::iterator i = NewList.begin(),
+// iend = NewList.end();
+// i != iend;
+// ++i) {
+// if ((*i)->getAsString() == LHS->getAsString()) {
+// *i = MHS;
+// }
+// }
+// return new ListInit(NewList);
+// }
+// }
+// break;
+// }
+
+// case FOREACH: {
+// DagInit *MHSd = dynamic_cast<DagInit*>(MHS);
+// ListInit *MHSl = dynamic_cast<ListInit*>(MHS);
+
+// DagRecTy *DagType = dynamic_cast<DagRecTy*>(getType());
+// ListRecTy *ListType = dynamic_cast<ListRecTy*>(getType());
+
+// OpInit *RHSo = dynamic_cast<OpInit*>(RHS);
+
+// if (!RHSo) {
+// cerr << "!foreach requires an operator\n";
+// assert(0 && "No operator for !foreach");
+// }
+
+// TypedInit *LHSt = dynamic_cast<TypedInit*>(LHS);
+
+// if (!LHSt) {
+// cerr << "!foreach requires typed variable\n";
+// assert(0 && "No typed variable for !foreach");
+// }
+
+// if (MHSd && DagType || MHSl && ListType) {
+// std::vector<Init *> NewOperands;
+// if (MHSd) {
+// Init *Val = MHSd->getOperator();
+// TypedInit *TVal = dynamic_cast<TypedInit*>(Val);
+
+// if (TVal && TVal->getType()->typeIsConvertibleTo(LHSt->getType())) {
+
+// // First, replace the foreach variable with the DAG leaf
+// for (int i = 0; i < RHSo->getNumOperands(); ++i) {
+// if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
+// NewOperands.push_back(Val);
+// }
+// else {
+// NewOperands.push_back(RHSo->getOperand(i));
+// }
+// }
+
+// // Now run the operator and use its result as the new leaf
+// OpInit *NewOp = RHSo->clone(NewOperands);
+// Val = NewOp->Fold(CurRec, CurMultiClass);
+// if (Val != NewOp) {
+// delete NewOp;
+// }
+// }
+
+// std::vector<std::pair<Init *, std::string> > args;
+// for (int i = 0; i < MHSd->getNumArgs(); ++i) {
+// Init *Arg;
+// std::string ArgName;
+// Arg = MHSd->getArg(i);
+// ArgName = MHSd->getArgName(i);
+
+// TypedInit *TArg = dynamic_cast<TypedInit*>(Arg);
+
+// if (TArg && TArg->getType()->typeIsConvertibleTo(LHSt->getType())) {
+// NewOperands.clear();
+
+// // First, replace the foreach variable with the DAG leaf
+// for (int i = 0; i < RHSo->getNumOperands(); ++i) {
+// if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
+// NewOperands.push_back(Arg);
+// }
+// else {
+// NewOperands.push_back(RHSo->getOperand(i));
+// }
+// }
+
+// // Now run the operator and use its result as the new leaf
+// OpInit *NewOp = RHSo->clone(NewOperands);
+// Arg = NewOp->Fold(CurRec, CurMultiClass);
+// if (Arg != NewOp) {
+// delete NewOp;
+// }
+// }
+
+// if (LHSt->getType()->getAsString() == "string") {
+// NewOperands.clear();
+
+// // First, replace the foreach variable with the DAG leaf
+// for (int i = 0; i < RHSo->getNumOperands(); ++i) {
+// if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
+// NewOperands.push_back(new StringInit(ArgName));
+// }
+// else {
+// NewOperands.push_back(RHSo->getOperand(i));
+// }
+// }
+
+// // Now run the operator and use its result as the new leaf
+// OpInit *NewOp = RHSo->clone(NewOperands);
+// Init *ArgNameInit = NewOp->Fold(CurRec, CurMultiClass);
+// StringInit *SArgNameInit = dynamic_cast<StringInit*>(ArgNameInit);
+// if (SArgNameInit) {
+// ArgName = SArgNameInit->getValue();
+// }
+// if (ArgNameInit != NewOp) {
+// delete NewOp;
+// }
+// delete ArgNameInit;
+// }
+
+// args.push_back(std::make_pair(Arg, ArgName));
+// }
+
+// return new DagInit(Val, args);
+// }
+// if (MHSl) {
+// std::vector<Init *> NewList(MHSl->begin(), MHSl->end());
+
+// for (ListInit::iterator li = NewList.begin(),
+// liend = NewList.end();
+// li != liend;
+// ++li) {
+// Init *Item = *li;
+// TypedInit *TItem = dynamic_cast<TypedInit*>(Item);
+// if (TItem && TItem->getType()->typeIsConvertibleTo(LHSt->getType())) {
+// // First, replace the foreach variable with the list item
+// for (int i = 0; i < RHSo->getNumOperands(); ++i) {
+// if (LHS->getAsString() == RHSo->getOperand(i)->getAsString()) {
+// NewOperands.push_back(Item);
+// }
+// else {
+// NewOperands.push_back(RHSo->getOperand(i));
+// }
+// }
+
+// // Now run the operator and use its result as the new list item
+// OpInit *NewOp = RHSo->clone(NewOperands);
+// *li = NewOp->Fold(CurRec, CurMultiClass);
+// if (*li != NewOp) {
+// delete NewOp;
+// }
+// }
+// }
+
+// return new ListInit(NewList);
+// }
+// }
+// break;
+// }
+// }
+
+// return this;
+// }
+
+// Init *TernOpInit::resolveReferences(Record &R, const RecordVal *RV) {
+// Init *lhs = LHS->resolveReferences(R, RV);
+// Init *mhs = MHS->resolveReferences(R, RV);
+// Init *rhs = RHS->resolveReferences(R, RV);
- return 0;
-}
+// if (LHS != lhs || MHS != mhs || RHS != rhs)
+// return (new TernOpInit(getOpcode(), lhs, mhs, rhs, getType()))->Fold(&R, 0);
+// return Fold(&R, 0);
+// }
+
+// std::string TernOpInit::getAsString() const {
+// std::string Result;
+// switch (Opc) {
+// case SUBST: Result = "!subst"; break;
+// case FOREACH: Result = "!foreach"; break;
+// }
+// return Result + "(" + LHS->getAsString() + ", " + MHS->getAsString() + ", "
+// + RHS->getAsString() + ")";
+// }
Init *TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h
index f76de7d4ef..b0b4ac17b4 100644
--- a/utils/TableGen/Record.h
+++ b/utils/TableGen/Record.h
@@ -41,7 +41,9 @@ class IntInit;
class StringInit;
class CodeInit;
class ListInit;
+ //class UnOpInit;
class BinOpInit;
+ //class TernOpInit;
class DefInit;
class DagInit;
class TypedInit;
@@ -77,9 +79,15 @@ 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( UnOpInit *UI) {
+// return convertValue((TypedInit*)UI);
+// }
virtual Init *convertValue( BinOpInit *UI) {
return convertValue((TypedInit*)UI);
}
+// virtual Init *convertValue( TernOpInit *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; }
@@ -125,7 +133,9 @@ 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( UnOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+ //virtual Init *convertValue( TernOpInit *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);}
@@ -167,7 +177,9 @@ 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( UnOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+ //virtual Init *convertValue( TernOpInit *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);}
@@ -205,7 +217,9 @@ 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( UnOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+ //virtual Init *convertValue( TernOpInit *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);}
@@ -237,7 +251,10 @@ public:
virtual Init *convertValue( IntInit *II) { return 0; }
virtual Init *convertValue(StringInit *SI) { return (Init*)SI; }
virtual Init *convertValue( ListInit *LI) { return 0; }
+ //virtual Init *convertValue( UnOpInit *BO);
virtual Init *convertValue( BinOpInit *BO);
+ //virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
+
virtual Init *convertValue( CodeInit *CI) { return 0; }
virtual Init *convertValue(VarBitInit *VB) { return 0; }
virtual Init *convertValue( DefInit *DI) { return 0; }
@@ -284,7 +301,9 @@ 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( UnOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+ //virtual Init *convertValue( TernOpInit *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);}
@@ -321,7 +340,9 @@ 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( UnOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+ //virtual Init *convertValue( TernOpInit *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);}
@@ -354,7 +375,9 @@ public:
virtual Init *convertValue( CodeInit *CI) { return 0; }
virtual Init *convertValue(VarBitInit *VB) { return 0; }
virtual Init *convertValue( DefInit *DI) { return 0; }
+ //virtual Init *convertValue( UnOpInit *BO);
virtual Init *convertValue( BinOpInit *BO);
+ //virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
virtual Init *convertValue( DagInit *CI) { return (Init*)CI; }
virtual Init *convertValue( TypedInit *TI);
virtual Init *convertValue( VarInit *VI) { return RecTy::convertValue(VI);}
@@ -395,7 +418,9 @@ 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( UnOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
+ //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
virtual Init *convertValue( DefInit *DI);
virtual Init *convertValue( DagInit *DI) { return 0; }
virtual Init *convertValue( TypedInit *VI);
@@ -686,10 +711,73 @@ public:
unsigned Elt) = 0;
};
+/// OpInit - Base class for operators
+///
+class OpInit : public TypedInit {
+public:
+ OpInit(RecTy *Type) : TypedInit(Type) {}
+
+ // Clone - Clone this operator, replacing arguments with the new list
+ virtual OpInit *clone(std::vector<Init *> &Operands) = 0;
+
+ virtual int getNumOperands(void) const = 0;
+ virtual Init *getOperand(int i) = 0;
+
+ // Fold - If possible, fold this to a simpler init. Return this if not
+ // possible to fold.
+ virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) = 0;
+
+ 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);
+};
+
+
+/// UnOpInit - !op (X) - Transform an init.
+///
+// class UnOpInit : public OpInit {
+// public:
+// enum UnaryOp { CAST };
+// private:
+// UnaryOp Opc;
+// Init *LHS;
+// public:
+// UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type) :
+// OpInit(Type), Opc(opc), LHS(lhs) {
+// }
+
+// // Clone - Clone this operator, replacing arguments with the new list
+// virtual OpInit *clone(std::vector<Init *> &Operands) {
+// assert(Operands.size() == 1 && "Wrong number of operands for unary operation");
+// return new UnOpInit(getOpcode(), *Operands.begin(), getType());
+// }
+
+// int getNumOperands(void) const { return 1; }
+// Init *getOperand(int i) {
+// assert(i == 0 && "Invalid operand id for unary operator");
+// return getOperand();
+// }
+
+// UnaryOp getOpcode() const { return Opc; }
+// Init *getOperand() const { return LHS; }
+
+// // Fold - If possible, fold this to a simpler init. Return this if not
+// // possible to fold.
+// Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
+
+// virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
+// virtual std::string getAsString() const;
+// };
/// BinOpInit - !op (X, Y) - Combine two inits.
///
-class BinOpInit : public TypedInit {
+class BinOpInit : public OpInit {
public:
enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, NAMECONCAT };
private:
@@ -697,9 +785,26 @@ private:
Init *LHS, *RHS;
public:
BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
- TypedInit(Type), Opc(opc), LHS(lhs), RHS(rhs) {
+ OpInit(Type), Opc(opc), LHS(lhs), RHS(rhs) {
}
+ // Clone - Clone this operator, replacing arguments with the new list
+ virtual OpInit *clone(std::vector<Init *> &Operands) {
+ assert(Operands.size() == 2 && "Wrong number of operands for binary operation");
+ return new BinOpInit(getOpcode(), Operands[0], Operands[1], getType());
+ }
+
+ int getNumOperands(void) const { return 2; }
+ Init *getOperand(int i) {
+ assert(i == 0 || i == 1 && "Invalid operand id for binary operator");
+ if (i == 0) {
+ return getLHS();
+ }
+ else {
+ return getRHS();
+ }
+ }
+
BinaryOp getOpcode() const { return Opc; }
Init *getLHS() const { return LHS; }
Init *getRHS() const { return RHS; }
@@ -708,20 +813,58 @@ public:
// 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;
};
+/// TernOpInit - !op (X, Y, Z) - Combine two inits.
+///
+// class TernOpInit : public OpInit {
+// public:
+// enum TernaryOp { SUBST, FOREACH };
+// private:
+// TernaryOp Opc;
+// Init *LHS, *MHS, *RHS;
+// public:
+// TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type) :
+// OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {
+// }
+
+// // Clone - Clone this operator, replacing arguments with the new list
+// virtual OpInit *clone(std::vector<Init *> &Operands) {
+// assert(Operands.size() == 3 && "Wrong number of operands for ternary operation");
+// return new TernOpInit(getOpcode(), Operands[0], Operands[1], Operands[2], getType());
+// }
+
+// int getNumOperands(void) const { return 3; }
+// Init *getOperand(int i) {
+// assert(i == 0 || i == 1 || i == 2 && "Invalid operand id for ternary operator");
+// if (i == 0) {
+// return getLHS();
+// }
+// else if (i == 1) {
+// return getMHS();
+// }
+// else {
+// return getRHS();
+// }
+// }
+
+// TernaryOp getOpcode() const { return Opc; }
+// Init *getLHS() const { return LHS; }
+// Init *getMHS() const { return MHS; }
+// 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 *resolveReferences(Record &R, const RecordVal *RV);
+
+// virtual std::string getAsString() const;
+// };
+
/// VarInit - 'Opcode' - Represent a reference to an entire variable object.
///
diff --git a/utils/TableGen/TGLexer.cpp b/utils/TableGen/TGLexer.cpp
index 8eb219b66b..5e96e50351 100644
--- a/utils/TableGen/TGLexer.cpp
+++ b/utils/TableGen/TGLexer.cpp
@@ -447,7 +447,10 @@ tgtok::TokKind TGLexer::LexExclaim() {
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;
-
+// if (Len == 5 && !memcmp(Start, "subst", 5)) return tgtok::XSubst;
+// if (Len == 7 && !memcmp(Start, "foreach", 7)) return tgtok::XForEach;
+// if (Len == 4 && !memcmp(Start, "cast", 4)) return tgtok::XCast;
+
return ReturnError(Start-1, "Unknown operator");
}
diff --git a/utils/TableGen/TGLexer.h b/utils/TableGen/TGLexer.h
index 734dc2651e..0f27308afd 100644
--- a/utils/TableGen/TGLexer.h
+++ b/utils/TableGen/TGLexer.h
@@ -45,7 +45,8 @@ namespace tgtok {
MultiClass, String,
// !keywords.
- XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat,
+ XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, //XSubst, XCast,
+ //XForEach,
// Integer value.
IntVal,
diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp
index ba181533c1..da2a5304ab 100644
--- a/utils/TableGen/TGParser.cpp
+++ b/utils/TableGen/TGParser.cpp
@@ -670,6 +670,237 @@ Init *TGParser::ParseIDValue(Record *CurRec,
return 0;
}
+/// ParseOperation - Parse an operator. This returns null on error.
+///
+/// Operation ::= XOperator ['<' Type '>'] '(' Args ')'
+///
+Init *TGParser::ParseOperation(Record *CurRec) {
+ switch (Lex.getCode()) {
+ default:
+ TokError("unknown operation");
+ return 0;
+ break;
+// case tgtok::XCast: { // Value ::= !unop '(' Value ')'
+// UnOpInit::UnaryOp Code;
+// RecTy *Type = 0;
+
+// switch (Lex.getCode()) {
+// default: assert(0 && "Unhandled code!");
+// case tgtok::XCast:
+// Lex.Lex(); // eat the operation
+// Code = UnOpInit::CAST;
+
+// Type = ParseOperatorType();
+
+// if (Type == 0) {
+// TokError("did not get type for binary operator");
+// return 0;
+// }
+
+// break;
+// }
+// if (Lex.getCode() != tgtok::l_paren) {
+// TokError("expected '(' after unary operator");
+// return 0;
+// }
+// Lex.Lex(); // eat the '('
+
+// Init *LHS = ParseValue(CurRec);
+// if (LHS == 0) return 0;
+
+// if (Lex.getCode() != tgtok::r_paren) {
+// TokError("expected ')' in unary operator");
+// return 0;
+// }
+// Lex.Lex(); // eat the ')'
+// return (new UnOpInit(Code, LHS, Type))->Fold(CurRec, CurMultiClass);
+// }
+
+ case tgtok::XConcat:
+ case tgtok::XSRA:
+ case tgtok::XSRL:
+ case tgtok::XSHL:
+ 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:
+ 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;
+
+ Type = ParseOperatorType();
+
+ if (Type == 0) {
+ TokError("did not get type for binary operator");
+ return 0;
+ }
+
+ break;
+ }
+ 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 ')'
+ return (new BinOpInit(Code, LHS, RHS, Type))->Fold(CurRec, CurMultiClass);
+ }
+
+// case tgtok::XForEach:
+// case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
+// TernOpInit::TernaryOp Code;
+// RecTy *Type = 0;
+
+
+// tgtok::TokKind LexCode = Lex.getCode();
+// Lex.Lex(); // eat the operation
+// switch (LexCode) {
+// default: assert(0 && "Unhandled code!");
+// case tgtok::XForEach:
+// Code = TernOpInit::FOREACH;
+// break;
+// case tgtok::XSubst:
+// Code = TernOpInit::SUBST;
+// break;
+// }
+// if (Lex.getCode() != tgtok::l_paren) {
+// TokError("expected '(' after ternary operator");
+// return 0;
+// }
+// Lex.Lex(); // eat the '('
+
+// Init *LHS = ParseValue(CurRec);
+// if (LHS == 0) return 0;
+
+// if (Lex.getCode() != tgtok::comma) {
+// TokError("expected ',' in ternary operator");
+// return 0;
+// }
+// Lex.Lex(); // eat the ','
+
+// Init *MHS = ParseValue(CurRec);
+// if (MHS == 0) return 0;
+
+// if (Lex.getCode() != tgtok::comma) {
+// TokError("expected ',' in ternary 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 ')'
+
+// switch (LexCode) {
+// default: assert(0 && "Unhandled code!");
+// case tgtok::XForEach: {
+// TypedInit *MHSt = dynamic_cast<TypedInit *>(MHS);
+// if (MHSt == 0) {
+// TokError("could not get type for !foreach");
+// return 0;
+// }
+// Type = MHSt->getType();
+// break;
+// }
+// case tgtok::XSubst: {
+// TypedInit *RHSt = dynamic_cast<TypedInit *>(RHS);
+// if (RHSt == 0) {
+// TokError("could not get type for !subst");
+// return 0;
+// }
+// Type = RHSt->getType();
+// break;
+// }
+// }
+// return (new TernOpInit(Code, LHS, MHS, RHS, Type))->Fold(CurRec, CurMultiClass);
+// }
+ }
+ TokError("could not parse operation");
+ return 0;
+}
+
+/// ParseOperatorType - Parse a type for an operator. This returns
+/// null on error.
+///
+/// OperatorType ::= '<' Type '>'
+///
+RecTy *TGParser::ParseOperatorType(void) {
+ RecTy *Type = 0;
+
+ if (Lex.getCode() != tgtok::less) {
+ TokError("expected type name for operator");
+ return 0;
+ }
+ Lex.Lex(); // eat the <
+
+ Type = ParseType();
+
+ if (Type == 0) {
+ TokError("expected type name for operator");
+ return 0;
+ }
+
+ if (Lex.getCode() != tgtok::greater) {
+ TokError("expected type name for operator");
+ return 0;
+ }
+ Lex.Lex(); // eat the >
+
+ return Type;
+}
+
+
/// ParseSimpleValue - Parse a tblgen value. This returns null on error.
///
/// SimpleValue ::= IDValue
@@ -798,6 +1029,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')'
Lex.Lex(); // eat the '('
if (Lex.getCode() != tgtok::Id
+ // && Lex.getCode() != tgtok::XCast
&& Lex.getCode() != tgtok::XNameConcat) {
TokError("expected identifier in dag init");
return 0;
@@ -809,54 +1041,8 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
if (Operator == 0) return 0;
}
else {
- 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;
- }
- 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, Type))->Fold(CurRec,
- CurMultiClass);
+ Operator = ParseOperation(CurRec);
+ if (Operator == 0) return 0;
}
// If the operator name is present, parse it.
@@ -883,91 +1069,20 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
Lex.Lex(); // eat the ')'
return new DagInit(Operator, OperatorName, DagArgs);
+ break;
}
+
+ // case tgtok::XCast: // Value ::= !unop '(' Value ')'
case tgtok::XConcat:
case tgtok::XSRA:
case tgtok::XSRL:
case tgtok::XSHL:
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:
- 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;
- }
- 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 ')'
- return (new BinOpInit(Code, LHS, RHS, Type))->Fold(CurRec, CurMultiClass);
+ // case tgtok::XForEach:
+ // case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
+ return ParseOperation(CurRec);
+ break;
}
}
diff --git a/utils/TableGen/TGParser.h b/utils/TableGen/TGParser.h
index 358fee65cb..f03052eb79 100644
--- a/utils/TableGen/TGParser.h
+++ b/utils/TableGen/TGParser.h
@@ -102,6 +102,8 @@ private: // Parser methods.
std::vector<unsigned> ParseRangeList();
bool ParseRangePiece(std::vector<unsigned> &Ranges);
RecTy *ParseType();
+ Init *ParseOperation(Record *CurRec);
+ RecTy *ParseOperatorType();
std::string ParseObjectName();
Record *ParseClassID();
MultiClass *ParseMultiClassID();