diff options
author | Duncan Sands <baldrick@free.fr> | 2008-12-12 08:05:40 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2008-12-12 08:05:40 +0000 |
commit | 08b7d4620ccd30d4c98cbaee60bbf24b23fb1e9b (patch) | |
tree | 2168afe43ac3a515c2cfb6ab1b891cd260a29d81 /lib/Target/Sparc | |
parent | 35decd05c23794fc3a492170639b7caa35dde4c3 (diff) | |
download | external_llvm-08b7d4620ccd30d4c98cbaee60bbf24b23fb1e9b.zip external_llvm-08b7d4620ccd30d4c98cbaee60bbf24b23fb1e9b.tar.gz external_llvm-08b7d4620ccd30d4c98cbaee60bbf24b23fb1e9b.tar.bz2 |
Don't make use of an illegal type (i64) when
lowering f64 function arguments.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60944 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Sparc')
-rw-r--r-- | lib/Target/Sparc/SparcISelLowering.cpp | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp index 7b7bf09..b1031b4 100644 --- a/lib/Target/Sparc/SparcISelLowering.cpp +++ b/lib/Target/Sparc/SparcISelLowering.cpp @@ -347,12 +347,37 @@ static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG) { RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Val)); } break; - case MVT::f64: + case MVT::f64: { ObjSize = 8; - // Otherwise, convert this to a FP value in int regs. - Val = DAG.getNode(ISD::BIT_CONVERT, MVT::i64, Val); - // FALL THROUGH - case MVT::i64: + if (RegsToPass.size() >= 6) { + ValToStore = Val; // Whole thing is passed in memory. + break; + } + + // Break into top and bottom parts by storing to the stack and loading + // out the parts as integers. Top part goes in a reg. + SDValue StackPtr = DAG.CreateStackTemporary(MVT::f64, MVT::i32); + SDValue Store = DAG.getStore(DAG.getEntryNode(), Val, StackPtr, NULL, 0); + // Sparc is big-endian, so the high part comes first. + SDValue Hi = DAG.getLoad(MVT::i32, Store, StackPtr, NULL, 0, 0); + // Increment the pointer to the other half. + StackPtr = DAG.getNode(ISD::ADD, StackPtr.getValueType(), StackPtr, + DAG.getIntPtrConstant(4)); + // Load the low part. + SDValue Lo = DAG.getLoad(MVT::i32, Store, StackPtr, NULL, 0, 0); + + RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Hi)); + + if (RegsToPass.size() >= 6) { + ValToStore = Lo; + ArgOffset += 4; + ObjSize = 4; + } else { + RegsToPass.push_back(std::make_pair(ArgRegs[RegsToPass.size()], Lo)); + } + break; + } + case MVT::i64: { ObjSize = 8; if (RegsToPass.size() >= 6) { ValToStore = Val; // Whole thing is passed in memory. @@ -375,6 +400,7 @@ static SDValue LowerCALL(SDValue Op, SelectionDAG &DAG) { } break; } + } if (ValToStore.getNode()) { SDValue StackPtr = DAG.getRegister(SP::O6, MVT::i32); |