split LowerMEMCPY into LowerMEMCPYCall and LowerMEMCPYInline in the ARM backend.
[oota-llvm.git] / lib / Target / PowerPC / PPCISelLowering.cpp
index aacadd8500a3329b806ff61c99d718dacd261d2f..bf0f46784a7079afbb9f3cfe5ad132a522272864 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "PPCISelLowering.h"
+#include "PPCMachineFunctionInfo.h"
+#include "PPCPredicates.h"
 #include "PPCTargetMachine.h"
 #include "PPCPerfectShuffle.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/VectorExtras.h"
 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/CodeGen/CallingConvLower.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/Intrinsics.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Target/TargetOptions.h"
+#include "llvm/Support/CommandLine.h"
 using namespace llvm;
 
-PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
-  : TargetLowering(TM) {
+static cl::opt<bool> EnablePPCPreinc("enable-ppc-preinc", 
+cl::desc("enable preincrement load/store generation on PPC (experimental)"),
+                                     cl::Hidden);
+
+PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
+  : TargetLowering(TM), PPCSubTarget(*TM.getSubtargetImpl()) {
     
-  // Fold away setcc operations if possible.
-  setSetCCIsExpensive();
   setPow2DivIsCheap();
   
   // Use _setjmp/_longjmp instead of setjmp/longjmp.
-  setUseUnderscoreSetJmpLongJmp(true);
+  setUseUnderscoreSetJmp(true);
+  setUseUnderscoreLongJmp(true);
     
   // Set up the register classes.
   addRegisterClass(MVT::i32, PPC::GPRCRegisterClass);
   addRegisterClass(MVT::f32, PPC::F4RCRegisterClass);
   addRegisterClass(MVT::f64, PPC::F8RCRegisterClass);
   
+  // PowerPC has an i16 but no i8 (or i1) SEXTLOAD
+  setLoadXAction(ISD::SEXTLOAD, MVT::i1, Expand);
+  setLoadXAction(ISD::SEXTLOAD, MVT::i8, Expand);
+  
+  // PowerPC does not have truncstore for i1.
+  setStoreXAction(MVT::i1, Promote);
+
+  // PowerPC has pre-inc load and store's.
+  setIndexedLoadAction(ISD::PRE_INC, MVT::i1, Legal);
+  setIndexedLoadAction(ISD::PRE_INC, MVT::i8, Legal);
+  setIndexedLoadAction(ISD::PRE_INC, MVT::i16, Legal);
+  setIndexedLoadAction(ISD::PRE_INC, MVT::i32, Legal);
+  setIndexedLoadAction(ISD::PRE_INC, MVT::i64, Legal);
+  setIndexedStoreAction(ISD::PRE_INC, MVT::i1, Legal);
+  setIndexedStoreAction(ISD::PRE_INC, MVT::i8, Legal);
+  setIndexedStoreAction(ISD::PRE_INC, MVT::i16, Legal);
+  setIndexedStoreAction(ISD::PRE_INC, MVT::i32, Legal);
+  setIndexedStoreAction(ISD::PRE_INC, MVT::i64, Legal);
+
   setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
   setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
 
+  // Shortening conversions involving ppcf128 get expanded (2 regs -> 1 reg)
+  setConvertAction(MVT::ppcf128, MVT::f64, Expand);
+  setConvertAction(MVT::ppcf128, MVT::f32, Expand);
+  // This is used in the ppcf128->int sequence.  Note it has different semantics
+  // from FP_ROUND:  that rounds to nearest, this rounds to zero.
+  setOperationAction(ISD::FP_ROUND_INREG, MVT::ppcf128, Custom);
+
   // PowerPC has no intrinsics for these particular operations
   setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
   setOperationAction(ISD::MEMSET, MVT::Other, Expand);
   setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
   
-  // PowerPC has an i16 but no i8 (or i1) SEXTLOAD
-  setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand);
-  setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand);
-  
   // PowerPC has no SREM/UREM instructions
   setOperationAction(ISD::SREM, MVT::i32, Expand);
   setOperationAction(ISD::UREM, MVT::i32, Expand);
   setOperationAction(ISD::SREM, MVT::i64, Expand);
   setOperationAction(ISD::UREM, MVT::i64, Expand);
-  
-  // We don't support sin/cos/sqrt/fmod
+
+  // Don't use SMUL_LOHI/UMUL_LOHI or SDIVREM/UDIVREM to lower SREM/UREM.
+  setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
+  setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
+  setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
+  setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
+  setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
+  setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
+  setOperationAction(ISD::UDIVREM, MVT::i64, Expand);
+  setOperationAction(ISD::SDIVREM, MVT::i64, Expand);
+  
+  // We don't support sin/cos/sqrt/fmod/pow
   setOperationAction(ISD::FSIN , MVT::f64, Expand);
   setOperationAction(ISD::FCOS , MVT::f64, Expand);
   setOperationAction(ISD::FREM , MVT::f64, Expand);
+  setOperationAction(ISD::FPOW , MVT::f64, Expand);
   setOperationAction(ISD::FSIN , MVT::f32, Expand);
   setOperationAction(ISD::FCOS , MVT::f32, Expand);
   setOperationAction(ISD::FREM , MVT::f32, Expand);
+  setOperationAction(ISD::FPOW , MVT::f32, Expand);
   
   // If we're enabling GP optimizations, use hardware square root
   if (!TM.getSubtarget<PPCSubtarget>().hasFSQRT()) {
@@ -104,6 +146,8 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
   
   // PowerPC does not have BRCOND which requires SetCC
   setOperationAction(ISD::BRCOND, MVT::Other, Expand);
+
+  setOperationAction(ISD::BR_JT,  MVT::Other, Expand);
   
   // PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores.
   setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
@@ -117,51 +161,63 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
   setOperationAction(ISD::BIT_CONVERT, MVT::i64, Expand);
   setOperationAction(ISD::BIT_CONVERT, MVT::f64, Expand);
 
-  // PowerPC does not have truncstore for i1.
-  setOperationAction(ISD::TRUNCSTORE, MVT::i1, Promote);
-
   // We cannot sextinreg(i1).  Expand to shifts.
   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, 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 (!TM.getSubtarget<PPCSubtarget>().isDarwin())
-    setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand);
+  if (!TM.getSubtarget<PPCSubtarget>().isDarwin()) {
+    setOperationAction(ISD::LABEL, MVT::Other, Expand);
+  } else {
+    setOperationAction(ISD::EXCEPTIONADDR, MVT::i64, Expand);
+    setOperationAction(ISD::EHSELECTION,   MVT::i64, Expand);
+    setOperationAction(ISD::EXCEPTIONADDR, MVT::i32, Expand);
+    setOperationAction(ISD::EHSELECTION,   MVT::i32, Expand);
+  }
   
   // We want to legalize GlobalAddress and ConstantPool nodes into the 
   // appropriate instructions to materialize the address.
   setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
+  setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
   setOperationAction(ISD::ConstantPool,  MVT::i32, Custom);
   setOperationAction(ISD::JumpTable,     MVT::i32, Custom);
   setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
+  setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);
   setOperationAction(ISD::ConstantPool,  MVT::i64, Custom);
   setOperationAction(ISD::JumpTable,     MVT::i64, Custom);
   
   // RET must be custom lowered, to meet ABI requirements
   setOperationAction(ISD::RET               , MVT::Other, Custom);
-  
+
   // VASTART needs to be custom lowered to use the VarArgsFrameIndex
   setOperationAction(ISD::VASTART           , MVT::Other, Custom);
   
+  // VAARG is custom lowered with ELF 32 ABI
+  if (TM.getSubtarget<PPCSubtarget>().isELF32_ABI())
+    setOperationAction(ISD::VAARG, MVT::Other, Custom);
+  else
+    setOperationAction(ISD::VAARG, MVT::Other, Expand);
+  
   // Use the default implementation.
-  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);
-  
+  setOperationAction(ISD::STACKRESTORE      , MVT::Other, Custom);
+  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32  , Custom);
+  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64  , Custom);
+
   // We want to custom lower some of our intrinsics.
   setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
   
   if (TM.getSubtarget<PPCSubtarget>().has64BitSupport()) {
     // They also have instructions for converting between i64 and fp.
     setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
+    setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand);
     setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
-    
+    setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand);
+    setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
     // FIXME: disable this lowered code.  This generates 64-bit register values,
     // and we don't model the fact that the top part is clobbered by calls.  We
     // need to flag these together so that the value isn't live across a call.
@@ -175,22 +231,22 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
   }
 
   if (TM.getSubtarget<PPCSubtarget>().use64BitRegs()) {
-    // 64 bit PowerPC implementations can support i64 types directly
+    // 64-bit PowerPC implementations can support i64 types directly
     addRegisterClass(MVT::i64, PPC::G8RCRegisterClass);
     // BUILD_PAIR can't be handled natively, and should be expanded to shl/or
     setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
   } else {
-    // 32 bit PowerPC wants to expand i64 shifts itself.
-    setOperationAction(ISD::SHL, MVT::i64, Custom);
-    setOperationAction(ISD::SRL, MVT::i64, Custom);
-    setOperationAction(ISD::SRA, MVT::i64, Custom);
+    // 32-bit PowerPC wants to expand i64 shifts itself.
+    setOperationAction(ISD::SHL_PARTS, MVT::i32, Custom);
+    setOperationAction(ISD::SRA_PARTS, MVT::i32, Custom);
+    setOperationAction(ISD::SRL_PARTS, MVT::i32, Custom);
   }
 
   if (TM.getSubtarget<PPCSubtarget>().hasAltivec()) {
     // First set operation action for all vector types to expand. Then we
     // will selectively turn on ones that can be effectively codegen'd.
     for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
-         VT != (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++VT) {
+         VT <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++VT) {
       // add/sub are legal for all supported vector VT's.
       setOperationAction(ISD::ADD , (MVT::ValueType)VT, Legal);
       setOperationAction(ISD::SUB , (MVT::ValueType)VT, Legal);
@@ -220,11 +276,19 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
       setOperationAction(ISD::UDIV, (MVT::ValueType)VT, Expand);
       setOperationAction(ISD::UREM, (MVT::ValueType)VT, Expand);
       setOperationAction(ISD::FDIV, (MVT::ValueType)VT, Expand);
+      setOperationAction(ISD::FNEG, (MVT::ValueType)VT, Expand);
       setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Expand);
       setOperationAction(ISD::INSERT_VECTOR_ELT, (MVT::ValueType)VT, Expand);
       setOperationAction(ISD::BUILD_VECTOR, (MVT::ValueType)VT, Expand);
-
+      setOperationAction(ISD::UMUL_LOHI, (MVT::ValueType)VT, Expand);
+      setOperationAction(ISD::SMUL_LOHI, (MVT::ValueType)VT, Expand);
+      setOperationAction(ISD::UDIVREM, (MVT::ValueType)VT, Expand);
+      setOperationAction(ISD::SDIVREM, (MVT::ValueType)VT, Expand);
       setOperationAction(ISD::SCALAR_TO_VECTOR, (MVT::ValueType)VT, Expand);
+      setOperationAction(ISD::FPOW, (MVT::ValueType)VT, Expand);
+      setOperationAction(ISD::CTPOP, (MVT::ValueType)VT, Expand);
+      setOperationAction(ISD::CTLZ, (MVT::ValueType)VT, Expand);
+      setOperationAction(ISD::CTTZ, (MVT::ValueType)VT, Expand);
     }
 
     // We can custom expand all VECTOR_SHUFFLEs to VPERM, others we can handle
@@ -260,13 +324,30 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
   setSetCCResultType(MVT::i32);
   setShiftAmountType(MVT::i32);
   setSetCCResultContents(ZeroOrOneSetCCResult);
-  setStackPointerRegisterToSaveRestore(PPC::R1);
+  
+  if (TM.getSubtarget<PPCSubtarget>().isPPC64()) {
+    setStackPointerRegisterToSaveRestore(PPC::X1);
+    setExceptionPointerRegister(PPC::X3);
+    setExceptionSelectorRegister(PPC::X4);
+  } else {
+    setStackPointerRegisterToSaveRestore(PPC::R1);
+    setExceptionPointerRegister(PPC::R3);
+    setExceptionSelectorRegister(PPC::R4);
+  }
   
   // We have target-specific dag combine patterns for the following nodes:
   setTargetDAGCombine(ISD::SINT_TO_FP);
   setTargetDAGCombine(ISD::STORE);
   setTargetDAGCombine(ISD::BR_CC);
+  setTargetDAGCombine(ISD::BSWAP);
   
+  // Darwin long double math library functions have $LDBL128 appended.
+  if (TM.getSubtarget<PPCSubtarget>().isDarwin()) {
+    setLibcallName(RTLIB::SQRT_PPCF128, "sqrtl$LDBL128");
+    setLibcallName(RTLIB::POW_PPCF128, "powl$LDBL128");
+    setLibcallName(RTLIB::REM_PPCF128, "fmodl$LDBL128");
+  }
+
   computeRegisterProperties();
 }
 
@@ -283,19 +364,24 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
   case PPCISD::VPERM:         return "PPCISD::VPERM";
   case PPCISD::Hi:            return "PPCISD::Hi";
   case PPCISD::Lo:            return "PPCISD::Lo";
+  case PPCISD::DYNALLOC:      return "PPCISD::DYNALLOC";
   case PPCISD::GlobalBaseReg: return "PPCISD::GlobalBaseReg";
   case PPCISD::SRL:           return "PPCISD::SRL";
   case PPCISD::SRA:           return "PPCISD::SRA";
   case PPCISD::SHL:           return "PPCISD::SHL";
   case PPCISD::EXTSW_32:      return "PPCISD::EXTSW_32";
   case PPCISD::STD_32:        return "PPCISD::STD_32";
-  case PPCISD::CALL:          return "PPCISD::CALL";
+  case PPCISD::CALL_ELF:      return "PPCISD::CALL_ELF";
+  case PPCISD::CALL_Macho:    return "PPCISD::CALL_Macho";
   case PPCISD::MTCTR:         return "PPCISD::MTCTR";
-  case PPCISD::BCTRL:         return "PPCISD::BCTRL";
+  case PPCISD::BCTRL_Macho:   return "PPCISD::BCTRL_Macho";
+  case PPCISD::BCTRL_ELF:     return "PPCISD::BCTRL_ELF";
   case PPCISD::RET_FLAG:      return "PPCISD::RET_FLAG";
   case PPCISD::MFCR:          return "PPCISD::MFCR";
   case PPCISD::VCMP:          return "PPCISD::VCMP";
   case PPCISD::VCMPo:         return "PPCISD::VCMPo";
+  case PPCISD::LBRX:          return "PPCISD::LBRX";
+  case PPCISD::STBRX:         return "PPCISD::STBRX";
   case PPCISD::COND_BRANCH:   return "PPCISD::COND_BRANCH";
   }
 }
@@ -307,12 +393,12 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
 /// isFloatingPointZero - Return true if this is 0.0 or -0.0.
 static bool isFloatingPointZero(SDOperand Op) {
   if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Op))
-    return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0);
-  else if (Op.getOpcode() == ISD::EXTLOAD || Op.getOpcode() == ISD::LOAD) {
+    return CFP->getValueAPF().isZero();
+  else if (ISD::isEXTLoad(Op.Val) || ISD::isNON_EXTLoad(Op.Val)) {
     // Maybe this has already been legalized into the constant pool?
     if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op.getOperand(1)))
-      if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->get()))
-        return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0);
+      if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
+        return CFP->getValueAPF().isZero();
   }
   return false;
 }
@@ -469,6 +555,16 @@ bool PPC::isSplatShuffleMask(SDNode *N, unsigned EltSize) {
   return true;
 }
 
+/// isAllNegativeZeroVector - Returns true if all elements of build_vector
+/// are -0.0.
+bool PPC::isAllNegativeZeroVector(SDNode *N) {
+  assert(N->getOpcode() == ISD::BUILD_VECTOR);
+  if (PPC::isSplatShuffleMask(N, N->getNumOperands()))
+    if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N))
+      return CFP->getValueAPF().isNegZero();
+  return false;
+}
+
 /// getVSPLTImmediate - Return the appropriate VSPLT* immediate to splat the
 /// specified isSplatShuffleMask VECTOR_SHUFFLE mask.
 unsigned PPC::getVSPLTImmediate(SDNode *N, unsigned EltSize) {
@@ -557,7 +653,7 @@ SDOperand PPC::get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) {
     ValSizeInBytes = MVT::getSizeInBits(CN->getValueType(0))/8;
   } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
     assert(CN->getValueType(0) == MVT::f32 && "Only one legal FP vector type!");
-    Value = FloatToBits(CN->getValue());
+    Value = FloatToBits(CN->getValueAPF().convertToFloat());
     ValSizeInBytes = 4;
   }
 
@@ -591,6 +687,315 @@ SDOperand PPC::get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) {
   return SDOperand();
 }
 
+//===----------------------------------------------------------------------===//
+//  Addressing Mode Selection
+//===----------------------------------------------------------------------===//
+
+/// isIntS16Immediate - This method tests to see if the node is either a 32-bit
+/// or 64-bit immediate, and if the value can be accurately represented as a
+/// sign extension from a 16-bit value.  If so, this returns true and the
+/// immediate.
+static bool isIntS16Immediate(SDNode *N, short &Imm) {
+  if (N->getOpcode() != ISD::Constant)
+    return false;
+  
+  Imm = (short)cast<ConstantSDNode>(N)->getValue();
+  if (N->getValueType(0) == MVT::i32)
+    return Imm == (int32_t)cast<ConstantSDNode>(N)->getValue();
+  else
+    return Imm == (int64_t)cast<ConstantSDNode>(N)->getValue();
+}
+static bool isIntS16Immediate(SDOperand Op, short &Imm) {
+  return isIntS16Immediate(Op.Val, Imm);
+}
+
+
+/// SelectAddressRegReg - Given the specified addressed, check to see if it
+/// can be represented as an indexed [r+r] operation.  Returns false if it
+/// can be more efficiently represented with [r+imm].
+bool PPCTargetLowering::SelectAddressRegReg(SDOperand N, SDOperand &Base,
+                                            SDOperand &Index,
+                                            SelectionDAG &DAG) {
+  short imm = 0;
+  if (N.getOpcode() == ISD::ADD) {
+    if (isIntS16Immediate(N.getOperand(1), imm))
+      return false;    // r+i
+    if (N.getOperand(1).getOpcode() == PPCISD::Lo)
+      return false;    // r+i
+    
+    Base = N.getOperand(0);
+    Index = N.getOperand(1);
+    return true;
+  } else if (N.getOpcode() == ISD::OR) {
+    if (isIntS16Immediate(N.getOperand(1), imm))
+      return false;    // r+i can fold it if we can.
+    
+    // If this is an or of disjoint bitfields, we can codegen this as an add
+    // (for better address arithmetic) if the LHS and RHS of the OR are provably
+    // disjoint.
+    uint64_t LHSKnownZero, LHSKnownOne;
+    uint64_t RHSKnownZero, RHSKnownOne;
+    DAG.ComputeMaskedBits(N.getOperand(0), ~0U, LHSKnownZero, LHSKnownOne);
+    
+    if (LHSKnownZero) {
+      DAG.ComputeMaskedBits(N.getOperand(1), ~0U, RHSKnownZero, RHSKnownOne);
+      // If all of the bits are known zero on the LHS or RHS, the add won't
+      // carry.
+      if ((LHSKnownZero | RHSKnownZero) == ~0U) {
+        Base = N.getOperand(0);
+        Index = N.getOperand(1);
+        return true;
+      }
+    }
+  }
+  
+  return false;
+}
+
+/// Returns true if the address N can be represented by a base register plus
+/// a signed 16-bit displacement [r+imm], and if it is not better
+/// represented as reg+reg.
+bool PPCTargetLowering::SelectAddressRegImm(SDOperand N, SDOperand &Disp,
+                                            SDOperand &Base, SelectionDAG &DAG){
+  // If this can be more profitably realized as r+r, fail.
+  if (SelectAddressRegReg(N, Disp, Base, DAG))
+    return false;
+  
+  if (N.getOpcode() == ISD::ADD) {
+    short imm = 0;
+    if (isIntS16Immediate(N.getOperand(1), imm)) {
+      Disp = DAG.getTargetConstant((int)imm & 0xFFFF, MVT::i32);
+      if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0))) {
+        Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
+      } else {
+        Base = N.getOperand(0);
+      }
+      return true; // [r+i]
+    } else if (N.getOperand(1).getOpcode() == PPCISD::Lo) {
+      // Match LOAD (ADD (X, Lo(G))).
+      assert(!cast<ConstantSDNode>(N.getOperand(1).getOperand(1))->getValue()
+             && "Cannot handle constant offsets yet!");
+      Disp = N.getOperand(1).getOperand(0);  // The global address.
+      assert(Disp.getOpcode() == ISD::TargetGlobalAddress ||
+             Disp.getOpcode() == ISD::TargetConstantPool ||
+             Disp.getOpcode() == ISD::TargetJumpTable);
+      Base = N.getOperand(0);
+      return true;  // [&g+r]
+    }
+  } else if (N.getOpcode() == ISD::OR) {
+    short imm = 0;
+    if (isIntS16Immediate(N.getOperand(1), imm)) {
+      // If this is an or of disjoint bitfields, we can codegen this as an add
+      // (for better address arithmetic) if the LHS and RHS of the OR are
+      // provably disjoint.
+      uint64_t LHSKnownZero, LHSKnownOne;
+      DAG.ComputeMaskedBits(N.getOperand(0), ~0U, LHSKnownZero, LHSKnownOne);
+      if ((LHSKnownZero|~(unsigned)imm) == ~0U) {
+        // If all of the bits are known zero on the LHS or RHS, the add won't
+        // carry.
+        Base = N.getOperand(0);
+        Disp = DAG.getTargetConstant((int)imm & 0xFFFF, MVT::i32);
+        return true;
+      }
+    }
+  } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) {
+    // Loading from a constant address.
+    
+    // If this address fits entirely in a 16-bit sext immediate field, codegen
+    // this as "d, 0"
+    short Imm;
+    if (isIntS16Immediate(CN, Imm)) {
+      Disp = DAG.getTargetConstant(Imm, CN->getValueType(0));
+      Base = DAG.getRegister(PPC::R0, CN->getValueType(0));
+      return true;
+    }
+
+    // Handle 32-bit sext immediates with LIS + addr mode.
+    if (CN->getValueType(0) == MVT::i32 ||
+        (int64_t)CN->getValue() == (int)CN->getValue()) {
+      int Addr = (int)CN->getValue();
+      
+      // Otherwise, break this down into an LIS + disp.
+      Disp = DAG.getTargetConstant((short)Addr, MVT::i32);
+      
+      Base = DAG.getTargetConstant((Addr - (signed short)Addr) >> 16, MVT::i32);
+      unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
+      Base = SDOperand(DAG.getTargetNode(Opc, CN->getValueType(0), Base), 0);
+      return true;
+    }
+  }
+  
+  Disp = DAG.getTargetConstant(0, getPointerTy());
+  if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N))
+    Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
+  else
+    Base = N;
+  return true;      // [r+0]
+}
+
+/// SelectAddressRegRegOnly - Given the specified addressed, force it to be
+/// represented as an indexed [r+r] operation.
+bool PPCTargetLowering::SelectAddressRegRegOnly(SDOperand N, SDOperand &Base,
+                                                SDOperand &Index,
+                                                SelectionDAG &DAG) {
+  // Check to see if we can easily represent this as an [r+r] address.  This
+  // will fail if it thinks that the address is more profitably represented as
+  // reg+imm, e.g. where imm = 0.
+  if (SelectAddressRegReg(N, Base, Index, DAG))
+    return true;
+  
+  // If the operand is an addition, always emit this as [r+r], since this is
+  // better (for code size, and execution, as the memop does the add for free)
+  // than emitting an explicit add.
+  if (N.getOpcode() == ISD::ADD) {
+    Base = N.getOperand(0);
+    Index = N.getOperand(1);
+    return true;
+  }
+  
+  // Otherwise, do it the hard way, using R0 as the base register.
+  Base = DAG.getRegister(PPC::R0, N.getValueType());
+  Index = N;
+  return true;
+}
+
+/// SelectAddressRegImmShift - Returns true if the address N can be
+/// represented by a base register plus a signed 14-bit displacement
+/// [r+imm*4].  Suitable for use by STD and friends.
+bool PPCTargetLowering::SelectAddressRegImmShift(SDOperand N, SDOperand &Disp,
+                                                 SDOperand &Base,
+                                                 SelectionDAG &DAG) {
+  // If this can be more profitably realized as r+r, fail.
+  if (SelectAddressRegReg(N, Disp, Base, DAG))
+    return false;
+  
+  if (N.getOpcode() == ISD::ADD) {
+    short imm = 0;
+    if (isIntS16Immediate(N.getOperand(1), imm) && (imm & 3) == 0) {
+      Disp =  DAG.getTargetConstant(((int)imm & 0xFFFF) >> 2, MVT::i32);
+      if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0))) {
+        Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
+      } else {
+        Base = N.getOperand(0);
+      }
+      return true; // [r+i]
+    } else if (N.getOperand(1).getOpcode() == PPCISD::Lo) {
+      // Match LOAD (ADD (X, Lo(G))).
+      assert(!cast<ConstantSDNode>(N.getOperand(1).getOperand(1))->getValue()
+             && "Cannot handle constant offsets yet!");
+      Disp = N.getOperand(1).getOperand(0);  // The global address.
+      assert(Disp.getOpcode() == ISD::TargetGlobalAddress ||
+             Disp.getOpcode() == ISD::TargetConstantPool ||
+             Disp.getOpcode() == ISD::TargetJumpTable);
+      Base = N.getOperand(0);
+      return true;  // [&g+r]
+    }
+  } else if (N.getOpcode() == ISD::OR) {
+    short imm = 0;
+    if (isIntS16Immediate(N.getOperand(1), imm) && (imm & 3) == 0) {
+      // If this is an or of disjoint bitfields, we can codegen this as an add
+      // (for better address arithmetic) if the LHS and RHS of the OR are
+      // provably disjoint.
+      uint64_t LHSKnownZero, LHSKnownOne;
+      DAG.ComputeMaskedBits(N.getOperand(0), ~0U, LHSKnownZero, LHSKnownOne);
+      if ((LHSKnownZero|~(unsigned)imm) == ~0U) {
+        // If all of the bits are known zero on the LHS or RHS, the add won't
+        // carry.
+        Base = N.getOperand(0);
+        Disp = DAG.getTargetConstant(((int)imm & 0xFFFF) >> 2, MVT::i32);
+        return true;
+      }
+    }
+  } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) {
+    // Loading from a constant address.  Verify low two bits are clear.
+    if ((CN->getValue() & 3) == 0) {
+      // If this address fits entirely in a 14-bit sext immediate field, codegen
+      // this as "d, 0"
+      short Imm;
+      if (isIntS16Immediate(CN, Imm)) {
+        Disp = DAG.getTargetConstant((unsigned short)Imm >> 2, getPointerTy());
+        Base = DAG.getRegister(PPC::R0, CN->getValueType(0));
+        return true;
+      }
+    
+      // Fold the low-part of 32-bit absolute addresses into addr mode.
+      if (CN->getValueType(0) == MVT::i32 ||
+          (int64_t)CN->getValue() == (int)CN->getValue()) {
+        int Addr = (int)CN->getValue();
+      
+        // Otherwise, break this down into an LIS + disp.
+        Disp = DAG.getTargetConstant((short)Addr >> 2, MVT::i32);
+        
+        Base = DAG.getTargetConstant((Addr-(signed short)Addr) >> 16, MVT::i32);
+        unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
+        Base = SDOperand(DAG.getTargetNode(Opc, CN->getValueType(0), Base), 0);
+        return true;
+      }
+    }
+  }
+  
+  Disp = DAG.getTargetConstant(0, getPointerTy());
+  if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N))
+    Base = DAG.getTargetFrameIndex(FI->getIndex(), N.getValueType());
+  else
+    Base = N;
+  return true;      // [r+0]
+}
+
+
+/// 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 PPCTargetLowering::getPreIndexedAddressParts(SDNode *N, SDOperand &Base,
+                                                  SDOperand &Offset,
+                                                  ISD::MemIndexedMode &AM,
+                                                  SelectionDAG &DAG) {
+  // Disabled by default for now.
+  if (!EnablePPCPreinc) return false;
+  
+  SDOperand Ptr;
+  MVT::ValueType VT;
+  if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
+    Ptr = LD->getBasePtr();
+    VT = LD->getLoadedVT();
+    
+  } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
+    ST = ST;
+    Ptr = ST->getBasePtr();
+    VT  = ST->getStoredVT();
+  } else
+    return false;
+
+  // PowerPC doesn't have preinc load/store instructions for vectors.
+  if (MVT::isVector(VT))
+    return false;
+  
+  // TODO: Check reg+reg first.
+  
+  // LDU/STU use reg+imm*4, others use reg+imm.
+  if (VT != MVT::i64) {
+    // reg + imm
+    if (!SelectAddressRegImm(Ptr, Offset, Base, DAG))
+      return false;
+  } else {
+    // reg + imm * 4.
+    if (!SelectAddressRegImmShift(Ptr, Offset, Base, DAG))
+      return false;
+  }
+
+  if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
+    // PPC64 doesn't have lwau, but it does have lwaux.  Reject preinc load of
+    // sext i32 to i64 when addr mode is r+i.
+    if (LD->getValueType(0) == MVT::i64 && LD->getLoadedVT() == MVT::i32 &&
+        LD->getExtensionType() == ISD::SEXTLOAD &&
+        isa<ConstantSDNode>(Offset))
+      return false;
+  }    
+  
+  AM = ISD::PRE_INC;
+  return true;
+}
+
 //===----------------------------------------------------------------------===//
 //  LowerOperation implementation
 //===----------------------------------------------------------------------===//
@@ -598,7 +1003,7 @@ SDOperand PPC::get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG) {
 static SDOperand LowerConstantPool(SDOperand Op, SelectionDAG &DAG) {
   MVT::ValueType PtrVT = Op.getValueType();
   ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
-  Constant *C = CP->get();
+  Constant *C = CP->getConstVal();
   SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment());
   SDOperand Zero = DAG.getConstant(0, PtrVT);
 
@@ -616,7 +1021,7 @@ static SDOperand LowerConstantPool(SDOperand Op, SelectionDAG &DAG) {
     return DAG.getNode(ISD::ADD, PtrVT, Hi, Lo);
   }
   
-  if (TM.getRelocationModel() == Reloc::PIC) {
+  if (TM.getRelocationModel() == Reloc::PIC_) {
     // With PIC, the first instruction is actually "GR+hi(&G)".
     Hi = DAG.getNode(ISD::ADD, PtrVT,
                      DAG.getNode(PPCISD::GlobalBaseReg, PtrVT), Hi);
@@ -646,16 +1051,20 @@ static SDOperand LowerJumpTable(SDOperand Op, SelectionDAG &DAG) {
     return DAG.getNode(ISD::ADD, PtrVT, Hi, Lo);
   }
   
-  if (TM.getRelocationModel() == Reloc::PIC) {
+  if (TM.getRelocationModel() == Reloc::PIC_) {
     // With PIC, the first instruction is actually "GR+hi(&G)".
     Hi = DAG.getNode(ISD::ADD, PtrVT,
-                     DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi);
+                     DAG.getNode(PPCISD::GlobalBaseReg, PtrVT), Hi);
   }
   
   Lo = DAG.getNode(ISD::ADD, PtrVT, Hi, Lo);
   return Lo;
 }
 
+static SDOperand LowerGlobalTLSAddress(SDOperand Op, SelectionDAG &DAG) {
+  assert(0 && "TLS not implemented for PPC.");
+}
+
 static SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
   MVT::ValueType PtrVT = Op.getValueType();
   GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
@@ -677,7 +1086,7 @@ static SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
     return DAG.getNode(ISD::ADD, PtrVT, Hi, Lo);
   }
   
-  if (TM.getRelocationModel() == Reloc::PIC) {
+  if (TM.getRelocationModel() == Reloc::PIC_) {
     // With PIC, the first instruction is actually "GR+hi(&G)".
     Hi = DAG.getNode(ISD::ADD, PtrVT,
                      DAG.getNode(PPCISD::GlobalBaseReg, PtrVT), Hi);
@@ -685,13 +1094,12 @@ static SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
   
   Lo = DAG.getNode(ISD::ADD, PtrVT, Hi, Lo);
   
-  if (!GV->hasWeakLinkage() && !GV->hasLinkOnceLinkage() &&
-      (!GV->isExternal() || GV->hasNotBeenReadFromBytecode()))
+  if (!TM.getSubtarget<PPCSubtarget>().hasLazyResolverStub(GV))
     return Lo;
   
   // If the global is weak or external, we have to go through the lazy
   // resolution stub.
-  return DAG.getLoad(PtrVT, DAG.getEntryNode(), Lo, DAG.getSrcValue(0));
+  return DAG.getLoad(PtrVT, DAG.getEntryNode(), Lo, NULL, 0);
 }
 
 static SDOperand LowerSETCC(SDOperand Op, SelectionDAG &DAG) {
@@ -722,42 +1130,154 @@ static SDOperand LowerSETCC(SDOperand Op, SelectionDAG &DAG) {
   }
   
   // If we have an integer seteq/setne, turn it into a compare against zero
-  // by subtracting the rhs from the lhs, which is faster than setting a
-  // condition register, reading it back out, and masking the correct bit.
+  // by xor'ing the rhs with the lhs, which is faster than setting a
+  // condition register, reading it back out, and masking the correct bit.  The
+  // normal approach here uses sub to do this instead of xor.  Using xor exposes
+  // the result to other bit-twiddling opportunities.
   MVT::ValueType LHSVT = Op.getOperand(0).getValueType();
   if (MVT::isInteger(LHSVT) && (CC == ISD::SETEQ || CC == ISD::SETNE)) {
     MVT::ValueType VT = Op.getValueType();
-    SDOperand Sub = DAG.getNode(ISD::SUB, LHSVT, Op.getOperand(0), 
+    SDOperand Sub = DAG.getNode(ISD::XOR, LHSVT, Op.getOperand(0), 
                                 Op.getOperand(1));
     return DAG.getSetCC(VT, Sub, DAG.getConstant(0, LHSVT), CC);
   }
   return SDOperand();
 }
 
+static SDOperand LowerVAARG(SDOperand Op, SelectionDAG &DAG,
+                              int VarArgsFrameIndex,
+                              int VarArgsStackOffset,
+                              unsigned VarArgsNumGPR,
+                              unsigned VarArgsNumFPR,
+                              const PPCSubtarget &Subtarget) {
+  
+  assert(0 && "VAARG in ELF32 ABI not implemented yet!");
+}
+
 static SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG,
-                              unsigned VarArgsFrameIndex) {
-  // vastart just stores the address of the VarArgsFrameIndex slot into the
-  // memory location argument.
-  SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32);
-  return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), FR, 
-                     Op.getOperand(1), Op.getOperand(2));
+                              int VarArgsFrameIndex,
+                              int VarArgsStackOffset,
+                              unsigned VarArgsNumGPR,
+                              unsigned VarArgsNumFPR,
+                              const PPCSubtarget &Subtarget) {
+
+  if (Subtarget.isMachoABI()) {
+    // 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());
+  }
+
+  // For ELF 32 ABI we follow the layout of the va_list struct.
+  // We suppose the given va_list is already allocated.
+  //
+  // typedef struct {
+  //  char gpr;     /* index into the array of 8 GPRs
+  //                 * stored in the register save area
+  //                 * gpr=0 corresponds to r3,
+  //                 * gpr=1 to r4, etc.
+  //                 */
+  //  char fpr;     /* index into the array of 8 FPRs
+  //                 * stored in the register save area
+  //                 * fpr=0 corresponds to f1,
+  //                 * fpr=1 to f2, etc.
+  //                 */
+  //  char *overflow_arg_area;
+  //                /* location on stack that holds
+  //                 * the next overflow argument
+  //                 */
+  //  char *reg_save_area;
+  //               /* where r3:r10 and f1:f8 (if saved)
+  //                * are stored
+  //                */
+  // } va_list[1];
+
+
+  SDOperand ArgGPR = DAG.getConstant(VarArgsNumGPR, MVT::i8);
+  SDOperand ArgFPR = DAG.getConstant(VarArgsNumFPR, MVT::i8);
+  
+
+  MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
+  
+  SDOperand StackOffset = DAG.getFrameIndex(VarArgsStackOffset, PtrVT);
+  SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
+  
+  SDOperand ConstFrameOffset = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8,
+                                               PtrVT);
+  SDOperand ConstStackOffset = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8 - 1,
+                                               PtrVT);
+  SDOperand ConstFPROffset   = DAG.getConstant(1, PtrVT);
+  
+  SrcValueSDNode *SV = cast<SrcValueSDNode>(Op.getOperand(2));
+  
+  // Store first byte : number of int regs
+  SDOperand firstStore = DAG.getStore(Op.getOperand(0), ArgGPR,
+                                      Op.getOperand(1), SV->getValue(),
+                                      SV->getOffset());
+  SDOperand nextPtr = DAG.getNode(ISD::ADD, PtrVT, Op.getOperand(1),
+                                  ConstFPROffset);
+  
+  // Store second byte : number of float regs
+  SDOperand secondStore = DAG.getStore(firstStore, ArgFPR, nextPtr,
+                                       SV->getValue(), SV->getOffset());
+  nextPtr = DAG.getNode(ISD::ADD, PtrVT, nextPtr, ConstStackOffset);
+  
+  // Store second word : arguments given on stack
+  SDOperand thirdStore = DAG.getStore(secondStore, StackOffset, nextPtr,
+                                      SV->getValue(), SV->getOffset());
+  nextPtr = DAG.getNode(ISD::ADD, PtrVT, nextPtr, ConstFrameOffset);
+
+  // Store third word : arguments given in registers
+  return DAG.getStore(thirdStore, FR, nextPtr, SV->getValue(),
+                      SV->getOffset());
+
+}
+
+#include "PPCGenCallingConv.inc"
+
+/// GetFPR - Get the set of FP registers that should be allocated for arguments,
+/// depending on which subtarget is selected.
+static const unsigned *GetFPR(const PPCSubtarget &Subtarget) {
+  if (Subtarget.isMachoABI()) {
+    static const unsigned FPR[] = {
+      PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
+      PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
+    };
+    return FPR;
+  }
+  
+  
+  static const unsigned FPR[] = {
+    PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
+    PPC::F8
+  };
+  return FPR;
 }
 
 static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
-                                       int &VarArgsFrameIndex) {
+                                       int &VarArgsFrameIndex,
+                                       int &VarArgsStackOffset,
+                                       unsigned &VarArgsNumGPR,
+                                       unsigned &VarArgsNumFPR,
+                                       const PPCSubtarget &Subtarget) {
   // TODO: add description of PPC stack frame format, or at least some docs.
   //
   MachineFunction &MF = DAG.getMachineFunction();
   MachineFrameInfo *MFI = MF.getFrameInfo();
   SSARegMap *RegMap = MF.getSSARegMap();
-  std::vector<SDOperand> ArgValues;
+  SmallVector<SDOperand, 8> ArgValues;
   SDOperand Root = Op.getOperand(0);
   
-  unsigned ArgOffset = 24;
-  const unsigned Num_GPR_Regs = 8;
-  const unsigned Num_FPR_Regs = 13;
-  const unsigned Num_VR_Regs  = 12;
-  unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
+  MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
+  bool isPPC64 = PtrVT == MVT::i64;
+  bool isMachoABI = Subtarget.isMachoABI();
+  bool isELF32_ABI = Subtarget.isELF32_ABI();
+  unsigned PtrByteSize = isPPC64 ? 8 : 4;
+
+  unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI);
   
   static const unsigned GPR_32[] = {           // 32-bit registers.
     PPC::R3, PPC::R4, PPC::R5, PPC::R6,
@@ -767,35 +1287,49 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
     PPC::X3, PPC::X4, PPC::X5, PPC::X6,
     PPC::X7, PPC::X8, PPC::X9, PPC::X10,
   };
-  static const unsigned FPR[] = {
-    PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
-    PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
-  };
+  
+  static const unsigned *FPR = GetFPR(Subtarget);
+  
   static const unsigned VR[] = {
     PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
     PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
   };
 
-  MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
-  bool isPPC64 = PtrVT == MVT::i64;
+  const unsigned Num_GPR_Regs = array_lengthof(GPR_32);
+  const unsigned Num_FPR_Regs = isMachoABI ? 13 : 8;
+  const unsigned Num_VR_Regs  = array_lengthof( VR);
+
+  unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
+  
   const unsigned *GPR = isPPC64 ? GPR_64 : GPR_32;
   
   // Add DAG nodes to load the arguments or copy them out of registers.  On
-  // entry to a function on PPC, the arguments start at offset 24, although the
-  // first ones are often in registers.
+  // entry to a function on PPC, the arguments start after the linkage area,
+  // although the first ones are often in registers.
+  // 
+  // In the ELF 32 ABI, GPRs and stack are double word align: an argument
+  // represented with two words (long long or double) must be copied to an
+  // even GPR_idx value or to an even ArgOffset value.
+
   for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) {
     SDOperand ArgVal;
     bool needsLoad = false;
     MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType();
     unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8;
+    unsigned ArgSize = ObjSize;
+    unsigned Flags = cast<ConstantSDNode>(Op.getOperand(ArgNo+3))->getValue();
+    unsigned AlignFlag = 1 << ISD::ParamFlags::OrigAlignmentOffs;
+    // See if next argument requires stack alignment in ELF
+    bool Expand = (ObjectVT == MVT::f64) || ((ArgNo + 1 < e) &&
+      (cast<ConstantSDNode>(Op.getOperand(ArgNo+4))->getValue() & AlignFlag) &&
+      (!(Flags & AlignFlag)));
 
     unsigned CurArgOffset = ArgOffset;
     switch (ObjectVT) {
     default: assert(0 && "Unhandled argument type!");
     case MVT::i32:
-      // All int arguments reserve stack space.
-      ArgOffset += isPPC64 ? 8 : 4;
-
+      // Double word align in ELF
+      if (Expand && isELF32_ABI) GPR_idx += (GPR_idx % 2);
       if (GPR_idx != Num_GPR_Regs) {
         unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
         MF.addLiveIn(GPR[GPR_idx], VReg);
@@ -803,12 +1337,16 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
         ++GPR_idx;
       } else {
         needsLoad = true;
+        ArgSize = PtrByteSize;
       }
+      // Stack align in ELF
+      if (needsLoad && Expand && isELF32_ABI) 
+        ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize;
+      // All int arguments reserve stack space in Macho ABI.
+      if (isMachoABI || needsLoad) ArgOffset += PtrByteSize;
       break;
-    case MVT::i64:  // PPC64
-      // All int arguments reserve stack space.
-      ArgOffset += 8;
       
+    case MVT::i64:  // PPC64
       if (GPR_idx != Num_GPR_Regs) {
         unsigned VReg = RegMap->createVirtualRegister(&PPC::G8RCRegClass);
         MF.addLiveIn(GPR[GPR_idx], VReg);
@@ -817,17 +1355,17 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
       } else {
         needsLoad = true;
       }
+      // All int arguments reserve stack space in Macho ABI.
+      if (isMachoABI || needsLoad) ArgOffset += 8;
       break;
+      
     case MVT::f32:
     case MVT::f64:
-      // All FP arguments reserve stack space.
-      ArgOffset += ObjSize;
-
       // Every 4 bytes of argument space consumes one of the GPRs available for
       // argument passing.
-      if (GPR_idx != Num_GPR_Regs) {
+      if (GPR_idx != Num_GPR_Regs && isMachoABI) {
         ++GPR_idx;
-        if (ObjSize == 8 && GPR_idx != Num_GPR_Regs)
+        if (ObjSize == 8 && GPR_idx != Num_GPR_Regs && !isPPC64)
           ++GPR_idx;
       }
       if (FPR_idx != Num_FPR_Regs) {
@@ -842,6 +1380,12 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
       } else {
         needsLoad = true;
       }
+      
+      // Stack align in ELF
+      if (needsLoad && Expand && isELF32_ABI)
+        ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize;
+      // All FP arguments reserve stack space in Macho ABI.
+      if (isMachoABI || needsLoad) ArgOffset += isPPC64 ? 8 : ObjSize;
       break;
     case MVT::v4f32:
     case MVT::v4i32:
@@ -868,10 +1412,10 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
       // If the argument is actually used, emit a load from the right stack
       // slot.
       if (!Op.Val->hasNUsesOfValue(0, ArgNo)) {
-        int FI = MFI->CreateFixedObject(ObjSize, CurArgOffset);
+        int FI = MFI->CreateFixedObject(ObjSize,
+                                        CurArgOffset + (ArgSize - ObjSize));
         SDOperand FIN = DAG.getFrameIndex(FI, PtrVT);
-        ArgVal = DAG.getLoad(ObjectVT, Root, FIN,
-                             DAG.getSrcValue(NULL));
+        ArgVal = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0);
       } else {
         // Don't emit a dead load.
         ArgVal = DAG.getNode(ISD::UNDEF, ObjectVT);
@@ -885,26 +1429,93 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
   // the start of the first vararg value... for expansion of llvm.va_start.
   bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
   if (isVarArg) {
+    
+    int depth;
+    if (isELF32_ABI) {
+      VarArgsNumGPR = GPR_idx;
+      VarArgsNumFPR = FPR_idx;
+   
+      // Make room for Num_GPR_Regs, Num_FPR_Regs and for a possible frame
+      // pointer.
+      depth = -(Num_GPR_Regs * MVT::getSizeInBits(PtrVT)/8 +
+                Num_FPR_Regs * MVT::getSizeInBits(MVT::f64)/8 +
+                MVT::getSizeInBits(PtrVT)/8);
+      
+      VarArgsStackOffset = MFI->CreateFixedObject(MVT::getSizeInBits(PtrVT)/8,
+                                                  ArgOffset);
+
+    }
+    else
+      depth = ArgOffset;
+    
     VarArgsFrameIndex = MFI->CreateFixedObject(MVT::getSizeInBits(PtrVT)/8,
-                                               ArgOffset);
+                                               depth);
     SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
+    
+    SmallVector<SDOperand, 8> MemOps;
+    
+    // In ELF 32 ABI, the fixed integer arguments of a variadic function are
+    // stored to the VarArgsFrameIndex on the stack.
+    if (isELF32_ABI) {
+      for (GPR_idx = 0; GPR_idx != VarArgsNumGPR; ++GPR_idx) {
+        SDOperand Val = DAG.getRegister(GPR[GPR_idx], PtrVT);
+        SDOperand Store = DAG.getStore(Root, Val, FIN, NULL, 0);
+        MemOps.push_back(Store);
+        // Increment the address by four for the next argument to store
+        SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8, PtrVT);
+        FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff);
+      }
+    }
+
     // If this function is vararg, store any remaining integer argument regs
     // to their spots on the stack so that they may be loaded by deferencing the
     // result of va_next.
-    std::vector<SDOperand> MemOps;
     for (; GPR_idx != Num_GPR_Regs; ++GPR_idx) {
-      unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
+      unsigned VReg;
+      if (isPPC64)
+        VReg = RegMap->createVirtualRegister(&PPC::G8RCRegClass);
+      else
+        VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
+
       MF.addLiveIn(GPR[GPR_idx], VReg);
       SDOperand Val = DAG.getCopyFromReg(Root, VReg, PtrVT);
-      SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
-                                    Val, FIN, DAG.getSrcValue(NULL));
+      SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
       MemOps.push_back(Store);
       // Increment the address by four for the next argument to store
       SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8, PtrVT);
       FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff);
     }
+
+    // In ELF 32 ABI, the double arguments are stored to the VarArgsFrameIndex
+    // on the stack.
+    if (isELF32_ABI) {
+      for (FPR_idx = 0; FPR_idx != VarArgsNumFPR; ++FPR_idx) {
+        SDOperand Val = DAG.getRegister(FPR[FPR_idx], MVT::f64);
+        SDOperand Store = DAG.getStore(Root, Val, FIN, NULL, 0);
+        MemOps.push_back(Store);
+        // Increment the address by eight for the next argument to store
+        SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(MVT::f64)/8,
+                                           PtrVT);
+        FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff);
+      }
+
+      for (; FPR_idx != Num_FPR_Regs; ++FPR_idx) {
+        unsigned VReg;
+        VReg = RegMap->createVirtualRegister(&PPC::F8RCRegClass);
+
+        MF.addLiveIn(FPR[FPR_idx], VReg);
+        SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::f64);
+        SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
+        MemOps.push_back(Store);
+        // Increment the address by eight for the next argument to store
+        SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(MVT::f64)/8,
+                                           PtrVT);
+        FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff);
+      }
+    }
+
     if (!MemOps.empty())
-      Root = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps);
+      Root = DAG.getNode(ISD::TokenFactor, MVT::Other,&MemOps[0],MemOps.size());
   }
   
   ArgValues.push_back(Root);
@@ -912,7 +1523,7 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
   // 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);
+  return DAG.getNode(ISD::MERGE_VALUES, RetVT, &ArgValues[0], ArgValues.size());
 }
 
 /// isCallCompatibleAddress - Return the immediate to use if the specified
@@ -930,18 +1541,19 @@ static SDNode *isBLACompatibleAddress(SDOperand Op, SelectionDAG &DAG) {
 }
 
 
-static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
-  SDOperand Chain = Op.getOperand(0);
-  unsigned CallingConv= cast<ConstantSDNode>(Op.getOperand(1))->getValue();
-  bool isVarArg       = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
-  bool isTailCall     = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
-  SDOperand Callee    = Op.getOperand(4);
-  unsigned NumOps     = (Op.getNumOperands() - 5) / 2;
+static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG,
+                           const PPCSubtarget &Subtarget) {
+  SDOperand Chain  = Op.getOperand(0);
+  bool isVarArg    = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
+  SDOperand Callee = Op.getOperand(4);
+  unsigned NumOps  = (Op.getNumOperands() - 5) / 2;
+  
+  bool isMachoABI = Subtarget.isMachoABI();
+  bool isELF32_ABI  = Subtarget.isELF32_ABI();
 
   MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
   bool isPPC64 = PtrVT == MVT::i64;
   unsigned PtrByteSize = isPPC64 ? 8 : 4;
-
   
   // args_to_use will accumulate outgoing args for the PPCISD::CALL case in
   // SelectExpr to use to put the arguments in the appropriate registers.
@@ -950,19 +1562,22 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   // Count how many bytes are to be pushed on the stack, including the linkage
   // area, and parameter passing area.  We start with 24/48 bytes, which is
   // prereserved space for [SP][CR][LR][3 x unused].
-  unsigned NumBytes = 6*PtrByteSize;
+  unsigned NumBytes = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI);
   
   // Add up all the space actually used.
-  for (unsigned i = 0; i != NumOps; ++i)
-    NumBytes += MVT::getSizeInBits(Op.getOperand(5+2*i).getValueType())/8;
+  for (unsigned i = 0; i != NumOps; ++i) {
+    unsigned ArgSize =MVT::getSizeInBits(Op.getOperand(5+2*i).getValueType())/8;
+    ArgSize = std::max(ArgSize, PtrByteSize);
+    NumBytes += ArgSize;
+  }
 
   // The prolog code of the callee may store up to 8 GPR argument registers to
   // the stack, allowing va_start to index over them in memory if its varargs.
   // Because we cannot tell if this is needed on the caller side, we have to
   // conservatively assume that it is needed.  As such, make sure we have at
   // least enough stack space for the caller to store the 8 GPRs.
-  if (NumBytes < 6*PtrByteSize+8*PtrByteSize)
-    NumBytes = 6*PtrByteSize+8*PtrByteSize;
+  NumBytes = std::max(NumBytes,
+                      PPCFrameInfo::getMinCallFrameSize(isPPC64, isMachoABI));
   
   // Adjust the stack pointer for the new arguments...
   // These operations are automatically eliminated by the prolog/epilog pass
@@ -982,8 +1597,9 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   // memory.  Also, if this is a vararg function, floating point operations
   // must be stored to our stack, and loaded into integer regs as well, if
   // any integer regs are available for argument passing.
-  unsigned ArgOffset = 6*PtrByteSize;
+  unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI);
   unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
+  
   static const unsigned GPR_32[] = {           // 32-bit registers.
     PPC::R3, PPC::R4, PPC::R5, PPC::R6,
     PPC::R7, PPC::R8, PPC::R9, PPC::R10,
@@ -992,35 +1608,48 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
     PPC::X3, PPC::X4, PPC::X5, PPC::X6,
     PPC::X7, PPC::X8, PPC::X9, PPC::X10,
   };
-  static const unsigned FPR[] = {
-    PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
-    PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
-  };
+  static const unsigned *FPR = GetFPR(Subtarget);
+  
   static const unsigned VR[] = {
     PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
     PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
   };
-  const unsigned NumGPRs = sizeof(GPR_32)/sizeof(GPR_32[0]);
-  const unsigned NumFPRs = sizeof(FPR)/sizeof(FPR[0]);
-  const unsigned NumVRs  = sizeof( VR)/sizeof( VR[0]);
+  const unsigned NumGPRs = array_lengthof(GPR_32);
+  const unsigned NumFPRs = isMachoABI ? 13 : 8;
+  const unsigned NumVRs  = array_lengthof( VR);
   
   const unsigned *GPR = isPPC64 ? GPR_64 : GPR_32;
 
   std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
-  std::vector<SDOperand> MemOpChains;
+  SmallVector<SDOperand, 8> MemOpChains;
   for (unsigned i = 0; i != NumOps; ++i) {
+    bool inMem = false;
     SDOperand Arg = Op.getOperand(5+2*i);
-    
+    unsigned Flags = cast<ConstantSDNode>(Op.getOperand(5+2*i+1))->getValue();
+    unsigned AlignFlag = 1 << ISD::ParamFlags::OrigAlignmentOffs;
+    // See if next argument requires stack alignment in ELF
+    unsigned next = 5+2*(i+1)+1;
+    bool Expand = (Arg.getValueType() == MVT::f64) || ((i + 1 < NumOps) &&
+      (cast<ConstantSDNode>(Op.getOperand(next))->getValue() & AlignFlag) &&
+      (!(Flags & AlignFlag)));
+
     // PtrOff will be used to store the current argument to the stack if a
     // register cannot be found for it.
-    SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
+    SDOperand PtrOff;
+    
+    // Stack align in ELF 32
+    if (isELF32_ABI && Expand)
+      PtrOff = DAG.getConstant(ArgOffset + ((ArgOffset/4) % 2) * PtrByteSize,
+                               StackPtr.getValueType());
+    else
+      PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType());
+
     PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff);
 
     // On PPC64, promote integers to 64-bit values.
     if (isPPC64 && Arg.getValueType() == MVT::i32) {
-      unsigned ExtOp = ISD::ZERO_EXTEND;
-      if (cast<ConstantSDNode>(Op.getOperand(5+2*i+1))->getValue())
-        ExtOp = ISD::SIGN_EXTEND;
+      unsigned ExtOp = (Flags & 1) ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
+
       Arg = DAG.getNode(ExtOp, MVT::i64, Arg);
     }
     
@@ -1028,57 +1657,77 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
     default: assert(0 && "Unexpected ValueType for argument!");
     case MVT::i32:
     case MVT::i64:
+      // Double word align in ELF
+      if (isELF32_ABI && Expand) GPR_idx += (GPR_idx % 2);
       if (GPR_idx != NumGPRs) {
         RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Arg));
       } else {
-        MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                          Arg, PtrOff, DAG.getSrcValue(NULL)));
+        MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
+        inMem = true;
+      }
+      if (inMem || isMachoABI) {
+        // Stack align in ELF
+        if (isELF32_ABI && Expand)
+          ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize;
+
+        ArgOffset += PtrByteSize;
       }
-      ArgOffset += PtrByteSize;
       break;
     case MVT::f32:
     case MVT::f64:
+      if (isVarArg) {
+        // Float varargs need to be promoted to double.
+        if (Arg.getValueType() == MVT::f32)
+          Arg = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Arg);
+      }
+    
       if (FPR_idx != NumFPRs) {
         RegsToPass.push_back(std::make_pair(FPR[FPR_idx++], Arg));
 
         if (isVarArg) {
-          SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                        Arg, PtrOff,
-                                        DAG.getSrcValue(NULL));
+          SDOperand Store = DAG.getStore(Chain, Arg, PtrOff, NULL, 0);
           MemOpChains.push_back(Store);
 
           // Float varargs are always shadowed in available integer registers
           if (GPR_idx != NumGPRs) {
-            SDOperand Load = DAG.getLoad(PtrVT, Store, PtrOff,
-                                         DAG.getSrcValue(NULL));
+            SDOperand Load = DAG.getLoad(PtrVT, Store, PtrOff, NULL, 0);
             MemOpChains.push_back(Load.getValue(1));
-            RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
+            if (isMachoABI) RegsToPass.push_back(std::make_pair(GPR[GPR_idx++],
+                                                                Load));
           }
-          if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64{
+          if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64 && !isPPC64){
             SDOperand ConstFour = DAG.getConstant(4, PtrOff.getValueType());
             PtrOff = DAG.getNode(ISD::ADD, PtrVT, PtrOff, ConstFour);
-            SDOperand Load = DAG.getLoad(PtrVT, Store, PtrOff,
-                                         DAG.getSrcValue(NULL));
+            SDOperand Load = DAG.getLoad(PtrVT, Store, PtrOff, NULL, 0);
             MemOpChains.push_back(Load.getValue(1));
-            RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
+            if (isMachoABI) RegsToPass.push_back(std::make_pair(GPR[GPR_idx++],
+                                                                Load));
           }
         } else {
           // If we have any FPRs remaining, we may also have GPRs remaining.
           // Args passed in FPRs consume either 1 (f32) or 2 (f64) available
           // GPRs.
-          if (GPR_idx != NumGPRs)
-            ++GPR_idx;
-          if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64 && !isPPC64)
-            ++GPR_idx;
+          if (isMachoABI) {
+            if (GPR_idx != NumGPRs)
+              ++GPR_idx;
+            if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64 &&
+                !isPPC64)  // PPC64 has 64-bit GPR's obviously :)
+              ++GPR_idx;
+          }
         }
       } else {
-        MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                          Arg, PtrOff, DAG.getSrcValue(NULL)));
+        MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
+        inMem = true;
+      }
+      if (inMem || isMachoABI) {
+        // Stack align in ELF
+        if (isELF32_ABI && Expand)
+          ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize;
+        if (isPPC64)
+          ArgOffset += 8;
+        else
+          ArgOffset += Arg.getValueType() == MVT::f32 ? 4 : 8;
       }
-      if (isPPC64)
-        ArgOffset += 8;
-      else
-        ArgOffset += Arg.getValueType() == MVT::f32 ? 4 : 8;
       break;
     case MVT::v4f32:
     case MVT::v4i32:
@@ -1092,7 +1741,8 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
     }
   }
   if (!MemOpChains.empty())
-    Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOpChains);
+    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.
@@ -1102,13 +1752,20 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
                              InFlag);
     InFlag = Chain.getValue(1);
   }
-  
+  // With the ELF 32 ABI, set CR6 to true if this is a vararg call.
+  if (isVarArg && isELF32_ABI) {
+    SDOperand SetCR(DAG.getTargetNode(PPC::SETCR, MVT::i32), 0);
+    Chain = DAG.getCopyToReg(Chain, PPC::CR6, SetCR, 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.
 
-  std::vector<SDOperand> Ops;
-  unsigned CallOpc = PPCISD::CALL;
+  SmallVector<SDOperand, 8> Ops;
+  unsigned CallOpc = isMachoABI? PPCISD::CALL_Macho : PPCISD::CALL_ELF;
   
   // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
   // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
@@ -1123,24 +1780,21 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   else {
     // Otherwise, this is an indirect call.  We have to use a MTCTR/BCTRL pair
     // to do the call, we can't use PPCISD::CALL.
-    Ops.push_back(Chain);
-    Ops.push_back(Callee);
-    
-    if (InFlag.Val)
-      Ops.push_back(InFlag);
-    Chain = DAG.getNode(PPCISD::MTCTR, NodeTys, Ops);
+    SDOperand MTCTROps[] = {Chain, Callee, InFlag};
+    Chain = DAG.getNode(PPCISD::MTCTR, NodeTys, MTCTROps, 2+(InFlag.Val!=0));
     InFlag = Chain.getValue(1);
     
     // Copy the callee address into R12 on darwin.
-    Chain = DAG.getCopyToReg(Chain, PPC::R12, Callee, InFlag);
-    InFlag = Chain.getValue(1);
+    if (isMachoABI) {
+      Chain = DAG.getCopyToReg(Chain, PPC::R12, Callee, InFlag);
+      InFlag = Chain.getValue(1);
+    }
 
     NodeTys.clear();
     NodeTys.push_back(MVT::Other);
     NodeTys.push_back(MVT::Flag);
-    Ops.clear();
     Ops.push_back(Chain);
-    CallOpc = PPCISD::BCTRL;
+    CallOpc = isMachoABI ? PPCISD::BCTRL_Macho : PPCISD::BCTRL_ELF;
     Callee.Val = 0;
   }
 
@@ -1158,10 +1812,11 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   
   if (InFlag.Val)
     Ops.push_back(InFlag);
-  Chain = DAG.getNode(CallOpc, NodeTys, Ops);
+  Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size());
   InFlag = Chain.getValue(1);
 
-  std::vector<SDOperand> ResultVals;
+  SDOperand ResultVals[3];
+  unsigned NumResults = 0;
   NodeTys.clear();
   
   // If the call has results, copy the values out of the ret val registers.
@@ -1170,28 +1825,44 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   case MVT::Other: break;
   case MVT::i32:
     if (Op.Val->getValueType(1) == MVT::i32) {
-      Chain = DAG.getCopyFromReg(Chain, PPC::R4, MVT::i32, InFlag).getValue(1);
-      ResultVals.push_back(Chain.getValue(0));
-      Chain = DAG.getCopyFromReg(Chain, PPC::R3, MVT::i32,
+      Chain = DAG.getCopyFromReg(Chain, PPC::R3, MVT::i32, InFlag).getValue(1);
+      ResultVals[0] = Chain.getValue(0);
+      Chain = DAG.getCopyFromReg(Chain, PPC::R4, MVT::i32,
                                  Chain.getValue(2)).getValue(1);
-      ResultVals.push_back(Chain.getValue(0));
+      ResultVals[1] = Chain.getValue(0);
+      NumResults = 2;
       NodeTys.push_back(MVT::i32);
     } else {
       Chain = DAG.getCopyFromReg(Chain, PPC::R3, MVT::i32, InFlag).getValue(1);
-      ResultVals.push_back(Chain.getValue(0));
+      ResultVals[0] = Chain.getValue(0);
+      NumResults = 1;
     }
     NodeTys.push_back(MVT::i32);
     break;
   case MVT::i64:
     Chain = DAG.getCopyFromReg(Chain, PPC::X3, MVT::i64, InFlag).getValue(1);
-    ResultVals.push_back(Chain.getValue(0));
+    ResultVals[0] = Chain.getValue(0);
+    NumResults = 1;
     NodeTys.push_back(MVT::i64);
     break;
-  case MVT::f32:
   case MVT::f64:
+    if (Op.Val->getValueType(1) == MVT::f64) {
+      Chain = DAG.getCopyFromReg(Chain, PPC::F1, MVT::f64, InFlag).getValue(1);
+      ResultVals[0] = Chain.getValue(0);
+      Chain = DAG.getCopyFromReg(Chain, PPC::F2, MVT::f64,
+                                 Chain.getValue(2)).getValue(1);
+      ResultVals[1] = Chain.getValue(0);
+      NumResults = 2;
+      NodeTys.push_back(MVT::f64);
+      NodeTys.push_back(MVT::f64);
+      break;
+    } 
+    // else fall through
+  case MVT::f32:
     Chain = DAG.getCopyFromReg(Chain, PPC::F1, Op.Val->getValueType(0),
                                InFlag).getValue(1);
-    ResultVals.push_back(Chain.getValue(0));
+    ResultVals[0] = Chain.getValue(0);
+    NumResults = 1;
     NodeTys.push_back(Op.Val->getValueType(0));
     break;
   case MVT::v4f32:
@@ -1200,7 +1871,8 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   case MVT::v16i8:
     Chain = DAG.getCopyFromReg(Chain, PPC::V2, Op.Val->getValueType(0),
                                    InFlag).getValue(1);
-    ResultVals.push_back(Chain.getValue(0));
+    ResultVals[0] = Chain.getValue(0);
+    NumResults = 1;
     NodeTys.push_back(Op.Val->getValueType(0));
     break;
   }
@@ -1210,59 +1882,113 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   NodeTys.push_back(MVT::Other);
   
   // If the function returns void, just return the chain.
-  if (ResultVals.empty())
+  if (NumResults == 0)
     return Chain;
   
   // Otherwise, merge everything together with a MERGE_VALUES node.
-  ResultVals.push_back(Chain);
-  SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys, ResultVals);
+  ResultVals[NumResults++] = Chain;
+  SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys,
+                              ResultVals, NumResults);
   return Res.getValue(Op.ResNo);
 }
 
-static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) {
-  SDOperand Copy;
-  switch(Op.getNumOperands()) {
-  default:
-    assert(0 && "Do not know how to return this many arguments!");
-    abort();
-  case 1: 
-    return SDOperand(); // ret void is legal
-  case 3: {
-    MVT::ValueType ArgVT = Op.getOperand(1).getValueType();
-    unsigned ArgReg;
-    if (ArgVT == MVT::i32) {
-      ArgReg = PPC::R3;
-    } else if (ArgVT == MVT::i64) {
-      ArgReg = PPC::X3;
-    } else if (MVT::isFloatingPoint(ArgVT)) {
-      ArgReg = PPC::F1;
-    } else {
-      assert(MVT::isVector(ArgVT));
-      ArgReg = PPC::V2;
-    }
-    
-    Copy = DAG.getCopyToReg(Op.getOperand(0), ArgReg, Op.getOperand(1),
-                            SDOperand());
-    
-    // If we haven't noted the R3/F1 are live out, do so now.
-    if (DAG.getMachineFunction().liveout_empty())
-      DAG.getMachineFunction().addLiveOut(ArgReg);
-    break;
+static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG, TargetMachine &TM) {
+  SmallVector<CCValAssign, 16> RVLocs;
+  unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
+  bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
+  CCState CCInfo(CC, isVarArg, TM, RVLocs);
+  CCInfo.AnalyzeReturn(Op.Val, RetCC_PPC);
+  
+  // If this is the first return lowered for this function, add the regs to the
+  // liveout set for the function.
+  if (DAG.getMachineFunction().liveout_empty()) {
+    for (unsigned i = 0; i != RVLocs.size(); ++i)
+      DAG.getMachineFunction().addLiveOut(RVLocs[i].getLocReg());
   }
-  case 5:
-    Copy = DAG.getCopyToReg(Op.getOperand(0), PPC::R3, Op.getOperand(3), 
-                            SDOperand());
-    Copy = DAG.getCopyToReg(Copy, PPC::R4, Op.getOperand(1),Copy.getValue(1));
-    // If we haven't noted the R3+R4 are live out, do so now.
-    if (DAG.getMachineFunction().liveout_empty()) {
-      DAG.getMachineFunction().addLiveOut(PPC::R3);
-      DAG.getMachineFunction().addLiveOut(PPC::R4);
-    }
-    break;
+
+  SDOperand Chain = Op.getOperand(0);
+  SDOperand Flag;
+  
+  // Copy the result values into the output registers.
+  for (unsigned i = 0; i != RVLocs.size(); ++i) {
+    CCValAssign &VA = RVLocs[i];
+    assert(VA.isRegLoc() && "Can only return in registers!");
+    Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1), Flag);
+    Flag = Chain.getValue(1);
+  }
+
+  if (Flag.Val)
+    return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Chain, Flag);
+  else
+    return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Chain);
+}
+
+static SDOperand LowerSTACKRESTORE(SDOperand Op, SelectionDAG &DAG,
+                                   const PPCSubtarget &Subtarget) {
+  // When we pop the dynamic allocation we need to restore the SP link.
+  
+  // Get the corect type for pointers.
+  MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
+
+  // Construct the stack pointer operand.
+  bool IsPPC64 = Subtarget.isPPC64();
+  unsigned SP = IsPPC64 ? PPC::X1 : PPC::R1;
+  SDOperand StackPtr = DAG.getRegister(SP, PtrVT);
+
+  // Get the operands for the STACKRESTORE.
+  SDOperand Chain = Op.getOperand(0);
+  SDOperand SaveSP = Op.getOperand(1);
+  
+  // Load the old link SP.
+  SDOperand LoadLinkSP = DAG.getLoad(PtrVT, Chain, StackPtr, NULL, 0);
+  
+  // Restore the stack pointer.
+  Chain = DAG.getCopyToReg(LoadLinkSP.getValue(1), SP, SaveSP);
+  
+  // Store the old link SP.
+  return DAG.getStore(Chain, LoadLinkSP, StackPtr, NULL, 0);
+}
+
+static SDOperand LowerDYNAMIC_STACKALLOC(SDOperand Op, SelectionDAG &DAG,
+                                         const PPCSubtarget &Subtarget) {
+  MachineFunction &MF = DAG.getMachineFunction();
+  bool IsPPC64 = Subtarget.isPPC64();
+  bool isMachoABI = Subtarget.isMachoABI();
+
+  // Get current frame pointer save index.  The users of this index will be
+  // primarily DYNALLOC instructions.
+  PPCFunctionInfo *FI = MF.getInfo<PPCFunctionInfo>();
+  int FPSI = FI->getFramePointerSaveIndex();
+   
+  // If the frame pointer save index hasn't been defined yet.
+  if (!FPSI) {
+    // Find out what the fix offset of the frame pointer save area.
+    int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, isMachoABI);
+    
+    // Allocate the frame index for frame pointer save area.
+    FPSI = MF.getFrameInfo()->CreateFixedObject(IsPPC64? 8 : 4, FPOffset); 
+    // Save the result.
+    FI->setFramePointerSaveIndex(FPSI);                      
   }
-  return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
+
+  // Get the inputs.
+  SDOperand Chain = Op.getOperand(0);
+  SDOperand Size  = Op.getOperand(1);
+  
+  // Get the corect type for pointers.
+  MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
+  // Negate the size.
+  SDOperand NegSize = DAG.getNode(ISD::SUB, PtrVT,
+                                  DAG.getConstant(0, PtrVT), Size);
+  // Construct a node for the frame pointer save index.
+  SDOperand FPSIdx = DAG.getFrameIndex(FPSI, PtrVT);
+  // Build a DYNALLOC node.
+  SDOperand Ops[3] = { Chain, NegSize, FPSIdx };
+  SDVTList VTs = DAG.getVTList(PtrVT, MVT::Other);
+  return DAG.getNode(PPCISD::DYNALLOC, VTs, Ops, 3);
 }
 
+
 /// LowerSELECT_CC - Lower floating point select_cc's into fsel instruction when
 /// possible.
 static SDOperand LowerSELECT_CC(SDOperand Op, SelectionDAG &DAG) {
@@ -1309,7 +2035,7 @@ static SDOperand LowerSELECT_CC(SDOperand Op, SelectionDAG &DAG) {
                          DAG.getNode(ISD::FNEG, MVT::f64, LHS), TV, FV);
     }
       
-      SDOperand Cmp;
+  SDOperand Cmp;
   switch (CC) {
   default: break;       // SETUO etc aren't handled by fsel.
   case ISD::SETULT:
@@ -1362,10 +2088,75 @@ static SDOperand LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG) {
   }
   
   // Convert the FP value to an int value through memory.
-  SDOperand Bits = DAG.getNode(ISD::BIT_CONVERT, MVT::i64, Tmp);
+  SDOperand FIPtr = DAG.CreateStackTemporary(MVT::f64);
+  
+  // Emit a store to the stack slot.
+  SDOperand Chain = DAG.getStore(DAG.getEntryNode(), Tmp, FIPtr, NULL, 0);
+
+  // Result is a load from the stack slot.  If loading 4 bytes, make sure to
+  // add in a bias.
   if (Op.getValueType() == MVT::i32)
-    Bits = DAG.getNode(ISD::TRUNCATE, MVT::i32, Bits);
-  return Bits;
+    FIPtr = DAG.getNode(ISD::ADD, FIPtr.getValueType(), FIPtr,
+                        DAG.getConstant(4, FIPtr.getValueType()));
+  return DAG.getLoad(Op.getValueType(), Chain, FIPtr, NULL, 0);
+}
+
+static SDOperand LowerFP_ROUND_INREG(SDOperand Op, SelectionDAG &DAG) {
+  assert(Op.getValueType() == MVT::ppcf128);
+  SDNode *Node = Op.Val;
+  assert(Node->getOperand(0).getValueType() == MVT::ppcf128);
+  assert(Node->getOperand(0).Val->getOpcode() == ISD::BUILD_PAIR);
+  SDOperand Lo = Node->getOperand(0).Val->getOperand(0);
+  SDOperand Hi = Node->getOperand(0).Val->getOperand(1);
+
+  // This sequence changes FPSCR to do round-to-zero, adds the two halves
+  // of the long double, and puts FPSCR back the way it was.  We do not
+  // actually model FPSCR.
+  std::vector<MVT::ValueType> NodeTys;
+  SDOperand Ops[4], Result, MFFSreg, InFlag, FPreg;
+
+  NodeTys.push_back(MVT::f64);   // Return register
+  NodeTys.push_back(MVT::Flag);    // Returns a flag for later insns
+  Result = DAG.getNode(PPCISD::MFFS, NodeTys, &InFlag, 0);
+  MFFSreg = Result.getValue(0);
+  InFlag = Result.getValue(1);
+
+  NodeTys.clear();
+  NodeTys.push_back(MVT::Flag);   // Returns a flag
+  Ops[0] = DAG.getConstant(31, MVT::i32);
+  Ops[1] = InFlag;
+  Result = DAG.getNode(PPCISD::MTFSB1, NodeTys, Ops, 2);
+  InFlag = Result.getValue(0);
+
+  NodeTys.clear();
+  NodeTys.push_back(MVT::Flag);   // Returns a flag
+  Ops[0] = DAG.getConstant(30, MVT::i32);
+  Ops[1] = InFlag;
+  Result = DAG.getNode(PPCISD::MTFSB0, NodeTys, Ops, 2);
+  InFlag = Result.getValue(0);
+
+  NodeTys.clear();
+  NodeTys.push_back(MVT::f64);    // result of add
+  NodeTys.push_back(MVT::Flag);   // Returns a flag
+  Ops[0] = Lo;
+  Ops[1] = Hi;
+  Ops[2] = InFlag;
+  Result = DAG.getNode(PPCISD::FADDRTZ, NodeTys, Ops, 3);
+  FPreg = Result.getValue(0);
+  InFlag = Result.getValue(1);
+
+  NodeTys.clear();
+  NodeTys.push_back(MVT::f64);
+  Ops[0] = DAG.getConstant(1, MVT::i32);
+  Ops[1] = MFFSreg;
+  Ops[2] = FPreg;
+  Ops[3] = InFlag;
+  Result = DAG.getNode(PPCISD::MTFSF, NodeTys, Ops, 4);
+  FPreg = Result.getValue(0);
+
+  // We know the low half is about to be thrown away, so just use something
+  // convenient.
+  return DAG.getNode(ISD::BUILD_PAIR, Lo.getValueType(), FPreg, FPreg);
 }
 
 static SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
@@ -1385,7 +2176,8 @@ static SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
   // then lfd it and fcfid it.
   MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo();
   int FrameIdx = FrameInfo->CreateStackObject(8, 8);
-  SDOperand FIdx = DAG.getFrameIndex(FrameIdx, MVT::i32);
+  MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
+  SDOperand FIdx = DAG.getFrameIndex(FrameIdx, PtrVT);
   
   SDOperand Ext64 = DAG.getNode(PPCISD::EXTSW_32, MVT::i32,
                                 Op.getOperand(0));
@@ -1395,7 +2187,7 @@ static SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
                                 DAG.getEntryNode(), Ext64, FIdx,
                                 DAG.getSrcValue(NULL));
   // Load the value as a double.
-  SDOperand Ld = DAG.getLoad(MVT::f64, Store, FIdx, DAG.getSrcValue(NULL));
+  SDOperand Ld = DAG.getLoad(MVT::f64, Store, FIdx, NULL, 0);
   
   // FCFID it and return it.
   SDOperand FP = DAG.getNode(PPCISD::FCFID, MVT::f64, Ld);
@@ -1404,20 +2196,15 @@ static SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
   return FP;
 }
 
-static SDOperand LowerSHL(SDOperand Op, SelectionDAG &DAG,
-                          MVT::ValueType PtrVT) {
-  assert(Op.getValueType() == MVT::i64 &&
+static SDOperand LowerSHL_PARTS(SDOperand Op, SelectionDAG &DAG) {
+  assert(Op.getNumOperands() == 3 && Op.getValueType() == MVT::i32 &&
          Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!");
-  // The generic code does a fine job expanding shift by a constant.
-  if (isa<ConstantSDNode>(Op.getOperand(1))) return SDOperand();
   
-  // Otherwise, expand into a bunch of logical ops.  Note that these ops
+  // Expand into a bunch of logical ops.  Note that these ops
   // depend on the PPC behavior for oversized shift amounts.
-  SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
-                             DAG.getConstant(0, PtrVT));
-  SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
-                             DAG.getConstant(1, PtrVT));
-  SDOperand Amt = Op.getOperand(1);
+  SDOperand Lo = Op.getOperand(0);
+  SDOperand Hi = Op.getOperand(1);
+  SDOperand Amt = Op.getOperand(2);
   
   SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
                                DAG.getConstant(32, MVT::i32), Amt);
@@ -1429,23 +2216,20 @@ static SDOperand LowerSHL(SDOperand Op, SelectionDAG &DAG,
   SDOperand Tmp6 = DAG.getNode(PPCISD::SHL, MVT::i32, Lo, Tmp5);
   SDOperand OutHi = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6);
   SDOperand OutLo = DAG.getNode(PPCISD::SHL, MVT::i32, Lo, Amt);
-  return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
+  SDOperand OutOps[] = { OutLo, OutHi };
+  return DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(MVT::i32, MVT::i32),
+                     OutOps, 2);
 }
 
-static SDOperand LowerSRL(SDOperand Op, SelectionDAG &DAG,
-                          MVT::ValueType PtrVT) {
-  assert(Op.getValueType() == MVT::i64 &&
-         Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!");
-  // The generic code does a fine job expanding shift by a constant.
-  if (isa<ConstantSDNode>(Op.getOperand(1))) return SDOperand();
+static SDOperand LowerSRL_PARTS(SDOperand Op, SelectionDAG &DAG) {
+  assert(Op.getNumOperands() == 3 && Op.getValueType() == MVT::i32 &&
+         Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SRL!");
   
   // Otherwise, expand into a bunch of logical ops.  Note that these ops
   // depend on the PPC behavior for oversized shift amounts.
-  SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
-                             DAG.getConstant(0, PtrVT));
-  SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
-                             DAG.getConstant(1, PtrVT));
-  SDOperand Amt = Op.getOperand(1);
+  SDOperand Lo = Op.getOperand(0);
+  SDOperand Hi = Op.getOperand(1);
+  SDOperand Amt = Op.getOperand(2);
   
   SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
                                DAG.getConstant(32, MVT::i32), Amt);
@@ -1457,22 +2241,19 @@ static SDOperand LowerSRL(SDOperand Op, SelectionDAG &DAG,
   SDOperand Tmp6 = DAG.getNode(PPCISD::SRL, MVT::i32, Hi, Tmp5);
   SDOperand OutLo = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6);
   SDOperand OutHi = DAG.getNode(PPCISD::SRL, MVT::i32, Hi, Amt);
-  return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
+  SDOperand OutOps[] = { OutLo, OutHi };
+  return DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(MVT::i32, MVT::i32),
+                     OutOps, 2);
 }
 
-static SDOperand LowerSRA(SDOperand Op, SelectionDAG &DAG,
-                          MVT::ValueType PtrVT) {
-  assert(Op.getValueType() == MVT::i64 &&
+static SDOperand LowerSRA_PARTS(SDOperand Op, SelectionDAG &DAG) {
+  assert(Op.getNumOperands() == 3 && Op.getValueType() == MVT::i32 &&
          Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SRA!");
-  // The generic code does a fine job expanding shift by a constant.
-  if (isa<ConstantSDNode>(Op.getOperand(1))) return SDOperand();
   
   // Otherwise, expand into a bunch of logical ops, followed by a select_cc.
-  SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
-                             DAG.getConstant(0, PtrVT));
-  SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
-                             DAG.getConstant(1, PtrVT));
-  SDOperand Amt = Op.getOperand(1);
+  SDOperand Lo = Op.getOperand(0);
+  SDOperand Hi = Op.getOperand(1);
+  SDOperand Amt = Op.getOperand(2);
   
   SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
                                DAG.getConstant(32, MVT::i32), Amt);
@@ -1485,7 +2266,9 @@ static SDOperand LowerSRA(SDOperand Op, SelectionDAG &DAG,
   SDOperand OutHi = DAG.getNode(PPCISD::SRA, MVT::i32, Hi, Amt);
   SDOperand OutLo = DAG.getSelectCC(Tmp5, DAG.getConstant(0, MVT::i32),
                                     Tmp4, Tmp6, ISD::SETLE);
-  return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
+  SDOperand OutOps[] = { OutLo, OutHi };
+  return DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(MVT::i32, MVT::i32),
+                     OutOps, 2);
 }
 
 //===----------------------------------------------------------------------===//
@@ -1519,7 +2302,7 @@ static bool GetConstantBuildVectorBits(SDNode *BV, uint64_t VectorBits[2],
     } else if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(OpVal)) {
       assert(CN->getValueType(0) == MVT::f32 &&
              "Only one legal FP vector type!");
-      EltBits = FloatToBits(CN->getValue());
+      EltBits = FloatToBits(CN->getValueAPF().convertToFloat());
     } else {
       // Nonconstant element.
       return true;
@@ -1591,20 +2374,26 @@ static bool isConstantSplat(const uint64_t Bits128[2],
 static SDOperand BuildSplatI(int Val, unsigned SplatSize, MVT::ValueType VT,
                              SelectionDAG &DAG) {
   assert(Val >= -16 && Val <= 15 && "vsplti is out of range!");
-  
-  // Force vspltis[hw] -1 to vspltisb -1.
-  if (Val == -1) SplatSize = 1;
-  
+
   static const MVT::ValueType VTys[] = { // canonical VT to use for each size.
     MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
   };
+
+  MVT::ValueType ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
+  
+  // Force vspltis[hw] -1 to vspltisb -1 to canonicalize.
+  if (Val == -1)
+    SplatSize = 1;
+  
   MVT::ValueType CanonicalVT = VTys[SplatSize-1];
   
   // Build a canonical splat for this value.
-  SDOperand Elt = DAG.getConstant(Val, MVT::getVectorBaseType(CanonicalVT));
-  std::vector<SDOperand> Ops(MVT::getVectorNumElements(CanonicalVT), Elt);
-  SDOperand Res = DAG.getNode(ISD::BUILD_VECTOR, CanonicalVT, Ops);
-  return DAG.getNode(ISD::BIT_CONVERT, VT, Res);
+  SDOperand Elt = DAG.getConstant(Val, MVT::getVectorElementType(CanonicalVT));
+  SmallVector<SDOperand, 8> Ops;
+  Ops.assign(MVT::getVectorNumElements(CanonicalVT), Elt);
+  SDOperand Res = DAG.getNode(ISD::BUILD_VECTOR, CanonicalVT,
+                              &Ops[0], Ops.size());
+  return DAG.getNode(ISD::BIT_CONVERT, ReqVT, Res);
 }
 
 /// BuildIntrinsicOp - Return a binary operator intrinsic node with the
@@ -1636,11 +2425,11 @@ static SDOperand BuildVSLDOI(SDOperand LHS, SDOperand RHS, unsigned Amt,
   LHS = DAG.getNode(ISD::BIT_CONVERT, MVT::v16i8, LHS);
   RHS = DAG.getNode(ISD::BIT_CONVERT, MVT::v16i8, RHS);
   
-  std::vector<SDOperand> Ops;
+  SDOperand Ops[16];
   for (unsigned i = 0; i != 16; ++i)
-    Ops.push_back(DAG.getConstant(i+Amt, MVT::i32));
+    Ops[i] = DAG.getConstant(i+Amt, MVT::i32);
   SDOperand T = DAG.getNode(ISD::VECTOR_SHUFFLE, MVT::v16i8, LHS, RHS,
-                            DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8, Ops));
+                            DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8, Ops,16));
   return DAG.getNode(ISD::BIT_CONVERT, VT, T);
 }
 
@@ -1713,11 +2502,12 @@ static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
 
     // Check to see if this is a wide variety of vsplti*, binop self cases.
     unsigned SplatBitSize = SplatSize*8;
-    static const char SplatCsts[] = {
+    static const signed char SplatCsts[] = {
       -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
       -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
     };
-    for (unsigned idx = 0; idx < sizeof(SplatCsts)/sizeof(SplatCsts[0]); ++idx){
+    
+    for (unsigned idx = 0; idx < array_lengthof(SplatCsts); ++idx) {
       // Indirect through the SplatCsts array so that we favor 'vsplti -1' for
       // cases which are ambiguous (e.g. formation of 0x8000_0000).  'vsplti -1'
       int i = SplatCsts[idx];
@@ -1728,43 +2518,47 @@ static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
       
       // vsplti + shl self.
       if (SextVal == (i << (int)TypeShiftAmt)) {
-        Op = BuildSplatI(i, SplatSize, Op.getValueType(), DAG);
+        SDOperand Res = BuildSplatI(i, SplatSize, MVT::Other, DAG);
         static const unsigned IIDs[] = { // Intrinsic to use for each size.
           Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
           Intrinsic::ppc_altivec_vslw
         };
-        return BuildIntrinsicOp(IIDs[SplatSize-1], Op, Op, DAG);
+        Res = BuildIntrinsicOp(IIDs[SplatSize-1], Res, Res, DAG);
+        return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), Res);
       }
       
       // vsplti + srl self.
       if (SextVal == (int)((unsigned)i >> TypeShiftAmt)) {
-        Op = BuildSplatI(i, SplatSize, Op.getValueType(), DAG);
+        SDOperand Res = BuildSplatI(i, SplatSize, MVT::Other, DAG);
         static const unsigned IIDs[] = { // Intrinsic to use for each size.
           Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
           Intrinsic::ppc_altivec_vsrw
         };
-        return BuildIntrinsicOp(IIDs[SplatSize-1], Op, Op, DAG);
+        Res = BuildIntrinsicOp(IIDs[SplatSize-1], Res, Res, DAG);
+        return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), Res);
       }
       
       // vsplti + sra self.
       if (SextVal == (int)((unsigned)i >> TypeShiftAmt)) {
-        Op = BuildSplatI(i, SplatSize, Op.getValueType(), DAG);
+        SDOperand Res = BuildSplatI(i, SplatSize, MVT::Other, DAG);
         static const unsigned IIDs[] = { // Intrinsic to use for each size.
           Intrinsic::ppc_altivec_vsrab, Intrinsic::ppc_altivec_vsrah, 0,
           Intrinsic::ppc_altivec_vsraw
         };
-        return BuildIntrinsicOp(IIDs[SplatSize-1], Op, Op, DAG);
+        Res = BuildIntrinsicOp(IIDs[SplatSize-1], Res, Res, DAG);
+        return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), Res);
       }
       
       // vsplti + rol self.
       if (SextVal == (int)(((unsigned)i << TypeShiftAmt) |
                            ((unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
-        Op = BuildSplatI(i, SplatSize, Op.getValueType(), DAG);
+        SDOperand Res = BuildSplatI(i, SplatSize, MVT::Other, DAG);
         static const unsigned IIDs[] = { // Intrinsic to use for each size.
           Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
           Intrinsic::ppc_altivec_vrlw
         };
-        return BuildIntrinsicOp(IIDs[SplatSize-1], Op, Op, DAG);
+        Res = BuildIntrinsicOp(IIDs[SplatSize-1], Res, Res, DAG);
+        return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), Res);
       }
 
       // t = vsplti c, result = vsldoi t, t, 1
@@ -1788,15 +2582,17 @@ static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
     
     // Odd, in range [17,31]:  (vsplti C)-(vsplti -16).
     if (SextVal >= 0 && SextVal <= 31) {
-      SDOperand LHS = BuildSplatI(SextVal-16, SplatSize, Op.getValueType(),DAG);
-      SDOperand RHS = BuildSplatI(-16, SplatSize, Op.getValueType(), DAG);
-      return DAG.getNode(ISD::SUB, Op.getValueType(), LHS, RHS);
+      SDOperand LHS = BuildSplatI(SextVal-16, SplatSize, MVT::Other, DAG);
+      SDOperand RHS = BuildSplatI(-16, SplatSize, MVT::Other, DAG);
+      LHS = DAG.getNode(ISD::SUB, LHS.getValueType(), LHS, RHS);
+      return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), LHS);
     }
     // Odd, in range [-31,-17]:  (vsplti C)+(vsplti -16).
     if (SextVal >= -31 && SextVal <= 0) {
-      SDOperand LHS = BuildSplatI(SextVal+16, SplatSize, Op.getValueType(),DAG);
-      SDOperand RHS = BuildSplatI(-16, SplatSize, Op.getValueType(), DAG);
-      return DAG.getNode(ISD::ADD, Op.getValueType(), LHS, RHS);
+      SDOperand LHS = BuildSplatI(SextVal+16, SplatSize, MVT::Other, DAG);
+      SDOperand RHS = BuildSplatI(-16, SplatSize, MVT::Other, DAG);
+      LHS = DAG.getNode(ISD::ADD, LHS.getValueType(), LHS, RHS);
+      return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), LHS);
     }
   }
     
@@ -1872,12 +2668,12 @@ static SDOperand GeneratePerfectShuffle(unsigned PFEntry, SDOperand LHS,
   case OP_VSLDOI12:
     return BuildVSLDOI(OpLHS, OpRHS, 12, OpLHS.getValueType(), DAG);
   }
-  std::vector<SDOperand> Ops;
+  SDOperand Ops[16];
   for (unsigned i = 0; i != 16; ++i)
-    Ops.push_back(DAG.getConstant(ShufIdxs[i], MVT::i32));
+    Ops[i] = DAG.getConstant(ShufIdxs[i], MVT::i32);
   
   return DAG.getNode(ISD::VECTOR_SHUFFLE, OpLHS.getValueType(), OpLHS, OpRHS,
-                     DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8, Ops));
+                     DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8, Ops, 16));
 }
 
 /// LowerVECTOR_SHUFFLE - Return the code we lower for VECTOR_SHUFFLE.  If this
@@ -1982,10 +2778,10 @@ static SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
   
   // The SHUFFLE_VECTOR mask is almost exactly what we want for vperm, except
   // that it is in input element units, not in bytes.  Convert now.
-  MVT::ValueType EltVT = MVT::getVectorBaseType(V1.getValueType());
+  MVT::ValueType EltVT = MVT::getVectorElementType(V1.getValueType());
   unsigned BytesPerElement = MVT::getSizeInBits(EltVT)/8;
   
-  std::vector<SDOperand> ResultMask;
+  SmallVector<SDOperand, 16> ResultMask;
   for (unsigned i = 0, e = PermMask.getNumOperands(); i != e; ++i) {
     unsigned SrcElt;
     if (PermMask.getOperand(i).getOpcode() == ISD::UNDEF)
@@ -1998,7 +2794,8 @@ static SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
                                            MVT::i8));
   }
   
-  SDOperand VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8, ResultMask);
+  SDOperand VPermMask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
+                                    &ResultMask[0], ResultMask.size());
   return DAG.getNode(PPCISD::VPERM, V1.getValueType(), V1, V2, VPermMask);
 }
 
@@ -2064,14 +2861,15 @@ static SDOperand LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG) {
   }
   
   // Create the PPCISD altivec 'dot' comparison node.
-  std::vector<SDOperand> Ops;
+  SDOperand Ops[] = {
+    Op.getOperand(2),  // LHS
+    Op.getOperand(3),  // RHS
+    DAG.getConstant(CompareOpc, MVT::i32)
+  };
   std::vector<MVT::ValueType> VTs;
-  Ops.push_back(Op.getOperand(2));  // LHS
-  Ops.push_back(Op.getOperand(3));  // RHS
-  Ops.push_back(DAG.getConstant(CompareOpc, MVT::i32));
   VTs.push_back(Op.getOperand(2).getValueType());
   VTs.push_back(MVT::Flag);
-  SDOperand CompNode = DAG.getNode(PPCISD::VCMPo, VTs, Ops);
+  SDOperand CompNode = DAG.getNode(PPCISD::VCMPo, VTs, Ops, 3);
   
   // Now that we have the comparison, emit a copy from the CR to a GPR.
   // This is flagged to the above dot comparison.
@@ -2116,13 +2914,14 @@ static SDOperand LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG) {
   // Create a stack slot that is 16-byte aligned.
   MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo();
   int FrameIdx = FrameInfo->CreateStackObject(16, 16);
-  SDOperand FIdx = DAG.getFrameIndex(FrameIdx, MVT::i32);
+  MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
+  SDOperand FIdx = DAG.getFrameIndex(FrameIdx, PtrVT);
   
   // Store the input value into Value#0 of the stack slot.
-  SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
-                                Op.getOperand(0), FIdx,DAG.getSrcValue(NULL));
+  SDOperand Store = DAG.getStore(DAG.getEntryNode(),
+                                 Op.getOperand(0), FIdx, NULL, 0);
   // Load it out.
-  return DAG.getLoad(Op.getValueType(), Store, FIdx, DAG.getSrcValue(NULL));
+  return DAG.getLoad(Op.getValueType(), Store, FIdx, NULL, 0);
 }
 
 static SDOperand LowerMUL(SDOperand Op, SelectionDAG &DAG) {
@@ -2171,14 +2970,13 @@ static SDOperand LowerMUL(SDOperand Op, SelectionDAG &DAG) {
     OddParts = DAG.getNode(ISD::BIT_CONVERT, MVT::v16i8, OddParts);
     
     // Merge the results together.
-    std::vector<SDOperand> Ops;
+    SDOperand Ops[16];
     for (unsigned i = 0; i != 8; ++i) {
-      Ops.push_back(DAG.getConstant(2*i+1, MVT::i8));
-      Ops.push_back(DAG.getConstant(2*i+1+16, MVT::i8));
+      Ops[i*2  ] = DAG.getConstant(2*i+1, MVT::i8);
+      Ops[i*2+1] = DAG.getConstant(2*i+1+16, MVT::i8);
     }
-    
     return DAG.getNode(ISD::VECTOR_SHUFFLE, MVT::v16i8, EvenParts, OddParts,
-                       DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8, Ops));
+                       DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8, Ops, 16));
   } else {
     assert(0 && "Unknown mul to lower!");
     abort();
@@ -2192,22 +2990,37 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   default: assert(0 && "Wasn't expecting to be able to lower this!"); 
   case ISD::ConstantPool:       return LowerConstantPool(Op, DAG);
   case ISD::GlobalAddress:      return LowerGlobalAddress(Op, DAG);
+  case ISD::GlobalTLSAddress:   return LowerGlobalTLSAddress(Op, DAG);
   case ISD::JumpTable:          return LowerJumpTable(Op, DAG);
   case ISD::SETCC:              return LowerSETCC(Op, DAG);
-  case ISD::VASTART:            return LowerVASTART(Op, DAG, VarArgsFrameIndex);
+  case ISD::VASTART:            
+    return LowerVASTART(Op, DAG, VarArgsFrameIndex, VarArgsStackOffset,
+                        VarArgsNumGPR, VarArgsNumFPR, PPCSubTarget);
+  
+  case ISD::VAARG:            
+    return LowerVAARG(Op, DAG, VarArgsFrameIndex, VarArgsStackOffset,
+                      VarArgsNumGPR, VarArgsNumFPR, PPCSubTarget);
+
   case ISD::FORMAL_ARGUMENTS:
-      return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
-  case ISD::CALL:               return LowerCALL(Op, DAG);
-  case ISD::RET:                return LowerRET(Op, DAG);
+    return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex, 
+                                 VarArgsStackOffset, VarArgsNumGPR,
+                                 VarArgsNumFPR, PPCSubTarget);
+
+  case ISD::CALL:               return LowerCALL(Op, DAG, PPCSubTarget);
+  case ISD::RET:                return LowerRET(Op, DAG, getTargetMachine());
+  case ISD::STACKRESTORE:       return LowerSTACKRESTORE(Op, DAG, PPCSubTarget);
+  case ISD::DYNAMIC_STACKALLOC:
+    return LowerDYNAMIC_STACKALLOC(Op, DAG, PPCSubTarget);
     
   case ISD::SELECT_CC:          return LowerSELECT_CC(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_ROUND_INREG:     return LowerFP_ROUND_INREG(Op, DAG);
 
   // Lower 64-bit shifts.
-  case ISD::SHL:                return LowerSHL(Op, DAG, getPointerTy());
-  case ISD::SRL:                return LowerSRL(Op, DAG, getPointerTy());
-  case ISD::SRA:                return LowerSRA(Op, DAG, getPointerTy());
+  case ISD::SHL_PARTS:          return LowerSHL_PARTS(Op, DAG);
+  case ISD::SRL_PARTS:          return LowerSRL_PARTS(Op, DAG);
+  case ISD::SRA_PARTS:          return LowerSRA_PARTS(Op, DAG);
 
   // Vector-related lowering.
   case ISD::BUILD_VECTOR:       return LowerBUILD_VECTOR(Op, DAG);
@@ -2215,6 +3028,10 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
   case ISD::SCALAR_TO_VECTOR:   return LowerSCALAR_TO_VECTOR(Op, DAG);
   case ISD::MUL:                return LowerMUL(Op, DAG);
+  
+  // Frame & Return address.  Currently unimplemented
+  case ISD::RETURNADDR:         break;
+  case ISD::FRAMEADDR:          return LowerFRAMEADDR(Op, DAG);
   }
   return SDOperand();
 }
@@ -2226,6 +3043,7 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
 MachineBasicBlock *
 PPCTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
                                            MachineBasicBlock *BB) {
+  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
   assert((MI->getOpcode() == PPC::SELECT_CC_I4 ||
           MI->getOpcode() == PPC::SELECT_CC_I8 ||
           MI->getOpcode() == PPC::SELECT_CC_F4 ||
@@ -2250,8 +3068,9 @@ PPCTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
   MachineBasicBlock *thisMBB = BB;
   MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
   MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
-  BuildMI(BB, MI->getOperand(4).getImmedValue(), 2)
-    .addReg(MI->getOperand(1).getReg()).addMBB(sinkMBB);
+  unsigned SelectPred = MI->getOperand(4).getImm();
+  BuildMI(BB, TII->get(PPC::BCC))
+    .addImm(SelectPred).addReg(MI->getOperand(1).getReg()).addMBB(sinkMBB);
   MachineFunction *F = BB->getParent();
   F->getBasicBlockList().insert(It, copy0MBB);
   F->getBasicBlockList().insert(It, sinkMBB);
@@ -2279,7 +3098,7 @@ PPCTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
   //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
   //  ...
   BB = sinkMBB;
-  BuildMI(BB, PPC::PHI, 4, MI->getOperand(0).getReg())
+  BuildMI(BB, TII->get(PPC::PHI), MI->getOperand(0).getReg())
     .addReg(MI->getOperand(3).getReg()).addMBB(copy0MBB)
     .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB);
 
@@ -2297,6 +3116,26 @@ SDOperand PPCTargetLowering::PerformDAGCombine(SDNode *N,
   SelectionDAG &DAG = DCI.DAG;
   switch (N->getOpcode()) {
   default: break;
+  case PPCISD::SHL:
+    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(0))) {
+      if (C->getValue() == 0)   // 0 << V -> 0.
+        return N->getOperand(0);
+    }
+    break;
+  case PPCISD::SRL:
+    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(0))) {
+      if (C->getValue() == 0)   // 0 >>u V -> 0.
+        return N->getOperand(0);
+    }
+    break;
+  case PPCISD::SRA:
+    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(0))) {
+      if (C->getValue() == 0 ||   //  0 >>s V -> 0.
+          C->isAllOnesValue())    // -1 >>s V -> -1.
+        return N->getOperand(0);
+    }
+    break;
+    
   case ISD::SINT_TO_FP:
     if (TM.getSubtarget<PPCSubtarget>().has64BitSupport()) {
       if (N->getOperand(0).getOpcode() == ISD::FP_TO_SINT) {
@@ -2344,6 +3183,59 @@ SDOperand PPCTargetLowering::PerformDAGCombine(SDNode *N,
       DCI.AddToWorklist(Val.Val);
       return Val;
     }
+    
+    // Turn STORE (BSWAP) -> sthbrx/stwbrx.
+    if (N->getOperand(1).getOpcode() == ISD::BSWAP &&
+        N->getOperand(1).Val->hasOneUse() &&
+        (N->getOperand(1).getValueType() == MVT::i32 ||
+         N->getOperand(1).getValueType() == MVT::i16)) {
+      SDOperand BSwapOp = N->getOperand(1).getOperand(0);
+      // Do an any-extend to 32-bits if this is a half-word input.
+      if (BSwapOp.getValueType() == MVT::i16)
+        BSwapOp = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, BSwapOp);
+
+      return DAG.getNode(PPCISD::STBRX, MVT::Other, N->getOperand(0), BSwapOp,
+                         N->getOperand(2), N->getOperand(3),
+                         DAG.getValueType(N->getOperand(1).getValueType()));
+    }
+    break;
+  case ISD::BSWAP:
+    // Turn BSWAP (LOAD) -> lhbrx/lwbrx.
+    if (ISD::isNON_EXTLoad(N->getOperand(0).Val) &&
+        N->getOperand(0).hasOneUse() &&
+        (N->getValueType(0) == MVT::i32 || N->getValueType(0) == MVT::i16)) {
+      SDOperand Load = N->getOperand(0);
+      LoadSDNode *LD = cast<LoadSDNode>(Load);
+      // Create the byte-swapping load.
+      std::vector<MVT::ValueType> VTs;
+      VTs.push_back(MVT::i32);
+      VTs.push_back(MVT::Other);
+      SDOperand SV = DAG.getSrcValue(LD->getSrcValue(), LD->getSrcValueOffset());
+      SDOperand Ops[] = {
+        LD->getChain(),    // Chain
+        LD->getBasePtr(),  // Ptr
+        SV,                // SrcValue
+        DAG.getValueType(N->getValueType(0)) // VT
+      };
+      SDOperand BSLoad = DAG.getNode(PPCISD::LBRX, VTs, Ops, 4);
+
+      // If this is an i16 load, insert the truncate.  
+      SDOperand ResVal = BSLoad;
+      if (N->getValueType(0) == MVT::i16)
+        ResVal = DAG.getNode(ISD::TRUNCATE, MVT::i16, BSLoad);
+      
+      // First, combine the bswap away.  This makes the value produced by the
+      // load dead.
+      DCI.CombineTo(N, ResVal);
+
+      // Next, combine the load away, we give it a bogus result value but a real
+      // chain result.  The result value is dead because the bswap is dead.
+      DCI.CombineTo(Load.Val, ResVal, BSLoad.getValue(1));
+      
+      // Return N so it doesn't get rechecked!
+      return SDOperand(N, 0);
+    }
+    
     break;
   case PPCISD::VCMP: {
     // If a VCMPo node already exists with exactly the same operands as this
@@ -2425,36 +3317,37 @@ SDOperand PPCTargetLowering::PerformDAGCombine(SDNode *N,
       bool BranchOnWhenPredTrue = (CC == ISD::SETEQ) ^ (Val == 0);
       
       // Create the PPCISD altivec 'dot' comparison node.
-      std::vector<SDOperand> Ops;
       std::vector<MVT::ValueType> VTs;
-      Ops.push_back(LHS.getOperand(2));  // LHS of compare
-      Ops.push_back(LHS.getOperand(3));  // RHS of compare
-      Ops.push_back(DAG.getConstant(CompareOpc, MVT::i32));
+      SDOperand Ops[] = {
+        LHS.getOperand(2),  // LHS of compare
+        LHS.getOperand(3),  // RHS of compare
+        DAG.getConstant(CompareOpc, MVT::i32)
+      };
       VTs.push_back(LHS.getOperand(2).getValueType());
       VTs.push_back(MVT::Flag);
-      SDOperand CompNode = DAG.getNode(PPCISD::VCMPo, VTs, Ops);
+      SDOperand CompNode = DAG.getNode(PPCISD::VCMPo, VTs, Ops, 3);
       
       // Unpack the result based on how the target uses it.
-      unsigned CompOpc;
+      PPC::Predicate CompOpc;
       switch (cast<ConstantSDNode>(LHS.getOperand(1))->getValue()) {
       default:  // Can't happen, don't crash on invalid number though.
       case 0:   // Branch on the value of the EQ bit of CR6.
-        CompOpc = BranchOnWhenPredTrue ? PPC::BEQ : PPC::BNE;
+        CompOpc = BranchOnWhenPredTrue ? PPC::PRED_EQ : PPC::PRED_NE;
         break;
       case 1:   // Branch on the inverted value of the EQ bit of CR6.
-        CompOpc = BranchOnWhenPredTrue ? PPC::BNE : PPC::BEQ;
+        CompOpc = BranchOnWhenPredTrue ? PPC::PRED_NE : PPC::PRED_EQ;
         break;
       case 2:   // Branch on the value of the LT bit of CR6.
-        CompOpc = BranchOnWhenPredTrue ? PPC::BLT : PPC::BGE;
+        CompOpc = BranchOnWhenPredTrue ? PPC::PRED_LT : PPC::PRED_GE;
         break;
       case 3:   // Branch on the inverted value of the LT bit of CR6.
-        CompOpc = BranchOnWhenPredTrue ? PPC::BGE : PPC::BLT;
+        CompOpc = BranchOnWhenPredTrue ? PPC::PRED_GE : PPC::PRED_LT;
         break;
       }
 
       return DAG.getNode(PPCISD::COND_BRANCH, MVT::Other, N->getOperand(0),
-                         DAG.getRegister(PPC::CR6, MVT::i32),
                          DAG.getConstant(CompOpc, MVT::i32),
+                         DAG.getRegister(PPC::CR6, MVT::i32),
                          N->getOperand(4), CompNode.getValue(1));
     }
     break;
@@ -2472,11 +3365,18 @@ void PPCTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
                                                        uint64_t Mask,
                                                        uint64_t &KnownZero, 
                                                        uint64_t &KnownOne,
+                                                       const SelectionDAG &DAG,
                                                        unsigned Depth) const {
   KnownZero = 0;
   KnownOne = 0;
   switch (Op.getOpcode()) {
   default: break;
+  case PPCISD::LBRX: {
+    // lhbrx is known to have the top bits cleared out.
+    if (cast<VTSDNode>(Op.getOperand(3))->getVT() == MVT::i16)
+      KnownZero = 0xFFFF0000;
+    break;
+  }
   case ISD::INTRINSIC_WO_CHAIN: {
     switch (cast<ConstantSDNode>(Op.getOperand(0))->getValue()) {
     default: break;
@@ -2501,82 +3401,58 @@ void PPCTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
 }
 
 
-/// getConstraintType - Given a constraint letter, return the type of
+/// getConstraintType - Given a constraint, return the type of
 /// constraint it is for this target.
 PPCTargetLowering::ConstraintType 
-PPCTargetLowering::getConstraintType(char ConstraintLetter) const {
-  switch (ConstraintLetter) {
-  default: break;
-  case 'b':
-  case 'r':
-  case 'f':
-  case 'v':
-  case 'y':
-    return C_RegisterClass;
-  }  
-  return TargetLowering::getConstraintType(ConstraintLetter);
+PPCTargetLowering::getConstraintType(const std::string &Constraint) const {
+  if (Constraint.size() == 1) {
+    switch (Constraint[0]) {
+    default: break;
+    case 'b':
+    case 'r':
+    case 'f':
+    case 'v':
+    case 'y':
+      return C_RegisterClass;
+    }
+  }
+  return TargetLowering::getConstraintType(Constraint);
 }
 
-
-std::vector<unsigned> PPCTargetLowering::
-getRegClassForInlineAsmConstraint(const std::string &Constraint,
-                                  MVT::ValueType VT) const {
+std::pair<unsigned, const TargetRegisterClass*> 
+PPCTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
+                                                MVT::ValueType VT) const {
   if (Constraint.size() == 1) {
-    switch (Constraint[0]) {      // GCC RS6000 Constraint Letters
-    default: break;  // Unknown constriant letter
-    case 'b': 
-      return make_vector<unsigned>(/*no R0*/ PPC::R1 , PPC::R2 , PPC::R3 ,
-                                   PPC::R4 , PPC::R5 , PPC::R6 , PPC::R7 ,
-                                   PPC::R8 , PPC::R9 , PPC::R10, PPC::R11, 
-                                   PPC::R12, PPC::R13, PPC::R14, PPC::R15, 
-                                   PPC::R16, PPC::R17, PPC::R18, PPC::R19, 
-                                   PPC::R20, PPC::R21, PPC::R22, PPC::R23, 
-                                   PPC::R24, PPC::R25, PPC::R26, PPC::R27, 
-                                   PPC::R28, PPC::R29, PPC::R30, PPC::R31, 
-                                   0);
-    case 'r': 
-      return make_vector<unsigned>(PPC::R0 , PPC::R1 , PPC::R2 , PPC::R3 ,
-                                   PPC::R4 , PPC::R5 , PPC::R6 , PPC::R7 ,
-                                   PPC::R8 , PPC::R9 , PPC::R10, PPC::R11, 
-                                   PPC::R12, PPC::R13, PPC::R14, PPC::R15, 
-                                   PPC::R16, PPC::R17, PPC::R18, PPC::R19, 
-                                   PPC::R20, PPC::R21, PPC::R22, PPC::R23, 
-                                   PPC::R24, PPC::R25, PPC::R26, PPC::R27, 
-                                   PPC::R28, PPC::R29, PPC::R30, PPC::R31, 
-                                   0);
-    case 'f': 
-      return make_vector<unsigned>(PPC::F0 , PPC::F1 , PPC::F2 , PPC::F3 ,
-                                   PPC::F4 , PPC::F5 , PPC::F6 , PPC::F7 ,
-                                   PPC::F8 , PPC::F9 , PPC::F10, PPC::F11, 
-                                   PPC::F12, PPC::F13, PPC::F14, PPC::F15, 
-                                   PPC::F16, PPC::F17, PPC::F18, PPC::F19, 
-                                   PPC::F20, PPC::F21, PPC::F22, PPC::F23, 
-                                   PPC::F24, PPC::F25, PPC::F26, PPC::F27, 
-                                   PPC::F28, PPC::F29, PPC::F30, PPC::F31, 
-                                   0);
+    // GCC RS6000 Constraint Letters
+    switch (Constraint[0]) {
+    case 'b':   // R1-R31
+    case 'r':   // R0-R31
+      if (VT == MVT::i64 && PPCSubTarget.isPPC64())
+        return std::make_pair(0U, PPC::G8RCRegisterClass);
+      return std::make_pair(0U, PPC::GPRCRegisterClass);
+    case 'f':
+      if (VT == MVT::f32)
+        return std::make_pair(0U, PPC::F4RCRegisterClass);
+      else if (VT == MVT::f64)
+        return std::make_pair(0U, PPC::F8RCRegisterClass);
+      break;
     case 'v': 
-      return make_vector<unsigned>(PPC::V0 , PPC::V1 , PPC::V2 , PPC::V3 ,
-                                   PPC::V4 , PPC::V5 , PPC::V6 , PPC::V7 ,
-                                   PPC::V8 , PPC::V9 , PPC::V10, PPC::V11, 
-                                   PPC::V12, PPC::V13, PPC::V14, PPC::V15, 
-                                   PPC::V16, PPC::V17, PPC::V18, PPC::V19, 
-                                   PPC::V20, PPC::V21, PPC::V22, PPC::V23, 
-                                   PPC::V24, PPC::V25, PPC::V26, PPC::V27, 
-                                   PPC::V28, PPC::V29, PPC::V30, PPC::V31, 
-                                   0);
-    case 'y': 
-      return make_vector<unsigned>(PPC::CR0, PPC::CR1, PPC::CR2, PPC::CR3,
-                                   PPC::CR4, PPC::CR5, PPC::CR6, PPC::CR7,
-                                   0);
+      return std::make_pair(0U, PPC::VRRCRegisterClass);
+    case 'y':   // crrc
+      return std::make_pair(0U, PPC::CRRCRegisterClass);
     }
   }
   
-  return std::vector<unsigned>();
+  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
 }
 
-// isOperandValidForConstraint
-bool PPCTargetLowering::
-isOperandValidForConstraint(SDOperand Op, char Letter) {
+
+/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
+/// vector.  If it is invalid, don't add anything to Ops.
+void PPCTargetLowering::LowerAsmOperandForConstraint(SDOperand Op, char Letter,
+                                                     std::vector<SDOperand>&Ops,
+                                                     SelectionDAG &DAG) {
+  SDOperand Result(0,0);
   switch (Letter) {
   default: break;
   case 'I':
@@ -2587,37 +3463,120 @@ isOperandValidForConstraint(SDOperand Op, char Letter) {
   case 'N':
   case 'O':
   case 'P': {
-    if (!isa<ConstantSDNode>(Op)) return false;  // Must be an immediate.
-    unsigned Value = cast<ConstantSDNode>(Op)->getValue();
+    ConstantSDNode *CST = dyn_cast<ConstantSDNode>(Op);
+    if (!CST) return; // Must be an immediate to match.
+    unsigned Value = CST->getValue();
     switch (Letter) {
     default: assert(0 && "Unknown constraint letter!");
     case 'I':  // "I" is a signed 16-bit constant.
-      return (short)Value == (int)Value;
+      if ((short)Value == (int)Value)
+        Result = DAG.getTargetConstant(Value, Op.getValueType());
+      break;
     case 'J':  // "J" is a constant with only the high-order 16 bits nonzero.
     case 'L':  // "L" is a signed 16-bit constant shifted left 16 bits.
-      return (short)Value == 0;
+      if ((short)Value == 0)
+        Result = DAG.getTargetConstant(Value, Op.getValueType());
+      break;
     case 'K':  // "K" is a constant with only the low-order 16 bits nonzero.
-      return (Value >> 16) == 0;
+      if ((Value >> 16) == 0)
+        Result = DAG.getTargetConstant(Value, Op.getValueType());
+      break;
     case 'M':  // "M" is a constant that is greater than 31.
-      return Value > 31;
+      if (Value > 31)
+        Result = DAG.getTargetConstant(Value, Op.getValueType());
+      break;
     case 'N':  // "N" is a positive constant that is an exact power of two.
-      return (int)Value > 0 && isPowerOf2_32(Value);
+      if ((int)Value > 0 && isPowerOf2_32(Value))
+        Result = DAG.getTargetConstant(Value, Op.getValueType());
+      break;
     case 'O':  // "O" is the constant zero. 
-      return Value == 0;
+      if (Value == 0)
+        Result = DAG.getTargetConstant(Value, Op.getValueType());
+      break;
     case 'P':  // "P" is a constant whose negation is a signed 16-bit constant.
-      return (short)-Value == (int)-Value;
+      if ((short)-Value == (int)-Value)
+        Result = DAG.getTargetConstant(Value, Op.getValueType());
+      break;
     }
     break;
   }
   }
   
+  if (Result.Val) {
+    Ops.push_back(Result);
+    return;
+  }
+  
   // Handle standard constraint letters.
-  return TargetLowering::isOperandValidForConstraint(Op, Letter);
+  TargetLowering::LowerAsmOperandForConstraint(Op, Letter, Ops, DAG);
+}
+
+// isLegalAddressingMode - Return true if the addressing mode represented
+// by AM is legal for this target, for a load/store of the specified type.
+bool PPCTargetLowering::isLegalAddressingMode(const AddrMode &AM, 
+                                              const Type *Ty) const {
+  // FIXME: PPC does not allow r+i addressing modes for vectors!
+  
+  // PPC allows a sign-extended 16-bit immediate field.
+  if (AM.BaseOffs <= -(1LL << 16) || AM.BaseOffs >= (1LL << 16)-1)
+    return false;
+  
+  // No global is ever allowed as a base.
+  if (AM.BaseGV)
+    return false;
+  
+  // PPC only support r+r, 
+  switch (AM.Scale) {
+  case 0:  // "r+i" or just "i", depending on HasBaseReg.
+    break;
+  case 1:
+    if (AM.HasBaseReg && AM.BaseOffs)  // "r+r+i" is not allowed.
+      return false;
+    // Otherwise we have r+r or r+i.
+    break;
+  case 2:
+    if (AM.HasBaseReg || AM.BaseOffs)  // 2*r+r  or  2*r+i is not allowed.
+      return false;
+    // Allow 2*r as r+r.
+    break;
+  default:
+    // No other scales are supported.
+    return false;
+  }
+  
+  return true;
 }
 
 /// isLegalAddressImmediate - Return true if the integer value can be used
-/// as the offset of the target addressing mode.
-bool PPCTargetLowering::isLegalAddressImmediate(int64_t V) const {
+/// as the offset of the target addressing mode for load / store of the
+/// given type.
+bool PPCTargetLowering::isLegalAddressImmediate(int64_t V,const Type *Ty) const{
   // PPC allows a sign-extended 16-bit immediate field.
   return (V > -(1 << 16) && V < (1 << 16)-1);
 }
+
+bool PPCTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
+  return false; 
+}
+
+SDOperand PPCTargetLowering::LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG)
+{
+  // Depths > 0 not supported yet! 
+  if (cast<ConstantSDNode>(Op.getOperand(0))->getValue() > 0)
+    return SDOperand();
+  
+  MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
+  bool isPPC64 = PtrVT == MVT::i64;
+  
+  MachineFunction &MF = DAG.getMachineFunction();
+  MachineFrameInfo *MFI = MF.getFrameInfo();
+  bool is31 = (NoFramePointerElim || MFI->hasVarSizedObjects()) 
+                  && MFI->getStackSize();
+
+  if (isPPC64)
+    return DAG.getCopyFromReg(DAG.getEntryNode(), is31 ? PPC::X31 : PPC::X1,
+      MVT::i64);
+  else
+    return DAG.getCopyFromReg(DAG.getEntryNode(), is31 ? PPC::R31 : PPC::R1,
+      MVT::i32);
+}