Teach tablegen how to inherit from classes in 'defm' definitions.

The rule is simple: only inherit from a class list if they come
in the end, after the last multiclass.

llvm-svn: 106305
This commit is contained in:
Bruno Cardoso Lopes 2010-06-18 19:53:41 +00:00
parent 4c807fca97
commit 23f8321cbc
3 changed files with 127 additions and 0 deletions

View File

@ -732,6 +732,47 @@ multiclass instanciations.
</pre>
</div>
<p>
defm declarations can inherit from classes too, the
rule to follow is that the class list must start after the
last multiclass, and there must be at least one multiclass
before them.
</p>
<div class="doc_code">
<pre>
<b>class</b> XD { bits&lt;4&gt; Prefix = 11; }
<b>class</b> XS { bits&lt;4&gt; Prefix = 12; }
<b>class</b> I&lt;bits<4&gt; op> {
bits&lt;4&gt; opcode = op;
}
<b>multiclass</b> R {
<b>def</b> rr : I&lt;4&gt;;
<b>def</b> rm : I&lt;2&gt;;
}
<b>multiclass</b> Y {
<b>defm</b> SS : R, XD;
<b>defm</b> SD : R, XS;
}
<b>defm</b> Instr : Y;
<i>// Results</i>
<b>def</b> InstrSDrm {
bits&lt;4&gt; opcode = { 0, 0, 1, 0 };
bits&lt;4&gt; Prefix = { 1, 1, 0, 0 };
}
...
<b>def</b> InstrSSrr {
bits&lt;4&gt; opcode = { 0, 1, 0, 0 };
bits&lt;4&gt; Prefix = { 1, 0, 1, 1 };
}
</pre>
</div>
</div>
<!-- ======================================================================= -->

View File

@ -0,0 +1,36 @@
// RUN: tblgen %s | FileCheck %s
// XFAIL: vg_leak
class XD { bits<4> Prefix = 11; }
// CHECK: Prefix = { 1, 1, 0, 0 };
class XS { bits<4> Prefix = 12; }
class VEX { bit hasVEX_4VPrefix = 1; }
def xd : XD;
class BaseI {
bits<4> Prefix = 0;
bit hasVEX_4VPrefix = 0;
}
class I<bits<4> op> : BaseI {
bits<4> opcode = op;
int val = !if(!eq(Prefix, xd.Prefix), 7, 21);
}
multiclass R {
def rr : I<4>;
}
multiclass M {
def rm : I<2>;
}
multiclass Y {
defm SS : R, M, XD;
// CHECK: Prefix = { 1, 1, 0, 0 };
// CHECK: Prefix = { 1, 1, 0, 0 };
defm SD : R, M, XS;
}
defm Instr : Y, VEX;

View File

@ -1907,6 +1907,12 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
if (Lex.Lex() != tgtok::colon)
return TokError("expected ':' after defm identifier");
// Keep track of the new generated record definitions.
std::vector<Record*> NewRecDefs;
// This record also inherits from a regular class (non-multiclass)?
bool InheritFromClass = false;
// eat the colon.
Lex.Lex();
@ -2016,15 +2022,59 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
Records.addDef(CurRec);
CurRec->resolveReferences();
}
NewRecDefs.push_back(CurRec);
}
if (Lex.getCode() != tgtok::comma) break;
Lex.Lex(); // eat ','.
SubClassLoc = Lex.getLoc();
// A defm can inherit from regular classes (non-multiclass) as
// long as they come in the end of the inheritance list.
InheritFromClass = (Records.getClass(Lex.getCurStrVal()) != 0);
if (InheritFromClass)
break;
Ref = ParseSubClassReference(0, true);
}
if (InheritFromClass) {
// Process all the classes to inherit as if they were part of a
// regular 'def' and inherit all record values.
SubClassReference SubClass = ParseSubClassReference(0, false);
while (1) {
// Check for error.
if (SubClass.Rec == 0) return true;
// Get the expanded definition prototypes and teach them about
// the record values the current class to inherit has
for (unsigned i = 0, e = NewRecDefs.size(); i != e; ++i) {
Record *CurRec = NewRecDefs[i];
// Add it.
if (AddSubClass(CurRec, SubClass))
return true;
// Process any variables on the let stack.
for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name,
LetStack[i][j].Bits, LetStack[i][j].Value))
return true;
if (!CurMultiClass)
CurRec->resolveReferences();
}
if (Lex.getCode() != tgtok::comma) break;
Lex.Lex(); // eat ','.
SubClass = ParseSubClassReference(0, false);
}
}
if (Lex.getCode() != tgtok::semi)
return TokError("expected ';' at end of defm");
Lex.Lex();