aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/PowerPC
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2008-03-17 02:13:43 +0000
committerDale Johannesen <dalej@apple.com>2008-03-17 02:13:43 +0000
commitfdd3ade005c7bd60f3dc74a49db82f91654e99ae (patch)
tree71d9aa132c7a35f4173d6fa1d4857c9ec70c7e97 /lib/Target/PowerPC
parent349155b671a0908a994f6d54a5576eae85237212 (diff)
downloadexternal_llvm-fdd3ade005c7bd60f3dc74a49db82f91654e99ae.zip
external_llvm-fdd3ade005c7bd60f3dc74a49db82f91654e99ae.tar.gz
external_llvm-fdd3ade005c7bd60f3dc74a49db82f91654e99ae.tar.bz2
Next round of PPC32 ABI changes. Allow for gcc
behavior where a callee thinks a param will be present in memory, even though the ABI doc says it doesn't have to be. Handle complex long long and complex double (4 and 8 return regs). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48439 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC')
-rw-r--r--lib/Target/PowerPC/PPCCallingConv.td2
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp77
2 files changed, 66 insertions, 13 deletions
diff --git a/lib/Target/PowerPC/PPCCallingConv.td b/lib/Target/PowerPC/PPCCallingConv.td
index b73711b..6b6ae07 100644
--- a/lib/Target/PowerPC/PPCCallingConv.td
+++ b/lib/Target/PowerPC/PPCCallingConv.td
@@ -22,7 +22,7 @@ class CCIfSubtarget<string F, CCAction A>
// Return-value convention for PowerPC
def RetCC_PPC : CallingConv<[
- CCIfType<[i32], CCAssignToReg<[R3, R4]>>,
+ CCIfType<[i32], CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10]>>,
CCIfType<[i64], CCAssignToReg<[X3, X4]>>,
CCIfType<[f32], CCAssignToReg<[F1]>>,
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index 5bea470..c6885cf 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -1922,6 +1922,18 @@ SDOperand PPCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG,
}
continue;
}
+ // Copy entire object into memory. There are cases where gcc-generated
+ // code assumes it is there, even if it could be put entirely into
+ // registers. (This is not what the doc says.)
+ SDOperand MemcpyCall = CreateCopyOfByValArgument(Arg, PtrOff,
+ CallSeqStart.Val->getOperand(0),
+ Flags, DAG, Size);
+ // This must go outside the CALLSEQ_START..END.
+ SDOperand NewCallSeqStart = DAG.getCALLSEQ_START(MemcpyCall,
+ CallSeqStart.Val->getOperand(1));
+ DAG.ReplaceAllUsesWith(CallSeqStart.Val, NewCallSeqStart.Val);
+ Chain = CallSeqStart = NewCallSeqStart;
+ // And copy the pieces of it that fit into registers.
for (unsigned j=0; j<Size; j+=PtrByteSize) {
SDOperand Const = DAG.getConstant(j, PtrOff.getValueType());
SDOperand AddArg = DAG.getNode(ISD::ADD, PtrVT, Arg, Const);
@@ -1932,16 +1944,7 @@ SDOperand PPCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG,
if (isMachoABI)
ArgOffset += PtrByteSize;
} else {
- SDOperand AddPtr = DAG.getNode(ISD::ADD, PtrVT, PtrOff, Const);
- SDOperand MemcpyCall = CreateCopyOfByValArgument(AddArg, AddPtr,
- CallSeqStart.Val->getOperand(0),
- Flags, DAG, Size - j);
- // This must go outside the CALLSEQ_START..END.
- SDOperand NewCallSeqStart = DAG.getCALLSEQ_START(MemcpyCall,
- CallSeqStart.Val->getOperand(1));
- DAG.ReplaceAllUsesWith(CallSeqStart.Val, NewCallSeqStart.Val);
- Chain = CallSeqStart = NewCallSeqStart;
- ArgOffset += ((Size - j + 3)/4)*4;
+ ArgOffset += ((Size - j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
break;
}
}
@@ -2181,7 +2184,7 @@ SDOperand PPCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG,
if (Op.Val->getValueType(0) != MVT::Other)
InFlag = Chain.getValue(1);
- SDOperand ResultVals[3];
+ SDOperand ResultVals[9];
unsigned NumResults = 0;
NodeTys.clear();
@@ -2190,7 +2193,57 @@ SDOperand PPCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG,
default: assert(0 && "Unexpected ret value!");
case MVT::Other: break;
case MVT::i32:
- if (Op.Val->getValueType(1) == MVT::i32) {
+ // There are 8 result regs for Complex double, and 4 for Complex long long.
+ if (Op.Val->getNumValues()>=8 && Op.Val->getValueType(7) == MVT::i32) {
+ Chain = DAG.getCopyFromReg(Chain, PPC::R3, MVT::i32, InFlag).getValue(1);
+ ResultVals[0] = Chain.getValue(0);
+ Chain = DAG.getCopyFromReg(Chain, PPC::R4, MVT::i32,
+ Chain.getValue(2)).getValue(1);
+ ResultVals[1] = Chain.getValue(0);
+ Chain = DAG.getCopyFromReg(Chain, PPC::R5, MVT::i32,
+ Chain.getValue(2)).getValue(1);
+ ResultVals[2] = Chain.getValue(0);
+ Chain = DAG.getCopyFromReg(Chain, PPC::R6, MVT::i32,
+ Chain.getValue(2)).getValue(1);
+ ResultVals[3] = Chain.getValue(0);
+ Chain = DAG.getCopyFromReg(Chain, PPC::R7, MVT::i32,
+ Chain.getValue(2)).getValue(1);
+ ResultVals[4] = Chain.getValue(0);
+ Chain = DAG.getCopyFromReg(Chain, PPC::R8, MVT::i32,
+ Chain.getValue(2)).getValue(1);
+ ResultVals[5] = Chain.getValue(0);
+ Chain = DAG.getCopyFromReg(Chain, PPC::R9, MVT::i32,
+ Chain.getValue(2)).getValue(1);
+ ResultVals[6] = Chain.getValue(0);
+ Chain = DAG.getCopyFromReg(Chain, PPC::R10, MVT::i32,
+ Chain.getValue(2)).getValue(1);
+ ResultVals[7] = Chain.getValue(0);
+ NumResults = 8;
+ NodeTys.push_back(MVT::i32);
+ NodeTys.push_back(MVT::i32);
+ NodeTys.push_back(MVT::i32);
+ NodeTys.push_back(MVT::i32);
+ NodeTys.push_back(MVT::i32);
+ NodeTys.push_back(MVT::i32);
+ NodeTys.push_back(MVT::i32);
+ } else if (Op.Val->getNumValues()>=4 &&
+ Op.Val->getValueType(3) == MVT::i32) {
+ Chain = DAG.getCopyFromReg(Chain, PPC::R3, MVT::i32, InFlag).getValue(1);
+ ResultVals[0] = Chain.getValue(0);
+ Chain = DAG.getCopyFromReg(Chain, PPC::R4, MVT::i32,
+ Chain.getValue(2)).getValue(1);
+ ResultVals[1] = Chain.getValue(0);
+ Chain = DAG.getCopyFromReg(Chain, PPC::R5, MVT::i32,
+ Chain.getValue(2)).getValue(1);
+ ResultVals[2] = Chain.getValue(0);
+ Chain = DAG.getCopyFromReg(Chain, PPC::R6, MVT::i32,
+ Chain.getValue(2)).getValue(1);
+ ResultVals[3] = Chain.getValue(0);
+ NumResults = 4;
+ NodeTys.push_back(MVT::i32);
+ NodeTys.push_back(MVT::i32);
+ NodeTys.push_back(MVT::i32);
+ } else if (Op.Val->getValueType(1) == MVT::i32) {
Chain = DAG.getCopyFromReg(Chain, PPC::R3, MVT::i32, InFlag).getValue(1);
ResultVals[0] = Chain.getValue(0);
Chain = DAG.getCopyFromReg(Chain, PPC::R4, MVT::i32,