Get closer to having varargs working. There's still something strange
authorNate Begeman <natebegeman@mac.com>
Sat, 26 Mar 2005 07:46:36 +0000 (07:46 +0000)
committerNate Begeman <natebegeman@mac.com>
Sat, 26 Mar 2005 07:46:36 +0000 (07:46 +0000)
going on with copies between floating point and integer register files
being generated.  Once that is solved, varargs will be done.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@20856 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCISelPattern.cpp

index 16955717f35c962f53e06c0a159caccea9f77fab..7ec033afb8660b25f277bbaf8420763e27295036 100644 (file)
@@ -132,7 +132,8 @@ PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
         needsLoad = true;
       }
       break;
-      case MVT::i64: ObjSize = 8; 
+      case MVT::i64: ObjSize = 8;
+      // FIXME: can split 64b load between reg/mem if it is last arg in regs
       if (GPR_remaining > 1) {
         BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx]);
         BuildMI(&BB, PPC::IMPLICIT_DEF, 0, GPR[GPR_idx+1]);
@@ -263,8 +264,9 @@ PPC32TargetLowering::LowerCallTo(SDOperand Chain,
       // register cannot be found for it.
       SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
       PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
+      MVT::ValueType ArgVT = getValueType(Args[i].second);
       
-      switch (getValueType(Args[i].second)) {
+      switch (ArgVT) {
       default: assert(0 && "Unexpected ValueType for argument!");
       case MVT::i1:
       case MVT::i8:
@@ -287,27 +289,25 @@ PPC32TargetLowering::LowerCallTo(SDOperand Chain,
         ArgOffset += 4;
         break;
       case MVT::i64:
-        // If we have 2 or more GPRs, we won't do anything and let the ISD::CALL
-        // functionality in SelectExpr move pieces for us.
-        if (GPR_remaining > 1) {
-          SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, 
-            Args[i].first, DAG.getConstant(1, MVT::i32));
-          SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, 
-            Args[i].first, DAG.getConstant(0, MVT::i32));
-          args_to_use.push_back(Hi);          
-          args_to_use.push_back(Lo);          
-          GPR_remaining -= 2;
-        } else if (GPR_remaining > 0) {
+        // If we have one free GPR left, we can place the upper half of the i64
+        // in it, and store the other half to the stack.  If we have two or more
+        // free GPRs, then we can pass both halves of the i64 in registers.
+        if (GPR_remaining > 0) {
           SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, 
             Args[i].first, DAG.getConstant(1, MVT::i32));
           SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, 
             Args[i].first, DAG.getConstant(0, MVT::i32));
-          args_to_use.push_back(Hi);          
-          SDOperand ConstFour = DAG.getConstant(4, getPointerTy());
-          PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour);
-          Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                       Lo, PtrOff));
-          --GPR_remaining;
+          args_to_use.push_back(Hi);
+          if (GPR_remaining > 1) {
+            args_to_use.push_back(Lo);
+            GPR_remaining -= 2;
+          } else {
+            SDOperand ConstFour = DAG.getConstant(4, getPointerTy());
+            PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour);
+            Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
+                                         Lo, PtrOff));
+            --GPR_remaining;
+          }
         } else {
           Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
                                        Args[i].first, PtrOff));
@@ -315,32 +315,33 @@ PPC32TargetLowering::LowerCallTo(SDOperand Chain,
         ArgOffset += 8;
         break;
       case MVT::f32:
-        if (FPR_remaining > 0 && GPR_remaining > 0 && isVarArg) {
-          --FPR_remaining;
-          ArgOffset += 4;
-        } else if (FPR_remaining > 0) {
-          args_to_use.push_back(Args[i].first);
-          --FPR_remaining;
-          if (GPR_remaining > 0) --GPR_remaining;
-        } else {
-          Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                       Args[i].first, PtrOff));
-        }
-        ArgOffset += 4;
-        break;
       case MVT::f64:
-        if (FPR_remaining > 0 && GPR_remaining > 0 && isVarArg) {
-          --FPR_remaining;
-        } else if (FPR_remaining > 0) {
+        if (FPR_remaining > 0) {
+          if (isVarArg) {
+            // FIXME: Need FunctionType information so we can conditionally
+            // store only the non-fixed arguments in a vararg function.
+            Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
+                                         Args[i].first, PtrOff));
+            if (GPR_remaining > 0)
+              args_to_use.push_back(DAG.getLoad(MVT::i32, Chain, PtrOff));
+            if (GPR_remaining > 1) {
+              SDOperand ConstFour = DAG.getConstant(4, getPointerTy());
+              PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour);
+              args_to_use.push_back(DAG.getLoad(MVT::i32, Chain, PtrOff));
+            }
+          }
           args_to_use.push_back(Args[i].first);
           --FPR_remaining;
+          // 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_remaining > 0) --GPR_remaining;
-          if (GPR_remaining > 0) --GPR_remaining;
+          if (GPR_remaining > 0 && MVT::f64 == ArgVT) --GPR_remaining;
         } else {
           Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
                                        Args[i].first, PtrOff));
         }
-        ArgOffset += 8;
+        ArgOffset += (ArgVT == MVT::f32) ? 4 : 8;
         break;
       }
     }