aboutsummaryrefslogtreecommitdiffstats
path: root/lib
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
commit8c0f244c3ed90a3f702bac09334cac2d3236aecb (patch)
tree2168afe43ac3a515c2cfb6ab1b891cd260a29d81 /lib
parentff17b032dd433c022440217e209d79c2600c7887 (diff)
downloadexternal_llvm-8c0f244c3ed90a3f702bac09334cac2d3236aecb.zip
external_llvm-8c0f244c3ed90a3f702bac09334cac2d3236aecb.tar.gz
external_llvm-8c0f244c3ed90a3f702bac09334cac2d3236aecb.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')
-rw-r--r--lib/Target/Sparc/SparcISelLowering.cpp36
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);