summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/Sparc/SparcCallingConv.td11
-rw-r--r--lib/Target/Sparc/SparcISelLowering.cpp4
2 files changed, 12 insertions, 3 deletions
diff --git a/lib/Target/Sparc/SparcCallingConv.td b/lib/Target/Sparc/SparcCallingConv.td
index acd4ec21de..dfaaabf344 100644
--- a/lib/Target/Sparc/SparcCallingConv.td
+++ b/lib/Target/Sparc/SparcCallingConv.td
@@ -103,7 +103,7 @@ def RetCC_Sparc32 : CallingConv<[
// Function return values are passed exactly like function arguments, except a
// struct up to 32 bytes in size can be returned in registers.
-// Function arguments AND return values.
+// Function arguments AND most return values.
def CC_Sparc64 : CallingConv<[
// The frontend uses the inreg flag to indicate i32 and float arguments from
// structs. These arguments are not promoted to 64 bits, but they can still
@@ -118,6 +118,15 @@ def CC_Sparc64 : CallingConv<[
CCCustom<"CC_Sparc64_Full">
]>;
+def RetCC_Sparc64 : CallingConv<[
+ // A single f32 return value always goes in %f0. The ABI doesn't specify what
+ // happens to multiple f32 return values outside a struct.
+ CCIfType<[f32], CCCustom<"CC_Sparc64_Half">>,
+
+ // Otherwise, return values are passed exactly like arguments.
+ CCDelegateTo<CC_Sparc64>
+]>;
+
// Callee-saved registers are handled by the register window mechanism.
def CSR : CalleeSavedRegs<(add)> {
let OtherPreserved = (add (sequence "I%u", 0, 7),
diff --git a/lib/Target/Sparc/SparcISelLowering.cpp b/lib/Target/Sparc/SparcISelLowering.cpp
index 2fce971edf..fce2c0d5b0 100644
--- a/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/lib/Target/Sparc/SparcISelLowering.cpp
@@ -254,7 +254,7 @@ SparcTargetLowering::LowerReturn_64(SDValue Chain,
DAG.getTarget(), RVLocs, *DAG.getContext());
// Analyze return values.
- CCInfo.AnalyzeReturn(Outs, CC_Sparc64);
+ CCInfo.AnalyzeReturn(Outs, RetCC_Sparc64);
SDValue Flag;
SmallVector<SDValue, 4> RetOps(1, Chain);
@@ -1258,7 +1258,7 @@ SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI,
if (CLI.Ins.size() == 1 && CLI.Ins[0].VT == MVT::f32 && CLI.CS == 0)
CLI.Ins[0].Flags.setInReg();
- RVInfo.AnalyzeCallResult(CLI.Ins, CC_Sparc64);
+ RVInfo.AnalyzeCallResult(CLI.Ins, RetCC_Sparc64);
// Copy all of the result registers out of their specified physreg.
for (unsigned i = 0; i != RVLocs.size(); ++i) {