ARMELFStreamer.cpp revision 276479
1249259Sdim//===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim//
10249259Sdim// This file assembles .s files and emits ARM ELF .o object files. Different
11249259Sdim// from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to
12249259Sdim// delimit regions of data and code.
13249259Sdim//
14249259Sdim//===----------------------------------------------------------------------===//
15249259Sdim
16276479Sdim#include "ARMArchName.h"
17261991Sdim#include "ARMFPUName.h"
18251662Sdim#include "ARMRegisterInfo.h"
19251662Sdim#include "ARMUnwindOpAsm.h"
20276479Sdim#include "llvm/ADT/StringExtras.h"
21249259Sdim#include "llvm/ADT/Twine.h"
22249259Sdim#include "llvm/MC/MCAsmBackend.h"
23276479Sdim#include "llvm/MC/MCAsmInfo.h"
24249259Sdim#include "llvm/MC/MCAssembler.h"
25249259Sdim#include "llvm/MC/MCCodeEmitter.h"
26249259Sdim#include "llvm/MC/MCContext.h"
27249259Sdim#include "llvm/MC/MCELF.h"
28249259Sdim#include "llvm/MC/MCELFStreamer.h"
29249259Sdim#include "llvm/MC/MCELFSymbolFlags.h"
30249259Sdim#include "llvm/MC/MCExpr.h"
31249259Sdim#include "llvm/MC/MCInst.h"
32261991Sdim#include "llvm/MC/MCInstPrinter.h"
33276479Sdim#include "llvm/MC/MCObjectFileInfo.h"
34249259Sdim#include "llvm/MC/MCObjectStreamer.h"
35251662Sdim#include "llvm/MC/MCRegisterInfo.h"
36249259Sdim#include "llvm/MC/MCSection.h"
37249259Sdim#include "llvm/MC/MCSectionELF.h"
38249259Sdim#include "llvm/MC/MCStreamer.h"
39249259Sdim#include "llvm/MC/MCSymbol.h"
40249259Sdim#include "llvm/MC/MCValue.h"
41276479Sdim#include "llvm/Support/ARMBuildAttributes.h"
42276479Sdim#include "llvm/Support/ARMEHABI.h"
43249259Sdim#include "llvm/Support/Debug.h"
44249259Sdim#include "llvm/Support/ELF.h"
45261991Sdim#include "llvm/Support/FormattedStream.h"
46276479Sdim#include "llvm/Support/LEB128.h"
47249259Sdim#include "llvm/Support/raw_ostream.h"
48261991Sdim#include <algorithm>
49249259Sdim
50249259Sdimusing namespace llvm;
51249259Sdim
52251662Sdimstatic std::string GetAEABIUnwindPersonalityName(unsigned Index) {
53276479Sdim  assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX &&
54276479Sdim         "Invalid personality index");
55251662Sdim  return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
56251662Sdim}
57251662Sdim
58261991Sdimstatic const char *GetFPUName(unsigned ID) {
59261991Sdim  switch (ID) {
60261991Sdim  default:
61261991Sdim    llvm_unreachable("Unknown FPU kind");
62261991Sdim    break;
63261991Sdim#define ARM_FPU_NAME(NAME, ID) case ARM::ID: return NAME;
64261991Sdim#include "ARMFPUName.def"
65261991Sdim  }
66276479Sdim  return nullptr;
67261991Sdim}
68261991Sdim
69276479Sdimstatic const char *GetArchName(unsigned ID) {
70276479Sdim  switch (ID) {
71276479Sdim  default:
72276479Sdim    llvm_unreachable("Unknown ARCH kind");
73276479Sdim    break;
74276479Sdim#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \
75276479Sdim  case ARM::ID: return NAME;
76276479Sdim#define ARM_ARCH_ALIAS(NAME, ID) /* empty */
77276479Sdim#include "ARMArchName.def"
78276479Sdim  }
79276479Sdim  return nullptr;
80276479Sdim}
81276479Sdim
82276479Sdimstatic const char *GetArchDefaultCPUName(unsigned ID) {
83276479Sdim  switch (ID) {
84276479Sdim  default:
85276479Sdim    llvm_unreachable("Unknown ARCH kind");
86276479Sdim    break;
87276479Sdim#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \
88276479Sdim  case ARM::ID: return DEFAULT_CPU_NAME;
89276479Sdim#define ARM_ARCH_ALIAS(NAME, ID) /* empty */
90276479Sdim#include "ARMArchName.def"
91276479Sdim  }
92276479Sdim  return nullptr;
93276479Sdim}
94276479Sdim
95276479Sdimstatic unsigned GetArchDefaultCPUArch(unsigned ID) {
96276479Sdim  switch (ID) {
97276479Sdim  default:
98276479Sdim    llvm_unreachable("Unknown ARCH kind");
99276479Sdim    break;
100276479Sdim#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \
101276479Sdim  case ARM::ID: return ARMBuildAttrs::DEFAULT_CPU_ARCH;
102276479Sdim#define ARM_ARCH_ALIAS(NAME, ID) /* empty */
103276479Sdim#include "ARMArchName.def"
104276479Sdim  }
105276479Sdim  return 0;
106276479Sdim}
107276479Sdim
108249259Sdimnamespace {
109249259Sdim
110261991Sdimclass ARMELFStreamer;
111261991Sdim
112261991Sdimclass ARMTargetAsmStreamer : public ARMTargetStreamer {
113261991Sdim  formatted_raw_ostream &OS;
114261991Sdim  MCInstPrinter &InstPrinter;
115276479Sdim  bool IsVerboseAsm;
116261991Sdim
117276479Sdim  void emitFnStart() override;
118276479Sdim  void emitFnEnd() override;
119276479Sdim  void emitCantUnwind() override;
120276479Sdim  void emitPersonality(const MCSymbol *Personality) override;
121276479Sdim  void emitPersonalityIndex(unsigned Index) override;
122276479Sdim  void emitHandlerData() override;
123276479Sdim  void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
124276479Sdim  void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
125276479Sdim  void emitPad(int64_t Offset) override;
126276479Sdim  void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
127276479Sdim                   bool isVector) override;
128276479Sdim  void emitUnwindRaw(int64_t Offset,
129276479Sdim                     const SmallVectorImpl<uint8_t> &Opcodes) override;
130261991Sdim
131276479Sdim  void switchVendor(StringRef Vendor) override;
132276479Sdim  void emitAttribute(unsigned Attribute, unsigned Value) override;
133276479Sdim  void emitTextAttribute(unsigned Attribute, StringRef String) override;
134276479Sdim  void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
135276479Sdim                            StringRef StrinValue) override;
136276479Sdim  void emitArch(unsigned Arch) override;
137276479Sdim  void emitObjectArch(unsigned Arch) override;
138276479Sdim  void emitFPU(unsigned FPU) override;
139276479Sdim  void emitInst(uint32_t Inst, char Suffix = '\0') override;
140276479Sdim  void finishAttributeSection() override;
141261991Sdim
142276479Sdim  void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
143276479Sdim  void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
144276479Sdim
145261991Sdimpublic:
146276479Sdim  ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS,
147276479Sdim                       MCInstPrinter &InstPrinter, bool VerboseAsm);
148261991Sdim};
149261991Sdim
150276479SdimARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer &S,
151276479Sdim                                           formatted_raw_ostream &OS,
152276479Sdim                                           MCInstPrinter &InstPrinter,
153276479Sdim                                           bool VerboseAsm)
154276479Sdim    : ARMTargetStreamer(S), OS(OS), InstPrinter(InstPrinter),
155276479Sdim      IsVerboseAsm(VerboseAsm) {}
156261991Sdimvoid ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; }
157261991Sdimvoid ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; }
158261991Sdimvoid ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; }
159261991Sdimvoid ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) {
160261991Sdim  OS << "\t.personality " << Personality->getName() << '\n';
161261991Sdim}
162276479Sdimvoid ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) {
163276479Sdim  OS << "\t.personalityindex " << Index << '\n';
164276479Sdim}
165261991Sdimvoid ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }
166261991Sdimvoid ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
167261991Sdim                                     int64_t Offset) {
168261991Sdim  OS << "\t.setfp\t";
169261991Sdim  InstPrinter.printRegName(OS, FpReg);
170261991Sdim  OS << ", ";
171261991Sdim  InstPrinter.printRegName(OS, SpReg);
172261991Sdim  if (Offset)
173261991Sdim    OS << ", #" << Offset;
174261991Sdim  OS << '\n';
175261991Sdim}
176276479Sdimvoid ARMTargetAsmStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
177276479Sdim  assert((Reg != ARM::SP && Reg != ARM::PC) &&
178276479Sdim         "the operand of .movsp cannot be either sp or pc");
179276479Sdim
180276479Sdim  OS << "\t.movsp\t";
181276479Sdim  InstPrinter.printRegName(OS, Reg);
182276479Sdim  if (Offset)
183276479Sdim    OS << ", #" << Offset;
184276479Sdim  OS << '\n';
185276479Sdim}
186261991Sdimvoid ARMTargetAsmStreamer::emitPad(int64_t Offset) {
187261991Sdim  OS << "\t.pad\t#" << Offset << '\n';
188261991Sdim}
189261991Sdimvoid ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
190261991Sdim                                       bool isVector) {
191261991Sdim  assert(RegList.size() && "RegList should not be empty");
192261991Sdim  if (isVector)
193261991Sdim    OS << "\t.vsave\t{";
194261991Sdim  else
195261991Sdim    OS << "\t.save\t{";
196261991Sdim
197261991Sdim  InstPrinter.printRegName(OS, RegList[0]);
198261991Sdim
199261991Sdim  for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
200261991Sdim    OS << ", ";
201261991Sdim    InstPrinter.printRegName(OS, RegList[i]);
202261991Sdim  }
203261991Sdim
204261991Sdim  OS << "}\n";
205261991Sdim}
206261991Sdimvoid ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {
207261991Sdim}
208261991Sdimvoid ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
209276479Sdim  OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value);
210276479Sdim  if (IsVerboseAsm) {
211276479Sdim    StringRef Name = ARMBuildAttrs::AttrTypeAsString(Attribute);
212276479Sdim    if (!Name.empty())
213276479Sdim      OS << "\t@ " << Name;
214276479Sdim  }
215276479Sdim  OS << "\n";
216261991Sdim}
217261991Sdimvoid ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
218261991Sdim                                             StringRef String) {
219261991Sdim  switch (Attribute) {
220261991Sdim  case ARMBuildAttrs::CPU_name:
221276479Sdim    OS << "\t.cpu\t" << String.lower();
222261991Sdim    break;
223276479Sdim  default:
224276479Sdim    OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\"";
225276479Sdim    if (IsVerboseAsm) {
226276479Sdim      StringRef Name = ARMBuildAttrs::AttrTypeAsString(Attribute);
227276479Sdim      if (!Name.empty())
228276479Sdim        OS << "\t@ " << Name;
229276479Sdim    }
230276479Sdim    break;
231261991Sdim  }
232276479Sdim  OS << "\n";
233261991Sdim}
234276479Sdimvoid ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute,
235276479Sdim                                                unsigned IntValue,
236276479Sdim                                                StringRef StringValue) {
237276479Sdim  switch (Attribute) {
238276479Sdim  default: llvm_unreachable("unsupported multi-value attribute in asm mode");
239276479Sdim  case ARMBuildAttrs::compatibility:
240276479Sdim    OS << "\t.eabi_attribute\t" << Attribute << ", " << IntValue;
241276479Sdim    if (!StringValue.empty())
242276479Sdim      OS << ", \"" << StringValue << "\"";
243276479Sdim    if (IsVerboseAsm)
244276479Sdim      OS << "\t@ " << ARMBuildAttrs::AttrTypeAsString(Attribute);
245276479Sdim    break;
246276479Sdim  }
247276479Sdim  OS << "\n";
248276479Sdim}
249276479Sdimvoid ARMTargetAsmStreamer::emitArch(unsigned Arch) {
250276479Sdim  OS << "\t.arch\t" << GetArchName(Arch) << "\n";
251276479Sdim}
252276479Sdimvoid ARMTargetAsmStreamer::emitObjectArch(unsigned Arch) {
253276479Sdim  OS << "\t.object_arch\t" << GetArchName(Arch) << '\n';
254276479Sdim}
255261991Sdimvoid ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
256261991Sdim  OS << "\t.fpu\t" << GetFPUName(FPU) << "\n";
257261991Sdim}
258261991Sdimvoid ARMTargetAsmStreamer::finishAttributeSection() {
259261991Sdim}
260276479Sdimvoid
261276479SdimARMTargetAsmStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
262276479Sdim  OS << "\t.tlsdescseq\t" << S->getSymbol().getName();
263276479Sdim}
264261991Sdim
265276479Sdimvoid ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
266276479Sdim  OS << "\t.thumb_set\t" << *Symbol << ", " << *Value << '\n';
267276479Sdim}
268276479Sdim
269276479Sdimvoid ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) {
270276479Sdim  OS << "\t.inst";
271276479Sdim  if (Suffix)
272276479Sdim    OS << "." << Suffix;
273276479Sdim  OS << "\t0x" << utohexstr(Inst) << "\n";
274276479Sdim}
275276479Sdim
276276479Sdimvoid ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset,
277276479Sdim                                      const SmallVectorImpl<uint8_t> &Opcodes) {
278276479Sdim  OS << "\t.unwind_raw " << Offset;
279276479Sdim  for (SmallVectorImpl<uint8_t>::const_iterator OCI = Opcodes.begin(),
280276479Sdim                                                OCE = Opcodes.end();
281276479Sdim       OCI != OCE; ++OCI)
282276479Sdim    OS << ", 0x" << utohexstr(*OCI);
283276479Sdim  OS << '\n';
284276479Sdim}
285276479Sdim
286261991Sdimclass ARMTargetELFStreamer : public ARMTargetStreamer {
287261991Sdimprivate:
288261991Sdim  // This structure holds all attributes, accounting for
289261991Sdim  // their string/numeric value, so we can later emmit them
290261991Sdim  // in declaration order, keeping all in the same vector
291261991Sdim  struct AttributeItem {
292261991Sdim    enum {
293261991Sdim      HiddenAttribute = 0,
294261991Sdim      NumericAttribute,
295276479Sdim      TextAttribute,
296276479Sdim      NumericAndTextAttributes
297261991Sdim    } Type;
298261991Sdim    unsigned Tag;
299261991Sdim    unsigned IntValue;
300261991Sdim    StringRef StringValue;
301261991Sdim
302261991Sdim    static bool LessTag(const AttributeItem &LHS, const AttributeItem &RHS) {
303261991Sdim      return (LHS.Tag < RHS.Tag);
304261991Sdim    }
305261991Sdim  };
306261991Sdim
307261991Sdim  StringRef CurrentVendor;
308261991Sdim  unsigned FPU;
309276479Sdim  unsigned Arch;
310276479Sdim  unsigned EmittedArch;
311261991Sdim  SmallVector<AttributeItem, 64> Contents;
312261991Sdim
313261991Sdim  const MCSection *AttributeSection;
314261991Sdim
315261991Sdim  AttributeItem *getAttributeItem(unsigned Attribute) {
316261991Sdim    for (size_t i = 0; i < Contents.size(); ++i)
317261991Sdim      if (Contents[i].Tag == Attribute)
318261991Sdim        return &Contents[i];
319276479Sdim    return nullptr;
320261991Sdim  }
321261991Sdim
322261991Sdim  void setAttributeItem(unsigned Attribute, unsigned Value,
323261991Sdim                        bool OverwriteExisting) {
324261991Sdim    // Look for existing attribute item
325261991Sdim    if (AttributeItem *Item = getAttributeItem(Attribute)) {
326261991Sdim      if (!OverwriteExisting)
327261991Sdim        return;
328276479Sdim      Item->Type = AttributeItem::NumericAttribute;
329261991Sdim      Item->IntValue = Value;
330261991Sdim      return;
331261991Sdim    }
332261991Sdim
333261991Sdim    // Create new attribute item
334261991Sdim    AttributeItem Item = {
335261991Sdim      AttributeItem::NumericAttribute,
336261991Sdim      Attribute,
337261991Sdim      Value,
338261991Sdim      StringRef("")
339261991Sdim    };
340261991Sdim    Contents.push_back(Item);
341261991Sdim  }
342261991Sdim
343261991Sdim  void setAttributeItem(unsigned Attribute, StringRef Value,
344261991Sdim                        bool OverwriteExisting) {
345261991Sdim    // Look for existing attribute item
346261991Sdim    if (AttributeItem *Item = getAttributeItem(Attribute)) {
347261991Sdim      if (!OverwriteExisting)
348261991Sdim        return;
349276479Sdim      Item->Type = AttributeItem::TextAttribute;
350261991Sdim      Item->StringValue = Value;
351261991Sdim      return;
352261991Sdim    }
353261991Sdim
354261991Sdim    // Create new attribute item
355261991Sdim    AttributeItem Item = {
356261991Sdim      AttributeItem::TextAttribute,
357261991Sdim      Attribute,
358261991Sdim      0,
359261991Sdim      Value
360261991Sdim    };
361261991Sdim    Contents.push_back(Item);
362261991Sdim  }
363261991Sdim
364276479Sdim  void setAttributeItems(unsigned Attribute, unsigned IntValue,
365276479Sdim                         StringRef StringValue, bool OverwriteExisting) {
366276479Sdim    // Look for existing attribute item
367276479Sdim    if (AttributeItem *Item = getAttributeItem(Attribute)) {
368276479Sdim      if (!OverwriteExisting)
369276479Sdim        return;
370276479Sdim      Item->Type = AttributeItem::NumericAndTextAttributes;
371276479Sdim      Item->IntValue = IntValue;
372276479Sdim      Item->StringValue = StringValue;
373276479Sdim      return;
374276479Sdim    }
375276479Sdim
376276479Sdim    // Create new attribute item
377276479Sdim    AttributeItem Item = {
378276479Sdim      AttributeItem::NumericAndTextAttributes,
379276479Sdim      Attribute,
380276479Sdim      IntValue,
381276479Sdim      StringValue
382276479Sdim    };
383276479Sdim    Contents.push_back(Item);
384276479Sdim  }
385276479Sdim
386276479Sdim  void emitArchDefaultAttributes();
387261991Sdim  void emitFPUDefaultAttributes();
388261991Sdim
389261991Sdim  ARMELFStreamer &getStreamer();
390261991Sdim
391276479Sdim  void emitFnStart() override;
392276479Sdim  void emitFnEnd() override;
393276479Sdim  void emitCantUnwind() override;
394276479Sdim  void emitPersonality(const MCSymbol *Personality) override;
395276479Sdim  void emitPersonalityIndex(unsigned Index) override;
396276479Sdim  void emitHandlerData() override;
397276479Sdim  void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
398276479Sdim  void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
399276479Sdim  void emitPad(int64_t Offset) override;
400276479Sdim  void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
401276479Sdim                   bool isVector) override;
402276479Sdim  void emitUnwindRaw(int64_t Offset,
403276479Sdim                     const SmallVectorImpl<uint8_t> &Opcodes) override;
404261991Sdim
405276479Sdim  void switchVendor(StringRef Vendor) override;
406276479Sdim  void emitAttribute(unsigned Attribute, unsigned Value) override;
407276479Sdim  void emitTextAttribute(unsigned Attribute, StringRef String) override;
408276479Sdim  void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
409276479Sdim                            StringRef StringValue) override;
410276479Sdim  void emitArch(unsigned Arch) override;
411276479Sdim  void emitObjectArch(unsigned Arch) override;
412276479Sdim  void emitFPU(unsigned FPU) override;
413276479Sdim  void emitInst(uint32_t Inst, char Suffix = '\0') override;
414276479Sdim  void finishAttributeSection() override;
415276479Sdim  void emitLabel(MCSymbol *Symbol) override;
416261991Sdim
417276479Sdim  void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
418276479Sdim  void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
419276479Sdim
420261991Sdim  size_t calculateContentSize() const;
421261991Sdim
422261991Sdimpublic:
423276479Sdim  ARMTargetELFStreamer(MCStreamer &S)
424276479Sdim    : ARMTargetStreamer(S), CurrentVendor("aeabi"), FPU(ARM::INVALID_FPU),
425276479Sdim      Arch(ARM::INVALID_ARCH), EmittedArch(ARM::INVALID_ARCH),
426276479Sdim      AttributeSection(nullptr) {}
427261991Sdim};
428261991Sdim
429249259Sdim/// Extend the generic ELFStreamer class so that it can emit mapping symbols at
430249259Sdim/// the appropriate points in the object files. These symbols are defined in the
431249259Sdim/// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.
432249259Sdim///
433249259Sdim/// In brief: $a, $t or $d should be emitted at the start of each contiguous
434249259Sdim/// region of ARM code, Thumb code or data in a section. In practice, this
435249259Sdim/// emission does not rely on explicit assembler directives but on inherent
436249259Sdim/// properties of the directives doing the emission (e.g. ".byte" is data, "add
437249259Sdim/// r0, r0, r0" an instruction).
438249259Sdim///
439249259Sdim/// As a result this system is orthogonal to the DataRegion infrastructure used
440249259Sdim/// by MachO. Beware!
441249259Sdimclass ARMELFStreamer : public MCELFStreamer {
442249259Sdimpublic:
443261991Sdim  friend class ARMTargetELFStreamer;
444261991Sdim
445276479Sdim  ARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
446276479Sdim                 MCCodeEmitter *Emitter, bool IsThumb)
447276479Sdim      : MCELFStreamer(Context, TAB, OS, Emitter), IsThumb(IsThumb),
448276479Sdim        MappingSymbolCounter(0), LastEMS(EMS_None) {
449251662Sdim    Reset();
450251662Sdim  }
451249259Sdim
452249259Sdim  ~ARMELFStreamer() {}
453249259Sdim
454276479Sdim  void FinishImpl() override;
455261991Sdim
456249259Sdim  // ARM exception handling directives
457261991Sdim  void emitFnStart();
458261991Sdim  void emitFnEnd();
459261991Sdim  void emitCantUnwind();
460261991Sdim  void emitPersonality(const MCSymbol *Per);
461276479Sdim  void emitPersonalityIndex(unsigned index);
462261991Sdim  void emitHandlerData();
463261991Sdim  void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0);
464276479Sdim  void emitMovSP(unsigned Reg, int64_t Offset = 0);
465261991Sdim  void emitPad(int64_t Offset);
466261991Sdim  void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector);
467276479Sdim  void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes);
468249259Sdim
469276479Sdim  void ChangeSection(const MCSection *Section,
470276479Sdim                     const MCExpr *Subsection) override {
471249259Sdim    // We have to keep track of the mapping symbol state of any sections we
472249259Sdim    // use. Each one should start off as EMS_None, which is provided as the
473249259Sdim    // default constructor by DenseMap::lookup.
474251662Sdim    LastMappingSymbols[getPreviousSection().first] = LastEMS;
475249259Sdim    LastEMS = LastMappingSymbols.lookup(Section);
476249259Sdim
477251662Sdim    MCELFStreamer::ChangeSection(Section, Subsection);
478249259Sdim  }
479249259Sdim
480249259Sdim  /// This function is the one used to emit instruction data into the ELF
481249259Sdim  /// streamer. We override it to add the appropriate mapping symbol if
482249259Sdim  /// necessary.
483276479Sdim  void EmitInstruction(const MCInst& Inst,
484276479Sdim                       const MCSubtargetInfo &STI) override {
485249259Sdim    if (IsThumb)
486249259Sdim      EmitThumbMappingSymbol();
487249259Sdim    else
488249259Sdim      EmitARMMappingSymbol();
489249259Sdim
490276479Sdim    MCELFStreamer::EmitInstruction(Inst, STI);
491249259Sdim  }
492249259Sdim
493276479Sdim  void emitInst(uint32_t Inst, char Suffix) {
494276479Sdim    unsigned Size;
495276479Sdim    char Buffer[4];
496276479Sdim    const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian();
497276479Sdim
498276479Sdim    switch (Suffix) {
499276479Sdim    case '\0':
500276479Sdim      Size = 4;
501276479Sdim
502276479Sdim      assert(!IsThumb);
503276479Sdim      EmitARMMappingSymbol();
504276479Sdim      for (unsigned II = 0, IE = Size; II != IE; II++) {
505276479Sdim        const unsigned I = LittleEndian ? (Size - II - 1) : II;
506276479Sdim        Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);
507276479Sdim      }
508276479Sdim
509276479Sdim      break;
510276479Sdim    case 'n':
511276479Sdim    case 'w':
512276479Sdim      Size = (Suffix == 'n' ? 2 : 4);
513276479Sdim
514276479Sdim      assert(IsThumb);
515276479Sdim      EmitThumbMappingSymbol();
516276479Sdim      for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {
517276479Sdim        const unsigned I0 = LittleEndian ? II + 0 : (Size - II - 1);
518276479Sdim        const unsigned I1 = LittleEndian ? II + 1 : (Size - II - 2);
519276479Sdim        Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);
520276479Sdim        Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);
521276479Sdim      }
522276479Sdim
523276479Sdim      break;
524276479Sdim    default:
525276479Sdim      llvm_unreachable("Invalid Suffix");
526276479Sdim    }
527276479Sdim
528276479Sdim    MCELFStreamer::EmitBytes(StringRef(Buffer, Size));
529276479Sdim  }
530276479Sdim
531249259Sdim  /// This is one of the functions used to emit data into an ELF section, so the
532249259Sdim  /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
533249259Sdim  /// necessary.
534276479Sdim  void EmitBytes(StringRef Data) override {
535249259Sdim    EmitDataMappingSymbol();
536261991Sdim    MCELFStreamer::EmitBytes(Data);
537249259Sdim  }
538249259Sdim
539249259Sdim  /// This is one of the functions used to emit data into an ELF section, so the
540249259Sdim  /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
541249259Sdim  /// necessary.
542276479Sdim  void EmitValueImpl(const MCExpr *Value, unsigned Size,
543276479Sdim                     const SMLoc &Loc) override {
544249259Sdim    EmitDataMappingSymbol();
545261991Sdim    MCELFStreamer::EmitValueImpl(Value, Size);
546249259Sdim  }
547249259Sdim
548276479Sdim  void EmitAssemblerFlag(MCAssemblerFlag Flag) override {
549249259Sdim    MCELFStreamer::EmitAssemblerFlag(Flag);
550249259Sdim
551249259Sdim    switch (Flag) {
552249259Sdim    case MCAF_SyntaxUnified:
553249259Sdim      return; // no-op here.
554249259Sdim    case MCAF_Code16:
555249259Sdim      IsThumb = true;
556249259Sdim      return; // Change to Thumb mode
557249259Sdim    case MCAF_Code32:
558249259Sdim      IsThumb = false;
559249259Sdim      return; // Change to ARM mode
560249259Sdim    case MCAF_Code64:
561249259Sdim      return;
562249259Sdim    case MCAF_SubsectionsViaSymbols:
563249259Sdim      return;
564249259Sdim    }
565249259Sdim  }
566249259Sdim
567249259Sdimprivate:
568249259Sdim  enum ElfMappingSymbol {
569249259Sdim    EMS_None,
570249259Sdim    EMS_ARM,
571249259Sdim    EMS_Thumb,
572249259Sdim    EMS_Data
573249259Sdim  };
574249259Sdim
575249259Sdim  void EmitDataMappingSymbol() {
576249259Sdim    if (LastEMS == EMS_Data) return;
577249259Sdim    EmitMappingSymbol("$d");
578249259Sdim    LastEMS = EMS_Data;
579249259Sdim  }
580249259Sdim
581249259Sdim  void EmitThumbMappingSymbol() {
582249259Sdim    if (LastEMS == EMS_Thumb) return;
583249259Sdim    EmitMappingSymbol("$t");
584249259Sdim    LastEMS = EMS_Thumb;
585249259Sdim  }
586249259Sdim
587249259Sdim  void EmitARMMappingSymbol() {
588249259Sdim    if (LastEMS == EMS_ARM) return;
589249259Sdim    EmitMappingSymbol("$a");
590249259Sdim    LastEMS = EMS_ARM;
591249259Sdim  }
592249259Sdim
593249259Sdim  void EmitMappingSymbol(StringRef Name) {
594249259Sdim    MCSymbol *Start = getContext().CreateTempSymbol();
595249259Sdim    EmitLabel(Start);
596249259Sdim
597249259Sdim    MCSymbol *Symbol =
598249259Sdim      getContext().GetOrCreateSymbol(Name + "." +
599249259Sdim                                     Twine(MappingSymbolCounter++));
600249259Sdim
601249259Sdim    MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
602249259Sdim    MCELF::SetType(SD, ELF::STT_NOTYPE);
603249259Sdim    MCELF::SetBinding(SD, ELF::STB_LOCAL);
604249259Sdim    SD.setExternal(false);
605261991Sdim    AssignSection(Symbol, getCurrentSection().first);
606249259Sdim
607249259Sdim    const MCExpr *Value = MCSymbolRefExpr::Create(Start, getContext());
608249259Sdim    Symbol->setVariableValue(Value);
609249259Sdim  }
610249259Sdim
611276479Sdim  void EmitThumbFunc(MCSymbol *Func) override {
612249259Sdim    getAssembler().setIsThumbFunc(Func);
613276479Sdim    EmitSymbolAttribute(Func, MCSA_ELF_TypeFunction);
614249259Sdim  }
615249259Sdim
616249259Sdim  // Helper functions for ARM exception handling directives
617249259Sdim  void Reset();
618249259Sdim
619249259Sdim  void EmitPersonalityFixup(StringRef Name);
620261991Sdim  void FlushPendingOffset();
621261991Sdim  void FlushUnwindOpcodes(bool NoHandlerData);
622249259Sdim
623249259Sdim  void SwitchToEHSection(const char *Prefix, unsigned Type, unsigned Flags,
624249259Sdim                         SectionKind Kind, const MCSymbol &Fn);
625249259Sdim  void SwitchToExTabSection(const MCSymbol &FnStart);
626249259Sdim  void SwitchToExIdxSection(const MCSymbol &FnStart);
627249259Sdim
628276479Sdim  void EmitFixup(const MCExpr *Expr, MCFixupKind Kind);
629276479Sdim
630249259Sdim  bool IsThumb;
631249259Sdim  int64_t MappingSymbolCounter;
632249259Sdim
633249259Sdim  DenseMap<const MCSection *, ElfMappingSymbol> LastMappingSymbols;
634249259Sdim  ElfMappingSymbol LastEMS;
635249259Sdim
636249259Sdim  // ARM Exception Handling Frame Information
637249259Sdim  MCSymbol *ExTab;
638249259Sdim  MCSymbol *FnStart;
639249259Sdim  const MCSymbol *Personality;
640261991Sdim  unsigned PersonalityIndex;
641261991Sdim  unsigned FPReg; // Frame pointer register
642261991Sdim  int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp)
643261991Sdim  int64_t SPOffset; // Offset: (final $sp) - (initial $sp)
644261991Sdim  int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp)
645251662Sdim  bool UsedFP;
646249259Sdim  bool CantUnwind;
647261991Sdim  SmallVector<uint8_t, 64> Opcodes;
648251662Sdim  UnwindOpcodeAssembler UnwindOpAsm;
649249259Sdim};
650251662Sdim} // end anonymous namespace
651249259Sdim
652261991SdimARMELFStreamer &ARMTargetELFStreamer::getStreamer() {
653276479Sdim  return static_cast<ARMELFStreamer &>(Streamer);
654261991Sdim}
655261991Sdim
656261991Sdimvoid ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }
657261991Sdimvoid ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }
658261991Sdimvoid ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }
659261991Sdimvoid ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) {
660261991Sdim  getStreamer().emitPersonality(Personality);
661261991Sdim}
662276479Sdimvoid ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index) {
663276479Sdim  getStreamer().emitPersonalityIndex(Index);
664276479Sdim}
665261991Sdimvoid ARMTargetELFStreamer::emitHandlerData() {
666261991Sdim  getStreamer().emitHandlerData();
667261991Sdim}
668261991Sdimvoid ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
669261991Sdim                                     int64_t Offset) {
670261991Sdim  getStreamer().emitSetFP(FpReg, SpReg, Offset);
671261991Sdim}
672276479Sdimvoid ARMTargetELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
673276479Sdim  getStreamer().emitMovSP(Reg, Offset);
674276479Sdim}
675261991Sdimvoid ARMTargetELFStreamer::emitPad(int64_t Offset) {
676261991Sdim  getStreamer().emitPad(Offset);
677261991Sdim}
678261991Sdimvoid ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
679261991Sdim                                       bool isVector) {
680261991Sdim  getStreamer().emitRegSave(RegList, isVector);
681261991Sdim}
682276479Sdimvoid ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset,
683276479Sdim                                      const SmallVectorImpl<uint8_t> &Opcodes) {
684276479Sdim  getStreamer().emitUnwindRaw(Offset, Opcodes);
685276479Sdim}
686261991Sdimvoid ARMTargetELFStreamer::switchVendor(StringRef Vendor) {
687261991Sdim  assert(!Vendor.empty() && "Vendor cannot be empty.");
688261991Sdim
689261991Sdim  if (CurrentVendor == Vendor)
690261991Sdim    return;
691261991Sdim
692261991Sdim  if (!CurrentVendor.empty())
693261991Sdim    finishAttributeSection();
694261991Sdim
695261991Sdim  assert(Contents.empty() &&
696261991Sdim         ".ARM.attributes should be flushed before changing vendor");
697261991Sdim  CurrentVendor = Vendor;
698261991Sdim
699261991Sdim}
700261991Sdimvoid ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
701261991Sdim  setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
702261991Sdim}
703261991Sdimvoid ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute,
704261991Sdim                                             StringRef Value) {
705261991Sdim  setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
706261991Sdim}
707276479Sdimvoid ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
708276479Sdim                                                unsigned IntValue,
709276479Sdim                                                StringRef StringValue) {
710276479Sdim  setAttributeItems(Attribute, IntValue, StringValue,
711276479Sdim                    /* OverwriteExisting= */ true);
712276479Sdim}
713276479Sdimvoid ARMTargetELFStreamer::emitArch(unsigned Value) {
714276479Sdim  Arch = Value;
715276479Sdim}
716276479Sdimvoid ARMTargetELFStreamer::emitObjectArch(unsigned Value) {
717276479Sdim  EmittedArch = Value;
718276479Sdim}
719276479Sdimvoid ARMTargetELFStreamer::emitArchDefaultAttributes() {
720276479Sdim  using namespace ARMBuildAttrs;
721276479Sdim
722276479Sdim  setAttributeItem(CPU_name, GetArchDefaultCPUName(Arch), false);
723276479Sdim  if (EmittedArch == ARM::INVALID_ARCH)
724276479Sdim    setAttributeItem(CPU_arch, GetArchDefaultCPUArch(Arch), false);
725276479Sdim  else
726276479Sdim    setAttributeItem(CPU_arch, GetArchDefaultCPUArch(EmittedArch), false);
727276479Sdim
728276479Sdim  switch (Arch) {
729276479Sdim  case ARM::ARMV2:
730276479Sdim  case ARM::ARMV2A:
731276479Sdim  case ARM::ARMV3:
732276479Sdim  case ARM::ARMV3M:
733276479Sdim  case ARM::ARMV4:
734276479Sdim  case ARM::ARMV5:
735276479Sdim    setAttributeItem(ARM_ISA_use, Allowed, false);
736276479Sdim    break;
737276479Sdim
738276479Sdim  case ARM::ARMV4T:
739276479Sdim  case ARM::ARMV5T:
740276479Sdim  case ARM::ARMV5TE:
741276479Sdim  case ARM::ARMV6:
742276479Sdim  case ARM::ARMV6J:
743276479Sdim    setAttributeItem(ARM_ISA_use, Allowed, false);
744276479Sdim    setAttributeItem(THUMB_ISA_use, Allowed, false);
745276479Sdim    break;
746276479Sdim
747276479Sdim  case ARM::ARMV6T2:
748276479Sdim    setAttributeItem(ARM_ISA_use, Allowed, false);
749276479Sdim    setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
750276479Sdim    break;
751276479Sdim
752276479Sdim  case ARM::ARMV6Z:
753276479Sdim  case ARM::ARMV6ZK:
754276479Sdim    setAttributeItem(ARM_ISA_use, Allowed, false);
755276479Sdim    setAttributeItem(THUMB_ISA_use, Allowed, false);
756276479Sdim    setAttributeItem(Virtualization_use, AllowTZ, false);
757276479Sdim    break;
758276479Sdim
759276479Sdim  case ARM::ARMV6M:
760276479Sdim    setAttributeItem(THUMB_ISA_use, Allowed, false);
761276479Sdim    break;
762276479Sdim
763276479Sdim  case ARM::ARMV7:
764276479Sdim    setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
765276479Sdim    break;
766276479Sdim
767276479Sdim  case ARM::ARMV7A:
768276479Sdim    setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
769276479Sdim    setAttributeItem(ARM_ISA_use, Allowed, false);
770276479Sdim    setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
771276479Sdim    break;
772276479Sdim
773276479Sdim  case ARM::ARMV7R:
774276479Sdim    setAttributeItem(CPU_arch_profile, RealTimeProfile, false);
775276479Sdim    setAttributeItem(ARM_ISA_use, Allowed, false);
776276479Sdim    setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
777276479Sdim    break;
778276479Sdim
779276479Sdim  case ARM::ARMV7M:
780276479Sdim    setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
781276479Sdim    setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
782276479Sdim    break;
783276479Sdim
784276479Sdim  case ARM::ARMV8A:
785276479Sdim    setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
786276479Sdim    setAttributeItem(ARM_ISA_use, Allowed, false);
787276479Sdim    setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
788276479Sdim    setAttributeItem(MPextension_use, Allowed, false);
789276479Sdim    setAttributeItem(Virtualization_use, AllowTZVirtualization, false);
790276479Sdim    break;
791276479Sdim
792276479Sdim  case ARM::IWMMXT:
793276479Sdim    setAttributeItem(ARM_ISA_use, Allowed, false);
794276479Sdim    setAttributeItem(THUMB_ISA_use, Allowed, false);
795276479Sdim    setAttributeItem(WMMX_arch, AllowWMMXv1, false);
796276479Sdim    break;
797276479Sdim
798276479Sdim  case ARM::IWMMXT2:
799276479Sdim    setAttributeItem(ARM_ISA_use, Allowed, false);
800276479Sdim    setAttributeItem(THUMB_ISA_use, Allowed, false);
801276479Sdim    setAttributeItem(WMMX_arch, AllowWMMXv2, false);
802276479Sdim    break;
803276479Sdim
804276479Sdim  default:
805276479Sdim    report_fatal_error("Unknown Arch: " + Twine(Arch));
806276479Sdim    break;
807276479Sdim  }
808276479Sdim}
809261991Sdimvoid ARMTargetELFStreamer::emitFPU(unsigned Value) {
810261991Sdim  FPU = Value;
811261991Sdim}
812261991Sdimvoid ARMTargetELFStreamer::emitFPUDefaultAttributes() {
813261991Sdim  switch (FPU) {
814261991Sdim  case ARM::VFP:
815261991Sdim  case ARM::VFPV2:
816276479Sdim    setAttributeItem(ARMBuildAttrs::FP_arch,
817261991Sdim                     ARMBuildAttrs::AllowFPv2,
818261991Sdim                     /* OverwriteExisting= */ false);
819261991Sdim    break;
820261991Sdim
821261991Sdim  case ARM::VFPV3:
822276479Sdim    setAttributeItem(ARMBuildAttrs::FP_arch,
823261991Sdim                     ARMBuildAttrs::AllowFPv3A,
824261991Sdim                     /* OverwriteExisting= */ false);
825261991Sdim    break;
826261991Sdim
827261991Sdim  case ARM::VFPV3_D16:
828276479Sdim    setAttributeItem(ARMBuildAttrs::FP_arch,
829261991Sdim                     ARMBuildAttrs::AllowFPv3B,
830261991Sdim                     /* OverwriteExisting= */ false);
831261991Sdim    break;
832261991Sdim
833261991Sdim  case ARM::VFPV4:
834276479Sdim    setAttributeItem(ARMBuildAttrs::FP_arch,
835261991Sdim                     ARMBuildAttrs::AllowFPv4A,
836261991Sdim                     /* OverwriteExisting= */ false);
837261991Sdim    break;
838261991Sdim
839261991Sdim  case ARM::VFPV4_D16:
840276479Sdim    setAttributeItem(ARMBuildAttrs::FP_arch,
841261991Sdim                     ARMBuildAttrs::AllowFPv4B,
842261991Sdim                     /* OverwriteExisting= */ false);
843261991Sdim    break;
844261991Sdim
845261991Sdim  case ARM::FP_ARMV8:
846276479Sdim    setAttributeItem(ARMBuildAttrs::FP_arch,
847261991Sdim                     ARMBuildAttrs::AllowFPARMv8A,
848261991Sdim                     /* OverwriteExisting= */ false);
849261991Sdim    break;
850261991Sdim
851261991Sdim  case ARM::NEON:
852276479Sdim    setAttributeItem(ARMBuildAttrs::FP_arch,
853261991Sdim                     ARMBuildAttrs::AllowFPv3A,
854261991Sdim                     /* OverwriteExisting= */ false);
855261991Sdim    setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
856261991Sdim                     ARMBuildAttrs::AllowNeon,
857261991Sdim                     /* OverwriteExisting= */ false);
858261991Sdim    break;
859261991Sdim
860261991Sdim  case ARM::NEON_VFPV4:
861276479Sdim    setAttributeItem(ARMBuildAttrs::FP_arch,
862261991Sdim                     ARMBuildAttrs::AllowFPv4A,
863261991Sdim                     /* OverwriteExisting= */ false);
864261991Sdim    setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
865261991Sdim                     ARMBuildAttrs::AllowNeon2,
866261991Sdim                     /* OverwriteExisting= */ false);
867261991Sdim    break;
868261991Sdim
869261991Sdim  case ARM::NEON_FP_ARMV8:
870261991Sdim  case ARM::CRYPTO_NEON_FP_ARMV8:
871276479Sdim    setAttributeItem(ARMBuildAttrs::FP_arch,
872261991Sdim                     ARMBuildAttrs::AllowFPARMv8A,
873261991Sdim                     /* OverwriteExisting= */ false);
874261991Sdim    setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
875261991Sdim                     ARMBuildAttrs::AllowNeonARMv8,
876261991Sdim                     /* OverwriteExisting= */ false);
877261991Sdim    break;
878261991Sdim
879276479Sdim  case ARM::SOFTVFP:
880276479Sdim    break;
881276479Sdim
882261991Sdim  default:
883261991Sdim    report_fatal_error("Unknown FPU: " + Twine(FPU));
884261991Sdim    break;
885261991Sdim  }
886261991Sdim}
887261991Sdimsize_t ARMTargetELFStreamer::calculateContentSize() const {
888261991Sdim  size_t Result = 0;
889261991Sdim  for (size_t i = 0; i < Contents.size(); ++i) {
890261991Sdim    AttributeItem item = Contents[i];
891261991Sdim    switch (item.Type) {
892261991Sdim    case AttributeItem::HiddenAttribute:
893261991Sdim      break;
894261991Sdim    case AttributeItem::NumericAttribute:
895276479Sdim      Result += getULEB128Size(item.Tag);
896276479Sdim      Result += getULEB128Size(item.IntValue);
897261991Sdim      break;
898261991Sdim    case AttributeItem::TextAttribute:
899276479Sdim      Result += getULEB128Size(item.Tag);
900261991Sdim      Result += item.StringValue.size() + 1; // string + '\0'
901261991Sdim      break;
902276479Sdim    case AttributeItem::NumericAndTextAttributes:
903276479Sdim      Result += getULEB128Size(item.Tag);
904276479Sdim      Result += getULEB128Size(item.IntValue);
905276479Sdim      Result += item.StringValue.size() + 1; // string + '\0';
906276479Sdim      break;
907261991Sdim    }
908261991Sdim  }
909261991Sdim  return Result;
910261991Sdim}
911261991Sdimvoid ARMTargetELFStreamer::finishAttributeSection() {
912261991Sdim  // <format-version>
913261991Sdim  // [ <section-length> "vendor-name"
914261991Sdim  // [ <file-tag> <size> <attribute>*
915261991Sdim  //   | <section-tag> <size> <section-number>* 0 <attribute>*
916261991Sdim  //   | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
917261991Sdim  //   ]+
918261991Sdim  // ]*
919261991Sdim
920261991Sdim  if (FPU != ARM::INVALID_FPU)
921261991Sdim    emitFPUDefaultAttributes();
922261991Sdim
923276479Sdim  if (Arch != ARM::INVALID_ARCH)
924276479Sdim    emitArchDefaultAttributes();
925276479Sdim
926261991Sdim  if (Contents.empty())
927261991Sdim    return;
928261991Sdim
929261991Sdim  std::sort(Contents.begin(), Contents.end(), AttributeItem::LessTag);
930261991Sdim
931261991Sdim  ARMELFStreamer &Streamer = getStreamer();
932261991Sdim
933261991Sdim  // Switch to .ARM.attributes section
934261991Sdim  if (AttributeSection) {
935261991Sdim    Streamer.SwitchSection(AttributeSection);
936261991Sdim  } else {
937261991Sdim    AttributeSection =
938261991Sdim      Streamer.getContext().getELFSection(".ARM.attributes",
939261991Sdim                                          ELF::SHT_ARM_ATTRIBUTES,
940261991Sdim                                          0,
941261991Sdim                                          SectionKind::getMetadata());
942261991Sdim    Streamer.SwitchSection(AttributeSection);
943261991Sdim
944261991Sdim    // Format version
945261991Sdim    Streamer.EmitIntValue(0x41, 1);
946261991Sdim  }
947261991Sdim
948261991Sdim  // Vendor size + Vendor name + '\0'
949261991Sdim  const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
950261991Sdim
951261991Sdim  // Tag + Tag Size
952261991Sdim  const size_t TagHeaderSize = 1 + 4;
953261991Sdim
954261991Sdim  const size_t ContentsSize = calculateContentSize();
955261991Sdim
956261991Sdim  Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
957261991Sdim  Streamer.EmitBytes(CurrentVendor);
958261991Sdim  Streamer.EmitIntValue(0, 1); // '\0'
959261991Sdim
960261991Sdim  Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
961261991Sdim  Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
962261991Sdim
963261991Sdim  // Size should have been accounted for already, now
964261991Sdim  // emit each field as its type (ULEB or String)
965261991Sdim  for (size_t i = 0; i < Contents.size(); ++i) {
966261991Sdim    AttributeItem item = Contents[i];
967261991Sdim    Streamer.EmitULEB128IntValue(item.Tag);
968261991Sdim    switch (item.Type) {
969261991Sdim    default: llvm_unreachable("Invalid attribute type");
970261991Sdim    case AttributeItem::NumericAttribute:
971261991Sdim      Streamer.EmitULEB128IntValue(item.IntValue);
972261991Sdim      break;
973261991Sdim    case AttributeItem::TextAttribute:
974261991Sdim      Streamer.EmitBytes(item.StringValue.upper());
975261991Sdim      Streamer.EmitIntValue(0, 1); // '\0'
976261991Sdim      break;
977276479Sdim    case AttributeItem::NumericAndTextAttributes:
978276479Sdim      Streamer.EmitULEB128IntValue(item.IntValue);
979276479Sdim      Streamer.EmitBytes(item.StringValue.upper());
980276479Sdim      Streamer.EmitIntValue(0, 1); // '\0'
981276479Sdim      break;
982261991Sdim    }
983261991Sdim  }
984261991Sdim
985261991Sdim  Contents.clear();
986261991Sdim  FPU = ARM::INVALID_FPU;
987261991Sdim}
988261991Sdim
989276479Sdimvoid ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
990276479Sdim  ARMELFStreamer &Streamer = getStreamer();
991276479Sdim  if (!Streamer.IsThumb)
992276479Sdim    return;
993276479Sdim
994276479Sdim  const MCSymbolData &SD = Streamer.getOrCreateSymbolData(Symbol);
995276479Sdim  unsigned Type = MCELF::GetType(SD);
996276479Sdim  if (Type == ELF_STT_Func || Type == ELF_STT_GnuIFunc)
997276479Sdim    Streamer.EmitThumbFunc(Symbol);
998276479Sdim}
999276479Sdim
1000276479Sdimvoid
1001276479SdimARMTargetELFStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
1002276479Sdim  getStreamer().EmitFixup(S, FK_Data_4);
1003276479Sdim}
1004276479Sdim
1005276479Sdimvoid ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
1006276479Sdim  if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) {
1007276479Sdim    const MCSymbol &Sym = SRE->getSymbol();
1008276479Sdim    if (!Sym.isDefined()) {
1009276479Sdim      getStreamer().EmitAssignment(Symbol, Value);
1010276479Sdim      return;
1011276479Sdim    }
1012276479Sdim  }
1013276479Sdim
1014276479Sdim  getStreamer().EmitThumbFunc(Symbol);
1015276479Sdim  getStreamer().EmitAssignment(Symbol, Value);
1016276479Sdim}
1017276479Sdim
1018276479Sdimvoid ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {
1019276479Sdim  getStreamer().emitInst(Inst, Suffix);
1020276479Sdim}
1021276479Sdim
1022261991Sdimvoid ARMELFStreamer::FinishImpl() {
1023276479Sdim  MCTargetStreamer &TS = *getTargetStreamer();
1024261991Sdim  ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1025261991Sdim  ATS.finishAttributeSection();
1026261991Sdim
1027261991Sdim  MCELFStreamer::FinishImpl();
1028261991Sdim}
1029261991Sdim
1030249259Sdiminline void ARMELFStreamer::SwitchToEHSection(const char *Prefix,
1031249259Sdim                                              unsigned Type,
1032249259Sdim                                              unsigned Flags,
1033249259Sdim                                              SectionKind Kind,
1034249259Sdim                                              const MCSymbol &Fn) {
1035249259Sdim  const MCSectionELF &FnSection =
1036249259Sdim    static_cast<const MCSectionELF &>(Fn.getSection());
1037249259Sdim
1038249259Sdim  // Create the name for new section
1039249259Sdim  StringRef FnSecName(FnSection.getSectionName());
1040249259Sdim  SmallString<128> EHSecName(Prefix);
1041249259Sdim  if (FnSecName != ".text") {
1042249259Sdim    EHSecName += FnSecName;
1043249259Sdim  }
1044249259Sdim
1045249259Sdim  // Get .ARM.extab or .ARM.exidx section
1046276479Sdim  const MCSectionELF *EHSection = nullptr;
1047249259Sdim  if (const MCSymbol *Group = FnSection.getGroup()) {
1048249259Sdim    EHSection = getContext().getELFSection(
1049249259Sdim      EHSecName, Type, Flags | ELF::SHF_GROUP, Kind,
1050249259Sdim      FnSection.getEntrySize(), Group->getName());
1051249259Sdim  } else {
1052249259Sdim    EHSection = getContext().getELFSection(EHSecName, Type, Flags, Kind);
1053249259Sdim  }
1054251662Sdim  assert(EHSection && "Failed to get the required EH section");
1055249259Sdim
1056249259Sdim  // Switch to .ARM.extab or .ARM.exidx section
1057249259Sdim  SwitchSection(EHSection);
1058276479Sdim  EmitCodeAlignment(4);
1059249259Sdim}
1060249259Sdim
1061249259Sdiminline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
1062249259Sdim  SwitchToEHSection(".ARM.extab",
1063249259Sdim                    ELF::SHT_PROGBITS,
1064249259Sdim                    ELF::SHF_ALLOC,
1065249259Sdim                    SectionKind::getDataRel(),
1066249259Sdim                    FnStart);
1067249259Sdim}
1068249259Sdim
1069249259Sdiminline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
1070249259Sdim  SwitchToEHSection(".ARM.exidx",
1071249259Sdim                    ELF::SHT_ARM_EXIDX,
1072249259Sdim                    ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER,
1073249259Sdim                    SectionKind::getDataRel(),
1074249259Sdim                    FnStart);
1075249259Sdim}
1076276479Sdimvoid ARMELFStreamer::EmitFixup(const MCExpr *Expr, MCFixupKind Kind) {
1077276479Sdim  MCDataFragment *Frag = getOrCreateDataFragment();
1078276479Sdim  Frag->getFixups().push_back(MCFixup::Create(Frag->getContents().size(), Expr,
1079276479Sdim                                              Kind));
1080276479Sdim}
1081249259Sdim
1082249259Sdimvoid ARMELFStreamer::Reset() {
1083276479Sdim  ExTab = nullptr;
1084276479Sdim  FnStart = nullptr;
1085276479Sdim  Personality = nullptr;
1086276479Sdim  PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX;
1087261991Sdim  FPReg = ARM::SP;
1088251662Sdim  FPOffset = 0;
1089251662Sdim  SPOffset = 0;
1090261991Sdim  PendingOffset = 0;
1091251662Sdim  UsedFP = false;
1092249259Sdim  CantUnwind = false;
1093251662Sdim
1094261991Sdim  Opcodes.clear();
1095251662Sdim  UnwindOpAsm.Reset();
1096249259Sdim}
1097249259Sdim
1098261991Sdimvoid ARMELFStreamer::emitFnStart() {
1099276479Sdim  assert(FnStart == nullptr);
1100249259Sdim  FnStart = getContext().CreateTempSymbol();
1101249259Sdim  EmitLabel(FnStart);
1102249259Sdim}
1103249259Sdim
1104261991Sdimvoid ARMELFStreamer::emitFnEnd() {
1105276479Sdim  assert(FnStart && ".fnstart must precedes .fnend");
1106249259Sdim
1107249259Sdim  // Emit unwind opcodes if there is no .handlerdata directive
1108261991Sdim  if (!ExTab && !CantUnwind)
1109261991Sdim    FlushUnwindOpcodes(true);
1110249259Sdim
1111249259Sdim  // Emit the exception index table entry
1112249259Sdim  SwitchToExIdxSection(*FnStart);
1113249259Sdim
1114276479Sdim  if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX)
1115251662Sdim    EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
1116249259Sdim
1117249259Sdim  const MCSymbolRefExpr *FnStartRef =
1118249259Sdim    MCSymbolRefExpr::Create(FnStart,
1119249259Sdim                            MCSymbolRefExpr::VK_ARM_PREL31,
1120249259Sdim                            getContext());
1121249259Sdim
1122261991Sdim  EmitValue(FnStartRef, 4);
1123249259Sdim
1124249259Sdim  if (CantUnwind) {
1125276479Sdim    EmitIntValue(ARM::EHABI::EXIDX_CANTUNWIND, 4);
1126251662Sdim  } else if (ExTab) {
1127251662Sdim    // Emit a reference to the unwind opcodes in the ".ARM.extab" section.
1128249259Sdim    const MCSymbolRefExpr *ExTabEntryRef =
1129249259Sdim      MCSymbolRefExpr::Create(ExTab,
1130249259Sdim                              MCSymbolRefExpr::VK_ARM_PREL31,
1131249259Sdim                              getContext());
1132261991Sdim    EmitValue(ExTabEntryRef, 4);
1133251662Sdim  } else {
1134251662Sdim    // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
1135251662Sdim    // the second word of exception index table entry.  The size of the unwind
1136251662Sdim    // opcodes should always be 4 bytes.
1137276479Sdim    assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 &&
1138276479Sdim           "Compact model must use __aeabi_unwind_cpp_pr0 as personality");
1139261991Sdim    assert(Opcodes.size() == 4u &&
1140276479Sdim           "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4");
1141276479Sdim    uint64_t Intval = Opcodes[0] |
1142276479Sdim                      Opcodes[1] << 8 |
1143276479Sdim                      Opcodes[2] << 16 |
1144276479Sdim                      Opcodes[3] << 24;
1145276479Sdim    EmitIntValue(Intval, Opcodes.size());
1146249259Sdim  }
1147249259Sdim
1148261991Sdim  // Switch to the section containing FnStart
1149261991Sdim  SwitchSection(&FnStart->getSection());
1150261991Sdim
1151249259Sdim  // Clean exception handling frame information
1152249259Sdim  Reset();
1153249259Sdim}
1154249259Sdim
1155261991Sdimvoid ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
1156261991Sdim
1157261991Sdim// Add the R_ARM_NONE fixup at the same position
1158261991Sdimvoid ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
1159261991Sdim  const MCSymbol *PersonalitySym = getContext().GetOrCreateSymbol(Name);
1160261991Sdim
1161261991Sdim  const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::Create(
1162261991Sdim      PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext());
1163261991Sdim
1164276479Sdim  visitUsedExpr(*PersonalityRef);
1165261991Sdim  MCDataFragment *DF = getOrCreateDataFragment();
1166261991Sdim  DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
1167261991Sdim                                            PersonalityRef,
1168261991Sdim                                            MCFixup::getKindForSize(4, false)));
1169249259Sdim}
1170249259Sdim
1171261991Sdimvoid ARMELFStreamer::FlushPendingOffset() {
1172261991Sdim  if (PendingOffset != 0) {
1173261991Sdim    UnwindOpAsm.EmitSPOffset(-PendingOffset);
1174261991Sdim    PendingOffset = 0;
1175261991Sdim  }
1176261991Sdim}
1177261991Sdim
1178261991Sdimvoid ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
1179261991Sdim  // Emit the unwind opcode to restore $sp.
1180261991Sdim  if (UsedFP) {
1181261991Sdim    const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1182261991Sdim    int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
1183261991Sdim    UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
1184261991Sdim    UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
1185261991Sdim  } else {
1186261991Sdim    FlushPendingOffset();
1187261991Sdim  }
1188261991Sdim
1189261991Sdim  // Finalize the unwind opcode sequence
1190261991Sdim  UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);
1191261991Sdim
1192261991Sdim  // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
1193261991Sdim  // section.  Thus, we don't have to create an entry in the .ARM.extab
1194261991Sdim  // section.
1195276479Sdim  if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0)
1196261991Sdim    return;
1197261991Sdim
1198261991Sdim  // Switch to .ARM.extab section.
1199249259Sdim  SwitchToExTabSection(*FnStart);
1200249259Sdim
1201249259Sdim  // Create .ARM.extab label for offset in .ARM.exidx
1202249259Sdim  assert(!ExTab);
1203249259Sdim  ExTab = getContext().CreateTempSymbol();
1204249259Sdim  EmitLabel(ExTab);
1205249259Sdim
1206261991Sdim  // Emit personality
1207261991Sdim  if (Personality) {
1208261991Sdim    const MCSymbolRefExpr *PersonalityRef =
1209261991Sdim      MCSymbolRefExpr::Create(Personality,
1210261991Sdim                              MCSymbolRefExpr::VK_ARM_PREL31,
1211261991Sdim                              getContext());
1212249259Sdim
1213261991Sdim    EmitValue(PersonalityRef, 4);
1214261991Sdim  }
1215249259Sdim
1216261991Sdim  // Emit unwind opcodes
1217276479Sdim  assert((Opcodes.size() % 4) == 0 &&
1218276479Sdim         "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4");
1219276479Sdim  for (unsigned I = 0; I != Opcodes.size(); I += 4) {
1220276479Sdim    uint64_t Intval = Opcodes[I] |
1221276479Sdim                      Opcodes[I + 1] << 8 |
1222276479Sdim                      Opcodes[I + 2] << 16 |
1223276479Sdim                      Opcodes[I + 3] << 24;
1224276479Sdim    EmitIntValue(Intval, 4);
1225276479Sdim  }
1226249259Sdim
1227261991Sdim  // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
1228261991Sdim  // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
1229261991Sdim  // after the unwind opcodes.  The handler data consists of several 32-bit
1230261991Sdim  // words, and should be terminated by zero.
1231261991Sdim  //
1232261991Sdim  // In case that the .handlerdata directive is not specified by the
1233261991Sdim  // programmer, we should emit zero to terminate the handler data.
1234261991Sdim  if (NoHandlerData && !Personality)
1235261991Sdim    EmitIntValue(0, 4);
1236249259Sdim}
1237249259Sdim
1238261991Sdimvoid ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
1239261991Sdim
1240261991Sdimvoid ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
1241249259Sdim  Personality = Per;
1242251662Sdim  UnwindOpAsm.setPersonality(Per);
1243249259Sdim}
1244249259Sdim
1245276479Sdimvoid ARMELFStreamer::emitPersonalityIndex(unsigned Index) {
1246276479Sdim  assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index");
1247276479Sdim  PersonalityIndex = Index;
1248276479Sdim}
1249276479Sdim
1250261991Sdimvoid ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg,
1251249259Sdim                               int64_t Offset) {
1252261991Sdim  assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
1253251662Sdim         "the operand of .setfp directive should be either $sp or $fp");
1254251662Sdim
1255251662Sdim  UsedFP = true;
1256261991Sdim  FPReg = NewFPReg;
1257261991Sdim
1258261991Sdim  if (NewSPReg == ARM::SP)
1259261991Sdim    FPOffset = SPOffset + Offset;
1260261991Sdim  else
1261261991Sdim    FPOffset += Offset;
1262249259Sdim}
1263249259Sdim
1264276479Sdimvoid ARMELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
1265276479Sdim  assert((Reg != ARM::SP && Reg != ARM::PC) &&
1266276479Sdim         "the operand of .movsp cannot be either sp or pc");
1267276479Sdim  assert(FPReg == ARM::SP && "current FP must be SP");
1268276479Sdim
1269276479Sdim  FlushPendingOffset();
1270276479Sdim
1271276479Sdim  FPReg = Reg;
1272276479Sdim  FPOffset = SPOffset + Offset;
1273276479Sdim
1274276479Sdim  const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1275276479Sdim  UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
1276276479Sdim}
1277276479Sdim
1278261991Sdimvoid ARMELFStreamer::emitPad(int64_t Offset) {
1279261991Sdim  // Track the change of the $sp offset
1280261991Sdim  SPOffset -= Offset;
1281261991Sdim
1282261991Sdim  // To squash multiple .pad directives, we should delay the unwind opcode
1283261991Sdim  // until the .save, .vsave, .handlerdata, or .fnend directives.
1284261991Sdim  PendingOffset -= Offset;
1285249259Sdim}
1286249259Sdim
1287261991Sdimvoid ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
1288249259Sdim                                 bool IsVector) {
1289261991Sdim  // Collect the registers in the register list
1290261991Sdim  unsigned Count = 0;
1291261991Sdim  uint32_t Mask = 0;
1292261991Sdim  const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1293261991Sdim  for (size_t i = 0; i < RegList.size(); ++i) {
1294261991Sdim    unsigned Reg = MRI->getEncodingValue(RegList[i]);
1295261991Sdim    assert(Reg < (IsVector ? 32U : 16U) && "Register out of range");
1296261991Sdim    unsigned Bit = (1u << Reg);
1297261991Sdim    if ((Mask & Bit) == 0) {
1298261991Sdim      Mask |= Bit;
1299261991Sdim      ++Count;
1300261991Sdim    }
1301261991Sdim  }
1302251662Sdim
1303261991Sdim  // Track the change the $sp offset: For the .save directive, the
1304261991Sdim  // corresponding push instruction will decrease the $sp by (4 * Count).
1305261991Sdim  // For the .vsave directive, the corresponding vpush instruction will
1306261991Sdim  // decrease $sp by (8 * Count).
1307261991Sdim  SPOffset -= Count * (IsVector ? 8 : 4);
1308251662Sdim
1309261991Sdim  // Emit the opcode
1310261991Sdim  FlushPendingOffset();
1311261991Sdim  if (IsVector)
1312261991Sdim    UnwindOpAsm.EmitVFPRegSave(Mask);
1313261991Sdim  else
1314261991Sdim    UnwindOpAsm.EmitRegSave(Mask);
1315249259Sdim}
1316249259Sdim
1317276479Sdimvoid ARMELFStreamer::emitUnwindRaw(int64_t Offset,
1318276479Sdim                                   const SmallVectorImpl<uint8_t> &Opcodes) {
1319276479Sdim  FlushPendingOffset();
1320276479Sdim  SPOffset = SPOffset - Offset;
1321276479Sdim  UnwindOpAsm.EmitRaw(Opcodes);
1322276479Sdim}
1323276479Sdim
1324249259Sdimnamespace llvm {
1325261991Sdim
1326261991SdimMCStreamer *createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
1327276479Sdim                                bool isVerboseAsm, bool useDwarfDirectory,
1328261991Sdim                                MCInstPrinter *InstPrint, MCCodeEmitter *CE,
1329261991Sdim                                MCAsmBackend *TAB, bool ShowInst) {
1330276479Sdim  MCStreamer *S = llvm::createAsmStreamer(
1331276479Sdim      Ctx, OS, isVerboseAsm, useDwarfDirectory, InstPrint, CE, TAB, ShowInst);
1332276479Sdim  new ARMTargetAsmStreamer(*S, OS, *InstPrint, isVerboseAsm);
1333276479Sdim  return S;
1334276479Sdim}
1335261991Sdim
1336276479SdimMCStreamer *createARMNullStreamer(MCContext &Ctx) {
1337276479Sdim  MCStreamer *S = llvm::createNullStreamer(Ctx);
1338276479Sdim  new ARMTargetStreamer(*S);
1339276479Sdim  return S;
1340261991Sdim}
1341261991Sdim
1342249259Sdim  MCELFStreamer* createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
1343249259Sdim                                      raw_ostream &OS, MCCodeEmitter *Emitter,
1344249259Sdim                                      bool RelaxAll, bool NoExecStack,
1345249259Sdim                                      bool IsThumb) {
1346276479Sdim    ARMELFStreamer *S = new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb);
1347276479Sdim    new ARMTargetELFStreamer(*S);
1348261991Sdim    // FIXME: This should eventually end up somewhere else where more
1349261991Sdim    // intelligent flag decisions can be made. For now we are just maintaining
1350261991Sdim    // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
1351261991Sdim    S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
1352261991Sdim
1353249259Sdim    if (RelaxAll)
1354249259Sdim      S->getAssembler().setRelaxAll(true);
1355249259Sdim    if (NoExecStack)
1356249259Sdim      S->getAssembler().setNoExecStack(true);
1357249259Sdim    return S;
1358249259Sdim  }
1359249259Sdim
1360249259Sdim}
1361249259Sdim
1362249259Sdim
1363