]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/patches/patch-r262261-llvm-r198580-sparc.diff
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / patches / patch-r262261-llvm-r198580-sparc.diff
1 Pull in r198580 from upstream llvm trunk (by Venkatraman Govindaraju):
2
3   [Sparc] Add ELF Object Writer for Sparc. 
4
5 Introduced here: http://svnweb.freebsd.org/changeset/base/262261
6
7 Index: lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
8 ===================================================================
9 --- lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
10 +++ lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
11 @@ -12,6 +12,7 @@
12  //===----------------------------------------------------------------------===//
13  
14  #define DEBUG_TYPE "mccodeemitter"
15 +#include "SparcMCExpr.h"
16  #include "SparcMCTargetDesc.h"
17  #include "MCTargetDesc/SparcFixupKinds.h"
18  #include "llvm/MC/MCCodeEmitter.h"
19 @@ -92,6 +93,41 @@ getMachineOpValue(const MCInst &MI, const MCOperan
20  
21    assert(MO.isExpr());
22    const MCExpr *Expr = MO.getExpr();
23 +  if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) {
24 +    switch(SExpr->getKind()) {
25 +    default: assert(0 && "Unhandled sparc expression!"); break;
26 +    case SparcMCExpr::VK_Sparc_LO:
27 +      Fixups.push_back(MCFixup::Create(0, Expr,
28 +                                       (MCFixupKind)Sparc::fixup_sparc_lo10));
29 +      break;
30 +    case SparcMCExpr::VK_Sparc_HI:
31 +      Fixups.push_back(MCFixup::Create(0, Expr,
32 +                                       (MCFixupKind)Sparc::fixup_sparc_hi22));
33 +      break;
34 +    case SparcMCExpr::VK_Sparc_H44:
35 +      Fixups.push_back(MCFixup::Create(0, Expr,
36 +                                       (MCFixupKind)Sparc::fixup_sparc_h44));
37 +      break;
38 +    case SparcMCExpr::VK_Sparc_M44:
39 +      Fixups.push_back(MCFixup::Create(0, Expr,
40 +                                       (MCFixupKind)Sparc::fixup_sparc_m44));
41 +      break;
42 +    case SparcMCExpr::VK_Sparc_L44:
43 +      Fixups.push_back(MCFixup::Create(0, Expr,
44 +                                       (MCFixupKind)Sparc::fixup_sparc_l44));
45 +      break;
46 +    case SparcMCExpr::VK_Sparc_HH:
47 +      Fixups.push_back(MCFixup::Create(0, Expr,
48 +                                       (MCFixupKind)Sparc::fixup_sparc_hh));
49 +      break;
50 +    case SparcMCExpr::VK_Sparc_HM:
51 +      Fixups.push_back(MCFixup::Create(0, Expr,
52 +                                       (MCFixupKind)Sparc::fixup_sparc_hm));
53 +      break;
54 +    }
55 +    return 0;
56 +  }
57 +
58    int64_t Res;
59    if (Expr->EvaluateAsAbsolute(Res))
60      return Res;
61 Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
62 ===================================================================
63 --- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
64 +++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.cpp
65 @@ -89,6 +89,14 @@ static MCCodeGenInfo *createSparcV9MCCodeGenInfo(S
66    return X;
67  }
68  
69 +static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
70 +                                    MCContext &Context, MCAsmBackend &MAB,
71 +                                    raw_ostream &OS, MCCodeEmitter *Emitter,
72 +                                    bool RelaxAll, bool NoExecStack) {
73 +  SparcTargetELFStreamer *S = new SparcTargetELFStreamer();
74 +  return createELFStreamer(Context, S, MAB, OS, Emitter, RelaxAll, NoExecStack);
75 +}
76 +
77  static MCStreamer *
78  createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
79                      bool isVerboseAsm, bool useLoc, bool useCFI,
80 @@ -148,6 +156,13 @@ extern "C" void LLVMInitializeSparcTargetMC() {
81    TargetRegistry::RegisterMCAsmBackend(TheSparcV9Target,
82                                         createSparcAsmBackend);
83  
84 +  // Register the object streamer.
85 +  TargetRegistry::RegisterMCObjectStreamer(TheSparcTarget,
86 +                                           createMCStreamer);
87 +  TargetRegistry::RegisterMCObjectStreamer(TheSparcV9Target,
88 +                                           createMCStreamer);
89 +
90 +  // Register the asm streamer.
91    TargetRegistry::RegisterAsmStreamer(TheSparcTarget,
92                                        createMCAsmStreamer);
93    TargetRegistry::RegisterAsmStreamer(TheSparcV9Target,
94 Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
95 ===================================================================
96 --- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
97 +++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
98 @@ -10,6 +10,7 @@
99  #include "llvm/MC/MCAsmBackend.h"
100  #include "MCTargetDesc/SparcMCTargetDesc.h"
101  #include "MCTargetDesc/SparcFixupKinds.h"
102 +#include "llvm/MC/MCELFObjectWriter.h"
103  #include "llvm/MC/MCFixupKindInfo.h"
104  #include "llvm/MC/MCObjectWriter.h"
105  #include "llvm/Support/TargetRegistry.h"
106 @@ -16,11 +17,43 @@
107  
108  using namespace llvm;
109  
110 +static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
111 +  switch (Kind) {
112 +  default:
113 +    llvm_unreachable("Unknown fixup kind!");
114 +  case FK_Data_1:
115 +  case FK_Data_2:
116 +  case FK_Data_4:
117 +  case FK_Data_8:
118 +    return Value;
119 +  case Sparc::fixup_sparc_call30:
120 +    return Value & 0x3fffffff;
121 +  case Sparc::fixup_sparc_br22:
122 +    return Value & 0x3fffff;
123 +  case Sparc::fixup_sparc_br19:
124 +    return Value & 0x1ffff;
125 +  case Sparc::fixup_sparc_hi22:
126 +    return (Value >> 10) & 0x3fffff;
127 +  case Sparc::fixup_sparc_lo10:
128 +    return Value & 0x3ff;
129 +  case Sparc::fixup_sparc_h44:
130 +    return (Value >> 22) & 0x3fffff;
131 +  case Sparc::fixup_sparc_m44:
132 +    return (Value >> 12) & 0x3ff;
133 +  case Sparc::fixup_sparc_l44:
134 +    return Value & 0xfff;
135 +  case Sparc::fixup_sparc_hh:
136 +    return (Value >> 42) & 0x3fffff;
137 +  case Sparc::fixup_sparc_hm:
138 +    return (Value >>32) & 0x3ff;
139 +  }
140 +}
141 +
142  namespace {
143    class SparcAsmBackend : public MCAsmBackend {
144 -
145 +    const Target &TheTarget;
146    public:
147 -    SparcAsmBackend(const Target &T) : MCAsmBackend() {}
148 +    SparcAsmBackend(const Target &T) : MCAsmBackend(), TheTarget(T) {}
149  
150      unsigned getNumFixupKinds() const {
151        return Sparc::NumTargetFixupKinds;
152 @@ -31,7 +64,14 @@ namespace {
153          // name                    offset bits  flags
154          { "fixup_sparc_call30",     0,     30,  MCFixupKindInfo::FKF_IsPCRel },
155          { "fixup_sparc_br22",       0,     22,  MCFixupKindInfo::FKF_IsPCRel },
156 -        { "fixup_sparc_br19",       0,     19,  MCFixupKindInfo::FKF_IsPCRel }
157 +        { "fixup_sparc_br19",       0,     19,  MCFixupKindInfo::FKF_IsPCRel },
158 +        { "fixup_sparc_hi22",       0,     22,  0 },
159 +        { "fixup_sparc_lo10",       0,     10,  0 },
160 +        { "fixup_sparc_h44",        0,     22,  0 },
161 +        { "fixup_sparc_m44",        0,     10,  0 },
162 +        { "fixup_sparc_l44",        0,     12,  0 },
163 +        { "fixup_sparc_hh",         0,     21,  0 },
164 +        { "fixup_sparc_hm",         0,     10,  0 },
165        };
166  
167        if (Kind < FirstTargetFixupKind)
168 @@ -68,21 +108,38 @@ namespace {
169          OW->Write8(0);
170        return true;
171      }
172 +
173 +    bool is64Bit() const {
174 +      StringRef name = TheTarget.getName();
175 +      return name == "sparcv9";
176 +    }
177    };
178  
179    class ELFSparcAsmBackend : public SparcAsmBackend {
180 +    Triple::OSType OSType;
181    public:
182      ELFSparcAsmBackend(const Target &T, Triple::OSType OSType) :
183 -      SparcAsmBackend(T) { }
184 +      SparcAsmBackend(T), OSType(OSType) { }
185  
186      void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
187                      uint64_t Value) const {
188 -      assert(0 && "applyFixup not implemented yet");
189 +
190 +      Value = adjustFixupValue(Fixup.getKind(), Value);
191 +      if (!Value) return;           // Doesn't change encoding.
192 +
193 +      unsigned Offset = Fixup.getOffset();
194 +
195 +      // For each byte of the fragment that the fixup touches, mask in the bits
196 +      // from the fixup value. The Value has been "split up" into the
197 +      // appropriate bitfields above.
198 +      for (unsigned i = 0; i != 4; ++i)
199 +        Data[Offset + i] |= uint8_t((Value >> ((4 - i - 1)*8)) & 0xff);
200 +
201      }
202  
203      MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
204 -      assert(0 && "Object Writer not implemented yet");
205 -      return 0;
206 +      uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType);
207 +      return createSparcELFObjectWriter(OS, is64Bit(), OSABI);
208      }
209  
210      virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
211 Index: lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
212 ===================================================================
213 --- lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
214 +++ lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
215 @@ -22,10 +22,32 @@ namespace llvm {
216        /// branches
217        fixup_sparc_br22,
218  
219 -      /// fixup_sparc_br22 - 22-bit PC relative relocation for
220 +      /// fixup_sparc_br19 - 19-bit PC relative relocation for
221        /// branches on icc/xcc
222        fixup_sparc_br19,
223  
224 +      /// fixup_sparc_hi22  - 22-bit fixup corresponding to %hi(foo)
225 +      /// for sethi
226 +      fixup_sparc_hi22,
227 +
228 +      /// fixup_sparc_lo10  - 10-bit fixup corresponding to %lo(foo)
229 +      fixup_sparc_lo10,
230 +
231 +      /// fixup_sparc_h44  - 22-bit fixup corresponding to %h44(foo)
232 +      fixup_sparc_h44,
233 +
234 +      /// fixup_sparc_m44  - 10-bit fixup corresponding to %m44(foo)
235 +      fixup_sparc_m44,
236 +
237 +      /// fixup_sparc_l44  - 12-bit fixup corresponding to %l44(foo)
238 +      fixup_sparc_l44,
239 +
240 +      /// fixup_sparc_hh  -  22-bit fixup corresponding to %hh(foo)
241 +      fixup_sparc_hh,
242 +
243 +      /// fixup_sparc_hm  -  10-bit fixup corresponding to %hm(foo)
244 +      fixup_sparc_hm,
245 +
246        // Marker
247        LastTargetFixupKind,
248        NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
249 Index: lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
250 ===================================================================
251 --- lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
252 +++ lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
253 @@ -0,0 +1,86 @@
254 +//===-- SparcELFObjectWriter.cpp - Sparc ELF Writer -----------------------===//
255 +//
256 +//                     The LLVM Compiler Infrastructure
257 +//
258 +// This file is distributed under the University of Illinois Open Source
259 +// License. See LICENSE.TXT for details.
260 +//
261 +//===----------------------------------------------------------------------===//
262 +
263 +#include "MCTargetDesc/SparcMCTargetDesc.h"
264 +#include "MCTargetDesc/SparcFixupKinds.h"
265 +#include "llvm/ADT/STLExtras.h"
266 +#include "llvm/MC/MCELFObjectWriter.h"
267 +#include "llvm/MC/MCExpr.h"
268 +#include "llvm/MC/MCValue.h"
269 +#include "llvm/Support/ErrorHandling.h"
270 +
271 +using namespace llvm;
272 +
273 +namespace {
274 +  class SparcELFObjectWriter : public MCELFObjectTargetWriter {
275 +  public:
276 +    SparcELFObjectWriter(bool Is64Bit, uint8_t OSABI)
277 +      : MCELFObjectTargetWriter(Is64Bit, OSABI,
278 +                                Is64Bit ?  ELF::EM_SPARCV9 : ELF::EM_SPARC,
279 +                                /*HasRelocationAddend*/ true) {}
280 +
281 +    virtual ~SparcELFObjectWriter() {}
282 +  protected:
283 +    virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
284 +                                  bool IsPCRel, bool IsRelocWithSymbol,
285 +                                  int64_t Addend) const;
286 +
287 +  };
288 +}
289 +
290 +
291 +unsigned SparcELFObjectWriter::GetRelocType(const MCValue &Target,
292 +                                            const MCFixup &Fixup,
293 +                                            bool IsPCRel,
294 +                                            bool IsRelocWithSymbol,
295 +                                            int64_t Addend) const {
296 +  if (IsPCRel) {
297 +    switch((unsigned)Fixup.getKind()) {
298 +    default:
299 +      llvm_unreachable("Unimplemented fixup -> relocation");
300 +    case FK_Data_1:                  return ELF::R_SPARC_DISP8;
301 +    case FK_Data_2:                  return ELF::R_SPARC_DISP16;
302 +    case FK_Data_4:                  return ELF::R_SPARC_DISP32;
303 +    case FK_Data_8:                  return ELF::R_SPARC_DISP64;
304 +    case Sparc::fixup_sparc_call30:  return ELF::R_SPARC_WDISP30;
305 +    case Sparc::fixup_sparc_br22:    return ELF::R_SPARC_WDISP22;
306 +    case Sparc::fixup_sparc_br19:    return ELF::R_SPARC_WDISP19;
307 +    }
308 +  }
309 +
310 +  switch((unsigned)Fixup.getKind()) {
311 +  default:
312 +    llvm_unreachable("Unimplemented fixup -> relocation");
313 +  case FK_Data_1:                return ELF::R_SPARC_8;
314 +  case FK_Data_2:                return ((Fixup.getOffset() % 2)
315 +                                         ? ELF::R_SPARC_UA16
316 +                                         : ELF::R_SPARC_16);
317 +  case FK_Data_4:                return ((Fixup.getOffset() % 4)
318 +                                         ? ELF::R_SPARC_UA32
319 +                                         : ELF::R_SPARC_32);
320 +  case FK_Data_8:                return ((Fixup.getOffset() % 8)
321 +                                         ? ELF::R_SPARC_UA64
322 +                                         : ELF::R_SPARC_64);
323 +  case Sparc::fixup_sparc_hi22:  return ELF::R_SPARC_HI22;
324 +  case Sparc::fixup_sparc_lo10:  return ELF::R_SPARC_LO10;
325 +  case Sparc::fixup_sparc_h44:   return ELF::R_SPARC_H44;
326 +  case Sparc::fixup_sparc_m44:   return ELF::R_SPARC_M44;
327 +  case Sparc::fixup_sparc_l44:   return ELF::R_SPARC_L44;
328 +  case Sparc::fixup_sparc_hh:    return ELF::R_SPARC_HH22;
329 +  case Sparc::fixup_sparc_hm:    return ELF::R_SPARC_HM10;
330 +  }
331 +  return ELF::R_SPARC_NONE;
332 +}
333 +
334 +MCObjectWriter *llvm::createSparcELFObjectWriter(raw_ostream &OS,
335 +                                                 bool Is64Bit,
336 +                                                 uint8_t OSABI) {
337 +  MCELFObjectTargetWriter *MOTW = new SparcELFObjectWriter(Is64Bit, OSABI);
338 +  return createELFObjectWriter(MOTW, OS,  /*IsLittleEndian=*/false);
339 +}
340 Index: lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
341 ===================================================================
342 --- lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
343 +++ lib/Target/Sparc/MCTargetDesc/SparcMCTargetDesc.h
344 @@ -14,15 +14,19 @@
345  #ifndef SPARCMCTARGETDESC_H
346  #define SPARCMCTARGETDESC_H
347  
348 +#include "llvm/Support/DataTypes.h"
349 +
350  namespace llvm {
351  class MCAsmBackend;
352  class MCCodeEmitter;
353  class MCContext;
354  class MCInstrInfo;
355 +class MCObjectWriter;
356  class MCRegisterInfo;
357  class MCSubtargetInfo;
358  class Target;
359  class StringRef;
360 +class raw_ostream;
361  
362  extern Target TheSparcTarget;
363  extern Target TheSparcV9Target;
364 @@ -35,7 +39,9 @@ MCAsmBackend *createSparcAsmBackend(const Target &
365                                      const MCRegisterInfo &MRI,
366                                      StringRef TT,
367                                      StringRef CPU);
368 -
369 +MCObjectWriter *createSparcELFObjectWriter(raw_ostream &OS,
370 +                                           bool Is64Bit,
371 +                                           uint8_t OSABI);
372  } // End llvm namespace
373  
374  // Defines symbolic names for Sparc registers.  This defines a mapping from
375 Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
376 ===================================================================
377 --- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
378 +++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
379 @@ -70,15 +70,67 @@ void SparcMCExpr::PrintImpl(raw_ostream &OS) const
380  bool
381  SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
382                                           const MCAsmLayout *Layout) const {
383 -  assert(0 && "FIXME: Implement SparcMCExpr::EvaluateAsRelocatableImpl");
384    return getSubExpr()->EvaluateAsRelocatable(Res, *Layout);
385  }
386  
387 +static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
388 +  assert(0 && "Implement fixELFSymbolsInTLSFixupsImpl!");
389 +}
390  
391  void SparcMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
392 -  assert(0 && "FIXME: Implement SparcMCExpr::fixELFSymbolsInTLSFixups");
393 +  switch(getKind()) {
394 +  default: return;
395 +  case VK_Sparc_TLS_GD_HI22:
396 +  case VK_Sparc_TLS_GD_LO10:
397 +  case VK_Sparc_TLS_GD_ADD:
398 +  case VK_Sparc_TLS_GD_CALL:
399 +  case VK_Sparc_TLS_LDM_HI22:
400 +  case VK_Sparc_TLS_LDM_LO10:
401 +  case VK_Sparc_TLS_LDM_ADD:
402 +  case VK_Sparc_TLS_LDM_CALL:
403 +  case VK_Sparc_TLS_LDO_HIX22:
404 +  case VK_Sparc_TLS_LDO_LOX10:
405 +  case VK_Sparc_TLS_LDO_ADD:
406 +  case VK_Sparc_TLS_IE_HI22:
407 +  case VK_Sparc_TLS_IE_LO10:
408 +  case VK_Sparc_TLS_IE_LD:
409 +  case VK_Sparc_TLS_IE_LDX:
410 +  case VK_Sparc_TLS_IE_ADD:
411 +  case VK_Sparc_TLS_LE_HIX22:
412 +  case VK_Sparc_TLS_LE_LOX10: break;
413 +  }
414 +  fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);
415  }
416  
417 +// FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps
418 +// that method should be made public?
419 +// FIXME: really do above: now that at least three other backends are using it.
420 +static void AddValueSymbolsImpl(const MCExpr *Value, MCAssembler *Asm) {
421 +  switch (Value->getKind()) {
422 +  case MCExpr::Target:
423 +    llvm_unreachable("Can't handle nested target expr!");
424 +    break;
425 +
426 +  case MCExpr::Constant:
427 +    break;
428 +
429 +  case MCExpr::Binary: {
430 +    const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
431 +    AddValueSymbolsImpl(BE->getLHS(), Asm);
432 +    AddValueSymbolsImpl(BE->getRHS(), Asm);
433 +    break;
434 +  }
435 +
436 +  case MCExpr::SymbolRef:
437 +    Asm->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
438 +    break;
439 +
440 +  case MCExpr::Unary:
441 +    AddValueSymbolsImpl(cast<MCUnaryExpr>(Value)->getSubExpr(), Asm);
442 +    break;
443 +  }
444 +}
445 +
446  void SparcMCExpr::AddValueSymbols(MCAssembler *Asm) const {
447 -  assert(0 && "FIXME: Implement SparcMCExpr::AddValueSymbols");
448 +  AddValueSymbolsImpl(getSubExpr(), Asm);
449  }
450 Index: lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
451 ===================================================================
452 --- lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
453 +++ lib/Target/Sparc/MCTargetDesc/CMakeLists.txt
454 @@ -1,5 +1,6 @@
455  add_llvm_library(LLVMSparcDesc
456    SparcAsmBackend.cpp
457 +  SparcELFObjectWriter.cpp
458    SparcMCAsmInfo.cpp
459    SparcMCCodeEmitter.cpp
460    SparcMCTargetDesc.cpp