diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp
new file mode 100644
index 0000000..5d42d34
--- /dev/null
+++ b/utils/TableGen/CodeGenInstruction.cpp
@@ -0,0 +1,280 @@
+//===- CodeGenInstruction.cpp - CodeGen Instruction Class Wrapper ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the CodeGenInstruction class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenInstruction.h"
+#include "Record.h"
+#include "llvm/ADT/StringExtras.h"
+#include <set>
+using namespace llvm;
+
+static void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) {
+  // FIXME: Only supports TIED_TO for now.
+  std::string::size_type pos = CStr.find_first_of('=');
+  assert(pos != std::string::npos && "Unrecognized constraint");
+  std::string Name = CStr.substr(0, pos);
+  
+  // TIED_TO: $src1 = $dst
+  std::string::size_type wpos = Name.find_first_of(" \t");
+  if (wpos == std::string::npos)
+    throw "Illegal format for tied-to constraint: '" + CStr + "'";
+  std::string DestOpName = Name.substr(0, wpos);
+  std::pair<unsigned,unsigned> DestOp = I->ParseOperandName(DestOpName, false);
+  
+  Name = CStr.substr(pos+1);
+  wpos = Name.find_first_not_of(" \t");
+  if (wpos == std::string::npos)
+    throw "Illegal format for tied-to constraint: '" + CStr + "'";
+  
+  std::pair<unsigned,unsigned> SrcOp =
+  I->ParseOperandName(Name.substr(wpos), false);
+  if (SrcOp > DestOp)
+    throw "Illegal tied-to operand constraint '" + CStr + "'";
+  
+  
+  unsigned FlatOpNo = I->getFlattenedOperandNumber(SrcOp);
+  // Build the string for the operand.
+  std::string OpConstraint =
+  "((" + utostr(FlatOpNo) + " << 16) | (1 << TOI::TIED_TO))";
+  
+  
+  if (!I->OperandList[DestOp.first].Constraints[DestOp.second].empty())
+    throw "Operand '" + DestOpName + "' cannot have multiple constraints!";
+  I->OperandList[DestOp.first].Constraints[DestOp.second] = OpConstraint;
+}
+
+static void ParseConstraints(const std::string &CStr, CodeGenInstruction *I) {
+  // Make sure the constraints list for each operand is large enough to hold
+  // constraint info, even if none is present.
+  for (unsigned i = 0, e = I->OperandList.size(); i != e; ++i) 
+    I->OperandList[i].Constraints.resize(I->OperandList[i].MINumOperands);
+  
+  if (CStr.empty()) return;
+  
+  const std::string delims(",");
+  std::string::size_type bidx, eidx;
+  
+  bidx = CStr.find_first_not_of(delims);
+  while (bidx != std::string::npos) {
+    eidx = CStr.find_first_of(delims, bidx);
+    if (eidx == std::string::npos)
+      eidx = CStr.length();
+    
+    ParseConstraint(CStr.substr(bidx, eidx), I);
+    bidx = CStr.find_first_not_of(delims, eidx);
+  }
+}
+
+CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
+  : TheDef(R), AsmString(AsmStr) {
+  Name      = R->getValueAsString("Name");
+  Namespace = R->getValueAsString("Namespace");
+
+  isReturn     = R->getValueAsBit("isReturn");
+  isBranch     = R->getValueAsBit("isBranch");
+  isIndirectBranch = R->getValueAsBit("isIndirectBranch");
+  isBarrier    = R->getValueAsBit("isBarrier");
+  isCall       = R->getValueAsBit("isCall");
+  isLoad       = R->getValueAsBit("isLoad");
+  isStore      = R->getValueAsBit("isStore");
+  isImplicitDef= R->getValueAsBit("isImplicitDef");
+  bool isTwoAddress = R->getValueAsBit("isTwoAddress");
+  isPredicable = R->getValueAsBit("isPredicable");
+  isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
+  isCommutable = R->getValueAsBit("isCommutable");
+  isTerminator = R->getValueAsBit("isTerminator");
+  isReMaterializable = R->getValueAsBit("isReMaterializable");
+  hasDelaySlot = R->getValueAsBit("hasDelaySlot");
+  usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter");
+  hasCtrlDep   = R->getValueAsBit("hasCtrlDep");
+  isNotDuplicable = R->getValueAsBit("isNotDuplicable");
+  mayHaveSideEffects = R->getValueAsBit("mayHaveSideEffects");
+  neverHasSideEffects = R->getValueAsBit("neverHasSideEffects");
+  hasOptionalDef = false;
+  hasVariableNumberOfOperands = false;
+
+  if (mayHaveSideEffects && neverHasSideEffects)
+    throw R->getName() +
+      ": cannot have both 'mayHaveSideEffects' and 'neverHasSideEffects' set!";
+
+  DagInit *DI;
+  try {
+    DI = R->getValueAsDag("OutOperandList");
+  } catch (...) {
+    // Error getting operand list, just ignore it (sparcv9).
+    AsmString.clear();
+    OperandList.clear();
+    return;
+  }
+  NumDefs = DI->getNumArgs();
+
+  DagInit *IDI;
+  try {
+    IDI = R->getValueAsDag("InOperandList");
+  } catch (...) {
+    // Error getting operand list, just ignore it (sparcv9).
+    AsmString.clear();
+    OperandList.clear();
+    return;
+  }
+  DI = (DagInit*)(new BinOpInit(BinOpInit::CONCAT, DI, IDI))->Fold();
+
+  unsigned MIOperandNo = 0;
+  std::set<std::string> OperandNames;
+  for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) {
+    DefInit *Arg = dynamic_cast<DefInit*>(DI->getArg(i));
+    if (!Arg)
+      throw "Illegal operand for the '" + R->getName() + "' instruction!";
+
+    Record *Rec = Arg->getDef();
+    std::string PrintMethod = "printOperand";
+    unsigned NumOps = 1;
+    DagInit *MIOpInfo = 0;
+    if (Rec->isSubClassOf("Operand")) {
+      PrintMethod = Rec->getValueAsString("PrintMethod");
+      MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
+      
+      // Verify that MIOpInfo has an 'ops' root value.
+      if (!dynamic_cast<DefInit*>(MIOpInfo->getOperator()) ||
+          dynamic_cast<DefInit*>(MIOpInfo->getOperator())
+               ->getDef()->getName() != "ops")
+        throw "Bad value for MIOperandInfo in operand '" + Rec->getName() +
+              "'\n";
+
+      // If we have MIOpInfo, then we have #operands equal to number of entries
+      // in MIOperandInfo.
+      if (unsigned NumArgs = MIOpInfo->getNumArgs())
+        NumOps = NumArgs;
+
+      if (Rec->isSubClassOf("PredicateOperand"))
+        isPredicable = true;
+      else if (Rec->isSubClassOf("OptionalDefOperand"))
+        hasOptionalDef = true;
+    } else if (Rec->getName() == "variable_ops") {
+      hasVariableNumberOfOperands = true;
+      continue;
+    } else if (!Rec->isSubClassOf("RegisterClass") && 
+               Rec->getName() != "ptr_rc")
+      throw "Unknown operand class '" + Rec->getName() +
+            "' in instruction '" + R->getName() + "' instruction!";
+
+    // Check that the operand has a name and that it's unique.
+    if (DI->getArgName(i).empty())
+      throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
+        " has no name!";
+    if (!OperandNames.insert(DI->getArgName(i)).second)
+      throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
+        " has the same name as a previous operand!";
+    
+    OperandList.push_back(OperandInfo(Rec, DI->getArgName(i), PrintMethod, 
+                                      MIOperandNo, NumOps, MIOpInfo));
+    MIOperandNo += NumOps;
+  }
+
+  // Parse Constraints.
+  ParseConstraints(R->getValueAsString("Constraints"), this);
+  
+  // For backward compatibility: isTwoAddress means operand 1 is tied to
+  // operand 0.
+  if (isTwoAddress) {
+    if (!OperandList[1].Constraints[0].empty())
+      throw R->getName() + ": cannot use isTwoAddress property: instruction "
+            "already has constraint set!";
+    OperandList[1].Constraints[0] = "((0 << 16) | (1 << TOI::TIED_TO))";
+  }
+  
+  // Any operands with unset constraints get 0 as their constraint.
+  for (unsigned op = 0, e = OperandList.size(); op != e; ++op)
+    for (unsigned j = 0, e = OperandList[op].MINumOperands; j != e; ++j)
+      if (OperandList[op].Constraints[j].empty())
+        OperandList[op].Constraints[j] = "0";
+  
+  // Parse the DisableEncoding field.
+  std::string DisableEncoding = R->getValueAsString("DisableEncoding");
+  while (1) {
+    std::string OpName = getToken(DisableEncoding, " ,\t");
+    if (OpName.empty()) break;
+
+    // Figure out which operand this is.
+    std::pair<unsigned,unsigned> Op = ParseOperandName(OpName, false);
+
+    // Mark the operand as not-to-be encoded.
+    if (Op.second >= OperandList[Op.first].DoNotEncode.size())
+      OperandList[Op.first].DoNotEncode.resize(Op.second+1);
+    OperandList[Op.first].DoNotEncode[Op.second] = true;
+  }
+}
+
+/// getName - Return the contents of the instruction Name field if set,
+/// otherwise return the name of the def.
+std::string CodeGenInstruction::getName() const {
+  if (!Name.empty()) return Name;
+  return TheDef->getName();
+}
+
+
+/// getOperandNamed - Return the index of the operand with the specified
+/// non-empty name.  If the instruction does not have an operand with the
+/// specified name, throw an exception.
+///
+unsigned CodeGenInstruction::getOperandNamed(const std::string &Name) const {
+  assert(!Name.empty() && "Cannot search for operand with no name!");
+  for (unsigned i = 0, e = OperandList.size(); i != e; ++i)
+    if (OperandList[i].Name == Name) return i;
+  throw "Instruction '" + TheDef->getName() +
+        "' does not have an operand named '$" + Name + "'!";
+}
+
+std::pair<unsigned,unsigned> 
+CodeGenInstruction::ParseOperandName(const std::string &Op,
+                                     bool AllowWholeOp) {
+  if (Op.empty() || Op[0] != '$')
+    throw TheDef->getName() + ": Illegal operand name: '" + Op + "'";
+  
+  std::string OpName = Op.substr(1);
+  std::string SubOpName;
+  
+  // Check to see if this is $foo.bar.
+  std::string::size_type DotIdx = OpName.find_first_of(".");
+  if (DotIdx != std::string::npos) {
+    SubOpName = OpName.substr(DotIdx+1);
+    if (SubOpName.empty())
+      throw TheDef->getName() + ": illegal empty suboperand name in '" +Op +"'";
+    OpName = OpName.substr(0, DotIdx);
+  }
+  
+  unsigned OpIdx = getOperandNamed(OpName);
+
+  if (SubOpName.empty()) {  // If no suboperand name was specified:
+    // If one was needed, throw.
+    if (OperandList[OpIdx].MINumOperands > 1 && !AllowWholeOp &&
+        SubOpName.empty())
+      throw TheDef->getName() + ": Illegal to refer to"
+            " whole operand part of complex operand '" + Op + "'";
+  
+    // Otherwise, return the operand.
+    return std::make_pair(OpIdx, 0U);
+  }
+  
+  // Find the suboperand number involved.
+  DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo;
+  if (MIOpInfo == 0)
+    throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'";
+  
+  // Find the operand with the right name.
+  for (unsigned i = 0, e = MIOpInfo->getNumArgs(); i != e; ++i)
+    if (MIOpInfo->getArgName(i) == SubOpName)
+      return std::make_pair(OpIdx, i);
+
+  // Otherwise, didn't find it!
+  throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'";
+}
diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h
index 249c1df..4f776ca 100644
--- a/utils/TableGen/CodeGenInstruction.h
+++ b/utils/TableGen/CodeGenInstruction.h
@@ -32,7 +32,11 @@
     /// AsmString - The format string used to emit a .s file for the
     /// instruction.
     std::string AsmString;
-
+    
+    /// getName - Return the contents of the instruction Name field if set,
+    /// otherwise return the name of the def.
+    std::string getName() const;
+    
     /// OperandInfo - The information we keep track of for each operand in the
     /// operand list for a tablegen instruction.
     struct OperandInfo {
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index 2688914..53dbbf8 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -1,4 +1,4 @@
-//===- CodeGenTarget.cpp - CodeGen Target Class Wrapper ---------*- C++ -*-===//
+//===- CodeGenTarget.cpp - CodeGen Target Class Wrapper -------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This class wrap target description classes used by the various code
+// This class wraps target description classes used by the various code
 // generation TableGen backends.  This makes it easier to access the data and
 // provides a single place that needs to check it for validity.  All of these
 // classes throw exceptions on error conditions.
@@ -20,7 +20,6 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Streams.h"
-#include <set>
 #include <algorithm>
 using namespace llvm;
 
@@ -324,267 +323,6 @@
   return getInstructionSet()->getValueAsBit("isLittleEndianEncoding");
 }
 
-
-
-static void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) {
-  // FIXME: Only supports TIED_TO for now.
-  std::string::size_type pos = CStr.find_first_of('=');
-  assert(pos != std::string::npos && "Unrecognized constraint");
-  std::string Name = CStr.substr(0, pos);
-
-  // TIED_TO: $src1 = $dst
-  std::string::size_type wpos = Name.find_first_of(" \t");
-  if (wpos == std::string::npos)
-    throw "Illegal format for tied-to constraint: '" + CStr + "'";
-  std::string DestOpName = Name.substr(0, wpos);
-  std::pair<unsigned,unsigned> DestOp = I->ParseOperandName(DestOpName, false);
-
-  Name = CStr.substr(pos+1);
-  wpos = Name.find_first_not_of(" \t");
-  if (wpos == std::string::npos)
-    throw "Illegal format for tied-to constraint: '" + CStr + "'";
-    
-  std::pair<unsigned,unsigned> SrcOp =
-    I->ParseOperandName(Name.substr(wpos), false);
-  if (SrcOp > DestOp)
-    throw "Illegal tied-to operand constraint '" + CStr + "'";
-  
-  
-  unsigned FlatOpNo = I->getFlattenedOperandNumber(SrcOp);
-  // Build the string for the operand.
-  std::string OpConstraint =
-    "((" + utostr(FlatOpNo) + " << 16) | (1 << TOI::TIED_TO))";
-
-  
-  if (!I->OperandList[DestOp.first].Constraints[DestOp.second].empty())
-    throw "Operand '" + DestOpName + "' cannot have multiple constraints!";
-  I->OperandList[DestOp.first].Constraints[DestOp.second] = OpConstraint;
-}
-
-static void ParseConstraints(const std::string &CStr, CodeGenInstruction *I) {
-  // Make sure the constraints list for each operand is large enough to hold
-  // constraint info, even if none is present.
-  for (unsigned i = 0, e = I->OperandList.size(); i != e; ++i) 
-    I->OperandList[i].Constraints.resize(I->OperandList[i].MINumOperands);
-  
-  if (CStr.empty()) return;
-  
-  const std::string delims(",");
-  std::string::size_type bidx, eidx;
-
-  bidx = CStr.find_first_not_of(delims);
-  while (bidx != std::string::npos) {
-    eidx = CStr.find_first_of(delims, bidx);
-    if (eidx == std::string::npos)
-      eidx = CStr.length();
-    
-    ParseConstraint(CStr.substr(bidx, eidx), I);
-    bidx = CStr.find_first_not_of(delims, eidx);
-  }
-}
-
-CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
-  : TheDef(R), AsmString(AsmStr) {
-  Name      = R->getValueAsString("Name");
-  Namespace = R->getValueAsString("Namespace");
-
-  isReturn     = R->getValueAsBit("isReturn");
-  isBranch     = R->getValueAsBit("isBranch");
-  isIndirectBranch = R->getValueAsBit("isIndirectBranch");
-  isBarrier    = R->getValueAsBit("isBarrier");
-  isCall       = R->getValueAsBit("isCall");
-  isLoad       = R->getValueAsBit("isLoad");
-  isStore      = R->getValueAsBit("isStore");
-  isImplicitDef= R->getValueAsBit("isImplicitDef");
-  bool isTwoAddress = R->getValueAsBit("isTwoAddress");
-  isPredicable = R->getValueAsBit("isPredicable");
-  isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress");
-  isCommutable = R->getValueAsBit("isCommutable");
-  isTerminator = R->getValueAsBit("isTerminator");
-  isReMaterializable = R->getValueAsBit("isReMaterializable");
-  hasDelaySlot = R->getValueAsBit("hasDelaySlot");
-  usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter");
-  hasCtrlDep   = R->getValueAsBit("hasCtrlDep");
-  isNotDuplicable = R->getValueAsBit("isNotDuplicable");
-  mayHaveSideEffects = R->getValueAsBit("mayHaveSideEffects");
-  neverHasSideEffects = R->getValueAsBit("neverHasSideEffects");
-  hasOptionalDef = false;
-  hasVariableNumberOfOperands = false;
-
-  if (mayHaveSideEffects && neverHasSideEffects)
-    throw R->getName() +
-      ": cannot have both 'mayHaveSideEffects' and 'neverHasSideEffects' set!";
-
-  DagInit *DI;
-  try {
-    DI = R->getValueAsDag("OutOperandList");
-  } catch (...) {
-    // Error getting operand list, just ignore it (sparcv9).
-    AsmString.clear();
-    OperandList.clear();
-    return;
-  }
-  NumDefs = DI->getNumArgs();
-
-  DagInit *IDI;
-  try {
-    IDI = R->getValueAsDag("InOperandList");
-  } catch (...) {
-    // Error getting operand list, just ignore it (sparcv9).
-    AsmString.clear();
-    OperandList.clear();
-    return;
-  }
-  DI = (DagInit*)(new BinOpInit(BinOpInit::CONCAT, DI, IDI))->Fold();
-
-  unsigned MIOperandNo = 0;
-  std::set<std::string> OperandNames;
-  for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) {
-    DefInit *Arg = dynamic_cast<DefInit*>(DI->getArg(i));
-    if (!Arg)
-      throw "Illegal operand for the '" + R->getName() + "' instruction!";
-
-    Record *Rec = Arg->getDef();
-    std::string PrintMethod = "printOperand";
-    unsigned NumOps = 1;
-    DagInit *MIOpInfo = 0;
-    if (Rec->isSubClassOf("Operand")) {
-      PrintMethod = Rec->getValueAsString("PrintMethod");
-      MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
-      
-      // Verify that MIOpInfo has an 'ops' root value.
-      if (!dynamic_cast<DefInit*>(MIOpInfo->getOperator()) ||
-          dynamic_cast<DefInit*>(MIOpInfo->getOperator())
-               ->getDef()->getName() != "ops")
-        throw "Bad value for MIOperandInfo in operand '" + Rec->getName() +
-              "'\n";
-
-      // If we have MIOpInfo, then we have #operands equal to number of entries
-      // in MIOperandInfo.
-      if (unsigned NumArgs = MIOpInfo->getNumArgs())
-        NumOps = NumArgs;
-
-      if (Rec->isSubClassOf("PredicateOperand"))
-        isPredicable = true;
-      else if (Rec->isSubClassOf("OptionalDefOperand"))
-        hasOptionalDef = true;
-    } else if (Rec->getName() == "variable_ops") {
-      hasVariableNumberOfOperands = true;
-      continue;
-    } else if (!Rec->isSubClassOf("RegisterClass") && 
-               Rec->getName() != "ptr_rc")
-      throw "Unknown operand class '" + Rec->getName() +
-            "' in instruction '" + R->getName() + "' instruction!";
-
-    // Check that the operand has a name and that it's unique.
-    if (DI->getArgName(i).empty())
-      throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
-        " has no name!";
-    if (!OperandNames.insert(DI->getArgName(i)).second)
-      throw "In instruction '" + R->getName() + "', operand #" + utostr(i) +
-        " has the same name as a previous operand!";
-    
-    OperandList.push_back(OperandInfo(Rec, DI->getArgName(i), PrintMethod, 
-                                      MIOperandNo, NumOps, MIOpInfo));
-    MIOperandNo += NumOps;
-  }
-
-  // Parse Constraints.
-  ParseConstraints(R->getValueAsString("Constraints"), this);
-  
-  // For backward compatibility: isTwoAddress means operand 1 is tied to
-  // operand 0.
-  if (isTwoAddress) {
-    if (!OperandList[1].Constraints[0].empty())
-      throw R->getName() + ": cannot use isTwoAddress property: instruction "
-            "already has constraint set!";
-    OperandList[1].Constraints[0] = "((0 << 16) | (1 << TOI::TIED_TO))";
-  }
-  
-  // Any operands with unset constraints get 0 as their constraint.
-  for (unsigned op = 0, e = OperandList.size(); op != e; ++op)
-    for (unsigned j = 0, e = OperandList[op].MINumOperands; j != e; ++j)
-      if (OperandList[op].Constraints[j].empty())
-        OperandList[op].Constraints[j] = "0";
-  
-  // Parse the DisableEncoding field.
-  std::string DisableEncoding = R->getValueAsString("DisableEncoding");
-  while (1) {
-    std::string OpName = getToken(DisableEncoding, " ,\t");
-    if (OpName.empty()) break;
-
-    // Figure out which operand this is.
-    std::pair<unsigned,unsigned> Op = ParseOperandName(OpName, false);
-
-    // Mark the operand as not-to-be encoded.
-    if (Op.second >= OperandList[Op.first].DoNotEncode.size())
-      OperandList[Op.first].DoNotEncode.resize(Op.second+1);
-    OperandList[Op.first].DoNotEncode[Op.second] = true;
-  }
-}
-
-
-
-/// getOperandNamed - Return the index of the operand with the specified
-/// non-empty name.  If the instruction does not have an operand with the
-/// specified name, throw an exception.
-///
-unsigned CodeGenInstruction::getOperandNamed(const std::string &Name) const {
-  assert(!Name.empty() && "Cannot search for operand with no name!");
-  for (unsigned i = 0, e = OperandList.size(); i != e; ++i)
-    if (OperandList[i].Name == Name) return i;
-  throw "Instruction '" + TheDef->getName() +
-        "' does not have an operand named '$" + Name + "'!";
-}
-
-std::pair<unsigned,unsigned> 
-CodeGenInstruction::ParseOperandName(const std::string &Op,
-                                     bool AllowWholeOp) {
-  if (Op.empty() || Op[0] != '$')
-    throw TheDef->getName() + ": Illegal operand name: '" + Op + "'";
-  
-  std::string OpName = Op.substr(1);
-  std::string SubOpName;
-  
-  // Check to see if this is $foo.bar.
-  std::string::size_type DotIdx = OpName.find_first_of(".");
-  if (DotIdx != std::string::npos) {
-    SubOpName = OpName.substr(DotIdx+1);
-    if (SubOpName.empty())
-      throw TheDef->getName() + ": illegal empty suboperand name in '" +Op +"'";
-    OpName = OpName.substr(0, DotIdx);
-  }
-  
-  unsigned OpIdx = getOperandNamed(OpName);
-
-  if (SubOpName.empty()) {  // If no suboperand name was specified:
-    // If one was needed, throw.
-    if (OperandList[OpIdx].MINumOperands > 1 && !AllowWholeOp &&
-        SubOpName.empty())
-      throw TheDef->getName() + ": Illegal to refer to"
-            " whole operand part of complex operand '" + Op + "'";
-  
-    // Otherwise, return the operand.
-    return std::make_pair(OpIdx, 0U);
-  }
-  
-  // Find the suboperand number involved.
-  DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo;
-  if (MIOpInfo == 0)
-    throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'";
-  
-  // Find the operand with the right name.
-  for (unsigned i = 0, e = MIOpInfo->getNumArgs(); i != e; ++i)
-    if (MIOpInfo->getArgName(i) == SubOpName)
-      return std::make_pair(OpIdx, i);
-
-  // Otherwise, didn't find it!
-  throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'";
-}
-
-
-
-
 //===----------------------------------------------------------------------===//
 // ComplexPattern implementation
 //
