Default ISD::PREFETCH to expand.
[oota-llvm.git] / lib / Target / Sparc / SparcISelDAGToDAG.cpp
index 7275ce652a2253e1c13f7879c26197a2989f2e18..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 <queue>
 #include <set>
@@ -109,19 +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 RetTyIsSigned, 
-                  bool isVarArg, unsigned CC, bool isTailCall, SDOperand Callee,
+      LowerCallTo(SDOperand Chain, const Type *RetTy,
+                  bool RetSExt, bool RetZExt, bool isVarArg,
+                  unsigned CC, bool isTailCall, SDOperand Callee,
                   ArgListTy &Args, SelectionDAG &DAG);
-    virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
-                                                       MachineBasicBlock *MBB);
+    virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
+                                                        MachineBasicBlock *MBB);
     
     virtual const char *getTargetNodeName(unsigned Opcode) const;
   };
@@ -137,9 +140,14 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
 
   // 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
@@ -147,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);
@@ -186,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);
@@ -199,11 +212,16 @@ 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);
@@ -211,7 +229,7 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
 
   // 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.
@@ -224,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();
 }
@@ -258,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?"); 
     
@@ -287,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[] = {
@@ -313,8 +335,8 @@ 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 = ISD::AssertSext;
@@ -351,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);
@@ -385,8 +407,8 @@ SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
       } 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);
@@ -396,8 +418,8 @@ SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
         
         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);
@@ -426,8 +448,8 @@ 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);
@@ -450,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;
   }
   
@@ -469,8 +491,8 @@ SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
 
 std::pair<SDOperand, SDOperand>
 SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
-                                 bool RetTyIsSigned, 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;
@@ -634,11 +656,16 @@ SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
       Chain = RetVal.getValue(1);
       
       // Add a note to keep track of whether it is sign or zero extended.
-      ISD::NodeType AssertKind = ISD::AssertZext;
-      if (RetTyIsSigned)
+      ISD::NodeType AssertKind = ISD::DELETED_NODE;
+      if (RetSExt)
         AssertKind = ISD::AssertSext;
-      RetVal = DAG.getNode(AssertKind, MVT::i32, RetVal, 
-                           DAG.getValueType(RetTyVT));
+      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;
     }
@@ -664,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);
 }
 
@@ -696,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);
@@ -787,25 +817,23 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     SDOperand Offset = DAG.getNode(ISD::ADD, MVT::i32,
                                    DAG.getRegister(SP::I6, MVT::i32),
                                 DAG.getConstant(VarArgsFrameOffset, MVT::i32));
-    SrcValueSDNode *SV = cast<SrcValueSDNode>(Op.getOperand(2));
-    return DAG.getStore(Op.getOperand(0), Offset, 
-                        Op.getOperand(1), SV->getValue(), SV->getOffset());
+    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);
-    SrcValueSDNode *SV = cast<SrcValueSDNode>(Node->getOperand(2));
-    SDOperand VAList = DAG.getLoad(getPointerTy(), InChain, VAListPtr,
-                                   SV->getValue(), SV->getOffset());
+    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.getStore(VAList.getValue(1), NextPtr,
-                           VAListPtr, SV->getValue(), SV->getOffset());
+                           VAListPtr, SV, 0);
     // Load the actual argument out of the pointer VAList, unless this is an
     // f64 load.
     if (VT != MVT::f64) {
@@ -878,8 +906,8 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
 }
 
 MachineBasicBlock *
-SparcTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
-                                             MachineBasicBlock *BB) {
+SparcTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
+                                                 MachineBasicBlock *BB) {
   const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
   unsigned BROpcode;
   unsigned CC;
@@ -898,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