Make BinOps typed and require a type specifier for !nameconcat. This
[oota-llvm.git] / utils / TableGen / TGParser.cpp
index 6c1640757a14c4a0b491fa3c4c8496c8e3715d1a..c3b17ac603933342d31cce6842ebd98941df17a4 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Chris Lattner and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -23,25 +23,27 @@ using namespace llvm;
 //===----------------------------------------------------------------------===//
 
 namespace llvm {
-struct MultiClass {
-  Record Rec;  // Placeholder for template args and Name.
-  std::vector<Record*> DefPrototypes;
-    
-  MultiClass(const std::string &Name) : Rec(Name) {}
-};
-  
 struct SubClassReference {
-  TGParser::LocTy RefLoc;
+  TGLoc RefLoc;
   Record *Rec;
   std::vector<Init*> TemplateArgs;
-  SubClassReference() : RefLoc(0), Rec(0) {}
+  SubClassReference() : Rec(0) {}
   
   bool isInvalid() const { return Rec == 0; }
 };
+
+struct SubMultiClassReference {
+  TGLoc RefLoc;
+  MultiClass *MC;
+  std::vector<Init*> TemplateArgs;
+  SubMultiClassReference() : MC(0) {}
+  
+  bool isInvalid() const { return MC == 0; }
+};
   
 } // end namespace llvm
 
-bool TGParser::AddValue(Record *CurRec, LocTy Loc, const RecordVal &RV) {
+bool TGParser::AddValue(Record *CurRec, TGLoc Loc, const RecordVal &RV) {
   if (CurRec == 0)
     CurRec = &CurMultiClass->Rec;
   
@@ -60,7 +62,7 @@ bool TGParser::AddValue(Record *CurRec, LocTy Loc, const RecordVal &RV) {
 
 /// SetValue -
 /// Return true on error, false on success.
-bool TGParser::SetValue(Record *CurRec, LocTy Loc, const std::string &ValName, 
+bool TGParser::SetValue(Record *CurRec, TGLoc Loc, const std::string &ValName, 
                         const std::vector<unsigned> &BitList, Init *V) {
   if (!V) return false;
 
@@ -124,7 +126,7 @@ bool TGParser::SetValue(Record *CurRec, LocTy Loc, const std::string &ValName,
 
 /// AddSubClass - Add SubClass as a subclass to CurRec, resolving its template
 /// args as SubClass's template arguments.
-bool TGParser::AddSubClass(Record *CurRec, class SubClassReference &SubClass) {
+bool TGParser::AddSubClass(Record *CurRec, SubClassReference &SubClass) {
   Record *SC = SubClass.Rec;
   // Add all of the values in the subclass into the current class.
   const std::vector<RecordVal> &Vals = SC->getValues();
@@ -177,6 +179,85 @@ bool TGParser::AddSubClass(Record *CurRec, class SubClassReference &SubClass) {
   return false;
 }
 
+/// AddSubMultiClass - Add SubMultiClass as a subclass to
+/// CurMultiClass, resolving its template args as SubMultiClass's
+/// template arguments.
+bool TGParser::AddSubMultiClass(MultiClass *CurMultiClass, class SubMultiClassReference &SubMultiClass) {
+  MultiClass *SMC = SubMultiClass.MC;
+  Record *CurRec = &CurMultiClass->Rec;
+
+  const std::vector<RecordVal> &MCVals = CurMultiClass->Rec.getValues();
+
+  // Add all of the values in the subclass into the current class.
+  const std::vector<RecordVal> &SMCVals = SMC->Rec.getValues();
+  for (unsigned i = 0, e = SMCVals.size(); i != e; ++i)
+    if (AddValue(CurRec, SubMultiClass.RefLoc, SMCVals[i]))
+      return true;
+
+  // Add all of the defs in the subclass into the current multiclass.
+  for (MultiClass::RecordVector::const_iterator i = SMC->DefPrototypes.begin(),
+         iend = SMC->DefPrototypes.end();
+       i != iend;
+       ++i) {
+    // Clone the def and add it to the current multiclass
+    Record *NewDef = new Record(**i);
+
+    // Add all of the values in the superclass into the current def.
+    for (unsigned i = 0, e = MCVals.size(); i != e; ++i)
+      if (AddValue(NewDef, SubMultiClass.RefLoc, MCVals[i]))
+        return true;
+
+    CurMultiClass->DefPrototypes.push_back(NewDef);
+  }
+  
+  const std::vector<std::string> &SMCTArgs = SMC->Rec.getTemplateArgs();
+
+  // Ensure that an appropriate number of template arguments are specified.
+  if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size())
+    return Error(SubMultiClass.RefLoc, "More template args specified than expected");
+  
+  // 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 = SMCTArgs.size(); i != e; ++i) {
+    if (i < SubMultiClass.TemplateArgs.size()) {
+      // If a value is specified for this template arg, set it in the superclass now.
+      if (SetValue(CurRec, SubMultiClass.RefLoc, SMCTArgs[i], std::vector<unsigned>(), 
+                   SubMultiClass.TemplateArgs[i]))
+        return true;
+
+      // Resolve it next.
+      CurRec->resolveReferencesTo(CurRec->getValue(SMCTArgs[i]));
+      
+      // Now remove it.
+      CurRec->removeValue(SMCTArgs[i]);
+
+      // If a value is specified for this template arg, set it in the defs now.
+      for (MultiClass::RecordVector::iterator j = CurMultiClass->DefPrototypes.begin(),
+             jend = CurMultiClass->DefPrototypes.end();
+           j != jend;
+           ++j) {
+        Record *Def = *j;
+
+        if (SetValue(Def, SubMultiClass.RefLoc, SMCTArgs[i], std::vector<unsigned>(), 
+                     SubMultiClass.TemplateArgs[i]))
+          return true;
+
+        // Resolve it next.
+        Def->resolveReferencesTo(Def->getValue(SMCTArgs[i]));
+
+        // Now remove it
+        Def->removeValue(SMCTArgs[i]);
+      }
+    } else if (!CurRec->getValue(SMCTArgs[i])->getValue()->isComplete()) {
+      return Error(SubMultiClass.RefLoc,"Value not specified for template argument #"
+                   + utostr(i) + " (" + SMCTArgs[i] + ") of subclass '" + 
+                   SMC->Rec.getName() + "'!");
+    }
+  }
+
+  return false;
+}
+
 //===----------------------------------------------------------------------===//
 // Parser Code
 //===----------------------------------------------------------------------===//
@@ -223,6 +304,25 @@ Record *TGParser::ParseClassID() {
   return Result;
 }
 
+/// ParseMultiClassID - Parse and resolve a reference to a multiclass name.  This returns
+/// null on error.
+///
+///    MultiClassID ::= ID
+///
+MultiClass *TGParser::ParseMultiClassID() {
+  if (Lex.getCode() != tgtok::Id) {
+    TokError("expected name for ClassID");
+    return 0;
+  }
+  
+  MultiClass *Result = MultiClasses[Lex.getCurStrVal()];
+  if (Result == 0)
+    TokError("Couldn't find class '" + Lex.getCurStrVal() + "'");
+  
+  Lex.Lex();
+  return Result;
+}
+
 Record *TGParser::ParseDefmID() {
   if (Lex.getCode() != tgtok::Id) {
     TokError("expected multiclass name");
@@ -285,14 +385,58 @@ ParseSubClassReference(Record *CurRec, bool isDefm) {
   return Result;
 }
 
+/// ParseSubMultiClassReference - Parse a reference to a subclass or to a templated
+/// submulticlass.  This returns a SubMultiClassRefTy with a null Record* on error.
+///
+///  SubMultiClassRef ::= MultiClassID
+///  SubMultiClassRef ::= MultiClassID '<' ValueList '>'
+///
+SubMultiClassReference TGParser::
+ParseSubMultiClassReference(MultiClass *CurMC) {
+  SubMultiClassReference Result;
+  Result.RefLoc = Lex.getLoc();
+  
+  Result.MC = ParseMultiClassID();
+  if (Result.MC == 0) return Result;
+  
+  // If there is no template arg list, we're done.
+  if (Lex.getCode() != tgtok::less)
+    return Result;
+  Lex.Lex();  // Eat the '<'
+  
+  if (Lex.getCode() == tgtok::greater) {
+    TokError("subclass reference requires a non-empty list of template values");
+    Result.MC = 0;
+    return Result;
+  }
+  
+  Result.TemplateArgs = ParseValueList(&CurMC->Rec);
+  if (Result.TemplateArgs.empty()) {
+    Result.MC = 0;   // Error parsing value list.
+    return Result;
+  }
+    
+  if (Lex.getCode() != tgtok::greater) {
+    TokError("expected '>' in template value list");
+    Result.MC = 0;
+    return Result;
+  }
+  Lex.Lex();
+
+  return Result;
+}
+
 /// ParseRangePiece - Parse a bit/value range.
 ///   RangePiece ::= INTVAL
 ///   RangePiece ::= INTVAL '-' INTVAL
 ///   RangePiece ::= INTVAL INTVAL
 bool TGParser::ParseRangePiece(std::vector<unsigned> &Ranges) {
-  assert(Lex.getCode() == tgtok::IntVal && "Invalid range");
-  int Start = Lex.getCurIntVal();
-  int End;
+  if (Lex.getCode() != tgtok::IntVal) {
+    TokError("expected integer or bitrange");
+    return true;
+  }
+  int64_t Start = Lex.getCurIntVal();
+  int64_t End;
   
   if (Start < 0)
     return TokError("invalid range, cannot be negative");
@@ -354,7 +498,7 @@ bool TGParser::ParseOptionalRangeList(std::vector<unsigned> &Ranges) {
   if (Lex.getCode() != tgtok::less)
     return false;
   
-  LocTy StartLoc = Lex.getLoc();
+  TGLoc StartLoc = Lex.getLoc();
   Lex.Lex(); // eat the '<'
   
   // Parse the range list.
@@ -376,7 +520,7 @@ bool TGParser::ParseOptionalBitList(std::vector<unsigned> &Ranges) {
   if (Lex.getCode() != tgtok::l_brace)
     return false;
   
-  LocTy StartLoc = Lex.getLoc();
+  TGLoc StartLoc = Lex.getLoc();
   Lex.Lex(); // eat the '{'
   
   // Parse the range list.
@@ -423,7 +567,7 @@ RecTy *TGParser::ParseType() {
       TokError("expected integer in bits<n> type");
       return 0;
     }
-    unsigned Val = Lex.getCurIntVal();
+    uint64_t Val = Lex.getCurIntVal();
     if (Lex.Lex() != tgtok::greater) {  // Eat count.
       TokError("expected '>' at end of bits<n> type");
       return 0;
@@ -461,7 +605,7 @@ RecTy *TGParser::ParseType() {
 Init *TGParser::ParseIDValue(Record *CurRec) {
   assert(Lex.getCode() == tgtok::Id && "Expected ID in ParseIDValue");
   std::string Name = Lex.getCurStrVal();
-  LocTy Loc = Lex.getLoc();
+  TGLoc Loc = Lex.getLoc();
   Lex.Lex();
   return ParseIDValue(CurRec, Name, Loc);
 }
@@ -469,7 +613,7 @@ Init *TGParser::ParseIDValue(Record *CurRec) {
 /// ParseIDValue - This is just like ParseIDValue above, but it assumes the ID
 /// has already been read.
 Init *TGParser::ParseIDValue(Record *CurRec, 
-                             const std::string &Name, LocTy NameLoc) {
+                             const std::string &Name, TGLoc NameLoc) {
   if (CurRec) {
     if (const RecordVal *RV = CurRec->getValue(Name))
       return new VarInit(Name, RV->getType());
@@ -502,7 +646,7 @@ Init *TGParser::ParseIDValue(Record *CurRec,
 ///
 ///   SimpleValue ::= IDValue
 ///   SimpleValue ::= INTVAL
-///   SimpleValue ::= STRVAL
+///   SimpleValue ::= STRVAL+
 ///   SimpleValue ::= CODEFRAGMENT
 ///   SimpleValue ::= '?'
 ///   SimpleValue ::= '{' ValueList '}'
@@ -520,12 +664,24 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
   switch (Lex.getCode()) {
   default: TokError("Unknown token when parsing a value"); break;
   case tgtok::IntVal: R = new IntInit(Lex.getCurIntVal()); Lex.Lex(); break;
-  case tgtok::StrVal: R = new StringInit(Lex.getCurStrVal()); Lex.Lex(); break;
+  case tgtok::StrVal: {
+    std::string Val = Lex.getCurStrVal();
+    Lex.Lex();
+    
+    // Handle multiple consecutive concatenated strings.
+    while (Lex.getCode() == tgtok::StrVal) {
+      Val += Lex.getCurStrVal();
+      Lex.Lex();
+    }
+    
+    R = new StringInit(Val);
+    break;
+  }
   case tgtok::CodeFragment:
       R = new CodeInit(Lex.getCurStrVal()); Lex.Lex(); break;
   case tgtok::question: R = new UnsetInit(); Lex.Lex(); break;
   case tgtok::Id: {
-    LocTy NameLoc = Lex.getLoc();
+    TGLoc NameLoc = Lex.getLoc();
     std::string Name = Lex.getCurStrVal();
     if (Lex.Lex() != tgtok::less)  // consume the Id.
       return ParseIDValue(CurRec, Name, NameLoc);    // Value ::= IDValue
@@ -555,7 +711,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
     
     // Create the new record, set it as CurRec temporarily.
     static unsigned AnonCounter = 0;
-    Record *NewRec = new Record("anonymous.val."+utostr(AnonCounter++));
+    Record *NewRec = new Record("anonymous.val."+utostr(AnonCounter++),NameLoc);
     SubClassReference SCRef;
     SCRef.RefLoc = NameLoc;
     SCRef.Rec = Class;
@@ -570,7 +726,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
     return new DefInit(NewRec);
   }    
   case tgtok::l_brace: {           // Value ::= '{' ValueList '}'
-    LocTy BraceLoc = Lex.getLoc();
+    TGLoc BraceLoc = Lex.getLoc();
     Lex.Lex(); // eat the '{'
     std::vector<Init*> Vals;
     
@@ -613,8 +769,77 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
   }
   case tgtok::l_paren: {         // Value ::= '(' IDValue DagArgList ')'
     Lex.Lex();   // eat the '('
-    Init *Operator = ParseIDValue(CurRec);
-    if (Operator == 0) return 0;
+    if (Lex.getCode() != tgtok::Id
+        && Lex.getCode() != tgtok::XNameConcat) {
+      TokError("expected identifier in dag init");
+      return 0;
+    }
+    
+    Init *Operator = 0;
+    if (Lex.getCode() == tgtok::Id) {
+      Operator = ParseIDValue(CurRec);
+      if (Operator == 0) return 0;
+    }
+    else {
+      BinOpInit::BinaryOp Code = BinOpInit::NAMECONCAT;
+      Lex.Lex();  // eat the operation
+
+      if (Lex.getCode() != tgtok::less) {
+        TokError("expected type name for nameconcat");
+        return 0;
+      }
+      Lex.Lex();  // eat the <
+
+      RecTy *Type = ParseType();
+
+      if (Type == 0) {
+        TokError("expected type name for nameconcat");
+        return 0;
+      }
+
+      if (Lex.getCode() != tgtok::greater) {
+        TokError("expected type name for nameconcat");
+        return 0;
+      }
+      Lex.Lex();  // eat the >
+
+      if (Lex.getCode() != tgtok::l_paren) {
+        TokError("expected '(' after binary operator");
+        return 0;
+      }
+      Lex.Lex();  // eat the '('
+
+      Init *LHS = ParseValue(CurRec);
+      if (LHS == 0) return 0;
+
+      if (Lex.getCode() != tgtok::comma) {
+        TokError("expected ',' in binary operator");
+        return 0;
+      }
+      Lex.Lex();  // eat the ','
+
+      Init *RHS = ParseValue(CurRec);
+       if (RHS == 0) return 0;
+
+       if (Lex.getCode() != tgtok::r_paren) {
+         TokError("expected ')' in binary operator");
+         return 0;
+       }
+       Lex.Lex();  // eat the ')'
+       Operator = (new BinOpInit(Code, LHS, RHS, Type))->Fold(CurRec, CurMultiClass);
+    }
+
+    // If the operator name is present, parse it.
+    std::string OperatorName;
+    if (Lex.getCode() == tgtok::colon) {
+      if (Lex.Lex() != tgtok::VarName) { // eat the ':'
+        TokError("expected variable name in dag operator");
+        return 0;
+      }
+      OperatorName = Lex.getCurStrVal();
+      Lex.Lex();  // eat the VarName.
+    }
     
     std::vector<std::pair<llvm::Init*, std::string> > DagArgs;
     if (Lex.getCode() != tgtok::r_paren) {
@@ -628,29 +853,74 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
     }
     Lex.Lex();  // eat the ')'
     
-    return new DagInit(Operator, DagArgs);
+    return new DagInit(Operator, OperatorName, DagArgs);
   }
   case tgtok::XConcat:
   case tgtok::XSRA: 
   case tgtok::XSRL:
   case tgtok::XSHL:
-  case tgtok::XStrConcat: {  // Value ::= !binop '(' Value ',' Value ')'
+  case tgtok::XStrConcat:
+  case tgtok::XNameConcat: {  // Value ::= !binop '(' Value ',' Value ')'
     BinOpInit::BinaryOp Code;
+    RecTy *Type = 0;
+
+
     switch (Lex.getCode()) {
     default: assert(0 && "Unhandled code!");
-    case tgtok::XConcat:    Code = BinOpInit::CONCAT; break;
-    case tgtok::XSRA:       Code = BinOpInit::SRA; break;
-    case tgtok::XSRL:       Code = BinOpInit::SRL; break;
-    case tgtok::XSHL:       Code = BinOpInit::SHL; break;
-    case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break;
+    case tgtok::XConcat:     
+      Lex.Lex();  // eat the operation
+      Code = BinOpInit::CONCAT;
+      Type = new DagRecTy();
+      break;
+    case tgtok::XSRA:        
+      Lex.Lex();  // eat the operation
+      Code = BinOpInit::SRA;
+      Type = new IntRecTy();
+      break;
+    case tgtok::XSRL:        
+      Lex.Lex();  // eat the operation
+      Code = BinOpInit::SRL;
+      Type = new IntRecTy();
+      break;
+    case tgtok::XSHL:        
+      Lex.Lex();  // eat the operation
+      Code = BinOpInit::SHL;
+      Type = new IntRecTy();
+      break;
+    case tgtok::XStrConcat:  
+      Lex.Lex();  // eat the operation
+      Code = BinOpInit::STRCONCAT;
+      Type = new StringRecTy();
+      break;
+    case tgtok::XNameConcat: 
+      Lex.Lex();  // eat the operation
+      Code = BinOpInit::NAMECONCAT;
+      if (Lex.getCode() != tgtok::less) {
+        TokError("expected type name for nameconcat");
+        return 0;
+      }
+      Lex.Lex();  // eat the <
+
+      Type = ParseType();
+
+      if (Type == 0) {
+        TokError("expected type name for nameconcat");
+        return 0;
+      }
+
+      if (Lex.getCode() != tgtok::greater) {
+        TokError("expected type name for nameconcat");
+        return 0;
+      }
+      Lex.Lex();  // eat the >
+      break;
     }
-    Lex.Lex();  // eat the operation
     if (Lex.getCode() != tgtok::l_paren) {
       TokError("expected '(' after binary operator");
       return 0;
     }
     Lex.Lex();  // eat the '('
-    
+
     Init *LHS = ParseValue(CurRec);
     if (LHS == 0) return 0;
 
@@ -668,7 +938,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
       return 0;
     }
     Lex.Lex();  // eat the ')'
-    return (new BinOpInit(Code, LHS, RHS))->Fold();
+    return (new BinOpInit(Code, LHS, RHS, Type))->Fold(CurRec, CurMultiClass);
   }
   }
   
@@ -691,7 +961,7 @@ Init *TGParser::ParseValue(Record *CurRec) {
     switch (Lex.getCode()) {
     default: return Result;
     case tgtok::l_brace: {
-      LocTy CurlyLoc = Lex.getLoc();
+      TGLoc CurlyLoc = Lex.getLoc();
       Lex.Lex(); // eat the '{'
       std::vector<unsigned> Ranges = ParseRangeList();
       if (Ranges.empty()) return 0;
@@ -713,7 +983,7 @@ Init *TGParser::ParseValue(Record *CurRec) {
       break;
     }
     case tgtok::l_square: {
-      LocTy SquareLoc = Lex.getLoc();
+      TGLoc SquareLoc = Lex.getLoc();
       Lex.Lex(); // eat the '['
       std::vector<unsigned> Ranges = ParseRangeList();
       if (Ranges.empty()) return 0;
@@ -829,7 +1099,7 @@ std::string TGParser::ParseDeclaration(Record *CurRec,
     return "";
   }
   
-  LocTy IdLoc = Lex.getLoc();
+  TGLoc IdLoc = Lex.getLoc();
   std::string DeclName = Lex.getCurStrVal();
   Lex.Lex();
   
@@ -850,7 +1120,7 @@ std::string TGParser::ParseDeclaration(Record *CurRec,
   // If a value is present, parse it.
   if (Lex.getCode() == tgtok::equal) {
     Lex.Lex();
-    LocTy ValLoc = Lex.getLoc();
+    TGLoc ValLoc = Lex.getLoc();
     Init *Val = ParseValue(CurRec);
     if (Val == 0 ||
         SetValue(CurRec, ValLoc, DeclName, std::vector<unsigned>(), Val))
@@ -916,7 +1186,7 @@ bool TGParser::ParseBodyItem(Record *CurRec) {
   if (Lex.Lex() != tgtok::Id)
     return TokError("expected field identifier after let");
   
-  LocTy IdLoc = Lex.getLoc();
+  TGLoc IdLoc = Lex.getLoc();
   std::string FieldName = Lex.getCurStrVal();
   Lex.Lex();  // eat the field name.
   
@@ -1014,12 +1284,12 @@ bool TGParser::ParseObjectBody(Record *CurRec) {
 ///   DefInst ::= DEF ObjectName ObjectBody
 ///
 llvm::Record *TGParser::ParseDef(MultiClass *CurMultiClass) {
-  LocTy DefLoc = Lex.getLoc();
+  TGLoc DefLoc = Lex.getLoc();
   assert(Lex.getCode() == tgtok::Def && "Unknown tok");
   Lex.Lex();  // Eat the 'def' token.  
 
   // Parse ObjectName and make a record for it.
-  Record *CurRec = new Record(ParseObjectName());
+  Record *CurRec = new Record(ParseObjectName(), DefLoc);
   
   if (!CurMultiClass) {
     // Top-level def definition.
@@ -1073,7 +1343,7 @@ bool TGParser::ParseClass() {
       return TokError("Class '" + CurRec->getName() + "' already defined");
   } else {
     // If this is the first reference to this class, create and add it.
-    CurRec = new Record(Lex.getCurStrVal());
+    CurRec = new Record(Lex.getCurStrVal(), Lex.getLoc());
     Records.addClass(CurRec);
   }
   Lex.Lex(); // eat the name.
@@ -1102,7 +1372,7 @@ std::vector<LetRecord> TGParser::ParseLetList() {
       return std::vector<LetRecord>();
     }
     std::string Name = Lex.getCurStrVal();
-    LocTy NameLoc = Lex.getLoc();
+    TGLoc NameLoc = Lex.getLoc();
     Lex.Lex();  // Eat the identifier. 
 
     // Check for an optional RangeList.
@@ -1154,7 +1424,7 @@ bool TGParser::ParseTopLevelLet() {
     if (ParseObject())
       return true;
   } else {   // Object ::= LETCommand '{' ObjectList '}'
-    LocTy BraceLoc = Lex.getLoc();
+    TGLoc BraceLoc = Lex.getLoc();
     // Otherwise, this is a group let.
     Lex.Lex();  // eat the '{'.
     
@@ -1199,7 +1469,7 @@ bool TGParser::ParseMultiClassDef(MultiClass *CurMC) {
 
 /// ParseMultiClass - Parse a multiclass definition.
 ///
-///  MultiClassInst ::= MULTICLASS ID TemplateArgList? '{' MultiClassDef+ '}'
+///  MultiClassInst ::= MULTICLASS ID TemplateArgList? ':' BaseMultiClassList '{' MultiClassDef+ '}'
 ///
 bool TGParser::ParseMultiClass() {
   assert(Lex.getCode() == tgtok::MultiClass && "Unexpected token");
@@ -1212,7 +1482,7 @@ bool TGParser::ParseMultiClass() {
   if (MultiClasses.count(Name))
     return TokError("multiclass '" + Name + "' already defined");
   
-  CurMultiClass  = MultiClasses[Name] = new MultiClass(Name);
+  CurMultiClass = MultiClasses[Name] = new MultiClass(Name, Lex.getLoc());
   Lex.Lex();  // Eat the identifier.
   
   // If there are template args, parse them.
@@ -1220,6 +1490,26 @@ bool TGParser::ParseMultiClass() {
     if (ParseTemplateArgList(0))
       return true;
 
+  // If there are submulticlasses, parse them.
+  if (Lex.getCode() == tgtok::colon) {
+    Lex.Lex();
+    
+    // Read all of the submulticlasses.
+    SubMultiClassReference SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
+    while (1) {
+      // Check for error.
+      if (SubMultiClass.MC == 0) return true;
+     
+      // Add it.
+      if (AddSubMultiClass(CurMultiClass, SubMultiClass))
+        return true;
+      
+      if (Lex.getCode() != tgtok::comma) break;
+      Lex.Lex(); // eat ','.
+      SubMultiClass = ParseSubMultiClassReference(CurMultiClass);
+    }
+  }
+
   if (Lex.getCode() != tgtok::l_brace)
     return TokError("expected '{' in multiclass definition");
 
@@ -1245,7 +1535,7 @@ bool TGParser::ParseDefm() {
   if (Lex.Lex() != tgtok::Id)  // eat the defm.
     return TokError("expected identifier after defm");
   
-  LocTy DefmPrefixLoc = Lex.getLoc();
+  TGLoc DefmPrefixLoc = Lex.getLoc();
   std::string DefmPrefix = Lex.getCurStrVal();
   if (Lex.Lex() != tgtok::colon)
     return TokError("expected ':' after defm identifier");
@@ -1253,79 +1543,87 @@ bool TGParser::ParseDefm() {
   // eat the colon.
   Lex.Lex();
 
-  LocTy SubClassLoc = Lex.getLoc();
+  TGLoc SubClassLoc = Lex.getLoc();
   SubClassReference Ref = ParseSubClassReference(0, true);
-  if (Ref.Rec == 0) return true;
-  
-  if (Lex.getCode() != tgtok::semi)
-    return TokError("expected ';' at end of defm");
-  Lex.Lex();
-  
-  // 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[Ref.Rec->getName()];
-  assert(MC && "Didn't lookup multiclass correctly?");
-  std::vector<Init*> &TemplateVals = Ref.TemplateArgs;
-  
-  // Verify that the correct number of template arguments were specified.
-  const std::vector<std::string> &TArgs = MC->Rec.getTemplateArgs();
-  if (TArgs.size() < TemplateVals.size())
-    return Error(SubClassLoc,
-                 "more template args specified than multiclass expects");
-  
-  // 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.
-    Record *CurRec = new Record(DefmPrefix + DefProto->getName());
-    
-    SubClassReference Ref;
-    Ref.RefLoc = DefmPrefixLoc;
-    Ref.Rec = DefProto;
-    AddSubClass(CurRec, Ref);
-    
-    // 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.
-        if (SetValue(CurRec, DefmPrefixLoc, TArgs[i], std::vector<unsigned>(),
-                     TemplateVals[i]))
-          return true;
-        
-        // Resolve it next.
-        CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
-        
-        // Now remove it.
-        CurRec->removeValue(TArgs[i]);
-        
-      } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
-        return Error(SubClassLoc, "value not specified for template argument #"+
-                     utostr(i) + " (" + TArgs[i] + ") of multiclassclass '" +
-                     MC->Rec.getName() + "'");
+
+  while (1) {
+    if (Ref.Rec == 0) return true;
+
+    // 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[Ref.Rec->getName()];
+    assert(MC && "Didn't lookup multiclass correctly?");
+    std::vector<Init*> &TemplateVals = Ref.TemplateArgs;   
+
+    // Verify that the correct number of template arguments were specified.
+    const std::vector<std::string> &TArgs = MC->Rec.getTemplateArgs();
+    if (TArgs.size() < TemplateVals.size())
+      return Error(SubClassLoc,
+                   "more template args specified than multiclass expects");
+
+    // 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.
+      Record *CurRec = new Record(DefmPrefix + DefProto->getName(), DefmPrefixLoc);
+
+      SubClassReference Ref;
+      Ref.RefLoc = DefmPrefixLoc;
+      Ref.Rec = DefProto;
+      AddSubClass(CurRec, Ref);
+
+      // 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.
+          if (SetValue(CurRec, DefmPrefixLoc, TArgs[i], std::vector<unsigned>(),
+                       TemplateVals[i]))
+            return true;
+
+          // Resolve it next.
+          CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i]));
+
+          // Now remove it.
+          CurRec->removeValue(TArgs[i]);
+
+        } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
+          return Error(SubClassLoc, "value not specified for template argument #"+
+                       utostr(i) + " (" + TArgs[i] + ") of multiclassclass '" +
+                       MC->Rec.getName() + "'");
+        }
       }
+
+      // If the mdef is inside a 'let' expression, add to each def.
+      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)) {
+            Error(DefmPrefixLoc, "when instantiating this defm");
+            return true;
+          }
+
+      // Ensure redefinition doesn't happen.
+      if (Records.getDef(CurRec->getName()))
+        return Error(DefmPrefixLoc, "def '" + CurRec->getName() + 
+                     "' already defined, instantiating defm with subdef '" + 
+                     DefProto->getName() + "'");
+      Records.addDef(CurRec);
+      CurRec->resolveReferences();
     }
-    
-    // If the mdef is inside a 'let' expression, add to each def.
-    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)) {
-          Error(DefmPrefixLoc, "when instantiating this defm");
-          return true;
-        }
-    
-    
-    // Ensure redefinition doesn't happen.
-    if (Records.getDef(CurRec->getName()))
-      return Error(DefmPrefixLoc, "def '" + CurRec->getName() + 
-                   "' already defined, instantiating defm with subdef '" + 
-                   DefProto->getName() + "'");
-    Records.addDef(CurRec);
-    CurRec->resolveReferences();
+
+    if (Lex.getCode() != tgtok::comma) break;
+    Lex.Lex(); // eat ','.
+
+    SubClassLoc = Lex.getLoc();
+    Ref = ParseSubClassReference(0, true);
   }
+
+  if (Lex.getCode() != tgtok::semi)
+    return TokError("expected ';' at end of defm");
+  Lex.Lex();
   
   return false;
 }