llvm.org GIT mirror llvm / 6625eff
Add General Dynamic TLS model for X86-64. Some parts looks really ugly (look for tlsaddr pattern), 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 Anton Korobeynikov 12 years ago
4 changed file(s) with 62 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
346346
347347 if (GV->hasExternalWeakLinkage())
348348 ExtWeakSymbols.insert(GV);
349
349
350350 int Offset = MO.getOffset();
351351 if (Offset > 0)
352352 O << "+" << Offset;
354354 O << Offset;
355355
356356 if (isThreadLocal) {
357 if (TM.getRelocationModel() == Reloc::PIC_)
357 if (TM.getRelocationModel() == Reloc::PIC_ || Subtarget->is64Bit())
358358 O << "@TLSGD"; // general dynamic TLS model
359359 else
360360 if (GV->isDeclaration())
266266 setOperationAction(ISD::JumpTable , MVT::i32 , Custom);
267267 setOperationAction(ISD::GlobalAddress , MVT::i32 , Custom);
268268 setOperationAction(ISD::GlobalTLSAddress, MVT::i32 , Custom);
269 if (Subtarget->is64Bit())
270 setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);
269271 setOperationAction(ISD::ExternalSymbol , MVT::i32 , Custom);
270272 if (Subtarget->is64Bit()) {
271273 setOperationAction(ISD::ConstantPool , MVT::i64 , Custom);
40004002 return Result;
40014003 }
40024004
4003 // Lower ISD::GlobalTLSAddress using the "general dynamic" model
4005 // Lower ISD::GlobalTLSAddress using the "general dynamic" model, 32 bit
40044006 static SDOperand
4005 LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
4006 const MVT::ValueType PtrVT) {
4007 LowerToTLSGeneralDynamicModel32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
4008 const MVT::ValueType PtrVT) {
40074009 SDOperand InFlag;
40084010 SDOperand Chain = DAG.getCopyToReg(DAG.getEntryNode(), X86::EBX,
40094011 DAG.getNode(X86ISD::GlobalBaseReg,
40364038 InFlag = Chain.getValue(1);
40374039
40384040 return DAG.getCopyFromReg(Chain, X86::EAX, PtrVT, InFlag);
4041 }
4042
4043 // Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit
4044 static SDOperand
4045 LowerToTLSGeneralDynamicModel64(GlobalAddressSDNode *GA, SelectionDAG &DAG,
4046 const MVT::ValueType PtrVT) {
4047 SDOperand InFlag, Chain;
4048
4049 // emit leaq symbol@TLSGD(%rip), %rdi
4050 SDVTList NodeTys = DAG.getVTList(PtrVT, MVT::Other, MVT::Flag);
4051 SDOperand TGA = DAG.getTargetGlobalAddress(GA->getGlobal(),
4052 GA->getValueType(0),
4053 GA->getOffset());
4054 SDOperand Ops[] = { DAG.getEntryNode(), TGA};
4055 SDOperand Result = DAG.getNode(X86ISD::TLSADDR, NodeTys, Ops, 2);
4056 Chain = Result.getValue(1);
4057 InFlag = Result.getValue(2);
4058
4059 // call ___tls_get_addr. This function receives its argument in
4060 // the register RDI.
4061 Chain = DAG.getCopyToReg(Chain, X86::RDI, Result, InFlag);
4062 InFlag = Chain.getValue(1);
4063
4064 NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
4065 SDOperand Ops1[] = { Chain,
4066 DAG.getTargetExternalSymbol("___tls_get_addr",
4067 PtrVT),
4068 DAG.getRegister(X86::RDI, PtrVT),
4069 InFlag };
4070 Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops1, 4);
4071 InFlag = Chain.getValue(1);
4072
4073 return DAG.getCopyFromReg(Chain, X86::RAX, PtrVT, InFlag);
40394074 }
40404075
40414076 // Lower ISD::GlobalTLSAddress using the "initial exec" (for no-pic) or
40654100 X86TargetLowering::LowerGlobalTLSAddress(SDOperand Op, SelectionDAG &DAG) {
40664101 // TODO: implement the "local dynamic" model
40674102 // TODO: implement the "initial exec"model for pic executables
4068 assert(!Subtarget->is64Bit() && Subtarget->isTargetELF() &&
4069 "TLS not implemented for non-ELF and 64-bit targets");
4103 assert(Subtarget->isTargetELF() &&
4104 "TLS not implemented for non-ELF targets");
40704105 GlobalAddressSDNode *GA = cast(Op);
40714106 // If the relocation model is PIC, use the "General Dynamic" TLS Model,
40724107 // otherwise use the "Local Exec"TLS Model
4073 if (getTargetMachine().getRelocationModel() == Reloc::PIC_)
4074 return LowerToTLSGeneralDynamicModel(GA, DAG, getPointerTy());
4075 else
4076 return LowerToTLSExecModel(GA, DAG, getPointerTy());
4108 if (Subtarget->is64Bit()) {
4109 return LowerToTLSGeneralDynamicModel64(GA, DAG, getPointerTy());
4110 } else {
4111 if (getTargetMachine().getRelocationModel() == Reloc::PIC_)
4112 return LowerToTLSGeneralDynamicModel32(GA, DAG, getPointerTy());
4113 else
4114 return LowerToTLSExecModel(GA, DAG, getPointerTy());
4115 }
40774116 }
40784117
40794118 SDOperand
11011101 "mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
11021102 [(set GR64:$dst, i64immZExt32:$src)]>;
11031103
1104 //===----------------------------------------------------------------------===//
1105 // Thread Local Storage Instructions
1106 //===----------------------------------------------------------------------===//
1107
1108 def TLS_addr64 : I<0, Pseudo, (outs GR64:$dst), (ins i64imm:$sym),
1109 ".byte\t0x66; leaq\t${sym:mem}(%rip), $dst; .word\t0x6666; rex64",
1110 [(set GR64:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>;
11041111
11051112 //===----------------------------------------------------------------------===//
11061113 // Atomic Instructions
108108 def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
109109
110110 def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
111 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
111 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
112112 def X86TLStp : SDNode<"X86ISD::THREAD_POINTER", SDT_X86TLSTP, []>;
113113
114114 def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
24992499 //
25002500
25012501 let Uses = [EBX] in
2502 def TLS_addr : I<0, Pseudo, (outs GR32:$dst), (ins i32imm:$sym),
2503 "leal\t${sym:mem}(,%ebx,1), $dst",
2504 [(set GR32:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>;
2502 def TLS_addr32 : I<0, Pseudo, (outs GR32:$dst), (ins i32imm:$sym),
2503 "leal\t${sym:mem}(,%ebx,1), $dst",
2504 [(set GR32:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>;
25052505
25062506 let AddedComplexity = 10 in
2507 def TLS_gs_rr : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$src),
2507 def TLS_gs_rr : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$src),
25082508 "movl\t%gs:($src), $dst",
25092509 [(set GR32:$dst, (load (add X86TLStp, GR32:$src)))]>;
25102510