mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-03 19:15:30 +00:00
[TLS on Darwin] use a different mask for tls calls on x86-64.
Calls involved in thread-local variable lookup save more registers than normal calls. rdar://problem/23073171 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252837 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c1ad62ec03
commit
6c3ce45003
@ -796,6 +796,12 @@ def CSR_64EHRet : CalleeSavedRegs<(add RAX, RDX, CSR_64)>;
|
||||
def CSR_Win64 : CalleeSavedRegs<(add RBX, RBP, RDI, RSI, R12, R13, R14, R15,
|
||||
(sequence "XMM%u", 6, 15))>;
|
||||
|
||||
// The function used by Darwin to obtain the address of a thread-local variable
|
||||
// uses rdi to pass a single parameter and rax for the return value. All other
|
||||
// GPRs are preserved.
|
||||
def CSR_64_TLS_Darwin : CalleeSavedRegs<(add CSR_64, RCX, RDX, RSI,
|
||||
R8, R9, R10, R11)>;
|
||||
|
||||
// All GPRs - except r11
|
||||
def CSR_64_RT_MostRegs : CalleeSavedRegs<(add CSR_64, RAX, RCX, RDX, RSI, RDI,
|
||||
R8, R9, R10, RSP)>;
|
||||
|
@ -21461,6 +21461,8 @@ X86TargetLowering::EmitLoweredTLSCall(MachineInstr *MI,
|
||||
// FIXME: The 32-bit calls have non-standard calling conventions. Use a
|
||||
// proper register mask.
|
||||
const uint32_t *RegMask =
|
||||
Subtarget->is64Bit() ?
|
||||
Subtarget->getRegisterInfo()->getDarwinTLSCallPreservedMask() :
|
||||
Subtarget->getRegisterInfo()->getCallPreservedMask(*F, CallingConv::C);
|
||||
if (Subtarget->is64Bit()) {
|
||||
MachineInstrBuilder MIB = BuildMI(*BB, MI, DL,
|
||||
|
@ -347,6 +347,10 @@ X86RegisterInfo::getNoPreservedMask() const {
|
||||
return CSR_NoRegs_RegMask;
|
||||
}
|
||||
|
||||
const uint32_t *X86RegisterInfo::getDarwinTLSCallPreservedMask() const {
|
||||
return CSR_64_TLS_Darwin_RegMask;
|
||||
}
|
||||
|
||||
BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
||||
BitVector Reserved(getNumRegs());
|
||||
const X86FrameLowering *TFI = getFrameLowering(MF);
|
||||
|
@ -98,6 +98,10 @@ public:
|
||||
CallingConv::ID) const override;
|
||||
const uint32_t *getNoPreservedMask() const override;
|
||||
|
||||
// Calls involved in thread-local variable lookup save more registers than
|
||||
// normal calls, so they need a different mask to represent this.
|
||||
const uint32_t *getDarwinTLSCallPreservedMask() const;
|
||||
|
||||
/// getReservedRegs - Returns a bitset indexed by physical register number
|
||||
/// indicating if a register is a special register that has particular uses and
|
||||
/// should be considered unavailable at all times, e.g. SP, RA. This is used by
|
||||
|
28
test/CodeGen/X86/darwin-tls.ll
Normal file
28
test/CodeGen/X86/darwin-tls.ll
Normal file
@ -0,0 +1,28 @@
|
||||
; RUN: llc < %s -mtriple x86_64-apple-darwin | FileCheck %s
|
||||
|
||||
@a = thread_local global i32 4, align 4
|
||||
|
||||
define i32 @f2(i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) {
|
||||
entry:
|
||||
; Parameters are in %edi, %esi, %edx, %ecx, %r8d, there is no need to save
|
||||
; these parameters except the one in %edi, before making the TLS call.
|
||||
; %edi is used to pass parameter to the TLS call.
|
||||
; CHECK-NOT: movl %r8d
|
||||
; CHECK-NOT: movl %ecx
|
||||
; CHECK-NOT: movl %edx
|
||||
; CHECK-NOT: movl %esi
|
||||
; CHECK: movq {{.*}}TLVP{{.*}}, %rdi
|
||||
; CHECK-NEXT: callq
|
||||
; CHECK-NEXT: movl (%rax),
|
||||
; CHECK-NOT: movl {{.*}}, %esi
|
||||
; CHECK-NOT: movl {{.*}}, %edx
|
||||
; CHECK-NOT: movl {{.*}}, %ecx
|
||||
; CHECK-NOT: movl {{.*}}, %r8d
|
||||
; CHECK: callq
|
||||
%0 = load i32, i32* @a, align 4
|
||||
%call = tail call i32 @f3(i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5)
|
||||
%add = add nsw i32 %call, %0
|
||||
ret i32 %add
|
||||
}
|
||||
|
||||
declare i32 @f3(i32, i32, i32, i32, i32)
|
Loading…
x
Reference in New Issue
Block a user