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
,
94 const MCExpr
*Subsection
) {
95 MCELFStreamer::SwitchSection(Section
, Subsection
);
99 void MipsELFStreamer::EmitValueImpl(const MCExpr
*Value
, unsigned Size
,
101 MCELFStreamer::EmitValueImpl(Value
, Size
, Loc
);
105 void MipsELFStreamer::EmitIntValue(uint64_t Value
, unsigned Size
) {
106 MCELFStreamer::EmitIntValue(Value
, Size
);
110 void MipsELFStreamer::EmitMipsOptionRecords() {
111 for (const auto &I
: MipsOptionRecords
)
112 I
->EmitMipsOptionRecord();
115 MCELFStreamer
*llvm::createMipsELFStreamer(
116 MCContext
&Context
, std::unique_ptr
<MCAsmBackend
> MAB
,
117 std::unique_ptr
<MCObjectWriter
> OW
, std::unique_ptr
<MCCodeEmitter
> Emitter
,
119 return new MipsELFStreamer(Context
, std::move(MAB
), std::move(OW
),