diff --git a/llvm/Makefile.rules b/llvm/Makefile.rules
index 9dcb5ddd5fea..228fd733e7ed 100644
--- a/llvm/Makefile.rules
+++ b/llvm/Makefile.rules
@@ -1750,6 +1750,11 @@ $(ObjDir)/%GenMCCodeEmitter.inc.tmp: %.td $(ObjDir)/.dir
 	$(Echo) "Building $(<F) MC code emitter with tblgen"
 	$(Verb) $(TableGen) -gen-emitter -mc-emitter -o $(call SYSPATH, $@) $<
 
+$(TARGET:%=$(ObjDir)/%GenMCPseudoLowering.inc.tmp): \
+$(ObjDir)/%GenMCPseudoLowering.inc.tmp: %.td $(ObjDir)/.dir
+	$(Echo) "Building $(<F) MC Pseudo instruction expander with tblgen"
+	$(Verb) $(TableGen) -gen-pseudo-lowering -o $(call SYSPATH, $@) $<
+
 $(TARGET:%=$(ObjDir)/%GenCodeEmitter.inc.tmp): \
 $(ObjDir)/%GenCodeEmitter.inc.tmp: %.td $(ObjDir)/.dir
 	$(Echo) "Building $(<F) code emitter with tblgen"
diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td
index afc6aa65e5be..ebe962bbc424 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -373,6 +373,14 @@ class Instruction {
   ///@}
 }
 
+/// PseudoInstExpansion - Expansion information for a pseudo-instruction.
+/// Which instruction it expands to and how the operands map from the
+/// pseudo.
+class PseudoInstExpansion<dag Result> {
+  dag ResultInst = Result;     // The instruction to generate.
+  bit isPseudo = 1;
+}
+
 /// Predicates - These are extra conditionals which are turned into instruction
 /// selector matching code. Currently each predicate is just a string.
 class Predicate<string cond> {
diff --git a/llvm/utils/TableGen/CMakeLists.txt b/llvm/utils/TableGen/CMakeLists.txt
index 957045e74b78..4d71259a8315 100644
--- a/llvm/utils/TableGen/CMakeLists.txt
+++ b/llvm/utils/TableGen/CMakeLists.txt
@@ -34,6 +34,7 @@ add_llvm_utility(tblgen
   LLVMCConfigurationEmitter.cpp
   NeonEmitter.cpp
   OptParserEmitter.cpp
+  PseudoLoweringEmitter.cpp
   Record.cpp
   RegisterInfoEmitter.cpp
   SetTheory.cpp
diff --git a/llvm/utils/TableGen/PseudoLoweringEmitter.cpp b/llvm/utils/TableGen/PseudoLoweringEmitter.cpp
new file mode 100644
index 000000000000..db33c1f7f686
--- /dev/null
+++ b/llvm/utils/TableGen/PseudoLoweringEmitter.cpp
@@ -0,0 +1,243 @@
+//===- PseudoLoweringEmitter.cpp - PseudoLowering Generator -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "pseudo-lowering"
+#include "Error.h"
+#include "CodeGenInstruction.h"
+#include "PseudoLoweringEmitter.h"
+#include "Record.h"
+#include "llvm/ADT/IndexedMap.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Debug.h"
+#include <vector>
+using namespace llvm;
+
+// FIXME: This pass currently can only expand a pseudo to a single instruction.
+//        The pseudo expansion really should take a list of dags, not just
+//        a single dag, so we can do fancier things.
+
+unsigned PseudoLoweringEmitter::
+addDagOperandMapping(Record *Rec, DagInit *Dag, CodeGenInstruction &Insn,
+                     IndexedMap<OpData> &OperandMap, unsigned BaseIdx) {
+  unsigned OpsAdded = 0;
+  for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) {
+    if (DefInit *DI = dynamic_cast<DefInit*>(Dag->getArg(i))) {
+      // Physical register reference. Explicit check for the special case
+      // "zero_reg" definition.
+      if (DI->getDef()->isSubClassOf("Register") ||
+          DI->getDef()->getName() == "zero_reg") {
+        OperandMap[BaseIdx + i].Kind = OpData::Reg;
+        OperandMap[BaseIdx + i].Data.Reg = DI->getDef();
+        ++OpsAdded;
+        continue;
+      }
+
+      // Normal operands should always have the same type, or we have a
+      // problem.
+      // FIXME: We probably shouldn't ever get a non-zero BaseIdx here.
+      assert(BaseIdx == 0 && "Named subargument in pseudo expansion?!");
+      if (DI->getDef() != Insn.Operands[BaseIdx + i].Rec)
+        throw TGError(Rec->getLoc(),
+                      "Pseudo operand type '" + DI->getDef()->getName() +
+                      "' does not match expansion operand type '" +
+                      Insn.Operands[BaseIdx + i].Rec->getName() + "'");
+      // Source operand maps to destination operand. The Data element
+      // will be filled in later, just set the Kind for now. Do it
+      // for each corresponding MachineInstr operand, not just the first.
+      for (unsigned I = 0, E = Insn.Operands[i].MINumOperands; I != E; ++I)
+        OperandMap[BaseIdx + i + I].Kind = OpData::Operand;
+      OpsAdded += Insn.Operands[i].MINumOperands;
+    } else if (IntInit *II = dynamic_cast<IntInit*>(Dag->getArg(i))) {
+      OperandMap[BaseIdx + i].Kind = OpData::Imm;
+      OperandMap[BaseIdx + i].Data.Imm = II->getValue();
+      ++OpsAdded;
+    } else if (DagInit *SubDag = dynamic_cast<DagInit*>(Dag->getArg(i))) {
+      // Just add the operands recursively. This is almost certainly
+      // a constant value for a complex operand (> 1 MI operand).
+      unsigned NewOps =
+        addDagOperandMapping(Rec, SubDag, Insn, OperandMap, BaseIdx + i);
+      OpsAdded += NewOps;
+      // Since we added more than one, we also need to adjust the base.
+      BaseIdx += NewOps - 1;
+    } else
+      assert(0 && "Unhandled pseudo-expansion argument type!");
+  }
+  return OpsAdded;
+}
+
+void PseudoLoweringEmitter::evaluateExpansion(Record *Rec) {
+  DEBUG(dbgs() << "Pseudo definition: " << Rec->getName() << "\n");
+
+  // Validate that the result pattern has the corrent number and types
+  // of arguments for the instruction it references.
+  DagInit *Dag = Rec->getValueAsDag("ResultInst");
+  assert(Dag && "Missing result instruction in pseudo expansion!");
+  DEBUG(dbgs() << "  Result: " << *Dag << "\n");
+
+  DefInit *OpDef = dynamic_cast<DefInit*>(Dag->getOperator());
+  if (!OpDef)
+    throw TGError(Rec->getLoc(), Rec->getName() +
+                  " has unexpected operator type!");
+  Record *Operator = OpDef->getDef();
+  if (!Operator->isSubClassOf("Instruction"))
+    throw TGError(Rec->getLoc(), "Pseudo result '" + Operator->getName() +
+                                 "' is not an instruction!");
+
+  CodeGenInstruction Insn(Operator);
+
+  if (Insn.isCodeGenOnly || Insn.isPseudo)
+    throw TGError(Rec->getLoc(), "Pseudo result '" + Operator->getName() +
+                                 "' cannot be another pseudo instruction!");
+
+  if (Insn.Operands.size() != Dag->getNumArgs())
+    throw TGError(Rec->getLoc(), "Pseudo result '" + Operator->getName() +
+                                 "' operand count mismatch");
+
+  IndexedMap<OpData> OperandMap;
+  OperandMap.grow(Insn.Operands.size());
+
+  addDagOperandMapping(Rec, Dag, Insn, OperandMap, 0);
+
+  // If there are more operands that weren't in the DAG, they have to
+  // be operands that have default values, or we have an error. Currently,
+  // PredicateOperand and OptionalDefOperand both have default values.
+
+
+  // Validate that each result pattern argument has a matching (by name)
+  // argument in the source instruction, in either the (outs) or (ins) list.
+  // Also check that the type of the arguments match.
+  //
+  // Record the mapping of the source to result arguments for use by
+  // the lowering emitter.
+  CodeGenInstruction SourceInsn(Rec);
+  StringMap<unsigned> SourceOperands;
+  for (unsigned i = 0, e = SourceInsn.Operands.size(); i != e; ++i)
+    SourceOperands[SourceInsn.Operands[i].Name] = i;
+
+  DEBUG(dbgs() << "  Operand mapping:\n");
+  for (unsigned i = 0, e = Insn.Operands.size(); i != e; ++i) {
+    // We've already handled constant values. Just map instruction operands
+    // here.
+    if (OperandMap[Insn.Operands[i].MIOperandNo].Kind != OpData::Operand)
+      continue;
+    StringMap<unsigned>::iterator SourceOp =
+      SourceOperands.find(Dag->getArgName(i));
+    if (SourceOp == SourceOperands.end())
+      throw TGError(Rec->getLoc(),
+                    "Pseudo output operand '" + Dag->getArgName(i) +
+                    "' has no matching source operand.");
+    // Map the source operand to the destination operand index for each
+    // MachineInstr operand.
+    for (unsigned I = 0, E = Insn.Operands[i].MINumOperands; I != E; ++I)
+      OperandMap[Insn.Operands[i].MIOperandNo + I].Data.Operand =
+        SourceOp->getValue();
+
+    DEBUG(dbgs() << "    " << SourceOp->getValue() << " ==> " << i << "\n");
+  }
+
+  Expansions.push_back(PseudoExpansion(SourceInsn, Insn, OperandMap));
+}
+
+void PseudoLoweringEmitter::emitLoweringEmitter(raw_ostream &o) {
+  // Emit file header.
+  EmitSourceFileHeader("Pseudo-instruction MC lowering Source Fragment", o);
+
+  o << "bool " << Target.getName() + "AsmPrinter" << "::\n"
+    << "emitPseudoExpansionLowering(MCStreamer &OutStreamer,\n"
+    << "                            const MachineInstr *MI) {\n"
+    << "  switch (MI->getOpcode()) {\n"
+    << "    default: return false;\n";
+  for (unsigned i = 0, e = Expansions.size(); i != e; ++i) {
+    PseudoExpansion &Expansion = Expansions[i];
+    CodeGenInstruction &Source = Expansion.Source;
+    CodeGenInstruction &Dest = Expansion.Dest;
+    o << "    case " << Source.Namespace << "::"
+      << Source.TheDef->getName() << ": {\n"
+      << "      MCInst TmpInst;\n"
+      << "      MCOperand MCOp;\n"
+      << "      TmpInst.setOpcode(" << Dest.Namespace << "::"
+      << Dest.TheDef->getName() << ");\n";
+
+    // Copy the operands from the source instruction.
+    // FIXME: Instruction operands with defaults values (predicates and cc_out
+    //        in ARM, for example shouldn't need explicit values in the
+    //        expansion DAG.
+    unsigned MIOpNo = 0;
+    for (unsigned OpNo = 0, E = Dest.Operands.size(); OpNo != E;
+         ++OpNo) {
+      o << "      // Operand: " << Dest.Operands[OpNo].Name << "\n";
+      for (unsigned i = 0, e = Dest.Operands[OpNo].MINumOperands;
+           i != e; ++i) {
+        switch (Expansion.OperandMap[MIOpNo + i].Kind) {
+        default:
+          llvm_unreachable("Unknown operand type?!");
+        case OpData::Operand:
+          o << "      lowerOperand(MI->getOperand("
+            << Source.Operands[Expansion.OperandMap[MIOpNo].Data
+                .Operand].MIOperandNo + i
+            << "), MCOp);\n"
+            << "      TmpInst.addOperand(MCOp);\n";
+          break;
+        case OpData::Imm:
+          o << "      TmpInst.addOperand(MCOperand::CreateImm("
+            << Expansion.OperandMap[MIOpNo + i].Data.Imm << "));\n";
+          break;
+        case OpData::Reg: {
+          Record *Reg = Expansion.OperandMap[MIOpNo + i].Data.Reg;
+          o << "      TmpInst.addOperand(MCOperand::CreateReg(";
+          // "zero_reg" is special.
+          if (Reg->getName() == "zero_reg")
+            o << "0";
+          else
+            o << Reg->getValueAsString("Namespace") << "::" << Reg->getName();
+          o << "));\n";
+          break;
+        }
+        }
+      }
+      MIOpNo += Dest.Operands[OpNo].MINumOperands;
+    }
+    if (Dest.Operands.isVariadic) {
+      o << "      // variable_ops\n";
+      o << "      for (unsigned i = " << MIOpNo
+        << ", e = MI->getNumOperands(); i != e; ++i)\n"
+        << "        if (lowerOperand(MI->getOperand(i), MCOp))\n"
+        << "          TmpInst.addOperand(MCOp);\n";
+    }
+    o << "      OutStreamer.EmitInstruction(TmpInst);\n"
+      << "      break;\n"
+      << "    }\n";
+  }
+  o << "  }\n  return true;\n}\n\n";
+}
+
+void PseudoLoweringEmitter::run(raw_ostream &o) {
+  Record *ExpansionClass = Records.getClass("PseudoInstExpansion");
+  Record *InstructionClass = Records.getClass("PseudoInstExpansion");
+  assert(ExpansionClass && "PseudoInstExpansion class definition missing!");
+  assert(InstructionClass && "Instruction class definition missing!");
+
+  std::vector<Record*> Insts;
+  for (std::map<std::string, Record*>::const_iterator I =
+         Records.getDefs().begin(), E = Records.getDefs().end(); I != E; ++I) {
+    if (I->second->isSubClassOf(ExpansionClass) &&
+        I->second->isSubClassOf(InstructionClass))
+      Insts.push_back(I->second);
+  }
+
+  // Process the pseudo expansion definitions, validating them as we do so.
+  for (unsigned i = 0, e = Insts.size(); i != e; ++i)
+    evaluateExpansion(Insts[i]);
+
+  // Generate expansion code to lower the pseudo to an MCInst of the real
+  // instruction.
+  emitLoweringEmitter(o);
+}
+
diff --git a/llvm/utils/TableGen/PseudoLoweringEmitter.h b/llvm/utils/TableGen/PseudoLoweringEmitter.h
new file mode 100644
index 000000000000..2749280e6a9d
--- /dev/null
+++ b/llvm/utils/TableGen/PseudoLoweringEmitter.h
@@ -0,0 +1,65 @@
+//===- PseudoLoweringEmitter.h - PseudoLowering Generator -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef PSEUDOLOWERINGEMITTER_H
+#define PSEUDOLOWERINGEMITTER_H
+
+#include "CodeGenInstruction.h"
+#include "CodeGenTarget.h"
+#include "TableGenBackend.h"
+#include "llvm/ADT/IndexedMap.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+
+class PseudoLoweringEmitter : public TableGenBackend {
+  struct OpData {
+    enum MapKind { Operand, Imm, Reg };
+    MapKind Kind;
+    union {
+      unsigned Operand;   // Operand number mapped to.
+      uint64_t Imm;       // Integer immedate value.
+      Record *Reg;        // Physical register.
+    } Data;
+  };
+  struct PseudoExpansion {
+    CodeGenInstruction Source;  // The source pseudo instruction definition.
+    CodeGenInstruction Dest;    // The destination instruction to lower to.
+    IndexedMap<OpData> OperandMap;
+
+    PseudoExpansion(CodeGenInstruction &s, CodeGenInstruction &d,
+                    IndexedMap<OpData> &m) :
+      Source(s), Dest(d), OperandMap(m) {}
+  };
+
+  RecordKeeper &Records;
+
+  // It's overkill to have an instance of the full CodeGenTarget object,
+  // but it loads everything on demand, not in the constructor, so it's
+  // lightweight in performance, so it works out OK.
+  CodeGenTarget Target;
+
+  SmallVector<PseudoExpansion, 64> Expansions;
+
+  unsigned addDagOperandMapping(Record *Rec, DagInit *Dag,
+                                CodeGenInstruction &Insn,
+                                IndexedMap<OpData> &OperandMap,
+                                unsigned BaseIdx);
+  void evaluateExpansion(Record *Pseudo);
+  void emitLoweringEmitter(raw_ostream &o);
+public:
+  PseudoLoweringEmitter(RecordKeeper &R) : Records(R), Target(R) {}
+
+  /// run - Output the pseudo-lowerings.
+  void run(raw_ostream &o);
+};
+
+} // end llvm namespace
+
+#endif
diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp
index ce16c9ade8ea..e8eacb841d03 100644
--- a/llvm/utils/TableGen/TableGen.cpp
+++ b/llvm/utils/TableGen/TableGen.cpp
@@ -33,6 +33,7 @@
 #include "LLVMCConfigurationEmitter.h"
 #include "NeonEmitter.h"
 #include "OptParserEmitter.h"
+#include "PseudoLoweringEmitter.h"
 #include "Record.h"
 #include "RegisterInfoEmitter.h"
 #include "ARMDecoderEmitter.h"
@@ -59,6 +60,7 @@ enum ActionType {
   GenAsmMatcher,
   GenARMDecoder,
   GenDisassembler,
+  GenPseudoLowering,
   GenCallingConv,
   GenClangAttrClasses,
   GenClangAttrImpl,
@@ -106,6 +108,8 @@ namespace {
                                "Generate decoders for ARM/Thumb"),
                     clEnumValN(GenDisassembler, "gen-disassembler",
                                "Generate disassembler"),
+                    clEnumValN(GenPseudoLowering, "gen-pseudo-lowering",
+                               "Generate pseudo instruction lowering"),
                     clEnumValN(GenAsmMatcher, "gen-asm-matcher",
                                "Generate assembly instruction matcher"),
                     clEnumValN(GenDAGISel, "gen-dag-isel",
@@ -314,6 +318,9 @@ int main(int argc, char **argv) {
     case GenDisassembler:
       DisassemblerEmitter(Records).run(Out.os());
       break;
+    case GenPseudoLowering:
+      PseudoLoweringEmitter(Records).run(Out.os());
+      break;
     case GenOptParserDefs:
       OptParserEmitter(Records, true).run(Out.os());
       break;