[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Chris Lattner lattner at cs.uiuc.edu
Mon Jun 26 15:48:47 PDT 2006



Changes in directory llvm/lib/Target/PowerPC:

PPCISelLowering.cpp updated: 1.191 -> 1.192
---
Log message:

Improve PPC64 calling convention support


---
Diffs of the changes:  (+84 -37)

 PPCISelLowering.cpp |  121 ++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 84 insertions(+), 37 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.191 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.192
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.191	Tue Jun 20 19:34:03 2006
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp	Mon Jun 26 17:48:35 2006
@@ -733,8 +733,8 @@
                      Op.getOperand(1), Op.getOperand(2));
 }
 
-static SDOperand LowerFORMAL_ARGUMENTS_32(SDOperand Op, SelectionDAG &DAG,
-                                          int &VarArgsFrameIndex) {
+static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG,
+                                       int &VarArgsFrameIndex) {
   // TODO: add description of PPC stack frame format, or at least some docs.
   //
   MachineFunction &MF = DAG.getMachineFunction();
@@ -748,10 +748,15 @@
   const unsigned Num_FPR_Regs = 13;
   const unsigned Num_VR_Regs  = 12;
   unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
-  static const unsigned GPR[] = {
+  
+  static const unsigned GPR_32[] = {           // 32-bit registers.
     PPC::R3, PPC::R4, PPC::R5, PPC::R6,
     PPC::R7, PPC::R8, PPC::R9, PPC::R10,
   };
+  static const unsigned GPR_64[] = {           // 64-bit registers.
+    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
@@ -760,6 +765,10 @@
     PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
     PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
   };
+
+  MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
+  bool isPPC64 = PtrVT == MVT::i64;
+  const unsigned *GPR = isPPC64 ? GPR_64 : GPR_32;
   
   // Add DAG nodes to load the arguments or copy them out of registers.  On
   // entry to a function on PPC, the arguments start at offset 24, although the
@@ -771,12 +780,11 @@
     unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8;
 
     unsigned CurArgOffset = ArgOffset;
-    
     switch (ObjectVT) {
     default: assert(0 && "Unhandled argument type!");
     case MVT::i32:
       // All int arguments reserve stack space.
-      ArgOffset += 4;
+      ArgOffset += isPPC64 ? 8 : 4;
 
       if (GPR_idx != Num_GPR_Regs) {
         unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
@@ -787,6 +795,19 @@
         needsLoad = true;
       }
       break;
+    case MVT::i64:  // PPC64
+      // All int arguments reserve stack space.
+      ArgOffset += 8;
+      
+      if (GPR_idx != Num_GPR_Regs) {
+        unsigned VReg = RegMap->createVirtualRegister(&PPC::G8RCRegClass);
+        MF.addLiveIn(GPR[GPR_idx], VReg);
+        ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i64);
+        ++GPR_idx;
+      } else {
+        needsLoad = true;
+      }
+      break;
     case MVT::f32:
     case MVT::f64:
       // All FP arguments reserve stack space.
@@ -838,7 +859,7 @@
       // slot.
       if (!Op.Val->hasNUsesOfValue(0, ArgNo)) {
         int FI = MFI->CreateFixedObject(ObjSize, CurArgOffset);
-        SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
+        SDOperand FIN = DAG.getFrameIndex(FI, PtrVT);
         ArgVal = DAG.getLoad(ObjectVT, Root, FIN,
                              DAG.getSrcValue(NULL));
       } else {
@@ -854,8 +875,9 @@
   // the start of the first vararg value... for expansion of llvm.va_start.
   bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
   if (isVarArg) {
-    VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset);
-    SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32);
+    VarArgsFrameIndex = MFI->CreateFixedObject(MVT::getSizeInBits(PtrVT)/8,
+                                               ArgOffset);
+    SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT);
     // If this function is vararg, store any remaining integer argument regs
     // to their spots on the stack so that they may be loaded by deferencing the
     // result of va_next.
@@ -863,13 +885,13 @@
     for (; GPR_idx != Num_GPR_Regs; ++GPR_idx) {
       unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass);
       MF.addLiveIn(GPR[GPR_idx], VReg);
-      SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::i32);
+      SDOperand Val = DAG.getCopyFromReg(Root, VReg, PtrVT);
       SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
                                     Val, FIN, DAG.getSrcValue(NULL));
       MemOps.push_back(Store);
       // Increment the address by four for the next argument to store
-      SDOperand PtrOff = DAG.getConstant(4, MVT::i32);
-      FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, PtrOff);
+      SDOperand PtrOff = DAG.getConstant(MVT::getSizeInBits(PtrVT)/8, PtrVT);
+      FIN = DAG.getNode(ISD::ADD, PtrOff.getValueType(), FIN, PtrOff);
     }
     if (!MemOps.empty())
       Root = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps);
@@ -883,11 +905,6 @@
   return DAG.getNode(ISD::MERGE_VALUES, RetVT, ArgValues);
 }
 
-static SDOperand LowerFORMAL_ARGUMENTS_64(SDOperand Op, SelectionDAG &DAG,
-                                          int &VarArgsFrameIndex) {
-  return LowerFORMAL_ARGUMENTS_32(Op, DAG, VarArgsFrameIndex);
-}
-
 /// isCallCompatibleAddress - Return the immediate to use if the specified
 /// 32-bit value is representable in the immediate field of a BxA instruction.
 static SDNode *isBLACompatibleAddress(SDOperand Op, SelectionDAG &DAG) {
@@ -911,14 +928,19 @@
   SDOperand Callee    = Op.getOperand(4);
   unsigned NumOps     = (Op.getNumOperands() - 5) / 2;
 
+  MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
+  bool isPPC64 = PtrVT == MVT::i64;
+  unsigned PtrByteSize = isPPC64 ? 8 : 4;
+
+  
   // args_to_use will accumulate outgoing args for the PPCISD::CALL case in
   // SelectExpr to use to put the arguments in the appropriate registers.
   std::vector<SDOperand> args_to_use;
   
   // Count how many bytes are to be pushed on the stack, including the linkage
-  // area, and parameter passing area.  We start with 24 bytes, which is
+  // area, and parameter passing area.  We start with 24/48 bytes, which is
   // prereserved space for [SP][CR][LR][3 x unused].
-  unsigned NumBytes = 24;
+  unsigned NumBytes = 6*PtrByteSize;
   
   // Add up all the space actually used.
   for (unsigned i = 0; i != NumOps; ++i)
@@ -929,29 +951,37 @@
   // Because we cannot tell if this is needed on the caller side, we have to
   // conservatively assume that it is needed.  As such, make sure we have at
   // least enough stack space for the caller to store the 8 GPRs.
-  if (NumBytes < 24+8*4)
-    NumBytes = 24+8*4;
+  if (NumBytes < 6*PtrByteSize+8*PtrByteSize)
+    NumBytes = 6*PtrByteSize+8*PtrByteSize;
   
   // Adjust the stack pointer for the new arguments...
   // These operations are automatically eliminated by the prolog/epilog pass
   Chain = DAG.getCALLSEQ_START(Chain,
-                               DAG.getConstant(NumBytes, MVT::i32));
+                               DAG.getConstant(NumBytes, PtrVT));
   
   // Set up a copy of the stack pointer for use loading and storing any
   // arguments that may not fit in the registers available for argument
   // passing.
-  SDOperand StackPtr = DAG.getRegister(PPC::R1, MVT::i32);
+  SDOperand StackPtr;
+  if (isPPC64)
+    StackPtr = DAG.getRegister(PPC::X1, MVT::i64);
+  else
+    StackPtr = DAG.getRegister(PPC::R1, MVT::i32);
   
   // Figure out which arguments are going to go in registers, and which in
   // 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 = 24;
+  unsigned ArgOffset = 6*PtrByteSize;
   unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
-  static const unsigned GPR[] = {
+  static const unsigned GPR_32[] = {           // 32-bit registers.
     PPC::R3, PPC::R4, PPC::R5, PPC::R6,
     PPC::R7, PPC::R8, PPC::R9, PPC::R10,
   };
+  static const unsigned GPR_64[] = {           // 64-bit registers.
+    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
@@ -960,10 +990,12 @@
     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)/sizeof(GPR[0]);
+  const unsigned NumGPRs = sizeof(GPR_32)/sizeof(GPR_32[0]);
   const unsigned NumFPRs = sizeof(FPR)/sizeof(FPR[0]);
   const unsigned NumVRs  = sizeof( VR)/sizeof( VR[0]);
   
+  const unsigned *GPR = isPPC64 ? GPR_64 : GPR_32;
+
   std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
   std::vector<SDOperand> MemOpChains;
   for (unsigned i = 0; i != NumOps; ++i) {
@@ -972,17 +1004,27 @@
     // 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());
-    PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
+    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;
+      Arg = DAG.getNode(ExtOp, MVT::i64, Arg);
+    }
+    
     switch (Arg.getValueType()) {
     default: assert(0 && "Unexpected ValueType for argument!");
     case MVT::i32:
+    case MVT::i64:
       if (GPR_idx != NumGPRs) {
         RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Arg));
       } else {
         MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
                                           Arg, PtrOff, DAG.getSrcValue(NULL)));
       }
-      ArgOffset += 4;
+      ArgOffset += PtrByteSize;
       break;
     case MVT::f32:
     case MVT::f64:
@@ -997,15 +1039,15 @@
 
           // Float varargs are always shadowed in available integer registers
           if (GPR_idx != NumGPRs) {
-            SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff,
+            SDOperand Load = DAG.getLoad(PtrVT, Store, PtrOff,
                                          DAG.getSrcValue(NULL));
             MemOpChains.push_back(Load.getValue(1));
             RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
           }
           if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64) {
             SDOperand ConstFour = DAG.getConstant(4, PtrOff.getValueType());
-            PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour);
-            SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff,
+            PtrOff = DAG.getNode(ISD::ADD, PtrVT, PtrOff, ConstFour);
+            SDOperand Load = DAG.getLoad(PtrVT, Store, PtrOff,
                                          DAG.getSrcValue(NULL));
             MemOpChains.push_back(Load.getValue(1));
             RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load));
@@ -1016,14 +1058,17 @@
           // GPRs.
           if (GPR_idx != NumGPRs)
             ++GPR_idx;
-          if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64)
+          if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64 && !isPPC64)
             ++GPR_idx;
         }
       } else {
         MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
                                           Arg, PtrOff, DAG.getSrcValue(NULL)));
       }
-      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:
@@ -1127,6 +1172,11 @@
     }
     NodeTys.push_back(MVT::i32);
     break;
+  case MVT::i64:
+    Chain = DAG.getCopyFromReg(Chain, PPC::X3, MVT::i64, InFlag).getValue(1);
+    ResultVals.push_back(Chain.getValue(0));
+    NodeTys.push_back(MVT::i64);
+    break;
   case MVT::f32:
   case MVT::f64:
     Chain = DAG.getCopyFromReg(Chain, PPC::F1, Op.Val->getValueType(0),
@@ -1146,7 +1196,7 @@
   }
   
   Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain,
-                      DAG.getConstant(NumBytes, MVT::i32));
+                      DAG.getConstant(NumBytes, PtrVT));
   NodeTys.push_back(MVT::Other);
   
   // If the function returns void, just return the chain.
@@ -2136,10 +2186,7 @@
   case ISD::SETCC:              return LowerSETCC(Op, DAG);
   case ISD::VASTART:            return LowerVASTART(Op, DAG, VarArgsFrameIndex);
   case ISD::FORMAL_ARGUMENTS:
-    if (getPointerTy() == MVT::i32)
-      return LowerFORMAL_ARGUMENTS_32(Op, DAG, VarArgsFrameIndex);
-    else
-      return LowerFORMAL_ARGUMENTS_64(Op, DAG, VarArgsFrameIndex);
+      return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex);
   case ISD::CALL:               return LowerCALL(Op, DAG);
   case ISD::RET:                return LowerRET(Op, DAG);
     






More information about the llvm-commits mailing list