diff --git a/llvm/lib/Target/ARM/ARM.h b/llvm/lib/Target/ARM/ARM.h
index db27073..1d626d1 100644
--- a/llvm/lib/Target/ARM/ARM.h
+++ b/llvm/lib/Target/ARM/ARM.h
@@ -20,43 +20,77 @@
 #include <cassert>
 
 namespace llvm {
-  // Enums corresponding to ARM condition codes
-  namespace ARMCC {
-    enum CondCodes {
-      EQ,
-      NE,
-      CS,
-      CC,
-      MI,
-      PL,
-      VS,
-      VC,
-      HI,
-      LS,
-      GE,
-      LT,
-      GT,
-      LE,
-      AL
-    };
+
+class ARMTargetMachine;
+class FunctionPass;
+
+// Enums corresponding to ARM condition codes
+namespace ARMCC {
+  enum CondCodes {
+    EQ,
+    NE,
+    HS,
+    LO,
+    MI,
+    PL,
+    VS,
+    VC,
+    HI,
+    LS,
+    GE,
+    LT,
+    GT,
+    LE,
+    AL
+  };
+  
+  inline static CondCodes getOppositeCondition(CondCodes CC){
+    switch (CC) {
+    default: assert(0 && "Unknown condition code");
+    case EQ: return NE;
+    case NE: return EQ;
+    case HS: return LO;
+    case LO: return HS;
+    case MI: return PL;
+    case PL: return MI;
+    case VS: return VC;
+    case VC: return VS;
+    case HI: return LS;
+    case LS: return HI;
+    case GE: return LT;
+    case LT: return GE;
+    case GT: return LE;
+    case LE: return GT;
+    }
   }
+}
 
-  namespace ARMShift {
-    enum ShiftTypes {
-      LSL,
-      LSR,
-      ASR,
-      ROR,
-      RRX
-    };
+inline static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {
+  switch (CC) {
+  default: assert(0 && "Unknown condition code");
+  case ARMCC::EQ:  return "eq";
+  case ARMCC::NE:  return "ne";
+  case ARMCC::HS:  return "hs";
+  case ARMCC::LO:  return "lo";
+  case ARMCC::MI:  return "mi";
+  case ARMCC::PL:  return "pl";
+  case ARMCC::VS:  return "vs";
+  case ARMCC::VC:  return "vc";
+  case ARMCC::HI:  return "hi";
+  case ARMCC::LS:  return "ls";
+  case ARMCC::GE:  return "ge";
+  case ARMCC::LT:  return "lt";
+  case ARMCC::GT:  return "gt";
+  case ARMCC::LE:  return "le";
+  case ARMCC::AL:  return "al";
   }
+}
 
-  class FunctionPass;
-  class TargetMachine;
+FunctionPass *createARMISelDag(ARMTargetMachine &TM);
+FunctionPass *createARMCodePrinterPass(std::ostream &O, ARMTargetMachine &TM);
+FunctionPass *createARMLoadStoreOptimizationPass();
+FunctionPass *createARMConstantIslandPass();
 
-  FunctionPass *createARMISelDag(TargetMachine &TM);
-  FunctionPass *createARMCodePrinterPass(std::ostream &OS, TargetMachine &TM);
-  FunctionPass *createARMFixMulPass();
 } // end namespace llvm;
 
 // Defines symbolic names for ARM registers.  This defines a mapping from
diff --git a/llvm/lib/Target/ARM/ARM.td b/llvm/lib/Target/ARM/ARM.td
index 4015349..6faf938 100644
--- a/llvm/lib/Target/ARM/ARM.td
+++ b/llvm/lib/Target/ARM/ARM.td
@@ -18,6 +18,73 @@
 include "../Target.td"
 
 //===----------------------------------------------------------------------===//
+// ARM Subtarget features.
+//
+
+def ArchV4T     : SubtargetFeature<"v4t", "ARMArchVersion", "V4T",
+                                   "ARM v4T">;
+def ArchV5T     : SubtargetFeature<"v5t", "ARMArchVersion", "V5T",
+                                   "ARM v5T">;
+def ArchV5TE    : SubtargetFeature<"v5te", "ARMArchVersion", "V5TE",
+                                   "ARM v5TE, v5TEj, v5TExp">;
+def ArchV6      : SubtargetFeature<"v6", "ARMArchVersion", "V6",
+                                   "ARM v6">;
+def FeatureVFP2 : SubtargetFeature<"vfp2", "HasVFP2", "true",
+                                   "Enable VFP2 instructions ">;
+
+//===----------------------------------------------------------------------===//
+// ARM Processors supported.
+//
+
+class Proc<string Name, list<SubtargetFeature> Features>
+ : Processor<Name, NoItineraries, Features>;
+
+// V4 Processors.
+def : Proc<"generic",         []>;
+def : Proc<"arm8",            []>;
+def : Proc<"arm810",          []>;
+def : Proc<"strongarm",       []>;
+def : Proc<"strongarm110",    []>;
+def : Proc<"strongarm1100",   []>;
+def : Proc<"strongarm1110",   []>;
+
+// V4T Processors.
+def : Proc<"arm7tdmi",        [ArchV4T]>;
+def : Proc<"arm7tdmi-s",      [ArchV4T]>;
+def : Proc<"arm710t",         [ArchV4T]>;
+def : Proc<"arm720t",         [ArchV4T]>;
+def : Proc<"arm9",            [ArchV4T]>;
+def : Proc<"arm9tdmi",        [ArchV4T]>;
+def : Proc<"arm920",          [ArchV4T]>;
+def : Proc<"arm920t",         [ArchV4T]>;
+def : Proc<"arm922t",         [ArchV4T]>;
+def : Proc<"arm940t",         [ArchV4T]>;
+def : Proc<"ep9312",          [ArchV4T]>;
+
+// V5T Processors.
+def : Proc<"arm10tdmi",       [ArchV5T]>;
+def : Proc<"arm1020t",        [ArchV5T]>;
+
+// V5TE Processors.
+def : Proc<"arm9e",           [ArchV5TE]>;
+def : Proc<"arm946e-s",       [ArchV5TE]>;
+def : Proc<"arm966e-s",       [ArchV5TE]>;
+def : Proc<"arm968e-s",       [ArchV5TE]>;
+def : Proc<"arm10e",          [ArchV5TE]>;
+def : Proc<"arm1020e",        [ArchV5TE]>;
+def : Proc<"arm1022e",        [ArchV5TE]>;
+def : Proc<"xscale",          [ArchV5TE]>;
+def : Proc<"iwmmxt",          [ArchV5TE]>;
+
+// V6 Processors.
+def : Proc<"arm1136j-s",      [ArchV6]>;
+def : Proc<"arm1136jf-s",     [ArchV6, FeatureVFP2]>;
+def : Proc<"arm1176jz-s",     [ArchV6]>;
+def : Proc<"arm1176jzf-s",    [ArchV6, FeatureVFP2]>;
+def : Proc<"mpcorenovfp",     [ArchV6]>;
+def : Proc<"mpcore",          [ArchV6, FeatureVFP2]>;
+
+//===----------------------------------------------------------------------===//
 // Register File Description
 //===----------------------------------------------------------------------===//
 
@@ -31,8 +98,14 @@
 
 def ARMInstrInfo : InstrInfo {
   // Define how we want to layout our target-specific information field.
-  let TSFlagsFields = [];
-  let TSFlagsShifts = [];
+  let TSFlagsFields = ["AddrModeBits",
+                       "SizeFlag",
+                       "IndexModeBits",
+                       "Opcode"];
+  let TSFlagsShifts = [0,
+                       4,
+                       7,
+                       9];
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/ARM/ARMAddressingModes.h b/llvm/lib/Target/ARM/ARMAddressingModes.h
new file mode 100644
index 0000000..3f47a69
--- /dev/null
+++ b/llvm/lib/Target/ARM/ARMAddressingModes.h
@@ -0,0 +1,394 @@
+//===- ARMAddressingModes.h - ARM Addressing Modes --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the ARM addressing mode implementation stuff.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_ARM_ARMADDRESSINGMODES_H
+#define LLVM_TARGET_ARM_ARMADDRESSINGMODES_H
+
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+
+namespace llvm {
+  
+/// ARM_AM - ARM Addressing Mode Stuff
+namespace ARM_AM {
+  enum ShiftOpc {
+    no_shift = 0,
+    asr,
+    lsl,
+    lsr,
+    ror,
+    rrx
+  };
+  
+  enum AddrOpc {
+    add = '+', sub = '-'
+  };
+  
+  static inline const char *getShiftOpcStr(ShiftOpc Op) {
+    switch (Op) {
+    default: assert(0 && "Unknown shift opc!");
+    case ARM_AM::asr: return "asr";
+    case ARM_AM::lsl: return "lsl";
+    case ARM_AM::lsr: return "lsr";
+    case ARM_AM::ror: return "ror";
+    case ARM_AM::rrx: return "rrx";
+    }
+  }
+  
+  static inline ShiftOpc getShiftOpcForNode(SDOperand N) {
+    switch (N.getOpcode()) {
+    default:          return ARM_AM::no_shift;
+    case ISD::SHL:    return ARM_AM::lsl;
+    case ISD::SRL:    return ARM_AM::lsr;
+    case ISD::SRA:    return ARM_AM::asr;
+    case ISD::ROTR:   return ARM_AM::ror;
+    //case ISD::ROTL:  // Only if imm -> turn into ROTR.
+    // Can't handle RRX here, because it would require folding a flag into
+    // the addressing mode.  :(  This causes us to miss certain things.
+    //case ARMISD::RRX: return ARM_AM::rrx;
+    }
+  }
+
+  enum AMSubMode {
+    bad_am_submode = 0,
+    ia,
+    ib,
+    da,
+    db
+  };
+
+  static inline const char *getAMSubModeStr(AMSubMode Mode) {
+    switch (Mode) {
+    default: assert(0 && "Unknown addressing sub-mode!");
+    case ARM_AM::ia: return "ia";
+    case ARM_AM::ib: return "ib";
+    case ARM_AM::da: return "da";
+    case ARM_AM::db: return "db";
+    }
+  }
+
+  static inline const char *getAMSubModeAltStr(AMSubMode Mode, bool isLD) {
+    switch (Mode) {
+    default: assert(0 && "Unknown addressing sub-mode!");
+    case ARM_AM::ia: return isLD ? "fd" : "ea";
+    case ARM_AM::ib: return isLD ? "ed" : "fa";
+    case ARM_AM::da: return isLD ? "fa" : "ed";
+    case ARM_AM::db: return isLD ? "ea" : "fd";
+    }
+  }
+
+  /// rotr32 - Rotate a 32-bit unsigned value right by a specified # bits.
+  ///
+  static inline unsigned rotr32(unsigned Val, unsigned Amt) {
+    assert(Amt < 32 && "Invalid rotate amount");
+    return (Val >> Amt) | (Val << ((32-Amt)&31));
+  }
+  
+  /// rotl32 - Rotate a 32-bit unsigned value left by a specified # bits.
+  ///
+  static inline unsigned rotl32(unsigned Val, unsigned Amt) {
+    assert(Amt < 32 && "Invalid rotate amount");
+    return (Val << Amt) | (Val >> ((32-Amt)&31));
+  }
+  
+  //===--------------------------------------------------------------------===//
+  // Addressing Mode #1: shift_operand with registers
+  //===--------------------------------------------------------------------===//
+  //
+  // This 'addressing mode' is used for arithmetic instructions.  It can
+  // represent things like:
+  //   reg
+  //   reg [asr|lsl|lsr|ror|rrx] reg
+  //   reg [asr|lsl|lsr|ror|rrx] imm
+  //
+  // This is stored three operands [rega, regb, opc].  The first is the base
+  // reg, the second is the shift amount (or reg0 if not present or imm).  The
+  // third operand encodes the shift opcode and the imm if a reg isn't present.
+  //
+  static inline unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm) {
+    return ShOp | (Imm << 3);
+  }
+  static inline unsigned getSORegOffset(unsigned Op) {
+    return Op >> 3;
+  }
+  static inline ShiftOpc getSORegShOp(unsigned Op) {
+    return (ShiftOpc)(Op & 7);
+  }
+
+  /// getSOImmValImm - Given an encoded imm field for the reg/imm form, return
+  /// the 8-bit imm value.
+  static inline unsigned getSOImmValImm(unsigned Imm) {
+    return Imm & 0xFF;
+  }
+  /// getSOImmValRotate - Given an encoded imm field for the reg/imm form, return
+  /// the rotate amount.
+  static inline unsigned getSOImmValRot(unsigned Imm) {
+    return (Imm >> 8) * 2;
+  }
+  
+  /// getSOImmValRotate - Try to handle Imm with an immediate shifter operand,
+  /// computing the rotate amount to use.  If this immediate value cannot be
+  /// handled with a single shifter-op, determine a good rotate amount that will
+  /// take a maximal chunk of bits out of the immediate.
+  static inline unsigned getSOImmValRotate(unsigned Imm) {
+    // 8-bit (or less) immediates are trivially shifter_operands with a rotate
+    // of zero.
+    if ((Imm & ~255U) == 0) return 0;
+    
+    // Use CTZ to compute the rotate amount.
+    unsigned TZ = CountTrailingZeros_32(Imm);
+    
+    // Rotate amount must be even.  Something like 0x200 must be rotated 8 bits,
+    // not 9.
+    unsigned RotAmt = TZ & ~1;
+    
+    // If we can handle this spread, return it.
+    if ((rotr32(Imm, RotAmt) & ~255U) == 0)
+      return (32-RotAmt)&31;  // HW rotates right, not left.
+
+    // For values like 0xF000000F, we should skip the first run of ones, then
+    // retry the hunt.
+    if (Imm & 1) {
+      unsigned TrailingOnes = CountTrailingZeros_32(~Imm);
+      if (TrailingOnes != 32) {  // Avoid overflow on 0xFFFFFFFF
+        // Restart the search for a high-order bit after the initial seconds of
+        // ones.
+        unsigned TZ2 = CountTrailingZeros_32(Imm & ~((1 << TrailingOnes)-1));
+      
+        // Rotate amount must be even.
+        unsigned RotAmt2 = TZ2 & ~1;
+        
+        // If this fits, use it.
+        if (RotAmt2 != 32 && (rotr32(Imm, RotAmt2) & ~255U) == 0)
+          return (32-RotAmt2)&31;  // HW rotates right, not left.
+      }
+    }
+    
+    // Otherwise, we have no way to cover this span of bits with a single
+    // shifter_op immediate.  Return a chunk of bits that will be useful to
+    // handle.
+    return (32-RotAmt)&31;  // HW rotates right, not left.
+  }
+
+  /// getSOImmVal - Given a 32-bit immediate, if it is something that can fit
+  /// into an shifter_operand immediate operand, return the 12-bit encoding for
+  /// it.  If not, return -1.
+  static inline int getSOImmVal(unsigned Arg) {
+    // 8-bit (or less) immediates are trivially shifter_operands with a rotate
+    // of zero.
+    if ((Arg & ~255U) == 0) return Arg;
+    
+    unsigned RotAmt = getSOImmValRotate(Arg);
+
+    // If this cannot be handled with a single shifter_op, bail out.
+    if (rotr32(~255U, RotAmt) & Arg)
+      return -1;
+      
+    // Encode this correctly.
+    return rotl32(Arg, RotAmt) | ((RotAmt>>1) << 8);
+  }
+  
+  /// isSOImmTwoPartVal - Return true if the specified value can be obtained by
+  /// or'ing together two SOImmVal's.
+  static inline bool isSOImmTwoPartVal(unsigned V) {
+    // If this can be handled with a single shifter_op, bail out.
+    V = rotr32(~255U, getSOImmValRotate(V)) & V;
+    if (V == 0)
+      return false;
+    
+    // If this can be handled with two shifter_op's, accept.
+    V = rotr32(~255U, getSOImmValRotate(V)) & V;
+    return V == 0;
+  }
+  
+  /// getSOImmTwoPartFirst - If V is a value that satisfies isSOImmTwoPartVal,
+  /// return the first chunk of it.
+  static inline unsigned getSOImmTwoPartFirst(unsigned V) {
+    return rotr32(255U, getSOImmValRotate(V)) & V;
+  }
+
+  /// getSOImmTwoPartSecond - If V is a value that satisfies isSOImmTwoPartVal,
+  /// return the second chunk of it.
+  static inline unsigned getSOImmTwoPartSecond(unsigned V) {
+    // Mask out the first hunk.  
+    V = rotr32(~255U, getSOImmValRotate(V)) & V;
+    
+    // Take what's left.
+    assert(V == (rotr32(255U, getSOImmValRotate(V)) & V));
+    return V;
+  }
+  
+  /// getThumbImmValShift - Try to handle Imm with a 8-bit immediate followed
+  /// by a left shift. Returns the shift amount to use.
+  static inline unsigned getThumbImmValShift(unsigned Imm) {
+    // 8-bit (or less) immediates are trivially immediate operand with a shift
+    // of zero.
+    if ((Imm & ~255U) == 0) return 0;
+
+    // Use CTZ to compute the shift amount.
+    return CountTrailingZeros_32(Imm);
+  }
+
+  /// isThumbImmShiftedVal - Return true if the specified value can be obtained
+  /// by left shifting a 8-bit immediate.
+  static inline bool isThumbImmShiftedVal(unsigned V) {
+    // If this can be handled with 
+    V = (~255U << getThumbImmValShift(V)) & V;
+    return V == 0;
+  }
+
+  /// getThumbImmNonShiftedVal - If V is a value that satisfies
+  /// isThumbImmShiftedVal, return the non-shiftd value.
+  static inline unsigned getThumbImmNonShiftedVal(unsigned V) {
+    return V >> getThumbImmValShift(V);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Addressing Mode #2
+  //===--------------------------------------------------------------------===//
+  //
+  // This is used for most simple load/store instructions.
+  //
+  // addrmode2 := reg +/- reg shop imm
+  // addrmode2 := reg +/- imm12
+  //
+  // The first operand is always a Reg.  The second operand is a reg if in
+  // reg/reg form, otherwise it's reg#0.  The third field encodes the operation
+  // in bit 12, the immediate in bits 0-11, and the shift op in 13-15.
+  //
+  // If this addressing mode is a frame index (before prolog/epilog insertion
+  // and code rewriting), this operand will have the form:  FI#, reg0, <offs>
+  // with no shift amount for the frame offset.
+  // 
+  static inline unsigned getAM2Opc(AddrOpc Opc, unsigned Imm12, ShiftOpc SO) {
+    assert(Imm12 < (1 << 12) && "Imm too large!");
+    bool isSub = Opc == sub;
+    return Imm12 | ((int)isSub << 12) | (SO << 13);
+  }
+  static inline unsigned getAM2Offset(unsigned AM2Opc) {
+    return AM2Opc & ((1 << 12)-1);
+  }
+  static inline AddrOpc getAM2Op(unsigned AM2Opc) {
+    return ((AM2Opc >> 12) & 1) ? sub : add;
+  }
+  static inline ShiftOpc getAM2ShiftOpc(unsigned AM2Opc) {
+    return (ShiftOpc)(AM2Opc >> 13);
+  }
+  
+  
+  //===--------------------------------------------------------------------===//
+  // Addressing Mode #3
+  //===--------------------------------------------------------------------===//
+  //
+  // This is used for sign-extending loads, and load/store-pair instructions.
+  //
+  // addrmode3 := reg +/- reg
+  // addrmode3 := reg +/- imm8
+  //
+  // The first operand is always a Reg.  The second operand is a reg if in
+  // reg/reg form, otherwise it's reg#0.  The third field encodes the operation
+  // in bit 8, the immediate in bits 0-7.
+  
+  /// getAM3Opc - This function encodes the addrmode3 opc field.
+  static inline unsigned getAM3Opc(AddrOpc Opc, unsigned char Offset) {
+    bool isSub = Opc == sub;
+    return ((int)isSub << 8) | Offset;
+  }
+  static inline unsigned char getAM3Offset(unsigned AM3Opc) {
+    return AM3Opc & 0xFF;
+  }
+  static inline AddrOpc getAM3Op(unsigned AM3Opc) {
+    return ((AM3Opc >> 8) & 1) ? sub : add;
+  }
+  
+  //===--------------------------------------------------------------------===//
+  // Addressing Mode #4
+  //===--------------------------------------------------------------------===//
+  //
+  // This is used for load / store multiple instructions.
+  //
+  // addrmode4 := reg, <mode>
+  //
+  // The four modes are:
+  //    IA - Increment after
+  //    IB - Increment before
+  //    DA - Decrement after
+  //    DB - Decrement before
+  //
+  // If the 4th bit (writeback)is set, then the base register is updated after
+  // the memory transfer.
+
+  static inline AMSubMode getAM4SubMode(unsigned Mode) {
+    return (AMSubMode)(Mode & 0x7);
+  }
+
+  static inline unsigned getAM4ModeImm(AMSubMode SubMode, bool WB = false) {
+    return (int)SubMode | ((int)WB << 3);
+  }
+
+  static inline bool getAM4WBFlag(unsigned Mode) {
+    return (Mode >> 3) & 1;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Addressing Mode #5
+  //===--------------------------------------------------------------------===//
+  //
+  // This is used for coprocessor instructions, such as FP load/stores.
+  //
+  // addrmode5 := reg +/- imm8*4
+  //
+  // The first operand is always a Reg.  The third field encodes the operation
+  // in bit 8, the immediate in bits 0-7.
+  //
+  // This can also be used for FP load/store multiple ops. The third field encodes
+  // writeback mode in bit 8, the number of registers (or 2 times the number of
+  // registers for DPR ops) in bits 0-7. In addition, bit 9-11 encodes one of the
+  // following two sub-modes:
+  //
+  //    IA - Increment after
+  //    DB - Decrement before
+  
+  /// getAM5Opc - This function encodes the addrmode5 opc field.
+  static inline unsigned getAM5Opc(AddrOpc Opc, unsigned char Offset) {
+    bool isSub = Opc == sub;
+    return ((int)isSub << 8) | Offset;
+  }
+  static inline unsigned char getAM5Offset(unsigned AM5Opc) {
+    return AM5Opc & 0xFF;
+  }
+  static inline AddrOpc getAM5Op(unsigned AM5Opc) {
+    return ((AM5Opc >> 8) & 1) ? sub : add;
+  }
+
+  /// getAM5Opc - This function encodes the addrmode5 opc field for FLDM and
+  /// FSTM instructions.
+  static inline unsigned getAM5Opc(AMSubMode SubMode, bool WB,
+                                   unsigned char Offset) {
+    assert((SubMode == ia || SubMode == db) &&
+           "Illegal addressing mode 5 sub-mode!");
+    return ((int)SubMode << 9) | ((int)WB << 8) | Offset;
+  }
+  static inline AMSubMode getAM5SubMode(unsigned AM5Opc) {
+    return (AMSubMode)((AM5Opc >> 9) & 0x7);
+  }
+  static inline bool getAM5WBFlag(unsigned AM5Opc) {
+    return ((AM5Opc >> 8) & 1);
+  }
+  
+} // end namespace ARM_AM
+} // end namespace llvm
+
+#endif
+
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
index 653d500..a6ceb85 100644
--- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -15,54 +15,49 @@
 
 #define DEBUG_TYPE "asm-printer"
 #include "ARM.h"
-#include "ARMInstrInfo.h"
+#include "ARMTargetMachine.h"
+#include "ARMAddressingModes.h"
+#include "ARMConstantPoolValue.h"
+#include "ARMMachineFunctionInfo.h"
 #include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
 #include "llvm/Module.h"
 #include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/DwarfWriter.h"
+#include "llvm/CodeGen/MachineDebugInfo.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
-#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetMachine.h"
-#include "llvm/Support/Mangler.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Mangler.h"
 #include "llvm/Support/MathExtras.h"
 #include <cctype>
+#include <iostream>
+#include <set>
 using namespace llvm;
 
 STATISTIC(EmittedInsts, "Number of machine instrs printed");
 
 namespace {
-  static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {
-    switch (CC) {
-    default: assert(0 && "Unknown condition code");
-    case ARMCC::EQ:  return "eq";
-    case ARMCC::NE:  return "ne";
-    case ARMCC::CS:  return "cs";
-    case ARMCC::CC:  return "cc";
-    case ARMCC::MI:  return "mi";
-    case ARMCC::PL:  return "pl";
-    case ARMCC::VS:  return "vs";
-    case ARMCC::VC:  return "vc";
-    case ARMCC::HI:  return "hi";
-    case ARMCC::LS:  return "ls";
-    case ARMCC::GE:  return "ge";
-    case ARMCC::LT:  return "lt";
-    case ARMCC::GT:  return "gt";
-    case ARMCC::LE:  return "le";
-    case ARMCC::AL:  return "al";
-    }
-  }
-
   struct VISIBILITY_HIDDEN ARMAsmPrinter : public AsmPrinter {
     ARMAsmPrinter(std::ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
-      : AsmPrinter(O, TM, T) {
+      : AsmPrinter(O, TM, T), DW(O, this, T), AFI(NULL), InCPMode(false) {
+      Subtarget = &TM.getSubtarget<ARMSubtarget>();
     }
 
+    DwarfWriter DW;
+
+    /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
+    /// make the right decision when printing asm code for different targets.
+    const ARMSubtarget *Subtarget;
+
+    /// AFI - Keep a pointer to ARMFunctionInfo for the current
+    /// MachineFunction
+    ARMFunctionInfo *AFI;
+
     /// We name each basic block in a Function with a unique number, so
     /// that we can consistently refer to them later. This is cleared
     /// at the beginning of each call to runOnMachineFunction().
@@ -70,22 +65,79 @@
     typedef std::map<const Value *, unsigned> ValueMapTy;
     ValueMapTy NumberForBB;
 
+    /// Keeps the set of GlobalValues that require non-lazy-pointers for
+    /// indirect access.
+    std::set<std::string> GVNonLazyPtrs;
+
+    /// Keeps the set of external function GlobalAddresses that the asm
+    /// printer should generate stubs for.
+    std::set<std::string> FnStubs;
+
+    /// True if asm printer is printing a series of CONSTPOOL_ENTRY.
+    bool InCPMode;
+    
     virtual const char *getPassName() const {
       return "ARM Assembly Printer";
     }
 
-    void printAddrMode1(const MachineInstr *MI, int opNum);
-    void printAddrMode2(const MachineInstr *MI, int opNum);
-    void printAddrMode5(const MachineInstr *MI, int opNum);
-    void printOperand(const MachineInstr *MI, int opNum);
-    void printMemOperand(const MachineInstr *MI, int opNum,
-                         const char *Modifier = 0);
+    void printOperand(const MachineInstr *MI, int opNum,
+                      const char *Modifier = 0);
+    void printSOImmOperand(const MachineInstr *MI, int opNum);
+    void printSORegOperand(const MachineInstr *MI, int opNum);
+    void printAddrMode2Operand(const MachineInstr *MI, int OpNo);
+    void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNo);
+    void printAddrMode3Operand(const MachineInstr *MI, int OpNo);
+    void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNo);
+    void printAddrMode4Operand(const MachineInstr *MI, int OpNo,
+                               const char *Modifier = 0);
+    void printAddrMode5Operand(const MachineInstr *MI, int OpNo,
+                               const char *Modifier = 0);
+    void printAddrModePCOperand(const MachineInstr *MI, int OpNo,
+                                const char *Modifier = 0);
+    void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNo);
+    void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNo,
+                                      unsigned Scale);
+    void printThumbAddrModeRI5_1Operand(const MachineInstr *MI, int OpNo);
+    void printThumbAddrModeRI5_2Operand(const MachineInstr *MI, int OpNo);
+    void printThumbAddrModeRI5_4Operand(const MachineInstr *MI, int OpNo);
+    void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNo);
     void printCCOperand(const MachineInstr *MI, int opNum);
+    void printPCLabel(const MachineInstr *MI, int opNum);
+    void printRegisterList(const MachineInstr *MI, int opNum);
+    void printCPInstOperand(const MachineInstr *MI, int opNum,
+                            const char *Modifier);
+    void printJTBlockOperand(const MachineInstr *MI, int opNum);
+
+    virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+                                 unsigned AsmVariant, const char *ExtraCode);
 
     bool printInstruction(const MachineInstr *MI);  // autogenerated.
+    void printMachineInstruction(const MachineInstr *MI);
     bool runOnMachineFunction(MachineFunction &F);
     bool doInitialization(Module &M);
     bool doFinalization(Module &M);
+
+    virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
+      printDataDirective(MCPV->getType());
+
+      ARMConstantPoolValue *ACPV = (ARMConstantPoolValue*)MCPV;
+      std::string Name = Mang->getValueName(ACPV->getGV());
+      if (ACPV->isNonLazyPointer()) {
+        GVNonLazyPtrs.insert(Name);
+        O << TAI->getPrivateGlobalPrefix() << Name << "$non_lazy_ptr";
+      } else
+        O << Name;
+      if (ACPV->getPCAdjustment() != 0)
+        O << "-(" << TAI->getPrivateGlobalPrefix() << "PC"
+          << utostr(ACPV->getLabelId())
+          << "+" << (unsigned)ACPV->getPCAdjustment() << ")";
+      O << "\n";
+    }
+    
+    void getAnalysisUsage(AnalysisUsage &AU) const {
+      AU.setPreservesAll();
+      AU.addRequired<MachineDebugInfo>();
+    }
   };
 } // end of anonymous namespace
 
@@ -97,55 +149,64 @@
 /// regardless of whether the function is in SSA form.
 ///
 FunctionPass *llvm::createARMCodePrinterPass(std::ostream &o,
-                                               TargetMachine &tm) {
+                                             ARMTargetMachine &tm) {
   return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo());
 }
 
-/// runOnMachineFunction - This uses the printMachineInstruction()
+/// runOnMachineFunction - This uses the printInstruction()
 /// method to print assembly for each instruction.
 ///
 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
-  SetupMachineFunction(MF);
-  O << "\n\n";
+  AFI = MF.getInfo<ARMFunctionInfo>();
 
-  // Print out constants referenced by the function
-  EmitConstantPool(MF.getConstantPool());
-
-  const std::vector<MachineConstantPoolEntry>
-    &CP = MF.getConstantPool()->getConstants();
-  for (unsigned i = 0, e = CP.size(); i != e; ++i) {
-    MachineConstantPoolEntry CPE = CP[i];
-    if (!CPE.isMachineConstantPoolEntry()){
-      Constant *CV = CPE.Val.ConstVal;
-      if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
-        if (GV->hasExternalWeakLinkage()) {
-          ExtWeakSymbols.insert(GV);
-        }
-      }
-    }
+  if (Subtarget->isDarwin()) {
+    DW.SetDebugInfo(&getAnalysis<MachineDebugInfo>());
   }
 
-  // Print out jump tables referenced by the function
-  EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
+  SetupMachineFunction(MF);
+  O << "\n";
 
+  // NOTE: we don't print out constant pools here, they are handled as
+  // instructions.
+
+  O << "\n";
   // Print out labels for the function.
   const Function *F = MF.getFunction();
-  SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
-
   switch (F->getLinkage()) {
   default: assert(0 && "Unknown linkage type!");
   case Function::InternalLinkage:
+    SwitchToTextSection("\t.text", F);
     break;
   case Function::ExternalLinkage:
+    SwitchToTextSection("\t.text", F);
     O << "\t.globl\t" << CurrentFnName << "\n";
     break;
   case Function::WeakLinkage:
   case Function::LinkOnceLinkage:
-    O << TAI->getWeakRefDirective() << CurrentFnName << "\n";
+    if (Subtarget->isDarwin()) {
+      SwitchToTextSection(
+                ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F);
+      O << "\t.globl\t" << CurrentFnName << "\n";
+      O << "\t.weak_definition\t" << CurrentFnName << "\n";
+    } else {
+      O << TAI->getWeakRefDirective() << CurrentFnName << "\n";
+    }
     break;
   }
-  EmitAlignment(2, F);
+
+  if (AFI->isThumbFunction()) {
+    EmitAlignment(1, F);
+    O << "\t.code\t16\n";
+    O << "\t.thumb_func\t" << CurrentFnName << "\n";
+    InCPMode = false;
+  } else
+    EmitAlignment(2, F);
+
   O << CurrentFnName << ":\n";
+  if (Subtarget->isDarwin()) {
+    // Emit pre-function debug information.
+    DW.BeginFunction(&MF);
+  }
 
   // Print out code for the function.
   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
@@ -158,127 +219,340 @@
     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
          II != E; ++II) {
       // Print the assembly for the instruction.
-      O << "\t";
-      ++EmittedInsts;
-      printInstruction(II);
+      printMachineInstruction(II);
     }
   }
 
+  if (TAI->hasDotTypeDotSizeDirective())
+    O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n";
+
+  if (Subtarget->isDarwin()) {
+    // Emit post-function debug information.
+    DW.EndFunction();
+  }
+
   return false;
 }
 
-void ARMAsmPrinter::printAddrMode1(const MachineInstr *MI, int opNum) {
-  const MachineOperand &Arg       = MI->getOperand(opNum);
-  const MachineOperand &Shift     = MI->getOperand(opNum + 1);
-  const MachineOperand &ShiftType = MI->getOperand(opNum + 2);
-
-  if(Arg.isImmediate()) {
-    assert(Shift.getImmedValue() == 0);
-    printOperand(MI, opNum);
-  } else {
-    assert(Arg.isRegister());
-    printOperand(MI, opNum);
-    if(Shift.isRegister() || Shift.getImmedValue() != 0) {
-      const char *s = NULL;
-      switch(ShiftType.getImmedValue()) {
-      case ARMShift::LSL:
-	s = ", lsl ";
-	break;
-      case ARMShift::LSR:
-	s = ", lsr ";
-	break;
-      case ARMShift::ASR:
-	s = ", asr ";
-	break;
-      case ARMShift::ROR:
-	s = ", ror ";
-	break;
-      case ARMShift::RRX:
-	s = ", rrx ";
-	break;
-      }
-      O << s;
-      printOperand(MI, opNum + 1);
-    }
-  }
-}
-
-void ARMAsmPrinter::printAddrMode2(const MachineInstr *MI, int opNum) {
-  const MachineOperand &Arg    = MI->getOperand(opNum);
-  const MachineOperand &Offset = MI->getOperand(opNum + 1);
-  assert(Offset.isImmediate());
-
-  if (Arg.isConstantPoolIndex()) {
-    assert(Offset.getImmedValue() == 0);
-    printOperand(MI, opNum);
-  } else {
-    assert(Arg.isRegister());
-    O << '[';
-    printOperand(MI, opNum);
-    O << ", ";
-    printOperand(MI, opNum + 1);
-    O << ']';
-  }
-}
-
-void ARMAsmPrinter::printAddrMode5(const MachineInstr *MI, int opNum) {
-  const MachineOperand &Arg    = MI->getOperand(opNum);
-  const MachineOperand &Offset = MI->getOperand(opNum + 1);
-  assert(Offset.isImmediate());
-
-  if (Arg.isConstantPoolIndex()) {
-    assert(Offset.getImmedValue() == 0);
-    printOperand(MI, opNum);
-  } else {
-    assert(Arg.isRegister());
-    O << '[';
-    printOperand(MI, opNum);
-    O << ", ";
-    printOperand(MI, opNum + 1);
-    O << ']';
-  }
-}
-
-void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
-  const MachineOperand &MO = MI->getOperand (opNum);
-  const MRegisterInfo &RI = *TM.getRegisterInfo();
+void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
+                                 const char *Modifier) {
+  const MachineOperand &MO = MI->getOperand(opNum);
   switch (MO.getType()) {
   case MachineOperand::MO_Register:
     if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
-      O << LowercaseString (RI.get(MO.getReg()).Name);
+      O << TM.getRegisterInfo()->get(MO.getReg()).Name;
     else
       assert(0 && "not implemented");
     break;
-  case MachineOperand::MO_Immediate:
-    O << "#" << (int)MO.getImmedValue();
+  case MachineOperand::MO_Immediate: {
+    if (!Modifier || strcmp(Modifier, "no_hash") != 0)
+      O << "#";
+
+    O << (int)MO.getImmedValue();
     break;
+  }
   case MachineOperand::MO_MachineBasicBlock:
     printBasicBlockLabel(MO.getMachineBasicBlock());
     return;
   case MachineOperand::MO_GlobalAddress: {
+    bool isCallOp = Modifier && !strcmp(Modifier, "call");
     GlobalValue *GV = MO.getGlobal();
     std::string Name = Mang->getValueName(GV);
-    O << Name;
-    if (GV->hasExternalWeakLinkage()) {
+    bool isExt = (GV->isExternal() || GV->hasWeakLinkage() ||
+                  GV->hasLinkOnceLinkage());
+    if (isExt && isCallOp && Subtarget->isDarwin() &&
+        TM.getRelocationModel() != Reloc::Static) {
+      O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
+      FnStubs.insert(Name);
+    } else
+      O << Name;
+
+    if (GV->hasExternalWeakLinkage())
       ExtWeakSymbols.insert(GV);
-    }
+    break;
   }
+  case MachineOperand::MO_ExternalSymbol: {
+    bool isCallOp = Modifier && !strcmp(Modifier, "call");
+    std::string Name(TAI->getGlobalPrefix());
+    Name += MO.getSymbolName();
+    if (isCallOp && Subtarget->isDarwin() &&
+        TM.getRelocationModel() != Reloc::Static) {
+      O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
+      FnStubs.insert(Name);
+    } else
+      O << Name;
     break;
-  case MachineOperand::MO_ExternalSymbol:
-    O << TAI->getGlobalPrefix() << MO.getSymbolName();
-    break;
+  }
   case MachineOperand::MO_ConstantPoolIndex:
     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
       << '_' << MO.getConstantPoolIndex();
     break;
+  case MachineOperand::MO_JumpTableIndex:
+    O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
+      << '_' << MO.getJumpTableIndex();
+    break;
   default:
     O << "<unknown operand type>"; abort (); break;
   }
 }
 
-void ARMAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
-                                      const char *Modifier) {
-  assert(0 && "not implemented");
+/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
+/// immediate in bits 0-7.
+void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) {
+  const MachineOperand &MO = MI->getOperand(OpNum);
+  assert(MO.isImmediate() && (MO.getImmedValue() < (1 << 12)) &&
+         "Not a valid so_imm value!");
+  unsigned Imm = ARM_AM::getSOImmValImm(MO.getImmedValue());
+  unsigned Rot = ARM_AM::getSOImmValRot(MO.getImmedValue());
+  
+  // Print low-level immediate formation info, per
+  // A5.1.3: "Data-processing operands - Immediate".
+  if (Rot) {
+    O << "#" << Imm << ", " << Rot;
+    // Pretty printed version.
+    O << ' ' << TAI->getCommentString() << ' ' << (int)ARM_AM::rotr32(Imm, Rot);
+  } else {
+    O << "#" << Imm;
+  }
+}
+
+// so_reg is a 4-operand unit corresponding to register forms of the A5.1
+// "Addressing Mode 1 - Data-processing operands" forms.  This includes:
+//    REG 0   0    - e.g. R5
+//    REG REG 0,SH_OPC     - e.g. R5, ROR R3
+//    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
+void ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op) {
+  const MachineOperand &MO1 = MI->getOperand(Op);
+  const MachineOperand &MO2 = MI->getOperand(Op+1);
+  const MachineOperand &MO3 = MI->getOperand(Op+2);
+
+  assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
+  O << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+
+  // Print the shift opc.
+  O << ", "
+    << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImmedValue()))
+    << " ";
+
+  if (MO2.getReg()) {
+    assert(MRegisterInfo::isPhysicalRegister(MO2.getReg()));
+    O << TM.getRegisterInfo()->get(MO2.getReg()).Name;
+    assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
+  } else {
+    O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
+  }
+}
+
+void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) {
+  const MachineOperand &MO1 = MI->getOperand(Op);
+  const MachineOperand &MO2 = MI->getOperand(Op+1);
+  const MachineOperand &MO3 = MI->getOperand(Op+2);
+
+  if (!MO1.isRegister()) {   // FIXME: This is for CP entries, but isn't right.
+    printOperand(MI, Op);
+    return;
+  }
+
+  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+
+  if (!MO2.getReg()) {
+    if (ARM_AM::getAM2Offset(MO3.getImm()))  // Don't print +0.
+      O << ", #"
+        << (char)ARM_AM::getAM2Op(MO3.getImm())
+        << ARM_AM::getAM2Offset(MO3.getImm());
+    O << "]";
+    return;
+  }
+
+  O << ", "
+    << (char)ARM_AM::getAM2Op(MO3.getImm())
+    << TM.getRegisterInfo()->get(MO2.getReg()).Name;
+  
+  if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
+    O << ", "
+      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImmedValue()))
+      << " #" << ShImm;
+  O << "]";
+}
+
+void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op){
+  const MachineOperand &MO1 = MI->getOperand(Op);
+  const MachineOperand &MO2 = MI->getOperand(Op+1);
+
+  if (!MO1.getReg()) {
+    if (ARM_AM::getAM2Offset(MO2.getImm()))  // Don't print +0.
+      O << "#"
+        << (char)ARM_AM::getAM2Op(MO2.getImm())
+        << ARM_AM::getAM2Offset(MO2.getImm());
+    return;
+  }
+
+  O << (char)ARM_AM::getAM2Op(MO2.getImm())
+    << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+  
+  if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
+    O << ", "
+      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImmedValue()))
+      << " #" << ShImm;
+}
+
+void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op) {
+  const MachineOperand &MO1 = MI->getOperand(Op);
+  const MachineOperand &MO2 = MI->getOperand(Op+1);
+  const MachineOperand &MO3 = MI->getOperand(Op+2);
+  
+  assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
+  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+
+  if (MO2.getReg()) {
+    O << ", "
+      << (char)ARM_AM::getAM3Op(MO3.getImm())
+      << TM.getRegisterInfo()->get(MO2.getReg()).Name
+      << "]";
+    return;
+  }
+  
+  if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
+    O << ", #"
+      << (char)ARM_AM::getAM3Op(MO3.getImm())
+      << ImmOffs;
+  O << "]";
+}
+
+void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op){
+  const MachineOperand &MO1 = MI->getOperand(Op);
+  const MachineOperand &MO2 = MI->getOperand(Op+1);
+
+  if (MO1.getReg()) {
+    O << (char)ARM_AM::getAM3Op(MO2.getImm())
+      << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+    return;
+  }
+
+  unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
+  O << "#"
+  << (char)ARM_AM::getAM3Op(MO2.getImm())
+    << ImmOffs;
+}
+  
+void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
+                                          const char *Modifier) {
+  const MachineOperand &MO1 = MI->getOperand(Op);
+  const MachineOperand &MO2 = MI->getOperand(Op+1);
+  ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
+  if (Modifier && strcmp(Modifier, "submode") == 0) {
+    if (MO1.getReg() == ARM::SP) {
+      bool isLDM = (MI->getOpcode() == ARM::LDM ||
+                    MI->getOpcode() == ARM::LDM_RET);
+      O << ARM_AM::getAMSubModeAltStr(Mode, isLDM);
+    } else
+      O << ARM_AM::getAMSubModeStr(Mode);
+  } else {
+    printOperand(MI, Op);
+    if (ARM_AM::getAM4WBFlag(MO2.getImm()))
+      O << "!";
+  }
+}
+
+void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
+                                          const char *Modifier) {
+  const MachineOperand &MO1 = MI->getOperand(Op);
+  const MachineOperand &MO2 = MI->getOperand(Op+1);
+
+  if (!MO1.isRegister()) {   // FIXME: This is for CP entries, but isn't right.
+    printOperand(MI, Op);
+    return;
+  }
+  
+  assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
+
+  if (Modifier && strcmp(Modifier, "submode") == 0) {
+    ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm());
+    if (MO1.getReg() == ARM::SP) {
+      bool isFLDM = (MI->getOpcode() == ARM::FLDMD ||
+                     MI->getOpcode() == ARM::FLDMS);
+      O << ARM_AM::getAMSubModeAltStr(Mode, isFLDM);
+    } else
+      O << ARM_AM::getAMSubModeStr(Mode);
+    return;
+  } else if (Modifier && strcmp(Modifier, "base") == 0) {
+    // Used for FSTM{D|S} and LSTM{D|S} operations.
+    O << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+    if (ARM_AM::getAM5WBFlag(MO2.getImm()))
+      O << "!";
+    return;
+  }
+  
+  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+  
+  if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
+    O << ", #"
+      << (char)ARM_AM::getAM5Op(MO2.getImm())
+      << ImmOffs*4;
+  }
+  O << "]";
+}
+
+void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
+                                           const char *Modifier) {
+  if (Modifier && strcmp(Modifier, "label") == 0) {
+    printPCLabel(MI, Op+1);
+    return;
+  }
+
+  const MachineOperand &MO1 = MI->getOperand(Op);
+  assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
+  O << "[pc, +" << TM.getRegisterInfo()->get(MO1.getReg()).Name << "]";
+}
+
+void
+ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op) {
+  const MachineOperand &MO1 = MI->getOperand(Op);
+  const MachineOperand &MO2 = MI->getOperand(Op+1);
+  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+  O << ", " << TM.getRegisterInfo()->get(MO2.getReg()).Name << "]";
+}
+
+void
+ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
+                                            unsigned Scale) {
+  const MachineOperand &MO1 = MI->getOperand(Op);
+  const MachineOperand &MO2 = MI->getOperand(Op+1);
+
+  if (!MO1.isRegister()) {   // FIXME: This is for CP entries, but isn't right.
+    printOperand(MI, Op);
+    return;
+  }
+
+  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+  if (unsigned ImmOffs = MO2.getImm()) {
+    O << ", #" << ImmOffs;
+    if (Scale > 1)
+      O << " * " << Scale;
+  }
+  O << "]";
+}
+
+void
+ARMAsmPrinter::printThumbAddrModeRI5_1Operand(const MachineInstr *MI, int Op) {
+  printThumbAddrModeRI5Operand(MI, Op, 1);
+}
+void
+ARMAsmPrinter::printThumbAddrModeRI5_2Operand(const MachineInstr *MI, int Op) {
+  printThumbAddrModeRI5Operand(MI, Op, 2);
+}
+void
+ARMAsmPrinter::printThumbAddrModeRI5_4Operand(const MachineInstr *MI, int Op) {
+  printThumbAddrModeRI5Operand(MI, Op, 4);
+}
+
+void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) {
+  const MachineOperand &MO1 = MI->getOperand(Op);
+  const MachineOperand &MO2 = MI->getOperand(Op+1);
+  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+  if (unsigned ImmOffs = MO2.getImm())
+    O << ", #" << ImmOffs << " * 4";
+  O << "]";
 }
 
 void ARMAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
@@ -286,9 +560,140 @@
   O << ARMCondCodeToString((ARMCC::CondCodes)CC);
 }
 
+void ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int opNum) {
+  int Id = (int)MI->getOperand(opNum).getImmedValue();
+  O << TAI->getPrivateGlobalPrefix() << "PC" << Id;
+}
+
+void ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int opNum) {
+  O << "{";
+  for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) {
+    printOperand(MI, i);
+    if (i != e-1) O << ", ";
+  }
+  O << "}";
+}
+
+void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNo,
+                                       const char *Modifier) {
+  assert(Modifier && "This operand only works with a modifier!");
+  // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
+  // data itself.
+  if (!strcmp(Modifier, "label")) {
+    unsigned ID = MI->getOperand(OpNo).getImm();
+    O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
+      << '_' << ID << ":\n";
+  } else {
+    assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
+    unsigned CPI = MI->getOperand(OpNo).getConstantPoolIndex();
+
+    const MachineConstantPoolEntry &MCPE =  // Chasing pointers is fun?
+      MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI];
+    
+    if (MCPE.isMachineConstantPoolEntry())
+      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
+    else
+      EmitGlobalConstant(MCPE.Val.ConstVal);
+  }
+}
+
+void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNo) {
+  const MachineOperand &MO1 = MI->getOperand(OpNo);
+  const MachineOperand &MO2 = MI->getOperand(OpNo+1); // Unique Id
+  unsigned JTI = MO1.getJumpTableIndex();
+  O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
+    << '_' << JTI << '_' << MO2.getImmedValue() << ":\n";
+
+  const char *JTEntryDirective = TAI->getJumpTableDirective();
+  if (!JTEntryDirective)
+    JTEntryDirective = TAI->getData32bitsDirective();
+
+  const MachineFunction *MF = MI->getParent()->getParent();
+  MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
+  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
+  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
+  bool UseSet= TAI->getSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
+  std::set<MachineBasicBlock*> JTSets;
+  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
+    MachineBasicBlock *MBB = JTBBs[i];
+    if (UseSet && JTSets.insert(MBB).second)
+      printSetLabel(JTI, MO2.getImmedValue(), MBB);
+
+    O << JTEntryDirective << ' ';
+    if (UseSet)
+      O << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
+        << '_' << JTI << '_' << MO2.getImmedValue()
+        << "_set_" << MBB->getNumber();
+    else if (TM.getRelocationModel() == Reloc::PIC_) {
+      printBasicBlockLabel(MBB, false, false);
+      // If the arch uses custom Jump Table directives, don't calc relative to JT
+      if (!TAI->getJumpTableDirective()) 
+        O << '-' << TAI->getPrivateGlobalPrefix() << "JTI"
+          << getFunctionNumber() << '_' << JTI << '_' << MO2.getImmedValue();
+    } else
+      printBasicBlockLabel(MBB, false, false);
+    O << '\n';
+  }
+}
+
+
+bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+                                    unsigned AsmVariant, const char *ExtraCode){
+  // Does this asm operand have a single letter operand modifier?
+  if (ExtraCode && ExtraCode[0]) {
+    if (ExtraCode[1] != 0) return true; // Unknown modifier.
+    
+    switch (ExtraCode[0]) {
+    default: return true;  // Unknown modifier.
+    case 'Q':
+      if (TM.getTargetData()->isLittleEndian())
+        break;
+      // Fallthrough
+    case 'R':
+      if (TM.getTargetData()->isBigEndian())
+        break;
+      // Fallthrough
+    case 'H': // Write second word of DI / DF reference.  
+      // Verify that this operand has two consecutive registers.
+      if (!MI->getOperand(OpNo).isRegister() ||
+          OpNo+1 == MI->getNumOperands() ||
+          !MI->getOperand(OpNo+1).isRegister())
+        return true;
+      ++OpNo;   // Return the high-part.
+    }
+  }
+  
+  printOperand(MI, OpNo);
+  return false;
+}
+
+void ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
+  ++EmittedInsts;
+
+  if (MI->getOpcode() == ARM::CONSTPOOL_ENTRY) {
+    if (!InCPMode && AFI->isThumbFunction()) {
+      EmitAlignment(2);
+      InCPMode = true;
+    }
+  } else {
+    if (InCPMode && AFI->isThumbFunction()) {
+      EmitAlignment(1);
+      InCPMode = false;
+    }
+    O << "\t";
+  }
+
+  // Call the autogenerated instruction printer routines.
+  printInstruction(MI);
+}
+
 bool ARMAsmPrinter::doInitialization(Module &M) {
-  AsmPrinter::doInitialization(M);
-  return false; // success
+  if (Subtarget->isDarwin()) {
+    // Emit initial debug information.
+    DW.BeginModule(&M);
+  }
+  
+  return AsmPrinter::doInitialization(M);
 }
 
 bool ARMAsmPrinter::doFinalization(Module &M) {
@@ -302,53 +707,154 @@
     if (EmitSpecialLLVMGlobal(I))
       continue;
 
-    O << "\n\n";
     std::string name = Mang->getValueName(I);
     Constant *C = I->getInitializer();
     unsigned Size = TD->getTypeSize(C->getType());
-    unsigned Align = Log2_32(TD->getTypeAlignment(C->getType()));
+    unsigned Align = TD->getPreferredAlignmentLog(I);
 
     if (C->isNullValue() &&
         !I->hasSection() &&
-        (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
-         I->hasWeakLinkage())) {
-      SwitchToDataSection(".data", I);
-      if (I->hasInternalLinkage())
-        O << "\t.local " << name << "\n";
-
-      O << "\t.comm " << name << "," << Size
-        << "," << (unsigned) (1 << Align);
-      O << "\n";
+        (I->hasInternalLinkage() || I->hasWeakLinkage() ||
+         I->hasLinkOnceLinkage() ||
+         (Subtarget->isDarwin() &&  I->hasExternalLinkage()))) {
+      if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
+      if (I->hasExternalLinkage()) {
+          O << "\t.globl\t" << name << "\n";
+          O << "\t.zerofill __DATA__, __common, " << name << ", "
+            << Size << ", " << Align;
+      } else {
+        SwitchToDataSection(TAI->getDataSection(), I);
+        if (TAI->getLCOMMDirective() != NULL) {
+          if (I->hasInternalLinkage()) {
+            O << TAI->getLCOMMDirective() << name << "," << Size;
+            if (Subtarget->isDarwin())
+              O << "," << Align;
+          } else
+            O << TAI->getCOMMDirective()  << name << "," << Size;
+        } else {
+          if (I->hasInternalLinkage())
+            O << "\t.local\t" << name << "\n";
+          O << TAI->getCOMMDirective()  << name << "," << Size;
+          if (TAI->getCOMMDirectiveTakesAlignment())
+            O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+        }
+      }
+      O << "\t\t" << TAI->getCommentString() << " " << I->getName() << "\n";
+      continue;
     } else {
       switch (I->getLinkage()) {
       default:
         assert(0 && "Unknown linkage type!");
         break;
+      case GlobalValue::LinkOnceLinkage:
+      case GlobalValue::WeakLinkage:
+        if (Subtarget->isDarwin()) {
+          O << "\t.globl " << name << "\n"
+            << "\t.weak_definition " << name << "\n";
+          SwitchToDataSection("\t.section __DATA,__const_coal,coalesced", I);
+        } else {
+          O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n"
+            << "\t.weak " << name << "\n";
+        }
+        break;
       case GlobalValue::ExternalLinkage:
         O << "\t.globl " << name << "\n";
-        break;
+        // FALL THROUGH
       case GlobalValue::InternalLinkage:
+        if (I->isConstant()) {
+          const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
+          if (TAI->getCStringSection() && CVA && CVA->isCString()) {
+            SwitchToDataSection(TAI->getCStringSection(), I);
+            break;
+          }
+        }
+
+        if (I->hasSection() &&
+            (I->getSection() == ".ctors" ||
+             I->getSection() == ".dtors")) {
+          assert(!Subtarget->isDarwin());
+          std::string SectionName = ".section " + I->getSection();
+          SectionName += ",\"aw\",@progbits";
+          SwitchToDataSection(SectionName.c_str());
+        } else {
+          SwitchToDataSection(TAI->getDataSection(), I);
+        }
+
         break;
       }
+    }
 
-      if (I->hasSection() &&
-          (I->getSection() == ".ctors" ||
-           I->getSection() == ".dtors")) {
-        std::string SectionName = ".section " + I->getSection();
-
-        SectionName += ",\"aw\",%progbits";
-
-        SwitchToDataSection(SectionName.c_str());
-      } else {
-        SwitchToDataSection(TAI->getDataSection(), I);
-      }
-
-      EmitAlignment(Align, I);
+    EmitAlignment(Align, I);
+    if (TAI->hasDotTypeDotSizeDirective()) {
       O << "\t.type " << name << ", %object\n";
       O << "\t.size " << name << ", " << Size << "\n";
-      O << name << ":\n";
-      EmitGlobalConstant(C);
     }
+    O << name << ":\n";
+    
+    // If the initializer is a extern weak symbol, remember to emit the weak
+    // reference!
+    if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
+      if (GV->hasExternalWeakLinkage())
+      ExtWeakSymbols.insert(GV);
+
+    EmitGlobalConstant(C);
+    O << '\n';
+  }
+
+  if (Subtarget->isDarwin()) {
+    // Output stubs for dynamically-linked functions
+    unsigned j = 1;
+    for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
+         i != e; ++i, ++j) {
+      if (TM.getRelocationModel() == Reloc::PIC_)
+        SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs,"
+                            "none,16", 0);
+      else
+        SwitchToTextSection(".section __TEXT,__symbol_stub4,symbol_stubs,"
+                            "none,12", 0);
+
+      EmitAlignment(2);
+      O << "\t.code\t32\n";
+
+      O << "L" << *i << "$stub:\n";
+      O << "\t.indirect_symbol " << *i << "\n";
+      O << "\tldr ip, L" << *i << "$slp\n";
+      if (TM.getRelocationModel() == Reloc::PIC_) {
+        O << "L" << *i << "$scv:\n";
+        O << "\tadd ip, pc, ip\n";
+      }
+      O << "\tldr pc, [ip, #0]\n";
+      O << "L" << *i << "$slp:\n";
+      if (TM.getRelocationModel() == Reloc::PIC_)
+        O << "\t.long\tL" << *i << "$lazy_ptr-(L" << *i << "$scv+8)\n";
+      else
+        O << "\t.long\tL" << *i << "$lazy_ptr\n";
+      SwitchToDataSection(".lazy_symbol_pointer", 0);
+      O << "L" << *i << "$lazy_ptr:\n";
+      O << "\t.indirect_symbol " << *i << "\n";
+      O << "\t.long\tdyld_stub_binding_helper\n";
+    }
+    O << "\n";
+
+    // Output non-lazy-pointers for external and common global variables.
+    if (GVNonLazyPtrs.begin() != GVNonLazyPtrs.end())
+      SwitchToDataSection(".non_lazy_symbol_pointer", 0);
+    for (std::set<std::string>::iterator i = GVNonLazyPtrs.begin(),
+           e = GVNonLazyPtrs.end(); i != e; ++i) {
+      O << "L" << *i << "$non_lazy_ptr:\n";
+      O << "\t.indirect_symbol " << *i << "\n";
+      O << "\t.long\t0\n";
+    }
+
+    // Emit initial debug information.
+    DW.EndModule();
+
+    // Funny Darwin hack: This flag tells the linker that no global symbols
+    // contain code that falls through to other global symbols (e.g. the obvious
+    // implementation of multiple entry points).  If this doesn't occur, the
+    // linker can safely perform dead code stripping.  Since LLVM never
+    // generates code that does this, it is always safe to set.
+    O << "\t.subsections_via_symbols\n";
   }
 
   AsmPrinter::doFinalization(M);
diff --git a/llvm/lib/Target/ARM/ARMCommon.cpp b/llvm/lib/Target/ARM/ARMCommon.cpp
deleted file mode 100644
index fd37573..0000000
--- a/llvm/lib/Target/ARM/ARMCommon.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-//===-- ARMCommon.cpp - Define support functions for ARM --------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the "Instituto Nokia de Tecnologia" and
-// is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//
-//
-//===----------------------------------------------------------------------===//
-#include "ARMCommon.h"
-
-static inline unsigned rotateL(unsigned x, unsigned n){
-  return ((x << n) | (x  >> (32 - n)));
-}
-
-static inline unsigned rotateR(unsigned x, unsigned n){
-  return ((x >> n) | (x  << (32 - n)));
-}
-
-// finds the end position of largest sequence of zeros in binary representation
-// of 'immediate'.
-static int findLargestZeroSequence(unsigned immediate){
-  int max_zero_pos = 0;
-  int max_zero_length = 0;
-  int zero_pos;
-  int zero_length;
-  int pos = 0;
-  int end_pos;
-
-  while ((immediate & 0x3) == 0) {
-    immediate = rotateR(immediate, 2);
-    pos+=2;
-  }
-  end_pos = pos+32;
-
-  while (pos<end_pos){
-    while (((immediate & 0x3) != 0)&&(pos<end_pos)) {
-      immediate = rotateR(immediate, 2);
-      pos+=2;
-    }
-    zero_pos = pos;
-    while (((immediate & 0x3) == 0)&&(pos<end_pos)) {
-      immediate = rotateR(immediate, 2);
-      pos+=2;
-    }
-    zero_length = pos - zero_pos;
-    if (zero_length > max_zero_length){
-      max_zero_length = zero_length;
-      max_zero_pos = zero_pos % 32;
-    }
-
-  }
-
-  return (max_zero_pos + max_zero_length) % 32;
-}
-
-std::vector<unsigned> splitImmediate(unsigned immediate){
-  std::vector<unsigned> immediatePieces;
-
-  if (immediate == 0){
-    immediatePieces.push_back(0);
-  } else {
-    int start_pos = findLargestZeroSequence(immediate);
-    unsigned immediate_tmp = rotateR(immediate, start_pos);
-    int pos = 0;
-    while (pos < 32){
-      while(((immediate_tmp&0x3) == 0)&&(pos<32)){
-        immediate_tmp = rotateR(immediate_tmp,2);
-        pos+=2;
-      }
-      if (pos < 32){
-        immediatePieces.push_back(rotateL(immediate_tmp&0xFF,
-                                          (start_pos + pos) % 32 ));
-        immediate_tmp = rotateR(immediate_tmp,8);
-        pos+=8;
-      }
-    }
-  }
-  return immediatePieces;
-}
diff --git a/llvm/lib/Target/ARM/ARMCommon.h b/llvm/lib/Target/ARM/ARMCommon.h
deleted file mode 100644
index c35150b..0000000
--- a/llvm/lib/Target/ARM/ARMCommon.h
+++ /dev/null
@@ -1,22 +0,0 @@
-//===-- ARMCommon.h - Define support functions for ARM ----------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the "Instituto Nokia de Tecnologia" and
-// is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ARM_COMMON_H
-#define ARM_COMMON_H
-
-#include <vector>
-
-std::vector<unsigned> splitImmediate(unsigned immediate);
-
-#endif
diff --git a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
new file mode 100644
index 0000000..183bde8
--- /dev/null
+++ b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
@@ -0,0 +1,490 @@
+//===-- ARMConstantIslandPass.cpp - ARM constant islands --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a pass that splits the constant pool up into 'islands'
+// which are scattered through-out the function.  This is required due to the
+// limited pc-relative displacements that ARM has.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "arm-cp-islands"
+#include "ARM.h"
+#include "ARMInstrInfo.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Statistic.h"
+#include <iostream>
+using namespace llvm;
+
+STATISTIC(NumSplit, "Number of uncond branches inserted");
+
+namespace {
+  /// ARMConstantIslands - Due to limited pc-relative displacements, ARM
+  /// requires constant pool entries to be scattered among the instructions
+  /// inside a function.  To do this, it completely ignores the normal LLVM
+  /// constant pool, instead, it places constants where-ever it feels like with
+  /// special instructions.
+  ///
+  /// The terminology used in this pass includes:
+  ///   Islands - Clumps of constants placed in the function.
+  ///   Water   - Potential places where an island could be formed.
+  ///   CPE     - A constant pool entry that has been placed somewhere, which
+  ///             tracks a list of users.
+  class VISIBILITY_HIDDEN ARMConstantIslands : public MachineFunctionPass {
+    /// NextUID - Assign unique ID's to CPE's.
+    unsigned NextUID;
+    
+    /// BBSizes - The size of each MachineBasicBlock in bytes of code, indexed
+    /// by MBB Number.
+    std::vector<unsigned> BBSizes;
+    
+    /// WaterList - A sorted list of basic blocks where islands could be placed
+    /// (i.e. blocks that don't fall through to the following block, due
+    /// to a return, unreachable, or unconditional branch).
+    std::vector<MachineBasicBlock*> WaterList;
+    
+    /// CPUser - One user of a constant pool, keeping the machine instruction
+    /// pointer, the constant pool being referenced, and the max displacement
+    /// allowed from the instruction to the CP.
+    struct CPUser {
+      MachineInstr *MI;
+      MachineInstr *CPEMI;
+      unsigned MaxDisp;
+      CPUser(MachineInstr *mi, MachineInstr *cpemi, unsigned maxdisp)
+        : MI(mi), CPEMI(cpemi), MaxDisp(maxdisp) {}
+    };
+    
+    /// CPUsers - Keep track of all of the machine instructions that use various
+    /// constant pools and their max displacement.
+    std::vector<CPUser> CPUsers;
+    
+    const TargetInstrInfo *TII;
+    const TargetAsmInfo   *TAI;
+  public:
+    virtual bool runOnMachineFunction(MachineFunction &Fn);
+
+    virtual const char *getPassName() const {
+      return "ARM constant island placement pass";
+    }
+    
+  private:
+    void DoInitialPlacement(MachineFunction &Fn,
+                            std::vector<MachineInstr*> &CPEMIs);
+    void InitialFunctionScan(MachineFunction &Fn,
+                             const std::vector<MachineInstr*> &CPEMIs);
+    void SplitBlockBeforeInstr(MachineInstr *MI);
+    bool HandleConstantPoolUser(MachineFunction &Fn, CPUser &U);
+    void UpdateForInsertedWaterBlock(MachineBasicBlock *NewBB);
+
+    unsigned GetInstSize(MachineInstr *MI) const;
+    unsigned GetOffsetOf(MachineInstr *MI) const;
+  };
+}
+
+/// createARMLoadStoreOptimizationPass - returns an instance of the load / store
+/// optimization pass.
+FunctionPass *llvm::createARMConstantIslandPass() {
+  return new ARMConstantIslands();
+}
+
+bool ARMConstantIslands::runOnMachineFunction(MachineFunction &Fn) {
+  // If there are no constants, there is nothing to do.
+  MachineConstantPool &MCP = *Fn.getConstantPool();
+  if (MCP.isEmpty()) return false;
+  
+  TII = Fn.getTarget().getInstrInfo();
+  TAI = Fn.getTarget().getTargetAsmInfo();
+  
+  // Renumber all of the machine basic blocks in the function, guaranteeing that
+  // the numbers agree with the position of the block in the function.
+  Fn.RenumberBlocks();
+
+  // Perform the initial placement of the constant pool entries.  To start with,
+  // we put them all at the end of the function.
+  std::vector<MachineInstr*> CPEMIs;
+  DoInitialPlacement(Fn, CPEMIs);
+  
+  /// The next UID to take is the first unused one.
+  NextUID = CPEMIs.size();
+  
+  // Do the initial scan of the function, building up information about the
+  // sizes of each block, the location of all the water, and finding all of the
+  // constant pool users.
+  InitialFunctionScan(Fn, CPEMIs);
+  CPEMIs.clear();
+  
+  // Iteratively place constant pool entries until there is no change.
+  bool MadeChange;
+  do {
+    MadeChange = false;
+    for (unsigned i = 0, e = CPUsers.size(); i != e; ++i)
+      MadeChange |= HandleConstantPoolUser(Fn, CPUsers[i]);
+  } while (MadeChange);
+  
+  BBSizes.clear();
+  WaterList.clear();
+  CPUsers.clear();
+    
+  return true;
+}
+
+/// DoInitialPlacement - Perform the initial placement of the constant pool
+/// entries.  To start with, we put them all at the end of the function.
+void ARMConstantIslands::DoInitialPlacement(MachineFunction &Fn,
+                                            std::vector<MachineInstr*> &CPEMIs){
+  // Create the basic block to hold the CPE's.
+  MachineBasicBlock *BB = new MachineBasicBlock();
+  Fn.getBasicBlockList().push_back(BB);
+  
+  // Add all of the constants from the constant pool to the end block, use an
+  // identity mapping of CPI's to CPE's.
+  const std::vector<MachineConstantPoolEntry> &CPs =
+    Fn.getConstantPool()->getConstants();
+  
+  const TargetData &TD = *Fn.getTarget().getTargetData();
+  for (unsigned i = 0, e = CPs.size(); i != e; ++i) {
+    unsigned Size = TD.getTypeSize(CPs[i].getType());
+    // Verify that all constant pool entries are a multiple of 4 bytes.  If not,
+    // we would have to pad them out or something so that instructions stay
+    // aligned.
+    assert((Size & 3) == 0 && "CP Entry not multiple of 4 bytes!");
+    MachineInstr *CPEMI =
+      BuildMI(BB, TII->get(ARM::CONSTPOOL_ENTRY))
+                           .addImm(i).addConstantPoolIndex(i).addImm(Size);
+    CPEMIs.push_back(CPEMI);
+    DEBUG(std::cerr << "Moved CPI#" << i << " to end of function as #"
+                    << i << "\n");
+  }
+}
+
+/// BBHasFallthrough - Return true of the specified basic block can fallthrough
+/// into the block immediately after it.
+static bool BBHasFallthrough(MachineBasicBlock *MBB) {
+  // Get the next machine basic block in the function.
+  MachineFunction::iterator MBBI = MBB;
+  if (next(MBBI) == MBB->getParent()->end())  // Can't fall off end of function.
+    return false;
+  
+  MachineBasicBlock *NextBB = next(MBBI);
+  for (MachineBasicBlock::succ_iterator I = MBB->succ_begin(),
+       E = MBB->succ_end(); I != E; ++I)
+    if (*I == NextBB)
+      return true;
+  
+  return false;
+}
+
+/// InitialFunctionScan - Do the initial scan of the function, building up
+/// information about the sizes of each block, the location of all the water,
+/// and finding all of the constant pool users.
+void ARMConstantIslands::InitialFunctionScan(MachineFunction &Fn,
+                                     const std::vector<MachineInstr*> &CPEMIs) {
+  for (MachineFunction::iterator MBBI = Fn.begin(), E = Fn.end();
+       MBBI != E; ++MBBI) {
+    MachineBasicBlock &MBB = *MBBI;
+    
+    // If this block doesn't fall through into the next MBB, then this is
+    // 'water' that a constant pool island could be placed.
+    if (!BBHasFallthrough(&MBB))
+      WaterList.push_back(&MBB);
+    
+    unsigned MBBSize = 0;
+    for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
+         I != E; ++I) {
+      // Add instruction size to MBBSize.
+      MBBSize += GetInstSize(I);
+
+      // Scan the instructions for constant pool operands.
+      for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op)
+        if (I->getOperand(op).isConstantPoolIndex()) {
+          // We found one.  The addressing mode tells us the max displacement
+          // from the PC that this instruction permits.
+          unsigned MaxOffs = 0;
+          
+          // Basic size info comes from the TSFlags field.
+          unsigned TSFlags = I->getInstrDescriptor()->TSFlags;
+          switch (TSFlags & ARMII::AddrModeMask) {
+          default: 
+            // Constant pool entries can reach anything.
+            if (I->getOpcode() == ARM::CONSTPOOL_ENTRY)
+              continue;
+            assert(0 && "Unknown addressing mode for CP reference!");
+          case ARMII::AddrMode1: // AM1: 8 bits << 2
+            MaxOffs = 1 << (8+2);   // Taking the address of a CP entry.
+            break;
+          case ARMII::AddrMode2:
+            MaxOffs = 1 << 12;   // +-offset_12
+            break;
+          case ARMII::AddrMode3:
+            MaxOffs = 1 << 8;   // +-offset_8
+            break;
+            // addrmode4 has no immediate offset.
+          case ARMII::AddrMode5:
+            MaxOffs = 1 << (8+2);   // +-(offset_8*4)
+            break;
+          case ARMII::AddrModeT1:
+            MaxOffs = 1 << 5;
+            break;
+          case ARMII::AddrModeT2:
+            MaxOffs = 1 << (5+1);
+            break;
+          case ARMII::AddrModeT4:
+            MaxOffs = 1 << (5+2);
+            break;
+          }
+          
+          // Remember that this is a user of a CP entry.
+          MachineInstr *CPEMI =CPEMIs[I->getOperand(op).getConstantPoolIndex()];
+          CPUsers.push_back(CPUser(I, CPEMI, MaxOffs));
+          
+          // Instructions can only use one CP entry, don't bother scanning the
+          // rest of the operands.
+          break;
+        }
+    }
+    BBSizes.push_back(MBBSize);
+  }
+}
+
+/// FIXME: Works around a gcc miscompilation with -fstrict-aliasing
+static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
+                                unsigned JTI) DISABLE_INLINE;
+static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT,
+                                unsigned JTI) {
+  return JT[JTI].MBBs.size();
+}
+
+/// GetInstSize - Return the size of the specified MachineInstr.
+///
+unsigned ARMConstantIslands::GetInstSize(MachineInstr *MI) const {
+  // Basic size info comes from the TSFlags field.
+  unsigned TSFlags = MI->getInstrDescriptor()->TSFlags;
+  
+  switch ((TSFlags & ARMII::SizeMask) >> ARMII::SizeShift) {
+  default:
+    // If this machine instr is an inline asm, measure it.
+    if (MI->getOpcode() == ARM::INLINEASM)
+      return TAI->getInlineAsmLength(MI->getOperand(0).getSymbolName());
+    assert(0 && "Unknown or unset size field for instr!");
+    break;
+  case ARMII::Size8Bytes: return 8;          // Arm instruction x 2.
+  case ARMII::Size4Bytes: return 4;          // Arm instruction.
+  case ARMII::Size2Bytes: return 2;          // Thumb instruction.
+  case ARMII::SizeSpecial: {
+    switch (MI->getOpcode()) {
+    case ARM::CONSTPOOL_ENTRY:
+      // If this machine instr is a constant pool entry, its size is recorded as
+      // operand #2.
+      return MI->getOperand(2).getImm();
+    case ARM::BR_JTr:
+    case ARM::BR_JTm:
+    case ARM::BR_JTadd: {
+      // These are jumptable branches, i.e. a branch followed by an inlined
+      // jumptable. The size is 4 + 4 * number of entries.
+      unsigned JTI = MI->getOperand(MI->getNumOperands()-2).getJumpTableIndex();
+      const MachineFunction *MF = MI->getParent()->getParent();
+      MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
+      const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
+      assert(JTI < JT.size());
+      return getNumJTEntries(JT, JTI) * 4 + 4;
+    }
+    default:
+      // Otherwise, pseudo-instruction sizes are zero.
+      return 0;
+    }
+  }
+  }
+}
+
+/// GetOffsetOf - Return the current offset of the specified machine instruction
+/// from the start of the function.  This offset changes as stuff is moved
+/// around inside the function.
+unsigned ARMConstantIslands::GetOffsetOf(MachineInstr *MI) const {
+  MachineBasicBlock *MBB = MI->getParent();
+  
+  // The offset is composed of two things: the sum of the sizes of all MBB's
+  // before this instruction's block, and the offset from the start of the block
+  // it is in.
+  unsigned Offset = 0;
+  
+  // Sum block sizes before MBB.
+  for (unsigned BB = 0, e = MBB->getNumber(); BB != e; ++BB)
+    Offset += BBSizes[BB];
+
+  // Sum instructions before MI in MBB.
+  for (MachineBasicBlock::iterator I = MBB->begin(); ; ++I) {
+    assert(I != MBB->end() && "Didn't find MI in its own basic block?");
+    if (&*I == MI) return Offset;
+    Offset += GetInstSize(I);
+  }
+}
+
+/// CompareMBBNumbers - Little predicate function to sort the WaterList by MBB
+/// ID.
+static bool CompareMBBNumbers(const MachineBasicBlock *LHS,
+                              const MachineBasicBlock *RHS) {
+  return LHS->getNumber() < RHS->getNumber();
+}
+
+/// UpdateForInsertedWaterBlock - When a block is newly inserted into the
+/// machine function, it upsets all of the block numbers.  Renumber the blocks
+/// and update the arrays that parallel this numbering.
+void ARMConstantIslands::UpdateForInsertedWaterBlock(MachineBasicBlock *NewBB) {
+  // Renumber the MBB's to keep them consequtive.
+  NewBB->getParent()->RenumberBlocks(NewBB);
+  
+  // Insert a size into BBSizes to align it properly with the (newly
+  // renumbered) block numbers.
+  BBSizes.insert(BBSizes.begin()+NewBB->getNumber(), 0);
+  
+  // Next, update WaterList.  Specifically, we need to add NewMBB as having 
+  // available water after it.
+  std::vector<MachineBasicBlock*>::iterator IP =
+    std::lower_bound(WaterList.begin(), WaterList.end(), NewBB,
+                     CompareMBBNumbers);
+  WaterList.insert(IP, NewBB);
+}
+
+
+/// Split the basic block containing MI into two blocks, which are joined by
+/// an unconditional branch.  Update datastructures and renumber blocks to
+/// account for this change.
+void ARMConstantIslands::SplitBlockBeforeInstr(MachineInstr *MI) {
+  MachineBasicBlock *OrigBB = MI->getParent();
+
+  // Create a new MBB for the code after the OrigBB.
+  MachineBasicBlock *NewBB = new MachineBasicBlock(OrigBB->getBasicBlock());
+  MachineFunction::iterator MBBI = OrigBB; ++MBBI;
+  OrigBB->getParent()->getBasicBlockList().insert(MBBI, NewBB);
+  
+  // Splice the instructions starting with MI over to NewBB.
+  NewBB->splice(NewBB->end(), OrigBB, MI, OrigBB->end());
+  
+  // Add an unconditional branch from OrigBB to NewBB.
+  BuildMI(OrigBB, TII->get(ARM::B)).addMBB(NewBB);
+  NumSplit++;
+  
+  // Update the CFG.  All succs of OrigBB are now succs of NewBB.
+  while (!OrigBB->succ_empty()) {
+    MachineBasicBlock *Succ = *OrigBB->succ_begin();
+    OrigBB->removeSuccessor(Succ);
+    NewBB->addSuccessor(Succ);
+    
+    // This pass should be run after register allocation, so there should be no
+    // PHI nodes to update.
+    assert((Succ->empty() || Succ->begin()->getOpcode() != TargetInstrInfo::PHI)
+           && "PHI nodes should be eliminated by now!");
+  }
+  
+  // OrigBB branches to NewBB.
+  OrigBB->addSuccessor(NewBB);
+  
+  // Update internal data structures to account for the newly inserted MBB.
+  UpdateForInsertedWaterBlock(NewBB);
+  
+  // Figure out how large the first NewMBB is.
+  unsigned NewBBSize = 0;
+  for (MachineBasicBlock::iterator I = NewBB->begin(), E = NewBB->end();
+       I != E; ++I)
+    NewBBSize += GetInstSize(I);
+  
+  // Set the size of NewBB in BBSizes.
+  BBSizes[NewBB->getNumber()] = NewBBSize;
+  
+  // We removed instructions from UserMBB, subtract that off from its size.
+  // Add 4 to the block to count the unconditional branch we added to it.
+  BBSizes[OrigBB->getNumber()] -= NewBBSize-4;
+}
+
+/// HandleConstantPoolUser - Analyze the specified user, checking to see if it
+/// is out-of-range.  If so, pick it up the constant pool value and move it some
+/// place in-range.
+bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &Fn, CPUser &U){
+  MachineInstr *UserMI = U.MI;
+  MachineInstr *CPEMI  = U.CPEMI;
+
+  unsigned UserOffset = GetOffsetOf(UserMI);
+  unsigned CPEOffset  = GetOffsetOf(CPEMI);
+  
+  DEBUG(std::cerr << "User of CPE#" << CPEMI->getOperand(0).getImm()
+                  << " max delta=" << U.MaxDisp
+                  << " at offset " << int(UserOffset-CPEOffset) << "\t"
+                  << *UserMI);
+
+  // Check to see if the CPE is already in-range.
+  if (UserOffset < CPEOffset) {
+    // User before the CPE.
+    if (CPEOffset-UserOffset <= U.MaxDisp)
+      return false;
+  } else {
+    if (UserOffset-CPEOffset <= U.MaxDisp)
+      return false;
+  }
+  
+ 
+  // Solution guaranteed to work: split the user's MBB right before the user and
+  // insert a clone the CPE into the newly created water.
+  
+  // If the user isn't at the start of its MBB, or if there is a fall-through
+  // into the user's MBB, split the MBB before the User.
+  MachineBasicBlock *UserMBB = UserMI->getParent();
+  if (&UserMBB->front() != UserMI ||
+      UserMBB == &Fn.front() || // entry MBB of function.
+      BBHasFallthrough(prior(MachineFunction::iterator(UserMBB)))) {
+    // TODO: Search for the best place to split the code.  In practice, using
+    // loop nesting information to insert these guys outside of loops would be
+    // sufficient.    
+    SplitBlockBeforeInstr(UserMI);
+    
+    // UserMI's BB may have changed.
+    UserMBB = UserMI->getParent();
+  }
+  
+  // Okay, we know we can put an island before UserMBB now, do it!
+  MachineBasicBlock *NewIsland = new MachineBasicBlock();
+  Fn.getBasicBlockList().insert(UserMBB, NewIsland);
+
+  // Update internal data structures to account for the newly inserted MBB.
+  UpdateForInsertedWaterBlock(NewIsland);
+
+  // Now that we have an island to add the CPE to, clone the original CPE and
+  // add it to the island.
+  unsigned ID  = NextUID++;
+  unsigned CPI = CPEMI->getOperand(1).getConstantPoolIndex();
+  unsigned Size = CPEMI->getOperand(2).getImm();
+  
+  // Build a new CPE for this user.
+  U.CPEMI = BuildMI(NewIsland, TII->get(ARM::CONSTPOOL_ENTRY))
+                .addImm(ID).addConstantPoolIndex(CPI).addImm(Size);
+  
+  // Increase the size of the island block to account for the new entry.
+  BBSizes[NewIsland->getNumber()] += Size;
+  
+  // Finally, change the CPI in the instruction operand to be ID.
+  for (unsigned i = 0, e = UserMI->getNumOperands(); i != e; ++i)
+    if (UserMI->getOperand(i).isConstantPoolIndex()) {
+      UserMI->getOperand(i).setConstantPoolIndex(ID);
+      break;
+    }
+      
+  DEBUG(std::cerr << "  Moved CPE to #" << ID << " CPI=" << CPI << "\t"
+                  << *UserMI);
+  
+      
+  return true;
+}
+
diff --git a/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp b/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp
new file mode 100644
index 0000000..97cca07
--- /dev/null
+++ b/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp
@@ -0,0 +1,55 @@
+//===- ARMConstantPoolValue.cpp - ARM constantpool value --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Evan Cheng and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the ARM specific constantpool value class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ARMConstantPoolValue.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/GlobalValue.h"
+using namespace llvm;
+
+ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv, unsigned id,
+                                         bool isNonLazy, unsigned char PCAdj)
+  : MachineConstantPoolValue((const Type*)gv->getType()),
+    GV(gv), LabelId(id), isNonLazyPtr(isNonLazy), PCAdjust(PCAdj) {}
+
+int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
+                                                    unsigned Alignment) {
+  unsigned AlignMask = (1 << Alignment)-1;
+  const std::vector<MachineConstantPoolEntry> Constants = CP->getConstants();
+  for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
+    if (Constants[i].isMachineConstantPoolEntry() &&
+        (Constants[i].Offset & AlignMask) == 0) {
+      ARMConstantPoolValue *CPV =
+        (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal;
+      if (CPV->GV == GV && CPV->LabelId == LabelId &&
+          CPV->isNonLazyPtr == isNonLazyPtr)
+        return i;
+    }
+  }
+
+  return -1;
+}
+
+void
+ARMConstantPoolValue::AddSelectionDAGCSEId(FoldingSetNodeID &ID) {
+  ID.AddPointer(GV);
+  ID.AddInteger(LabelId);
+  ID.AddInteger((unsigned)isNonLazyPtr);
+  ID.AddInteger(PCAdjust);
+}
+
+void ARMConstantPoolValue::print(std::ostream &O) const {
+  O << GV->getName();
+  if (isNonLazyPtr) O << "$non_lazy_ptr";
+  if (PCAdjust != 0) O << "-(LPIC" << LabelId << "+"
+                       << (unsigned)PCAdjust << ")";
+}
diff --git a/llvm/lib/Target/ARM/ARMConstantPoolValue.h b/llvm/lib/Target/ARM/ARMConstantPoolValue.h
new file mode 100644
index 0000000..a9143d4
--- /dev/null
+++ b/llvm/lib/Target/ARM/ARMConstantPoolValue.h
@@ -0,0 +1,50 @@
+//===- ARMConstantPoolValue.h - ARM constantpool value ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Evan Cheng and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the ARM specific constantpool value class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_ARM_CONSTANTPOOLVALUE_H
+#define LLVM_TARGET_ARM_CONSTANTPOOLVALUE_H
+
+#include "llvm/CodeGen/MachineConstantPool.h"
+
+namespace llvm {
+
+/// ARMConstantPoolValue - ARM specific constantpool value. This is used to
+/// represent PC relative displacement between the address of the load
+/// instruction and the global value being loaded, i.e. (&GV-(LPIC+8)).
+class ARMConstantPoolValue : public MachineConstantPoolValue {
+  GlobalValue *GV;         // GlobalValue being loaded.
+  unsigned LabelId;        // Label id of the load.
+  bool isNonLazyPtr;       // True if loading a Mac OS X non_lazy_ptr stub.
+  unsigned char PCAdjust;  // Extra adjustment if constantpool is pc relative.
+                           // 8 for ARM, 4 for Thumb.
+
+public:
+  ARMConstantPoolValue(GlobalValue *gv, unsigned id, bool isNonLazy = false,
+                       unsigned char PCAdj = 0);
+
+  GlobalValue *getGV() const { return GV; }
+  unsigned getLabelId() const { return LabelId; }
+  bool isNonLazyPointer() const { return isNonLazyPtr; }
+  unsigned char getPCAdjustment() const { return PCAdjust; }
+
+  virtual int getExistingMachineCPValue(MachineConstantPool *CP,
+                                        unsigned Alignment);
+
+  virtual void AddSelectionDAGCSEId(FoldingSetNodeID &ID);
+
+  virtual void print(std::ostream &O) const;
+};
+  
+}
+
+#endif
diff --git a/llvm/lib/Target/ARM/ARMFrameInfo.h b/llvm/lib/Target/ARM/ARMFrameInfo.h
index 5bd7f67..c56640a 100644
--- a/llvm/lib/Target/ARM/ARMFrameInfo.h
+++ b/llvm/lib/Target/ARM/ARMFrameInfo.h
@@ -17,17 +17,15 @@
 
 #include "ARM.h"
 #include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/Target/TargetMachine.h"
+#include "ARMSubtarget.h"
 
 namespace llvm {
 
-class ARMFrameInfo: public TargetFrameInfo {
-
+class ARMFrameInfo : public TargetFrameInfo {
 public:
-  ARMFrameInfo()
-    : TargetFrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) {
+  ARMFrameInfo(const ARMSubtarget &ST)
+    : TargetFrameInfo(StackGrowsDown, ST.getStackAlignment(), 0) {
   }
-
 };
 
 } // End llvm namespace
diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 2a5f3e3..f5f4599 100644
--- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -12,14 +12,14 @@
 //===----------------------------------------------------------------------===//
 
 #include "ARM.h"
+#include "ARMISelLowering.h"
 #include "ARMTargetMachine.h"
-#include "ARMCommon.h"
+#include "ARMAddressingModes.h"
 #include "llvm/CallingConv.h"
+#include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
-#include "llvm/Constants.h"
 #include "llvm/Intrinsics.h"
-#include "llvm/ADT/VectorExtras.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -28,924 +28,9 @@
 #include "llvm/CodeGen/SSARegMap.h"
 #include "llvm/Target/TargetLowering.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/MathExtras.h"
-#include <vector>
+#include <iostream>
 using namespace llvm;
 
-namespace {
-  class ARMTargetLowering : public TargetLowering {
-    int VarArgsFrameIndex;            // FrameIndex for start of varargs area.
-  public:
-    ARMTargetLowering(TargetMachine &TM);
-    virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
-    virtual const char *getTargetNodeName(unsigned Opcode) const;
-    std::vector<unsigned>
-    getRegClassForInlineAsmConstraint(const std::string &Constraint,
-				      MVT::ValueType VT) const;
-  };
-
-}
-
-ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
-  : TargetLowering(TM) {
-  addRegisterClass(MVT::i32, ARM::IntRegsRegisterClass);
-  addRegisterClass(MVT::f32, ARM::FPRegsRegisterClass);
-  addRegisterClass(MVT::f64, ARM::DFPRegsRegisterClass);
-
-  setLoadXAction(ISD::EXTLOAD, MVT::f32, Expand);
-
-  setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
-  setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
-
-  setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
-  setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
-
-  setOperationAction(ISD::RET,           MVT::Other, Custom);
-  setOperationAction(ISD::GlobalAddress, MVT::i32,   Custom);
-  setOperationAction(ISD::ConstantPool,  MVT::i32,   Custom);
-
-  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
-  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand);
-  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand);
-
-  setOperationAction(ISD::SELECT, MVT::i32, Expand);
-  setOperationAction(ISD::SELECT, MVT::f32, Expand);
-  setOperationAction(ISD::SELECT, MVT::f64, Expand);
-
-  setOperationAction(ISD::SETCC, MVT::i32, Expand);
-  setOperationAction(ISD::SETCC, MVT::f32, Expand);
-  setOperationAction(ISD::SETCC, MVT::f64, Expand);
-
-  setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
-  setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
-  setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
-
-  setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
-  setOperationAction(ISD::MEMSET, MVT::Other, Expand);
-  setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
-
-  setOperationAction(ISD::BR_JT, MVT::Other, Expand);
-  setOperationAction(ISD::BRIND, MVT::Other, Expand);
-  setOperationAction(ISD::BR_CC, MVT::i32, Custom);
-  setOperationAction(ISD::BR_CC, MVT::f32, Custom);
-  setOperationAction(ISD::BR_CC, MVT::f64, Custom);
-
-  setOperationAction(ISD::BRCOND,        MVT::Other, Expand);
-
-  setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
-  setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
-  setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
-  setOperationAction(ISD::SDIV,      MVT::i32, Expand);
-  setOperationAction(ISD::UDIV,      MVT::i32, Expand);
-  setOperationAction(ISD::SREM,      MVT::i32, Expand);
-  setOperationAction(ISD::UREM,      MVT::i32, Expand);
-
-  setOperationAction(ISD::VASTART,       MVT::Other, Custom);
-  setOperationAction(ISD::VACOPY,            MVT::Other, Expand);
-  setOperationAction(ISD::VAEND,         MVT::Other, Expand);
-  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
-
-  setOperationAction(ISD::ConstantFP, MVT::f64, Custom);
-  setOperationAction(ISD::ConstantFP, MVT::f32, Custom);
-
-  setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
-  setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
-
-  setStackPointerRegisterToSaveRestore(ARM::R13);
-
-  setSchedulingPreference(SchedulingForRegPressure);
-  computeRegisterProperties();
-}
-
-namespace llvm {
-  namespace ARMISD {
-    enum NodeType {
-      // Start the numbering where the builting ops and target ops leave off.
-      FIRST_NUMBER = ISD::BUILTIN_OP_END+ARM::INSTRUCTION_LIST_END,
-      /// CALL - A direct function call.
-      CALL,
-
-      /// Return with a flag operand.
-      RET_FLAG,
-
-      CMP,
-
-      SELECT,
-
-      BR,
-
-      FSITOS,
-      FTOSIS,
-
-      FSITOD,
-      FTOSID,
-
-      FUITOS,
-      FTOUIS,
-
-      FUITOD,
-      FTOUID,
-
-      FMRRD,
-
-      FMDRR,
-
-      FMSTAT
-    };
-  }
-}
-
-/// DAGFPCCToARMCC - Convert a DAG fp condition code to an ARM CC
-// Unordered = !N & !Z & C & V = V
-// Ordered   =  N | Z | !C | !V = N | Z | !V
-static std::vector<unsigned> DAGFPCCToARMCC(ISD::CondCode CC) {
-  switch (CC) {
-  default:
-    assert(0 && "Unknown fp condition code!");
-// SETOEQ = (N | Z | !V) & Z = Z                               = EQ
-  case ISD::SETEQ:
-  case ISD::SETOEQ: return make_vector<unsigned>(ARMCC::EQ, 0);
-// SETOGT = (N | Z | !V) & !N & !Z = !V &!N &!Z = (N = V) & !Z = GT
-  case ISD::SETGT:
-  case ISD::SETOGT: return make_vector<unsigned>(ARMCC::GT, 0);
-// SETOGE = (N | Z | !V) & !N = (Z | !V) & !N = !V & !N        = GE
-  case ISD::SETGE:
-  case ISD::SETOGE: return make_vector<unsigned>(ARMCC::GE, 0);
-// SETOLT = (N | Z | !V) & N = N                               = MI
-  case ISD::SETLT:
-  case ISD::SETOLT: return make_vector<unsigned>(ARMCC::MI, 0);
-// SETOLE = (N | Z | !V) & (N | Z) = N | Z = !C | Z            = LS
-  case ISD::SETLE:
-  case ISD::SETOLE: return make_vector<unsigned>(ARMCC::LS, 0);
-// SETONE = OGT | OLT 
-  case ISD::SETONE: return make_vector<unsigned>(ARMCC::GT, ARMCC::MI, 0);
-// SETO   = N | Z | !V = Z | !V = !V                           = VC
-  case ISD::SETO:   return make_vector<unsigned>(ARMCC::VC, 0);
-// SETUO  = V                                                  = VS
-  case ISD::SETUO:  return make_vector<unsigned>(ARMCC::VS, 0);
-// SETUEQ = V | Z  (need two instructions)                     = EQ/VS
-  case ISD::SETUEQ: return make_vector<unsigned>(ARMCC::EQ, ARMCC::VS, 0);
-// SETUGT = V | (!Z & !N) = !Z & !N = !Z & C                   = HI
-  case ISD::SETUGT: return make_vector<unsigned>(ARMCC::HI, 0);
-// SETUGE = V | !N = !N                                        = PL
-  case ISD::SETUGE: return make_vector<unsigned>(ARMCC::PL, 0);
-// SETULT = V | N                                              = LT
-  case ISD::SETULT: return make_vector<unsigned>(ARMCC::LT, 0);
-// SETULE = V | Z | N                                          = LE
-  case ISD::SETULE: return make_vector<unsigned>(ARMCC::LE, 0);
-// SETUNE = V | !Z = !Z                                        = NE
-  case ISD::SETNE:
-  case ISD::SETUNE: return make_vector<unsigned>(ARMCC::NE, 0);
-  }
-}
-
-/// DAGIntCCToARMCC - Convert a DAG integer condition code to an ARM CC
-static std::vector<unsigned> DAGIntCCToARMCC(ISD::CondCode CC) {
-  switch (CC) {
-  default:
-    assert(0 && "Unknown integer condition code!");
-  case ISD::SETEQ:  return make_vector<unsigned>(ARMCC::EQ, 0);
-  case ISD::SETNE:  return make_vector<unsigned>(ARMCC::NE, 0);
-  case ISD::SETLT:  return make_vector<unsigned>(ARMCC::LT, 0);
-  case ISD::SETLE:  return make_vector<unsigned>(ARMCC::LE, 0);
-  case ISD::SETGT:  return make_vector<unsigned>(ARMCC::GT, 0);
-  case ISD::SETGE:  return make_vector<unsigned>(ARMCC::GE, 0);
-  case ISD::SETULT: return make_vector<unsigned>(ARMCC::CC, 0);
-  case ISD::SETULE: return make_vector<unsigned>(ARMCC::LS, 0);
-  case ISD::SETUGT: return make_vector<unsigned>(ARMCC::HI, 0);
-  case ISD::SETUGE: return make_vector<unsigned>(ARMCC::CS, 0);
-  }
-}
-
-std::vector<unsigned> ARMTargetLowering::
-getRegClassForInlineAsmConstraint(const std::string &Constraint,
-                                  MVT::ValueType VT) const {
-  if (Constraint.size() == 1) {
-    // FIXME: handling only r regs
-    switch (Constraint[0]) {
-    default: break;  // Unknown constraint letter
-
-    case 'r':   // GENERAL_REGS
-    case 'R':   // LEGACY_REGS
-      if (VT == MVT::i32)
-        return make_vector<unsigned>(ARM::R0,  ARM::R1,  ARM::R2,  ARM::R3,
-                                     ARM::R4,  ARM::R5,  ARM::R6,  ARM::R7,
-                                     ARM::R8,  ARM::R9,  ARM::R10, ARM::R11,
-                                     ARM::R12, ARM::R13, ARM::R14, 0);
-      break;
-
-    }
-  }
-
-  return std::vector<unsigned>();
-}
-
-const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
-  switch (Opcode) {
-  default: return 0;
-  case ARMISD::CALL:          return "ARMISD::CALL";
-  case ARMISD::RET_FLAG:      return "ARMISD::RET_FLAG";
-  case ARMISD::SELECT:        return "ARMISD::SELECT";
-  case ARMISD::CMP:           return "ARMISD::CMP";
-  case ARMISD::BR:            return "ARMISD::BR";
-  case ARMISD::FSITOS:        return "ARMISD::FSITOS";
-  case ARMISD::FTOSIS:        return "ARMISD::FTOSIS";
-  case ARMISD::FSITOD:        return "ARMISD::FSITOD";
-  case ARMISD::FTOSID:        return "ARMISD::FTOSID";
-  case ARMISD::FUITOS:        return "ARMISD::FUITOS";
-  case ARMISD::FTOUIS:        return "ARMISD::FTOUIS";
-  case ARMISD::FUITOD:        return "ARMISD::FUITOD";
-  case ARMISD::FTOUID:        return "ARMISD::FTOUID";
-  case ARMISD::FMRRD:         return "ARMISD::FMRRD";
-  case ARMISD::FMDRR:         return "ARMISD::FMDRR";
-  case ARMISD::FMSTAT:        return "ARMISD::FMSTAT";
-  }
-}
-
-class ArgumentLayout {
-  std::vector<bool>           is_reg;
-  std::vector<unsigned>       pos;
-  std::vector<MVT::ValueType> types;
-public:
-  ArgumentLayout(const std::vector<MVT::ValueType> &Types) {
-    types = Types;
-
-    unsigned      RegNum = 0;
-    unsigned StackOffset = 0;
-    for(std::vector<MVT::ValueType>::const_iterator I = Types.begin();
-        I != Types.end();
-        ++I) {
-      MVT::ValueType VT = *I;
-      assert(VT == MVT::i32 || VT == MVT::f32 || VT == MVT::f64);
-      unsigned     size = MVT::getSizeInBits(VT)/32;
-
-      RegNum = ((RegNum + size - 1) / size) * size;
-      if (RegNum < 4) {
-        pos.push_back(RegNum);
-        is_reg.push_back(true);
-        RegNum += size;
-      } else {
-        unsigned bytes = size * 32/8;
-        StackOffset = ((StackOffset + bytes - 1) / bytes) * bytes;
-        pos.push_back(StackOffset);
-        is_reg.push_back(false);
-        StackOffset += bytes;
-      }
-    }
-  }
-  unsigned getRegisterNum(unsigned argNum) {
-    assert(isRegister(argNum));
-    return pos[argNum];
-  }
-  unsigned getOffset(unsigned argNum) {
-    assert(isOffset(argNum));
-    return pos[argNum];
-  }
-  unsigned isRegister(unsigned argNum) {
-    assert(argNum < is_reg.size());
-    return is_reg[argNum];
-  }
-  unsigned isOffset(unsigned argNum) {
-    return !isRegister(argNum);
-  }
-  MVT::ValueType getType(unsigned argNum) {
-    assert(argNum < types.size());
-    return types[argNum];
-  }
-  unsigned getStackSize(void) {
-    int last = is_reg.size() - 1;
-    if (last < 0)
-      return 0;
-    if (isRegister(last))
-      return 0;
-    return getOffset(last) + MVT::getSizeInBits(getType(last))/8;
-  }
-  int lastRegArg(void) {
-    int size = is_reg.size();
-    int last = 0;
-    while(last < size && isRegister(last))
-      last++;
-    last--;
-    return last;
-  }
-  int lastRegNum(void) {
-    int            l = lastRegArg();
-    if (l < 0)
-      return -1;
-    unsigned       r = getRegisterNum(l);
-    MVT::ValueType t = getType(l);
-    assert(t == MVT::i32 || t == MVT::f32 || t == MVT::f64);
-    if (t == MVT::f64)
-      return r + 1;
-    return r;
-  }
-};
-
-// This transforms a ISD::CALL node into a
-// callseq_star <- ARMISD:CALL <- callseq_end
-// chain
-static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
-  SDOperand Chain    = Op.getOperand(0);
-  unsigned CallConv  = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
-  assert((CallConv == CallingConv::C ||
-          CallConv == CallingConv::Fast)
-         && "unknown calling convention");
-  SDOperand Callee   = Op.getOperand(4);
-  unsigned NumOps    = (Op.getNumOperands() - 5) / 2;
-  SDOperand StackPtr = DAG.getRegister(ARM::R13, MVT::i32);
-  static const unsigned regs[] = {
-    ARM::R0, ARM::R1, ARM::R2, ARM::R3
-  };
-
-  std::vector<MVT::ValueType> Types;
-  for (unsigned i = 0; i < NumOps; ++i) {
-    MVT::ValueType VT = Op.getOperand(5+2*i).getValueType();
-    Types.push_back(VT);
-  }
-  ArgumentLayout Layout(Types);
-
-  unsigned NumBytes = Layout.getStackSize();
-
-  Chain = DAG.getCALLSEQ_START(Chain,
-                               DAG.getConstant(NumBytes, MVT::i32));
-
-  //Build a sequence of stores
-  std::vector<SDOperand> MemOpChains;
-  for (unsigned i = Layout.lastRegArg() + 1; i < NumOps; ++i) {
-    SDOperand      Arg = Op.getOperand(5+2*i);
-    unsigned ArgOffset = Layout.getOffset(i);
-    SDOperand   PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
-    PtrOff             = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
-    MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
-  }
-  if (!MemOpChains.empty())
-    Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
-                        &MemOpChains[0], MemOpChains.size());
-
-  // If the callee is a GlobalAddress node (quite common, every direct call is)
-  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
-  // Likewise ExternalSymbol -> TargetExternalSymbol.
-  assert(Callee.getValueType() == MVT::i32);
-  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
-    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i32);
-  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
-    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32);
-
-  // If this is a direct call, pass the chain and the callee.
-  assert (Callee.Val);
-  std::vector<SDOperand> Ops;
-  Ops.push_back(Chain);
-  Ops.push_back(Callee);
-
-  // Build a sequence of copy-to-reg nodes chained together with token chain
-  // and flag operands which copy the outgoing args into the appropriate regs.
-  SDOperand InFlag;
-  for (int i = 0, e = Layout.lastRegArg(); i <= e; ++i) {
-    SDOperand     Arg = Op.getOperand(5+2*i);
-    unsigned   RegNum = Layout.getRegisterNum(i);
-    unsigned     Reg1 = regs[RegNum];
-    MVT::ValueType VT = Layout.getType(i);
-    assert(VT == Arg.getValueType());
-    assert(VT == MVT::i32 || VT == MVT::f32 || VT == MVT::f64);
-
-    // Add argument register to the end of the list so that it is known live
-    // into the call.
-    Ops.push_back(DAG.getRegister(Reg1, MVT::i32));
-    if (VT == MVT::f64) {
-      unsigned    Reg2 = regs[RegNum + 1];
-      SDOperand SDReg1 = DAG.getRegister(Reg1, MVT::i32);
-      SDOperand SDReg2 = DAG.getRegister(Reg2, MVT::i32);
-
-      Ops.push_back(DAG.getRegister(Reg2, MVT::i32));
-      SDVTList    VTs = DAG.getVTList(MVT::Other, MVT::Flag);
-      SDOperand Ops[] = {Chain, SDReg1, SDReg2, Arg, InFlag};
-      Chain = DAG.getNode(ARMISD::FMRRD, VTs, Ops, InFlag.Val ? 5 : 4);
-    } else {
-      if (VT == MVT::f32)
-        Arg = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Arg);
-      Chain = DAG.getCopyToReg(Chain, Reg1, Arg, InFlag);
-    }
-    InFlag = Chain.getValue(1);
-  }
-
-  std::vector<MVT::ValueType> NodeTys;
-  NodeTys.push_back(MVT::Other);   // Returns a chain
-  NodeTys.push_back(MVT::Flag);    // Returns a flag for retval copy to use.
-
-  unsigned CallOpc = ARMISD::CALL;
-  if (InFlag.Val)
-    Ops.push_back(InFlag);
-  Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size());
-  InFlag = Chain.getValue(1);
-
-  std::vector<SDOperand> ResultVals;
-  NodeTys.clear();
-
-  // If the call has results, copy the values out of the ret val registers.
-  MVT::ValueType VT = Op.Val->getValueType(0);
-  if (VT != MVT::Other) {
-    assert(VT == MVT::i32 || VT == MVT::f32 || VT == MVT::f64);
-
-    SDOperand Value1 = DAG.getCopyFromReg(Chain, ARM::R0, MVT::i32, InFlag);
-    Chain            = Value1.getValue(1);
-    InFlag           = Value1.getValue(2);
-    NodeTys.push_back(VT);
-    if (VT == MVT::i32) {
-      ResultVals.push_back(Value1);
-      if (Op.Val->getValueType(1) == MVT::i32) {
-        SDOperand Value2 = DAG.getCopyFromReg(Chain, ARM::R1, MVT::i32, InFlag);
-        Chain            = Value2.getValue(1);
-        ResultVals.push_back(Value2);
-        NodeTys.push_back(VT);
-      }
-    }
-    if (VT == MVT::f32) {
-      SDOperand Value = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, Value1);
-      ResultVals.push_back(Value);
-    }
-    if (VT == MVT::f64) {
-      SDOperand Value2 = DAG.getCopyFromReg(Chain, ARM::R1, MVT::i32, InFlag);
-      Chain            = Value2.getValue(1);
-      SDOperand Value  = DAG.getNode(ARMISD::FMDRR, MVT::f64, Value1, Value2);
-      ResultVals.push_back(Value);
-    }
-  }
-
-  Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain,
-                      DAG.getConstant(NumBytes, MVT::i32));
-  NodeTys.push_back(MVT::Other);
-
-  if (ResultVals.empty())
-    return Chain;
-
-  ResultVals.push_back(Chain);
-  SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys, &ResultVals[0],
-                              ResultVals.size());
-  return Res.getValue(Op.ResNo);
-}
-
-static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) {
-  SDOperand Copy;
-  SDOperand Chain = Op.getOperand(0);
-  SDOperand    R0 = DAG.getRegister(ARM::R0, MVT::i32);
-  SDOperand    R1 = DAG.getRegister(ARM::R1, MVT::i32);
-
-  switch(Op.getNumOperands()) {
-  default:
-    assert(0 && "Do not know how to return this many arguments!");
-    abort();
-  case 1: {
-    SDOperand LR = DAG.getRegister(ARM::R14, MVT::i32);
-    return DAG.getNode(ARMISD::RET_FLAG, MVT::Other, Chain);
-  }
-  case 3: {
-    SDOperand Val = Op.getOperand(1);
-    assert(Val.getValueType() == MVT::i32 ||
-	   Val.getValueType() == MVT::f32 ||
-	   Val.getValueType() == MVT::f64);
-
-    if (Val.getValueType() == MVT::f64) {
-      SDVTList    VTs = DAG.getVTList(MVT::Other, MVT::Flag);
-      SDOperand Ops[] = {Chain, R0, R1, Val};
-      Copy  = DAG.getNode(ARMISD::FMRRD, VTs, Ops, 4);
-    } else {
-      if (Val.getValueType() == MVT::f32)
-	Val = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Val);
-      Copy = DAG.getCopyToReg(Chain, R0, Val, SDOperand());
-    }
-
-    if (DAG.getMachineFunction().liveout_empty()) {
-      DAG.getMachineFunction().addLiveOut(ARM::R0);
-      if (Val.getValueType() == MVT::f64)
-        DAG.getMachineFunction().addLiveOut(ARM::R1);
-    }
-    break;
-  }
-  case 5:
-    Copy = DAG.getCopyToReg(Chain, ARM::R1, Op.getOperand(3), SDOperand());
-    Copy = DAG.getCopyToReg(Copy, ARM::R0, Op.getOperand(1), Copy.getValue(1));
-    // If we haven't noted the R0+R1 are live out, do so now.
-    if (DAG.getMachineFunction().liveout_empty()) {
-      DAG.getMachineFunction().addLiveOut(ARM::R0);
-      DAG.getMachineFunction().addLiveOut(ARM::R1);
-    }
-    break;
-  }
-
-  //We must use RET_FLAG instead of BRIND because BRIND doesn't have a flag
-  return DAG.getNode(ARMISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
-}
-
-static SDOperand LowerConstantPool(SDOperand Op, SelectionDAG &DAG) {
-  MVT::ValueType PtrVT = Op.getValueType();
-  ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
-  Constant *C = CP->getConstVal();
-  SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
-
-  return CPI;
-}
-
-SDOperand LegalizeImmediate(uint32_t immediate, SelectionDAG &DAG,
-                            bool canReturnConstant){
-  SDOperand Shift = DAG.getTargetConstant(0, MVT::i32);
-  SDOperand ShiftType = DAG.getTargetConstant(ARMShift::LSL, MVT::i32);
-  std::vector<unsigned>immediatePieces = splitImmediate(immediate);
-  if (immediatePieces.size()>1){
-    unsigned movInst = ARM::MOV;
-    unsigned orInst = ARM::ORR;
-    SDNode *node;
-    //try mvn
-    std::vector<unsigned>immediateNegPieces = splitImmediate(~immediate);
-    if (immediatePieces.size() > immediateNegPieces.size()) {
-      //use mvn/eor
-      movInst = ARM::MVN;
-      orInst = ARM::EOR;
-      immediatePieces = immediateNegPieces;
-    }
-    SDOperand n = DAG.getTargetConstant(immediatePieces[0], MVT::i32);
-    node = DAG.getTargetNode(movInst, MVT::i32, n, Shift, ShiftType);
-    std::vector<unsigned>::iterator it;
-    for (it=immediatePieces.begin()+1; it != immediatePieces.end(); ++it){
-      n = DAG.getTargetConstant(*it, MVT::i32);
-      SDOperand ops[] = {SDOperand(node, 0), n, Shift, ShiftType};
-      node = DAG.getTargetNode(orInst, MVT::i32, ops, 4);
-    }
-    return SDOperand(node, 0);
-  } else {
-    if (canReturnConstant)
-      return DAG.getTargetConstant(immediate, MVT::i32);
-    else {
-      SDOperand n = DAG.getTargetConstant(immediate, MVT::i32);
-      SDNode *node = DAG.getTargetNode(ARM::MOV,  MVT::i32, n, Shift,
-                                       ShiftType);
-      return SDOperand(node, 0);
-    }
-  }
-}
-
-static SDOperand LowerConstantFP(SDOperand Op, SelectionDAG &DAG) {
-  MVT::ValueType VT = Op.getValueType();
-  SDOperand Shift     = DAG.getTargetConstant(0, MVT::i32);
-  SDOperand ShiftType = DAG.getTargetConstant(ARMShift::LSL, MVT::i32);
-  SDNode *node;
-  switch (VT) {
-  default: assert(0 && "VT!=f32 && VT!=f64");
-  case MVT::f32: {
-    float val = cast<ConstantFPSDNode>(Op)->getValue();
-    uint32_t i32_val = FloatToBits(val);
-    SDOperand c = LegalizeImmediate(i32_val, DAG, false);
-    node = DAG.getTargetNode(ARM::FMSR, MVT::f32, c);
-    break;
-  }
-  case MVT::f64: {
-    double val = cast<ConstantFPSDNode>(Op)->getValue();
-    uint64_t i64_val = DoubleToBits(val);
-    SDOperand hi = LegalizeImmediate(Hi_32(i64_val), DAG, false);
-    SDOperand lo = LegalizeImmediate(Lo_32(i64_val), DAG, false);
-    node = DAG.getTargetNode(ARM::FMDRR, MVT::f64, lo, hi);
-    break;
-  }
-  }
-  return SDOperand(node, 0);
-}
-
-static SDOperand LowerGlobalAddress(SDOperand Op,
-				    SelectionDAG &DAG) {
-  GlobalValue  *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
-  int alignment = 2;
-  SDOperand CPAddr = DAG.getConstantPool(GV, MVT::i32, alignment);
-  return DAG.getLoad(MVT::i32, DAG.getEntryNode(), CPAddr, NULL, 0);
-}
-
-static SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG,
-                              unsigned VarArgsFrameIndex) {
-  // vastart just stores the address of the VarArgsFrameIndex slot into the
-  // memory location argument.
-  MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
-  SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
-  SrcValueSDNode *SV = cast<SrcValueSDNode>(Op.getOperand(2));
-  return DAG.getStore(Op.getOperand(0), FR, Op.getOperand(1), SV->getValue(),
-                      SV->getOffset());
-}
-
-static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
-				       int &VarArgsFrameIndex) {
-  MachineFunction   &MF = DAG.getMachineFunction();
-  MachineFrameInfo *MFI = MF.getFrameInfo();
-  SSARegMap     *RegMap = MF.getSSARegMap();
-  unsigned      NumArgs = Op.Val->getNumValues()-1;
-  SDOperand        Root = Op.getOperand(0);
-  bool         isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
-  static const unsigned REGS[] = {
-    ARM::R0, ARM::R1, ARM::R2, ARM::R3
-  };
-
-  std::vector<MVT::ValueType> Types(Op.Val->value_begin(), Op.Val->value_end() - 1);
-  ArgumentLayout Layout(Types);
-
-  std::vector<SDOperand> ArgValues;
-  for (unsigned ArgNo = 0; ArgNo < NumArgs; ++ArgNo) {
-    MVT::ValueType VT = Types[ArgNo];
-
-    SDOperand Value;
-    if (Layout.isRegister(ArgNo)) {
-      assert(VT == MVT::i32 || VT == MVT::f32 || VT == MVT::f64);
-      unsigned  RegNum = Layout.getRegisterNum(ArgNo);
-      unsigned    Reg1 = REGS[RegNum];
-      unsigned   VReg1 = RegMap->createVirtualRegister(&ARM::IntRegsRegClass);
-      SDOperand Value1 = DAG.getCopyFromReg(Root, VReg1, MVT::i32);
-      MF.addLiveIn(Reg1, VReg1);
-      if (VT == MVT::f64) {
-        unsigned    Reg2 = REGS[RegNum + 1];
-        unsigned   VReg2 = RegMap->createVirtualRegister(&ARM::IntRegsRegClass);
-        SDOperand Value2 = DAG.getCopyFromReg(Root, VReg2, MVT::i32);
-        MF.addLiveIn(Reg2, VReg2);
-        Value            = DAG.getNode(ARMISD::FMDRR, MVT::f64, Value1, Value2);
-      } else {
-        Value = Value1;
-        if (VT == MVT::f32)
-          Value = DAG.getNode(ISD::BIT_CONVERT, VT, Value);
-      }
-    } else {
-      // If the argument is actually used, emit a load from the right stack
-      // slot.
-      if (!Op.Val->hasNUsesOfValue(0, ArgNo)) {
-        unsigned Offset = Layout.getOffset(ArgNo);
-        unsigned   Size = MVT::getSizeInBits(VT)/8;
-        int          FI = MFI->CreateFixedObject(Size, Offset);
-        SDOperand   FIN = DAG.getFrameIndex(FI, VT);
-        Value = DAG.getLoad(VT, Root, FIN, NULL, 0);
-      } else {
-        Value = DAG.getNode(ISD::UNDEF, VT);
-      }
-    }
-    ArgValues.push_back(Value);
-  }
-
-  unsigned NextRegNum = Layout.lastRegNum() + 1;
-
-  if (isVarArg) {
-    //If this function is vararg we must store the remaing
-    //registers so that they can be acessed with va_start
-    VarArgsFrameIndex = MFI->CreateFixedObject(MVT::getSizeInBits(MVT::i32)/8,
-                                               -16 + NextRegNum * 4);
-
-    SmallVector<SDOperand, 4> MemOps;
-    for (unsigned RegNo = NextRegNum; RegNo < 4; ++RegNo) {
-      int RegOffset = - (4 - RegNo) * 4;
-      int FI = MFI->CreateFixedObject(MVT::getSizeInBits(MVT::i32)/8,
-				      RegOffset);
-      SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
-
-      unsigned VReg = RegMap->createVirtualRegister(&ARM::IntRegsRegClass);
-      MF.addLiveIn(REGS[RegNo], VReg);
-
-      SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::i32);
-      SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
-      MemOps.push_back(Store);
-    }
-    Root = DAG.getNode(ISD::TokenFactor, MVT::Other,&MemOps[0],MemOps.size());
-  }
-
-  ArgValues.push_back(Root);
-
-  // Return the new list of results.
-  std::vector<MVT::ValueType> RetVT(Op.Val->value_begin(),
-                                    Op.Val->value_end());
-  return DAG.getNode(ISD::MERGE_VALUES, RetVT, &ArgValues[0], ArgValues.size());
-}
-
-static SDOperand GetCMP(ISD::CondCode CC, SDOperand LHS, SDOperand RHS,
-                        SelectionDAG &DAG) {
-  MVT::ValueType vt = LHS.getValueType();
-  assert(vt == MVT::i32 || vt == MVT::f32 || vt == MVT::f64);
-
-  SDOperand Cmp = DAG.getNode(ARMISD::CMP,  MVT::Flag, LHS, RHS);
-
-  if (vt != MVT::i32)
-    Cmp = DAG.getNode(ARMISD::FMSTAT, MVT::Flag, Cmp);
-  return Cmp;
-}
-
-static std::vector<SDOperand> GetARMCC(ISD::CondCode CC, MVT::ValueType vt,
-                          SelectionDAG &DAG) {
-  assert(vt == MVT::i32 || vt == MVT::f32 || vt == MVT::f64);
-  std::vector<unsigned> vcc;
-  if (vt == MVT::i32)
-    vcc = DAGIntCCToARMCC(CC);
-  else
-    vcc = DAGFPCCToARMCC(CC);
-
-  std::vector<unsigned>::iterator it;
-  std::vector<SDOperand> result;
-  for( it = vcc.begin(); it != vcc.end(); it++ )
-    result.push_back(DAG.getConstant(*it,MVT::i32));
-  return result;
-}
-
-static bool isUInt8Immediate(uint32_t x) {
-  return x < (1 << 8);
-}
-
-static uint32_t rotateL(uint32_t x) {
-  uint32_t bit31 = (x & (1 << 31)) >> 31;
-  uint32_t     t = x << 1;
-  return t | bit31;
-}
-
-static bool isRotInt8Immediate(uint32_t x) {
-  int r;
-  for (r = 0; r < 16; r++) {
-    if (isUInt8Immediate(x))
-      return true;
-    x = rotateL(rotateL(x));
-  }
-  return false;
-}
-
-static void LowerCMP(SDOperand &Cmp, std::vector<SDOperand> &ARMCC,
-                     SDOperand LHS, SDOperand RHS, ISD::CondCode CC,
-                     SelectionDAG &DAG) {
-  MVT::ValueType vt = LHS.getValueType();
-  if (vt == MVT::i32) {
-    assert(!isa<ConstantSDNode>(LHS));
-    if (ConstantSDNode *SD_C = dyn_cast<ConstantSDNode>(RHS.Val)) {
-      uint32_t C = SD_C->getValue();
-
-      uint32_t NC;
-      switch(CC) {
-      default:
-        NC = C; break;
-      case ISD::SETLT:
-      case ISD::SETULT:
-      case ISD::SETGE:
-      case ISD::SETUGE:
-        NC = C - 1; break;
-      case ISD::SETLE:
-      case ISD::SETULE:
-      case ISD::SETGT:
-      case ISD::SETUGT:
-        NC = C + 1; break;
-      }
-
-      ISD::CondCode NCC;
-      switch(CC) {
-      default:
-        NCC = CC; break;
-      case ISD::SETLT:
-        NCC = ISD::SETLE; break;
-      case ISD::SETULT:
-        NCC = ISD::SETULE; break;
-      case ISD::SETGE:
-        NCC = ISD::SETGT; break;
-      case ISD::SETUGE:
-        NCC = ISD::SETUGT; break;
-      case ISD::SETLE:
-        NCC = ISD::SETLT; break;
-      case ISD::SETULE:
-        NCC = ISD::SETULT; break;
-      case ISD::SETGT:
-        NCC = ISD::SETGE; break;
-      case ISD::SETUGT:
-        NCC = ISD::SETUGE; break;
-      }
-
-      if (!isRotInt8Immediate(C) && isRotInt8Immediate(NC)) {
-        RHS = DAG.getConstant(NC, MVT::i32);
-        CC  = NCC;
-      }
-    }
-  }
-  Cmp   = GetCMP(CC, LHS, RHS, DAG);
-  ARMCC = GetARMCC(CC, vt, DAG);
-}
-
-static SDOperand LowerSELECT_CC(SDOperand Op, SelectionDAG &DAG) {
-  SDOperand LHS = Op.getOperand(0);
-  SDOperand RHS = Op.getOperand(1);
-  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
-  SDOperand TrueVal = Op.getOperand(2);
-  SDOperand FalseVal = Op.getOperand(3);
-  SDOperand Cmp;
-  std::vector<SDOperand> ARMCC;
-  LowerCMP(Cmp, ARMCC, LHS, RHS, CC, DAG);
-
-  SDOperand Aux = FalseVal;
-  SDVTList  VTs = DAG.getVTList(Op.getValueType(), MVT::Flag);
-  std::vector<SDOperand>::iterator it;
-  for (it = ARMCC.begin(); it != ARMCC.end(); ++it){
-    SDOperand  Flag = it == ARMCC.begin() ? Cmp : Aux.getValue(1);
-    SDOperand Ops[] = {TrueVal, Aux, *it, Flag};
-    Aux  = DAG.getNode(ARMISD::SELECT, VTs, Ops, 4);
-  }
-  return Aux;
-}
-
-static SDOperand LowerBR_CC(SDOperand Op, SelectionDAG &DAG) {
-  SDOperand  Chain = Op.getOperand(0);
-  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
-  SDOperand    LHS = Op.getOperand(2);
-  SDOperand    RHS = Op.getOperand(3);
-  SDOperand   Dest = Op.getOperand(4);
-  SDOperand Cmp;
-  std::vector<SDOperand> ARMCC;
-  LowerCMP(Cmp, ARMCC, LHS, RHS, CC, DAG);
-
-  SDOperand Aux = Chain;
-  SDVTList  VTs = DAG.getVTList(MVT::Other, MVT::Flag);
-  std::vector<SDOperand>::iterator it;
-  for (it = ARMCC.begin(); it != ARMCC.end(); it++){
-    SDOperand  Flag = it == ARMCC.begin() ? Cmp : Aux.getValue(1);
-    SDOperand Ops[] = {Aux, Dest, *it, Flag};
-    Aux = DAG.getNode(ARMISD::BR, VTs, Ops, 4);
-  }
-  return Aux;
-}
-
-static SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
-  SDOperand IntVal  = Op.getOperand(0);
-  assert(IntVal.getValueType() == MVT::i32);
-  MVT::ValueType vt = Op.getValueType();
-  assert(vt == MVT::f32 ||
-         vt == MVT::f64);
-
-  SDOperand Tmp = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, IntVal);
-  ARMISD::NodeType op = vt == MVT::f32 ? ARMISD::FSITOS : ARMISD::FSITOD;
-  return DAG.getNode(op, vt, Tmp);
-}
-
-static SDOperand LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG) {
-  assert(Op.getValueType() == MVT::i32);
-  SDOperand FloatVal = Op.getOperand(0);
-  MVT::ValueType  vt = FloatVal.getValueType();
-  assert(vt == MVT::f32 || vt == MVT::f64);
-
-  ARMISD::NodeType op = vt == MVT::f32 ? ARMISD::FTOSIS : ARMISD::FTOSID;
-  SDOperand Tmp = DAG.getNode(op, MVT::f32, FloatVal);
-  return DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Tmp);
-}
-
-static SDOperand LowerUINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
-  SDOperand IntVal  = Op.getOperand(0);
-  assert(IntVal.getValueType() == MVT::i32);
-  MVT::ValueType vt = Op.getValueType();
-  assert(vt == MVT::f32 ||
-         vt == MVT::f64);
-
-  SDOperand Tmp = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, IntVal);
-  ARMISD::NodeType op = vt == MVT::f32 ? ARMISD::FUITOS : ARMISD::FUITOD;
-  return DAG.getNode(op, vt, Tmp);
-}
-
-static SDOperand LowerFP_TO_UINT(SDOperand Op, SelectionDAG &DAG) {
-  assert(Op.getValueType() == MVT::i32);
-  SDOperand FloatVal = Op.getOperand(0);
-  MVT::ValueType  vt = FloatVal.getValueType();
-  assert(vt == MVT::f32 || vt == MVT::f64);
-
-  ARMISD::NodeType op = vt == MVT::f32 ? ARMISD::FTOUIS : ARMISD::FTOUID;
-  SDOperand Tmp = DAG.getNode(op, MVT::f32, FloatVal);
-  return DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Tmp);
-}
-
-SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
-  switch (Op.getOpcode()) {
-  default:
-    assert(0 && "Should not custom lower this!");
-    abort();
-  case ISD::ConstantPool:
-    return LowerConstantPool(Op, DAG);
-  case ISD::ConstantFP:
-    return LowerConstantFP(Op, DAG);
-  case ISD::GlobalAddress:
-    return LowerGlobalAddress(Op, DAG);
-  case ISD::FP_TO_SINT:
-    return LowerFP_TO_SINT(Op, DAG);
-  case ISD::SINT_TO_FP:
-    return LowerSINT_TO_FP(Op, DAG);
-  case ISD::FP_TO_UINT:
-    return LowerFP_TO_UINT(Op, DAG);
-  case ISD::UINT_TO_FP:
-    return LowerUINT_TO_FP(Op, DAG);
-  case ISD::FORMAL_ARGUMENTS:
-    return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
-  case ISD::CALL:
-    return LowerCALL(Op, DAG);
-  case ISD::RET:
-    return LowerRET(Op, DAG);
-  case ISD::SELECT_CC:
-    return LowerSELECT_CC(Op, DAG);
-  case ISD::BR_CC:
-    return LowerBR_CC(Op, DAG);
-  case ISD::VASTART:
-    return LowerVASTART(Op, DAG, VarArgsFrameIndex);
-  }
-}
-
-//===----------------------------------------------------------------------===//
-// Instruction Selector Implementation
-//===----------------------------------------------------------------------===//
-
 //===--------------------------------------------------------------------===//
 /// ARMDAGToDAGISel - ARM specific code to select ARM machine
 /// instructions for SelectionDAG operations.
@@ -954,25 +39,54 @@
 class ARMDAGToDAGISel : public SelectionDAGISel {
   ARMTargetLowering Lowering;
 
+  /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
+  /// make the right decision when generating code for different targets.
+  const ARMSubtarget *Subtarget;
+
 public:
-  ARMDAGToDAGISel(TargetMachine &TM)
-    : SelectionDAGISel(Lowering), Lowering(TM) {
+  ARMDAGToDAGISel(ARMTargetMachine &TM)
+    : SelectionDAGISel(Lowering), Lowering(TM),
+    Subtarget(&TM.getSubtarget<ARMSubtarget>()) {
   }
 
+  virtual const char *getPassName() const {
+    return "ARM Instruction Selection";
+  } 
+  
   SDNode *Select(SDOperand Op);
   virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
-  bool SelectAddrMode1(SDOperand Op, SDOperand N, SDOperand &Arg,
-                       SDOperand &Shift, SDOperand &ShiftType);
-  bool SelectAddrMode1a(SDOperand Op, SDOperand N, SDOperand &Arg,
-			SDOperand &Shift, SDOperand &ShiftType);
-  bool SelectAddrMode2(SDOperand Op, SDOperand N, SDOperand &Arg,
-                       SDOperand &Offset);
-  bool SelectAddrMode5(SDOperand Op, SDOperand N, SDOperand &Arg,
+  bool SelectAddrMode2(SDOperand Op, SDOperand N, SDOperand &Base,
+                       SDOperand &Offset, SDOperand &Opc);
+  bool SelectAddrMode2Offset(SDOperand Op, SDOperand N,
+                             SDOperand &Offset, SDOperand &Opc);
+  bool SelectAddrMode3(SDOperand Op, SDOperand N, SDOperand &Base,
+                       SDOperand &Offset, SDOperand &Opc);
+  bool SelectAddrMode3Offset(SDOperand Op, SDOperand N,
+                             SDOperand &Offset, SDOperand &Opc);
+  bool SelectAddrMode5(SDOperand Op, SDOperand N, SDOperand &Base,
                        SDOperand &Offset);
 
+  bool SelectAddrModePC(SDOperand Op, SDOperand N, SDOperand &Offset,
+                         SDOperand &Label);
+
+  bool SelectThumbAddrModeRR(SDOperand Op, SDOperand N, SDOperand &Base,
+                             SDOperand &Offset);
+  bool SelectThumbAddrModeRI5_1(SDOperand Op, SDOperand N, SDOperand &Base,
+                                SDOperand &Offset);
+  bool SelectThumbAddrModeRI5_2(SDOperand Op, SDOperand N, SDOperand &Base,
+                                SDOperand &Offset);
+  bool SelectThumbAddrModeRI5_4(SDOperand Op, SDOperand N, SDOperand &Base,
+                                SDOperand &Offset);
+  bool SelectThumbAddrModeSP(SDOperand Op, SDOperand N, SDOperand &Base,
+                             SDOperand &Offset);
+
+  bool SelectShifterOperandReg(SDOperand Op, SDOperand N, SDOperand &A,
+                               SDOperand &B, SDOperand &C);
+  
   // Include the pieces autogenerated from the target description.
 #include "ARMGenDAGISel.inc"
 };
+}
 
 void ARMDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
   DEBUG(BB->dump());
@@ -983,126 +97,476 @@
   ScheduleAndEmitDAG(DAG);
 }
 
-static bool isInt12Immediate(SDNode *N, short &Imm) {
-  if (N->getOpcode() != ISD::Constant)
-    return false;
-
-  int32_t t = cast<ConstantSDNode>(N)->getValue();
-  int max = 1<<12;
-  int min = -max;
-  if (t > min && t < max) {
-    Imm = t;
-    return true;
-  }
-  else
-    return false;
-}
-
-static bool isInt12Immediate(SDOperand Op, short &Imm) {
-  return isInt12Immediate(Op.Val, Imm);
-}
-
-bool ARMDAGToDAGISel::SelectAddrMode1(SDOperand Op,
-                                      SDOperand N,
-				      SDOperand &Arg,
-				      SDOperand &Shift,
-				      SDOperand &ShiftType) {
-  switch(N.getOpcode()) {
-  case ISD::Constant: {
-    uint32_t val = cast<ConstantSDNode>(N)->getValue();
-    Shift        = CurDAG->getTargetConstant(0, MVT::i32);
-    ShiftType    = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32);
-    Arg = LegalizeImmediate(val, *CurDAG, true);
-    return true;
-  }
-
-  case ISD::SRA:
-    Arg       = N.getOperand(0);
-    Shift     = N.getOperand(1);
-    ShiftType = CurDAG->getTargetConstant(ARMShift::ASR, MVT::i32);
-    return true;
-  case ISD::SRL:
-    Arg       = N.getOperand(0);
-    Shift     = N.getOperand(1);
-    ShiftType = CurDAG->getTargetConstant(ARMShift::LSR, MVT::i32);
-    return true;
-  case ISD::SHL:
-    Arg       = N.getOperand(0);
-    Shift     = N.getOperand(1);
-    ShiftType = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32);
-    return true;
-  }
-
-  Arg       = N;
-  Shift     = CurDAG->getTargetConstant(0, MVT::i32);
-  ShiftType = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32);
-  return true;
-}
-
 bool ARMDAGToDAGISel::SelectAddrMode2(SDOperand Op, SDOperand N,
-                                      SDOperand &Arg, SDOperand &Offset) {
-  //TODO: complete and cleanup!
-  SDOperand Zero = CurDAG->getTargetConstant(0, MVT::i32);
-  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N)) {
-    Arg    = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
-    Offset = Zero;
+                                      SDOperand &Base, SDOperand &Offset,
+                                      SDOperand &Opc) {
+  if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) {
+    Base = N;
+    if (N.getOpcode() == ISD::FrameIndex) {
+      int FI = cast<FrameIndexSDNode>(N)->getIndex();
+      Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
+    } else if (N.getOpcode() == ARMISD::Wrapper) {
+      Base = N.getOperand(0);
+    }
+    Offset = CurDAG->getRegister(0, MVT::i32);
+    Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0,
+                                                      ARM_AM::no_shift),
+                                    MVT::i32);
     return true;
   }
-  if (N.getOpcode() == ISD::ADD) {
-    short imm = 0;
-    if (isInt12Immediate(N.getOperand(1), imm)) {
-      Offset = CurDAG->getTargetConstant(imm, MVT::i32);
-      if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0))) {
-	Arg = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType());
-      } else {
-	Arg = N.getOperand(0);
+  
+  // Match simple R +/- imm12 operands.
+  if (N.getOpcode() == ISD::ADD)
+    if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
+      int RHSC = (int)RHS->getValue();
+      if (RHSC >= 0 && RHSC < 0x1000) { // 12 bits.
+        Base = N.getOperand(0);
+        Offset = CurDAG->getRegister(0, MVT::i32);
+        Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, RHSC,
+                                                          ARM_AM::no_shift),
+                                        MVT::i32);
+        return true;
+      } else if (RHSC < 0 && RHSC > -0x1000) {
+        Base = N.getOperand(0);
+        Offset = CurDAG->getRegister(0, MVT::i32);
+        Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::sub, -RHSC,
+                                                          ARM_AM::no_shift),
+                                        MVT::i32);
+        return true;
       }
-      return true; // [r+i]
+    }
+  
+  // Otherwise this is R +/- [possibly shifted] R
+  ARM_AM::AddrOpc AddSub = N.getOpcode() == ISD::ADD ? ARM_AM::add:ARM_AM::sub;
+  ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(1));
+  unsigned ShAmt = 0;
+  
+  Base   = N.getOperand(0);
+  Offset = N.getOperand(1);
+  
+  if (ShOpcVal != ARM_AM::no_shift) {
+    // Check to see if the RHS of the shift is a constant, if not, we can't fold
+    // it.
+    if (ConstantSDNode *Sh =
+           dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) {
+      ShAmt = Sh->getValue();
+      Offset = N.getOperand(1).getOperand(0);
+    } else {
+      ShOpcVal = ARM_AM::no_shift;
     }
   }
-  Offset = Zero;
-  if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N))
-    Arg = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType());
-  else
-    Arg = N;
+  
+  // Try matching (R shl C) + (R).
+  if (N.getOpcode() == ISD::ADD && ShOpcVal == ARM_AM::no_shift) {
+    ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0));
+    if (ShOpcVal != ARM_AM::no_shift) {
+      // Check to see if the RHS of the shift is a constant, if not, we can't
+      // fold it.
+      if (ConstantSDNode *Sh =
+          dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) {
+        ShAmt = Sh->getValue();
+        Offset = N.getOperand(0).getOperand(0);
+        Base = N.getOperand(1);
+      } else {
+        ShOpcVal = ARM_AM::no_shift;
+      }
+    }
+  }
+  
+  Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal),
+                                  MVT::i32);
   return true;
 }
 
-bool ARMDAGToDAGISel::SelectAddrMode5(SDOperand Op,
-                                      SDOperand N, SDOperand &Arg,
-                                      SDOperand &Offset) {
-  //TODO: detect offset
-  Offset = CurDAG->getTargetConstant(0, MVT::i32);
-  Arg    = N;
+bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDOperand Op, SDOperand N,
+                                            SDOperand &Offset, SDOperand &Opc) {
+  unsigned Opcode = Op.getOpcode();
+  ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
+    ? cast<LoadSDNode>(Op)->getAddressingMode()
+    : cast<StoreSDNode>(Op)->getAddressingMode();
+  ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC)
+    ? ARM_AM::add : ARM_AM::sub;
+  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) {
+    int Val = (int)C->getValue();
+    if (Val >= 0 && Val < 0x1000) { // 12 bits.
+      Offset = CurDAG->getRegister(0, MVT::i32);
+      Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, Val,
+                                                        ARM_AM::no_shift),
+                                      MVT::i32);
+      return true;
+    }
+  }
+
+  Offset = N;
+  ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
+  unsigned ShAmt = 0;
+  if (ShOpcVal != ARM_AM::no_shift) {
+    // Check to see if the RHS of the shift is a constant, if not, we can't fold
+    // it.
+    if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
+      ShAmt = Sh->getValue();
+      Offset = N.getOperand(0);
+    } else {
+      ShOpcVal = ARM_AM::no_shift;
+    }
+  }
+
+  Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal),
+                                  MVT::i32);
   return true;
 }
 
+
+bool ARMDAGToDAGISel::SelectAddrMode3(SDOperand Op, SDOperand N,
+                                      SDOperand &Base, SDOperand &Offset,
+                                      SDOperand &Opc) {
+  if (N.getOpcode() == ISD::SUB) {
+    // X - C  is canonicalize to X + -C, no need to handle it here.
+    Base = N.getOperand(0);
+    Offset = N.getOperand(1);
+    Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, 0),MVT::i32);
+    return true;
+  }
+  
+  if (N.getOpcode() != ISD::ADD) {
+    Base = N;
+    if (N.getOpcode() == ISD::FrameIndex) {
+      int FI = cast<FrameIndexSDNode>(N)->getIndex();
+      Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
+    }
+    Offset = CurDAG->getRegister(0, MVT::i32);
+    Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0),MVT::i32);
+    return true;
+  }
+  
+  // If the RHS is +/- imm8, fold into addr mode.
+  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
+    int RHSC = (int)RHS->getValue();
+    if (RHSC >= 0 && RHSC < 256) {
+      Base = N.getOperand(0);
+      Offset = CurDAG->getRegister(0, MVT::i32);
+      Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, RHSC),
+                                      MVT::i32);
+      return true;
+    } else if (RHSC < 0 && RHSC > -256) { // note -256 itself isn't allowed.
+      Base = N.getOperand(0);
+      Offset = CurDAG->getRegister(0, MVT::i32);
+      Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, -RHSC),
+                                      MVT::i32);
+      return true;
+    }
+  }
+  
+  Base = N.getOperand(0);
+  Offset = N.getOperand(1);
+  Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), MVT::i32);
+  return true;
+}
+
+bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDOperand Op, SDOperand N,
+                                            SDOperand &Offset, SDOperand &Opc) {
+  unsigned Opcode = Op.getOpcode();
+  ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
+    ? cast<LoadSDNode>(Op)->getAddressingMode()
+    : cast<StoreSDNode>(Op)->getAddressingMode();
+  ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC)
+    ? ARM_AM::add : ARM_AM::sub;
+  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) {
+    int Val = (int)C->getValue();
+    if (Val >= 0 && Val < 256) {
+      Offset = CurDAG->getRegister(0, MVT::i32);
+      Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, Val), MVT::i32);
+      return true;
+    }
+  }
+
+  Offset = N;
+  Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, 0), MVT::i32);
+  return true;
+}
+
+
+bool ARMDAGToDAGISel::SelectAddrMode5(SDOperand Op, SDOperand N,
+                                      SDOperand &Base, SDOperand &Offset) {
+  if (N.getOpcode() != ISD::ADD) {
+    Base = N;
+    if (N.getOpcode() == ISD::FrameIndex) {
+      int FI = cast<FrameIndexSDNode>(N)->getIndex();
+      Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
+    } else if (N.getOpcode() == ARMISD::Wrapper) {
+      Base = N.getOperand(0);
+    }
+    Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0),
+                                       MVT::i32);
+    return true;
+  }
+  
+  // If the RHS is +/- imm8, fold into addr mode.
+  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
+    int RHSC = (int)RHS->getValue();
+    if ((RHSC & 3) == 0) {  // The constant is implicitly multiplied by 4.
+      RHSC >>= 2;
+      if (RHSC >= 0 && RHSC < 256) {
+        Base = N.getOperand(0);
+        Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, RHSC),
+                                           MVT::i32);
+        return true;
+      } else if (RHSC < 0 && RHSC > -256) { // note -256 itself isn't allowed.
+        Base = N.getOperand(0);
+        Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::sub,-RHSC),
+                                           MVT::i32);
+        return true;
+      }
+    }
+  }
+  
+  Base = N;
+  Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0),
+                                     MVT::i32);
+  return true;
+}
+
+bool ARMDAGToDAGISel::SelectAddrModePC(SDOperand Op, SDOperand N,
+                                        SDOperand &Offset, SDOperand &Label) {
+  if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) {
+    Offset = N.getOperand(0);
+    SDOperand N1 = N.getOperand(1);
+    Label  = CurDAG->getTargetConstant(cast<ConstantSDNode>(N1)->getValue(),
+                                       MVT::i32);
+    return true;
+  }
+  return false;
+}
+
+bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDOperand Op, SDOperand N,
+                                            SDOperand &Base, SDOperand &Offset){
+  if (N.getOpcode() != ISD::ADD)
+    return false;
+  Base = N.getOperand(0);
+  Offset = N.getOperand(1);
+  return true;
+}
+
+static bool SelectThumbAddrModeRI5(SDOperand N, unsigned Scale,
+                                   TargetLowering &TLI, SelectionDAG *CurDAG,
+                                   SDOperand &Base, SDOperand &Offset) {
+  if (N.getOpcode() == ISD::FrameIndex)
+    return false;
+    
+  if (N.getOpcode() != ISD::ADD) {
+    Base = (N.getOpcode() == ARMISD::Wrapper) ? N.getOperand(0) : N;
+    Offset = CurDAG->getTargetConstant(0, MVT::i32);
+    return true;
+  }
+
+  // If the RHS is + imm5 * scale, fold into addr mode.
+  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
+    int RHSC = (int)RHS->getValue();
+    if ((RHSC & (Scale-1)) == 0) {  // The constant is implicitly multiplied.
+      RHSC /= Scale;
+      if (RHSC >= 0 && RHSC < 32) {
+        Base = N.getOperand(0);
+        Offset = CurDAG->getTargetConstant(RHSC, MVT::i32);
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+bool ARMDAGToDAGISel::SelectThumbAddrModeRI5_1(SDOperand Op, SDOperand N,
+                                            SDOperand &Base, SDOperand &Offset){
+  return SelectThumbAddrModeRI5(N, 1, TLI, CurDAG, Base, Offset);
+}
+
+bool ARMDAGToDAGISel::SelectThumbAddrModeRI5_2(SDOperand Op, SDOperand N,
+                                            SDOperand &Base, SDOperand &Offset){
+  return SelectThumbAddrModeRI5(N, 2, TLI, CurDAG, Base, Offset);
+}
+
+bool ARMDAGToDAGISel::SelectThumbAddrModeRI5_4(SDOperand Op, SDOperand N,
+                                            SDOperand &Base, SDOperand &Offset){
+  return SelectThumbAddrModeRI5(N, 4, TLI, CurDAG, Base, Offset);
+}
+
+bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDOperand Op, SDOperand N,
+                                           SDOperand &Base, SDOperand &Offset) {
+  if (N.getOpcode() == ISD::FrameIndex) {
+    int FI = cast<FrameIndexSDNode>(N)->getIndex();
+    Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
+    Offset = CurDAG->getTargetConstant(0, MVT::i32);
+    return true;
+  }
+  
+  return false;
+}
+
+bool ARMDAGToDAGISel::SelectShifterOperandReg(SDOperand Op,
+                                              SDOperand N, 
+                                              SDOperand &BaseReg,
+                                              SDOperand &ShReg,
+                                              SDOperand &Opc) {
+  ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
+
+  // Don't match base register only case. That is matched to a separate
+  // lower complexity pattern with explicit register operand.
+  if (ShOpcVal == ARM_AM::no_shift) return false;
+  
+  BaseReg = N.getOperand(0);
+  unsigned ShImmVal = 0;
+  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
+    ShReg = CurDAG->getRegister(0, MVT::i32);
+    ShImmVal = RHS->getValue() & 31;
+  } else {
+    ShReg = N.getOperand(1);
+  }
+  Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal),
+                                  MVT::i32);
+  return true;
+}
+
+
 SDNode *ARMDAGToDAGISel::Select(SDOperand Op) {
   SDNode *N = Op.Val;
+  unsigned Opcode = N->getOpcode();
+
+  if (Opcode >= ISD::BUILTIN_OP_END && Opcode < ARMISD::FIRST_NUMBER)
+    return NULL;   // Already selected.
 
   switch (N->getOpcode()) {
-  default:
-    return SelectCode(Op);
+  default: break;
+  case ISD::Constant: {
+    unsigned Val = cast<ConstantSDNode>(N)->getValue();
+    bool UseCP = true;
+    if (Subtarget->isThumb())
+      UseCP = (Val > 255 &&                          // MOV
+               ~Val > 255 &&                         // MOV + MVN
+               !ARM_AM::isThumbImmShiftedVal(Val));  // MOV + LSL
+    else
+      UseCP = (ARM_AM::getSOImmVal(Val) == -1 &&     // MOV
+               ARM_AM::getSOImmVal(~Val) == -1 &&    // MVN
+               !ARM_AM::isSOImmTwoPartVal(Val));     // two instrs.
+    if (UseCP) {
+      SDOperand CPIdx =
+        CurDAG->getTargetConstantPool(ConstantInt::get(Type::Int32Ty, Val),
+                                      TLI.getPointerTy());
+      SDOperand Ops[] = {
+        CPIdx, 
+        CurDAG->getRegister(0, MVT::i32),
+        CurDAG->getTargetConstant(0, MVT::i32),
+        CurDAG->getEntryNode()
+      };
+      SDNode *ResNode = 
+        CurDAG->getTargetNode(ARM::LDR, MVT::i32, MVT::Other, Ops, 4);
+      ReplaceUses(Op, SDOperand(ResNode, 0));
+      return NULL;
+    }
+      
+    // Other cases are autogenerated.
     break;
+  }
   case ISD::FrameIndex: {
+    // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm.
     int FI = cast<FrameIndexSDNode>(N)->getIndex();
-    SDOperand Ops[] = {CurDAG->getTargetFrameIndex(FI, MVT::i32),
-                       CurDAG->getTargetConstant(0, MVT::i32),
-                       CurDAG->getTargetConstant(0, MVT::i32),
-                       CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32)};
+    unsigned Opc = Subtarget->isThumb() ? ARM::tADDrSPi : ARM::ADDri;
+    SDOperand TFI = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
+    return CurDAG->SelectNodeTo(N, Opc, MVT::i32, TFI,
+                                CurDAG->getTargetConstant(0, MVT::i32));
+  }
+  case ISD::MUL:
+    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
+      unsigned RHSV = C->getValue();
+      if (!RHSV) break;
+      if (isPowerOf2_32(RHSV-1)) {  // 2^n+1?
+        SDOperand V = Op.getOperand(0);
+        AddToISelQueue(V);
+        unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV-1));
+        SDOperand Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32),
+          CurDAG->getTargetConstant(ShImm, MVT::i32)
+        };
+        return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 4);
+      }
+      if (isPowerOf2_32(RHSV+1)) {  // 2^n-1?
+        SDOperand V = Op.getOperand(0);
+        AddToISelQueue(V);
+        unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV+1));
+        SDOperand Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32),
+          CurDAG->getTargetConstant(ShImm, MVT::i32)
+        };
+        return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 4);
+      }
+    }
+    break;
+  case ARMISD::FMRRD:
+    AddToISelQueue(Op.getOperand(0));
+    return CurDAG->getTargetNode(ARM::FMRRD, MVT::i32, MVT::i32,
+                                 Op.getOperand(0));
+  case ARMISD::MULHILOU:
+    AddToISelQueue(Op.getOperand(0));
+    AddToISelQueue(Op.getOperand(1));
+    return CurDAG->getTargetNode(ARM::UMULL, MVT::i32, MVT::i32,
+                                 Op.getOperand(0), Op.getOperand(1));
+  case ARMISD::MULHILOS:
+    AddToISelQueue(Op.getOperand(0));
+    AddToISelQueue(Op.getOperand(1));
+    return CurDAG->getTargetNode(ARM::SMULL, MVT::i32, MVT::i32,
+                                 Op.getOperand(0), Op.getOperand(1));
+  case ISD::LOAD: {
+    LoadSDNode *LD = cast<LoadSDNode>(Op);
+    ISD::MemIndexedMode AM = LD->getAddressingMode();
+    MVT::ValueType LoadedVT = LD->getLoadedVT();
+    if (AM != ISD::UNINDEXED) {
+      SDOperand Offset, AMOpc;
+      bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC);
+      unsigned Opcode = 0;
+      bool Match = false;
+      if (LoadedVT == MVT::i32 &&
+          SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) {
+        Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST;
+        Match = true;
+      } else if (LoadedVT == MVT::i16 &&
+                 SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) {
+        Match = true;
+        Opcode = (LD->getExtensionType() == ISD::SEXTLOAD)
+          ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST)
+          : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST);
+      } else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) {
+        if (LD->getExtensionType() == ISD::SEXTLOAD) {
+          if (SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) {
+            Match = true;
+            Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST;
+          }
+        } else {
+          if (SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) {
+            Match = true;
+            Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST;
+          }
+        }
+      }
 
-    return CurDAG->SelectNodeTo(N, ARM::ADD, MVT::i32, Ops,
-                                sizeof(Ops)/sizeof(SDOperand));
+      if (Match) {
+        SDOperand Chain = LD->getChain();
+        SDOperand Base = LD->getBasePtr();
+        AddToISelQueue(Chain);
+        AddToISelQueue(Base);
+        AddToISelQueue(Offset);
+        SDOperand Ops[] = { Base, Offset, AMOpc, Chain };
+        return CurDAG->getTargetNode(Opcode, MVT::i32, MVT::i32,
+                                     MVT::Other, Ops, 4);
+      }
+    }
+    // Other cases are autogenerated.
     break;
   }
   }
-}
 
-}  // end anonymous namespace
+  return SelectCode(Op);
+}
 
 /// createARMISelDag - This pass converts a legalized DAG into a
 /// ARM-specific DAG, ready for instruction scheduling.
 ///
-FunctionPass *llvm::createARMISelDag(TargetMachine &TM) {
+FunctionPass *llvm::createARMISelDag(ARMTargetMachine &TM) {
   return new ARMDAGToDAGISel(TM);
 }
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
new file mode 100644
index 0000000..f4cba4b
--- /dev/null
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -0,0 +1,1414 @@
+//===-- ARMISelLowering.cpp - ARM DAG Lowering Implementation -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Evan Cheng and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interfaces that ARM uses to lower LLVM code into a
+// selection DAG.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ARM.h"
+#include "ARMAddressingModes.h"
+#include "ARMConstantPoolValue.h"
+#include "ARMISelLowering.h"
+#include "ARMMachineFunctionInfo.h"
+#include "ARMRegisterInfo.h"
+#include "ARMSubtarget.h"
+#include "ARMTargetMachine.h"
+#include "llvm/CallingConv.h"
+#include "llvm/Constants.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/SSARegMap.h"
+#include "llvm/ADT/VectorExtras.h"
+using namespace llvm;
+
+ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
+    : TargetLowering(TM), ARMPCLabelIndex(0) {
+  Subtarget = &TM.getSubtarget<ARMSubtarget>();
+
+  // Uses VFP for Thumb libfuncs if available.
+  if (Subtarget->isThumb() && Subtarget->hasVFP2()) {
+    // Single-precision floating-point arithmetic.
+    setLibcallName(RTLIB::ADD_F32, "__addsf3vfp");
+    setLibcallName(RTLIB::SUB_F32, "__subsf3vfp");
+    setLibcallName(RTLIB::MUL_F32, "__mulsf3vfp");
+    setLibcallName(RTLIB::DIV_F32, "__divsf3vfp");
+
+    // Double-precision floating-point arithmetic.
+    setLibcallName(RTLIB::ADD_F64, "__adddf3vfp");
+    setLibcallName(RTLIB::SUB_F64, "__subdf3vfp");
+    setLibcallName(RTLIB::MUL_F64, "__muldf3vfp");
+    setLibcallName(RTLIB::DIV_F64, "__divdf3vfp");
+
+    // Single-precision comparisons.
+    setLibcallName(RTLIB::OEQ_F32, "__eqsf2vfp");
+    setLibcallName(RTLIB::UNE_F32, "__nesf2vfp");
+    setLibcallName(RTLIB::OLT_F32, "__ltsf2vfp");
+    setLibcallName(RTLIB::OLE_F32, "__lesf2vfp");
+    setLibcallName(RTLIB::OGE_F32, "__gesf2vfp");
+    setLibcallName(RTLIB::OGT_F32, "__gtsf2vfp");
+    setLibcallName(RTLIB::UO_F32,  "__unordsf2vfp");
+
+    // Double-precision comparisons.
+    setLibcallName(RTLIB::OEQ_F64, "__eqdf2vfp");
+    setLibcallName(RTLIB::UNE_F64, "__nedf2vfp");
+    setLibcallName(RTLIB::OLT_F64, "__ltdf2vfp");
+    setLibcallName(RTLIB::OLE_F64, "__ledf2vfp");
+    setLibcallName(RTLIB::OGE_F64, "__gedf2vfp");
+    setLibcallName(RTLIB::OGT_F64, "__gtdf2vfp");
+    setLibcallName(RTLIB::UO_F64,  "__unorddf2vfp");
+
+    // Floating-point to integer conversions.
+    // i64 conversions are done via library routines even when generating VFP
+    // instructions, so use the same ones.
+    setLibcallName(RTLIB::FPTOSINT_F64_I32, "__fixdfsivfp");
+    setLibcallName(RTLIB::FPTOUINT_F64_I32, "__fixunsdfsivfp");
+    setLibcallName(RTLIB::FPTOSINT_F32_I32, "__fixsfsivfp");
+    setLibcallName(RTLIB::FPTOUINT_F32_I32, "__fixunssfsivfp");
+
+    // Conversions between floating types.
+    setLibcallName(RTLIB::FPROUND_F64_F32, "__truncdfsf2vfp");
+    setLibcallName(RTLIB::FPEXT_F32_F64,   "__extendsfdf2vfp");
+
+    // Integer to floating-point conversions.
+    // i64 conversions are done via library routines even when generating VFP
+    // instructions, so use the same ones.
+    // FIXME: There appears to be some naming inconsistency in ARM libgcc: e.g.
+    // __floatunsidf vs. __floatunssidfvfp.
+    setLibcallName(RTLIB::SINTTOFP_I32_F64, "__floatsidfvfp");
+    setLibcallName(RTLIB::UINTTOFP_I32_F64, "__floatunssidfvfp");
+    setLibcallName(RTLIB::SINTTOFP_I32_F32, "__floatsisfvfp");
+    setLibcallName(RTLIB::UINTTOFP_I32_F32, "__floatunssisfvfp");
+  }
+
+  addRegisterClass(MVT::i32, ARM::GPRRegisterClass);
+  if (Subtarget->hasVFP2() && !Subtarget->isThumb()) {
+    addRegisterClass(MVT::f32, ARM::SPRRegisterClass);
+    addRegisterClass(MVT::f64, ARM::DPRRegisterClass);
+  }
+
+  // ARM does not have f32 extending load.
+  setLoadXAction(ISD::EXTLOAD, MVT::f32, Expand);
+
+  // ARM supports all 4 flavors of integer indexed load / store.
+  for (unsigned im = (unsigned)ISD::PRE_INC;
+       im != (unsigned)ISD::LAST_INDEXED_MODE; ++im) {
+    setIndexedLoadAction(im,  MVT::i1,  Legal);
+    setIndexedLoadAction(im,  MVT::i8,  Legal);
+    setIndexedLoadAction(im,  MVT::i16, Legal);
+    setIndexedLoadAction(im,  MVT::i32, Legal);
+    setIndexedStoreAction(im, MVT::i1,  Legal);
+    setIndexedStoreAction(im, MVT::i8,  Legal);
+    setIndexedStoreAction(im, MVT::i16, Legal);
+    setIndexedStoreAction(im, MVT::i32, Legal);
+  }
+
+  // i64 operation support.
+  if (Subtarget->isThumb()) {
+    setOperationAction(ISD::MUL,     MVT::i64, Expand);
+    setOperationAction(ISD::MULHU,   MVT::i32, Expand);
+    setOperationAction(ISD::MULHS,   MVT::i32, Expand);
+  } else {
+    setOperationAction(ISD::MUL,     MVT::i64, Custom);
+    setOperationAction(ISD::MULHU,   MVT::i32, Custom);
+    if (!Subtarget->hasV6Ops())
+      setOperationAction(ISD::MULHS, MVT::i32, Custom);
+  }
+  setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
+  setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
+  setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
+  setOperationAction(ISD::SRL,       MVT::i64, Custom);
+  setOperationAction(ISD::SRA,       MVT::i64, Custom);
+
+  // ARM does not have ROTL.
+  setOperationAction(ISD::ROTL,  MVT::i32, Expand);
+  setOperationAction(ISD::CTTZ , MVT::i32, Expand);
+  setOperationAction(ISD::CTPOP, MVT::i32, Expand);
+  if (!Subtarget->hasV5TOps())
+    setOperationAction(ISD::CTLZ, MVT::i32, Expand);
+
+  // These are expanded into libcalls.
+  setOperationAction(ISD::SDIV,  MVT::i32, Expand);
+  setOperationAction(ISD::UDIV,  MVT::i32, Expand);
+  setOperationAction(ISD::SREM,  MVT::i32, Expand);
+  setOperationAction(ISD::UREM,  MVT::i32, Expand);
+  
+  // Support label based line numbers.
+  setOperationAction(ISD::LOCATION, MVT::Other, Expand);
+  setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
+  // FIXME - use subtarget debug flags
+  if (Subtarget->isDarwin())
+    setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand);
+
+  setOperationAction(ISD::RET,           MVT::Other, Custom);
+  setOperationAction(ISD::GlobalAddress, MVT::i32,   Custom);
+  setOperationAction(ISD::ConstantPool,  MVT::i32,   Custom);
+
+  // Expand mem operations genericly.
+  setOperationAction(ISD::MEMSET          , MVT::Other, Expand);
+  setOperationAction(ISD::MEMCPY          , MVT::Other, Expand);
+  setOperationAction(ISD::MEMMOVE         , MVT::Other, Expand);
+  
+  // Use the default implementation.
+  setOperationAction(ISD::VASTART           , MVT::Other, Expand);
+  setOperationAction(ISD::VAARG             , MVT::Other, Expand);
+  setOperationAction(ISD::VACOPY            , MVT::Other, Expand);
+  setOperationAction(ISD::VAEND             , MVT::Other, Expand);
+  setOperationAction(ISD::STACKSAVE,          MVT::Other, Expand); 
+  setOperationAction(ISD::STACKRESTORE,       MVT::Other, Expand);
+  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32  , Expand);
+
+  if (!Subtarget->hasV6Ops()) {
+    setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
+    setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8,  Expand);
+  }
+  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
+
+  if (Subtarget->hasVFP2() && !Subtarget->isThumb())
+    // Turn f64->i64 into FMRRD iff target supports vfp2.
+    setOperationAction(ISD::BIT_CONVERT, MVT::i64, Custom);
+  
+  setOperationAction(ISD::SETCC    , MVT::i32, Expand);
+  setOperationAction(ISD::SETCC    , MVT::f32, Expand);
+  setOperationAction(ISD::SETCC    , MVT::f64, Expand);
+  setOperationAction(ISD::SELECT   , MVT::i32, Expand);
+  setOperationAction(ISD::SELECT   , MVT::f32, Expand);
+  setOperationAction(ISD::SELECT   , MVT::f64, Expand);
+  setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
+  setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
+  setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
+
+  setOperationAction(ISD::BRCOND   , MVT::Other, Expand);
+  setOperationAction(ISD::BR_CC    , MVT::i32,   Custom);
+  setOperationAction(ISD::BR_CC    , MVT::f32,   Custom);
+  setOperationAction(ISD::BR_CC    , MVT::f64,   Custom);
+  setOperationAction(ISD::BR_JT    , MVT::Other, Custom);
+
+  setOperationAction(ISD::VASTART,       MVT::Other, Custom);
+  setOperationAction(ISD::VACOPY,        MVT::Other, Expand); 
+  setOperationAction(ISD::VAEND,         MVT::Other, Expand);
+  setOperationAction(ISD::STACKSAVE,     MVT::Other, Expand); 
+  setOperationAction(ISD::STACKRESTORE,  MVT::Other, Expand);
+
+  // FP Constants can't be immediates.
+  setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
+  setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
+
+  // We don't support sin/cos/fmod/copysign
+  setOperationAction(ISD::FSIN     , MVT::f64, Expand);
+  setOperationAction(ISD::FSIN     , MVT::f32, Expand);
+  setOperationAction(ISD::FCOS     , MVT::f32, Expand);
+  setOperationAction(ISD::FCOS     , MVT::f64, Expand);
+  setOperationAction(ISD::FREM     , MVT::f64, Expand);
+  setOperationAction(ISD::FREM     , MVT::f32, Expand);
+  setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom);
+  setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom);
+  
+  // int <-> fp are custom expanded into bit_convert + ARMISD ops.
+  setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
+  setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
+  setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
+  setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
+
+  setStackPointerRegisterToSaveRestore(ARM::SP);
+
+  setSchedulingPreference(SchedulingForRegPressure);
+  computeRegisterProperties();
+}
+
+
+const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
+  switch (Opcode) {
+  default: return 0;
+  case ARMISD::Wrapper:       return "ARMISD::Wrapper";
+  case ARMISD::WrapperCall:   return "ARMISD::WrapperCall";
+  case ARMISD::WrapperJT:     return "ARMISD::WrapperJT";
+  case ARMISD::CALL:          return "ARMISD::CALL";
+  case ARMISD::CALL_NOLINK:   return "ARMISD::CALL_NOLINK";
+  case ARMISD::tCALL:         return "ARMISD::tCALL";
+  case ARMISD::BRCOND:        return "ARMISD::BRCOND";
+  case ARMISD::BR_JT:         return "ARMISD::BR_JT";
+  case ARMISD::RET_FLAG:      return "ARMISD::RET_FLAG";
+  case ARMISD::PIC_ADD:       return "ARMISD::PIC_ADD";
+  case ARMISD::CMP:           return "ARMISD::CMP";
+  case ARMISD::CMPFP:         return "ARMISD::CMPFP";
+  case ARMISD::CMPFPw0:       return "ARMISD::CMPFPw0";
+  case ARMISD::FMSTAT:        return "ARMISD::FMSTAT";
+  case ARMISD::CMOV:          return "ARMISD::CMOV";
+  case ARMISD::CNEG:          return "ARMISD::CNEG";
+    
+  case ARMISD::FTOSI:         return "ARMISD::FTOSI";
+  case ARMISD::FTOUI:         return "ARMISD::FTOUI";
+  case ARMISD::SITOF:         return "ARMISD::SITOF";
+  case ARMISD::UITOF:         return "ARMISD::UITOF";
+  case ARMISD::MULHILOU:      return "ARMISD::MULHILOU";
+  case ARMISD::MULHILOS:      return "ARMISD::MULHILOS";
+
+  case ARMISD::SRL_FLAG:      return "ARMISD::SRL_FLAG";
+  case ARMISD::SRA_FLAG:      return "ARMISD::SRA_FLAG";
+  case ARMISD::RRX:           return "ARMISD::RRX";
+      
+  case ARMISD::FMRRD:         return "ARMISD::FMRRD";
+  case ARMISD::FMDRR:         return "ARMISD::FMDRR";
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Lowering Code
+//===----------------------------------------------------------------------===//
+
+
+/// IntCCToARMCC - Convert a DAG integer condition code to an ARM CC
+static ARMCC::CondCodes IntCCToARMCC(ISD::CondCode CC) {
+  switch (CC) {
+  default: assert(0 && "Unknown condition code!");
+  case ISD::SETNE:  return ARMCC::NE;
+  case ISD::SETEQ:  return ARMCC::EQ;
+  case ISD::SETGT:  return ARMCC::GT;
+  case ISD::SETGE:  return ARMCC::GE;
+  case ISD::SETLT:  return ARMCC::LT;
+  case ISD::SETLE:  return ARMCC::LE;
+  case ISD::SETUGT: return ARMCC::HI;
+  case ISD::SETUGE: return ARMCC::HS;
+  case ISD::SETULT: return ARMCC::LO;
+  case ISD::SETULE: return ARMCC::LS;
+  }
+}
+
+/// FPCCToARMCC - Convert a DAG fp condition code to an ARM CC. It
+/// returns true if the operands should be inverted to form the proper
+/// comparison.
+static bool FPCCToARMCC(ISD::CondCode CC, ARMCC::CondCodes &CondCode,
+                        ARMCC::CondCodes &CondCode2) {
+  bool Invert = false;
+  CondCode2 = ARMCC::AL;
+  switch (CC) {
+  default: assert(0 && "Unknown FP condition!");
+  case ISD::SETEQ:
+  case ISD::SETOEQ: CondCode = ARMCC::EQ; break;
+  case ISD::SETGT:
+  case ISD::SETOGT: CondCode = ARMCC::GT; break;
+  case ISD::SETGE:
+  case ISD::SETOGE: CondCode = ARMCC::GE; break;
+  case ISD::SETOLT: CondCode = ARMCC::MI; break;
+  case ISD::SETOLE: CondCode = ARMCC::GT; Invert = true; break;
+  case ISD::SETONE: CondCode = ARMCC::MI; CondCode2 = ARMCC::GT; break;
+  case ISD::SETO:   CondCode = ARMCC::VC; break;
+  case ISD::SETUO:  CondCode = ARMCC::VS; break;
+  case ISD::SETUEQ: CondCode = ARMCC::EQ; CondCode2 = ARMCC::VS; break;
+  case ISD::SETUGT: CondCode = ARMCC::HI; break;
+  case ISD::SETUGE: CondCode = ARMCC::PL; break;
+  case ISD::SETLT:
+  case ISD::SETULT: CondCode = ARMCC::LT; break;
+  case ISD::SETLE:
+  case ISD::SETULE: CondCode = ARMCC::LE; break;
+  case ISD::SETNE:
+  case ISD::SETUNE: CondCode = ARMCC::NE; break;
+  }
+  return Invert;
+}
+
+static void
+HowToPassArgument(MVT::ValueType ObjectVT,
+                  unsigned NumGPRs, unsigned &ObjSize, unsigned &ObjGPRs) {
+  ObjSize = 0;
+  ObjGPRs = 0;
+
+  switch (ObjectVT) {
+  default: assert(0 && "Unhandled argument type!");
+  case MVT::i32:
+  case MVT::f32:
+    if (NumGPRs < 4)
+      ObjGPRs = 1;
+    else
+      ObjSize = 4;
+    break;
+  case MVT::i64:
+  case MVT::f64:
+    if (NumGPRs < 3)
+      ObjGPRs = 2;
+    else if (NumGPRs == 3) {
+      ObjGPRs = 1;
+      ObjSize = 4;
+    } else
+      ObjSize = 8;
+  }
+}
+
+// This transforms a ISD::CALL node into a
+// callseq_star <- ARMISD:CALL <- callseq_end
+// chain
+SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
+  MVT::ValueType RetVT= Op.Val->getValueType(0);
+  SDOperand Chain    = Op.getOperand(0);
+  unsigned CallConv  = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
+  assert((CallConv == CallingConv::C ||
+          CallConv == CallingConv::CSRet ||
+          CallConv == CallingConv::Fast) && "unknown calling convention");
+  SDOperand Callee   = Op.getOperand(4);
+  unsigned NumOps    = (Op.getNumOperands() - 5) / 2;
+  unsigned ArgOffset = 0;   // Frame mechanisms handle retaddr slot
+  unsigned NumGPRs = 0;     // GPRs used for parameter passing.
+
+  // Count how many bytes are to be pushed on the stack.
+  unsigned NumBytes = 0;
+
+  // Add up all the space actually used.
+  for (unsigned i = 0; i < NumOps; ++i) {
+    unsigned ObjSize = 0;
+    unsigned ObjGPRs = 0;
+    MVT::ValueType ObjectVT = Op.getOperand(5+2*i).getValueType();
+    HowToPassArgument(ObjectVT, NumGPRs, ObjSize, ObjGPRs);
+    NumBytes += ObjSize;
+    NumGPRs += ObjGPRs;
+  }
+
+  // Adjust the stack pointer for the new arguments...
+  // These operations are automatically eliminated by the prolog/epilog pass
+  Chain = DAG.getCALLSEQ_START(Chain,
+                               DAG.getConstant(NumBytes, MVT::i32));
+
+  SDOperand StackPtr = DAG.getRegister(ARM::SP, MVT::i32);
+
+  static const unsigned GPRArgRegs[] = {
+    ARM::R0, ARM::R1, ARM::R2, ARM::R3
+  };
+
+  NumGPRs = 0;
+  std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
+  std::vector<SDOperand> MemOpChains;
+  for (unsigned i = 0; i != NumOps; ++i) {
+    SDOperand Arg = Op.getOperand(5+2*i);
+    MVT::ValueType ArgVT = Arg.getValueType();
+
+    unsigned ObjSize = 0;
+    unsigned ObjGPRs = 0;
+    HowToPassArgument(ArgVT, NumGPRs, ObjSize, ObjGPRs);
+    if (ObjGPRs > 0) {
+      switch (ArgVT) {
+      default: assert(0 && "Unexpected ValueType for argument!");
+      case MVT::i32:
+        RegsToPass.push_back(std::make_pair(GPRArgRegs[NumGPRs], Arg));
+        break;
+      case MVT::f32: 
+        RegsToPass.push_back(std::make_pair(GPRArgRegs[NumGPRs],
+                                 DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Arg)));
+        break;
+      case MVT::i64: {
+        SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Arg,
+                                   DAG.getConstant(0, getPointerTy()));
+        SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Arg,
+                                   DAG.getConstant(1, getPointerTy()));
+        RegsToPass.push_back(std::make_pair(GPRArgRegs[NumGPRs], Lo));
+        if (ObjGPRs == 2)
+          RegsToPass.push_back(std::make_pair(GPRArgRegs[NumGPRs+1], Hi));
+        else {
+          SDOperand PtrOff= DAG.getConstant(ArgOffset, StackPtr.getValueType());
+          PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
+          MemOpChains.push_back(DAG.getStore(Chain, Hi, PtrOff, NULL, 0));
+        }
+        break;
+      } 
+      case MVT::f64: {
+        SDOperand Cvt = DAG.getNode(ARMISD::FMRRD,
+                                    DAG.getVTList(MVT::i32, MVT::i32),
+                                    &Arg, 1);
+        RegsToPass.push_back(std::make_pair(GPRArgRegs[NumGPRs], Cvt));
+        if (ObjGPRs == 2)
+          RegsToPass.push_back(std::make_pair(GPRArgRegs[NumGPRs+1],
+                                              Cvt.getValue(1)));
+        else {
+          SDOperand PtrOff= DAG.getConstant(ArgOffset, StackPtr.getValueType());
+          PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
+          MemOpChains.push_back(DAG.getStore(Chain, Cvt.getValue(1), PtrOff,
+                                             NULL, 0));
+        }
+        break;
+      }
+      }
+    } else {
+      assert(ObjSize != 0);
+      SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
+      PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
+      MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
+    }
+
+    NumGPRs += ObjGPRs;
+    ArgOffset += ObjSize;
+  }
+
+  if (!MemOpChains.empty())
+    Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
+                        &MemOpChains[0], MemOpChains.size());
+
+  // Build a sequence of copy-to-reg nodes chained together with token chain
+  // and flag operands which copy the outgoing args into the appropriate regs.
+  SDOperand InFlag;
+  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
+    Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
+                             InFlag);
+    InFlag = Chain.getValue(1);
+  }
+
+  // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
+  // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
+  // node so that legalize doesn't hack it.
+  bool isDirect = false;
+  bool isARMFunc = false;
+  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
+    GlobalValue *GV = G->getGlobal();
+    Callee = DAG.getTargetGlobalAddress(GV, getPointerTy());
+    isDirect = true;
+    bool isExt = (GV->isExternal() || GV->hasWeakLinkage() ||
+                  GV->hasLinkOnceLinkage());
+    bool isStub = (isExt && Subtarget->isDarwin()) &&
+                   getTargetMachine().getRelocationModel() != Reloc::Static;
+    isARMFunc = !Subtarget->isThumb() || isStub;
+    // Wrap it since tBX takes a register source operand.
+    if (isARMFunc && Subtarget->isThumb() && !Subtarget->hasV5TOps())
+      Callee = DAG.getNode(ARMISD::WrapperCall, MVT::i32, Callee);
+  } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
+    Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
+    isDirect = true;
+    bool isStub = Subtarget->isDarwin() &&
+                  getTargetMachine().getRelocationModel() != Reloc::Static;
+    isARMFunc = !Subtarget->isThumb() || isStub;
+    // Wrap it since tBX takes a register source operand.
+    if (!Subtarget->hasV5TOps() && Subtarget->isThumb())
+      Callee = DAG.getNode(ARMISD::WrapperCall, MVT::i32, Callee);
+  }
+
+  std::vector<MVT::ValueType> NodeTys;
+  NodeTys.push_back(MVT::Other);   // Returns a chain
+  NodeTys.push_back(MVT::Flag);    // Returns a flag for retval copy to use.
+
+  std::vector<SDOperand> Ops;
+  Ops.push_back(Chain);
+  Ops.push_back(Callee);
+
+  // Add argument registers to the end of the list so that they are known live
+  // into the call.
+  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
+    Ops.push_back(DAG.getRegister(RegsToPass[i].first,
+                                  RegsToPass[i].second.getValueType()));
+
+  // FIXME: handle tail calls differently.
+  unsigned CallOpc;
+  if (Subtarget->isThumb()) {
+    if (!Subtarget->hasV5TOps() && (!isDirect || isARMFunc))
+      CallOpc = ARMISD::CALL_NOLINK;
+    else
+      CallOpc = isARMFunc ? ARMISD::CALL : ARMISD::tCALL;
+  } else {
+    CallOpc = (isDirect || Subtarget->hasV5TOps())
+      ? ARMISD::CALL : ARMISD::CALL_NOLINK;
+  }
+  if (InFlag.Val)
+    Ops.push_back(InFlag);
+  Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size());
+  InFlag = Chain.getValue(1);
+
+  SDOperand CSOps[] = { Chain, DAG.getConstant(NumBytes, MVT::i32), InFlag };
+  Chain = DAG.getNode(ISD::CALLSEQ_END, 
+                      DAG.getNodeValueTypes(MVT::Other, MVT::Flag),
+                      ((RetVT != MVT::Other) ? 2 : 1), CSOps, 3);
+  if (RetVT != MVT::Other)
+    InFlag = Chain.getValue(1);
+
+  std::vector<SDOperand> ResultVals;
+  NodeTys.clear();
+
+  // If the call has results, copy the values out of the ret val registers.
+  switch (RetVT) {
+  default: assert(0 && "Unexpected ret value!");
+  case MVT::Other:
+    break;
+  case MVT::i32:
+    Chain = DAG.getCopyFromReg(Chain, ARM::R0, MVT::i32, InFlag).getValue(1);
+    ResultVals.push_back(Chain.getValue(0));
+    if (Op.Val->getValueType(1) == MVT::i32) {
+      // Returns a i64 value.
+      Chain = DAG.getCopyFromReg(Chain, ARM::R1, MVT::i32,
+                                 Chain.getValue(2)).getValue(1);
+      ResultVals.push_back(Chain.getValue(0));
+      NodeTys.push_back(MVT::i32);
+    }
+    NodeTys.push_back(MVT::i32);
+    break;
+  case MVT::f32:
+    Chain = DAG.getCopyFromReg(Chain, ARM::R0, MVT::i32, InFlag).getValue(1);
+    ResultVals.push_back(DAG.getNode(ISD::BIT_CONVERT, MVT::f32,
+                                     Chain.getValue(0)));
+    NodeTys.push_back(MVT::f32);
+    break;
+  case MVT::f64: {
+    SDOperand Lo = DAG.getCopyFromReg(Chain, ARM::R0, MVT::i32, InFlag);
+    SDOperand Hi = DAG.getCopyFromReg(Lo, ARM::R1, MVT::i32, Lo.getValue(2));
+    ResultVals.push_back(DAG.getNode(ARMISD::FMDRR, MVT::f64, Lo, Hi));
+    NodeTys.push_back(MVT::f64);
+    break;
+  }
+  }
+
+  NodeTys.push_back(MVT::Other);
+
+  if (ResultVals.empty())
+    return Chain;
+
+  ResultVals.push_back(Chain);
+  SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys, &ResultVals[0],
+                              ResultVals.size());
+  return Res.getValue(Op.ResNo);
+}
+
+static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) {
+  SDOperand Copy;
+  SDOperand Chain = Op.getOperand(0);
+  switch(Op.getNumOperands()) {
+  default:
+    assert(0 && "Do not know how to return this many arguments!");
+    abort();
+  case 1: {
+    SDOperand LR = DAG.getRegister(ARM::LR, MVT::i32);
+    return DAG.getNode(ARMISD::RET_FLAG, MVT::Other, Chain);
+  }
+  case 3:
+    Op = Op.getOperand(1);
+    if (Op.getValueType() == MVT::f32) {
+      Op = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Op);
+    } else if (Op.getValueType() == MVT::f64) {
+      // Recursively legalize f64 -> i64.
+      Op = DAG.getNode(ISD::BIT_CONVERT, MVT::i64, Op);
+      return DAG.getNode(ISD::RET, MVT::Other, Chain, Op,
+                         DAG.getConstant(0, MVT::i32));
+    }
+    Copy = DAG.getCopyToReg(Chain, ARM::R0, Op, SDOperand());
+    if (DAG.getMachineFunction().liveout_empty())
+      DAG.getMachineFunction().addLiveOut(ARM::R0);
+    break;
+  case 5:
+    Copy = DAG.getCopyToReg(Chain, ARM::R1, Op.getOperand(3), SDOperand());
+    Copy = DAG.getCopyToReg(Copy, ARM::R0, Op.getOperand(1), Copy.getValue(1));
+    // If we haven't noted the R0+R1 are live out, do so now.
+    if (DAG.getMachineFunction().liveout_empty()) {
+      DAG.getMachineFunction().addLiveOut(ARM::R0);
+      DAG.getMachineFunction().addLiveOut(ARM::R1);
+    }
+    break;
+  }
+
+  //We must use RET_FLAG instead of BRIND because BRIND doesn't have a flag
+  return DAG.getNode(ARMISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
+}
+
+// ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as 
+// their target countpart wrapped in the ARMISD::Wrapper node. Suppose N is
+// one of the above mentioned nodes. It has to be wrapped because otherwise
+// Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only
+// be used to form addressing mode. These wrapped nodes will be selected
+// into MOVri.
+static SDOperand LowerConstantPool(SDOperand Op, SelectionDAG &DAG) {
+  MVT::ValueType PtrVT = Op.getValueType();
+  ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
+  SDOperand Res;
+  if (CP->isMachineConstantPoolEntry())
+    Res = DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT,
+                                    CP->getAlignment());
+  else
+    Res = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT,
+                                    CP->getAlignment());
+  return DAG.getNode(ARMISD::Wrapper, MVT::i32, Res);
+}
+
+/// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol
+/// even in dynamic-no-pic mode.
+static bool GVIsIndirectSymbol(GlobalValue *GV) {
+  return (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
+          (GV->isExternal() && !GV->hasNotBeenReadFromBytecode()));
+}
+
+SDOperand ARMTargetLowering::LowerGlobalAddress(SDOperand Op,
+                                                SelectionDAG &DAG) {
+  MVT::ValueType PtrVT = getPointerTy();
+  GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
+  Reloc::Model RelocM = getTargetMachine().getRelocationModel();
+  bool IsIndirect = Subtarget->isDarwin() && GVIsIndirectSymbol(GV);
+  SDOperand CPAddr;
+  if (RelocM == Reloc::Static)
+    CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 2);
+  else {
+    unsigned PCAdj = (RelocM != Reloc::PIC_)
+      ? 0 : (Subtarget->isThumb() ? 4 : 8);
+    ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, ARMPCLabelIndex,
+                                                         IsIndirect, PCAdj);
+    CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 2);
+  }
+  CPAddr = DAG.getNode(ARMISD::Wrapper, MVT::i32, CPAddr);
+
+  SDOperand Result = DAG.getLoad(PtrVT, DAG.getEntryNode(), CPAddr, NULL, 0);
+  SDOperand Chain = Result.getValue(1);
+
+  if (RelocM == Reloc::PIC_) {
+    SDOperand PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32);
+    Result = DAG.getNode(ARMISD::PIC_ADD, PtrVT, Result, PICLabel);
+  }
+  if (IsIndirect)
+    Result = DAG.getLoad(PtrVT, Chain, Result, NULL, 0);
+
+  return Result;
+}
+
+static SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG,
+                              unsigned VarArgsFrameIndex) {
+  // vastart just stores the address of the VarArgsFrameIndex slot into the
+  // memory location argument.
+  MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
+  SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
+  SrcValueSDNode *SV = cast<SrcValueSDNode>(Op.getOperand(2));
+  return DAG.getStore(Op.getOperand(0), FR, Op.getOperand(1), SV->getValue(),
+                      SV->getOffset());
+}
+
+static SDOperand LowerFORMAL_ARGUMENT(SDOperand Op, SelectionDAG &DAG,
+				      unsigned *vRegs, unsigned ArgNo,
+                                      unsigned &NumGPRs, unsigned &ArgOffset) {
+  MachineFunction &MF = DAG.getMachineFunction();
+  MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType();
+  SDOperand Root = Op.getOperand(0);
+  std::vector<SDOperand> ArgValues;
+  SSARegMap *RegMap = MF.getSSARegMap();
+
+  static const unsigned GPRArgRegs[] = {
+    ARM::R0, ARM::R1, ARM::R2, ARM::R3
+  };
+
+  unsigned ObjSize = 0;
+  unsigned ObjGPRs = 0;
+  HowToPassArgument(ObjectVT, NumGPRs, ObjSize, ObjGPRs);
+
+  SDOperand ArgValue;
+  if (ObjGPRs == 1) {
+    unsigned VReg = RegMap->createVirtualRegister(&ARM::GPRRegClass);
+    MF.addLiveIn(GPRArgRegs[NumGPRs], VReg);
+    vRegs[NumGPRs] = VReg;
+    ArgValue = DAG.getCopyFromReg(Root, VReg, MVT::i32);
+    if (ObjectVT == MVT::f32)
+      ArgValue = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, ArgValue);
+  } else if (ObjGPRs == 2) {
+    unsigned VReg = RegMap->createVirtualRegister(&ARM::GPRRegClass);
+    MF.addLiveIn(GPRArgRegs[NumGPRs], VReg);
+    vRegs[NumGPRs] = VReg;
+    ArgValue = DAG.getCopyFromReg(Root, VReg, MVT::i32);
+
+    VReg = RegMap->createVirtualRegister(&ARM::GPRRegClass);
+    MF.addLiveIn(GPRArgRegs[NumGPRs+1], VReg);
+    vRegs[NumGPRs+1] = VReg;
+    SDOperand ArgValue2 = DAG.getCopyFromReg(Root, VReg, MVT::i32);
+
+    if (ObjectVT == MVT::i64)
+      ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, ArgValue, ArgValue2);
+    else
+      ArgValue = DAG.getNode(ARMISD::FMDRR, MVT::f64, ArgValue, ArgValue2);
+  }
+  NumGPRs += ObjGPRs;
+
+  if (ObjSize) {
+    // If the argument is actually used, emit a load from the right stack
+    // slot.
+    if (!Op.Val->hasNUsesOfValue(0, ArgNo)) {
+      MachineFrameInfo *MFI = MF.getFrameInfo();
+      int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
+      SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
+      if (ObjGPRs == 0)
+        ArgValue = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
+      else {
+        SDOperand ArgValue2 =
+          DAG.getLoad(MVT::i32, Root, FIN, NULL, 0);
+        if (ObjectVT == MVT::i64)
+          ArgValue= DAG.getNode(ISD::BUILD_PAIR, MVT::i64, ArgValue, ArgValue2);
+        else
+          ArgValue= DAG.getNode(ARMISD::FMDRR, MVT::f64, ArgValue, ArgValue2);
+      }
+    } else {
+      // Don't emit a dead load.
+      ArgValue = DAG.getNode(ISD::UNDEF, ObjectVT);
+    }
+
+    ArgOffset += ObjSize;   // Move on to the next argument.
+  }
+
+  return ArgValue;
+}
+
+SDOperand
+ARMTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
+  std::vector<SDOperand> ArgValues;
+  SDOperand Root = Op.getOperand(0);
+  unsigned ArgOffset = 0;   // Frame mechanisms handle retaddr slot
+  unsigned NumGPRs = 0;     // GPRs used for parameter passing.
+  unsigned VRegs[4];
+
+  unsigned NumArgs = Op.Val->getNumValues()-1;
+  for (unsigned ArgNo = 0; ArgNo < NumArgs; ++ArgNo)
+    ArgValues.push_back(LowerFORMAL_ARGUMENT(Op, DAG, VRegs, ArgNo,
+                                             NumGPRs, ArgOffset));
+
+  bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
+  if (isVarArg) {
+    static const unsigned GPRArgRegs[] = {
+      ARM::R0, ARM::R1, ARM::R2, ARM::R3
+    };
+
+    MachineFunction &MF = DAG.getMachineFunction();
+    SSARegMap *RegMap = MF.getSSARegMap();
+    MachineFrameInfo *MFI = MF.getFrameInfo();
+    ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+    unsigned VARegSaveSize = (4 - NumGPRs) * 4;
+    if (VARegSaveSize) {
+      // 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.
+      AFI->setVarArgsRegSaveSize(VARegSaveSize);
+      VarArgsFrameIndex = MFI->CreateFixedObject(VARegSaveSize, ArgOffset);
+      SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy());
+
+      SmallVector<SDOperand, 4> MemOps;
+      for (; NumGPRs < 4; ++NumGPRs) {
+        unsigned VReg = RegMap->createVirtualRegister(&ARM::GPRRegClass);
+        MF.addLiveIn(GPRArgRegs[NumGPRs], VReg);
+        SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::i32);
+        SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
+        MemOps.push_back(Store);
+        FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
+                          DAG.getConstant(4, getPointerTy()));
+      }
+      if (!MemOps.empty())
+        Root = DAG.getNode(ISD::TokenFactor, MVT::Other,
+                           &MemOps[0], MemOps.size());
+    } else
+      // This will point to the next argument passed via stack.
+      VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset);
+  }
+
+  ArgValues.push_back(Root);
+
+  // Return the new list of results.
+  std::vector<MVT::ValueType> RetVT(Op.Val->value_begin(),
+                                    Op.Val->value_end());
+  return DAG.getNode(ISD::MERGE_VALUES, RetVT, &ArgValues[0], ArgValues.size());
+}
+
+/// isFloatingPointZero - Return true if this is +0.0.
+static bool isFloatingPointZero(SDOperand Op) {
+  if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Op))
+    return CFP->isExactlyValue(0.0);
+  else if (ISD::isEXTLoad(Op.Val) || ISD::isNON_EXTLoad(Op.Val)) {
+    // Maybe this has already been legalized into the constant pool?
+    if (Op.getOperand(1).getOpcode() == ARMISD::Wrapper) {
+      SDOperand WrapperOp = Op.getOperand(1).getOperand(0);
+      if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(WrapperOp))
+        if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
+          return CFP->isExactlyValue(0.0);
+    }
+  }
+  return false;
+}
+
+static bool isLegalCmpImmediate(int C, bool isThumb) {
+  return ( isThumb && (C & ~255U) == 0) ||
+         (!isThumb && ARM_AM::getSOImmVal(C) != -1);
+}
+
+/// Returns appropriate ARM CMP (cmp) and corresponding condition code for
+/// the given operands.
+static SDOperand getARMCmp(SDOperand LHS, SDOperand RHS, ISD::CondCode CC,
+                           SDOperand &ARMCC, SelectionDAG &DAG, bool isThumb) {
+  if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS.Val)) {
+    int C = (int)RHSC->getValue();
+    if (!isLegalCmpImmediate(C, isThumb)) {
+      // Constant does not fit, try adjusting it by one?
+      switch (CC) {
+      default: break;
+      case ISD::SETLT:
+      case ISD::SETULT:
+      case ISD::SETGE:
+      case ISD::SETUGE:
+        if (isLegalCmpImmediate(C-1, isThumb)) {
+          switch (CC) {
+          default: break;
+          case ISD::SETLT:  CC = ISD::SETLE;  break;
+          case ISD::SETULT: CC = ISD::SETULE; break;
+          case ISD::SETGE:  CC = ISD::SETGT;  break;
+          case ISD::SETUGE: CC = ISD::SETUGT; break;
+          }
+          RHS = DAG.getConstant(C-1, MVT::i32);
+        }
+        break;
+      case ISD::SETLE:
+      case ISD::SETULE:
+      case ISD::SETGT:
+      case ISD::SETUGT:
+        if (isLegalCmpImmediate(C+1, isThumb)) {
+          switch (CC) {
+          default: break;
+          case ISD::SETLE:  CC = ISD::SETLT;  break;
+          case ISD::SETULE: CC = ISD::SETULT; break;
+          case ISD::SETGT:  CC = ISD::SETGE;  break;
+          case ISD::SETUGT: CC = ISD::SETUGE; break;
+          }
+          RHS = DAG.getConstant(C+1, MVT::i32);
+        }
+        break;
+      }
+    }
+  }
+
+  ARMCC::CondCodes CondCode = IntCCToARMCC(CC);
+  ARMCC = DAG.getConstant(CondCode, MVT::i32);
+  return DAG.getNode(ARMISD::CMP, MVT::Flag, LHS, RHS);
+}
+
+/// Returns a appropriate VFP CMP (fcmp{s|d}+fmstat) for the given operands.
+static SDOperand getVFPCmp(SDOperand LHS, SDOperand RHS, SelectionDAG &DAG) {
+  SDOperand Cmp;
+  if (!isFloatingPointZero(RHS))
+    Cmp = DAG.getNode(ARMISD::CMPFP, MVT::Flag, LHS, RHS);
+  else
+    Cmp = DAG.getNode(ARMISD::CMPFPw0, MVT::Flag, LHS);
+  return DAG.getNode(ARMISD::FMSTAT, MVT::Flag, Cmp);
+}
+
+static SDOperand LowerSELECT_CC(SDOperand Op, SelectionDAG &DAG,
+                                const ARMSubtarget *ST) {
+  MVT::ValueType VT = Op.getValueType();
+  SDOperand LHS = Op.getOperand(0);
+  SDOperand RHS = Op.getOperand(1);
+  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
+  SDOperand TrueVal = Op.getOperand(2);
+  SDOperand FalseVal = Op.getOperand(3);
+
+  if (LHS.getValueType() == MVT::i32) {
+    SDOperand ARMCC;
+    SDOperand Cmp = getARMCmp(LHS, RHS, CC, ARMCC, DAG, ST->isThumb());
+    return DAG.getNode(ARMISD::CMOV, VT, FalseVal, TrueVal, ARMCC, Cmp);
+  }
+
+  ARMCC::CondCodes CondCode, CondCode2;
+  if (FPCCToARMCC(CC, CondCode, CondCode2))
+    std::swap(TrueVal, FalseVal);
+
+  SDOperand ARMCC = DAG.getConstant(CondCode, MVT::i32);
+  SDOperand Cmp = getVFPCmp(LHS, RHS, DAG);
+  SDOperand Result = DAG.getNode(ARMISD::CMOV, VT, FalseVal, TrueVal,
+                                 ARMCC, Cmp);
+  if (CondCode2 != ARMCC::AL) {
+    SDOperand ARMCC2 = DAG.getConstant(CondCode2, MVT::i32);
+    // FIXME: Needs another CMP because flag can have but one use.
+    SDOperand Cmp2 = getVFPCmp(LHS, RHS, DAG);
+    Result = DAG.getNode(ARMISD::CMOV, VT, Result, TrueVal, ARMCC2, Cmp2);
+  }
+  return Result;
+}
+
+static SDOperand LowerBR_CC(SDOperand Op, SelectionDAG &DAG,
+                            const ARMSubtarget *ST) {
+  SDOperand  Chain = Op.getOperand(0);
+  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
+  SDOperand    LHS = Op.getOperand(2);
+  SDOperand    RHS = Op.getOperand(3);
+  SDOperand   Dest = Op.getOperand(4);
+
+  if (LHS.getValueType() == MVT::i32) {
+    SDOperand ARMCC;
+    SDOperand Cmp = getARMCmp(LHS, RHS, CC, ARMCC, DAG, ST->isThumb());
+    return DAG.getNode(ARMISD::BRCOND, MVT::Other, Chain, Dest, ARMCC, Cmp);
+  }
+
+  assert(LHS.getValueType() == MVT::f32 || LHS.getValueType() == MVT::f64);
+  ARMCC::CondCodes CondCode, CondCode2;
+  if (FPCCToARMCC(CC, CondCode, CondCode2))
+    // Swap the LHS/RHS of the comparison if needed.
+    std::swap(LHS, RHS);
+  
+  SDOperand Cmp = getVFPCmp(LHS, RHS, DAG);
+  SDOperand ARMCC = DAG.getConstant(CondCode, MVT::i32);
+  SDVTList VTList = DAG.getVTList(MVT::Other, MVT::Flag);
+  SDOperand Ops[] = { Chain, Dest, ARMCC, Cmp };
+  SDOperand Res = DAG.getNode(ARMISD::BRCOND, VTList, Ops, 4);
+  if (CondCode2 != ARMCC::AL) {
+    ARMCC = DAG.getConstant(CondCode2, MVT::i32);
+    SDOperand Ops[] = { Res, Dest, ARMCC, Res.getValue(1) };
+    Res = DAG.getNode(ARMISD::BRCOND, VTList, Ops, 4);
+  }
+  return Res;
+}
+
+SDOperand ARMTargetLowering::LowerBR_JT(SDOperand Op, SelectionDAG &DAG) {
+  SDOperand Chain = Op.getOperand(0);
+  SDOperand Table = Op.getOperand(1);
+  SDOperand Index = Op.getOperand(2);
+
+  MVT::ValueType PTy = getPointerTy();
+  JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
+  ARMFunctionInfo *AFI = DAG.getMachineFunction().getInfo<ARMFunctionInfo>();
+  SDOperand UId =  DAG.getConstant(AFI->createJumpTableUId(), PTy);
+  SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy);
+  Table = DAG.getNode(ARMISD::WrapperJT, MVT::i32, JTI, UId);
+  Index = DAG.getNode(ISD::MUL, PTy, Index, DAG.getConstant(4, PTy));
+  SDOperand Addr = DAG.getNode(ISD::ADD, PTy, Index, Table);
+  bool isPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_;
+  Addr = DAG.getLoad(isPIC ? MVT::i32 : PTy, Chain, Addr, NULL, 0);
+  Chain = Addr.getValue(1);
+  if (isPIC)
+    Addr = DAG.getNode(ISD::ADD, PTy, Addr, Table);
+  return DAG.getNode(ARMISD::BR_JT, MVT::Other, Chain, Addr, JTI, UId);
+}
+
+static SDOperand LowerFP_TO_INT(SDOperand Op, SelectionDAG &DAG) {
+  unsigned Opc =
+    Op.getOpcode() == ISD::FP_TO_SINT ? ARMISD::FTOSI : ARMISD::FTOUI;
+  Op = DAG.getNode(Opc, MVT::f32, Op.getOperand(0));
+  return DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Op);
+}
+
+static SDOperand LowerINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
+  MVT::ValueType VT = Op.getValueType();
+  unsigned Opc =
+    Op.getOpcode() == ISD::SINT_TO_FP ? ARMISD::SITOF : ARMISD::UITOF;
+
+  Op = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, Op.getOperand(0));
+  return DAG.getNode(Opc, VT, Op);
+}
+
+static SDOperand LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) {
+  // Implement fcopysign with a fabs and a conditional fneg.
+  SDOperand Tmp0 = Op.getOperand(0);
+  SDOperand Tmp1 = Op.getOperand(1);
+  MVT::ValueType VT = Op.getValueType();
+  MVT::ValueType SrcVT = Tmp1.getValueType();
+  SDOperand AbsVal = DAG.getNode(ISD::FABS, VT, Tmp0);
+  SDOperand Cmp = getVFPCmp(Tmp1, DAG.getConstantFP(0.0, SrcVT), DAG);
+  SDOperand ARMCC = DAG.getConstant(ARMCC::LT, MVT::i32);
+  return DAG.getNode(ARMISD::CNEG, VT, AbsVal, AbsVal, ARMCC, Cmp);
+}
+
+static SDOperand LowerBIT_CONVERT(SDOperand Op, SelectionDAG &DAG) {
+  // Turn f64->i64 into FMRRD.
+  assert(Op.getValueType() == MVT::i64 &&
+         Op.getOperand(0).getValueType() == MVT::f64);
+
+  Op = Op.getOperand(0);
+  SDOperand Cvt = DAG.getNode(ARMISD::FMRRD, DAG.getVTList(MVT::i32, MVT::i32),
+                              &Op, 1);
+  
+  // Merge the pieces into a single i64 value.
+  return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Cvt, Cvt.getValue(1));
+}
+
+static SDOperand LowerMUL(SDOperand Op, SelectionDAG &DAG) {
+  // FIXME: All this code is target-independent.  Create a new target-indep
+  // MULHILO node and move this code to the legalizer.
+  //
+  assert(Op.getValueType() == MVT::i64 && "Only handles i64 expand right now!");
+  
+  SDOperand LL = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
+                             DAG.getConstant(0, MVT::i32));
+  SDOperand RL = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(1),
+                             DAG.getConstant(0, MVT::i32));
+
+  const TargetLowering &TL = DAG.getTargetLoweringInfo();
+  unsigned LHSSB = TL.ComputeNumSignBits(Op.getOperand(0));
+  unsigned RHSSB = TL.ComputeNumSignBits(Op.getOperand(1));
+  
+  SDOperand Lo, Hi;
+  // Figure out how to lower this multiply.
+  if (LHSSB >= 33 && RHSSB >= 33) {
+    // If the input values are both sign extended, we can emit a mulhs+mul.
+    Lo = DAG.getNode(ISD::MUL, MVT::i32, LL, RL);
+    Hi = DAG.getNode(ISD::MULHS, MVT::i32, LL, RL);
+  } else if (LHSSB == 32 && RHSSB == 32 &&
+             TL.MaskedValueIsZero(Op.getOperand(0), 0xFFFFFFFF00000000ULL) &&
+             TL.MaskedValueIsZero(Op.getOperand(1), 0xFFFFFFFF00000000ULL)) {
+    // If the inputs are zero extended, use mulhu.
+    Lo = DAG.getNode(ISD::MUL, MVT::i32, LL, RL);
+    Hi = DAG.getNode(ISD::MULHU, MVT::i32, LL, RL);
+  } else {
+    SDOperand LH = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
+                               DAG.getConstant(1, MVT::i32));
+    SDOperand RH = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(1),
+                               DAG.getConstant(1, MVT::i32));
+  
+    // Lo,Hi = umul LHS, RHS.
+    SDOperand Ops[] = { LL, RL };
+    SDOperand UMul64 = DAG.getNode(ARMISD::MULHILOU,
+                                   DAG.getVTList(MVT::i32, MVT::i32), Ops, 2);
+    Lo = UMul64;
+    Hi = UMul64.getValue(1);
+    RH = DAG.getNode(ISD::MUL, MVT::i32, LL, RH);
+    LH = DAG.getNode(ISD::MUL, MVT::i32, LH, RL);
+    Hi = DAG.getNode(ISD::ADD, MVT::i32, Hi, RH);
+    Hi = DAG.getNode(ISD::ADD, MVT::i32, Hi, LH);
+  }
+  
+  // Merge the pieces into a single i64 value.
+  return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi);
+}
+
+static SDOperand LowerMULHU(SDOperand Op, SelectionDAG &DAG) {
+  SDOperand Ops[] = { Op.getOperand(0), Op.getOperand(1) };
+  return DAG.getNode(ARMISD::MULHILOU,
+                     DAG.getVTList(MVT::i32, MVT::i32), Ops, 2).getValue(1);
+}
+
+static SDOperand LowerMULHS(SDOperand Op, SelectionDAG &DAG) {
+  SDOperand Ops[] = { Op.getOperand(0), Op.getOperand(1) };
+  return DAG.getNode(ARMISD::MULHILOS,
+                     DAG.getVTList(MVT::i32, MVT::i32), Ops, 2).getValue(1);
+}
+
+static SDOperand LowerSRx(SDOperand Op, SelectionDAG &DAG,
+                          const ARMSubtarget *ST) {
+  assert(Op.getValueType() == MVT::i64 &&
+         (Op.getOpcode() == ISD::SRL || Op.getOpcode() == ISD::SRA) &&
+         "Unknown shift to lower!");
+  
+  // We only lower SRA, SRL of 1 here, all others use generic lowering.
+  if (!isa<ConstantSDNode>(Op.getOperand(1)) ||
+      cast<ConstantSDNode>(Op.getOperand(1))->getValue() != 1)
+    return SDOperand();
+  
+  // If we are in thumb mode, we don't have RRX.
+  if (ST->isThumb()) return SDOperand();
+  
+  // Okay, we have a 64-bit SRA or SRL of 1.  Lower this to an RRX expr.
+  SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
+                             DAG.getConstant(0, MVT::i32));
+  SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
+                             DAG.getConstant(1, MVT::i32));
+
+  // First, build a SRA_FLAG/SRL_FLAG op, which shifts the top part by one and
+  // captures the result into a carry flag.
+  unsigned Opc = Op.getOpcode() == ISD::SRL ? ARMISD::SRL_FLAG:ARMISD::SRA_FLAG;
+  Hi = DAG.getNode(Opc, DAG.getVTList(MVT::i32, MVT::Flag), &Hi, 1);
+  
+  // The low part is an ARMISD::RRX operand, which shifts the carry in.
+  Lo = DAG.getNode(ARMISD::RRX, MVT::i32, Lo, Hi.getValue(1));
+  
+  // Merge the pieces into a single i64 value.
+  return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi);
+}
+
+SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
+  switch (Op.getOpcode()) {
+  default: assert(0 && "Don't know how to custom lower this!"); abort();
+  case ISD::ConstantPool:  return LowerConstantPool(Op, DAG);
+  case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
+  case ISD::CALL:          return LowerCALL(Op, DAG);
+  case ISD::RET:           return LowerRET(Op, DAG);
+  case ISD::SELECT_CC:     return LowerSELECT_CC(Op, DAG, Subtarget);
+  case ISD::BR_CC:         return LowerBR_CC(Op, DAG, Subtarget);
+  case ISD::BR_JT:         return LowerBR_JT(Op, DAG);
+  case ISD::VASTART:       return LowerVASTART(Op, DAG, VarArgsFrameIndex);
+  case ISD::SINT_TO_FP:
+  case ISD::UINT_TO_FP:    return LowerINT_TO_FP(Op, DAG);
+  case ISD::FP_TO_SINT:
+  case ISD::FP_TO_UINT:    return LowerFP_TO_INT(Op, DAG);
+  case ISD::FCOPYSIGN:     return LowerFCOPYSIGN(Op, DAG);
+  case ISD::BIT_CONVERT:   return LowerBIT_CONVERT(Op, DAG);
+  case ISD::MUL:           return LowerMUL(Op, DAG);
+  case ISD::MULHU:         return LowerMULHU(Op, DAG);
+  case ISD::MULHS:         return LowerMULHS(Op, DAG);
+  case ISD::SRL:
+  case ISD::SRA:           return LowerSRx(Op, DAG, Subtarget);
+  case ISD::FORMAL_ARGUMENTS:
+    return LowerFORMAL_ARGUMENTS(Op, DAG);
+  }
+}
+
+//===----------------------------------------------------------------------===//
+//                           ARM Scheduler Hooks
+//===----------------------------------------------------------------------===//
+
+MachineBasicBlock *
+ARMTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
+                                           MachineBasicBlock *BB) {
+  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
+  switch (MI->getOpcode()) {
+  default: assert(false && "Unexpected instr type to insert");
+  case ARM::tMOVCCr: {
+    // To "insert" a SELECT_CC instruction, we actually have to insert the
+    // diamond control-flow pattern.  The incoming instruction knows the
+    // destination vreg to set, the condition code register to branch on, the
+    // true/false values to select between, and a branch opcode to use.
+    const BasicBlock *LLVM_BB = BB->getBasicBlock();
+    ilist<MachineBasicBlock>::iterator It = BB;
+    ++It;
+
+    //  thisMBB:
+    //  ...
+    //   TrueVal = ...
+    //   cmpTY ccX, r1, r2
+    //   bCC copy1MBB
+    //   fallthrough --> copy0MBB
+    MachineBasicBlock *thisMBB  = BB;
+    MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
+    MachineBasicBlock *sinkMBB  = new MachineBasicBlock(LLVM_BB);
+    BuildMI(BB, TII->get(ARM::tBcc)).addMBB(sinkMBB)
+      .addImm(MI->getOperand(3).getImm());
+    MachineFunction *F = BB->getParent();
+    F->getBasicBlockList().insert(It, copy0MBB);
+    F->getBasicBlockList().insert(It, sinkMBB);
+    // Update machine-CFG edges by first adding all successors of the current
+    // block to the new block which will contain the Phi node for the select.
+    for(MachineBasicBlock::succ_iterator i = BB->succ_begin(),
+        e = BB->succ_end(); i != e; ++i)
+      sinkMBB->addSuccessor(*i);
+    // Next, remove all successors of the current block, and add the true
+    // and fallthrough blocks as its successors.
+    while(!BB->succ_empty())
+      BB->removeSuccessor(BB->succ_begin());
+    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, TII->get(ARM::PHI), MI->getOperand(0).getReg())
+      .addReg(MI->getOperand(1).getReg()).addMBB(copy0MBB)
+      .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB);
+
+    delete MI;   // The pseudo instruction is gone now.
+    return BB;
+  }
+  }
+}
+
+//===----------------------------------------------------------------------===//
+//                           ARM Optimization Hooks
+//===----------------------------------------------------------------------===//
+
+/// isLegalAddressImmediate - Return true if the integer value or
+/// GlobalValue can be used as the offset of the target addressing mode.
+bool ARMTargetLowering::isLegalAddressImmediate(int64_t V) const {
+  // ARM allows a 12-bit immediate field.
+  return V == V & ((1LL << 12) - 1);
+}
+
+bool ARMTargetLowering::isLegalAddressImmediate(GlobalValue *GV) const {
+  return false;
+}
+
+static bool getIndexedAddressParts(SDNode *Ptr, MVT::ValueType VT,
+                                   bool isSEXTLoad, SDOperand &Base,
+                                   SDOperand &Offset, bool &isInc,
+                                   SelectionDAG &DAG) {
+  if (Ptr->getOpcode() != ISD::ADD && Ptr->getOpcode() != ISD::SUB)
+    return false;
+
+  if (VT == MVT::i16 || ((VT == MVT::i8 || VT == MVT::i1) && isSEXTLoad)) {
+    // AddressingMode 3
+    Base = Ptr->getOperand(0);
+    if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Ptr->getOperand(1))) {
+      int RHSC = (int)RHS->getValue();
+      if (RHSC < 0 && RHSC > -256) {
+        isInc = false;
+        Offset = DAG.getConstant(-RHSC, RHS->getValueType(0));
+        return true;
+      }
+    }
+    isInc = (Ptr->getOpcode() == ISD::ADD);
+    Offset = Ptr->getOperand(1);
+    return true;
+  } else if (VT == MVT::i32 || VT == MVT::i8 || VT == MVT::i1) {
+    // AddressingMode 2
+    if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Ptr->getOperand(1))) {
+      int RHSC = (int)RHS->getValue();
+      if (RHSC < 0 && RHSC > -0x1000) {
+        isInc = false;
+        Offset = DAG.getConstant(-RHSC, RHS->getValueType(0));
+        Base = Ptr->getOperand(0);
+        return true;
+      }
+    }
+
+    if (Ptr->getOpcode() == ISD::ADD) {
+      isInc = true;
+      ARM_AM::ShiftOpc ShOpcVal= ARM_AM::getShiftOpcForNode(Ptr->getOperand(0));
+      if (ShOpcVal != ARM_AM::no_shift) {
+        Base = Ptr->getOperand(1);
+        Offset = Ptr->getOperand(0);
+      } else {
+        Base = Ptr->getOperand(0);
+        Offset = Ptr->getOperand(1);
+      }
+      return true;
+    }
+
+    isInc = (Ptr->getOpcode() == ISD::ADD);
+    Base = Ptr->getOperand(0);
+    Offset = Ptr->getOperand(1);
+    return true;
+  }
+
+  // FIXME: Use FLDM / FSTM to emulate indexed FP load / store.
+  return false;
+}
+
+/// getPreIndexedAddressParts - returns true by value, base pointer and
+/// offset pointer and addressing mode by reference if the node's address
+/// can be legally represented as pre-indexed load / store address.
+bool
+ARMTargetLowering::getPreIndexedAddressParts(SDNode *N, SDOperand &Base,
+                                             SDOperand &Offset,
+                                             ISD::MemIndexedMode &AM,
+                                             SelectionDAG &DAG) {
+  if (Subtarget->isThumb())
+    return false;
+
+  MVT::ValueType VT;
+  SDOperand Ptr;
+  bool isSEXTLoad = false;
+  if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
+    Ptr = LD->getBasePtr();
+    VT  = LD->getLoadedVT();
+    isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
+  } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
+    Ptr = ST->getBasePtr();
+    VT  = ST->getStoredVT();
+  } else
+    return false;
+
+  bool isInc;
+  bool isLegal = getIndexedAddressParts(Ptr.Val, VT, isSEXTLoad, Base, Offset,
+                                        isInc, DAG);
+  if (isLegal) {
+    AM = isInc ? ISD::PRE_INC : ISD::PRE_DEC;
+    return true;
+  }
+  return false;
+}
+
+/// getPostIndexedAddressParts - returns true by value, base pointer and
+/// offset pointer and addressing mode by reference if this node can be
+/// combined with a load / store to form a post-indexed load / store.
+bool ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
+                                                   SDOperand &Base,
+                                                   SDOperand &Offset,
+                                                   ISD::MemIndexedMode &AM,
+                                                   SelectionDAG &DAG) {
+  if (Subtarget->isThumb())
+    return false;
+
+  MVT::ValueType VT;
+  SDOperand Ptr;
+  bool isSEXTLoad = false;
+  if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
+    VT  = LD->getLoadedVT();
+    isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD;
+  } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
+    VT  = ST->getStoredVT();
+  } else
+    return false;
+
+  bool isInc;
+  bool isLegal = getIndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
+                                        isInc, DAG);
+  if (isLegal) {
+    AM = isInc ? ISD::POST_INC : ISD::POST_DEC;
+    return true;
+  }
+  return false;
+}
+
+void ARMTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
+                                                       uint64_t Mask,
+                                                       uint64_t &KnownZero, 
+                                                       uint64_t &KnownOne,
+                                                       unsigned Depth) const {
+  KnownZero = 0;
+  KnownOne = 0;
+  switch (Op.getOpcode()) {
+  default: break;
+  case ARMISD::CMOV: {
+    // Bits are known zero/one if known on the LHS and RHS.
+    ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero, KnownOne, Depth+1);
+    if (KnownZero == 0 && KnownOne == 0) return;
+
+    uint64_t KnownZeroRHS, KnownOneRHS;
+    ComputeMaskedBits(Op.getOperand(1), Mask,
+                      KnownZeroRHS, KnownOneRHS, Depth+1);
+    KnownZero &= KnownZeroRHS;
+    KnownOne  &= KnownOneRHS;
+    return;
+  }
+  }
+}
+
+//===----------------------------------------------------------------------===//
+//                           ARM Inline Assembly Support
+//===----------------------------------------------------------------------===//
+
+/// getConstraintType - Given a constraint letter, return the type of
+/// constraint it is for this target.
+ARMTargetLowering::ConstraintType
+ARMTargetLowering::getConstraintType(char ConstraintLetter) const {
+  switch (ConstraintLetter) {
+    case 'l':
+      return C_RegisterClass;
+    default: return TargetLowering::getConstraintType(ConstraintLetter);
+  }
+}
+
+std::pair<unsigned, const TargetRegisterClass*> 
+ARMTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
+                                                MVT::ValueType VT) const {
+  if (Constraint.size() == 1) {
+    // GCC RS6000 Constraint Letters
+    switch (Constraint[0]) {
+      case 'l':
+      // FIXME: in thumb mode, 'l' is only low-regs.
+      // FALL THROUGH.
+      case 'r':
+        return std::make_pair(0U, ARM::GPRRegisterClass);
+        break;
+    }
+  }
+  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
+}
+
+std::vector<unsigned> ARMTargetLowering::
+getRegClassForInlineAsmConstraint(const std::string &Constraint,
+                                  MVT::ValueType VT) const {
+  if (Constraint.size() != 1)
+    return std::vector<unsigned>();
+
+  switch (Constraint[0]) {      // GCC ARM Constraint Letters
+  default: break;
+  case 'l':
+  case 'r':
+    return make_vector<unsigned>(ARM::R0, ARM::R1, ARM::R2, ARM::R3,
+                                 ARM::R4, ARM::R5, ARM::R6, ARM::R7,
+                                 ARM::R8, ARM::R9, ARM::R10, ARM::R11,
+                                 ARM::R12, ARM::LR, 0);
+  }
+
+  return std::vector<unsigned>();
+}
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h
new file mode 100644
index 0000000..5f7ed65
--- /dev/null
+++ b/llvm/lib/Target/ARM/ARMISelLowering.h
@@ -0,0 +1,134 @@
+//===-- ARMISelLowering.h - ARM DAG Lowering Interface ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Evan Cheng and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interfaces that ARM uses to lower LLVM code into a
+// selection DAG.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ARMISELLOWERING_H
+#define ARMISELLOWERING_H
+
+#include "llvm/Target/TargetLowering.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include <vector>
+
+namespace llvm {
+  class ARMConstantPoolValue;
+  class ARMSubtarget;
+
+  namespace ARMISD {
+    // ARM Specific DAG Nodes
+    enum NodeType {
+      // Start the numbering where the builting ops and target ops leave off.
+      FIRST_NUMBER = ISD::BUILTIN_OP_END+ARM::INSTRUCTION_LIST_END,
+
+      Wrapper,      // Wrapper - A wrapper node for TargetConstantPool,
+                    // TargetExternalSymbol, and TargetGlobalAddress.
+      WrapperCall,  // WrapperCall - Same as wrapper, but mark the wrapped
+                    // node as call operand.
+      WrapperJT,    // WrapperJT - A wrapper node for TargetJumpTable
+      
+      CALL,         // Function call.
+      CALL_NOLINK,  // Function call with branch not branch-and-link.
+      tCALL,        // Thumb function call.
+      BRCOND,       // Conditional branch.
+      BR_JT,        // Jumptable branch.
+      RET_FLAG,     // Return with a flag operand.
+
+      PIC_ADD,      // Add with a PC operand and a PIC label.
+
+      CMP,          // ARM compare instructions.
+      CMPFP,        // ARM VFP compare instruction, sets FPSCR.
+      CMPFPw0,      // ARM VFP compare against zero instruction, sets FPSCR.
+      FMSTAT,       // ARM fmstat instruction.
+      CMOV,         // ARM conditional move instructions.
+      CNEG,         // ARM conditional negate instructions.
+      
+      FTOSI,        // FP to sint within a FP register.
+      FTOUI,        // FP to uint within a FP register.
+      SITOF,        // sint to FP within a FP register.
+      UITOF,        // uint to FP within a FP register.
+
+      MULHILOU,     // Lo,Hi = umul LHS, RHS.
+      MULHILOS,     // Lo,Hi = smul LHS, RHS.
+      
+      SRL_FLAG,     // V,Flag = srl_flag X -> srl X, 1 + save carry out.
+      SRA_FLAG,     // V,Flag = sra_flag X -> sra X, 1 + save carry out.
+      RRX,          // V = RRX X, Flag     -> srl X, 1 + shift in carry flag.
+      
+      FMRRD,        // double to two gprs.
+      FMDRR         // Two gprs to double.
+    };
+  }
+
+  //===----------------------------------------------------------------------===//
+  //  ARMTargetLowering - X86 Implementation of the TargetLowering interface
+  
+  class ARMTargetLowering : public TargetLowering {
+    int VarArgsFrameIndex;            // FrameIndex for start of varargs area.
+  public:
+    ARMTargetLowering(TargetMachine &TM);
+
+    virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
+    virtual const char *getTargetNodeName(unsigned Opcode) const;
+
+    virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
+                                                       MachineBasicBlock *MBB);
+
+    /// isLegalAddressImmediate - Return true if the integer value or
+    /// GlobalValue can be used as the offset of the target addressing mode.
+    virtual bool isLegalAddressImmediate(int64_t V) const;
+    virtual bool isLegalAddressImmediate(GlobalValue *GV) const;
+
+    /// getPreIndexedAddressParts - returns true by value, base pointer and
+    /// offset pointer and addressing mode by reference if the node's address
+    /// can be legally represented as pre-indexed load / store address.
+    virtual bool getPreIndexedAddressParts(SDNode *N, SDOperand &Base,
+                                           SDOperand &Offset,
+                                           ISD::MemIndexedMode &AM,
+                                           SelectionDAG &DAG);
+
+    /// getPostIndexedAddressParts - returns true by value, base pointer and
+    /// offset pointer and addressing mode by reference if this node can be
+    /// combined with a load / store to form a post-indexed load / store.
+    virtual bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
+                                            SDOperand &Base, SDOperand &Offset,
+                                            ISD::MemIndexedMode &AM,
+                                            SelectionDAG &DAG);
+
+    virtual void computeMaskedBitsForTargetNode(const SDOperand Op,
+                                                uint64_t Mask,
+                                                uint64_t &KnownZero, 
+                                                uint64_t &KnownOne,
+                                                unsigned Depth) const;
+    ConstraintType getConstraintType(char ConstraintLetter) const;
+    std::pair<unsigned, const TargetRegisterClass*> 
+      getRegForInlineAsmConstraint(const std::string &Constraint,
+                                   MVT::ValueType VT) const;
+    std::vector<unsigned>
+    getRegClassForInlineAsmConstraint(const std::string &Constraint,
+                                      MVT::ValueType VT) const;
+  private:
+    /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
+    /// make the right decision when generating code for different targets.
+    const ARMSubtarget *Subtarget;
+
+    /// ARMPCLabelIndex - Keep track the number of ARM PC labels created.
+    ///
+    unsigned ARMPCLabelIndex;
+
+    SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG);
+    SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG);
+    SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG);
+    SDOperand LowerBR_JT(SDOperand Op, SelectionDAG &DAG);
+  };
+}
+
+#endif  // ARMISELLOWERING_H
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.cpp b/llvm/lib/Target/ARM/ARMInstrInfo.cpp
index f99615b..b5425fe 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.cpp
@@ -14,46 +14,409 @@
 
 #include "ARMInstrInfo.h"
 #include "ARM.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "ARMAddressingModes.h"
 #include "ARMGenInstrInfo.inc"
+#include "ARMMachineFunctionInfo.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/LiveVariables.h"
+#include "llvm/Support/CommandLine.h"
 using namespace llvm;
 
-ARMInstrInfo::ARMInstrInfo()
+static cl::opt<bool> EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden,
+                                  cl::desc("Enable ARM 2-addr to 3-addr conv"));
+
+ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI)
   : TargetInstrInfo(ARMInsts, sizeof(ARMInsts)/sizeof(ARMInsts[0])),
-    RI(*this) {
+    RI(*this, STI) {
+}
+
+unsigned ARMInstrInfo::getDWARF_LABELOpcode() const {
+  return ARM::DWARF_LABEL;
 }
 
 const TargetRegisterClass *ARMInstrInfo::getPointerRegClass() const {
-  return &ARM::IntRegsRegClass;
+  return &ARM::GPRRegClass;
 }
 
 /// Return true if the instruction is a register to register move and
 /// leave the source and dest operands in the passed parameters.
 ///
 bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI,
-                                 unsigned &SrcReg, unsigned &DstReg) const {
+                               unsigned &SrcReg, unsigned &DstReg) const {
   MachineOpCode oc = MI.getOpcode();
   switch (oc) {
-  case ARM::MOV: {
-    assert(MI.getNumOperands() == 4 &&
-	   MI.getOperand(0).isRegister() &&
+  default:
+    return false;
+  case ARM::FCPYS:
+  case ARM::FCPYD:
+    SrcReg = MI.getOperand(1).getReg();
+    DstReg = MI.getOperand(0).getReg();
+    return true;
+  case ARM::MOVrr:
+  case ARM::tMOVrr:
+    assert(MI.getNumOperands() == 2 && MI.getOperand(0).isRegister() &&
+	   MI.getOperand(1).isRegister() &&
 	   "Invalid ARM MOV instruction");
-    const MachineOperand   &Arg = MI.getOperand(1);
-    const MachineOperand &Shift = MI.getOperand(2);
-    if (Arg.isRegister() && Shift.isImmediate() && Shift.getImmedValue() == 0) {
-      SrcReg = MI.getOperand(1).getReg();
-      DstReg = MI.getOperand(0).getReg();
-      return true;
-    }
+    SrcReg = MI.getOperand(1).getReg();
+    DstReg = MI.getOperand(0).getReg();
+    return true;
   }
-  }
-  return false;
 }
 
-void ARMInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
-                                  MachineBasicBlock *FBB,
-                                  const std::vector<MachineOperand> &Cond)const{
-  // Can only insert uncond branches so far.
-  assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!");
-  BuildMI(&MBB, get(ARM::b)).addMBB(TBB);
+unsigned ARMInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const{
+  switch (MI->getOpcode()) {
+  default: break;
+  case ARM::LDR:
+    if (MI->getOperand(1).isFrameIndex() &&
+        MI->getOperand(2).isReg() &&
+        MI->getOperand(3).isImmediate() && 
+        MI->getOperand(2).getReg() == 0 &&
+        MI->getOperand(3).getImmedValue() == 0) {
+      FrameIndex = MI->getOperand(1).getFrameIndex();
+      return MI->getOperand(0).getReg();
+    }
+    break;
+  case ARM::FLDD:
+  case ARM::FLDS:
+    if (MI->getOperand(1).isFrameIndex() &&
+        MI->getOperand(2).isImmediate() && 
+        MI->getOperand(2).getImmedValue() == 0) {
+      FrameIndex = MI->getOperand(1).getFrameIndex();
+      return MI->getOperand(0).getReg();
+    }
+    break;
+  case ARM::tLDRspi:
+    if (MI->getOperand(1).isFrameIndex() &&
+        MI->getOperand(2).isImmediate() && 
+        MI->getOperand(2).getImmedValue() == 0) {
+      FrameIndex = MI->getOperand(1).getFrameIndex();
+      return MI->getOperand(0).getReg();
+    }
+    break;
+  }
+  return 0;
+}
+
+unsigned ARMInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const {
+  switch (MI->getOpcode()) {
+  default: break;
+  case ARM::STR:
+    if (MI->getOperand(1).isFrameIndex() &&
+        MI->getOperand(2).isReg() &&
+        MI->getOperand(3).isImmediate() && 
+        MI->getOperand(2).getReg() == 0 &&
+        MI->getOperand(3).getImmedValue() == 0) {
+      FrameIndex = MI->getOperand(1).getFrameIndex();
+      return MI->getOperand(0).getReg();
+    }
+    break;
+  case ARM::FSTD:
+  case ARM::FSTS:
+    if (MI->getOperand(1).isFrameIndex() &&
+        MI->getOperand(2).isImmediate() && 
+        MI->getOperand(2).getImmedValue() == 0) {
+      FrameIndex = MI->getOperand(1).getFrameIndex();
+      return MI->getOperand(0).getReg();
+    }
+    break;
+  case ARM::tSTRspi:
+    if (MI->getOperand(1).isFrameIndex() &&
+        MI->getOperand(2).isImmediate() && 
+        MI->getOperand(2).getImmedValue() == 0) {
+      FrameIndex = MI->getOperand(1).getFrameIndex();
+      return MI->getOperand(0).getReg();
+    }
+    break;
+  }
+  return 0;
+}
+
+static unsigned getUnindexedOpcode(unsigned Opc) {
+  switch (Opc) {
+  default: break;
+  case ARM::LDR_PRE:
+  case ARM::LDR_POST:
+    return ARM::LDR;
+  case ARM::LDRH_PRE:
+  case ARM::LDRH_POST:
+    return ARM::LDRH;
+  case ARM::LDRB_PRE:
+  case ARM::LDRB_POST:
+    return ARM::LDRB;
+  case ARM::LDRSH_PRE:
+  case ARM::LDRSH_POST:
+    return ARM::LDRSH;
+  case ARM::LDRSB_PRE:
+  case ARM::LDRSB_POST:
+    return ARM::LDRSB;
+  case ARM::STR_PRE:
+  case ARM::STR_POST:
+    return ARM::STR;
+  case ARM::STRH_PRE:
+  case ARM::STRH_POST:
+    return ARM::STRH;
+  case ARM::STRB_PRE:
+  case ARM::STRB_POST:
+    return ARM::STRB;
+  }
+  return 0;
+}
+
+MachineInstr *
+ARMInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI,
+                                    MachineBasicBlock::iterator &MBBI,
+                                    LiveVariables &LV) const {
+  if (!EnableARM3Addr)
+    return NULL;
+
+  MachineInstr *MI = MBBI;
+  unsigned TSFlags = MI->getInstrDescriptor()->TSFlags;
+  bool isPre = false;
+  switch ((TSFlags & ARMII::IndexModeMask) >> ARMII::IndexModeShift) {
+  default: return NULL;
+  case ARMII::IndexModePre:
+    isPre = true;
+    break;
+  case ARMII::IndexModePost:
+    break;
+  }
+
+  // Try spliting an indexed load / store to a un-indexed one plus an add/sub
+  // operation.
+  unsigned MemOpc = getUnindexedOpcode(MI->getOpcode());
+  if (MemOpc == 0)
+    return NULL;
+
+  MachineInstr *UpdateMI = NULL;
+  MachineInstr *MemMI = NULL;
+  unsigned AddrMode = (TSFlags & ARMII::AddrModeMask);
+  unsigned NumOps = MI->getNumOperands();
+  bool isLoad = (MI->getInstrDescriptor()->Flags & M_LOAD_FLAG) != 0;
+  const MachineOperand &WB = isLoad ? MI->getOperand(1) : MI->getOperand(0);
+  const MachineOperand &Base = MI->getOperand(2);
+  const MachineOperand &Offset = MI->getOperand(NumOps-2);
+  unsigned WBReg = WB.getReg();
+  unsigned BaseReg = Base.getReg();
+  unsigned OffReg = Offset.getReg();
+  unsigned OffImm = MI->getOperand(NumOps-1).getImm();
+  switch (AddrMode) {
+  default:
+    assert(false && "Unknown indexed op!");
+    return NULL;
+  case ARMII::AddrMode2: {
+    bool isSub = ARM_AM::getAM2Op(OffImm) == ARM_AM::sub;
+    unsigned Amt = ARM_AM::getAM2Offset(OffImm);
+    if (OffReg == 0) {
+      int SOImmVal = ARM_AM::getSOImmVal(Amt);
+      if (SOImmVal == -1)
+        // Can't encode it in a so_imm operand. This transformation will
+        // add more than 1 instruction. Abandon!
+        return NULL;
+      UpdateMI = BuildMI(get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
+        .addReg(BaseReg).addImm(SOImmVal);
+    } else if (Amt != 0) {
+      ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm);
+      unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt);
+      UpdateMI = BuildMI(get(isSub ? ARM::SUBrs : ARM::ADDrs), WBReg)
+        .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc);
+    } else 
+      UpdateMI = BuildMI(get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
+        .addReg(BaseReg).addReg(OffReg);
+    break;
+  }
+  case ARMII::AddrMode3 : {
+    bool isSub = ARM_AM::getAM3Op(OffImm) == ARM_AM::sub;
+    unsigned Amt = ARM_AM::getAM3Offset(OffImm);
+    if (OffReg == 0)
+      // Immediate is 8-bits. It's guaranteed to fit in a so_imm operand.
+      UpdateMI = BuildMI(get(isSub ? ARM::SUBri : ARM::ADDri), WBReg)
+        .addReg(BaseReg).addImm(Amt);
+    else
+      UpdateMI = BuildMI(get(isSub ? ARM::SUBrr : ARM::ADDrr), WBReg)
+        .addReg(BaseReg).addReg(OffReg);
+    break;
+  }
+  }
+
+  std::vector<MachineInstr*> NewMIs;
+  if (isPre) {
+    if (isLoad)
+      MemMI = BuildMI(get(MemOpc), MI->getOperand(0).getReg())
+        .addReg(WBReg).addReg(0).addImm(0);
+    else
+      MemMI = BuildMI(get(MemOpc)).addReg(MI->getOperand(1).getReg())
+        .addReg(WBReg).addReg(0).addImm(0);
+    NewMIs.push_back(MemMI);
+    NewMIs.push_back(UpdateMI);
+  } else {
+    if (isLoad)
+      MemMI = BuildMI(get(MemOpc), MI->getOperand(0).getReg())
+        .addReg(BaseReg).addReg(0).addImm(0);
+    else
+      MemMI = BuildMI(get(MemOpc)).addReg(MI->getOperand(1).getReg())
+        .addReg(BaseReg).addReg(0).addImm(0);
+    if (WB.isDead())
+      UpdateMI->getOperand(0).setIsDead();
+    NewMIs.push_back(UpdateMI);
+    NewMIs.push_back(MemMI);
+  }
+  
+  // Transfer LiveVariables states, kill / dead info.
+  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+    MachineOperand &MO = MI->getOperand(i);
+    if (MO.isRegister() && MO.getReg() &&
+        MRegisterInfo::isVirtualRegister(MO.getReg())) {
+      unsigned Reg = MO.getReg();
+      LiveVariables::VarInfo &VI = LV.getVarInfo(Reg);
+      if (MO.isDef()) {
+        MachineInstr *NewMI = (Reg == WBReg) ? UpdateMI : MemMI;
+        if (MO.isDead())
+          LV.addVirtualRegisterDead(Reg, NewMI);
+        // Update the defining instruction.
+        if (VI.DefInst == MI)
+          VI.DefInst = NewMI;
+      }
+      if (MO.isUse() && MO.isKill()) {
+        for (unsigned j = 0; j < 2; ++j) {
+          // Look at the two new MI's in reverse order.
+          MachineInstr *NewMI = NewMIs[j];
+          MachineOperand *NMO = NewMI->findRegisterUseOperand(Reg);
+          if (!NMO)
+            continue;
+          LV.addVirtualRegisterKilled(Reg, NewMI);
+          if (VI.removeKill(MI))
+            VI.Kills.push_back(NewMI);
+          break;
+        }
+      }
+    }
+  }
+
+  MFI->insert(MBBI, NewMIs[1]);
+  MFI->insert(MBBI, NewMIs[0]);
+  return NewMIs[0];
+}
+
+// Branch analysis.
+bool ARMInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
+                                 MachineBasicBlock *&FBB,
+                                 std::vector<MachineOperand> &Cond) const {
+  // If the block has no terminators, it just falls into the block after it.
+  MachineBasicBlock::iterator I = MBB.end();
+  if (I == MBB.begin() || !isTerminatorInstr((--I)->getOpcode()))
+    return false;
+  
+  // Get the last instruction in the block.
+  MachineInstr *LastInst = I;
+  
+  // If there is only one terminator instruction, process it.
+  unsigned LastOpc = LastInst->getOpcode();
+  if (I == MBB.begin() || !isTerminatorInstr((--I)->getOpcode())) {
+    if (LastOpc == ARM::B || LastOpc == ARM::tB) {
+      TBB = LastInst->getOperand(0).getMachineBasicBlock();
+      return false;
+    }
+    if (LastOpc == ARM::Bcc || LastOpc == ARM::tBcc) {
+      // Block ends with fall-through condbranch.
+      TBB = LastInst->getOperand(0).getMachineBasicBlock();
+      Cond.push_back(LastInst->getOperand(1));
+      return false;
+    }
+    return true;  // Can't handle indirect branch.
+  }
+  
+  // Get the instruction before it if it is a terminator.
+  MachineInstr *SecondLastInst = I;
+  
+  // If there are three terminators, we don't know what sort of block this is.
+  if (SecondLastInst && I != MBB.begin() &&
+      isTerminatorInstr((--I)->getOpcode()))
+    return true;
+  
+  // If the block ends with ARM::B/ARM::tB and a ARM::Bcc/ARM::tBcc, handle it.
+  unsigned SecondLastOpc = SecondLastInst->getOpcode();
+  if ((SecondLastOpc == ARM::Bcc && LastOpc == ARM::B) ||
+      (SecondLastOpc == ARM::tBcc && LastOpc == ARM::tB)) {
+    TBB =  SecondLastInst->getOperand(0).getMachineBasicBlock();
+    Cond.push_back(SecondLastInst->getOperand(1));
+    FBB = LastInst->getOperand(0).getMachineBasicBlock();
+    return false;
+  }
+  
+  // Otherwise, can't handle this.
+  return true;
+}
+
+
+void ARMInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
+  MachineFunction &MF = *MBB.getParent();
+  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+  int BOpc   = AFI->isThumbFunction() ? ARM::tB : ARM::B;
+  int BccOpc = AFI->isThumbFunction() ? ARM::tBcc : ARM::Bcc;
+
+  MachineBasicBlock::iterator I = MBB.end();
+  if (I == MBB.begin()) return;
+  --I;
+  if (I->getOpcode() != BOpc && I->getOpcode() != BccOpc)
+    return;
+  
+  // Remove the branch.
+  I->eraseFromParent();
+  
+  I = MBB.end();
+  
+  if (I == MBB.begin()) return;
+  --I;
+  if (I->getOpcode() != BccOpc)
+    return;
+  
+  // Remove the branch.
+  I->eraseFromParent();
+}
+
+void ARMInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
+                                MachineBasicBlock *FBB,
+                                const std::vector<MachineOperand> &Cond) const {
+  MachineFunction &MF = *MBB.getParent();
+  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+  int BOpc   = AFI->isThumbFunction() ? ARM::tB : ARM::B;
+  int BccOpc = AFI->isThumbFunction() ? ARM::tBcc : ARM::Bcc;
+
+  // Shouldn't be a fall through.
+  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
+  assert((Cond.size() == 1 || Cond.size() == 0) &&
+         "ARM branch conditions have two components!");
+  
+  if (FBB == 0) {
+    if (Cond.empty()) // Unconditional branch?
+      BuildMI(&MBB, get(BOpc)).addMBB(TBB);
+    else
+      BuildMI(&MBB, get(BccOpc)).addMBB(TBB).addImm(Cond[0].getImm());
+    return;
+  }
+  
+  // Two-way conditional branch.
+  BuildMI(&MBB, get(BccOpc)).addMBB(TBB).addImm(Cond[0].getImm());
+  BuildMI(&MBB, get(BOpc)).addMBB(FBB);
+}
+
+bool ARMInstrInfo::BlockHasNoFallThrough(MachineBasicBlock &MBB) const {
+  if (MBB.empty()) return false;
+  
+  switch (MBB.back().getOpcode()) {
+  case ARM::B:
+  case ARM::tB:       // Uncond branch.
+  case ARM::BR_JTr:   // Jumptable branch.
+  case ARM::BR_JTm:   // Jumptable branch through mem.
+  case ARM::BR_JTadd: // Jumptable branch add to pc.
+    return true;
+  default: return false;
+  }
+}
+
+bool ARMInstrInfo::
+ReverseBranchCondition(std::vector<MachineOperand> &Cond) const {
+  ARMCC::CondCodes CC = (ARMCC::CondCodes)(int)Cond[0].getImm();
+  Cond[0].setImm(ARMCC::getOppositeCondition(CC));
+  return false;
 }
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.h b/llvm/lib/Target/ARM/ARMInstrInfo.h
index 0621c70..0208121 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.h
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.h
@@ -1,4 +1,4 @@
-//===- ARMInstrInfo.h - ARM Instruction Information --------------*- C++ -*-===//
+//===- ARMInstrInfo.h - ARM Instruction Information -------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -19,11 +19,56 @@
 #include "ARMRegisterInfo.h"
 
 namespace llvm {
+  class ARMSubtarget;
+
+/// ARMII - This namespace holds all of the target specific flags that
+/// instruction info tracks.
+///
+namespace ARMII {
+  enum {
+    //===------------------------------------------------------------------===//
+    // Instruction Flags.
+
+    //===------------------------------------------------------------------===//
+    // This three-bit field describes the addressing mode used.  Zero is unused
+    // so that we can tell if we forgot to set a value.
+
+    AddrModeMask  = 0xf,
+    AddrMode1     = 1,
+    AddrMode2     = 2,
+    AddrMode3     = 3,
+    AddrMode4     = 4,
+    AddrMode5     = 5,
+    AddrModeT1    = 6,
+    AddrModeT2    = 7,
+    AddrModeT4    = 8,
+    AddrModeTs    = 9,   // i8 * 4 for pc and sp relative data
+
+    // Size* - Flags to keep track of the size of an instruction.
+    SizeShift     = 4,
+    SizeMask      = 7 << SizeShift,
+    SizeSpecial   = 1,   // 0 byte pseudo or special case.
+    Size8Bytes    = 2,
+    Size4Bytes    = 3,
+    Size2Bytes    = 4,
+    
+    // IndexMode - Unindex, pre-indexed, or post-indexed. Only valid for load
+    // and store ops 
+    IndexModeShift = 7,
+    IndexModeMask  = 3 << IndexModeShift,
+    IndexModePre   = 1,
+    IndexModePost  = 2,
+    
+    // Opcode
+    OpcodeShift   = 9,
+    OpcodeMask    = 0xf << OpcodeShift
+  };
+}
 
 class ARMInstrInfo : public TargetInstrInfo {
   const ARMRegisterInfo RI;
 public:
-  ARMInstrInfo();
+  ARMInstrInfo(const ARMSubtarget &STI);
 
   /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info.  As
   /// such, whenever a client has an instance of instruction info, it should
@@ -35,15 +80,33 @@
   /// This is used for addressing modes.
   virtual const TargetRegisterClass *getPointerRegClass() const;
 
+  /// getDWARF_LABELOpcode - Return the opcode of the target's DWARF_LABEL
+  /// instruction if it has one.  This is used by codegen passes that update
+  /// DWARF line number info as they modify the code.
+  virtual unsigned getDWARF_LABELOpcode() const;
+  
   /// 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 &SrcReg, unsigned &DstReg) const;
+  virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const;
+  virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const;
+  
+  virtual MachineInstr *convertToThreeAddress(MachineFunction::iterator &MFI,
+                                              MachineBasicBlock::iterator &MBBI,
+                                              LiveVariables &LV) const;
 
+  // Branch analysis.
+  virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
+                             MachineBasicBlock *&FBB,
+                             std::vector<MachineOperand> &Cond) const;
+  virtual void RemoveBranch(MachineBasicBlock &MBB) const;
   virtual void InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
                             MachineBasicBlock *FBB,
                             const std::vector<MachineOperand> &Cond) const;
+  virtual bool BlockHasNoFallThrough(MachineBasicBlock &MBB) const;
+  virtual bool ReverseBranchCondition(std::vector<MachineOperand> &Cond) const;
 };
 
 }
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index beed8ab..bde81bc 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -1,4 +1,4 @@
-//===- ARMInstrInfo.td - Target Description for ARM Target ----------------===//
+//===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -12,351 +12,1184 @@
 //
 //===----------------------------------------------------------------------===//
 
-// Address operands
-def op_addr_mode1 : Operand<iPTR> {
-  let PrintMethod = "printAddrMode1";
-  let MIOperandInfo = (ops ptr_rc, ptr_rc, i32imm);
-}
+//===----------------------------------------------------------------------===//
+// ARM specific DAG Nodes.
+//
 
-def op_addr_mode2 : Operand<iPTR> {
-  let PrintMethod = "printAddrMode2";
-  let MIOperandInfo = (ops ptr_rc, i32imm);
-}
+// Type profiles.
+def SDT_ARMCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
 
-def op_addr_mode5 : Operand<iPTR> {
-  let PrintMethod = "printAddrMode5";
-  let MIOperandInfo = (ops ptr_rc, i32imm);
-}
+def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>;
 
-// Define ARM specific addressing mode.
-//Addressing Mode 1: data processing operands
-def addr_mode1 : ComplexPattern<iPTR, 3, "SelectAddrMode1", [imm, sra, shl, srl],
-                                []>;
+def SDT_ARMcall    : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
 
-//Addressing Mode 2: Load and Store Word or Unsigned Byte
-def addr_mode2 : ComplexPattern<iPTR, 2, "SelectAddrMode2", [], []>;
+def SDT_ARMCMov    : SDTypeProfile<1, 3,
+                                   [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
+                                    SDTCisVT<3, i32>]>;
 
-//Addressing Mode 5: VFP load/store
-def addr_mode5 : ComplexPattern<iPTR, 2, "SelectAddrMode5", [], []>;
+def SDT_ARMBrcond  : SDTypeProfile<0, 2,
+                                   [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
+
+def SDT_ARMBrJT    : SDTypeProfile<0, 3,
+                                  [SDTCisPtrTy<0>, SDTCisVT<1, i32>,
+                                   SDTCisVT<2, i32>]>;
+
+def SDT_ARMCmp     : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
+
+def SDT_ARMPICAdd  : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
+                                          SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
+
+// Node definitions.
+def ARMWrapper       : SDNode<"ARMISD::Wrapper",     SDTIntUnaryOp>;
+def ARMWrapperCall   : SDNode<"ARMISD::WrapperCall", SDTIntUnaryOp>;
+def ARMWrapperJT     : SDNode<"ARMISD::WrapperJT",   SDTIntBinOp>;
+
+def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeq,
+    		              [SDNPHasChain, SDNPOutFlag]>;
+def ARMcallseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_ARMCallSeq,
+    		              [SDNPHasChain, SDNPOutFlag]>;
+
+def ARMcall          : SDNode<"ARMISD::CALL", SDT_ARMcall,
+                              [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
+def ARMcall_nolink   : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall,
+                              [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
+
+def ARMretflag       : SDNode<"ARMISD::RET_FLAG", SDTRet,
+                              [SDNPHasChain, SDNPOptInFlag]>;
+
+def ARMcmov          : SDNode<"ARMISD::CMOV", SDT_ARMCMov,
+                              [SDNPInFlag]>;
+def ARMcneg          : SDNode<"ARMISD::CNEG", SDT_ARMCMov,
+                              [SDNPInFlag]>;
+
+def ARMbrcond        : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond,
+                              [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
+
+def ARMbrjt          : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT,
+                              [SDNPHasChain]>;
+
+def ARMcmp           : SDNode<"ARMISD::CMP", SDT_ARMCmp,
+                              [SDNPOutFlag]>;
+
+def ARMpic_add       : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>;
+
+def ARMsrl_flag      : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
+def ARMsra_flag      : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
+def ARMrrx           : SDNode<"ARMISD::RRX"     , SDTIntUnaryOp, [SDNPInFlag ]>;
 
 //===----------------------------------------------------------------------===//
-// Instruction Class Templates
+// ARM Instruction Predicate Definitions.
+//
+def HasV5T  : Predicate<"Subtarget->hasV5TOps()">;
+def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">;
+def HasV6   : Predicate<"Subtarget->hasV6Ops()">;
+def IsThumb : Predicate<"Subtarget->isThumb()">;
+def IsARM   : Predicate<"!Subtarget->isThumb()">;
+
 //===----------------------------------------------------------------------===//
-class InstARM<dag ops, string asmstr, list<dag> pattern> : Instruction {
+// ARM Flag Definitions.
+
+class RegConstraint<string C> {
+  string Constraints = C;
+}
+
+//===----------------------------------------------------------------------===//
+//  ARM specific transformation functions and pattern fragments.
+//
+
+// so_imm_XFORM - Return a so_imm value packed into the format described for
+// so_imm def below.
+def so_imm_XFORM : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(N->getValue()),
+                                   MVT::i32);
+}]>;
+
+// so_imm_neg_XFORM - Return a so_imm value packed into the format described for
+// so_imm_neg def below.
+def so_imm_neg_XFORM : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(-(int)N->getValue()),
+                                   MVT::i32);
+}]>;
+
+// so_imm_not_XFORM - Return a so_imm value packed into the format described for
+// so_imm_not def below.
+def so_imm_not_XFORM : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(~(int)N->getValue()),
+                                   MVT::i32);
+}]>;
+
+// rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24.
+def rot_imm : PatLeaf<(i32 imm), [{
+  int32_t v = (int32_t)N->getValue();
+  return v == 8 || v == 16 || v == 24;
+}]>;
+
+/// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15].
+def imm1_15 : PatLeaf<(i32 imm), [{
+  return (int32_t)N->getValue() >= 1 && (int32_t)N->getValue() < 16;
+}]>;
+
+/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31].
+def imm16_31 : PatLeaf<(i32 imm), [{
+  return (int32_t)N->getValue() >= 16 && (int32_t)N->getValue() < 32;
+}]>;
+
+def so_imm_neg : 
+  PatLeaf<(imm), [{ return ARM_AM::getSOImmVal(-(int)N->getValue()) != -1; }],
+          so_imm_neg_XFORM>;
+
+def so_imm_not : 
+  PatLeaf<(imm), [{ return ARM_AM::getSOImmVal(~(int)N->getValue()) != -1; }],
+          so_imm_not_XFORM>;
+
+// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
+def sext_16_node : PatLeaf<(i32 GPR:$a), [{
+  return TLI.ComputeNumSignBits(SDOperand(N,0)) >= 17;
+}]>;
+
+
+// Break so_imm's up into two pieces.  This handles immediates with up to 16
+// bits set in them.  This uses so_imm2part to match and so_imm2part_[12] to
+// get the first/second pieces.
+def so_imm2part : PatLeaf<(imm), [{
+  return ARM_AM::isSOImmTwoPartVal((unsigned)N->getValue());
+}]>;
+
+def so_imm2part_1 : SDNodeXForm<imm, [{
+  unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getValue());
+  return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(V), MVT::i32);
+}]>;
+
+def so_imm2part_2 : SDNodeXForm<imm, [{
+  unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getValue());
+  return CurDAG->getTargetConstant(ARM_AM::getSOImmVal(V), MVT::i32);
+}]>;
+
+
+
+//===----------------------------------------------------------------------===//
+// Operand Definitions.
+//
+
+// Branch target.
+def brtarget : Operand<OtherVT>;
+
+// Operand for printing out a condition code.
+def CCOp : Operand<i32> {
+  let PrintMethod = "printCCOperand";
+}
+
+// A list of registers separated by comma. Used by load/store multiple.
+def reglist : Operand<i32> {
+  let PrintMethod = "printRegisterList";
+}
+
+// An operand for the CONSTPOOL_ENTRY pseudo-instruction.
+def cpinst_operand : Operand<i32> {
+  let PrintMethod = "printCPInstOperand";
+}
+
+def jtblock_operand : Operand<i32> {
+  let PrintMethod = "printJTBlockOperand";
+}
+
+// Local PC labels.
+def pclabel : Operand<i32> {
+  let PrintMethod = "printPCLabel";
+}
+
+// shifter_operand operands: so_reg and so_imm.
+def so_reg : Operand<i32>,    // reg reg imm
+            ComplexPattern<i32, 3, "SelectShifterOperandReg",
+                            [shl,srl,sra,rotr]> {
+  let PrintMethod = "printSORegOperand";
+  let MIOperandInfo = (ops GPR, GPR, i32imm);
+}
+
+// so_imm - Match a 32-bit shifter_operand immediate operand, which is an
+// 8-bit immediate rotated by an arbitrary number of bits.  so_imm values are
+// represented in the imm field in the same 12-bit form that they are encoded
+// into so_imm instructions: the 8-bit immediate is the least significant bits
+// [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11].
+def so_imm : Operand<i32>,
+             PatLeaf<(imm),
+                     [{ return ARM_AM::getSOImmVal(N->getValue()) != -1; }],
+                     so_imm_XFORM> {
+  let PrintMethod = "printSOImmOperand";
+}
+
+
+// Define ARM specific addressing modes.
+
+// addrmode2 := reg +/- reg shop imm
+// addrmode2 := reg +/- imm12
+//
+def addrmode2 : Operand<i32>,
+                ComplexPattern<i32, 3, "SelectAddrMode2", []> {
+  let PrintMethod = "printAddrMode2Operand";
+  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
+}
+
+def am2offset : Operand<i32>,
+                ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> {
+  let PrintMethod = "printAddrMode2OffsetOperand";
+  let MIOperandInfo = (ops GPR, i32imm);
+}
+
+// addrmode3 := reg +/- reg
+// addrmode3 := reg +/- imm8
+//
+def addrmode3 : Operand<i32>,
+                ComplexPattern<i32, 3, "SelectAddrMode3", []> {
+  let PrintMethod = "printAddrMode3Operand";
+  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
+}
+
+def am3offset : Operand<i32>,
+                ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> {
+  let PrintMethod = "printAddrMode3OffsetOperand";
+  let MIOperandInfo = (ops GPR, i32imm);
+}
+
+// addrmode4 := reg, <mode|W>
+//
+def addrmode4 : Operand<i32>,
+                ComplexPattern<i32, 2, "", []> {
+  let PrintMethod = "printAddrMode4Operand";
+  let MIOperandInfo = (ops GPR, i32imm);
+}
+
+// addrmode5 := reg +/- imm8*4
+//
+def addrmode5 : Operand<i32>,
+                ComplexPattern<i32, 2, "SelectAddrMode5", []> {
+  let PrintMethod = "printAddrMode5Operand";
+  let MIOperandInfo = (ops GPR, i32imm);
+}
+
+// addrmodepc := pc + reg
+//
+def addrmodepc : Operand<i32>,
+                 ComplexPattern<i32, 2, "SelectAddrModePC", []> {
+  let PrintMethod = "printAddrModePCOperand";
+  let MIOperandInfo = (ops GPR, i32imm);
+}
+
+//===----------------------------------------------------------------------===//
+// ARM Instruction flags.  These need to match ARMInstrInfo.h.
+//
+
+// Addressing mode.
+class AddrMode<bits<4> val> {
+  bits<4> Value = val;
+}
+def AddrModeNone : AddrMode<0>;
+def AddrMode1    : AddrMode<1>;
+def AddrMode2    : AddrMode<2>;
+def AddrMode3    : AddrMode<3>;
+def AddrMode4    : AddrMode<4>;
+def AddrMode5    : AddrMode<5>;
+def AddrModeT1   : AddrMode<6>;
+def AddrModeT2   : AddrMode<7>;
+def AddrModeT4   : AddrMode<8>;
+def AddrModeTs   : AddrMode<9>;
+
+// Instruction size.
+class SizeFlagVal<bits<3> val> {
+  bits<3> Value = val;
+}
+def SizeInvalid  : SizeFlagVal<0>;  // Unset.
+def SizeSpecial  : SizeFlagVal<1>;  // Pseudo or special.
+def Size8Bytes   : SizeFlagVal<2>;
+def Size4Bytes   : SizeFlagVal<3>;
+def Size2Bytes   : SizeFlagVal<4>;
+
+// Load / store index mode.
+class IndexMode<bits<2> val> {
+  bits<2> Value = val;
+}
+def IndexModeNone : IndexMode<0>;
+def IndexModePre  : IndexMode<1>;
+def IndexModePost : IndexMode<2>;
+
+//===----------------------------------------------------------------------===//
+// ARM Instruction templates.
+//
+
+// ARMPat - Same as Pat<>, but requires that the compiler be in ARM mode.
+class ARMPat<dag pattern, dag result> : Pat<pattern, result> {
+  list<Predicate> Predicates = [IsARM];
+}
+class ARMV6Pat<dag pattern, dag result> : Pat<pattern, result> {
+  list<Predicate> Predicates = [IsARM, HasV6];
+}
+
+
+class InstARM<bits<4> opcod, AddrMode am, SizeFlagVal sz, IndexMode im,
+              dag ops, string asmstr, string cstr>
+  : Instruction {
   let Namespace = "ARM";
 
+  bits<4> Opcode = opcod;
+  AddrMode AM = am;
+  bits<4> AddrModeBits = AM.Value;
+  
+  SizeFlagVal SZ = sz;
+  bits<3> SizeFlag = SZ.Value;
+
+  IndexMode IM = im;
+  bits<2> IndexModeBits = IM.Value;
+  
   dag OperandList = ops;
   let AsmString   = asmstr;
+  let Constraints = cstr;
+}
+
+class PseudoInst<dag ops, string asm, list<dag> pattern>
+  : InstARM<0, AddrModeNone, SizeSpecial, IndexModeNone, ops, asm, ""> {
   let Pattern = pattern;
 }
 
-class IntBinOp<string OpcStr, SDNode OpNode> :
-        InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b),
-                 !strconcat(OpcStr, " $dst, $a, $b"),
-                 [(set IntRegs:$dst, (OpNode IntRegs:$a, IntRegs:$b))]>;
+class I<dag ops, AddrMode am, SizeFlagVal sz, IndexMode im,
+        string asm, string cstr, list<dag> pattern>
+  // FIXME: Set all opcodes to 0 for now.
+  : InstARM<0, am, sz, im, ops, asm, cstr> {
+  let Pattern = pattern;
+  list<Predicate> Predicates = [IsARM];
+}
 
-class FPBinOp<string OpcStr, SDNode OpNode> :
-        InstARM<(ops FPRegs:$dst, FPRegs:$a, FPRegs:$b),
-                 !strconcat(OpcStr, " $dst, $a, $b"),
-                 [(set FPRegs:$dst, (OpNode FPRegs:$a, FPRegs:$b))]>;
+class AI<dag ops, string asm, list<dag> pattern>
+  : I<ops, AddrModeNone, Size4Bytes, IndexModeNone, asm, "", pattern>;
+class AI1<dag ops, string asm, list<dag> pattern>
+  : I<ops, AddrMode1, Size4Bytes, IndexModeNone, asm, "", pattern>;
+class AI2<dag ops, string asm, list<dag> pattern>
+  : I<ops, AddrMode2, Size4Bytes, IndexModeNone, asm, "", pattern>;
+class AI3<dag ops, string asm, list<dag> pattern>
+  : I<ops, AddrMode3, Size4Bytes, IndexModeNone, asm, "", pattern>;
+class AI4<dag ops, string asm, list<dag> pattern>
+  : I<ops, AddrMode4, Size4Bytes, IndexModeNone, asm, "", pattern>;
+class AIx2<dag ops, string asm, list<dag> pattern>
+  : I<ops, AddrModeNone, Size8Bytes, IndexModeNone, asm, "", pattern>;
 
-class DFPBinOp<string OpcStr, SDNode OpNode> :
-        InstARM<(ops DFPRegs:$dst, DFPRegs:$a, DFPRegs:$b),
-                 !strconcat(OpcStr, " $dst, $a, $b"),
-                 [(set DFPRegs:$dst, (OpNode DFPRegs:$a, DFPRegs:$b))]>;
+// Pre-indexed ops
+class AI2pr<dag ops, string asm, string cstr, list<dag> pattern>
+  : I<ops, AddrMode2, Size4Bytes, IndexModePre, asm, cstr, pattern>;
+class AI3pr<dag ops, string asm, string cstr, list<dag> pattern>
+  : I<ops, AddrMode3, Size4Bytes, IndexModePre, asm, cstr, pattern>;
 
-class FPUnaryOp<string OpcStr, SDNode OpNode> :
-        InstARM<(ops FPRegs:$dst, FPRegs:$src),
-                 !strconcat(OpcStr, " $dst, $src"),
-                 [(set FPRegs:$dst, (OpNode FPRegs:$src))]>;
+// Post-indexed ops
+class AI2po<dag ops, string asm, string cstr, list<dag> pattern>
+  : I<ops, AddrMode2, Size4Bytes, IndexModePost, asm, cstr, pattern>;
+class AI3po<dag ops, string asm, string cstr, list<dag> pattern>
+  : I<ops, AddrMode3, Size4Bytes, IndexModePost, asm, cstr, pattern>;
 
-class DFPUnaryOp<string OpcStr, SDNode OpNode> :
-        InstARM<(ops DFPRegs:$dst, DFPRegs:$src),
-                 !strconcat(OpcStr, " $dst, $src"),
-                 [(set DFPRegs:$dst, (OpNode DFPRegs:$src))]>;
+// BR_JT instructions
+class JTI<dag ops, string asm, list<dag> pattern>
+  : I<ops, AddrModeNone, SizeSpecial, IndexModeNone, asm, "", pattern>;
+class JTI1<dag ops, string asm, list<dag> pattern>
+  : I<ops, AddrMode1, SizeSpecial, IndexModeNone, asm, "", pattern>;
+class JTI2<dag ops, string asm, list<dag> pattern>
+  : I<ops, AddrMode2, SizeSpecial, IndexModeNone, asm, "", pattern>;
 
-class Addr1BinOp<string OpcStr, SDNode OpNode> :
-        InstARM<(ops IntRegs:$dst, IntRegs:$a, op_addr_mode1:$b),
-                 !strconcat(OpcStr, " $dst, $a, $b"),
-                 [(set IntRegs:$dst, (OpNode IntRegs:$a, addr_mode1:$b))]>;
+
+class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
+class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
+
+
+/// AI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
+/// binop that produces a value.
+multiclass AI1_bin_irs<string opc, PatFrag opnode> {
+  def ri : AI1<(ops GPR:$dst, GPR:$a, so_imm:$b),
+               !strconcat(opc, " $dst, $a, $b"),
+               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>;
+  def rr : AI1<(ops GPR:$dst, GPR:$a, GPR:$b),
+               !strconcat(opc, " $dst, $a, $b"),
+               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>;
+  def rs : AI1<(ops GPR:$dst, GPR:$a, so_reg:$b),
+               !strconcat(opc, " $dst, $a, $b"),
+               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>;
+}
+
+/// AI1_bin0_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns.
+/// Similar to AI1_bin_irs except the instruction does not produce a result.
+multiclass AI1_bin0_irs<string opc, PatFrag opnode> {
+  def ri : AI1<(ops GPR:$a, so_imm:$b),
+               !strconcat(opc, " $a, $b"),
+               [(opnode GPR:$a, so_imm:$b)]>;
+  def rr : AI1<(ops GPR:$a, GPR:$b),
+               !strconcat(opc, " $a, $b"),
+               [(opnode GPR:$a, GPR:$b)]>;
+  def rs : AI1<(ops GPR:$a, so_reg:$b),
+               !strconcat(opc, " $a, $b"),
+               [(opnode GPR:$a, so_reg:$b)]>;
+}
+
+/// AI1_bin_is - Defines a set of (op r, {so_imm|so_reg}) patterns for a binop.
+multiclass AI1_bin_is<string opc, PatFrag opnode> {
+  def ri : AI1<(ops GPR:$dst, GPR:$a, so_imm:$b),
+               !strconcat(opc, " $dst, $a, $b"),
+               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>;
+  def rs : AI1<(ops GPR:$dst, GPR:$a, so_reg:$b),
+               !strconcat(opc, " $dst, $a, $b"),
+               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>;
+}
+
+/// AI1_unary_irs - Defines a set of (op {so_imm|r|so_reg}) patterns for unary
+/// ops.
+multiclass AI1_unary_irs<string opc, PatFrag opnode> {
+  def i : AI1<(ops GPR:$dst, so_imm:$a),
+              !strconcat(opc, " $dst, $a"),
+              [(set GPR:$dst, (opnode so_imm:$a))]>;
+  def r : AI1<(ops GPR:$dst, GPR:$a),
+              !strconcat(opc, " $dst, $a"),
+              [(set GPR:$dst, (opnode GPR:$a))]>;
+  def s : AI1<(ops GPR:$dst, so_reg:$a),
+              !strconcat(opc, " $dst, $a"),
+              [(set GPR:$dst, (opnode so_reg:$a))]>;
+}
+
+/// AI_unary_rrot - A unary operation with two forms: one whose operand is a
+/// register and one whose operand is a register rotated by 8/16/24.
+multiclass AI_unary_rrot<string opc, PatFrag opnode> {
+  def r     : AI<(ops GPR:$dst, GPR:$Src),
+                 !strconcat(opc, " $dst, $Src"),
+                 [(set GPR:$dst, (opnode GPR:$Src))]>, Requires<[IsARM, HasV6]>;
+  def r_rot : AI<(ops GPR:$dst, GPR:$Src, i32imm:$rot),
+                 !strconcat(opc, " $dst, $Src, ror $rot"),
+                 [(set GPR:$dst, (opnode (rotr GPR:$Src, rot_imm:$rot)))]>,
+              Requires<[IsARM, HasV6]>;
+}
+
+/// AI_bin_rrot - A binary operation with two forms: one whose operand is a
+/// register and one whose operand is a register rotated by 8/16/24.
+multiclass AI_bin_rrot<string opc, PatFrag opnode> {
+  def rr     : AI<(ops GPR:$dst, GPR:$LHS, GPR:$RHS),
+                  !strconcat(opc, " $dst, $LHS, $RHS"),
+                  [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
+                  Requires<[IsARM, HasV6]>;
+  def rr_rot : AI<(ops GPR:$dst, GPR:$LHS, GPR:$RHS, i32imm:$rot),
+                  !strconcat(opc, " $dst, $LHS, $RHS, ror $rot"),
+                  [(set GPR:$dst, (opnode GPR:$LHS,
+                                          (rotr GPR:$RHS, rot_imm:$rot)))]>,
+                  Requires<[IsARM, HasV6]>;
+}
+
 
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
 
-def brtarget : Operand<OtherVT>;
+//===----------------------------------------------------------------------===//
+//  Miscellaneous Instructions.
+//
+def IMPLICIT_DEF_GPR : 
+PseudoInst<(ops GPR:$rD),
+           "@ IMPLICIT_DEF_GPR $rD",
+           [(set GPR:$rD, (undef))]>;
 
-// Operand for printing out a condition code.
-let PrintMethod = "printCCOperand" in
-  def CCOp : Operand<i32>;
 
-def SDT_ARMCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
-def callseq_start  : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeq,
-    		             [SDNPHasChain, SDNPOutFlag]>;
-def callseq_end    : SDNode<"ISD::CALLSEQ_END",   SDT_ARMCallSeq,
-    		             [SDNPHasChain, SDNPOutFlag]>;
+/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in
+/// the function.  The first operand is the ID# for this instruction, the second
+/// is the index into the MachineConstantPool that this is, the third is the
+/// size in bytes of this constant pool entry.
+def CONSTPOOL_ENTRY :
+PseudoInst<(ops cpinst_operand:$instid, cpinst_operand:$cpidx, i32imm:$size),
+           "${instid:label} ${cpidx:cpentry}", []>;
 
-def SDT_ARMcall    : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
-def ARMcall        : SDNode<"ARMISD::CALL", SDT_ARMcall,
-                           [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
-def retflag        : SDNode<"ARMISD::RET_FLAG", SDTRet,
-	                   [SDNPHasChain, SDNPOptInFlag]>;
+def ADJCALLSTACKUP :
+PseudoInst<(ops i32imm:$amt),
+           "@ ADJCALLSTACKUP $amt",
+           [(ARMcallseq_end imm:$amt)]>, Imp<[SP],[SP]>;
 
-def SDTarmselect   : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>]>;
-def armselect      : SDNode<"ARMISD::SELECT", SDTarmselect, [SDNPInFlag, SDNPOutFlag]>;
+def ADJCALLSTACKDOWN : 
+PseudoInst<(ops i32imm:$amt),
+           "@ ADJCALLSTACKDOWN $amt",
+           [(ARMcallseq_start imm:$amt)]>, Imp<[SP],[SP]>;
 
-def SDTarmfmstat   : SDTypeProfile<0, 0, []>;
-def armfmstat      : SDNode<"ARMISD::FMSTAT", SDTarmfmstat, [SDNPInFlag, SDNPOutFlag]>;
+def DWARF_LOC :
+PseudoInst<(ops i32imm:$line, i32imm:$col, i32imm:$file),
+           ".loc $file, $line, $col",
+           [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>;
 
-def SDTarmbr       : SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
-def armbr          : SDNode<"ARMISD::BR", SDTarmbr, [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
+def DWARF_LABEL :
+PseudoInst<(ops i32imm:$id),
+           "\nLdebug_loc${id:no_hash}:",
+           [(dwarf_label (i32 imm:$id))]>;
 
-def SDTVoidBinOp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
-def armcmp       : SDNode<"ARMISD::CMP",  SDTVoidBinOp, [SDNPOutFlag]>;
+def PICADD : AI1<(ops GPR:$dst, GPR:$a, pclabel:$cp),
+                  "\n$cp:\n\tadd $dst, pc, $a",
+                  [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
+let AddedComplexity = 10 in
+def PICLD : AI2<(ops GPR:$dst, addrmodepc:$addr),
+                  "\n${addr:label}:\n\tldr $dst, $addr",
+                  [(set GPR:$dst, (load addrmodepc:$addr))]>;
 
-def armfsitos      : SDNode<"ARMISD::FSITOS", SDTUnaryOp>;
-def armftosis      : SDNode<"ARMISD::FTOSIS", SDTUnaryOp>;
-def armfsitod      : SDNode<"ARMISD::FSITOD", SDTUnaryOp>;
-def armftosid      : SDNode<"ARMISD::FTOSID", SDTUnaryOp>;
-def armfuitos      : SDNode<"ARMISD::FUITOS", SDTUnaryOp>;
-def armftouis      : SDNode<"ARMISD::FTOUIS", SDTUnaryOp>;
-def armfuitod      : SDNode<"ARMISD::FUITOD", SDTUnaryOp>;
-def armftouid      : SDNode<"ARMISD::FTOUID", SDTUnaryOp>;
+//===----------------------------------------------------------------------===//
+//  Control Flow Instructions.
+//
 
-def SDTarmfmrrd    : SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>, SDTCisFP<2>]>;
-def armfmrrd       : SDNode<"ARMISD::FMRRD", SDTarmfmrrd,
-                            [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
+let isReturn = 1, isTerminator = 1 in
+  def BX_RET : AI<(ops), "bx lr", [(ARMretflag)]>;
 
-def SDTarmfmdrr    : SDTypeProfile<1, 2, [SDTCisFP<0>, SDTCisInt<1>, SDTCisInt<2>]>;
-def armfmdrr       : SDNode<"ARMISD::FMDRR", SDTarmfmdrr, []>;
+// FIXME: remove when we have a way to marking a MI with these properties.
+let isLoad = 1, isReturn = 1, isTerminator = 1 in
+  def LDM_RET : AI4<(ops addrmode4:$addr, reglist:$dst1, variable_ops),
+                    "ldm${addr:submode} $addr, $dst1",
+                    []>;
 
-def ADJCALLSTACKUP : InstARM<(ops i32imm:$amt),
-                            "!ADJCALLSTACKUP $amt",
-                            [(callseq_end imm:$amt)]>, Imp<[R13],[R13]>;
-
-def ADJCALLSTACKDOWN : InstARM<(ops i32imm:$amt),
-                               "!ADJCALLSTACKDOWN $amt",
-                               [(callseq_start imm:$amt)]>, Imp<[R13],[R13]>;
-
-def IMPLICIT_DEF_Int : InstARM<(ops IntRegs:$dst),
-                               "@IMPLICIT_DEF $dst",
-                               [(set IntRegs:$dst, (undef))]>;
-def IMPLICIT_DEF_FP  : InstARM<(ops FPRegs:$dst), "@IMPLICIT_DEF $dst",
-                               [(set FPRegs:$dst, (undef))]>;
-def IMPLICIT_DEF_DFP : InstARM<(ops DFPRegs:$dst), "@IMPLICIT_DEF $dst",
-                               [(set DFPRegs:$dst, (undef))]>;
-
-let isReturn = 1 in {
-  def bx: InstARM<(ops), "bx r14", [(retflag)]>;
+let isCall = 1, noResults = 1, 
+  Defs = [R0, R1, R2, R3, R12, LR,
+          D0, D1, D2, D3, D4, D5, D6, D7] in {
+  def BL  : AI<(ops i32imm:$func, variable_ops),
+               "bl ${func:call}",
+               [(ARMcall tglobaladdr:$func)]>;
+  // ARMv5T and above
+  def BLX : AI<(ops GPR:$dst, variable_ops),
+               "blx $dst",
+               [(ARMcall GPR:$dst)]>, Requires<[IsARM, HasV5T]>;
+  // ARMv4T
+  def BX : AIx2<(ops GPR:$dst, variable_ops),
+                "mov lr, pc\n\tbx $dst",
+                [(ARMcall_nolink GPR:$dst)]>;
 }
 
-let noResults = 1, Defs = [R0, R1, R2, R3, R14] in {
-  def bl: InstARM<(ops i32imm:$func, variable_ops), "bl $func", []>;
-  def blx     : InstARM<(ops IntRegs:$func, variable_ops), "blx $func", [(ARMcall IntRegs:$func)]>;
+let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
+  def B : AI<(ops brtarget:$dst), "b $dst",
+             [(br bb:$dst)]>;
+
+  def BR_JTr : JTI<(ops GPR:$dst, jtblock_operand:$jt, i32imm:$id),
+                    "mov pc, $dst \n$jt",
+                    [(ARMbrjt GPR:$dst, tjumptable:$jt, imm:$id)]>;
+  def BR_JTm : JTI2<(ops addrmode2:$dst, jtblock_operand:$jt, i32imm:$id),
+                     "ldr pc, $dst \n$jt",
+                     [(ARMbrjt (i32 (load addrmode2:$dst)), tjumptable:$jt,
+                       imm:$id)]>;
+  def BR_JTadd : JTI1<(ops GPR:$dst, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
+                       "add pc, $dst, $idx \n$jt",
+                       [(ARMbrjt (add GPR:$dst, GPR:$idx), tjumptable:$jt,
+                         imm:$id)]>;
 }
 
-def LDR     : InstARM<(ops IntRegs:$dst, op_addr_mode2:$addr),
-                     "ldr $dst, $addr",
-                     [(set IntRegs:$dst, (load addr_mode2:$addr))]>;
+let isBranch = 1, isTerminator = 1, noResults = 1, isBarrier = 1 in
+  def Bcc : AI<(ops brtarget:$dst, CCOp:$cc), "b$cc $dst",
+                [(ARMbrcond bb:$dst, imm:$cc)]>;
 
-def LDRB    : InstARM<(ops IntRegs:$dst, IntRegs:$addr),
-                       "ldrb $dst, [$addr]",
-                       [(set IntRegs:$dst, (zextloadi8 IntRegs:$addr))]>;
+//===----------------------------------------------------------------------===//
+//  Load / store Instructions.
+//
 
-def LDRSB   : InstARM<(ops IntRegs:$dst, IntRegs:$addr),
-                       "ldrsb $dst, [$addr]",
-                       [(set IntRegs:$dst, (sextloadi8 IntRegs:$addr))]>;
+// Load
+let isLoad = 1 in {
+def LDR  : AI2<(ops GPR:$dst, addrmode2:$addr),
+               "ldr $dst, $addr",
+               [(set GPR:$dst, (load addrmode2:$addr))]>;
 
-def LDRH    : InstARM<(ops IntRegs:$dst, IntRegs:$addr),
-                       "ldrh $dst, [$addr]",
-                       [(set IntRegs:$dst, (zextloadi16 IntRegs:$addr))]>;
+// Loads with zero extension
+def LDRH  : AI3<(ops GPR:$dst, addrmode3:$addr),
+                 "ldrh $dst, $addr",
+                [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
 
-def LDRSH   : InstARM<(ops IntRegs:$dst, IntRegs:$addr),
-                       "ldrsh $dst, [$addr]",
-                       [(set IntRegs:$dst, (sextloadi16 IntRegs:$addr))]>;
+def LDRB  : AI2<(ops GPR:$dst, addrmode2:$addr),
+                 "ldrb $dst, $addr",
+                [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
 
-def STR     : InstARM<(ops IntRegs:$src, op_addr_mode2:$addr),
-                     "str $src, $addr",
-                     [(store IntRegs:$src, addr_mode2:$addr)]>;
+// Loads with sign extension
+def LDRSH : AI3<(ops GPR:$dst, addrmode3:$addr),
+                 "ldrsh $dst, $addr",
+                [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
 
-def STRB    : InstARM<(ops IntRegs:$src, IntRegs:$addr),
-                       "strb $src, [$addr]",
-                       [(truncstorei8 IntRegs:$src, IntRegs:$addr)]>;
+def LDRSB : AI3<(ops GPR:$dst, addrmode3:$addr),
+                 "ldrsb $dst, $addr",
+                [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
 
-def STRH    : InstARM<(ops IntRegs:$src, IntRegs:$addr),
-                       "strh $src, [$addr]",
-                       [(truncstorei16 IntRegs:$src, IntRegs:$addr)]>;
+// Load doubleword
+def LDRD  : AI3<(ops GPR:$dst, addrmode3:$addr),
+                 "ldrd $dst, $addr",
+                []>, Requires<[IsARM, HasV5T]>;
 
-def MOV   : InstARM<(ops IntRegs:$dst, op_addr_mode1:$src),
-                    "mov $dst, $src", [(set IntRegs:$dst, addr_mode1:$src)]>;
+// Indexed loads
+def LDR_PRE  : AI2pr<(ops GPR:$dst, GPR:$base_wb, addrmode2:$addr),
+                    "ldr $dst, $addr!", "$addr.base = $base_wb", []>;
 
-def MVN     : InstARM<(ops IntRegs:$dst, op_addr_mode1:$src),
-                       "mvn $dst, $src", [(set IntRegs:$dst, (not addr_mode1:$src))]>;
+def LDR_POST : AI2po<(ops GPR:$dst, GPR:$base_wb, GPR:$base, am2offset:$offset),
+                    "ldr $dst, [$base], $offset", "$base = $base_wb", []>;
 
-def ADD     : Addr1BinOp<"add",  add>;
-def ADCS    : Addr1BinOp<"adcs", adde>;
-def ADDS    : Addr1BinOp<"adds", addc>;
-def SUB     : Addr1BinOp<"sub",  sub>;
-def SBCS    : Addr1BinOp<"sbcs", sube>;
-def SUBS    : Addr1BinOp<"subs", subc>;
-def AND     : Addr1BinOp<"and",  and>;
-def EOR     : Addr1BinOp<"eor",  xor>;
-def ORR     : Addr1BinOp<"orr",  or>;
+def LDRH_PRE  : AI3pr<(ops GPR:$dst, GPR:$base_wb, addrmode3:$addr),
+                     "ldrh $dst, $addr!", "$addr.base = $base_wb", []>;
 
-let isTwoAddress = 1 in {
-  def movcond : InstARM<(ops IntRegs:$dst, IntRegs:$false,
-			 op_addr_mode1:$true, CCOp:$cc),
-	                 "mov$cc $dst, $true",
-		         [(set IntRegs:$dst, (armselect addr_mode1:$true,
-			   IntRegs:$false, imm:$cc))]>;
+def LDRH_POST : AI3po<(ops GPR:$dst, GPR:$base_wb, GPR:$base,am3offset:$offset),
+                     "ldrh $dst, [$base], $offset", "$base = $base_wb", []>;
 
-  def fcpyscond : InstARM<(ops FPRegs:$dst, FPRegs:$false,
-			 FPRegs:$true, CCOp:$cc),
-	                 "fcpys$cc $dst, $true",
-		         [(set FPRegs:$dst, (armselect FPRegs:$true,
-			   FPRegs:$false, imm:$cc))]>;
+def LDRB_PRE  : AI2pr<(ops GPR:$dst, GPR:$base_wb, addrmode2:$addr),
+                     "ldrb $dst, $addr!", "$addr.base = $base_wb", []>;
 
-  def fcpydcond : InstARM<(ops DFPRegs:$dst, DFPRegs:$false,
-			 DFPRegs:$true, CCOp:$cc),
-	                 "fcpyd$cc $dst, $true",
-		         [(set DFPRegs:$dst, (armselect DFPRegs:$true,
-			   DFPRegs:$false, imm:$cc))]>;
+def LDRB_POST : AI2po<(ops GPR:$dst, GPR:$base_wb, GPR:$base,am2offset:$offset),
+                     "ldrb $dst, [$base], $offset", "$base = $base_wb", []>;
+
+def LDRSH_PRE : AI3pr<(ops GPR:$dst, GPR:$base_wb, addrmode3:$addr),
+                      "ldrsh $dst, $addr!", "$addr.base = $base_wb", []>;
+
+def LDRSH_POST: AI3po<(ops GPR:$dst, GPR:$base_wb, GPR:$base,am3offset:$offset),
+                      "ldrsh $dst, [$base], $offset", "$base = $base_wb", []>;
+
+def LDRSB_PRE : AI3pr<(ops GPR:$dst, GPR:$base_wb, addrmode3:$addr),
+                      "ldrsb $dst, $addr!", "$addr.base = $base_wb", []>;
+
+def LDRSB_POST: AI3po<(ops GPR:$dst, GPR:$base_wb, GPR:$base,am3offset:$offset),
+                      "ldrsb $dst, [$base], $offset", "$base = $base_wb", []>;
+} // isLoad
+
+// Store
+let isStore = 1 in {
+def STR  : AI2<(ops GPR:$src, addrmode2:$addr),
+               "str $src, $addr",
+               [(store GPR:$src, addrmode2:$addr)]>;
+
+// Stores with truncate
+def STRH : AI3<(ops GPR:$src, addrmode3:$addr),
+               "strh $src, $addr",
+               [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
+
+def STRB : AI2<(ops GPR:$src, addrmode2:$addr),
+               "strb $src, $addr",
+               [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
+
+// Store doubleword
+def STRD : AI3<(ops GPR:$src, addrmode3:$addr),
+               "strd $src, $addr",
+               []>, Requires<[IsARM, HasV5T]>;
+
+// Indexed stores
+def STR_PRE  : AI2pr<(ops GPR:$base_wb, GPR:$src, GPR:$base, am2offset:$offset),
+                    "str $src, [$base, $offset]!", "$base = $base_wb",
+                    [(set GPR:$base_wb,
+                      (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
+
+def STR_POST : AI2po<(ops  GPR:$base_wb, GPR:$src, GPR:$base,am2offset:$offset),
+                    "str $src, [$base], $offset", "$base = $base_wb",
+                    [(set GPR:$base_wb,
+                      (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
+
+def STRH_PRE : AI3pr<(ops  GPR:$base_wb, GPR:$src, GPR:$base,am3offset:$offset),
+                     "strh $src, [$base, $offset]!", "$base = $base_wb",
+                    [(set GPR:$base_wb,
+                      (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
+
+def STRH_POST: AI3po<(ops  GPR:$base_wb, GPR:$src, GPR:$base,am3offset:$offset),
+                     "strh $src, [$base], $offset", "$base = $base_wb",
+                    [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
+                                         GPR:$base, am3offset:$offset))]>;
+
+def STRB_PRE : AI2pr<(ops  GPR:$base_wb, GPR:$src, GPR:$base,am2offset:$offset),
+                     "strb $src, [$base, $offset]!", "$base = $base_wb",
+                    [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
+                                         GPR:$base, am2offset:$offset))]>;
+
+def STRB_POST: AI2po<(ops  GPR:$base_wb, GPR:$src, GPR:$base,am2offset:$offset),
+                     "strb $src, [$base], $offset", "$base = $base_wb",
+                    [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
+                                         GPR:$base, am2offset:$offset))]>;
+} // isStore
+
+//===----------------------------------------------------------------------===//
+//  Load / store multiple Instructions.
+//
+
+let isLoad = 1 in
+def LDM : AI4<(ops addrmode4:$addr, reglist:$dst1, variable_ops),
+              "ldm${addr:submode} $addr, $dst1",
+              []>;
+
+let isStore = 1 in
+def STM : AI4<(ops addrmode4:$addr, reglist:$src1, variable_ops),
+              "stm${addr:submode} $addr, $src1",
+              []>;
+
+//===----------------------------------------------------------------------===//
+//  Move Instructions.
+//
+
+def MOVrr : AI1<(ops GPR:$dst, GPR:$src),
+                "mov $dst, $src", []>;
+def MOVrs : AI1<(ops GPR:$dst, so_reg:$src),
+                "mov $dst, $src", [(set GPR:$dst, so_reg:$src)]>;
+def MOVri : AI1<(ops GPR:$dst, so_imm:$src),
+                "mov $dst, $src", [(set GPR:$dst, so_imm:$src)]>;
+
+// These aren't really mov instructions, but we have to define them this way
+// due to flag operands.
+
+def MOVsrl_flag : AI1<(ops GPR:$dst, GPR:$src),
+                      "movs $dst, $src, lsr #1",
+                      [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>;
+def MOVsra_flag : AI1<(ops GPR:$dst, GPR:$src),
+                      "movs $dst, $src, asr #1",
+                      [(set GPR:$dst, (ARMsra_flag GPR:$src))]>;
+def MOVrrx      : AI1<(ops GPR:$dst, GPR:$src),
+                      "mov $dst, $src, rrx",
+                      [(set GPR:$dst, (ARMrrx GPR:$src))]>;
+
+
+//===----------------------------------------------------------------------===//
+//  Extend Instructions.
+//
+
+// Sign extenders
+
+defm SXTB  : AI_unary_rrot<"sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
+defm SXTH  : AI_unary_rrot<"sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
+
+defm SXTAB : AI_bin_rrot<"sxtab",
+                        BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
+defm SXTAH : AI_bin_rrot<"sxtah",
+                        BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
+
+// TODO: SXT(A){B|H}16
+
+// Zero extenders
+
+let AddedComplexity = 16 in {
+defm UXTB   : AI_unary_rrot<"uxtb"  , UnOpFrag<(and node:$Src, 0x000000FF)>>;
+defm UXTH   : AI_unary_rrot<"uxth"  , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
+defm UXTB16 : AI_unary_rrot<"uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
+
+def : ARMV6Pat<(and (shl GPR:$Src, 8), 0xFF00FF),
+               (UXTB16r_rot GPR:$Src, 24)>;
+def : ARMV6Pat<(and (srl GPR:$Src, 8), 0xFF00FF),
+               (UXTB16r_rot GPR:$Src, 8)>;
+
+defm UXTAB : AI_bin_rrot<"uxtab",
+                        BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
+defm UXTAH : AI_bin_rrot<"uxtah",
+                        BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
 }
 
-def MUL     : IntBinOp<"mul", mul>;
+// This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
+//defm UXTAB16 : xxx<"uxtab16", 0xff00ff>;
 
-let Defs = [R0] in {
-  def SMULL   : IntBinOp<"smull r12,", mulhs>;
-  def UMULL   : IntBinOp<"umull r12,", mulhu>;
+// TODO: UXT(A){B|H}16
+
+//===----------------------------------------------------------------------===//
+//  Arithmetic Instructions.
+//
+
+defm ADD  : AI1_bin_irs<"add" , BinOpFrag<(add  node:$LHS, node:$RHS)>>;
+defm ADDS : AI1_bin_irs<"adds", BinOpFrag<(addc node:$LHS, node:$RHS)>>;
+defm ADC  : AI1_bin_irs<"adc" , BinOpFrag<(adde node:$LHS, node:$RHS)>>;
+defm SUB  : AI1_bin_irs<"sub" , BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
+defm SUBS : AI1_bin_irs<"subs", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
+defm SBC  : AI1_bin_irs<"sbc" , BinOpFrag<(sube node:$LHS, node:$RHS)>>;
+
+// These don't define reg/reg forms, because they are handled above.
+defm RSB  : AI1_bin_is <"rsb" , BinOpFrag<(sub  node:$RHS, node:$LHS)>>;
+defm RSBS : AI1_bin_is <"rsbs", BinOpFrag<(subc node:$RHS, node:$LHS)>>;
+defm RSC  : AI1_bin_is <"rsc" , BinOpFrag<(sube node:$RHS, node:$LHS)>>;
+
+// (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
+def : ARMPat<(add    GPR:$src, so_imm_neg:$imm),
+             (SUBri  GPR:$src, so_imm_neg:$imm)>;
+
+//def : ARMPat<(addc   GPR:$src, so_imm_neg:$imm),
+//             (SUBSri GPR:$src, so_imm_neg:$imm)>;
+//def : ARMPat<(adde   GPR:$src, so_imm_neg:$imm),
+//             (SBCri  GPR:$src, so_imm_neg:$imm)>;
+
+// Note: These are implemented in C++ code, because they have to generate
+// ADD/SUBrs instructions, which use a complex pattern that a xform function
+// cannot produce.
+// (mul X, 2^n+1) -> (add (X << n), X)
+// (mul X, 2^n-1) -> (rsb X, (X << n))
+
+
+//===----------------------------------------------------------------------===//
+//  Bitwise Instructions.
+//
+
+defm AND   : AI1_bin_irs<"and", BinOpFrag<(and node:$LHS, node:$RHS)>>;
+defm ORR   : AI1_bin_irs<"orr", BinOpFrag<(or  node:$LHS, node:$RHS)>>;
+defm EOR   : AI1_bin_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>>;
+defm BIC   : AI1_bin_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
+
+defm MVN   : AI1_unary_irs<"mvn", not>;
+
+def : ARMPat<(i32  so_imm_not:$imm),
+             (MVNi so_imm_not:$imm)>;
+
+def : ARMPat<(and   GPR:$src, so_imm_not:$imm),
+             (BICri GPR:$src, so_imm_not:$imm)>;
+
+//===----------------------------------------------------------------------===//
+//  Multiply Instructions.
+//
+
+// AI_orr - Defines a (op r, r) pattern.
+class AI_orr<string opc, SDNode opnode>
+  : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
+       !strconcat(opc, " $dst, $a, $b"),
+       [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>;
+
+// AI_oorr - Defines a (op (op r, r), r) pattern.
+class AI_oorr<string opc, SDNode opnode1, SDNode opnode2>
+  : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$c),
+       !strconcat(opc, " $dst, $a, $b, $c"),
+       [(set GPR:$dst, (opnode1 (opnode2 GPR:$a, GPR:$b), GPR:$c))]>;
+
+def MUL  : AI_orr<"mul", mul>;
+def MLA  : AI_oorr<"mla", add, mul>;
+
+// Extra precision multiplies with low / high results
+def SMULL : AI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b),
+               "smull $ldst, $hdst, $a, $b",
+               []>;
+
+def UMULL : AI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b),
+               "umull $ldst, $hdst, $a, $b",
+               []>;
+
+// Multiply + accumulate
+def SMLAL : AI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b),
+               "smlal $ldst, $hdst, $a, $b",
+               []>;
+
+def UMLAL : AI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b),
+               "umlal $ldst, $hdst, $a, $b",
+               []>;
+
+def UMAAL : AI<(ops GPR:$ldst, GPR:$hdst, GPR:$a, GPR:$b),
+               "umaal $ldst, $hdst, $a, $b",
+               []>, Requires<[IsARM, HasV6]>;
+
+// Most significant word multiply
+def SMMUL : AI_orr<"smmul", mulhs>, Requires<[IsARM, HasV6]>;
+def SMMLA : AI_oorr<"smmla", add, mulhs>, Requires<[IsARM, HasV6]>;
+
+
+def SMMLS : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$c),
+               "smmls $dst, $a, $b, $c",
+               [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
+               Requires<[IsARM, HasV6]>;
+
+multiclass AI_smul<string opc, PatFrag opnode> {
+  def BB1 : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
+               !strconcat(opc, "bb $dst, $a, $b"),
+               [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
+                                       (sext_inreg GPR:$b, i16)))]>,
+            Requires<[IsARM, HasV5TE]>;
+  def BB2 : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
+               !strconcat(opc, "bb $dst, $a, $b"),
+               [(set GPR:$dst, (opnode (sra (shl GPR:$a, 16), 16),
+                                       (sra (shl GPR:$b, 16), 16)))]>,
+            Requires<[IsARM, HasV5TE]>;
+  def BB3 : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
+               !strconcat(opc, "bb $dst, $a, $b"),
+               [(set GPR:$dst, (opnode sext_16_node:$a, sext_16_node:$b))]>,
+            Requires<[IsARM, HasV5TE]>;
+
+  def BT1 : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
+               !strconcat(opc, "bt $dst, $a, $b"),
+               [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
+                                       (sra GPR:$b, 16)))]>,
+            Requires<[IsARM, HasV5TE]>;
+  def BT2 : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
+               !strconcat(opc, "bt $dst, $a, $b"),
+               [(set GPR:$dst, (opnode (sra (shl GPR:$a, 16), 16),
+                                       (sra GPR:$b, 16)))]>,
+            Requires<[IsARM, HasV5TE]>;
+  def BT3 : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
+               !strconcat(opc, "bt $dst, $a, $b"),
+               [(set GPR:$dst, (opnode sext_16_node:$a, (sra GPR:$b, 16)))]>,
+            Requires<[IsARM, HasV5TE]>;
+
+  def TB1 : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
+               !strconcat(opc, "tb $dst, $a, $b"),
+               [(set GPR:$dst, (opnode (sra GPR:$a, 16),
+                                       (sext_inreg GPR:$b, i16)))]>,
+            Requires<[IsARM, HasV5TE]>;
+  def TB2 : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
+               !strconcat(opc, "tb $dst, $a, $b"),
+               [(set GPR:$dst, (opnode (sra GPR:$a, 16),
+                                       (sra (shl GPR:$b, 16), 16)))]>,
+            Requires<[IsARM, HasV5TE]>;
+  def TB3 : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
+               !strconcat(opc, "tb $dst, $a, $b"),
+               [(set GPR:$dst, (opnode (sra GPR:$a, 16), sext_16_node:$b))]>,
+            Requires<[IsARM, HasV5TE]>;
+
+  def TT : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
+              !strconcat(opc, "tt $dst, $a, $b"),
+              [(set GPR:$dst, (opnode (sra GPR:$a, 16),
+                                      (sra GPR:$b, 16)))]>,
+            Requires<[IsARM, HasV5TE]>;
+
+  def WB1 : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
+               !strconcat(opc, "wb $dst, $a, $b"),
+               [(set GPR:$dst, (sra (opnode GPR:$a,
+                                     (sext_inreg GPR:$b, i16)), 16))]>,
+            Requires<[IsARM, HasV5TE]>;
+  def WB2 : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
+               !strconcat(opc, "wb $dst, $a, $b"),
+               [(set GPR:$dst, (sra (opnode GPR:$a,
+                                     (sra (shl GPR:$b, 16), 16)), 16))]>,
+            Requires<[IsARM, HasV5TE]>;
+  def WB3 : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
+               !strconcat(opc, "wb $dst, $a, $b"),
+               [(set GPR:$dst, (sra (opnode GPR:$a, sext_16_node:$b), 16))]>,
+            Requires<[IsARM, HasV5TE]>;
+
+  def WT : AI<(ops GPR:$dst, GPR:$a, GPR:$b),
+              !strconcat(opc, "wt $dst, $a, $b"),
+              [(set GPR:$dst, (sra (opnode GPR:$a,
+                                    (sra GPR:$b, 16)), 16))]>,
+            Requires<[IsARM, HasV5TE]>;
 }
 
-let isTerminator = 1, isBranch = 1 in {
-  def bcond   : InstARM<(ops brtarget:$dst, CCOp:$cc),
-	                    "b$cc $dst",
-		            [(armbr bb:$dst, imm:$cc)]>;
+multiclass AI_smla<string opc, PatFrag opnode> {
+  def BB1 : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$acc),
+               !strconcat(opc, "bb $dst, $a, $b, $acc"),
+               [(set GPR:$dst, (add GPR:$acc,
+                                (opnode (sext_inreg GPR:$a, i16),
+                                        (sext_inreg GPR:$b, i16))))]>,
+            Requires<[IsARM, HasV5TE]>;
+  def BB2 : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$acc),
+               !strconcat(opc, "bb $dst, $a, $b, $acc"),
+               [(set GPR:$dst, (add GPR:$acc,
+                                (opnode (sra (shl GPR:$a, 16), 16),
+                                        (sra (shl GPR:$b, 16), 16))))]>,
+            Requires<[IsARM, HasV5TE]>;
+  def BB3 : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$acc),
+               !strconcat(opc, "bb $dst, $a, $b, $acc"),
+               [(set GPR:$dst, (add GPR:$acc,
+                                (opnode sext_16_node:$a, sext_16_node:$b)))]>,
+            Requires<[IsARM, HasV5TE]>;
 
-  def b       : InstARM<(ops brtarget:$dst),
-                        "b $dst",
-                        [(br bb:$dst)]>;
+  def BT1 : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$acc),
+               !strconcat(opc, "bt $dst, $a, $b, $acc"),
+               [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
+                                                      (sra GPR:$b, 16))))]>,
+            Requires<[IsARM, HasV5TE]>;
+  def BT2 : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$acc),
+               !strconcat(opc, "bt $dst, $a, $b, $acc"),
+              [(set GPR:$dst, (add GPR:$acc, (opnode (sra (shl GPR:$a, 16), 16),
+                                                     (sra GPR:$b, 16))))]>,
+            Requires<[IsARM, HasV5TE]>;
+  def BT3 : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$acc),
+               !strconcat(opc, "bt $dst, $a, $b, $acc"),
+               [(set GPR:$dst, (add GPR:$acc, (opnode sext_16_node:$a,
+                                                      (sra GPR:$b, 16))))]>,
+            Requires<[IsARM, HasV5TE]>;
+
+  def TB1 : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$acc),
+               !strconcat(opc, "tb $dst, $a, $b, $acc"),
+               [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, 16),
+                                                  (sext_inreg GPR:$b, i16))))]>,
+            Requires<[IsARM, HasV5TE]>;
+  def TB2 : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$acc),
+               !strconcat(opc, "tb $dst, $a, $b, $acc"),
+             [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, 16),
+                                                (sra (shl GPR:$b, 16), 16))))]>,
+            Requires<[IsARM, HasV5TE]>;
+  def TB3 : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$acc),
+               !strconcat(opc, "tb $dst, $a, $b, $acc"),
+               [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, 16),
+                                                      sext_16_node:$b)))]>,
+            Requires<[IsARM, HasV5TE]>;
+
+  def TT : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$acc),
+              !strconcat(opc, "tt $dst, $a, $b, $acc"),
+              [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, 16),
+                                                     (sra GPR:$b, 16))))]>,
+            Requires<[IsARM, HasV5TE]>;
+
+  def WB1 : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$acc),
+               !strconcat(opc, "wb $dst, $a, $b, $acc"),
+               [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
+                                             (sext_inreg GPR:$b, i16)), 16)))]>,
+            Requires<[IsARM, HasV5TE]>;
+  def WB2 : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$acc),
+               !strconcat(opc, "wb $dst, $a, $b, $acc"),
+             [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
+                                           (sra (shl GPR:$b, 16), 16)), 16)))]>,
+            Requires<[IsARM, HasV5TE]>;
+  def WB3 : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$acc),
+               !strconcat(opc, "wb $dst, $a, $b, $acc"),
+               [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
+                                              sext_16_node:$b), 16)))]>,
+            Requires<[IsARM, HasV5TE]>;
+
+  def WT : AI<(ops GPR:$dst, GPR:$a, GPR:$b, GPR:$acc),
+              !strconcat(opc, "wt $dst, $a, $b, $acc"),
+              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
+                                                   (sra GPR:$b, 16)), 16)))]>,
+            Requires<[IsARM, HasV5TE]>;
 }
 
-def cmp      : InstARM<(ops IntRegs:$a, op_addr_mode1:$b),
-	               "cmp $a, $b",
-		       [(armcmp IntRegs:$a, addr_mode1:$b)]>;
+defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
+defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
 
-// Floating Point Compare
-def fcmps   : InstARM<(ops FPRegs:$a, FPRegs:$b),
-	               "fcmps $a, $b",
-		       [(armcmp FPRegs:$a, FPRegs:$b)]>;
+// TODO: Halfword multiple accumulate long: SMLAL<x><y>
+// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
 
-def fcmpd   : InstARM<(ops DFPRegs:$a, DFPRegs:$b),
-	               "fcmpd $a, $b",
-		       [(armcmp DFPRegs:$a, DFPRegs:$b)]>;
+//===----------------------------------------------------------------------===//
+//  Misc. Arithmetic Instructions.
+//
 
-// Floating Point Copy
-def FCPYS   : InstARM<(ops FPRegs:$dst, FPRegs:$src), "fcpys $dst, $src", []>;
+def CLZ  : AI<(ops GPR:$dst, GPR:$src),
+              "clz $dst, $src",
+              [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]>;
 
-def FCPYD   : InstARM<(ops DFPRegs:$dst, DFPRegs:$src), "fcpyd $dst, $src", []>;
+def REV  : AI<(ops GPR:$dst, GPR:$src),
+              "rev $dst, $src",
+              [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]>;
 
-// Floating Point Conversion
-// We use bitconvert for moving the data between the register classes.
-// The format conversion is done with ARM specific nodes
+def REV16 : AI<(ops GPR:$dst, GPR:$src),
+               "rev16 $dst, $src",
+               [(set GPR:$dst,
+                   (or (and (srl GPR:$src, 8), 0xFF),
+                       (or (and (shl GPR:$src, 8), 0xFF00),
+                           (or (and (srl GPR:$src, 8), 0xFF0000),
+                               (and (shl GPR:$src, 8), 0xFF000000)))))]>,
+               Requires<[IsARM, HasV6]>;
 
-def FMSR    : InstARM<(ops FPRegs:$dst, IntRegs:$src),
-                       "fmsr $dst, $src", [(set FPRegs:$dst, (bitconvert IntRegs:$src))]>;
+def REVSH : AI<(ops GPR:$dst, GPR:$src),
+               "revsh $dst, $src",
+               [(set GPR:$dst,
+                  (sext_inreg
+                    (or (srl (and GPR:$src, 0xFFFF), 8),
+                        (shl GPR:$src, 8)), i16))]>,
+               Requires<[IsARM, HasV6]>;
 
-def FMRS    : InstARM<(ops IntRegs:$dst, FPRegs:$src),
-                       "fmrs $dst, $src", [(set IntRegs:$dst, (bitconvert FPRegs:$src))]>;
+def PKHBT : AI<(ops GPR:$dst, GPR:$src1, GPR:$src2, i32imm:$shamt),
+               "pkhbt $dst, $src1, $src2, LSL $shamt",
+               [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
+                                   (and (shl GPR:$src2, (i32 imm:$shamt)),
+                                        0xFFFF0000)))]>,
+               Requires<[IsARM, HasV6]>;
 
-def FMRRD   : InstARM<(ops IntRegs:$i0, IntRegs:$i1, DFPRegs:$src),
-                       "fmrrd $i0, $i1, $src", [(armfmrrd IntRegs:$i0, IntRegs:$i1, DFPRegs:$src)]>;
+// Alternate cases for PKHBT where identities eliminate some nodes.
+def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
+               (PKHBT GPR:$src1, GPR:$src2, 0)>;
+def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
+               (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
 
-def FMDRR   : InstARM<(ops DFPRegs:$dst, IntRegs:$i0, IntRegs:$i1),
-                       "fmdrr $dst, $i0, $i1", [(set DFPRegs:$dst, (armfmdrr IntRegs:$i0, IntRegs:$i1))]>;
 
-def FSITOS  : InstARM<(ops FPRegs:$dst, FPRegs:$src),
-                       "fsitos $dst, $src", [(set FPRegs:$dst, (armfsitos FPRegs:$src))]>;
+def PKHTB : AI<(ops  GPR:$dst, GPR:$src1, GPR:$src2, i32imm:$shamt),
+               "pkhtb $dst, $src1, $src2, ASR $shamt",
+               [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
+                                   (and (sra GPR:$src2, imm16_31:$shamt),
+                                        0xFFFF)))]>, Requires<[IsARM, HasV6]>;
 
-def FTOSIS  : InstARM<(ops FPRegs:$dst, FPRegs:$src),
-                       "ftosis $dst, $src", [(set FPRegs:$dst, (armftosis FPRegs:$src))]>;
+// Alternate cases for PKHTB where identities eliminate some nodes.  Note that
+// a shift amount of 0 is *not legal* here, it is PKHBT instead.
+def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, 16)),
+               (PKHTB GPR:$src1, GPR:$src2, 16)>;
+def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
+                   (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
+               (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
 
-def FSITOD  : InstARM<(ops DFPRegs:$dst, FPRegs:$src),
-                       "fsitod $dst, $src", [(set DFPRegs:$dst, (armfsitod FPRegs:$src))]>;
 
-def FTOSID  : InstARM<(ops FPRegs:$dst, DFPRegs:$src),
-                       "ftosid $dst, $src", [(set FPRegs:$dst, (armftosid DFPRegs:$src))]>;
+//===----------------------------------------------------------------------===//
+//  Comparison Instructions...
+//
 
-def FUITOS  : InstARM<(ops FPRegs:$dst, FPRegs:$src),
-                       "fuitos $dst, $src", [(set FPRegs:$dst, (armfuitos FPRegs:$src))]>;
+defm CMP  : AI1_bin0_irs<"cmp", BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
+defm CMN  : AI1_bin0_irs<"cmn", BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
 
-def FTOUIS  : InstARM<(ops FPRegs:$dst, FPRegs:$src),
-                       "ftouis $dst, $src", [(set FPRegs:$dst, (armftouis FPRegs:$src))]>;
+def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
+             (CMNri  GPR:$src, so_imm_neg:$imm)>;
 
-def FUITOD  : InstARM<(ops DFPRegs:$dst, FPRegs:$src),
-                       "fuitod $dst, $src", [(set DFPRegs:$dst, (armfuitod FPRegs:$src))]>;
+// Note that TST/TEQ don't set all the same flags that CMP does!
+def TSTrr : AI1<(ops GPR:$a, so_reg:$b), "tst $a, $b", []>;
+def TSTri : AI1<(ops GPR:$a, so_imm:$b), "tst $a, $b", []>;
+def TEQrr : AI1<(ops GPR:$a, so_reg:$b), "teq $a, $b", []>;
+def TEQri : AI1<(ops GPR:$a, so_imm:$b), "teq $a, $b", []>;
 
-def FTOUID  : InstARM<(ops FPRegs:$dst, DFPRegs:$src),
-                       "ftouid $dst, $src", [(set FPRegs:$dst, (armftouid DFPRegs:$src))]>;
+// Conditional moves
+def MOVCCr : AI<(ops GPR:$dst, GPR:$false, GPR:$true, CCOp:$cc),
+                "mov$cc $dst, $true",
+                [(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc))]>,
+                RegConstraint<"$false = $dst">;
 
-def FCVTDS  : InstARM<(ops DFPRegs:$dst, FPRegs:$src),
-                       "fcvtds $dst, $src", [(set DFPRegs:$dst, (fextend FPRegs:$src))]>;
+def MOVCCs : AI<(ops GPR:$dst, GPR:$false, so_reg:$true, CCOp:$cc),
+                "mov$cc $dst, $true",
+                [(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true,imm:$cc))]>,
+                RegConstraint<"$false = $dst">;
 
-def FCVTSD  : InstARM<(ops FPRegs:$dst, DFPRegs:$src),
-                       "fcvtsd $dst, $src", [(set FPRegs:$dst, (fround DFPRegs:$src))]>;
+def MOVCCi : AI<(ops GPR:$dst, GPR:$false, so_imm:$true, CCOp:$cc),
+                "mov$cc $dst, $true",
+                [(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true,imm:$cc))]>,
+                RegConstraint<"$false = $dst">;
 
-def FMSTAT  : InstARM<(ops ), "fmstat", [(armfmstat)]>;
 
-// Floating Point Arithmetic
-def FADDS   : FPBinOp<"fadds",  fadd>;
-def FADDD   : DFPBinOp<"faddd", fadd>;
-def FSUBS   : FPBinOp<"fsubs",  fsub>;
-def FSUBD   : DFPBinOp<"fsubd", fsub>;
+// LEApcrel - Load a pc-relative address into a register without offending the
+// assembler.
+def LEApcrel : AI1<(ops GPR:$dst, i32imm:$label),
+                   !strconcat(!strconcat(".set PCRELV${:uid}, ($label-(",
+                                         "${:private}PCRELL${:uid}+8))\n"),
+                              !strconcat("${:private}PCRELL${:uid}:\n\t",
+                                         "add $dst, pc, #PCRELV${:uid}")),
+                   []>;
 
-def FNEGS   : FPUnaryOp<"fnegs",  fneg>;
-def FNEGD   : DFPUnaryOp<"fnegd", fneg>;
-def FABSS   : FPUnaryOp<"fabss",  fabs>;
-def FABSD   : DFPUnaryOp<"fabsd", fabs>;
+def LEApcrelJT : AI1<(ops GPR:$dst, i32imm:$label, i32imm:$id),
+          !strconcat(!strconcat(".set PCRELV${:uid}, (${label}_${id:no_hash}-(",
+                                         "${:private}PCRELL${:uid}+8))\n"),
+                              !strconcat("${:private}PCRELL${:uid}:\n\t",
+                                         "add $dst, pc, #PCRELV${:uid}")),
+                   []>;
 
-def FMULS   : FPBinOp<"fmuls", fmul>;
-def FMULD   : DFPBinOp<"fmuld", fmul>;
-def FDIVS   : FPBinOp<"fdivs", fdiv>;
-def FDIVD   : DFPBinOp<"fdivd", fdiv>;
+//===----------------------------------------------------------------------===//
+// Non-Instruction Patterns
+//
 
-// Floating Point Load
-def FLDS  : InstARM<(ops FPRegs:$dst, op_addr_mode5:$addr),
-                     "flds $dst, $addr",
-                     [(set FPRegs:$dst, (load addr_mode5:$addr))]>;
+// ConstantPool, GlobalAddress, and JumpTable
+def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>;
+def : ARMPat<(ARMWrapper  tconstpool  :$dst), (LEApcrel tconstpool  :$dst)>;
+def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
+          (LEApcrelJT tjumptable:$dst, imm:$id)>;
 
-def FLDD  : InstARM<(ops DFPRegs:$dst, op_addr_mode5:$addr),
-                     "fldd $dst, $addr",
-                     [(set DFPRegs:$dst, (load addr_mode5:$addr))]>;
+// Large immediate handling.
 
-// Floating Point Store
-def FSTS    : InstARM<(ops FPRegs:$src, op_addr_mode5:$addr),
-                       "fsts $src, $addr",
-                       [(store FPRegs:$src, addr_mode5:$addr)]>;
+// Two piece so_imms.
+def : ARMPat<(i32 so_imm2part:$src),
+             (ORRri (MOVri (so_imm2part_1 imm:$src)),
+                    (so_imm2part_2 imm:$src))>;
 
-def FSTD    : InstARM<(ops DFPRegs:$src, op_addr_mode5:$addr),
-                       "fstd $src, $addr",
-                       [(store DFPRegs:$src, addr_mode5:$addr)]>;
+def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS),
+              (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
+                     (so_imm2part_2 imm:$RHS))>;
+def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS),
+              (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)),
+                     (so_imm2part_2 imm:$RHS))>;
 
-def : Pat<(ARMcall tglobaladdr:$dst),
-          (bl tglobaladdr:$dst)>;
+// TODO: add,sub,and, 3-instr forms?
 
-def : Pat<(ARMcall texternalsym:$dst),
-          (bl texternalsym:$dst)>;
 
-def : Pat<(extloadi8 IntRegs:$addr),
-          (LDRB IntRegs:$addr)>;
-def : Pat<(extloadi16 IntRegs:$addr),
-          (LDRH IntRegs:$addr)>;
+// Direct calls
+def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>;
 
-// extload bool -> extload byte
-def : Pat<(extloadi1 IntRegs:$addr), (LDRB IntRegs:$addr)>;
+// zextload i1 -> zextload i8
+def : ARMPat<(zextloadi1 addrmode2:$addr),  (LDRB addrmode2:$addr)>;
 
-// zextload bool -> zextload byte
-def : Pat<(i32 (zextloadi1 IntRegs:$addr)), (LDRB IntRegs:$addr)>;
+// extload -> zextload
+def : ARMPat<(extloadi1  addrmode2:$addr),  (LDRB addrmode2:$addr)>;
+def : ARMPat<(extloadi8  addrmode2:$addr),  (LDRB addrmode2:$addr)>;
+def : ARMPat<(extloadi16 addrmode3:$addr),  (LDRH addrmode3:$addr)>;
 
-// truncstore bool -> truncstore byte.
-def : Pat<(truncstorei1 IntRegs:$src, IntRegs:$addr),
-          (STRB IntRegs:$src, IntRegs:$addr)>;
+// truncstore i1 -> truncstore i8
+def : Pat<(truncstorei1 GPR:$src, addrmode2:$dst), 
+          (STRB GPR:$src, addrmode2:$dst)>;
+def : Pat<(pre_truncsti1 GPR:$src, GPR:$base, am2offset:$offset), 
+          (STRB_PRE GPR:$src, GPR:$base, am2offset:$offset)>;
+def : Pat<(post_truncsti1 GPR:$src, GPR:$base, am2offset:$offset), 
+          (STRB_POST GPR:$src, GPR:$base, am2offset:$offset)>;
+
+//===----------------------------------------------------------------------===//
+// Thumb Support
+//
+
+include "ARMInstrThumb.td"
+
+//===----------------------------------------------------------------------===//
+// Floating Point Support
+//
+
+include "ARMInstrVFP.td"
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td
new file mode 100644
index 0000000..58cef04
--- /dev/null
+++ b/llvm/lib/Target/ARM/ARMInstrThumb.td
@@ -0,0 +1,513 @@
+//===- ARMInstrThumb.td - Thumb support for ARM ---------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the Thumb instruction set.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Thumb specific DAG Nodes.
+//
+
+def ARMtcall : SDNode<"ARMISD::tCALL", SDT_ARMcall,
+                      [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
+
+// TI - Thumb instruction.
+
+// ThumbPat - Same as Pat<>, but requires that the compiler be in Thumb mode.
+class ThumbPat<dag pattern, dag result> : Pat<pattern, result> {
+  list<Predicate> Predicates = [IsThumb];
+}
+
+class ThumbV5Pat<dag pattern, dag result> : Pat<pattern, result> {
+  list<Predicate> Predicates = [IsThumb, HasV5T];
+}
+
+class ThumbI<dag ops, AddrMode am, SizeFlagVal sz,
+             string asm, string cstr, list<dag> pattern>
+  // FIXME: Set all opcodes to 0 for now.
+  : InstARM<0, am, sz, IndexModeNone, ops, asm, cstr> {
+  let Pattern = pattern;
+  list<Predicate> Predicates = [IsThumb];
+}
+
+class TI<dag ops, string asm, list<dag> pattern>
+  : ThumbI<ops, AddrModeNone, Size2Bytes, asm, "", pattern>;
+class TI1<dag ops, string asm, list<dag> pattern>
+  : ThumbI<ops, AddrModeT1, Size2Bytes, asm, "", pattern>;
+class TI2<dag ops, string asm, list<dag> pattern>
+  : ThumbI<ops, AddrModeT2, Size2Bytes, asm, "", pattern>;
+class TI4<dag ops, string asm, list<dag> pattern>
+  : ThumbI<ops, AddrModeT4, Size2Bytes, asm, "", pattern>;
+class TIs<dag ops, string asm, list<dag> pattern>
+  : ThumbI<ops, AddrModeTs, Size2Bytes, asm, "", pattern>;
+
+// Two-address instructions
+class TIt<dag ops, string asm, list<dag> pattern>
+  : ThumbI<ops, AddrModeNone, Size2Bytes, asm, "$lhs = $dst", pattern>;
+
+// BL, BLX(1) are translated by assembler into two instructions
+class TIx2<dag ops, string asm, list<dag> pattern>
+  : ThumbI<ops, AddrModeNone, Size4Bytes, asm, "", pattern>;
+
+def imm_neg_XFORM : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant(-(int)N->getValue(), MVT::i32);
+}]>;
+def imm_comp_XFORM : SDNodeXForm<imm, [{
+  return CurDAG->getTargetConstant(~((uint32_t)N->getValue()), MVT::i32);
+}]>;
+
+
+/// imm0_7 predicate - True if the 32-bit immediate is in the range [0,7].
+def imm0_7 : PatLeaf<(i32 imm), [{
+  return (uint32_t)N->getValue() < 8;
+}]>;
+def imm0_7_neg : PatLeaf<(i32 imm), [{
+  return (uint32_t)-N->getValue() < 8;
+}], imm_neg_XFORM>;
+
+def imm0_255 : PatLeaf<(i32 imm), [{
+  return (uint32_t)N->getValue() < 256;
+}]>;
+def imm0_255_comp : PatLeaf<(i32 imm), [{
+  return ~((uint32_t)N->getValue()) < 256;
+}]>;
+
+def imm8_255 : PatLeaf<(i32 imm), [{
+  return (uint32_t)N->getValue() >= 8 && (uint32_t)N->getValue() < 256;
+}]>;
+def imm8_255_neg : PatLeaf<(i32 imm), [{
+  unsigned Val = -N->getValue();
+  return Val >= 8 && Val < 256;
+}], imm_neg_XFORM>;
+
+// Break imm's up into two pieces: an immediate + a left shift.
+// This uses thumb_immshifted to match and thumb_immshifted_val and
+// thumb_immshifted_shamt to get the val/shift pieces.
+def thumb_immshifted : PatLeaf<(imm), [{
+  return ARM_AM::isThumbImmShiftedVal((unsigned)N->getValue());
+}]>;
+
+def thumb_immshifted_val : SDNodeXForm<imm, [{
+  unsigned V = ARM_AM::getThumbImmNonShiftedVal((unsigned)N->getValue());
+  return CurDAG->getTargetConstant(V, MVT::i32);
+}]>;
+
+def thumb_immshifted_shamt : SDNodeXForm<imm, [{
+  unsigned V = ARM_AM::getThumbImmValShift((unsigned)N->getValue());
+  return CurDAG->getTargetConstant(V, MVT::i32);
+}]>;
+
+// Define Thumb specific addressing modes.
+
+// t_addrmode_rr := reg + reg
+//
+def t_addrmode_rr : Operand<i32>,
+                    ComplexPattern<i32, 2, "SelectThumbAddrModeRR", []> {
+  let PrintMethod = "printThumbAddrModeRROperand";
+  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg);
+}
+
+// t_addrmode_ri5_{1|2|4} := reg + imm5 * {1|2|4}
+//
+def t_addrmode_ri5_1 : Operand<i32>,
+                       ComplexPattern<i32, 2, "SelectThumbAddrModeRI5_1", []> {
+  let PrintMethod = "printThumbAddrModeRI5_1Operand";
+  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
+}
+def t_addrmode_ri5_2 : Operand<i32>,
+                       ComplexPattern<i32, 2, "SelectThumbAddrModeRI5_2", []> {
+  let PrintMethod = "printThumbAddrModeRI5_2Operand";
+  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
+}
+def t_addrmode_ri5_4 : Operand<i32>,
+                       ComplexPattern<i32, 2, "SelectThumbAddrModeRI5_4", []> {
+  let PrintMethod = "printThumbAddrModeRI5_4Operand";
+  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
+}
+
+// t_addrmode_sp := sp + imm8 * 4
+//
+def t_addrmode_sp : Operand<i32>,
+                    ComplexPattern<i32, 2, "SelectThumbAddrModeSP", []> {
+  let PrintMethod = "printThumbAddrModeSPOperand";
+  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
+}
+
+//===----------------------------------------------------------------------===//
+//  Miscellaneous Instructions.
+//
+
+def tPICADD : TIt<(ops GPR:$dst, GPR:$lhs, pclabel:$cp),
+                  "\n$cp:\n\tadd $dst, pc",
+                  [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>;
+
+//===----------------------------------------------------------------------===//
+//  Control Flow Instructions.
+//
+
+let isReturn = 1, isTerminator = 1 in
+  def tBX_RET : TI<(ops), "bx lr", [(ARMretflag)]>;
+
+// FIXME: remove when we have a way to marking a MI with these properties.
+let isLoad = 1, isReturn = 1, isTerminator = 1 in
+def tPOP_RET : TI<(ops reglist:$dst1, variable_ops),
+                   "pop $dst1", []>;
+
+let isCall = 1, noResults = 1, 
+  Defs = [R0, R1, R2, R3, LR,
+          D0, D1, D2, D3, D4, D5, D6, D7] in {
+  def tBL  : TIx2<(ops i32imm:$func, variable_ops),
+                   "bl ${func:call}",
+                   [(ARMtcall tglobaladdr:$func)]>;
+  // ARMv5T and above
+  def tBLXi : TIx2<(ops i32imm:$func, variable_ops),
+                    "blx ${func:call}",
+                    [(ARMcall tglobaladdr:$func)]>, Requires<[HasV5T]>;
+  def tBLXr : TI<(ops GPR:$dst, variable_ops),
+                  "blx $dst",
+                  [(ARMtcall GPR:$dst)]>, Requires<[HasV5T]>;
+  // ARMv4T
+  def tBX : TIx2<(ops GPR:$dst, variable_ops),
+                  "cpy lr, pc\n\tbx $dst",
+                  [(ARMcall_nolink GPR:$dst)]>;
+}
+
+let isBranch = 1, isTerminator = 1, isBarrier = 1 in
+  def tB   : TI<(ops brtarget:$dst), "b $dst", [(br bb:$dst)]>;
+
+let isBranch = 1, isTerminator = 1, noResults = 1, isBarrier = 1 in
+  def tBcc : TI<(ops brtarget:$dst, CCOp:$cc), "b$cc $dst",
+                 [(ARMbrcond bb:$dst, imm:$cc)]>;
+
+//===----------------------------------------------------------------------===//
+//  Load Store Instructions.
+//
+
+let isLoad = 1 in {
+def tLDRri : TI4<(ops GPR:$dst, t_addrmode_ri5_4:$addr),
+                 "ldr $dst, $addr",
+                 [(set GPR:$dst, (load t_addrmode_ri5_4:$addr))]>;
+
+def tLDRrr : TI<(ops GPR:$dst, t_addrmode_rr:$addr),
+                "ldr $dst, $addr",
+                [(set GPR:$dst, (load t_addrmode_rr:$addr))]>;
+// def tLDRpci
+def tLDRspi : TIs<(ops GPR:$dst, t_addrmode_sp:$addr),
+                  "ldr $dst, $addr",
+                  [(set GPR:$dst, (load t_addrmode_sp:$addr))]>;
+
+def tLDRBri : TI1<(ops GPR:$dst, t_addrmode_ri5_1:$addr),
+                  "ldrb $dst, $addr",
+                  [(set GPR:$dst, (zextloadi8 t_addrmode_ri5_1:$addr))]>;
+
+def tLDRBrr : TI1<(ops GPR:$dst, t_addrmode_rr:$addr),
+                  "ldrb $dst, $addr",
+                  [(set GPR:$dst, (zextloadi8 t_addrmode_rr:$addr))]>;
+
+def tLDRHri : TI2<(ops GPR:$dst, t_addrmode_ri5_2:$addr),
+                  "ldrh $dst, $addr",
+                  [(set GPR:$dst, (zextloadi16 t_addrmode_ri5_2:$addr))]>;
+
+def tLDRHrr : TI2<(ops GPR:$dst, t_addrmode_rr:$addr),
+                  "ldrh $dst, $addr",
+                  [(set GPR:$dst, (zextloadi16 t_addrmode_rr:$addr))]>;
+
+def tLDRSBrr : TI1<(ops GPR:$dst, t_addrmode_rr:$addr),
+                   "ldrsb $dst, $addr",
+                   [(set GPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>;
+
+def tLDRSHrr : TI2<(ops GPR:$dst, t_addrmode_rr:$addr),
+                   "ldrsh $dst, $addr",
+                   [(set GPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>;
+} // isLoad
+
+let isStore = 1 in {
+def tSTRri : TI4<(ops GPR:$src, t_addrmode_ri5_4:$addr),
+                 "str $src, $addr",
+                 [(store GPR:$src, t_addrmode_ri5_4:$addr)]>;
+
+def tSTRrr : TI<(ops GPR:$src, t_addrmode_rr:$addr),
+                 "str $src, $addr",
+                 [(store GPR:$src, t_addrmode_rr:$addr)]>;
+
+def tSTRspi : TIs<(ops GPR:$src, t_addrmode_sp:$addr),
+                   "str $src, $addr",
+                   [(store GPR:$src, t_addrmode_sp:$addr)]>;
+
+def tSTRBri : TI1<(ops GPR:$src, t_addrmode_ri5_1:$addr),
+                   "strb $src, $addr",
+                   [(truncstorei8 GPR:$src, t_addrmode_ri5_1:$addr)]>;
+
+def tSTRBrr : TI1<(ops GPR:$src, t_addrmode_rr:$addr),
+                   "strb $src, $addr",
+                   [(truncstorei8 GPR:$src, t_addrmode_rr:$addr)]>;
+
+def tSTRHri : TI2<(ops GPR:$src, t_addrmode_ri5_2:$addr),
+                   "strh $src, $addr",
+                   [(truncstorei16 GPR:$src, t_addrmode_ri5_1:$addr)]>;
+
+def tSTRHrr : TI2<(ops GPR:$src, t_addrmode_rr:$addr),
+                   "strh $src, $addr",
+                   [(truncstorei16 GPR:$src, t_addrmode_rr:$addr)]>;
+}
+
+//===----------------------------------------------------------------------===//
+//  Load / store multiple Instructions.
+//
+
+// TODO: A7-44: LDMIA - load multiple
+
+let isLoad = 1 in
+def tPOP : TI<(ops reglist:$dst1, variable_ops),
+               "pop $dst1", []>;
+
+let isStore = 1 in
+def tPUSH : TI<(ops reglist:$src1, variable_ops),
+                "push $src1", []>;
+
+//===----------------------------------------------------------------------===//
+//  Arithmetic Instructions.
+//
+
+def tADDi3 : TI<(ops GPR:$dst, GPR:$lhs, i32imm:$rhs),
+                "add $dst, $lhs, $rhs",
+                [(set GPR:$dst, (add GPR:$lhs, imm0_7:$rhs))]>;
+
+def tADDi8 : TIt<(ops GPR:$dst, GPR:$lhs, i32imm:$rhs),
+                 "add $dst, $rhs",
+                 [(set GPR:$dst, (add GPR:$lhs, imm8_255:$rhs))]>;
+
+def tADDrr : TI<(ops GPR:$dst, GPR:$lhs, GPR:$rhs),
+                "add $dst, $lhs, $rhs",
+                [(set GPR:$dst, (add GPR:$lhs, GPR:$rhs))]>;
+
+def tADDhirr : TIt<(ops GPR:$dst, GPR:$lhs, GPR:$rhs),
+                   "add $dst, $rhs", []>;
+
+def tADDrPCi : TI<(ops GPR:$dst, i32imm:$rhs),
+                  "add $dst, pc, $rhs * 4", []>;
+def tADDrSPi : TI<(ops GPR:$dst, GPR:$sp, i32imm:$rhs),
+                  "add $dst, $sp, $rhs * 4", []>;
+def tADDspi : TI<(ops GPR:$sp, i32imm:$rhs),
+                 "add $sp, $rhs * 4", []>;
+
+
+def tAND : TIt<(ops GPR:$dst, GPR:$lhs, GPR:$rhs),
+                "and $dst, $rhs",
+                [(set GPR:$dst, (and GPR:$lhs, GPR:$rhs))]>;
+
+def tASRri : TI<(ops GPR:$dst, GPR:$lhs, i32imm:$rhs),
+                "asr $dst, $lhs, $rhs",
+                [(set GPR:$dst, (sra GPR:$lhs, imm:$rhs))]>;
+
+def tASRrr : TIt<(ops GPR:$dst, GPR:$lhs, GPR:$rhs),
+                 "asr $dst, $rhs",
+                 [(set GPR:$dst, (sra GPR:$lhs, GPR:$rhs))]>;
+
+def tBIC : TIt<(ops GPR:$dst, GPR:$lhs, GPR:$rhs),
+               "bic $dst, $rhs",
+               [(set GPR:$dst, (and GPR:$lhs, (not GPR:$rhs)))]>;
+
+
+def tCMN : TI<(ops GPR:$lhs, GPR:$rhs),
+              "cmn $lhs, $rhs",
+              [(ARMcmp GPR:$lhs, (ineg GPR:$rhs))]>;
+
+def tCMPi8 : TI<(ops GPR:$lhs, i32imm:$rhs),
+               "cmp $lhs, $rhs",
+               [(ARMcmp GPR:$lhs, imm0_255:$rhs)]>;
+
+def tCMPr : TI<(ops GPR:$lhs, GPR:$rhs),
+               "cmp $lhs, $rhs",
+               [(ARMcmp GPR:$lhs, GPR:$rhs)]>;
+               
+// TODO: A7-37: CMP(3) - cmp hi regs
+
+def tEOR : TIt<(ops GPR:$dst, GPR:$lhs, GPR:$rhs),
+               "eor $dst, $rhs",
+               [(set GPR:$dst, (xor GPR:$lhs, GPR:$rhs))]>;
+
+def tLSLri : TI<(ops GPR:$dst, GPR:$lhs, i32imm:$rhs),
+                "lsl $dst, $lhs, $rhs",
+                [(set GPR:$dst, (shl GPR:$lhs, imm:$rhs))]>;
+
+def tLSLrr : TIt<(ops GPR:$dst, GPR:$lhs, GPR:$rhs),
+                 "lsl $dst, $rhs",
+                 [(set GPR:$dst, (shl GPR:$lhs, GPR:$rhs))]>;
+
+def tLSRri : TI<(ops GPR:$dst, GPR:$lhs, i32imm:$rhs),
+                "lsr $dst, $lhs, $rhs",
+                [(set GPR:$dst, (srl GPR:$lhs, imm:$rhs))]>;
+
+def tLSRrr : TIt<(ops GPR:$dst, GPR:$lhs, GPR:$rhs),
+                 "lsr $dst, $rhs",
+                 [(set GPR:$dst, (srl GPR:$lhs, GPR:$rhs))]>;
+
+def tMOVri8 : TI<(ops GPR:$dst, i32imm:$src),
+                 "mov $dst, $src",
+                 [(set GPR:$dst, imm0_255:$src)]>;
+
+// TODO: A7-73: MOV(2) - mov setting flag.
+
+
+// Note: MOV(2) of two low regs updates the flags, so we emit this as 'cpy',
+// which is MOV(3).  This also supports high registers.
+def tMOVrr  : TI<(ops GPR:$dst, GPR:$src),
+                 "cpy $dst, $src", []>;
+
+def tMUL : TIt<(ops GPR:$dst, GPR:$lhs, GPR:$rhs),
+               "mul $dst, $rhs",
+               [(set GPR:$dst, (mul GPR:$lhs, GPR:$rhs))]>;
+
+def tMVN : TI<(ops GPR:$dst, GPR:$src),
+              "mvn $dst, $src",
+              [(set GPR:$dst, (not GPR:$src))]>;
+
+def tNEG : TI<(ops GPR:$dst, GPR:$src),
+              "neg $dst, $src",
+              [(set GPR:$dst, (ineg GPR:$src))]>;
+
+def tORR : TIt<(ops GPR:$dst, GPR:$lhs, GPR:$rhs),
+               "orr $dst, $rhs",
+               [(set GPR:$dst, (or GPR:$lhs, GPR:$rhs))]>;
+
+
+def tREV : TI<(ops GPR:$dst, GPR:$src),
+              "rev $dst, $src",
+              [(set GPR:$dst, (bswap GPR:$src))]>, 
+              Requires<[IsThumb, HasV6]>;
+
+def tREV16 : TI<(ops GPR:$dst, GPR:$src),
+                "rev16 $dst, $src",
+                [(set GPR:$dst,
+                    (or (and (srl GPR:$src, 8), 0xFF),
+                        (or (and (shl GPR:$src, 8), 0xFF00),
+                            (or (and (srl GPR:$src, 8), 0xFF0000),
+                                (and (shl GPR:$src, 8), 0xFF000000)))))]>,
+                Requires<[IsThumb, HasV6]>;
+
+def tREVSH : TI<(ops GPR:$dst, GPR:$src),
+                "revsh $dst, $src",
+                [(set GPR:$dst,
+                   (sext_inreg
+                     (or (srl (and GPR:$src, 0xFFFF), 8),
+                         (shl GPR:$src, 8)), i16))]>,
+                Requires<[IsThumb, HasV6]>;
+
+def tROR : TIt<(ops GPR:$dst, GPR:$lhs, GPR:$rhs),
+                "ror $dst, $rhs",
+                [(set GPR:$dst, (rotr GPR:$lhs, GPR:$rhs))]>;
+
+def tSBC : TIt<(ops GPR:$dst, GPR:$lhs, GPR:$rhs),
+                "sbc $dst, $rhs",
+                [(set GPR:$dst, (sube GPR:$lhs, GPR:$rhs))]>;
+
+// TODO: A7-96: STMIA - store multiple.
+
+def tSUBi3 : TI<(ops GPR:$dst, GPR:$lhs, i32imm:$rhs),
+                "sub $dst, $lhs, $rhs",
+                [(set GPR:$dst, (add GPR:$lhs, imm0_7_neg:$rhs))]>;
+                
+def tSUBi8 : TIt<(ops GPR:$dst, GPR:$lhs, i32imm:$rhs),
+                  "sub $dst, $rhs",
+                  [(set GPR:$dst, (add GPR:$lhs, imm8_255_neg:$rhs))]>;
+                
+def tSUBrr : TI<(ops GPR:$dst, GPR:$lhs, GPR:$rhs),
+                "sub $dst, $lhs, $rhs",
+                [(set GPR:$dst, (sub GPR:$lhs, GPR:$rhs))]>;
+
+def tSUBspi : TI<(ops GPR:$sp, i32imm:$rhs),
+                 "sub $sp, $rhs * 4", []>;
+
+def tSXTB  : TI<(ops GPR:$dst, GPR:$src),
+                "sxtb $dst, $src",
+                [(set GPR:$dst, (sext_inreg GPR:$src, i8))]>,
+                Requires<[IsThumb, HasV6]>;
+def tSXTH  : TI<(ops GPR:$dst, GPR:$src),
+                "sxth $dst, $src",
+                [(set GPR:$dst, (sext_inreg GPR:$src, i16))]>,
+                Requires<[IsThumb, HasV6]>;
+
+// TODO: A7-122: TST - test.
+
+def tUXTB  : TI<(ops GPR:$dst, GPR:$src),
+                "uxtb $dst, $src",
+                [(set GPR:$dst, (and GPR:$src, 0xFF))]>,
+                Requires<[IsThumb, HasV6]>;
+def tUXTH  : TI<(ops GPR:$dst, GPR:$src),
+                "uxth $dst, $src",
+                [(set GPR:$dst, (and GPR:$src, 0xFFFF))]>, 
+                Requires<[IsThumb, HasV6]>;
+
+
+// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC DAG operation.
+// Expanded by the scheduler into a branch sequence.
+let usesCustomDAGSchedInserter = 1 in  // Expanded by the scheduler.
+  def tMOVCCr :
+  PseudoInst<(ops GPR:$dst, GPR:$false, GPR:$true, CCOp:$cc),
+              "@ tMOVCCr $cc",
+              [(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc))]>;
+
+// tLEApcrel - Load a pc-relative address into a register without offending the
+// assembler.
+def tLEApcrel : TI<(ops GPR:$dst, i32imm:$label),
+                    !strconcat(!strconcat(".set PCRELV${:uid}, ($label-(",
+                                          "${:private}PCRELL${:uid}+4))\n"),
+                               !strconcat("${:private}PCRELL${:uid}:\n\t",
+                                          "add $dst, pc, #PCRELV${:uid}")),
+                    []>;
+
+def tLEApcrelCall : TI<(ops GPR:$dst, i32imm:$label),
+                   !strconcat(!strconcat(".set PCRELV${:uid}, (${label:call}-(",
+                                         "${:private}PCRELL${:uid}+4))\n"),
+                              !strconcat("${:private}PCRELL${:uid}:\n\t",
+                                         "add $dst, pc, #PCRELV${:uid}")),
+                   []>;
+
+//===----------------------------------------------------------------------===//
+// Non-Instruction Patterns
+//
+
+// ConstantPool, GlobalAddress
+def : ThumbPat<(ARMWrapper  tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>;
+def : ThumbPat<(ARMWrapper  tconstpool  :$dst), (tLEApcrel tconstpool  :$dst)>;
+def : ThumbPat<(ARMWrapperCall tglobaladdr :$dst),
+               (tLEApcrelCall  tglobaladdr :$dst)>;
+def : ThumbPat<(ARMWrapperCall texternalsym:$dst),
+               (tLEApcrelCall  texternalsym:$dst)>;
+
+// Direct calls
+def : ThumbPat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>;
+def : ThumbV5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>;
+
+// Indirect calls to ARM routines
+def : ThumbV5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>;
+
+// zextload i1 -> zextload i8
+def : ThumbPat<(zextloadi1 t_addrmode_ri5_1:$addr),
+               (tLDRBri t_addrmode_ri5_1:$addr)>;
+def : ThumbPat<(zextloadi1 t_addrmode_rr:$addr),
+               (tLDRBri t_addrmode_rr:$addr)>;
+                  
+// truncstore i1 -> truncstore i8
+def : ThumbPat<(truncstorei1 GPR:$src, t_addrmode_ri5_1:$dst), 
+               (tSTRBri GPR:$src, t_addrmode_ri5_1:$dst)>;
+def : ThumbPat<(truncstorei1 GPR:$src, t_addrmode_rr:$dst), 
+               (tSTRBrr GPR:$src, t_addrmode_rr:$dst)>;
+
+// Large immediate handling.
+
+// Two piece imms.
+def : ThumbPat<(i32 thumb_immshifted:$src),
+               (tLSLri (tMOVri8 (thumb_immshifted_val imm:$src)),
+                       (thumb_immshifted_shamt imm:$src))>;
+
+def : ThumbPat<(i32 imm0_255_comp:$src),
+               (tMVN (tMOVri8 (imm_comp_XFORM imm:$src)))>;
diff --git a/llvm/lib/Target/ARM/ARMInstrVFP.td b/llvm/lib/Target/ARM/ARMInstrVFP.td
new file mode 100644
index 0000000..cac8e44
--- /dev/null
+++ b/llvm/lib/Target/ARM/ARMInstrVFP.td
@@ -0,0 +1,359 @@
+//===- ARMInstrVFP.td - VFP support for ARM -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the ARM VP instruction set.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// ARM VFP Instruction templates.
+//
+
+// ARM Float Instruction
+class ASI<dag ops, string asm, list<dag> pattern> : AI<ops, asm, pattern> {
+  // TODO: Mark the instructions with the appropriate subtarget info.
+}
+
+class ASI5<dag ops, string asm, list<dag> pattern>
+  : I<ops, AddrMode5, Size4Bytes, IndexModeNone, asm, "", pattern> {
+  // TODO: Mark the instructions with the appropriate subtarget info.
+}
+
+// ARM Double Instruction
+class ADI<dag ops, string asm, list<dag> pattern> : AI<ops, asm, pattern> {
+  // TODO: Mark the instructions with the appropriate subtarget info.
+}
+
+class ADI5<dag ops, string asm, list<dag> pattern>
+  : I<ops, AddrMode5, Size4Bytes, IndexModeNone, asm, "", pattern> {
+  // TODO: Mark the instructions with the appropriate subtarget info.
+}
+
+def SDT_FTOI :
+SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>;
+def SDT_ITOF :
+SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>;
+def SDT_CMPFP0 :
+SDTypeProfile<0, 1, [SDTCisFP<0>]>;
+def SDT_FMDRR :
+SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>,
+                     SDTCisSameAs<1, 2>]>;
+
+def arm_ftoui  : SDNode<"ARMISD::FTOUI", SDT_FTOI>;
+def arm_ftosi  : SDNode<"ARMISD::FTOSI", SDT_FTOI>;
+def arm_sitof  : SDNode<"ARMISD::SITOF", SDT_ITOF>;
+def arm_uitof  : SDNode<"ARMISD::UITOF", SDT_ITOF>;
+def arm_fmstat : SDNode<"ARMISD::FMSTAT", SDTRet, [SDNPInFlag,SDNPOutFlag]>;
+def arm_cmpfp  : SDNode<"ARMISD::CMPFP", SDT_ARMCmp, [SDNPOutFlag]>;
+def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0", SDT_CMPFP0, [SDNPOutFlag]>;
+def arm_fmdrr  : SDNode<"ARMISD::FMDRR", SDT_FMDRR>;
+
+//===----------------------------------------------------------------------===//
+//  Load / store Instructions.
+//
+
+let isLoad = 1 in {
+def FLDD  : ADI5<(ops DPR:$dst, addrmode5:$addr),
+                 "fldd $dst, $addr",
+                 [(set DPR:$dst, (load addrmode5:$addr))]>;
+
+def FLDS  : ASI5<(ops SPR:$dst, addrmode5:$addr),
+                 "flds $dst, $addr",
+                 [(set SPR:$dst, (load addrmode5:$addr))]>;
+} // isLoad
+
+let isStore = 1 in {
+def FSTD  : ADI5<(ops DPR:$src, addrmode5:$addr),
+                 "fstd $src, $addr",
+                 [(store DPR:$src, addrmode5:$addr)]>;
+
+def FSTS  : ASI5<(ops SPR:$src, addrmode5:$addr),
+                 "fsts $src, $addr",
+                 [(store SPR:$src, addrmode5:$addr)]>;
+} // isStore
+
+//===----------------------------------------------------------------------===//
+//  Load / store multiple Instructions.
+//
+
+let isLoad = 1 in {
+def FLDMD : ADI5<(ops addrmode5:$addr, reglist:$dst1, variable_ops),
+                 "fldm${addr:submode}d ${addr:base}, $dst1",
+                 []>;
+
+def FLDMS : ASI5<(ops addrmode5:$addr, reglist:$dst1, variable_ops),
+                 "fldm${addr:submode}s ${addr:base}, $dst1",
+                 []>;
+} // isLoad
+
+let isStore = 1 in {
+def FSTMD : ADI5<(ops addrmode5:$addr, reglist:$src1, variable_ops),
+                 "fstm${addr:submode}d ${addr:base}, $src1",
+                 []>;
+
+def FSTMS : ASI5<(ops addrmode5:$addr, reglist:$src1, variable_ops),
+                 "fstm${addr:submode}s ${addr:base}, $src1",
+                 []>;
+} // isStore
+
+// FLDMX, FSTMX - mixing S/D registers for pre-armv6 cores
+
+//===----------------------------------------------------------------------===//
+// FP Binary Operations.
+//
+
+def FADDD  : ADI<(ops DPR:$dst, DPR:$a, DPR:$b),
+                 "faddd $dst, $a, $b",
+                 [(set DPR:$dst, (fadd DPR:$a, DPR:$b))]>;
+
+def FADDS  : ASI<(ops SPR:$dst, SPR:$a, SPR:$b),
+                 "fadds $dst, $a, $b",
+                 [(set SPR:$dst, (fadd SPR:$a, SPR:$b))]>;
+
+def FCMPED : ADI<(ops DPR:$a, DPR:$b),
+                 "fcmped $a, $b",
+                 [(arm_cmpfp DPR:$a, DPR:$b)]>;
+
+def FCMPES : ASI<(ops SPR:$a, SPR:$b),
+                 "fcmpes $a, $b",
+                 [(arm_cmpfp SPR:$a, SPR:$b)]>;
+
+def FDIVD  : ADI<(ops DPR:$dst, DPR:$a, DPR:$b),
+                 "fdivd $dst, $a, $b",
+                 [(set DPR:$dst, (fdiv DPR:$a, DPR:$b))]>;
+
+def FDIVS  : ASI<(ops SPR:$dst, SPR:$a, SPR:$b),
+                 "fdivs $dst, $a, $b",
+                 [(set SPR:$dst, (fdiv SPR:$a, SPR:$b))]>;
+
+def FMULD  : ADI<(ops DPR:$dst, DPR:$a, DPR:$b),
+                 "fmuld $dst, $a, $b",
+                 [(set DPR:$dst, (fmul DPR:$a, DPR:$b))]>;
+
+def FMULS  : ASI<(ops SPR:$dst, SPR:$a, SPR:$b),
+                 "fmuls $dst, $a, $b",
+                 [(set SPR:$dst, (fmul SPR:$a, SPR:$b))]>;
+
+
+def FNMULD  : ADI<(ops DPR:$dst, DPR:$a, DPR:$b),
+                  "fnmuld $dst, $a, $b",
+                  [(set DPR:$dst, (fneg (fmul DPR:$a, DPR:$b)))]>;
+
+def FNMULS  : ASI<(ops SPR:$dst, SPR:$a, SPR:$b),
+                  "fnmuls $dst, $a, $b",
+                  [(set SPR:$dst, (fneg (fmul SPR:$a, SPR:$b)))]>;
+
+def FSUBD  : ADI<(ops DPR:$dst, DPR:$a, DPR:$b),
+                 "fsubd $dst, $a, $b",
+                 [(set DPR:$dst, (fsub DPR:$a, DPR:$b))]>;
+
+def FSUBS  : ASI<(ops SPR:$dst, SPR:$a, SPR:$b),
+                 "fsubs $dst, $a, $b",
+                 [(set SPR:$dst, (fsub SPR:$a, SPR:$b))]>;
+
+//===----------------------------------------------------------------------===//
+// FP Unary Operations.
+//
+
+def FABSD  : ADI<(ops DPR:$dst, DPR:$a),
+                 "fabsd $dst, $a",
+                 [(set DPR:$dst, (fabs DPR:$a))]>;
+
+def FABSS  : ASI<(ops SPR:$dst, SPR:$a),
+                 "fabss $dst, $a",
+                 [(set SPR:$dst, (fabs SPR:$a))]>;
+
+def FCMPEZD : ADI<(ops DPR:$a),
+                  "fcmpezd $a",
+                  [(arm_cmpfp0 DPR:$a)]>;
+
+def FCMPEZS : ASI<(ops SPR:$a),
+                  "fcmpezs $a",
+                  [(arm_cmpfp0 SPR:$a)]>;
+
+def FCVTDS : ADI<(ops DPR:$dst, SPR:$a),
+                 "fcvtds $dst, $a",
+                 [(set DPR:$dst, (fextend SPR:$a))]>;
+
+def FCVTSD : ADI<(ops SPR:$dst, DPR:$a),
+                 "fcvtsd $dst, $a",
+                 [(set SPR:$dst, (fround DPR:$a))]>;
+
+def FCPYD  : ADI<(ops DPR:$dst, DPR:$a),
+                 "fcpyd $dst, $a",
+                 [/*(set DPR:$dst, DPR:$a)*/]>;
+
+def FCPYS  : ASI<(ops SPR:$dst, SPR:$a),
+                 "fcpys $dst, $a",
+                 [/*(set SPR:$dst, SPR:$a)*/]>;
+
+def FNEGD  : ADI<(ops DPR:$dst, DPR:$a),
+                 "fnegd $dst, $a",
+                 [(set DPR:$dst, (fneg DPR:$a))]>;
+
+def FNEGS  : ASI<(ops SPR:$dst, SPR:$a),
+                 "fnegs $dst, $a",
+                 [(set SPR:$dst, (fneg SPR:$a))]>;
+
+def FSQRTD  : ADI<(ops DPR:$dst, DPR:$a),
+                 "fsqrtd $dst, $a",
+                 [(set DPR:$dst, (fsqrt DPR:$a))]>;
+
+def FSQRTS  : ASI<(ops SPR:$dst, SPR:$a),
+                 "fsqrts $dst, $a",
+                 [(set SPR:$dst, (fsqrt SPR:$a))]>;
+
+//===----------------------------------------------------------------------===//
+// FP <-> GPR Copies.  Int <-> FP Conversions.
+//
+
+def IMPLICIT_DEF_SPR : PseudoInst<(ops SPR:$rD),
+                                  "@ IMPLICIT_DEF_SPR $rD",
+                                  [(set SPR:$rD, (undef))]>;
+def IMPLICIT_DEF_DPR : PseudoInst<(ops DPR:$rD),
+                                  "@ IMPLICIT_DEF_DPR $rD",
+                                  [(set DPR:$rD, (undef))]>;
+
+def FMRS   : ASI<(ops GPR:$dst, SPR:$src),
+                 "fmrs $dst, $src",
+                 [(set GPR:$dst, (bitconvert SPR:$src))]>;
+
+def FMSR   : ASI<(ops SPR:$dst, GPR:$src),
+                 "fmsr $dst, $src",
+                 [(set SPR:$dst, (bitconvert GPR:$src))]>;
+
+
+def FMRRD  : ADI<(ops GPR:$dst1, GPR:$dst2, DPR:$src),
+                 "fmrrd $dst1, $dst2, $src",
+                 [/* FIXME: Can't write pattern for multiple result instr*/]>;
+
+// FMDHR: GPR -> SPR
+// FMDLR: GPR -> SPR
+
+def FMDRR : ADI<(ops DPR:$dst, GPR:$src1, GPR:$src2),
+                "fmdrr $dst, $src1, $src2",
+                [(set DPR:$dst, (arm_fmdrr GPR:$src1, GPR:$src2))]>;
+
+// FMRDH: SPR -> GPR
+// FMRDL: SPR -> GPR
+// FMRRS: SPR -> GPR
+// FMRX : SPR system reg -> GPR
+
+// FMSRR: GPR -> SPR
+
+
+def FMSTAT : ASI<(ops), "fmstat", [(arm_fmstat)]>;
+
+// FMXR: GPR -> VFP Sstem reg
+
+
+// Int to FP:
+
+def FSITOD : ADI<(ops DPR:$dst, SPR:$a),
+                 "fsitod $dst, $a",
+                 [(set DPR:$dst, (arm_sitof SPR:$a))]>;
+
+def FSITOS : ASI<(ops SPR:$dst, SPR:$a),
+                 "fsitos $dst, $a",
+                 [(set SPR:$dst, (arm_sitof SPR:$a))]>;
+
+def FUITOD : ADI<(ops DPR:$dst, SPR:$a),
+                 "fuitod $dst, $a",
+                 [(set DPR:$dst, (arm_uitof SPR:$a))]>;
+
+def FUITOS : ASI<(ops SPR:$dst, SPR:$a),
+                 "fuitos $dst, $a",
+                 [(set SPR:$dst, (arm_uitof SPR:$a))]>;
+
+// FP to Int:
+// Always set Z bit in the instruction, i.e. "round towards zero" variants.
+
+def FTOSIZD : ADI<(ops SPR:$dst, DPR:$a),
+                 "ftosizd $dst, $a",
+                 [(set SPR:$dst, (arm_ftosi DPR:$a))]>;
+
+def FTOSIZS : ASI<(ops SPR:$dst, SPR:$a),
+                 "ftosizs $dst, $a",
+                 [(set SPR:$dst, (arm_ftosi SPR:$a))]>;
+
+def FTOUIZD : ADI<(ops SPR:$dst, DPR:$a),
+                 "ftouizd $dst, $a",
+                 [(set SPR:$dst, (arm_ftoui DPR:$a))]>;
+
+def FTOUIZS : ASI<(ops SPR:$dst, SPR:$a),
+                 "ftouizs $dst, $a",
+                 [(set SPR:$dst, (arm_ftoui SPR:$a))]>;
+
+//===----------------------------------------------------------------------===//
+// FP FMA Operations.
+//
+
+def FMACD : ADI<(ops DPR:$dst, DPR:$dstin, DPR:$a, DPR:$b),
+                "fmacd $dst, $a, $b",
+                [(set DPR:$dst, (fadd (fmul DPR:$a, DPR:$b), DPR:$dstin))]>,
+                RegConstraint<"$dstin = $dst">;
+
+def FMACS : ASI<(ops SPR:$dst, SPR:$dstin, SPR:$a, SPR:$b),
+                "fmacs $dst, $a, $b",
+                [(set SPR:$dst, (fadd (fmul SPR:$a, SPR:$b), SPR:$dstin))]>,
+                RegConstraint<"$dstin = $dst">;
+
+def FMSCD : ADI<(ops DPR:$dst, DPR:$dstin, DPR:$a, DPR:$b),
+                "fmscd $dst, $a, $b",
+                [(set DPR:$dst, (fsub (fmul DPR:$a, DPR:$b), DPR:$dstin))]>,
+                RegConstraint<"$dstin = $dst">;
+
+def FMSCS : ASI<(ops SPR:$dst, SPR:$dstin, SPR:$a, SPR:$b),
+                "fmscs $dst, $a, $b",
+                [(set SPR:$dst, (fsub (fmul SPR:$a, SPR:$b), SPR:$dstin))]>,
+                RegConstraint<"$dstin = $dst">;
+
+def FNMACD : ADI<(ops DPR:$dst, DPR:$dstin, DPR:$a, DPR:$b),
+                 "fnmacd $dst, $a, $b",
+             [(set DPR:$dst, (fadd (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>,
+                RegConstraint<"$dstin = $dst">;
+
+def FNMACS : ASI<(ops SPR:$dst, SPR:$dstin, SPR:$a, SPR:$b),
+                "fnmacs $dst, $a, $b",
+             [(set SPR:$dst, (fadd (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin))]>,
+                RegConstraint<"$dstin = $dst">;
+
+def FNMSCD : ADI<(ops DPR:$dst, DPR:$dstin, DPR:$a, DPR:$b),
+                 "fnmscd $dst, $a, $b",
+             [(set DPR:$dst, (fsub (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>,
+                RegConstraint<"$dstin = $dst">;
+
+def FNMSCS : ASI<(ops SPR:$dst, SPR:$dstin, SPR:$a, SPR:$b),
+                "fnmscs $dst, $a, $b",
+             [(set SPR:$dst, (fsub (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin))]>,
+                RegConstraint<"$dstin = $dst">;
+
+//===----------------------------------------------------------------------===//
+// FP Conditional moves.
+//
+
+def FCPYDcc  : ADI<(ops DPR:$dst, DPR:$false, DPR:$true, CCOp:$cc),
+                   "fcpyd$cc $dst, $true",
+                   [(set DPR:$dst, (ARMcmov DPR:$false, DPR:$true, imm:$cc))]>,
+                   RegConstraint<"$false = $dst">;
+
+def FCPYScc  : ASI<(ops SPR:$dst, SPR:$false, SPR:$true, CCOp:$cc),
+                   "fcpys$cc $dst, $true",
+                   [(set SPR:$dst, (ARMcmov SPR:$false, SPR:$true, imm:$cc))]>,
+                   RegConstraint<"$false = $dst">;
+
+def FNEGDcc  : ADI<(ops DPR:$dst, DPR:$false, DPR:$true, CCOp:$cc),
+                   "fnegd$cc $dst, $true",
+                   [(set DPR:$dst, (ARMcneg DPR:$false, DPR:$true, imm:$cc))]>,
+                   RegConstraint<"$false = $dst">;
+
+def FNEGScc  : ASI<(ops SPR:$dst, SPR:$false, SPR:$true, CCOp:$cc),
+                   "fnegs$cc $dst, $true",
+                   [(set SPR:$dst, (ARMcneg SPR:$false, SPR:$true, imm:$cc))]>,
+                   RegConstraint<"$false = $dst">;
diff --git a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
new file mode 100644
index 0000000..704898e
--- /dev/null
+++ b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
@@ -0,0 +1,628 @@
+//===-- ARMLoadStoreOptimizer.cpp - ARM load / store opt. pass ----*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Evan Cheng and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a pass that performs load / store related peephole
+// optimizations. This pass should be run after register allocation.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "arm-ldst-opt"
+#include "ARM.h"
+#include "ARMAddressingModes.h"
+#include "ARMRegisterInfo.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetMachine.h"
+using namespace llvm;
+
+STATISTIC(NumLDMGened , "Number of ldm instructions generated");
+STATISTIC(NumSTMGened , "Number of stm instructions generated");
+STATISTIC(NumFLDMGened, "Number of fldm instructions generated");
+STATISTIC(NumFSTMGened, "Number of fstm instructions generated");
+
+namespace {
+  struct VISIBILITY_HIDDEN ARMLoadStoreOpt : public MachineFunctionPass {
+    const TargetInstrInfo *TII;
+
+    virtual bool runOnMachineFunction(MachineFunction &Fn);
+
+    virtual const char *getPassName() const {
+      return "ARM load / store optimization pass";
+    }
+
+  private:
+    struct MemOpQueueEntry {
+      int Offset;
+      unsigned Position;
+      MachineBasicBlock::iterator MBBI;
+      bool Merged;
+      MemOpQueueEntry(int o, int p, MachineBasicBlock::iterator i)
+        : Offset(o), Position(p), MBBI(i), Merged(false) {};
+    };
+    typedef SmallVector<MemOpQueueEntry,8> MemOpQueue;
+    typedef MemOpQueue::iterator MemOpQueueIter;
+
+    SmallVector<MachineBasicBlock::iterator, 4>
+    MergeLDR_STR(MachineBasicBlock &MBB, unsigned SIndex, unsigned Base,
+                 int Opcode, unsigned Size, MemOpQueue &MemOps);
+
+    bool LoadStoreMultipleOpti(MachineBasicBlock &MBB);
+    bool MergeReturnIntoLDM(MachineBasicBlock &MBB);
+  };
+}
+
+/// createARMLoadStoreOptimizationPass - returns an instance of the load / store
+/// optimization pass.
+FunctionPass *llvm::createARMLoadStoreOptimizationPass() {
+  return new ARMLoadStoreOpt();
+}
+
+static int getLoadStoreMultipleOpcode(int Opcode) {
+  switch (Opcode) {
+  case ARM::LDR:
+    NumLDMGened++;
+    return ARM::LDM;
+  case ARM::STR:
+    NumSTMGened++;
+    return ARM::STM;
+  case ARM::FLDS:
+    NumFLDMGened++;
+    return ARM::FLDMS;
+  case ARM::FSTS:
+    NumFSTMGened++;
+    return ARM::FSTMS;
+  case ARM::FLDD:
+    NumFLDMGened++;
+    return ARM::FLDMD;
+  case ARM::FSTD:
+    NumFSTMGened++;
+    return ARM::FSTMD;
+  default: abort();
+  }
+  return 0;
+}
+
+/// mergeOps - Create and insert a LDM or STM with Base as base register and
+/// registers in Regs as the register operands that would be loaded / stored.
+/// It returns true if the transformation is done. 
+static bool mergeOps(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+                     int Offset, unsigned Base, int Opcode,
+                     SmallVector<unsigned, 8> &Regs,
+                     const TargetInstrInfo *TII) {
+  // Only a single register to load / store. Don't bother.
+  unsigned NumRegs = Regs.size();
+  if (NumRegs <= 1)
+    return false;
+
+  ARM_AM::AMSubMode Mode = ARM_AM::ia;
+  bool isAM4 = Opcode == ARM::LDR || Opcode == ARM::STR;
+  if (isAM4 && Offset == 4)
+    Mode = ARM_AM::ib;
+  else if (isAM4 && Offset == -4 * (int)NumRegs + 4)
+    Mode = ARM_AM::da;
+  else if (isAM4 && Offset == -4 * (int)NumRegs)
+    Mode = ARM_AM::db;
+  else if (Offset != 0) {
+    // If starting offset isn't zero, insert a MI to materialize a new base.
+    // But only do so if it is cost effective, i.e. merging more than two
+    // loads / stores.
+    if (NumRegs <= 2)
+      return false;
+
+    unsigned NewBase;
+    if (Opcode == ARM::LDR)
+      // If it is a load, then just use one of the destination register to
+      // use as the new base.
+      NewBase = Regs[NumRegs-1];
+    else {
+      // FIXME: Try scavenging a register to use as a new base.
+      NewBase = ARM::R12;
+    }
+    int BaseOpc = ARM::ADDri;
+    if (Offset < 0) {
+      BaseOpc = ARM::SUBri;
+      Offset = - Offset;
+    }
+    int ImmedOffset = ARM_AM::getSOImmVal(Offset);
+    if (ImmedOffset == -1)
+      return false;  // Probably not worth it then.
+    BuildMI(MBB, MBBI, TII->get(BaseOpc), NewBase).addReg(Base).addImm(ImmedOffset);
+    Base = NewBase;
+  }
+
+  bool isDPR = Opcode == ARM::FLDD || Opcode == ARM::FSTD;
+  bool isDef = Opcode == ARM::LDR || Opcode == ARM::FLDS || Opcode == ARM::FLDD;
+  Opcode = getLoadStoreMultipleOpcode(Opcode);
+  MachineInstrBuilder MIB = (isAM4)
+    ? BuildMI(MBB, MBBI, TII->get(Opcode)).addReg(Base)
+        .addImm(ARM_AM::getAM4ModeImm(Mode))
+    : BuildMI(MBB, MBBI, TII->get(Opcode)).addReg(Base)
+        .addImm(ARM_AM::getAM5Opc(Mode, false, isDPR ? NumRegs<<1 : NumRegs));
+  for (unsigned i = 0; i != NumRegs; ++i)
+    MIB = MIB.addReg(Regs[i], Opcode == isDef);
+
+  return true;
+}
+
+SmallVector<MachineBasicBlock::iterator, 4>
+ARMLoadStoreOpt::MergeLDR_STR(MachineBasicBlock &MBB,
+                              unsigned SIndex, unsigned Base, int Opcode,
+                              unsigned Size, MemOpQueue &MemOps) {
+  bool isAM4 = Opcode == ARM::LDR || Opcode == ARM::STR;
+  SmallVector<MachineBasicBlock::iterator, 4> Merges;
+  int Offset = MemOps[SIndex].Offset;
+  int SOffset = Offset;
+  unsigned Pos = MemOps[SIndex].Position;
+  MachineBasicBlock::iterator Loc = MemOps[SIndex].MBBI;
+  SmallVector<unsigned, 8> Regs;
+  unsigned PReg = MemOps[SIndex].MBBI->getOperand(0).getReg();
+  unsigned PRegNum = ARMRegisterInfo::getRegisterNumbering(PReg);
+  Regs.push_back(PReg);
+  for (unsigned i = SIndex+1, e = MemOps.size(); i != e; ++i) {
+    int NewOffset = MemOps[i].Offset;
+    unsigned Reg = MemOps[i].MBBI->getOperand(0).getReg();
+    unsigned RegNum = ARMRegisterInfo::getRegisterNumbering(Reg);
+    // AM4 - register numbers in ascending order.
+    // AM5 - consecutive register numbers in ascending order.
+    if (NewOffset == Offset + (int)Size &&
+        ((isAM4 && RegNum > PRegNum) || RegNum == PRegNum+1)) {
+      Offset += Size;
+      Regs.push_back(Reg);
+      PRegNum = RegNum;
+    } else {
+      // Can't merge this in. Try merge the earlier ones first.
+      if (mergeOps(MBB, ++Loc, SOffset, Base, Opcode, Regs, TII)) {
+        Merges.push_back(prior(Loc));
+        for (unsigned j = SIndex; j < i; ++j) {
+          MBB.erase(MemOps[j].MBBI);
+          MemOps[j].Merged = true;
+        }
+      }
+      SmallVector<MachineBasicBlock::iterator, 4> Merges2 =
+        MergeLDR_STR(MBB, i, Base, Opcode, Size, MemOps);
+      Merges.append(Merges2.begin(), Merges2.end());
+      return Merges;
+    }
+
+    if (MemOps[i].Position > Pos) {
+      Pos = MemOps[i].Position;
+      Loc = MemOps[i].MBBI;
+    }
+  }
+
+  if (mergeOps(MBB, ++Loc, SOffset, Base, Opcode, Regs, TII)) {
+    Merges.push_back(prior(Loc));
+    for (unsigned i = SIndex, e = MemOps.size(); i != e; ++i) {
+      MBB.erase(MemOps[i].MBBI);
+      MemOps[i].Merged = true;
+    }
+  }
+
+  return Merges;
+}
+
+static inline bool isMatchingDecrement(MachineInstr *MI, unsigned Base,
+                                       unsigned Bytes) {
+  return (MI && MI->getOpcode() == ARM::SUBri &&
+          MI->getOperand(0).getReg() == Base &&
+          MI->getOperand(1).getReg() == Base &&
+          ARM_AM::getAM2Offset(MI->getOperand(2).getImm()) == Bytes);
+}
+
+static inline bool isMatchingIncrement(MachineInstr *MI, unsigned Base,
+                                       unsigned Bytes) {
+  return (MI && MI->getOpcode() == ARM::ADDri &&
+          MI->getOperand(0).getReg() == Base &&
+          MI->getOperand(1).getReg() == Base &&
+          ARM_AM::getAM2Offset(MI->getOperand(2).getImm()) == Bytes);
+}
+
+static inline unsigned getLSMultipleTransferSize(MachineInstr *MI) {
+  switch (MI->getOpcode()) {
+  default: return 0;
+  case ARM::LDR:
+  case ARM::STR:
+  case ARM::FLDS:
+  case ARM::FSTS:
+    return 4;
+  case ARM::FLDD:
+  case ARM::FSTD:
+    return 8;
+  case ARM::LDM:
+  case ARM::STM:
+    return (MI->getNumOperands() - 2) * 4;
+  case ARM::FLDMS:
+  case ARM::FSTMS:
+  case ARM::FLDMD:
+  case ARM::FSTMD:
+    return ARM_AM::getAM5Offset(MI->getOperand(1).getImm()) * 4;
+  }
+}
+
+/// mergeBaseUpdateLSMultiple - Fold proceeding/trailing inc/dec of base
+/// register into the LDM/STM/FLDM{D|S}/FSTM{D|S} op when possible:
+///
+/// stmia rn, <ra, rb, rc>
+/// rn := rn + 4 * 3;
+/// =>
+/// stmia rn!, <ra, rb, rc>
+///
+/// rn := rn - 4 * 3;
+/// ldmia rn, <ra, rb, rc>
+/// =>
+/// ldmdb rn!, <ra, rb, rc>
+static bool mergeBaseUpdateLSMultiple(MachineBasicBlock &MBB,
+                                      MachineBasicBlock::iterator MBBI) {
+  MachineInstr *MI = MBBI;
+  unsigned Base = MI->getOperand(0).getReg();
+  unsigned Bytes = getLSMultipleTransferSize(MI);
+  int Opcode = MI->getOpcode();
+  bool isAM4 = Opcode == ARM::LDM || Opcode == ARM::STM;
+
+  if (isAM4) {
+    if (ARM_AM::getAM4WBFlag(MI->getOperand(1).getImm()))
+      return false;
+
+    // Can't use the updating AM4 sub-mode if the base register is also a dest
+    // register. e.g. ldmdb r0!, {r0, r1, r2}. The behavior is undefined.
+    for (unsigned i = 2, e = MI->getNumOperands(); i != e; ++i) {
+      if (MI->getOperand(i).getReg() == Base)
+        return false;
+    }
+
+    ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MI->getOperand(1).getImm());
+    if (MBBI != MBB.begin()) {
+      MachineBasicBlock::iterator PrevMBBI = prior(MBBI);
+      if (Mode == ARM_AM::ia &&
+          isMatchingDecrement(PrevMBBI, Base, Bytes)) {
+        MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(ARM_AM::db, true));
+        MBB.erase(PrevMBBI);
+        return true;
+      } else if (Mode == ARM_AM::ib &&
+                 isMatchingDecrement(PrevMBBI, Base, Bytes)) {
+        MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(ARM_AM::da, true));
+        MBB.erase(PrevMBBI);
+        return true;
+      }
+    }
+
+    if (MBBI != MBB.end()) {
+      MachineBasicBlock::iterator NextMBBI = next(MBBI);
+      if ((Mode == ARM_AM::ia || Mode == ARM_AM::ib) &&
+          isMatchingIncrement(NextMBBI, Base, Bytes)) {
+        MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(Mode, true));
+        MBB.erase(NextMBBI);
+        return true;
+      } else if ((Mode == ARM_AM::da || Mode == ARM_AM::db) &&
+                 isMatchingDecrement(NextMBBI, Base, Bytes)) {
+        MI->getOperand(1).setImm(ARM_AM::getAM4ModeImm(Mode, true));
+        MBB.erase(NextMBBI);
+        return true;
+      }
+    }
+  } else {
+    // FLDM{D|S}, FSTM{D|S} addressing mode 5 ops.
+    if (ARM_AM::getAM5WBFlag(MI->getOperand(1).getImm()))
+      return false;
+
+    ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MI->getOperand(1).getImm());
+    unsigned Offset = ARM_AM::getAM5Offset(MI->getOperand(1).getImm());
+    if (MBBI != MBB.begin()) {
+      MachineBasicBlock::iterator PrevMBBI = prior(MBBI);
+      if (Mode == ARM_AM::ia &&
+          isMatchingDecrement(PrevMBBI, Base, Bytes)) {
+        MI->getOperand(1).setImm(ARM_AM::getAM5Opc(ARM_AM::db, true, Offset));
+        MBB.erase(PrevMBBI);
+        return true;
+      }
+    }
+
+    if (MBBI != MBB.end()) {
+      MachineBasicBlock::iterator NextMBBI = next(MBBI);
+      if (Mode == ARM_AM::ia &&
+          isMatchingIncrement(NextMBBI, Base, Bytes)) {
+        MI->getOperand(1).setImm(ARM_AM::getAM5Opc(ARM_AM::ia, true, Offset));
+        MBB.erase(NextMBBI);
+      }
+      return true;
+    }
+  }
+
+  return false;
+}
+
+static unsigned getPreIndexedLoadStoreOpcode(unsigned Opc) {
+  switch (Opc) {
+  case ARM::LDR: return ARM::LDR_PRE;
+  case ARM::STR: return ARM::STR_PRE;
+  case ARM::FLDS: return ARM::FLDMS;
+  case ARM::FLDD: return ARM::FLDMD;
+  case ARM::FSTS: return ARM::FSTMS;
+  case ARM::FSTD: return ARM::FSTMD;
+  default: abort();
+  }
+  return 0;
+}
+
+static unsigned getPostIndexedLoadStoreOpcode(unsigned Opc) {
+  switch (Opc) {
+  case ARM::LDR: return ARM::LDR_POST;
+  case ARM::STR: return ARM::STR_POST;
+  case ARM::FLDS: return ARM::FLDMS;
+  case ARM::FLDD: return ARM::FLDMD;
+  case ARM::FSTS: return ARM::FSTMS;
+  case ARM::FSTD: return ARM::FSTMD;
+  default: abort();
+  }
+  return 0;
+}
+
+/// mergeBaseUpdateLoadStore - Fold proceeding/trailing inc/dec of base
+/// register into the LDR/STR/FLD{D|S}/FST{D|S} op when possible:
+static bool mergeBaseUpdateLoadStore(MachineBasicBlock &MBB,
+                                     MachineBasicBlock::iterator MBBI,
+                                     const TargetInstrInfo *TII) {
+  MachineInstr *MI = MBBI;
+  unsigned Base = MI->getOperand(1).getReg();
+  unsigned Bytes = getLSMultipleTransferSize(MI);
+  int Opcode = MI->getOpcode();
+  bool isAM2 = Opcode == ARM::LDR || Opcode == ARM::STR;
+  if ((isAM2 && ARM_AM::getAM2Offset(MI->getOperand(3).getImm()) != 0) ||
+      (!isAM2 && ARM_AM::getAM5Offset(MI->getOperand(2).getImm()) != 0))
+    return false;
+
+  bool isLd = Opcode == ARM::LDR || Opcode == ARM::FLDS || Opcode == ARM::FLDD;
+  // Can't do the merge if the destination register is the same as the would-be
+  // writeback register.
+  if (isLd && MI->getOperand(0).getReg() == Base)
+    return false;
+
+  bool DoMerge = false;
+  ARM_AM::AddrOpc AddSub = ARM_AM::add;
+  unsigned NewOpc = 0;
+  if (MBBI != MBB.begin()) {
+    MachineBasicBlock::iterator PrevMBBI = prior(MBBI);
+    if (isMatchingDecrement(PrevMBBI, Base, Bytes)) {
+      DoMerge = true;
+      AddSub = ARM_AM::sub;
+      NewOpc = getPreIndexedLoadStoreOpcode(Opcode);
+    } else if (isAM2 && isMatchingIncrement(PrevMBBI, Base, Bytes)) {
+      DoMerge = true;
+      NewOpc = getPreIndexedLoadStoreOpcode(Opcode);
+    }
+    if (DoMerge)
+      MBB.erase(PrevMBBI);
+  }
+
+  if (!DoMerge && MBBI != MBB.end()) {
+    MachineBasicBlock::iterator NextMBBI = next(MBBI);
+    if (isAM2 && isMatchingDecrement(NextMBBI, Base, Bytes)) {
+      DoMerge = true;
+      AddSub = ARM_AM::sub;
+      NewOpc = getPostIndexedLoadStoreOpcode(Opcode);
+    } else if (isMatchingIncrement(NextMBBI, Base, Bytes)) {
+      DoMerge = true;
+      NewOpc = getPostIndexedLoadStoreOpcode(Opcode);
+    }
+    if (DoMerge)
+      MBB.erase(NextMBBI);
+  }
+
+  if (!DoMerge)
+    return false;
+
+  bool isDPR = NewOpc == ARM::FLDMD || NewOpc == ARM::FSTMD;
+  unsigned Offset = isAM2 ? ARM_AM::getAM2Opc(AddSub, Bytes, ARM_AM::no_shift)
+    : ARM_AM::getAM5Opc((AddSub == ARM_AM::sub) ? ARM_AM::db : ARM_AM::ia,
+                        true, isDPR ? 2 : 1);
+  if (isLd) {
+    if (isAM2)
+      BuildMI(MBB, MBBI, TII->get(NewOpc), MI->getOperand(0).getReg())
+        .addReg(Base, true).addReg(Base).addReg(0).addImm(Offset);
+    else
+      BuildMI(MBB, MBBI, TII->get(NewOpc)).addReg(Base)
+        .addImm(Offset).addReg(MI->getOperand(0).getReg(), true);
+  } else {
+    if (isAM2)
+      BuildMI(MBB, MBBI, TII->get(NewOpc), Base).addReg(MI->getOperand(0).getReg())
+        .addReg(Base).addReg(0).addImm(Offset);
+    else
+      BuildMI(MBB, MBBI, TII->get(NewOpc)).addReg(Base)
+        .addImm(Offset).addReg(MI->getOperand(0).getReg(), false);
+  }
+  MBB.erase(MBBI);
+
+  return true;
+}
+
+/// LoadStoreMultipleOpti - An optimization pass to turn multiple LDR / STR
+/// ops of the same base and incrementing offset into LDM / STM ops.
+bool ARMLoadStoreOpt::LoadStoreMultipleOpti(MachineBasicBlock &MBB) {
+  unsigned NumMerges = 0;
+  unsigned NumMemOps = 0;
+  MemOpQueue MemOps;
+  unsigned CurrBase = 0;
+  int CurrOpc = -1;
+  unsigned CurrSize = 0;
+  unsigned Position = 0;
+  MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
+  while (MBBI != E) {
+    bool Advance  = false;
+    bool TryMerge = false;
+    bool Clobber  = false;
+
+    int Opcode = MBBI->getOpcode();
+    bool isMemOp = false;
+    bool isAM2 = false;
+    unsigned Size = 4;
+    switch (Opcode) {
+    case ARM::LDR:
+    case ARM::STR:
+      isMemOp =
+        (MBBI->getOperand(1).isRegister() && MBBI->getOperand(2).getReg() == 0);
+      isAM2 = true;
+      break;
+    case ARM::FLDS:
+    case ARM::FSTS:
+      isMemOp = MBBI->getOperand(1).isRegister();
+      break;
+    case ARM::FLDD:
+    case ARM::FSTD:
+      isMemOp = MBBI->getOperand(1).isRegister();
+      Size = 8;
+      break;
+    }
+    if (isMemOp) {
+      unsigned Base = MBBI->getOperand(1).getReg();
+      unsigned OffIdx = MBBI->getNumOperands()-1;
+      unsigned OffField = MBBI->getOperand(OffIdx).getImm();
+      int Offset = isAM2
+        ? ARM_AM::getAM2Offset(OffField) : ARM_AM::getAM5Offset(OffField) * 4;
+      if (isAM2) {
+        if (ARM_AM::getAM2Op(OffField) == ARM_AM::sub)
+          Offset = -Offset;
+      } else {
+        if (ARM_AM::getAM5Op(OffField) == ARM_AM::sub)
+          Offset = -Offset;
+      }
+      // Watch out for:
+      // r4 := ldr [r5]
+      // r5 := ldr [r5, #4]
+      // r6 := ldr [r5, #8]
+      //
+      // The second ldr has effectively broken the chain even though it
+      // looks like the later ldr(s) use the same base register. Try to
+      // merge the ldr's so far, including this one. But don't try to
+      // combine the following ldr(s).
+      Clobber = (Opcode == ARM::LDR && Base == MBBI->getOperand(0).getReg());
+      if (CurrBase == 0 && !Clobber) {
+        // Start of a new chain.
+        CurrBase = Base;
+        CurrOpc  = Opcode;
+        CurrSize = Size;
+        MemOps.push_back(MemOpQueueEntry(Offset, Position, MBBI));
+        NumMemOps++;
+        Advance = true;
+      } else {
+        if (Clobber) {
+          TryMerge = true;
+          Advance = true;
+        }
+
+        if (CurrOpc == Opcode && CurrBase == Base) {
+          // Continue adding to the queue.
+          if (Offset > MemOps.back().Offset) {
+            MemOps.push_back(MemOpQueueEntry(Offset, Position, MBBI));
+            NumMemOps++;
+            Advance = true;
+          } else {
+            for (MemOpQueueIter I = MemOps.begin(), E = MemOps.end();
+                 I != E; ++I) {
+              if (Offset < I->Offset) {
+                MemOps.insert(I, MemOpQueueEntry(Offset, Position, MBBI));
+                NumMemOps++;
+                Advance = true;
+                break;
+              } else if (Offset == I->Offset) {
+                // Collision! This can't be merged!
+                break;
+              }
+            }
+          }
+        }
+      }
+    }
+
+    if (Advance) {
+      ++Position;
+      ++MBBI;
+    } else
+      TryMerge = true;
+
+    if (TryMerge) {
+      if (NumMemOps > 1) {
+        SmallVector<MachineBasicBlock::iterator,4> MBBII =
+          MergeLDR_STR(MBB, 0, CurrBase, CurrOpc, CurrSize,MemOps);
+        // Try folding preceeding/trailing base inc/dec into the generated
+        // LDM/STM ops.
+        for (unsigned i = 0, e = MBBII.size(); i < e; ++i)
+          if (mergeBaseUpdateLSMultiple(MBB, MBBII[i]))
+            NumMerges++;
+        NumMerges += MBBII.size();
+      }
+
+      // Try folding preceeding/trailing base inc/dec into those load/store
+      // that were not merged to form LDM/STM ops.
+      for (unsigned i = 0; i != NumMemOps; ++i)
+        if (!MemOps[i].Merged)
+          if (mergeBaseUpdateLoadStore(MBB, MemOps[i].MBBI, TII))
+            NumMerges++;
+
+      CurrBase = 0;
+      CurrOpc = -1;
+      if (NumMemOps) {
+        MemOps.clear();
+        NumMemOps = 0;
+      }
+
+      // If iterator hasn't been advanced and this is not a memory op, skip it.
+      // It can't start a new chain anyway.
+      if (!Advance && !isMemOp && MBBI != E) {
+        ++Position;
+        ++MBBI;
+      }
+    }
+  }
+  return NumMerges > 0;
+}
+
+/// MergeReturnIntoLDM - If this is a exit BB, try merging the return op
+/// (bx lr) into the preceeding stack restore so it directly restore the value
+/// of LR into pc.
+///   ldmfd sp!, {r7, lr}
+///   bx lr
+/// =>
+///   ldmfd sp!, {r7, pc}
+bool ARMLoadStoreOpt::MergeReturnIntoLDM(MachineBasicBlock &MBB) {
+  if (MBB.empty()) return false;
+
+  MachineBasicBlock::iterator MBBI = prior(MBB.end());
+  if (MBBI->getOpcode() == ARM::BX_RET && MBBI != MBB.begin()) {
+    MachineInstr *PrevMI = prior(MBBI);
+    if (PrevMI->getOpcode() == ARM::LDM) {
+      MachineOperand &MO = PrevMI->getOperand(PrevMI->getNumOperands()-1);
+      if (MO.getReg() == ARM::LR) {
+        PrevMI->setInstrDescriptor(TII->get(ARM::LDM_RET));
+        MO.setReg(ARM::PC);
+        MBB.erase(MBBI);
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+bool ARMLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
+  TII = Fn.getTarget().getInstrInfo();
+  bool Modified = false;
+  for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
+       ++MFI) {
+    MachineBasicBlock &MBB = *MFI;
+    Modified |= LoadStoreMultipleOpti(MBB);
+    Modified |= MergeReturnIntoLDM(MBB);
+  }
+  return Modified;
+}
diff --git a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h
new file mode 100644
index 0000000..4de3dbc
--- /dev/null
+++ b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h
@@ -0,0 +1,136 @@
+//====- ARMMachineFuctionInfo.h - ARM machine function info -----*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the Evan Cheng and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file declares ARM-specific per-machine-function information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ARMMACHINEFUNCTIONINFO_H
+#define ARMMACHINEFUNCTIONINFO_H
+
+#include "ARMSubtarget.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/Target/TargetMachine.h"
+
+namespace llvm {
+
+/// ARMFunctionInfo - This class is derived from MachineFunction private
+/// ARM target-specific information for each MachineFunction.
+class ARMFunctionInfo : public MachineFunctionInfo {
+
+  /// isThumb - True if this function is compiled under Thumb mode.
+  ///
+  bool isThumb;
+
+  /// VarArgsRegSaveSize - Size of the register save area for vararg functions.
+  ///
+  unsigned VarArgsRegSaveSize;
+
+  /// FramePtrSpilled - True if FP register is spilled. Set by
+  /// processFunctionBeforeCalleeSavedScan().
+  bool FramePtrSpilled;
+
+  /// FramePtrSpillOffset - If FramePtrSpilled, this records the frame pointer
+  /// spill stack offset.
+  unsigned FramePtrSpillOffset;
+
+  /// GPRCS1Offset, GPRCS2Offset, DPRCSOffset - Starting offset of callee saved
+  /// register spills areas. For Mac OS X:
+  ///
+  /// GPR callee-saved (1) : r4, r5, r6, r7, lr
+  /// --------------------------------------------
+  /// GPR callee-saved (2) : r8, r10, r11
+  /// --------------------------------------------
+  /// DPR callee-saved : d8 - d15
+  unsigned GPRCS1Offset;
+  unsigned GPRCS2Offset;
+  unsigned DPRCSOffset;
+
+  /// GPRCS1Size, GPRCS2Size, DPRCSSize - Sizes of callee saved register spills
+  /// areas.
+  unsigned GPRCS1Size;
+  unsigned GPRCS2Size;
+  unsigned DPRCSSize;
+
+  /// GPRCS1Frames, GPRCS2Frames, DPRCSFrames - Keeps track of frame indices
+  /// which belong to these spill areas.
+  std::set<int> GPRCS1Frames;
+  std::set<int> GPRCS2Frames;
+  std::set<int> DPRCSFrames;
+
+  /// JumpTableUId - Unique id for jumptables.
+  ///
+  unsigned JumpTableUId;
+
+public:
+  ARMFunctionInfo() :
+    isThumb(false),
+    VarArgsRegSaveSize(0), FramePtrSpilled(false), FramePtrSpillOffset(0),
+    GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
+    GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), JumpTableUId(0) {}
+
+  ARMFunctionInfo(MachineFunction &MF) :
+    isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()),
+    VarArgsRegSaveSize(0), FramePtrSpilled(false), FramePtrSpillOffset(0),
+    GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
+    GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), JumpTableUId(0) {}
+
+  bool isThumbFunction() const { return isThumb; }
+
+  unsigned getVarArgsRegSaveSize() const { return VarArgsRegSaveSize; }
+  void setVarArgsRegSaveSize(unsigned s) { VarArgsRegSaveSize = s; }
+
+  bool isFramePtrSpilled() const { return FramePtrSpilled; }
+  void setFramePtrSpilled(bool s) { FramePtrSpilled = s; }
+  unsigned getFramePtrSpillOffset() const { return FramePtrSpillOffset; }
+  void setFramePtrSpillOffset(unsigned o) { FramePtrSpillOffset = o; }
+  
+  unsigned getGPRCalleeSavedArea1Offset() const { return GPRCS1Offset; }
+  unsigned getGPRCalleeSavedArea2Offset() const { return GPRCS2Offset; }
+  unsigned getDPRCalleeSavedAreaOffset()  const { return DPRCSOffset; }
+
+  void setGPRCalleeSavedArea1Offset(unsigned o) { GPRCS1Offset = o; }
+  void setGPRCalleeSavedArea2Offset(unsigned o) { GPRCS2Offset = o; }
+  void setDPRCalleeSavedAreaOffset(unsigned o)  { DPRCSOffset = o; }
+
+  unsigned getGPRCalleeSavedArea1Size() const { return GPRCS1Size; }
+  unsigned getGPRCalleeSavedArea2Size() const { return GPRCS2Size; }
+  unsigned getDPRCalleeSavedAreaSize()  const { return DPRCSSize; }
+
+  void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }
+  void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }
+  void setDPRCalleeSavedAreaSize(unsigned s)  { DPRCSSize = s; }
+
+  bool isGPRCalleeSavedArea1Frame(unsigned fi) const {
+    return GPRCS1Frames.count(fi);
+  }
+  bool isGPRCalleeSavedArea2Frame(unsigned fi) const {
+    return GPRCS2Frames.count(fi);
+  }
+  bool isDPRCalleeSavedAreaFrame(unsigned fi) const {
+    return DPRCSFrames.count(fi);
+  }
+
+  void addGPRCalleeSavedArea1Frame(unsigned fi) {
+    GPRCS1Frames.insert(fi);
+  }
+  void addGPRCalleeSavedArea2Frame(unsigned fi) {
+    GPRCS2Frames.insert(fi);
+  }
+  void addDPRCalleeSavedAreaFrame(unsigned fi) {
+    DPRCSFrames.insert(fi);
+  }
+
+  unsigned createJumpTableUId() {
+    return JumpTableUId++;
+  }
+};
+} // End llvm namespace
+
+#endif // ARMMACHINEFUNCTIONINFO_H
diff --git a/llvm/lib/Target/ARM/ARMMul.cpp b/llvm/lib/Target/ARM/ARMMul.cpp
deleted file mode 100644
index c4eeaac..0000000
--- a/llvm/lib/Target/ARM/ARMMul.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-//===-- ARMMul.cpp - Define TargetMachine for A5CRM -----------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file was developed by the "Instituto Nokia de Tecnologia" and
-// is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Modify the ARM multiplication instructions so that Rd{Hi,Lo} and Rm are distinct
-//
-//===----------------------------------------------------------------------===//
-
-
-#include "ARM.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Support/Compiler.h"
-
-using namespace llvm;
-
-namespace {
-  class VISIBILITY_HIDDEN FixMul : public MachineFunctionPass {
-    virtual bool runOnMachineFunction(MachineFunction &MF);
-  };
-}
-
-FunctionPass *llvm::createARMFixMulPass() { return new FixMul(); }
-
-bool FixMul::runOnMachineFunction(MachineFunction &MF) {
-  bool Changed = false;
-
-  for (MachineFunction::iterator BB = MF.begin(), E = MF.end();
-       BB != E; ++BB) {
-    MachineBasicBlock &MBB = *BB;
-
-    for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
-         I != E; ++I) {
-      MachineInstr *MI = I;
-
-      int Op = MI->getOpcode();
-      if (Op == ARM::MUL ||
-          Op == ARM::SMULL ||
-          Op == ARM::UMULL) {
-        MachineOperand &RdOp = MI->getOperand(0);
-        MachineOperand &RmOp = MI->getOperand(1);
-        MachineOperand &RsOp = MI->getOperand(2);
-
-        unsigned Rd = RdOp.getReg();
-        unsigned Rm = RmOp.getReg();
-        unsigned Rs = RsOp.getReg();
-
-        if (Rd == Rm) {
-          Changed = true;
-          if (Rd != Rs) {
-	    //Rd and Rm must be distinct, but Rd can be equal to Rs.
-	    //Swap Rs and Rm
-            RmOp.setReg(Rs);
-            RsOp.setReg(Rm);
-          } else {
-            unsigned scratch = Op == ARM::MUL ? ARM::R12 : ARM::R0;
-            BuildMI(MBB, I, MF.getTarget().getInstrInfo()->get(ARM::MOV),
-                    scratch).addReg(Rm).addImm(0).addImm(ARMShift::LSL);
-            RmOp.setReg(scratch);
-          }
-        }
-      }
-    }
-  }
-
-  return Changed;
-}
diff --git a/llvm/lib/Target/ARM/ARMRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMRegisterInfo.cpp
index 16a1a29..5ae482b 100644
--- a/llvm/lib/Target/ARM/ARMRegisterInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMRegisterInfo.cpp
@@ -13,243 +13,1023 @@
 //===----------------------------------------------------------------------===//
 
 #include "ARM.h"
+#include "ARMAddressingModes.h"
+#include "ARMInstrInfo.h"
+#include "ARMMachineFunctionInfo.h"
 #include "ARMRegisterInfo.h"
-#include "ARMCommon.h"
+#include "ARMSubtarget.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineLocation.h"
-#include "llvm/Type.h"
 #include "llvm/Target/TargetFrameInfo.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Type.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/STLExtras.h"
+#include <algorithm>
+#include <iostream>
 using namespace llvm;
 
-// 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(const MachineFunction &MF) {
-  const MachineFrameInfo *MFI = MF.getFrameInfo();
-  return NoFramePointerElim || MFI->hasVarSizedObjects();
-}
-
-static void splitInstructionWithImmediate(MachineBasicBlock &BB,
-				       MachineBasicBlock::iterator I,
-				       const TargetInstrDescriptor &TID,
-				       unsigned DestReg,
-				       unsigned OrigReg,
-				       unsigned immediate){
-  std::vector<unsigned> immediatePieces = splitImmediate(immediate);
-  std::vector<unsigned>::iterator it;
-  for (it=immediatePieces.begin(); it != immediatePieces.end(); ++it){
-    BuildMI(BB, I, TID, DestReg).addReg(OrigReg)
-	.addImm(*it).addImm(0).addImm(ARMShift::LSL);
+unsigned ARMRegisterInfo::getRegisterNumbering(unsigned RegEnum) {
+  using namespace ARM;
+  switch (RegEnum) {
+  case R0:  case S0:  case D0:  return 0;
+  case R1:  case S1:  case D1:  return 1;
+  case R2:  case S2:  case D2:  return 2;
+  case R3:  case S3:  case D3:  return 3;
+  case R4:  case S4:  case D4:  return 4;
+  case R5:  case S5:  case D5:  return 5;
+  case R6:  case S6:  case D6:  return 6;
+  case R7:  case S7:  case D7:  return 7;
+  case R8:  case S8:  case D8:  return 8;
+  case R9:  case S9:  case D9:  return 9;
+  case R10: case S10: case D10: return 10;
+  case R11: case S11: case D11: return 11;
+  case R12: case S12: case D12: return 12;
+  case SP:  case S13: case D13: return 13;
+  case LR:  case S14: case D14: return 14;
+  case PC:  case S15: case D15: return 15;
+  case S16: return 16;
+  case S17: return 17;
+  case S18: return 18;
+  case S19: return 19;
+  case S20: return 20;
+  case S21: return 21;
+  case S22: return 22;
+  case S23: return 23;
+  case S24: return 24;
+  case S25: return 25;
+  case S26: return 26;
+  case S27: return 27;
+  case S28: return 28;
+  case S29: return 29;
+  case S30: return 30;
+  case S31: return 31;
+  default:
+    std::cerr << "Unknown ARM register!\n";
+    abort();
   }
 }
 
-ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii)
+ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii,
+                                 const ARMSubtarget &sti)
   : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
-    TII(tii) {
+    TII(tii), STI(sti),
+    FramePtr(STI.useThumbBacktraces() ? ARM::R7 : ARM::R11) {
+}
+
+bool ARMRegisterInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
+                                                MachineBasicBlock::iterator MI,
+                                const std::vector<CalleeSavedInfo> &CSI) const {
+  MachineFunction &MF = *MBB.getParent();
+  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+  if (!AFI->isThumbFunction() || CSI.empty())
+    return false;
+
+  MachineInstrBuilder MIB = BuildMI(MBB, MI, TII.get(ARM::tPUSH));
+  for (unsigned i = CSI.size(); i != 0; --i)
+    MIB.addReg(CSI[i-1].getReg());
+  return true;
+}
+
+bool ARMRegisterInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
+                                                 MachineBasicBlock::iterator MI,
+                                const std::vector<CalleeSavedInfo> &CSI) const {
+  MachineFunction &MF = *MBB.getParent();
+  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+  if (!AFI->isThumbFunction() || CSI.empty())
+    return false;
+
+  MachineInstr *PopMI = new MachineInstr(TII.get(ARM::tPOP));
+  MBB.insert(MI, PopMI);
+  for (unsigned i = CSI.size(); i != 0; --i) {
+    unsigned Reg = CSI[i-1].getReg();
+    if (Reg == ARM::LR) {
+      Reg = ARM::PC;
+      PopMI->setInstrDescriptor(TII.get(ARM::tPOP_RET));
+      MBB.erase(MI);
+    }
+    PopMI->addRegOperand(Reg, true);
+  }
+  return true;
 }
 
 void ARMRegisterInfo::
 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
                     unsigned SrcReg, int FI,
                     const TargetRegisterClass *RC) const {
-  assert (RC == ARM::IntRegsRegisterClass);
-  BuildMI(MBB, I, TII.get(ARM::STR)).addReg(SrcReg).addFrameIndex(FI).addImm(0);
+  if (RC == ARM::GPRRegisterClass) {
+    MachineFunction &MF = *MBB.getParent();
+    ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+    if (AFI->isThumbFunction())
+      BuildMI(MBB, I, TII.get(ARM::tSTRspi)).addReg(SrcReg)
+        .addFrameIndex(FI).addImm(0);
+    else
+      BuildMI(MBB, I, TII.get(ARM::STR)).addReg(SrcReg)
+          .addFrameIndex(FI).addReg(0).addImm(0);
+  } else if (RC == ARM::DPRRegisterClass) {
+    BuildMI(MBB, I, TII.get(ARM::FSTD)).addReg(SrcReg)
+    .addFrameIndex(FI).addImm(0);
+  } else {
+    assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
+    BuildMI(MBB, I, TII.get(ARM::FSTS)).addReg(SrcReg)
+      .addFrameIndex(FI).addImm(0);
+  }
 }
 
 void ARMRegisterInfo::
 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
                      unsigned DestReg, int FI,
                      const TargetRegisterClass *RC) const {
-  assert (RC == ARM::IntRegsRegisterClass);
-  BuildMI(MBB, I, TII.get(ARM::LDR), DestReg).addFrameIndex(FI).addImm(0);
+  if (RC == ARM::GPRRegisterClass) {
+    MachineFunction &MF = *MBB.getParent();
+    ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+    if (AFI->isThumbFunction())
+      BuildMI(MBB, I, TII.get(ARM::tLDRspi), DestReg)
+        .addFrameIndex(FI).addImm(0);
+    else
+      BuildMI(MBB, I, TII.get(ARM::LDR), DestReg)
+      .addFrameIndex(FI).addReg(0).addImm(0);
+  } else if (RC == ARM::DPRRegisterClass) {
+    BuildMI(MBB, I, TII.get(ARM::FLDD), DestReg)
+      .addFrameIndex(FI).addImm(0);
+  } else {
+    assert(RC == ARM::SPRRegisterClass && "Unknown regclass!");
+    BuildMI(MBB, I, TII.get(ARM::FLDS), DestReg)
+      .addFrameIndex(FI).addImm(0);
+  }
 }
 
 void ARMRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
-                                     MachineBasicBlock::iterator I,
-                                     unsigned DestReg, unsigned SrcReg,
-                                     const TargetRegisterClass *RC) const {
-  assert(RC == ARM::IntRegsRegisterClass ||
-         RC == ARM::FPRegsRegisterClass  ||
-         RC == ARM::DFPRegsRegisterClass);
-
-  if (RC == ARM::IntRegsRegisterClass)
-    BuildMI(MBB, I, TII.get(ARM::MOV), DestReg).addReg(SrcReg).addImm(0)
-      .addImm(ARMShift::LSL);
-  else if (RC == ARM::FPRegsRegisterClass)
+                                   MachineBasicBlock::iterator I,
+                                   unsigned DestReg, unsigned SrcReg,
+                                   const TargetRegisterClass *RC) const {
+  if (RC == ARM::GPRRegisterClass) {
+    MachineFunction &MF = *MBB.getParent();
+    ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+    BuildMI(MBB, I, TII.get(AFI->isThumbFunction() ? ARM::tMOVrr : ARM::MOVrr),
+            DestReg).addReg(SrcReg);
+  } else if (RC == ARM::SPRRegisterClass)
     BuildMI(MBB, I, TII.get(ARM::FCPYS), DestReg).addReg(SrcReg);
-  else
+  else if (RC == ARM::DPRRegisterClass)
     BuildMI(MBB, I, TII.get(ARM::FCPYD), DestReg).addReg(SrcReg);
+  else
+    abort();
 }
 
-MachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr* MI,
-                                                   unsigned OpNum,
-                                                   int FI) const {
-  return NULL;
+MachineInstr *ARMRegisterInfo::foldMemoryOperand(MachineInstr *MI,
+                                                 unsigned OpNum, int FI) const {
+  unsigned Opc = MI->getOpcode();
+  MachineInstr *NewMI = NULL;
+  switch (Opc) {
+  default: break;
+  case ARM::MOVrr: {
+    if (OpNum == 0) { // move -> store
+      unsigned SrcReg = MI->getOperand(1).getReg();
+      NewMI = BuildMI(TII.get(ARM::STR)).addReg(SrcReg).addFrameIndex(FI)
+        .addReg(0).addImm(0);
+    } else {          // move -> load
+      unsigned DstReg = MI->getOperand(0).getReg();
+      NewMI = BuildMI(TII.get(ARM::LDR), DstReg).addFrameIndex(FI).addReg(0)
+        .addImm(0);
+    }
+    break;
+  }
+  case ARM::tMOVrr: {
+    if (OpNum == 0) { // move -> store
+      unsigned SrcReg = MI->getOperand(1).getReg();
+      NewMI = BuildMI(TII.get(ARM::tSTRspi)).addReg(SrcReg).addFrameIndex(FI)
+        .addImm(0);
+    } else {          // move -> load
+      unsigned DstReg = MI->getOperand(0).getReg();
+      NewMI = BuildMI(TII.get(ARM::tLDRspi), DstReg).addFrameIndex(FI)
+        .addImm(0);
+    }
+    break;
+  }
+  case ARM::FCPYS: {
+    if (OpNum == 0) { // move -> store
+      unsigned SrcReg = MI->getOperand(1).getReg();
+      NewMI = BuildMI(TII.get(ARM::FSTS)).addReg(SrcReg).addFrameIndex(FI)
+        .addImm(0);
+    } else {          // move -> load
+      unsigned DstReg = MI->getOperand(0).getReg();
+      NewMI = BuildMI(TII.get(ARM::FLDS), DstReg).addFrameIndex(FI).addImm(0);
+    }
+    break;
+  }
+  case ARM::FCPYD: {
+    if (OpNum == 0) { // move -> store
+      unsigned SrcReg = MI->getOperand(1).getReg();
+      NewMI = BuildMI(TII.get(ARM::FSTD)).addReg(SrcReg).addFrameIndex(FI)
+        .addImm(0);
+    } else {          // move -> load
+      unsigned DstReg = MI->getOperand(0).getReg();
+      NewMI = BuildMI(TII.get(ARM::FLDD), DstReg).addFrameIndex(FI).addImm(0);
+    }
+    break;
+  }
+  }
+
+  if (NewMI)
+    NewMI->copyKillDeadInfo(MI);
+  return NewMI;
 }
 
 const unsigned* ARMRegisterInfo::getCalleeSavedRegs() const {
   static const unsigned CalleeSavedRegs[] = {
-    ARM::R4,  ARM::R5, ARM::R6,  ARM::R7,
-    ARM::R8,  ARM::R9, ARM::R10, ARM::R11,
-    ARM::R14, 0
+    ARM::LR, ARM::R11, ARM::R10, ARM::R9, ARM::R8,
+    ARM::R7, ARM::R6,  ARM::R5,  ARM::R4,
+
+    ARM::D15, ARM::D14, ARM::D13, ARM::D12,
+    ARM::D11, ARM::D10, ARM::D9,  ARM::D8,
+    0
   };
-  return CalleeSavedRegs;
+
+  static const unsigned DarwinCalleeSavedRegs[] = {
+    ARM::LR,  ARM::R7,  ARM::R6, ARM::R5, ARM::R4,
+    ARM::R11, ARM::R10, ARM::R9, ARM::R8,
+
+    ARM::D15, ARM::D14, ARM::D13, ARM::D12,
+    ARM::D11, ARM::D10, ARM::D9,  ARM::D8,
+    0
+  };
+  return STI.isDarwin() ? DarwinCalleeSavedRegs : CalleeSavedRegs;
 }
 
 const TargetRegisterClass* const *
 ARMRegisterInfo::getCalleeSavedRegClasses() const {
   static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
-    &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass,
-    &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass, &ARM::IntRegsRegClass,
-    &ARM::IntRegsRegClass, 0
+    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
+    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
+    &ARM::GPRRegClass, &ARM::GPRRegClass, &ARM::GPRRegClass,
+
+    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
+    &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass, &ARM::DPRRegClass,
+    0
   };
   return CalleeSavedRegClasses;
 }
 
+/// 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(const MachineFunction &MF) {
+  return NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects();
+}
+
+/// emitARMRegPlusImmediate - Emit a series of instructions to materialize
+/// a destreg = basereg + immediate in ARM code.
+static
+void emitARMRegPlusImmediate(MachineBasicBlock &MBB,
+                             MachineBasicBlock::iterator &MBBI,
+                             unsigned DestReg, unsigned BaseReg,
+                             int NumBytes, const TargetInstrInfo &TII) {
+  bool isSub = NumBytes < 0;
+  if (isSub) NumBytes = -NumBytes;
+
+  while (NumBytes) {
+    unsigned RotAmt = ARM_AM::getSOImmValRotate(NumBytes);
+    unsigned ThisVal = NumBytes & ARM_AM::rotr32(0xFF, RotAmt);
+    assert(ThisVal && "Didn't extract field correctly");
+    
+    // We will handle these bits from offset, clear them.
+    NumBytes &= ~ThisVal;
+    
+    // Get the properly encoded SOImmVal field.
+    int SOImmVal = ARM_AM::getSOImmVal(ThisVal);
+    assert(SOImmVal != -1 && "Bit extraction didn't work?");
+    
+    // Build the new ADD / SUB.
+    BuildMI(MBB, MBBI, TII.get(isSub ? ARM::SUBri : ARM::ADDri), DestReg)
+      .addReg(BaseReg).addImm(SOImmVal);
+    BaseReg = DestReg;
+  }
+}
+
+/// isLowRegister - Returns true if the register is low register r0-r7.
+///
+static bool isLowRegister(unsigned Reg) {
+  using namespace ARM;
+  switch (Reg) {
+  case R0:  case R1:  case R2:  case R3:
+  case R4:  case R5:  case R6:  case R7:
+    return true;
+  default:
+    return false;
+  }
+}
+
+/// emitThumbRegPlusImmediate - Emit a series of instructions to materialize
+/// a destreg = basereg + immediate in Thumb code.
+static
+void emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
+                               MachineBasicBlock::iterator &MBBI,
+                               unsigned DestReg, unsigned BaseReg,
+                               int NumBytes, const TargetInstrInfo &TII) {
+  bool isSub = NumBytes < 0;
+  unsigned Bytes = (unsigned)NumBytes;
+  if (isSub) Bytes = -NumBytes;
+  bool isMul4 = (Bytes & 3) == 0;
+  bool isTwoAddr = false;
+  unsigned NumBits = 1;
+  unsigned Opc = 0;
+  unsigned ExtraOpc = 0;
+
+  if (DestReg == BaseReg && BaseReg == ARM::SP) {
+    assert(isMul4 && "Thumb sp inc / dec size must be multiple of 4!");
+    Bytes >>= 2;  // Implicitly multiplied by 4.
+    NumBits = 7;
+    Opc = isSub ? ARM::tSUBspi : ARM::tADDspi;
+    isTwoAddr = true;
+  } else if (!isSub && BaseReg == ARM::SP) {
+    if (!isMul4) {
+      Bytes &= ~3;
+      ExtraOpc = ARM::tADDi3;
+    }
+    Bytes >>= 2;  // Implicitly multiplied by 4.
+    NumBits = 8;
+    Opc = ARM::tADDrSPi;
+  } else {
+    if (DestReg != BaseReg) {
+      if (isLowRegister(DestReg) && isLowRegister(BaseReg)) {
+        // If both are low registers, emit DestReg = add BaseReg, max(Imm, 7)
+        unsigned Chunk = (1 << 3) - 1;
+        unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
+        Bytes -= ThisVal;
+        BuildMI(MBB, MBBI, TII.get(isSub ? ARM::tSUBi3 : ARM::tADDi3), DestReg)
+          .addReg(BaseReg).addImm(ThisVal);
+      } else {
+        BuildMI(MBB, MBBI, TII.get(ARM::tMOVrr), DestReg).addReg(BaseReg);
+      }
+      BaseReg = DestReg;
+    }
+    NumBits = 8;
+    Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
+    isTwoAddr = true;
+  }
+
+  unsigned Chunk = (1 << NumBits) - 1;
+  while (Bytes) {
+    unsigned ThisVal = (Bytes > Chunk) ? Chunk : Bytes;
+    Bytes -= ThisVal;    
+    // Build the new tADD / tSUB.
+    if (isTwoAddr)
+      BuildMI(MBB, MBBI, TII.get(Opc), DestReg).addImm(ThisVal);
+    else {
+      BuildMI(MBB, MBBI, TII.get(Opc), DestReg).addReg(BaseReg).addImm(ThisVal);
+      BaseReg = DestReg;
+
+      if (Opc == ARM::tADDrSPi) {
+        // r4 = add sp, imm
+        // r4 = add r4, imm
+        // ...
+        NumBits = 8;
+        Opc = isSub ? ARM::tSUBi8 : ARM::tADDi8;
+        isTwoAddr = true;
+      }
+    }
+  }
+
+  if (ExtraOpc)
+    BuildMI(MBB, MBBI, TII.get(ExtraOpc), DestReg).addReg(DestReg)
+      .addImm(((unsigned)NumBytes) & 3);
+}
+
+static
+void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
+                  int NumBytes, bool isThumb, const TargetInstrInfo &TII) {
+  if (isThumb)
+    emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII);
+  else
+    emitARMRegPlusImmediate(MBB, MBBI, ARM::SP, ARM::SP, NumBytes, TII);
+}
+
 void ARMRegisterInfo::
 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
                               MachineBasicBlock::iterator I) const {
-  if (hasFP(MF)) {
+  if (MF.getFrameInfo()->hasVarSizedObjects()) {
+    // If we have alloca, convert as follows:
+    // ADJCALLSTACKDOWN -> sub, sp, sp, amount
+    // ADJCALLSTACKUP   -> add, sp, sp, amount
     MachineInstr *Old = I;
     unsigned Amount = Old->getOperand(0).getImmedValue();
     if (Amount != 0) {
+      ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+      // 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() == ARM::ADJCALLSTACKDOWN) {
-        // sub sp, sp, amount
-	splitInstructionWithImmediate(MBB, I, TII.get(ARM::SUB), ARM::R13,
-				   ARM::R13, Amount);
+        emitSPUpdate(MBB, I, -Amount, AFI->isThumbFunction(), TII);
       } else {
-        // add sp, sp, amount
         assert(Old->getOpcode() == ARM::ADJCALLSTACKUP);
-	splitInstructionWithImmediate(MBB, I, TII.get(ARM::ADD), ARM::R13,
-				   ARM::R13, Amount);
+        emitSPUpdate(MBB, I, Amount, AFI->isThumbFunction(), TII);
       }
     }
   }
   MBB.erase(I);
 }
 
-void
-ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
+/// emitThumbConstant - Emit a series of instructions to materialize a
+/// constant.
+static void emitThumbConstant(MachineBasicBlock &MBB,
+                              MachineBasicBlock::iterator &MBBI,
+                              unsigned DestReg, int Imm,
+                              const TargetInstrInfo &TII) {
+  bool isSub = Imm < 0;
+  if (isSub) Imm = -Imm;
+
+  int Chunk = (1 << 8) - 1;
+  int ThisVal = (Imm > Chunk) ? Chunk : Imm;
+  Imm -= ThisVal;
+  BuildMI(MBB, MBBI, TII.get(ARM::tMOVri8), DestReg).addImm(ThisVal);
+  if (Imm > 0) 
+    emitThumbRegPlusImmediate(MBB, MBBI, DestReg, DestReg, Imm, TII);
+  if (isSub)
+    BuildMI(MBB, MBBI, TII.get(ARM::tNEG), DestReg).addReg(DestReg);
+}
+
+void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{
+  unsigned i = 0;
   MachineInstr &MI = *II;
   MachineBasicBlock &MBB = *MI.getParent();
   MachineFunction &MF = *MBB.getParent();
+  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+  bool isThumb = AFI->isThumbFunction();
 
-  assert (MI.getOpcode() == ARM::LDR ||
-          MI.getOpcode() == ARM::STR ||
-          MI.getOpcode() == ARM::ADD);
+  while (!MI.getOperand(i).isFrameIndex()) {
+    ++i;
+    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
+  }
+  
+  unsigned FrameReg = ARM::SP;
+  int FrameIndex = MI.getOperand(i).getFrameIndex();
+  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 
+               MF.getFrameInfo()->getStackSize();
 
-  unsigned FrameIdx = 1;
-  unsigned   OffIdx = 2;
+  if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
+    Offset -= AFI->getGPRCalleeSavedArea1Offset();
+  else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
+    Offset -= AFI->getGPRCalleeSavedArea2Offset();
+  else if (AFI->isDPRCalleeSavedAreaFrame(FrameIndex))
+    Offset -= AFI->getDPRCalleeSavedAreaOffset();
+  else if (MF.getFrameInfo()->hasVarSizedObjects()) {
+    // There is alloca()'s in this function, must reference off the frame
+    // pointer instead.
+    FrameReg = getFrameRegister(MF);
+    Offset -= AFI->getFramePtrSpillOffset();
+  }
 
-  int FrameIndex = MI.getOperand(FrameIdx).getFrameIndex();
+  unsigned Opcode = MI.getOpcode();
+  const TargetInstrDescriptor &Desc = TII.get(Opcode);
+  unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
+  bool isSub = false;
+  
+  if (Opcode == ARM::ADDri) {
+    Offset += MI.getOperand(i+1).getImm();
+    if (Offset == 0) {
+      // Turn it into a move.
+      MI.setInstrDescriptor(TII.get(ARM::MOVrr));
+      MI.getOperand(i).ChangeToRegister(FrameReg, false);
+      MI.RemoveOperand(i+1);
+      return;
+    } else if (Offset < 0) {
+      Offset = -Offset;
+      isSub = true;
+      MI.setInstrDescriptor(TII.get(ARM::SUBri));
+    }
 
-  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
-               MI.getOperand(OffIdx).getImmedValue();
+    // Common case: small offset, fits into instruction.
+    int ImmedOffset = ARM_AM::getSOImmVal(Offset);
+    if (ImmedOffset != -1) {
+      // Replace the FrameIndex with sp / fp
+      MI.getOperand(i).ChangeToRegister(FrameReg, false);
+      MI.getOperand(i+1).ChangeToImmediate(ImmedOffset);
+      return;
+    }
+    
+    // Otherwise, we fallback to common code below to form the imm offset with
+    // a sequence of ADDri instructions.  First though, pull as much of the imm
+    // into this ADDri as possible.
+    unsigned RotAmt = ARM_AM::getSOImmValRotate(Offset);
+    unsigned ThisImmVal = Offset & ARM_AM::rotr32(0xFF, (32-RotAmt) & 31);
+    
+    // We will handle these bits from offset, clear them.
+    Offset &= ~ThisImmVal;
+    
+    // Get the properly encoded SOImmVal field.
+    int ThisSOImmVal = ARM_AM::getSOImmVal(ThisImmVal);
+    assert(ThisSOImmVal != -1 && "Bit extraction didn't work?");    
+    MI.getOperand(i+1).ChangeToImmediate(ThisSOImmVal);
+  } else if (Opcode == ARM::tADDrSPi) {
+    Offset += MI.getOperand(i+1).getImm();
+    assert((Offset & 3) == 0 &&
+           "add/sub sp, #imm immediate must be multiple of 4!");
+    Offset >>= 2;
+    if (Offset == 0) {
+      // Turn it into a move.
+      MI.setInstrDescriptor(TII.get(ARM::tMOVrr));
+      MI.getOperand(i).ChangeToRegister(FrameReg, false);
+      MI.RemoveOperand(i+1);
+      return;
+    }
 
-  unsigned StackSize = MF.getFrameInfo()->getStackSize();
+    // Common case: small offset, fits into instruction.
+    if ((Offset & ~255U) == 0) {
+      // Replace the FrameIndex with sp / fp
+      MI.getOperand(i).ChangeToRegister(FrameReg, false);
+      MI.getOperand(i+1).ChangeToImmediate(Offset);
+      return;
+    }
 
-  Offset += StackSize;
-
-  assert (Offset >= 0);
-  unsigned BaseRegister = hasFP(MF) ? ARM::R11 : ARM::R13;
-  if (Offset < 4096) {
-    // Replace the FrameIndex with r13
-    MI.getOperand(FrameIdx).ChangeToRegister(BaseRegister, false);
-    // Replace the ldr offset with Offset
-    MI.getOperand(OffIdx).ChangeToImmediate(Offset);
+    unsigned DestReg = MI.getOperand(0).getReg();
+    if (Offset > 0) {
+      // Translate r0 = add sp, imm to
+      // r0 = add sp, 255*4
+      // r0 = add r0, (imm - 255*4)
+      MI.getOperand(i).ChangeToRegister(FrameReg, false);
+      MI.getOperand(i+1).ChangeToImmediate(255);
+      Offset = (Offset - 255) << 2;
+      MachineBasicBlock::iterator NII = next(II);
+      emitThumbRegPlusImmediate(MBB, NII, DestReg, DestReg, Offset, TII);
+    } else {
+      // Translate r0 = add sp, -imm to
+      // r0 = -imm (this is then translated into a series of instructons)
+      // r0 = add r0, sp
+      Offset <<= 2;
+      emitThumbConstant(MBB, II, DestReg, Offset, TII);
+      MI.setInstrDescriptor(TII.get(ARM::tADDhirr));
+      MI.getOperand(i).ChangeToRegister(DestReg, false);
+      MI.getOperand(i+1).ChangeToRegister(FrameReg, false);
+    }
+    return;
   } else {
-    // Insert a set of r12 with the full address
-    // r12 = r13 + offset
-    MachineBasicBlock *MBB2 = MI.getParent();
-    splitInstructionWithImmediate(*MBB2, II, TII.get(ARM::ADD), ARM::R12,
-			       BaseRegister, Offset);
+    unsigned ImmIdx = 0;
+    int InstrOffs = 0;
+    unsigned NumBits = 0;
+    unsigned Scale = 1;
+    switch (AddrMode) {
+    case ARMII::AddrMode2: {
+      ImmIdx = i+2;
+      InstrOffs = ARM_AM::getAM2Offset(MI.getOperand(ImmIdx).getImm());
+      if (ARM_AM::getAM2Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
+        InstrOffs *= -1;
+      NumBits = 12;
+      break;
+    }
+    case ARMII::AddrMode3: {
+      ImmIdx = i+2;
+      InstrOffs = ARM_AM::getAM3Offset(MI.getOperand(ImmIdx).getImm());
+      if (ARM_AM::getAM3Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
+        InstrOffs *= -1;
+      NumBits = 8;
+      break;
+    }
+    case ARMII::AddrMode5: {
+      ImmIdx = i+1;
+      InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm());
+      if (ARM_AM::getAM5Op(MI.getOperand(ImmIdx).getImm()) == ARM_AM::sub)
+        InstrOffs *= -1;
+      NumBits = 8;
+      Scale = 4;
+      break;
+    }
+    case ARMII::AddrModeTs: {
+      ImmIdx = i+1;
+      InstrOffs = MI.getOperand(ImmIdx).getImm();
+      NumBits = 8;
+      Scale = 4;
+      break;
+    }
+    default:
+      std::cerr << "Unsupported addressing mode!\n";
+      abort();
+      break;
+    }
 
-    // Replace the FrameIndex with r12
-    MI.getOperand(FrameIdx).ChangeToRegister(ARM::R12, false);
+    Offset += InstrOffs * Scale;
+    assert((Scale == 1 || (Offset & (Scale-1)) == 0) &&
+           "Can't encode this offset!");
+    if (Offset < 0) {
+      Offset = -Offset;
+      isSub = true;
+    }
+
+    MachineOperand &ImmOp = MI.getOperand(ImmIdx);
+    int ImmedOffset = Offset / Scale;
+    unsigned Mask = (1 << NumBits) - 1;
+    if ((unsigned)Offset <= Mask * Scale) {
+      // Replace the FrameIndex with sp
+      MI.getOperand(i).ChangeToRegister(FrameReg, false);
+      if (isSub)
+        ImmedOffset |= 1 << NumBits;
+      ImmOp.ChangeToImmediate(ImmedOffset);
+      return;
+    }
+
+    // Otherwise, it didn't fit.  Pull in what we can to simplify the immediate.
+    ImmedOffset = ImmedOffset & Mask;
+    if (isSub)
+      ImmedOffset |= 1 << NumBits;
+    ImmOp.ChangeToImmediate(ImmedOffset);
+    Offset &= ~(Mask*Scale);
+  }
+  
+  // If we get here, the immediate doesn't fit into the instruction.  We folded
+  // as much as possible above, handle the rest, providing a register that is
+  // SP+LargeImm.
+  assert(Offset && "This code isn't needed if offset already handled!");
+
+  if (isThumb) {
+    if (TII.isLoad(Opcode)) {
+      // Use the destination register to materialize sp + offset.
+      unsigned TmpReg = MI.getOperand(0).getReg();
+      emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg,
+                                isSub ? -Offset : Offset, TII);
+      MI.getOperand(i).ChangeToRegister(TmpReg, false);
+    } else if (TII.isStore(Opcode)) {
+      // FIXME! This is horrific!!! We need register scavenging.
+      // Our temporary workaround has marked r3 unavailable. Of course, r3 is
+      // also a ABI register so it's possible that is is the register that is
+      // being storing here. If that's the case, we do the following:
+      // r12 = r2
+      // Use r2 to materialize sp + offset
+      // str r12, r2
+      // r2 = r12
+      unsigned DestReg = MI.getOperand(0).getReg();
+      unsigned TmpReg = ARM::R3;
+      if (DestReg == ARM::R3) {
+        BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R12).addReg(ARM::R2);
+        TmpReg = ARM::R2;
+      }
+      emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg,
+                                isSub ? -Offset : Offset, TII);
+      MI.getOperand(i).ChangeToRegister(DestReg, false);
+      if (DestReg == ARM::R3)
+        BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R2).addReg(ARM::R12);
+    } else
+      assert(false && "Unexpected opcode!");
+  } else {
+    // Insert a set of r12 with the full address: r12 = sp + offset
+    // If the offset we have is too large to fit into the instruction, we need
+    // to form it with a series of ADDri's.  Do this by taking 8-bit chunks
+    // out of 'Offset'.
+    emitARMRegPlusImmediate(MBB, II, ARM::R12, FrameReg,
+                            isSub ? -Offset : Offset, TII);
+    MI.getOperand(i).ChangeToRegister(ARM::R12, false);
   }
 }
 
 void ARMRegisterInfo::
-processFunctionBeforeFrameFinalized(MachineFunction &MF) const {}
+processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const {
+  // This tells PEI to spill the FP as if it is any other callee-save register to
+  // take advantage the eliminateFrameIndex machinery. This also ensures it is
+  // spilled in the order specified by getCalleeSavedRegs() to make it easier
+  // to combine multiple loads / stores.
+  bool FramePtrSpilled = MF.getFrameInfo()->hasVarSizedObjects();
+  bool CS1Spilled = false;
+  bool LRSpilled = false;
+  unsigned NumGPRSpills = 0;
+  SmallVector<unsigned, 4> UnspilledCS1GPRs;
+  SmallVector<unsigned, 4> UnspilledCS2GPRs;
+  if (!FramePtrSpilled && NoFramePointerElim) {
+    // Don't spill FP if the frame can be eliminated. This is determined
+    // by scanning the callee-save registers to see if any is used.
+    const unsigned *CSRegs = getCalleeSavedRegs();
+    const TargetRegisterClass* const *CSRegClasses = getCalleeSavedRegClasses();
+    for (unsigned i = 0; CSRegs[i]; ++i) {
+      unsigned Reg = CSRegs[i];
+      bool Spilled = false;
+      if (MF.isPhysRegUsed(Reg)) {
+        Spilled = true;
+        FramePtrSpilled = true;
+      } else {
+        // Check alias registers too.
+        for (const unsigned *Aliases = getAliasSet(Reg); *Aliases; ++Aliases) {
+          if (MF.isPhysRegUsed(*Aliases)) {
+            Spilled = true;
+            FramePtrSpilled = true;
+          }
+        }
+      }
+
+      if (CSRegClasses[i] == &ARM::GPRRegClass) {
+        if (Spilled) {
+          NumGPRSpills++;
+
+          // Keep track if LR and any of R4, R5, R6, and R7 is spilled.
+          switch (Reg) {
+          case ARM::LR:
+            LRSpilled = true;
+            // Fallthrough
+          case ARM::R4:
+          case ARM::R5:
+          case ARM::R6:
+          case ARM::R7:
+            CS1Spilled = true;
+            break;
+          default:
+            break;
+          }
+        } else { 
+          switch (Reg) {
+          case ARM::R4:
+          case ARM::R5:
+          case ARM::R6:
+          case ARM::R7:
+          case ARM::LR:
+            UnspilledCS1GPRs.push_back(Reg);
+            break;
+          default:
+            UnspilledCS2GPRs.push_back(Reg);
+            break;
+          }
+        }
+      }
+    }
+  }
+
+  if (FramePtrSpilled) {
+    ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+    AFI->setFramePtrSpilled(true);
+
+    // If LR is not spilled, but at least one of R4, R5, R6, and R7 is spilled.
+    // Spill LR as well so we can fold BX_RET to the registers restore (LDM).
+    if (!LRSpilled && CS1Spilled) {
+      MF.changePhyRegUsed(ARM::LR, true);
+      NumGPRSpills++;
+      UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(),
+                                    UnspilledCS1GPRs.end(), (unsigned)ARM::LR));
+    }
+
+    // If stack and double are 8-byte aligned and we are spilling a odd number
+    // of GPRs. Spill one extra callee save GPR so we won't have to pad between
+    // the integer and double callee save areas.
+    unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
+    if (TargetAlign == 8 && (NumGPRSpills & 1)) {
+      if (CS1Spilled && !UnspilledCS1GPRs.empty())
+        MF.changePhyRegUsed(UnspilledCS1GPRs.front(), true);
+      else
+        MF.changePhyRegUsed(UnspilledCS2GPRs.front(), true);
+    }
+    MF.changePhyRegUsed(FramePtr, true);
+  }
+}
+
+/// Move iterator pass the next bunch of callee save load / store ops for
+/// the particular spill area (1: integer area 1, 2: integer area 2,
+/// 3: fp area, 0: don't care).
+static void movePastCSLoadStoreOps(MachineBasicBlock &MBB,
+                                   MachineBasicBlock::iterator &MBBI,
+                                   int Opc, unsigned Area,
+                                   const ARMSubtarget &STI) {
+  while (MBBI != MBB.end() &&
+         MBBI->getOpcode() == Opc && MBBI->getOperand(1).isFrameIndex()) {
+    if (Area != 0) {
+      bool Done = false;
+      unsigned Category = 0;
+      switch (MBBI->getOperand(0).getReg()) {
+      case ARM::R4:
+      case ARM::R5:
+      case ARM::R6:
+      case ARM::R7:
+      case ARM::LR:
+        Category = 1;
+        break;
+      case ARM::R8:
+      case ARM::R9:
+      case ARM::R10:
+      case ARM::R11:
+        Category = STI.isDarwin() ? 2 : 1;
+        break;
+      case ARM::D8:
+      case ARM::D9:
+      case ARM::D10:
+      case ARM::D11:
+      case ARM::D12:
+      case ARM::D13:
+      case ARM::D14:
+      case ARM::D15:
+        Category = 3;
+        break;
+      default:
+        Done = true;
+        break;
+      }
+      if (Done || Category != Area)
+        break;
+    }
+
+    ++MBBI;
+  }
+}
 
 void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
   MachineBasicBlock &MBB = MF.front();
   MachineBasicBlock::iterator MBBI = MBB.begin();
   MachineFrameInfo  *MFI = MF.getFrameInfo();
-  int           NumBytes = (int) MFI->getStackSize();
+  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+  bool isThumb = AFI->isThumbFunction();
+  unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
+  unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
+  unsigned NumBytes = MFI->getStackSize();
+  const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
 
-  bool HasFP = hasFP(MF);
+  // Determine the sizes of each callee-save spill areas and record which frame
+  // belongs to which callee-save spill areas.
+  unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
+  int FramePtrSpillFI = 0;
+  if (AFI->isFramePtrSpilled()) {
+    if (VARegSaveSize)
+      emitSPUpdate(MBB, MBBI, -VARegSaveSize, isThumb, TII);
 
-  if (MFI->hasCalls()) {
+    for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
+      unsigned Reg = CSI[i].getReg();
+      int FI = CSI[i].getFrameIdx();
+      switch (Reg) {
+      case ARM::R4:
+      case ARM::R5:
+      case ARM::R6:
+      case ARM::R7:
+      case ARM::LR:
+        if (Reg == FramePtr)
+          FramePtrSpillFI = FI;
+        AFI->addGPRCalleeSavedArea1Frame(FI);
+        GPRCS1Size += 4;
+        break;
+      case ARM::R8:
+      case ARM::R9:
+      case ARM::R10:
+      case ARM::R11:
+        if (Reg == FramePtr)
+          FramePtrSpillFI = FI;
+        if (STI.isDarwin()) {
+          AFI->addGPRCalleeSavedArea2Frame(FI);
+          GPRCS2Size += 4;
+        } else {
+          AFI->addGPRCalleeSavedArea1Frame(FI);
+          GPRCS1Size += 4;
+        }
+        break;
+      default:
+        AFI->addDPRCalleeSavedAreaFrame(FI);
+        DPRCSSize += 8;
+      }
+    }
+
+    if (!isThumb) {
+      // Build the new SUBri to adjust SP for integer callee-save spill area 1.
+      emitSPUpdate(MBB, MBBI, -GPRCS1Size, isThumb, TII);
+      movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 1, STI);
+    } else {
+      if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH)
+        ++MBBI;
+    }
+
+    // Point FP to the stack slot that contains the previous FP.
+    BuildMI(MBB, MBBI, TII.get(isThumb ? ARM::tADDrSPi : ARM::ADDri), FramePtr)
+      .addFrameIndex(FramePtrSpillFI).addImm(0);
+
+    if (!isThumb) {
+      // Build the new SUBri to adjust SP for integer callee-save spill area 2.
+      emitSPUpdate(MBB, MBBI, -GPRCS2Size, false, TII);
+
+      // Build the new SUBri to adjust SP for FP callee-save spill area.
+      movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 2, STI);
+      emitSPUpdate(MBB, MBBI, -DPRCSSize, false, TII);
+    }
+  }
+
+  // If necessary, add one more SUBri to account for the call frame
+  // and/or local storage, alloca area.
+  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();
-  }
+    if (!MF.getFrameInfo()->hasVarSizedObjects())
+      NumBytes += MFI->getMaxCallFrameSize();
 
-  if (HasFP)
-    // Add space for storing the FP
-    NumBytes += 4;
-
-  // Align to 8 bytes
-  NumBytes = ((NumBytes + 7) / 8) * 8;
-
+  // Round the size to a multiple of the alignment.
+  NumBytes = (NumBytes+Align-1)/Align*Align;
   MFI->setStackSize(NumBytes);
 
-  if (NumBytes) {
-    //sub sp, sp, #NumBytes
-    splitInstructionWithImmediate(MBB, MBBI, TII.get(ARM::SUB), ARM::R13,
-                                  ARM::R13, NumBytes);
-  }
+  // Determine starting offsets of spill areas.
+  if (AFI->isFramePtrSpilled()) {
+    unsigned DPRCSOffset  = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
+    unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
+    unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
+    AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes);
+    AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
+    AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
+    AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
+  
+    NumBytes = DPRCSOffset;
+    if (NumBytes) {
+      // Insert it after all the callee-save spills.
+      if (!isThumb)
+        movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 3, STI);
+      emitSPUpdate(MBB, MBBI, -NumBytes, isThumb, TII);
+    }
+  } else 
+    emitSPUpdate(MBB, MBBI, -NumBytes, isThumb, TII);
 
+  AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
+  AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
+  AFI->setDPRCalleeSavedAreaSize(DPRCSSize);
+}
 
-  if (HasFP) {
-    BuildMI(MBB, MBBI, TII.get(ARM::STR))
-      .addReg(ARM::R11).addReg(ARM::R13).addImm(0);
-    BuildMI(MBB, MBBI, TII.get(ARM::MOV), ARM::R11).addReg(ARM::R13).addImm(0).
-      addImm(ARMShift::LSL);
-  }
+static bool isCalleeSavedRegister(unsigned Reg, const unsigned *CSRegs) {
+  for (unsigned i = 0; CSRegs[i]; ++i)
+    if (Reg == CSRegs[i])
+      return true;
+  return false;
+}
+
+static bool isCSRestore(MachineInstr *MI, const unsigned *CSRegs) {
+  return ((MI->getOpcode() == ARM::FLDD ||
+           MI->getOpcode() == ARM::LDR  ||
+           MI->getOpcode() == ARM::tLDRspi) &&
+          MI->getOperand(1).isFrameIndex() &&
+          isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs));
 }
 
 void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
 				   MachineBasicBlock &MBB) const {
   MachineBasicBlock::iterator MBBI = prior(MBB.end());
-  assert(MBBI->getOpcode() == ARM::bx &&
+  assert((MBBI->getOpcode() == ARM::BX_RET ||
+          MBBI->getOpcode() == ARM::tBX_RET ||
+          MBBI->getOpcode() == ARM::tPOP_RET) &&
          "Can only insert epilog into returning blocks");
 
   MachineFrameInfo *MFI = MF.getFrameInfo();
-  int          NumBytes = (int) MFI->getStackSize();
+  ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
+  bool isThumb = AFI->isThumbFunction();
+  unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
+  int NumBytes = (int)MFI->getStackSize();
+  if (AFI->isFramePtrSpilled()) {
+    // Unwind MBBI to point to first LDR / FLDD.
+    const unsigned *CSRegs = getCalleeSavedRegs();
+    if (MBBI != MBB.begin()) {
+      do
+        --MBBI;
+      while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs));
+      if (!isCSRestore(MBBI, CSRegs))
+        ++MBBI;
+    }
 
-  if (hasFP(MF)) {
-    BuildMI(MBB, MBBI, TII.get(ARM::MOV), ARM::R13).addReg(ARM::R11).addImm(0).
-      addImm(ARMShift::LSL);
-    BuildMI(MBB, MBBI, TII.get(ARM::LDR), ARM::R11).addReg(ARM::R13).addImm(0);
+    // Move SP to start of FP callee save spill area.
+    NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
+                 AFI->getGPRCalleeSavedArea2Size() +
+                 AFI->getDPRCalleeSavedAreaSize());
+    if (isThumb)
+      emitSPUpdate(MBB, MBBI, -NumBytes, isThumb, TII);
+    else {
+      NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
+      // Reset SP based on frame pointer only if the stack frame extends beyond
+      // frame pointer stack slot.
+      if (AFI->getGPRCalleeSavedArea2Size() ||
+          AFI->getDPRCalleeSavedAreaSize()  ||
+          AFI->getDPRCalleeSavedAreaOffset())
+        if (NumBytes)
+          BuildMI(MBB, MBBI, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr)
+            .addImm(NumBytes);
+        else
+          BuildMI(MBB, MBBI, TII.get(isThumb ? ARM::tMOVrr : ARM::MOVrr),
+                  ARM::SP).addReg(FramePtr);
+
+      // Move SP to start of integer callee save spill area 2.
+      movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 3, STI);
+      emitSPUpdate(MBB, MBBI, AFI->getDPRCalleeSavedAreaSize(), false, TII);
+
+      // Move SP to start of integer callee save spill area 1.
+      movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 2, STI);
+      emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea2Size(), false, TII);
+
+      // Move SP to SP upon entry to the function.
+      movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 1, STI);
+      emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea1Size(), false, TII);
+    }
+
+    if (VARegSaveSize)
+      emitSPUpdate(MBB, MBBI, VARegSaveSize, isThumb, TII);
+  } else if (NumBytes != 0) {
+    emitSPUpdate(MBB, MBBI, NumBytes, isThumb, TII);
   }
-
-  if (NumBytes){
-    //add sp, sp, #NumBytes
-    splitInstructionWithImmediate(MBB, MBBI, TII.get(ARM::ADD), ARM::R13,
-                                  ARM::R13, NumBytes);
-  }
-
 }
 
 unsigned ARMRegisterInfo::getRARegister() const {
-  return ARM::R14;
+  return ARM::LR;
 }
 
 unsigned ARMRegisterInfo::getFrameRegister(MachineFunction &MF) const {
-  return hasFP(MF) ? ARM::R11 : ARM::R13;
+  return STI.useThumbBacktraces() ? ARM::R7 : ARM::R11;
 }
 
 #include "ARMGenRegisterInfo.inc"
diff --git a/llvm/lib/Target/ARM/ARMRegisterInfo.h b/llvm/lib/Target/ARM/ARMRegisterInfo.h
index 16c277e..6b9ac39 100644
--- a/llvm/lib/Target/ARM/ARMRegisterInfo.h
+++ b/llvm/lib/Target/ARM/ARMRegisterInfo.h
@@ -17,18 +17,36 @@
 
 #include "llvm/Target/MRegisterInfo.h"
 #include "ARMGenRegisterInfo.h.inc"
+#include <set>
 
 namespace llvm {
-
-class Type;
-class TargetInstrInfo;
+  class TargetInstrInfo;
+  class ARMSubtarget;
+  class Type;
 
 struct ARMRegisterInfo : public ARMGenRegisterInfo {
   const TargetInstrInfo &TII;
+  const ARMSubtarget &STI;
+private:
+  /// FramePtr - ARM physical register used as frame ptr.
+  unsigned FramePtr;
 
-  ARMRegisterInfo(const TargetInstrInfo &tii);
+public:
+  ARMRegisterInfo(const TargetInstrInfo &tii, const ARMSubtarget &STI);
+
+  /// getRegisterNumbering - Given the enum value for some register, e.g.
+  /// ARM::LR, return the number that it corresponds to (e.g. 14).
+  static unsigned getRegisterNumbering(unsigned RegEnum);
 
   /// Code Generation virtual methods...
+  bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
+                                 MachineBasicBlock::iterator MI,
+                                 const std::vector<CalleeSavedInfo> &CSI) const;
+
+  bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
+                                   MachineBasicBlock::iterator MI,
+                                 const std::vector<CalleeSavedInfo> &CSI) const;
+
   void storeRegToStackSlot(MachineBasicBlock &MBB,
                            MachineBasicBlock::iterator MBBI,
                            unsigned SrcReg, int FrameIndex,
@@ -43,9 +61,8 @@
                     unsigned DestReg, unsigned SrcReg,
                     const TargetRegisterClass *RC) const;
 
-  virtual MachineInstr* foldMemoryOperand(MachineInstr* MI,
-                                          unsigned OpNum,
-                                          int FrameIndex) const;
+  MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum,
+                                  int FrameIndex) const;
 
   const unsigned *getCalleeSavedRegs() const;
 
@@ -57,7 +74,7 @@
 
   void eliminateFrameIndex(MachineBasicBlock::iterator II) const;
 
-  void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
+  void processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const;
 
   void emitPrologue(MachineFunction &MF) const;
   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
diff --git a/llvm/lib/Target/ARM/ARMRegisterInfo.td b/llvm/lib/Target/ARM/ARMRegisterInfo.td
index 24f53d9..51d52c6 100644
--- a/llvm/lib/Target/ARM/ARMRegisterInfo.td
+++ b/llvm/lib/Target/ARM/ARMRegisterInfo.td
@@ -1,4 +1,4 @@
-//===- ARMRegisterInfo.td - ARM Register defs ----------*- tablegen -*-===//
+//===- ARMRegisterInfo.td - ARM Register defs -------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -13,129 +13,169 @@
 //===----------------------------------------------------------------------===//
 
 // Registers are identified with 4-bit ID numbers.
-class ARMReg<string n> : Register<n> {
-  let Namespace = "ARM";
-}
-
-// Ri - 32-bit integer registers
-class Ri<bits<4> num, string n> : ARMReg<n> {
+class ARMReg<bits<4> num, string n, list<Register> aliases = []> : Register<n> {
   field bits<4> Num;
-  let Num = num;
-}
-// Rf - 32-bit floating-point registers
-class Rf<bits<5> num, string n> : ARMReg<n> {
-  field bits<5> Num;
-  let Num = num;
-}
-// Rd - Slots in the FP register file for 64-bit floating-point values.
-class Rd<bits<5> num, string n, list<Register> aliases> : ARMReg<n> {
-  field bits<5> Num;
-  let Num = num;
+  let Namespace = "ARM";
   let Aliases = aliases;
 }
 
+class ARMFReg<bits<5> num, string n> : Register<n> {
+  field bits<5> Num;
+  let Namespace = "ARM";
+}
+
 // Integer registers
-def R0  : Ri< 0, "R0">,  DwarfRegNum<0>;
-def R1  : Ri< 1, "R1">,  DwarfRegNum<1>;
-def R2  : Ri< 2, "R2">,  DwarfRegNum<2>;
-def R3  : Ri< 3, "R3">,  DwarfRegNum<3>;
-def R4  : Ri< 4, "R4">,  DwarfRegNum<4>;
-def R5  : Ri< 5, "R5">,  DwarfRegNum<5>;
-def R6  : Ri< 6, "R6">,  DwarfRegNum<6>;
-def R7  : Ri< 7, "R7">,  DwarfRegNum<7>;
-def R8  : Ri< 8, "R8">,  DwarfRegNum<8>;
-def R9  : Ri< 9, "R9">,  DwarfRegNum<9>;
-def R10 : Ri<10, "R10">, DwarfRegNum<10>;
-def R11 : Ri<11, "R11">, DwarfRegNum<11>;
-def R12 : Ri<12, "R12">, DwarfRegNum<12>;
-def R13 : Ri<13, "R13">, DwarfRegNum<13>;
-def R14 : Ri<14, "R14">, DwarfRegNum<14>;
-def R15 : Ri<15, "R15">, DwarfRegNum<15>;
+def R0  : ARMReg< 0, "r0">,  DwarfRegNum<0>;
+def R1  : ARMReg< 1, "r1">,  DwarfRegNum<1>;
+def R2  : ARMReg< 2, "r2">,  DwarfRegNum<2>;
+def R3  : ARMReg< 3, "r3">,  DwarfRegNum<3>;
+def R4  : ARMReg< 4, "r4">,  DwarfRegNum<4>;
+def R5  : ARMReg< 5, "r5">,  DwarfRegNum<5>;
+def R6  : ARMReg< 6, "r6">,  DwarfRegNum<6>;
+def R7  : ARMReg< 7, "r7">,  DwarfRegNum<7>;
+def R8  : ARMReg< 8, "r8">,  DwarfRegNum<8>;
+def R9  : ARMReg< 9, "r9">,  DwarfRegNum<9>;
+def R10 : ARMReg<10, "r10">, DwarfRegNum<10>;
+def R11 : ARMReg<11, "r11">, DwarfRegNum<11>;
+def R12 : ARMReg<12, "r12">, DwarfRegNum<12>;
+def SP  : ARMReg<13, "sp">,  DwarfRegNum<13>;
+def LR  : ARMReg<14, "lr">,  DwarfRegNum<14>;
+def PC  : ARMReg<15, "pc">,  DwarfRegNum<15>;
 
-// TODO: update to VFP-v3
-// Floating-point registers
-def S0  : Rf< 0,  "S0">, DwarfRegNum<64>;
-def S1  : Rf< 1,  "S1">, DwarfRegNum<65>;
-def S2  : Rf< 2,  "S2">, DwarfRegNum<66>;
-def S3  : Rf< 3,  "S3">, DwarfRegNum<67>;
-def S4  : Rf< 4,  "S4">, DwarfRegNum<68>;
-def S5  : Rf< 5,  "S5">, DwarfRegNum<69>;
-def S6  : Rf< 6,  "S6">, DwarfRegNum<70>;
-def S7  : Rf< 7,  "S7">, DwarfRegNum<71>;
-def S8  : Rf< 8,  "S8">, DwarfRegNum<72>;
-def S9  : Rf< 9,  "S9">, DwarfRegNum<73>;
-def S10 : Rf<10, "S10">, DwarfRegNum<74>;
-def S11 : Rf<11, "S11">, DwarfRegNum<75>;
-def S12 : Rf<12, "S12">, DwarfRegNum<76>;
-def S13 : Rf<13, "S13">, DwarfRegNum<77>;
-def S14 : Rf<14, "S14">, DwarfRegNum<78>;
-def S15 : Rf<15, "S15">, DwarfRegNum<79>;
-def S16 : Rf<16, "S16">, DwarfRegNum<80>;
-def S17 : Rf<17, "S17">, DwarfRegNum<81>;
-def S18 : Rf<18, "S18">, DwarfRegNum<82>;
-def S19 : Rf<19, "S19">, DwarfRegNum<83>;
-def S20 : Rf<20, "S20">, DwarfRegNum<84>;
-def S21 : Rf<21, "S21">, DwarfRegNum<85>;
-def S22 : Rf<22, "S22">, DwarfRegNum<86>;
-def S23 : Rf<23, "S23">, DwarfRegNum<87>;
-def S24 : Rf<24, "S24">, DwarfRegNum<88>;
-def S25 : Rf<25, "S25">, DwarfRegNum<89>;
-def S26 : Rf<26, "S26">, DwarfRegNum<90>;
-def S27 : Rf<27, "S27">, DwarfRegNum<91>;
-def S28 : Rf<28, "S28">, DwarfRegNum<92>;
-def S29 : Rf<29, "S29">, DwarfRegNum<93>;
-def S30 : Rf<30, "S30">, DwarfRegNum<94>;
-def S31 : Rf<31, "S31">, DwarfRegNum<95>;
+// Float registers
+def S0  : ARMFReg< 0, "s0">;  def S1  : ARMFReg< 1, "s1">;
+def S2  : ARMFReg< 2, "s2">;  def S3  : ARMFReg< 3, "s3">;
+def S4  : ARMFReg< 4, "s4">;  def S5  : ARMFReg< 5, "s5">;
+def S6  : ARMFReg< 6, "s6">;  def S7  : ARMFReg< 7, "s7">;
+def S8  : ARMFReg< 8, "s8">;  def S9  : ARMFReg< 9, "s9">;
+def S10 : ARMFReg<10, "s10">; def S11 : ARMFReg<11, "s11">;
+def S12 : ARMFReg<12, "s12">; def S13 : ARMFReg<13, "s13">;
+def S14 : ARMFReg<14, "s14">; def S15 : ARMFReg<15, "s15">;
+def S16 : ARMFReg<16, "s16">; def S17 : ARMFReg<17, "s17">;
+def S18 : ARMFReg<18, "s18">; def S19 : ARMFReg<19, "s19">;
+def S20 : ARMFReg<20, "s20">; def S21 : ARMFReg<21, "s21">;
+def S22 : ARMFReg<22, "s22">; def S23 : ARMFReg<23, "s23">;
+def S24 : ARMFReg<24, "s24">; def S25 : ARMFReg<25, "s25">;
+def S26 : ARMFReg<26, "s26">; def S27 : ARMFReg<27, "s27">;
+def S28 : ARMFReg<28, "s28">; def S29 : ARMFReg<29, "s29">;
+def S30 : ARMFReg<30, "s30">; def S31 : ARMFReg<31, "s31">;
 
-// Aliases of the S* registers used to hold 64-bit fp values (doubles)
-def D0  : Rd< 0,  "D0", [S0,   S1]>, DwarfRegNum<64>;
-def D1  : Rd< 2,  "D1", [S2,   S3]>, DwarfRegNum<66>;
-def D2  : Rd< 4,  "D2", [S4,   S5]>, DwarfRegNum<68>;
-def D3  : Rd< 6,  "D3", [S6,   S7]>, DwarfRegNum<70>;
-def D4  : Rd< 8,  "D4", [S8,   S9]>, DwarfRegNum<72>;
-def D5  : Rd<10,  "D5", [S10, S11]>, DwarfRegNum<74>;
-def D6  : Rd<12,  "D6", [S12, S13]>, DwarfRegNum<76>;
-def D7  : Rd<14,  "D7", [S14, S15]>, DwarfRegNum<78>;
-def D8  : Rd<16,  "D8", [S16, S17]>, DwarfRegNum<80>;
-def D9  : Rd<18,  "D9", [S18, S19]>, DwarfRegNum<82>;
-def D10 : Rd<20, "D10", [S20, S21]>, DwarfRegNum<84>;
-def D11 : Rd<22, "D11", [S22, S23]>, DwarfRegNum<86>;
-def D12 : Rd<24, "D12", [S24, S25]>, DwarfRegNum<88>;
-def D13 : Rd<26, "D13", [S26, S27]>, DwarfRegNum<90>;
-def D14 : Rd<28, "D14", [S28, S29]>, DwarfRegNum<92>;
-def D15 : Rd<30, "D15", [S30, S31]>, DwarfRegNum<94>;
+// Aliases of the F* registers used to hold 64-bit fp values (doubles)
+def D0  : ARMReg< 0,  "d0", [S0,   S1]>;
+def D1  : ARMReg< 1,  "d1", [S2,   S3]>; 
+def D2  : ARMReg< 2,  "d2", [S4,   S5]>;
+def D3  : ARMReg< 3,  "d3", [S6,   S7]>;
+def D4  : ARMReg< 4,  "d4", [S8,   S9]>;
+def D5  : ARMReg< 5,  "d5", [S10, S11]>;
+def D6  : ARMReg< 6,  "d6", [S12, S13]>;
+def D7  : ARMReg< 7,  "d7", [S14, S15]>;
+def D8  : ARMReg< 8,  "d8", [S16, S17]>;
+def D9  : ARMReg< 9,  "d9", [S18, S19]>;
+def D10 : ARMReg<10, "d10", [S20, S21]>;
+def D11 : ARMReg<11, "d11", [S22, S23]>;
+def D12 : ARMReg<12, "d12", [S24, S25]>;
+def D13 : ARMReg<13, "d13", [S26, S27]>;
+def D14 : ARMReg<14, "d14", [S28, S29]>;
+def D15 : ARMReg<15, "d15", [S30, S31]>;
 
 // Register classes.
 //
-// FIXME: the register order should be defined in terms of the preferred
-// allocation order...
+// pc  == Program Counter
+// lr  == Link Register
+// sp  == Stack Pointer
+// r12 == ip (scratch)
+// r7  == Frame Pointer (thumb-style backtraces)
+// r11 == Frame Pointer (arm-style backtraces)
+// r10 == Stack Limit
 //
-def IntRegs : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, R6,
-	                                       R7, R8, R9, R10, R11, R12,
-                                               R13, R14, R15]> {
+def GPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, R6,
+                                           R7, R8, R9, R10, R12, R11,
+                                           LR, SP, PC]> {
   let MethodProtos = [{
+    iterator allocation_order_begin(const MachineFunction &MF) const;
     iterator allocation_order_end(const MachineFunction &MF) const;
   }];
+  // FIXME: We are reserving r12 in case the PEI needs to use it to
+  // generate large stack offset. Make it available once we have register
+  // scavenging.
   let MethodBodies = [{
-    IntRegsClass::iterator
-    IntRegsClass::allocation_order_end(const MachineFunction &MF) const {
-      // r15 == Program Counter
-      // r14 == Link Register
-      // r13 == Stack Pointer
-      // r12 == ip (scratch)
-      // r11 == Frame Pointer
-      // r10 == Stack Limit
-      if (hasFP(MF))
-        return end() - 5;
-      else
-        return end() - 4;
+    // FP is R11, R9 is available.
+    static const unsigned ARM_GPR_AO_1[] = {
+      ARM::R0, ARM::R1, ARM::R2, ARM::R3,
+      ARM::R4, ARM::R5, ARM::R6, ARM::R7,
+      ARM::R8, ARM::R9, ARM::R10,
+      ARM::LR, ARM::R11 };
+    // FP is R11, R9 is not available.
+    static const unsigned ARM_GPR_AO_2[] = {
+      ARM::R0, ARM::R1, ARM::R2, ARM::R3,
+      ARM::R4, ARM::R5, ARM::R6, ARM::R7,
+      ARM::R8, ARM::R10,
+      ARM::LR, ARM::R11 };
+    // FP is R7, R9 is available.
+    static const unsigned ARM_GPR_AO_3[] = {
+      ARM::R0, ARM::R1, ARM::R2, ARM::R3,
+      ARM::R4, ARM::R5, ARM::R6, ARM::R8,
+      ARM::R9, ARM::R10,ARM::R11,
+      ARM::LR, ARM::R7 };
+    // FP is R7, R9 is not available.
+    static const unsigned ARM_GPR_AO_4[] = {
+      ARM::R0, ARM::R1, ARM::R2, ARM::R3,
+      ARM::R4, ARM::R5, ARM::R6, ARM::R8,
+      ARM::R10,ARM::R11,
+      ARM::LR, ARM::R7 };
+    // FP is R7, only low registers available.
+    static const unsigned THUMB_GPR_AO[] = {
+      ARM::R0, ARM::R1, ARM::R2,
+      ARM::R4, ARM::R5, ARM::R6, ARM::R7 };
+
+    GPRClass::iterator
+    GPRClass::allocation_order_begin(const MachineFunction &MF) const {
+      const TargetMachine &TM = MF.getTarget();
+      const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
+      if (Subtarget.isThumb())
+        return THUMB_GPR_AO;
+      if (Subtarget.useThumbBacktraces()) {
+        if (Subtarget.isR9Reserved())
+          return ARM_GPR_AO_4;
+        else
+          return ARM_GPR_AO_3;
+      } else {
+        if (Subtarget.isR9Reserved())
+          return ARM_GPR_AO_2;
+        else
+          return ARM_GPR_AO_1;
+      }
+    }
+
+    GPRClass::iterator
+    GPRClass::allocation_order_end(const MachineFunction &MF) const {
+      const TargetMachine &TM = MF.getTarget();
+      const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
+      GPRClass::iterator I;
+      if (Subtarget.isThumb())
+        I = THUMB_GPR_AO + (sizeof(THUMB_GPR_AO)/sizeof(unsigned));
+      else if (Subtarget.useThumbBacktraces()) {
+        if (Subtarget.isR9Reserved())
+          I = ARM_GPR_AO_4 + (sizeof(ARM_GPR_AO_4)/sizeof(unsigned));
+        else
+          I = ARM_GPR_AO_3 + (sizeof(ARM_GPR_AO_3)/sizeof(unsigned));
+      } else {
+        if (Subtarget.isR9Reserved())
+          I = ARM_GPR_AO_2 + (sizeof(ARM_GPR_AO_2)/sizeof(unsigned));
+        else
+          I = ARM_GPR_AO_1 + (sizeof(ARM_GPR_AO_1)/sizeof(unsigned));
+      }
+
+      return hasFP(MF) ? I-1 : I;
     }
   }];
 }
 
-def FPRegs : RegisterClass<"ARM", [f32], 32, [S0, S1, S2, S3, S4, S5, S6, S7, S8,
+def SPR : RegisterClass<"ARM", [f32], 32, [S0, S1, S2, S3, S4, S5, S6, S7, S8,
   S9, S10, S11, S12, S13, S14, S15, S16, S17, S18, S19, S20, S21, S22,
   S23, S24, S25, S26, S27, S28, S29, S30, S31]>;
 
-def DFPRegs : RegisterClass<"ARM", [f64], 64, [D0, D1, D2, D3, D4, D5, D6, D7,
-  D8, D9, D10, D11, D12, D13, D14, D15]>;
+// ARM requires only word alignment for double. It's more performant if it
+// is double-word alignment though.
+def DPR : RegisterClass<"ARM", [f64], 64, [D0, D1, D2, D3, D4, D5, D6, D7, D8,
+  D9, D10, D11, D12, D13, D14, D15]>;
diff --git a/llvm/lib/Target/ARM/ARMSubtarget.cpp b/llvm/lib/Target/ARM/ARMSubtarget.cpp
new file mode 100644
index 0000000..35bb9ac
--- /dev/null
+++ b/llvm/lib/Target/ARM/ARMSubtarget.cpp
@@ -0,0 +1,52 @@
+//===-- ARMSubtarget.cpp - ARM Subtarget Information ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Evan Cheng and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the ARM specific subclass of TargetSubtarget.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ARMSubtarget.h"
+#include "ARMGenSubtarget.inc"
+#include "llvm/Module.h"
+#include "llvm/Support/CommandLine.h"
+using namespace llvm;
+
+// FIXME: this is temporary.
+static cl::opt<bool> Thumb("enable-thumb",
+                           cl::desc("Switch to thumb mode in ARM backend"));
+
+ARMSubtarget::ARMSubtarget(const Module &M, const std::string &FS)
+  : ARMArchVersion(V4T), HasVFP2(false), IsDarwin(false),
+    UseThumbBacktraces(false), IsR9Reserved(false), stackAlignment(8) {
+
+  // Determine default and user specified characteristics
+  std::string CPU = "generic";
+
+  // Parse features string.
+  ParseSubtargetFeatures(FS, CPU);
+
+  IsThumb = Thumb;
+  
+  // Set the boolean corresponding to the current target triple, or the default
+  // if one cannot be determined, to true.
+  const std::string& TT = M.getTargetTriple();
+  if (TT.length() > 5) {
+    IsDarwin = TT.find("-darwin") != std::string::npos;
+  } else if (TT.empty()) {
+#if defined(__APPLE__)
+    IsDarwin = true;
+#endif
+  }
+
+  if (IsDarwin) {
+    UseThumbBacktraces = true;
+    IsR9Reserved = true;
+    stackAlignment = 4;
+  } 
+}
diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h
new file mode 100644
index 0000000..d5c4b5e
--- /dev/null
+++ b/llvm/lib/Target/ARM/ARMSubtarget.h
@@ -0,0 +1,82 @@
+//=====---- ARMSubtarget.h - Define Subtarget for the ARM -----*- C++ -*--====//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Evan Cheng and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the ARM specific subclass of TargetSubtarget.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef ARMSUBTARGET_H
+#define ARMSUBTARGET_H
+
+#include "llvm/Target/TargetSubtarget.h"
+#include <string>
+
+namespace llvm {
+class Module;
+
+class ARMSubtarget : public TargetSubtarget {
+protected:
+  enum ARMArchEnum {
+    V4T, V5T, V5TE, V6
+  };
+
+  /// ARMArchVersion - ARM architecture vecrsion: V4T (base), V5T, V5TE,
+  /// and V6.
+  ARMArchEnum ARMArchVersion;
+
+  /// HasVFP2 - True if the processor supports Vector Floating Point (VFP) V2
+  /// instructions.
+  bool HasVFP2;
+
+  /// IsThumb - True if we are in thumb mode, false if in ARM mode.
+  bool IsThumb;
+
+  bool IsDarwin;
+  
+  /// UseThumbBacktraces - True if we use thumb style backtraces.
+  bool UseThumbBacktraces;
+
+  /// IsR9Reserved - True if R9 is a not available as general purpose register.
+  bool IsR9Reserved;
+  
+  /// stackAlignment - The minimum alignment known to hold of the stack frame on
+  /// entry to the function and which must be maintained by every function.
+  unsigned stackAlignment;
+
+ public:
+  /// This constructor initializes the data members to match that
+  /// of the specified module.
+  ///
+  ARMSubtarget(const Module &M, const std::string &FS);
+
+  /// ParseSubtargetFeatures - Parses features string setting specified 
+  /// subtarget options.  Definition of function is auto generated by tblgen.
+  void ParseSubtargetFeatures(const std::string &FS, const std::string &CPU);
+
+  bool hasV4TOps()  const { return ARMArchVersion >= V4T; }
+  bool hasV5TOps()  const { return ARMArchVersion >= V5T; }
+  bool hasV5TEOps() const { return ARMArchVersion >= V5TE; }
+  bool hasV6Ops()   const { return ARMArchVersion >= V6; }
+
+  bool hasVFP2() const { return HasVFP2; }
+  
+  bool isDarwin() const { return IsDarwin; }
+  bool isThumb() const { return IsThumb; }
+
+  bool useThumbBacktraces() const { return UseThumbBacktraces; }
+  bool isR9Reserved() const { return IsR9Reserved; }
+
+  /// getStackAlignment - Returns the minimum alignment known to hold of the
+  /// stack frame on entry to the function and which must be maintained by every
+  /// function for this subtarget.
+  unsigned getStackAlignment() const { return stackAlignment; }
+};
+} // End llvm namespace
+
+#endif  // ARMSUBTARGET_H
diff --git a/llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp b/llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp
index a1c623c..65848e5 100644
--- a/llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp
@@ -12,18 +12,50 @@
 //===----------------------------------------------------------------------===//
 
 #include "ARMTargetAsmInfo.h"
-
+#include "ARMTargetMachine.h"
 using namespace llvm;
 
 ARMTargetAsmInfo::ARMTargetAsmInfo(const ARMTargetMachine &TM) {
-  Data16bitsDirective = "\t.half\t";
-  Data32bitsDirective = "\t.word\t";
+  const ARMSubtarget *Subtarget = &TM.getSubtarget<ARMSubtarget>();
+  if (Subtarget->isDarwin()) {
+    HasDotTypeDotSizeDirective = false;
+    PrivateGlobalPrefix = "L";
+    GlobalPrefix = "_";
+    ZeroDirective = "\t.space\t";
+    SetDirective = "\t.set";
+    WeakRefDirective = "\t.weak_reference\t";
+    JumpTableDataSection = ".const";
+    CStringSection = "\t.cstring";
+    StaticCtorsSection = ".mod_init_func";
+    StaticDtorsSection = ".mod_term_func";
+    InlineAsmStart = "@ InlineAsm Start";
+    InlineAsmEnd = "@ InlineAsm End";
+    LCOMMDirective = "\t.lcomm\t";
+    COMMDirectiveTakesAlignment = false;
+    
+    NeedsSet = true;
+    DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug";
+    DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug";
+    DwarfLineSection = ".section __DWARF,__debug_line,regular,debug";
+    DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug";
+    DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug";
+    DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug";
+    DwarfStrSection = ".section __DWARF,__debug_str,regular,debug";
+    DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug";
+    DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug";
+    DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug";
+    DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug";
+  } else {
+    Data16bitsDirective = "\t.half\t";
+    Data32bitsDirective = "\t.word\t";
+    ZeroDirective = "\t.skip\t";
+    WeakRefDirective = "\t.weak\t";
+    StaticCtorsSection = "\t.section .ctors,\"aw\",%progbits";
+    StaticDtorsSection = "\t.section .dtors,\"aw\",%progbits";
+  }
+  AlignmentIsInBytes = false; 
   Data64bitsDirective = 0;
-  ZeroDirective = "\t.skip\t";
   CommentString = "@";
+  DataSection = "\t.data";
   ConstantPoolSection = "\t.text\n";
-  AlignmentIsInBytes = false;
-  WeakRefDirective = "\t.weak\t";
-  StaticCtorsSection = "\t.section .ctors,\"aw\",%progbits";
-  StaticDtorsSection = "\t.section .dtors,\"aw\",%progbits";
 }
diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
index 4328ca8..195689e 100644
--- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
@@ -11,30 +11,32 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "ARMTargetAsmInfo.h"
 #include "ARMTargetMachine.h"
+#include "ARMTargetAsmInfo.h"
 #include "ARMFrameInfo.h"
 #include "ARM.h"
 #include "llvm/Module.h"
 #include "llvm/PassManager.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Target/TargetMachineRegistry.h"
+#include "llvm/Target/TargetOptions.h"
 using namespace llvm;
 
+static cl::opt<bool> DisableLdStOpti("disable-arm-loadstore-opti", cl::Hidden,
+                              cl::desc("Disable load store optimization pass"));
+
 namespace {
   // Register the target.
   RegisterTarget<ARMTargetMachine> X("arm", "  ARM");
 }
 
-
-const TargetAsmInfo *ARMTargetMachine::createTargetAsmInfo() const {
-  return new ARMTargetAsmInfo(*this);
-}
-
-
 /// TargetMachine ctor - Create an ILP32 architecture model
 ///
 ARMTargetMachine::ARMTargetMachine(const Module &M, const std::string &FS)
-  : DataLayout("e-p:32:32") {
+  : Subtarget(M, FS), DataLayout("e-p:32:32-d:32"), InstrInfo(Subtarget),
+    FrameInfo(Subtarget) {
+  if (Subtarget.isDarwin())
+    NoFramePointerElim = true;
 }
 
 unsigned ARMTargetMachine::getModuleMatchQuality(const Module &M) {
@@ -49,14 +51,23 @@
 }
 
 
+const TargetAsmInfo *ARMTargetMachine::createTargetAsmInfo() const {
+  return new ARMTargetAsmInfo(*this);
+}
+
+
 // Pass Pipeline Configuration
 bool ARMTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast) {
   PM.add(createARMISelDag(*this));
   return false;
 }
 
-bool ARMTargetMachine::addPostRegAlloc(FunctionPassManager &PM, bool Fast) {
-  PM.add(createARMFixMulPass());
+bool ARMTargetMachine::addPreEmitPass(FunctionPassManager &PM, bool Fast) {
+  // FIXME: temporarily disabling load / store optimization pass for Thumb mode.
+  if (!Fast && !DisableLdStOpti && !Subtarget.isThumb())
+    PM.add(createARMLoadStoreOptimizationPass());
+  
+  PM.add(createARMConstantIslandPass());
   return true;
 }
 
diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.h b/llvm/lib/Target/ARM/ARMTargetMachine.h
index b9a3d98..9c888ea 100644
--- a/llvm/lib/Target/ARM/ARMTargetMachine.h
+++ b/llvm/lib/Target/ARM/ARMTargetMachine.h
@@ -20,19 +20,17 @@
 #include "llvm/Target/TargetFrameInfo.h"
 #include "ARMInstrInfo.h"
 #include "ARMFrameInfo.h"
+#include "ARMSubtarget.h"
 
 namespace llvm {
 
 class Module;
 
 class ARMTargetMachine : public LLVMTargetMachine {
-  const TargetData DataLayout;       // Calculates type size & alignment
-  ARMInstrInfo InstrInfo;
-  ARMFrameInfo FrameInfo;
-  
-protected:
-  virtual const TargetAsmInfo *createTargetAsmInfo() const;
-
+  ARMSubtarget      Subtarget;
+  const TargetData  DataLayout;       // Calculates type size & alignment
+  ARMInstrInfo      InstrInfo;
+  ARMFrameInfo      FrameInfo;
 public:
   ARMTargetMachine(const Module &M, const std::string &FS);
 
@@ -42,11 +40,14 @@
     return &InstrInfo.getRegisterInfo();
   }
   virtual const TargetData       *getTargetData() const { return &DataLayout; }
+  virtual const ARMSubtarget  *getSubtargetImpl() const { return &Subtarget; }
   static unsigned getModuleMatchQuality(const Module &M);
 
+  virtual const TargetAsmInfo *createTargetAsmInfo() const;
+  
   // Pass Pipeline Configuration
   virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
-  virtual bool addPostRegAlloc(FunctionPassManager &PM, bool Fast);
+  virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast);
   virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast, 
                                   std::ostream &Out);
 };
diff --git a/llvm/lib/Target/ARM/Makefile b/llvm/lib/Target/ARM/Makefile
index 4310b8c..77300a1 100644
--- a/llvm/lib/Target/ARM/Makefile
+++ b/llvm/lib/Target/ARM/Makefile
@@ -7,6 +7,7 @@
 # License. See LICENSE.TXT for details.
 #
 ##===----------------------------------------------------------------------===##
+
 LEVEL = ../../..
 LIBRARYNAME = LLVMARM
 TARGET = ARM
@@ -15,7 +16,6 @@
 BUILT_SOURCES = ARMGenRegisterInfo.h.inc ARMGenRegisterNames.inc \
                 ARMGenRegisterInfo.inc ARMGenInstrNames.inc \
                 ARMGenInstrInfo.inc ARMGenAsmWriter.inc \
-                ARMGenDAGISel.inc
+                ARMGenDAGISel.inc ARMGenSubtarget.inc
 
 include $(LEVEL)/Makefile.common
-
diff --git a/llvm/lib/Target/ARM/README-Thumb.txt b/llvm/lib/Target/ARM/README-Thumb.txt
new file mode 100644
index 0000000..e9e943d
--- /dev/null
+++ b/llvm/lib/Target/ARM/README-Thumb.txt
@@ -0,0 +1,17 @@
+//===---------------------------------------------------------------------===//
+// Random ideas for the ARM backend (Thumb specific).
+//===---------------------------------------------------------------------===//
+
+* Add support for compiling functions in both ARM and Thumb mode, then taking
+  the smallest.
+* Add support for compiling individual basic blocks in thumb mode, when in a 
+  larger ARM function.  This can be used for presumed cold code, like paths
+  to abort (failure path of asserts), EH handling code, etc.
+
+* Thumb doesn't have normal pre/post increment addressing modes, but you can
+  load/store 32-bit integers with pre/postinc by using load/store multiple
+  instrs with a single register.
+
+* Make better use of high registers r8, r10, r11, r12 (ip). Some variants of add
+  and cmp instructions can use high registers. Also, we can use them as
+  temporaries to spill values into.
diff --git a/llvm/lib/Target/ARM/README.txt b/llvm/lib/Target/ARM/README.txt
index 0f79322..000e8e6 100644
--- a/llvm/lib/Target/ARM/README.txt
+++ b/llvm/lib/Target/ARM/README.txt
@@ -2,69 +2,438 @@
 // Random ideas for the ARM backend.
 //===---------------------------------------------------------------------===//
 
-Consider implementing a select with two conditional moves:
+Reimplement 'select' in terms of 'SEL'.
 
-cmp x, y
-moveq dst, a
-movne dst, b
+* We would really like to support UXTAB16, but we need to prove that the
+  add doesn't need to overflow between the two 16-bit chunks.
 
-----------------------------------------------------------
+* implement predication support
+* Implement pre/post increment support.  (e.g. PR935)
+* Coalesce stack slots!
+* Implement smarter constant generation for binops with large immediates.
 
+* Consider materializing FP constants like 0.0f and 1.0f using integer 
+  immediate instructions then copy to FPU.  Slower than load into FPU?
 
-%tmp1 = shl int %b, ubyte %c
-%tmp4 = add int %a, %tmp1
+//===---------------------------------------------------------------------===//
 
-compiles to
+The constant island pass is extremely naive.  If a constant pool entry is
+out of range, it *always* splits a block and inserts a copy of the cp 
+entry inline.  It should:
 
-add r0, r0, r1, lsl r2
+1. Check to see if there is already a copy of this constant nearby.  If so, 
+   reuse it.
+2. Instead of always splitting blocks to insert the constant, insert it in 
+   nearby 'water'.
+3. Constant island references should be ref counted.  If a constant reference
+   is out-of-range, and the last reference to a constant is relocated, the
+   dead constant should be removed.
 
-but
+This pass has all the framework needed to implement this, but it hasn't 
+been done.
 
-%tmp1 = shl int %b, ubyte %c
-%tmp4 = add int %tmp1, %a
+//===---------------------------------------------------------------------===//
 
-compiles to
-mov r1, r1, lsl r2
-add r0, r1, r0
+We need to start generating predicated instructions.  The .td files have a way
+to express this now (see the PPC conditional return instruction), but the 
+branch folding pass (or a new if-cvt pass) should start producing these, at
+least in the trivial case.
 
----------------------------------------------------------
-%tmp1 = shl int %b, ubyte 4
-%tmp2 = add int %a, %tmp1
+Among the obvious wins, doing so can eliminate the need to custom expand 
+copysign (i.e. we won't need to custom expand it to get the conditional
+negate).
 
-compiles to
+//===---------------------------------------------------------------------===//
 
-mov r2, #4
-add r0, r0, r1, lsl r2
+Implement long long "X-3" with instructions that fold the immediate in.  These
+were disabled due to badness with the ARM carry flag on subtracts.
 
-should be
+//===---------------------------------------------------------------------===//
 
-add r0, r0, r1, lsl #4
+We currently compile abs:
+int foo(int p) { return p < 0 ? -p : p; }
 
-----------------------------------------------------------
+into:
 
-add an offset to FLDS/FLDD/FSTD/FSTS addressing mode
+_foo:
+        rsb r1, r0, #0
+        cmn r0, #1
+        movgt r1, r0
+        mov r0, r1
+        bx lr
 
-----------------------------------------------------------
+This is very, uh, literal.  This could be a 3 operation sequence:
+  t = (p sra 31); 
+  res = (p xor t)-t
 
-the function
+Which would be better.  This occurs in png decode.
 
-void %f() {
+//===---------------------------------------------------------------------===//
+
+More load / store optimizations:
+1) Look past instructions without side-effects (not load, store, branch, etc.)
+   when forming the list of loads / stores to optimize.
+
+2) Smarter register allocation?
+We are probably missing some opportunities to use ldm / stm. Consider:
+
+ldr r5, [r0]
+ldr r4, [r0, #4]
+
+This cannot be merged into a ldm. Perhaps we will need to do the transformation
+before register allocation. Then teach the register allocator to allocate a
+chunk of consecutive registers.
+
+3) Better representation for block transfer? This is from Olden/power:
+
+	fldd d0, [r4]
+	fstd d0, [r4, #+32]
+	fldd d0, [r4, #+8]
+	fstd d0, [r4, #+40]
+	fldd d0, [r4, #+16]
+	fstd d0, [r4, #+48]
+	fldd d0, [r4, #+24]
+	fstd d0, [r4, #+56]
+
+If we can spare the registers, it would be better to use fldm and fstm here.
+Need major register allocator enhancement though.
+
+4) Can we recognize the relative position of constantpool entries? i.e. Treat
+
+	ldr r0, LCPI17_3
+	ldr r1, LCPI17_4
+	ldr r2, LCPI17_5
+
+   as
+	ldr r0, LCPI17
+	ldr r1, LCPI17+4
+	ldr r2, LCPI17+8
+
+   Then the ldr's can be combined into a single ldm. See Olden/power.
+
+Note for ARM v4 gcc uses ldmia to load a pair of 32-bit values to represent a
+double 64-bit FP constant:
+
+	adr	r0, L6
+	ldmia	r0, {r0-r1}
+
+	.align 2
+L6:
+	.long	-858993459
+	.long	1074318540
+
+5) Can we make use of ldrd and strd? Instead of generating ldm / stm, use
+ldrd/strd instead if there are only two destination registers that form an
+odd/even pair. However, we probably would pay a penalty if the address is not
+aligned on 8-byte boundary. This requires more information on load / store
+nodes (and MI's?) then we currently carry.
+
+//===---------------------------------------------------------------------===//
+
+* Consider this silly example:
+
+double bar(double x) {  
+  double r = foo(3.1);
+  return x+r;
+}
+
+_bar:
+	sub sp, sp, #16
+	str r4, [sp, #+12]
+	str r5, [sp, #+8]
+	str lr, [sp, #+4]
+	mov r4, r0
+	mov r5, r1
+	ldr r0, LCPI2_0
+	bl _foo
+	fmsr f0, r0
+	fcvtsd d0, f0
+	fmdrr d1, r4, r5
+	faddd d0, d0, d1
+	fmrrd r0, r1, d0
+	ldr lr, [sp, #+4]
+	ldr r5, [sp, #+8]
+	ldr r4, [sp, #+12]
+	add sp, sp, #16
+	bx lr
+
+Ignore the prologue and epilogue stuff for a second. Note 
+	mov r4, r0
+	mov r5, r1
+the copys to callee-save registers and the fact they are only being used by the
+fmdrr instruction. It would have been better had the fmdrr been scheduled
+before the call and place the result in a callee-save DPR register. The two
+mov ops would not have been necessary.
+
+//===---------------------------------------------------------------------===//
+
+Calling convention related stuff:
+
+* gcc's parameter passing implementation is terrible and we suffer as a result:
+
+e.g.
+struct s {
+  double d1;
+  int s1;
+};
+
+void foo(struct s S) {
+  printf("%g, %d\n", S.d1, S.s1);
+}
+
+'S' is passed via registers r0, r1, r2. But gcc stores them to the stack, and
+then reload them to r1, r2, and r3 before issuing the call (r0 contains the
+address of the format string):
+
+	stmfd	sp!, {r7, lr}
+	add	r7, sp, #0
+	sub	sp, sp, #12
+	stmia	sp, {r0, r1, r2}
+	ldmia	sp, {r1-r2}
+	ldr	r0, L5
+	ldr	r3, [sp, #8]
+L2:
+	add	r0, pc, r0
+	bl	L_printf$stub
+
+Instead of a stmia, ldmia, and a ldr, wouldn't it be better to do three moves?
+
+* Return an aggregate type is even worse:
+
+e.g.
+struct s foo(void) {
+  struct s S = {1.1, 2};
+  return S;
+}
+
+	mov	ip, r0
+	ldr	r0, L5
+	sub	sp, sp, #12
+L2:
+	add	r0, pc, r0
+	@ lr needed for prologue
+	ldmia	r0, {r0, r1, r2}
+	stmia	sp, {r0, r1, r2}
+	stmia	ip, {r0, r1, r2}
+	mov	r0, ip
+	add	sp, sp, #12
+	bx	lr
+
+r0 (and later ip) is the hidden parameter from caller to store the value in. The
+first ldmia loads the constants into r0, r1, r2. The last stmia stores r0, r1,
+r2 into the address passed in. However, there is one additional stmia that
+stores r0, r1, and r2 to some stack location. The store is dead.
+
+The llvm-gcc generated code looks like this:
+
+csretcc void %foo(%struct.s* %agg.result) {
 entry:
-	call void %g( int 1, int 2, int 3, int 4, int 5 )
+	%S = alloca %struct.s, align 4		; <%struct.s*> [#uses=1]
+	%memtmp = alloca %struct.s		; <%struct.s*> [#uses=1]
+	cast %struct.s* %S to sbyte*		; <sbyte*>:0 [#uses=2]
+	call void %llvm.memcpy.i32( sbyte* %0, sbyte* cast ({ double, int }* %C.0.904 to sbyte*), uint 12, uint 4 )
+	cast %struct.s* %agg.result to sbyte*		; <sbyte*>:1 [#uses=2]
+	call void %llvm.memcpy.i32( sbyte* %1, sbyte* %0, uint 12, uint 0 )
+	cast %struct.s* %memtmp to sbyte*		; <sbyte*>:2 [#uses=1]
+	call void %llvm.memcpy.i32( sbyte* %2, sbyte* %1, uint 12, uint 0 )
 	ret void
 }
 
-declare void %g(int, int, int, int, int)
+llc ends up issuing two memcpy's (the first memcpy becomes 3 loads from
+constantpool). Perhaps we should 1) fix llvm-gcc so the memcpy is translated
+into a number of load and stores, or 2) custom lower memcpy (of small size) to
+be ldmia / stmia. I think option 2 is better but the current register
+allocator cannot allocate a chunk of registers at a time.
 
-Only needs 8 bytes of stack space. We currently allocate 16.
+A feasible temporary solution is to use specific physical registers at the
+lowering time for small (<= 4 words?) transfer size.
 
-----------------------------------------------------------
+* ARM CSRet calling convention requires the hidden argument to be returned by
+the callee.
 
-32 x 32 -> 64 multiplications currently uses two instructions. We
-should try to declare smull and umull as returning two values.
+//===---------------------------------------------------------------------===//
 
-----------------------------------------------------------
+We can definitely do a better job on BB placements to eliminate some branches.
+It's very common to see llvm generated assembly code that looks like this:
 
-Implement addressing modes 2 (ldrb) and 3 (ldrsb)
+LBB3:
+ ...
+LBB4:
+...
+  beq LBB3
+  b LBB2
 
-----------------------------------------------------------
+If BB4 is the only predecessor of BB3, then we can emit BB3 after BB4. We can
+then eliminate beq and and turn the unconditional branch to LBB2 to a bne.
+
+See McCat/18-imp/ComputeBoundingBoxes for an example.
+
+//===---------------------------------------------------------------------===//
+
+We need register scavenging.  Currently, the 'ip' register is reserved in case
+frame indexes are too big.  This means that we generate extra code for stuff 
+like this:
+
+void foo(unsigned x, unsigned y, unsigned z, unsigned *a, unsigned *b, unsigned *c) { 
+   short Rconst = (short) (16384.0f * 1.40200 + 0.5 );
+   *a = x * Rconst;
+   *b = y * Rconst;
+   *c = z * Rconst;
+}
+
+we compile it to:
+
+_foo:
+***     stmfd sp!, {r4, r7}
+***     add r7, sp, #4
+        mov r4, #186
+        orr r4, r4, #89, 24 @ 22784
+        mul r0, r0, r4
+        str r0, [r3]
+        mul r0, r1, r4
+        ldr r1, [sp, #+8]
+        str r0, [r1]
+        mul r0, r2, r4
+        ldr r1, [sp, #+12]
+        str r0, [r1]
+***     sub sp, r7, #4
+***     ldmfd sp!, {r4, r7}
+        bx lr
+
+GCC produces:
+
+_foo:
+        ldr     ip, L4
+        mul     r0, ip, r0
+        mul     r1, ip, r1
+        str     r0, [r3, #0]
+        ldr     r3, [sp, #0]
+        mul     r2, ip, r2
+        str     r1, [r3, #0]
+        ldr     r3, [sp, #4]
+        str     r2, [r3, #0]
+        bx      lr
+L4:
+        .long   22970
+
+This is apparently all because we couldn't use ip here.
+
+//===---------------------------------------------------------------------===//
+
+Pre-/post- indexed load / stores:
+
+1) We should not make the pre/post- indexed load/store transform if the base ptr
+is guaranteed to be live beyond the load/store. This can happen if the base
+ptr is live out of the block we are performing the optimization. e.g.
+
+mov r1, r2
+ldr r3, [r1], #4
+...
+
+vs.
+
+ldr r3, [r2]
+add r1, r2, #4
+...
+
+In most cases, this is just a wasted optimization. However, sometimes it can
+negatively impact the performance because two-address code is more restrictive
+when it comes to scheduling.
+
+Unfortunately, liveout information is currently unavailable during DAG combine
+time.
+
+2) Consider spliting a indexed load / store into a pair of add/sub + load/store
+   to solve #1 (in TwoAddressInstructionPass.cpp).
+
+3) Enhance LSR to generate more opportunities for indexed ops.
+
+4) Once we added support for multiple result patterns, write indexed loads
+   patterns instead of C++ instruction selection code.
+
+5) Use FLDM / FSTM to emulate indexed FP load / store.
+
+//===---------------------------------------------------------------------===//
+
+We should add i64 support to take advantage of the 64-bit load / stores.
+We can add a pseudo i64 register class containing pseudo registers that are
+register pairs. All other ops (e.g. add, sub) would be expanded as usual.
+
+We need to add pseudo instructions (i.e. gethi / getlo) to extract i32 registers
+from the i64 register. These are single moves which can be eliminated if the
+destination register is a sub-register of the source. We should implement proper
+subreg support in the register allocator to coalesce these away.
+
+There are other minor issues such as multiple instructions for a spill / restore
+/ move.
+
+//===---------------------------------------------------------------------===//
+
+Implement support for some more tricky ways to materialize immediates.  For
+example, to get 0xffff8000, we can use:
+
+mov r9, #&3f8000
+sub r9, r9, #&400000
+
+//===---------------------------------------------------------------------===//
+
+We sometimes generate multiple add / sub instructions to update sp in prologue
+and epilogue if the inc / dec value is too large to fit in a single immediate
+operand. In some cases, perhaps it might be better to load the value from a
+constantpool instead.
+
+//===---------------------------------------------------------------------===//
+
+GCC generates significantly better code for this function.
+
+int foo(int StackPtr, unsigned char *Line, unsigned char *Stack, int LineLen) {
+    int i = 0;
+
+    if (StackPtr != 0) {
+       while (StackPtr != 0 && i < (((LineLen) < (32768))? (LineLen) : (32768)))
+          Line[i++] = Stack[--StackPtr];
+        if (LineLen > 32768)
+        {
+            while (StackPtr != 0 && i < LineLen)
+            {
+                i++;
+                --StackPtr;
+            }
+        }
+    }
+    return StackPtr;
+}
+
+//===---------------------------------------------------------------------===//
+
+This should compile to the mlas instruction:
+int mlas(int x, int y, int z) { return ((x * y + z) < 0) ? 7 : 13; }
+
+//===---------------------------------------------------------------------===//
+
+At some point, we should triage these to see if they still apply to us:
+
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19598
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18560
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27016
+
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11831
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11826
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11825
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11824
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11823
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11820
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10982
+
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10242
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9831
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9760
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9759
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9703
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9702
+http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9663
+
+http://www.inf.u-szeged.hu/gcc-arm/
+http://citeseer.ist.psu.edu/debus04linktime.html
+
+//===---------------------------------------------------------------------===//
