1 Pull in r200962 from upstream llvm trunk (by Venkatraman Govindaraju):
3 [Sparc] Emit relocations for Thread Local Storage (TLS) when integrated assembler is used.
5 Introduced here: http://svn.freebsd.org/changeset/base/262261
7 Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
8 ===================================================================
9 --- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
10 +++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
11 @@ -26,31 +26,65 @@ static unsigned adjustFixupValue(unsigned Kind, ui
16 case Sparc::fixup_sparc_wplt30:
17 case Sparc::fixup_sparc_call30:
18 return (Value >> 2) & 0x3fffffff;
20 case Sparc::fixup_sparc_br22:
21 return (Value >> 2) & 0x3fffff;
23 case Sparc::fixup_sparc_br19:
24 return (Value >> 2) & 0x7ffff;
26 case Sparc::fixup_sparc_pc22:
27 case Sparc::fixup_sparc_got22:
28 + case Sparc::fixup_sparc_tls_gd_hi22:
29 + case Sparc::fixup_sparc_tls_ldm_hi22:
30 + case Sparc::fixup_sparc_tls_ie_hi22:
31 case Sparc::fixup_sparc_hi22:
32 return (Value >> 10) & 0x3fffff;
34 case Sparc::fixup_sparc_pc10:
35 case Sparc::fixup_sparc_got10:
36 + case Sparc::fixup_sparc_tls_gd_lo10:
37 + case Sparc::fixup_sparc_tls_ldm_lo10:
38 + case Sparc::fixup_sparc_tls_ie_lo10:
39 case Sparc::fixup_sparc_lo10:
42 + case Sparc::fixup_sparc_tls_ldo_hix22:
43 + case Sparc::fixup_sparc_tls_le_hix22:
44 + return (~Value >> 10) & 0x3fffff;
46 + case Sparc::fixup_sparc_tls_ldo_lox10:
47 + case Sparc::fixup_sparc_tls_le_lox10:
48 + return (~(~Value & 0x3ff)) & 0x1fff;
50 case Sparc::fixup_sparc_h44:
51 return (Value >> 22) & 0x3fffff;
53 case Sparc::fixup_sparc_m44:
54 return (Value >> 12) & 0x3ff;
56 case Sparc::fixup_sparc_l44:
59 case Sparc::fixup_sparc_hh:
60 return (Value >> 42) & 0x3fffff;
62 case Sparc::fixup_sparc_hm:
63 return (Value >> 32) & 0x3ff;
65 + case Sparc::fixup_sparc_tls_gd_add:
66 + case Sparc::fixup_sparc_tls_gd_call:
67 + case Sparc::fixup_sparc_tls_ldm_add:
68 + case Sparc::fixup_sparc_tls_ldm_call:
69 + case Sparc::fixup_sparc_tls_ldo_add:
70 + case Sparc::fixup_sparc_tls_ie_ld:
71 + case Sparc::fixup_sparc_tls_ie_ldx:
72 + case Sparc::fixup_sparc_tls_ie_add:
77 @@ -81,7 +115,25 @@ namespace {
78 { "fixup_sparc_pc10", 22, 10, MCFixupKindInfo::FKF_IsPCRel },
79 { "fixup_sparc_got22", 10, 22, 0 },
80 { "fixup_sparc_got10", 22, 10, 0 },
81 - { "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel }
82 + { "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
83 + { "fixup_sparc_tls_gd_hi22", 10, 22, 0 },
84 + { "fixup_sparc_tls_gd_lo10", 22, 10, 0 },
85 + { "fixup_sparc_tls_gd_add", 0, 0, 0 },
86 + { "fixup_sparc_tls_gd_call", 0, 0, 0 },
87 + { "fixup_sparc_tls_ldm_hi22", 10, 22, 0 },
88 + { "fixup_sparc_tls_ldm_lo10", 22, 10, 0 },
89 + { "fixup_sparc_tls_ldm_add", 0, 0, 0 },
90 + { "fixup_sparc_tls_ldm_call", 0, 0, 0 },
91 + { "fixup_sparc_tls_ldo_hix22", 10, 22, 0 },
92 + { "fixup_sparc_tls_ldo_lox10", 22, 10, 0 },
93 + { "fixup_sparc_tls_ldo_add", 0, 0, 0 },
94 + { "fixup_sparc_tls_ie_hi22", 10, 22, 0 },
95 + { "fixup_sparc_tls_ie_lo10", 22, 10, 0 },
96 + { "fixup_sparc_tls_ie_ld", 0, 0, 0 },
97 + { "fixup_sparc_tls_ie_ldx", 0, 0, 0 },
98 + { "fixup_sparc_tls_ie_add", 0, 0, 0 },
99 + { "fixup_sparc_tls_le_hix22", 0, 0, 0 },
100 + { "fixup_sparc_tls_le_lox10", 0, 0, 0 }
103 if (Kind < FirstTargetFixupKind)
104 @@ -101,11 +153,28 @@ namespace {
106 switch ((Sparc::Fixups)Fixup.getKind()) {
108 - case Sparc::fixup_sparc_wplt30: IsResolved = false; break;
109 + case Sparc::fixup_sparc_wplt30:
110 + case Sparc::fixup_sparc_tls_gd_hi22:
111 + case Sparc::fixup_sparc_tls_gd_lo10:
112 + case Sparc::fixup_sparc_tls_gd_add:
113 + case Sparc::fixup_sparc_tls_gd_call:
114 + case Sparc::fixup_sparc_tls_ldm_hi22:
115 + case Sparc::fixup_sparc_tls_ldm_lo10:
116 + case Sparc::fixup_sparc_tls_ldm_add:
117 + case Sparc::fixup_sparc_tls_ldm_call:
118 + case Sparc::fixup_sparc_tls_ldo_hix22:
119 + case Sparc::fixup_sparc_tls_ldo_lox10:
120 + case Sparc::fixup_sparc_tls_ldo_add:
121 + case Sparc::fixup_sparc_tls_ie_hi22:
122 + case Sparc::fixup_sparc_tls_ie_lo10:
123 + case Sparc::fixup_sparc_tls_ie_ld:
124 + case Sparc::fixup_sparc_tls_ie_ldx:
125 + case Sparc::fixup_sparc_tls_ie_add:
126 + case Sparc::fixup_sparc_tls_le_hix22:
127 + case Sparc::fixup_sparc_tls_le_lox10: IsResolved = false; break;
132 bool mayNeedRelaxation(const MCInst &Inst) const {
135 Index: lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
136 ===================================================================
137 --- lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
138 +++ lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
139 @@ -63,6 +63,26 @@ namespace llvm {
140 /// fixup_sparc_wplt30
143 + /// fixups for Thread Local Storage
144 + fixup_sparc_tls_gd_hi22,
145 + fixup_sparc_tls_gd_lo10,
146 + fixup_sparc_tls_gd_add,
147 + fixup_sparc_tls_gd_call,
148 + fixup_sparc_tls_ldm_hi22,
149 + fixup_sparc_tls_ldm_lo10,
150 + fixup_sparc_tls_ldm_add,
151 + fixup_sparc_tls_ldm_call,
152 + fixup_sparc_tls_ldo_hix22,
153 + fixup_sparc_tls_ldo_lox10,
154 + fixup_sparc_tls_ldo_add,
155 + fixup_sparc_tls_ie_hi22,
156 + fixup_sparc_tls_ie_lo10,
157 + fixup_sparc_tls_ie_ld,
158 + fixup_sparc_tls_ie_ldx,
159 + fixup_sparc_tls_ie_add,
160 + fixup_sparc_tls_le_hix22,
161 + fixup_sparc_tls_le_lox10,
165 NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
166 Index: lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
167 ===================================================================
168 --- lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
169 +++ lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
170 @@ -91,6 +91,24 @@ unsigned SparcELFObjectWriter::GetRelocType(const
171 case Sparc::fixup_sparc_hm: return ELF::R_SPARC_HM10;
172 case Sparc::fixup_sparc_got22: return ELF::R_SPARC_GOT22;
173 case Sparc::fixup_sparc_got10: return ELF::R_SPARC_GOT10;
174 + case Sparc::fixup_sparc_tls_gd_hi22: return ELF::R_SPARC_TLS_GD_HI22;
175 + case Sparc::fixup_sparc_tls_gd_lo10: return ELF::R_SPARC_TLS_GD_LO10;
176 + case Sparc::fixup_sparc_tls_gd_add: return ELF::R_SPARC_TLS_GD_ADD;
177 + case Sparc::fixup_sparc_tls_gd_call: return ELF::R_SPARC_TLS_GD_CALL;
178 + case Sparc::fixup_sparc_tls_ldm_hi22: return ELF::R_SPARC_TLS_LDM_HI22;
179 + case Sparc::fixup_sparc_tls_ldm_lo10: return ELF::R_SPARC_TLS_LDM_LO10;
180 + case Sparc::fixup_sparc_tls_ldm_add: return ELF::R_SPARC_TLS_LDM_ADD;
181 + case Sparc::fixup_sparc_tls_ldm_call: return ELF::R_SPARC_TLS_LDM_CALL;
182 + case Sparc::fixup_sparc_tls_ldo_hix22: return ELF::R_SPARC_TLS_LDO_HIX22;
183 + case Sparc::fixup_sparc_tls_ldo_lox10: return ELF::R_SPARC_TLS_LDO_LOX10;
184 + case Sparc::fixup_sparc_tls_ldo_add: return ELF::R_SPARC_TLS_LDO_ADD;
185 + case Sparc::fixup_sparc_tls_ie_hi22: return ELF::R_SPARC_TLS_IE_HI22;
186 + case Sparc::fixup_sparc_tls_ie_lo10: return ELF::R_SPARC_TLS_IE_LO10;
187 + case Sparc::fixup_sparc_tls_ie_ld: return ELF::R_SPARC_TLS_IE_LD;
188 + case Sparc::fixup_sparc_tls_ie_ldx: return ELF::R_SPARC_TLS_IE_LDX;
189 + case Sparc::fixup_sparc_tls_ie_add: return ELF::R_SPARC_TLS_IE_ADD;
190 + case Sparc::fixup_sparc_tls_le_hix22: return ELF::R_SPARC_TLS_LE_HIX22;
191 + case Sparc::fixup_sparc_tls_le_lox10: return ELF::R_SPARC_TLS_LE_LOX10;
194 return ELF::R_SPARC_NONE;
195 Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
196 ===================================================================
197 --- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
198 +++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
199 @@ -135,6 +135,25 @@ Sparc::Fixups SparcMCExpr::getFixupKind(SparcMCExp
200 case VK_Sparc_PC10: return Sparc::fixup_sparc_pc10;
201 case VK_Sparc_GOT22: return Sparc::fixup_sparc_got22;
202 case VK_Sparc_GOT10: return Sparc::fixup_sparc_got10;
203 + case VK_Sparc_WPLT30: return Sparc::fixup_sparc_wplt30;
204 + case VK_Sparc_TLS_GD_HI22: return Sparc::fixup_sparc_tls_gd_hi22;
205 + case VK_Sparc_TLS_GD_LO10: return Sparc::fixup_sparc_tls_gd_lo10;
206 + case VK_Sparc_TLS_GD_ADD: return Sparc::fixup_sparc_tls_gd_add;
207 + case VK_Sparc_TLS_GD_CALL: return Sparc::fixup_sparc_tls_gd_call;
208 + case VK_Sparc_TLS_LDM_HI22: return Sparc::fixup_sparc_tls_ldm_hi22;
209 + case VK_Sparc_TLS_LDM_LO10: return Sparc::fixup_sparc_tls_ldm_lo10;
210 + case VK_Sparc_TLS_LDM_ADD: return Sparc::fixup_sparc_tls_ldm_add;
211 + case VK_Sparc_TLS_LDM_CALL: return Sparc::fixup_sparc_tls_ldm_call;
212 + case VK_Sparc_TLS_LDO_HIX22: return Sparc::fixup_sparc_tls_ldo_hix22;
213 + case VK_Sparc_TLS_LDO_LOX10: return Sparc::fixup_sparc_tls_ldo_lox10;
214 + case VK_Sparc_TLS_LDO_ADD: return Sparc::fixup_sparc_tls_ldo_add;
215 + case VK_Sparc_TLS_IE_HI22: return Sparc::fixup_sparc_tls_ie_hi22;
216 + case VK_Sparc_TLS_IE_LO10: return Sparc::fixup_sparc_tls_ie_lo10;
217 + case VK_Sparc_TLS_IE_LD: return Sparc::fixup_sparc_tls_ie_ld;
218 + case VK_Sparc_TLS_IE_LDX: return Sparc::fixup_sparc_tls_ie_ldx;
219 + case VK_Sparc_TLS_IE_ADD: return Sparc::fixup_sparc_tls_ie_add;
220 + case VK_Sparc_TLS_LE_HIX22: return Sparc::fixup_sparc_tls_le_hix22;
221 + case VK_Sparc_TLS_LE_LOX10: return Sparc::fixup_sparc_tls_le_lox10;
225 @@ -147,7 +166,33 @@ SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Re
228 static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
229 - assert(0 && "Implement fixELFSymbolsInTLSFixupsImpl!");
230 + switch (Expr->getKind()) {
231 + case MCExpr::Target:
232 + llvm_unreachable("Can't handle nested target expr!");
235 + case MCExpr::Constant:
238 + case MCExpr::Binary: {
239 + const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
240 + fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm);
241 + fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm);
245 + case MCExpr::SymbolRef: {
246 + const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
247 + MCSymbolData &SD = Asm.getOrCreateSymbolData(SymRef.getSymbol());
248 + MCELF::SetType(SD, ELF::STT_TLS);
252 + case MCExpr::Unary:
253 + fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);
259 void SparcMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
260 Index: lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
261 ===================================================================
262 --- lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
263 +++ lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
265 #include "llvm/MC/MCExpr.h"
266 #include "llvm/MC/MCInst.h"
267 #include "llvm/MC/MCRegisterInfo.h"
268 +#include "llvm/MC/MCSymbol.h"
269 #include "llvm/ADT/Statistic.h"
270 #include "llvm/Support/raw_ostream.h"
272 @@ -76,6 +77,21 @@ EncodeInstruction(const MCInst &MI, raw_ostream &O
273 OS << (char)(Bits >> 24);
276 + unsigned tlsOpNo = 0;
277 + switch (MI.getOpcode()) {
279 + case SP::TLS_CALL: tlsOpNo = 1; break;
280 + case SP::TLS_ADDrr:
281 + case SP::TLS_ADDXrr:
283 + case SP::TLS_LDXrr: tlsOpNo = 3; break;
285 + if (tlsOpNo != 0) {
286 + const MCOperand &MO = MI.getOperand(tlsOpNo);
287 + uint64_t op = getMachineOpValue(MI, MO, Fixups);
288 + assert(op == 0 && "Unexpected operand value!");
289 + (void)op; // suppress warning.
292 ++MCNumEmitted; // Keep track of the # of mi's emitted.
294 @@ -114,6 +130,21 @@ getCallTargetOpValue(const MCInst &MI, unsigned Op
295 if (MO.isReg() || MO.isImm())
296 return getMachineOpValue(MI, MO, Fixups);
298 + if (MI.getOpcode() == SP::TLS_CALL) {
299 + // No fixups for __tls_get_addr. Will emit for fixups for tls_symbol in
300 + // EncodeInstruction.
302 + // Verify that the callee is actually __tls_get_addr.
303 + const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(MO.getExpr());
304 + assert(SExpr && SExpr->getSubExpr()->getKind() == MCExpr::SymbolRef &&
305 + "Unexpected expression in TLS_CALL");
306 + const MCSymbolRefExpr *SymExpr = cast<MCSymbolRefExpr>(SExpr->getSubExpr());
307 + assert(SymExpr->getSymbol().getName() == "__tls_get_addr" &&
308 + "Unexpected function for TLS_CALL");
313 MCFixupKind fixupKind = (MCFixupKind)Sparc::fixup_sparc_call30;
315 if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(MO.getExpr())) {
316 Index: test/CodeGen/SPARC/tls.ll
317 ===================================================================
318 --- test/CodeGen/SPARC/tls.ll
319 +++ test/CodeGen/SPARC/tls.ll
321 ; RUN: llc <%s -march=sparc -relocation-model=pic | FileCheck %s --check-prefix=pic
322 ; RUN: llc <%s -march=sparcv9 -relocation-model=pic | FileCheck %s --check-prefix=pic
324 +; RUN: llc <%s -march=sparc -relocation-model=static -filetype=obj | llvm-readobj -r | FileCheck %s --check-prefix=v8abs-obj
325 +; RUN: llc <%s -march=sparcv9 -relocation-model=static -filetype=obj | llvm-readobj -r | FileCheck %s --check-prefix=v9abs-obj
326 +; RUN: llc <%s -march=sparc -relocation-model=pic -filetype=obj | llvm-readobj -r | FileCheck %s --check-prefix=pic-obj
327 +; RUN: llc <%s -march=sparcv9 -relocation-model=pic -filetype=obj | llvm-readobj -r | FileCheck %s --check-prefix=pic-obj
329 @local_symbol = internal thread_local global i32 0
330 @extern_symbol = external thread_local global i32
331 @@ -69,3 +73,47 @@ entry:
332 store i32 %1, i32* @extern_symbol, align 4
337 +; v8abs-obj: Relocations [
338 +; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LE_HIX22 local_symbol 0x0
339 +; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LE_LOX10 local_symbol 0x0
340 +; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_HI22 _GLOBAL_OFFSET_TABLE_ 0x0
341 +; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_LO10 _GLOBAL_OFFSET_TABLE_ 0x0
342 +; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_HI22 extern_symbol 0x0
343 +; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_LO10 extern_symbol 0x0
344 +; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_LD extern_symbol 0x0
345 +; v8abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_ADD extern_symbol 0x0
348 +; v9abs-obj: Relocations [
349 +; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LE_HIX22 local_symbol 0x0
350 +; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LE_LOX10 local_symbol 0x0
351 +; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_H44 _GLOBAL_OFFSET_TABLE_ 0x0
352 +; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_M44 _GLOBAL_OFFSET_TABLE_ 0x0
353 +; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_L44 _GLOBAL_OFFSET_TABLE_ 0x0
354 +; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_HI22 extern_symbol 0x0
355 +; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_LO10 extern_symbol 0x0
356 +; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_LDX extern_symbol 0x0
357 +; v9abs-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_IE_ADD extern_symbol 0x0
360 +; pic-obj: Relocations [
361 +; pic-obj: Section (2) .rela.text {
362 +; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x4
363 +; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x8
364 +; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDO_HIX22 local_symbol 0x0
365 +; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDO_LOX10 local_symbol 0x0
366 +; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDM_HI22 local_symbol 0x0
367 +; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDM_LO10 local_symbol 0x0
368 +; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDM_ADD local_symbol 0x0
369 +; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDM_CALL local_symbol 0x0
370 +; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_LDO_ADD local_symbol 0x0
371 +; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x4
372 +; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x8
373 +; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_GD_HI22 extern_symbol 0x0
374 +; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_GD_LO10 extern_symbol 0x0
375 +; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_GD_ADD extern_symbol 0x0
376 +; pic-obj: 0x{{[0-9,A-F]+}} R_SPARC_TLS_GD_CALL extern_symbol 0x0