From 23f8321cbcb61272ce4e6fbc78e7a8738ba3f861 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Fri, 18 Jun 2010 19:53:41 +0000 Subject: [PATCH] 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 --- llvm/docs/TableGenFundamentals.html | 41 +++++++++++++++++++++++ llvm/test/TableGen/defmclass.td | 36 +++++++++++++++++++++ llvm/utils/TableGen/TGParser.cpp | 50 +++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 llvm/test/TableGen/defmclass.td diff --git a/llvm/docs/TableGenFundamentals.html b/llvm/docs/TableGenFundamentals.html index f7a082d7050e..81f3cfe0448d 100644 --- a/llvm/docs/TableGenFundamentals.html +++ b/llvm/docs/TableGenFundamentals.html @@ -732,6 +732,47 @@ multiclass instanciations. +

+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. +

+ +
+
+class XD { bits<4> Prefix = 11; }
+class XS { bits<4> Prefix = 12; }
+
+class I<bits<4> op> {
+  bits<4> opcode = op;
+}
+
+multiclass R {
+  def rr : I<4>;
+  def rm : I<2>;
+}
+
+multiclass Y {
+  defm SS : R, XD;
+  defm SD : R, XS;
+}
+
+defm Instr : Y;
+
+// Results
+def InstrSDrm {
+  bits<4> opcode = { 0, 0, 1, 0 };
+  bits<4> Prefix = { 1, 1, 0, 0 };
+}
+...
+def InstrSSrr {
+  bits<4> opcode = { 0, 1, 0, 0 };
+  bits<4> Prefix = { 1, 0, 1, 1 };
+}
+
+
+ diff --git a/llvm/test/TableGen/defmclass.td b/llvm/test/TableGen/defmclass.td new file mode 100644 index 000000000000..ef8e8f794bac --- /dev/null +++ b/llvm/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 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/llvm/utils/TableGen/TGParser.cpp b/llvm/utils/TableGen/TGParser.cpp index 49ff0b0c4cd1..3770848702c1 100644 --- a/llvm/utils/TableGen/TGParser.cpp +++ b/llvm/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 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();