forked from OSchip/llvm-project
CXX_FAST_TLS calling convention: Add support for ARM on Darwin.
rdar://9001553 llvm-svn: 257417
This commit is contained in:
parent
26c6765bd6
commit
1602605bf8
|
@ -87,6 +87,8 @@ ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
|||
}
|
||||
}
|
||||
|
||||
if (STI.isTargetDarwin() && F->getCallingConv() == CallingConv::CXX_FAST_TLS)
|
||||
return CSR_iOS_CXX_TLS_SaveList;
|
||||
return RegList;
|
||||
}
|
||||
|
||||
|
@ -97,6 +99,8 @@ ARMBaseRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
|
|||
if (CC == CallingConv::GHC)
|
||||
// This is academic becase all GHC calls are (supposed to be) tail calls
|
||||
return CSR_NoRegs_RegMask;
|
||||
if (STI.isTargetDarwin() && CC == CallingConv::CXX_FAST_TLS)
|
||||
return CSR_iOS_CXX_TLS_RegMask;
|
||||
return STI.isTargetDarwin() ? CSR_iOS_RegMask : CSR_AAPCS_RegMask;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,12 @@ static inline bool isARMArea3Register(unsigned Reg, bool isIOS) {
|
|||
switch (Reg) {
|
||||
case D15: case D14: case D13: case D12:
|
||||
case D11: case D10: case D9: case D8:
|
||||
case D7: case D6: case D5: case D4:
|
||||
case D3: case D2: case D1: case D0:
|
||||
case D31: case D30: case D29: case D28:
|
||||
case D27: case D26: case D25: case D24:
|
||||
case D23: case D22: case D21: case D20:
|
||||
case D19: case D18: case D17: case D16:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -229,6 +229,11 @@ def CSR_iOS_TLSCall : CalleeSavedRegs<(add LR, SP,
|
|||
(sequence "R%u", 12, 1),
|
||||
(sequence "D%u", 31, 0))>;
|
||||
|
||||
// C++ TLS access function saves all registers except SP. Try to match
|
||||
// the order of CSRs in CSR_iOS.
|
||||
def CSR_iOS_CXX_TLS : CalleeSavedRegs<(add CSR_iOS, (sequence "R%u", 12, 1),
|
||||
(sequence "D%u", 31, 0))>;
|
||||
|
||||
// The "interrupt" attribute is used to generate code that is acceptable in
|
||||
// exception-handlers of various kinds. It makes us use a different return
|
||||
// instruction (handled elsewhere) and affects which registers we must return to
|
||||
|
|
|
@ -1385,6 +1385,7 @@ ARMTargetLowering::getEffectiveCallingConv(CallingConv::ID CC,
|
|||
else
|
||||
return CallingConv::ARM_AAPCS;
|
||||
case CallingConv::Fast:
|
||||
case CallingConv::CXX_FAST_TLS:
|
||||
if (!Subtarget->isAAPCS_ABI()) {
|
||||
if (Subtarget->hasVFP2() && !Subtarget->isThumb1Only() && !isVarArg)
|
||||
return CallingConv::Fast;
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
; RUN: llc < %s -mtriple=armv7k-apple-watchos2.0 | FileCheck %s
|
||||
; RUN: llc < %s -mtriple=armv7k-apple-watchos2.0 -enable-shrink-wrap=true | FileCheck --check-prefix=CHECK %s
|
||||
; RUN: llc < %s -mtriple=armv7-apple-ios8.0 | FileCheck %s
|
||||
; RUN: llc < %s -mtriple=armv7-apple-ios8.0 -enable-shrink-wrap=true | FileCheck --check-prefix=CHECK %s
|
||||
|
||||
%struct.S = type { i8 }
|
||||
|
||||
@sg = internal thread_local global %struct.S zeroinitializer, align 1
|
||||
@__dso_handle = external global i8
|
||||
@__tls_guard = internal thread_local unnamed_addr global i1 false
|
||||
|
||||
declare %struct.S* @_ZN1SC1Ev(%struct.S* returned)
|
||||
declare %struct.S* @_ZN1SD1Ev(%struct.S* returned)
|
||||
declare i32 @_tlv_atexit(void (i8*)*, i8*, i8*)
|
||||
|
||||
define cxx_fast_tlscc nonnull %struct.S* @_ZTW2sg() nounwind {
|
||||
%.b.i = load i1, i1* @__tls_guard, align 1
|
||||
br i1 %.b.i, label %__tls_init.exit, label %init.i
|
||||
|
||||
init.i:
|
||||
store i1 true, i1* @__tls_guard, align 1
|
||||
%call.i.i = tail call %struct.S* @_ZN1SC1Ev(%struct.S* nonnull @sg)
|
||||
%1 = tail call i32 @_tlv_atexit(void (i8*)* nonnull bitcast (%struct.S* (%struct.S*)* @_ZN1SD1Ev to void (i8*)*), i8* nonnull getelementptr inbounds (%struct.S, %struct.S* @sg, i64 0, i32 0), i8* nonnull @__dso_handle)
|
||||
br label %__tls_init.exit
|
||||
|
||||
__tls_init.exit:
|
||||
ret %struct.S* @sg
|
||||
}
|
||||
|
||||
; CHECK-LABEL: _ZTW2sg
|
||||
; CHECK: push {r1, r2, r3, r4, r7, lr}
|
||||
; CHECK: push {r9, r12}
|
||||
; CHECK: vpush {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
|
||||
; CHECK: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
|
||||
; CHECK: blx
|
||||
; CHECK: bne [[BB_end:.?LBB0_[0-9]+]]
|
||||
; CHECK; blx
|
||||
; CHECK: tlv_atexit
|
||||
; CHECK: [[BB_end]]:
|
||||
; CHECK: blx
|
||||
; CHECK: vpop {d0, d1, d2, d3, d4, d5, d6, d7}
|
||||
; CHECK: vpop {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
|
||||
; CHECK: pop {r9, r12}
|
||||
; CHECK: pop {r1, r2, r3, r4, r7, pc}
|
Loading…
Reference in New Issue