Add General Dynamic TLS model for X86-64. Some parts looks really ugly (look for...
authorAnton Korobeynikov <asl@math.spbu.ru>
Sun, 4 May 2008 21:36:32 +0000 (21:36 +0000)
committerAnton Korobeynikov <asl@math.spbu.ru>
Sun, 4 May 2008 21:36:32 +0000 (21:36 +0000)
but should work. Work is in progress, more models will follow

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50630 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ATTAsmPrinter.cpp
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86Instr64bit.td
lib/Target/X86/X86InstrInfo.td

index 78240b363330e1491a52433c9055d6a0d577da7c..6909da1b2457b85bab66ee5c0b6fb4fe280d4197 100644 (file)
@@ -347,7 +347,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
 
     if (GV->hasExternalWeakLinkage())
       ExtWeakSymbols.insert(GV);
-    
+
     int Offset = MO.getOffset();
     if (Offset > 0)
       O << "+" << Offset;
@@ -355,7 +355,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
       O << Offset;
 
     if (isThreadLocal) {
-      if (TM.getRelocationModel() == Reloc::PIC_)
+      if (TM.getRelocationModel() == Reloc::PIC_ || Subtarget->is64Bit())
         O << "@TLSGD"; // general dynamic TLS model
       else
         if (GV->isDeclaration())
index 440839933dff20c7d71a5d36a1183fa0fe47b694..e90c9303f3dd2d1eb7b91fa9ead031abc5bab44f 100644 (file)
@@ -267,6 +267,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   setOperationAction(ISD::JumpTable       , MVT::i32  , Custom);
   setOperationAction(ISD::GlobalAddress   , MVT::i32  , Custom);
   setOperationAction(ISD::GlobalTLSAddress, MVT::i32  , Custom);
+  if (Subtarget->is64Bit())
+    setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);
   setOperationAction(ISD::ExternalSymbol  , MVT::i32  , Custom);
   if (Subtarget->is64Bit()) {
     setOperationAction(ISD::ConstantPool  , MVT::i64  , Custom);
@@ -4001,10 +4003,10 @@ X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
   return Result;
 }
 
-// Lower ISD::GlobalTLSAddress using the "general dynamic" model
+// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 32 bit
 static SDOperand
-LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
-                              const MVT::ValueType PtrVT) {
+LowerToTLSGeneralDynamicModel32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
+                                const MVT::ValueType PtrVT) {
   SDOperand InFlag;
   SDOperand Chain = DAG.getCopyToReg(DAG.getEntryNode(), X86::EBX,
                                      DAG.getNode(X86ISD::GlobalBaseReg,
@@ -4039,6 +4041,39 @@ LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
   return DAG.getCopyFromReg(Chain, X86::EAX, PtrVT, InFlag);
 }
 
+// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit
+static SDOperand
+LowerToTLSGeneralDynamicModel64(GlobalAddressSDNode *GA, SelectionDAG &DAG,
+                                const MVT::ValueType PtrVT) {
+  SDOperand InFlag, Chain;
+
+  // emit leaq symbol@TLSGD(%rip), %rdi
+  SDVTList NodeTys = DAG.getVTList(PtrVT, MVT::Other, MVT::Flag);
+  SDOperand TGA = DAG.getTargetGlobalAddress(GA->getGlobal(),
+                                             GA->getValueType(0),
+                                             GA->getOffset());
+  SDOperand Ops[]  = { DAG.getEntryNode(), TGA};
+  SDOperand Result = DAG.getNode(X86ISD::TLSADDR, NodeTys, Ops, 2);
+  Chain  = Result.getValue(1);
+  InFlag = Result.getValue(2);
+
+  // call ___tls_get_addr. This function receives its argument in
+  // the register RDI.
+  Chain = DAG.getCopyToReg(Chain, X86::RDI, 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::RDI, PtrVT),
+                      InFlag };
+  Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops1, 4);
+  InFlag = Chain.getValue(1);
+
+  return DAG.getCopyFromReg(Chain, X86::RAX, PtrVT, InFlag);
+}
+
 // Lower ISD::GlobalTLSAddress using the "initial exec" (for no-pic) or
 // "local exec" model.
 static SDOperand
@@ -4066,15 +4101,19 @@ 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() && Subtarget->isTargetELF() &&
-         "TLS not implemented for non-ELF and 64-bit targets");
+  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, getPointerTy());
-  else
-    return LowerToTLSExecModel(GA, DAG, getPointerTy());
+  if (Subtarget->is64Bit()) {
+    return LowerToTLSGeneralDynamicModel64(GA, DAG, getPointerTy());
+  } else {
+    if (getTargetMachine().getRelocationModel() == Reloc::PIC_)
+      return LowerToTLSGeneralDynamicModel32(GA, DAG, getPointerTy());
+    else
+      return LowerToTLSExecModel(GA, DAG, getPointerTy());
+  }
 }
 
 SDOperand
index 1bf1b1aedb161d86266245da6f1a729e7b00a66a..25a7b56ace0652f5e07b2ee41775cec805e59984 100644 (file)
@@ -1102,6 +1102,13 @@ def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64i32imm:$src),
                         "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
                         [(set GR64:$dst, i64immZExt32:$src)]>;
 
+//===----------------------------------------------------------------------===//
+// Thread Local Storage Instructions
+//===----------------------------------------------------------------------===//
+
+def TLS_addr64 : I<0, Pseudo, (outs GR64:$dst), (ins i64imm:$sym),
+                  ".byte\t0x66; leaq\t${sym:mem}(%rip), $dst; .word\t0x6666; rex64",
+                  [(set GR64:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>;
 
 //===----------------------------------------------------------------------===//
 // Atomic Instructions
index bea4798f52d308614b8fe5c58e9c1b5f36f7231a..c539eca940c94a47c823a206445ad86bbbf304d7 100644 (file)
@@ -109,7 +109,7 @@ def X86Wrapper    : SDNode<"X86ISD::Wrapper",     SDTX86Wrapper>;
 def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP",  SDTX86Wrapper>;
 
 def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
-                        [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
+                        [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
 def X86TLStp : SDNode<"X86ISD::THREAD_POINTER", SDT_X86TLSTP, []>;
 
 def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
@@ -2500,12 +2500,12 @@ def MOV32_mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32_:$src),
 //
 
 let Uses = [EBX] in
-def TLS_addr : I<0, Pseudo, (outs GR32:$dst), (ins i32imm:$sym),
-               "leal\t${sym:mem}(,%ebx,1), $dst",
-               [(set GR32:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>;
+def TLS_addr32 : I<0, Pseudo, (outs GR32:$dst), (ins i32imm:$sym),
+                  "leal\t${sym:mem}(,%ebx,1), $dst",
+                  [(set GR32:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>;
 
 let AddedComplexity = 10 in
-def TLS_gs_rr : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$src),
+def TLS_gs_rr  : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$src),
                   "movl\t%gs:($src), $dst",
                   [(set GR32:$dst, (load (add X86TLStp, GR32:$src)))]>;