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