1//===- lib/MC/MCGOFFStreamer.cpp - GOFF Object Output ---------------------===//
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//===----------------------------------------------------------------------===//
8//
9// This file assembles .s files and emits GOFF .o object files.
10//
11//===----------------------------------------------------------------------===//
12
13#include "llvm/MC/MCGOFFStreamer.h"
14#include "llvm/MC/MCAsmBackend.h"
15#include "llvm/MC/MCAssembler.h"
16#include "llvm/MC/MCCodeEmitter.h"
17#include "llvm/MC/MCContext.h"
18#include "llvm/MC/MCDirectives.h"
19#include "llvm/MC/MCGOFFObjectWriter.h"
20#include "llvm/MC/MCObjectStreamer.h"
21#include "llvm/MC/MCSymbolGOFF.h"
22#include "llvm/MC/TargetRegistry.h"
23
24using namespace llvm;
25
26MCGOFFStreamer::MCGOFFStreamer(MCContext &Context,
27 std::unique_ptr<MCAsmBackend> MAB,
28 std::unique_ptr<MCObjectWriter> OW,
29 std::unique_ptr<MCCodeEmitter> Emitter)
30 : MCObjectStreamer(Context, std::move(MAB), std::move(OW),
31 std::move(Emitter)) {}
32
33MCGOFFStreamer::~MCGOFFStreamer() = default;
34
35void MCGOFFStreamer::finishImpl() {
36 getWriter().setRootSD(static_cast<MCSectionGOFF *>(
37 getContext().getObjectFileInfo()->getTextSection())
38 ->getParent());
39 MCObjectStreamer::finishImpl();
40}
41
42GOFFObjectWriter &MCGOFFStreamer::getWriter() {
43 return static_cast<GOFFObjectWriter &>(getAssembler().getWriter());
44}
45
46void MCGOFFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
47 // Make sure that all section are registered in the correct order.
48 SmallVector<MCSectionGOFF *> Sections;
49 for (auto *S = static_cast<MCSectionGOFF *>(Section); S; S = S->getParent())
50 Sections.push_back(Elt: S);
51 while (!Sections.empty()) {
52 auto *S = Sections.pop_back_val();
53 MCObjectStreamer::changeSection(Section: S, Subsection: Sections.empty() ? Subsection : 0);
54 }
55}
56
57void MCGOFFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
58 MCSectionGOFF *Section =
59 static_cast<MCSectionGOFF *>(getCurrentSectionOnly());
60 if (Section->isPR()) {
61 if (Section->getBeginSymbol() == nullptr)
62 Section->setBeginSymbol(Symbol);
63 else
64 getContext().reportError(
65 L: Loc, Msg: "only one symbol can be defined in a PR section.");
66 }
67 MCObjectStreamer::emitLabel(Symbol, Loc);
68}
69
70bool MCGOFFStreamer::emitSymbolAttribute(MCSymbol *Sym,
71 MCSymbolAttr Attribute) {
72 return static_cast<MCSymbolGOFF *>(Sym)->setSymbolAttribute(Attribute);
73}
74
75void MCGOFFStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size,
76 Align ByteAlignment) {
77 auto *Symbol = static_cast<MCSymbolGOFF *>(S);
78 MCSectionGOFF *Section =
79 Symbol->getSectionForCommonSymbol(Ctx&: getContext(), ByteAlignment);
80 pushSection();
81 switchSection(Section);
82 emitLabel(Symbol);
83 emitZeros(NumBytes: Size);
84 popSection();
85}
86
87MCStreamer *llvm::createGOFFStreamer(MCContext &Context,
88 std::unique_ptr<MCAsmBackend> &&MAB,
89 std::unique_ptr<MCObjectWriter> &&OW,
90 std::unique_ptr<MCCodeEmitter> &&CE) {
91 MCGOFFStreamer *S =
92 new MCGOFFStreamer(Context, std::move(MAB), std::move(OW), std::move(CE));
93 return S;
94}
95