Default ISD::PREFETCH to expand.
[oota-llvm.git] / lib / Target / Sparc / SparcISelDAGToDAG.cpp
index c5ad35ac12ba1e6d76a10c42a13ed4dc210c48af..95f4e0867307624b8325e6412b8990079755f0dd 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Chris Lattner and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
-#include "llvm/CodeGen/SSARegMap.h"
 #include "llvm/Target/TargetLowering.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/Debug.h"
-#include <iostream>
+#include <queue>
 #include <set>
 using namespace llvm;
 
@@ -75,12 +76,18 @@ static SPCC::CondCodes IntCondCCodeToICC(ISD::CondCode CC) {
 static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) {
   switch (CC) {
   default: assert(0 && "Unknown fp condition code!");
-  case ISD::SETEQ:  return SPCC::FCC_E;
-  case ISD::SETNE:  return SPCC::FCC_NE;
-  case ISD::SETLT:  return SPCC::FCC_L;
-  case ISD::SETGT:  return SPCC::FCC_G;
-  case ISD::SETLE:  return SPCC::FCC_LE;
-  case ISD::SETGE:  return SPCC::FCC_GE;
+  case ISD::SETEQ:
+  case ISD::SETOEQ: return SPCC::FCC_E;
+  case ISD::SETNE:
+  case ISD::SETUNE: return SPCC::FCC_NE;
+  case ISD::SETLT:
+  case ISD::SETOLT: return SPCC::FCC_L;
+  case ISD::SETGT:
+  case ISD::SETOGT: return SPCC::FCC_G;
+  case ISD::SETLE:
+  case ISD::SETOLE: return SPCC::FCC_LE;
+  case ISD::SETGE:
+  case ISD::SETOGE: return SPCC::FCC_GE;
   case ISD::SETULT: return SPCC::FCC_UL;
   case ISD::SETULE: return SPCC::FCC_ULE;
   case ISD::SETUGT: return SPCC::FCC_UG;
@@ -103,20 +110,21 @@ namespace {
     /// in Mask are known to be either zero or one and return them in the 
     /// KnownZero/KnownOne bitsets.
     virtual void computeMaskedBitsForTargetNode(const SDOperand Op,
-                                                uint64_t Mask,
-                                                uint64_t &KnownZero, 
-                                                uint64_t &KnownOne,
+                                                const APInt &Mask,
+                                                APInt &KnownZero, 
+                                                APInt &KnownOne,
+                                                const SelectionDAG &DAG,
                                                 unsigned Depth = 0) const;
     
     virtual std::vector<SDOperand>
       LowerArguments(Function &F, SelectionDAG &DAG);
     virtual std::pair<SDOperand, SDOperand>
-      LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
-                  unsigned CC,
-                  bool isTailCall, SDOperand Callee, ArgListTy &Args,
-                  SelectionDAG &DAG);
-    virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
-                                                       MachineBasicBlock *MBB);
+      LowerCallTo(SDOperand Chain, const Type *RetTy,
+                  bool RetSExt, bool RetZExt, bool isVarArg,
+                  unsigned CC, bool isTailCall, SDOperand Callee,
+                  ArgListTy &Args, SelectionDAG &DAG);
+    virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
+                                                        MachineBasicBlock *MBB);
     
     virtual const char *getTargetNodeName(unsigned Opcode) const;
   };
@@ -130,8 +138,16 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
   addRegisterClass(MVT::f32, SP::FPRegsRegisterClass);
   addRegisterClass(MVT::f64, SP::DFPRegsRegisterClass);
 
+  // Turn FP extload into load/fextend
+  setLoadXAction(ISD::EXTLOAD, MVT::f32, Expand);
+  // Sparc doesn't have i1 sign extending load
+  setLoadXAction(ISD::SEXTLOAD, MVT::i1, Promote);
+  // Turn FP truncstore into trunc + store.
+  setTruncStoreAction(MVT::f64, MVT::f32, Expand);
+
   // Custom legalize GlobalAddress nodes into LO/HI parts.
   setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
+  setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
   setOperationAction(ISD::ConstantPool , MVT::i32, Custom);
   
   // Sparc doesn't have sext_inreg, replace them with shl/sra
@@ -139,9 +155,11 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand);
   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand);
 
-  // Sparc has no REM operation.
+  // Sparc has no REM or DIVREM operations.
   setOperationAction(ISD::UREM, MVT::i32, Expand);
   setOperationAction(ISD::SREM, MVT::i32, Expand);
+  setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
+  setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
 
   // Custom expand fp<->sint
   setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
@@ -154,9 +172,6 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
   setOperationAction(ISD::BIT_CONVERT, MVT::f32, Expand);
   setOperationAction(ISD::BIT_CONVERT, MVT::i32, Expand);
   
-  // Turn FP extload into load/fextend
-  setOperationAction(ISD::EXTLOAD, MVT::f32, Expand);
-  
   // Sparc has no select or setcc: expand to SELECT_CC.
   setOperationAction(ISD::SELECT, MVT::i32, Expand);
   setOperationAction(ISD::SELECT, MVT::f32, Expand);
@@ -167,7 +182,8 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
   
   // Sparc doesn't have BRCOND either, it has BR_CC.
   setOperationAction(ISD::BRCOND, MVT::Other, Expand);
-  setOperationAction(ISD::BRIND, MVT::i32, Expand);
+  setOperationAction(ISD::BRIND, MVT::Other, Expand);
+  setOperationAction(ISD::BR_JT, MVT::Other, Expand);
   setOperationAction(ISD::BR_CC, MVT::i32, Custom);
   setOperationAction(ISD::BR_CC, MVT::f32, Custom);
   setOperationAction(ISD::BR_CC, MVT::f64, Custom);
@@ -180,11 +196,14 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
   setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
   setOperationAction(ISD::MEMSET, MVT::Other, Expand);
   setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
-  
+  setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
+
   setOperationAction(ISD::FSIN , MVT::f64, Expand);
   setOperationAction(ISD::FCOS , MVT::f64, Expand);
+  setOperationAction(ISD::FREM , MVT::f64, Expand);
   setOperationAction(ISD::FSIN , MVT::f32, Expand);
   setOperationAction(ISD::FCOS , MVT::f32, Expand);
+  setOperationAction(ISD::FREM , MVT::f32, Expand);
   setOperationAction(ISD::CTPOP, MVT::i32, Expand);
   setOperationAction(ISD::CTTZ , MVT::i32, Expand);
   setOperationAction(ISD::CTLZ , MVT::i32, Expand);
@@ -193,19 +212,24 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
   setOperationAction(ISD::BSWAP, MVT::i32, Expand);
   setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
   setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
+  setOperationAction(ISD::FPOW , MVT::f64, Expand);
+  setOperationAction(ISD::FPOW , MVT::f32, Expand);
 
   setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
   setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
   setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
 
+  // FIXME: Sparc provides these multiplies, but we don't have them yet.
+  setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
+    
   // We don't have line number support yet.
   setOperationAction(ISD::LOCATION, MVT::Other, Expand);
   setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
-  setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand);
+  setOperationAction(ISD::LABEL, MVT::Other, Expand);
 
   // 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 needs to be lowered to not do unaligned accesses for doubles.
@@ -218,14 +242,15 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
   setOperationAction(ISD::STACKRESTORE      , MVT::Other, Expand);
   setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32  , Custom);
 
-  setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
-  setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
-  
+  // No debug info support yet.
+  setOperationAction(ISD::LOCATION, MVT::Other, Expand);
+  setOperationAction(ISD::LABEL, MVT::Other, Expand);
+  setOperationAction(ISD::DECLARE, MVT::Other, Expand);
+    
   setStackPointerRegisterToSaveRestore(SP::O6);
 
-  if (TM.getSubtarget<SparcSubtarget>().isV9()) {
+  if (TM.getSubtarget<SparcSubtarget>().isV9())
     setOperationAction(ISD::CTPOP, MVT::i32, Legal);
-  }
   
   computeRegisterProperties();
 }
@@ -252,19 +277,22 @@ const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const {
 /// be zero. Op is expected to be a target specific node. Used by DAG
 /// combiner.
 void SparcTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
-                                                         uint64_t Mask,
-                                                         uint64_t &KnownZero, 
-                                                         uint64_t &KnownOne,
+                                                         const APInt &Mask,
+                                                         APInt &KnownZero, 
+                                                         APInt &KnownOne,
+                                                         const SelectionDAG &DAG,
                                                          unsigned Depth) const {
-  uint64_t KnownZero2, KnownOne2;
-  KnownZero = KnownOne = 0;   // Don't know anything.
+  APInt KnownZero2, KnownOne2;
+  KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0);   // Don't know anything.
   
   switch (Op.getOpcode()) {
   default: break;
   case SPISD::SELECT_ICC:
   case SPISD::SELECT_FCC:
-    ComputeMaskedBits(Op.getOperand(1), Mask, KnownZero, KnownOne, Depth+1);
-    ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero2, KnownOne2, Depth+1);
+    DAG.ComputeMaskedBits(Op.getOperand(1), Mask, KnownZero, KnownOne,
+                          Depth+1);
+    DAG.ComputeMaskedBits(Op.getOperand(0), Mask, KnownZero2, KnownOne2,
+                          Depth+1);
     assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); 
     assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); 
     
@@ -281,7 +309,7 @@ void SparcTargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
 std::vector<SDOperand>
 SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
   MachineFunction &MF = DAG.getMachineFunction();
-  SSARegMap *RegMap = MF.getSSARegMap();
+  MachineRegisterInfo &RegInfo = MF.getRegInfo();
   std::vector<SDOperand> ArgValues;
   
   static const unsigned ArgRegs[] = {
@@ -307,12 +335,11 @@ SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
         if (CurArgReg < ArgRegEnd) ++CurArgReg;
         ArgValues.push_back(DAG.getNode(ISD::UNDEF, ObjectVT));
       } else if (CurArgReg < ArgRegEnd) {  // Lives in an incoming GPR
-        unsigned VReg = RegMap->createVirtualRegister(&SP::IntRegsRegClass);
-        MF.addLiveIn(*CurArgReg++, VReg);
+        unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
+        MF.getRegInfo().addLiveIn(*CurArgReg++, VReg);
         SDOperand Arg = DAG.getCopyFromReg(Root, VReg, MVT::i32);
         if (ObjectVT != MVT::i32) {
-          unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext 
-                                                       : ISD::AssertZext;
+          unsigned AssertOp = ISD::AssertSext;
           Arg = DAG.getNode(AssertOp, MVT::i32, Arg, 
                             DAG.getValueType(ObjectVT));
           Arg = DAG.getNode(ISD::TRUNCATE, ObjectVT, Arg);
@@ -323,17 +350,16 @@ SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
         SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
         SDOperand Load;
         if (ObjectVT == MVT::i32) {
-          Load = DAG.getLoad(MVT::i32, Root, FIPtr, DAG.getSrcValue(0));
+          Load = DAG.getLoad(MVT::i32, Root, FIPtr, NULL, 0);
         } else {
-          unsigned LoadOp =
-            I->getType()->isSigned() ? ISD::SEXTLOAD : ISD::ZEXTLOAD;
+          ISD::LoadExtType LoadOp = ISD::SEXTLOAD;
 
           // Sparc is big endian, so add an offset based on the ObjectVT.
           unsigned Offset = 4-std::max(1U, MVT::getSizeInBits(ObjectVT)/8);
           FIPtr = DAG.getNode(ISD::ADD, MVT::i32, FIPtr,
                               DAG.getConstant(Offset, MVT::i32));
           Load = DAG.getExtLoad(LoadOp, MVT::i32, Root, FIPtr,
-                                DAG.getSrcValue(0), ObjectVT);
+                                NULL, 0, ObjectVT);
           Load = DAG.getNode(ISD::TRUNCATE, ObjectVT, Load);
         }
         ArgValues.push_back(Load);
@@ -347,8 +373,8 @@ SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
         ArgValues.push_back(DAG.getNode(ISD::UNDEF, ObjectVT));
       } else if (CurArgReg < ArgRegEnd) {  // Lives in an incoming GPR
         // FP value is passed in an integer register.
-        unsigned VReg = RegMap->createVirtualRegister(&SP::IntRegsRegClass);
-        MF.addLiveIn(*CurArgReg++, VReg);
+        unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
+        MF.getRegInfo().addLiveIn(*CurArgReg++, VReg);
         SDOperand Arg = DAG.getCopyFromReg(Root, VReg, MVT::i32);
 
         Arg = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, Arg);
@@ -356,7 +382,7 @@ SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
       } else {
         int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset);
         SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
-        SDOperand Load = DAG.getLoad(MVT::f32, Root, FIPtr, DAG.getSrcValue(0));
+        SDOperand Load = DAG.getLoad(MVT::f32, Root, FIPtr, NULL, 0);
         ArgValues.push_back(Load);
       }
       ArgOffset += 4;
@@ -377,29 +403,28 @@ SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
         // because the double wouldn't be aligned!
         int FrameIdx = MF.getFrameInfo()->CreateFixedObject(8, ArgOffset);
         SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
-        ArgValues.push_back(DAG.getLoad(MVT::f64, Root, FIPtr, 
-                                        DAG.getSrcValue(0)));
+        ArgValues.push_back(DAG.getLoad(MVT::f64, Root, FIPtr, NULL, 0));
       } else {
         SDOperand HiVal;
         if (CurArgReg < ArgRegEnd) {  // Lives in an incoming GPR
-          unsigned VRegHi = RegMap->createVirtualRegister(&SP::IntRegsRegClass);
-          MF.addLiveIn(*CurArgReg++, VRegHi);
+          unsigned VRegHi = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
+          MF.getRegInfo().addLiveIn(*CurArgReg++, VRegHi);
           HiVal = DAG.getCopyFromReg(Root, VRegHi, MVT::i32);
         } else {
           int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset);
           SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
-          HiVal = DAG.getLoad(MVT::i32, Root, FIPtr, DAG.getSrcValue(0));
+          HiVal = DAG.getLoad(MVT::i32, Root, FIPtr, NULL, 0);
         }
         
         SDOperand LoVal;
         if (CurArgReg < ArgRegEnd) {  // Lives in an incoming GPR
-          unsigned VRegLo = RegMap->createVirtualRegister(&SP::IntRegsRegClass);
-          MF.addLiveIn(*CurArgReg++, VRegLo);
+          unsigned VRegLo = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
+          MF.getRegInfo().addLiveIn(*CurArgReg++, VRegLo);
           LoVal = DAG.getCopyFromReg(Root, VRegLo, MVT::i32);
         } else {
           int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset+4);
           SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
-          LoVal = DAG.getLoad(MVT::i32, Root, FIPtr, DAG.getSrcValue(0));
+          LoVal = DAG.getLoad(MVT::i32, Root, FIPtr, NULL, 0);
         }
         
         // Compose the two halves together into an i64 unit.
@@ -423,21 +448,21 @@ SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
     VarArgsFrameOffset = ArgOffset;
     
     for (; CurArgReg != ArgRegEnd; ++CurArgReg) {
-      unsigned VReg = RegMap->createVirtualRegister(&SP::IntRegsRegClass);
-      MF.addLiveIn(*CurArgReg, VReg);
+      unsigned VReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
+      MF.getRegInfo().addLiveIn(*CurArgReg, VReg);
       SDOperand Arg = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
 
       int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset);
       SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32);
 
-      OutChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(),
-                                      Arg, FIPtr, DAG.getSrcValue(0)));
+      OutChains.push_back(DAG.getStore(DAG.getRoot(), Arg, FIPtr, NULL, 0));
       ArgOffset += 4;
     }
   }
   
   if (!OutChains.empty())
-    DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains));
+    DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other,
+                            &OutChains[0], OutChains.size()));
   
   // Finally, inform the code generator which regs we return values in.
   switch (getValueType(F.getReturnType())) {
@@ -447,17 +472,17 @@ SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
   case MVT::i8:
   case MVT::i16:
   case MVT::i32:
-    MF.addLiveOut(SP::I0);
+    MF.getRegInfo().addLiveOut(SP::I0);
     break;
   case MVT::i64:
-    MF.addLiveOut(SP::I0);
-    MF.addLiveOut(SP::I1);
+    MF.getRegInfo().addLiveOut(SP::I0);
+    MF.getRegInfo().addLiveOut(SP::I1);
     break;
   case MVT::f32:
-    MF.addLiveOut(SP::F0);
+    MF.getRegInfo().addLiveOut(SP::F0);
     break;
   case MVT::f64:
-    MF.addLiveOut(SP::D0);
+    MF.getRegInfo().addLiveOut(SP::D0);
     break;
   }
   
@@ -466,13 +491,13 @@ SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
 
 std::pair<SDOperand, SDOperand>
 SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
-                                 bool isVarArg, unsigned CC,
-                                 bool isTailCall, SDOperand Callee, 
+                                 bool RetSExt, bool RetZExt, bool isVarArg,
+                                 unsigned CC, bool isTailCall, SDOperand Callee,
                                  ArgListTy &Args, SelectionDAG &DAG) {
   // Count the size of the outgoing arguments.
   unsigned ArgsSize = 0;
   for (unsigned i = 0, e = Args.size(); i != e; ++i) {
-    switch (getValueType(Args[i].second)) {
+    switch (getValueType(Args[i].Ty)) {
     default: assert(0 && "Unknown value type!");
     case MVT::i1:
     case MVT::i8:
@@ -497,12 +522,12 @@ SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
 
   Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(ArgsSize, getPointerTy()));
   
-  SDOperand StackPtr, NullSV;
+  SDOperand StackPtr;
   std::vector<SDOperand> Stores;
   std::vector<SDOperand> RegValuesToPass;
   unsigned ArgOffset = 68;
   for (unsigned i = 0, e = Args.size(); i != e; ++i) {
-    SDOperand Val = Args[i].first;
+    SDOperand Val = Args[i].Node;
     MVT::ValueType ObjectVT = Val.getValueType();
     SDOperand ValToStore(0, 0);
     unsigned ObjSize;
@@ -510,14 +535,17 @@ SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
     default: assert(0 && "Unhandled argument type!");
     case MVT::i1:
     case MVT::i8:
-    case MVT::i16:
+    case MVT::i16: {
       // Promote the integer to 32-bits.  If the input type is signed, use a
       // sign extend, otherwise use a zero extend.
-      if (Args[i].second->isSigned())
-        Val = DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Val);
-      else
-        Val = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Val);
+      ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
+      if (Args[i].isSExt)
+        ExtendKind = ISD::SIGN_EXTEND;
+      else if (Args[i].isZExt)
+        ExtendKind = ISD::ZERO_EXTEND;
+      Val = DAG.getNode(ExtendKind, MVT::i32, Val);
       // FALL THROUGH
+    }
     case MVT::i32:
       ObjSize = 4;
 
@@ -558,9 +586,9 @@ SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
       }
       
       // Split the value into top and bottom part.  Top part goes in a reg.
-      SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Val, 
+      SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, getPointerTy(), Val, 
                                  DAG.getConstant(1, MVT::i32));
-      SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Val,
+      SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, getPointerTy(), Val,
                                  DAG.getConstant(0, MVT::i32));
       RegValuesToPass.push_back(Hi);
       
@@ -577,19 +605,17 @@ SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
     if (ValToStore.Val) {
       if (!StackPtr.Val) {
         StackPtr = DAG.getRegister(SP::O6, MVT::i32);
-        NullSV = DAG.getSrcValue(NULL);
       }
       SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
       PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
-      Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                   ValToStore, PtrOff, NullSV));
+      Stores.push_back(DAG.getStore(Chain, ValToStore, PtrOff, NULL, 0));
     }
     ArgOffset += ObjSize;
   }
   
   // Emit all stores, make sure the occur before any copies into physregs.
   if (!Stores.empty())
-    Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores);
+    Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0],Stores.size());
   
   static const unsigned ArgRegs[] = {
     SP::O0, SP::O1, SP::O2, SP::O3, SP::O4, SP::O5
@@ -614,12 +640,8 @@ SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
   std::vector<MVT::ValueType> NodeTys;
   NodeTys.push_back(MVT::Other);   // Returns a chain
   NodeTys.push_back(MVT::Flag);    // Returns a flag for retval copy to use.
-  std::vector<SDOperand> Ops;
-  Ops.push_back(Chain);
-  Ops.push_back(Callee);
-  if (InFlag.Val)
-    Ops.push_back(InFlag);
-  Chain = DAG.getNode(SPISD::CALL, NodeTys, Ops);
+  SDOperand Ops[] = { Chain, Callee, InFlag };
+  Chain = DAG.getNode(SPISD::CALL, NodeTys, Ops, InFlag.Val ? 3 : 2);
   InFlag = Chain.getValue(1);
   
   MVT::ValueType RetTyVT = getValueType(RetTy);
@@ -629,15 +651,24 @@ SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
     default: assert(0 && "Unknown value type to return!");
     case MVT::i1:
     case MVT::i8:
-    case MVT::i16:
+    case MVT::i16: {
       RetVal = DAG.getCopyFromReg(Chain, SP::O0, MVT::i32, InFlag);
       Chain = RetVal.getValue(1);
       
       // Add a note to keep track of whether it is sign or zero extended.
-      RetVal = DAG.getNode(RetTy->isSigned() ? ISD::AssertSext :ISD::AssertZext,
-                           MVT::i32, RetVal, DAG.getValueType(RetTyVT));
+      ISD::NodeType AssertKind = ISD::DELETED_NODE;
+      if (RetSExt)
+        AssertKind = ISD::AssertSext;
+      else if (RetZExt)
+        AssertKind = ISD::AssertZext;
+
+      if (AssertKind != ISD::DELETED_NODE)
+        RetVal = DAG.getNode(AssertKind, MVT::i32, RetVal,
+                             DAG.getValueType(RetTyVT));
+
       RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal);
       break;
+    }
     case MVT::i32:
       RetVal = DAG.getCopyFromReg(Chain, SP::O0, MVT::i32, InFlag);
       Chain = RetVal.getValue(1);
@@ -660,9 +691,10 @@ SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
     }
   }
   
-  Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain,
-                      DAG.getConstant(ArgsSize, getPointerTy()));
-  
+  Chain = DAG.getCALLSEQ_END(Chain,
+                             DAG.getConstant(ArgsSize, getPointerTy()),
+                             DAG.getConstant(0, getPointerTy()),
+                             SDOperand());
   return std::make_pair(RetVal, Chain);
 }
 
@@ -692,6 +724,8 @@ SDOperand SparcTargetLowering::
 LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   switch (Op.getOpcode()) {
   default: assert(0 && "Should not custom lower this!");
+  case ISD::GlobalTLSAddress:
+    assert(0 && "TLS not implemented for Sparc.");
   case ISD::GlobalAddress: {
     GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
     SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32);
@@ -700,7 +734,7 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi);
   }
   case ISD::ConstantPool: {
-    Constant *C = cast<ConstantPoolSDNode>(Op)->get();
+    Constant *C = cast<ConstantPoolSDNode>(Op)->getConstVal();
     SDOperand CP = DAG.getTargetConstantPool(C, MVT::i32,
                                   cast<ConstantPoolSDNode>(Op)->getAlignment());
     SDOperand Hi = DAG.getNode(SPISD::Hi, MVT::i32, CP);
@@ -736,10 +770,8 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
       std::vector<MVT::ValueType> VTs;
       VTs.push_back(MVT::i32);
       VTs.push_back(MVT::Flag);
-      std::vector<SDOperand> Ops;
-      Ops.push_back(LHS);
-      Ops.push_back(RHS);
-      CompareFlag = DAG.getNode(SPISD::CMPICC, VTs, Ops).getValue(1);
+      SDOperand Ops[2] = { LHS, RHS };
+      CompareFlag = DAG.getNode(SPISD::CMPICC, VTs, Ops, 2).getValue(1);
       if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
       Opc = SPISD::BRICC;
     } else {
@@ -767,10 +799,8 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
       std::vector<MVT::ValueType> VTs;
       VTs.push_back(LHS.getValueType());   // subcc returns a value
       VTs.push_back(MVT::Flag);
-      std::vector<SDOperand> Ops;
-      Ops.push_back(LHS);
-      Ops.push_back(RHS);
-      CompareFlag = DAG.getNode(SPISD::CMPICC, VTs, Ops).getValue(1);
+      SDOperand Ops[2] = { LHS, RHS };
+      CompareFlag = DAG.getNode(SPISD::CMPICC, VTs, Ops, 2).getValue(1);
       Opc = SPISD::SELECT_ICC;
       if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC);
     } else {
@@ -787,38 +817,37 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     SDOperand Offset = DAG.getNode(ISD::ADD, MVT::i32,
                                    DAG.getRegister(SP::I6, MVT::i32),
                                 DAG.getConstant(VarArgsFrameOffset, MVT::i32));
-    return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), Offset, 
-                       Op.getOperand(1), Op.getOperand(2));
+    const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
+    return DAG.getStore(Op.getOperand(0), Offset, Op.getOperand(1), SV, 0);
   }
   case ISD::VAARG: {
     SDNode *Node = Op.Val;
     MVT::ValueType VT = Node->getValueType(0);
     SDOperand InChain = Node->getOperand(0);
     SDOperand VAListPtr = Node->getOperand(1);
-    SDOperand VAList = DAG.getLoad(getPointerTy(), InChain, VAListPtr,
-                                   Node->getOperand(2));
+    const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
+    SDOperand VAList = DAG.getLoad(getPointerTy(), InChain, VAListPtr, SV, 0);
     // Increment the pointer, VAList, to the next vaarg
     SDOperand NextPtr = DAG.getNode(ISD::ADD, getPointerTy(), VAList, 
                                     DAG.getConstant(MVT::getSizeInBits(VT)/8, 
                                                     getPointerTy()));
     // Store the incremented VAList to the legalized pointer
-    InChain = DAG.getNode(ISD::STORE, MVT::Other, VAList.getValue(1), NextPtr,
-                          VAListPtr, Node->getOperand(2));
+    InChain = DAG.getStore(VAList.getValue(1), NextPtr,
+                           VAListPtr, SV, 0);
     // Load the actual argument out of the pointer VAList, unless this is an
     // f64 load.
     if (VT != MVT::f64) {
-      return DAG.getLoad(VT, InChain, VAList, DAG.getSrcValue(0));
+      return DAG.getLoad(VT, InChain, VAList, NULL, 0);
     } else {
       // Otherwise, load it as i64, then do a bitconvert.
-      SDOperand V = DAG.getLoad(MVT::i64, InChain, VAList, DAG.getSrcValue(0));
+      SDOperand V = DAG.getLoad(MVT::i64, InChain, VAList, NULL, 0);
       std::vector<MVT::ValueType> Tys;
       Tys.push_back(MVT::f64);
       Tys.push_back(MVT::Other);
-      std::vector<SDOperand> Ops;
       // Bit-Convert the value to f64.
-      Ops.push_back(DAG.getNode(ISD::BIT_CONVERT, MVT::f64, V));
-      Ops.push_back(V.getValue(1));
-      return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops);
+      SDOperand Ops[2] = { DAG.getNode(ISD::BIT_CONVERT, MVT::f64, V),
+                           V.getValue(1) };
+      return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops, 2);
     }
   }
   case ISD::DYNAMIC_STACKALLOC: {
@@ -837,10 +866,8 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     std::vector<MVT::ValueType> Tys;
     Tys.push_back(MVT::i32);
     Tys.push_back(MVT::Other);
-    std::vector<SDOperand> Ops;
-    Ops.push_back(NewVal);
-    Ops.push_back(Chain);
-    return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops);
+    SDOperand Ops[2] = { NewVal, Chain };
+    return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops, 2);
   }
   case ISD::RET: {
     SDOperand Copy;
@@ -851,7 +878,7 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
       abort();
     case 1: 
       return SDOperand(); // ret void is legal
-    case 2: {
+    case 3: {
       unsigned ArgReg;
       switch(Op.getOperand(1).getValueType()) {
       default: assert(0 && "Unknown type to return!");
@@ -863,20 +890,25 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
                               SDOperand());
       break;
     }
-    case 3:
-      Copy = DAG.getCopyToReg(Op.getOperand(0), SP::I0, Op.getOperand(2), 
+    case 5:
+      Copy = DAG.getCopyToReg(Op.getOperand(0), SP::I0, Op.getOperand(3), 
                               SDOperand());
       Copy = DAG.getCopyToReg(Copy, SP::I1, Op.getOperand(1), Copy.getValue(1));
       break;
     }
     return DAG.getNode(SPISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
   }
+  // Frame & Return address.  Currently unimplemented
+  case ISD::RETURNADDR:         break;
+  case ISD::FRAMEADDR:          break;
   }
+  return SDOperand();
 }
 
 MachineBasicBlock *
-SparcTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
-                                             MachineBasicBlock *BB) {
+SparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
+                                                 MachineBasicBlock *BB) {
+  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
   unsigned BROpcode;
   unsigned CC;
   // Figure out the conditional branch opcode to use for this select_cc.
@@ -894,7 +926,7 @@ SparcTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
     break;
   }
 
-  CC = (SPCC::CondCodes)MI->getOperand(3).getImmedValue();
+  CC = (SPCC::CondCodes)MI->getOperand(3).getImm();
   
   // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
   // control-flow pattern.  The incoming instruction knows the destination vreg
@@ -912,7 +944,7 @@ SparcTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
   MachineBasicBlock *thisMBB = BB;
   MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
   MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
-  BuildMI(BB, BROpcode, 2).addMBB(sinkMBB).addImm(CC);
+  BuildMI(BB, TII.get(BROpcode)).addMBB(sinkMBB).addImm(CC);
   MachineFunction *F = BB->getParent();
   F->getBasicBlockList().insert(It, copy0MBB);
   F->getBasicBlockList().insert(It, sinkMBB);
@@ -940,7 +972,7 @@ SparcTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
   //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
   //  ...
   BB = sinkMBB;
-  BuildMI(BB, SP::PHI, 4, MI->getOperand(0).getReg())
+  BuildMI(BB, TII.get(SP::PHI), MI->getOperand(0).getReg())
     .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
     .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
   
@@ -969,11 +1001,12 @@ public:
       Subtarget(TM.getSubtarget<SparcSubtarget>()) {
   }
 
-  void Select(SDOperand &Result, SDOperand Op);
+  SDNode *Select(SDOperand Op);
 
   // Complex Pattern Selectors.
-  bool SelectADDRrr(SDOperand N, SDOperand &R1, SDOperand &R2);
-  bool SelectADDRri(SDOperand N, SDOperand &Base, SDOperand &Offset);
+  bool SelectADDRrr(SDOperand Op, SDOperand N, SDOperand &R1, SDOperand &R2);
+  bool SelectADDRri(SDOperand Op, SDOperand N, SDOperand &Base,
+                    SDOperand &Offset);
   
   /// InstructionSelectBasicBlock - This callback is invoked by
   /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
@@ -995,18 +1028,14 @@ void SparcDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
   
   // Select target instructions for the DAG.
   DAG.setRoot(SelectRoot(DAG.getRoot()));
-  assert(InFlightSet.empty() && "ISel InFlightSet has not been emptied!");
-  CodeGenMap.clear();
-  HandleMap.clear();
-  ReplaceMap.clear();
   DAG.RemoveDeadNodes();
   
   // Emit machine code to BB. 
   ScheduleAndEmitDAG(DAG);
 }
 
-bool SparcDAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
-                                     SDOperand &Offset) {
+bool SparcDAGToDAGISel::SelectADDRri(SDOperand Op, SDOperand Addr,
+                                     SDOperand &Base, SDOperand &Offset) {
   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
     Offset = CurDAG->getTargetConstant(0, MVT::i32);
@@ -1046,8 +1075,8 @@ bool SparcDAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
   return true;
 }
 
-bool SparcDAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1, 
-                                     SDOperand &R2) {
+bool SparcDAGToDAGISel::SelectADDRrr(SDOperand Op, SDOperand Addr,
+                                     SDOperand &R1,  SDOperand &R2) {
   if (Addr.getOpcode() == ISD::FrameIndex) return false;
   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
       Addr.getOpcode() == ISD::TargetGlobalAddress)
@@ -1070,29 +1099,21 @@ bool SparcDAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1,
   return true;
 }
 
-void SparcDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
+SDNode *SparcDAGToDAGISel::Select(SDOperand Op) {
   SDNode *N = Op.Val;
   if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
-      N->getOpcode() < SPISD::FIRST_NUMBER) {
-    Result = Op;
-    return;   // Already selected.
-  }
+      N->getOpcode() < SPISD::FIRST_NUMBER)
+    return NULL;   // Already selected.
 
-                 // If this has already been converted, use it.
-  std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
-  if (CGMI != CodeGenMap.end()) {
-    Result = CGMI->second;
-    return;
-  }
-  
   switch (N->getOpcode()) {
   default: break;
   case ISD::SDIV:
   case ISD::UDIV: {
     // FIXME: should use a custom expander to expose the SRA to the dag.
-    SDOperand DivLHS, DivRHS;
-    Select(DivLHS, N->getOperand(0));
-    Select(DivRHS, N->getOperand(1));
+    SDOperand DivLHS = N->getOperand(0);
+    SDOperand DivRHS = N->getOperand(1);
+    AddToISelQueue(DivLHS);
+    AddToISelQueue(DivRHS);
     
     // Set the Y register to the high-part.
     SDOperand TopPart;
@@ -1107,25 +1128,26 @@ void SparcDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
 
     // FIXME: Handle div by immediate.
     unsigned Opcode = N->getOpcode() == ISD::SDIV ? SP::SDIVrr : SP::UDIVrr;
-    Result = CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart);
-    return;
+    return CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS,
+                                TopPart);
   }    
   case ISD::MULHU:
   case ISD::MULHS: {
     // FIXME: Handle mul by immediate.
-    SDOperand MulLHS, MulRHS;
-    Select(MulLHS, N->getOperand(0));
-    Select(MulRHS, N->getOperand(1));
+    SDOperand MulLHS = N->getOperand(0);
+    SDOperand MulRHS = N->getOperand(1);
+    AddToISelQueue(MulLHS);
+    AddToISelQueue(MulRHS);
     unsigned Opcode = N->getOpcode() == ISD::MULHU ? SP::UMULrr : SP::SMULrr;
     SDNode *Mul = CurDAG->getTargetNode(Opcode, MVT::i32, MVT::Flag,
                                         MulLHS, MulRHS);
     // The high part is in the Y register.
-    Result = CurDAG->SelectNodeTo(N, SP::RDY, MVT::i32, SDOperand(Mul, 1));
-    return;
+    return CurDAG->SelectNodeTo(N, SP::RDY, MVT::i32, SDOperand(Mul, 1));
+    return NULL;
   }
   }
   
-  SelectCode(Result, Op);
+  return SelectCode(Op);
 }