1 //===-------- MipsELFStreamer.cpp - ELF Object Output ---------------------===//
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
7 //===----------------------------------------------------------------------===//
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 #include "llvm/Support/Casting.h"
25 MipsELFStreamer::MipsELFStreamer(MCContext
&Context
,
26 std::unique_ptr
<MCAsmBackend
> MAB
,
27 std::unique_ptr
<MCObjectWriter
> OW
,
28 std::unique_ptr
<MCCodeEmitter
> Emitter
)
29 : MCELFStreamer(Context
, std::move(MAB
), std::move(OW
),
31 RegInfoRecord
= new MipsRegInfoRecord(this, Context
);
32 MipsOptionRecords
.push_back(
33 std::unique_ptr
<MipsRegInfoRecord
>(RegInfoRecord
));
36 void MipsELFStreamer::emitInstruction(const MCInst
&Inst
,
37 const MCSubtargetInfo
&STI
) {
38 MCELFStreamer::emitInstruction(Inst
, STI
);
40 MCContext
&Context
= getContext();
41 const MCRegisterInfo
*MCRegInfo
= Context
.getRegisterInfo();
43 for (unsigned OpIndex
= 0; OpIndex
< Inst
.getNumOperands(); ++OpIndex
) {
44 const MCOperand
&Op
= Inst
.getOperand(OpIndex
);
49 unsigned Reg
= Op
.getReg();
50 RegInfoRecord
->SetPhysRegUsed(Reg
, MCRegInfo
);
53 createPendingLabelRelocs();
56 void MipsELFStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo
&Frame
) {
57 Frame
.Begin
= getContext().createTempSymbol();
58 MCELFStreamer::emitLabel(Frame
.Begin
);
61 MCSymbol
*MipsELFStreamer::emitCFILabel() {
62 MCSymbol
*Label
= getContext().createTempSymbol("cfi", true);
63 MCELFStreamer::emitLabel(Label
);
67 void MipsELFStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo
&Frame
) {
68 Frame
.End
= getContext().createTempSymbol();
69 MCELFStreamer::emitLabel(Frame
.End
);
72 void MipsELFStreamer::createPendingLabelRelocs() {
73 MipsTargetELFStreamer
*ELFTargetStreamer
=
74 static_cast<MipsTargetELFStreamer
*>(getTargetStreamer());
76 // FIXME: Also mark labels when in MIPS16 mode.
77 if (ELFTargetStreamer
->isMicroMipsEnabled()) {
78 for (auto *L
: Labels
) {
79 auto *Label
= cast
<MCSymbolELF
>(L
);
80 getAssembler().registerSymbol(*Label
);
81 Label
->setOther(ELF::STO_MIPS_MICROMIPS
);
88 void MipsELFStreamer::emitLabel(MCSymbol
*Symbol
, SMLoc Loc
) {
89 MCELFStreamer::emitLabel(Symbol
);
90 Labels
.push_back(Symbol
);
93 void MipsELFStreamer::switchSection(MCSection
*Section
, uint32_t Subsection
) {
94 MCELFStreamer::switchSection(Section
, Subsection
);
98 void MipsELFStreamer::emitValueImpl(const MCExpr
*Value
, unsigned Size
,
100 MCELFStreamer::emitValueImpl(Value
, Size
, Loc
);
104 void MipsELFStreamer::emitIntValue(uint64_t Value
, unsigned Size
) {
105 MCELFStreamer::emitIntValue(Value
, Size
);
109 void MipsELFStreamer::EmitMipsOptionRecords() {
110 for (const auto &I
: MipsOptionRecords
)
111 I
->EmitMipsOptionRecord();
115 llvm::createMipsELFStreamer(MCContext
&Context
,
116 std::unique_ptr
<MCAsmBackend
> MAB
,
117 std::unique_ptr
<MCObjectWriter
> OW
,
118 std::unique_ptr
<MCCodeEmitter
> Emitter
) {
119 return new MipsELFStreamer(Context
, std::move(MAB
), std::move(OW
),