[llvm-commits] CVS: llvm/lib/Target/ARM/ARMAsmPrinter.cpp ARMConstantPoolValue.cpp ARMConstantPoolValue.h ARMISelLowering.cpp ARMISelLowering.h ARMInstrInfo.td ARMInstrThumb.td ARMTargetAsmInfo.cpp

Lauro Ramos Venancio lauro.venancio at gmail.com
Fri Apr 27 06:55:05 PDT 2007



Changes in directory llvm/lib/Target/ARM:

ARMAsmPrinter.cpp updated: 1.67 -> 1.68
ARMConstantPoolValue.cpp updated: 1.3 -> 1.4
ARMConstantPoolValue.h updated: 1.3 -> 1.4
ARMISelLowering.cpp updated: 1.46 -> 1.47
ARMISelLowering.h updated: 1.14 -> 1.15
ARMInstrInfo.td updated: 1.96 -> 1.97
ARMInstrThumb.td updated: 1.23 -> 1.24
ARMTargetAsmInfo.cpp updated: 1.14 -> 1.15
---
Log message:

ARM TLS: implement "general dynamic", "initial exec" and "local exec" models.


---
Diffs of the changes:  (+157 -13)

 ARMAsmPrinter.cpp        |   16 ++++++--
 ARMConstantPoolValue.cpp |   19 ++++++----
 ARMConstantPoolValue.h   |    8 +++-
 ARMISelLowering.cpp      |   89 +++++++++++++++++++++++++++++++++++++++++++++++
 ARMISelLowering.h        |    9 ++++
 ARMInstrInfo.td          |   15 +++++++
 ARMInstrThumb.td         |   12 ++++++
 ARMTargetAsmInfo.cpp     |    2 +
 8 files changed, 157 insertions(+), 13 deletions(-)


Index: llvm/lib/Target/ARM/ARMAsmPrinter.cpp
diff -u llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.67 llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.68
--- llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.67	Wed Apr 25 09:50:40 2007
+++ llvm/lib/Target/ARM/ARMAsmPrinter.cpp	Fri Apr 27 08:54:47 2007
@@ -134,10 +134,14 @@
       } else
         O << Name;
       if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
-      if (ACPV->getPCAdjustment() != 0)
+      if (ACPV->getPCAdjustment() != 0) {
         O << "-(" << TAI->getPrivateGlobalPrefix() << "PC"
           << utostr(ACPV->getLabelId())
-          << "+" << (unsigned)ACPV->getPCAdjustment() << ")";
+          << "+" << (unsigned)ACPV->getPCAdjustment();
+         if (ACPV->mustAddCurrentAddress())
+           O << "-.";
+         O << ")";
+      }
       O << "\n";
 
       // If the constant pool value is a extern weak symbol, remember to emit
@@ -869,9 +873,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/ARM/ARMConstantPoolValue.cpp
diff -u llvm/lib/Target/ARM/ARMConstantPoolValue.cpp:1.3 llvm/lib/Target/ARM/ARMConstantPoolValue.cpp:1.4
--- llvm/lib/Target/ARM/ARMConstantPoolValue.cpp:1.3	Sat Apr 21 19:04:12 2007
+++ llvm/lib/Target/ARM/ARMConstantPoolValue.cpp	Fri Apr 27 08:54:47 2007
@@ -20,18 +20,20 @@
 ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv, unsigned id,
                                            ARMCP::ARMCPKind k,
                                            unsigned char PCAdj,
-                                           const char *Modif)
+                                           const char *Modif,
+                                           bool AddCA)
   : MachineConstantPoolValue((const Type*)gv->getType()),
     GV(gv), S(NULL), LabelId(id), Kind(k), PCAdjust(PCAdj),
-    Modifier(Modif) {}
+    Modifier(Modif), AddCurrentAddress(AddCA) {}
 
 ARMConstantPoolValue::ARMConstantPoolValue(const char *s, unsigned id,
                                            ARMCP::ARMCPKind k,
                                            unsigned char PCAdj,
-                                           const char *Modif)
+                                           const char *Modif,
+                                           bool AddCA)
   : MachineConstantPoolValue((const Type*)Type::Int32Ty),
     GV(NULL), S(s), LabelId(id), Kind(k), PCAdjust(PCAdj),
-    Modifier(Modif) {}
+    Modifier(Modif), AddCurrentAddress(AddCA) {}
 
 ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv,
                                            ARMCP::ARMCPKind k,
@@ -78,6 +80,11 @@
   if (isNonLazyPointer()) O << "$non_lazy_ptr";
   else if (isStub()) O << "$stub";
   if (Modifier) O << "(" << Modifier << ")";
-  if (PCAdjust != 0) O << "-(LPIC" << LabelId << "+"
-                       << (unsigned)PCAdjust << ")";
+  if (PCAdjust != 0) {
+    O << "-(LPIC" << LabelId << "+"
+      << (unsigned)PCAdjust;
+    if (AddCurrentAddress)
+      O << "-.";
+    O << ")";
+  }
 }


Index: llvm/lib/Target/ARM/ARMConstantPoolValue.h
diff -u llvm/lib/Target/ARM/ARMConstantPoolValue.h:1.3 llvm/lib/Target/ARM/ARMConstantPoolValue.h:1.4
--- llvm/lib/Target/ARM/ARMConstantPoolValue.h:1.3	Sat Apr 21 19:04:12 2007
+++ llvm/lib/Target/ARM/ARMConstantPoolValue.h	Fri Apr 27 08:54:47 2007
@@ -37,14 +37,17 @@
   unsigned char PCAdjust;  // Extra adjustment if constantpool is pc relative.
                            // 8 for ARM, 4 for Thumb.
   const char *Modifier;    // GV modifier i.e. (&GV(modifier)-(LPIC+8))
+  bool AddCurrentAddress;
 
 public:
   ARMConstantPoolValue(GlobalValue *gv, unsigned id,
                        ARMCP::ARMCPKind Kind = ARMCP::CPValue,
-                       unsigned char PCAdj = 0, const char *Modifier = NULL);
+                       unsigned char PCAdj = 0, const char *Modifier = NULL,
+                       bool AddCurrentAddress = false);
   ARMConstantPoolValue(const char *s, unsigned id,
                        ARMCP::ARMCPKind Kind = ARMCP::CPValue,
-                       unsigned char PCAdj = 0, const char *Modifier = NULL);
+                       unsigned char PCAdj = 0, const char *Modifier = NULL,
+                       bool AddCurrentAddress = false);
   ARMConstantPoolValue(GlobalValue *GV, ARMCP::ARMCPKind Kind,
                        const char *Modifier);
 
@@ -53,6 +56,7 @@
   const char *getSymbol() const { return S; }
   const char *getModifier() const { return Modifier; }
   bool hasModifier() const { return Modifier != NULL; }
+  bool mustAddCurrentAddress() const { return AddCurrentAddress; }
   unsigned getLabelId() const { return LabelId; }
   bool isNonLazyPointer() const { return Kind == ARMCP::CPNonLazyPtr; }
   bool isStub() const { return Kind == ARMCP::CPStub; }


Index: llvm/lib/Target/ARM/ARMISelLowering.cpp
diff -u llvm/lib/Target/ARM/ARMISelLowering.cpp:1.46 llvm/lib/Target/ARM/ARMISelLowering.cpp:1.47
--- llvm/lib/Target/ARM/ARMISelLowering.cpp:1.46	Fri Apr 27 03:15:43 2007
+++ llvm/lib/Target/ARM/ARMISelLowering.cpp	Fri Apr 27 08:54:47 2007
@@ -186,6 +186,7 @@
   setOperationAction(ISD::GlobalAddress, MVT::i32,   Custom);
   setOperationAction(ISD::ConstantPool,  MVT::i32,   Custom);
   setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom);
+  setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
 
   // Expand mem operations genericly.
   setOperationAction(ISD::MEMSET          , MVT::Other, Expand);
@@ -293,6 +294,8 @@
       
   case ARMISD::FMRRD:         return "ARMISD::FMRRD";
   case ARMISD::FMDRR:         return "ARMISD::FMDRR";
+
+  case ARMISD::THREAD_POINTER:return "ARMISD::THREAD_POINTER";
   }
 }
 
@@ -701,6 +704,91 @@
   return DAG.getNode(ARMISD::Wrapper, MVT::i32, Res);
 }
 
+// Lower ISD::GlobalTLSAddress using the "general dynamic" model
+SDOperand
+ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
+                                                 SelectionDAG &DAG) {
+  MVT::ValueType PtrVT = getPointerTy();
+  unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
+  ARMConstantPoolValue *CPV =
+    new ARMConstantPoolValue(GA->getGlobal(), ARMPCLabelIndex, ARMCP::CPValue,
+                             PCAdj, "tlsgd", true);
+  SDOperand Argument = DAG.getTargetConstantPool(CPV, PtrVT, 2);
+  Argument = DAG.getNode(ARMISD::Wrapper, MVT::i32, Argument);
+  Argument = DAG.getLoad(PtrVT, DAG.getEntryNode(), Argument, NULL, 0);
+  SDOperand Chain = Argument.getValue(1);
+
+  SDOperand PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32);
+  Argument = DAG.getNode(ARMISD::PIC_ADD, PtrVT, Argument, PICLabel);
+
+  // call __tls_get_addr.
+  ArgListTy Args;
+  ArgListEntry Entry;
+  Entry.Node = Argument;
+  Entry.Ty = (const Type *) Type::Int32Ty;
+  Args.push_back(Entry);
+  std::pair<SDOperand, SDOperand> CallResult =
+    LowerCallTo(Chain, (const Type *) Type::Int32Ty, false, false,
+                CallingConv::C, false,
+                DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG);
+  return CallResult.first;
+}
+
+// Lower ISD::GlobalTLSAddress using the "initial exec" or
+// "local exec" model.
+SDOperand
+ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA,
+                                            SelectionDAG &DAG) {
+  GlobalValue *GV = GA->getGlobal();
+  SDOperand Offset;
+  SDOperand Chain = DAG.getEntryNode();
+  MVT::ValueType PtrVT = getPointerTy();
+  // Get the Thread Pointer
+  SDOperand ThreadPointer = DAG.getNode(ARMISD::THREAD_POINTER, PtrVT);
+
+  if (GV->isDeclaration()){
+    // initial exec model
+    unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
+    ARMConstantPoolValue *CPV =
+      new ARMConstantPoolValue(GA->getGlobal(), ARMPCLabelIndex, ARMCP::CPValue,
+                               PCAdj, "gottpoff", true);
+    Offset = DAG.getTargetConstantPool(CPV, PtrVT, 2);
+    Offset = DAG.getNode(ARMISD::Wrapper, MVT::i32, Offset);
+    Offset = DAG.getLoad(PtrVT, Chain, Offset, NULL, 0);
+    Chain = Offset.getValue(1);
+
+    SDOperand PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32);
+    Offset = DAG.getNode(ARMISD::PIC_ADD, PtrVT, Offset, PICLabel);
+
+    Offset = DAG.getLoad(PtrVT, Chain, Offset, NULL, 0);
+  } else {
+    // local exec model
+    ARMConstantPoolValue *CPV =
+      new ARMConstantPoolValue(GV, ARMCP::CPValue, "tpoff");
+    Offset = DAG.getTargetConstantPool(CPV, PtrVT, 2);
+    Offset = DAG.getNode(ARMISD::Wrapper, MVT::i32, Offset);
+    Offset = DAG.getLoad(PtrVT, Chain, Offset, NULL, 0);
+  }
+
+  // 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
+ARMTargetLowering::LowerGlobalTLSAddress(SDOperand Op, SelectionDAG &DAG) {
+  // TODO: implement the "local dynamic" model
+  assert(Subtarget->isTargetELF() &&
+         "TLS not implemented for non-ELF targets");
+  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);
+  else
+    return LowerToTLSExecModels(GA, DAG);
+}
+
 SDOperand ARMTargetLowering::LowerGlobalAddressELF(SDOperand Op,
                                                    SelectionDAG &DAG) {
   MVT::ValueType PtrVT = getPointerTy();
@@ -1249,6 +1337,7 @@
   case ISD::GlobalAddress:
     return Subtarget->isTargetDarwin() ? LowerGlobalAddressDarwin(Op, DAG) :
       LowerGlobalAddressELF(Op, DAG);
+  case ISD::GlobalTLSAddress:   return LowerGlobalTLSAddress(Op, DAG);
   case ISD::CALL:          return LowerCALL(Op, DAG);
   case ISD::RET:           return LowerRET(Op, DAG);
   case ISD::SELECT_CC:     return LowerSELECT_CC(Op, DAG, Subtarget);


Index: llvm/lib/Target/ARM/ARMISelLowering.h
diff -u llvm/lib/Target/ARM/ARMISelLowering.h:1.14 llvm/lib/Target/ARM/ARMISelLowering.h:1.15
--- llvm/lib/Target/ARM/ARMISelLowering.h:1.14	Sat Apr 21 19:04:12 2007
+++ llvm/lib/Target/ARM/ARMISelLowering.h	Fri Apr 27 08:54:47 2007
@@ -63,7 +63,9 @@
       RRX,          // V = RRX X, Flag     -> srl X, 1 + shift in carry flag.
       
       FMRRD,        // double to two gprs.
-      FMDRR         // Two gprs to double.
+      FMDRR,         // Two gprs to double.
+
+      THREAD_POINTER
     };
   }
 
@@ -125,6 +127,11 @@
     SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerGlobalAddressDarwin(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerGlobalAddressELF(SDOperand Op, SelectionDAG &DAG);
+    SDOperand LowerGlobalTLSAddress(SDOperand Op, SelectionDAG &DAG);
+    SDOperand LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
+                                            SelectionDAG &DAG);
+    SDOperand LowerToTLSExecModels(GlobalAddressSDNode *GA,
+                                       SelectionDAG &DAG);
     SDOperand LowerGLOBAL_OFFSET_TABLE(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerBR_JT(SDOperand Op, SelectionDAG &DAG);


Index: llvm/lib/Target/ARM/ARMInstrInfo.td
diff -u llvm/lib/Target/ARM/ARMInstrInfo.td:1.96 llvm/lib/Target/ARM/ARMInstrInfo.td:1.97
--- llvm/lib/Target/ARM/ARMInstrInfo.td:1.96	Tue Apr 17 17:39:58 2007
+++ llvm/lib/Target/ARM/ARMInstrInfo.td	Fri Apr 27 08:54:47 2007
@@ -39,6 +39,8 @@
 def SDT_ARMPICAdd  : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
                                           SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
 
+def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
+
 // Node definitions.
 def ARMWrapper       : SDNode<"ARMISD::Wrapper",     SDTIntUnaryOp>;
 def ARMWrapperJT     : SDNode<"ARMISD::WrapperJT",   SDTIntBinOp>;
@@ -79,6 +81,8 @@
 def ARMsra_flag      : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
 def ARMrrx           : SDNode<"ARMISD::RRX"     , SDTIntUnaryOp, [SDNPInFlag ]>;
 
+def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
+
 //===----------------------------------------------------------------------===//
 // ARM Instruction Predicate Definitions.
 //
@@ -1068,6 +1072,17 @@
                               !strconcat("${:private}PCRELL${:uid}:\n\t",
                                          "add $dst, pc, #PCRELV${:uid}")),
                    []>;
+//===----------------------------------------------------------------------===//
+// TLS Instructions
+//
+
+// __aeabi_read_tp preserves the registers r1-r3.
+let isCall = 1,
+  Defs = [R0, R12, LR] in {
+  def TPsoft  : AI<(ops),
+               "bl __aeabi_read_tp",
+               [(set R0, ARMthread_pointer)]>;
+}
 
 //===----------------------------------------------------------------------===//
 // Non-Instruction Patterns


Index: llvm/lib/Target/ARM/ARMInstrThumb.td
diff -u llvm/lib/Target/ARM/ARMInstrThumb.td:1.23 llvm/lib/Target/ARM/ARMInstrThumb.td:1.24
--- llvm/lib/Target/ARM/ARMInstrThumb.td:1.23	Fri Apr 27 02:50:02 2007
+++ llvm/lib/Target/ARM/ARMInstrThumb.td	Fri Apr 27 08:54:47 2007
@@ -524,6 +524,18 @@
                     []>;
 
 //===----------------------------------------------------------------------===//
+// TLS Instructions
+//
+
+// __aeabi_read_tp preserves the registers r1-r3.
+let isCall = 1,
+  Defs = [R0, LR] in {
+  def tTPsoft  : TIx2<(ops),
+               "bl __aeabi_read_tp",
+               [(set R0, ARMthread_pointer)]>;
+}
+
+//===----------------------------------------------------------------------===//
 // Non-Instruction Patterns
 //
 


Index: llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp
diff -u llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp:1.14 llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp:1.15
--- llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp:1.14	Mon Apr 23 15:04:35 2007
+++ llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp	Fri Apr 27 08:54:47 2007
@@ -70,6 +70,8 @@
       StaticCtorsSection = "\t.section .ctors,\"aw\",%progbits";
       StaticDtorsSection = "\t.section .dtors,\"aw\",%progbits";
     }
+    TLSDataSection = "\t.section .tdata,\"awT\",%progbits";
+    TLSBSSSection = "\t.section .tbss,\"awT\",%nobits";
   }
 
   ZeroDirective = "\t.space\t";






More information about the llvm-commits mailing list