forked from OSchip/llvm-project
[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
This commit is contained in:
parent
928d7573dd
commit
30e0ce8e9f
|
@ -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]>>,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
; RUN: llc -O2 -mtriple=powerpc-unknown-linux-gnu < %s | FileCheck %s
|
||||
|
||||
target datalayout = "E-m:e-p:32:32-i64:64-n32"
|
||||
target triple = "powerpc-buildroot-linux-gnu"
|
||||
|
||||
@x = global ppc_fp128 0xM3FF00000000000000000000000000000, align 16
|
||||
@.str = private unnamed_addr constant [9 x i8] c"%Lf %Lf\0A\00", align 1
|
||||
|
||||
define void @foo() #0 {
|
||||
entry:
|
||||
%0 = load ppc_fp128, ppc_fp128* @x, align 16
|
||||
%call = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0), ppc_fp128 %0, ppc_fp128 %0)
|
||||
ret void
|
||||
}
|
||||
; Do not put second argument of function in r8 register, because there is no enough registers
|
||||
; left for long double type (4 registers in soft float mode). Instead in r8 register this
|
||||
; argument put on stack.
|
||||
; CHECK-NOT: mr 8, 4
|
||||
; CHECK: stw 7, 20(1)
|
||||
; CHECK: stw 6, 16(1)
|
||||
; CHECK: stw 5, 12(1)
|
||||
; CHECK: stw 4, 8(1)
|
||||
|
||||
declare i32 @printf(i8* nocapture readonly, ...)
|
||||
|
||||
attributes #0 = { "use-soft-float"="true" }
|
Loading…
Reference in New Issue