summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Sparc/SparcISelLowering.cpp
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2008-12-12 08:05:40 +0000
committerDuncan Sands <baldrick@free.fr>2008-12-12 08:05:40 +0000
commitdd6f3dbd051cef3ec1cfbe46c70f5b4203e72236 (patch)
tree95bb4c787debacdc4e07a6b255d2975f41139d31 /llvm/lib/Target/Sparc/SparcISelLowering.cpp
parent30032889aed4c622bcf5745775aba3d10fda4aa8 (diff)
downloadbcm5719-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.cpp36
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);
OpenPOWER on IntegriCloud