mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-28 09:31:03 +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>
|
</pre>
|
||||||
</div>
|
</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>
|
</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)
|
if (Lex.Lex() != tgtok::colon)
|
||||||
return TokError("expected ':' after defm identifier");
|
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.
|
// eat the colon.
|
||||||
Lex.Lex();
|
Lex.Lex();
|
||||||
|
|
||||||
@ -2016,15 +2022,59 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) {
|
|||||||
Records.addDef(CurRec);
|
Records.addDef(CurRec);
|
||||||
CurRec->resolveReferences();
|
CurRec->resolveReferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NewRecDefs.push_back(CurRec);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Lex.getCode() != tgtok::comma) break;
|
if (Lex.getCode() != tgtok::comma) break;
|
||||||
Lex.Lex(); // eat ','.
|
Lex.Lex(); // eat ','.
|
||||||
|
|
||||||
SubClassLoc = Lex.getLoc();
|
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);
|
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)
|
if (Lex.getCode() != tgtok::semi)
|
||||||
return TokError("expected ';' at end of defm");
|
return TokError("expected ';' at end of defm");
|
||||||
Lex.Lex();
|
Lex.Lex();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user