From d418c1b768b5ff26afe05a5ce84d920bbbc99583 Mon Sep 17 00:00:00 2001 From: David Greene Date: Thu, 14 May 2009 20:54:48 +0000 Subject: 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 --- utils/TableGen/Record.cpp | 374 +++++++++++++++++++++++++++++++++++++++++--- utils/TableGen/Record.h | 165 +++++++++++++++++-- utils/TableGen/TGLexer.cpp | 5 +- utils/TableGen/TGLexer.h | 3 +- utils/TableGen/TGParser.cpp | 367 ++++++++++++++++++++++++++++--------------- utils/TableGen/TGParser.h | 2 + 6 files changed, 751 insertions(+), 165 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp index d420e63..0f31861 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(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(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(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(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(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(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); + +// DagInit *RHSd = dynamic_cast(RHS); +// ListInit *RHSl = dynamic_cast(RHS); + +// DagRecTy *DagType = dynamic_cast(getType()); +// ListRecTy *ListType = dynamic_cast(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 > 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 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(MHS); +// ListInit *MHSl = dynamic_cast(MHS); + +// DagRecTy *DagType = dynamic_cast(getType()); +// ListRecTy *ListType = dynamic_cast(getType()); + +// OpInit *RHSo = dynamic_cast(RHS); + +// if (!RHSo) { +// cerr << "!foreach requires an operator\n"; +// assert(0 && "No operator for !foreach"); +// } + +// TypedInit *LHSt = dynamic_cast(LHS); + +// 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 (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 > 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(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(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 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)); +// } +// } + +// // 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 &Bits) { BitsRecTy *T = dynamic_cast(getType()); diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h index f76de7d..b0b4ac1 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 &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 &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 &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 &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 8eb219b..5e96e50 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 734dc26..0f27308 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 ba18153..da2a530 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(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; +} + +/// 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 358fee6..f03052e 100644 --- a/utils/TableGen/TGParser.h +++ b/utils/TableGen/TGParser.h @@ -102,6 +102,8 @@ private: // Parser methods. std::vector ParseRangeList(); bool ParseRangePiece(std::vector &Ranges); RecTy *ParseType(); + Init *ParseOperation(Record *CurRec); + RecTy *ParseOperatorType(); std::string ParseObjectName(); Record *ParseClassID(); MultiClass *ParseMultiClassID(); -- cgit v1.1