llvm.org GIT mirror llvm / b3a0417
Implement "general dynamic", "initial exec" and "local exec" TLS models for X86 32 bits. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36283 91177308-0d34-0410-b5e6-96231b3b80d8 Lauro Ramos Venancio 13 years ago
13 changed file(s) with 188 addition(s) and 17 deletion(s). Raw diff Collapse all Expand all
397397 SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
398398 MVT::ValueType VT2, MVT::ValueType VT3,
399399 SDOperand Op1, SDOperand Op2);
400 SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
401 MVT::ValueType VT2, MVT::ValueType VT3,
402 SDOperand Op1, SDOperand Op2, SDOperand Op3);
400403 SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
401404 MVT::ValueType VT2, MVT::ValueType VT3,
402405 const SDOperand *Ops, unsigned NumOps);
1818 #ifndef LLVM_CODEGEN_SELECTIONDAGNODES_H
1919 #define LLVM_CODEGEN_SELECTIONDAGNODES_H
2020
21 #include "llvm/GlobalVariable.h"
2122 #include "llvm/Value.h"
2223 #include "llvm/ADT/FoldingSet.h"
2324 #include "llvm/ADT/GraphTraits.h"
9495 // Various leaf nodes.
9596 STRING, BasicBlock, VALUETYPE, CONDCODE, Register,
9697 Constant, ConstantFP,
97 GlobalAddress, FrameIndex, JumpTable, ConstantPool, ExternalSymbol,
98 GlobalAddress, GlobalTLSAddress, FrameIndex,
99 JumpTable, ConstantPool, ExternalSymbol,
98100
99101 // The address of the GOT
100102 GLOBAL_OFFSET_TABLE,
123125 // anything else with this node, and this is valid in the target-specific
124126 // dag, turning into a GlobalAddress operand.
125127 TargetGlobalAddress,
128 TargetGlobalTLSAddress,
126129 TargetFrameIndex,
127130 TargetJumpTable,
128131 TargetConstantPool,
11631166 friend class SelectionDAG;
11641167 GlobalAddressSDNode(bool isTarget, const GlobalValue *GA, MVT::ValueType VT,
11651168 int o = 0)
1166 : SDNode(isTarget ? ISD::TargetGlobalAddress : ISD::GlobalAddress,
1169 : SDNode(dyn_cast(GA) &&
1170 dyn_cast(GA)->isThreadLocal() ?
1171 // Thread Local
1172 (isTarget ? ISD::TargetGlobalTLSAddress : ISD::GlobalTLSAddress) :
1173 // Non Thread Local
1174 (isTarget ? ISD::TargetGlobalAddress : ISD::GlobalAddress),
11671175 getSDVTList(VT)), Offset(o) {
11681176 TheGlobal = const_cast(GA);
11691177 }
11751183 static bool classof(const GlobalAddressSDNode *) { return true; }
11761184 static bool classof(const SDNode *N) {
11771185 return N->getOpcode() == ISD::GlobalAddress ||
1178 N->getOpcode() == ISD::TargetGlobalAddress;
1179 }
1180 };
1181
1186 N->getOpcode() == ISD::TargetGlobalAddress ||
1187 N->getOpcode() == ISD::GlobalTLSAddress ||
1188 N->getOpcode() == ISD::TargetGlobalTLSAddress;
1189 }
1190 };
11821191
11831192 class FrameIndexSDNode : public SDNode {
11841193 int FI;
4242 /// target doesn't support a BSS section.
4343 ///
4444 const char *BSSSection; // Default to ".bss".
45
45
46 /// TLSDataSection - Section directive for Thread Local data.
47 ///
48 const char *TLSDataSection;// Defaults to ".section .tdata,"awT",@progbits".
49
50 /// TLSBSSSection - Section directive for Thread Local uninitialized data.
51 /// Null if this target doesn't support a BSS section.
52 ///
53 const char *TLSBSSSection;// Default to ".section .tbss,"awT",@nobits".
4654 /// ZeroFillDirective - Directive for emitting a global to the ZeroFill
4755 /// section on this target. Null if this target doesn't support zerofill.
4856 const char *ZeroFillDirective; // Default is null.
361369 const char *getBSSSection() const {
362370 return BSSSection;
363371 }
372 const char *getTLSDataSection() const {
373 return TLSDataSection;
374 }
375 const char *getTLSBSSSection() const {
376 return TLSBSSSection;
377 }
364378 const char *getZeroFillDirective() const {
365379 return ZeroFillDirective;
366380 }
621621 case ISD::TargetConstantFP:
622622 case ISD::TargetConstantPool:
623623 case ISD::TargetGlobalAddress:
624 case ISD::TargetGlobalTLSAddress:
624625 case ISD::TargetExternalSymbol:
625626 case ISD::VALUETYPE:
626627 case ISD::SRCVALUE:
652653 assert(0 && "Do not know how to legalize this operator!");
653654 abort();
654655 case ISD::GlobalAddress:
656 case ISD::GlobalTLSAddress:
655657 case ISD::ExternalSymbol:
656658 case ISD::ConstantPool:
657659 case ISD::JumpTable: // Nothing to do.
1313 #include "llvm/CodeGen/SelectionDAG.h"
1414 #include "llvm/Constants.h"
1515 #include "llvm/GlobalValue.h"
16 #include "llvm/GlobalVariable.h"
1617 #include "llvm/Intrinsics.h"
1718 #include "llvm/Assembly/Writer.h"
1819 #include "llvm/CodeGen/MachineBasicBlock.h"
295296 ID.AddDouble(cast(N)->getValue());
296297 break;
297298 case ISD::TargetGlobalAddress:
298 case ISD::GlobalAddress: {
299 case ISD::GlobalAddress:
300 case ISD::TargetGlobalTLSAddress:
301 case ISD::GlobalTLSAddress: {
299302 GlobalAddressSDNode *GA = cast(N);
300303 ID.AddPointer(GA->getGlobal());
301304 ID.AddInteger(GA->getOffset());
691694 SDOperand SelectionDAG::getGlobalAddress(const GlobalValue *GV,
692695 MVT::ValueType VT, int Offset,
693696 bool isTargetGA) {
694 unsigned Opc = isTargetGA ? ISD::TargetGlobalAddress : ISD::GlobalAddress;
697 const GlobalVariable *GVar = dyn_cast(GV);
698 unsigned Opc;
699 if (GVar && GVar->isThreadLocal())
700 Opc = isTargetGA ? ISD::TargetGlobalTLSAddress : ISD::GlobalTLSAddress;
701 else
702 Opc = isTargetGA ? ISD::TargetGlobalAddress : ISD::GlobalAddress;
695703 FoldingSetNodeID ID;
696704 AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0);
697705 ID.AddPointer(GV);
22812289 SDOperand Ops[] = { Op1, Op2 };
22822290 return getNode(ISD::BUILTIN_OP_END+Opcode, VTs, 3, Ops, 2).Val;
22832291 }
2292 SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT::ValueType VT1,
2293 MVT::ValueType VT2, MVT::ValueType VT3,
2294 SDOperand Op1, SDOperand Op2,
2295 SDOperand Op3) {
2296 const MVT::ValueType *VTs = getNodeValueTypes(VT1, VT2, VT3);
2297 SDOperand Ops[] = { Op1, Op2, Op3 };
2298 return getNode(ISD::BUILTIN_OP_END+Opcode, VTs, 3, Ops, 3).Val;
2299 }
22842300 SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT::ValueType VT1,
22852301 MVT::ValueType VT2, MVT::ValueType VT3,
22862302 const SDOperand *Ops, unsigned NumOps) {
27012717 case ISD::Constant: return "Constant";
27022718 case ISD::ConstantFP: return "ConstantFP";
27032719 case ISD::GlobalAddress: return "GlobalAddress";
2720 case ISD::GlobalTLSAddress: return "GlobalTLSAddress";
27042721 case ISD::FrameIndex: return "FrameIndex";
27052722 case ISD::JumpTable: return "JumpTable";
27062723 case ISD::GLOBAL_OFFSET_TABLE: return "GLOBAL_OFFSET_TABLE";
27242741 case ISD::TargetConstant: return "TargetConstant";
27252742 case ISD::TargetConstantFP:return "TargetConstantFP";
27262743 case ISD::TargetGlobalAddress: return "TargetGlobalAddress";
2744 case ISD::TargetGlobalTLSAddress: return "TargetGlobalTLSAddress";
27272745 case ISD::TargetFrameIndex: return "TargetFrameIndex";
27282746 case ISD::TargetJumpTable: return "TargetJumpTable";
27292747 case ISD::TargetConstantPool: return "TargetConstantPool";
1919 TextSection(".text"),
2020 DataSection(".data"),
2121 BSSSection(".bss"),
22 TLSDataSection("\t.section .tdata,\"awT\",@progbits"),
23 TLSBSSSection("\t.section .tbss,\"awT\",@nobits"),
2224 ZeroFillDirective(0),
2325 AddressSize(4),
2426 NeedsSet(false),
210210 "GlobalAddressSDNode">;
211211 def tglobaladdr : SDNode<"ISD::TargetGlobalAddress", SDTPtrLeaf, [],
212212 "GlobalAddressSDNode">;
213 def globaltlsaddr : SDNode<"ISD::GlobalTLSAddress", SDTPtrLeaf, [],
214 "GlobalAddressSDNode">;
215 def tglobaltlsaddr : SDNode<"ISD::TargetGlobalTLSAddress", SDTPtrLeaf, [],
216 "GlobalAddressSDNode">;
213217 def constpool : SDNode<"ISD::ConstantPool", SDTPtrLeaf, [],
214218 "ConstantPoolSDNode">;
215219 def tconstpool : SDNode<"ISD::TargetConstantPool", SDTPtrLeaf, [],
271271 case MachineOperand::MO_GlobalAddress: {
272272 bool isCallOp = Modifier && !strcmp(Modifier, "call");
273273 bool isMemOp = Modifier && !strcmp(Modifier, "mem");
274 if (!isMemOp && !isCallOp) O << '$';
275274
276275 GlobalValue *GV = MO.getGlobal();
276 GlobalVariable *GVar = dyn_cast(GV);
277 bool isThreadLocal = GVar && GVar->isThreadLocal();
278
279 if (!isMemOp && !isCallOp && !isThreadLocal) O << '$';
280
277281 std::string Name = Mang->getValueName(GV);
278282 X86SharedAsmPrinter::decorateName(Name, GV);
279283
327331 else if (Offset < 0)
328332 O << Offset;
329333
330 if (isMemOp) {
334 if (isThreadLocal) {
335 if (TM.getRelocationModel() == Reloc::PIC_)
336 O << "@TLSGD"; // general dynamic TLS model
337 else
338 if (GV->isDeclaration())
339 O << "@INDNTPOFF"; // initial exec TLS model
340 else
341 O << "@NTPOFF"; // local exec TLS model
342 } else if (isMemOp) {
331343 if (printGOT(TM, Subtarget)) {
332344 if (Subtarget->GVRequiresExtraLoad(GV, TM, false))
333345 O << "@GOT";
170170 }
171171 }
172172
173 if (!I->hasSection() &&
173 if (!I->hasSection() && !I->isThreadLocal() &&
174174 (I->hasInternalLinkage() || I->hasWeakLinkage() ||
175175 I->hasLinkOnceLinkage())) {
176176 if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
255255 SwitchToDataSection(SectionName.c_str());
256256 } else {
257257 if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection())
258 SwitchToDataSection(TAI->getBSSSection(), I);
258 SwitchToDataSection(I->isThreadLocal() ? TAI->getTLSBSSSection() :
259 TAI->getBSSSection(), I);
259260 else if (!I->isConstant())
260 SwitchToDataSection(TAI->getDataSection(), I);
261 SwitchToDataSection(I->isThreadLocal() ? TAI->getTLSDataSection() :
262 TAI->getDataSection(), I);
263 else if (I->isThreadLocal())
264 SwitchToDataSection(TAI->getTLSDataSection());
261265 else {
262266 // Read-only data.
263267 bool HasReloc = C->ContainsRelocations();
1919 #include "llvm/CallingConv.h"
2020 #include "llvm/Constants.h"
2121 #include "llvm/DerivedTypes.h"
22 #include "llvm/GlobalVariable.h"
2223 #include "llvm/Function.h"
2324 #include "llvm/Intrinsics.h"
2425 #include "llvm/ADT/VectorExtras.h"
199200 setOperationAction(ISD::ConstantPool , MVT::i32 , Custom);
200201 setOperationAction(ISD::JumpTable , MVT::i32 , Custom);
201202 setOperationAction(ISD::GlobalAddress , MVT::i32 , Custom);
203 setOperationAction(ISD::GlobalTLSAddress, MVT::i32 , Custom);
202204 setOperationAction(ISD::ExternalSymbol , MVT::i32 , Custom);
203205 if (Subtarget->is64Bit()) {
204206 setOperationAction(ISD::ConstantPool , MVT::i64 , Custom);
29402942 Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
29412943
29422944 return Result;
2945 }
2946
2947 // Lower ISD::GlobalTLSAddress using the "general dynamic" model
2948 static SDOperand
2949 LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
2950 const MVT::ValueType PtrVT) {
2951 SDOperand InFlag;
2952 SDOperand Chain = DAG.getCopyToReg(DAG.getEntryNode(), X86::EBX,
2953 DAG.getNode(X86ISD::GlobalBaseReg,
2954 PtrVT), InFlag);
2955 InFlag = Chain.getValue(1);
2956
2957 // emit leal symbol@TLSGD(,%ebx,1), %eax
2958 SDVTList NodeTys = DAG.getVTList(PtrVT, MVT::Other, MVT::Flag);
2959 SDOperand TGA = DAG.getTargetGlobalAddress(GA->getGlobal(),
2960 GA->getValueType(0),
2961 GA->getOffset());
2962 SDOperand Ops[] = { Chain, TGA, InFlag };
2963 SDOperand Result = DAG.getNode(X86ISD::TLSADDR, NodeTys, Ops, 3);
2964 InFlag = Result.getValue(2);
2965 Chain = Result.getValue(1);
2966
2967 // call ___tls_get_addr. This function receives its argument in
2968 // the register EAX.
2969 Chain = DAG.getCopyToReg(Chain, X86::EAX, Result, InFlag);
2970 InFlag = Chain.getValue(1);
2971
2972 NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
2973 SDOperand Ops1[] = { Chain,
2974 DAG.getTargetExternalSymbol("___tls_get_addr",
2975 PtrVT),
2976 DAG.getRegister(X86::EAX, PtrVT),
2977 DAG.getRegister(X86::EBX, PtrVT),
2978 InFlag };
2979 Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops1, 5);
2980 InFlag = Chain.getValue(1);
2981
2982 return DAG.getCopyFromReg(Chain, X86::EAX, PtrVT, InFlag);
2983 }
2984
2985 // Lower ISD::GlobalTLSAddress using the "initial exec" (for no-pic) or
2986 // "local exec" model.
2987 static SDOperand
2988 LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
2989 const MVT::ValueType PtrVT) {
2990 // Get the Thread Pointer
2991 SDOperand ThreadPointer = DAG.getNode(X86ISD::THREAD_POINTER, PtrVT);
2992 // emit "addl x@ntpoff,%eax" (local exec) or "addl x@indntpoff,%eax" (initial
2993 // exec)
2994 SDOperand TGA = DAG.getTargetGlobalAddress(GA->getGlobal(),
2995 GA->getValueType(0),
2996 GA->getOffset());
2997 SDOperand Offset = DAG.getNode(X86ISD::Wrapper, PtrVT, TGA);
2998 // The address of the thread local variable is the add of the thread
2999 // pointer with the offset of the variable.
3000 return DAG.getNode(ISD::ADD, PtrVT, ThreadPointer, Offset);
3001 }
3002
3003 SDOperand
3004 X86TargetLowering::LowerGlobalTLSAddress(SDOperand Op, SelectionDAG &DAG) {
3005 // TODO: implement the "local dynamic" model
3006 // TODO: implement the "initial exec"model for pic executables
3007 assert(!Subtarget->is64Bit() && "TLS not implemented for X86_64");
3008 GlobalAddressSDNode *GA = cast(Op);
3009 // If the relocation model is PIC, use the "General Dynamic" TLS Model,
3010 // otherwise use the "Local Exec"TLS Model
3011 if (getTargetMachine().getRelocationModel() == Reloc::PIC_)
3012 return LowerToTLSGeneralDynamicModel(GA, DAG, getPointerTy());
3013 else
3014 return LowerToTLSExecModel(GA, DAG, getPointerTy());
29433015 }
29443016
29453017 SDOperand
40214093 case ISD::SCALAR_TO_VECTOR: return LowerSCALAR_TO_VECTOR(Op, DAG);
40224094 case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
40234095 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
4096 case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
40244097 case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG);
40254098 case ISD::SHL_PARTS:
40264099 case ISD::SRA_PARTS:
40894162 case X86ISD::PINSRW: return "X86ISD::PINSRW";
40904163 case X86ISD::FMAX: return "X86ISD::FMAX";
40914164 case X86ISD::FMIN: return "X86ISD::FMIN";
4165 case X86ISD::TLSADDR: return "X86ISD::TLSADDR";
4166 case X86ISD::THREAD_POINTER: return "X86ISD::THREAD_POINTER";
40924167 }
40934168 }
40944169
175175
176176 /// FMAX, FMIN - Floating point max and min.
177177 ///
178 FMAX, FMIN
178 FMAX, FMIN,
179 // Thread Local Storage
180 TLSADDR, THREAD_POINTER
179181 };
180182 }
181183
385387 SDOperand LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG);
386388 SDOperand LowerConstantPool(SDOperand Op, SelectionDAG &DAG);
387389 SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG);
390 SDOperand LowerGlobalTLSAddress(SDOperand Op, SelectionDAG &DAG);
388391 SDOperand LowerExternalSymbol(SDOperand Op, SelectionDAG &DAG);
389392 SDOperand LowerShift(SDOperand Op, SelectionDAG &DAG);
390393 SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG);
4646
4747 def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
4848
49 def SDT_X86TLSADDR : SDTypeProfile<1, 1, [SDTCisPtrTy<0>, SDTCisInt<1>]>;
50
51 def SDT_X86TLSTP : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
52
4953 def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>;
5054 def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>;
5155
8589
8690 def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
8791 def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
92
93 def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
94 [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
95 def X86TLStp : SDNode<"X86ISD::THREAD_POINTER", SDT_X86TLSTP, []>;
96
8897
8998 //===----------------------------------------------------------------------===//
9099 // X86 Operand Definitions.
24482457 "mov{l} {$src, $dst|$dst, $src}", []>;
24492458
24502459 //===----------------------------------------------------------------------===//
2460 // Thread Local Storage Instructions
2461 //
2462
2463 def TLS_addr : I<0, Pseudo, (ops GR32:$dst, i32imm:$sym),
2464 "leal $sym(,%ebx,1), $dst",
2465 [(set GR32:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>,
2466 Imp<[EBX],[]>;
2467
2468 def TLS_tp : I<0, Pseudo, (ops GR32:$dst),
2469 "movl %gs:0, $dst",
2470 [(set GR32:$dst, X86TLStp)]>;
2471
2472 //===----------------------------------------------------------------------===//
24512473 // DWARF Pseudo Instructions
24522474 //
24532475
26532653 } else {
26542654 NodeOps.push_back(Val);
26552655 }
2656 } else if (!N->isLeaf() && N->getOperator()->getName() == "tglobaladdr") {
2656 } else if (!N->isLeaf() && (N->getOperator()->getName() == "tglobaladdr"
2657 || N->getOperator()->getName() == "tglobaltlsaddr")) {
26572658 Record *Op = OperatorMap[N->getName()];
26582659 // Transform GlobalAddress to TargetGlobalAddress
2659 if (Op && Op->getName() == "globaladdr") {
2660 if (Op && (Op->getName() == "globaladdr" ||
2661 Op->getName() == "globaltlsaddr")) {
26602662 emitCode("SDOperand Tmp" + utostr(ResNo) + " = CurDAG->getTarget"
26612663 "GlobalAddress(cast(" + Val +
26622664 ")->getGlobal(), " + getEnumName(N->getTypeNum(0)) +
37153717 << " case ISD::TargetConstantPool:\n"
37163718 << " case ISD::TargetFrameIndex:\n"
37173719 << " case ISD::TargetJumpTable:\n"
3720 << " case ISD::TargetGlobalTLSAddress:\n"
37183721 << " case ISD::TargetGlobalAddress: {\n"
37193722 << " return NULL;\n"
37203723 << " }\n"