mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-07 19:47:09 +00:00
Fix PR 4004 by including the call to __tls_get_addr in X86tlsaddr. This is not
very elegant, but neither is the tls specification :-( git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69968 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
15684b2955
commit
15f1b66d64
@ -4745,7 +4745,7 @@ X86TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) {
|
|||||||
|
|
||||||
static SDValue
|
static SDValue
|
||||||
GetTLSADDR(SelectionDAG &DAG, SDValue Chain, GlobalAddressSDNode *GA,
|
GetTLSADDR(SelectionDAG &DAG, SDValue Chain, GlobalAddressSDNode *GA,
|
||||||
SDValue *InFlag) {
|
SDValue *InFlag, const MVT PtrVT, unsigned ReturnReg) {
|
||||||
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
|
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
|
||||||
DebugLoc dl = GA->getDebugLoc();
|
DebugLoc dl = GA->getDebugLoc();
|
||||||
SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(),
|
SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(),
|
||||||
@ -4753,11 +4753,13 @@ GetTLSADDR(SelectionDAG &DAG, SDValue Chain, GlobalAddressSDNode *GA,
|
|||||||
GA->getOffset());
|
GA->getOffset());
|
||||||
if (InFlag) {
|
if (InFlag) {
|
||||||
SDValue Ops[] = { Chain, TGA, *InFlag };
|
SDValue Ops[] = { Chain, TGA, *InFlag };
|
||||||
return DAG.getNode(X86ISD::TLSADDR, dl, NodeTys, Ops, 3);
|
Chain = DAG.getNode(X86ISD::TLSADDR, dl, NodeTys, Ops, 3);
|
||||||
} else {
|
} else {
|
||||||
SDValue Ops[] = { Chain, TGA };
|
SDValue Ops[] = { Chain, TGA };
|
||||||
return DAG.getNode(X86ISD::TLSADDR, dl, NodeTys, Ops, 2);
|
Chain = DAG.getNode(X86ISD::TLSADDR, dl, NodeTys, Ops, 2);
|
||||||
}
|
}
|
||||||
|
SDValue Flag = Chain.getValue(1);
|
||||||
|
return DAG.getCopyFromReg(Chain, dl, ReturnReg, PtrVT, Flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 32 bit
|
// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 32 bit
|
||||||
@ -4772,42 +4774,14 @@ LowerToTLSGeneralDynamicModel32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
|
|||||||
PtrVT), InFlag);
|
PtrVT), InFlag);
|
||||||
InFlag = Chain.getValue(1);
|
InFlag = Chain.getValue(1);
|
||||||
|
|
||||||
Chain = GetTLSADDR(DAG, Chain, GA, &InFlag);
|
return GetTLSADDR(DAG, Chain, GA, &InFlag, PtrVT, X86::EAX);
|
||||||
InFlag = Chain.getValue(1);
|
|
||||||
|
|
||||||
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
|
|
||||||
SDValue Ops1[] = { Chain,
|
|
||||||
DAG.getTargetExternalSymbol("___tls_get_addr",
|
|
||||||
PtrVT),
|
|
||||||
DAG.getRegister(X86::EAX, PtrVT),
|
|
||||||
DAG.getRegister(X86::EBX, PtrVT),
|
|
||||||
InFlag };
|
|
||||||
Chain = DAG.getNode(X86ISD::CALL, dl, NodeTys, Ops1, 5);
|
|
||||||
InFlag = Chain.getValue(1);
|
|
||||||
|
|
||||||
return DAG.getCopyFromReg(Chain, dl, X86::EAX, PtrVT, InFlag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit
|
// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit
|
||||||
static SDValue
|
static SDValue
|
||||||
LowerToTLSGeneralDynamicModel64(GlobalAddressSDNode *GA, SelectionDAG &DAG,
|
LowerToTLSGeneralDynamicModel64(GlobalAddressSDNode *GA, SelectionDAG &DAG,
|
||||||
const MVT PtrVT) {
|
const MVT PtrVT) {
|
||||||
SDValue InFlag, Chain;
|
return GetTLSADDR(DAG, DAG.getEntryNode(), GA, NULL, PtrVT, X86::RAX);
|
||||||
DebugLoc dl = GA->getDebugLoc(); // ? function entry point might be better
|
|
||||||
|
|
||||||
Chain = GetTLSADDR(DAG, DAG.getEntryNode(), GA, NULL);
|
|
||||||
InFlag = Chain.getValue(1);
|
|
||||||
|
|
||||||
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
|
|
||||||
SDValue Ops1[] = { Chain,
|
|
||||||
DAG.getTargetExternalSymbol("__tls_get_addr",
|
|
||||||
PtrVT),
|
|
||||||
DAG.getRegister(X86::RDI, PtrVT),
|
|
||||||
InFlag };
|
|
||||||
Chain = DAG.getNode(X86ISD::CALL, dl, NodeTys, Ops1, 4);
|
|
||||||
InFlag = Chain.getValue(1);
|
|
||||||
|
|
||||||
return DAG.getCopyFromReg(Chain, dl, X86::RAX, PtrVT, InFlag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lower ISD::GlobalTLSAddress using the "initial exec" (for no-pic) or
|
// Lower ISD::GlobalTLSAddress using the "initial exec" (for no-pic) or
|
||||||
|
@ -1303,9 +1303,17 @@ def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64i32imm:$src),
|
|||||||
// Thread Local Storage Instructions
|
// Thread Local Storage Instructions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
let hasSideEffects = 1, Defs = [RDI] in
|
// All calls clobber the non-callee saved registers. RSP is marked as
|
||||||
|
// a use to prevent stack-pointer assignments that appear immediately
|
||||||
|
// before calls from potentially appearing dead.
|
||||||
|
let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
|
||||||
|
FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0, ST1,
|
||||||
|
MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
|
||||||
|
XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
|
||||||
|
XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
|
||||||
|
Uses = [RSP] in
|
||||||
def TLS_addr64 : I<0, Pseudo, (outs), (ins i64imm:$sym),
|
def TLS_addr64 : I<0, Pseudo, (outs), (ins i64imm:$sym),
|
||||||
".byte\t0x66; leaq\t${sym:mem}(%rip), %rdi; .word\t0x6666; rex64",
|
".byte\t0x66; leaq\t${sym:mem}(%rip), %rdi; .word\t0x6666; rex64;call\t__tls_get_addr@PLT",
|
||||||
[(X86tlsaddr tglobaltlsaddr:$sym)]>,
|
[(X86tlsaddr tglobaltlsaddr:$sym)]>,
|
||||||
Requires<[In64BitMode]>;
|
Requires<[In64BitMode]>;
|
||||||
|
|
||||||
|
@ -2977,9 +2977,16 @@ def MOV32r0 : I<0x31, MRMInitReg, (outs GR32:$dst), (ins),
|
|||||||
// Thread Local Storage Instructions
|
// Thread Local Storage Instructions
|
||||||
//
|
//
|
||||||
|
|
||||||
let hasSideEffects = 1, Uses = [EBX], Defs = [EAX] in
|
// All calls clobber the non-callee saved registers. ESP is marked as
|
||||||
|
// a use to prevent stack-pointer assignments that appear immediately
|
||||||
|
// before calls from potentially appearing dead.
|
||||||
|
let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0,
|
||||||
|
MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7,
|
||||||
|
XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
|
||||||
|
XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, EFLAGS],
|
||||||
|
Uses = [ESP, EBX] in
|
||||||
def TLS_addr32 : I<0, Pseudo, (outs), (ins i32imm:$sym),
|
def TLS_addr32 : I<0, Pseudo, (outs), (ins i32imm:$sym),
|
||||||
"leal\t${sym:mem}(,%ebx,1), %eax",
|
"leal\t${sym:mem}(,%ebx,1), %eax; call\t___tls_get_addr@PLT",
|
||||||
[(X86tlsaddr tglobaltlsaddr:$sym)]>,
|
[(X86tlsaddr tglobaltlsaddr:$sym)]>,
|
||||||
Requires<[In32BitMode]>;
|
Requires<[In32BitMode]>;
|
||||||
|
|
||||||
|
13
test/CodeGen/X86/2009-04-24.ll
Normal file
13
test/CodeGen/X86/2009-04-24.ll
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
; RUN: llvm-as < %s | llc -march=x86 -mtriple=i386-linux-gnu -regalloc=local -relocation-model=pic > %t
|
||||||
|
; RUN: grep {leal.*TLSGD.*___tls_get_addr} %t
|
||||||
|
; RUN: llvm-as < %s | llc -march=x86-64 -mtriple=x86_64-linux-gnu -regalloc=local -relocation-model=pic > %t2
|
||||||
|
; RUN: grep {leaq.*TLSGD.*__tls_get_addr} %t2
|
||||||
|
; PR/4004
|
||||||
|
|
||||||
|
@i = thread_local global i32 15
|
||||||
|
|
||||||
|
define i32 @f() {
|
||||||
|
entry:
|
||||||
|
%tmp1 = load i32* @i
|
||||||
|
ret i32 %tmp1
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user