[RISCV] Refactor predicates for rvv intrinsic patterns.
[llvm-project.git] / llvm / lib / MC / MCObjectStreamer.cpp
blob4c79df014a6c1ed5acfb49108fe9be2d63a30eff
1 //===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/MC/MCObjectStreamer.h"
10 #include "llvm/MC/MCAsmBackend.h"
11 #include "llvm/MC/MCAsmInfo.h"
12 #include "llvm/MC/MCAssembler.h"
13 #include "llvm/MC/MCCodeEmitter.h"
14 #include "llvm/MC/MCCodeView.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCDwarf.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCObjectFileInfo.h"
19 #include "llvm/MC/MCObjectWriter.h"
20 #include "llvm/MC/MCSection.h"
21 #include "llvm/MC/MCSymbol.h"
22 #include "llvm/MC/MCValue.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/SourceMgr.h"
25 using namespace llvm;
27 MCObjectStreamer::MCObjectStreamer(MCContext &Context,
28 std::unique_ptr<MCAsmBackend> TAB,
29 std::unique_ptr<MCObjectWriter> OW,
30 std::unique_ptr<MCCodeEmitter> Emitter)
31 : MCStreamer(Context),
32 Assembler(std::make_unique<MCAssembler>(
33 Context, std::move(TAB), std::move(Emitter), std::move(OW))),
34 EmitEHFrame(true), EmitDebugFrame(false) {
35 if (Assembler->getBackendPtr())
36 setAllowAutoPadding(Assembler->getBackend().allowAutoPadding());
39 MCObjectStreamer::~MCObjectStreamer() = default;
41 // AssemblerPtr is used for evaluation of expressions and causes
42 // difference between asm and object outputs. Return nullptr to in
43 // inline asm mode to limit divergence to assembly inputs.
44 MCAssembler *MCObjectStreamer::getAssemblerPtr() {
45 if (getUseAssemblerInfoForParsing())
46 return Assembler.get();
47 return nullptr;
50 void MCObjectStreamer::addPendingLabel(MCSymbol* S) {
51 MCSection *CurSection = getCurrentSectionOnly();
52 if (CurSection) {
53 // Register labels that have not yet been assigned to a Section.
54 if (!PendingLabels.empty()) {
55 for (MCSymbol* Sym : PendingLabels)
56 CurSection->addPendingLabel(Sym);
57 PendingLabels.clear();
60 // Add this label to the current Section / Subsection.
61 CurSection->addPendingLabel(S, CurSubsectionIdx);
63 // Add this Section to the list of PendingLabelSections.
64 PendingLabelSections.insert(CurSection);
65 } else
66 // There is no Section / Subsection for this label yet.
67 PendingLabels.push_back(S);
70 void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
71 MCSection *CurSection = getCurrentSectionOnly();
72 if (!CurSection) {
73 assert(PendingLabels.empty());
74 return;
76 // Register labels that have not yet been assigned to a Section.
77 if (!PendingLabels.empty()) {
78 for (MCSymbol* Sym : PendingLabels)
79 CurSection->addPendingLabel(Sym, CurSubsectionIdx);
80 PendingLabels.clear();
83 // Associate a fragment with this label, either the supplied fragment
84 // or an empty data fragment.
85 if (F)
86 CurSection->flushPendingLabels(F, FOffset, CurSubsectionIdx);
87 else
88 CurSection->flushPendingLabels(nullptr, 0, CurSubsectionIdx);
91 void MCObjectStreamer::flushPendingLabels() {
92 // Register labels that have not yet been assigned to a Section.
93 if (!PendingLabels.empty()) {
94 MCSection *CurSection = getCurrentSectionOnly();
95 assert(CurSection);
96 for (MCSymbol* Sym : PendingLabels)
97 CurSection->addPendingLabel(Sym, CurSubsectionIdx);
98 PendingLabels.clear();
101 // Assign an empty data fragment to all remaining pending labels.
102 for (MCSection* Section : PendingLabelSections)
103 Section->flushPendingLabels();
106 // When fixup's offset is a forward declared label, e.g.:
108 // .reloc 1f, R_MIPS_JALR, foo
109 // 1: nop
111 // postpone adding it to Fixups vector until the label is defined and its offset
112 // is known.
113 void MCObjectStreamer::resolvePendingFixups() {
114 for (PendingMCFixup &PendingFixup : PendingFixups) {
115 if (!PendingFixup.Sym || PendingFixup.Sym->isUndefined ()) {
116 getContext().reportError(PendingFixup.Fixup.getLoc(),
117 "unresolved relocation offset");
118 continue;
120 flushPendingLabels(PendingFixup.DF, PendingFixup.DF->getContents().size());
121 PendingFixup.Fixup.setOffset(PendingFixup.Sym->getOffset() +
122 PendingFixup.Fixup.getOffset());
124 // If the location symbol to relocate is in MCEncodedFragmentWithFixups,
125 // put the Fixup into location symbol's fragment. Otherwise
126 // put into PendingFixup.DF
127 MCFragment *SymFragment = PendingFixup.Sym->getFragment();
128 switch (SymFragment->getKind()) {
129 case MCFragment::FT_Relaxable:
130 case MCFragment::FT_Dwarf:
131 case MCFragment::FT_PseudoProbe:
132 cast<MCEncodedFragmentWithFixups<8, 1>>(SymFragment)
133 ->getFixups()
134 .push_back(PendingFixup.Fixup);
135 break;
136 case MCFragment::FT_Data:
137 case MCFragment::FT_CVDefRange:
138 cast<MCEncodedFragmentWithFixups<32, 4>>(SymFragment)
139 ->getFixups()
140 .push_back(PendingFixup.Fixup);
141 break;
142 default:
143 PendingFixup.DF->getFixups().push_back(PendingFixup.Fixup);
144 break;
147 PendingFixups.clear();
150 // As a compile-time optimization, avoid allocating and evaluating an MCExpr
151 // tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment.
152 static std::optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
153 const MCSymbol *Lo) {
154 assert(Hi && Lo);
155 if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
156 Hi->isVariable() || Lo->isVariable())
157 return std::nullopt;
159 return Hi->getOffset() - Lo->getOffset();
162 void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
163 const MCSymbol *Lo,
164 unsigned Size) {
165 if (!getAssembler().getContext().getTargetTriple().isRISCV())
166 if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo))
167 return emitIntValue(*Diff, Size);
168 MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
171 void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
172 const MCSymbol *Lo) {
173 if (!getAssembler().getContext().getTargetTriple().isRISCV())
174 if (std::optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) {
175 emitULEB128IntValue(*Diff);
176 return;
178 MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo);
181 void MCObjectStreamer::reset() {
182 if (Assembler)
183 Assembler->reset();
184 CurInsertionPoint = MCSection::iterator();
185 EmitEHFrame = true;
186 EmitDebugFrame = false;
187 PendingLabels.clear();
188 PendingLabelSections.clear();
189 MCStreamer::reset();
192 void MCObjectStreamer::emitFrames(MCAsmBackend *MAB) {
193 if (!getNumFrameInfos())
194 return;
196 if (EmitEHFrame)
197 MCDwarfFrameEmitter::Emit(*this, MAB, true);
199 if (EmitDebugFrame)
200 MCDwarfFrameEmitter::Emit(*this, MAB, false);
203 MCFragment *MCObjectStreamer::getCurrentFragment() const {
204 assert(getCurrentSectionOnly() && "No current section!");
206 if (CurInsertionPoint != getCurrentSectionOnly()->getFragmentList().begin())
207 return &*std::prev(CurInsertionPoint);
209 return nullptr;
212 static bool canReuseDataFragment(const MCDataFragment &F,
213 const MCAssembler &Assembler,
214 const MCSubtargetInfo *STI) {
215 if (!F.hasInstructions())
216 return true;
217 // When bundling is enabled, we don't want to add data to a fragment that
218 // already has instructions (see MCELFStreamer::emitInstToData for details)
219 if (Assembler.isBundlingEnabled())
220 return Assembler.getRelaxAll();
221 // If the subtarget is changed mid fragment we start a new fragment to record
222 // the new STI.
223 return !STI || F.getSubtargetInfo() == STI;
226 MCDataFragment *
227 MCObjectStreamer::getOrCreateDataFragment(const MCSubtargetInfo *STI) {
228 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
229 if (!F || !canReuseDataFragment(*F, *Assembler, STI)) {
230 F = new MCDataFragment();
231 insert(F);
233 return F;
236 void MCObjectStreamer::visitUsedSymbol(const MCSymbol &Sym) {
237 Assembler->registerSymbol(Sym);
240 void MCObjectStreamer::emitCFISections(bool EH, bool Debug) {
241 MCStreamer::emitCFISections(EH, Debug);
242 EmitEHFrame = EH;
243 EmitDebugFrame = Debug;
246 void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
247 SMLoc Loc) {
248 MCStreamer::emitValueImpl(Value, Size, Loc);
249 MCDataFragment *DF = getOrCreateDataFragment();
250 flushPendingLabels(DF, DF->getContents().size());
252 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
254 // Avoid fixups when possible.
255 int64_t AbsValue;
256 if (Value->evaluateAsAbsolute(AbsValue, getAssemblerPtr())) {
257 if (!isUIntN(8 * Size, AbsValue) && !isIntN(8 * Size, AbsValue)) {
258 getContext().reportError(
259 Loc, "value evaluated as " + Twine(AbsValue) + " is out of range.");
260 return;
262 emitIntValue(AbsValue, Size);
263 return;
265 DF->getFixups().push_back(
266 MCFixup::create(DF->getContents().size(), Value,
267 MCFixup::getKindForSize(Size, false), Loc));
268 DF->getContents().resize(DF->getContents().size() + Size, 0);
271 MCSymbol *MCObjectStreamer::emitCFILabel() {
272 MCSymbol *Label = getContext().createTempSymbol("cfi");
273 emitLabel(Label);
274 return Label;
277 void MCObjectStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
278 // We need to create a local symbol to avoid relocations.
279 Frame.Begin = getContext().createTempSymbol();
280 emitLabel(Frame.Begin);
283 void MCObjectStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
284 Frame.End = getContext().createTempSymbol();
285 emitLabel(Frame.End);
288 void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
289 MCStreamer::emitLabel(Symbol, Loc);
291 getAssembler().registerSymbol(*Symbol);
293 // If there is a current fragment, mark the symbol as pointing into it.
294 // Otherwise queue the label and set its fragment pointer when we emit the
295 // next fragment.
296 auto *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
297 if (F && !(getAssembler().isBundlingEnabled() &&
298 getAssembler().getRelaxAll())) {
299 Symbol->setFragment(F);
300 Symbol->setOffset(F->getContents().size());
301 } else {
302 // Assign all pending labels to offset 0 within the dummy "pending"
303 // fragment. (They will all be reassigned to a real fragment in
304 // flushPendingLabels())
305 Symbol->setOffset(0);
306 addPendingLabel(Symbol);
309 emitPendingAssignments(Symbol);
312 void MCObjectStreamer::emitPendingAssignments(MCSymbol *Symbol) {
313 auto Assignments = pendingAssignments.find(Symbol);
314 if (Assignments != pendingAssignments.end()) {
315 for (const PendingAssignment &A : Assignments->second)
316 emitAssignment(A.Symbol, A.Value);
318 pendingAssignments.erase(Assignments);
322 // Emit a label at a previously emitted fragment/offset position. This must be
323 // within the currently-active section.
324 void MCObjectStreamer::emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc,
325 MCFragment *F, uint64_t Offset) {
326 assert(F->getParent() == getCurrentSectionOnly());
328 MCStreamer::emitLabel(Symbol, Loc);
329 getAssembler().registerSymbol(*Symbol);
330 auto *DF = dyn_cast_or_null<MCDataFragment>(F);
331 Symbol->setOffset(Offset);
332 if (DF) {
333 Symbol->setFragment(F);
334 } else {
335 assert(isa<MCDummyFragment>(F) &&
336 "F must either be an MCDataFragment or the pending MCDummyFragment");
337 assert(Offset == 0);
338 addPendingLabel(Symbol);
342 void MCObjectStreamer::emitULEB128Value(const MCExpr *Value) {
343 int64_t IntValue;
344 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
345 emitULEB128IntValue(IntValue);
346 return;
348 insert(new MCLEBFragment(*Value, false));
351 void MCObjectStreamer::emitSLEB128Value(const MCExpr *Value) {
352 int64_t IntValue;
353 if (Value->evaluateAsAbsolute(IntValue, getAssemblerPtr())) {
354 emitSLEB128IntValue(IntValue);
355 return;
357 insert(new MCLEBFragment(*Value, true));
360 void MCObjectStreamer::emitWeakReference(MCSymbol *Alias,
361 const MCSymbol *Symbol) {
362 report_fatal_error("This file format doesn't support weak aliases.");
365 void MCObjectStreamer::changeSection(MCSection *Section,
366 const MCExpr *Subsection) {
367 changeSectionImpl(Section, Subsection);
370 bool MCObjectStreamer::changeSectionImpl(MCSection *Section,
371 const MCExpr *Subsection) {
372 assert(Section && "Cannot switch to a null section!");
373 getContext().clearDwarfLocSeen();
375 bool Created = getAssembler().registerSection(*Section);
377 int64_t IntSubsection = 0;
378 if (Subsection &&
379 !Subsection->evaluateAsAbsolute(IntSubsection, getAssemblerPtr()))
380 report_fatal_error("Cannot evaluate subsection number");
381 if (IntSubsection < 0 || IntSubsection > 8192)
382 report_fatal_error("Subsection number out of range");
383 CurSubsectionIdx = unsigned(IntSubsection);
384 CurInsertionPoint =
385 Section->getSubsectionInsertionPoint(CurSubsectionIdx);
386 return Created;
389 void MCObjectStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
390 getAssembler().registerSymbol(*Symbol);
391 MCStreamer::emitAssignment(Symbol, Value);
392 emitPendingAssignments(Symbol);
395 void MCObjectStreamer::emitConditionalAssignment(MCSymbol *Symbol,
396 const MCExpr *Value) {
397 const MCSymbol *Target = &cast<MCSymbolRefExpr>(*Value).getSymbol();
399 // If the symbol already exists, emit the assignment. Otherwise, emit it
400 // later only if the symbol is also emitted.
401 if (Target->isRegistered())
402 emitAssignment(Symbol, Value);
403 else
404 pendingAssignments[Target].push_back({Symbol, Value});
407 bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
408 return Sec.hasInstructions();
411 void MCObjectStreamer::emitInstruction(const MCInst &Inst,
412 const MCSubtargetInfo &STI) {
413 const MCSection &Sec = *getCurrentSectionOnly();
414 if (Sec.isVirtualSection()) {
415 getContext().reportError(Inst.getLoc(), Twine(Sec.getVirtualSectionKind()) +
416 " section '" + Sec.getName() +
417 "' cannot have instructions");
418 return;
420 getAssembler().getBackend().emitInstructionBegin(*this, Inst, STI);
421 emitInstructionImpl(Inst, STI);
422 getAssembler().getBackend().emitInstructionEnd(*this, Inst);
425 void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst,
426 const MCSubtargetInfo &STI) {
427 MCStreamer::emitInstruction(Inst, STI);
429 MCSection *Sec = getCurrentSectionOnly();
430 Sec->setHasInstructions(true);
432 // Now that a machine instruction has been assembled into this section, make
433 // a line entry for any .loc directive that has been seen.
434 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
436 // If this instruction doesn't need relaxation, just emit it as data.
437 MCAssembler &Assembler = getAssembler();
438 MCAsmBackend &Backend = Assembler.getBackend();
439 if (!(Backend.mayNeedRelaxation(Inst, STI) ||
440 Backend.allowEnhancedRelaxation())) {
441 emitInstToData(Inst, STI);
442 return;
445 // Otherwise, relax and emit it as data if either:
446 // - The RelaxAll flag was passed
447 // - Bundling is enabled and this instruction is inside a bundle-locked
448 // group. We want to emit all such instructions into the same data
449 // fragment.
450 if (Assembler.getRelaxAll() ||
451 (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
452 MCInst Relaxed = Inst;
453 while (Backend.mayNeedRelaxation(Relaxed, STI))
454 Backend.relaxInstruction(Relaxed, STI);
455 emitInstToData(Relaxed, STI);
456 return;
459 // Otherwise emit to a separate fragment.
460 emitInstToFragment(Inst, STI);
463 void MCObjectStreamer::emitInstToFragment(const MCInst &Inst,
464 const MCSubtargetInfo &STI) {
465 if (getAssembler().getRelaxAll() && getAssembler().isBundlingEnabled())
466 llvm_unreachable("All instructions should have already been relaxed");
468 // Always create a new, separate fragment here, because its size can change
469 // during relaxation.
470 MCRelaxableFragment *IF = new MCRelaxableFragment(Inst, STI);
471 insert(IF);
473 SmallString<128> Code;
474 getAssembler().getEmitter().encodeInstruction(Inst, Code, IF->getFixups(),
475 STI);
476 IF->getContents().append(Code.begin(), Code.end());
479 #ifndef NDEBUG
480 static const char *const BundlingNotImplementedMsg =
481 "Aligned bundling is not implemented for this object format";
482 #endif
484 void MCObjectStreamer::emitBundleAlignMode(Align Alignment) {
485 llvm_unreachable(BundlingNotImplementedMsg);
488 void MCObjectStreamer::emitBundleLock(bool AlignToEnd) {
489 llvm_unreachable(BundlingNotImplementedMsg);
492 void MCObjectStreamer::emitBundleUnlock() {
493 llvm_unreachable(BundlingNotImplementedMsg);
496 void MCObjectStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
497 unsigned Column, unsigned Flags,
498 unsigned Isa,
499 unsigned Discriminator,
500 StringRef FileName) {
501 // In case we see two .loc directives in a row, make sure the
502 // first one gets a line entry.
503 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
505 this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
506 Discriminator, FileName);
509 static const MCExpr *buildSymbolDiff(MCObjectStreamer &OS, const MCSymbol *A,
510 const MCSymbol *B) {
511 MCContext &Context = OS.getContext();
512 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
513 const MCExpr *ARef = MCSymbolRefExpr::create(A, Variant, Context);
514 const MCExpr *BRef = MCSymbolRefExpr::create(B, Variant, Context);
515 const MCExpr *AddrDelta =
516 MCBinaryExpr::create(MCBinaryExpr::Sub, ARef, BRef, Context);
517 return AddrDelta;
520 static void emitDwarfSetLineAddr(MCObjectStreamer &OS,
521 MCDwarfLineTableParams Params,
522 int64_t LineDelta, const MCSymbol *Label,
523 int PointerSize) {
524 // emit the sequence to set the address
525 OS.emitIntValue(dwarf::DW_LNS_extended_op, 1);
526 OS.emitULEB128IntValue(PointerSize + 1);
527 OS.emitIntValue(dwarf::DW_LNE_set_address, 1);
528 OS.emitSymbolValue(Label, PointerSize);
530 // emit the sequence for the LineDelta (from 1) and a zero address delta.
531 MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
534 void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
535 const MCSymbol *LastLabel,
536 const MCSymbol *Label,
537 unsigned PointerSize) {
538 if (!LastLabel) {
539 emitDwarfSetLineAddr(*this, Assembler->getDWARFLinetableParams(), LineDelta,
540 Label, PointerSize);
541 return;
543 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
544 insert(new MCDwarfLineAddrFragment(LineDelta, *AddrDelta));
547 void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section,
548 MCSymbol *LastLabel) {
549 // Emit a DW_LNE_end_sequence for the end of the section.
550 // Use the section end label to compute the address delta and use INT64_MAX
551 // as the line delta which is the signal that this is actually a
552 // DW_LNE_end_sequence.
553 MCSymbol *SectionEnd = endSection(Section);
555 // Switch back the dwarf line section, in case endSection had to switch the
556 // section.
557 MCContext &Ctx = getContext();
558 switchSection(Ctx.getObjectFileInfo()->getDwarfLineSection());
560 const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
561 emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
562 AsmInfo->getCodePointerSize());
565 void MCObjectStreamer::emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
566 const MCSymbol *Label) {
567 const MCExpr *AddrDelta = buildSymbolDiff(*this, Label, LastLabel);
568 insert(new MCDwarfCallFrameFragment(*AddrDelta));
571 void MCObjectStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
572 unsigned Line, unsigned Column,
573 bool PrologueEnd, bool IsStmt,
574 StringRef FileName, SMLoc Loc) {
575 // Validate the directive.
576 if (!checkCVLocSection(FunctionId, FileNo, Loc))
577 return;
579 // Emit a label at the current position and record it in the CodeViewContext.
580 MCSymbol *LineSym = getContext().createTempSymbol();
581 emitLabel(LineSym);
582 getContext().getCVContext().recordCVLoc(getContext(), LineSym, FunctionId,
583 FileNo, Line, Column, PrologueEnd,
584 IsStmt);
587 void MCObjectStreamer::emitCVLinetableDirective(unsigned FunctionId,
588 const MCSymbol *Begin,
589 const MCSymbol *End) {
590 getContext().getCVContext().emitLineTableForFunction(*this, FunctionId, Begin,
591 End);
592 this->MCStreamer::emitCVLinetableDirective(FunctionId, Begin, End);
595 void MCObjectStreamer::emitCVInlineLinetableDirective(
596 unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum,
597 const MCSymbol *FnStartSym, const MCSymbol *FnEndSym) {
598 getContext().getCVContext().emitInlineLineTableForFunction(
599 *this, PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym,
600 FnEndSym);
601 this->MCStreamer::emitCVInlineLinetableDirective(
602 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
605 void MCObjectStreamer::emitCVDefRangeDirective(
606 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
607 StringRef FixedSizePortion) {
608 MCFragment *Frag =
609 getContext().getCVContext().emitDefRange(*this, Ranges, FixedSizePortion);
610 // Attach labels that were pending before we created the defrange fragment to
611 // the beginning of the new fragment.
612 flushPendingLabels(Frag, 0);
613 this->MCStreamer::emitCVDefRangeDirective(Ranges, FixedSizePortion);
616 void MCObjectStreamer::emitCVStringTableDirective() {
617 getContext().getCVContext().emitStringTable(*this);
619 void MCObjectStreamer::emitCVFileChecksumsDirective() {
620 getContext().getCVContext().emitFileChecksums(*this);
623 void MCObjectStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) {
624 getContext().getCVContext().emitFileChecksumOffset(*this, FileNo);
627 void MCObjectStreamer::emitBytes(StringRef Data) {
628 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
629 MCDataFragment *DF = getOrCreateDataFragment();
630 flushPendingLabels(DF, DF->getContents().size());
631 DF->getContents().append(Data.begin(), Data.end());
634 void MCObjectStreamer::emitValueToAlignment(Align Alignment, int64_t Value,
635 unsigned ValueSize,
636 unsigned MaxBytesToEmit) {
637 if (MaxBytesToEmit == 0)
638 MaxBytesToEmit = Alignment.value();
639 insert(new MCAlignFragment(Alignment, Value, ValueSize, MaxBytesToEmit));
641 // Update the maximum alignment on the current section if necessary.
642 MCSection *CurSec = getCurrentSectionOnly();
643 CurSec->ensureMinAlignment(Alignment);
646 void MCObjectStreamer::emitCodeAlignment(Align Alignment,
647 const MCSubtargetInfo *STI,
648 unsigned MaxBytesToEmit) {
649 emitValueToAlignment(Alignment, 0, 1, MaxBytesToEmit);
650 cast<MCAlignFragment>(getCurrentFragment())->setEmitNops(true, STI);
653 void MCObjectStreamer::emitValueToOffset(const MCExpr *Offset,
654 unsigned char Value,
655 SMLoc Loc) {
656 insert(new MCOrgFragment(*Offset, Value, Loc));
659 // Associate DTPRel32 fixup with data and resize data area
660 void MCObjectStreamer::emitDTPRel32Value(const MCExpr *Value) {
661 MCDataFragment *DF = getOrCreateDataFragment();
662 flushPendingLabels(DF, DF->getContents().size());
664 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
665 Value, FK_DTPRel_4));
666 DF->getContents().resize(DF->getContents().size() + 4, 0);
669 // Associate DTPRel64 fixup with data and resize data area
670 void MCObjectStreamer::emitDTPRel64Value(const MCExpr *Value) {
671 MCDataFragment *DF = getOrCreateDataFragment();
672 flushPendingLabels(DF, DF->getContents().size());
674 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
675 Value, FK_DTPRel_8));
676 DF->getContents().resize(DF->getContents().size() + 8, 0);
679 // Associate TPRel32 fixup with data and resize data area
680 void MCObjectStreamer::emitTPRel32Value(const MCExpr *Value) {
681 MCDataFragment *DF = getOrCreateDataFragment();
682 flushPendingLabels(DF, DF->getContents().size());
684 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
685 Value, FK_TPRel_4));
686 DF->getContents().resize(DF->getContents().size() + 4, 0);
689 // Associate TPRel64 fixup with data and resize data area
690 void MCObjectStreamer::emitTPRel64Value(const MCExpr *Value) {
691 MCDataFragment *DF = getOrCreateDataFragment();
692 flushPendingLabels(DF, DF->getContents().size());
694 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
695 Value, FK_TPRel_8));
696 DF->getContents().resize(DF->getContents().size() + 8, 0);
699 // Associate GPRel32 fixup with data and resize data area
700 void MCObjectStreamer::emitGPRel32Value(const MCExpr *Value) {
701 MCDataFragment *DF = getOrCreateDataFragment();
702 flushPendingLabels(DF, DF->getContents().size());
704 DF->getFixups().push_back(
705 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
706 DF->getContents().resize(DF->getContents().size() + 4, 0);
709 // Associate GPRel64 fixup with data and resize data area
710 void MCObjectStreamer::emitGPRel64Value(const MCExpr *Value) {
711 MCDataFragment *DF = getOrCreateDataFragment();
712 flushPendingLabels(DF, DF->getContents().size());
714 DF->getFixups().push_back(
715 MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4));
716 DF->getContents().resize(DF->getContents().size() + 8, 0);
719 static std::optional<std::pair<bool, std::string>>
720 getOffsetAndDataFragment(const MCSymbol &Symbol, uint32_t &RelocOffset,
721 MCDataFragment *&DF) {
722 if (Symbol.isVariable()) {
723 const MCExpr *SymbolExpr = Symbol.getVariableValue();
724 MCValue OffsetVal;
725 if(!SymbolExpr->evaluateAsRelocatable(OffsetVal, nullptr, nullptr))
726 return std::make_pair(false,
727 std::string("symbol in .reloc offset is not "
728 "relocatable"));
729 if (OffsetVal.isAbsolute()) {
730 RelocOffset = OffsetVal.getConstant();
731 MCFragment *Fragment = Symbol.getFragment();
732 // FIXME Support symbols with no DF. For example:
733 // .reloc .data, ENUM_VALUE, <some expr>
734 if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
735 return std::make_pair(false,
736 std::string("symbol in offset has no data "
737 "fragment"));
738 DF = cast<MCDataFragment>(Fragment);
739 return std::nullopt;
742 if (OffsetVal.getSymB())
743 return std::make_pair(false,
744 std::string(".reloc symbol offset is not "
745 "representable"));
747 const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*OffsetVal.getSymA());
748 if (!SRE.getSymbol().isDefined())
749 return std::make_pair(false,
750 std::string("symbol used in the .reloc offset is "
751 "not defined"));
753 if (SRE.getSymbol().isVariable())
754 return std::make_pair(false,
755 std::string("symbol used in the .reloc offset is "
756 "variable"));
758 MCFragment *Fragment = SRE.getSymbol().getFragment();
759 // FIXME Support symbols with no DF. For example:
760 // .reloc .data, ENUM_VALUE, <some expr>
761 if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
762 return std::make_pair(false,
763 std::string("symbol in offset has no data "
764 "fragment"));
765 RelocOffset = SRE.getSymbol().getOffset() + OffsetVal.getConstant();
766 DF = cast<MCDataFragment>(Fragment);
767 } else {
768 RelocOffset = Symbol.getOffset();
769 MCFragment *Fragment = Symbol.getFragment();
770 // FIXME Support symbols with no DF. For example:
771 // .reloc .data, ENUM_VALUE, <some expr>
772 if (!Fragment || Fragment->getKind() != MCFragment::FT_Data)
773 return std::make_pair(false,
774 std::string("symbol in offset has no data "
775 "fragment"));
776 DF = cast<MCDataFragment>(Fragment);
778 return std::nullopt;
781 std::optional<std::pair<bool, std::string>>
782 MCObjectStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,
783 const MCExpr *Expr, SMLoc Loc,
784 const MCSubtargetInfo &STI) {
785 std::optional<MCFixupKind> MaybeKind =
786 Assembler->getBackend().getFixupKind(Name);
787 if (!MaybeKind)
788 return std::make_pair(true, std::string("unknown relocation name"));
790 MCFixupKind Kind = *MaybeKind;
792 if (Expr == nullptr)
793 Expr =
794 MCSymbolRefExpr::create(getContext().createTempSymbol(), getContext());
796 MCDataFragment *DF = getOrCreateDataFragment(&STI);
797 flushPendingLabels(DF, DF->getContents().size());
799 MCValue OffsetVal;
800 if (!Offset.evaluateAsRelocatable(OffsetVal, nullptr, nullptr))
801 return std::make_pair(false,
802 std::string(".reloc offset is not relocatable"));
803 if (OffsetVal.isAbsolute()) {
804 if (OffsetVal.getConstant() < 0)
805 return std::make_pair(false, std::string(".reloc offset is negative"));
806 DF->getFixups().push_back(
807 MCFixup::create(OffsetVal.getConstant(), Expr, Kind, Loc));
808 return std::nullopt;
810 if (OffsetVal.getSymB())
811 return std::make_pair(false,
812 std::string(".reloc offset is not representable"));
814 const MCSymbolRefExpr &SRE = cast<MCSymbolRefExpr>(*OffsetVal.getSymA());
815 const MCSymbol &Symbol = SRE.getSymbol();
816 if (Symbol.isDefined()) {
817 uint32_t SymbolOffset = 0;
818 std::optional<std::pair<bool, std::string>> Error =
819 getOffsetAndDataFragment(Symbol, SymbolOffset, DF);
821 if (Error != std::nullopt)
822 return Error;
824 DF->getFixups().push_back(
825 MCFixup::create(SymbolOffset + OffsetVal.getConstant(),
826 Expr, Kind, Loc));
827 return std::nullopt;
830 PendingFixups.emplace_back(
831 &SRE.getSymbol(), DF,
832 MCFixup::create(OffsetVal.getConstant(), Expr, Kind, Loc));
833 return std::nullopt;
836 void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
837 SMLoc Loc) {
838 MCDataFragment *DF = getOrCreateDataFragment();
839 flushPendingLabels(DF, DF->getContents().size());
841 assert(getCurrentSectionOnly() && "need a section");
842 insert(new MCFillFragment(FillValue, 1, NumBytes, Loc));
845 void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
846 int64_t Expr, SMLoc Loc) {
847 int64_t IntNumValues;
848 // Do additional checking now if we can resolve the value.
849 if (NumValues.evaluateAsAbsolute(IntNumValues, getAssemblerPtr())) {
850 if (IntNumValues < 0) {
851 getContext().getSourceManager()->PrintMessage(
852 Loc, SourceMgr::DK_Warning,
853 "'.fill' directive with negative repeat count has no effect");
854 return;
856 // Emit now if we can for better errors.
857 int64_t NonZeroSize = Size > 4 ? 4 : Size;
858 Expr &= ~0ULL >> (64 - NonZeroSize * 8);
859 for (uint64_t i = 0, e = IntNumValues; i != e; ++i) {
860 emitIntValue(Expr, NonZeroSize);
861 if (NonZeroSize < Size)
862 emitIntValue(0, Size - NonZeroSize);
864 return;
867 // Otherwise emit as fragment.
868 MCDataFragment *DF = getOrCreateDataFragment();
869 flushPendingLabels(DF, DF->getContents().size());
871 assert(getCurrentSectionOnly() && "need a section");
872 insert(new MCFillFragment(Expr, Size, NumValues, Loc));
875 void MCObjectStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLength,
876 SMLoc Loc, const MCSubtargetInfo &STI) {
877 // Emit an NOP fragment.
878 MCDataFragment *DF = getOrCreateDataFragment();
879 flushPendingLabels(DF, DF->getContents().size());
881 assert(getCurrentSectionOnly() && "need a section");
883 insert(new MCNopsFragment(NumBytes, ControlledNopLength, Loc, STI));
886 void MCObjectStreamer::emitFileDirective(StringRef Filename) {
887 getAssembler().addFileName(Filename);
890 void MCObjectStreamer::emitFileDirective(StringRef Filename,
891 StringRef CompilerVerion,
892 StringRef TimeStamp,
893 StringRef Description) {
894 getAssembler().addFileName(Filename);
895 // TODO: add additional info to integrated assembler.
898 void MCObjectStreamer::emitAddrsig() {
899 getAssembler().getWriter().emitAddrsigSection();
902 void MCObjectStreamer::emitAddrsigSym(const MCSymbol *Sym) {
903 getAssembler().getWriter().addAddrsigSymbol(Sym);
906 void MCObjectStreamer::finishImpl() {
907 getContext().RemapDebugPaths();
909 // If we are generating dwarf for assembly source files dump out the sections.
910 if (getContext().getGenDwarfForAssembly())
911 MCGenDwarfInfo::Emit(this);
913 // Dump out the dwarf file & directory tables and line tables.
914 MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams());
916 // Emit pseudo probes for the current module.
917 MCPseudoProbeTable::emit(this);
919 // Update any remaining pending labels with empty data fragments.
920 flushPendingLabels();
922 resolvePendingFixups();
923 getAssembler().Finish();