mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-30 19:35:54 +00:00
[X86] Implement the local-exec TLS model for Windows targets
We know that _tls_index is zero for local-exec TLS variables because they are always defined in the executable. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237772 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
37e9aba0db
commit
349f0b12a4
@ -11289,7 +11289,6 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
|
||||
|
||||
if (Subtarget->isTargetELF()) {
|
||||
TLSModel::Model model = DAG.getTarget().getTLSModel(GV);
|
||||
|
||||
switch (model) {
|
||||
case TLSModel::GeneralDynamic:
|
||||
if (Subtarget->is64Bit())
|
||||
@ -11388,21 +11387,27 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
|
||||
DAG.getLoad(getPointerTy(), dl, Chain, TlsArray,
|
||||
MachinePointerInfo(Ptr), false, false, false, 0);
|
||||
|
||||
// Load the _tls_index variable
|
||||
SDValue IDX = DAG.getExternalSymbol("_tls_index", getPointerTy());
|
||||
if (Subtarget->is64Bit())
|
||||
IDX = DAG.getExtLoad(ISD::ZEXTLOAD, dl, getPointerTy(), Chain,
|
||||
IDX, MachinePointerInfo(), MVT::i32,
|
||||
false, false, false, 0);
|
||||
else
|
||||
IDX = DAG.getLoad(getPointerTy(), dl, Chain, IDX, MachinePointerInfo(),
|
||||
false, false, false, 0);
|
||||
SDValue res;
|
||||
if (GV->getThreadLocalMode() == GlobalVariable::LocalExecTLSModel) {
|
||||
res = ThreadPointer;
|
||||
} else {
|
||||
// Load the _tls_index variable
|
||||
SDValue IDX = DAG.getExternalSymbol("_tls_index", getPointerTy());
|
||||
if (Subtarget->is64Bit())
|
||||
IDX = DAG.getExtLoad(ISD::ZEXTLOAD, dl, getPointerTy(), Chain, IDX,
|
||||
MachinePointerInfo(), MVT::i32, false, false,
|
||||
false, 0);
|
||||
else
|
||||
IDX = DAG.getLoad(getPointerTy(), dl, Chain, IDX, MachinePointerInfo(),
|
||||
false, false, false, 0);
|
||||
|
||||
SDValue Scale = DAG.getConstant(Log2_64_Ceil(TD->getPointerSize()), dl,
|
||||
getPointerTy());
|
||||
IDX = DAG.getNode(ISD::SHL, dl, getPointerTy(), IDX, Scale);
|
||||
SDValue Scale = DAG.getConstant(Log2_64_Ceil(TD->getPointerSize()), dl,
|
||||
getPointerTy());
|
||||
IDX = DAG.getNode(ISD::SHL, dl, getPointerTy(), IDX, Scale);
|
||||
|
||||
res = DAG.getNode(ISD::ADD, dl, getPointerTy(), ThreadPointer, IDX);
|
||||
}
|
||||
|
||||
SDValue res = DAG.getNode(ISD::ADD, dl, getPointerTy(), ThreadPointer, IDX);
|
||||
res = DAG.getLoad(getPointerTy(), dl, Chain, res, MachinePointerInfo(),
|
||||
false, false, false, 0);
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
@i5 = external hidden thread_local global i32
|
||||
@s1 = thread_local global i16 15
|
||||
@b1 = thread_local global i8 0
|
||||
@b2 = thread_local(localexec) global i8 0
|
||||
|
||||
define i32 @f1() {
|
||||
; X32_LINUX-LABEL: f1:
|
||||
@ -409,3 +410,31 @@ entry:
|
||||
ret i32 %tmp2
|
||||
}
|
||||
|
||||
define i8* @f15() {
|
||||
; X32_LINUX-LABEL: f15:
|
||||
; X32_LINUX: movl %gs:0, %eax
|
||||
; X32_LINUX-NEXT: leal b2@NTPOFF(%eax), %eax
|
||||
; X32_LINUX-NEXT: ret
|
||||
; X64_LINUX-LABEL: f15:
|
||||
; X64_LINUX: movq %fs:0, %rax
|
||||
; X64_LINUX-NEXT: leaq b2@TPOFF(%rax), %rax
|
||||
; X64_LINUX-NEXT: ret
|
||||
; X32_WIN-LABEL: f15:
|
||||
; X32_WIN: movl %fs:__tls_array, %eax
|
||||
; X32_WIN-NEXT: movl (%eax), %eax
|
||||
; X32_WIN-NEXT: leal _b2@SECREL32(%eax), %eax
|
||||
; X32_WIN-NEXT: ret
|
||||
; X64_WIN-LABEL: f15:
|
||||
; X64_WIN: movq %gs:88, %rax
|
||||
; X64_WIN-NEXT: movq (%rax), %rax
|
||||
; X64_WIN-NEXT: leaq b2@SECREL32(%rax), %rax
|
||||
; X64_WIN-NEXT: ret
|
||||
; MINGW32-LABEL: f15:
|
||||
; MINGW32: movl %fs:44, %eax
|
||||
; MINGW32-NEXT: movl (%eax), %eax
|
||||
; MINGW32-NEXT: leal _b2@SECREL32(%eax), %eax
|
||||
; MINGW32-NEXT: ret
|
||||
entry:
|
||||
ret i8* @b2
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user