1 Pull in r200961 from upstream llvm trunk (by Venkatraman Govindaraju):
3 [Sparc] Emit correct relocations for PIC code when integrated assembler is used.
5 Introduced here: http://svnweb.freebsd.org/changeset/base/262261
7 Index: test/CodeGen/SPARC/obj-relocs.ll
8 ===================================================================
9 --- test/CodeGen/SPARC/obj-relocs.ll
10 +++ test/CodeGen/SPARC/obj-relocs.ll
12 +; RUN: llc < %s -march=sparcv9 -filetype=obj --relocation-model=static | llvm-readobj -r | FileCheck %s --check-prefix=CHECK-ABS
13 +; RUN: llc < %s -march=sparcv9 -filetype=obj --relocation-model=pic | llvm-readobj -r | FileCheck %s --check-prefix=CHECK-PIC
15 +;CHECK-ABS: Relocations [
16 +;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_H44 AGlobalVar 0x0
17 +;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_M44 AGlobalVar 0x0
18 +;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_L44 AGlobalVar 0x0
19 +;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_WDISP30 bar 0x0
22 +; CHECK-PIC: Relocations [
23 +; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x4
24 +; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x8
25 +; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_GOT22 AGlobalVar 0x0
26 +; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_GOT10 AGlobalVar 0x0
27 +; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_WPLT30 bar 0x0
31 +@AGlobalVar = global i64 0, align 8
33 +; CHECK-ASM: sethi %h44(AGlobalVar), [[R:%[goli][0-7]]]
34 +; CHECK-ASM: add [[R]], %m44(AGlobalVar), [[R]]
35 +define i64 @foo(i64 %a) {
37 + %0 = load i64* @AGlobalVar, align 4
39 + %2 = call i64 @bar(i64 %1)
44 +declare i64 @bar(i64)
45 Index: lib/Target/Sparc/SparcISelLowering.cpp
46 ===================================================================
47 --- lib/Target/Sparc/SparcISelLowering.cpp
48 +++ lib/Target/Sparc/SparcISelLowering.cpp
49 @@ -895,10 +895,12 @@ SparcTargetLowering::LowerCall_32(TargetLowering::
50 // If the callee is a GlobalAddress node (quite common, every direct call is)
51 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
52 // Likewise ExternalSymbol -> TargetExternalSymbol.
53 + unsigned TF = ((getTargetMachine().getRelocationModel() == Reloc::PIC_)
54 + ? SparcMCExpr::VK_Sparc_WPLT30 : 0);
55 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
56 - Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32);
57 + Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32, 0, TF);
58 else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
59 - Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32);
60 + Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32, TF);
62 // Returns a chain & a flag for retval copy to use
63 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
64 @@ -1209,10 +1211,13 @@ SparcTargetLowering::LowerCall_64(TargetLowering::
65 // Likewise ExternalSymbol -> TargetExternalSymbol.
66 SDValue Callee = CLI.Callee;
67 bool hasReturnsTwice = hasReturnsTwiceAttr(DAG, Callee, CLI.CS);
68 + unsigned TF = ((getTargetMachine().getRelocationModel() == Reloc::PIC_)
69 + ? SparcMCExpr::VK_Sparc_WPLT30 : 0);
70 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
71 - Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy());
72 + Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy(), 0,
74 else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
75 - Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy());
76 + Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy(), TF);
78 // Build the operands for the call instruction itself.
79 SmallVector<SDValue, 8> Ops;
80 @@ -1796,8 +1801,8 @@ SDValue SparcTargetLowering::makeAddress(SDValue O
81 // Handle PIC mode first.
82 if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
83 // This is the pic32 code model, the GOT is known to be smaller than 4GB.
84 - SDValue HiLo = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_HI,
85 - SparcMCExpr::VK_Sparc_LO, DAG);
86 + SDValue HiLo = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_GOT22,
87 + SparcMCExpr::VK_Sparc_GOT10, DAG);
88 SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, VT);
89 SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, HiLo);
90 // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this
91 Index: lib/Target/Sparc/SparcAsmPrinter.cpp
92 ===================================================================
93 --- lib/Target/Sparc/SparcAsmPrinter.cpp
94 +++ lib/Target/Sparc/SparcAsmPrinter.cpp
95 @@ -232,12 +232,12 @@ void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(co
96 MCOperand Callee = createPCXCallOP(EndLabel, OutContext);
97 EmitCall(OutStreamer, Callee);
98 OutStreamer.EmitLabel(SethiLabel);
99 - MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_HI,
100 + MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_PC22,
101 GOTLabel, StartLabel, SethiLabel,
103 EmitSETHI(OutStreamer, hiImm, MCRegOP);
104 OutStreamer.EmitLabel(EndLabel);
105 - MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_LO,
106 + MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_PC10,
107 GOTLabel, StartLabel, EndLabel,
109 EmitOR(OutStreamer, MCRegOP, loImm, MCRegOP);
110 Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
111 ===================================================================
112 --- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
113 +++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
114 @@ -26,6 +26,7 @@ static unsigned adjustFixupValue(unsigned Kind, ui
118 + case Sparc::fixup_sparc_wplt30:
119 case Sparc::fixup_sparc_call30:
120 return (Value >> 2) & 0x3fffffff;
121 case Sparc::fixup_sparc_br22:
122 @@ -32,8 +33,12 @@ static unsigned adjustFixupValue(unsigned Kind, ui
123 return (Value >> 2) & 0x3fffff;
124 case Sparc::fixup_sparc_br19:
125 return (Value >> 2) & 0x7ffff;
126 + case Sparc::fixup_sparc_pc22:
127 + case Sparc::fixup_sparc_got22:
128 case Sparc::fixup_sparc_hi22:
129 return (Value >> 10) & 0x3fffff;
130 + case Sparc::fixup_sparc_pc10:
131 + case Sparc::fixup_sparc_got10:
132 case Sparc::fixup_sparc_lo10:
133 return Value & 0x3ff;
134 case Sparc::fixup_sparc_h44:
135 @@ -72,6 +77,11 @@ namespace {
136 { "fixup_sparc_l44", 20, 12, 0 },
137 { "fixup_sparc_hh", 10, 22, 0 },
138 { "fixup_sparc_hm", 22, 10, 0 },
139 + { "fixup_sparc_pc22", 10, 22, MCFixupKindInfo::FKF_IsPCRel },
140 + { "fixup_sparc_pc10", 22, 10, MCFixupKindInfo::FKF_IsPCRel },
141 + { "fixup_sparc_got22", 10, 22, 0 },
142 + { "fixup_sparc_got10", 22, 10, 0 },
143 + { "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel }
146 if (Kind < FirstTargetFixupKind)
147 @@ -82,6 +92,20 @@ namespace {
148 return Infos[Kind - FirstTargetFixupKind];
151 + void processFixupValue(const MCAssembler &Asm,
152 + const MCAsmLayout &Layout,
153 + const MCFixup &Fixup,
154 + const MCFragment *DF,
157 + bool &IsResolved) {
158 + switch ((Sparc::Fixups)Fixup.getKind()) {
160 + case Sparc::fixup_sparc_wplt30: IsResolved = false; break;
165 bool mayNeedRelaxation(const MCInst &Inst) const {
168 Index: lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
169 ===================================================================
170 --- lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
171 +++ lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
172 @@ -48,6 +48,21 @@ namespace llvm {
173 /// fixup_sparc_hm - 10-bit fixup corresponding to %hm(foo)
176 + /// fixup_sparc_pc22 - 22-bit fixup corresponding to %pc22(foo)
179 + /// fixup_sparc_pc10 - 10-bit fixup corresponding to %pc10(foo)
182 + /// fixup_sparc_got22 - 22-bit fixup corresponding to %got22(foo)
185 + /// fixup_sparc_got10 - 10-bit fixup corresponding to %got10(foo)
188 + /// fixup_sparc_wplt30
189 + fixup_sparc_wplt30,
193 NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
194 Index: lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
195 ===================================================================
196 --- lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
197 +++ lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
200 //===----------------------------------------------------------------------===//
202 +#include "MCTargetDesc/SparcFixupKinds.h"
203 +#include "MCTargetDesc/SparcMCExpr.h"
204 #include "MCTargetDesc/SparcMCTargetDesc.h"
205 -#include "MCTargetDesc/SparcFixupKinds.h"
206 #include "llvm/ADT/STLExtras.h"
207 #include "llvm/MC/MCELFObjectWriter.h"
208 #include "llvm/MC/MCExpr.h"
209 @@ -31,6 +32,11 @@ namespace {
210 bool IsPCRel, bool IsRelocWithSymbol,
211 int64_t Addend) const;
213 + virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
214 + const MCValue &Target,
215 + const MCFragment &F,
216 + const MCFixup &Fixup,
217 + bool IsPCRel) const;
221 @@ -40,6 +46,12 @@ unsigned SparcELFObjectWriter::GetRelocType(const
223 bool IsRelocWithSymbol,
224 int64_t Addend) const {
226 + if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Fixup.getValue())) {
227 + if (SExpr->getKind() == SparcMCExpr::VK_Sparc_R_DISP32)
228 + return ELF::R_SPARC_DISP32;
232 switch((unsigned)Fixup.getKind()) {
234 @@ -51,6 +63,9 @@ unsigned SparcELFObjectWriter::GetRelocType(const
235 case Sparc::fixup_sparc_call30: return ELF::R_SPARC_WDISP30;
236 case Sparc::fixup_sparc_br22: return ELF::R_SPARC_WDISP22;
237 case Sparc::fixup_sparc_br19: return ELF::R_SPARC_WDISP19;
238 + case Sparc::fixup_sparc_pc22: return ELF::R_SPARC_PC22;
239 + case Sparc::fixup_sparc_pc10: return ELF::R_SPARC_PC10;
240 + case Sparc::fixup_sparc_wplt30: return ELF::R_SPARC_WPLT30;
244 @@ -74,10 +89,30 @@ unsigned SparcELFObjectWriter::GetRelocType(const
245 case Sparc::fixup_sparc_l44: return ELF::R_SPARC_L44;
246 case Sparc::fixup_sparc_hh: return ELF::R_SPARC_HH22;
247 case Sparc::fixup_sparc_hm: return ELF::R_SPARC_HM10;
248 + case Sparc::fixup_sparc_got22: return ELF::R_SPARC_GOT22;
249 + case Sparc::fixup_sparc_got10: return ELF::R_SPARC_GOT10;
252 return ELF::R_SPARC_NONE;
255 +const MCSymbol *SparcELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
256 + const MCValue &Target,
257 + const MCFragment &F,
258 + const MCFixup &Fixup,
259 + bool IsPCRel) const {
261 + if (!Target.getSymA())
263 + switch((unsigned)Fixup.getKind()) {
265 + case Sparc::fixup_sparc_got22:
266 + case Sparc::fixup_sparc_got10:
267 + return &Target.getSymA()->getSymbol().AliasedSymbol();
272 MCObjectWriter *llvm::createSparcELFObjectWriter(raw_ostream &OS,
275 Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
276 ===================================================================
277 --- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
278 +++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
280 #include "llvm/MC/MCContext.h"
281 #include "llvm/MC/MCAssembler.h"
282 #include "llvm/MC/MCELF.h"
283 +#include "llvm/MC/MCSymbol.h"
284 #include "llvm/Object/ELF.h"
287 @@ -54,6 +55,13 @@ bool SparcMCExpr::printVariantKind(raw_ostream &OS
288 case VK_Sparc_L44: OS << "%l44("; break;
289 case VK_Sparc_HH: OS << "%hh("; break;
290 case VK_Sparc_HM: OS << "%hm("; break;
291 + // FIXME: use %pc22/%pc10, if system assembler supports them.
292 + case VK_Sparc_PC22: OS << "%hi("; break;
293 + case VK_Sparc_PC10: OS << "%lo("; break;
294 + // FIXME: use %got22/%got10, if system assembler supports them.
295 + case VK_Sparc_GOT22: OS << "%hi("; break;
296 + case VK_Sparc_GOT10: OS << "%lo("; break;
297 + case VK_Sparc_WPLT30: closeParen = false; break;
298 case VK_Sparc_R_DISP32: OS << "%r_disp32("; break;
299 case VK_Sparc_TLS_GD_HI22: OS << "%tgd_hi22("; break;
300 case VK_Sparc_TLS_GD_LO10: OS << "%tgd_lo10("; break;
301 @@ -87,6 +95,10 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariant
302 .Case("l44", VK_Sparc_L44)
303 .Case("hh", VK_Sparc_HH)
304 .Case("hm", VK_Sparc_HM)
305 + .Case("pc22", VK_Sparc_PC22)
306 + .Case("pc10", VK_Sparc_PC10)
307 + .Case("got22", VK_Sparc_GOT22)
308 + .Case("got10", VK_Sparc_GOT10)
309 .Case("r_disp32", VK_Sparc_R_DISP32)
310 .Case("tgd_hi22", VK_Sparc_TLS_GD_HI22)
311 .Case("tgd_lo10", VK_Sparc_TLS_GD_LO10)
312 @@ -109,9 +121,26 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariant
313 .Default(VK_Sparc_None);
316 +Sparc::Fixups SparcMCExpr::getFixupKind(SparcMCExpr::VariantKind Kind) {
318 + default: assert(0 && "Unhandled SparcMCExpr::VariantKind");
319 + case VK_Sparc_LO: return Sparc::fixup_sparc_lo10;
320 + case VK_Sparc_HI: return Sparc::fixup_sparc_hi22;
321 + case VK_Sparc_H44: return Sparc::fixup_sparc_h44;
322 + case VK_Sparc_M44: return Sparc::fixup_sparc_m44;
323 + case VK_Sparc_L44: return Sparc::fixup_sparc_l44;
324 + case VK_Sparc_HH: return Sparc::fixup_sparc_hh;
325 + case VK_Sparc_HM: return Sparc::fixup_sparc_hm;
326 + case VK_Sparc_PC22: return Sparc::fixup_sparc_pc22;
327 + case VK_Sparc_PC10: return Sparc::fixup_sparc_pc10;
328 + case VK_Sparc_GOT22: return Sparc::fixup_sparc_got22;
329 + case VK_Sparc_GOT10: return Sparc::fixup_sparc_got10;
334 SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
335 - const MCAsmLayout *Layout) const {
336 + const MCAsmLayout *Layout) const {
339 return getSubExpr()->EvaluateAsRelocatable(Res, *Layout);
340 Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
341 ===================================================================
342 --- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
343 +++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
345 #ifndef LLVM_SPARCMCEXPR_H
346 #define LLVM_SPARCMCEXPR_H
348 +#include "SparcFixupKinds.h"
349 #include "llvm/MC/MCExpr.h"
352 @@ -31,6 +32,11 @@ class SparcMCExpr : public MCTargetExpr {
362 VK_Sparc_TLS_GD_HI22,
363 VK_Sparc_TLS_GD_LO10,
364 @@ -75,6 +81,9 @@ class SparcMCExpr : public MCTargetExpr {
365 /// getSubExpr - Get the child of this expression.
366 const MCExpr *getSubExpr() const { return Expr; }
368 + /// getFixupKind - Get the fixup kind of this expression.
369 + Sparc::Fixups getFixupKind() const { return getFixupKind(Kind); }
372 void PrintImpl(raw_ostream &OS) const;
373 bool EvaluateAsRelocatableImpl(MCValue &Res,
374 @@ -94,6 +103,7 @@ class SparcMCExpr : public MCTargetExpr {
376 static VariantKind parseVariantKind(StringRef name);
377 static bool printVariantKind(raw_ostream &OS, VariantKind Kind);
378 + static Sparc::Fixups getFixupKind(VariantKind Kind);
381 } // end namespace llvm.
382 Index: lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
383 ===================================================================
384 --- lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
385 +++ lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
386 @@ -94,37 +94,8 @@ getMachineOpValue(const MCInst &MI, const MCOperan
388 const MCExpr *Expr = MO.getExpr();
389 if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) {
390 - switch(SExpr->getKind()) {
391 - default: assert(0 && "Unhandled sparc expression!"); break;
392 - case SparcMCExpr::VK_Sparc_LO:
393 - Fixups.push_back(MCFixup::Create(0, Expr,
394 - (MCFixupKind)Sparc::fixup_sparc_lo10));
396 - case SparcMCExpr::VK_Sparc_HI:
397 - Fixups.push_back(MCFixup::Create(0, Expr,
398 - (MCFixupKind)Sparc::fixup_sparc_hi22));
400 - case SparcMCExpr::VK_Sparc_H44:
401 - Fixups.push_back(MCFixup::Create(0, Expr,
402 - (MCFixupKind)Sparc::fixup_sparc_h44));
404 - case SparcMCExpr::VK_Sparc_M44:
405 - Fixups.push_back(MCFixup::Create(0, Expr,
406 - (MCFixupKind)Sparc::fixup_sparc_m44));
408 - case SparcMCExpr::VK_Sparc_L44:
409 - Fixups.push_back(MCFixup::Create(0, Expr,
410 - (MCFixupKind)Sparc::fixup_sparc_l44));
412 - case SparcMCExpr::VK_Sparc_HH:
413 - Fixups.push_back(MCFixup::Create(0, Expr,
414 - (MCFixupKind)Sparc::fixup_sparc_hh));
416 - case SparcMCExpr::VK_Sparc_HM:
417 - Fixups.push_back(MCFixup::Create(0, Expr,
418 - (MCFixupKind)Sparc::fixup_sparc_hm));
421 + MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind();
422 + Fixups.push_back(MCFixup::Create(0, Expr, Kind));
426 @@ -143,8 +114,15 @@ getCallTargetOpValue(const MCInst &MI, unsigned Op
427 if (MO.isReg() || MO.isImm())
428 return getMachineOpValue(MI, MO, Fixups);
430 - Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
431 - (MCFixupKind)Sparc::fixup_sparc_call30));
432 + MCFixupKind fixupKind = (MCFixupKind)Sparc::fixup_sparc_call30;
434 + if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(MO.getExpr())) {
435 + if (SExpr->getKind() == SparcMCExpr::VK_Sparc_WPLT30)
436 + fixupKind = (MCFixupKind)Sparc::fixup_sparc_wplt30;
439 + Fixups.push_back(MCFixup::Create(0, MO.getExpr(), fixupKind));