1*9880d681SAndroid Build Coastguard Worker //===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCObjectStreamer.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmBackend.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAssembler.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCCodeEmitter.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCDwarf.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCObjectWriter.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSection.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/SourceMgr.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
25*9880d681SAndroid Build Coastguard Worker using namespace llvm;
26*9880d681SAndroid Build Coastguard Worker
MCObjectStreamer(MCContext & Context,MCAsmBackend & TAB,raw_pwrite_stream & OS,MCCodeEmitter * Emitter_)27*9880d681SAndroid Build Coastguard Worker MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
28*9880d681SAndroid Build Coastguard Worker raw_pwrite_stream &OS,
29*9880d681SAndroid Build Coastguard Worker MCCodeEmitter *Emitter_)
30*9880d681SAndroid Build Coastguard Worker : MCStreamer(Context),
31*9880d681SAndroid Build Coastguard Worker Assembler(new MCAssembler(Context, TAB, *Emitter_,
32*9880d681SAndroid Build Coastguard Worker *TAB.createObjectWriter(OS))),
33*9880d681SAndroid Build Coastguard Worker EmitEHFrame(true), EmitDebugFrame(false) {}
34*9880d681SAndroid Build Coastguard Worker
~MCObjectStreamer()35*9880d681SAndroid Build Coastguard Worker MCObjectStreamer::~MCObjectStreamer() {
36*9880d681SAndroid Build Coastguard Worker delete &Assembler->getBackend();
37*9880d681SAndroid Build Coastguard Worker delete &Assembler->getEmitter();
38*9880d681SAndroid Build Coastguard Worker delete &Assembler->getWriter();
39*9880d681SAndroid Build Coastguard Worker delete Assembler;
40*9880d681SAndroid Build Coastguard Worker }
41*9880d681SAndroid Build Coastguard Worker
flushPendingLabels(MCFragment * F,uint64_t FOffset)42*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
43*9880d681SAndroid Build Coastguard Worker if (PendingLabels.empty())
44*9880d681SAndroid Build Coastguard Worker return;
45*9880d681SAndroid Build Coastguard Worker if (!F) {
46*9880d681SAndroid Build Coastguard Worker F = new MCDataFragment();
47*9880d681SAndroid Build Coastguard Worker MCSection *CurSection = getCurrentSectionOnly();
48*9880d681SAndroid Build Coastguard Worker CurSection->getFragmentList().insert(CurInsertionPoint, F);
49*9880d681SAndroid Build Coastguard Worker F->setParent(CurSection);
50*9880d681SAndroid Build Coastguard Worker }
51*9880d681SAndroid Build Coastguard Worker for (MCSymbol *Sym : PendingLabels) {
52*9880d681SAndroid Build Coastguard Worker Sym->setFragment(F);
53*9880d681SAndroid Build Coastguard Worker Sym->setOffset(FOffset);
54*9880d681SAndroid Build Coastguard Worker }
55*9880d681SAndroid Build Coastguard Worker PendingLabels.clear();
56*9880d681SAndroid Build Coastguard Worker }
57*9880d681SAndroid Build Coastguard Worker
emitAbsoluteSymbolDiff(const MCSymbol * Hi,const MCSymbol * Lo,unsigned Size)58*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
59*9880d681SAndroid Build Coastguard Worker const MCSymbol *Lo,
60*9880d681SAndroid Build Coastguard Worker unsigned Size) {
61*9880d681SAndroid Build Coastguard Worker // If not assigned to the same (valid) fragment, fallback.
62*9880d681SAndroid Build Coastguard Worker if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
63*9880d681SAndroid Build Coastguard Worker Hi->isVariable() || Lo->isVariable()) {
64*9880d681SAndroid Build Coastguard Worker MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
65*9880d681SAndroid Build Coastguard Worker return;
66*9880d681SAndroid Build Coastguard Worker }
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Worker EmitIntValue(Hi->getOffset() - Lo->getOffset(), Size);
69*9880d681SAndroid Build Coastguard Worker }
70*9880d681SAndroid Build Coastguard Worker
reset()71*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::reset() {
72*9880d681SAndroid Build Coastguard Worker if (Assembler)
73*9880d681SAndroid Build Coastguard Worker Assembler->reset();
74*9880d681SAndroid Build Coastguard Worker CurInsertionPoint = MCSection::iterator();
75*9880d681SAndroid Build Coastguard Worker EmitEHFrame = true;
76*9880d681SAndroid Build Coastguard Worker EmitDebugFrame = false;
77*9880d681SAndroid Build Coastguard Worker PendingLabels.clear();
78*9880d681SAndroid Build Coastguard Worker MCStreamer::reset();
79*9880d681SAndroid Build Coastguard Worker }
80*9880d681SAndroid Build Coastguard Worker
EmitFrames(MCAsmBackend * MAB)81*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitFrames(MCAsmBackend *MAB) {
82*9880d681SAndroid Build Coastguard Worker if (!getNumFrameInfos())
83*9880d681SAndroid Build Coastguard Worker return;
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker if (EmitEHFrame)
86*9880d681SAndroid Build Coastguard Worker MCDwarfFrameEmitter::Emit(*this, MAB, true);
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker if (EmitDebugFrame)
89*9880d681SAndroid Build Coastguard Worker MCDwarfFrameEmitter::Emit(*this, MAB, false);
90*9880d681SAndroid Build Coastguard Worker }
91*9880d681SAndroid Build Coastguard Worker
getCurrentFragment() const92*9880d681SAndroid Build Coastguard Worker MCFragment *MCObjectStreamer::getCurrentFragment() const {
93*9880d681SAndroid Build Coastguard Worker assert(getCurrentSectionOnly() && "No current section!");
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin())
96*9880d681SAndroid Build Coastguard Worker return &*std::prev(CurInsertionPoint);
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker return nullptr;
99*9880d681SAndroid Build Coastguard Worker }
100*9880d681SAndroid Build Coastguard Worker
getOrCreateDataFragment()101*9880d681SAndroid Build Coastguard Worker MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() {
102*9880d681SAndroid Build Coastguard Worker MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
103*9880d681SAndroid Build Coastguard Worker // When bundling is enabled, we don't want to add data to a fragment that
104*9880d681SAndroid Build Coastguard Worker // already has instructions (see MCELFStreamer::EmitInstToData for details)
105*9880d681SAndroid Build Coastguard Worker if (!F || (Assembler->isBundlingEnabled() && !Assembler->getRelaxAll() &&
106*9880d681SAndroid Build Coastguard Worker F->hasInstructions())) {
107*9880d681SAndroid Build Coastguard Worker F = new MCDataFragment();
108*9880d681SAndroid Build Coastguard Worker insert(F);
109*9880d681SAndroid Build Coastguard Worker }
110*9880d681SAndroid Build Coastguard Worker return F;
111*9880d681SAndroid Build Coastguard Worker }
112*9880d681SAndroid Build Coastguard Worker
visitUsedSymbol(const MCSymbol & Sym)113*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
114*9880d681SAndroid Build Coastguard Worker Assembler->registerSymbol(Sym);
115*9880d681SAndroid Build Coastguard Worker }
116*9880d681SAndroid Build Coastguard Worker
EmitCFISections(bool EH,bool Debug)117*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitCFISections(bool EH, bool Debug) {
118*9880d681SAndroid Build Coastguard Worker MCStreamer::EmitCFISections(EH, Debug);
119*9880d681SAndroid Build Coastguard Worker EmitEHFrame = EH;
120*9880d681SAndroid Build Coastguard Worker EmitDebugFrame = Debug;
121*9880d681SAndroid Build Coastguard Worker }
122*9880d681SAndroid Build Coastguard Worker
EmitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)123*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
124*9880d681SAndroid Build Coastguard Worker SMLoc Loc) {
125*9880d681SAndroid Build Coastguard Worker MCStreamer::EmitValueImpl(Value, Size, Loc);
126*9880d681SAndroid Build Coastguard Worker MCDataFragment *DF = getOrCreateDataFragment();
127*9880d681SAndroid Build Coastguard Worker flushPendingLabels(DF, DF->getContents().size());
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Worker MCCVLineEntry::Make(this);
130*9880d681SAndroid Build Coastguard Worker MCDwarfLineEntry::Make(this, getCurrentSection().first);
131*9880d681SAndroid Build Coastguard Worker
132*9880d681SAndroid Build Coastguard Worker // Avoid fixups when possible.
133*9880d681SAndroid Build Coastguard Worker int64_t AbsValue;
134*9880d681SAndroid Build Coastguard Worker if (Value->evaluateAsAbsolute(AbsValue, getAssembler())) {
135*9880d681SAndroid Build Coastguard Worker EmitIntValue(AbsValue, Size);
136*9880d681SAndroid Build Coastguard Worker return;
137*9880d681SAndroid Build Coastguard Worker }
138*9880d681SAndroid Build Coastguard Worker DF->getFixups().push_back(
139*9880d681SAndroid Build Coastguard Worker MCFixup::create(DF->getContents().size(), Value,
140*9880d681SAndroid Build Coastguard Worker MCFixup::getKindForSize(Size, false), Loc));
141*9880d681SAndroid Build Coastguard Worker DF->getContents().resize(DF->getContents().size() + Size, 0);
142*9880d681SAndroid Build Coastguard Worker }
143*9880d681SAndroid Build Coastguard Worker
EmitCFIStartProcImpl(MCDwarfFrameInfo & Frame)144*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
145*9880d681SAndroid Build Coastguard Worker // We need to create a local symbol to avoid relocations.
146*9880d681SAndroid Build Coastguard Worker Frame.Begin = getContext().createTempSymbol();
147*9880d681SAndroid Build Coastguard Worker EmitLabel(Frame.Begin);
148*9880d681SAndroid Build Coastguard Worker }
149*9880d681SAndroid Build Coastguard Worker
EmitCFIEndProcImpl(MCDwarfFrameInfo & Frame)150*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
151*9880d681SAndroid Build Coastguard Worker Frame.End = getContext().createTempSymbol();
152*9880d681SAndroid Build Coastguard Worker EmitLabel(Frame.End);
153*9880d681SAndroid Build Coastguard Worker }
154*9880d681SAndroid Build Coastguard Worker
EmitLabel(MCSymbol * Symbol)155*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
156*9880d681SAndroid Build Coastguard Worker MCStreamer::EmitLabel(Symbol);
157*9880d681SAndroid Build Coastguard Worker
158*9880d681SAndroid Build Coastguard Worker getAssembler().registerSymbol(*Symbol);
159*9880d681SAndroid Build Coastguard Worker
160*9880d681SAndroid Build Coastguard Worker // If there is a current fragment, mark the symbol as pointing into it.
161*9880d681SAndroid Build Coastguard Worker // Otherwise queue the label and set its fragment pointer when we emit the
162*9880d681SAndroid Build Coastguard Worker // next fragment.
163*9880d681SAndroid Build Coastguard Worker auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
164*9880d681SAndroid Build Coastguard Worker if (F && !(getAssembler().isBundlingEnabled() &&
165*9880d681SAndroid Build Coastguard Worker getAssembler().getRelaxAll())) {
166*9880d681SAndroid Build Coastguard Worker Symbol->setFragment(F);
167*9880d681SAndroid Build Coastguard Worker Symbol->setOffset(F->getContents().size());
168*9880d681SAndroid Build Coastguard Worker } else {
169*9880d681SAndroid Build Coastguard Worker PendingLabels.push_back(Symbol);
170*9880d681SAndroid Build Coastguard Worker }
171*9880d681SAndroid Build Coastguard Worker }
172*9880d681SAndroid Build Coastguard Worker
EmitULEB128Value(const MCExpr * Value)173*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
174*9880d681SAndroid Build Coastguard Worker int64_t IntValue;
175*9880d681SAndroid Build Coastguard Worker if (Value->evaluateAsAbsolute(IntValue, getAssembler())) {
176*9880d681SAndroid Build Coastguard Worker EmitULEB128IntValue(IntValue);
177*9880d681SAndroid Build Coastguard Worker return;
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker insert(new MCLEBFragment(*Value, false));
180*9880d681SAndroid Build Coastguard Worker }
181*9880d681SAndroid Build Coastguard Worker
EmitSLEB128Value(const MCExpr * Value)182*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
183*9880d681SAndroid Build Coastguard Worker int64_t IntValue;
184*9880d681SAndroid Build Coastguard Worker if (Value->evaluateAsAbsolute(IntValue, getAssembler())) {
185*9880d681SAndroid Build Coastguard Worker EmitSLEB128IntValue(IntValue);
186*9880d681SAndroid Build Coastguard Worker return;
187*9880d681SAndroid Build Coastguard Worker }
188*9880d681SAndroid Build Coastguard Worker insert(new MCLEBFragment(*Value, true));
189*9880d681SAndroid Build Coastguard Worker }
190*9880d681SAndroid Build Coastguard Worker
EmitWeakReference(MCSymbol * Alias,const MCSymbol * Symbol)191*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
192*9880d681SAndroid Build Coastguard Worker const MCSymbol *Symbol) {
193*9880d681SAndroid Build Coastguard Worker report_fatal_error("This file format doesn't support weak aliases.");
194*9880d681SAndroid Build Coastguard Worker }
195*9880d681SAndroid Build Coastguard Worker
ChangeSection(MCSection * Section,const MCExpr * Subsection)196*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::ChangeSection(MCSection *Section,
197*9880d681SAndroid Build Coastguard Worker const MCExpr *Subsection) {
198*9880d681SAndroid Build Coastguard Worker changeSectionImpl(Section, Subsection);
199*9880d681SAndroid Build Coastguard Worker }
200*9880d681SAndroid Build Coastguard Worker
changeSectionImpl(MCSection * Section,const MCExpr * Subsection)201*9880d681SAndroid Build Coastguard Worker bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
202*9880d681SAndroid Build Coastguard Worker const MCExpr *Subsection) {
203*9880d681SAndroid Build Coastguard Worker assert(Section && "Cannot switch to a null section!");
204*9880d681SAndroid Build Coastguard Worker flushPendingLabels(nullptr);
205*9880d681SAndroid Build Coastguard Worker
206*9880d681SAndroid Build Coastguard Worker bool Created = getAssembler().registerSection(*Section);
207*9880d681SAndroid Build Coastguard Worker
208*9880d681SAndroid Build Coastguard Worker int64_t IntSubsection = 0;
209*9880d681SAndroid Build Coastguard Worker if (Subsection &&
210*9880d681SAndroid Build Coastguard Worker !Subsection->evaluateAsAbsolute(IntSubsection, getAssembler()))
211*9880d681SAndroid Build Coastguard Worker report_fatal_error("Cannot evaluate subsection number");
212*9880d681SAndroid Build Coastguard Worker if (IntSubsection < 0 || IntSubsection > 8192)
213*9880d681SAndroid Build Coastguard Worker report_fatal_error("Subsection number out of range");
214*9880d681SAndroid Build Coastguard Worker CurInsertionPoint =
215*9880d681SAndroid Build Coastguard Worker Section->getSubsectionInsertionPoint(unsigned(IntSubsection));
216*9880d681SAndroid Build Coastguard Worker return Created;
217*9880d681SAndroid Build Coastguard Worker }
218*9880d681SAndroid Build Coastguard Worker
EmitAssignment(MCSymbol * Symbol,const MCExpr * Value)219*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
220*9880d681SAndroid Build Coastguard Worker getAssembler().registerSymbol(*Symbol);
221*9880d681SAndroid Build Coastguard Worker MCStreamer::EmitAssignment(Symbol, Value);
222*9880d681SAndroid Build Coastguard Worker }
223*9880d681SAndroid Build Coastguard Worker
mayHaveInstructions(MCSection & Sec) const224*9880d681SAndroid Build Coastguard Worker bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
225*9880d681SAndroid Build Coastguard Worker return Sec.hasInstructions();
226*9880d681SAndroid Build Coastguard Worker }
227*9880d681SAndroid Build Coastguard Worker
EmitInstruction(const MCInst & Inst,const MCSubtargetInfo & STI)228*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitInstruction(const MCInst &Inst,
229*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI) {
230*9880d681SAndroid Build Coastguard Worker MCStreamer::EmitInstruction(Inst, STI);
231*9880d681SAndroid Build Coastguard Worker
232*9880d681SAndroid Build Coastguard Worker MCSection *Sec = getCurrentSectionOnly();
233*9880d681SAndroid Build Coastguard Worker Sec->setHasInstructions(true);
234*9880d681SAndroid Build Coastguard Worker
235*9880d681SAndroid Build Coastguard Worker // Now that a machine instruction has been assembled into this section, make
236*9880d681SAndroid Build Coastguard Worker // a line entry for any .loc directive that has been seen.
237*9880d681SAndroid Build Coastguard Worker MCCVLineEntry::Make(this);
238*9880d681SAndroid Build Coastguard Worker MCDwarfLineEntry::Make(this, getCurrentSection().first);
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Worker // If this instruction doesn't need relaxation, just emit it as data.
241*9880d681SAndroid Build Coastguard Worker MCAssembler &Assembler = getAssembler();
242*9880d681SAndroid Build Coastguard Worker if (!Assembler.getBackend().mayNeedRelaxation(Inst)) {
243*9880d681SAndroid Build Coastguard Worker EmitInstToData(Inst, STI);
244*9880d681SAndroid Build Coastguard Worker return;
245*9880d681SAndroid Build Coastguard Worker }
246*9880d681SAndroid Build Coastguard Worker
247*9880d681SAndroid Build Coastguard Worker // Otherwise, relax and emit it as data if either:
248*9880d681SAndroid Build Coastguard Worker // - The RelaxAll flag was passed
249*9880d681SAndroid Build Coastguard Worker // - Bundling is enabled and this instruction is inside a bundle-locked
250*9880d681SAndroid Build Coastguard Worker // group. We want to emit all such instructions into the same data
251*9880d681SAndroid Build Coastguard Worker // fragment.
252*9880d681SAndroid Build Coastguard Worker if (Assembler.getRelaxAll() ||
253*9880d681SAndroid Build Coastguard Worker (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
254*9880d681SAndroid Build Coastguard Worker MCInst Relaxed;
255*9880d681SAndroid Build Coastguard Worker getAssembler().getBackend().relaxInstruction(Inst, STI, Relaxed);
256*9880d681SAndroid Build Coastguard Worker while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
257*9880d681SAndroid Build Coastguard Worker getAssembler().getBackend().relaxInstruction(Relaxed, STI, Relaxed);
258*9880d681SAndroid Build Coastguard Worker EmitInstToData(Relaxed, STI);
259*9880d681SAndroid Build Coastguard Worker return;
260*9880d681SAndroid Build Coastguard Worker }
261*9880d681SAndroid Build Coastguard Worker
262*9880d681SAndroid Build Coastguard Worker // Otherwise emit to a separate fragment.
263*9880d681SAndroid Build Coastguard Worker EmitInstToFragment(Inst, STI);
264*9880d681SAndroid Build Coastguard Worker }
265*9880d681SAndroid Build Coastguard Worker
EmitInstToFragment(const MCInst & Inst,const MCSubtargetInfo & STI)266*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst,
267*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI) {
268*9880d681SAndroid Build Coastguard Worker if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled())
269*9880d681SAndroid Build Coastguard Worker llvm_unreachable("All instructions should have already been relaxed");
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker // Always create a new, separate fragment here, because its size can change
272*9880d681SAndroid Build Coastguard Worker // during relaxation.
273*9880d681SAndroid Build Coastguard Worker MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
274*9880d681SAndroid Build Coastguard Worker insert(IF);
275*9880d681SAndroid Build Coastguard Worker
276*9880d681SAndroid Build Coastguard Worker SmallString<128> Code;
277*9880d681SAndroid Build Coastguard Worker raw_svector_ostream VecOS(Code);
278*9880d681SAndroid Build Coastguard Worker getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(),
279*9880d681SAndroid Build Coastguard Worker STI);
280*9880d681SAndroid Build Coastguard Worker IF->getContents().append(Code.begin(), Code.end());
281*9880d681SAndroid Build Coastguard Worker }
282*9880d681SAndroid Build Coastguard Worker
283*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
284*9880d681SAndroid Build Coastguard Worker static const char *const BundlingNotImplementedMsg =
285*9880d681SAndroid Build Coastguard Worker "Aligned bundling is not implemented for this object format";
286*9880d681SAndroid Build Coastguard Worker #endif
287*9880d681SAndroid Build Coastguard Worker
EmitBundleAlignMode(unsigned AlignPow2)288*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
289*9880d681SAndroid Build Coastguard Worker llvm_unreachable(BundlingNotImplementedMsg);
290*9880d681SAndroid Build Coastguard Worker }
291*9880d681SAndroid Build Coastguard Worker
EmitBundleLock(bool AlignToEnd)292*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitBundleLock(bool AlignToEnd) {
293*9880d681SAndroid Build Coastguard Worker llvm_unreachable(BundlingNotImplementedMsg);
294*9880d681SAndroid Build Coastguard Worker }
295*9880d681SAndroid Build Coastguard Worker
EmitBundleUnlock()296*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitBundleUnlock() {
297*9880d681SAndroid Build Coastguard Worker llvm_unreachable(BundlingNotImplementedMsg);
298*9880d681SAndroid Build Coastguard Worker }
299*9880d681SAndroid Build Coastguard Worker
EmitDwarfLocDirective(unsigned FileNo,unsigned Line,unsigned Column,unsigned Flags,unsigned Isa,unsigned Discriminator,StringRef FileName)300*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
301*9880d681SAndroid Build Coastguard Worker unsigned Column, unsigned Flags,
302*9880d681SAndroid Build Coastguard Worker unsigned Isa,
303*9880d681SAndroid Build Coastguard Worker unsigned Discriminator,
304*9880d681SAndroid Build Coastguard Worker StringRef FileName) {
305*9880d681SAndroid Build Coastguard Worker // In case we see two .loc directives in a row, make sure the
306*9880d681SAndroid Build Coastguard Worker // first one gets a line entry.
307*9880d681SAndroid Build Coastguard Worker MCDwarfLineEntry::Make(this, getCurrentSection().first);
308*9880d681SAndroid Build Coastguard Worker
309*9880d681SAndroid Build Coastguard Worker this->MCStreamer::EmitDwarfLocDirective(FileNo, Line, Column, Flags,
310*9880d681SAndroid Build Coastguard Worker Isa, Discriminator, FileName);
311*9880d681SAndroid Build Coastguard Worker }
312*9880d681SAndroid Build Coastguard Worker
buildSymbolDiff(MCObjectStreamer & OS,const MCSymbol * A,const MCSymbol * B)313*9880d681SAndroid Build Coastguard Worker static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
314*9880d681SAndroid Build Coastguard Worker const MCSymbol *B) {
315*9880d681SAndroid Build Coastguard Worker MCContext &Context = OS.getContext();
316*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
317*9880d681SAndroid Build Coastguard Worker const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
318*9880d681SAndroid Build Coastguard Worker const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
319*9880d681SAndroid Build Coastguard Worker const MCExpr *AddrDelta =
320*9880d681SAndroid Build Coastguard Worker MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
321*9880d681SAndroid Build Coastguard Worker return AddrDelta;
322*9880d681SAndroid Build Coastguard Worker }
323*9880d681SAndroid Build Coastguard Worker
emitDwarfSetLineAddr(MCObjectStreamer & OS,MCDwarfLineTableParams Params,int64_t LineDelta,const MCSymbol * Label,int PointerSize)324*9880d681SAndroid Build Coastguard Worker static void emitDwarfSetLineAddr(MCObjectStreamer &OS,
325*9880d681SAndroid Build Coastguard Worker MCDwarfLineTableParams Params,
326*9880d681SAndroid Build Coastguard Worker int64_t LineDelta, const MCSymbol *Label,
327*9880d681SAndroid Build Coastguard Worker int PointerSize) {
328*9880d681SAndroid Build Coastguard Worker // emit the sequence to set the address
329*9880d681SAndroid Build Coastguard Worker OS.EmitIntValue(dwarf::DW_LNS_extended_op, 1);
330*9880d681SAndroid Build Coastguard Worker OS.EmitULEB128IntValue(PointerSize + 1);
331*9880d681SAndroid Build Coastguard Worker OS.EmitIntValue(dwarf::DW_LNE_set_address, 1);
332*9880d681SAndroid Build Coastguard Worker OS.EmitSymbolValue(Label, PointerSize);
333*9880d681SAndroid Build Coastguard Worker
334*9880d681SAndroid Build Coastguard Worker // emit the sequence for the LineDelta (from 1) and a zero address delta.
335*9880d681SAndroid Build Coastguard Worker MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
336*9880d681SAndroid Build Coastguard Worker }
337*9880d681SAndroid Build Coastguard Worker
EmitDwarfAdvanceLineAddr(int64_t LineDelta,const MCSymbol * LastLabel,const MCSymbol * Label,unsigned PointerSize)338*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
339*9880d681SAndroid Build Coastguard Worker const MCSymbol *LastLabel,
340*9880d681SAndroid Build Coastguard Worker const MCSymbol *Label,
341*9880d681SAndroid Build Coastguard Worker unsigned PointerSize) {
342*9880d681SAndroid Build Coastguard Worker if (!LastLabel) {
343*9880d681SAndroid Build Coastguard Worker emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,
344*9880d681SAndroid Build Coastguard Worker Label, PointerSize);
345*9880d681SAndroid Build Coastguard Worker return;
346*9880d681SAndroid Build Coastguard Worker }
347*9880d681SAndroid Build Coastguard Worker const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
348*9880d681SAndroid Build Coastguard Worker int64_t Res;
349*9880d681SAndroid Build Coastguard Worker if (AddrDelta->evaluateAsAbsolute(Res, getAssembler())) {
350*9880d681SAndroid Build Coastguard Worker MCDwarfLineAddr::Emit(this, Assembler->getDWARFLinetableParams(), LineDelta,
351*9880d681SAndroid Build Coastguard Worker Res);
352*9880d681SAndroid Build Coastguard Worker return;
353*9880d681SAndroid Build Coastguard Worker }
354*9880d681SAndroid Build Coastguard Worker insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
355*9880d681SAndroid Build Coastguard Worker }
356*9880d681SAndroid Build Coastguard Worker
EmitDwarfAdvanceFrameAddr(const MCSymbol * LastLabel,const MCSymbol * Label)357*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
358*9880d681SAndroid Build Coastguard Worker const MCSymbol *Label) {
359*9880d681SAndroid Build Coastguard Worker const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
360*9880d681SAndroid Build Coastguard Worker int64_t Res;
361*9880d681SAndroid Build Coastguard Worker if (AddrDelta->evaluateAsAbsolute(Res, getAssembler())) {
362*9880d681SAndroid Build Coastguard Worker MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
363*9880d681SAndroid Build Coastguard Worker return;
364*9880d681SAndroid Build Coastguard Worker }
365*9880d681SAndroid Build Coastguard Worker insert(new MCDwarfCallFrameFragment(*AddrDelta));
366*9880d681SAndroid Build Coastguard Worker }
367*9880d681SAndroid Build Coastguard Worker
EmitCVLocDirective(unsigned FunctionId,unsigned FileNo,unsigned Line,unsigned Column,bool PrologueEnd,bool IsStmt,StringRef FileName)368*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
369*9880d681SAndroid Build Coastguard Worker unsigned Line, unsigned Column,
370*9880d681SAndroid Build Coastguard Worker bool PrologueEnd, bool IsStmt,
371*9880d681SAndroid Build Coastguard Worker StringRef FileName) {
372*9880d681SAndroid Build Coastguard Worker // In case we see two .cv_loc directives in a row, make sure the
373*9880d681SAndroid Build Coastguard Worker // first one gets a line entry.
374*9880d681SAndroid Build Coastguard Worker MCCVLineEntry::Make(this);
375*9880d681SAndroid Build Coastguard Worker
376*9880d681SAndroid Build Coastguard Worker this->MCStreamer::EmitCVLocDirective(FunctionId, FileNo, Line, Column,
377*9880d681SAndroid Build Coastguard Worker PrologueEnd, IsStmt, FileName);
378*9880d681SAndroid Build Coastguard Worker }
379*9880d681SAndroid Build Coastguard Worker
EmitCVLinetableDirective(unsigned FunctionId,const MCSymbol * Begin,const MCSymbol * End)380*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitCVLinetableDirective(unsigned FunctionId,
381*9880d681SAndroid Build Coastguard Worker const MCSymbol *Begin,
382*9880d681SAndroid Build Coastguard Worker const MCSymbol *End) {
383*9880d681SAndroid Build Coastguard Worker getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,
384*9880d681SAndroid Build Coastguard Worker End);
385*9880d681SAndroid Build Coastguard Worker this->MCStreamer::EmitCVLinetableDirective(FunctionId, Begin, End);
386*9880d681SAndroid Build Coastguard Worker }
387*9880d681SAndroid Build Coastguard Worker
EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,unsigned SourceFileId,unsigned SourceLineNum,const MCSymbol * FnStartSym,const MCSymbol * FnEndSym,ArrayRef<unsigned> SecondaryFunctionIds)388*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitCVInlineLinetableDirective(
389*9880d681SAndroid Build Coastguard Worker unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
390*9880d681SAndroid Build Coastguard Worker const MCSymbol *FnStartSym, const MCSymbol *FnEndSym,
391*9880d681SAndroid Build Coastguard Worker ArrayRef<unsigned> SecondaryFunctionIds) {
392*9880d681SAndroid Build Coastguard Worker getContext().getCVContext().emitInlineLineTableForFunction(
393*9880d681SAndroid Build Coastguard Worker *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
394*9880d681SAndroid Build Coastguard Worker FnEndSym, SecondaryFunctionIds);
395*9880d681SAndroid Build Coastguard Worker this->MCStreamer::EmitCVInlineLinetableDirective(
396*9880d681SAndroid Build Coastguard Worker PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym,
397*9880d681SAndroid Build Coastguard Worker SecondaryFunctionIds);
398*9880d681SAndroid Build Coastguard Worker }
399*9880d681SAndroid Build Coastguard Worker
EmitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,StringRef FixedSizePortion)400*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitCVDefRangeDirective(
401*9880d681SAndroid Build Coastguard Worker ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
402*9880d681SAndroid Build Coastguard Worker StringRef FixedSizePortion) {
403*9880d681SAndroid Build Coastguard Worker getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
404*9880d681SAndroid Build Coastguard Worker this->MCStreamer::EmitCVDefRangeDirective(Ranges, FixedSizePortion);
405*9880d681SAndroid Build Coastguard Worker }
406*9880d681SAndroid Build Coastguard Worker
EmitCVStringTableDirective()407*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitCVStringTableDirective() {
408*9880d681SAndroid Build Coastguard Worker getContext().getCVContext().emitStringTable(*this);
409*9880d681SAndroid Build Coastguard Worker }
EmitCVFileChecksumsDirective()410*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitCVFileChecksumsDirective() {
411*9880d681SAndroid Build Coastguard Worker getContext().getCVContext().emitFileChecksums(*this);
412*9880d681SAndroid Build Coastguard Worker }
413*9880d681SAndroid Build Coastguard Worker
414*9880d681SAndroid Build Coastguard Worker
EmitBytes(StringRef Data)415*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitBytes(StringRef Data) {
416*9880d681SAndroid Build Coastguard Worker MCCVLineEntry::Make(this);
417*9880d681SAndroid Build Coastguard Worker MCDwarfLineEntry::Make(this, getCurrentSection().first);
418*9880d681SAndroid Build Coastguard Worker MCDataFragment *DF = getOrCreateDataFragment();
419*9880d681SAndroid Build Coastguard Worker flushPendingLabels(DF, DF->getContents().size());
420*9880d681SAndroid Build Coastguard Worker DF->getContents().append(Data.begin(), Data.end());
421*9880d681SAndroid Build Coastguard Worker }
422*9880d681SAndroid Build Coastguard Worker
EmitValueToAlignment(unsigned ByteAlignment,int64_t Value,unsigned ValueSize,unsigned MaxBytesToEmit)423*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment,
424*9880d681SAndroid Build Coastguard Worker int64_t Value,
425*9880d681SAndroid Build Coastguard Worker unsigned ValueSize,
426*9880d681SAndroid Build Coastguard Worker unsigned MaxBytesToEmit) {
427*9880d681SAndroid Build Coastguard Worker if (MaxBytesToEmit == 0)
428*9880d681SAndroid Build Coastguard Worker MaxBytesToEmit = ByteAlignment;
429*9880d681SAndroid Build Coastguard Worker insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit));
430*9880d681SAndroid Build Coastguard Worker
431*9880d681SAndroid Build Coastguard Worker // Update the maximum alignment on the current section if necessary.
432*9880d681SAndroid Build Coastguard Worker MCSection *CurSec = getCurrentSection().first;
433*9880d681SAndroid Build Coastguard Worker if (ByteAlignment > CurSec->getAlignment())
434*9880d681SAndroid Build Coastguard Worker CurSec->setAlignment(ByteAlignment);
435*9880d681SAndroid Build Coastguard Worker }
436*9880d681SAndroid Build Coastguard Worker
EmitCodeAlignment(unsigned ByteAlignment,unsigned MaxBytesToEmit)437*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitCodeAlignment(unsigned ByteAlignment,
438*9880d681SAndroid Build Coastguard Worker unsigned MaxBytesToEmit) {
439*9880d681SAndroid Build Coastguard Worker EmitValueToAlignment(ByteAlignment, 0, 1, MaxBytesToEmit);
440*9880d681SAndroid Build Coastguard Worker cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true);
441*9880d681SAndroid Build Coastguard Worker }
442*9880d681SAndroid Build Coastguard Worker
emitValueToOffset(const MCExpr * Offset,unsigned char Value)443*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
444*9880d681SAndroid Build Coastguard Worker unsigned char Value) {
445*9880d681SAndroid Build Coastguard Worker insert(new MCOrgFragment(*Offset, Value));
446*9880d681SAndroid Build Coastguard Worker }
447*9880d681SAndroid Build Coastguard Worker
448*9880d681SAndroid Build Coastguard Worker // Associate GPRel32 fixup with data and resize data area
EmitGPRel32Value(const MCExpr * Value)449*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) {
450*9880d681SAndroid Build Coastguard Worker MCDataFragment *DF = getOrCreateDataFragment();
451*9880d681SAndroid Build Coastguard Worker flushPendingLabels(DF, DF->getContents().size());
452*9880d681SAndroid Build Coastguard Worker
453*9880d681SAndroid Build Coastguard Worker DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
454*9880d681SAndroid Build Coastguard Worker Value, FK_GPRel_4));
455*9880d681SAndroid Build Coastguard Worker DF->getContents().resize(DF->getContents().size() + 4, 0);
456*9880d681SAndroid Build Coastguard Worker }
457*9880d681SAndroid Build Coastguard Worker
458*9880d681SAndroid Build Coastguard Worker // Associate GPRel32 fixup with data and resize data area
EmitGPRel64Value(const MCExpr * Value)459*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) {
460*9880d681SAndroid Build Coastguard Worker MCDataFragment *DF = getOrCreateDataFragment();
461*9880d681SAndroid Build Coastguard Worker flushPendingLabels(DF, DF->getContents().size());
462*9880d681SAndroid Build Coastguard Worker
463*9880d681SAndroid Build Coastguard Worker DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
464*9880d681SAndroid Build Coastguard Worker Value, FK_GPRel_4));
465*9880d681SAndroid Build Coastguard Worker DF->getContents().resize(DF->getContents().size() + 8, 0);
466*9880d681SAndroid Build Coastguard Worker }
467*9880d681SAndroid Build Coastguard Worker
EmitRelocDirective(const MCExpr & Offset,StringRef Name,const MCExpr * Expr,SMLoc Loc)468*9880d681SAndroid Build Coastguard Worker bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name,
469*9880d681SAndroid Build Coastguard Worker const MCExpr *Expr, SMLoc Loc) {
470*9880d681SAndroid Build Coastguard Worker int64_t OffsetValue;
471*9880d681SAndroid Build Coastguard Worker if (!Offset.evaluateAsAbsolute(OffsetValue))
472*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Offset is not absolute");
473*9880d681SAndroid Build Coastguard Worker
474*9880d681SAndroid Build Coastguard Worker if (OffsetValue < 0)
475*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Offset is negative");
476*9880d681SAndroid Build Coastguard Worker
477*9880d681SAndroid Build Coastguard Worker MCDataFragment *DF = getOrCreateDataFragment();
478*9880d681SAndroid Build Coastguard Worker flushPendingLabels(DF, DF->getContents().size());
479*9880d681SAndroid Build Coastguard Worker
480*9880d681SAndroid Build Coastguard Worker Optional<MCFixupKind> MaybeKind = Assembler->getBackend().getFixupKind(Name);
481*9880d681SAndroid Build Coastguard Worker if (!MaybeKind.hasValue())
482*9880d681SAndroid Build Coastguard Worker return true;
483*9880d681SAndroid Build Coastguard Worker
484*9880d681SAndroid Build Coastguard Worker MCFixupKind Kind = *MaybeKind;
485*9880d681SAndroid Build Coastguard Worker
486*9880d681SAndroid Build Coastguard Worker if (Expr == nullptr)
487*9880d681SAndroid Build Coastguard Worker Expr =
488*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
489*9880d681SAndroid Build Coastguard Worker DF->getFixups().push_back(MCFixup::create(OffsetValue, Expr, Kind, Loc));
490*9880d681SAndroid Build Coastguard Worker return false;
491*9880d681SAndroid Build Coastguard Worker }
492*9880d681SAndroid Build Coastguard Worker
emitFill(uint64_t NumBytes,uint8_t FillValue)493*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
494*9880d681SAndroid Build Coastguard Worker const MCSection *Sec = getCurrentSection().first;
495*9880d681SAndroid Build Coastguard Worker (void)Sec;
496*9880d681SAndroid Build Coastguard Worker assert(Sec && "need a section");
497*9880d681SAndroid Build Coastguard Worker insert(new MCFillFragment(FillValue, NumBytes));
498*9880d681SAndroid Build Coastguard Worker }
499*9880d681SAndroid Build Coastguard Worker
emitFill(const MCExpr & NumBytes,uint64_t FillValue,SMLoc Loc)500*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
501*9880d681SAndroid Build Coastguard Worker SMLoc Loc) {
502*9880d681SAndroid Build Coastguard Worker MCDataFragment *DF = getOrCreateDataFragment();
503*9880d681SAndroid Build Coastguard Worker flushPendingLabels(DF, DF->getContents().size());
504*9880d681SAndroid Build Coastguard Worker
505*9880d681SAndroid Build Coastguard Worker int64_t IntNumBytes;
506*9880d681SAndroid Build Coastguard Worker if (!NumBytes.evaluateAsAbsolute(IntNumBytes, getAssembler())) {
507*9880d681SAndroid Build Coastguard Worker getContext().reportError(Loc, "expected absolute expression");
508*9880d681SAndroid Build Coastguard Worker return;
509*9880d681SAndroid Build Coastguard Worker }
510*9880d681SAndroid Build Coastguard Worker
511*9880d681SAndroid Build Coastguard Worker if (IntNumBytes <= 0) {
512*9880d681SAndroid Build Coastguard Worker getContext().reportError(Loc, "invalid number of bytes");
513*9880d681SAndroid Build Coastguard Worker return;
514*9880d681SAndroid Build Coastguard Worker }
515*9880d681SAndroid Build Coastguard Worker
516*9880d681SAndroid Build Coastguard Worker emitFill(IntNumBytes, FillValue);
517*9880d681SAndroid Build Coastguard Worker }
518*9880d681SAndroid Build Coastguard Worker
emitFill(const MCExpr & NumValues,int64_t Size,int64_t Expr,SMLoc Loc)519*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
520*9880d681SAndroid Build Coastguard Worker int64_t Expr, SMLoc Loc) {
521*9880d681SAndroid Build Coastguard Worker int64_t IntNumValues;
522*9880d681SAndroid Build Coastguard Worker if (!NumValues.evaluateAsAbsolute(IntNumValues, getAssembler())) {
523*9880d681SAndroid Build Coastguard Worker getContext().reportError(Loc, "expected absolute expression");
524*9880d681SAndroid Build Coastguard Worker return;
525*9880d681SAndroid Build Coastguard Worker }
526*9880d681SAndroid Build Coastguard Worker
527*9880d681SAndroid Build Coastguard Worker if (IntNumValues < 0) {
528*9880d681SAndroid Build Coastguard Worker getContext().getSourceManager()->PrintMessage(
529*9880d681SAndroid Build Coastguard Worker Loc, SourceMgr::DK_Warning,
530*9880d681SAndroid Build Coastguard Worker "'.fill' directive with negative repeat count has no effect");
531*9880d681SAndroid Build Coastguard Worker return;
532*9880d681SAndroid Build Coastguard Worker }
533*9880d681SAndroid Build Coastguard Worker
534*9880d681SAndroid Build Coastguard Worker MCStreamer::emitFill(IntNumValues, Size, Expr);
535*9880d681SAndroid Build Coastguard Worker }
536*9880d681SAndroid Build Coastguard Worker
FinishImpl()537*9880d681SAndroid Build Coastguard Worker void MCObjectStreamer::FinishImpl() {
538*9880d681SAndroid Build Coastguard Worker // If we are generating dwarf for assembly source files dump out the sections.
539*9880d681SAndroid Build Coastguard Worker if (getContext().getGenDwarfForAssembly())
540*9880d681SAndroid Build Coastguard Worker MCGenDwarfInfo::Emit(this);
541*9880d681SAndroid Build Coastguard Worker
542*9880d681SAndroid Build Coastguard Worker // Dump out the dwarf file & directory tables and line tables.
543*9880d681SAndroid Build Coastguard Worker MCDwarfLineTable::Emit(this, getAssembler().getDWARFLinetableParams());
544*9880d681SAndroid Build Coastguard Worker
545*9880d681SAndroid Build Coastguard Worker flushPendingLabels(nullptr);
546*9880d681SAndroid Build Coastguard Worker getAssembler().Finish();
547*9880d681SAndroid Build Coastguard Worker }
548