diff options
author | Dale Johannesen <dalej@apple.com> | 2008-03-17 02:13:43 +0000 |
---|---|---|
committer | Dale Johannesen <dalej@apple.com> | 2008-03-17 02:13:43 +0000 |
commit | fdd3ade005c7bd60f3dc74a49db82f91654e99ae (patch) | |
tree | 71d9aa132c7a35f4173d6fa1d4857c9ec70c7e97 /lib/Target/PowerPC | |
parent | 349155b671a0908a994f6d54a5576eae85237212 (diff) | |
download | external_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.td | 2 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.cpp | 77 |
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, |