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 if (ELFTargetStreamer->isMicroMipsEnabled() ||
76 ELFTargetStreamer->isMips16Enabled()) {
77 for (auto *L : Labels) {
78 auto *Label = static_cast<MCSymbolELF *>(L);
79 getAssembler().registerSymbol(Symbol: *Label);
80 Label->setOther(ELFTargetStreamer->isMips16Enabled()
81 ? ELF::STO_MIPS_MIPS16
82 : ELF::STO_MIPS_MICROMIPS);
83 }
84 }
85
86 Labels.clear();
87}
88
89void MipsELFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
90 MCELFStreamer::emitLabel(Symbol);
91 Labels.push_back(Elt: Symbol);
92}
93
94void MipsELFStreamer::switchSection(MCSection *Section, uint32_t Subsection) {
95 MCELFStreamer::switchSection(Section, Subsec: Subsection);
96 Labels.clear();
97}
98
99void MipsELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
100 SMLoc Loc) {
101 MCELFStreamer::emitValueImpl(Value, Size, Loc);
102 Labels.clear();
103}
104
105void MipsELFStreamer::emitIntValue(uint64_t Value, unsigned Size) {
106 MCELFStreamer::emitIntValue(Value, Size);
107 Labels.clear();
108}
109
110void MipsELFStreamer::emitBytes(StringRef Data) {
111 MCELFStreamer::emitBytes(Data);
112 Labels.clear();
113}
114
115void MipsELFStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
116 SMLoc Loc) {
117 MCELFStreamer::emitFill(NumBytes, FillValue, Loc);
118 Labels.clear();
119}
120
121void MipsELFStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
122 int64_t Expr, SMLoc Loc) {
123 MCELFStreamer::emitFill(NumValues, Size, Expr, Loc);
124 Labels.clear();
125}
126
127void MipsELFStreamer::EmitMipsOptionRecords() {
128 for (const auto &I : MipsOptionRecords)
129 I->EmitMipsOptionRecord();
130}
131
132MCELFStreamer *
133llvm::createMipsELFStreamer(MCContext &Context,
134 std::unique_ptr<MCAsmBackend> MAB,
135 std::unique_ptr<MCObjectWriter> OW,
136 std::unique_ptr<MCCodeEmitter> Emitter) {
137 return new MipsELFStreamer(Context, std::move(MAB), std::move(OW),
138 std::move(Emitter));
139}
140