Flip the ownership of MCStreamer and MCTargetStreamer.
[oota-llvm.git] / lib / Target / ARM / MCTargetDesc / ARMELFStreamer.cpp
1 //===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file assembles .s files and emits ARM ELF .o object files. Different
11 // from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to
12 // delimit regions of data and code.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "ARMRegisterInfo.h"
17 #include "ARMUnwindOp.h"
18 #include "ARMUnwindOpAsm.h"
19 #include "llvm/ADT/SmallPtrSet.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/MC/MCAsmBackend.h"
22 #include "llvm/MC/MCAssembler.h"
23 #include "llvm/MC/MCCodeEmitter.h"
24 #include "llvm/MC/MCContext.h"
25 #include "llvm/MC/MCELF.h"
26 #include "llvm/MC/MCELFStreamer.h"
27 #include "llvm/MC/MCELFSymbolFlags.h"
28 #include "llvm/MC/MCExpr.h"
29 #include "llvm/MC/MCInst.h"
30 #include "llvm/MC/MCInstPrinter.h"
31 #include "llvm/MC/MCObjectStreamer.h"
32 #include "llvm/MC/MCRegisterInfo.h"
33 #include "llvm/MC/MCSection.h"
34 #include "llvm/MC/MCSectionELF.h"
35 #include "llvm/MC/MCStreamer.h"
36 #include "llvm/MC/MCSymbol.h"
37 #include "llvm/MC/MCValue.h"
38 #include "llvm/Support/Debug.h"
39 #include "llvm/Support/ELF.h"
40 #include "llvm/Support/FormattedStream.h"
41 #include "llvm/Support/raw_ostream.h"
42
43 using namespace llvm;
44
45 static std::string GetAEABIUnwindPersonalityName(unsigned Index) {
46   assert(Index < NUM_PERSONALITY_INDEX && "Invalid personality index");
47   return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
48 }
49
50 namespace {
51
52 class ARMELFStreamer;
53
54 class ARMTargetAsmStreamer : public ARMTargetStreamer {
55   formatted_raw_ostream &OS;
56   MCInstPrinter &InstPrinter;
57
58   virtual void emitFnStart();
59   virtual void emitFnEnd();
60   virtual void emitCantUnwind();
61   virtual void emitPersonality(const MCSymbol *Personality);
62   virtual void emitHandlerData();
63   virtual void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
64   virtual void emitPad(int64_t Offset);
65   virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
66                            bool isVector);
67
68 public:
69   ARMTargetAsmStreamer(formatted_raw_ostream &OS, MCInstPrinter &InstPrinter);
70 };
71
72 ARMTargetAsmStreamer::ARMTargetAsmStreamer(formatted_raw_ostream &OS,
73                                            MCInstPrinter &InstPrinter)
74     : OS(OS), InstPrinter(InstPrinter) {}
75 void ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; }
76 void ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; }
77 void ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; }
78 void ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) {
79   OS << "\t.personality " << Personality->getName() << '\n';
80 }
81 void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }
82 void ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
83                                      int64_t Offset) {
84   OS << "\t.setfp\t";
85   InstPrinter.printRegName(OS, FpReg);
86   OS << ", ";
87   InstPrinter.printRegName(OS, SpReg);
88   if (Offset)
89     OS << ", #" << Offset;
90   OS << '\n';
91 }
92 void ARMTargetAsmStreamer::emitPad(int64_t Offset) {
93   OS << "\t.pad\t#" << Offset << '\n';
94 }
95 void ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
96                                        bool isVector) {
97   assert(RegList.size() && "RegList should not be empty");
98   if (isVector)
99     OS << "\t.vsave\t{";
100   else
101     OS << "\t.save\t{";
102
103   InstPrinter.printRegName(OS, RegList[0]);
104
105   for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
106     OS << ", ";
107     InstPrinter.printRegName(OS, RegList[i]);
108   }
109
110   OS << "}\n";
111 }
112
113 class ARMTargetELFStreamer : public ARMTargetStreamer {
114   ARMELFStreamer &getStreamer();
115   virtual void emitFnStart();
116   virtual void emitFnEnd();
117   virtual void emitCantUnwind();
118   virtual void emitPersonality(const MCSymbol *Personality);
119   virtual void emitHandlerData();
120   virtual void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
121   virtual void emitPad(int64_t Offset);
122   virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
123                            bool isVector);
124 };
125
126 /// Extend the generic ELFStreamer class so that it can emit mapping symbols at
127 /// the appropriate points in the object files. These symbols are defined in the
128 /// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.
129 ///
130 /// In brief: $a, $t or $d should be emitted at the start of each contiguous
131 /// region of ARM code, Thumb code or data in a section. In practice, this
132 /// emission does not rely on explicit assembler directives but on inherent
133 /// properties of the directives doing the emission (e.g. ".byte" is data, "add
134 /// r0, r0, r0" an instruction).
135 ///
136 /// As a result this system is orthogonal to the DataRegion infrastructure used
137 /// by MachO. Beware!
138 class ARMELFStreamer : public MCELFStreamer {
139 public:
140   friend class ARMTargetELFStreamer;
141
142   ARMELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer,
143                  MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter,
144                  bool IsThumb)
145       : MCELFStreamer(Context, TargetStreamer, TAB, OS, Emitter),
146         IsThumb(IsThumb), MappingSymbolCounter(0), LastEMS(EMS_None) {
147     Reset();
148   }
149
150   ~ARMELFStreamer() {}
151
152   // ARM exception handling directives
153   void emitFnStart();
154   void emitFnEnd();
155   void emitCantUnwind();
156   void emitPersonality(const MCSymbol *Per);
157   void emitHandlerData();
158   void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0);
159   void emitPad(int64_t Offset);
160   void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector);
161
162   virtual void ChangeSection(const MCSection *Section,
163                              const MCExpr *Subsection) {
164     // We have to keep track of the mapping symbol state of any sections we
165     // use. Each one should start off as EMS_None, which is provided as the
166     // default constructor by DenseMap::lookup.
167     LastMappingSymbols[getPreviousSection().first] = LastEMS;
168     LastEMS = LastMappingSymbols.lookup(Section);
169
170     MCELFStreamer::ChangeSection(Section, Subsection);
171   }
172
173   /// This function is the one used to emit instruction data into the ELF
174   /// streamer. We override it to add the appropriate mapping symbol if
175   /// necessary.
176   virtual void EmitInstruction(const MCInst& Inst) {
177     if (IsThumb)
178       EmitThumbMappingSymbol();
179     else
180       EmitARMMappingSymbol();
181
182     MCELFStreamer::EmitInstruction(Inst);
183   }
184
185   /// This is one of the functions used to emit data into an ELF section, so the
186   /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
187   /// necessary.
188   virtual void EmitBytes(StringRef Data) {
189     EmitDataMappingSymbol();
190     MCELFStreamer::EmitBytes(Data);
191   }
192
193   /// This is one of the functions used to emit data into an ELF section, so the
194   /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
195   /// necessary.
196   virtual void EmitValueImpl(const MCExpr *Value, unsigned Size) {
197     EmitDataMappingSymbol();
198     MCELFStreamer::EmitValueImpl(Value, Size);
199   }
200
201   virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {
202     MCELFStreamer::EmitAssemblerFlag(Flag);
203
204     switch (Flag) {
205     case MCAF_SyntaxUnified:
206       return; // no-op here.
207     case MCAF_Code16:
208       IsThumb = true;
209       return; // Change to Thumb mode
210     case MCAF_Code32:
211       IsThumb = false;
212       return; // Change to ARM mode
213     case MCAF_Code64:
214       return;
215     case MCAF_SubsectionsViaSymbols:
216       return;
217     }
218   }
219
220 private:
221   enum ElfMappingSymbol {
222     EMS_None,
223     EMS_ARM,
224     EMS_Thumb,
225     EMS_Data
226   };
227
228   void EmitDataMappingSymbol() {
229     if (LastEMS == EMS_Data) return;
230     EmitMappingSymbol("$d");
231     LastEMS = EMS_Data;
232   }
233
234   void EmitThumbMappingSymbol() {
235     if (LastEMS == EMS_Thumb) return;
236     EmitMappingSymbol("$t");
237     LastEMS = EMS_Thumb;
238   }
239
240   void EmitARMMappingSymbol() {
241     if (LastEMS == EMS_ARM) return;
242     EmitMappingSymbol("$a");
243     LastEMS = EMS_ARM;
244   }
245
246   void EmitMappingSymbol(StringRef Name) {
247     MCSymbol *Start = getContext().CreateTempSymbol();
248     EmitLabel(Start);
249
250     MCSymbol *Symbol =
251       getContext().GetOrCreateSymbol(Name + "." +
252                                      Twine(MappingSymbolCounter++));
253
254     MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
255     MCELF::SetType(SD, ELF::STT_NOTYPE);
256     MCELF::SetBinding(SD, ELF::STB_LOCAL);
257     SD.setExternal(false);
258     AssignSection(Symbol, getCurrentSection().first);
259
260     const MCExpr *Value = MCSymbolRefExpr::Create(Start, getContext());
261     Symbol->setVariableValue(Value);
262   }
263
264   void EmitThumbFunc(MCSymbol *Func) {
265     // FIXME: Anything needed here to flag the function as thumb?
266
267     getAssembler().setIsThumbFunc(Func);
268
269     MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Func);
270     SD.setFlags(SD.getFlags() | ELF_Other_ThumbFunc);
271   }
272
273   // Helper functions for ARM exception handling directives
274   void Reset();
275
276   void EmitPersonalityFixup(StringRef Name);
277   void FlushPendingOffset();
278   void FlushUnwindOpcodes(bool NoHandlerData);
279
280   void SwitchToEHSection(const char *Prefix, unsigned Type, unsigned Flags,
281                          SectionKind Kind, const MCSymbol &Fn);
282   void SwitchToExTabSection(const MCSymbol &FnStart);
283   void SwitchToExIdxSection(const MCSymbol &FnStart);
284
285   bool IsThumb;
286   int64_t MappingSymbolCounter;
287
288   DenseMap<const MCSection *, ElfMappingSymbol> LastMappingSymbols;
289   ElfMappingSymbol LastEMS;
290
291   // ARM Exception Handling Frame Information
292   MCSymbol *ExTab;
293   MCSymbol *FnStart;
294   const MCSymbol *Personality;
295   unsigned PersonalityIndex;
296   unsigned FPReg; // Frame pointer register
297   int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp)
298   int64_t SPOffset; // Offset: (final $sp) - (initial $sp)
299   int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp)
300   bool UsedFP;
301   bool CantUnwind;
302   SmallVector<uint8_t, 64> Opcodes;
303   UnwindOpcodeAssembler UnwindOpAsm;
304 };
305 } // end anonymous namespace
306
307 ARMELFStreamer &ARMTargetELFStreamer::getStreamer() {
308   ARMELFStreamer *S = static_cast<ARMELFStreamer *>(Streamer);
309   return *S;
310 }
311
312 void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }
313 void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }
314 void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }
315 void ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) {
316   getStreamer().emitPersonality(Personality);
317 }
318 void ARMTargetELFStreamer::emitHandlerData() {
319   getStreamer().emitHandlerData();
320 }
321 void ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
322                                      int64_t Offset) {
323   getStreamer().emitSetFP(FpReg, SpReg, Offset);
324 }
325 void ARMTargetELFStreamer::emitPad(int64_t Offset) {
326   getStreamer().emitPad(Offset);
327 }
328 void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
329                                        bool isVector) {
330   getStreamer().emitRegSave(RegList, isVector);
331 }
332
333 inline void ARMELFStreamer::SwitchToEHSection(const char *Prefix,
334                                               unsigned Type,
335                                               unsigned Flags,
336                                               SectionKind Kind,
337                                               const MCSymbol &Fn) {
338   const MCSectionELF &FnSection =
339     static_cast<const MCSectionELF &>(Fn.getSection());
340
341   // Create the name for new section
342   StringRef FnSecName(FnSection.getSectionName());
343   SmallString<128> EHSecName(Prefix);
344   if (FnSecName != ".text") {
345     EHSecName += FnSecName;
346   }
347
348   // Get .ARM.extab or .ARM.exidx section
349   const MCSectionELF *EHSection = NULL;
350   if (const MCSymbol *Group = FnSection.getGroup()) {
351     EHSection = getContext().getELFSection(
352       EHSecName, Type, Flags | ELF::SHF_GROUP, Kind,
353       FnSection.getEntrySize(), Group->getName());
354   } else {
355     EHSection = getContext().getELFSection(EHSecName, Type, Flags, Kind);
356   }
357   assert(EHSection && "Failed to get the required EH section");
358
359   // Switch to .ARM.extab or .ARM.exidx section
360   SwitchSection(EHSection);
361   EmitCodeAlignment(4, 0);
362 }
363
364 inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
365   SwitchToEHSection(".ARM.extab",
366                     ELF::SHT_PROGBITS,
367                     ELF::SHF_ALLOC,
368                     SectionKind::getDataRel(),
369                     FnStart);
370 }
371
372 inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
373   SwitchToEHSection(".ARM.exidx",
374                     ELF::SHT_ARM_EXIDX,
375                     ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER,
376                     SectionKind::getDataRel(),
377                     FnStart);
378 }
379
380 void ARMELFStreamer::Reset() {
381   ExTab = NULL;
382   FnStart = NULL;
383   Personality = NULL;
384   PersonalityIndex = NUM_PERSONALITY_INDEX;
385   FPReg = ARM::SP;
386   FPOffset = 0;
387   SPOffset = 0;
388   PendingOffset = 0;
389   UsedFP = false;
390   CantUnwind = false;
391
392   Opcodes.clear();
393   UnwindOpAsm.Reset();
394 }
395
396 void ARMELFStreamer::emitFnStart() {
397   assert(FnStart == 0);
398   FnStart = getContext().CreateTempSymbol();
399   EmitLabel(FnStart);
400 }
401
402 void ARMELFStreamer::emitFnEnd() {
403   assert(FnStart && ".fnstart must preceeds .fnend");
404
405   // Emit unwind opcodes if there is no .handlerdata directive
406   if (!ExTab && !CantUnwind)
407     FlushUnwindOpcodes(true);
408
409   // Emit the exception index table entry
410   SwitchToExIdxSection(*FnStart);
411
412   if (PersonalityIndex < NUM_PERSONALITY_INDEX)
413     EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
414
415   const MCSymbolRefExpr *FnStartRef =
416     MCSymbolRefExpr::Create(FnStart,
417                             MCSymbolRefExpr::VK_ARM_PREL31,
418                             getContext());
419
420   EmitValue(FnStartRef, 4);
421
422   if (CantUnwind) {
423     EmitIntValue(EXIDX_CANTUNWIND, 4);
424   } else if (ExTab) {
425     // Emit a reference to the unwind opcodes in the ".ARM.extab" section.
426     const MCSymbolRefExpr *ExTabEntryRef =
427       MCSymbolRefExpr::Create(ExTab,
428                               MCSymbolRefExpr::VK_ARM_PREL31,
429                               getContext());
430     EmitValue(ExTabEntryRef, 4);
431   } else {
432     // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
433     // the second word of exception index table entry.  The size of the unwind
434     // opcodes should always be 4 bytes.
435     assert(PersonalityIndex == AEABI_UNWIND_CPP_PR0 &&
436            "Compact model must use __aeabi_cpp_unwind_pr0 as personality");
437     assert(Opcodes.size() == 4u &&
438            "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be equal to 4");
439     EmitBytes(StringRef(reinterpret_cast<const char*>(Opcodes.data()),
440                         Opcodes.size()));
441   }
442
443   // Switch to the section containing FnStart
444   SwitchSection(&FnStart->getSection());
445
446   // Clean exception handling frame information
447   Reset();
448 }
449
450 void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
451
452 // Add the R_ARM_NONE fixup at the same position
453 void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
454   const MCSymbol *PersonalitySym = getContext().GetOrCreateSymbol(Name);
455
456   const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::Create(
457       PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext());
458
459   AddValueSymbols(PersonalityRef);
460   MCDataFragment *DF = getOrCreateDataFragment();
461   DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
462                                             PersonalityRef,
463                                             MCFixup::getKindForSize(4, false)));
464 }
465
466 void ARMELFStreamer::FlushPendingOffset() {
467   if (PendingOffset != 0) {
468     UnwindOpAsm.EmitSPOffset(-PendingOffset);
469     PendingOffset = 0;
470   }
471 }
472
473 void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
474   // Emit the unwind opcode to restore $sp.
475   if (UsedFP) {
476     const MCRegisterInfo *MRI = getContext().getRegisterInfo();
477     int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
478     UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
479     UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
480   } else {
481     FlushPendingOffset();
482   }
483
484   // Finalize the unwind opcode sequence
485   UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);
486
487   // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
488   // section.  Thus, we don't have to create an entry in the .ARM.extab
489   // section.
490   if (NoHandlerData && PersonalityIndex == AEABI_UNWIND_CPP_PR0)
491     return;
492
493   // Switch to .ARM.extab section.
494   SwitchToExTabSection(*FnStart);
495
496   // Create .ARM.extab label for offset in .ARM.exidx
497   assert(!ExTab);
498   ExTab = getContext().CreateTempSymbol();
499   EmitLabel(ExTab);
500
501   // Emit personality
502   if (Personality) {
503     const MCSymbolRefExpr *PersonalityRef =
504       MCSymbolRefExpr::Create(Personality,
505                               MCSymbolRefExpr::VK_ARM_PREL31,
506                               getContext());
507
508     EmitValue(PersonalityRef, 4);
509   }
510
511   // Emit unwind opcodes
512   EmitBytes(StringRef(reinterpret_cast<const char *>(Opcodes.data()),
513                       Opcodes.size()));
514
515   // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
516   // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
517   // after the unwind opcodes.  The handler data consists of several 32-bit
518   // words, and should be terminated by zero.
519   //
520   // In case that the .handlerdata directive is not specified by the
521   // programmer, we should emit zero to terminate the handler data.
522   if (NoHandlerData && !Personality)
523     EmitIntValue(0, 4);
524 }
525
526 void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
527
528 void ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
529   Personality = Per;
530   UnwindOpAsm.setPersonality(Per);
531 }
532
533 void ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg,
534                                int64_t Offset) {
535   assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
536          "the operand of .setfp directive should be either $sp or $fp");
537
538   UsedFP = true;
539   FPReg = NewFPReg;
540
541   if (NewSPReg == ARM::SP)
542     FPOffset = SPOffset + Offset;
543   else
544     FPOffset += Offset;
545 }
546
547 void ARMELFStreamer::emitPad(int64_t Offset) {
548   // Track the change of the $sp offset
549   SPOffset -= Offset;
550
551   // To squash multiple .pad directives, we should delay the unwind opcode
552   // until the .save, .vsave, .handlerdata, or .fnend directives.
553   PendingOffset -= Offset;
554 }
555
556 void ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
557                                  bool IsVector) {
558   // Collect the registers in the register list
559   unsigned Count = 0;
560   uint32_t Mask = 0;
561   const MCRegisterInfo *MRI = getContext().getRegisterInfo();
562   for (size_t i = 0; i < RegList.size(); ++i) {
563     unsigned Reg = MRI->getEncodingValue(RegList[i]);
564     assert(Reg < (IsVector ? 32U : 16U) && "Register out of range");
565     unsigned Bit = (1u << Reg);
566     if ((Mask & Bit) == 0) {
567       Mask |= Bit;
568       ++Count;
569     }
570   }
571
572   // Track the change the $sp offset: For the .save directive, the
573   // corresponding push instruction will decrease the $sp by (4 * Count).
574   // For the .vsave directive, the corresponding vpush instruction will
575   // decrease $sp by (8 * Count).
576   SPOffset -= Count * (IsVector ? 8 : 4);
577
578   // Emit the opcode
579   FlushPendingOffset();
580   if (IsVector)
581     UnwindOpAsm.EmitVFPRegSave(Mask);
582   else
583     UnwindOpAsm.EmitRegSave(Mask);
584 }
585
586 namespace llvm {
587
588 MCStreamer *createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
589                                 bool isVerboseAsm, bool useLoc, bool useCFI,
590                                 bool useDwarfDirectory,
591                                 MCInstPrinter *InstPrint, MCCodeEmitter *CE,
592                                 MCAsmBackend *TAB, bool ShowInst) {
593   ARMTargetAsmStreamer *S = new ARMTargetAsmStreamer(OS, *InstPrint);
594
595   return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI,
596                                  useDwarfDirectory, InstPrint, CE, TAB,
597                                  ShowInst);
598 }
599
600   MCELFStreamer* createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
601                                       raw_ostream &OS, MCCodeEmitter *Emitter,
602                                       bool RelaxAll, bool NoExecStack,
603                                       bool IsThumb) {
604     ARMTargetELFStreamer *TS = new ARMTargetELFStreamer();
605     ARMELFStreamer *S =
606         new ARMELFStreamer(Context, TS, TAB, OS, Emitter, IsThumb);
607     // FIXME: This should eventually end up somewhere else where more
608     // intelligent flag decisions can be made. For now we are just maintaining
609     // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
610     S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
611
612     if (RelaxAll)
613       S->getAssembler().setRelaxAll(true);
614     if (NoExecStack)
615       S->getAssembler().setNoExecStack(true);
616     return S;
617   }
618
619 }
620
621