16eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover//===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===//
26eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover//
36eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover//                     The LLVM Compiler Infrastructure
46eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover//
56eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover// This file is distributed under the University of Illinois Open Source
66eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover// License. See LICENSE.TXT for details.
76eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover//
86eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover//===----------------------------------------------------------------------===//
96eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover//
106eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover// This file assembles .s files and emits ARM ELF .o object files. Different
116eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover// from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to
126eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover// delimit regions of data and code.
136eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover//
146eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover//===----------------------------------------------------------------------===//
156eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
16532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien#include "ARMRegisterInfo.h"
17532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien#include "ARMUnwindOpAsm.h"
1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/StringExtras.h"
190c66e07863f2bcb054ffc4d58ae30a048b7406c7Benjamin Kramer#include "llvm/ADT/Twine.h"
200c66e07863f2bcb054ffc4d58ae30a048b7406c7Benjamin Kramer#include "llvm/MC/MCAsmBackend.h"
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCAsmInfo.h"
226eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCAssembler.h"
236eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCCodeEmitter.h"
246eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCContext.h"
256eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCELFStreamer.h"
266eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCExpr.h"
276eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCInst.h"
28320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola#include "llvm/MC/MCInstPrinter.h"
29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCObjectFileInfo.h"
306eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCObjectStreamer.h"
31532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien#include "llvm/MC/MCRegisterInfo.h"
326eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCSection.h"
330c66e07863f2bcb054ffc4d58ae30a048b7406c7Benjamin Kramer#include "llvm/MC/MCSectionELF.h"
340c66e07863f2bcb054ffc4d58ae30a048b7406c7Benjamin Kramer#include "llvm/MC/MCStreamer.h"
356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/MC/MCSymbolELF.h"
366eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCValue.h"
3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/ARMBuildAttributes.h"
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/ARMEHABI.h"
396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/Support/TargetParser.h"
406eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/Support/Debug.h"
416eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/Support/ELF.h"
42320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola#include "llvm/Support/FormattedStream.h"
4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/LEB128.h"
446eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/Support/raw_ostream.h"
4523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien#include <algorithm>
466eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
476eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northoverusing namespace llvm;
486eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
49532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chienstatic std::string GetAEABIUnwindPersonalityName(unsigned Index) {
5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX &&
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         "Invalid personality index");
52532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien  return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
53532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien}
54532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien
556eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northovernamespace {
566eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
57320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolaclass ARMELFStreamer;
58320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
59320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolaclass ARMTargetAsmStreamer : public ARMTargetStreamer {
60320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  formatted_raw_ostream &OS;
61320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  MCInstPrinter &InstPrinter;
6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool IsVerboseAsm;
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitFnStart() override;
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitFnEnd() override;
6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitCantUnwind() override;
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitPersonality(const MCSymbol *Personality) override;
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitPersonalityIndex(unsigned Index) override;
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitHandlerData() override;
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitPad(int64_t Offset) override;
7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   bool isVector) override;
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitUnwindRaw(int64_t Offset,
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     const SmallVectorImpl<uint8_t> &Opcodes) override;
7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void switchVendor(StringRef Vendor) override;
7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitAttribute(unsigned Attribute, unsigned Value) override;
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitTextAttribute(unsigned Attribute, StringRef String) override;
8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
82f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                            StringRef StringValue) override;
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitArch(unsigned Arch) override;
84ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void emitArchExtension(unsigned ArchExt) override;
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitObjectArch(unsigned Arch) override;
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitFPU(unsigned FPU) override;
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitInst(uint32_t Inst, char Suffix = '\0') override;
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void finishAttributeSection() override;
8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
9223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
93320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolapublic:
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS,
9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       MCInstPrinter &InstPrinter, bool VerboseAsm);
96320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola};
97320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer &S,
9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                           formatted_raw_ostream &OS,
10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                           MCInstPrinter &InstPrinter,
10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                           bool VerboseAsm)
10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    : ARMTargetStreamer(S), OS(OS), InstPrinter(InstPrinter),
10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      IsVerboseAsm(VerboseAsm) {}
104320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; }
105320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; }
106320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; }
107320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) {
108320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  OS << "\t.personality " << Personality->getName() << '\n';
109320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola}
11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) {
11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.personalityindex " << Index << '\n';
11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
113320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }
114320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
115320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola                                     int64_t Offset) {
116320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  OS << "\t.setfp\t";
117320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  InstPrinter.printRegName(OS, FpReg);
118320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  OS << ", ";
119320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  InstPrinter.printRegName(OS, SpReg);
120320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  if (Offset)
121320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola    OS << ", #" << Offset;
122320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  OS << '\n';
123320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola}
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetAsmStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert((Reg != ARM::SP && Reg != ARM::PC) &&
12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         "the operand of .movsp cannot be either sp or pc");
12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.movsp\t";
12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  InstPrinter.printRegName(OS, Reg);
13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Offset)
13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << ", #" << Offset;
13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << '\n';
13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
134320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetAsmStreamer::emitPad(int64_t Offset) {
135320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  OS << "\t.pad\t#" << Offset << '\n';
136320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola}
137320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
138320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola                                       bool isVector) {
139320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  assert(RegList.size() && "RegList should not be empty");
140320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  if (isVector)
141320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola    OS << "\t.vsave\t{";
142320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  else
143320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola    OS << "\t.save\t{";
144320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
145320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  InstPrinter.printRegName(OS, RegList[0]);
146320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
147320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
148320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola    OS << ", ";
149320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola    InstPrinter.printRegName(OS, RegList[i]);
150320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  }
151320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
152320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  OS << "}\n";
153320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola}
15423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {
15523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien}
15623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value);
15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (IsVerboseAsm) {
15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StringRef Name = ARMBuildAttrs::AttrTypeAsString(Attribute);
16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!Name.empty())
16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "\t@ " << Name;
16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\n";
16423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien}
16523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
16623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                                             StringRef String) {
16723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  switch (Attribute) {
16823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  case ARMBuildAttrs::CPU_name:
16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "\t.cpu\t" << String.lower();
17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\"";
17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (IsVerboseAsm) {
17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      StringRef Name = ARMBuildAttrs::AttrTypeAsString(Attribute);
17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (!Name.empty())
17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        OS << "\t@ " << Name;
17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
17823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    break;
17923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  }
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\n";
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute,
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                unsigned IntValue,
18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                StringRef StringValue) {
18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (Attribute) {
18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default: llvm_unreachable("unsupported multi-value attribute in asm mode");
18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case ARMBuildAttrs::compatibility:
18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "\t.eabi_attribute\t" << Attribute << ", " << IntValue;
18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!StringValue.empty())
19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << ", \"" << StringValue << "\"";
19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (IsVerboseAsm)
19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "\t@ " << ARMBuildAttrs::AttrTypeAsString(Attribute);
19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\n";
19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetAsmStreamer::emitArch(unsigned Arch) {
198f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  OS << "\t.arch\t" << ARM::getArchName(Arch) << "\n";
19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
200ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid ARMTargetAsmStreamer::emitArchExtension(unsigned ArchExt) {
201f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  OS << "\t.arch_extension\t" << ARM::getArchExtName(ArchExt) << "\n";
202ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetAsmStreamer::emitObjectArch(unsigned Arch) {
204f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  OS << "\t.object_arch\t" << ARM::getArchName(Arch) << '\n';
20523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien}
20623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
207f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  OS << "\t.fpu\t" << ARM::getFPUName(FPU) << "\n";
20823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien}
20923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetAsmStreamer::finishAttributeSection() {
21023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien}
21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid
21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesARMTargetAsmStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.tlsdescseq\t" << S->getSymbol().getName();
21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
2176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
2186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  OS << "\t.thumb_set\t";
2206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  Symbol->print(OS, MAI);
2216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  OS << ", ";
2226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  Value->print(OS, MAI);
2236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  OS << '\n';
224dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
225dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) {
22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.inst";
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Suffix)
22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "." << Suffix;
2306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  OS << "\t0x" << Twine::utohexstr(Inst) << "\n";
23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset,
23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      const SmallVectorImpl<uint8_t> &Opcodes) {
23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << "\t.unwind_raw " << Offset;
23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (SmallVectorImpl<uint8_t>::const_iterator OCI = Opcodes.begin(),
23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                OCE = Opcodes.end();
23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       OCI != OCE; ++OCI)
2396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    OS << ", 0x" << Twine::utohexstr(*OCI);
24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OS << '\n';
24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
242320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
243320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolaclass ARMTargetELFStreamer : public ARMTargetStreamer {
24423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienprivate:
24523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  // This structure holds all attributes, accounting for
246f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // their string/numeric value, so we can later emit them
24723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  // in declaration order, keeping all in the same vector
24823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  struct AttributeItem {
24923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    enum {
25023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      HiddenAttribute = 0,
25123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      NumericAttribute,
25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      TextAttribute,
25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      NumericAndTextAttributes
25423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    } Type;
25523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    unsigned Tag;
25623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    unsigned IntValue;
257f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    std::string StringValue;
25823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
25923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    static bool LessTag(const AttributeItem &LHS, const AttributeItem &RHS) {
260ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // The conformance tag must be emitted first when serialised
261ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // into an object file. Specifically, the addenda to the ARM ABI
262ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // states that (2.3.7.4):
263ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      //
264ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // "To simplify recognition by consumers in the common case of
265ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // claiming conformity for the whole file, this tag should be
266ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // emitted first in a file-scope sub-subsection of the first
267ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // public subsection of the attributes section."
268ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      //
269ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // So it is special-cased in this comparison predicate when the
270ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // attributes are sorted in finishAttributeSection().
271ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return (RHS.Tag != ARMBuildAttrs::conformance) &&
272ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines             ((LHS.Tag == ARMBuildAttrs::conformance) || (LHS.Tag < RHS.Tag));
27323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    }
27423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  };
27523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
27623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  StringRef CurrentVendor;
27723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  unsigned FPU;
27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Arch;
27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned EmittedArch;
28023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  SmallVector<AttributeItem, 64> Contents;
28123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
2826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCSection *AttributeSection;
28323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
28423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  AttributeItem *getAttributeItem(unsigned Attribute) {
28523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    for (size_t i = 0; i < Contents.size(); ++i)
28623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      if (Contents[i].Tag == Attribute)
28723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien        return &Contents[i];
288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return nullptr;
28923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  }
29023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
29123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  void setAttributeItem(unsigned Attribute, unsigned Value,
29223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                        bool OverwriteExisting) {
29323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    // Look for existing attribute item
29423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    if (AttributeItem *Item = getAttributeItem(Attribute)) {
29523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      if (!OverwriteExisting)
29623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien        return;
29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Item->Type = AttributeItem::NumericAttribute;
29823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      Item->IntValue = Value;
29923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      return;
30023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    }
30123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
30223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    // Create new attribute item
30323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    AttributeItem Item = {
30423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      AttributeItem::NumericAttribute,
30523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      Attribute,
30623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      Value,
30723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      StringRef("")
30823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    };
30923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    Contents.push_back(Item);
31023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  }
31123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
31223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  void setAttributeItem(unsigned Attribute, StringRef Value,
31323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                        bool OverwriteExisting) {
31423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    // Look for existing attribute item
31523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    if (AttributeItem *Item = getAttributeItem(Attribute)) {
31623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      if (!OverwriteExisting)
31723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien        return;
31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Item->Type = AttributeItem::TextAttribute;
31923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      Item->StringValue = Value;
32023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      return;
32123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    }
32223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
32323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    // Create new attribute item
32423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    AttributeItem Item = {
32523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      AttributeItem::TextAttribute,
32623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      Attribute,
32723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      0,
32823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      Value
32923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    };
33023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    Contents.push_back(Item);
33123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  }
33223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void setAttributeItems(unsigned Attribute, unsigned IntValue,
33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         StringRef StringValue, bool OverwriteExisting) {
33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Look for existing attribute item
33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (AttributeItem *Item = getAttributeItem(Attribute)) {
33736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (!OverwriteExisting)
33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return;
33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Item->Type = AttributeItem::NumericAndTextAttributes;
34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Item->IntValue = IntValue;
34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Item->StringValue = StringValue;
34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return;
34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Create new attribute item
34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    AttributeItem Item = {
34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      AttributeItem::NumericAndTextAttributes,
34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Attribute,
34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      IntValue,
35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      StringValue
35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    };
35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Contents.push_back(Item);
35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitArchDefaultAttributes();
35623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  void emitFPUDefaultAttributes();
35723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
358320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  ARMELFStreamer &getStreamer();
35923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
36036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitFnStart() override;
36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitFnEnd() override;
36236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitCantUnwind() override;
36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitPersonality(const MCSymbol *Personality) override;
36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitPersonalityIndex(unsigned Index) override;
36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitHandlerData() override;
36636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitPad(int64_t Offset) override;
36936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   bool isVector) override;
37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitUnwindRaw(int64_t Offset,
37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                     const SmallVectorImpl<uint8_t> &Opcodes) override;
37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void switchVendor(StringRef Vendor) override;
37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitAttribute(unsigned Attribute, unsigned Value) override;
37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitTextAttribute(unsigned Attribute, StringRef String) override;
37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                            StringRef StringValue) override;
37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitArch(unsigned Arch) override;
38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitObjectArch(unsigned Arch) override;
38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitFPU(unsigned FPU) override;
38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitInst(uint32_t Inst, char Suffix = '\0') override;
38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void finishAttributeSection() override;
384dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void emitLabel(MCSymbol *Symbol) override;
38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
387dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
38823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
38923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  size_t calculateContentSize() const;
39023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
391de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Reset state between object emissions
392de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void reset() override;
393de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
39423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienpublic:
39536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ARMTargetELFStreamer(MCStreamer &S)
3966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    : ARMTargetStreamer(S), CurrentVendor("aeabi"), FPU(ARM::FK_INVALID),
3976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Arch(ARM::AK_INVALID), EmittedArch(ARM::AK_INVALID),
398dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AttributeSection(nullptr) {}
399320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola};
400320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
4016eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// Extend the generic ELFStreamer class so that it can emit mapping symbols at
4026eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// the appropriate points in the object files. These symbols are defined in the
4036eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.
4046eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover///
4056eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// In brief: $a, $t or $d should be emitted at the start of each contiguous
4066eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// region of ARM code, Thumb code or data in a section. In practice, this
4076eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// emission does not rely on explicit assembler directives but on inherent
4086eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// properties of the directives doing the emission (e.g. ".byte" is data, "add
4096eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// r0, r0, r0" an instruction).
4106eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover///
4116eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// As a result this system is orthogonal to the DataRegion infrastructure used
4126eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover/// by MachO. Beware!
4136eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northoverclass ARMELFStreamer : public MCELFStreamer {
4146eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northoverpublic:
415320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  friend class ARMTargetELFStreamer;
416320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
4170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  ARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS,
41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                 MCCodeEmitter *Emitter, bool IsThumb)
41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      : MCELFStreamer(Context, TAB, OS, Emitter), IsThumb(IsThumb),
42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        MappingSymbolCounter(0), LastEMS(EMS_None) {
421de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    EHReset();
422532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien  }
4236eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
4246eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  ~ARMELFStreamer() {}
4256eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
42636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void FinishImpl() override;
42723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
42852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  // ARM exception handling directives
429320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  void emitFnStart();
430320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  void emitFnEnd();
431320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  void emitCantUnwind();
432320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  void emitPersonality(const MCSymbol *Per);
43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitPersonalityIndex(unsigned index);
434320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  void emitHandlerData();
435320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0);
43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitMovSP(unsigned Reg, int64_t Offset = 0);
437320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  void emitPad(int64_t Offset);
438320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector);
43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes);
44052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
4416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  void ChangeSection(MCSection *Section, const MCExpr *Subsection) override {
4426eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    // We have to keep track of the mapping symbol state of any sections we
4436eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    // use. Each one should start off as EMS_None, which is provided as the
4446eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    // default constructor by DenseMap::lookup.
445df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne    LastMappingSymbols[getPreviousSection().first] = LastEMS;
4466eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    LastEMS = LastMappingSymbols.lookup(Section);
4476eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
448df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne    MCELFStreamer::ChangeSection(Section, Subsection);
4496eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  }
4506eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
4516eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  /// This function is the one used to emit instruction data into the ELF
4526eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  /// streamer. We override it to add the appropriate mapping symbol if
4536eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  /// necessary.
45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitInstruction(const MCInst& Inst,
45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       const MCSubtargetInfo &STI) override {
4566eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    if (IsThumb)
4576eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover      EmitThumbMappingSymbol();
4586eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    else
4596eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover      EmitARMMappingSymbol();
4606eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
46136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MCELFStreamer::EmitInstruction(Inst, STI);
46236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void emitInst(uint32_t Inst, char Suffix) {
46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Size;
46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    char Buffer[4];
46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian();
46836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
46936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    switch (Suffix) {
47036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case '\0':
47136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Size = 4;
47236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
47336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      assert(!IsThumb);
47436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      EmitARMMappingSymbol();
47536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      for (unsigned II = 0, IE = Size; II != IE; II++) {
47636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        const unsigned I = LittleEndian ? (Size - II - 1) : II;
47736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);
47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case 'n':
48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case 'w':
48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Size = (Suffix == 'n' ? 2 : 4);
48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      assert(IsThumb);
48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      EmitThumbMappingSymbol();
48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {
48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        const unsigned I0 = LittleEndian ? II + 0 : (Size - II - 1);
48936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        const unsigned I1 = LittleEndian ? II + 1 : (Size - II - 2);
49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);
49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);
49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    default:
49636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      llvm_unreachable("Invalid Suffix");
49736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
49936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MCELFStreamer::EmitBytes(StringRef(Buffer, Size));
5006eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  }
5016eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
5026eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  /// This is one of the functions used to emit data into an ELF section, so the
5036eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
5046eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  /// necessary.
50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitBytes(StringRef Data) override {
5066eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    EmitDataMappingSymbol();
507a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindola    MCELFStreamer::EmitBytes(Data);
5086eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  }
5096eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
5106eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  /// This is one of the functions used to emit data into an ELF section, so the
5116eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
5126eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  /// necessary.
513f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override {
514ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (const MCSymbolRefExpr *SRE = dyn_cast_or_null<MCSymbolRefExpr>(Value))
515f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_SBREL && !(Size == 4)) {
516f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        getContext().reportError(Loc, "relocated expression must be 32-bit");
517f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return;
518f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
519ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
5206eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    EmitDataMappingSymbol();
521f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MCELFStreamer::EmitValueImpl(Value, Size, Loc);
5226eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  }
5236eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
52436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitAssemblerFlag(MCAssemblerFlag Flag) override {
5256eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    MCELFStreamer::EmitAssemblerFlag(Flag);
5266eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
5276eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    switch (Flag) {
5286eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    case MCAF_SyntaxUnified:
5296eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover      return; // no-op here.
5306eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    case MCAF_Code16:
5316eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover      IsThumb = true;
5326eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover      return; // Change to Thumb mode
5336eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    case MCAF_Code32:
5346eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover      IsThumb = false;
5356eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover      return; // Change to ARM mode
5366eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    case MCAF_Code64:
5376eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover      return;
5386eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    case MCAF_SubsectionsViaSymbols:
5396eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover      return;
5406eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    }
5416eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  }
5426eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
5436eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northoverprivate:
5446eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  enum ElfMappingSymbol {
5456eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    EMS_None,
5466eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    EMS_ARM,
5476eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    EMS_Thumb,
5486eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    EMS_Data
5496eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  };
5506eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
5516eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  void EmitDataMappingSymbol() {
5526eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    if (LastEMS == EMS_Data) return;
5536eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    EmitMappingSymbol("$d");
5546eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    LastEMS = EMS_Data;
5556eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  }
5566eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
5576eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  void EmitThumbMappingSymbol() {
5586eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    if (LastEMS == EMS_Thumb) return;
5596eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    EmitMappingSymbol("$t");
5606eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    LastEMS = EMS_Thumb;
5616eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  }
5626eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
5636eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  void EmitARMMappingSymbol() {
5646eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    if (LastEMS == EMS_ARM) return;
5656eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    EmitMappingSymbol("$a");
5666eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    LastEMS = EMS_ARM;
5676eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  }
5686eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
5696eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  void EmitMappingSymbol(StringRef Name) {
5706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
5716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        Name + "." + Twine(MappingSymbolCounter++)));
572f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    EmitLabel(Symbol);
5736eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
5746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Symbol->setType(ELF::STT_NOTYPE);
5756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Symbol->setBinding(ELF::STB_LOCAL);
5766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Symbol->setExternal(false);
5776eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  }
5786eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
57936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitThumbFunc(MCSymbol *Func) override {
5806eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    getAssembler().setIsThumbFunc(Func);
581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    EmitSymbolAttribute(Func, MCSA_ELF_TypeFunction);
5826eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  }
5836eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
58452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  // Helper functions for ARM exception handling directives
585de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void EHReset();
586de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
587de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Reset state between object emissions
588de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void reset() override;
58952b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
59052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  void EmitPersonalityFixup(StringRef Name);
59118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  void FlushPendingOffset();
5920a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien  void FlushUnwindOpcodes(bool NoHandlerData);
59352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
59452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  void SwitchToEHSection(const char *Prefix, unsigned Type, unsigned Flags,
59552b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien                         SectionKind Kind, const MCSymbol &Fn);
59652b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  void SwitchToExTabSection(const MCSymbol &FnStart);
59752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  void SwitchToExIdxSection(const MCSymbol &FnStart);
5986eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
59936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void EmitFixup(const MCExpr *Expr, MCFixupKind Kind);
60036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6016eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  bool IsThumb;
6026eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  int64_t MappingSymbolCounter;
6036eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
6046eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  DenseMap<const MCSection *, ElfMappingSymbol> LastMappingSymbols;
6056eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  ElfMappingSymbol LastEMS;
6066eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
60752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  // ARM Exception Handling Frame Information
60852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  MCSymbol *ExTab;
60952b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  MCSymbol *FnStart;
61052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  const MCSymbol *Personality;
61118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  unsigned PersonalityIndex;
61218cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  unsigned FPReg; // Frame pointer register
61318cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp)
61418cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  int64_t SPOffset; // Offset: (final $sp) - (initial $sp)
61518cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp)
616532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien  bool UsedFP;
61752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  bool CantUnwind;
61818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  SmallVector<uint8_t, 64> Opcodes;
619532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien  UnwindOpcodeAssembler UnwindOpAsm;
6206eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover};
621532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien} // end anonymous namespace
6226eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
623320296a4cfe414ce59f406b8a5ce15272f563103Rafael EspindolaARMELFStreamer &ARMTargetELFStreamer::getStreamer() {
62436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return static_cast<ARMELFStreamer &>(Streamer);
625320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola}
626320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
627320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }
628320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }
629320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }
630320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) {
631320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  getStreamer().emitPersonality(Personality);
632320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola}
63336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index) {
63436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  getStreamer().emitPersonalityIndex(Index);
63536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
636320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetELFStreamer::emitHandlerData() {
637320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  getStreamer().emitHandlerData();
638320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola}
639320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
640320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola                                     int64_t Offset) {
641320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  getStreamer().emitSetFP(FpReg, SpReg, Offset);
642320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola}
64336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
64436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  getStreamer().emitMovSP(Reg, Offset);
64536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
646320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetELFStreamer::emitPad(int64_t Offset) {
647320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  getStreamer().emitPad(Offset);
648320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola}
649320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
650320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola                                       bool isVector) {
651320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  getStreamer().emitRegSave(RegList, isVector);
652320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola}
65336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset,
65436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      const SmallVectorImpl<uint8_t> &Opcodes) {
65536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  getStreamer().emitUnwindRaw(Offset, Opcodes);
65636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
65723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetELFStreamer::switchVendor(StringRef Vendor) {
65823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  assert(!Vendor.empty() && "Vendor cannot be empty.");
65923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
66023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  if (CurrentVendor == Vendor)
66123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    return;
66223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
66323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  if (!CurrentVendor.empty())
66423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    finishAttributeSection();
66523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
66623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  assert(Contents.empty() &&
66723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien         ".ARM.attributes should be flushed before changing vendor");
66823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  CurrentVendor = Vendor;
66923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
67023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien}
67123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
67223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
67323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien}
67423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute,
67523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                                             StringRef Value) {
67623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
67723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien}
67836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
67936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                unsigned IntValue,
68036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                StringRef StringValue) {
68136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  setAttributeItems(Attribute, IntValue, StringValue,
68236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    /* OverwriteExisting= */ true);
68336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
68436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetELFStreamer::emitArch(unsigned Value) {
68536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Arch = Value;
68636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
68736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetELFStreamer::emitObjectArch(unsigned Value) {
68836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EmittedArch = Value;
68936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
69036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetELFStreamer::emitArchDefaultAttributes() {
69136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  using namespace ARMBuildAttrs;
69236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  setAttributeItem(CPU_name,
694f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                   ARM::getCPUAttr(Arch),
6956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                   false);
6966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
6976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (EmittedArch == ARM::AK_INVALID)
6986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    setAttributeItem(CPU_arch,
699f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     ARM::getArchAttr(Arch),
7006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                     false);
70136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  else
7026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    setAttributeItem(CPU_arch,
703f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     ARM::getArchAttr(EmittedArch),
7046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                     false);
70536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
70636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (Arch) {
7076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV2:
7086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV2A:
7096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV3:
7106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV3M:
7116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV4:
71236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARM_ISA_use, Allowed, false);
71336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
71436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV4T:
7166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV5T:
7176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV5TE:
7186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV6:
71936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARM_ISA_use, Allowed, false);
72036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(THUMB_ISA_use, Allowed, false);
72136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
72236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV6T2:
72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARM_ISA_use, Allowed, false);
72536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
72636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
72736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV6K:
729f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ARM::AK_ARMV6KZ:
73036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARM_ISA_use, Allowed, false);
73136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(THUMB_ISA_use, Allowed, false);
73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(Virtualization_use, AllowTZ, false);
73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV6M:
73636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(THUMB_ISA_use, Allowed, false);
73736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
73836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV7A:
74036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
74136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARM_ISA_use, Allowed, false);
74236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
74336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
74436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV7R:
74636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(CPU_arch_profile, RealTimeProfile, false);
74736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARM_ISA_use, Allowed, false);
74836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
74936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
75036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV7M:
75236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
75336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
75436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
75536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV8A:
7576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_ARMV8_1A:
758f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ARM::AK_ARMV8_2A:
75936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
76036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARM_ISA_use, Allowed, false);
76136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
76236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(MPextension_use, Allowed, false);
76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(Virtualization_use, AllowTZVirtualization, false);
76436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
76536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
766de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case ARM::AK_ARMV8MBaseline:
767de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case ARM::AK_ARMV8MMainline:
768de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false);
769de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
770de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    break;
771de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
7726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_IWMMXT:
77336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARM_ISA_use, Allowed, false);
77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(THUMB_ISA_use, Allowed, false);
77536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(WMMX_arch, AllowWMMXv1, false);
77636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
77736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::AK_IWMMXT2:
77936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARM_ISA_use, Allowed, false);
78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(THUMB_ISA_use, Allowed, false);
78136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(WMMX_arch, AllowWMMXv2, false);
78236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
78336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
78436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
78536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    report_fatal_error("Unknown Arch: " + Twine(Arch));
78636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
78736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
78836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
78923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetELFStreamer::emitFPU(unsigned Value) {
79023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  FPU = Value;
79123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien}
79223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetELFStreamer::emitFPUDefaultAttributes() {
79323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  switch (FPU) {
7946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::FK_VFP:
7956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::FK_VFPV2:
79636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARMBuildAttrs::FP_arch,
79723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     ARMBuildAttrs::AllowFPv2,
79823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     /* OverwriteExisting= */ false);
79923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    break;
80023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
8016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::FK_VFPV3:
80236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARMBuildAttrs::FP_arch,
80323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     ARMBuildAttrs::AllowFPv3A,
80423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     /* OverwriteExisting= */ false);
80523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    break;
80623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
807f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ARM::FK_VFPV3_FP16:
808f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    setAttributeItem(ARMBuildAttrs::FP_arch,
809f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     ARMBuildAttrs::AllowFPv3A,
810f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     /* OverwriteExisting= */ false);
811f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    setAttributeItem(ARMBuildAttrs::FP_HP_extension,
812f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     ARMBuildAttrs::AllowHPFP,
813f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     /* OverwriteExisting= */ false);
814f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
815f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
8166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::FK_VFPV3_D16:
81736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARMBuildAttrs::FP_arch,
81823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     ARMBuildAttrs::AllowFPv3B,
81923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     /* OverwriteExisting= */ false);
82023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    break;
82123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
822f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ARM::FK_VFPV3_D16_FP16:
823f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    setAttributeItem(ARMBuildAttrs::FP_arch,
824f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     ARMBuildAttrs::AllowFPv3B,
825f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     /* OverwriteExisting= */ false);
826f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    setAttributeItem(ARMBuildAttrs::FP_HP_extension,
827f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     ARMBuildAttrs::AllowHPFP,
828f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     /* OverwriteExisting= */ false);
829f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
830f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
831f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ARM::FK_VFPV3XD:
832f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    setAttributeItem(ARMBuildAttrs::FP_arch,
833f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     ARMBuildAttrs::AllowFPv3B,
834f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     /* OverwriteExisting= */ false);
835f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
836f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ARM::FK_VFPV3XD_FP16:
837f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    setAttributeItem(ARMBuildAttrs::FP_arch,
838f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     ARMBuildAttrs::AllowFPv3B,
839f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     /* OverwriteExisting= */ false);
840f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    setAttributeItem(ARMBuildAttrs::FP_HP_extension,
841f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     ARMBuildAttrs::AllowHPFP,
842f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     /* OverwriteExisting= */ false);
843f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
844f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
8456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::FK_VFPV4:
84636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARMBuildAttrs::FP_arch,
84723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     ARMBuildAttrs::AllowFPv4A,
84823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     /* OverwriteExisting= */ false);
84923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    break;
85023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
8516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same
8526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // as _D16 here.
8536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::FK_FPV4_SP_D16:
8546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::FK_VFPV4_D16:
85536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARMBuildAttrs::FP_arch,
85623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     ARMBuildAttrs::AllowFPv4B,
85723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     /* OverwriteExisting= */ false);
85823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    break;
85923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
8606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::FK_FP_ARMV8:
86136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARMBuildAttrs::FP_arch,
86223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     ARMBuildAttrs::AllowFPARMv8A,
86323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     /* OverwriteExisting= */ false);
86423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    break;
86523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
86637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so
86737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // uses the FP_ARMV8_D16 build attribute.
8686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::FK_FPV5_SP_D16:
8696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::FK_FPV5_D16:
87037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    setAttributeItem(ARMBuildAttrs::FP_arch,
87137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                     ARMBuildAttrs::AllowFPARMv8B,
87237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                     /* OverwriteExisting= */ false);
87337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    break;
87437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
8756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::FK_NEON:
87636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARMBuildAttrs::FP_arch,
87723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     ARMBuildAttrs::AllowFPv3A,
87823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     /* OverwriteExisting= */ false);
87923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
88023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     ARMBuildAttrs::AllowNeon,
88123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     /* OverwriteExisting= */ false);
88223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    break;
88323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
884f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case ARM::FK_NEON_FP16:
885f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    setAttributeItem(ARMBuildAttrs::FP_arch,
886f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     ARMBuildAttrs::AllowFPv3A,
887f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     /* OverwriteExisting= */ false);
888f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
889f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     ARMBuildAttrs::AllowNeon,
890f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     /* OverwriteExisting= */ false);
891f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    setAttributeItem(ARMBuildAttrs::FP_HP_extension,
892f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     ARMBuildAttrs::AllowHPFP,
893f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     /* OverwriteExisting= */ false);
894f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
895f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
8966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::FK_NEON_VFPV4:
89736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARMBuildAttrs::FP_arch,
89823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     ARMBuildAttrs::AllowFPv4A,
89923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     /* OverwriteExisting= */ false);
90023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
90123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     ARMBuildAttrs::AllowNeon2,
90223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     /* OverwriteExisting= */ false);
90323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    break;
90423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
9056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::FK_NEON_FP_ARMV8:
9066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::FK_CRYPTO_NEON_FP_ARMV8:
90736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setAttributeItem(ARMBuildAttrs::FP_arch,
90823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     ARMBuildAttrs::AllowFPARMv8A,
90923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien                     /* OverwriteExisting= */ false);
9104c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    // 'Advanced_SIMD_arch' must be emitted not here, but within
9114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a()
91223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    break;
91323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
9146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::FK_SOFTVFP:
9156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case ARM::FK_NONE:
91636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
91736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
91823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  default:
91923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    report_fatal_error("Unknown FPU: " + Twine(FPU));
92023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    break;
92123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  }
92223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien}
92323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chiensize_t ARMTargetELFStreamer::calculateContentSize() const {
92423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  size_t Result = 0;
92523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  for (size_t i = 0; i < Contents.size(); ++i) {
92623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    AttributeItem item = Contents[i];
92723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    switch (item.Type) {
92823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    case AttributeItem::HiddenAttribute:
92923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      break;
93023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    case AttributeItem::NumericAttribute:
93136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Result += getULEB128Size(item.Tag);
93236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Result += getULEB128Size(item.IntValue);
93323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      break;
93423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    case AttributeItem::TextAttribute:
93536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Result += getULEB128Size(item.Tag);
93623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      Result += item.StringValue.size() + 1; // string + '\0'
93723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      break;
93836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case AttributeItem::NumericAndTextAttributes:
93936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Result += getULEB128Size(item.Tag);
94036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Result += getULEB128Size(item.IntValue);
94136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Result += item.StringValue.size() + 1; // string + '\0';
94236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
94323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    }
94423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  }
94523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  return Result;
94623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien}
94723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMTargetELFStreamer::finishAttributeSection() {
94823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  // <format-version>
94923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  // [ <section-length> "vendor-name"
95023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  // [ <file-tag> <size> <attribute>*
95123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  //   | <section-tag> <size> <section-number>* 0 <attribute>*
95223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  //   | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
95323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  //   ]+
95423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  // ]*
95523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
9566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (FPU != ARM::FK_INVALID)
95723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    emitFPUDefaultAttributes();
95823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
9596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Arch != ARM::AK_INVALID)
96036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    emitArchDefaultAttributes();
96136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
96223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  if (Contents.empty())
96323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    return;
96423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
96523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  std::sort(Contents.begin(), Contents.end(), AttributeItem::LessTag);
96623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
96723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  ARMELFStreamer &Streamer = getStreamer();
96823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
96923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  // Switch to .ARM.attributes section
97023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  if (AttributeSection) {
97123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    Streamer.SwitchSection(AttributeSection);
97223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  } else {
973ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    AttributeSection = Streamer.getContext().getELFSection(
974ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        ".ARM.attributes", ELF::SHT_ARM_ATTRIBUTES, 0);
97523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    Streamer.SwitchSection(AttributeSection);
97623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
97723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    // Format version
97823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    Streamer.EmitIntValue(0x41, 1);
97923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  }
98023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
98123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  // Vendor size + Vendor name + '\0'
98223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
98323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
98423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  // Tag + Tag Size
98523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  const size_t TagHeaderSize = 1 + 4;
98623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
98723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  const size_t ContentsSize = calculateContentSize();
98823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
98923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
99023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  Streamer.EmitBytes(CurrentVendor);
99123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  Streamer.EmitIntValue(0, 1); // '\0'
99223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
99323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  Streamer.EmitIntValue(ARMBuildAttrs::File, 1);
99423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
99523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
99623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  // Size should have been accounted for already, now
99723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  // emit each field as its type (ULEB or String)
99823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  for (size_t i = 0; i < Contents.size(); ++i) {
99923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    AttributeItem item = Contents[i];
100023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    Streamer.EmitULEB128IntValue(item.Tag);
100123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    switch (item.Type) {
100223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    default: llvm_unreachable("Invalid attribute type");
100323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    case AttributeItem::NumericAttribute:
100423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      Streamer.EmitULEB128IntValue(item.IntValue);
100523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      break;
100623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    case AttributeItem::TextAttribute:
1007ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Streamer.EmitBytes(item.StringValue);
100823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      Streamer.EmitIntValue(0, 1); // '\0'
100923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien      break;
101036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case AttributeItem::NumericAndTextAttributes:
101136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Streamer.EmitULEB128IntValue(item.IntValue);
1012ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Streamer.EmitBytes(item.StringValue);
101336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Streamer.EmitIntValue(0, 1); // '\0'
101436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
101523125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien    }
101623125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  }
101723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
101823125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  Contents.clear();
10196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  FPU = ARM::FK_INVALID;
102023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien}
1021dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1022dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
1023dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ARMELFStreamer &Streamer = getStreamer();
1024dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Streamer.IsThumb)
1025dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return;
1026dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
10276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  Streamer.getAssembler().registerSymbol(*Symbol);
10286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned Type = cast<MCSymbolELF>(Symbol)->getType();
10296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC)
1030dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Streamer.EmitThumbFunc(Symbol);
1031dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1032dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
103336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid
103436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesARMTargetELFStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
103536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  getStreamer().EmitFixup(S, FK_Data_4);
103636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
1037dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1038dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
1039dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) {
1040dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const MCSymbol &Sym = SRE->getSymbol();
1041dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!Sym.isDefined()) {
1042dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      getStreamer().EmitAssignment(Symbol, Value);
1043dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return;
1044dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1045dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1046dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1047dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  getStreamer().EmitThumbFunc(Symbol);
1048dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  getStreamer().EmitAssignment(Symbol, Value);
1049dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
1050dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
105136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {
105236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  getStreamer().emitInst(Inst, Suffix);
105336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
105423125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
1055de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid ARMTargetELFStreamer::reset() { AttributeSection = nullptr; }
1056de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
105723125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chienvoid ARMELFStreamer::FinishImpl() {
105836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCTargetStreamer &TS = *getTargetStreamer();
105923125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
106023125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  ATS.finishAttributeSection();
106123125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien
106223125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien  MCELFStreamer::FinishImpl();
106323125d02d929758e1b0dbb30b13f1deff7a5ea4bLogan Chien}
1064320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
1065de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid ARMELFStreamer::reset() {
1066de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MCTargetStreamer &TS = *getTargetStreamer();
1067de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1068de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  ATS.reset();
1069de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MappingSymbolCounter = 0;
1070de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MCELFStreamer::reset();
1071de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // MCELFStreamer clear's the assembler's e_flags. However, for
1072de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // arm we manually set the ABI version on streamer creation, so
1073de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // do the same here
1074de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
1075de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
1076de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
107752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chieninline void ARMELFStreamer::SwitchToEHSection(const char *Prefix,
107852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien                                              unsigned Type,
107952b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien                                              unsigned Flags,
108052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien                                              SectionKind Kind,
108152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien                                              const MCSymbol &Fn) {
108252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  const MCSectionELF &FnSection =
108352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien    static_cast<const MCSectionELF &>(Fn.getSection());
108452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
108552b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  // Create the name for new section
108652b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  StringRef FnSecName(FnSection.getSectionName());
108752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  SmallString<128> EHSecName(Prefix);
108852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  if (FnSecName != ".text") {
108952b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien    EHSecName += FnSecName;
109052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  }
109152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
109252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  // Get .ARM.extab or .ARM.exidx section
10936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const MCSymbolELF *Group = FnSection.getGroup();
10940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (Group)
10950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    Flags |= ELF::SHF_GROUP;
10966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCSectionELF *EHSection =
10970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      getContext().getELFSection(EHSecName, Type, Flags, 0, Group,
10980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                 FnSection.getUniqueID(), nullptr, &FnSection);
10990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
1100532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien  assert(EHSection && "Failed to get the required EH section");
110152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
110252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  // Switch to .ARM.extab or .ARM.exidx section
110352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  SwitchSection(EHSection);
110436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EmitCodeAlignment(4);
110552b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien}
110652b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
110752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chieninline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
1108f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SwitchToEHSection(".ARM.extab", ELF::SHT_PROGBITS, ELF::SHF_ALLOC,
1109f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                    SectionKind::getData(), FnStart);
111052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien}
111152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
111252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chieninline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
1113f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  SwitchToEHSection(".ARM.exidx", ELF::SHT_ARM_EXIDX,
111452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien                    ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER,
1115f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                    SectionKind::getData(), FnStart);
111652b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien}
111736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMELFStreamer::EmitFixup(const MCExpr *Expr, MCFixupKind Kind) {
111836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCDataFragment *Frag = getOrCreateDataFragment();
11196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  Frag->getFixups().push_back(MCFixup::create(Frag->getContents().size(), Expr,
112036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                              Kind));
112136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
112252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
1123de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid ARMELFStreamer::EHReset() {
1124dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ExTab = nullptr;
1125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  FnStart = nullptr;
1126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Personality = nullptr;
112736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX;
112818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  FPReg = ARM::SP;
1129532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien  FPOffset = 0;
1130532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien  SPOffset = 0;
113118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  PendingOffset = 0;
1132532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien  UsedFP = false;
113352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  CantUnwind = false;
1134532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien
113518cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  Opcodes.clear();
1136532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien  UnwindOpAsm.Reset();
113752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien}
113852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
1139320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::emitFnStart() {
1140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(FnStart == nullptr);
11416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  FnStart = getContext().createTempSymbol();
114252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  EmitLabel(FnStart);
114352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien}
114452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
1145320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::emitFnEnd() {
114636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(FnStart && ".fnstart must precedes .fnend");
114752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
114852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  // Emit unwind opcodes if there is no .handlerdata directive
1149c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien  if (!ExTab && !CantUnwind)
1150c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien    FlushUnwindOpcodes(true);
115152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
115252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  // Emit the exception index table entry
115352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  SwitchToExIdxSection(*FnStart);
115452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
115536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX)
1156532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien    EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
115752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
115852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  const MCSymbolRefExpr *FnStartRef =
11596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    MCSymbolRefExpr::create(FnStart,
116052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien                            MCSymbolRefExpr::VK_ARM_PREL31,
116152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien                            getContext());
116252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
1163a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindola  EmitValue(FnStartRef, 4);
116452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
116552b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  if (CantUnwind) {
116636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EmitIntValue(ARM::EHABI::EXIDX_CANTUNWIND, 4);
1167532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien  } else if (ExTab) {
1168532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien    // Emit a reference to the unwind opcodes in the ".ARM.extab" section.
116952b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien    const MCSymbolRefExpr *ExTabEntryRef =
11706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      MCSymbolRefExpr::create(ExTab,
117152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien                              MCSymbolRefExpr::VK_ARM_PREL31,
117252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien                              getContext());
1173a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindola    EmitValue(ExTabEntryRef, 4);
1174532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien  } else {
1175532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien    // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
1176532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien    // the second word of exception index table entry.  The size of the unwind
1177532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien    // opcodes should always be 4 bytes.
117836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 &&
1179dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           "Compact model must use __aeabi_unwind_cpp_pr0 as personality");
118018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien    assert(Opcodes.size() == 4u &&
1181dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines           "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4");
1182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t Intval = Opcodes[0] |
1183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                      Opcodes[1] << 8 |
1184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                      Opcodes[2] << 16 |
1185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                      Opcodes[3] << 24;
1186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    EmitIntValue(Intval, Opcodes.size());
118752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  }
118852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
1189c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien  // Switch to the section containing FnStart
1190c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien  SwitchSection(&FnStart->getSection());
1191c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien
119252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  // Clean exception handling frame information
1193de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  EHReset();
119452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien}
119552b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
1196320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
1197320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
1198320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola// Add the R_ARM_NONE fixup at the same position
1199320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
12006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const MCSymbol *PersonalitySym = getContext().getOrCreateSymbol(Name);
1201320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
12026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::create(
1203320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola      PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext());
1204320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
1205c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  visitUsedExpr(*PersonalityRef);
1206320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  MCDataFragment *DF = getOrCreateDataFragment();
12076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
1208320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola                                            PersonalityRef,
1209320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola                                            MCFixup::getKindForSize(4, false)));
121052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien}
121152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
121218cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chienvoid ARMELFStreamer::FlushPendingOffset() {
121318cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  if (PendingOffset != 0) {
121418cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien    UnwindOpAsm.EmitSPOffset(-PendingOffset);
121518cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien    PendingOffset = 0;
121618cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  }
121718cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien}
121818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien
12190a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chienvoid ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
122018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  // Emit the unwind opcode to restore $sp.
122118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  if (UsedFP) {
122299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    const MCRegisterInfo *MRI = getContext().getRegisterInfo();
122318cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien    int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
122418cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien    UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
122599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
122618cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  } else {
122718cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien    FlushPendingOffset();
122818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  }
122918cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien
123018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  // Finalize the unwind opcode sequence
123118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);
1232c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien
1233c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien  // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
1234c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien  // section.  Thus, we don't have to create an entry in the .ARM.extab
1235c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien  // section.
123636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0)
1237c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien    return;
1238c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien
1239c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien  // Switch to .ARM.extab section.
124052b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  SwitchToExTabSection(*FnStart);
124152b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
124252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  // Create .ARM.extab label for offset in .ARM.exidx
124352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  assert(!ExTab);
12446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  ExTab = getContext().createTempSymbol();
124552b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  EmitLabel(ExTab);
124652b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
1247c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien  // Emit personality
1248c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien  if (Personality) {
1249c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien    const MCSymbolRefExpr *PersonalityRef =
12506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      MCSymbolRefExpr::create(Personality,
1251c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien                              MCSymbolRefExpr::VK_ARM_PREL31,
1252c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien                              getContext());
125352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
1254a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindola    EmitValue(PersonalityRef, 4);
1255c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien  }
125652b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
125752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  // Emit unwind opcodes
1258dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert((Opcodes.size() % 4) == 0 &&
1259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4");
1260dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (unsigned I = 0; I != Opcodes.size(); I += 4) {
1261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t Intval = Opcodes[I] |
1262dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                      Opcodes[I + 1] << 8 |
1263dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                      Opcodes[I + 2] << 16 |
1264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                      Opcodes[I + 3] << 24;
1265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    EmitIntValue(Intval, 4);
1266dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
12670a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien
12680a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien  // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
12690a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien  // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
12700a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien  // after the unwind opcodes.  The handler data consists of several 32-bit
12710a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien  // words, and should be terminated by zero.
12720a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien  //
12730a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien  // In case that the .handlerdata directive is not specified by the
12740a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien  // programmer, we should emit zero to terminate the handler data.
12750a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien  if (NoHandlerData && !Personality)
12760a39e264330c5f6eb9e5e9e60d276613985e178dLogan Chien    EmitIntValue(0, 4);
127752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien}
127852b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
1279320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
1280c24a374331fc97dd215937c8f0a9bf5271f39657Logan Chien
1281320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
128252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien  Personality = Per;
1283532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien  UnwindOpAsm.setPersonality(Per);
128452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien}
128552b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
128636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMELFStreamer::emitPersonalityIndex(unsigned Index) {
128736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index");
128836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  PersonalityIndex = Index;
128936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
129036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1291320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg,
129252b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien                               int64_t Offset) {
129318cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
1294532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien         "the operand of .setfp directive should be either $sp or $fp");
1295532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien
1296532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien  UsedFP = true;
129718cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  FPReg = NewFPReg;
129818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien
129918cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  if (NewSPReg == ARM::SP)
130018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien    FPOffset = SPOffset + Offset;
130118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  else
130218cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien    FPOffset += Offset;
130352b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien}
130452b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
130536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
130636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert((Reg != ARM::SP && Reg != ARM::PC) &&
130736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         "the operand of .movsp cannot be either sp or pc");
130836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(FPReg == ARM::SP && "current FP must be SP");
130936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
131036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  FlushPendingOffset();
131136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
131236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  FPReg = Reg;
131336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  FPOffset = SPOffset + Offset;
131436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
131536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCRegisterInfo *MRI = getContext().getRegisterInfo();
131636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
131736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
131836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1319320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::emitPad(int64_t Offset) {
132018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  // Track the change of the $sp offset
132118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  SPOffset -= Offset;
132218cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien
132318cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  // To squash multiple .pad directives, we should delay the unwind opcode
132418cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  // until the .save, .vsave, .handlerdata, or .fnend directives.
132518cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  PendingOffset -= Offset;
132652b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien}
132752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
1328320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindolavoid ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
132952b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien                                 bool IsVector) {
133018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  // Collect the registers in the register list
133118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  unsigned Count = 0;
133218cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  uint32_t Mask = 0;
133399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1334532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien  for (size_t i = 0; i < RegList.size(); ++i) {
133599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    unsigned Reg = MRI->getEncodingValue(RegList[i]);
13366c1bd2919ee76ef4953136f0b73192fbef3a69abAaron Ballman    assert(Reg < (IsVector ? 32U : 16U) && "Register out of range");
133718cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien    unsigned Bit = (1u << Reg);
133818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien    if ((Mask & Bit) == 0) {
133918cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien      Mask |= Bit;
134018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien      ++Count;
134118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien    }
1342532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien  }
134318cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien
134418cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  // Track the change the $sp offset: For the .save directive, the
134518cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  // corresponding push instruction will decrease the $sp by (4 * Count).
134618cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  // For the .vsave directive, the corresponding vpush instruction will
134718cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  // decrease $sp by (8 * Count).
134818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  SPOffset -= Count * (IsVector ? 8 : 4);
134918cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien
135018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  // Emit the opcode
135118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  FlushPendingOffset();
135218cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  if (IsVector)
135318cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien    UnwindOpAsm.EmitVFPRegSave(Mask);
135418cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien  else
135518cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien    UnwindOpAsm.EmitRegSave(Mask);
135652b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien}
135752b1b3bbc6c8a7c7e5669e3169984a48b3f1a4b3Logan Chien
135836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid ARMELFStreamer::emitUnwindRaw(int64_t Offset,
135936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   const SmallVectorImpl<uint8_t> &Opcodes) {
136036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  FlushPendingOffset();
136136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SPOffset = SPOffset - Offset;
136236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  UnwindOpAsm.EmitRaw(Opcodes);
136336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
136436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
13656eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northovernamespace llvm {
1366320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
13674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarMCTargetStreamer *createARMTargetAsmStreamer(MCStreamer &S,
13684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                             formatted_raw_ostream &OS,
13694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                             MCInstPrinter *InstPrint,
13704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                             bool isVerboseAsm) {
13714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  return new ARMTargetAsmStreamer(S, OS, *InstPrint, isVerboseAsm);
1372320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola}
1373320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
1374ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesMCTargetStreamer *createARMNullTargetStreamer(MCStreamer &S) {
1375ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return new ARMTargetStreamer(S);
1376c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
1377c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
13784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarMCTargetStreamer *createARMObjectTargetStreamer(MCStreamer &S,
13794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                                const MCSubtargetInfo &STI) {
1380f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const Triple &TT = STI.getTargetTriple();
1381f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (TT.isOSBinFormatELF())
13824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    return new ARMTargetELFStreamer(S);
13834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  return new ARMTargetStreamer(S);
13844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar}
13854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
138637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
13870c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                    raw_pwrite_stream &OS,
13880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                    MCCodeEmitter *Emitter, bool RelaxAll,
13890c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                    bool IsThumb) {
139036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ARMELFStreamer *S = new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb);
13915e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola    // FIXME: This should eventually end up somewhere else where more
13925e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola    // intelligent flag decisions can be made. For now we are just maintaining
13935e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola    // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
13945e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola    S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
13955e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola
13966eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    if (RelaxAll)
13976eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover      S->getAssembler().setRelaxAll(true);
13986eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover    return S;
13996eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover  }
14006eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
14016eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover}
14026eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
14036eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover
1404