aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC/PPCISelPattern.cpp
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2005-04-10 05:53:14 +0000
committerNate Begeman <natebegeman@mac.com>2005-04-10 05:53:14 +0000
commitc5b1cd22b57d36229560a8919d3e59b4dae34e2a (patch)
treed9357dbce7e49b29ec1bd2bd16b3990ccc7339b5 /lib/Target/PowerPC/PPCISelPattern.cpp
parent232ee95a09a583b7d66b90ee7ddf7fdb9c194a04 (diff)
Fix 64 bit argument loading that straddles the args in regs / args on stack
boundary. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21206 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC/PPCISelPattern.cpp')
-rw-r--r--lib/Target/PowerPC/PPCISelPattern.cpp22
1 files changed, 15 insertions, 7 deletions
diff --git a/lib/Target/PowerPC/PPCISelPattern.cpp b/lib/Target/PowerPC/PPCISelPattern.cpp
index f6b47fc874..b8529ba8cc 100644
--- a/lib/Target/PowerPC/PPCISelPattern.cpp
+++ b/lib/Target/PowerPC/PPCISelPattern.cpp
@@ -151,14 +151,22 @@ PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
break;
case MVT::i64: ObjSize = 8;
if (!ArgLive) break;
- // FIXME: can split 64b load between reg/mem if it is last arg in regs
- if (GPR_remaining > 1) {
+ if (GPR_remaining > 0) {
+ SDOperand argHi, argLo;
MF.addLiveIn(GPR[GPR_idx]);
- MF.addLiveIn(GPR[GPR_idx+1]);
- // Copy the extracted halves into the virtual registers
- SDOperand argHi = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32,
- DAG.getRoot());
- SDOperand argLo = DAG.getCopyFromReg(GPR[GPR_idx+1], MVT::i32, argHi);
+ argHi = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, DAG.getRoot());
+ // If we have two or more remaining argument registers, then both halves
+ // of the i64 can be sourced from there. Otherwise, the lower half will
+ // have to come off the stack. This can happen when an i64 is preceded
+ // by 28 bytes of arguments.
+ if (GPR_remaining > 1) {
+ MF.addLiveIn(GPR[GPR_idx+1]);
+ argLo = DAG.getCopyFromReg(GPR[GPR_idx+1], MVT::i32, argHi);
+ } else {
+ int FI = MFI->CreateFixedObject(4, ArgOffset+4);
+ SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
+ argLo = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN);
+ }
// Build the outgoing arg thingy
argt = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, argLo, argHi);
newroot = argLo;