summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/PowerPC
diff options
context:
space:
mode:
authorStrahinja Petrovic <strahinja.petrovic@rt-rk.com>2016-08-05 08:47:26 +0000
committerStrahinja Petrovic <strahinja.petrovic@rt-rk.com>2016-08-05 08:47:26 +0000
commit30e0ce8e9fc4598388fcd3c4d57894036cdd5903 (patch)
treeca5c55feadd0372d4ecc959e00f5213d96b8bc1d /llvm/lib/Target/PowerPC
parent928d7573ddace6e2bd0cd220d661c3e8cbae128e (diff)
downloadbcm5719-llvm-30e0ce8e9fc4598388fcd3c4d57894036cdd5903.tar.gz
bcm5719-llvm-30e0ce8e9fc4598388fcd3c4d57894036cdd5903.zip
[PowerPC] fix passing long double arguments to function (soft-float)
This patch fixes passing long double type arguments to function in soft float mode. If there is less than 4 argument registers free (long double type is mapped in 4 gpr registers in soft float mode) long double type argument must be passed through stack. Differential Revision: https://reviews.llvm.org/D20114. llvm-svn: 277804
Diffstat (limited to 'llvm/lib/Target/PowerPC')
-rw-r--r--llvm/lib/Target/PowerPC/PPCCallingConv.td6
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp26
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.h7
3 files changed, 39 insertions, 0 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCCallingConv.td b/llvm/lib/Target/PowerPC/PPCCallingConv.td
index 53d2f77ff91..db6d087e8e5 100644
--- a/llvm/lib/Target/PowerPC/PPCCallingConv.td
+++ b/llvm/lib/Target/PowerPC/PPCCallingConv.td
@@ -26,6 +26,9 @@ class CCIfNotSubtarget<string F, CCAction A>
class CCIfOrigArgWasNotPPCF128<CCAction A>
: CCIf<"!static_cast<PPCCCState *>(&State)->WasOriginalArgPPCF128(ValNo)",
A>;
+class CCIfOrigArgWasPPCF128<CCAction A>
+ : CCIf<"static_cast<PPCCCState *>(&State)->WasOriginalArgPPCF128(ValNo)",
+ A>;
//===----------------------------------------------------------------------===//
// Return Value Calling Convention
@@ -142,6 +145,9 @@ def CC_PPC32_SVR4_Common : CallingConv<[
CCIfType<[i32],
CCIfSplit<CCIfNotSubtarget<"useSoftFloat()",
CCCustom<"CC_PPC32_SVR4_Custom_AlignArgRegs">>>>,
+ CCIfSplit<CCIfSubtarget<"useSoftFloat()",
+ CCIfOrigArgWasPPCF128<CCCustom<
+ "CC_PPC32_SVR4_Custom_SkipLastArgRegsPPCF128">>>>,
// The 'nest' parameter, if any, is passed in R11.
CCIfNest<CCAssignToReg<[R11]>>,
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 472db99b0fc..2ccbcd9dd70 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -2676,6 +2676,32 @@ bool llvm::CC_PPC32_SVR4_Custom_AlignArgRegs(unsigned &ValNo, MVT &ValVT,
return false;
}
+bool
+llvm::CC_PPC32_SVR4_Custom_SkipLastArgRegsPPCF128(unsigned &ValNo, MVT &ValVT,
+ MVT &LocVT,
+ CCValAssign::LocInfo &LocInfo,
+ ISD::ArgFlagsTy &ArgFlags,
+ CCState &State) {
+ static const MCPhysReg ArgRegs[] = {
+ PPC::R3, PPC::R4, PPC::R5, PPC::R6,
+ PPC::R7, PPC::R8, PPC::R9, PPC::R10,
+ };
+ const unsigned NumArgRegs = array_lengthof(ArgRegs);
+
+ unsigned RegNum = State.getFirstUnallocated(ArgRegs);
+ int RegsLeft = NumArgRegs - RegNum;
+
+ // Skip if there is not enough registers left for long double type (4 gpr regs
+ // in soft float mode) and put long double argument on the stack.
+ if (RegNum != NumArgRegs && RegsLeft < 4) {
+ for (int i = 0; i < RegsLeft; i++) {
+ State.AllocateReg(ArgRegs[RegNum + i]);
+ }
+ }
+
+ return false;
+}
+
bool llvm::CC_PPC32_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, MVT &ValVT,
MVT &LocVT,
CCValAssign::LocInfo &LocInfo,
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index e3be8074e62..c12f9c664c9 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -953,6 +953,13 @@ namespace llvm {
ISD::ArgFlagsTy &ArgFlags,
CCState &State);
+ bool
+ CC_PPC32_SVR4_Custom_SkipLastArgRegsPPCF128(unsigned &ValNo, MVT &ValVT,
+ MVT &LocVT,
+ CCValAssign::LocInfo &LocInfo,
+ ISD::ArgFlagsTy &ArgFlags,
+ CCState &State);
+
bool CC_PPC32_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, MVT &ValVT,
MVT &LocVT,
CCValAssign::LocInfo &LocInfo,
OpenPOWER on IntegriCloud