[llvm-commits] [llvm] r48449 - in /llvm/trunk/lib/Target/Sparc: SparcCallingConv.td SparcISelLowering.cpp
Chris Lattner
sabre at nondot.org
Sun Mar 16 23:58:38 PDT 2008
Author: lattner
Date: Mon Mar 17 01:58:37 2008
New Revision: 48449
URL: http://llvm.org/viewvc/llvm-project?rev=48449&view=rev
Log:
Check in some #ifdef'd out code switching call argument
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.
Modified:
llvm/trunk/lib/Target/Sparc/SparcCallingConv.td
llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp
Modified: llvm/trunk/lib/Target/Sparc/SparcCallingConv.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcCallingConv.td?rev=48449&r1=48448&r2=48449&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcCallingConv.td (original)
+++ llvm/trunk/lib/Target/Sparc/SparcCallingConv.td Mon Mar 17 01:58:37 2008
@@ -21,3 +21,12 @@
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>
+]>;
Modified: llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp?rev=48449&r1=48448&r2=48449&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp Mon Mar 17 01:58:37 2008
@@ -231,38 +231,96 @@
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;
+
+#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));
+ }
- SDOperand StackPtr;
- std::vector<SDOperand> Stores;
- std::vector<SDOperand> RegValuesToPass;
+#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 @@
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 @@
// 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 @@
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 @@
// 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.
More information about the llvm-commits
mailing list