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 | dd6f3dbd051cef3ec1cfbe46c70f5b4203e72236 (patch) | |
tree | 95bb4c787debacdc4e07a6b255d2975f41139d31 /llvm/lib/Target/Sparc/SparcISelLowering.cpp | |
parent | 30032889aed4c622bcf5745775aba3d10fda4aa8 (diff) | |
download | bcm5719-llvm-dd6f3dbd051cef3ec1cfbe46c70f5b4203e72236.tar.gz bcm5719-llvm-dd6f3dbd051cef3ec1cfbe46c70f5b4203e72236.zip |
Don't make use of an illegal type (i64) when
lowering f64 function arguments.
llvm-svn: 60944
Diffstat (limited to 'llvm/lib/Target/Sparc/SparcISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/Sparc/SparcISelLowering.cpp | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp index 7b7bf096847..b1031b46be6 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/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); |