1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

Implement !cast.

llvm-svn: 71794
This commit is contained in:
David Greene 2009-05-14 21:22:49 +00:00
parent 5cc13bb60b
commit e2871b8c65
7 changed files with 248 additions and 157 deletions

View File

@ -398,11 +398,12 @@ supported include:</p>
<dt><tt>!strconcat(a, b)</tt></dt>
<dd>A string value that is the result of concatenating the 'a' and 'b'
strings.</dd>
<dt><tt>!cast<type>(a)</tt></dt>
<dd>A symbol of type <em>type</em> obtained by looking up the string 'a' in
the symbol table. If the type of 'a' does not match <em>type</em>, TableGen
aborts with an error. </dd>
<dt><tt>!nameconcat&lt;type&gt;(a, b)</tt></dt>
<dd>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.</dd>
<dd>Shorthand for !cast<type>(!strconcat(a, b))</dd>
</dl>
<p>Note that all of the values have rules specifying how they convert to values

90
test/TableGen/cast.td Normal file
View File

@ -0,0 +1,90 @@
// RUN: tblgen %s | grep {add_ps} | count 3
class ValueType<int size, int value> {
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> {
string Name = name;
}
class Inst<bits<8> opcode, dag oopnds, dag iopnds, string asmstr,
list<dag> pattern> {
bits<8> Opcode = opcode;
dag OutOperands = oopnds;
dag InOperands = iopnds;
string AssemblyString = asmstr;
list<dag> Pattern = pattern;
}
def ops;
def outs;
def ins;
def set;
// Define registers
class Register<string n> {
string Name = n;
}
class RegisterClass<list<ValueType> regTypes, list<Register> regList> {
list<ValueType> RegTypes = regTypes;
list<Register> 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<bits<8> opcode, string asmstr, string Intr> {
def PS : Inst<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
!strconcat(asmstr, "\t$dst, $src1, $src2"),
[(set VR128:$dst, (!cast<Intrinsic>(!strconcat(Intr, "_ps")) VR128:$src1, VR128:$src2))]>;
def PD : Inst<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
!strconcat(asmstr, "\t$dst, $src1, $src2"),
[(set VR128:$dst, (!cast<Intrinsic>(!strconcat(Intr, "_pd")) VR128:$src1, VR128:$src2))]>;
}
defm ADD : arith<0x58, "add", "int_x86_sse2_add">;
class IntInst<bits<8> opcode, string asmstr, Intrinsic Intr> :
Inst<opcode,(outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
!strconcat(asmstr, "\t$dst, $src1, $src2"),
[(set VR128:$dst, (Intr VR128:$src1, VR128:$src2))]>;
multiclass arith_int<bits<8> opcode, string asmstr, string Intr> {
def PS_Int : IntInst<opcode, asmstr, !cast<Intrinsic>(!strconcat(Intr, "_ps"))>;
def PD_Int : IntInst<opcode, asmstr, !cast<Intrinsic>(!strconcat(Intr, "_pd"))>;
}
defm ADD : arith_int<0x58, "add", "int_x86_sse2_add">;

View File

@ -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<StringInit*>(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<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());
// }
// 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()) {

View File

@ -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<Init *> &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<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();
// }
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.
///

View File

@ -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");
}

View File

@ -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.

View File

@ -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: