diff options
author | Manman Ren <manman.ren@gmail.com> | 2016-01-11 23:50:43 +0000 |
---|---|---|
committer | Manman Ren <manman.ren@gmail.com> | 2016-01-11 23:50:43 +0000 |
commit | 1602605bf85f4fcc37aa2481a0e9ad7772444c47 (patch) | |
tree | d8412907478e571a5746619948014b75b07d4a4a /llvm/lib | |
parent | 26c6765bd6fe1f672b0a58f35a89083518d67465 (diff) | |
download | bcm5719-llvm-1602605bf85f4fcc37aa2481a0e9ad7772444c47.tar.gz bcm5719-llvm-1602605bf85f4fcc37aa2481a0e9ad7772444c47.zip |
CXX_FAST_TLS calling convention: Add support for ARM on Darwin.
rdar://9001553
llvm-svn: 257417
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMBaseRegisterInfo.h | 6 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMCallingConv.td | 5 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 1 |
4 files changed, 16 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp index adc6b6b1894..595975de905 100644 --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -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; } diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h index e2335b0480e..4c762dc1a23 100644 --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h @@ -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; diff --git a/llvm/lib/Target/ARM/ARMCallingConv.td b/llvm/lib/Target/ARM/ARMCallingConv.td index 22ea166d540..e386a2e5cff 100644 --- a/llvm/lib/Target/ARM/ARMCallingConv.td +++ b/llvm/lib/Target/ARM/ARMCallingConv.td @@ -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 diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 1f93d2c38b9..3c7356ada6c 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -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; |