mirror of
https://github.com/RPCS3/llvm.git
synced 2026-07-18 21:24:32 -04:00
AArch64: support TLS on Darwin platforms in GlobalISel.
All TLS access on Darwin is in the "general dynamic" form where we call a function to resolve the address, so implementation is pretty simple. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@368418 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -121,6 +121,7 @@ private:
|
||||
bool selectIntrinsicRound(MachineInstr &I, MachineRegisterInfo &MRI) const;
|
||||
bool selectJumpTable(MachineInstr &I, MachineRegisterInfo &MRI) const;
|
||||
bool selectBrJT(MachineInstr &I, MachineRegisterInfo &MRI) const;
|
||||
bool selectTLSGlobalValue(MachineInstr &I, MachineRegisterInfo &MRI) const;
|
||||
|
||||
unsigned emitConstantPoolEntry(Constant *CPVal, MachineFunction &MF) const;
|
||||
MachineInstr *emitLoadFromConstantPool(Constant *CPVal,
|
||||
@@ -1690,10 +1691,9 @@ bool AArch64InstructionSelector::select(MachineInstr &I,
|
||||
|
||||
case TargetOpcode::G_GLOBAL_VALUE: {
|
||||
auto GV = I.getOperand(1).getGlobal();
|
||||
if (GV->isThreadLocal()) {
|
||||
// FIXME: we don't support TLS yet.
|
||||
return false;
|
||||
}
|
||||
if (GV->isThreadLocal())
|
||||
return selectTLSGlobalValue(I, MRI);
|
||||
|
||||
unsigned OpFlags = STI.ClassifyGlobalReference(GV, TM);
|
||||
if (OpFlags & AArch64II::MO_GOT) {
|
||||
I.setDesc(TII.get(AArch64::LOADgot));
|
||||
@@ -2361,6 +2361,36 @@ bool AArch64InstructionSelector::selectJumpTable(
|
||||
return constrainSelectedInstRegOperands(*MovMI, TII, TRI, RBI);
|
||||
}
|
||||
|
||||
bool AArch64InstructionSelector::selectTLSGlobalValue(
|
||||
MachineInstr &I, MachineRegisterInfo &MRI) const {
|
||||
if (!STI.isTargetMachO())
|
||||
return false;
|
||||
MachineFunction &MF = *I.getParent()->getParent();
|
||||
MF.getFrameInfo().setAdjustsStack(true);
|
||||
|
||||
const GlobalValue &GV = *I.getOperand(1).getGlobal();
|
||||
MachineIRBuilder MIB(I);
|
||||
|
||||
MIB.buildInstr(AArch64::LOADgot, {AArch64::X0}, {})
|
||||
.addGlobalAddress(&GV, 0, AArch64II::MO_TLS);
|
||||
|
||||
Register DestReg = MRI.createVirtualRegister(&AArch64::GPR64commonRegClass);
|
||||
MIB.buildInstr(AArch64::LDRXui, {DestReg}, {Register(AArch64::X0)}).addImm(0);
|
||||
|
||||
// TLS calls preserve all registers except those that absolutely must be
|
||||
// trashed: X0 (it takes an argument), LR (it's a call) and NZCV (let's not be
|
||||
// silly).
|
||||
MIB.buildInstr(AArch64::BLR, {}, {DestReg})
|
||||
.addDef(AArch64::X0, RegState::Implicit)
|
||||
.addRegMask(TRI.getTLSCallPreservedMask());
|
||||
|
||||
MIB.buildCopy(I.getOperand(0).getReg(), Register(AArch64::X0));
|
||||
RBI.constrainGenericRegister(I.getOperand(0).getReg(), AArch64::GPR64RegClass,
|
||||
MRI);
|
||||
I.eraseFromParent();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AArch64InstructionSelector::selectIntrinsicTrunc(
|
||||
MachineInstr &I, MachineRegisterInfo &MRI) const {
|
||||
const LLT SrcTy = MRI.getType(I.getOperand(0).getReg());
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
; RUN: llc -mtriple=arm64-apple-ios7.0 %s -o - | FileCheck %s
|
||||
; RUN: llc -mtriple=arm64-apple-ios7.0 -global-isel -global-isel-abort=1 -verify-machineinstrs %s -o - | FileCheck %s
|
||||
|
||||
@var = thread_local global i8 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user