From 4afc509b7ffe2c4ea234dfd7af5105feb21685d9 Mon Sep 17 00:00:00 2001 From: David Greene Date: Thu, 14 May 2009 21:54:42 +0000 Subject: [PATCH] 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 { let type = !(subst TYPE, v4f32, t); } def TheType : GenType; git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71801 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/TableGenFundamentals.html | 3 + test/TableGen/subst.td | 29 +++ utils/TableGen/Record.cpp | 377 ++++++++++++++++----------------- utils/TableGen/Record.h | 100 ++++----- utils/TableGen/TGLexer.cpp | 2 +- utils/TableGen/TGLexer.h | 2 +- utils/TableGen/TGParser.cpp | 130 ++++++------ 7 files changed, 333 insertions(+), 310 deletions(-) create mode 100644 test/TableGen/subst.td diff --git a/docs/TableGenFundamentals.html b/docs/TableGenFundamentals.html index 48fdd2a2018..0186453f368 100644 --- a/docs/TableGenFundamentals.html +++ b/docs/TableGenFundamentals.html @@ -404,6 +404,9 @@ the symbol table. If the type of 'a' does not match type, TableGen aborts with an error.
!nameconcat<type>(a, b)
Shorthand for !cast(!strconcat(a, b))
+
!subst(a, b, c)
+
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.

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 00000000000..ce9f45d0a48 --- /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 honorific = t; +} + +def Mr : Honorific<"Mr.">; +def Ms : Honorific<"Ms.">; +def Mrs : Honorific<"Mrs.">; +def TVAR : Honorific<"Bogus">; + +class Name { + string name = n; + Honorific honorific = t; +} + +class AName : + Name; + +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 2a8ddaa42c7..baff05c6efc 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(LHS); -// VarInit *LHSv = dynamic_cast(LHS); -// StringInit *LHSs = dynamic_cast(LHS); +Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { + switch (getOpcode()) { + default: assert(0 && "Unknown binop"); + case SUBST: { + DefInit *LHSd = dynamic_cast(LHS); + VarInit *LHSv = dynamic_cast(LHS); + StringInit *LHSs = dynamic_cast(LHS); -// DefInit *MHSd = dynamic_cast(MHS); -// VarInit *MHSv = dynamic_cast(MHS); -// StringInit *MHSs = dynamic_cast(MHS); + DefInit *MHSd = dynamic_cast(MHS); + VarInit *MHSv = dynamic_cast(MHS); + StringInit *MHSs = dynamic_cast(MHS); -// DagInit *RHSd = dynamic_cast(RHS); -// ListInit *RHSl = dynamic_cast(RHS); + DefInit *RHSd = dynamic_cast(RHS); + VarInit *RHSv = dynamic_cast(RHS); + StringInit *RHSs = dynamic_cast(RHS); -// DagRecTy *DagType = dynamic_cast(getType()); -// ListRecTy *ListType = dynamic_cast(getType()); + 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(); -// 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 > 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)); -// } + 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 DagInit(Val, args); -// } -// if (RHSl) { -// std::vector NewList(RHSl->begin(), RHSl->end()); + return new StringInit(Val); + } + } + break; + } -// 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(MHS); + ListInit *MHSl = dynamic_cast(MHS); -// case FOREACH: { -// DagInit *MHSd = dynamic_cast(MHS); -// ListInit *MHSl = dynamic_cast(MHS); + DagRecTy *DagType = dynamic_cast(getType()); + ListRecTy *ListType = dynamic_cast(getType()); -// DagRecTy *DagType = dynamic_cast(getType()); -// ListRecTy *ListType = dynamic_cast(getType()); + OpInit *RHSo = dynamic_cast(RHS); -// OpInit *RHSo = dynamic_cast(RHS); + if (!RHSo) { + cerr << "!foreach requires an operator\n"; + assert(0 && "No operator for !foreach"); + } -// if (!RHSo) { -// cerr << "!foreach requires an operator\n"; -// assert(0 && "No operator for !foreach"); -// } + TypedInit *LHSt = dynamic_cast(LHS); -// TypedInit *LHSt = dynamic_cast(LHS); + if (!LHSt) { + cerr << "!foreach requires typed variable\n"; + assert(0 && "No typed variable for !foreach"); + } -// if (!LHSt) { -// cerr << "!foreach requires typed variable\n"; -// assert(0 && "No typed variable for !foreach"); -// } + if (MHSd && DagType || MHSl && ListType) { + std::vector NewOperands; + if (MHSd) { + Init *Val = MHSd->getOperator(); + TypedInit *TVal = dynamic_cast(Val); -// if (MHSd && DagType || MHSl && ListType) { -// std::vector NewOperands; -// if (MHSd) { -// Init *Val = MHSd->getOperator(); -// TypedInit *TVal = dynamic_cast(Val); - -// if (TVal && TVal->getType()->typeIsConvertibleTo(LHSt->getType())) { + 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)); -// } -// } + // 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; -// } -// } + // 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 > args; -// for (int i = 0; i < MHSd->getNumArgs(); ++i) { -// Init *Arg; -// std::string ArgName; -// Arg = MHSd->getArg(i); -// ArgName = MHSd->getArgName(i); + std::vector > 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(Arg); + TypedInit *TArg = dynamic_cast(Arg); -// if (TArg && TArg->getType()->typeIsConvertibleTo(LHSt->getType())) { -// NewOperands.clear(); + 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)); -// } -// } + // 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; -// } -// } + // 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(); + 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)); -// } -// } + // 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(ArgNameInit); -// if (SArgNameInit) { -// ArgName = SArgNameInit->getValue(); -// } -// if (ArgNameInit != NewOp) { -// delete NewOp; -// } -// delete ArgNameInit; -// } + // 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(ArgNameInit); + if (SArgNameInit) { + ArgName = SArgNameInit->getValue(); + } + if (ArgNameInit != NewOp) { + delete NewOp; + } + delete ArgNameInit; + } -// args.push_back(std::make_pair(Arg, ArgName)); -// } + args.push_back(std::make_pair(Arg, ArgName)); + } -// return new DagInit(Val, args); -// } -// if (MHSl) { -// std::vector NewList(MHSl->begin(), MHSl->end()); + return new DagInit(Val, "", args); + } + if (MHSl) { + std::vector NewList(MHSl->begin(), MHSl->end()); -// for (ListInit::iterator li = NewList.begin(), -// liend = NewList.end(); -// li != liend; -// ++li) { -// Init *Item = *li; -// TypedInit *TItem = dynamic_cast(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)); -// } -// } + for (ListInit::iterator li = NewList.begin(), + liend = NewList.end(); + li != liend; + ++li) { + Init *Item = *li; + TypedInit *TItem = dynamic_cast(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; -// } -// } -// } + // 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 new ListInit(NewList); + } + } + break; + } + } -// return this; -// } + 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); +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); -// } + 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() + ")"; -// } +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 &Bits) { BitsRecTy *T = dynamic_cast(getType()); diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h index a81b056b170..59b6348a36e 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 &Operands) { -// assert(Operands.size() == 3 && "Wrong number of operands for ternary operation"); -// return new TernOpInit(getOpcode(), Operands[0], Operands[1], Operands[2], getType()); -// } + // Clone - Clone this operator, replacing arguments with the new list + virtual OpInit *clone(std::vector &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(); -// } -// } + 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; } + 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); + // 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 43afae9f0f2..264be4b98ba 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 b95ca9558cc..f152df0a2f5 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 6b4c431635c..967f5d0d5dd 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; + 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 '(' + 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; + 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 ',' + 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; + 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 ',' + 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; + 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 ')' + 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(MHS); -// if (MHSt == 0) { -// TokError("could not get type for !foreach"); -// return 0; -// } -// Type = MHSt->getType(); -// break; -// } -// case tgtok::XSubst: { -// TypedInit *RHSt = dynamic_cast(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); -// } + switch (LexCode) { + default: assert(0 && "Unhandled code!"); + //case tgtok::XForEach: { + //TypedInit *MHSt = dynamic_cast(MHS); + //if (MHSt == 0) { + // TokError("could not get type for !foreach"); + // return 0; + //} + //Type = MHSt->getType(); + //break; + //} + case tgtok::XSubst: { + TypedInit *RHSt = dynamic_cast(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; }