mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 02:33:33 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106305 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
78db186d2d
commit
6e0a99a7ab
@ -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<4> Prefix = 11; }
|
||||
<b>class</b> XS { bits<4> Prefix = 12; }
|
||||
|
||||
<b>class</b> I<bits<4> op> {
|
||||
bits<4> opcode = op;
|
||||
}
|
||||
|
||||
<b>multiclass</b> R {
|
||||
<b>def</b> rr : I<4>;
|
||||
<b>def</b> rm : I<2>;
|
||||
}
|
||||
|
||||
<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<4> opcode = { 0, 0, 1, 0 };
|
||||
bits<4> Prefix = { 1, 1, 0, 0 };
|
||||
}
|
||||
...
|
||||
<b>def</b> InstrSSrr {
|
||||
bits<4> opcode = { 0, 1, 0, 0 };
|
||||
bits<4> Prefix = { 1, 0, 1, 1 };
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
|
36
test/TableGen/defmclass.td
Normal file
36
test/TableGen/defmclass.td
Normal 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;
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user