[llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp X86AsmPrinter.cpp X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td

Lauro Ramos Venancio lauro.venancio at gmail.com
Fri Apr 20 14:38:41 PDT 2007



Changes in directory llvm/lib/Target/X86:

X86ATTAsmPrinter.cpp updated: 1.100 -> 1.101
X86AsmPrinter.cpp updated: 1.239 -> 1.240
X86ISelLowering.cpp updated: 1.393 -> 1.394
X86ISelLowering.h updated: 1.98 -> 1.99
X86InstrInfo.td updated: 1.302 -> 1.303
---
Log message:

Implement "general dynamic", "initial exec" and "local exec" TLS models for
X86 32 bits.


---
Diffs of the changes:  (+122 -6)

 X86ATTAsmPrinter.cpp |   16 +++++++++-
 X86AsmPrinter.cpp    |   10 ++++--
 X86ISelLowering.cpp  |   75 +++++++++++++++++++++++++++++++++++++++++++++++++++
 X86ISelLowering.h    |    5 ++-
 X86InstrInfo.td      |   22 ++++++++++++++
 5 files changed, 122 insertions(+), 6 deletions(-)


Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp
diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.100 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.101
--- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.100	Tue Apr 17 12:21:52 2007
+++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp	Fri Apr 20 16:38:10 2007
@@ -272,9 +272,13 @@
   case MachineOperand::MO_GlobalAddress: {
     bool isCallOp = Modifier && !strcmp(Modifier, "call");
     bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
-    if (!isMemOp && !isCallOp) O << '$';
 
     GlobalValue *GV = MO.getGlobal();
+    GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV);
+    bool isThreadLocal = GVar && GVar->isThreadLocal();
+
+    if (!isMemOp && !isCallOp && !isThreadLocal) O << '$';
+
     std::string Name = Mang->getValueName(GV);
     X86SharedAsmPrinter::decorateName(Name, GV);
     
@@ -328,7 +332,15 @@
     else if (Offset < 0)
       O << Offset;
 
-    if (isMemOp) {
+    if (isThreadLocal) {
+      if (TM.getRelocationModel() == Reloc::PIC_)
+        O << "@TLSGD"; // general dynamic TLS model
+      else
+        if (GV->isDeclaration())
+          O << "@INDNTPOFF"; // initial exec TLS model
+        else
+          O << "@NTPOFF"; // local exec TLS model
+    } else if (isMemOp) {
       if (printGOT(TM, Subtarget)) {
         if (Subtarget->GVRequiresExtraLoad(GV, TM, false))
           O << "@GOT";


Index: llvm/lib/Target/X86/X86AsmPrinter.cpp
diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.239 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.240
--- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.239	Tue Apr 17 12:21:52 2007
+++ llvm/lib/Target/X86/X86AsmPrinter.cpp	Fri Apr 20 16:38:10 2007
@@ -171,7 +171,7 @@
         }
       }
       
-      if (!I->hasSection() &&
+      if (!I->hasSection() && !I->isThreadLocal() &&
           (I->hasInternalLinkage() || I->hasWeakLinkage() ||
            I->hasLinkOnceLinkage())) {
         if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
@@ -256,9 +256,13 @@
         SwitchToDataSection(SectionName.c_str());
       } else {
         if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection())
-          SwitchToDataSection(TAI->getBSSSection(), I);
+          SwitchToDataSection(I->isThreadLocal() ? TAI->getTLSBSSSection() :
+                              TAI->getBSSSection(), I);
         else if (!I->isConstant())
-          SwitchToDataSection(TAI->getDataSection(), I);
+          SwitchToDataSection(I->isThreadLocal() ? TAI->getTLSDataSection() :
+                              TAI->getDataSection(), I);
+        else if (I->isThreadLocal())
+          SwitchToDataSection(TAI->getTLSDataSection());
         else {
           // Read-only data.
           bool HasReloc = C->ContainsRelocations();


Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.393 llvm/lib/Target/X86/X86ISelLowering.cpp:1.394
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.393	Tue Apr 17 14:34:00 2007
+++ llvm/lib/Target/X86/X86ISelLowering.cpp	Fri Apr 20 16:38:10 2007
@@ -20,6 +20,7 @@
 #include "llvm/CallingConv.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/GlobalVariable.h"
 #include "llvm/Function.h"
 #include "llvm/Intrinsics.h"
 #include "llvm/ADT/VectorExtras.h"
@@ -200,6 +201,7 @@
   setOperationAction(ISD::ConstantPool    , MVT::i32  , Custom);
   setOperationAction(ISD::JumpTable       , MVT::i32  , Custom);
   setOperationAction(ISD::GlobalAddress   , MVT::i32  , Custom);
+  setOperationAction(ISD::GlobalTLSAddress, MVT::i32  , Custom);
   setOperationAction(ISD::ExternalSymbol  , MVT::i32  , Custom);
   if (Subtarget->is64Bit()) {
     setOperationAction(ISD::ConstantPool  , MVT::i64  , Custom);
@@ -2943,6 +2945,76 @@
   return Result;
 }
 
+// Lower ISD::GlobalTLSAddress using the "general dynamic" model
+static SDOperand
+LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
+                              const MVT::ValueType PtrVT) {
+  SDOperand InFlag;
+  SDOperand Chain = DAG.getCopyToReg(DAG.getEntryNode(), X86::EBX,
+                                     DAG.getNode(X86ISD::GlobalBaseReg,
+                                                 PtrVT), InFlag);
+  InFlag = Chain.getValue(1);
+
+  // emit leal symbol at TLSGD(,%ebx,1), %eax
+  SDVTList NodeTys = DAG.getVTList(PtrVT, MVT::Other, MVT::Flag);
+  SDOperand TGA = DAG.getTargetGlobalAddress(GA->getGlobal(),
+                                             GA->getValueType(0),
+                                             GA->getOffset());
+  SDOperand Ops[] = { Chain,  TGA, InFlag };
+  SDOperand Result = DAG.getNode(X86ISD::TLSADDR, NodeTys, Ops, 3);
+  InFlag = Result.getValue(2);
+  Chain = Result.getValue(1);
+
+  // call ___tls_get_addr. This function receives its argument in
+  // the register EAX.
+  Chain = DAG.getCopyToReg(Chain, X86::EAX, Result, InFlag);
+  InFlag = Chain.getValue(1);
+
+  NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
+  SDOperand Ops1[] = { Chain,
+                      DAG.getTargetExternalSymbol("___tls_get_addr",
+                                                  PtrVT),
+                      DAG.getRegister(X86::EAX, PtrVT),
+                      DAG.getRegister(X86::EBX, PtrVT),
+                      InFlag };
+  Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops1, 5);
+  InFlag = Chain.getValue(1);
+
+  return DAG.getCopyFromReg(Chain, X86::EAX, PtrVT, InFlag);
+}
+
+// Lower ISD::GlobalTLSAddress using the "initial exec" (for no-pic) or
+// "local exec" model.
+static SDOperand
+LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
+                         const MVT::ValueType PtrVT) {
+  // Get the Thread Pointer
+  SDOperand ThreadPointer = DAG.getNode(X86ISD::THREAD_POINTER, PtrVT);
+  // emit "addl x at ntpoff,%eax" (local exec) or "addl x at indntpoff,%eax" (initial
+  // exec)
+  SDOperand TGA = DAG.getTargetGlobalAddress(GA->getGlobal(),
+                                             GA->getValueType(0),
+                                             GA->getOffset());
+  SDOperand Offset = DAG.getNode(X86ISD::Wrapper, PtrVT, TGA);
+  // The address of the thread local variable is the add of the thread
+  // pointer with the offset of the variable.
+  return DAG.getNode(ISD::ADD, PtrVT, ThreadPointer, Offset);
+}
+
+SDOperand
+X86TargetLowering::LowerGlobalTLSAddress(SDOperand Op, SelectionDAG &DAG) {
+  // TODO: implement the "local dynamic" model
+  // TODO: implement the "initial exec"model for pic executables 
+  assert(!Subtarget->is64Bit() && "TLS not implemented for X86_64");
+  GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
+  // If the relocation model is PIC, use the "General Dynamic" TLS Model,
+  // otherwise use the "Local Exec"TLS Model
+  if (getTargetMachine().getRelocationModel() == Reloc::PIC_)
+    return LowerToTLSGeneralDynamicModel(GA, DAG, getPointerTy());
+  else
+    return LowerToTLSExecModel(GA, DAG, getPointerTy());
+}
+
 SDOperand
 X86TargetLowering::LowerExternalSymbol(SDOperand Op, SelectionDAG &DAG) {
   const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
@@ -4022,6 +4094,7 @@
   case ISD::SCALAR_TO_VECTOR:   return LowerSCALAR_TO_VECTOR(Op, DAG);
   case ISD::ConstantPool:       return LowerConstantPool(Op, DAG);
   case ISD::GlobalAddress:      return LowerGlobalAddress(Op, DAG);
+  case ISD::GlobalTLSAddress:   return LowerGlobalTLSAddress(Op, DAG);
   case ISD::ExternalSymbol:     return LowerExternalSymbol(Op, DAG);
   case ISD::SHL_PARTS:
   case ISD::SRA_PARTS:
@@ -4090,6 +4163,8 @@
   case X86ISD::PINSRW:             return "X86ISD::PINSRW";
   case X86ISD::FMAX:               return "X86ISD::FMAX";
   case X86ISD::FMIN:               return "X86ISD::FMIN";
+  case X86ISD::TLSADDR:            return "X86ISD::TLSADDR";
+  case X86ISD::THREAD_POINTER:     return "X86ISD::THREAD_POINTER";
   }
 }
 


Index: llvm/lib/Target/X86/X86ISelLowering.h
diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.98 llvm/lib/Target/X86/X86ISelLowering.h:1.99
--- llvm/lib/Target/X86/X86ISelLowering.h:1.98	Tue Apr 17 04:20:00 2007
+++ llvm/lib/Target/X86/X86ISelLowering.h	Fri Apr 20 16:38:10 2007
@@ -176,7 +176,9 @@
 
       /// FMAX, FMIN - Floating point max and min.
       ///
-      FMAX, FMIN
+      FMAX, FMIN,
+      // Thread Local Storage
+      TLSADDR, THREAD_POINTER
     };
   }
 
@@ -386,6 +388,7 @@
     SDOperand LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerConstantPool(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG);
+    SDOperand LowerGlobalTLSAddress(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerExternalSymbol(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerShift(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG);


Index: llvm/lib/Target/X86/X86InstrInfo.td
diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.302 llvm/lib/Target/X86/X86InstrInfo.td:1.303
--- llvm/lib/Target/X86/X86InstrInfo.td:1.302	Tue Apr 17 04:20:00 2007
+++ llvm/lib/Target/X86/X86InstrInfo.td	Fri Apr 20 16:38:10 2007
@@ -47,6 +47,10 @@
 
 def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
 
+def SDT_X86TLSADDR : SDTypeProfile<1, 1, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
+
+def SDT_X86TLSTP : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
+
 def X86shld    : SDNode<"X86ISD::SHLD",     SDTIntShiftDOp>;
 def X86shrd    : SDNode<"X86ISD::SHRD",     SDTIntShiftDOp>;
 
@@ -87,6 +91,11 @@
 def X86Wrapper    : SDNode<"X86ISD::Wrapper",     SDTX86Wrapper>;
 def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP",  SDTX86Wrapper>;
 
+def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
+                        [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
+def X86TLStp : SDNode<"X86ISD::THREAD_POINTER", SDT_X86TLSTP, []>;
+
+
 //===----------------------------------------------------------------------===//
 // X86 Operand Definitions.
 //
@@ -2449,6 +2458,19 @@
                 "mov{l} {$src, $dst|$dst, $src}", []>;
 
 //===----------------------------------------------------------------------===//
+// Thread Local Storage Instructions
+//
+
+def TLS_addr : I<0, Pseudo, (ops GR32:$dst, i32imm:$sym),
+               "leal $sym(,%ebx,1), $dst",
+               [(set GR32:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>,
+               Imp<[EBX],[]>;
+
+def TLS_tp : I<0, Pseudo, (ops GR32:$dst),
+               "movl %gs:0, $dst",
+               [(set GR32:$dst, X86TLStp)]>;
+
+//===----------------------------------------------------------------------===//
 // DWARF Pseudo Instructions
 //
 






More information about the llvm-commits mailing list