diff --git a/docs/TableGenFundamentals.html b/docs/TableGenFundamentals.html
index f7a082d7050..81f3cfe0448 100644
--- a/docs/TableGenFundamentals.html
+++ b/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/test/TableGen/defmclass.td b/test/TableGen/defmclass.td
new file mode 100644
index 00000000000..ef8e8f794ba
--- /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 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 49ff0b0c4cd..3770848702c 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 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();