ARMELFStreamer.cpp revision 251662
1155192Srwatson//===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===//
2180701Srwatson//
3155192Srwatson//                     The LLVM Compiler Infrastructure
4155192Srwatson//
5155192Srwatson// This file is distributed under the University of Illinois Open Source
6155192Srwatson// License. See LICENSE.TXT for details.
7155192Srwatson//
8155192Srwatson//===----------------------------------------------------------------------===//
9155192Srwatson//
10155192Srwatson// This file assembles .s files and emits ARM ELF .o object files. Different
11155192Srwatson// from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to
12155192Srwatson// delimit regions of data and code.
13180701Srwatson//
14155192Srwatson//===----------------------------------------------------------------------===//
15155192Srwatson
16155192Srwatson#include "ARMRegisterInfo.h"
17155192Srwatson#include "ARMUnwindOp.h"
18155192Srwatson#include "ARMUnwindOpAsm.h"
19155192Srwatson#include "llvm/ADT/SmallPtrSet.h"
20155192Srwatson#include "llvm/ADT/Twine.h"
21155192Srwatson#include "llvm/MC/MCAsmBackend.h"
22155192Srwatson#include "llvm/MC/MCAssembler.h"
23155192Srwatson#include "llvm/MC/MCCodeEmitter.h"
24155192Srwatson#include "llvm/MC/MCContext.h"
25155192Srwatson#include "llvm/MC/MCELF.h"
26155192Srwatson#include "llvm/MC/MCELFStreamer.h"
27155192Srwatson#include "llvm/MC/MCELFSymbolFlags.h"
28155192Srwatson#include "llvm/MC/MCExpr.h"
29155192Srwatson#include "llvm/MC/MCInst.h"
30178186Srwatson#include "llvm/MC/MCObjectStreamer.h"
31178186Srwatson#include "llvm/MC/MCRegisterInfo.h"
32178186Srwatson#include "llvm/MC/MCSection.h"
33155192Srwatson#include "llvm/MC/MCSectionELF.h"
34155192Srwatson#include "llvm/MC/MCStreamer.h"
35155192Srwatson#include "llvm/MC/MCSymbol.h"
36155192Srwatson#include "llvm/MC/MCValue.h"
37155192Srwatson#include "llvm/Support/Debug.h"
38155192Srwatson#include "llvm/Support/ELF.h"
39155192Srwatson#include "llvm/Support/raw_ostream.h"
40160136Swsalamon
41155192Srwatsonusing namespace llvm;
42155192Srwatson
43155192Srwatsonstatic std::string GetAEABIUnwindPersonalityName(unsigned Index) {
44155192Srwatson  assert(Index < NUM_PERSONALITY_INDEX && "Invalid personality index");
45155192Srwatson  return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
46155192Srwatson}
47155192Srwatson
48155192Srwatsonnamespace {
49155192Srwatson
50155192Srwatson/// Extend the generic ELFStreamer class so that it can emit mapping symbols at
51155192Srwatson/// the appropriate points in the object files. These symbols are defined in the
52155192Srwatson/// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.
53155192Srwatson///
54155192Srwatson/// In brief: $a, $t or $d should be emitted at the start of each contiguous
55155192Srwatson/// region of ARM code, Thumb code or data in a section. In practice, this
56155192Srwatson/// emission does not rely on explicit assembler directives but on inherent
57155192Srwatson/// properties of the directives doing the emission (e.g. ".byte" is data, "add
58155192Srwatson/// r0, r0, r0" an instruction).
59155192Srwatson///
60155192Srwatson/// As a result this system is orthogonal to the DataRegion infrastructure used
61155192Srwatson/// by MachO. Beware!
62155192Srwatsonclass ARMELFStreamer : public MCELFStreamer {
63155192Srwatsonpublic:
64155192Srwatson  ARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
65155192Srwatson                 MCCodeEmitter *Emitter, bool IsThumb)
66155192Srwatson      : MCELFStreamer(SK_ARMELFStreamer, Context, TAB, OS, Emitter),
67155192Srwatson        IsThumb(IsThumb), MappingSymbolCounter(0), LastEMS(EMS_None) {
68155192Srwatson    Reset();
69155192Srwatson  }
70155192Srwatson
71155192Srwatson  ~ARMELFStreamer() {}
72155192Srwatson
73156889Srwatson  // ARM exception handling directives
74156889Srwatson  virtual void EmitFnStart();
75156889Srwatson  virtual void EmitFnEnd();
76156889Srwatson  virtual void EmitCantUnwind();
77156889Srwatson  virtual void EmitPersonality(const MCSymbol *Per);
78156889Srwatson  virtual void EmitHandlerData();
79155192Srwatson  virtual void EmitSetFP(unsigned NewFpReg,
80156889Srwatson                         unsigned NewSpReg,
81155192Srwatson                         int64_t Offset = 0);
82156889Srwatson  virtual void EmitPad(int64_t Offset);
83155192Srwatson  virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
84162466Srwatson                           bool isVector);
85155192Srwatson
86155192Srwatson  virtual void ChangeSection(const MCSection *Section,
87155192Srwatson                             const MCExpr *Subsection) {
88155192Srwatson    // We have to keep track of the mapping symbol state of any sections we
89155192Srwatson    // use. Each one should start off as EMS_None, which is provided as the
90155192Srwatson    // default constructor by DenseMap::lookup.
91155192Srwatson    LastMappingSymbols[getPreviousSection().first] = LastEMS;
92155192Srwatson    LastEMS = LastMappingSymbols.lookup(Section);
93155192Srwatson
94156889Srwatson    MCELFStreamer::ChangeSection(Section, Subsection);
95155192Srwatson  }
96155192Srwatson
97155192Srwatson  /// This function is the one used to emit instruction data into the ELF
98155192Srwatson  /// streamer. We override it to add the appropriate mapping symbol if
99155192Srwatson  /// necessary.
100155192Srwatson  virtual void EmitInstruction(const MCInst& Inst) {
101155192Srwatson    if (IsThumb)
102155192Srwatson      EmitThumbMappingSymbol();
103155192Srwatson    else
104155192Srwatson      EmitARMMappingSymbol();
105155192Srwatson
106155192Srwatson    MCELFStreamer::EmitInstruction(Inst);
107155192Srwatson  }
108155192Srwatson
109155192Srwatson  /// This is one of the functions used to emit data into an ELF section, so the
110155192Srwatson  /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
111155192Srwatson  /// necessary.
112155192Srwatson  virtual void EmitBytes(StringRef Data, unsigned AddrSpace) {
113155192Srwatson    EmitDataMappingSymbol();
114155192Srwatson    MCELFStreamer::EmitBytes(Data, AddrSpace);
115155192Srwatson  }
116156889Srwatson
117161635Srwatson  /// This is one of the functions used to emit data into an ELF section, so the
118162466Srwatson  /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
119170196Srwatson  /// necessary.
120162466Srwatson  virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
121162466Srwatson                             unsigned AddrSpace) {
122162466Srwatson    EmitDataMappingSymbol();
123162466Srwatson    MCELFStreamer::EmitValueImpl(Value, Size, AddrSpace);
124155192Srwatson  }
125162466Srwatson
126162466Srwatson  virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {
127155192Srwatson    MCELFStreamer::EmitAssemblerFlag(Flag);
128162466Srwatson
129162466Srwatson    switch (Flag) {
130162466Srwatson    case MCAF_SyntaxUnified:
131162466Srwatson      return; // no-op here.
132162466Srwatson    case MCAF_Code16:
133155192Srwatson      IsThumb = true;
134155192Srwatson      return; // Change to Thumb mode
135155192Srwatson    case MCAF_Code32:
136155192Srwatson      IsThumb = false;
137156889Srwatson      return; // Change to ARM mode
138156889Srwatson    case MCAF_Code64:
139155192Srwatson      return;
140155192Srwatson    case MCAF_SubsectionsViaSymbols:
141155192Srwatson      return;
142155192Srwatson    }
143155192Srwatson  }
144155192Srwatson
145156889Srwatson  static bool classof(const MCStreamer *S) {
146155192Srwatson    return S->getKind() == SK_ARMELFStreamer;
147155192Srwatson  }
148155192Srwatson
149155192Srwatsonprivate:
150156889Srwatson  enum ElfMappingSymbol {
151155192Srwatson    EMS_None,
152155192Srwatson    EMS_ARM,
153156889Srwatson    EMS_Thumb,
154155192Srwatson    EMS_Data
155155192Srwatson  };
156155192Srwatson
157155192Srwatson  void EmitDataMappingSymbol() {
158155192Srwatson    if (LastEMS == EMS_Data) return;
159170196Srwatson    EmitMappingSymbol("$d");
160155192Srwatson    LastEMS = EMS_Data;
161155192Srwatson  }
162155192Srwatson
163155192Srwatson  void EmitThumbMappingSymbol() {
164155192Srwatson    if (LastEMS == EMS_Thumb) return;
165155192Srwatson    EmitMappingSymbol("$t");
166155192Srwatson    LastEMS = EMS_Thumb;
167155192Srwatson  }
168155192Srwatson
169155192Srwatson  void EmitARMMappingSymbol() {
170155192Srwatson    if (LastEMS == EMS_ARM) return;
171155192Srwatson    EmitMappingSymbol("$a");
172155192Srwatson    LastEMS = EMS_ARM;
173155192Srwatson  }
174155192Srwatson
175155192Srwatson  void EmitMappingSymbol(StringRef Name) {
176155192Srwatson    MCSymbol *Start = getContext().CreateTempSymbol();
177155192Srwatson    EmitLabel(Start);
178155192Srwatson
179155192Srwatson    MCSymbol *Symbol =
180155192Srwatson      getContext().GetOrCreateSymbol(Name + "." +
181155192Srwatson                                     Twine(MappingSymbolCounter++));
182155192Srwatson
183155192Srwatson    MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
184155192Srwatson    MCELF::SetType(SD, ELF::STT_NOTYPE);
185155192Srwatson    MCELF::SetBinding(SD, ELF::STB_LOCAL);
186155192Srwatson    SD.setExternal(false);
187155192Srwatson    Symbol->setSection(*getCurrentSection().first);
188155192Srwatson
189155192Srwatson    const MCExpr *Value = MCSymbolRefExpr::Create(Start, getContext());
190155192Srwatson    Symbol->setVariableValue(Value);
191155192Srwatson  }
192155192Srwatson
193155192Srwatson  void EmitThumbFunc(MCSymbol *Func) {
194155192Srwatson    // FIXME: Anything needed here to flag the function as thumb?
195155192Srwatson
196155192Srwatson    getAssembler().setIsThumbFunc(Func);
197155192Srwatson
198155192Srwatson    MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Func);
199155192Srwatson    SD.setFlags(SD.getFlags() | ELF_Other_ThumbFunc);
200155192Srwatson  }
201155192Srwatson
202155192Srwatson  // Helper functions for ARM exception handling directives
203155192Srwatson  void Reset();
204155192Srwatson
205155192Srwatson  void EmitPersonalityFixup(StringRef Name);
206155192Srwatson  void CollectUnwindOpcodes();
207155192Srwatson
208155192Srwatson  void SwitchToEHSection(const char *Prefix, unsigned Type, unsigned Flags,
209155192Srwatson                         SectionKind Kind, const MCSymbol &Fn);
210155192Srwatson  void SwitchToExTabSection(const MCSymbol &FnStart);
211155192Srwatson  void SwitchToExIdxSection(const MCSymbol &FnStart);
212155192Srwatson
213156889Srwatson  bool IsThumb;
214156889Srwatson  int64_t MappingSymbolCounter;
215155192Srwatson
216155192Srwatson  DenseMap<const MCSection *, ElfMappingSymbol> LastMappingSymbols;
217155192Srwatson  ElfMappingSymbol LastEMS;
218155192Srwatson
219155192Srwatson  // ARM Exception Handling Frame Information
220155192Srwatson  MCSymbol *ExTab;
221159277Srwatson  MCSymbol *FnStart;
222159277Srwatson  const MCSymbol *Personality;
223172915Scsjp  uint32_t VFPRegSave; // Register mask for {d31-d0}
224159277Srwatson  uint32_t RegSave; // Register mask for {r15-r0}
225159277Srwatson  int64_t SPOffset;
226159277Srwatson  uint16_t FPReg;
227172915Scsjp  int64_t FPOffset;
228159277Srwatson  bool UsedFP;
229159277Srwatson  bool CantUnwind;
230159277Srwatson  UnwindOpcodeAssembler UnwindOpAsm;
231159277Srwatson};
232155192Srwatson} // end anonymous namespace
233155192Srwatson
234155192Srwatsoninline void ARMELFStreamer::SwitchToEHSection(const char *Prefix,
235160136Swsalamon                                              unsigned Type,
236160136Swsalamon                                              unsigned Flags,
237160136Swsalamon                                              SectionKind Kind,
238160136Swsalamon                                              const MCSymbol &Fn) {
239160136Swsalamon  const MCSectionELF &FnSection =
240160136Swsalamon    static_cast<const MCSectionELF &>(Fn.getSection());
241160136Swsalamon
242160136Swsalamon  // Create the name for new section
243160136Swsalamon  StringRef FnSecName(FnSection.getSectionName());
244160136Swsalamon  SmallString<128> EHSecName(Prefix);
245160136Swsalamon  if (FnSecName != ".text") {
246160136Swsalamon    EHSecName += FnSecName;
247160136Swsalamon  }
248160136Swsalamon
249160136Swsalamon  // Get .ARM.extab or .ARM.exidx section
250160136Swsalamon  const MCSectionELF *EHSection = NULL;
251160136Swsalamon  if (const MCSymbol *Group = FnSection.getGroup()) {
252160136Swsalamon    EHSection = getContext().getELFSection(
253160136Swsalamon      EHSecName, Type, Flags | ELF::SHF_GROUP, Kind,
254160136Swsalamon      FnSection.getEntrySize(), Group->getName());
255160136Swsalamon  } else {
256160136Swsalamon    EHSection = getContext().getELFSection(EHSecName, Type, Flags, Kind);
257160136Swsalamon  }
258155192Srwatson  assert(EHSection && "Failed to get the required EH section");
259155192Srwatson
260155192Srwatson  // Switch to .ARM.extab or .ARM.exidx section
261155192Srwatson  SwitchSection(EHSection);
262155192Srwatson  EmitCodeAlignment(4, 0);
263155192Srwatson}
264155192Srwatson
265155192Srwatsoninline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
266155192Srwatson  SwitchToEHSection(".ARM.extab",
267155192Srwatson                    ELF::SHT_PROGBITS,
268155192Srwatson                    ELF::SHF_ALLOC,
269156889Srwatson                    SectionKind::getDataRel(),
270155192Srwatson                    FnStart);
271156889Srwatson}
272156889Srwatson
273155192Srwatsoninline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
274156889Srwatson  SwitchToEHSection(".ARM.exidx",
275156889Srwatson                    ELF::SHT_ARM_EXIDX,
276155192Srwatson                    ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER,
277155192Srwatson                    SectionKind::getDataRel(),
278155192Srwatson                    FnStart);
279156889Srwatson}
280156889Srwatson
281156889Srwatsonvoid ARMELFStreamer::Reset() {
282155192Srwatson  const MCRegisterInfo &MRI = getContext().getRegisterInfo();
283156889Srwatson
284156889Srwatson  ExTab = NULL;
285155192Srwatson  FnStart = NULL;
286155192Srwatson  Personality = NULL;
287155192Srwatson  VFPRegSave = 0;
288156889Srwatson  RegSave = 0;
289156889Srwatson  FPReg = MRI.getEncodingValue(ARM::SP);
290156889Srwatson  FPOffset = 0;
291155192Srwatson  SPOffset = 0;
292156889Srwatson  UsedFP = false;
293156889Srwatson  CantUnwind = false;
294155192Srwatson
295156889Srwatson  UnwindOpAsm.Reset();
296156889Srwatson}
297155192Srwatson
298156889Srwatson// Add the R_ARM_NONE fixup at the same position
299156889Srwatsonvoid ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
300155192Srwatson  const MCSymbol *PersonalitySym = getContext().GetOrCreateSymbol(Name);
301156889Srwatson
302156889Srwatson  const MCSymbolRefExpr *PersonalityRef =
303155192Srwatson    MCSymbolRefExpr::Create(PersonalitySym,
304155192Srwatson                            MCSymbolRefExpr::VK_ARM_NONE,
305155192Srwatson                            getContext());
306156889Srwatson
307156889Srwatson  AddValueSymbols(PersonalityRef);
308156889Srwatson  MCDataFragment *DF = getOrCreateDataFragment();
309155192Srwatson  DF->getFixups().push_back(
310156889Srwatson    MCFixup::Create(DF->getContents().size(), PersonalityRef,
311156889Srwatson                    MCFixup::getKindForSize(4, false)));
312155192Srwatson}
313155192Srwatson
314155192Srwatsonvoid ARMELFStreamer::CollectUnwindOpcodes() {
315156889Srwatson  if (UsedFP) {
316156889Srwatson    UnwindOpAsm.EmitSetFP(FPReg);
317156889Srwatson    UnwindOpAsm.EmitSPOffset(-FPOffset);
318155192Srwatson  } else {
319156889Srwatson    UnwindOpAsm.EmitSPOffset(SPOffset);
320156889Srwatson  }
321155192Srwatson  UnwindOpAsm.EmitVFPRegSave(VFPRegSave);
322155192Srwatson  UnwindOpAsm.EmitRegSave(RegSave);
323155192Srwatson  UnwindOpAsm.Finalize();
324156889Srwatson}
325155192Srwatson
326156889Srwatsonvoid ARMELFStreamer::EmitFnStart() {
327156889Srwatson  assert(FnStart == 0);
328155192Srwatson  FnStart = getContext().CreateTempSymbol();
329156889Srwatson  EmitLabel(FnStart);
330156889Srwatson}
331155192Srwatson
332155192Srwatsonvoid ARMELFStreamer::EmitFnEnd() {
333155192Srwatson  assert(FnStart && ".fnstart must preceeds .fnend");
334156889Srwatson
335155192Srwatson  // Emit unwind opcodes if there is no .handlerdata directive
336156889Srwatson  if (!ExTab && !CantUnwind) {
337155192Srwatson    CollectUnwindOpcodes();
338155192Srwatson
339156889Srwatson    unsigned PersonalityIndex = UnwindOpAsm.getPersonalityIndex();
340155192Srwatson    if (PersonalityIndex == AEABI_UNWIND_CPP_PR1 ||
341155192Srwatson        PersonalityIndex == AEABI_UNWIND_CPP_PR2) {
342155192Srwatson      // For the __aeabi_unwind_cpp_pr1 and __aeabi_unwind_cpp_pr2, we have to
343156889Srwatson      // emit the unwind opcodes in the corresponding ".ARM.extab" section, and
344156889Srwatson      // then emit a reference to these unwind opcodes in the second word of
345156889Srwatson      // the exception index table entry.
346155192Srwatson      SwitchToExTabSection(*FnStart);
347156889Srwatson      ExTab = getContext().CreateTempSymbol();
348156889Srwatson      EmitLabel(ExTab);
349155192Srwatson      EmitBytes(UnwindOpAsm.data(), 0);
350155192Srwatson    }
351155192Srwatson  }
352156889Srwatson
353156889Srwatson  // Emit the exception index table entry
354156889Srwatson  SwitchToExIdxSection(*FnStart);
355155192Srwatson
356155192Srwatson  unsigned PersonalityIndex = UnwindOpAsm.getPersonalityIndex();
357155192Srwatson  if (PersonalityIndex < NUM_PERSONALITY_INDEX)
358155192Srwatson    EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
359155192Srwatson
360155192Srwatson  const MCSymbolRefExpr *FnStartRef =
361155192Srwatson    MCSymbolRefExpr::Create(FnStart,
362155192Srwatson                            MCSymbolRefExpr::VK_ARM_PREL31,
363155192Srwatson                            getContext());
364156889Srwatson
365156889Srwatson  EmitValue(FnStartRef, 4, 0);
366156889Srwatson
367156889Srwatson  if (CantUnwind) {
368155192Srwatson    EmitIntValue(EXIDX_CANTUNWIND, 4, 0);
369155192Srwatson  } else if (ExTab) {
370155192Srwatson    // Emit a reference to the unwind opcodes in the ".ARM.extab" section.
371156889Srwatson    const MCSymbolRefExpr *ExTabEntryRef =
372155192Srwatson      MCSymbolRefExpr::Create(ExTab,
373155192Srwatson                              MCSymbolRefExpr::VK_ARM_PREL31,
374155192Srwatson                              getContext());
375155192Srwatson    EmitValue(ExTabEntryRef, 4, 0);
376155192Srwatson  } else {
377155192Srwatson    // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
378155192Srwatson    // the second word of exception index table entry.  The size of the unwind
379155192Srwatson    // opcodes should always be 4 bytes.
380155192Srwatson    assert(PersonalityIndex == AEABI_UNWIND_CPP_PR0 &&
381155192Srwatson           "Compact model must use __aeabi_cpp_unwind_pr0 as personality");
382155192Srwatson    assert(UnwindOpAsm.size() == 4u &&
383155192Srwatson           "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be equal to 4");
384155192Srwatson    EmitBytes(UnwindOpAsm.data(), 0);
385155192Srwatson  }
386155192Srwatson
387155192Srwatson  // Clean exception handling frame information
388155192Srwatson  Reset();
389168688Scsjp}
390168688Scsjp
391168688Scsjpvoid ARMELFStreamer::EmitCantUnwind() {
392168688Scsjp  CantUnwind = true;
393168688Scsjp}
394168688Scsjp
395168688Scsjpvoid ARMELFStreamer::EmitHandlerData() {
396168688Scsjp  SwitchToExTabSection(*FnStart);
397168688Scsjp
398168688Scsjp  // Create .ARM.extab label for offset in .ARM.exidx
399168688Scsjp  assert(!ExTab);
400168688Scsjp  ExTab = getContext().CreateTempSymbol();
401168688Scsjp  EmitLabel(ExTab);
402168688Scsjp
403168688Scsjp  // Emit Personality
404168688Scsjp  assert(Personality && ".personality directive must preceed .handlerdata");
405168688Scsjp
406168688Scsjp  const MCSymbolRefExpr *PersonalityRef =
407168688Scsjp    MCSymbolRefExpr::Create(Personality,
408168688Scsjp                            MCSymbolRefExpr::VK_ARM_PREL31,
409168688Scsjp                            getContext());
410168688Scsjp
411168688Scsjp  EmitValue(PersonalityRef, 4, 0);
412168688Scsjp
413168688Scsjp  // Emit unwind opcodes
414168688Scsjp  CollectUnwindOpcodes();
415168688Scsjp  EmitBytes(UnwindOpAsm.data(), 0);
416168688Scsjp}
417168688Scsjp
418168688Scsjpvoid ARMELFStreamer::EmitPersonality(const MCSymbol *Per) {
419168688Scsjp  Personality = Per;
420168688Scsjp  UnwindOpAsm.setPersonality(Per);
421168688Scsjp}
422168688Scsjp
423155192Srwatsonvoid ARMELFStreamer::EmitSetFP(unsigned NewFPReg,
424156889Srwatson                               unsigned NewSPReg,
425156889Srwatson                               int64_t Offset) {
426156889Srwatson  assert(SPOffset == 0 &&
427155192Srwatson         "Current implementation assumes .setfp precedes .pad");
428155192Srwatson
429156889Srwatson  const MCRegisterInfo &MRI = getContext().getRegisterInfo();
430155192Srwatson
431155192Srwatson  uint16_t NewFPRegEncVal = MRI.getEncodingValue(NewFPReg);
432155192Srwatson#ifndef NDEBUG
433175455Scsjp  uint16_t NewSPRegEncVal = MRI.getEncodingValue(NewSPReg);
434155192Srwatson#endif
435162990Srwatson
436155192Srwatson  assert((NewSPReg == ARM::SP || NewSPRegEncVal == FPReg) &&
437156889Srwatson         "the operand of .setfp directive should be either $sp or $fp");
438162990Srwatson
439162990Srwatson  UsedFP = true;
440155192Srwatson  FPReg = NewFPRegEncVal;
441155192Srwatson  FPOffset = Offset;
442156889Srwatson}
443156889Srwatson
444156889Srwatsonvoid ARMELFStreamer::EmitPad(int64_t Offset) {
445155192Srwatson  SPOffset += Offset;
446155192Srwatson}
447155192Srwatson
448155192Srwatsonvoid ARMELFStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
449155192Srwatson                                 bool IsVector) {
450156889Srwatson  const MCRegisterInfo &MRI = getContext().getRegisterInfo();
451156889Srwatson
452155192Srwatson#ifndef NDEBUG
453155192Srwatson  unsigned Max = IsVector ? 32 : 16;
454155192Srwatson#endif
455156889Srwatson  uint32_t &RegMask = IsVector ? VFPRegSave : RegSave;
456156889Srwatson
457155192Srwatson  for (size_t i = 0; i < RegList.size(); ++i) {
458155192Srwatson    unsigned Reg = MRI.getEncodingValue(RegList[i]);
459155192Srwatson    assert(Reg < Max && "Register encoded value out of range");
460155192Srwatson    RegMask |= 1u << Reg;
461155192Srwatson  }
462155192Srwatson}
463155192Srwatson
464155192Srwatsonnamespace llvm {
465155192Srwatson  MCELFStreamer* createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
466155192Srwatson                                      raw_ostream &OS, MCCodeEmitter *Emitter,
467155192Srwatson                                      bool RelaxAll, bool NoExecStack,
468155192Srwatson                                      bool IsThumb) {
469155192Srwatson    ARMELFStreamer *S = new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb);
470155192Srwatson    if (RelaxAll)
471155192Srwatson      S->getAssembler().setRelaxAll(true);
472155192Srwatson    if (NoExecStack)
473155192Srwatson      S->getAssembler().setNoExecStack(true);
474155192Srwatson    return S;
475155192Srwatson  }
476155192Srwatson
477155192Srwatson}
478155192Srwatson
479155192Srwatson
480155192Srwatson