The ELF ABI specifies F1-F8 registers as argument registers for double, not
[oota-llvm.git] / lib / Target / PowerPC / PPCISelLowering.cpp
index d26bfb53cd3383b47e92144c3da0d131edbe22c1..5ac87104f99a9b5ee6c16e9847de47842d50686e 100644 (file)
@@ -18,6 +18,7 @@
 #include "PPCPerfectShuffle.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"
@@ -36,12 +37,11 @@ static cl::opt<bool> EnablePPCPreinc("enable-ppc-preinc");
 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);
@@ -141,14 +141,18 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
 
   // 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.
@@ -170,7 +174,7 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
   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::STACKRESTORE      , MVT::Other, Custom);
   setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32  , Custom);
   setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64  , Custom);
 
@@ -180,8 +184,11 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
   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.
@@ -281,10 +288,15 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
   setShiftAmountType(MVT::i32);
   setSetCCResultContents(ZeroOrOneSetCCResult);
   
-  if (TM.getSubtarget<PPCSubtarget>().isPPC64())
+  if (TM.getSubtarget<PPCSubtarget>().isPPC64()) {
     setStackPointerRegisterToSaveRestore(PPC::X1);
-  else 
+    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);
@@ -308,15 +320,18 @@ 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";
@@ -740,14 +755,18 @@ bool PPCTargetLowering::SelectAddressRegImm(SDOperand N, SDOperand &Disp,
       Base = DAG.getRegister(PPC::R0, CN->getValueType(0));
       return true;
     }
-    
-    // FIXME: Handle small sext constant offsets in PPC64 mode also!
-    if (CN->getValueType(0) == MVT::i32) {
+
+    // 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.getConstant(Addr - (signed short)Addr, MVT::i32);
+      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;
     }
   }
@@ -834,25 +853,30 @@ bool PPCTargetLowering::SelectAddressRegImmShift(SDOperand N, SDOperand &Disp,
       }
     }
   } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) {
-    // Loading from a constant address.
-    
-    // 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;
-    }
+    // 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;
+      }
     
-    // FIXME: Handle small sext constant offsets in PPC64 mode also!
-    if (CN->getValueType(0) == MVT::i32) {
-      int Addr = (int)CN->getValue();
+      // 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.getConstant(Addr - (signed short)Addr, MVT::i32);
-      return true;
+        // 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;
+      }
     }
   }
   
@@ -1012,8 +1036,7 @@ 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
@@ -1074,8 +1097,30 @@ static SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG,
                       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,
+                                       const PPCSubtarget &Subtarget) {
   // TODO: add description of PPC stack frame format, or at least some docs.
   //
   MachineFunction &MF = DAG.getMachineFunction();
@@ -1086,9 +1131,11 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
   
   MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
   bool isPPC64 = PtrVT == MVT::i64;
+  bool isMachoABI = Subtarget.isMachoABI();
+  bool isELF_ABI = Subtarget.isELF_ABI();
   unsigned PtrByteSize = isPPC64 ? 8 : 4;
 
-  unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64);
+  unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI);
   
   static const unsigned GPR_32[] = {           // 32-bit registers.
     PPC::R3, PPC::R4, PPC::R5, PPC::R6,
@@ -1098,17 +1145,16 @@ 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
   };
 
   const unsigned Num_GPR_Regs = sizeof(GPR_32)/sizeof(GPR_32[0]);
-  const unsigned Num_FPR_Regs = sizeof(FPR)/sizeof(FPR[0]);
+  const unsigned Num_FPR_Regs = isMachoABI ? 13 : 8;
   const unsigned Num_VR_Regs  = sizeof( VR)/sizeof( VR[0]);
 
   unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
@@ -1118,20 +1164,30 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
   // Add DAG nodes to load the arguments or copy them out of registers.  On
   // entry to a function on PPC, the arguments start after the linkage area,
   // although the first ones are often in registers.
+  // 
+  // In the ELF 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 += PtrByteSize;
-
+      // Double word align in ELF
+      if (Expand && isELF_ABI && !isPPC64) GPR_idx += (GPR_idx % 2);
       if (GPR_idx != Num_GPR_Regs) {
         unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
         MF.addLiveIn(GPR[GPR_idx], VReg);
@@ -1141,11 +1197,14 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
         needsLoad = true;
         ArgSize = PtrByteSize;
       }
+      // Stack align in ELF
+      if (needsLoad && Expand && isELF_ABI && !isPPC64) 
+        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);
@@ -1154,15 +1213,15 @@ 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 += isPPC64 ? 8 : 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 && !isPPC64)
           ++GPR_idx;
@@ -1179,6 +1238,12 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
       } else {
         needsLoad = true;
       }
+      
+      // Stack align in ELF
+      if (needsLoad && Expand && isELF_ABI && !isPPC64)
+        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:
@@ -1270,11 +1335,16 @@ static SDNode *isBLACompatibleAddress(SDOperand Op, SelectionDAG &DAG) {
   return DAG.getConstant((int)C->getValue() >> 2, MVT::i32).Val;
 }
 
-static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
-  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;
+
+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 isELF_ABI  = Subtarget.isELF_ABI();
 
   MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
   bool isPPC64 = PtrVT == MVT::i64;
@@ -1287,7 +1357,7 @@ 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 = PPCFrameInfo::getLinkageSize(isPPC64);
+  unsigned NumBytes = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI);
   
   // Add up all the space actually used.
   for (unsigned i = 0; i != NumOps; ++i) {
@@ -1301,7 +1371,8 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   // 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.
-  NumBytes = std::max(NumBytes, PPCFrameInfo::getMinCallFrameSize(isPPC64));
+  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
@@ -1321,7 +1392,7 @@ 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 = PPCFrameInfo::getLinkageSize(isPPC64);
+  unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI);
   unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
   
   static const unsigned GPR_32[] = {           // 32-bit registers.
@@ -1332,16 +1403,14 @@ 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 NumFPRs = isMachoABI ? 13 : 8;
   const unsigned NumVRs  = sizeof( VR)/sizeof( VR[0]);
   
   const unsigned *GPR = isPPC64 ? GPR_64 : GPR_32;
@@ -1349,18 +1418,33 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
   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
+    if (isELF_ABI && Expand && !isPPC64)
+      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);
     }
     
@@ -1368,15 +1452,30 @@ 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 (isELF_ABI && Expand && !isPPC64) GPR_idx += (GPR_idx % 2);
       if (GPR_idx != NumGPRs) {
         RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Arg));
       } else {
         MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
+        inMem = true;
+      }
+      if (inMem || isMachoABI) {
+        // Stack align in ELF
+        if (isELF_ABI && Expand && !isPPC64)
+          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));
 
@@ -1388,31 +1487,42 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
           if (GPR_idx != NumGPRs) {
             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, 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.getStore(Chain, Arg, PtrOff, NULL, 0));
+        inMem = true;
+      }
+      if (inMem || isMachoABI) {
+        // Stack align in ELF
+        if (isELF_ABI && Expand && !isPPC64)
+          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:
@@ -1437,13 +1547,20 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
                              InFlag);
     InFlag = Chain.getValue(1);
   }
-  
+  // With the ELF ABI, set CR6 to true if this is a vararg call.
+  if (isVarArg && isELF_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.
 
   SmallVector<SDOperand, 8> Ops;
-  unsigned CallOpc = PPCISD::CALL;
+  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
@@ -1463,14 +1580,16 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
     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.push_back(Chain);
-    CallOpc = PPCISD::BCTRL;
+    CallOpc = isMachoABI ? PPCISD::BCTRL_Macho : PPCISD::BCTRL_ELF;
     Callee.Val = 0;
   }
 
@@ -1556,66 +1675,80 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   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::isVector(ArgVT)) {
-      ArgReg = PPC::V2;
-    } else {
-      assert(MVT::isFloatingPoint(ArgVT));
-      ArgReg = PPC::F1;
-    }
-    
-    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();
+  CCState CCInfo(CC, 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);
   }
-  return DAG.getNode(PPCISD::RET_FLAG, MVT::Other, Copy, Copy.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 Offset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64);
+    int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, isMachoABI);
+    
     // Allocate the frame index for frame pointer save area.
-    FPSI = MF.getFrameInfo()->CreateFixedObject(IsPPC64? 8 : 4, Offset); 
+    FPSI = MF.getFrameInfo()->CreateFixedObject(IsPPC64? 8 : 4, FPOffset); 
     // Save the result.
     FI->setFramePointerSaveIndex(FPSI);                      
   }
@@ -1958,13 +2091,17 @@ 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.
@@ -1973,7 +2110,7 @@ static SDOperand BuildSplatI(int Val, unsigned SplatSize, MVT::ValueType VT,
   Ops.assign(MVT::getVectorNumElements(CanonicalVT), Elt);
   SDOperand Res = DAG.getNode(ISD::BUILD_VECTOR, CanonicalVT,
                               &Ops[0], Ops.size());
-  return DAG.getNode(ISD::BIT_CONVERT, VT, Res);
+  return DAG.getNode(ISD::BIT_CONVERT, ReqVT, Res);
 }
 
 /// BuildIntrinsicOp - Return a binary operator intrinsic node with the
@@ -2082,10 +2219,11 @@ 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){
       // Indirect through the SplatCsts array so that we favor 'vsplti -1' for
       // cases which are ambiguous (e.g. formation of 0x8000_0000).  'vsplti -1'
@@ -2097,43 +2235,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
@@ -2157,15 +2299,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, Op.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, Op.getValueType(), LHS, RHS);
+      return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), LHS);
     }
   }
     
@@ -2567,11 +2711,12 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   case ISD::SETCC:              return LowerSETCC(Op, DAG);
   case ISD::VASTART:            return LowerVASTART(Op, DAG, VarArgsFrameIndex);
   case ISD::FORMAL_ARGUMENTS:
-      return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
-  case ISD::CALL:               return LowerCALL(Op, DAG);
-  case ISD::RET:                return LowerRET(Op, DAG);
-  case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG,
-                                                               PPCSubTarget);
+    return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex, 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);
@@ -2588,6 +2733,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();
 }
@@ -2956,20 +3105,22 @@ 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::pair<unsigned, const TargetRegisterClass*> 
@@ -3048,13 +3199,69 @@ isOperandValidForConstraint(SDOperand Op, char Letter, SelectionDAG &DAG) {
   return TargetLowering::isOperandValidForConstraint(Op, Letter, 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;
+  }
+  
+  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 TargetLowering::isLegalAddressImmediate(GV); 
+  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::i32);
+  else
+    return DAG.getCopyFromReg(DAG.getEntryNode(), is31 ? PPC::R31 : PPC::R1,
+      MVT::i32);
 }