1//===-------- MipsELFStreamer.cpp - ELF 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#include "MipsELFStreamer.h"
10#include "MipsOptionRecord.h"
11#include "MipsTargetStreamer.h"
12#include "llvm/BinaryFormat/ELF.h"
13#include "llvm/MC/MCAsmBackend.h"
14#include "llvm/MC/MCAssembler.h"
15#include "llvm/MC/MCCodeEmitter.h"
16#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCDwarf.h"
18#include "llvm/MC/MCInst.h"
19#include "llvm/MC/MCObjectWriter.h"
20#include "llvm/MC/MCSymbolELF.h"
21
22using namespace llvm;
23
24MipsELFStreamer::MipsELFStreamer(MCContext &Context,
25 std::unique_ptr<MCAsmBackend> MAB,
26 std::unique_ptr<MCObjectWriter> OW,
27 std::unique_ptr<MCCodeEmitter> Emitter)
28 : MCELFStreamer(Context, std::move(MAB), std::move(OW),
29 std::move(Emitter)) {
30 RegInfoRecord = new MipsRegInfoRecord(this, Context);
31 MipsOptionRecords.push_back(
32 Elt: std::unique_ptr<MipsRegInfoRecord>(RegInfoRecord));
33}
34
35void MipsELFStreamer::emitInstruction(const MCInst &Inst,
36 const MCSubtargetInfo &STI) {
37 MCELFStreamer::emitInstruction(Inst, STI);
38
39 MCContext &Context = getContext();
40 const MCRegisterInfo *MCRegInfo = Context.getRegisterInfo();
41
42 for (unsigned OpIndex = 0; OpIndex < Inst.getNumOperands(); ++OpIndex) {
43 const MCOperand &Op = Inst.getOperand(i: OpIndex);
44
45 if (!Op.isReg())
46 continue;
47
48 MCRegister Reg = Op.getReg();
49 RegInfoRecord->SetPhysRegUsed(Reg, MCRegInfo);
50 }
51
52 createPendingLabelRelocs();
53}
54
55void MipsELFStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
56 Frame.Begin = getContext().createTempSymbol();
57 MCELFStreamer::emitLabel(Symbol: Frame.Begin);
58}
59
60MCSymbol *MipsELFStreamer::emitCFILabel() {
61 MCSymbol *Label = getContext().createTempSymbol(Name: "cfi", AlwaysAddSuffix: true);
62 MCELFStreamer::emitLabel(Symbol: Label);
63 return Label;
64}
65
66void MipsELFStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
67 Frame.End = getContext().createTempSymbol();
68 MCELFStreamer::emitLabel(Symbol: Frame.End);
69}
70
71void MipsELFStreamer::createPendingLabelRelocs() {
72 MipsTargetELFStreamer *ELFTargetStreamer =
73 static_cast<MipsTargetELFStreamer *>(getTargetStreamer());
74
75 // FIXME: Also mark labels when in MIPS16 mode.
76 if (ELFTargetStreamer->isMicroMipsEnabled()) {
77 for (auto *L : Labels) {
78 auto *Label = static_cast<MCSymbolELF *>(L);
79 getAssembler().registerSymbol(Symbol: *Label);
80 Label->setOther(ELF::STO_MIPS_MICROMIPS);
81 }
82 }
83
84 Labels.clear();
85}
86
87void MipsELFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
88 MCELFStreamer::emitLabel(Symbol);
89 Labels.push_back(Elt: Symbol);
90}
91
92void MipsELFStreamer::switchSection(MCSection *Section, uint32_t Subsection) {
93 MCELFStreamer::switchSection(Section, Subsec: Subsection);
94 Labels.clear();
95}
96
97void MipsELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
98 SMLoc Loc) {
99 MCELFStreamer::emitValueImpl(Value, Size, Loc);
100 Labels.clear();
101}
102
103void MipsELFStreamer::emitIntValue(uint64_t Value, unsigned Size) {
104 MCELFStreamer::emitIntValue(Value, Size);
105 Labels.clear();
106}
107
108void MipsELFStreamer::EmitMipsOptionRecords() {
109 for (const auto &I : MipsOptionRecords)
110 I->EmitMipsOptionRecord();
111}
112
113MCELFStreamer *
114llvm::createMipsELFStreamer(MCContext &Context,
115 std::unique_ptr<MCAsmBackend> MAB,
116 std::unique_ptr<MCObjectWriter> OW,
117 std::unique_ptr<MCCodeEmitter> Emitter) {
118 return new MipsELFStreamer(Context, std::move(MAB), std::move(OW),
119 std::move(Emitter));
120}
121