mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-19 16:35:10 +00:00
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
This commit is contained in:
parent
ccf85ded58
commit
d418c1b768
@ -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);
|
||||
// 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);
|
||||
|
||||
if (Folded != this) {
|
||||
TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
|
||||
if (Typed) {
|
||||
return Typed->resolveBitReference(R, IRV, Bit);
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
// }
|
||||
|
||||
Init *BinOpInit::resolveListElementReference(Record &R, const RecordVal *IRV,
|
||||
unsigned Elt) {
|
||||
Init *Folded = Fold(&R, 0);
|
||||
|
||||
if (Folded != this) {
|
||||
TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
|
||||
if (Typed) {
|
||||
return Typed->resolveListElementReference(R, IRV, Elt);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
// 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());
|
||||
|
@ -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,27 +711,21 @@ public:
|
||||
unsigned Elt) = 0;
|
||||
};
|
||||
|
||||
|
||||
/// BinOpInit - !op (X, Y) - Combine two inits.
|
||||
/// OpInit - Base class for operators
|
||||
///
|
||||
class BinOpInit : public TypedInit {
|
||||
class OpInit : public TypedInit {
|
||||
public:
|
||||
enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, NAMECONCAT };
|
||||
private:
|
||||
BinaryOp Opc;
|
||||
Init *LHS, *RHS;
|
||||
public:
|
||||
BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
|
||||
TypedInit(Type), Opc(opc), LHS(lhs), RHS(rhs) {
|
||||
}
|
||||
|
||||
BinaryOp getOpcode() const { return Opc; }
|
||||
Init *getLHS() const { return LHS; }
|
||||
Init *getRHS() const { return RHS; }
|
||||
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.
|
||||
Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
|
||||
virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) = 0;
|
||||
|
||||
virtual Init *convertInitializerTo(RecTy *Ty) {
|
||||
return Ty->convertValue(this);
|
||||
@ -716,12 +735,136 @@ public:
|
||||
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 OpInit {
|
||||
public:
|
||||
enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, NAMECONCAT };
|
||||
private:
|
||||
BinaryOp Opc;
|
||||
Init *LHS, *RHS;
|
||||
public:
|
||||
BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
|
||||
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; }
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
/// 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.
|
||||
///
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user