Lower TLS_addr32 and TLS_addr64.
authorRafael Espindola <rafael.espindola@gmail.com>
Sat, 27 Nov 2010 20:43:02 +0000 (20:43 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Sat, 27 Nov 2010 20:43:02 +0000 (20:43 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120225 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86ISelLowering.h
lib/Target/X86/X86InstrCompiler.td
test/CodeGen/X86/2009-04-24.ll
test/CodeGen/X86/2009-12-11-TLSNoRedZone.ll
test/CodeGen/X86/tls-pic.ll

index 6793b70dd57dde024b70beb3a0a21f4cfbceac8b..91768d4b9e033bc9bfd160c632d6363154b97005 100644 (file)
@@ -9922,6 +9922,44 @@ X86TargetLowering::EmitLoweredTLSCall(MachineInstr *MI,
   return BB;
 }
 
+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 {
@@ -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:
index fb8d09a1fde6592c3eaecdfc10d01fc266c17fc1..f2f19485be69d3ed385113b9d7d30dc0d60d1961 100644 (file)
@@ -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;
index b299b9012f5bcd9397bd2436ed183489fdad9bcd..447ac815ca03678aceff5a0de7812e2421449d65 100644 (file)
@@ -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]>;
 
index 757042e5be42e74814ac0ba39d49b1a391b56f9f..dd8823574cde5706813b3ed8bbefe76dcff77c0e 100644 (file)
@@ -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
index f7ba661c4f75c08382346a2d416d807412eae6c8..823e0ca465efa8549e9bdd972c66bc3f1eafb1b5 100644 (file)
@@ -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"
index 4cad8376d8d9ddd2019f220e317a48aec77aa866..b83416d4b32b84af0b7074bd675c63cbe0890146 100644 (file)
@@ -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