mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Make BinOps typed and require a type specifier for !nameconcat. This
allows binops to be used in typed contexts such as when passing arguments to classes. llvm-svn: 69921
This commit is contained in:
parent
ff776c8193
commit
a92a50c7c2
@ -398,11 +398,11 @@ 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>!nameconcat(a, b)</tt></dt>
|
||||
<dt><tt>!nameconcat<type>(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,
|
||||
TableGen emits an error and aborts.</dd>
|
||||
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>
|
||||
</dl>
|
||||
|
||||
<p>Note that all of the values have rules specifying how they convert to values
|
||||
|
@ -1,4 +1,4 @@
|
||||
// RUN: tblgen %s | grep {add_ps} | count 2
|
||||
// RUN: tblgen %s | grep {add_ps} | count 3
|
||||
|
||||
class ValueType<int size, int value> {
|
||||
int Size = size;
|
||||
@ -66,11 +66,25 @@ 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, (!nameconcat(Intr, "_ps") VR128:$src1, VR128:$src2))]>;
|
||||
[(set VR128:$dst, (!nameconcat<Intrinsic>(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, (!nameconcat(Intr, "_pd") VR128:$src1, VR128:$src2))]>;
|
||||
[(set VR128:$dst, (!nameconcat<Intrinsic>(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, !nameconcat<Intrinsic>(Intr, "_ps")>;
|
||||
|
||||
def PD_Int : IntInst<opcode, asmstr, !nameconcat<Intrinsic>(Intr, "_pd")>;
|
||||
}
|
||||
|
||||
defm ADD : arith_int<0x58, "add", "int_x86_sse2_add">;
|
||||
|
@ -127,7 +127,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
|
||||
OperandList.clear();
|
||||
return;
|
||||
}
|
||||
DI = (DagInit*)(new BinOpInit(BinOpInit::CONCAT, DI, IDI))->Fold(R, 0);
|
||||
DI = (DagInit*)(new BinOpInit(BinOpInit::CONCAT, DI, IDI, new DagRecTy))->Fold(R, 0);
|
||||
|
||||
unsigned MIOperandNo = 0;
|
||||
std::set<std::string> OperandNames;
|
||||
|
@ -138,10 +138,21 @@ Init *StringRecTy::convertValue(BinOpInit *BO) {
|
||||
Init *R = BO->getRHS()->convertInitializerTo(this);
|
||||
if (L == 0 || R == 0) return 0;
|
||||
if (L != BO->getLHS() || R != BO->getRHS())
|
||||
return new BinOpInit(BinOpInit::STRCONCAT, L, R);
|
||||
return new BinOpInit(BinOpInit::STRCONCAT, L, R, new StringRecTy);
|
||||
return BO;
|
||||
}
|
||||
return 0;
|
||||
if (BO->getOpcode() == BinOpInit::NAMECONCAT) {
|
||||
if (BO->getType()->getAsString() == getAsString()) {
|
||||
Init *L = BO->getLHS()->convertInitializerTo(this);
|
||||
Init *R = BO->getRHS()->convertInitializerTo(this);
|
||||
if (L == 0 || R == 0) return 0;
|
||||
if (L != BO->getLHS() || R != BO->getRHS())
|
||||
return new BinOpInit(BinOpInit::NAMECONCAT, L, R, new StringRecTy);
|
||||
return BO;
|
||||
}
|
||||
}
|
||||
|
||||
return convertValue((TypedInit*)BO);
|
||||
}
|
||||
|
||||
|
||||
@ -195,9 +206,19 @@ Init *DagRecTy::convertValue(BinOpInit *BO) {
|
||||
Init *R = BO->getRHS()->convertInitializerTo(this);
|
||||
if (L == 0 || R == 0) return 0;
|
||||
if (L != BO->getLHS() || R != BO->getRHS())
|
||||
return new BinOpInit(BinOpInit::CONCAT, L, R);
|
||||
return new BinOpInit(BinOpInit::CONCAT, L, R, new DagRecTy);
|
||||
return BO;
|
||||
}
|
||||
if (BO->getOpcode() == BinOpInit::NAMECONCAT) {
|
||||
if (BO->getType()->getAsString() == getAsString()) {
|
||||
Init *L = BO->getLHS()->convertInitializerTo(this);
|
||||
Init *R = BO->getRHS()->convertInitializerTo(this);
|
||||
if (L == 0 || R == 0) return 0;
|
||||
if (L != BO->getLHS() || R != BO->getRHS())
|
||||
return new BinOpInit(BinOpInit::CONCAT, L, R, new DagRecTy);
|
||||
return BO;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -445,13 +466,22 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
|
||||
|
||||
// From TGParser::ParseIDValue
|
||||
if (CurRec) {
|
||||
if (const RecordVal *RV = CurRec->getValue(Name))
|
||||
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());
|
||||
}
|
||||
}
|
||||
@ -461,6 +491,11 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
@ -501,7 +536,7 @@ Init *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) {
|
||||
Init *rhs = RHS->resolveReferences(R, RV);
|
||||
|
||||
if (LHS != lhs || RHS != rhs)
|
||||
return (new BinOpInit(getOpcode(), lhs, rhs))->Fold(&R, 0);
|
||||
return (new BinOpInit(getOpcode(), lhs, rhs, getType()))->Fold(&R, 0);
|
||||
return Fold(&R, 0);
|
||||
}
|
||||
|
||||
@ -513,11 +548,40 @@ std::string BinOpInit::getAsString() const {
|
||||
case SRA: Result = "!sra"; break;
|
||||
case SRL: Result = "!srl"; break;
|
||||
case STRCONCAT: Result = "!strconcat"; break;
|
||||
case NAMECONCAT: Result = "!nameconcat"; break;
|
||||
case NAMECONCAT:
|
||||
Result = "!nameconcat<" + getType()->getAsString() + ">"; break;
|
||||
}
|
||||
return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
|
||||
}
|
||||
|
||||
Init *BinOpInit::resolveBitReference(Record &R, const RecordVal *IRV,
|
||||
unsigned Bit) {
|
||||
Init *Folded = Fold(&R, 0);
|
||||
|
||||
if (Folded != this) {
|
||||
TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
|
||||
if (Typed) {
|
||||
return Typed->resolveBitReference(R, IRV, Bit);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Init *BinOpInit::resolveListElementReference(Record &R, const RecordVal *IRV,
|
||||
unsigned Elt) {
|
||||
Init *Folded = Fold(&R, 0);
|
||||
|
||||
if (Folded != this) {
|
||||
TypedInit *Typed = dynamic_cast<TypedInit *>(Folded);
|
||||
if (Typed) {
|
||||
return Typed->resolveListElementReference(R, IRV, Elt);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Init *TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
|
||||
BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
|
||||
if (T == 0) return 0; // Cannot subscript a non-bits variable...
|
||||
|
@ -77,7 +77,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( BinOpInit *UI) { return 0; }
|
||||
virtual Init *convertValue( BinOpInit *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; }
|
||||
@ -123,7 +125,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( BinOpInit *UI) { return 0; }
|
||||
virtual Init *convertValue( BinOpInit *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);}
|
||||
@ -165,7 +167,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( BinOpInit *UI) { return 0; }
|
||||
virtual Init *convertValue( BinOpInit *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);}
|
||||
@ -203,7 +205,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( BinOpInit *UI) { return 0; }
|
||||
virtual Init *convertValue( BinOpInit *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);}
|
||||
@ -282,7 +284,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( BinOpInit *UI) { return 0; }
|
||||
virtual Init *convertValue( BinOpInit *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);}
|
||||
@ -319,7 +321,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( BinOpInit *UI) { return 0; }
|
||||
virtual Init *convertValue( BinOpInit *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);}
|
||||
@ -393,7 +395,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( BinOpInit *UI) { return 0; }
|
||||
virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
|
||||
virtual Init *convertValue( DefInit *DI);
|
||||
virtual Init *convertValue( DagInit *DI) { return 0; }
|
||||
virtual Init *convertValue( TypedInit *VI);
|
||||
@ -656,36 +658,6 @@ public:
|
||||
inline bool empty() const { return Values.empty(); }
|
||||
};
|
||||
|
||||
/// BinOpInit - !op (X, Y) - Combine two inits.
|
||||
///
|
||||
class BinOpInit : public Init {
|
||||
public:
|
||||
enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, NAMECONCAT };
|
||||
private:
|
||||
BinaryOp Opc;
|
||||
Init *LHS, *RHS;
|
||||
public:
|
||||
BinOpInit(BinaryOp opc, Init *lhs, Init *rhs) : Opc(opc), LHS(lhs), RHS(rhs) {
|
||||
}
|
||||
|
||||
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 *convertInitializerTo(RecTy *Ty) {
|
||||
return Ty->convertValue(this);
|
||||
}
|
||||
|
||||
virtual Init *resolveReferences(Record &R, const RecordVal *RV);
|
||||
|
||||
virtual std::string getAsString() const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// TypedInit - This is the common super-class of types that have a specific,
|
||||
/// explicit, type.
|
||||
@ -714,6 +686,43 @@ public:
|
||||
unsigned Elt) = 0;
|
||||
};
|
||||
|
||||
|
||||
/// BinOpInit - !op (X, Y) - Combine two inits.
|
||||
///
|
||||
class BinOpInit : 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; }
|
||||
|
||||
// Fold - If possible, fold this to a simpler init. Return this if not
|
||||
// possible to fold.
|
||||
Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
|
||||
|
||||
virtual Init *convertInitializerTo(RecTy *Ty) {
|
||||
return Ty->convertValue(this);
|
||||
}
|
||||
|
||||
virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
|
||||
unsigned Bit);
|
||||
virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
|
||||
unsigned Elt);
|
||||
|
||||
virtual Init *resolveReferences(Record &R, const RecordVal *RV);
|
||||
|
||||
virtual std::string getAsString() const;
|
||||
};
|
||||
|
||||
|
||||
/// VarInit - 'Opcode' - Represent a reference to an entire variable object.
|
||||
///
|
||||
class VarInit : public TypedInit {
|
||||
|
@ -784,6 +784,26 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
|
||||
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;
|
||||
@ -807,7 +827,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
|
||||
return 0;
|
||||
}
|
||||
Lex.Lex(); // eat the ')'
|
||||
Operator = (new BinOpInit(Code, LHS, RHS))->Fold(CurRec, CurMultiClass);
|
||||
Operator = (new BinOpInit(Code, LHS, RHS, Type))->Fold(CurRec, CurMultiClass);
|
||||
}
|
||||
|
||||
// If the operator name is present, parse it.
|
||||
@ -842,16 +862,59 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
|
||||
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: Code = BinOpInit::CONCAT; break;
|
||||
case tgtok::XSRA: Code = BinOpInit::SRA; break;
|
||||
case tgtok::XSRL: Code = BinOpInit::SRL; break;
|
||||
case tgtok::XSHL: Code = BinOpInit::SHL; break;
|
||||
case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break;
|
||||
case tgtok::XNameConcat: Code = BinOpInit::NAMECONCAT; break;
|
||||
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;
|
||||
}
|
||||
Lex.Lex(); // eat the operation
|
||||
if (Lex.getCode() != tgtok::l_paren) {
|
||||
TokError("expected '(' after binary operator");
|
||||
return 0;
|
||||
@ -875,7 +938,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
|
||||
return 0;
|
||||
}
|
||||
Lex.Lex(); // eat the ')'
|
||||
return (new BinOpInit(Code, LHS, RHS))->Fold(CurRec, CurMultiClass);
|
||||
return (new BinOpInit(Code, LHS, RHS, Type))->Fold(CurRec, CurMultiClass);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user