mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-27 21:50:40 +00:00
Add support for a preserve_most calling convention to the AArch64 backend.
This change adds a support for a preserve_most calling convention to the AArch64 backend, similar to how it was done for X86-64. There is also a subsequent patch on top of this one to add a tail-calls support for this calling convention. Differential Revision: http://reviews.llvm.org/D18016 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@263092 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d449fa84ed
commit
c461035332
@ -310,3 +310,7 @@ def CSR_AArch64_AllRegs
|
|||||||
(sequence "Q%u", 0, 31))>;
|
(sequence "Q%u", 0, 31))>;
|
||||||
|
|
||||||
def CSR_AArch64_NoRegs : CalleeSavedRegs<(add)>;
|
def CSR_AArch64_NoRegs : CalleeSavedRegs<(add)>;
|
||||||
|
|
||||||
|
def CSR_AArch64_RT_MostRegs : CalleeSavedRegs<(add CSR_AArch64_AAPCS,
|
||||||
|
(sequence "X%u", 9, 15))>;
|
||||||
|
|
||||||
|
@ -723,10 +723,13 @@ static void computeCalleeSaveRegisterPairs(
|
|||||||
|
|
||||||
AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
|
AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
|
||||||
MachineFrameInfo *MFI = MF.getFrameInfo();
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
|
CallingConv::ID CC = MF.getFunction()->getCallingConv();
|
||||||
unsigned Count = CSI.size();
|
unsigned Count = CSI.size();
|
||||||
|
(void)CC;
|
||||||
// MachO's compact unwind format relies on all registers being stored in
|
// MachO's compact unwind format relies on all registers being stored in
|
||||||
// pairs.
|
// pairs.
|
||||||
assert((!MF.getSubtarget<AArch64Subtarget>().isTargetMachO() ||
|
assert((!MF.getSubtarget<AArch64Subtarget>().isTargetMachO() ||
|
||||||
|
CC == CallingConv::PreserveMost ||
|
||||||
(Count & 1) == 0) &&
|
(Count & 1) == 0) &&
|
||||||
"Odd number of callee-saved regs to spill!");
|
"Odd number of callee-saved regs to spill!");
|
||||||
unsigned Offset = AFI->getCalleeSavedStackSize();
|
unsigned Offset = AFI->getCalleeSavedStackSize();
|
||||||
@ -760,6 +763,7 @@ static void computeCalleeSaveRegisterPairs(
|
|||||||
// MachO's compact unwind format relies on all registers being stored in
|
// MachO's compact unwind format relies on all registers being stored in
|
||||||
// adjacent register pairs.
|
// adjacent register pairs.
|
||||||
assert((!MF.getSubtarget<AArch64Subtarget>().isTargetMachO() ||
|
assert((!MF.getSubtarget<AArch64Subtarget>().isTargetMachO() ||
|
||||||
|
CC == CallingConv::PreserveMost ||
|
||||||
(RPI.isPaired() &&
|
(RPI.isPaired() &&
|
||||||
((RPI.Reg1 == AArch64::LR && RPI.Reg2 == AArch64::FP) ||
|
((RPI.Reg1 == AArch64::LR && RPI.Reg2 == AArch64::FP) ||
|
||||||
RPI.Reg1 + 1 == RPI.Reg2))) &&
|
RPI.Reg1 + 1 == RPI.Reg2))) &&
|
||||||
|
@ -2455,6 +2455,7 @@ CCAssignFn *AArch64TargetLowering::CCAssignFnForCall(CallingConv::ID CC,
|
|||||||
return CC_AArch64_GHC;
|
return CC_AArch64_GHC;
|
||||||
case CallingConv::C:
|
case CallingConv::C:
|
||||||
case CallingConv::Fast:
|
case CallingConv::Fast:
|
||||||
|
case CallingConv::PreserveMost:
|
||||||
if (!Subtarget->isTargetDarwin())
|
if (!Subtarget->isTargetDarwin())
|
||||||
return CC_AArch64_AAPCS;
|
return CC_AArch64_AAPCS;
|
||||||
return IsVarArg ? CC_AArch64_DarwinPCS_VarArg : CC_AArch64_DarwinPCS;
|
return IsVarArg ? CC_AArch64_DarwinPCS_VarArg : CC_AArch64_DarwinPCS;
|
||||||
@ -2942,7 +2943,8 @@ bool AArch64TargetLowering::DoesCalleeRestoreStack(CallingConv::ID CallCC,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool AArch64TargetLowering::IsTailCallConvention(CallingConv::ID CallCC) const {
|
bool AArch64TargetLowering::IsTailCallConvention(CallingConv::ID CallCC) const {
|
||||||
return CallCC == CallingConv::Fast;
|
return CallCC == CallingConv::Fast ||
|
||||||
|
CallCC == CallingConv::PreserveMost;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// LowerCall - Lower a call to a callseq_start + CALL + callseq_end chain,
|
/// LowerCall - Lower a call to a callseq_start + CALL + callseq_end chain,
|
||||||
|
@ -51,6 +51,8 @@ AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
|||||||
return MF->getInfo<AArch64FunctionInfo>()->isSplitCSR() ?
|
return MF->getInfo<AArch64FunctionInfo>()->isSplitCSR() ?
|
||||||
CSR_AArch64_CXX_TLS_Darwin_PE_SaveList :
|
CSR_AArch64_CXX_TLS_Darwin_PE_SaveList :
|
||||||
CSR_AArch64_CXX_TLS_Darwin_SaveList;
|
CSR_AArch64_CXX_TLS_Darwin_SaveList;
|
||||||
|
if (MF->getFunction()->getCallingConv() == CallingConv::PreserveMost)
|
||||||
|
return CSR_AArch64_RT_MostRegs_SaveList;
|
||||||
else
|
else
|
||||||
return CSR_AArch64_AAPCS_SaveList;
|
return CSR_AArch64_AAPCS_SaveList;
|
||||||
}
|
}
|
||||||
@ -74,6 +76,8 @@ AArch64RegisterInfo::getCallPreservedMask(const MachineFunction &MF,
|
|||||||
return CSR_AArch64_AllRegs_RegMask;
|
return CSR_AArch64_AllRegs_RegMask;
|
||||||
if (CC == CallingConv::CXX_FAST_TLS)
|
if (CC == CallingConv::CXX_FAST_TLS)
|
||||||
return CSR_AArch64_CXX_TLS_Darwin_RegMask;
|
return CSR_AArch64_CXX_TLS_Darwin_RegMask;
|
||||||
|
if (CC == CallingConv::PreserveMost)
|
||||||
|
return CSR_AArch64_RT_MostRegs_RegMask;
|
||||||
else
|
else
|
||||||
return CSR_AArch64_AAPCS_RegMask;
|
return CSR_AArch64_AAPCS_RegMask;
|
||||||
}
|
}
|
||||||
|
@ -1378,6 +1378,8 @@ ARMTargetLowering::getEffectiveCallingConv(CallingConv::ID CC,
|
|||||||
case CallingConv::ARM_APCS:
|
case CallingConv::ARM_APCS:
|
||||||
case CallingConv::GHC:
|
case CallingConv::GHC:
|
||||||
return CC;
|
return CC;
|
||||||
|
case CallingConv::PreserveMost:
|
||||||
|
return CallingConv::PreserveMost;
|
||||||
case CallingConv::ARM_AAPCS_VFP:
|
case CallingConv::ARM_AAPCS_VFP:
|
||||||
return isVarArg ? CallingConv::ARM_AAPCS : CallingConv::ARM_AAPCS_VFP;
|
return isVarArg ? CallingConv::ARM_AAPCS : CallingConv::ARM_AAPCS_VFP;
|
||||||
case CallingConv::C:
|
case CallingConv::C:
|
||||||
@ -1420,6 +1422,8 @@ CCAssignFn *ARMTargetLowering::CCAssignFnForNode(CallingConv::ID CC,
|
|||||||
return (Return ? RetFastCC_ARM_APCS : FastCC_ARM_APCS);
|
return (Return ? RetFastCC_ARM_APCS : FastCC_ARM_APCS);
|
||||||
case CallingConv::GHC:
|
case CallingConv::GHC:
|
||||||
return (Return ? RetCC_ARM_APCS : CC_ARM_APCS_GHC);
|
return (Return ? RetCC_ARM_APCS : CC_ARM_APCS_GHC);
|
||||||
|
case CallingConv::PreserveMost:
|
||||||
|
return (Return ? RetCC_ARM_AAPCS : CC_ARM_AAPCS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
40
test/CodeGen/AArch64/preserve_mostcc.ll
Normal file
40
test/CodeGen/AArch64/preserve_mostcc.ll
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
; RUN: llc < %s -mtriple=arm64-apple-ios-8.0.0 | FileCheck %s
|
||||||
|
|
||||||
|
declare void @standard_cc_func()
|
||||||
|
declare preserve_mostcc void @preserve_mostcc_func()
|
||||||
|
|
||||||
|
; Registers r9-r15 should be saved before the call of a function
|
||||||
|
; with a standard calling convention.
|
||||||
|
define preserve_mostcc void @preserve_mostcc1() nounwind {
|
||||||
|
entry:
|
||||||
|
;CHECK-LABEL: preserve_mostcc1
|
||||||
|
;CHECK-NOT: stp
|
||||||
|
;CHECK-NOT: str
|
||||||
|
;CHECK: str x15
|
||||||
|
;CHECK-NEXT: stp x14, x13,
|
||||||
|
;CHECK-NEXT: stp x12, x11,
|
||||||
|
;CHECK-NEXT: stp x10, x9,
|
||||||
|
;CHECK: bl _standard_cc_func
|
||||||
|
call void @standard_cc_func()
|
||||||
|
;CHECK: ldp x10, x9,
|
||||||
|
;CHECK-NEXT: ldp x12, x11,
|
||||||
|
;CHECK-NEXT: ldp x14, x13,
|
||||||
|
;CHECK-NEXT: ldr x15
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; Registers r9-r15 don't need to be saved if one
|
||||||
|
; function with preserve_mostcc calling convention calls another
|
||||||
|
; function with preserve_mostcc calling convention, because the
|
||||||
|
; callee wil save these registers anyways.
|
||||||
|
define preserve_mostcc void @preserve_mostcc2() nounwind {
|
||||||
|
entry:
|
||||||
|
;CHECK-LABEL: preserve_mostcc2
|
||||||
|
;CHECK-NOT: x14
|
||||||
|
;CHECK: stp x29, x30,
|
||||||
|
;CHECK-NOT: x14
|
||||||
|
;CHECK: bl _preserve_mostcc_func
|
||||||
|
call preserve_mostcc void @preserve_mostcc_func()
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user