From e2871b8c656e99af98d7c0150feb527753d780bb Mon Sep 17 00:00:00 2001
From: David Greene
Date: Thu, 14 May 2009 21:22:49 +0000
Subject: [PATCH] Implement !cast.
llvm-svn: 71794
---
docs/TableGenFundamentals.html | 9 +-
test/TableGen/cast.td | 90 +++++++++++++++++++
utils/TableGen/Record.cpp | 160 ++++++++++++++++-----------------
utils/TableGen/Record.h | 80 ++++++++---------
utils/TableGen/TGLexer.cpp | 2 +-
utils/TableGen/TGLexer.h | 2 +-
utils/TableGen/TGParser.cpp | 62 ++++++-------
7 files changed, 248 insertions(+), 157 deletions(-)
create mode 100644 test/TableGen/cast.td
diff --git a/docs/TableGenFundamentals.html b/docs/TableGenFundamentals.html
index 8cc6f90eac9..48fdd2a2018 100644
--- a/docs/TableGenFundamentals.html
+++ b/docs/TableGenFundamentals.html
@@ -398,11 +398,12 @@ supported include:
!strconcat(a, b)
A string value that is the result of concatenating the 'a' and 'b'
strings.
+!cast(a)
+ A symbol of type type obtained by looking up the string 'a' in
+the symbol table. If the type of 'a' does not match type, TableGen
+aborts with an error.
!nameconcat<type>(a, b)
- A value that is the result of concatenating the 'a' and 'b'
- strings and looking up the resulting name in the symbol table. The symbol type
- determines the type of the resulting value. If the symbol is not found
- or the symbol type does not match 'type,' TableGen emits an error and aborts.
+ Shorthand for !cast(!strconcat(a, b))
Note that all of the values have rules specifying how they convert to values
diff --git a/test/TableGen/cast.td b/test/TableGen/cast.td
new file mode 100644
index 00000000000..4a771ae874f
--- /dev/null
+++ b/test/TableGen/cast.td
@@ -0,0 +1,90 @@
+// RUN: tblgen %s | grep {add_ps} | count 3
+
+class ValueType {
+ int Size = size;
+ int Value = value;
+}
+
+def v2i64 : ValueType<128, 22>; // 2 x i64 vector value
+def v2f64 : ValueType<128, 28>; // 2 x f64 vector value
+
+class Intrinsic {
+ string Name = name;
+}
+
+class Inst opcode, dag oopnds, dag iopnds, string asmstr,
+ list pattern> {
+ bits<8> Opcode = opcode;
+ dag OutOperands = oopnds;
+ dag InOperands = iopnds;
+ string AssemblyString = asmstr;
+ list Pattern = pattern;
+}
+
+def ops;
+def outs;
+def ins;
+
+def set;
+
+// Define registers
+class Register {
+ string Name = n;
+}
+
+class RegisterClass regTypes, list regList> {
+ list RegTypes = regTypes;
+ list MemberList = regList;
+}
+
+def XMM0: Register<"xmm0">;
+def XMM1: Register<"xmm1">;
+def XMM2: Register<"xmm2">;
+def XMM3: Register<"xmm3">;
+def XMM4: Register<"xmm4">;
+def XMM5: Register<"xmm5">;
+def XMM6: Register<"xmm6">;
+def XMM7: Register<"xmm7">;
+def XMM8: Register<"xmm8">;
+def XMM9: Register<"xmm9">;
+def XMM10: Register<"xmm10">;
+def XMM11: Register<"xmm11">;
+def XMM12: Register<"xmm12">;
+def XMM13: Register<"xmm13">;
+def XMM14: Register<"xmm14">;
+def XMM15: Register<"xmm15">;
+
+def VR128 : RegisterClass<[v2i64, v2f64],
+ [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
+ XMM8, XMM9, XMM10, XMM11,
+ XMM12, XMM13, XMM14, XMM15]>;
+
+// Define intrinsics
+def int_x86_sse2_add_ps : Intrinsic<"addps">;
+def int_x86_sse2_add_pd : Intrinsic<"addpd">;
+
+multiclass arith opcode, string asmstr, string Intr> {
+ def PS : Inst(!strconcat(Intr, "_ps")) VR128:$src1, VR128:$src2))]>;
+
+ def PD : Inst(!strconcat(Intr, "_pd")) VR128:$src1, VR128:$src2))]>;
+}
+
+defm ADD : arith<0x58, "add", "int_x86_sse2_add">;
+
+class IntInst opcode, string asmstr, Intrinsic Intr> :
+ Inst;
+
+
+multiclass arith_int opcode, string asmstr, string Intr> {
+ def PS_Int : IntInst(!strconcat(Intr, "_ps"))>;
+
+ def PD_Int : IntInst(!strconcat(Intr, "_pd"))>;
+}
+
+defm ADD : arith_int<0x58, "add", "int_x86_sse2_add">;
diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp
index 0f318612691..2a8ddaa42c7 100644
--- a/utils/TableGen/Record.cpp
+++ b/utils/TableGen/Record.cpp
@@ -132,17 +132,17 @@ 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;
-// }
+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);
-// }
+ return convertValue((TypedInit*)BO);
+}
Init *StringRecTy::convertValue(BinOpInit *BO) {
if (BO->getOpcode() == BinOpInit::STRCONCAT) {
@@ -212,16 +212,16 @@ 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(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) {
@@ -467,78 +467,78 @@ Init *OpInit::resolveListElementReference(Record &R, const RecordVal *IRV,
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();
+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());
-// }
+ // 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??");
+ 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";
-// }
+ if (RV->getType() != getType()) {
+ throw "type mismatch in nameconcat";
+ }
-// return new VarInit(TemplateArgName, RV->getType());
-// }
-// }
+ 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 (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";
-// }
+ if (RV->getType() != getType()) {
+ throw "type mismatch in nameconcat";
+ }
-// return new VarInit(MCName, RV->getType());
-// }
-// }
+ return new VarInit(MCName, RV->getType());
+ }
+ }
-// if (Record *D = Records.getDef(Name))
-// return new DefInit(D);
+ 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;
-// }
+ 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);
+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);
-// }
+ 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() + ")";
-// }
+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()) {
diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h
index b0b4ac17b48..a81b056b170 100644
--- a/utils/TableGen/Record.h
+++ b/utils/TableGen/Record.h
@@ -41,7 +41,7 @@ class IntInit;
class StringInit;
class CodeInit;
class ListInit;
- //class UnOpInit;
+class UnOpInit;
class BinOpInit;
//class TernOpInit;
class DefInit;
@@ -79,9 +79,9 @@ 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( UnOpInit *UI) {
+ return convertValue((TypedInit*)UI);
+ }
virtual Init *convertValue( BinOpInit *UI) {
return convertValue((TypedInit*)UI);
}
@@ -133,7 +133,7 @@ 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( 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);
@@ -177,7 +177,7 @@ 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( 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);
@@ -217,7 +217,7 @@ 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( 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);
@@ -251,7 +251,7 @@ 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( UnOpInit *BO);
virtual Init *convertValue( BinOpInit *BO);
//virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
@@ -301,7 +301,7 @@ 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( 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);
@@ -340,7 +340,7 @@ 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( 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);
@@ -375,7 +375,7 @@ 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( UnOpInit *BO);
virtual Init *convertValue( BinOpInit *BO);
//virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
virtual Init *convertValue( DagInit *CI) { return (Init*)CI; }
@@ -418,7 +418,7 @@ 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( 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);
@@ -740,40 +740,40 @@ public:
/// 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) {
-// }
+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());
-// }
+ // 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();
-// }
+ 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; }
+ 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);
+ // 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;
+};
/// BinOpInit - !op (X, Y) - Combine two inits.
///
diff --git a/utils/TableGen/TGLexer.cpp b/utils/TableGen/TGLexer.cpp
index 5e96e50351e..43afae9f0f2 100644
--- a/utils/TableGen/TGLexer.cpp
+++ b/utils/TableGen/TGLexer.cpp
@@ -449,7 +449,7 @@ tgtok::TokKind TGLexer::LexExclaim() {
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;
+ 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 0f27308afd0..b95ca9558cc 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, //XSubst, XCast,
+ XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, XCast, // XSubst,
//XForEach,
// Integer value.
diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp
index da2a5304ab3..6b4c431635c 100644
--- a/utils/TableGen/TGParser.cpp
+++ b/utils/TableGen/TGParser.cpp
@@ -680,41 +680,41 @@ Init *TGParser::ParseOperation(Record *CurRec) {
TokError("unknown operation");
return 0;
break;
-// case tgtok::XCast: { // Value ::= !unop '(' Value ')'
-// UnOpInit::UnaryOp Code;
-// RecTy *Type = 0;
+ 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;
+ switch (Lex.getCode()) {
+ default: assert(0 && "Unhandled code!");
+ case tgtok::XCast:
+ Lex.Lex(); // eat the operation
+ Code = UnOpInit::CAST;
-// Type = ParseOperatorType();
+ Type = ParseOperatorType();
-// if (Type == 0) {
-// TokError("did not get type for binary operator");
-// return 0;
-// }
+ 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 '('
+ 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;
+ 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);
-// }
+ 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:
@@ -1029,7 +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::XCast
&& Lex.getCode() != tgtok::XNameConcat) {
TokError("expected identifier in dag init");
return 0;
@@ -1072,7 +1072,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
break;
}
- // case tgtok::XCast: // Value ::= !unop '(' Value ')'
+ case tgtok::XCast: // Value ::= !unop '(' Value ')'
case tgtok::XConcat:
case tgtok::XSRA:
case tgtok::XSRL: