diff options
-rw-r--r-- | docs/TableGenFundamentals.html | 41 | ||||
-rw-r--r-- | test/TableGen/defmclass.td | 36 | ||||
-rw-r--r-- | utils/TableGen/TGParser.cpp | 50 |
3 files changed, 127 insertions, 0 deletions
diff --git a/docs/TableGenFundamentals.html b/docs/TableGenFundamentals.html index f7a082d705..81f3cfe044 100644 --- a/docs/TableGenFundamentals.html +++ b/docs/TableGenFundamentals.html @@ -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> <!-- ======================================================================= --> diff --git a/test/TableGen/defmclass.td b/test/TableGen/defmclass.td new file mode 100644 index 0000000000..ef8e8f794b --- /dev/null +++ b/test/TableGen/defmclass.td @@ -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; diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp index 49ff0b0c4c..3770848702 100644 --- a/utils/TableGen/TGParser.cpp +++ b/utils/TableGen/TGParser.cpp @@ -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(); |