diff --git a/lib/Target/PowerPC/Makefile b/lib/Target/PowerPC/Makefile
index 8975398..0a6463f 100644
--- a/lib/Target/PowerPC/Makefile
+++ b/lib/Target/PowerPC/Makefile
@@ -8,12 +8,11 @@
 ##===----------------------------------------------------------------------===##
 LEVEL = ../../..
 LIBRARYNAME = LLVMPowerPC
-TARGET = PowerPC PPC32 PPC64
+TARGET = PowerPC PPC32
 
 # Make sure that tblgen is run, first thing.
 BUILT_SOURCES = PowerPCGenInstrNames.inc PowerPCGenRegisterNames.inc \
                 PowerPCGenAsmWriter.inc  PPC32GenCodeEmitter.inc \
- PPC32GenRegisterInfo.h.inc PPC32GenRegisterInfo.inc PPC32GenInstrInfo.inc \
- PPC64GenRegisterInfo.h.inc PPC64GenRegisterInfo.inc PPC64GenInstrInfo.inc
+ PPC32GenRegisterInfo.h.inc PPC32GenRegisterInfo.inc PPC32GenInstrInfo.inc
 
 include $(LEVEL)/Makefile.common
diff --git a/lib/Target/PowerPC/PPC64CodeEmitter.cpp b/lib/Target/PowerPC/PPC64CodeEmitter.cpp
deleted file mode 100644
index 6c43804..0000000
--- a/lib/Target/PowerPC/PPC64CodeEmitter.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-//===-- PPC64CodeEmitter.cpp - JIT Code Emitter for PPC64 -----*- C++ -*-=//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//
-//===----------------------------------------------------------------------===//
-
-#include "PPC64JITInfo.h"
-#include "PPC64TargetMachine.h"
-using namespace llvm;
-
-/// addPassesToEmitMachineCode - Add passes to the specified pass manager to get
-/// machine code emitted.  This uses a MachineCodeEmitter object to handle
-/// actually outputting the machine code and resolving things like the address
-/// of functions.  This method should returns true if machine code emission is
-/// not supported.
-///
-bool PPC64TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM,
-                                                     MachineCodeEmitter &MCE) {
-  return true;
-  // It should go something like this:
-  // PM.add(new Emitter(MCE));  // Machine code emitter pass for PPC64
-  // Delete machine code for this function after emitting it:
-  // PM.add(createMachineCodeDeleter());
-}
-
-void PPC64JITInfo::replaceMachineCodeForFunction (void *Old, void *New) {
-  assert (0 && "PPC64JITInfo::replaceMachineCodeForFunction not implemented");
-}
-
diff --git a/lib/Target/PowerPC/PPC64ISelPattern.cpp b/lib/Target/PowerPC/PPC64ISelPattern.cpp
deleted file mode 100644
index eb4410b..0000000
--- a/lib/Target/PowerPC/PPC64ISelPattern.cpp
+++ /dev/null
@@ -1,1632 +0,0 @@
-//===-- PPC64ISelPattern.cpp - A pattern matching inst selector for PPC64 -===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by Nate Begeman and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a pattern matching instruction selector for 64 bit PowerPC.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PowerPC.h"
-#include "PowerPCInstrBuilder.h"
-#include "PowerPCInstrInfo.h"
-#include "PPC64RegisterInfo.h"
-#include "llvm/Constants.h"                   // FIXME: REMOVE
-#include "llvm/Function.h"
-#include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/CodeGen/SelectionDAGISel.h"
-#include "llvm/CodeGen/SSARegMap.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetLowering.h"
-#include "llvm/Target/TargetOptions.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/ADT/Statistic.h"
-#include <set>
-#include <algorithm>
-using namespace llvm;
-
-//===----------------------------------------------------------------------===//
-//  PPC64TargetLowering - PPC64 Implementation of the TargetLowering interface
-namespace {
-  class PPC64TargetLowering : public TargetLowering {
-    int VarArgsFrameIndex;            // FrameIndex for start of varargs area.
-    int ReturnAddrIndex;              // FrameIndex for return slot.
-  public:
-    PPC64TargetLowering(TargetMachine &TM) : TargetLowering(TM) {
-      // Fold away setcc operations if possible.
-      setSetCCIsExpensive();
-
-      // Set up the register classes.
-      addRegisterClass(MVT::i64, PPC64::GPRCRegisterClass);
-      addRegisterClass(MVT::f32, PPC64::FPRCRegisterClass);
-      addRegisterClass(MVT::f64, PPC64::FPRCRegisterClass);
-
-      // PowerPC has no intrinsics for these particular operations
-      setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
-      setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
-      setOperationAction(ISD::MEMSET, MVT::Other, Expand);
-      setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
-
-      // We don't support sin/cos/sqrt/fmod
-      setOperationAction(ISD::FSIN , MVT::f64, Expand);
-      setOperationAction(ISD::FCOS , MVT::f64, Expand);
-      setOperationAction(ISD::FSQRT, MVT::f64, Expand);
-      setOperationAction(ISD::SREM , MVT::f64, Expand);
-      setOperationAction(ISD::FSIN , MVT::f32, Expand);
-      setOperationAction(ISD::FCOS , MVT::f32, Expand);
-      setOperationAction(ISD::FSQRT, MVT::f32, Expand);
-      setOperationAction(ISD::SREM , MVT::f32, Expand);
-
-      // PPC 64 has i16 and i32 but no i8 (or i1) SEXTLOAD
-      setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand);
-      setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand);
-
-      // PowerPC has no SREM/UREM instructions
-      setOperationAction(ISD::SREM, MVT::i64, Expand);
-      setOperationAction(ISD::UREM, MVT::i64, Expand);
-
-      // PowerPC has these, but they are not implemented
-      setOperationAction(ISD::CTPOP, MVT::i64, Expand);
-      setOperationAction(ISD::CTTZ , MVT::i64, Expand);
-      setOperationAction(ISD::CTLZ , MVT::i64, Expand);
-
-      setShiftAmountFlavor(Extend);   // shl X, 32 == 0
-      addLegalFPImmediate(+0.0); // Necessary for FSEL
-      addLegalFPImmediate(-0.0); //
-
-      computeRegisterProperties();
-    }
-
-    /// LowerArguments - This hook must be implemented to indicate how we should
-    /// lower the arguments for the specified function, into the specified DAG.
-    virtual std::vector<SDOperand>
-    LowerArguments(Function &F, SelectionDAG &DAG);
-
-    /// LowerCallTo - This hook lowers an abstract call to a function into an
-    /// actual call.
-    virtual std::pair<SDOperand, SDOperand>
-    LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, unsigned CC,
-                bool isTailCall, SDOperand Callee, ArgListTy &Args,
-                SelectionDAG &DAG);
-
-    virtual std::pair<SDOperand, SDOperand>
-    LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest);
-
-    virtual std::pair<SDOperand,SDOperand>
-    LowerVAArgNext(SDOperand Chain, SDOperand VAList,
-                   const Type *ArgTy, SelectionDAG &DAG);
-
-    virtual std::pair<SDOperand, SDOperand>
-    LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
-                            SelectionDAG &DAG);
-  };
-}
-
-
-std::vector<SDOperand>
-PPC64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
-  //
-  // add beautiful description of PPC stack frame format, or at least some docs
-  //
-  MachineFunction &MF = DAG.getMachineFunction();
-  MachineFrameInfo *MFI = MF.getFrameInfo();
-  MachineBasicBlock& BB = MF.front();
-  std::vector<SDOperand> ArgValues;
-
-  // Due to the rather complicated nature of the PowerPC ABI, rather than a
-  // fixed size array of physical args, for the sake of simplicity let the STL
-  // handle tracking them for us.
-  std::vector<unsigned> argVR, argPR, argOp;
-  unsigned ArgOffset = 48;
-  unsigned GPR_remaining = 8;
-  unsigned FPR_remaining = 13;
-  unsigned GPR_idx = 0, FPR_idx = 0;
-  static const unsigned GPR[] = {
-    PPC::R3, PPC::R4, PPC::R5, PPC::R6,
-    PPC::R7, PPC::R8, PPC::R9, PPC::R10,
-  };
-  static const unsigned FPR[] = {
-    PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
-    PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
-  };
-
-  // Add DAG nodes to load the arguments...  On entry to a function on PPC,
-  // the arguments start at offset 48, although they are likely to be passed
-  // in registers.
-  for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
-    SDOperand newroot, argt;
-    bool needsLoad = false;
-    MVT::ValueType ObjectVT = getValueType(I->getType());
-
-    switch (ObjectVT) {
-    default: assert(0 && "Unhandled argument type!");
-    case MVT::i1:
-    case MVT::i8:
-    case MVT::i16:
-    case MVT::i32:
-    case MVT::i64:
-      if (GPR_remaining > 0) {
-        BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]);
-        argt = newroot = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32,
-                                            DAG.getRoot());
-        if (ObjectVT != MVT::i64)
-          argt = DAG.getNode(ISD::TRUNCATE, ObjectVT, newroot);
-      } else {
-        needsLoad = true;
-      }
-      break;
-    case MVT::f32:
-    case MVT::f64:
-      if (FPR_remaining > 0) {
-        BuildMI(&BB, PPC::IMPLICIT_DEF, 0, FPR[FPR_idx]);
-        argt = newroot = DAG.getCopyFromReg(FPR[FPR_idx], ObjectVT,
-                                            DAG.getRoot());
-        --FPR_remaining;
-        ++FPR_idx;
-      } else {
-        needsLoad = true;
-      }
-      break;
-    }
-
-    // We need to load the argument to a virtual register if we determined above
-    // that we ran out of physical registers of the appropriate type
-    if (needsLoad) {
-      unsigned SubregOffset = 0;
-      switch (ObjectVT) {
-      default: assert(0 && "Unhandled argument type!");
-      case MVT::i1:
-      case MVT::i8:   SubregOffset = 7; break;
-      case MVT::i16:  SubregOffset = 6; break;
-      case MVT::i32:
-      case MVT::f32:  SubregOffset = 4; break;
-      case MVT::i64:
-      case MVT::f64:  SubregOffset = 0; break;
-      }
-      int FI = MFI->CreateFixedObject(8, ArgOffset);
-      SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64);
-      FIN = DAG.getNode(ISD::ADD, MVT::i64, FIN,
-                        DAG.getConstant(SubregOffset, MVT::i64));
-      argt = newroot = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN,
-                                   DAG.getSrcValue(NULL));
-    }
-
-    // Every 4 bytes of argument space consumes one of the GPRs available for
-    // argument passing.
-    if (GPR_remaining > 0) {
-      --GPR_remaining;
-      ++GPR_idx;
-    }
-    ArgOffset += 8;
-
-    DAG.setRoot(newroot.getValue(1));
-    ArgValues.push_back(argt);
-  }
-
-  // If the function takes variable number of arguments, make a frame index for
-  // the start of the first vararg value... for expansion of llvm.va_start.
-  if (F.isVarArg()) {
-    VarArgsFrameIndex = MFI->CreateFixedObject(8, ArgOffset);
-    SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64);
-    // If this function is vararg, store any remaining integer argument regs
-    // to their spots on the stack so that they may be loaded by deferencing the
-    // result of va_next.
-    std::vector<SDOperand> MemOps;
-    for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) {
-      BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]);
-      SDOperand Val = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i64, DAG.getRoot());
-      SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
-                                    Val, FIN, DAG.getSrcValue(NULL));
-      MemOps.push_back(Store);
-      // Increment the address by eight for the next argument to store
-      SDOperand PtrOff = DAG.getConstant(8, getPointerTy());
-      FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, PtrOff);
-    }
-    DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps));
-  }
-
-  return ArgValues;
-}
-
-std::pair<SDOperand, SDOperand>
-PPC64TargetLowering::LowerCallTo(SDOperand Chain,
-                                 const Type *RetTy, bool isVarArg,
-                                 unsigned CallingConv, bool isTailCall,
-                                 SDOperand Callee, ArgListTy &Args,
-                                 SelectionDAG &DAG) {
-  // args_to_use will accumulate outgoing args for the ISD::CALL case in
-  // SelectExpr to use to put the arguments in the appropriate registers.
-  std::vector<SDOperand> args_to_use;
-
-  // Count how many bytes are to be pushed on the stack, including the linkage
-  // area, and parameter passing area.
-  unsigned NumBytes = 48;
-
-  if (Args.empty()) {
-    Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain,
-                        DAG.getConstant(NumBytes, getPointerTy()));
-  } else {
-    NumBytes = 8 * Args.size(); // All arguments are rounded up to 8 bytes
-
-    // Just to be safe, we'll always reserve the full 48 bytes of linkage area
-    // plus 64 bytes of argument space in case any called code gets funky on us.
-    // (Required by ABI to support var arg)
-    if (NumBytes < 112) NumBytes = 112;
-
-    // Adjust the stack pointer for the new arguments...
-    // These operations are automatically eliminated by the prolog/epilog pass
-    Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain,
-                        DAG.getConstant(NumBytes, getPointerTy()));
-
-    // Set up a copy of the stack pointer for use loading and storing any
-    // arguments that may not fit in the registers available for argument
-    // passing.
-    SDOperand StackPtr = DAG.getCopyFromReg(PPC::R1, MVT::i32,
-                                            DAG.getEntryNode());
-
-    // Figure out which arguments are going to go in registers, and which in
-    // memory.  Also, if this is a vararg function, floating point operations
-    // must be stored to our stack, and loaded into integer regs as well, if
-    // any integer regs are available for argument passing.
-    unsigned ArgOffset = 48;
-    unsigned GPR_remaining = 8;
-    unsigned FPR_remaining = 13;
-
-    std::vector<SDOperand> MemOps;
-    for (unsigned i = 0, e = Args.size(); i != e; ++i) {
-      // PtrOff will be used to store the current argument to the stack if a
-      // register cannot be found for it.
-      SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
-      PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
-      MVT::ValueType ArgVT = getValueType(Args[i].second);
-
-      switch (ArgVT) {
-      default: assert(0 && "Unexpected ValueType for argument!");
-      case MVT::i1:
-      case MVT::i8:
-      case MVT::i16:
-      case MVT::i32:
-        // Promote the integer to 64 bits.  If the input type is signed use a
-        // sign extend, otherwise use a zero extend.
-        if (Args[i].second->isSigned())
-          Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].first);
-        else
-          Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first);
-        // FALL THROUGH
-      case MVT::i64:
-        if (GPR_remaining > 0) {
-          args_to_use.push_back(Args[i].first);
-          --GPR_remaining;
-        } else {
-          MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                          Args[i].first, PtrOff,
-                                       DAG.getSrcValue(NULL)));
-        }
-        ArgOffset += 8;
-        break;
-      case MVT::f32:
-      case MVT::f64:
-        if (FPR_remaining > 0) {
-          args_to_use.push_back(Args[i].first);
-          --FPR_remaining;
-          if (isVarArg) {
-            SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                          Args[i].first, PtrOff,
-                                          DAG.getSrcValue(NULL));
-            MemOps.push_back(Store);
-            // Float varargs are always shadowed in available integer registers
-            if (GPR_remaining > 0) {
-              SDOperand Load = DAG.getLoad(MVT::i64, Store, PtrOff,
-                                           DAG.getSrcValue(NULL));
-              MemOps.push_back(Load);
-              args_to_use.push_back(Load);
-              --GPR_remaining;
-            }
-          } else {
-            // If we have any FPRs remaining, we may also have GPRs remaining.
-            // Args passed in FPRs also consume an available GPR.
-            if (GPR_remaining > 0) {
-              args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i64));
-              --GPR_remaining;
-            }
-          }
-        } else {
-          MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                          Args[i].first, PtrOff,
-                                       DAG.getSrcValue(NULL)));
-        }
-        ArgOffset += 8;
-        break;
-      }
-    }
-    if (!MemOps.empty())
-      Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps);
-  }
-
-  std::vector<MVT::ValueType> RetVals;
-  MVT::ValueType RetTyVT = getValueType(RetTy);
-  if (RetTyVT != MVT::isVoid)
-    RetVals.push_back(RetTyVT);
-  RetVals.push_back(MVT::Other);
-
-  SDOperand TheCall = SDOperand(DAG.getCall(RetVals,
-                                            Chain, Callee, args_to_use), 0);
-  Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
-  Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain,
-                      DAG.getConstant(NumBytes, getPointerTy()));
-  return std::make_pair(TheCall, Chain);
-}
-
-std::pair<SDOperand, SDOperand>
-PPC64TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG, SDOperand Dest) {
-  // vastart just stores the address of the VarArgsFrameIndex slot.
-  SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64);
-  SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, Dest, DAG.getSrcValue(NULL));
-  return std::make_pair(Result, Result);
-}
-
-std::pair<SDOperand,SDOperand> PPC64TargetLowering::
-LowerVAArgNext(SDOperand Chain, SDOperand VAList,
-               const Type *ArgTy, SelectionDAG &DAG) {
-  MVT::ValueType ArgVT = getValueType(ArgTy);
-  SDOperand Result;
-  SDOperand Val = DAG.getLoad(MVT::i64, Chain, VAList, DAG.getSrcValue(NULL));
-  Result = DAG.getLoad(ArgVT, Val.getValue(1), Val, DAG.getSrcValue(NULL));
-  Val = DAG.getNode(ISD::ADD, VAList.getValueType(), Val,
-                    DAG.getConstant(8, VAList.getValueType()));
-  Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                      Val, VAList, DAG.getSrcValue(NULL));
-  return std::make_pair(Result, Chain);
-}
-
-std::pair<SDOperand, SDOperand> PPC64TargetLowering::
-LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
-                        SelectionDAG &DAG) {
-  assert(0 && "LowerFrameReturnAddress unimplemented");
-  abort();
-}
-
-namespace {
-Statistic<>NotLogic("ppc-codegen", "Number of inverted logical ops");
-Statistic<>FusedFP("ppc-codegen", "Number of fused fp operations");
-//===--------------------------------------------------------------------===//
-/// ISel - PPC64 specific code to select PPC64 machine instructions for
-/// SelectionDAG operations.
-//===--------------------------------------------------------------------===//
-class ISel : public SelectionDAGISel {
-
-  /// Comment Here.
-  PPC64TargetLowering PPC64Lowering;
-
-  /// ExprMap - As shared expressions are codegen'd, we keep track of which
-  /// vreg the value is produced in, so we only emit one copy of each compiled
-  /// tree.
-  std::map<SDOperand, unsigned> ExprMap;
-
-  unsigned GlobalBaseReg;
-  bool GlobalBaseInitialized;
-
-public:
-  ISel(TargetMachine &TM) : SelectionDAGISel(PPC64Lowering), PPC64Lowering(TM)
-  {}
-
-  /// runOnFunction - Override this function in order to reset our per-function
-  /// variables.
-  virtual bool runOnFunction(Function &Fn) {
-    // Make sure we re-emit a set of the global base reg if necessary
-    GlobalBaseInitialized = false;
-    return SelectionDAGISel::runOnFunction(Fn);
-  }
-
-  /// InstructionSelectBasicBlock - This callback is invoked by
-  /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
-  virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
-    DEBUG(BB->dump());
-    // Codegen the basic block.
-    Select(DAG.getRoot());
-
-    // Clear state used for selection.
-    ExprMap.clear();
-  }
-
-  unsigned getGlobalBaseReg();
-  unsigned getConstDouble(double floatVal, unsigned Result);
-  unsigned SelectSetCR0(SDOperand CC);
-  unsigned SelectExpr(SDOperand N);
-  unsigned SelectExprFP(SDOperand N, unsigned Result);
-  void Select(SDOperand N);
-
-  bool SelectAddr(SDOperand N, unsigned& Reg, int& offset);
-  void SelectBranchCC(SDOperand N);
-};
-
-/// getImmediateForOpcode - This method returns a value indicating whether
-/// the ConstantSDNode N can be used as an immediate to Opcode.  The return
-/// values are either 0, 1 or 2.  0 indicates that either N is not a
-/// ConstantSDNode, or is not suitable for use by that opcode.  A return value
-/// of 1 indicates that the constant may be used in normal immediate form.  A
-/// return value of 2 indicates that the constant may be used in shifted
-/// immediate form.  A return value of 3 indicates that log base 2 of the
-/// constant may be used.
-///
-static unsigned getImmediateForOpcode(SDOperand N, unsigned Opcode,
-                                      unsigned& Imm, bool U = false) {
-  if (N.getOpcode() != ISD::Constant) return 0;
-
-  int v = (int)cast<ConstantSDNode>(N)->getSignExtended();
-
-  switch(Opcode) {
-  default: return 0;
-  case ISD::ADD:
-    if (isInt16(v))            { Imm = v & 0xFFFF; return 1; }
-    if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; }
-    break;
-  case ISD::AND:
-  case ISD::XOR:
-  case ISD::OR:
-    if (isUInt16(v))           { Imm = v & 0xFFFF; return 1; }
-    if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; }
-    break;
-  case ISD::MUL:
-  case ISD::SUB:
-    if (isInt16(v))            { Imm = v & 0xFFFF; return 1; }
-    break;
-  case ISD::SETCC:
-    if (U && isUInt16(v))      { Imm = v & 0xFFFF; return 1; }
-    if (!U && isInt16(v))      { Imm = v & 0xFFFF; return 1; }
-    break;
-  case ISD::SDIV:
-    if (isPowerOf2_32(v))      { Imm = Log2_32(v); return 3; }
-    break;
-  }
-  return 0;
-}
-
-/// getBCCForSetCC - Returns the PowerPC condition branch mnemonic corresponding
-/// to Condition.  If the Condition is unordered or unsigned, the bool argument
-/// U is set to true, otherwise it is set to false.
-static unsigned getBCCForSetCC(unsigned Condition, bool& U) {
-  U = false;
-  switch (Condition) {
-  default: assert(0 && "Unknown condition!"); abort();
-  case ISD::SETEQ:  return PPC::BEQ;
-  case ISD::SETNE:  return PPC::BNE;
-  case ISD::SETULT: U = true;
-  case ISD::SETLT:  return PPC::BLT;
-  case ISD::SETULE: U = true;
-  case ISD::SETLE:  return PPC::BLE;
-  case ISD::SETUGT: U = true;
-  case ISD::SETGT:  return PPC::BGT;
-  case ISD::SETUGE: U = true;
-  case ISD::SETGE:  return PPC::BGE;
-  }
-  return 0;
-}
-
-/// IndexedOpForOp - Return the indexed variant for each of the PowerPC load
-/// and store immediate instructions.
-static unsigned IndexedOpForOp(unsigned Opcode) {
-  switch(Opcode) {
-  default: assert(0 && "Unknown opcode!"); abort();
-  case PPC::LBZ: return PPC::LBZX;  case PPC::STB: return PPC::STBX;
-  case PPC::LHZ: return PPC::LHZX;  case PPC::STH: return PPC::STHX;
-  case PPC::LHA: return PPC::LHAX;  case PPC::STW: return PPC::STWX;
-  case PPC::LWZ: return PPC::LWZX;  case PPC::STD: return PPC::STDX;
-  case PPC::LD:  return PPC::LDX;   case PPC::STFS: return PPC::STFSX;
-  case PPC::LFS: return PPC::LFSX;  case PPC::STFD: return PPC::STFDX;
-  case PPC::LFD: return PPC::LFDX;
-  }
-  return 0;
-}
-}
-
-/// getGlobalBaseReg - Output the instructions required to put the
-/// base address to use for accessing globals into a register.
-///
-unsigned ISel::getGlobalBaseReg() {
-  if (!GlobalBaseInitialized) {
-    // Insert the set of GlobalBaseReg into the first MBB of the function
-    MachineBasicBlock &FirstMBB = BB->getParent()->front();
-    MachineBasicBlock::iterator MBBI = FirstMBB.begin();
-    GlobalBaseReg = MakeReg(MVT::i64);
-    BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR);
-    BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg).addReg(PPC::LR);
-    GlobalBaseInitialized = true;
-  }
-  return GlobalBaseReg;
-}
-
-/// getConstDouble - Loads a floating point value into a register, via the
-/// Constant Pool.  Optionally takes a register in which to load the value.
-unsigned ISel::getConstDouble(double doubleVal, unsigned Result=0) {
-  unsigned Tmp1 = MakeReg(MVT::i64);
-  if (0 == Result) Result = MakeReg(MVT::f64);
-  MachineConstantPool *CP = BB->getParent()->getConstantPool();
-  ConstantFP *CFP = ConstantFP::get(Type::DoubleTy, doubleVal);
-  unsigned CPI = CP->getConstantPoolIndex(CFP);
-  BuildMI(BB, PPC::ADDIS, 2, Tmp1).addReg(getGlobalBaseReg())
-    .addConstantPoolIndex(CPI);
-  BuildMI(BB, PPC::LFD, 2, Result).addConstantPoolIndex(CPI).addReg(Tmp1);
-  return Result;
-}
-
-unsigned ISel::SelectSetCR0(SDOperand CC) {
-  unsigned Opc, Tmp1, Tmp2;
-  static const unsigned CompareOpcodes[] =
-    { PPC::FCMPU, PPC::FCMPU, PPC::CMPW, PPC::CMPLW };
-
-  // If the first operand to the select is a SETCC node, then we can fold it
-  // into the branch that selects which value to return.
-  if (CC.getOpcode() == ISD::SETCC) {
-    bool U;
-    Opc = getBCCForSetCC(cast<CondCodeSDNode>(CC.getOperand(2))->get(), U);
-    Tmp1 = SelectExpr(CC.getOperand(0));
-
-    // Pass the optional argument U to getImmediateForOpcode for SETCC,
-    // so that it knows whether the SETCC immediate range is signed or not.
-    if (1 == getImmediateForOpcode(CC.getOperand(1), ISD::SETCC,
-                                   Tmp2, U)) {
-      if (U)
-        BuildMI(BB, PPC::CMPLWI, 2, PPC::CR0).addReg(Tmp1).addImm(Tmp2);
-      else
-        BuildMI(BB, PPC::CMPWI, 2, PPC::CR0).addReg(Tmp1).addSImm(Tmp2);
-    } else {
-      bool IsInteger = MVT::isInteger(CC.getOperand(0).getValueType());
-      unsigned CompareOpc = CompareOpcodes[2 * IsInteger + U];
-      Tmp2 = SelectExpr(CC.getOperand(1));
-      BuildMI(BB, CompareOpc, 2, PPC::CR0).addReg(Tmp1).addReg(Tmp2);
-    }
-  } else {
-    Tmp1 = SelectExpr(CC);
-    BuildMI(BB, PPC::CMPLWI, 2, PPC::CR0).addReg(Tmp1).addImm(0);
-    Opc = PPC::BNE;
-  }
-  return Opc;
-}
-
-/// Check to see if the load is a constant offset from a base register
-bool ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset)
-{
-  unsigned imm = 0, opcode = N.getOpcode();
-  if (N.getOpcode() == ISD::ADD) {
-    Reg = SelectExpr(N.getOperand(0));
-    if (1 == getImmediateForOpcode(N.getOperand(1), opcode, imm)) {
-      offset = imm;
-      return false;
-    }
-    offset = SelectExpr(N.getOperand(1));
-    return true;
-  }
-  Reg = SelectExpr(N);
-  offset = 0;
-  return false;
-}
-
-void ISel::SelectBranchCC(SDOperand N)
-{
-  assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???");
-  MachineBasicBlock *Dest =
-    cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
-
-  // Get the MBB we will fall through to so that we can hand it off to the
-  // branch selection pass as an argument to the PPC::COND_BRANCH pseudo op.
-  //ilist<MachineBasicBlock>::iterator It = BB;
-  //MachineBasicBlock *Fallthrough = ++It;
-
-  Select(N.getOperand(0));  //chain
-  unsigned Opc = SelectSetCR0(N.getOperand(1));
-  // FIXME: Use this once we have something approximating two-way branches
-  // We cannot currently use this in case the ISel hands us something like
-  // BRcc MBBx
-  // BR MBBy
-  // since the fallthrough basic block for the conditional branch does not start
-  // with the unconditional branch (it is skipped over).
-  //BuildMI(BB, PPC::COND_BRANCH, 4).addReg(PPC::CR0).addImm(Opc)
-  //  .addMBB(Dest).addMBB(Fallthrough);
-  BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(Dest);
-  return;
-}
-
-unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
-{
-  unsigned Tmp1, Tmp2, Tmp3;
-  unsigned Opc = 0;
-  SDNode *Node = N.Val;
-  MVT::ValueType DestType = N.getValueType();
-  unsigned opcode = N.getOpcode();
-
-  switch (opcode) {
-  default:
-    Node->dump();
-    assert(0 && "Node not handled!\n");
-
-  case ISD::SELECT: {
-    SDNode *Cond = N.getOperand(0).Val;
-    // Attempt to generate FSEL.  We can do this whenever we have an FP result,
-    // and an FP comparison in the SetCC node.
-    if (Cond->getOpcode() == ISD::SETCC &&
-        !MVT::isInteger(N.getOperand(1).getValueType()) &&
-        cast<CondCodeSDNode>(Cond->getOperand(2))->get() != ISD::SETEQ &&
-        cast<CondCodeSDNode>(Cond->getOperand(2))->get() != ISD::SETNE) {
-      MVT::ValueType VT = Cond->getOperand(0).getValueType();
-      ISD::CondCode CC = cast<CondCodeSDNode>(Cond->getOperand(2))->get();
-      Tmp1 = SelectExpr(Cond->getOperand(0));   // Val to compare against
-      unsigned TV = SelectExpr(N.getOperand(1)); // Use if TRUE
-      unsigned FV = SelectExpr(N.getOperand(2)); // Use if FALSE
-
-      ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Cond->getOperand(1));
-      if (CN && (CN->isExactlyValue(-0.0) || CN->isExactlyValue(0.0))) {
-        switch(CC) {
-        default: assert(0 && "Invalid FSEL condition"); abort();
-        case ISD::SETULT:
-        case ISD::SETLT:
-          BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(FV).addReg(TV);
-          return Result;
-        case ISD::SETUGE:
-        case ISD::SETGE:
-          BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(TV).addReg(FV);
-          return Result;
-        case ISD::SETUGT:
-        case ISD::SETGT: {
-          Tmp2 = MakeReg(VT);
-          BuildMI(BB, PPC::FNEG, 1, Tmp2).addReg(Tmp1);
-          BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp2).addReg(FV).addReg(TV);
-          return Result;
-        }
-        case ISD::SETULE:
-        case ISD::SETLE: {
-          Tmp2 = MakeReg(VT);
-          BuildMI(BB, PPC::FNEG, 1, Tmp2).addReg(Tmp1);
-          BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp2).addReg(TV).addReg(FV);
-          return Result;
-        }
-        }
-      } else {
-        Opc = (MVT::f64 == VT) ? PPC::FSUB : PPC::FSUBS;
-        Tmp2 = SelectExpr(Cond->getOperand(1));
-        Tmp3 =  MakeReg(VT);
-        switch(CC) {
-        default: assert(0 && "Invalid FSEL condition"); abort();
-        case ISD::SETULT:
-        case ISD::SETLT:
-          BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
-          BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(FV).addReg(TV);
-          return Result;
-        case ISD::SETUGE:
-        case ISD::SETGE:
-          BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
-          BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(TV).addReg(FV);
-          return Result;
-        case ISD::SETUGT:
-        case ISD::SETGT:
-          BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp2).addReg(Tmp1);
-          BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(FV).addReg(TV);
-          return Result;
-        case ISD::SETULE:
-        case ISD::SETLE:
-          BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp2).addReg(Tmp1);
-          BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(TV).addReg(FV);
-          return Result;
-        }
-      }
-      assert(0 && "Should never get here");
-      return 0;
-    }
-
-    unsigned TrueValue = SelectExpr(N.getOperand(1)); //Use if TRUE
-    unsigned FalseValue = SelectExpr(N.getOperand(2)); //Use if FALSE
-    Opc = SelectSetCR0(N.getOperand(0));
-
-    // Create an iterator with which to insert the MBB for copying the false
-    // value and the MBB to hold the PHI instruction for this SetCC.
-    MachineBasicBlock *thisMBB = BB;
-    const BasicBlock *LLVM_BB = BB->getBasicBlock();
-    ilist<MachineBasicBlock>::iterator It = BB;
-    ++It;
-
-    //  thisMBB:
-    //  ...
-    //   TrueVal = ...
-    //   cmpTY cr0, r1, r2
-    //   bCC copy1MBB
-    //   fallthrough --> copy0MBB
-    MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
-    MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
-    BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(sinkMBB);
-    MachineFunction *F = BB->getParent();
-    F->getBasicBlockList().insert(It, copy0MBB);
-    F->getBasicBlockList().insert(It, sinkMBB);
-    // Update machine-CFG edges
-    BB->addSuccessor(copy0MBB);
-    BB->addSuccessor(sinkMBB);
-
-    //  copy0MBB:
-    //   %FalseValue = ...
-    //   # fallthrough to sinkMBB
-    BB = copy0MBB;
-    // Update machine-CFG edges
-    BB->addSuccessor(sinkMBB);
-
-    //  sinkMBB:
-    //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
-    //  ...
-    BB = sinkMBB;
-    BuildMI(BB, PPC::PHI, 4, Result).addReg(FalseValue)
-      .addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB);
-    return Result;
-  }
-
-  case ISD::FNEG:
-    if (!NoExcessFPPrecision &&
-        ISD::ADD == N.getOperand(0).getOpcode() &&
-        N.getOperand(0).Val->hasOneUse() &&
-        ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() &&
-        N.getOperand(0).getOperand(0).Val->hasOneUse()) {
-      ++FusedFP; // Statistic
-      Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0));
-      Tmp2 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(1));
-      Tmp3 = SelectExpr(N.getOperand(0).getOperand(1));
-      Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS;
-      BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
-    } else if (!NoExcessFPPrecision &&
-        ISD::SUB == N.getOperand(0).getOpcode() &&
-        N.getOperand(0).Val->hasOneUse() &&
-        ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() &&
-        N.getOperand(0).getOperand(0).Val->hasOneUse()) {
-      ++FusedFP; // Statistic
-      Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0));
-      Tmp2 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(1));
-      Tmp3 = SelectExpr(N.getOperand(0).getOperand(1));
-      Opc = DestType == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS;
-      BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
-    } else if (ISD::FABS == N.getOperand(0).getOpcode()) {
-      Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
-      BuildMI(BB, PPC::FNABS, 1, Result).addReg(Tmp1);
-    } else {
-      Tmp1 = SelectExpr(N.getOperand(0));
-      BuildMI(BB, PPC::FNEG, 1, Result).addReg(Tmp1);
-    }
-    return Result;
-
-  case ISD::FABS:
-    Tmp1 = SelectExpr(N.getOperand(0));
-    BuildMI(BB, PPC::FABS, 1, Result).addReg(Tmp1);
-    return Result;
-
-  case ISD::FP_ROUND:
-    assert (DestType == MVT::f32 &&
-            N.getOperand(0).getValueType() == MVT::f64 &&
-            "only f64 to f32 conversion supported here");
-    Tmp1 = SelectExpr(N.getOperand(0));
-    BuildMI(BB, PPC::FRSP, 1, Result).addReg(Tmp1);
-    return Result;
-
-  case ISD::FP_EXTEND:
-    assert (DestType == MVT::f64 &&
-            N.getOperand(0).getValueType() == MVT::f32 &&
-            "only f32 to f64 conversion supported here");
-    Tmp1 = SelectExpr(N.getOperand(0));
-    BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1);
-    return Result;
-
-  case ISD::CopyFromReg:
-    if (Result == 1)
-      Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
-    Tmp1 = dyn_cast<RegSDNode>(Node)->getReg();
-    BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1);
-    return Result;
-
-  case ISD::ConstantFP: {
-    ConstantFPSDNode *CN = cast<ConstantFPSDNode>(N);
-    Result = getConstDouble(CN->getValue(), Result);
-    return Result;
-  }
-
-  case ISD::ADD:
-    if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL &&
-        N.getOperand(0).Val->hasOneUse()) {
-      ++FusedFP; // Statistic
-      Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
-      Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
-      Tmp3 = SelectExpr(N.getOperand(1));
-      Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS;
-      BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
-      return Result;
-    }
-    Opc = DestType == MVT::f64 ? PPC::FADD : PPC::FADDS;
-    Tmp1 = SelectExpr(N.getOperand(0));
-    Tmp2 = SelectExpr(N.getOperand(1));
-    BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
-    return Result;
-
-  case ISD::SUB:
-    if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL &&
-        N.getOperand(0).Val->hasOneUse()) {
-      ++FusedFP; // Statistic
-      Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
-      Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
-      Tmp3 = SelectExpr(N.getOperand(1));
-      Opc = DestType == MVT::f64 ? PPC::FMSUB : PPC::FMSUBS;
-      BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
-      return Result;
-    }
-    Opc = DestType == MVT::f64 ? PPC::FSUB : PPC::FSUBS;
-    Tmp1 = SelectExpr(N.getOperand(0));
-    Tmp2 = SelectExpr(N.getOperand(1));
-    BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
-    return Result;
-
-  case ISD::MUL:
-  case ISD::SDIV:
-    switch( opcode ) {
-    case ISD::MUL:  Opc = DestType == MVT::f64 ? PPC::FMUL : PPC::FMULS; break;
-    case ISD::SDIV: Opc = DestType == MVT::f64 ? PPC::FDIV : PPC::FDIVS; break;
-    };
-    Tmp1 = SelectExpr(N.getOperand(0));
-    Tmp2 = SelectExpr(N.getOperand(1));
-    BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
-    return Result;
-
-  case ISD::UINT_TO_FP:
-  case ISD::SINT_TO_FP: {
-    bool IsUnsigned = (ISD::UINT_TO_FP == opcode);
-    Tmp1 = SelectExpr(N.getOperand(0));  // Get the operand register
-    Tmp2 = MakeReg(MVT::f64); // temp reg to load the integer value into
-    Tmp3 = MakeReg(MVT::i64); // temp reg to hold the conversion constant
-    unsigned ConstF = MakeReg(MVT::f64); // temp reg to hold the fp constant
-
-    int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8);
-    MachineConstantPool *CP = BB->getParent()->getConstantPool();
-
-    // FIXME: pull this FP constant generation stuff out into something like
-    // the simple ISel's getReg.
-    if (IsUnsigned) {
-      addFrameReference(BuildMI(BB, PPC::STD, 3).addReg(Tmp1), FrameIdx);
-      addFrameReference(BuildMI(BB, PPC::LFD, 2, Tmp2), FrameIdx);
-      BuildMI(BB, PPC::FCFID, 1, Result).addReg(Tmp2);
-    } else {
-      ConstantFP *CFP = ConstantFP::get(Type::DoubleTy, 0x1.000008p52);
-      unsigned CPI = CP->getConstantPoolIndex(CFP);
-      // Load constant fp value
-      unsigned Tmp4 = MakeReg(MVT::i32);
-      unsigned TmpL = MakeReg(MVT::i32);
-      BuildMI(BB, PPC::ADDIS, 2, Tmp4).addReg(getGlobalBaseReg())
-        .addConstantPoolIndex(CPI);
-      BuildMI(BB, PPC::LFD, 2, ConstF).addConstantPoolIndex(CPI).addReg(Tmp4);
-      // Store the hi & low halves of the fp value, currently in int regs
-      BuildMI(BB, PPC::LIS, 1, Tmp3).addSImm(0x4330);
-      addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(Tmp3), FrameIdx);
-      BuildMI(BB, PPC::XORIS, 2, TmpL).addReg(Tmp1).addImm(0x8000);
-      addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(TmpL), FrameIdx, 4);
-      addFrameReference(BuildMI(BB, PPC::LFD, 2, Tmp2), FrameIdx);
-      // Generate the return value with a subtract
-      BuildMI(BB, PPC::FSUB, 2, Result).addReg(Tmp2).addReg(ConstF);
-    }
-    return Result;
-  }
-  }
-  assert(0 && "Should never get here");
-  return 0;
-}
-
-unsigned ISel::SelectExpr(SDOperand N) {
-  unsigned Result;
-  unsigned Tmp1, Tmp2, Tmp3;
-  unsigned Opc = 0;
-  unsigned opcode = N.getOpcode();
-
-  SDNode *Node = N.Val;
-  MVT::ValueType DestType = N.getValueType();
-
-  unsigned &Reg = ExprMap[N];
-  if (Reg) return Reg;
-
-  switch (N.getOpcode()) {
-  default:
-    Reg = Result = (N.getValueType() != MVT::Other) ?
-                            MakeReg(N.getValueType()) : 1;
-    break;
-  case ISD::TAILCALL:
-  case ISD::CALL:
-    // If this is a call instruction, make sure to prepare ALL of the result
-    // values as well as the chain.
-    if (Node->getNumValues() == 1)
-      Reg = Result = 1;  // Void call, just a chain.
-    else {
-      Result = MakeReg(Node->getValueType(0));
-      ExprMap[N.getValue(0)] = Result;
-      for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
-        ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
-      ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1;
-    }
-    break;
-  }
-
-  if (ISD::CopyFromReg == opcode)
-    DestType = N.getValue(0).getValueType();
-
-  if (DestType == MVT::f64 || DestType == MVT::f32)
-    if (ISD::LOAD != opcode && ISD::EXTLOAD != opcode && ISD::UNDEF != opcode)
-      return SelectExprFP(N, Result);
-
-  switch (opcode) {
-  default:
-    Node->dump();
-    assert(0 && "Node not handled!\n");
-  case ISD::UNDEF:
-    BuildMI(BB, PPC::IMPLICIT_DEF, 0, Result);
-    return Result;
-  case ISD::DYNAMIC_STACKALLOC:
-    // Generate both result values.  FIXME: Need a better commment here?
-    if (Result != 1)
-      ExprMap[N.getValue(1)] = 1;
-    else
-      Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
-
-    // FIXME: We are currently ignoring the requested alignment for handling
-    // greater than the stack alignment.  This will need to be revisited at some
-    // point.  Align = N.getOperand(2);
-    if (!isa<ConstantSDNode>(N.getOperand(2)) ||
-        cast<ConstantSDNode>(N.getOperand(2))->getValue() != 0) {
-      std::cerr << "Cannot allocate stack object with greater alignment than"
-                << " the stack alignment yet!";
-      abort();
-    }
-    Select(N.getOperand(0));
-    Tmp1 = SelectExpr(N.getOperand(1));
-    // Subtract size from stack pointer, thereby allocating some space.
-    BuildMI(BB, PPC::SUBF, 2, PPC::R1).addReg(Tmp1).addReg(PPC::R1);
-    // Put a pointer to the space into the result register by copying the SP
-    BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R1).addReg(PPC::R1);
-    return Result;
-
-  case ISD::ConstantPool:
-    Tmp1 = cast<ConstantPoolSDNode>(N)->getIndex();
-    Tmp2 = MakeReg(MVT::i64);
-    BuildMI(BB, PPC::ADDIS, 2, Tmp2).addReg(getGlobalBaseReg())
-      .addConstantPoolIndex(Tmp1);
-    BuildMI(BB, PPC::LA, 2, Result).addReg(Tmp2).addConstantPoolIndex(Tmp1);
-    return Result;
-
-  case ISD::FrameIndex:
-    Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
-    addFrameReference(BuildMI(BB, PPC::ADDI, 2, Result), (int)Tmp1, 0, false);
-    return Result;
-
-  case ISD::GlobalAddress: {
-    GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
-    Tmp1 = MakeReg(MVT::i64);
-    BuildMI(BB, PPC::ADDIS, 2, Tmp1).addReg(getGlobalBaseReg())
-      .addGlobalAddress(GV);
-    if (GV->hasWeakLinkage() || GV->isExternal()) {
-      BuildMI(BB, PPC::LD, 2, Result).addGlobalAddress(GV).addReg(Tmp1);
-    } else {
-      BuildMI(BB, PPC::LA, 2, Result).addReg(Tmp1).addGlobalAddress(GV);
-    }
-    return Result;
-  }
-
-  case ISD::LOAD:
-  case ISD::EXTLOAD:
-  case ISD::ZEXTLOAD:
-  case ISD::SEXTLOAD: {
-    MVT::ValueType TypeBeingLoaded = (ISD::LOAD == opcode) ?
-      Node->getValueType(0) : cast<VTSDNode>(Node->getOperand(3))->getVT();
-    bool sext = (ISD::SEXTLOAD == opcode);
-
-    // Make sure we generate both values.
-    if (Result != 1)
-      ExprMap[N.getValue(1)] = 1;   // Generate the token
-    else
-      Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
-
-    SDOperand Chain   = N.getOperand(0);
-    SDOperand Address = N.getOperand(1);
-    Select(Chain);
-
-    switch (TypeBeingLoaded) {
-    default: Node->dump(); assert(0 && "Cannot load this type!");
-    case MVT::i1:  Opc = PPC::LBZ; break;
-    case MVT::i8:  Opc = PPC::LBZ; break;
-    case MVT::i16: Opc = sext ? PPC::LHA : PPC::LHZ; break;
-    case MVT::i32: Opc = sext ? PPC::LWA : PPC::LWZ; break;
-    case MVT::i64: Opc = PPC::LD;  break;
-    case MVT::f32: Opc = PPC::LFS; break;
-    case MVT::f64: Opc = PPC::LFD; break;
-    }
-
-    if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
-      Tmp1 = MakeReg(MVT::i64);
-      int CPI = CP->getIndex();
-      BuildMI(BB, PPC::ADDIS, 2, Tmp1).addReg(getGlobalBaseReg())
-        .addConstantPoolIndex(CPI);
-      BuildMI(BB, Opc, 2, Result).addConstantPoolIndex(CPI).addReg(Tmp1);
-    }
-    else if(Address.getOpcode() == ISD::FrameIndex) {
-      Tmp1 = cast<FrameIndexSDNode>(Address)->getIndex();
-      addFrameReference(BuildMI(BB, Opc, 2, Result), (int)Tmp1);
-    } else {
-      int offset;
-      bool idx = SelectAddr(Address, Tmp1, offset);
-      if (idx) {
-        Opc = IndexedOpForOp(Opc);
-        BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(offset);
-      } else {
-        BuildMI(BB, Opc, 2, Result).addSImm(offset).addReg(Tmp1);
-      }
-    }
-    return Result;
-  }
-
-  case ISD::TAILCALL:
-  case ISD::CALL: {
-    unsigned GPR_idx = 0, FPR_idx = 0;
-    static const unsigned GPR[] = {
-      PPC::R3, PPC::R4, PPC::R5, PPC::R6,
-      PPC::R7, PPC::R8, PPC::R9, PPC::R10,
-    };
-    static const unsigned FPR[] = {
-      PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
-      PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
-    };
-
-    // Lower the chain for this call.
-    Select(N.getOperand(0));
-    ExprMap[N.getValue(Node->getNumValues()-1)] = 1;
-
-    MachineInstr *CallMI;
-    // Emit the correct call instruction based on the type of symbol called.
-    if (GlobalAddressSDNode *GASD =
-        dyn_cast<GlobalAddressSDNode>(N.getOperand(1))) {
-      CallMI = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(),
-                                                           true);
-    } else if (ExternalSymbolSDNode *ESSDN =
-               dyn_cast<ExternalSymbolSDNode>(N.getOperand(1))) {
-      CallMI = BuildMI(PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(),
-                                                            true);
-    } else {
-      Tmp1 = SelectExpr(N.getOperand(1));
-      BuildMI(BB, PPC::OR, 2, PPC::R12).addReg(Tmp1).addReg(Tmp1);
-      BuildMI(BB, PPC::MTCTR, 1).addReg(PPC::R12);
-      CallMI = BuildMI(PPC::CALLindirect, 3).addImm(20).addImm(0)
-        .addReg(PPC::R12);
-    }
-
-    // Load the register args to virtual regs
-    std::vector<unsigned> ArgVR;
-    for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
-      ArgVR.push_back(SelectExpr(N.getOperand(i)));
-
-    // Copy the virtual registers into the appropriate argument register
-    for(int i = 0, e = ArgVR.size(); i < e; ++i) {
-      switch(N.getOperand(i+2).getValueType()) {
-      default: Node->dump(); assert(0 && "Unknown value type for call");
-      case MVT::i1:
-      case MVT::i8:
-      case MVT::i16:
-      case MVT::i32:
-      case MVT::i64:
-        assert(GPR_idx < 8 && "Too many int args");
-        if (N.getOperand(i+2).getOpcode() != ISD::UNDEF) {
-          BuildMI(BB, PPC::OR,2,GPR[GPR_idx]).addReg(ArgVR[i]).addReg(ArgVR[i]);
-          CallMI->addRegOperand(GPR[GPR_idx], MachineOperand::Use);
-        }
-        ++GPR_idx;
-        break;
-      case MVT::f64:
-      case MVT::f32:
-        assert(FPR_idx < 13 && "Too many fp args");
-        BuildMI(BB, PPC::FMR, 1, FPR[FPR_idx]).addReg(ArgVR[i]);
-        CallMI->addRegOperand(FPR[FPR_idx], MachineOperand::Use);
-        ++FPR_idx;
-        break;
-      }
-    }
-
-    // Put the call instruction in the correct place in the MachineBasicBlock
-    BB->push_back(CallMI);
-
-    switch (Node->getValueType(0)) {
-    default: assert(0 && "Unknown value type for call result!");
-    case MVT::Other: return 1;
-    case MVT::i1:
-    case MVT::i8:
-    case MVT::i16:
-    case MVT::i32:
-    case MVT::i64:
-      BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R3).addReg(PPC::R3);
-      break;
-    case MVT::f32:
-    case MVT::f64:
-      BuildMI(BB, PPC::FMR, 1, Result).addReg(PPC::F1);
-      break;
-    }
-    return Result+N.ResNo;
-  }
-
-  case ISD::SIGN_EXTEND:
-  case ISD::SIGN_EXTEND_INREG:
-    Tmp1 = SelectExpr(N.getOperand(0));
-    switch(cast<VTSDNode>(Node->getOperand(1))->getVT()) {
-    default: Node->dump(); assert(0 && "Unhandled SIGN_EXTEND type"); break;
-    case MVT::i32:
-      BuildMI(BB, PPC::EXTSW, 1, Result).addReg(Tmp1);
-      break;
-    case MVT::i16:
-      BuildMI(BB, PPC::EXTSH, 1, Result).addReg(Tmp1);
-      break;
-    case MVT::i8:
-      BuildMI(BB, PPC::EXTSB, 1, Result).addReg(Tmp1);
-      break;
-    case MVT::i1:
-      BuildMI(BB, PPC::SUBFIC, 2, Result).addReg(Tmp1).addSImm(0);
-      break;
-    }
-    return Result;
-
-  case ISD::CopyFromReg:
-    if (Result == 1)
-      Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
-    Tmp1 = dyn_cast<RegSDNode>(Node)->getReg();
-    BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp1).addReg(Tmp1);
-    return Result;
-
-  case ISD::SHL:
-    Tmp1 = SelectExpr(N.getOperand(0));
-    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
-      Tmp2 = CN->getValue() & 0x3F;
-      BuildMI(BB, PPC::RLDICR, 3, Result).addReg(Tmp1).addImm(Tmp2)
-        .addImm(63-Tmp2);
-    } else {
-      Tmp2 = SelectExpr(N.getOperand(1));
-      BuildMI(BB, PPC::SLD, 2, Result).addReg(Tmp1).addReg(Tmp2);
-    }
-    return Result;
-
-  case ISD::SRL:
-    Tmp1 = SelectExpr(N.getOperand(0));
-    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
-      Tmp2 = CN->getValue() & 0x3F;
-      BuildMI(BB, PPC::RLDICL, 3, Result).addReg(Tmp1).addImm(64-Tmp2)
-        .addImm(Tmp2);
-    } else {
-      Tmp2 = SelectExpr(N.getOperand(1));
-      BuildMI(BB, PPC::SRD, 2, Result).addReg(Tmp1).addReg(Tmp2);
-    }
-    return Result;
-
-  case ISD::SRA:
-    Tmp1 = SelectExpr(N.getOperand(0));
-    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
-      Tmp2 = CN->getValue() & 0x3F;
-      BuildMI(BB, PPC::SRADI, 2, Result).addReg(Tmp1).addImm(Tmp2);
-    } else {
-      Tmp2 = SelectExpr(N.getOperand(1));
-      BuildMI(BB, PPC::SRAD, 2, Result).addReg(Tmp1).addReg(Tmp2);
-    }
-    return Result;
-
-  case ISD::ADD:
-    Tmp1 = SelectExpr(N.getOperand(0));
-    switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) {
-      default: assert(0 && "unhandled result code");
-      case 0: // No immediate
-        Tmp2 = SelectExpr(N.getOperand(1));
-        BuildMI(BB, PPC::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2);
-        break;
-      case 1: // Low immediate
-        BuildMI(BB, PPC::ADDI, 2, Result).addReg(Tmp1).addSImm(Tmp2);
-        break;
-      case 2: // Shifted immediate
-        BuildMI(BB, PPC::ADDIS, 2, Result).addReg(Tmp1).addSImm(Tmp2);
-        break;
-    }
-    return Result;
-
-  case ISD::AND:
-  case ISD::OR:
-    Tmp1 = SelectExpr(N.getOperand(0));
-    switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) {
-      default: assert(0 && "unhandled result code");
-      case 0: // No immediate
-        Tmp2 = SelectExpr(N.getOperand(1));
-        switch (opcode) {
-        case ISD::AND: Opc = PPC::AND; break;
-        case ISD::OR:  Opc = PPC::OR;  break;
-        }
-        BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
-        break;
-      case 1: // Low immediate
-        switch (opcode) {
-        case ISD::AND: Opc = PPC::ANDIo; break;
-        case ISD::OR:  Opc = PPC::ORI;   break;
-        }
-        BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
-        break;
-      case 2: // Shifted immediate
-        switch (opcode) {
-        case ISD::AND: Opc = PPC::ANDISo;  break;
-        case ISD::OR:  Opc = PPC::ORIS;    break;
-        }
-        BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addImm(Tmp2);
-        break;
-    }
-    return Result;
-
-  case ISD::XOR: {
-    // Check for EQV: xor, (xor a, -1), b
-    if (N.getOperand(0).getOpcode() == ISD::XOR &&
-        N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
-        cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->isAllOnesValue()) {
-      ++NotLogic;
-      Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
-      Tmp2 = SelectExpr(N.getOperand(1));
-      BuildMI(BB, PPC::EQV, 2, Result).addReg(Tmp1).addReg(Tmp2);
-      return Result;
-    }
-    // Check for NOT, NOR, and NAND: xor (copy, or, and), -1
-    if (N.getOperand(1).getOpcode() == ISD::Constant &&
-        cast<ConstantSDNode>(N.getOperand(1))->isAllOnesValue()) {
-      ++NotLogic;
-      switch(N.getOperand(0).getOpcode()) {
-      case ISD::OR:
-        Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
-        Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
-        BuildMI(BB, PPC::NOR, 2, Result).addReg(Tmp1).addReg(Tmp2);
-        break;
-      case ISD::AND:
-        Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
-        Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
-        BuildMI(BB, PPC::NAND, 2, Result).addReg(Tmp1).addReg(Tmp2);
-        break;
-      default:
-        Tmp1 = SelectExpr(N.getOperand(0));
-        BuildMI(BB, PPC::NOR, 2, Result).addReg(Tmp1).addReg(Tmp1);
-        break;
-      }
-      return Result;
-    }
-    Tmp1 = SelectExpr(N.getOperand(0));
-    switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) {
-      default: assert(0 && "unhandled result code");
-      case 0: // No immediate
-        Tmp2 = SelectExpr(N.getOperand(1));
-        BuildMI(BB, PPC::XOR, 2, Result).addReg(Tmp1).addReg(Tmp2);
-        break;
-      case 1: // Low immediate
-        BuildMI(BB, PPC::XORI, 2, Result).addReg(Tmp1).addImm(Tmp2);
-        break;
-      case 2: // Shifted immediate
-        BuildMI(BB, PPC::XORIS, 2, Result).addReg(Tmp1).addImm(Tmp2);
-        break;
-    }
-    return Result;
-  }
-
-  case ISD::SUB:
-    Tmp2 = SelectExpr(N.getOperand(1));
-    if (1 == getImmediateForOpcode(N.getOperand(0), opcode, Tmp1))
-      BuildMI(BB, PPC::SUBFIC, 2, Result).addReg(Tmp2).addSImm(Tmp1);
-    else {
-      Tmp1 = SelectExpr(N.getOperand(0));
-      BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp2).addReg(Tmp1);
-    }
-    return Result;
-
-  case ISD::MUL:
-    Tmp1 = SelectExpr(N.getOperand(0));
-    if (1 == getImmediateForOpcode(N.getOperand(1), opcode, Tmp2))
-      BuildMI(BB, PPC::MULLI, 2, Result).addReg(Tmp1).addSImm(Tmp2);
-    else {
-      Tmp2 = SelectExpr(N.getOperand(1));
-      BuildMI(BB, PPC::MULLD, 2, Result).addReg(Tmp1).addReg(Tmp2);
-    }
-    return Result;
-
-  case ISD::SDIV:
-  case ISD::UDIV:
-    if (3 == getImmediateForOpcode(N.getOperand(1), opcode, Tmp3)) {
-      Tmp1 = MakeReg(MVT::i64);
-      Tmp2 = SelectExpr(N.getOperand(0));
-      BuildMI(BB, PPC::SRADI, 2, Tmp1).addReg(Tmp2).addImm(Tmp3);
-      BuildMI(BB, PPC::ADDZE, 1, Result).addReg(Tmp1);
-      return Result;
-    }
-    Tmp1 = SelectExpr(N.getOperand(0));
-    Tmp2 = SelectExpr(N.getOperand(1));
-    Opc = (ISD::UDIV == opcode) ? PPC::DIVWU : PPC::DIVW;
-    BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
-    return Result;
-
-  case ISD::FP_TO_UINT:
-  case ISD::FP_TO_SINT: {
-    Tmp1 = SelectExpr(N.getOperand(0));
-    Tmp2 = MakeReg(MVT::f64);
-    BuildMI(BB, PPC::FCTIDZ, 1, Tmp2).addReg(Tmp1);
-    int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8);
-    addFrameReference(BuildMI(BB, PPC::STFD, 3).addReg(Tmp2), FrameIdx);
-    addFrameReference(BuildMI(BB, PPC::LD, 2, Result), FrameIdx);
-    return Result;
-  }
-
-  case ISD::SETCC: {
-    Opc = SelectSetCR0(N);
-
-    unsigned TrueValue = MakeReg(MVT::i32);
-    BuildMI(BB, PPC::LI, 1, TrueValue).addSImm(1);
-    unsigned FalseValue = MakeReg(MVT::i32);
-    BuildMI(BB, PPC::LI, 1, FalseValue).addSImm(0);
-
-    // Create an iterator with which to insert the MBB for copying the false
-    // value and the MBB to hold the PHI instruction for this SetCC.
-    MachineBasicBlock *thisMBB = BB;
-    const BasicBlock *LLVM_BB = BB->getBasicBlock();
-    ilist<MachineBasicBlock>::iterator It = BB;
-    ++It;
-
-    //  thisMBB:
-    //  ...
-    //   cmpTY cr0, r1, r2
-    //   %TrueValue = li 1
-    //   bCC sinkMBB
-    MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
-    MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
-    BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(sinkMBB);
-    MachineFunction *F = BB->getParent();
-    F->getBasicBlockList().insert(It, copy0MBB);
-    F->getBasicBlockList().insert(It, sinkMBB);
-    // Update machine-CFG edges
-    BB->addSuccessor(copy0MBB);
-    BB->addSuccessor(sinkMBB);
-
-    //  copy0MBB:
-    //   %FalseValue = li 0
-    //   fallthrough
-    BB = copy0MBB;
-    // Update machine-CFG edges
-    BB->addSuccessor(sinkMBB);
-
-    //  sinkMBB:
-    //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
-    //  ...
-    BB = sinkMBB;
-    BuildMI(BB, PPC::PHI, 4, Result).addReg(FalseValue)
-      .addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB);
-    return Result;
-  }
-
-  case ISD::SELECT: {
-    unsigned TrueValue = SelectExpr(N.getOperand(1)); //Use if TRUE
-    unsigned FalseValue = SelectExpr(N.getOperand(2)); //Use if FALSE
-    Opc = SelectSetCR0(N.getOperand(0));
-
-    // Create an iterator with which to insert the MBB for copying the false
-    // value and the MBB to hold the PHI instruction for this SetCC.
-    MachineBasicBlock *thisMBB = BB;
-    const BasicBlock *LLVM_BB = BB->getBasicBlock();
-    ilist<MachineBasicBlock>::iterator It = BB;
-    ++It;
-
-    //  thisMBB:
-    //  ...
-    //   TrueVal = ...
-    //   cmpTY cr0, r1, r2
-    //   bCC copy1MBB
-    //   fallthrough --> copy0MBB
-    MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
-    MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
-    BuildMI(BB, Opc, 2).addReg(PPC::CR0).addMBB(sinkMBB);
-    MachineFunction *F = BB->getParent();
-    F->getBasicBlockList().insert(It, copy0MBB);
-    F->getBasicBlockList().insert(It, sinkMBB);
-    // Update machine-CFG edges
-    BB->addSuccessor(copy0MBB);
-    BB->addSuccessor(sinkMBB);
-
-    //  copy0MBB:
-    //   %FalseValue = ...
-    //   # fallthrough to sinkMBB
-    BB = copy0MBB;
-    // Update machine-CFG edges
-    BB->addSuccessor(sinkMBB);
-
-    //  sinkMBB:
-    //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
-    //  ...
-    BB = sinkMBB;
-    BuildMI(BB, PPC::PHI, 4, Result).addReg(FalseValue)
-      .addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB);
-
-    // FIXME: Select i64?
-    return Result;
-  }
-
-  case ISD::Constant:
-    switch (N.getValueType()) {
-    default: assert(0 && "Cannot use constants of this type!");
-    case MVT::i1:
-      BuildMI(BB, PPC::LI, 1, Result)
-        .addSImm(!cast<ConstantSDNode>(N)->isNullValue());
-      break;
-    case MVT::i32:
-      {
-        int v = (int)cast<ConstantSDNode>(N)->getSignExtended();
-        if (v < 32768 && v >= -32768) {
-          BuildMI(BB, PPC::LI, 1, Result).addSImm(v);
-        } else {
-          Tmp1 = MakeReg(MVT::i32);
-          BuildMI(BB, PPC::LIS, 1, Tmp1).addSImm(v >> 16);
-          BuildMI(BB, PPC::ORI, 2, Result).addReg(Tmp1).addImm(v & 0xFFFF);
-        }
-      }
-    }
-    return Result;
-  }
-
-  return 0;
-}
-
-void ISel::Select(SDOperand N) {
-  unsigned Tmp1, Tmp2, Opc;
-  unsigned opcode = N.getOpcode();
-
-  if (!ExprMap.insert(std::make_pair(N, 1)).second)
-    return;  // Already selected.
-
-  SDNode *Node = N.Val;
-
-  switch (Node->getOpcode()) {
-  default:
-    Node->dump(); std::cerr << "\n";
-    assert(0 && "Node not handled yet!");
-  case ISD::EntryToken: return;  // Noop
-  case ISD::TokenFactor:
-    for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
-      Select(Node->getOperand(i));
-    return;
-  case ISD::CALLSEQ_START:
-  case ISD::CALLSEQ_END:
-    Select(N.getOperand(0));
-    Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
-    Opc = N.getOpcode() == ISD::CALLSEQ_START ? PPC::ADJCALLSTACKDOWN :
-      PPC::ADJCALLSTACKUP;
-    BuildMI(BB, Opc, 1).addImm(Tmp1);
-    return;
-  case ISD::BR: {
-    MachineBasicBlock *Dest =
-      cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
-    Select(N.getOperand(0));
-    BuildMI(BB, PPC::B, 1).addMBB(Dest);
-    return;
-  }
-  case ISD::BRCOND:
-    SelectBranchCC(N);
-    return;
-  case ISD::CopyToReg:
-    Select(N.getOperand(0));
-    Tmp1 = SelectExpr(N.getOperand(1));
-    Tmp2 = cast<RegSDNode>(N)->getReg();
-
-    if (Tmp1 != Tmp2) {
-      if (N.getOperand(1).getValueType() == MVT::f64 ||
-          N.getOperand(1).getValueType() == MVT::f32)
-        BuildMI(BB, PPC::FMR, 1, Tmp2).addReg(Tmp1);
-      else
-        BuildMI(BB, PPC::OR, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
-    }
-    return;
-  case ISD::ImplicitDef:
-    Select(N.getOperand(0));
-    BuildMI(BB, PPC::IMPLICIT_DEF, 0, cast<RegSDNode>(N)->getReg());
-    return;
-  case ISD::RET:
-    switch (N.getNumOperands()) {
-    default:
-      assert(0 && "Unknown return instruction!");
-    case 3:
-      assert(N.getOperand(1).getValueType() == MVT::i32 &&
-             N.getOperand(2).getValueType() == MVT::i32 &&
-             "Unknown two-register value!");
-      Select(N.getOperand(0));
-      Tmp1 = SelectExpr(N.getOperand(1));
-      Tmp2 = SelectExpr(N.getOperand(2));
-      BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp2).addReg(Tmp2);
-      BuildMI(BB, PPC::OR, 2, PPC::R4).addReg(Tmp1).addReg(Tmp1);
-      break;
-    case 2:
-      Select(N.getOperand(0));
-      Tmp1 = SelectExpr(N.getOperand(1));
-      switch (N.getOperand(1).getValueType()) {
-        default:
-          assert(0 && "Unknown return type!");
-        case MVT::f64:
-        case MVT::f32:
-          BuildMI(BB, PPC::FMR, 1, PPC::F1).addReg(Tmp1);
-          break;
-        case MVT::i32:
-          BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp1).addReg(Tmp1);
-          break;
-      }
-    case 1:
-      Select(N.getOperand(0));
-      break;
-    }
-    BuildMI(BB, PPC::BLR, 0); // Just emit a 'ret' instruction
-    return;
-  case ISD::TRUNCSTORE:
-  case ISD::STORE:
-    {
-      SDOperand Chain   = N.getOperand(0);
-      SDOperand Value   = N.getOperand(1);
-      SDOperand Address = N.getOperand(2);
-      Select(Chain);
-
-      Tmp1 = SelectExpr(Value); //value
-
-      if (opcode == ISD::STORE) {
-        switch(Value.getValueType()) {
-        default: assert(0 && "unknown Type in store");
-        case MVT::i64: Opc = PPC::STD; break;
-        case MVT::f64: Opc = PPC::STFD; break;
-        case MVT::f32: Opc = PPC::STFS; break;
-        }
-      } else { //ISD::TRUNCSTORE
-        switch(cast<VTSDNode>(Node->getOperand(4))->getVT()) {
-        default: assert(0 && "unknown Type in store");
-        case MVT::i1: //FIXME: DAG does not promote this load
-        case MVT::i8:  Opc= PPC::STB; break;
-        case MVT::i16: Opc = PPC::STH; break;
-        case MVT::i32: Opc = PPC::STW; break;
-        }
-      }
-
-      if(Address.getOpcode() == ISD::FrameIndex)
-      {
-        Tmp2 = cast<FrameIndexSDNode>(Address)->getIndex();
-        addFrameReference(BuildMI(BB, Opc, 3).addReg(Tmp1), (int)Tmp2);
-      }
-      else
-      {
-        int offset;
-        bool idx = SelectAddr(Address, Tmp2, offset);
-        if (idx) {
-          Opc = IndexedOpForOp(Opc);
-          BuildMI(BB, Opc, 3).addReg(Tmp1).addReg(Tmp2).addReg(offset);
-        } else {
-          BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2);
-        }
-      }
-      return;
-    }
-  case ISD::EXTLOAD:
-  case ISD::SEXTLOAD:
-  case ISD::ZEXTLOAD:
-  case ISD::LOAD:
-  case ISD::CopyFromReg:
-  case ISD::TAILCALL:
-  case ISD::CALL:
-  case ISD::DYNAMIC_STACKALLOC:
-    ExprMap.erase(N);
-    SelectExpr(N);
-    return;
-  }
-  assert(0 && "Should not be reached!");
-}
-
-
-/// createPPC64PatternInstructionSelector - This pass converts an LLVM function
-/// into a machine code representation using pattern matching and a machine
-/// description file.
-///
-FunctionPass *llvm::createPPC64ISelPattern(TargetMachine &TM) {
-  return new ISel(TM);
-}
-
diff --git a/lib/Target/PowerPC/PPC64InstrInfo.cpp b/lib/Target/PowerPC/PPC64InstrInfo.cpp
deleted file mode 100644
index 929f5d1..0000000
--- a/lib/Target/PowerPC/PPC64InstrInfo.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-//===- PPC64InstrInfo.cpp - PowerPC64 Instruction Information ---*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the PowerPC implementation of the TargetInstrInfo class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "PowerPC.h"
-#include "PPC64InstrInfo.h"
-#include "PPC64GenInstrInfo.inc"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include <iostream>
-using namespace llvm;
-
-PPC64InstrInfo::PPC64InstrInfo()
-  : TargetInstrInfo(PPC64Insts, sizeof(PPC64Insts)/sizeof(PPC64Insts[0])) { }
-
-bool PPC64InstrInfo::isMoveInstr(const MachineInstr& MI,
-                                 unsigned& sourceReg,
-                                 unsigned& destReg) const {
-  MachineOpCode oc = MI.getOpcode();
-  if (oc == PPC::OR) {                      // or r1, r2, r2
-    assert(MI.getNumOperands() == 3 &&
-           MI.getOperand(0).isRegister() &&
-           MI.getOperand(1).isRegister() &&
-           MI.getOperand(2).isRegister() &&
-           "invalid PPC OR instruction!");
-    if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
-      sourceReg = MI.getOperand(1).getReg();
-      destReg = MI.getOperand(0).getReg();
-      return true;
-    }
-  } else if (oc == PPC::ADDI) {             // addi r1, r2, 0
-    assert(MI.getNumOperands() == 3 &&
-           MI.getOperand(0).isRegister() &&
-           MI.getOperand(2).isImmediate() &&
-           "invalid PPC ADDI instruction!");
-    if (MI.getOperand(1).isRegister() && MI.getOperand(2).getImmedValue()==0) {
-      sourceReg = MI.getOperand(1).getReg();
-      destReg = MI.getOperand(0).getReg();
-      return true;
-    }
-  } else if (oc == PPC::FMR) {              // fmr r1, r2
-    assert(MI.getNumOperands() == 2 &&
-           MI.getOperand(0).isRegister() &&
-           MI.getOperand(1).isRegister() &&
-           "invalid PPC FMR instruction");
-    sourceReg = MI.getOperand(1).getReg();
-    destReg = MI.getOperand(0).getReg();
-    return true;
-  }
-  return false;
-}
diff --git a/lib/Target/PowerPC/PPC64InstrInfo.h b/lib/Target/PowerPC/PPC64InstrInfo.h
deleted file mode 100644
index e2e643c..0000000
--- a/lib/Target/PowerPC/PPC64InstrInfo.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//===- PPC64InstrInfo.h - PowerPC64 Instruction Information -----*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the PowerPC64 implementation of the TargetInstrInfo class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef POWERPC64_INSTRUCTIONINFO_H
-#define POWERPC64_INSTRUCTIONINFO_H
-
-#include "PowerPCInstrInfo.h"
-#include "PPC64RegisterInfo.h"
-
-namespace llvm {
-
-class PPC64InstrInfo : public TargetInstrInfo {
-  const PPC64RegisterInfo RI;
-public:
-  PPC64InstrInfo();
-
-  /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info.  As
-  /// such, whenever a client has an instance of instruction info, it should
-  /// always be able to get register info as well (through this method).
-  ///
-  virtual const MRegisterInfo &getRegisterInfo() const { return RI; }
-
-  //
-  // Return true if the instruction is a register to register move and
-  // leave the source and dest operands in the passed parameters.
-  //
-  virtual bool isMoveInstr(const MachineInstr& MI,
-                           unsigned& sourceReg,
-                           unsigned& destReg) const;
-
-  static unsigned invertPPCBranchOpcode(unsigned Opcode) {
-    switch (Opcode) {
-    default: assert(0 && "Unknown PPC branch opcode!");
-    case PPC::BEQ: return PPC::BNE;
-    case PPC::BNE: return PPC::BEQ;
-    case PPC::BLT: return PPC::BGE;
-    case PPC::BGE: return PPC::BLT;
-    case PPC::BGT: return PPC::BLE;
-    case PPC::BLE: return PPC::BGT;
-    }
-  }
-};
-
-}
-
-#endif
diff --git a/lib/Target/PowerPC/PPC64JITInfo.h b/lib/Target/PowerPC/PPC64JITInfo.h
deleted file mode 100644
index 9e994c2..0000000
--- a/lib/Target/PowerPC/PPC64JITInfo.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===- PPC64JITInfo.h - PowerPC/AIX impl. of the JIT interface -*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the PowerPC/AIX implementation of the TargetJITInfo class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef POWERPC_AIX_JITINFO_H
-#define POWERPC_AIX_JITINFO_H
-
-#include "PowerPCJITInfo.h"
-
-namespace llvm {
-  class TargetMachine;
-
-  class PPC64JITInfo : public PowerPCJITInfo {
-  public:
-    PPC64JITInfo(TargetMachine &tm) : PowerPCJITInfo(tm) {}
-
-    /// replaceMachineCodeForFunction - Make it so that calling the function
-    /// whose machine code is at OLD turns into a call to NEW, perhaps by
-    /// overwriting OLD with a branch to NEW.  This is used for self-modifying
-    /// code.
-    ///
-    virtual void replaceMachineCodeForFunction(void *Old, void *New);
-  };
-}
-
-#endif
diff --git a/lib/Target/PowerPC/PPC64RegisterInfo.cpp b/lib/Target/PowerPC/PPC64RegisterInfo.cpp
deleted file mode 100644
index fd5d442..0000000
--- a/lib/Target/PowerPC/PPC64RegisterInfo.cpp
+++ /dev/null
@@ -1,317 +0,0 @@
-//===- PPC64RegisterInfo.cpp - PowerPC64 Register Information ---*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the PowerPC64 implementation of the MRegisterInfo class.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "reginfo"
-#include "PowerPC.h"
-#include "PowerPCInstrBuilder.h"
-#include "PPC64RegisterInfo.h"
-#include "llvm/Constants.h"
-#include "llvm/Type.h"
-#include "llvm/CodeGen/ValueTypes.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetOptions.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/ADT/STLExtras.h"
-#include <cstdlib>
-#include <iostream>
-using namespace llvm;
-
-PPC64RegisterInfo::PPC64RegisterInfo()
-  : PPC64GenRegisterInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP) {
-  ImmToIdxMap[PPC::LD]   = PPC::LDX;    ImmToIdxMap[PPC::STD]  = PPC::STDX;
-  ImmToIdxMap[PPC::LBZ]  = PPC::LBZX;   ImmToIdxMap[PPC::STB]  = PPC::STBX;
-  ImmToIdxMap[PPC::LHZ]  = PPC::LHZX;   ImmToIdxMap[PPC::LHA]  = PPC::LHAX;
-  ImmToIdxMap[PPC::LWZ]  = PPC::LWZX;   ImmToIdxMap[PPC::LWA]  = PPC::LWAX;
-  ImmToIdxMap[PPC::LFS]  = PPC::LFSX;   ImmToIdxMap[PPC::LFD]  = PPC::LFDX;
-  ImmToIdxMap[PPC::STH]  = PPC::STHX;   ImmToIdxMap[PPC::STW]  = PPC::STWX;
-  ImmToIdxMap[PPC::STFS] = PPC::STFSX;  ImmToIdxMap[PPC::STFD] = PPC::STFDX;
-  ImmToIdxMap[PPC::ADDI] = PPC::ADD;
-}
-
-static const TargetRegisterClass *getClass(unsigned SrcReg) {
-  if (PPC64::FPRCRegisterClass->contains(SrcReg))
-    return PPC64::FPRCRegisterClass;
-  assert(PPC64::GPRCRegisterClass->contains(SrcReg) && "Reg not FPR or GPR");
-  return PPC64::GPRCRegisterClass;
-}
-
-static unsigned getIdx(const TargetRegisterClass *RC) {
-  if (RC == PPC64::GPRCRegisterClass) {
-    switch (RC->getSize()) {
-      default: assert(0 && "Invalid data size!");
-      case 1:  return 0;
-      case 2:  return 1;
-      case 4:  return 2;
-      case 8:  return 3;
-    }
-  } else if (RC == PPC64::FPRCRegisterClass) {
-    switch (RC->getSize()) {
-      default: assert(0 && "Invalid data size!");
-      case 4:  return 4;
-      case 8:  return 5;
-    }
-  }
-  std::cerr << "Invalid register class to getIdx()!\n";
-  abort();
-}
-
-void
-PPC64RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
-                                       MachineBasicBlock::iterator MI,
-                                       unsigned SrcReg, int FrameIdx) const {
-  static const unsigned Opcode[] = {
-    PPC::STB, PPC::STH, PPC::STW, PPC::STD, PPC::STFS, PPC::STFD
-  };
-  unsigned OC = Opcode[getIdx(getClass(SrcReg))];
-  if (SrcReg == PPC::LR) {
-    BuildMI(MBB, MI, PPC::MFLR, 1, PPC::R11).addReg(PPC::LR);
-    BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0);
-    addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(PPC::R11),FrameIdx);
-  } else {
-    BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0);
-    addFrameReference(BuildMI(MBB, MI, OC, 3).addReg(SrcReg),FrameIdx);
-  }
-}
-
-void
-PPC64RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
-                                        MachineBasicBlock::iterator MI,
-                                        unsigned DestReg, int FrameIdx) const{
-  static const unsigned Opcode[] = {
-    PPC::LBZ, PPC::LHZ, PPC::LWZ, PPC::LD, PPC::LFS, PPC::LFD
-  };
-  unsigned OC = Opcode[getIdx(getClass(DestReg))];
-  if (DestReg == PPC::LR) {
-    BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0);
-    addFrameReference(BuildMI(MBB, MI, OC, 2, PPC::R11), FrameIdx);
-    BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11);
-  } else {
-    BuildMI(MBB, MI, PPC::IMPLICIT_DEF, 0, PPC::R0);
-    addFrameReference(BuildMI(MBB, MI, OC, 2, DestReg), FrameIdx);
-  }
-}
-
-void PPC64RegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
-                                     MachineBasicBlock::iterator MI,
-                                     unsigned DestReg, unsigned SrcReg,
-                                     const TargetRegisterClass *RC) const {
-  MachineInstr *I;
-
-  if (RC == PPC64::GPRCRegisterClass) {
-    BuildMI(MBB, MI, PPC::OR, 2, DestReg).addReg(SrcReg).addReg(SrcReg);
-  } else if (RC == PPC64::FPRCRegisterClass) {
-    BuildMI(MBB, MI, PPC::FMR, 1, DestReg).addReg(SrcReg);
-  } else {
-    std::cerr << "Attempt to copy register that is not GPR or FPR";
-    abort();
-  }
-}
-
-//===----------------------------------------------------------------------===//
-// Stack Frame Processing methods
-//===----------------------------------------------------------------------===//
-
-// hasFP - Return true if the specified function should have a dedicated frame
-// pointer register.  This is true if the function has variable sized allocas or
-// if frame pointer elimination is disabled.
-//
-static bool hasFP(MachineFunction &MF) {
-  MachineFrameInfo *MFI = MF.getFrameInfo();
-  return MFI->hasVarSizedObjects();
-}
-
-void PPC64RegisterInfo::
-eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
-                              MachineBasicBlock::iterator I) const {
-  if (hasFP(MF)) {
-    // If we have a frame pointer, convert as follows:
-    // ADJCALLSTACKDOWN -> addi, r1, r1, -amount
-    // ADJCALLSTACKUP   -> addi, r1, r1, amount
-    MachineInstr *Old = I;
-    unsigned Amount = Old->getOperand(0).getImmedValue();
-    if (Amount != 0) {
-      // We need to keep the stack aligned properly.  To do this, we round the
-      // amount of space needed for the outgoing arguments up to the next
-      // alignment boundary.
-      unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
-      Amount = (Amount+Align-1)/Align*Align;
-
-      // Replace the pseudo instruction with a new instruction...
-      if (Old->getOpcode() == PPC::ADJCALLSTACKDOWN) {
-        MBB.insert(I, BuildMI(PPC::ADDI, 2, PPC::R1).addReg(PPC::R1)
-                .addSImm(-Amount));
-      } else {
-        assert(Old->getOpcode() == PPC::ADJCALLSTACKUP);
-        MBB.insert(I, BuildMI(PPC::ADDI, 2, PPC::R1).addReg(PPC::R1)
-                .addSImm(Amount));
-      }
-    }
-  }
-  MBB.erase(I);
-}
-
-void
-PPC64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
-  unsigned i = 0;
-  MachineInstr &MI = *II;
-  MachineBasicBlock &MBB = *MI.getParent();
-  MachineFunction &MF = *MBB.getParent();
-
-  while (!MI.getOperand(i).isFrameIndex()) {
-    ++i;
-    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
-  }
-
-  int FrameIndex = MI.getOperand(i).getFrameIndex();
-
-  // Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP).
-  MI.SetMachineOperandReg(i, hasFP(MF) ? PPC::R31 : PPC::R1);
-
-  // Take into account whether it's an add or mem instruction
-  unsigned OffIdx = (i == 2) ? 1 : 2;
-
-  // Now add the frame object offset to the offset from r1.
-  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
-               MI.getOperand(OffIdx).getImmedValue();
-
-  // If we're not using a Frame Pointer that has been set to the value of the
-  // SP before having the stack size subtracted from it, then add the stack size
-  // to Offset to get the correct offset.
-  Offset += MF.getFrameInfo()->getStackSize();
-
-  if (Offset > 32767 || Offset < -32768) {
-    // Insert a set of r0 with the full offset value before the ld, st, or add
-    MachineBasicBlock *MBB = MI.getParent();
-    MBB->insert(II, BuildMI(PPC::LIS, 1, PPC::R0).addSImm(Offset >> 16));
-    MBB->insert(II, BuildMI(PPC::ORI, 2, PPC::R0).addReg(PPC::R0)
-      .addImm(Offset));
-    // convert into indexed form of the instruction
-    // sth 0:rA, 1:imm 2:(rB) ==> sthx 0:rA, 2:rB, 1:r0
-    // addi 0:rA 1:rB, 2, imm ==> add 0:rA, 1:rB, 2:r0
-    unsigned NewOpcode =
-      const_cast<std::map<unsigned, unsigned>& >(ImmToIdxMap)[MI.getOpcode()];
-    assert(NewOpcode && "No indexed form of load or store available!");
-    MI.setOpcode(NewOpcode);
-    MI.SetMachineOperandReg(1, MI.getOperand(i).getReg());
-    MI.SetMachineOperandReg(2, PPC::R0);
-  } else {
-    MI.SetMachineOperandConst(OffIdx, MachineOperand::MO_SignExtendedImmed,
-                              Offset);
-  }
-}
-
-
-void PPC64RegisterInfo::emitPrologue(MachineFunction &MF) const {
-  MachineBasicBlock &MBB = MF.front();   // Prolog goes in entry BB
-  MachineBasicBlock::iterator MBBI = MBB.begin();
-  MachineFrameInfo *MFI = MF.getFrameInfo();
-  MachineInstr *MI;
-
-  // Get the number of bytes to allocate from the FrameInfo
-  unsigned NumBytes = MFI->getStackSize();
-
-  // If we have calls, we cannot use the red zone to store callee save registers
-  // and we must set up a stack frame, so calculate the necessary size here.
-  if (MFI->hasCalls()) {
-    // We reserve argument space for call sites in the function immediately on
-    // entry to the current function.  This eliminates the need for add/sub
-    // brackets around call sites.
-    NumBytes += MFI->getMaxCallFrameSize();
-  }
-
-  // Do we need to allocate space on the stack?
-  if (NumBytes == 0) return;
-
-  // Add the size of R1 to  NumBytes size for the store of R1 to the bottom
-  // of the stack and round the size to a multiple of the alignment.
-  unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
-  unsigned GPRSize = getSpillSize(PPC::R1)/8;
-  unsigned Size = hasFP(MF) ? GPRSize + GPRSize : GPRSize;
-  NumBytes = (NumBytes+Size+Align-1)/Align*Align;
-
-  // Update frame info to pretend that this is part of the stack...
-  MFI->setStackSize(NumBytes);
-
-  // adjust stack pointer: r1 -= numbytes
-  if (NumBytes <= 32768) {
-    MI=BuildMI(PPC::STDU,3).addReg(PPC::R1).addSImm(-NumBytes).addReg(PPC::R1);
-    MBB.insert(MBBI, MI);
-  } else {
-    int NegNumbytes = -NumBytes;
-    MI = BuildMI(PPC::LIS, 1, PPC::R0).addSImm(NegNumbytes >> 16);
-    MBB.insert(MBBI, MI);
-    MI = BuildMI(PPC::ORI, 2, PPC::R0).addReg(PPC::R0)
-      .addImm(NegNumbytes & 0xFFFF);
-    MBB.insert(MBBI, MI);
-    MI = BuildMI(PPC::STDUX, 3).addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0);
-    MBB.insert(MBBI, MI);
-  }
-
-  if (hasFP(MF)) {
-    MI = BuildMI(PPC::STD, 3).addReg(PPC::R31).addSImm(GPRSize).addReg(PPC::R1);
-    MBB.insert(MBBI, MI);
-    MI = BuildMI(PPC::OR, 2, PPC::R31).addReg(PPC::R1).addReg(PPC::R1);
-    MBB.insert(MBBI, MI);
-  }
-}
-
-void PPC64RegisterInfo::emitEpilogue(MachineFunction &MF,
-                                     MachineBasicBlock &MBB) const {
-  const MachineFrameInfo *MFI = MF.getFrameInfo();
-  MachineBasicBlock::iterator MBBI = prior(MBB.end());
-  MachineInstr *MI;
-  assert(MBBI->getOpcode() == PPC::BLR &&
-         "Can only insert epilog into returning blocks");
-
-  // Get the number of bytes allocated from the FrameInfo...
-  unsigned NumBytes = MFI->getStackSize();
-
-  if (NumBytes != 0) {
-    if (hasFP(MF)) {
-      MI = BuildMI(PPC::OR, 2, PPC::R1).addReg(PPC::R31).addReg(PPC::R31);
-      MBB.insert(MBBI, MI);
-      MI = BuildMI(PPC::LD, 2, PPC::R31).addSImm(4).addReg(PPC::R31);
-      MBB.insert(MBBI, MI);
-    }
-    MI = BuildMI(PPC::LD, 2, PPC::R1).addSImm(0).addReg(PPC::R1);
-    MBB.insert(MBBI, MI);
-  }
-}
-
-#include "PPC64GenRegisterInfo.inc"
-
-const TargetRegisterClass*
-PPC64RegisterInfo::getRegClassForType(const Type* Ty) const {
-  switch (Ty->getTypeID()) {
-    default:              assert(0 && "Invalid type to getClass!");
-    case Type::BoolTyID:
-    case Type::SByteTyID:
-    case Type::UByteTyID:
-    case Type::ShortTyID:
-    case Type::UShortTyID:
-    case Type::IntTyID:
-    case Type::UIntTyID:
-    case Type::PointerTyID:
-    case Type::LongTyID:
-    case Type::ULongTyID:  return &GPRCInstance;
-
-    case Type::FloatTyID:
-    case Type::DoubleTyID: return &FPRCInstance;
-  }
-}
-
diff --git a/lib/Target/PowerPC/PPC64RegisterInfo.h b/lib/Target/PowerPC/PPC64RegisterInfo.h
deleted file mode 100644
index 0580dc7..0000000
--- a/lib/Target/PowerPC/PPC64RegisterInfo.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//===- PPC64RegisterInfo.h - PowerPC64 Register Information Impl -*- C++ -*-==//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the PowerPC implementation of the MRegisterInfo class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef POWERPC64_REGISTERINFO_H
-#define POWERPC64_REGISTERINFO_H
-
-#include "PowerPC.h"
-#include "PPC64GenRegisterInfo.h.inc"
-#include <map>
-
-namespace llvm {
-
-class Type;
-
-class PPC64RegisterInfo : public PPC64GenRegisterInfo {
-  std::map<unsigned, unsigned> ImmToIdxMap;
-public:
-  PPC64RegisterInfo();
-  const TargetRegisterClass* getRegClassForType(const Type* Ty) const;
-
-  /// Code Generation virtual methods...
-  void storeRegToStackSlot(MachineBasicBlock &MBB,
-                           MachineBasicBlock::iterator MBBI,
-                           unsigned SrcReg, int FrameIndex) const;
-
-  void loadRegFromStackSlot(MachineBasicBlock &MBB,
-                            MachineBasicBlock::iterator MBBI,
-                            unsigned DestReg, int FrameIndex) const;
-
-  void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
-                    unsigned DestReg, unsigned SrcReg,
-                    const TargetRegisterClass *RC) const;
-
-  void eliminateCallFramePseudoInstr(MachineFunction &MF,
-                                     MachineBasicBlock &MBB,
-                                     MachineBasicBlock::iterator I) const;
-
-  void eliminateFrameIndex(MachineBasicBlock::iterator II) const;
-
-  void emitPrologue(MachineFunction &MF) const;
-  void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/lib/Target/PowerPC/PPC64TargetMachine.h b/lib/Target/PowerPC/PPC64TargetMachine.h
deleted file mode 100644
index 6d35527..0000000
--- a/lib/Target/PowerPC/PPC64TargetMachine.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===-- PPC64TargetMachine.h - Define TargetMachine for PowerPC64 -*- C++ -*-=//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the PowerPC specific subclass of TargetMachine.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef POWERPC64_TARGETMACHINE_H
-#define POWERPC64_TARGETMACHINE_H
-
-#include "PowerPCTargetMachine.h"
-#include "PPC64InstrInfo.h"
-#include "llvm/PassManager.h"
-
-namespace llvm {
-
-class IntrinsicLowering;
-
-class PPC64TargetMachine : public PowerPCTargetMachine {
-  PPC64InstrInfo InstrInfo;
-
-public:
-  PPC64TargetMachine(const Module &M, IntrinsicLowering *IL);
-  virtual const PPC64InstrInfo   *getInstrInfo() const { return &InstrInfo; }
-  virtual const MRegisterInfo *getRegisterInfo() const {
-    return &InstrInfo.getRegisterInfo();
-  }
-
-  static unsigned getModuleMatchQuality(const Module &M);
-
-  bool addPassesToEmitMachineCode(FunctionPassManager &PM,
-                                  MachineCodeEmitter &MCE);
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp
index 9b2670c..cc530a6 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -14,9 +14,7 @@
 #include "PowerPCTargetMachine.h"
 #include "PowerPCFrameInfo.h"
 #include "PPC32TargetMachine.h"
-#include "PPC64TargetMachine.h"
 #include "PPC32JITInfo.h"
-#include "PPC64JITInfo.h"
 #include "llvm/Module.h"
 #include "llvm/PassManager.h"
 #include "llvm/Analysis/Verifier.h"
@@ -35,16 +33,10 @@
 
 namespace {
   const std::string PPC32ID = "PowerPC/32bit";
-  const std::string PPC64ID = "PowerPC/64bit";
 
   // Register the targets
   RegisterTarget<PPC32TargetMachine>
   X("ppc32", "  PowerPC 32-bit");
-
-#if 0
-  RegisterTarget<PPC64TargetMachine>
-  Y("ppc64", "  PowerPC 64-bit (unimplemented)");
-#endif
 }
 
 PowerPCTargetMachine::PowerPCTargetMachine(const std::string &name,
@@ -75,8 +67,6 @@
                                                 CodeGenFileType FileType) {
   if (FileType != TargetMachine::AssemblyFile) return true;
 
-  bool LP64 = (0 != dynamic_cast<PPC64TargetMachine *>(this));
-
   if (EnablePPCLSR) {
     PM.add(createLoopStrengthReducePass());
     PM.add(createVerifierPass());
@@ -98,9 +88,7 @@
   PM.add(createUnreachableBlockEliminationPass());
 
   // Default to pattern ISel
-  if (LP64)
-    PM.add(createPPC64ISelPattern(*this));
-  else if (PatternISelTriState == 0)
+  if (PatternISelTriState == 0)
     PM.add(createPPC32ISelSimple(*this));
   else
     PM.add(createPPC32ISelPattern(*this));
@@ -138,8 +126,6 @@
   // The JIT does not support or need PIC.
   PICEnabled = false;
 
-  bool LP64 = (0 != dynamic_cast<PPC64TargetMachine *>(&TM));
-
   if (EnablePPCLSR) {
     PM.add(createLoopStrengthReducePass());
     PM.add(createCFGSimplificationPass());
@@ -160,9 +146,7 @@
   PM.add(createUnreachableBlockEliminationPass());
 
   // Default to pattern ISel
-  if (LP64)
-    PM.add(createPPC64ISelPattern(TM));
-  else if (PatternISelTriState == 0)
+  if (PatternISelTriState == 0)
     PM.add(createPPC32ISelSimple(TM));
   else
     PM.add(createPPC32ISelPattern(TM));
@@ -184,13 +168,6 @@
                          TargetData(PPC32ID,false,4,4,4,4,4,4,2,1,1),
                          PowerPCFrameInfo(*this, false)), JITInfo(*this) {}
 
-/// PPC64TargetMachine ctor - Create a LP64 architecture model
-///
-PPC64TargetMachine::PPC64TargetMachine(const Module &M, IntrinsicLowering *IL)
-  : PowerPCTargetMachine(PPC64ID, IL, M,
-                         TargetData(PPC64ID,false,8,4,4,4,4,4,2,1,1),
-                         PowerPCFrameInfo(*this, true)) {}
-
 unsigned PPC32TargetMachine::getModuleMatchQuality(const Module &M) {
   // We strongly match "powerpc-*".
   std::string TT = M.getTargetTriple();
@@ -206,14 +183,3 @@
 
   return getJITMatchQuality()/2;
 }
-
-unsigned PPC64TargetMachine::getModuleMatchQuality(const Module &M) {
-  if (M.getEndianness()  == Module::BigEndian &&
-      M.getPointerSize() == Module::Pointer64)
-    return 10;                                   // Direct match
-  else if (M.getEndianness() != Module::AnyEndianness ||
-           M.getPointerSize() != Module::AnyPointerSize)
-    return 0;                                    // Match for some other target
-
-  return getJITMatchQuality()/2;
-}
