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: