diff options
author | David Greene <greened@obbligato.org> | 2009-05-14 21:54:42 +0000 |
---|---|---|
committer | David Greene <greened@obbligato.org> | 2009-05-14 21:54:42 +0000 |
commit | 4afc509b7ffe2c4ea234dfd7af5105feb21685d9 (patch) | |
tree | e095d38947400d6afe3a6885a236a45e8cc3955a | |
parent | 94555c28462aab05157b41d78505d5753bd97dad (diff) |
Implement a !subst operation simmilar to $(subst) in GNU make to do
def/var/string substitution on generic pattern templates. For example:
def Type;
def v4f32 : Type;
def TYPE : Type;
class GenType<Type t> {
let type = !(subst TYPE, v4f32, t);
}
def TheType : GenType<TYPE>;
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71801 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | docs/TableGenFundamentals.html | 3 | ||||
-rw-r--r-- | test/TableGen/subst.td | 29 | ||||
-rw-r--r-- | utils/TableGen/Record.cpp | 433 | ||||
-rw-r--r-- | utils/TableGen/Record.h | 106 | ||||
-rw-r--r-- | utils/TableGen/TGLexer.cpp | 2 | ||||
-rw-r--r-- | utils/TableGen/TGLexer.h | 2 | ||||
-rw-r--r-- | utils/TableGen/TGParser.cpp | 144 |
7 files changed, 371 insertions, 348 deletions
diff --git a/docs/TableGenFundamentals.html b/docs/TableGenFundamentals.html index 48fdd2a201..0186453f36 100644 --- a/docs/TableGenFundamentals.html +++ b/docs/TableGenFundamentals.html @@ -404,6 +404,9 @@ the symbol table. If the type of 'a' does not match <em>type</em>, TableGen aborts with an error. </dd> <dt><tt>!nameconcat<type>(a, b)</tt></dt> <dd>Shorthand for !cast<type>(!strconcat(a, b))</dd> +<dt><tt>!subst(a, b, c)</tt></dt> + <dd>If 'a' and 'b' are of string type or are symbol references, substitute +'b' for 'a' in 'c.' This operation is analogous to $(subst) in GNU make.</dd> </dl> <p>Note that all of the values have rules specifying how they convert to values diff --git a/test/TableGen/subst.td b/test/TableGen/subst.td new file mode 100644 index 0000000000..ce9f45d0a4 --- /dev/null +++ b/test/TableGen/subst.td @@ -0,0 +1,29 @@ +// RUN: tblgen %s | grep {Smith} | count 7 +// RUN: tblgen %s | grep {Johnson} | count 2 +// RUN: tblgen %s | grep {FIRST} | count 1 +// RUN: tblgen %s | grep {LAST} | count 1 +// RUN: tblgen %s | grep {TVAR} | count 2 +// RUN: tblgen %s | grep {Bogus} | count 1 + +class Honorific<string t> { + string honorific = t; +} + +def Mr : Honorific<"Mr.">; +def Ms : Honorific<"Ms.">; +def Mrs : Honorific<"Mrs.">; +def TVAR : Honorific<"Bogus">; + +class Name<string n, Honorific t> { + string name = n; + Honorific honorific = t; +} + +class AName<string name, Honorific honorific> : + Name<!subst("FIRST", "John", !subst("LAST", "Smith", name)), + !subst(TVAR, Mr, honorific)>; + +def JohnSmith : AName<"FIRST LAST", TVAR>; +def JaneSmith : AName<"Jane LAST", Ms>; +def JohnSmithJones : AName<"FIRST LAST-Jones", Mr>; +def JimmyJohnson : AName<"Jimmy Johnson", Mr>; diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp index 2a8ddaa42c..baff05c6ef 100644 --- a/utils/TableGen/Record.cpp +++ b/utils/TableGen/Record.cpp @@ -678,231 +678,222 @@ std::string BinOpInit::getAsString() const { return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")"; } -// 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())) { +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); + + DefInit *RHSd = dynamic_cast<DefInit*>(RHS); + VarInit *RHSv = dynamic_cast<VarInit*>(RHS); + StringInit *RHSs = dynamic_cast<StringInit*>(RHS); + + if ((LHSd && MHSd && RHSd) + || (LHSv && MHSv && RHSv) + || (LHSs && MHSs && RHSs)) { + if (RHSd) { + Record *Val = RHSd->getDef(); + if (LHSd->getAsString() == RHSd->getAsString()) { + Val = MHSd->getDef(); + } + return new DefInit(Val); + } + if (RHSv) { + std::string Val = RHSv->getName(); + if (LHSv->getAsString() == RHSv->getAsString()) { + Val = MHSv->getName(); + } + return new VarInit(Val, getType()); + } + if (RHSs) { + std::string Val = RHSs->getValue(); + + std::string::size_type found; + do { + found = Val.find(LHSs->getValue()); + if (found != std::string::npos) { + Val.replace(found, LHSs->getValue().size(), MHSs->getValue()); + } + } while (found != std::string::npos); + + return new StringInit(Val); + } + } + 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; -// } -// } + // 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 (unsigned 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; -// } -// } -// } + 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 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); -// 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() + ")"; -// } + 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 a81b056b17..59b6348a36 100644 --- a/utils/TableGen/Record.h +++ b/utils/TableGen/Record.h @@ -43,7 +43,7 @@ class CodeInit; class ListInit; class UnOpInit; class BinOpInit; - //class TernOpInit; +class TernOpInit; class DefInit; class DagInit; class TypedInit; @@ -85,9 +85,9 @@ public: // These methods should only be called from subclasses of Init virtual Init *convertValue( BinOpInit *UI) { return convertValue((TypedInit*)UI); } -// virtual Init *convertValue( TernOpInit *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; } @@ -135,7 +135,7 @@ public: 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( 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);} @@ -179,7 +179,7 @@ public: 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( 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);} @@ -219,7 +219,7 @@ public: 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( 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);} @@ -253,7 +253,7 @@ public: 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( TernOpInit *BO) { return RecTy::convertValue(BO);} virtual Init *convertValue( CodeInit *CI) { return 0; } virtual Init *convertValue(VarBitInit *VB) { return 0; } @@ -303,7 +303,7 @@ public: 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( 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);} @@ -342,7 +342,7 @@ public: 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( 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);} @@ -377,7 +377,7 @@ public: 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( 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);} @@ -420,7 +420,7 @@ public: 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( TernOpInit *UI) { return RecTy::convertValue(UI);} virtual Init *convertValue( DefInit *DI); virtual Init *convertValue( DagInit *DI) { return 0; } virtual Init *convertValue( TypedInit *VI); @@ -820,50 +820,50 @@ public: /// 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) { -// } +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); + // 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 Init *resolveReferences(Record &R, const RecordVal *RV); -// virtual std::string getAsString() const; -// }; + 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 43afae9f0f..264be4b98b 100644 --- a/utils/TableGen/TGLexer.cpp +++ b/utils/TableGen/TGLexer.cpp @@ -447,7 +447,7 @@ 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 == 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; diff --git a/utils/TableGen/TGLexer.h b/utils/TableGen/TGLexer.h index b95ca9558c..f152df0a2f 100644 --- a/utils/TableGen/TGLexer.h +++ b/utils/TableGen/TGLexer.h @@ -45,7 +45,7 @@ namespace tgtok { MultiClass, String, // !keywords. - XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, XCast, // XSubst, + XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, XCast, XSubst, //XForEach, // Integer value. diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp index 6b4c431635..967f5d0d5d 100644 --- a/utils/TableGen/TGParser.cpp +++ b/utils/TableGen/TGParser.cpp @@ -793,78 +793,78 @@ Init *TGParser::ParseOperation(Record *CurRec) { } // 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 ',' + 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 *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); -// } + 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; @@ -1078,9 +1078,9 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) { case tgtok::XSRL: case tgtok::XSHL: case tgtok::XStrConcat: - case tgtok::XNameConcat: { // Value ::= !binop '(' Value ',' Value ')' + case tgtok::XNameConcat: // Value ::= !binop '(' Value ',' Value ')' // case tgtok::XForEach: - // case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')' + case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')' return ParseOperation(CurRec); break; } |