diff options
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 41 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.h | 3 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrCompiler.td | 15 | ||||
-rw-r--r-- | test/CodeGen/X86/2009-04-24.ll | 3 | ||||
-rw-r--r-- | test/CodeGen/X86/2009-12-11-TLSNoRedZone.ll | 2 | ||||
-rw-r--r-- | test/CodeGen/X86/tls-pic.ll | 16 |
6 files changed, 61 insertions, 19 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 6793b70..91768d4 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -9923,6 +9923,44 @@ X86TargetLowering::EmitLoweredTLSCall(MachineInstr *MI, } MachineBasicBlock * +X86TargetLowering::emitLoweredTLSAddr(MachineInstr *MI, + MachineBasicBlock *BB) const { + const X86InstrInfo *TII + = static_cast<const X86InstrInfo*>(getTargetMachine().getInstrInfo()); + DebugLoc DL = MI->getDebugLoc(); + if (Subtarget->is64Bit()) { + BuildMI(*BB, MI, DL, TII->get(X86::DATA16_PREFIX)); + MachineInstrBuilder MIB = BuildMI(*BB, MI, DL, TII->get(X86::LEA64r), + X86::RDI); + X86AddressMode Addr; + Addr.GV = MI->getOperand(3).getGlobal(); + Addr.GVOpFlags = MI->getOperand(3).getTargetFlags(); + Addr.Base.Reg = X86::RIP; + addFullAddress(MIB, Addr); + BuildMI(*BB, MI, DL, TII->get(X86::DATA16_PREFIX)); + BuildMI(*BB, MI, DL, TII->get(X86::DATA16_PREFIX)); + BuildMI(*BB, MI, DL, TII->get(X86::REX64_PREFIX)); + BuildMI(*BB, MI, DL, TII->get(X86::CALL64pcrel32)) + .addExternalSymbol("__tls_get_addr", X86II::MO_PLT) + .addReg(X86::RDI, RegState::Implicit); + } else { + MachineInstrBuilder MIB = BuildMI(*BB, MI, DL, TII->get(X86::LEA32r), + X86::EAX); + X86AddressMode Addr; + Addr.GV = MI->getOperand(3).getGlobal(); + Addr.GVOpFlags = MI->getOperand(3).getTargetFlags(); + Addr.IndexReg = X86::EBX; + addFullAddress(MIB, Addr); + BuildMI(*BB, MI, DL, TII->get(X86::CALLpcrel32)) + .addExternalSymbol("___tls_get_addr", X86II::MO_PLT) + .addReg(X86::EAX, RegState::Implicit); + } + + MI->eraseFromParent(); // The pseudo instruction is gone now. + return BB; +} + +MachineBasicBlock * X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const { switch (MI->getOpcode()) { @@ -9932,6 +9970,9 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, case X86::TLSCall_32: case X86::TLSCall_64: return EmitLoweredTLSCall(MI, BB); + case X86::TLS_addr32: + case X86::TLS_addr64: + return emitLoweredTLSAddr(MI, BB); case X86::CMOV_GR8: case X86::CMOV_FR32: case X86::CMOV_FR64: diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index fb8d09a..f2f1948 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -871,6 +871,9 @@ namespace llvm { MachineBasicBlock *EmitLoweredTLSCall(MachineInstr *MI, MachineBasicBlock *BB) const; + MachineBasicBlock *emitLoweredTLSAddr(MachineInstr *MI, + MachineBasicBlock *BB) const; + /// Emit nodes that will be selected as "test Op0,Op0", or something /// equivalent, for use with the given x86 condition code. SDValue EmitTest(SDValue Op0, unsigned X86CC, SelectionDAG &DAG) const; diff --git a/lib/Target/X86/X86InstrCompiler.td b/lib/Target/X86/X86InstrCompiler.td index b299b90..447ac81 100644 --- a/lib/Target/X86/X86InstrCompiler.td +++ b/lib/Target/X86/X86InstrCompiler.td @@ -242,10 +242,10 @@ 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] in + Uses = [ESP], + usesCustomInserter = 1 in def TLS_addr32 : I<0, Pseudo, (outs), (ins i32mem:$sym), - "leal\t$sym, %eax; " - "call\t___tls_get_addr@PLT", + "# TLS_addr32", [(X86tlsaddr tls32addr:$sym)]>, Requires<[In32BitMode]>; @@ -257,13 +257,10 @@ let Defs = [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, 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 + Uses = [RSP], + usesCustomInserter = 1 in def TLS_addr64 : I<0, Pseudo, (outs), (ins i64mem:$sym), - ".byte\t0x66; " - "leaq\t$sym(%rip), %rdi; " - ".word\t0x6666; " - "rex64; " - "call\t__tls_get_addr@PLT", + "# TLS_addr64", [(X86tlsaddr tls64addr:$sym)]>, Requires<[In64BitMode]>; diff --git a/test/CodeGen/X86/2009-04-24.ll b/test/CodeGen/X86/2009-04-24.ll index 757042e..dd88235 100644 --- a/test/CodeGen/X86/2009-04-24.ll +++ b/test/CodeGen/X86/2009-04-24.ll @@ -1,5 +1,6 @@ ; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu -regalloc=fast -relocation-model=pic > %t2 -; RUN: grep {leaq.*TLSGD.*__tls_get_addr} %t2 +; RUN: grep {leaq.*TLSGD} %t2 +; RUN; grep {__tls_get_addr} %t2 ; PR4004 @i = thread_local global i32 15 diff --git a/test/CodeGen/X86/2009-12-11-TLSNoRedZone.ll b/test/CodeGen/X86/2009-12-11-TLSNoRedZone.ll index f7ba661..823e0ca 100644 --- a/test/CodeGen/X86/2009-12-11-TLSNoRedZone.ll +++ b/test/CodeGen/X86/2009-12-11-TLSNoRedZone.ll @@ -21,7 +21,7 @@ define void @leaf() nounwind { ; CHECK: leaf: ; CHECK-NOT: -8(%rsp) ; CHECK: leaq link_ptr@TLSGD -; CHECK: call __tls_get_addr@PLT +; CHECK: callq __tls_get_addr@PLT "file foo2.c, line 14, bb1": %p = alloca %test*, align 8 ; <%test**> [#uses=4] br label %"file foo2.c, line 14, bb2" diff --git a/test/CodeGen/X86/tls-pic.ll b/test/CodeGen/X86/tls-pic.ll index 4cad837..b83416d 100644 --- a/test/CodeGen/X86/tls-pic.ll +++ b/test/CodeGen/X86/tls-pic.ll @@ -11,11 +11,11 @@ entry: ; X32: f1: ; X32: leal i@TLSGD(,%ebx), %eax -; X32: call ___tls_get_addr@PLT +; X32: calll ___tls_get_addr@PLT ; X64: f1: ; X64: leaq i@TLSGD(%rip), %rdi -; X64: call __tls_get_addr@PLT +; X64: callq __tls_get_addr@PLT @i2 = external thread_local global i32 @@ -27,11 +27,11 @@ entry: ; X32: f2: ; X32: leal i@TLSGD(,%ebx), %eax -; X32: call ___tls_get_addr@PLT +; X32: calll ___tls_get_addr@PLT ; X64: f2: ; X64: leaq i@TLSGD(%rip), %rdi -; X64: call __tls_get_addr@PLT +; X64: callq __tls_get_addr@PLT @@ -43,11 +43,11 @@ entry: ; X32: f3: ; X32: leal i@TLSGD(,%ebx), %eax -; X32: call ___tls_get_addr@PLT +; X32: calll ___tls_get_addr@PLT ; X64: f3: ; X64: leaq i@TLSGD(%rip), %rdi -; X64: call __tls_get_addr@PLT +; X64: callq __tls_get_addr@PLT define i32* @f4() nounwind { @@ -57,11 +57,11 @@ entry: ; X32: f4: ; X32: leal i@TLSGD(,%ebx), %eax -; X32: call ___tls_get_addr@PLT +; X32: calll ___tls_get_addr@PLT ; X64: f4: ; X64: leaq i@TLSGD(%rip), %rdi -; X64: call __tls_get_addr@PLT +; X64: callq __tls_get_addr@PLT |