llvm.org GIT mirror llvm / 57ac1f4
This patch implements the general dynamic TLS model for 64-bit PowerPC. Given a thread-local symbol x with global-dynamic access, the generated code to obtain x's address is: Instruction Relocation Symbol addis ra,r2,x@got@tlsgd@ha R_PPC64_GOT_TLSGD16_HA x addi r3,ra,x@got@tlsgd@l R_PPC64_GOT_TLSGD16_L x bl __tls_get_addr(x@tlsgd) R_PPC64_TLSGD x R_PPC64_REL24 __tls_get_addr nop <use address in r3> The implementation borrows from the medium code model work for introducing special forms of ADDIS and ADDI into the DAG representation. This is made slightly more complicated by having to introduce a call to the external function __tls_get_addr. Using the full call machinery is overkill and, more importantly, makes it difficult to add a special relocation. So I've introduced another opcode GET_TLS_ADDR to represent the function call, and surrounded it with register copies to set up the parameter and return value. Most of the code is pretty straightforward. I ran into one peculiarity when I introduced a new PPC opcode BL8_NOP_ELF_TLSGD, which is just like BL8_NOP_ELF except that it takes another parameter to represent the symbol ("x" above) that requires a relocation on the call. Something in the TblGen machinery causes BL8_NOP_ELF and BL8_NOP_ELF_TLSGD to be treated identically during the emit phase, so this second operand was never visited to generate relocations. This is the reason for the slightly messy workaround in PPCMCCodeEmitter.cpp:getDirectBrEncoding(). Two new tests are included to demonstrate correct external assembly and correct generation of relocations using the integrated assembler. Comments welcome! Thanks, Bill git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169910 91177308-0d34-0410-b5e6-96231b3b80d8 Bill Schmidt 6 years ago
15 changed file(s) with 246 addition(s) and 15 deletion(s). Raw diff Collapse all Expand all
180180 VK_PPC_TOC16_LO, // symbol@toc@l
181181 VK_PPC_GOT_TPREL16_DS, // symbol@got@tprel
182182 VK_PPC_TLS, // symbol@tls
183 VK_PPC_GOT_TLSGD16_HA, // symbol@got@tlsgd@ha
184 VK_PPC_GOT_TLSGD16_LO, // symbol@got@tlsgd@l
185 VK_PPC_TLSGD, // symbol@tlsgd
183186
184187 VK_Mips_GPREL,
185188 VK_Mips_GOT_CALL,
477477 R_PPC64_TOC16_DS = 63,
478478 R_PPC64_TOC16_LO_DS = 64,
479479 R_PPC64_TLS = 67,
480 R_PPC64_GOT_TPREL16_DS = 87
480 R_PPC64_GOT_TLSGD16_LO = 80,
481 R_PPC64_GOT_TLSGD16_HA = 82,
482 R_PPC64_GOT_TPREL16_DS = 87,
483 R_PPC64_TLSGD = 107
481484 };
482485
483486 // ARM Specific e_flags
212212 case VK_PPC_TOC16_LO: return "toc@l";
213213 case VK_PPC_GOT_TPREL16_DS: return "got@tprel";
214214 case VK_PPC_TLS: return "tls";
215 case VK_PPC_GOT_TLSGD16_HA: return "got@tlsgd@ha";
216 case VK_PPC_GOT_TLSGD16_LO: return "got@tlsgd@l";
217 case VK_PPC_TLSGD: return "tlsgd";
215218 case VK_Mips_GPREL: return "GPREL";
216219 case VK_Mips_GOT_CALL: return "GOT_CALL";
217220 case VK_Mips_GOT16: return "GOT16";
3131 case FK_Data_8:
3232 case PPC::fixup_ppc_toc:
3333 case PPC::fixup_ppc_tlsreg:
34 case PPC::fixup_ppc_tlsgd:
3435 return Value;
3536 case PPC::fixup_ppc_lo14:
3637 case PPC::fixup_ppc_toc16_ds:
8485 { "fixup_ppc_toc", 0, 64, 0 },
8586 { "fixup_ppc_toc16", 16, 16, 0 },
8687 { "fixup_ppc_toc16_ds", 16, 14, 0 },
87 { "fixup_ppc_tlsreg", 0, 0, 0 }
88 { "fixup_ppc_tlsreg", 0, 0, 0 },
89 { "fixup_ppc_tlsgd", 0, 0, 0 }
8890 };
8991
9092 if (Kind < FirstTargetFixupKind)
8484 case MCSymbolRefExpr::VK_PPC_TOC16_HA:
8585 Type = ELF::R_PPC64_TOC16_HA;
8686 break;
87 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_HA:
88 Type = ELF::R_PPC64_GOT_TLSGD16_HA;
89 break;
8790 }
8891 break;
8992 case PPC::fixup_ppc_lo16:
98101 case MCSymbolRefExpr::VK_PPC_TOC16_LO:
99102 Type = ELF::R_PPC64_TOC16_LO;
100103 break;
104 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_LO:
105 Type = ELF::R_PPC64_GOT_TLSGD16_LO;
106 break;
101107 }
102108 break;
103109 case PPC::fixup_ppc_lo14:
125131 break;
126132 case PPC::fixup_ppc_tlsreg:
127133 Type = ELF::R_PPC64_TLS;
134 break;
135 case PPC::fixup_ppc_tlsgd:
136 Type = ELF::R_PPC64_TLSGD;
128137 break;
129138 case FK_Data_8:
130139 switch (Modifier) {
4646
4747 /// fixup_ppc_tlsreg - Insert thread-pointer register number.
4848 fixup_ppc_tlsreg,
49
50 /// fixup_ppc_tlsgd - Not a true fixup, but ties a symbol to a call
51 /// to __tls_get_addr for the TLS global dynamic model.
52 fixup_ppc_tlsgd,
4953
5054 // Marker
5155 LastTargetFixupKind,
1616 #include "MCTargetDesc/PPCFixupKinds.h"
1717 #include "llvm/ADT/Statistic.h"
1818 #include "llvm/MC/MCCodeEmitter.h"
19 #include "llvm/MC/MCExpr.h"
1920 #include "llvm/MC/MCInst.h"
2021 #include "llvm/MC/MCInstrInfo.h"
2122 #include "llvm/MC/MCSubtargetInfo.h"
118119 // Add a fixup for the branch target.
119120 Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
120121 (MCFixupKind)PPC::fixup_ppc_br24));
122
123 // For special TLS calls, add another fixup for the symbol. Apparently
124 // BL8_NOP_ELF and BL8_NOP_ELF_TLSGD are sufficiently similar that TblGen
125 // will not generate a separate case for the latter, so this is the only
126 // way to get the extra fixup generated.
127 if (MI.getOpcode() == PPC::BL8_NOP_ELF_TLSGD) {
128 const MCOperand &MO2 = MI.getOperand(OpNo+1);
129 Fixups.push_back(MCFixup::Create(0, MO2.getExpr(),
130 (MCFixupKind)PPC::fixup_ppc_tlsgd));
131 }
121132 return 0;
122133 }
123134
221232 (MCFixupKind)PPC::fixup_ppc_tlsreg));
222233 return getPPCRegisterNumbering(PPC::X13);
223234 }
224
225235
226236 unsigned PPCMCCodeEmitter::
227237 get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
529529 OutStreamer.EmitInstruction(TmpInst);
530530 return;
531531 }
532 case PPC::ADDIStlsgdHA: {
533 // Transform: %Xd = ADDIStlsgdHA %X2,
534 // Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
535 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
536 const MachineOperand &MO = MI->getOperand(2);
537 const GlobalValue *GValue = MO.getGlobal();
538 MCSymbol *MOSymbol = Mang->getSymbol(GValue);
539 const MCExpr *SymGotTlsGD =
540 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_HA,
541 OutContext);
542 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
543 .addReg(MI->getOperand(0).getReg())
544 .addReg(PPC::X2)
545 .addExpr(SymGotTlsGD));
546 return;
547 }
548 case PPC::ADDItlsgdL: {
549 // Transform: %Xd = ADDItlsgdL %Xs,
550 // Into: %Xd = ADDI8L %Xs, sym@got@tlsgd@l
551 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
552 const MachineOperand &MO = MI->getOperand(2);
553 const GlobalValue *GValue = MO.getGlobal();
554 MCSymbol *MOSymbol = Mang->getSymbol(GValue);
555 const MCExpr *SymGotTlsGD =
556 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_LO,
557 OutContext);
558 OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDI8L)
559 .addReg(MI->getOperand(0).getReg())
560 .addReg(MI->getOperand(1).getReg())
561 .addExpr(SymGotTlsGD));
562 return;
563 }
564 case PPC::GETtlsADDR: {
565 // Transform: %X3 = GETtlsADDR %X3,
566 // Into: BL8_NOP_ELF_TLSGD __tls_get_addr(sym@tlsgd)
567 assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
568
569 StringRef Name = "__tls_get_addr";
570 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
571 const MCSymbolRefExpr *TlsRef =
572 MCSymbolRefExpr::Create(TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
573 const MachineOperand &MO = MI->getOperand(2);
574 const GlobalValue *GValue = MO.getGlobal();
575 MCSymbol *MOSymbol = Mang->getSymbol(GValue);
576 const MCExpr *SymVar =
577 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD,
578 OutContext);
579 OutStreamer.EmitInstruction(MCInstBuilder(PPC::BL8_NOP_ELF_TLSGD)
580 .addExpr(TlsRef)
581 .addExpr(SymVar));
582 return;
583 }
532584 case PPC::MFCRpseud:
533585 case PPC::MFCR8pseud:
534586 // Transform: %R3 = MFCRpseud %CR7
13151315 return CurDAG->getMachineNode(PPC::LDgotTPREL, dl, MVT::i64,
13161316 N->getOperand(0), N->getOperand(1));
13171317 }
1318 // FIXME: Try without these. Doesn't seem necessary.
1319 case PPCISD::ADDIS_TLSGD_HA: {
1320 assert (PPCSubTarget.isPPC64() && "Only supported for 64-bit ABI");
1321 return CurDAG->getMachineNode(PPC::ADDIStlsgdHA, dl, MVT::i64,
1322 N->getOperand(0), N->getOperand(1));
1323 }
1324 case PPCISD::ADDI_TLSGD_L: {
1325 assert (PPCSubTarget.isPPC64() && "Only supported for 64-bit ABI");
1326 return CurDAG->getMachineNode(PPC::ADDItlsgdL, dl, MVT::i64,
1327 N->getOperand(0), N->getOperand(1));
1328 }
1329 case PPCISD::GET_TLS_ADDR: {
1330 assert (PPCSubTarget.isPPC64() && "Only supported for 64-bit ABI");
1331 return CurDAG->getMachineNode(PPC::GETtlsADDR, dl, MVT::i64,
1332 N->getOperand(0), N->getOperand(1));
1333 }
13181334 }
13191335
13201336 return SelectCode(N);
579579 case PPCISD::ADDI_TOC_L: return "PPCISD::ADDI_TOC_L";
580580 case PPCISD::LD_GOT_TPREL: return "PPCISD::LD_GOT_TPREL";
581581 case PPCISD::ADD_TLS: return "PPCISD::ADD_TLS";
582 case PPCISD::ADDIS_TLSGD_HA: return "PPCISD::ADDIS_TLSGD_HA";
583 case PPCISD::ADDI_TLSGD_L: return "PPCISD::ADDI_TLSGD_L";
584 case PPCISD::GET_TLS_ADDR: return "PPCISD::GET_TLS_ADDR";
582585 }
583586 }
584587
13411344 if (!is64bit)
13421345 llvm_unreachable("only local-exec is currently supported for ppc32");
13431346
1344 if (Model != TLSModel::InitialExec)
1345 llvm_unreachable("only local-exec and initial-exec TLS modes supported");
1346
1347 SDValue GOTOffset = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
1348 PPCII::MO_GOT_TPREL16_DS);
1349 SDValue TPReg = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
1350 PPCII::MO_TLS);
1351 SDValue GOTReg = DAG.getRegister(is64bit ? PPC::X2 : PPC::R2,
1352 is64bit ? MVT::i64 : MVT::i32);
1353 SDValue TPOffset = DAG.getNode(PPCISD::LD_GOT_TPREL, dl, PtrVT,
1354 GOTOffset, GOTReg);
1355 return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TPReg);
1347 if (Model == TLSModel::InitialExec) {
1348 SDValue GOTOffset = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
1349 PPCII::MO_GOT_TPREL16_DS);
1350 SDValue TPReg = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
1351 PPCII::MO_TLS);
1352 SDValue GOTReg = DAG.getRegister(is64bit ? PPC::X2 : PPC::R2,
1353 is64bit ? MVT::i64 : MVT::i32);
1354 SDValue TPOffset = DAG.getNode(PPCISD::LD_GOT_TPREL, dl, PtrVT,
1355 GOTOffset, GOTReg);
1356 return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TPReg);
1357 }
1358
1359 if (Model == TLSModel::GeneralDynamic) {
1360 SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
1361 SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
1362 SDValue GOTEntryHi = DAG.getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
1363 GOTReg, TGA);
1364 SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSGD_L, dl, PtrVT,
1365 GOTEntryHi, TGA);
1366
1367 // We need a chain node, and don't have one handy. The underlying
1368 // call has no side effects, so using the function entry node
1369 // suffices.
1370 SDValue Chain = DAG.getEntryNode();
1371 Chain = DAG.getCopyToReg(Chain, dl, PPC::X3, GOTEntry);
1372 SDValue ParmReg = DAG.getRegister(PPC::X3, MVT::i64);
1373 SDValue TLSAddr = DAG.getNode(PPCISD::GET_TLS_ADDR, dl,
1374 PtrVT, ParmReg, TGA);
1375 // The call to GET_TLS_ADDR really is in X3 already, but
1376 // some hacks are needed here to tie everything together.
1377 // The extra copies dissolve during subsequent transforms.
1378 Chain = DAG.getCopyToReg(Chain, dl, PPC::X3, TLSAddr);
1379 return DAG.getCopyFromReg(Chain, dl, PPC::X3, PtrVT);
1380 }
1381
1382 llvm_unreachable("local-dynamic TLS mode is not yet supported");
13561383 }
13571384
13581385 SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op,
190190 /// identifies to the linker that the instruction is part of a
191191 /// TLS sequence.
192192 ADD_TLS,
193
194 /// G8RC = ADDIS_TLSGD_HA %X2, Symbol - For the general-dynamic TLS
195 /// model, produces an ADDIS8 instruction that adds the GOT base
196 /// register to sym@got@tlsgd@ha.
197 ADDIS_TLSGD_HA,
198
199 /// G8RC = ADDI_TLSGD_L G8RReg, Symbol - For the general-dynamic TLS
200 /// model, produces an ADDI8 instruction that adds G8RReg to
201 /// sym@got@tlsgd@l.
202 ADDI_TLSGD_L,
203
204 /// G8RC = GET_TLS_ADDR %X3, Symbol - For the general-dynamic TLS
205 /// model, produces a call to __tls_get_addr(sym@tlsgd).
206 GET_TLS_ADDR,
193207
194208 /// STD_32 - This is the STD instruction for use with "32-bit" registers.
195209 STD_32 = ISD::FIRST_TARGET_MEMORY_OPCODE,
4242 def tlsreg : Operand {
4343 let EncoderMethod = "getTLSRegEncoding";
4444 }
45 def tlsgd : Operand {}
4546
4647 //===----------------------------------------------------------------------===//
4748 // 64-bit transformation functions.
108109 def BL8_NOP_ELF : IForm_and_DForm_4_zero<18, 0, 1, 24,
109110 (outs), (ins calltarget:$func),
110111 "bl $func\n\tnop", BrB, []>;
112
113 let isCodeGenOnly = 1 in
114 def BL8_NOP_ELF_TLSGD : IForm_and_DForm_4_zero<18, 0, 1, 24,
115 (outs), (ins calltarget:$func, tlsgd:$sym),
116 "bl $func($sym)\n\tnop", BrB, []>;
111117
112118 def BLA8_ELF : IForm<18, 1, 1,
113119 (outs), (ins aaddr:$func),
715721 isPPC64;
716722 def : Pat<(PPCaddTls G8RC:$in, tglobaltlsaddr:$g),
717723 (ADD8TLS G8RC:$in, tglobaltlsaddr:$g)>;
724 def ADDIStlsgdHA: Pseudo<(outs G8RC:$rD), (ins G8RC:$reg, symbolHi64:$disp),
725 "#ADDIStlsgdHA",
726 [(set G8RC:$rD,
727 (PPCaddisTlsgdHA G8RC:$reg, tglobaladdr:$disp))]>,
728 isPPC64;
729 def ADDItlsgdL : Pseudo<(outs G8RC:$rD), (ins G8RC:$reg, symbolLo64:$disp),
730 "#ADDItlsgdL",
731 [(set G8RC:$rD,
732 (PPCaddiTlsgdL G8RC:$reg, tglobaladdr:$disp))]>,
733 isPPC64;
734 def GETtlsADDR : Pseudo<(outs G8RC:$rD), (ins G8RC:$reg, tlsgd:$sym),
735 "#GETtlsADDR",
736 [(set G8RC:$rD,
737 (PPCgetTlsAddr G8RC:$reg, tglobaladdr:$sym))]>,
738 isPPC64;
718739
719740 let PPC970_Unit = 2 in {
720741 // Truncating stores.
9292
9393 def PPCldGotTprel : SDNode<"PPCISD::LD_GOT_TPREL", SDTIntBinOp, [SDNPMayLoad]>;
9494 def PPCaddTls : SDNode<"PPCISD::ADD_TLS", SDTIntBinOp, []>;
95 def PPCaddisTlsgdHA : SDNode<"PPCISD::ADDIS_TLSGD_HA", SDTIntBinOp>;
96 def PPCaddiTlsgdL : SDNode<"PPCISD::ADDI_TLSGD_L", SDTIntBinOp>;
97 def PPCgetTlsAddr : SDNode<"PPCISD::GET_TLS_ADDR", SDTIntBinOp>;
9598
9699 def PPCvperm : SDNode<"PPCISD::VPERM", SDT_PPCvperm, []>;
97100
0 ; RUN: llc -mcpu=pwr7 -O0 -filetype=obj -relocation-model=pic %s -o - | \
1 ; RUN: elf-dump --dump-section-data | FileCheck %s
2
3 ; Test correct relocation generation for thread-local storage using
4 ; the general dynamic model and integrated assembly.
5
6 target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
7 target triple = "powerpc64-unknown-linux-gnu"
8
9 @a = thread_local global i32 0, align 4
10
11 define signext i32 @main() nounwind {
12 entry:
13 %retval = alloca i32, align 4
14 store i32 0, i32* %retval
15 %0 = load i32* @a, align 4
16 ret i32 %0
17 }
18
19 ; Verify generation of R_PPC64_GOT_TLSGD16_HA, R_PPC64_GOT_TLSGD16_LO,
20 ; and R_PPC64_TLSGD for accessing external variable a, and R_PPC64_REL24
21 ; for the call to __tls_get_addr.
22 ;
23 ; CHECK: '.rela.text'
24 ; CHECK: Relocation 0
25 ; CHECK-NEXT: 'r_offset'
26 ; CHECK-NEXT: 'r_sym', 0x[[SYM1:[0-9a-f]+]]
27 ; CHECK-NEXT: 'r_type', 0x00000052
28 ; CHECK: Relocation 1
29 ; CHECK-NEXT: 'r_offset'
30 ; CHECK-NEXT: 'r_sym', 0x[[SYM1]]
31 ; CHECK-NEXT: 'r_type', 0x00000050
32 ; CHECK: Relocation 2
33 ; CHECK-NEXT: 'r_offset'
34 ; CHECK-NEXT: 'r_sym', 0x[[SYM1]]
35 ; CHECK-NEXT: 'r_type', 0x0000006b
36 ; CHECK: Relocation 3
37 ; CHECK-NEXT: 'r_offset'
38 ; CHECK-NEXT: 'r_sym', 0x{{[0-9a-f]+}}
39 ; CHECK-NEXT: 'r_type', 0x0000000a
40
0 ; RUN: llc -mcpu=pwr7 -O0 -relocation-model=pic < %s | FileCheck %s
1
2 ; Test correct assembly code generation for thread-local storage using
3 ; the general dynamic model.
4
5 target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
6 target triple = "powerpc64-unknown-linux-gnu"
7
8 @a = thread_local global i32 0, align 4
9
10 define signext i32 @main() nounwind {
11 entry:
12 %retval = alloca i32, align 4
13 store i32 0, i32* %retval
14 %0 = load i32* @a, align 4
15 ret i32 %0
16 }
17
18 ; CHECK: addis [[REG:[0-9]+]], 2, a@got@tlsgd@ha
19 ; CHECK-NEXT: addi 3, [[REG]], a@got@tlsgd@l
20 ; CHECK-NEXT: bl __tls_get_addr(a@tlsgd)
21 ; CHECK-NEXT: nop
22