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