regenerate


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30029 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/FileParser.cpp.cvs b/utils/TableGen/FileParser.cpp.cvs
index c8fd87d..97045c5 100644
--- a/utils/TableGen/FileParser.cpp.cvs
+++ b/utils/TableGen/FileParser.cpp.cvs
@@ -20,18 +20,20 @@
 #define	DAG	263
 #define	CLASS	264
 #define	DEF	265
-#define	FIELD	266
-#define	LET	267
-#define	IN	268
-#define	SHLTOK	269
-#define	SRATOK	270
-#define	SRLTOK	271
-#define	STRCONCATTOK	272
-#define	INTVAL	273
-#define	ID	274
-#define	VARNAME	275
-#define	STRVAL	276
-#define	CODEFRAGMENT	277
+#define	MULTICLASS	266
+#define	DEFM	267
+#define	FIELD	268
+#define	LET	269
+#define	IN	270
+#define	SHLTOK	271
+#define	SRATOK	272
+#define	SRLTOK	273
+#define	STRCONCATTOK	274
+#define	INTVAL	275
+#define	ID	276
+#define	VARNAME	277
+#define	STRVAL	278
+#define	CODEFRAGMENT	279
 
 #line 14 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 
@@ -45,8 +47,19 @@
 int yylex();
 
 namespace llvm {
+  struct MultiClass {
+    Record Rec;  // Placeholder for template args and Name.
+    std::vector<Record*> DefPrototypes;
+    
+    MultiClass(const std::string &Name) : Rec(Name) {}
+  };
 
+  
+static std::map<std::string, MultiClass*> MultiClasses;
+  
 extern int Filelineno;
+static MultiClass *CurMultiClass = 0;    // Set while parsing a multiclass.
+static std::string *CurDefmPrefix = 0;   // Set while parsing defm.
 static Record *CurRec = 0;
 static bool ParsingTemplateArgs = false;
 
@@ -68,8 +81,16 @@
 
 extern std::ostream &err();
 
+/// getActiveRec - If inside a def/class definition, return the def/class.
+/// Otherwise, if within a multidef, return it.
+static Record *getActiveRec() {
+  return CurRec ? CurRec : &CurMultiClass->Rec;
+}
+
 static void addValue(const RecordVal &RV) {
-  if (RecordVal *ERV = CurRec->getValue(RV.getName())) {
+  Record *TheRec = getActiveRec();
+  
+  if (RecordVal *ERV = TheRec->getValue(RV.getName())) {
     // The value already exists in the class, treat this as a set...
     if (ERV->setValue(RV.getValue())) {
       err() << "New definition of '" << RV.getName() << "' of type '"
@@ -78,7 +99,7 @@
       exit(1);
     }
   } else {
-    CurRec->addValue(RV);
+    TheRec->addValue(RV);
   }
 }
 
@@ -171,33 +192,33 @@
   if (TArgs.size() < TemplateArgs.size()) {
     err() << "ERROR: More template args specified than expected!\n";
     exit(1);
-  } else {    // This class expects template arguments...
-    // Loop over all of the template arguments, setting them to the specified
-    // value or leaving them as the default if necessary.
-    for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
-      if (i < TemplateArgs.size()) {  // A value is specified for this temp-arg?
-        // Set it now.
-        setValue(TArgs[i], 0, TemplateArgs[i]);
+  }
+  
+  // Loop over all of the template arguments, setting them to the specified
+  // value or leaving them as the default if necessary.
+  for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
+    if (i < TemplateArgs.size()) {  // A value is specified for this temp-arg?
+      // Set it now.
+      setValue(TArgs[i], 0, TemplateArgs[i]);
 
-        // Resolve it next.
-        CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
-                                    
-        
-        // Now remove it.
-        CurRec->removeValue(TArgs[i]);
+      // Resolve it next.
+      CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
+                                  
+      
+      // Now remove it.
+      CurRec->removeValue(TArgs[i]);
 
-      } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
-        err() << "ERROR: Value not specified for template argument #"
-              << i << " (" << TArgs[i] << ") of subclass '" << SC->getName()
-              << "'!\n";
-        exit(1);
-      }
+    } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
+      err() << "ERROR: Value not specified for template argument #"
+            << i << " (" << TArgs[i] << ") of subclass '" << SC->getName()
+            << "'!\n";
+      exit(1);
     }
   }
 
   // Since everything went well, we can now set the "superclass" list for the
   // current record.
-  const std::vector<Record*> &SCs  = SC->getSuperClasses();
+  const std::vector<Record*> &SCs = SC->getSuperClasses();
   for (unsigned i = 0, e = SCs.size(); i != e; ++i)
     addSuperClass(SCs[i]);
   addSuperClass(SC);
@@ -208,7 +229,7 @@
 using namespace llvm;
 
 
-#line 189 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 208 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 typedef union {
   std::string*                StrVal;
   int                         IntVal;
@@ -217,6 +238,7 @@
   std::vector<llvm::Init*>*   FieldList;
   std::vector<unsigned>*      BitList;
   llvm::Record*               Rec;
+  std::vector<llvm::Record*>* RecList;
   SubClassRefTy*              SubClassRef;
   std::vector<SubClassRefTy>* SubClassList;
   std::vector<std::pair<llvm::Init*, std::string> >* DagValueList;
@@ -231,26 +253,26 @@
 
 
 
-#define	YYFINAL		168
+#define	YYFINAL		188
 #define	YYFLAG		-32768
-#define	YYNTBASE	39
+#define	YYNTBASE	41
 
-#define YYTRANSLATE(x) ((unsigned)(x) <= 277 ? yytranslate[x] : 80)
+#define YYTRANSLATE(x) ((unsigned)(x) <= 279 ? yytranslate[x] : 90)
 
 static const char yytranslate[] = {     0,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,    33,
-    34,     2,     2,    35,    37,    32,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,    36,    38,    24,
-    26,    25,    27,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,     2,    35,
+    36,     2,     2,    37,    39,    34,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,    38,    40,    26,
+    28,    27,    29,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-    30,     2,    31,     2,     2,     2,     2,     2,     2,     2,
+    32,     2,    33,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,    28,     2,    29,     2,     2,     2,     2,     2,
+     2,     2,    30,     2,    31,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -265,7 +287,7 @@
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     1,     3,     4,     5,     6,
      7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
-    17,    18,    19,    20,    21,    22,    23
+    17,    18,    19,    20,    21,    22,    23,    24,    25
 };
 
 #if YYDEBUG != 0
@@ -278,53 +300,60 @@
    163,   166,   173,   174,   177,   179,   183,   185,   190,   192,
    196,   197,   200,   202,   206,   210,   211,   213,   215,   216,
    218,   220,   222,   223,   227,   228,   229,   236,   240,   242,
-   244,   249,   251,   255,   256,   261,   266,   269,   271,   274
+   244,   247,   249,   250,   251,   260,   261,   268,   270,   272,
+   274,   276,   281,   283,   287,   288,   293,   298,   301,   303,
+   306
 };
 
-static const short yyrhs[] = {    20,
-     0,     5,     0,     4,     0,     6,    24,    19,    25,     0,
-     3,     0,     7,    24,    40,    25,     0,     8,     0,     9,
-     0,    39,     0,     0,    12,     0,     0,    26,    44,     0,
-    20,     0,    43,     0,    19,     0,    22,     0,    23,     0,
-    27,     0,    28,    51,    29,     0,    20,    24,    52,    25,
-     0,    44,    28,    49,    29,     0,    30,    51,    31,     0,
-    44,    32,    20,     0,    33,    43,    47,    34,     0,    44,
-    30,    49,    31,     0,    15,    33,    44,    35,    44,    34,
-     0,    16,    33,    44,    35,    44,    34,     0,    17,    33,
-    44,    35,    44,    34,     0,    18,    33,    44,    35,    44,
-    34,     0,     0,    36,    21,     0,    44,    45,     0,    46,
-    35,    44,    45,     0,     0,    46,     0,    19,     0,    19,
-    37,    19,     0,    19,    19,     0,    48,    35,    19,     0,
-    48,    35,    19,    37,    19,     0,    48,    35,    19,    19,
-     0,    48,     0,     0,    28,    49,    29,     0,     0,    52,
-     0,    44,     0,    52,    35,    44,     0,    41,    40,    20,
-    42,     0,    53,    38,     0,    13,    20,    50,    26,    44,
-    38,     0,     0,    55,    54,     0,    38,     0,    28,    55,
-    29,     0,    39,     0,    39,    24,    52,    25,     0,    57,
-     0,    58,    35,    57,     0,     0,    36,    58,     0,    53,
-     0,    60,    35,    53,     0,    24,    60,    25,     0,     0,
-    61,     0,    20,     0,     0,    63,     0,    64,     0,    64,
-     0,     0,    59,    68,    56,     0,     0,     0,    10,    65,
-    70,    62,    71,    67,     0,    11,    66,    67,     0,    69,
-     0,    72,     0,    20,    50,    26,    44,     0,    74,     0,
-    75,    35,    74,     0,     0,    13,    77,    75,    14,     0,
-    76,    28,    78,    29,     0,    76,    73,     0,    73,     0,
-    78,    73,     0,    78,     0
+static const short yyrhs[] = {    22,
+     0,     5,     0,     4,     0,     6,    26,    21,    27,     0,
+     3,     0,     7,    26,    42,    27,     0,     8,     0,     9,
+     0,    41,     0,     0,    14,     0,     0,    28,    46,     0,
+    22,     0,    45,     0,    21,     0,    24,     0,    25,     0,
+    29,     0,    30,    53,    31,     0,    22,    26,    54,    27,
+     0,    46,    30,    51,    31,     0,    32,    53,    33,     0,
+    46,    34,    22,     0,    35,    45,    49,    36,     0,    46,
+    32,    51,    33,     0,    17,    35,    46,    37,    46,    36,
+     0,    18,    35,    46,    37,    46,    36,     0,    19,    35,
+    46,    37,    46,    36,     0,    20,    35,    46,    37,    46,
+    36,     0,     0,    38,    23,     0,    46,    47,     0,    48,
+    37,    46,    47,     0,     0,    48,     0,    21,     0,    21,
+    39,    21,     0,    21,    21,     0,    50,    37,    21,     0,
+    50,    37,    21,    39,    21,     0,    50,    37,    21,    21,
+     0,    50,     0,     0,    30,    51,    31,     0,     0,    54,
+     0,    46,     0,    54,    37,    46,     0,    43,    42,    22,
+    44,     0,    55,    40,     0,    15,    22,    52,    28,    46,
+    40,     0,     0,    57,    56,     0,    40,     0,    30,    57,
+    31,     0,    41,     0,    41,    26,    54,    27,     0,    59,
+     0,    60,    37,    59,     0,     0,    38,    60,     0,    55,
+     0,    62,    37,    55,     0,    26,    62,    27,     0,     0,
+    63,     0,    22,     0,     0,    65,     0,    66,     0,    66,
+     0,     0,    61,    70,    58,     0,     0,     0,    10,    67,
+    72,    64,    73,    69,     0,    11,    68,    69,     0,    74,
+     0,    75,     0,    76,    75,     0,    22,     0,     0,     0,
+    12,    77,    79,    64,    80,    30,    76,    31,     0,     0,
+    13,    22,    82,    38,    59,    40,     0,    71,     0,    74,
+     0,    78,     0,    81,     0,    22,    52,    28,    46,     0,
+    84,     0,    85,    37,    84,     0,     0,    15,    87,    85,
+    16,     0,    86,    30,    88,    31,     0,    86,    83,     0,
+    83,     0,    88,    83,     0,    88,     0
 };
 
 #endif
 
 #if YYDEBUG != 0
 static const short yyrline[] = { 0,
-   223,   234,   236,   238,   240,   242,   244,   246,   248,   252,
-   252,   254,   254,   256,   273,   275,   277,   280,   283,   285,
-   298,   326,   333,   336,   343,   346,   354,   356,   358,   360,
-   364,   367,   371,   376,   382,   385,   388,   391,   404,   418,
-   420,   433,   449,   451,   451,   455,   457,   461,   464,   468,
-   478,   480,   486,   486,   487,   487,   489,   491,   495,   500,
-   505,   508,   512,   515,   520,   521,   521,   523,   523,   525,
-   532,   550,   562,   576,   581,   583,   585,   589,   598,   598,
-   600,   605,   605,   608,   608,   611,   614,   618,   618,   620
+   244,   266,   268,   270,   272,   274,   276,   278,   280,   284,
+   284,   286,   286,   288,   311,   313,   315,   318,   321,   323,
+   336,   364,   371,   374,   381,   384,   392,   394,   396,   398,
+   402,   405,   409,   414,   420,   423,   426,   429,   442,   456,
+   458,   471,   487,   489,   489,   493,   495,   499,   502,   506,
+   523,   525,   531,   531,   532,   532,   534,   536,   540,   545,
+   550,   553,   557,   560,   565,   566,   566,   568,   568,   570,
+   577,   595,   620,   634,   639,   641,   643,   647,   656,   670,
+   673,   677,   688,   690,   692,   697,   697,   759,   759,   760,
+   760,   762,   767,   767,   770,   770,   773,   776,   780,   780,
+   782
 };
 #endif
 
@@ -332,28 +361,32 @@
 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
 
 static const char * const yytname[] = {   "$","error","$undefined.","INT","BIT",
-"STRING","BITS","LIST","CODE","DAG","CLASS","DEF","FIELD","LET","IN","SHLTOK",
-"SRATOK","SRLTOK","STRCONCATTOK","INTVAL","ID","VARNAME","STRVAL","CODEFRAGMENT",
-"'<'","'>'","'='","'?'","'{'","'}'","'['","']'","'.'","'('","')'","','","':'",
-"'-'","';'","ClassID","Type","OptPrefix","OptValue","IDValue","Value","OptVarName",
-"DagArgListNE","DagArgList","RBitList","BitList","OptBitList","ValueList","ValueListNE",
-"Declaration","BodyItem","BodyList","Body","SubClassRef","ClassListNE","ClassList",
-"DeclListNE","TemplateArgList","OptTemplateArgList","OptID","ObjectName","ClassName",
-"DefName","ObjectBody","@1","ClassInst","@2","@3","DefInst","Object","LETItem",
-"LETList","LETCommand","@4","ObjectList","File", NULL
+"STRING","BITS","LIST","CODE","DAG","CLASS","DEF","MULTICLASS","DEFM","FIELD",
+"LET","IN","SHLTOK","SRATOK","SRLTOK","STRCONCATTOK","INTVAL","ID","VARNAME",
+"STRVAL","CODEFRAGMENT","'<'","'>'","'='","'?'","'{'","'}'","'['","']'","'.'",
+"'('","')'","','","':'","'-'","';'","ClassID","Type","OptPrefix","OptValue",
+"IDValue","Value","OptVarName","DagArgListNE","DagArgList","RBitList","BitList",
+"OptBitList","ValueList","ValueListNE","Declaration","BodyItem","BodyList","Body",
+"SubClassRef","ClassListNE","ClassList","DeclListNE","TemplateArgList","OptTemplateArgList",
+"OptID","ObjectName","ClassName","DefName","ObjectBody","@1","ClassInst","@2",
+"@3","DefInst","MultiClassDef","MultiClassBody","MultiClassName","MultiClassInst",
+"@4","@5","DefMInst","@6","Object","LETItem","LETList","LETCommand","@7","ObjectList",
+"File", NULL
 };
 #endif
 
 static const short yyr1[] = {     0,
-    39,    40,    40,    40,    40,    40,    40,    40,    40,    41,
-    41,    42,    42,    43,    44,    44,    44,    44,    44,    44,
-    44,    44,    44,    44,    44,    44,    44,    44,    44,    44,
-    45,    45,    46,    46,    47,    47,    48,    48,    48,    48,
-    48,    48,    49,    50,    50,    51,    51,    52,    52,    53,
-    54,    54,    55,    55,    56,    56,    57,    57,    58,    58,
-    59,    59,    60,    60,    61,    62,    62,    63,    63,    64,
-    65,    66,    68,    67,    70,    71,    69,    72,    73,    73,
-    74,    75,    75,    77,    76,    73,    73,    78,    78,    79
+    41,    42,    42,    42,    42,    42,    42,    42,    42,    43,
+    43,    44,    44,    45,    46,    46,    46,    46,    46,    46,
+    46,    46,    46,    46,    46,    46,    46,    46,    46,    46,
+    47,    47,    48,    48,    49,    49,    50,    50,    50,    50,
+    50,    50,    51,    52,    52,    53,    53,    54,    54,    55,
+    56,    56,    57,    57,    58,    58,    59,    59,    60,    60,
+    61,    61,    62,    62,    63,    64,    64,    65,    65,    66,
+    67,    68,    70,    69,    72,    73,    71,    74,    75,    76,
+    76,    77,    79,    80,    78,    82,    81,    83,    83,    83,
+    83,    84,    85,    85,    87,    86,    83,    83,    88,    88,
+    89
 };
 
 static const short yyr2[] = {     0,
@@ -365,107 +398,121 @@
      2,     6,     0,     2,     1,     3,     1,     4,     1,     3,
      0,     2,     1,     3,     3,     0,     1,     1,     0,     1,
      1,     1,     0,     3,     0,     0,     6,     3,     1,     1,
-     4,     1,     3,     0,     4,     4,     2,     1,     2,     1
+     2,     1,     0,     0,     8,     0,     6,     1,     1,     1,
+     1,     4,     1,     3,     0,     4,     4,     2,     1,     2,
+     1
 };
 
 static const short yydefact[] = {     0,
-    69,    69,    84,    79,    80,    88,     0,    90,    68,    70,
-    71,    75,    72,    61,     0,     0,    87,    89,    66,     0,
-    73,    78,    44,    82,     0,     0,    10,    67,    76,     1,
-    57,    59,    62,     0,     0,     0,    85,     0,    86,    11,
-     0,    63,     0,    61,     0,     0,    53,    55,    74,    37,
-    43,     0,     0,    83,     5,     3,     2,     0,     0,     7,
-     8,     9,     0,    65,    10,    77,     0,     0,     0,     0,
-    16,    14,    17,    18,    19,    46,    46,     0,    15,    48,
-     0,    60,    10,    39,     0,     0,    45,    81,     0,     0,
-    12,    64,     0,     0,     0,     0,     0,     0,    47,     0,
-    14,    35,     0,     0,     0,    58,     0,     0,    56,     0,
-    54,    38,    40,     0,     0,     0,    50,     0,     0,     0,
-     0,     0,    20,    23,    31,    36,     0,     0,     0,    24,
-    49,    44,    51,    42,     0,     4,     6,    13,     0,     0,
+    69,    69,     0,     0,    95,    88,    89,    90,    91,    99,
+     0,   101,    68,    70,    71,    75,    72,    61,    82,    83,
+    86,     0,     0,    98,   100,    66,     0,    73,    78,    66,
+     0,    44,    93,     0,     0,    10,    67,    76,     1,    57,
+    59,    62,     0,    84,     0,     0,     0,    96,     0,    97,
+    11,     0,    63,     0,    61,     0,     0,    53,    55,    74,
+     0,     0,    37,    43,     0,     0,    94,     5,     3,     2,
+     0,     0,     7,     8,     9,     0,    65,    10,    77,     0,
+     0,     0,     0,    16,    14,    17,    18,    19,    46,    46,
+     0,    15,    48,     0,    60,    10,     0,    87,    39,     0,
+     0,    45,    92,     0,     0,    12,    64,     0,     0,     0,
+     0,     0,     0,    47,     0,    14,    35,     0,     0,     0,
+    58,     0,     0,    56,     0,    54,    79,    80,     0,    38,
+    40,     0,     0,     0,    50,     0,     0,     0,     0,     0,
+    20,    23,    31,    36,     0,     0,     0,    24,    49,    44,
+    51,    85,    81,    42,     0,     4,     6,    13,     0,     0,
      0,     0,    21,     0,    33,     0,    25,    22,    26,     0,
     41,     0,     0,     0,     0,    32,    31,     0,    27,    28,
     29,    30,    34,     0,    52,     0,     0,     0
 };
 
-static const short yydefgoto[] = {    31,
-    63,    41,   117,    79,    80,   145,   126,   127,    51,    52,
-    36,    98,    99,    42,   111,    83,    49,    32,    33,    21,
-    43,    28,    29,    10,    11,    12,    14,    22,    34,     4,
-    19,    44,     5,     6,    24,    25,     7,    15,     8,   166
+static const short yydefgoto[] = {    40,
+    76,    52,   135,    92,    93,   165,   144,   145,    64,    65,
+    47,   113,   114,    53,   126,    96,    60,    41,    42,    28,
+    54,    37,    38,    14,    15,    16,    18,    29,    43,     6,
+    26,    55,     7,   128,   129,    20,     8,    30,    61,     9,
+    31,    10,    33,    34,    11,    22,    12,   186
 };
 
-static const short yypact[] = {    67,
-   -14,   -14,-32768,-32768,-32768,-32768,    19,    67,-32768,-32768,
--32768,-32768,-32768,    -3,    63,    67,-32768,-32768,    60,    65,
--32768,-32768,     7,-32768,   -11,    -6,    79,-32768,-32768,-32768,
-    71,-32768,     4,   -16,    82,    73,-32768,    63,-32768,-32768,
-    61,-32768,    11,    -3,    -2,    65,-32768,-32768,-32768,     0,
-    72,    98,    -2,-32768,-32768,-32768,-32768,   105,   106,-32768,
--32768,-32768,   111,-32768,    79,-32768,    99,   100,   101,   102,
--32768,   112,-32768,-32768,-32768,    -2,    -2,   117,-32768,    96,
-    23,-32768,    32,-32768,   119,   120,-32768,    96,   121,    61,
-   115,-32768,    -2,    -2,    -2,    -2,    -2,   113,   108,   114,
--32768,    -2,    82,    82,   124,-32768,    -2,   126,-32768,   109,
--32768,-32768,    15,   123,   125,    -2,-32768,    27,    62,    68,
-    74,    25,-32768,-32768,    43,   116,   118,   127,   122,-32768,
-    96,     7,-32768,-32768,   130,-32768,-32768,    96,    -2,    -2,
-    -2,    -2,-32768,   133,-32768,    -2,-32768,-32768,-32768,   129,
--32768,    80,    83,    88,    91,-32768,    43,    -2,-32768,-32768,
--32768,-32768,-32768,    44,-32768,   157,   158,-32768
+static const short yypact[] = {   129,
+     3,     3,    11,    19,-32768,-32768,-32768,-32768,-32768,-32768,
+     2,   129,-32768,-32768,-32768,-32768,-32768,    29,-32768,-32768,
+-32768,    24,   129,-32768,-32768,    43,    31,-32768,-32768,    43,
+    40,    50,-32768,    -6,    -4,    69,-32768,-32768,-32768,    59,
+-32768,    61,    10,-32768,    31,    81,    78,-32768,    24,-32768,
+-32768,    15,-32768,    12,    29,    41,    31,-32768,-32768,-32768,
+    84,    68,     8,    83,    87,    41,-32768,-32768,-32768,-32768,
+   111,   120,-32768,-32768,-32768,   126,-32768,    69,-32768,   114,
+   115,   116,   117,-32768,   127,-32768,-32768,-32768,    41,    41,
+   132,-32768,   113,    27,-32768,    60,   144,-32768,-32768,   135,
+   136,-32768,   113,   137,    15,   131,-32768,    41,    41,    41,
+    41,    41,   130,   123,   133,-32768,    41,    81,    81,   140,
+-32768,    41,   141,-32768,   124,-32768,-32768,-32768,     5,-32768,
+     9,   138,   142,    41,-32768,    67,    73,    79,    85,    45,
+-32768,-32768,    54,   134,   139,   143,   145,-32768,   113,    50,
+-32768,-32768,-32768,-32768,   146,-32768,-32768,   113,    41,    41,
+    41,    41,-32768,   147,-32768,    41,-32768,-32768,-32768,   148,
+-32768,    91,    94,    99,   102,-32768,    54,    41,-32768,-32768,
+-32768,-32768,-32768,    47,-32768,   168,   172,-32768
 };
 
-static const short yypgoto[] = {   -39,
-    69,-32768,-32768,    84,   -53,     3,-32768,-32768,-32768,   -93,
-    29,    86,   -44,   -27,-32768,-32768,-32768,   128,-32768,-32768,
--32768,-32768,-32768,-32768,   162,-32768,-32768,   131,-32768,-32768,
--32768,-32768,-32768,     1,   132,-32768,-32768,-32768,   149,-32768
+static const short yypgoto[] = {   -50,
+    72,-32768,-32768,    82,   -66,     4,-32768,-32768,-32768,   -29,
+    30,    89,   -55,   -44,-32768,-32768,-32768,   -19,-32768,-32768,
+-32768,-32768,   152,-32768,   181,-32768,-32768,   149,-32768,-32768,
+-32768,-32768,   -94,    55,-32768,-32768,-32768,-32768,-32768,-32768,
+-32768,    -7,   150,-32768,-32768,-32768,   162,-32768
 };
 
 
-#define	YYLAST		175
+#define	YYLAST		204
 
 
-static const short yytable[] = {    88,
-    81,    62,    37,     1,     2,     9,     3,    17,    18,   128,
-   129,    47,    67,    68,    69,    70,    71,    72,    84,    73,
-    74,    48,    39,    38,    75,    76,    18,    77,     1,     2,
-    78,     3,    20,   134,    35,    64,    85,    92,    46,   118,
-   119,   120,   121,    40,   108,    65,    16,   106,   125,   143,
-    62,   135,   122,   131,   103,   110,   104,   107,   105,   107,
-   109,   139,   138,    55,    56,    57,    58,    59,    60,    61,
-   103,   103,   104,   104,   105,   105,     1,     2,   144,     3,
-    30,   165,    23,    27,    30,   152,   153,   154,   155,   103,
-    40,   104,   157,   105,    45,   103,   140,   104,    53,   105,
-    50,   103,   141,   104,   164,   105,    86,   103,   142,   104,
-   103,   105,   104,   159,   105,   103,   160,   104,   103,   105,
-   104,   161,   105,   103,   162,   104,    87,   105,    89,    90,
-    91,    93,    94,    95,    96,    97,   101,   112,   113,   114,
-   116,   123,   107,   130,   124,   132,   133,   136,   151,   137,
-   146,   147,   149,   156,   158,   148,   167,   168,   115,   163,
-   150,   102,   100,    13,    26,     0,     0,     0,     0,    54,
-     0,     0,     0,    82,    66
+static const short yytable[] = {   103,
+    94,    75,   127,    24,    25,     1,     2,     3,     4,    48,
+     5,     1,     2,     3,     4,     2,     5,    68,    69,    70,
+    71,    72,    73,    74,    13,    62,    50,    25,    99,   154,
+    49,    23,    19,   107,   127,   152,    39,    95,    77,    58,
+    21,   136,   137,   138,   139,    32,   100,   155,    78,    59,
+   143,   125,    39,   121,    75,   149,   140,    80,    81,    82,
+    83,    84,    85,   122,    86,    87,    27,   158,    36,    88,
+    89,   163,    90,    51,   123,    91,   118,    45,   119,    46,
+   120,   122,    51,   118,    56,   119,   185,   120,   146,   147,
+   124,   164,   172,   173,   174,   175,   118,    57,   119,   177,
+   120,    63,   118,   159,   119,    66,   120,    98,   118,   160,
+   119,   184,   120,    97,   118,   161,   119,   102,   120,   101,
+   118,   162,   119,   118,   120,   119,   179,   120,   118,   180,
+   119,   118,   120,   119,   181,   120,   104,   182,     1,     2,
+     3,     4,   118,     5,   119,   105,   120,   106,   108,   109,
+   110,   111,   112,   116,     2,   130,   131,   132,   134,   122,
+   141,   148,   150,   151,   156,   142,   171,   187,   157,   176,
+   166,   188,   117,   168,   167,   178,   133,   169,   115,   170,
+   183,    44,    17,   153,    35,     0,     0,     0,     0,     0,
+     0,     0,     0,     0,     0,     0,     0,     0,    67,     0,
+     0,     0,     0,    79
 };
 
-static const short yycheck[] = {    53,
-    45,    41,    14,    10,    11,    20,    13,     7,     8,   103,
-   104,    28,    15,    16,    17,    18,    19,    20,    19,    22,
-    23,    38,    29,    35,    27,    28,    26,    30,    10,    11,
-    33,    13,    36,    19,    28,    25,    37,    65,    35,    93,
-    94,    95,    96,    12,    13,    35,    28,    25,   102,    25,
-    90,    37,    97,   107,    28,    83,    30,    35,    32,    35,
-    29,    35,   116,     3,     4,     5,     6,     7,     8,     9,
-    28,    28,    30,    30,    32,    32,    10,    11,    36,    13,
-    20,    38,    20,    24,    20,   139,   140,   141,   142,    28,
-    12,    30,   146,    32,    24,    28,    35,    30,    26,    32,
-    19,    28,    35,    30,   158,    32,    35,    28,    35,    30,
-    28,    32,    30,    34,    32,    28,    34,    30,    28,    32,
-    30,    34,    32,    28,    34,    30,    29,    32,    24,    24,
-    20,    33,    33,    33,    33,    24,    20,    19,    19,    19,
-    26,    29,    35,    20,    31,    20,    38,    25,    19,    25,
-    35,    34,    31,    21,    26,    29,     0,     0,    90,   157,
-   132,    78,    77,     2,    16,    -1,    -1,    -1,    -1,    38,
-    -1,    -1,    -1,    46,    44
+static const short yycheck[] = {    66,
+    56,    52,    97,    11,    12,    10,    11,    12,    13,    16,
+    15,    10,    11,    12,    13,    11,    15,     3,     4,     5,
+     6,     7,     8,     9,    22,    45,    31,    35,    21,    21,
+    37,    30,    22,    78,   129,    31,    22,    57,    27,    30,
+    22,   108,   109,   110,   111,    22,    39,    39,    37,    40,
+   117,    96,    22,    27,   105,   122,   112,    17,    18,    19,
+    20,    21,    22,    37,    24,    25,    38,   134,    26,    29,
+    30,    27,    32,    14,    15,    35,    30,    38,    32,    30,
+    34,    37,    14,    30,    26,    32,    40,    34,   118,   119,
+    31,    38,   159,   160,   161,   162,    30,    37,    32,   166,
+    34,    21,    30,    37,    32,    28,    34,    40,    30,    37,
+    32,   178,    34,    30,    30,    37,    32,    31,    34,    37,
+    30,    37,    32,    30,    34,    32,    36,    34,    30,    36,
+    32,    30,    34,    32,    36,    34,    26,    36,    10,    11,
+    12,    13,    30,    15,    32,    26,    34,    22,    35,    35,
+    35,    35,    26,    22,    11,    21,    21,    21,    28,    37,
+    31,    22,    22,    40,    27,    33,    21,     0,    27,    23,
+    37,     0,    91,    31,    36,    28,   105,    33,    90,   150,
+   177,    30,     2,   129,    23,    -1,    -1,    -1,    -1,    -1,
+    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    49,    -1,
+    -1,    -1,    -1,    55
 };
 /* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
 #line 3 "/usr/share/bison.simple"
@@ -1011,9 +1058,20 @@
   switch (yyn) {
 
 case 1:
-#line 223 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 244 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
-    yyval.Rec = Records.getClass(*yyvsp[0].StrVal);
+    if (CurDefmPrefix) {
+      // If CurDefmPrefix is set, we're parsing a defm, which means that this is
+      // actually the name of a multiclass.
+      MultiClass *MC = MultiClasses[*yyvsp[0].StrVal];
+      if (MC == 0) {
+        err() << "Couldn't find class '" << *yyvsp[0].StrVal << "'!\n";
+        exit(1);
+      }
+      yyval.Rec = &MC->Rec;
+    } else {
+      yyval.Rec = Records.getClass(*yyvsp[0].StrVal);
+    }
     if (yyval.Rec == 0) {
       err() << "Couldn't find class '" << *yyvsp[0].StrVal << "'!\n";
       exit(1);
@@ -1022,71 +1080,71 @@
   ;
     break;}
 case 2:
-#line 234 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 266 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {                       // string type
     yyval.Ty = new StringRecTy();
   ;
     break;}
 case 3:
-#line 236 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 268 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {                           // bit type
     yyval.Ty = new BitRecTy();
   ;
     break;}
 case 4:
-#line 238 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 270 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {           // bits<x> type
     yyval.Ty = new BitsRecTy(yyvsp[-1].IntVal);
   ;
     break;}
 case 5:
-#line 240 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 272 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {                           // int type
     yyval.Ty = new IntRecTy();
   ;
     break;}
 case 6:
-#line 242 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 274 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {          // list<x> type
     yyval.Ty = new ListRecTy(yyvsp[-1].Ty);
   ;
     break;}
 case 7:
-#line 244 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 276 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {                          // code type
     yyval.Ty = new CodeRecTy();
   ;
     break;}
 case 8:
-#line 246 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 278 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {                           // dag type
     yyval.Ty = new DagRecTy();
   ;
     break;}
 case 9:
-#line 248 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 280 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {                       // Record Type
     yyval.Ty = new RecordRecTy(yyvsp[0].Rec);
   ;
     break;}
 case 10:
-#line 252 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 284 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 { yyval.IntVal = 0; ;
     break;}
 case 11:
-#line 252 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 284 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 { yyval.IntVal = 1; ;
     break;}
 case 12:
-#line 254 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 286 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 { yyval.Initializer = 0; ;
     break;}
 case 13:
-#line 254 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 286 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 { yyval.Initializer = yyvsp[0].Initializer; ;
     break;}
 case 14:
-#line 256 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 288 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
   if (const RecordVal *RV = (CurRec ? CurRec->getValue(*yyvsp[0].StrVal) : 0)) {
     yyval.Initializer = new VarInit(*yyvsp[0].StrVal, RV->getType());
@@ -1094,6 +1152,12 @@
     const RecordVal *RV = CurRec->getValue(CurRec->getName()+":"+*yyvsp[0].StrVal);
     assert(RV && "Template arg doesn't exist??");
     yyval.Initializer = new VarInit(CurRec->getName()+":"+*yyvsp[0].StrVal, RV->getType());
+  } else if (CurMultiClass &&
+      CurMultiClass->Rec.isTemplateArg(CurMultiClass->Rec.getName()+"::"+*yyvsp[0].StrVal)) {
+    std::string Name = CurMultiClass->Rec.getName()+"::"+*yyvsp[0].StrVal;
+    const RecordVal *RV = CurMultiClass->Rec.getValue(Name);
+    assert(RV && "Template arg doesn't exist??");
+    yyval.Initializer = new VarInit(Name, RV->getType());
   } else if (Record *D = Records.getDef(*yyvsp[0].StrVal)) {
     yyval.Initializer = new DefInit(D);
   } else {
@@ -1105,39 +1169,39 @@
 ;
     break;}
 case 15:
-#line 273 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 311 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.Initializer = yyvsp[0].Initializer;
   ;
     break;}
 case 16:
-#line 275 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 313 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.Initializer = new IntInit(yyvsp[0].IntVal);
   ;
     break;}
 case 17:
-#line 277 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 315 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.Initializer = new StringInit(*yyvsp[0].StrVal);
     delete yyvsp[0].StrVal;
   ;
     break;}
 case 18:
-#line 280 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 318 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.Initializer = new CodeInit(*yyvsp[0].StrVal);
     delete yyvsp[0].StrVal;
   ;
     break;}
 case 19:
-#line 283 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 321 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.Initializer = new UnsetInit();
   ;
     break;}
 case 20:
-#line 285 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 323 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     BitsInit *Init = new BitsInit(yyvsp[-1].FieldList->size());
     for (unsigned i = 0, e = yyvsp[-1].FieldList->size(); i != e; ++i) {
@@ -1154,7 +1218,7 @@
   ;
     break;}
 case 21:
-#line 298 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 336 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     // This is a CLASS<initvalslist> expression.  This is supposed to synthesize
     // a new anonymous definition, deriving from CLASS<initvalslist> with no
@@ -1186,7 +1250,7 @@
   ;
     break;}
 case 22:
-#line 326 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 364 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.Initializer = yyvsp[-3].Initializer->convertInitializerBitRange(*yyvsp[-1].BitList);
     if (yyval.Initializer == 0) {
@@ -1197,14 +1261,14 @@
   ;
     break;}
 case 23:
-#line 333 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 371 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.Initializer = new ListInit(*yyvsp[-1].FieldList);
     delete yyvsp[-1].FieldList;
   ;
     break;}
 case 24:
-#line 336 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 374 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     if (!yyvsp[-2].Initializer->getFieldType(*yyvsp[0].StrVal)) {
       err() << "Cannot access field '" << *yyvsp[0].StrVal << "' of value '" << *yyvsp[-2].Initializer << "!\n";
@@ -1215,14 +1279,14 @@
   ;
     break;}
 case 25:
-#line 343 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 381 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.Initializer = new DagInit(yyvsp[-2].Initializer, *yyvsp[-1].DagValueList);
     delete yyvsp[-1].DagValueList;
   ;
     break;}
 case 26:
-#line 346 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 384 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     std::reverse(yyvsp[-1].BitList->begin(), yyvsp[-1].BitList->end());
     yyval.Initializer = yyvsp[-3].Initializer->convertInitListSlice(*yyvsp[-1].BitList);
@@ -1234,43 +1298,43 @@
   ;
     break;}
 case 27:
-#line 354 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 392 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.Initializer = (new BinOpInit(BinOpInit::SHL, yyvsp[-3].Initializer, yyvsp[-1].Initializer))->Fold();
   ;
     break;}
 case 28:
-#line 356 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 394 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.Initializer = (new BinOpInit(BinOpInit::SRA, yyvsp[-3].Initializer, yyvsp[-1].Initializer))->Fold();
   ;
     break;}
 case 29:
-#line 358 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 396 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.Initializer = (new BinOpInit(BinOpInit::SRL, yyvsp[-3].Initializer, yyvsp[-1].Initializer))->Fold();
   ;
     break;}
 case 30:
-#line 360 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 398 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.Initializer = (new BinOpInit(BinOpInit::STRCONCAT, yyvsp[-3].Initializer, yyvsp[-1].Initializer))->Fold();
   ;
     break;}
 case 31:
-#line 364 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 402 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.StrVal = new std::string();
   ;
     break;}
 case 32:
-#line 367 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 405 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.StrVal = yyvsp[0].StrVal;
   ;
     break;}
 case 33:
-#line 371 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 409 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.DagValueList = new std::vector<std::pair<Init*, std::string> >();
     yyval.DagValueList->push_back(std::make_pair(yyvsp[-1].Initializer, *yyvsp[0].StrVal));
@@ -1278,7 +1342,7 @@
   ;
     break;}
 case 34:
-#line 376 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 414 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyvsp[-3].DagValueList->push_back(std::make_pair(yyvsp[-1].Initializer, *yyvsp[0].StrVal));
     delete yyvsp[0].StrVal;
@@ -1286,24 +1350,24 @@
   ;
     break;}
 case 35:
-#line 382 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 420 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.DagValueList = new std::vector<std::pair<Init*, std::string> >();
   ;
     break;}
 case 36:
-#line 385 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 423 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 { yyval.DagValueList = yyvsp[0].DagValueList; ;
     break;}
 case 37:
-#line 388 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 426 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.BitList = new std::vector<unsigned>();
     yyval.BitList->push_back(yyvsp[0].IntVal);
   ;
     break;}
 case 38:
-#line 391 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 429 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     if (yyvsp[-2].IntVal < 0 || yyvsp[0].IntVal < 0) {
       err() << "Invalid range: " << yyvsp[-2].IntVal << "-" << yyvsp[0].IntVal << "!\n";
@@ -1320,7 +1384,7 @@
   ;
     break;}
 case 39:
-#line 404 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 442 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyvsp[0].IntVal = -yyvsp[0].IntVal;
     if (yyvsp[-1].IntVal < 0 || yyvsp[0].IntVal < 0) {
@@ -1338,13 +1402,13 @@
   ;
     break;}
 case 40:
-#line 418 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 456 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     (yyval.BitList=yyvsp[-2].BitList)->push_back(yyvsp[0].IntVal);
   ;
     break;}
 case 41:
-#line 420 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 458 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     if (yyvsp[-2].IntVal < 0 || yyvsp[0].IntVal < 0) {
       err() << "Invalid range: " << yyvsp[-2].IntVal << "-" << yyvsp[0].IntVal << "!\n";
@@ -1361,7 +1425,7 @@
   ;
     break;}
 case 42:
-#line 433 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 471 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyvsp[0].IntVal = -yyvsp[0].IntVal;
     if (yyvsp[-1].IntVal < 0 || yyvsp[0].IntVal < 0) {
@@ -1379,48 +1443,55 @@
   ;
     break;}
 case 43:
-#line 449 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 487 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 { yyval.BitList = yyvsp[0].BitList; std::reverse(yyvsp[0].BitList->begin(), yyvsp[0].BitList->end()); ;
     break;}
 case 44:
-#line 451 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 489 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 { yyval.BitList = 0; ;
     break;}
 case 45:
-#line 451 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 489 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 { yyval.BitList = yyvsp[-1].BitList; ;
     break;}
 case 46:
-#line 455 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 493 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.FieldList = new std::vector<Init*>();
   ;
     break;}
 case 47:
-#line 457 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 495 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.FieldList = yyvsp[0].FieldList;
   ;
     break;}
 case 48:
-#line 461 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 499 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.FieldList = new std::vector<Init*>();
     yyval.FieldList->push_back(yyvsp[0].Initializer);
   ;
     break;}
 case 49:
-#line 464 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 502 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     (yyval.FieldList = yyvsp[-2].FieldList)->push_back(yyvsp[0].Initializer);
   ;
     break;}
 case 50:
-#line 468 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 506 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
   std::string DecName = *yyvsp[-1].StrVal;
-  if (ParsingTemplateArgs)
-    DecName = CurRec->getName() + ":" + DecName;
+  if (ParsingTemplateArgs) {
+    if (CurRec) {
+      DecName = CurRec->getName() + ":" + DecName;
+    } else {
+      assert(CurMultiClass);
+    }
+    if (CurMultiClass)
+      DecName = CurMultiClass->Rec.getName() + "::" + DecName;
+  }
 
   addValue(RecordVal(DecName, yyvsp[-2].Ty, yyvsp[-3].IntVal));
   setValue(DecName, 0, yyvsp[0].Initializer);
@@ -1428,13 +1499,13 @@
 ;
     break;}
 case 51:
-#line 478 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 523 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
   delete yyvsp[-1].StrVal;
 ;
     break;}
 case 52:
-#line 480 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 525 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
   setValue(*yyvsp[-4].StrVal, yyvsp[-3].BitList, yyvsp[-1].Initializer);
   delete yyvsp[-4].StrVal;
@@ -1442,19 +1513,19 @@
 ;
     break;}
 case 57:
-#line 489 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 534 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.SubClassRef = new SubClassRefTy(yyvsp[0].Rec, new std::vector<Init*>());
   ;
     break;}
 case 58:
-#line 491 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 536 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.SubClassRef = new SubClassRefTy(yyvsp[-3].Rec, yyvsp[-1].FieldList);
   ;
     break;}
 case 59:
-#line 495 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 540 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.SubClassList = new std::vector<SubClassRefTy>();
     yyval.SubClassList->push_back(*yyvsp[0].SubClassRef);
@@ -1462,52 +1533,52 @@
   ;
     break;}
 case 60:
-#line 500 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 545 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     (yyval.SubClassList=yyvsp[-2].SubClassList)->push_back(*yyvsp[0].SubClassRef);
     delete yyvsp[0].SubClassRef;
   ;
     break;}
 case 61:
-#line 505 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 550 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.SubClassList = new std::vector<SubClassRefTy>();
   ;
     break;}
 case 62:
-#line 508 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 553 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     yyval.SubClassList = yyvsp[0].SubClassList;
   ;
     break;}
 case 63:
-#line 512 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 557 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
-  CurRec->addTemplateArg(*yyvsp[0].StrVal);
+  getActiveRec()->addTemplateArg(*yyvsp[0].StrVal);
   delete yyvsp[0].StrVal;
 ;
     break;}
 case 64:
-#line 515 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 560 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
-  CurRec->addTemplateArg(*yyvsp[0].StrVal);
+  getActiveRec()->addTemplateArg(*yyvsp[0].StrVal);
   delete yyvsp[0].StrVal;
 ;
     break;}
 case 65:
-#line 520 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 565 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {;
     break;}
 case 68:
-#line 523 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 568 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 { yyval.StrVal = yyvsp[0].StrVal; ;
     break;}
 case 69:
-#line 523 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 568 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 { yyval.StrVal = new std::string(); ;
     break;}
 case 70:
-#line 525 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 570 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
   static unsigned AnonCounter = 0;
   if (yyvsp[0].StrVal->empty())
@@ -1516,7 +1587,7 @@
 ;
     break;}
 case 71:
-#line 532 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 577 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
   // If a class of this name already exists, it must be a forward ref.
   if ((CurRec = Records.getClass(*yyvsp[0].StrVal))) {
@@ -1536,21 +1607,34 @@
 ;
     break;}
 case 72:
-#line 550 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 595 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
   CurRec = new Record(*yyvsp[0].StrVal);
   delete yyvsp[0].StrVal;
   
-  // Ensure redefinition doesn't happen.
-  if (Records.getDef(CurRec->getName())) {
-    err() << "Def '" << CurRec->getName() << "' already defined!\n";
-    exit(1);
+  if (!CurMultiClass) {
+    // Top-level def definition.
+    
+    // Ensure redefinition doesn't happen.
+    if (Records.getDef(CurRec->getName())) {
+      err() << "def '" << CurRec->getName() << "' already defined!\n";
+      exit(1);
+    }
+    Records.addDef(CurRec);
+  } else {
+    // Otherwise, a def inside a multiclass, add it to the multiclass.
+    for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size(); i != e; ++i)
+      if (CurMultiClass->DefPrototypes[i]->getName() == CurRec->getName()) {
+        err() << "def '" << CurRec->getName()
+              << "' already defined in this multiclass!\n";
+        exit(1);
+      }
+    CurMultiClass->DefPrototypes.push_back(CurRec);
   }
-  Records.addDef(CurRec);
 ;
     break;}
 case 73:
-#line 562 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 620 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
            for (unsigned i = 0, e = yyvsp[0].SubClassList->size(); i != e; ++i) {
              addSubClass((*yyvsp[0].SubClassList)[i].first, *(*yyvsp[0].SubClassList)[i].second);
@@ -1568,32 +1652,32 @@
          ;
     break;}
 case 74:
-#line 576 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 634 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
            yyval.Rec = CurRec;
            CurRec = 0;
          ;
     break;}
 case 75:
-#line 581 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 639 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
                 ParsingTemplateArgs = true;
             ;
     break;}
 case 76:
-#line 583 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 641 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
                 ParsingTemplateArgs = false;
             ;
     break;}
 case 77:
-#line 585 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 643 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
         yyval.Rec = yyvsp[0].Rec;
      ;
     break;}
 case 78:
-#line 589 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 647 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
   yyvsp[0].Rec->resolveReferences();
 
@@ -1602,39 +1686,168 @@
   yyval.Rec = yyvsp[0].Rec;
 ;
     break;}
+case 79:
+#line 656 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+{
+  yyval.Rec = yyvsp[0].Rec;
+  // Copy the template arguments for the multiclass into the def.
+  const std::vector<std::string> &TArgs = CurMultiClass->Rec.getTemplateArgs();
+  
+  for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
+    const RecordVal *RV = CurMultiClass->Rec.getValue(TArgs[i]);
+    assert(RV && "Template arg doesn't exist?");
+    yyval.Rec->addValue(*RV);
+  }
+;
+    break;}
+case 80:
+#line 670 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+{
+  yyval.RecList = new std::vector<Record*>();
+  yyval.RecList->push_back(yyvsp[0].Rec);
+;
+    break;}
 case 81:
-#line 600 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 673 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+{
+  yyval.RecList->push_back(yyvsp[0].Rec);  
+;
+    break;}
+case 82:
+#line 677 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+{
+  MultiClass *&MCE = MultiClasses[*yyvsp[0].StrVal];
+  if (MCE) {
+    err() << "multiclass '" << *yyvsp[0].StrVal << "' already defined!\n";
+    exit(1);
+  }
+  MCE = CurMultiClass = new MultiClass(*yyvsp[0].StrVal);
+  delete yyvsp[0].StrVal;
+;
+    break;}
+case 83:
+#line 688 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+{
+                                             ParsingTemplateArgs = true;
+                                           ;
+    break;}
+case 84:
+#line 690 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+{
+                                             ParsingTemplateArgs = false;
+                                           ;
+    break;}
+case 85:
+#line 692 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+{
+  CurMultiClass = 0;
+;
+    break;}
+case 86:
+#line 697 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+{ CurDefmPrefix = yyvsp[0].StrVal; ;
+    break;}
+case 87:
+#line 697 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+{
+  // To instantiate a multiclass, we need to first get the multiclass, then
+  // instantiate each def contained in the multiclass with the SubClassRef
+  // template parameters.
+  MultiClass *MC = MultiClasses[yyvsp[-1].SubClassRef->first->getName()];
+  assert(MC && "Didn't lookup multiclass correctly?");
+  std::vector<Init*> &TemplateVals = *yyvsp[-1].SubClassRef->second;
+  delete yyvsp[-1].SubClassRef;
+  
+  // Verify that the correct number of template arguments were specified.
+  const std::vector<std::string> &TArgs = MC->Rec.getTemplateArgs();
+  if (TArgs.size() < TemplateVals.size()) {
+    err() << "ERROR: More template args specified than multiclass expects!\n";
+    exit(1);
+  }
+  
+  // Loop over all the def's in the multiclass, instantiating each one.
+  for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) {
+    Record *DefProto = MC->DefPrototypes[i];
+    
+    // Add the suffix to the defm name to get the new name.
+    assert(CurRec == 0 && "A def is current?");
+    CurRec = new Record(*yyvsp[-4].StrVal + DefProto->getName());
+    
+    addSubClass(DefProto, std::vector<Init*>());
+    
+    // Loop over all of the template arguments, setting them to the specified
+    // value or leaving them as the default if necessary.
+    for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
+      if (i < TemplateVals.size()) { // A value is specified for this temp-arg?
+        // Set it now.
+        setValue(TArgs[i], 0, TemplateVals[i]);
+        
+        // Resolve it next.
+        CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
+        
+        // Now remove it.
+        CurRec->removeValue(TArgs[i]);
+        
+      } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
+        err() << "ERROR: Value not specified for template argument #"
+        << i << " (" << TArgs[i] << ") of multiclassclass '"
+        << MC->Rec.getName() << "'!\n";
+        exit(1);
+      }
+    }
+    
+    // Ensure redefinition doesn't happen.
+    if (Records.getDef(CurRec->getName())) {
+      err() << "def '" << CurRec->getName() << "' already defined, "
+            << "instantiating defm '" << *yyvsp[-4].StrVal << "' with subdef '"
+            << DefProto->getName() << "'!\n";
+      exit(1);
+    }
+    Records.addDef(CurRec);
+    CurRec = 0;
+  }
+  
+  delete &TemplateVals;
+  delete yyvsp[-4].StrVal;
+;
+    break;}
+case 88:
+#line 759 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+{;
+    break;}
+case 89:
+#line 759 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+{;
+    break;}
+case 92:
+#line 762 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
   LetStack.back().push_back(LetRecord(*yyvsp[-3].StrVal, yyvsp[-2].BitList, yyvsp[0].Initializer));
   delete yyvsp[-3].StrVal; delete yyvsp[-2].BitList;
 ;
     break;}
-case 84:
-#line 608 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+case 95:
+#line 770 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 { LetStack.push_back(std::vector<LetRecord>()); ;
     break;}
-case 86:
-#line 611 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+case 97:
+#line 773 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     LetStack.pop_back();
   ;
     break;}
-case 87:
-#line 614 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+case 98:
+#line 776 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {
     LetStack.pop_back();
   ;
     break;}
-case 88:
-#line 618 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+case 99:
+#line 780 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {;
     break;}
-case 89:
-#line 618 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
-{;
-    break;}
-case 90:
-#line 620 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+case 100:
+#line 780 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 {;
     break;}
 }
@@ -1859,7 +2072,7 @@
     }
   return 1;
 }
-#line 622 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
+#line 784 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y"
 
 
 int yyerror(const char *ErrorMsg) {