Skip to content

Commit

Permalink
Teach tablegen how to inherit from classes in 'defm' definitions.
Browse files Browse the repository at this point in the history
The rule is simple: only inherit from a class list if they come
in the end, after the last multiclass.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106305 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
bcardosolopes committed Jun 18, 2010
1 parent 78db186 commit 6e0a99a
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 0 deletions.
41 changes: 41 additions & 0 deletions docs/TableGenFundamentals.html
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,47 @@
</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>

<!-- ======================================================================= -->
Expand Down
36 changes: 36 additions & 0 deletions test/TableGen/defmclass.td
Original file line number Diff line number Diff line change
@@ -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;
50 changes: 50 additions & 0 deletions utils/TableGen/TGParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 6e0a99a

Please sign in to comment.