Output sinl for a long double FSIN node, not sin.
[oota-llvm.git] / lib / Target / PowerPC / PPCISelLowering.cpp
index e3610f89941de768b0504a5188903ac45b9264a2..d7ffc303f46f3e16537e90f011cf5b7abd5840d8 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.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -23,8 +23,8 @@
 #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/SSARegMap.h"
 #include "llvm/Constants.h"
 #include "llvm/Function.h"
 #include "llvm/Intrinsics.h"
@@ -167,14 +167,12 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
   // Support label based line numbers.
   setOperationAction(ISD::LOCATION, MVT::Other, Expand);
   setOperationAction(ISD::DEBUG_LOC, 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);
-  }
+  
+  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.
@@ -343,9 +341,11 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
   
   // Darwin long double math library functions have $LDBL128 appended.
   if (TM.getSubtarget<PPCSubtarget>().isDarwin()) {
-    setLibcallName(RTLIB::SQRT_PPCF128, "sqrtl$LDBL128");
+    setLibcallName(RTLIB::COS_PPCF128, "cosl$LDBL128");
     setLibcallName(RTLIB::POW_PPCF128, "powl$LDBL128");
     setLibcallName(RTLIB::REM_PPCF128, "fmodl$LDBL128");
+    setLibcallName(RTLIB::SIN_PPCF128, "sinl$LDBL128");
+    setLibcallName(RTLIB::SQRT_PPCF128, "sqrtl$LDBL128");
   }
 
   computeRegisterProperties();
@@ -1267,7 +1267,7 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
   //
   MachineFunction &MF = DAG.getMachineFunction();
   MachineFrameInfo *MFI = MF.getFrameInfo();
-  SSARegMap *RegMap = MF.getSSARegMap();
+  MachineRegisterInfo &RegInfo = MF.getRegInfo();
   SmallVector<SDOperand, 8> ArgValues;
   SDOperand Root = Op.getOperand(0);
   
@@ -1331,8 +1331,8 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
       // Double word align in ELF
       if (Expand && isELF32_ABI) GPR_idx += (GPR_idx % 2);
       if (GPR_idx != Num_GPR_Regs) {
-        unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
-        MF.addLiveIn(GPR[GPR_idx], VReg);
+        unsigned VReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
+        RegInfo.addLiveIn(GPR[GPR_idx], VReg);
         ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32);
         ++GPR_idx;
       } else {
@@ -1348,8 +1348,8 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
       
     case MVT::i64:  // PPC64
       if (GPR_idx != Num_GPR_Regs) {
-        unsigned VReg = RegMap->createVirtualRegister(&PPC::G8RCRegClass);
-        MF.addLiveIn(GPR[GPR_idx], VReg);
+        unsigned VReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
+        RegInfo.addLiveIn(GPR[GPR_idx], VReg);
         ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i64);
         ++GPR_idx;
       } else {
@@ -1371,10 +1371,10 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
       if (FPR_idx != Num_FPR_Regs) {
         unsigned VReg;
         if (ObjectVT == MVT::f32)
-          VReg = RegMap->createVirtualRegister(&PPC::F4RCRegClass);
+          VReg = RegInfo.createVirtualRegister(&PPC::F4RCRegClass);
         else
-          VReg = RegMap->createVirtualRegister(&PPC::F8RCRegClass);
-        MF.addLiveIn(FPR[FPR_idx], VReg);
+          VReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
+        RegInfo.addLiveIn(FPR[FPR_idx], VReg);
         ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
         ++FPR_idx;
       } else {
@@ -1393,8 +1393,8 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
     case MVT::v16i8:
       // Note that vector arguments in registers don't reserve stack space.
       if (VR_idx != Num_VR_Regs) {
-        unsigned VReg = RegMap->createVirtualRegister(&PPC::VRRCRegClass);
-        MF.addLiveIn(VR[VR_idx], VReg);
+        unsigned VReg = RegInfo.createVirtualRegister(&PPC::VRRCRegClass);
+        RegInfo.addLiveIn(VR[VR_idx], VReg);
         ArgVal = DAG.getCopyFromReg(Root, VReg, ObjectVT);
         ++VR_idx;
       } else {
@@ -1473,11 +1473,11 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
     for (; GPR_idx != Num_GPR_Regs; ++GPR_idx) {
       unsigned VReg;
       if (isPPC64)
-        VReg = RegMap->createVirtualRegister(&PPC::G8RCRegClass);
+        VReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
       else
-        VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
+        VReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
 
-      MF.addLiveIn(GPR[GPR_idx], VReg);
+      RegInfo.addLiveIn(GPR[GPR_idx], VReg);
       SDOperand Val = DAG.getCopyFromReg(Root, VReg, PtrVT);
       SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
       MemOps.push_back(Store);
@@ -1501,9 +1501,9 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
 
       for (; FPR_idx != Num_FPR_Regs; ++FPR_idx) {
         unsigned VReg;
-        VReg = RegMap->createVirtualRegister(&PPC::F8RCRegClass);
+        VReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
 
-        MF.addLiveIn(FPR[FPR_idx], VReg);
+        RegInfo.addLiveIn(FPR[FPR_idx], VReg);
         SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::f64);
         SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
         MemOps.push_back(Store);
@@ -1816,6 +1816,13 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG,
   Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size());
   InFlag = Chain.getValue(1);
 
+  Chain = DAG.getCALLSEQ_END(Chain,
+                             DAG.getConstant(NumBytes, PtrVT),
+                             DAG.getConstant(0, PtrVT),
+                             InFlag);
+  if (Op.Val->getValueType(0) != MVT::Other)
+    InFlag = Chain.getValue(1);
+
   SDOperand ResultVals[3];
   unsigned NumResults = 0;
   NodeTys.clear();
@@ -1878,8 +1885,6 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG,
     break;
   }
   
-  Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain,
-                      DAG.getConstant(NumBytes, PtrVT));
   NodeTys.push_back(MVT::Other);
   
   // If the function returns void, just return the chain.
@@ -1902,9 +1907,9 @@ static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG, TargetMachine &TM) {
   
   // 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()) {
+  if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
     for (unsigned i = 0; i != RVLocs.size(); ++i)
-      DAG.getMachineFunction().addLiveOut(RVLocs[i].getLocReg());
+      DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
   }
 
   SDOperand Chain = Op.getOperand(0);
@@ -2071,6 +2076,7 @@ static SDOperand LowerSELECT_CC(SDOperand Op, SelectionDAG &DAG) {
   return SDOperand();
 }
 
+// FIXME: Split this code up when LegalizeDAGTypes lands.
 static SDOperand LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG) {
   assert(MVT::isFloatingPoint(Op.getOperand(0).getValueType()));
   SDOperand Src = Op.getOperand(0);
@@ -3030,13 +3036,21 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &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;
+  // Frame & Return address.
+  case ISD::RETURNADDR:         return LowerRETURNADDR(Op, DAG);
   case ISD::FRAMEADDR:          return LowerFRAMEADDR(Op, DAG);
   }
   return SDOperand();
 }
 
+SDNode *PPCTargetLowering::ExpandOperationResult(SDNode *N, SelectionDAG &DAG) {
+  switch (N->getOpcode()) {
+  default: assert(0 && "Wasn't expecting to be able to lower this!");
+  case ISD::FP_TO_SINT: return LowerFP_TO_SINT(SDOperand(N, 0), DAG).Val;
+  }
+}
+
+
 //===----------------------------------------------------------------------===//
 //  Other Lowering Code
 //===----------------------------------------------------------------------===//
@@ -3143,7 +3157,8 @@ SDOperand PPCTargetLowering::PerformDAGCombine(SDNode *N,
         // Turn (sint_to_fp (fp_to_sint X)) -> fctidz/fcfid without load/stores.
         // We allow the src/dst to be either f32/f64, but the intermediate
         // type must be i64.
-        if (N->getOperand(0).getValueType() == MVT::i64) {
+        if (N->getOperand(0).getValueType() == MVT::i64 &&
+            N->getOperand(0).getOperand(0).getValueType() != MVT::ppcf128) {
           SDOperand Val = N->getOperand(0).getOperand(0);
           if (Val.getValueType() == MVT::f32) {
             Val = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Val);
@@ -3170,7 +3185,8 @@ SDOperand PPCTargetLowering::PerformDAGCombine(SDNode *N,
     // Turn STORE (FP_TO_SINT F) -> STFIWX(FCTIWZ(F)).
     if (TM.getSubtarget<PPCSubtarget>().hasSTFIWX() &&
         N->getOperand(1).getOpcode() == ISD::FP_TO_SINT &&
-        N->getOperand(1).getValueType() == MVT::i32) {
+        N->getOperand(1).getValueType() == MVT::i32 &&
+        N->getOperand(1).getOperand(0).getValueType() != MVT::ppcf128) {
       SDOperand Val = N->getOperand(1).getOperand(0);
       if (Val.getValueType() == MVT::f32) {
         Val = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Val);
@@ -3560,8 +3576,36 @@ bool PPCTargetLowering::isLegalAddressImmediate(llvm::GlobalValue* GV) const {
   return false; 
 }
 
-SDOperand PPCTargetLowering::LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG)
-{
+SDOperand PPCTargetLowering::LowerRETURNADDR(SDOperand Op, SelectionDAG &DAG) {
+  // Depths > 0 not supported yet! 
+  if (cast<ConstantSDNode>(Op.getOperand(0))->getValue() > 0)
+    return SDOperand();
+
+  MachineFunction &MF = DAG.getMachineFunction();
+  PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
+  int RAIdx = FuncInfo->getReturnAddrSaveIndex();
+  if (RAIdx == 0) {
+    bool isPPC64 = PPCSubTarget.isPPC64();
+    int Offset = 
+      PPCFrameInfo::getReturnSaveOffset(isPPC64, PPCSubTarget.isMachoABI());
+
+    // Set up a frame object for the return address.
+    RAIdx = MF.getFrameInfo()->CreateFixedObject(isPPC64 ? 8 : 4, Offset);
+    
+    // Remember it for next time.
+    FuncInfo->setReturnAddrSaveIndex(RAIdx);
+    
+    // Make sure the function really does not optimize away the store of the RA
+    // to the stack.
+    FuncInfo->setLRStoreRequired();
+  }
+  
+  // Just load the return address off the stack.
+  SDOperand RetAddrFI =  DAG.getFrameIndex(RAIdx, getPointerTy());
+  return DAG.getLoad(getPointerTy(), DAG.getEntryNode(), RetAddrFI, NULL, 0);
+}
+
+SDOperand PPCTargetLowering::LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG) {
   // Depths > 0 not supported yet! 
   if (cast<ConstantSDNode>(Op.getOperand(0))->getValue() > 0)
     return SDOperand();