Check in some #ifdef'd out code switching call argument
authorChris Lattner <sabre@nondot.org>
Mon, 17 Mar 2008 06:58:37 +0000 (06:58 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 17 Mar 2008 06:58:37 +0000 (06:58 +0000)
lowering over to SparcCallingConv.td.  We can't make the switch
yet because we can't say to pass f64 registers in 2 x i32 registers
with the td file yet.

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

lib/Target/Sparc/SparcCallingConv.td
lib/Target/Sparc/SparcISelLowering.cpp

index 02d24397e6da1cbaeec4052f25a66c56caf0e120..dc0bf8e31226b9ee0529df07943a9a525ca9a54f 100644 (file)
@@ -21,3 +21,12 @@ def RetCC_Sparc32 : CallingConv<[
   CCIfType<[f32], CCAssignToReg<[F0]>>,
   CCIfType<[f64], CCAssignToReg<[D0]>>
 ]>;
+
+// Sparc 32-bit C Calling convention.
+def CC_Sparc32 : CallingConv<[
+  // All arguments get passed in integer registers if there is space.
+  CCIfType<[i32, f32, f64], CCAssignToReg<[I0, I1, I2, I3, I4, I5]>>,
+  
+  // Alternatively, they are assigned to the stack in 4-byte aligned units.
+  CCAssignToStack<4, 4>
+]>;
index 88d5b7be17e2d6cceaf4e20f687c57f919bf9608..1d4fe0bc8cba877f198eeaf00d8bb99b17f936b8 100644 (file)
@@ -231,38 +231,96 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   SDOperand Callee = Op.getOperand(4);
   bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
 
+#if 0
+  // Analyze operands of the call, assigning locations to each operand.
+  SmallVector<CCValAssign, 16> ArgLocs;
+  CCState CCInfo(CallingConv, isVarArg, DAG.getTarget(), ArgLocs);
+  CCInfo.AnalyzeCallOperands(Op.Val, CC_Sparc32);
+  
+  // Get the size of the outgoing arguments stack space requirement.
+  unsigned ArgsSize = CCInfo.getNextStackOffset();
+  // FIXME: We can't use this until f64 is known to take two GPRs.
+#else
+  (void)CC_Sparc32;
+  
   // Count the size of the outgoing arguments.
   unsigned ArgsSize = 0;
   for (unsigned i = 5, e = Op.getNumOperands(); i != e; i += 2) {
     switch (Op.getOperand(i).getValueType()) {
-    default: assert(0 && "Unknown value type!");
-    case MVT::i1:
-    case MVT::i8:
-    case MVT::i16:
-    case MVT::i32:
-    case MVT::f32:
-      ArgsSize += 4;
-      break;
-    case MVT::i64:
-    case MVT::f64:
-      ArgsSize += 8;
-      break;
+      default: assert(0 && "Unknown value type!");
+      case MVT::i1:
+      case MVT::i8:
+      case MVT::i16:
+      case MVT::i32:
+      case MVT::f32:
+        ArgsSize += 4;
+        break;
+      case MVT::i64:
+      case MVT::f64:
+        ArgsSize += 8;
+        break;
     }
   }
   if (ArgsSize > 4*6)
     ArgsSize -= 4*6;    // Space for first 6 arguments is prereserved.
   else
     ArgsSize = 0;
-
+#endif  
+  
   // Keep stack frames 8-byte aligned.
   ArgsSize = (ArgsSize+7) & ~7;
 
-  Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(ArgsSize, MVT::i32));
+  Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(ArgsSize));
+  
+  SmallVector<std::pair<unsigned, SDOperand>, 8> RegsToPass;
+  SmallVector<SDOperand, 8> MemOpChains;
   
-  SDOperand StackPtr;
-  std::vector<SDOperand> Stores;
-  std::vector<SDOperand> RegValuesToPass;
+#if 0
+  // Walk the register/memloc assignments, inserting copies/loads.
+  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+    CCValAssign &VA = ArgLocs[i];
+    
+    // Arguments start after the 5 first operands of ISD::CALL
+    SDOperand Arg = Op.getOperand(5+2*VA.getValNo());
+
+    // Promote the value if needed.
+    switch (VA.getLocInfo()) {
+    default: assert(0 && "Unknown loc info!");
+    case CCValAssign::Full: break;
+    case CCValAssign::SExt:
+      Arg = DAG.getNode(ISD::SIGN_EXTEND, VA.getLocVT(), Arg);
+      break;
+    case CCValAssign::ZExt:
+      Arg = DAG.getNode(ISD::ZERO_EXTEND, VA.getLocVT(), Arg);
+      break;
+    case CCValAssign::AExt:
+      Arg = DAG.getNode(ISD::ANY_EXTEND, VA.getLocVT(), Arg);
+      break;
+    }
+    
+    // Arguments that can be passed on register must be kept at 
+    // RegsToPass vector
+    if (VA.isRegLoc()) {
+      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
+      continue;
+    }
+    
+    assert(VA.isMemLoc());
+    
+    // Create a store off the stack pointer for this argument.
+    SDOperand StackPtr = DAG.getRegister(SP::O6, MVT::i32);
+    // FIXME: VERIFY THAT 68 IS RIGHT.
+    SDOperand PtrOff = DAG.getIntPtrConstant(VA.getLocMemOffset()+68);
+    PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
+    MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
+  }
+  
+#else  
+  static const unsigned ArgRegs[] = {
+    SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5
+  };
   unsigned ArgOffset = 68;
+
   for (unsigned i = 5, e = Op.getNumOperands(); i != e; i += 2) {
     SDOperand Val = Op.getOperand(i);
     MVT::ValueType ObjectVT = Val.getValueType();
@@ -273,20 +331,20 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
     case MVT::i32:
       ObjSize = 4;
 
-      if (RegValuesToPass.size() >= 6) {
+      if (RegsToPass.size() >= 6) {
         ValToStore = Val;
       } else {
-        RegValuesToPass.push_back(Val);
+        RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Val));
       }
       break;
     case MVT::f32:
       ObjSize = 4;
-      if (RegValuesToPass.size() >= 6) {
+      if (RegsToPass.size() >= 6) {
         ValToStore = Val;
       } else {
         // Convert this to a FP value in an int reg.
         Val = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Val);
-        RegValuesToPass.push_back(Val);
+        RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Val));
       }
       break;
     case MVT::f64:
@@ -296,7 +354,7 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
       // FALL THROUGH
     case MVT::i64:
       ObjSize = 8;
-      if (RegValuesToPass.size() >= 6) {
+      if (RegsToPass.size() >= 6) {
         ValToStore = Val;    // Whole thing is passed in memory.
         break;
       }
@@ -306,42 +364,45 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
                                  DAG.getConstant(1, MVT::i32));
       SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Val,
                                  DAG.getConstant(0, MVT::i32));
-      RegValuesToPass.push_back(Hi);
+      RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Hi));
       
-      if (RegValuesToPass.size() >= 6) {
+      if (RegsToPass.size() >= 6) {
         ValToStore = Lo;
         ArgOffset += 4;
         ObjSize = 4;
       } else {
-        RegValuesToPass.push_back(Lo);
+        RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Lo));
       }
       break;
     }
     
     if (ValToStore.Val) {
-      if (!StackPtr.Val) {
-        StackPtr = DAG.getRegister(SP::O6, MVT::i32);
-      }
+      SDOperand StackPtr = DAG.getRegister(SP::O6, MVT::i32);
       SDOperand PtrOff = DAG.getConstant(ArgOffset, MVT::i32);
       PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
-      Stores.push_back(DAG.getStore(Chain, ValToStore, PtrOff, NULL, 0));
+      MemOpChains.push_back(DAG.getStore(Chain, ValToStore, PtrOff, NULL, 0));
     }
     ArgOffset += ObjSize;
   }
+#endif
   
   // Emit all stores, make sure the occur before any copies into physregs.
-  if (!Stores.empty())
-    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
-  };
-  
-  // Build a sequence of copy-to-reg nodes chained together with token chain
-  // and flag operands which copy the outgoing args into O[0-5].
+  if (!MemOpChains.empty())
+    Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
+                        &MemOpChains[0], MemOpChains.size());
+  
+  // Build a sequence of copy-to-reg nodes chained together with token 
+  // chain and flag operands which copy the outgoing args into registers.
+  // The InFlag in necessary since all emited instructions must be
+  // stuck together.
   SDOperand InFlag;
-  for (unsigned i = 0, e = RegValuesToPass.size(); i != e; ++i) {
-    Chain = DAG.getCopyToReg(Chain, ArgRegs[i], RegValuesToPass[i], InFlag);
+  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
+    unsigned Reg = RegsToPass[i].first;
+    // Remap I0->I7 -> O0->O7.
+    if (Reg >= SP::I0 && Reg <= SP::I7)
+      Reg = Reg-SP::I0+SP::O0;
+
+    Chain = DAG.getCopyToReg(Chain, Reg, RegsToPass[i].second, InFlag);
     InFlag = Chain.getValue(1);
   }
 
@@ -367,9 +428,9 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   
   // Assign locations to each value returned by this call.
   SmallVector<CCValAssign, 16> RVLocs;
-  CCState CCInfo(CallingConv, isVarArg, DAG.getTarget(), RVLocs);
+  CCState RVInfo(CallingConv, isVarArg, DAG.getTarget(), RVLocs);
   
-  CCInfo.AnalyzeCallResult(Op.Val, RetCC_Sparc32);
+  RVInfo.AnalyzeCallResult(Op.Val, RetCC_Sparc32);
   SmallVector<SDOperand, 8> ResultVals;
   
   // Copy all of the result registers out of their specified physreg.