mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-29 06:30:39 +00:00
Make IntInits and ListInits typed. This helps deduce types of !if and
other operators. For the rare cases where a list type cannot be deduced, provide a []<type> syntax, where <type> is the list element type. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73078 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
77c489dcae
commit
e1b469170b
@ -228,6 +228,7 @@ class SDNode<string opcode, SDTypeProfile typeprof,
|
||||
SDTypeProfile TypeProfile = typeprof;
|
||||
}
|
||||
|
||||
// Special TableGen-recognized dag nodes
|
||||
def set;
|
||||
def implicit;
|
||||
def parallel;
|
||||
|
87
test/TableGen/Slice.td
Normal file
87
test/TableGen/Slice.td
Normal file
@ -0,0 +1,87 @@
|
||||
// RUN: tblgen %s | grep {[(set VR128:$dst, (int_x86_sse2_add_pd VR128:$src1, VR128:$src2))]} | count 1
|
||||
// RUN: tblgen %s | grep {[(set VR128:$dst, (int_x86_sse2_add_ps VR128:$src1, VR128:$src2))]} | count 2
|
||||
|
||||
class ValueType<int size, int value> {
|
||||
int Size = size;
|
||||
int Value = value;
|
||||
}
|
||||
|
||||
def f32 : ValueType<32, 1>; // 2 x i64 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 FR32 : RegisterClass<[f32],
|
||||
[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
|
||||
XMM8, XMM9, XMM10, XMM11,
|
||||
XMM12, XMM13, XMM14, XMM15]>;
|
||||
|
||||
class SDNode {}
|
||||
def not : SDNode;
|
||||
|
||||
multiclass scalar<bits<8> opcode, string asmstr = "", list<list<dag>> patterns = []> {
|
||||
def SSrr : Inst<opcode, (outs FR32:$dst), (ins FR32:$src),
|
||||
!strconcat(asmstr, "\t$dst, $src"),
|
||||
!if(!null(patterns),[]<dag>,patterns[0])>;
|
||||
def SSrm : Inst<opcode, (outs FR32:$dst), (ins FR32:$src),
|
||||
!strconcat(asmstr, "\t$dst, $src"),
|
||||
!if(!null(patterns),[]<dag>,!if(!null(!cdr(patterns)),patterns[0],patterns[1]))>;
|
||||
}
|
||||
|
||||
multiclass vscalar<bits<8> opcode, string asmstr = "", list<list<dag>> patterns = []> {
|
||||
def V#NAME#SSrr : Inst<opcode, (outs FR32:$dst), (ins FR32:$src),
|
||||
!strconcat(asmstr, "\t$dst, $src"),
|
||||
!if(!null(patterns),[]<dag>,patterns[0])>;
|
||||
def V#NAME#SSrm : Inst<opcode, (outs FR32:$dst), (ins FR32:$src),
|
||||
!strconcat(asmstr, "\t$dst, $src"),
|
||||
!if(!null(patterns),[]<dag>,!if(!null(!cdr(patterns)),patterns[0],patterns[1]))>;
|
||||
}
|
||||
|
||||
multiclass myscalar<bits<8> opcode, string asmstr = "", list<list<dag>> patterns = []> :
|
||||
scalar<opcode, asmstr, patterns>,
|
||||
vscalar<opcode, asmstr, patterns>;
|
||||
|
||||
defm NOT : myscalar<0x10, "not", [[], [(set FR32:$dst, (f32 (not FR32:$src)))]]>;
|
@ -2007,9 +2007,28 @@ void CodeGenDAGPatterns::ParsePatterns() {
|
||||
Pattern = new TreePattern(Patterns[i], Tree, true, *this);
|
||||
else {
|
||||
std::vector<Init*> Values;
|
||||
for (unsigned j = 0, ee = Tree->getNumArgs(); j != ee; ++j)
|
||||
RecTy *ListTy = 0;
|
||||
for (unsigned j = 0, ee = Tree->getNumArgs(); j != ee; ++j) {
|
||||
Values.push_back(Tree->getArg(j));
|
||||
ListInit *LI = new ListInit(Values);
|
||||
TypedInit *TArg = dynamic_cast<TypedInit*>(Tree->getArg(j));
|
||||
if (TArg == 0) {
|
||||
cerr << "In dag: " << Tree->getAsString();
|
||||
cerr << " -- Untyped argument in pattern\n";
|
||||
assert(0 && "Untyped argument in pattern");
|
||||
}
|
||||
if (ListTy != 0) {
|
||||
ListTy = resolveTypes(ListTy, TArg->getType());
|
||||
if (ListTy == 0) {
|
||||
cerr << "In dag: " << Tree->getAsString();
|
||||
cerr << " -- Incompatible types in pattern arguments\n";
|
||||
assert(0 && "Incompatible types in pattern arguments");
|
||||
}
|
||||
}
|
||||
else {
|
||||
ListTy - TArg->getType();
|
||||
}
|
||||
}
|
||||
ListInit *LI = new ListInit(Values, new ListRecTy(ListTy));
|
||||
Pattern = new TreePattern(Patterns[i], LI, true, *this);
|
||||
}
|
||||
|
||||
|
@ -191,7 +191,12 @@ Init *ListRecTy::convertValue(ListInit *LI) {
|
||||
else
|
||||
return 0;
|
||||
|
||||
return new ListInit(Elements);
|
||||
ListRecTy *LType = dynamic_cast<ListRecTy*>(LI->getType());
|
||||
if (LType == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return new ListInit(Elements, new ListRecTy(Ty));
|
||||
}
|
||||
|
||||
Init *ListRecTy::convertValue(TypedInit *TI) {
|
||||
@ -272,6 +277,57 @@ bool RecordRecTy::baseClassOf(const RecordRecTy *RHS) const {
|
||||
}
|
||||
|
||||
|
||||
/// resolveTypes - Find a common type that T1 and T2 convert to.
|
||||
/// Return 0 if no such type exists.
|
||||
///
|
||||
RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
|
||||
if (!T1->typeIsConvertibleTo(T2)) {
|
||||
if (!T2->typeIsConvertibleTo(T1)) {
|
||||
// If one is a Record type, check superclasses
|
||||
RecordRecTy *RecTy1 = dynamic_cast<RecordRecTy*>(T1);
|
||||
if (RecTy1) {
|
||||
// See if T2 inherits from a type T1 also inherits from
|
||||
const std::vector<Record *> &T1SuperClasses = RecTy1->getRecord()->getSuperClasses();
|
||||
for(std::vector<Record *>::const_iterator i = T1SuperClasses.begin(),
|
||||
iend = T1SuperClasses.end();
|
||||
i != iend;
|
||||
++i) {
|
||||
RecordRecTy *SuperRecTy1 = new RecordRecTy(*i);
|
||||
RecTy *NewType1 = resolveTypes(SuperRecTy1, T2);
|
||||
if (NewType1 != 0) {
|
||||
if (NewType1 != SuperRecTy1) {
|
||||
delete SuperRecTy1;
|
||||
}
|
||||
return NewType1;
|
||||
}
|
||||
}
|
||||
}
|
||||
RecordRecTy *RecTy2 = dynamic_cast<RecordRecTy*>(T2);
|
||||
if (RecTy2) {
|
||||
// See if T1 inherits from a type T2 also inherits from
|
||||
const std::vector<Record *> &T2SuperClasses = RecTy2->getRecord()->getSuperClasses();
|
||||
for(std::vector<Record *>::const_iterator i = T2SuperClasses.begin(),
|
||||
iend = T2SuperClasses.end();
|
||||
i != iend;
|
||||
++i) {
|
||||
RecordRecTy *SuperRecTy2 = new RecordRecTy(*i);
|
||||
RecTy *NewType2 = resolveTypes(T1, SuperRecTy2);
|
||||
if (NewType2 != 0) {
|
||||
if (NewType2 != SuperRecTy2) {
|
||||
delete SuperRecTy2;
|
||||
}
|
||||
return NewType2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return T2;
|
||||
}
|
||||
return T1;
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Initializer implementations
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -400,7 +456,7 @@ Init *ListInit::convertInitListSlice(const std::vector<unsigned> &Elements) {
|
||||
return 0;
|
||||
Vals.push_back(getElement(Elements[i]));
|
||||
}
|
||||
return new ListInit(Vals);
|
||||
return new ListInit(Vals, getType());
|
||||
}
|
||||
|
||||
Record *ListInit::getElementAsRecord(unsigned i) const {
|
||||
@ -428,10 +484,20 @@ Init *ListInit::resolveReferences(Record &R, const RecordVal *RV) {
|
||||
}
|
||||
|
||||
if (Changed)
|
||||
return new ListInit(Resolved);
|
||||
return new ListInit(Resolved, getType());
|
||||
return this;
|
||||
}
|
||||
|
||||
Init *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV,
|
||||
unsigned Elt) {
|
||||
if (Elt >= getSize())
|
||||
return 0; // Out of range reference.
|
||||
Init *E = getElement(Elt);
|
||||
if (!dynamic_cast<UnsetInit*>(E)) // If the element is set
|
||||
return E; // Replace the VarListElementInit with it.
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string ListInit::getAsString() const {
|
||||
std::string Result = "[";
|
||||
for (unsigned i = 0, e = Values.size(); i != e; ++i) {
|
||||
@ -540,7 +606,7 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
|
||||
assert(0 && "Empty list in cdr");
|
||||
return 0;
|
||||
}
|
||||
ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end());
|
||||
ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end(), LHSl->getType());
|
||||
return Result;
|
||||
}
|
||||
break;
|
||||
@ -555,6 +621,16 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
|
||||
return new IntInit(0);
|
||||
}
|
||||
}
|
||||
StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
|
||||
if (LHSs) {
|
||||
if (LHSs->getValue().empty()) {
|
||||
return new IntInit(1);
|
||||
}
|
||||
else {
|
||||
return new IntInit(0);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -667,8 +743,8 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
|
||||
if (Record *D = Records.getDef(Name))
|
||||
return new DefInit(D);
|
||||
|
||||
cerr << "Variable not defined: '" + Name + "'\n";
|
||||
assert(0 && "Variable not found");
|
||||
cerr << "Variable not defined in !nameconcat: '" + Name + "'\n";
|
||||
assert(0 && "Variable not found in !nameconcat");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
@ -881,7 +957,7 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
|
||||
delete NewOp;
|
||||
}
|
||||
}
|
||||
return new ListInit(NewList);
|
||||
return new ListInit(NewList, MHSl->getType());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -1027,7 +1103,7 @@ Init *TypedInit::convertInitListSlice(const std::vector<unsigned> &Elements) {
|
||||
ListInits.reserve(Elements.size());
|
||||
for (unsigned i = 0, e = Elements.size(); i != e; ++i)
|
||||
ListInits.push_back(new VarListElementInit(this, Elements[i]));
|
||||
return new ListInit(ListInits);
|
||||
return new ListInit(ListInits, T);
|
||||
}
|
||||
|
||||
|
||||
|
@ -442,7 +442,10 @@ public:
|
||||
virtual bool baseClassOf(const RecordRecTy *RHS) const;
|
||||
};
|
||||
|
||||
|
||||
/// resolveTypes - Find a common type that T1 and T2 convert to.
|
||||
/// Return 0 if no such type exists.
|
||||
///
|
||||
RecTy *resolveTypes(RecTy *T1, RecTy *T2);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Initializer Classes
|
||||
@ -618,10 +621,10 @@ public:
|
||||
|
||||
/// IntInit - 7 - Represent an initalization by a literal integer value.
|
||||
///
|
||||
class IntInit : public Init {
|
||||
class IntInit : public TypedInit {
|
||||
int64_t Value;
|
||||
public:
|
||||
explicit IntInit(int64_t V) : Value(V) {}
|
||||
explicit IntInit(int64_t V) : TypedInit(new IntRecTy), Value(V) {}
|
||||
|
||||
int64_t getValue() const { return Value; }
|
||||
|
||||
@ -631,6 +634,25 @@ public:
|
||||
virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
|
||||
|
||||
virtual std::string getAsString() const;
|
||||
|
||||
/// resolveBitReference - This method is used to implement
|
||||
/// VarBitInit::resolveReferences. If the bit is able to be resolved, we
|
||||
/// simply return the resolved value, otherwise we return null.
|
||||
///
|
||||
virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
|
||||
unsigned Bit) {
|
||||
assert(0 && "Illegal bit reference off int");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// resolveListElementReference - This method is used to implement
|
||||
/// VarListElementInit::resolveReferences. If the list element is resolvable
|
||||
/// now, we return the resolved value, otherwise we return null.
|
||||
virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
|
||||
unsigned Elt) {
|
||||
assert(0 && "Illegal element reference off int");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -688,17 +710,18 @@ public:
|
||||
|
||||
/// ListInit - [AL, AH, CL] - Represent a list of defs
|
||||
///
|
||||
class ListInit : public Init {
|
||||
class ListInit : public TypedInit {
|
||||
std::vector<Init*> Values;
|
||||
public:
|
||||
typedef std::vector<Init*>::iterator iterator;
|
||||
typedef std::vector<Init*>::const_iterator const_iterator;
|
||||
|
||||
explicit ListInit(std::vector<Init*> &Vs) {
|
||||
explicit ListInit(std::vector<Init*> &Vs, RecTy *EltTy)
|
||||
: TypedInit(new ListRecTy(EltTy)) {
|
||||
Values.swap(Vs);
|
||||
}
|
||||
explicit ListInit(iterator Start, iterator End)
|
||||
: Values(Start, End) {}
|
||||
explicit ListInit(iterator Start, iterator End, RecTy *EltTy)
|
||||
: TypedInit(new ListRecTy(EltTy)), Values(Start, End) {}
|
||||
|
||||
unsigned getSize() const { return Values.size(); }
|
||||
Init *getElement(unsigned i) const {
|
||||
@ -730,6 +753,22 @@ public:
|
||||
|
||||
inline size_t size () const { return Values.size(); }
|
||||
inline bool empty() const { return Values.empty(); }
|
||||
|
||||
/// resolveBitReference - This method is used to implement
|
||||
/// VarBitInit::resolveReferences. If the bit is able to be resolved, we
|
||||
/// simply return the resolved value, otherwise we return null.
|
||||
///
|
||||
virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
|
||||
unsigned Bit) {
|
||||
assert(0 && "Illegal bit reference off list");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// resolveListElementReference - This method is used to implement
|
||||
/// VarListElementInit::resolveReferences. If the list element is resolvable
|
||||
/// now, we return the resolved value, otherwise we return null.
|
||||
virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
|
||||
unsigned Elt);
|
||||
};
|
||||
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
#include "TGParser.h"
|
||||
#include "Record.h"
|
||||
@ -396,7 +397,7 @@ ParseSubClassReference(Record *CurRec, bool isDefm) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
Result.TemplateArgs = ParseValueList(CurRec);
|
||||
Result.TemplateArgs = ParseValueList(CurRec, Result.Rec);
|
||||
if (Result.TemplateArgs.empty()) {
|
||||
Result.Rec = 0; // Error parsing value list.
|
||||
return Result;
|
||||
@ -438,7 +439,7 @@ ParseSubMultiClassReference(MultiClass *CurMC) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
Result.TemplateArgs = ParseValueList(&CurMC->Rec);
|
||||
Result.TemplateArgs = ParseValueList(&CurMC->Rec, &Result.MC->Rec);
|
||||
if (Result.TemplateArgs.empty()) {
|
||||
Result.MC = 0; // Error parsing value list.
|
||||
return Result;
|
||||
@ -728,21 +729,28 @@ Init *TGParser::ParseOperation(Record *CurRec) {
|
||||
|| Code == UnOpInit::CDR
|
||||
|| Code == UnOpInit::LNULL) {
|
||||
ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
|
||||
StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
|
||||
TypedInit *LHSt = dynamic_cast<TypedInit*>(LHS);
|
||||
if (LHSl == 0 && LHSt == 0) {
|
||||
TokError("expected list type argument in unary operator");
|
||||
if (LHSl == 0 && LHSs == 0 && LHSt == 0) {
|
||||
TokError("expected list or string type argument in unary operator");
|
||||
return 0;
|
||||
}
|
||||
if (LHSt) {
|
||||
ListRecTy *LType = dynamic_cast<ListRecTy*>(LHSt->getType());
|
||||
if (LType == 0) {
|
||||
TokError("expected list type argumnet in unary operator");
|
||||
StringRecTy *SType = dynamic_cast<StringRecTy*>(LHSt->getType());
|
||||
if (LType == 0 && SType == 0) {
|
||||
TokError("expected list or string type argumnet in unary operator");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (Code == UnOpInit::CAR
|
||||
|| Code == UnOpInit::CDR) {
|
||||
if (LHSl == 0 && LHSt == 0) {
|
||||
TokError("expected list type argumnet in unary operator");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (LHSl && LHSl->getSize() == 0) {
|
||||
TokError("empty list argument in unary operator");
|
||||
return 0;
|
||||
@ -1017,7 +1025,7 @@ RecTy *TGParser::ParseOperatorType(void) {
|
||||
/// SimpleValue ::= SRLTOK '(' Value ',' Value ')'
|
||||
/// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
|
||||
///
|
||||
Init *TGParser::ParseSimpleValue(Record *CurRec) {
|
||||
Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
|
||||
Init *R = 0;
|
||||
switch (Lex.getCode()) {
|
||||
default: TokError("Unknown token when parsing a value"); break;
|
||||
@ -1049,15 +1057,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
|
||||
TokError("expected non-empty value list");
|
||||
return 0;
|
||||
}
|
||||
std::vector<Init*> ValueList = ParseValueList(CurRec);
|
||||
if (ValueList.empty()) return 0;
|
||||
|
||||
if (Lex.getCode() != tgtok::greater) {
|
||||
TokError("expected '>' at end of value list");
|
||||
return 0;
|
||||
}
|
||||
Lex.Lex(); // eat the '>'
|
||||
|
||||
|
||||
// This is a CLASS<initvalslist> expression. This is supposed to synthesize
|
||||
// a new anonymous definition, deriving from CLASS<initvalslist> with no
|
||||
// body.
|
||||
@ -1066,6 +1066,15 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
|
||||
Error(NameLoc, "Expected a class name, got '" + Name + "'");
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<Init*> ValueList = ParseValueList(CurRec, Class);
|
||||
if (ValueList.empty()) return 0;
|
||||
|
||||
if (Lex.getCode() != tgtok::greater) {
|
||||
TokError("expected '>' at end of value list");
|
||||
return 0;
|
||||
}
|
||||
Lex.Lex(); // eat the '>'
|
||||
|
||||
// Create the new record, set it as CurRec temporarily.
|
||||
static unsigned AnonCounter = 0;
|
||||
@ -1114,8 +1123,22 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
|
||||
Lex.Lex(); // eat the '['
|
||||
std::vector<Init*> Vals;
|
||||
|
||||
RecTy *DeducedEltTy = 0;
|
||||
ListRecTy *GivenListTy = 0;
|
||||
|
||||
if (ItemType != 0) {
|
||||
ListRecTy *ListType = dynamic_cast<ListRecTy*>(ItemType);
|
||||
if (ListType == 0) {
|
||||
std::stringstream s;
|
||||
s << "Type mismatch for list, expected list type, got "
|
||||
<< ItemType->getAsString();
|
||||
TokError(s.str());
|
||||
}
|
||||
GivenListTy = ListType;
|
||||
}
|
||||
|
||||
if (Lex.getCode() != tgtok::r_square) {
|
||||
Vals = ParseValueList(CurRec);
|
||||
Vals = ParseValueList(CurRec, 0, GivenListTy ? GivenListTy->getElementType() : 0);
|
||||
if (Vals.empty()) return 0;
|
||||
}
|
||||
if (Lex.getCode() != tgtok::r_square) {
|
||||
@ -1123,7 +1146,77 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
|
||||
return 0;
|
||||
}
|
||||
Lex.Lex(); // eat the ']'
|
||||
return new ListInit(Vals);
|
||||
|
||||
RecTy *GivenEltTy = 0;
|
||||
if (Lex.getCode() == tgtok::less) {
|
||||
// Optional list element type
|
||||
Lex.Lex(); // eat the '<'
|
||||
|
||||
GivenEltTy = ParseType();
|
||||
if (GivenEltTy == 0) {
|
||||
// Couldn't parse element type
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Lex.getCode() != tgtok::greater) {
|
||||
TokError("expected '>' at end of list element type");
|
||||
return 0;
|
||||
}
|
||||
Lex.Lex(); // eat the '>'
|
||||
}
|
||||
|
||||
// Check elements
|
||||
RecTy *EltTy = 0;
|
||||
for (std::vector<Init *>::iterator i = Vals.begin(), ie = Vals.end();
|
||||
i != ie;
|
||||
++i) {
|
||||
TypedInit *TArg = dynamic_cast<TypedInit*>(*i);
|
||||
if (TArg == 0) {
|
||||
TokError("Untyped list element");
|
||||
return 0;
|
||||
}
|
||||
if (EltTy != 0) {
|
||||
EltTy = resolveTypes(EltTy, TArg->getType());
|
||||
if (EltTy == 0) {
|
||||
TokError("Incompatible types in list elements");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
EltTy = TArg->getType();
|
||||
}
|
||||
}
|
||||
|
||||
if (GivenEltTy != 0) {
|
||||
if (EltTy != 0) {
|
||||
// Verify consistency
|
||||
if (!EltTy->typeIsConvertibleTo(GivenEltTy)) {
|
||||
TokError("Incompatible types in list elements");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
EltTy = GivenEltTy;
|
||||
}
|
||||
|
||||
if (EltTy == 0) {
|
||||
if (ItemType == 0) {
|
||||
TokError("No type for list");
|
||||
return 0;
|
||||
}
|
||||
DeducedEltTy = GivenListTy->getElementType();
|
||||
}
|
||||
else {
|
||||
// Make sure the deduced type is compatible with the given type
|
||||
if (GivenListTy) {
|
||||
if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) {
|
||||
TokError("Element type mismatch for list");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
DeducedEltTy = EltTy;
|
||||
}
|
||||
|
||||
return new ListInit(Vals, DeducedEltTy);
|
||||
}
|
||||
case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')'
|
||||
Lex.Lex(); // eat the '('
|
||||
@ -1200,8 +1293,8 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
|
||||
/// ValueSuffix ::= '[' BitList ']'
|
||||
/// ValueSuffix ::= '.' ID
|
||||
///
|
||||
Init *TGParser::ParseValue(Record *CurRec) {
|
||||
Init *Result = ParseSimpleValue(CurRec);
|
||||
Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType) {
|
||||
Init *Result = ParseSimpleValue(CurRec, ItemType);
|
||||
if (Result == 0) return 0;
|
||||
|
||||
// Parse the suffixes now if present.
|
||||
@ -1306,15 +1399,31 @@ TGParser::ParseDagArgList(Record *CurRec) {
|
||||
///
|
||||
/// ValueList ::= Value (',' Value)
|
||||
///
|
||||
std::vector<Init*> TGParser::ParseValueList(Record *CurRec) {
|
||||
std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec, RecTy *EltTy) {
|
||||
std::vector<Init*> Result;
|
||||
Result.push_back(ParseValue(CurRec));
|
||||
RecTy *ItemType = EltTy;
|
||||
int ArgN = 0;
|
||||
if (ArgsRec != 0 && EltTy == 0) {
|
||||
const std::vector<std::string> &TArgs = ArgsRec->getTemplateArgs();
|
||||
const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
|
||||
assert(RV && "Template argument record not found??");
|
||||
ItemType = RV->getType();
|
||||
++ArgN;
|
||||
}
|
||||
Result.push_back(ParseValue(CurRec, ItemType));
|
||||
if (Result.back() == 0) return std::vector<Init*>();
|
||||
|
||||
while (Lex.getCode() == tgtok::comma) {
|
||||
Lex.Lex(); // Eat the comma
|
||||
|
||||
Result.push_back(ParseValue(CurRec));
|
||||
if (ArgsRec != 0 && EltTy == 0) {
|
||||
const std::vector<std::string> &TArgs = ArgsRec->getTemplateArgs();
|
||||
const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
|
||||
assert(RV && "Template argument record not found??");
|
||||
ItemType = RV->getType();
|
||||
++ArgN;
|
||||
}
|
||||
Result.push_back(ParseValue(CurRec, ItemType));
|
||||
if (Result.back() == 0) return std::vector<Init*>();
|
||||
}
|
||||
|
||||
@ -1369,7 +1478,7 @@ std::string TGParser::ParseDeclaration(Record *CurRec,
|
||||
if (Lex.getCode() == tgtok::equal) {
|
||||
Lex.Lex();
|
||||
TGLoc ValLoc = Lex.getLoc();
|
||||
Init *Val = ParseValue(CurRec);
|
||||
Init *Val = ParseValue(CurRec, Type);
|
||||
if (Val == 0 ||
|
||||
SetValue(CurRec, ValLoc, DeclName, std::vector<unsigned>(), Val))
|
||||
return "";
|
||||
@ -1447,7 +1556,13 @@ bool TGParser::ParseBodyItem(Record *CurRec) {
|
||||
return TokError("expected '=' in let expression");
|
||||
Lex.Lex(); // eat the '='.
|
||||
|
||||
Init *Val = ParseValue(CurRec);
|
||||
RecordVal *Field = CurRec->getValue(FieldName);
|
||||
if (Field == 0)
|
||||
return TokError("Value '" + FieldName + "' unknown!");
|
||||
|
||||
RecTy *Type = Field->getType();
|
||||
|
||||
Init *Val = ParseValue(CurRec, Type);
|
||||
if (Val == 0) return true;
|
||||
|
||||
if (Lex.getCode() != tgtok::semi)
|
||||
|
@ -93,9 +93,9 @@ private: // Parser methods.
|
||||
|
||||
Init *ParseIDValue(Record *CurRec);
|
||||
Init *ParseIDValue(Record *CurRec, const std::string &Name, TGLoc NameLoc);
|
||||
Init *ParseSimpleValue(Record *CurRec);
|
||||
Init *ParseValue(Record *CurRec);
|
||||
std::vector<Init*> ParseValueList(Record *CurRec);
|
||||
Init *ParseSimpleValue(Record *CurRec, RecTy *ItemType = 0);
|
||||
Init *ParseValue(Record *CurRec, RecTy *ItemType = 0);
|
||||
std::vector<Init*> ParseValueList(Record *CurRec, Record *ArgsRec = 0, RecTy *EltTy = 0);
|
||||
std::vector<std::pair<llvm::Init*, std::string> > ParseDagArgList(Record *);
|
||||
bool ParseOptionalRangeList(std::vector<unsigned> &Ranges);
|
||||
bool ParseOptionalBitList(std::vector<unsigned> &Ranges);
|
||||
|
Loading…
Reference in New Issue
Block a user