xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-------- MipsELFStreamer.cpp - ELF Object Output ---------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "MipsELFStreamer.h"
100b57cec5SDimitry Andric #include "MipsOptionRecord.h"
110b57cec5SDimitry Andric #include "MipsTargetStreamer.h"
120b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
130b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h"
140b57cec5SDimitry Andric #include "llvm/MC/MCAssembler.h"
150b57cec5SDimitry Andric #include "llvm/MC/MCCodeEmitter.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h"
210b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric using namespace llvm;
240b57cec5SDimitry Andric 
MipsELFStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> MAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter)250b57cec5SDimitry Andric MipsELFStreamer::MipsELFStreamer(MCContext &Context,
260b57cec5SDimitry Andric                                  std::unique_ptr<MCAsmBackend> MAB,
270b57cec5SDimitry Andric                                  std::unique_ptr<MCObjectWriter> OW,
280b57cec5SDimitry Andric                                  std::unique_ptr<MCCodeEmitter> Emitter)
290b57cec5SDimitry Andric     : MCELFStreamer(Context, std::move(MAB), std::move(OW),
300b57cec5SDimitry Andric                     std::move(Emitter)) {
310b57cec5SDimitry Andric   RegInfoRecord = new MipsRegInfoRecord(this, Context);
320b57cec5SDimitry Andric   MipsOptionRecords.push_back(
330b57cec5SDimitry Andric       std::unique_ptr<MipsRegInfoRecord>(RegInfoRecord));
340b57cec5SDimitry Andric }
350b57cec5SDimitry Andric 
emitInstruction(const MCInst & Inst,const MCSubtargetInfo & STI)365ffd83dbSDimitry Andric void MipsELFStreamer::emitInstruction(const MCInst &Inst,
370b57cec5SDimitry Andric                                       const MCSubtargetInfo &STI) {
385ffd83dbSDimitry Andric   MCELFStreamer::emitInstruction(Inst, STI);
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric   MCContext &Context = getContext();
410b57cec5SDimitry Andric   const MCRegisterInfo *MCRegInfo = Context.getRegisterInfo();
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric   for (unsigned OpIndex = 0; OpIndex < Inst.getNumOperands(); ++OpIndex) {
440b57cec5SDimitry Andric     const MCOperand &Op = Inst.getOperand(OpIndex);
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric     if (!Op.isReg())
470b57cec5SDimitry Andric       continue;
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric     unsigned Reg = Op.getReg();
500b57cec5SDimitry Andric     RegInfoRecord->SetPhysRegUsed(Reg, MCRegInfo);
510b57cec5SDimitry Andric   }
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric   createPendingLabelRelocs();
540b57cec5SDimitry Andric }
550b57cec5SDimitry Andric 
emitCFIStartProcImpl(MCDwarfFrameInfo & Frame)565ffd83dbSDimitry Andric void MipsELFStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
570b57cec5SDimitry Andric   Frame.Begin = getContext().createTempSymbol();
585ffd83dbSDimitry Andric   MCELFStreamer::emitLabel(Frame.Begin);
590b57cec5SDimitry Andric }
600b57cec5SDimitry Andric 
emitCFILabel()615ffd83dbSDimitry Andric MCSymbol *MipsELFStreamer::emitCFILabel() {
620b57cec5SDimitry Andric   MCSymbol *Label = getContext().createTempSymbol("cfi", true);
635ffd83dbSDimitry Andric   MCELFStreamer::emitLabel(Label);
640b57cec5SDimitry Andric   return Label;
650b57cec5SDimitry Andric }
660b57cec5SDimitry Andric 
emitCFIEndProcImpl(MCDwarfFrameInfo & Frame)675ffd83dbSDimitry Andric void MipsELFStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
680b57cec5SDimitry Andric   Frame.End = getContext().createTempSymbol();
695ffd83dbSDimitry Andric   MCELFStreamer::emitLabel(Frame.End);
700b57cec5SDimitry Andric }
710b57cec5SDimitry Andric 
createPendingLabelRelocs()720b57cec5SDimitry Andric void MipsELFStreamer::createPendingLabelRelocs() {
730b57cec5SDimitry Andric   MipsTargetELFStreamer *ELFTargetStreamer =
740b57cec5SDimitry Andric       static_cast<MipsTargetELFStreamer *>(getTargetStreamer());
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   // FIXME: Also mark labels when in MIPS16 mode.
770b57cec5SDimitry Andric   if (ELFTargetStreamer->isMicroMipsEnabled()) {
780b57cec5SDimitry Andric     for (auto *L : Labels) {
790b57cec5SDimitry Andric       auto *Label = cast<MCSymbolELF>(L);
800b57cec5SDimitry Andric       getAssembler().registerSymbol(*Label);
810b57cec5SDimitry Andric       Label->setOther(ELF::STO_MIPS_MICROMIPS);
820b57cec5SDimitry Andric     }
830b57cec5SDimitry Andric   }
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   Labels.clear();
860b57cec5SDimitry Andric }
870b57cec5SDimitry Andric 
emitLabel(MCSymbol * Symbol,SMLoc Loc)885ffd83dbSDimitry Andric void MipsELFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
895ffd83dbSDimitry Andric   MCELFStreamer::emitLabel(Symbol);
900b57cec5SDimitry Andric   Labels.push_back(Symbol);
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric 
switchSection(MCSection * Section,uint32_t Subsection)93*0fca6ea1SDimitry Andric void MipsELFStreamer::switchSection(MCSection *Section, uint32_t Subsection) {
9481ad6265SDimitry Andric   MCELFStreamer::switchSection(Section, Subsection);
950b57cec5SDimitry Andric   Labels.clear();
960b57cec5SDimitry Andric }
970b57cec5SDimitry Andric 
emitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)985ffd83dbSDimitry Andric void MipsELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
990b57cec5SDimitry Andric                                     SMLoc Loc) {
1005ffd83dbSDimitry Andric   MCELFStreamer::emitValueImpl(Value, Size, Loc);
1010b57cec5SDimitry Andric   Labels.clear();
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric 
emitIntValue(uint64_t Value,unsigned Size)1045ffd83dbSDimitry Andric void MipsELFStreamer::emitIntValue(uint64_t Value, unsigned Size) {
1055ffd83dbSDimitry Andric   MCELFStreamer::emitIntValue(Value, Size);
1060b57cec5SDimitry Andric   Labels.clear();
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric 
EmitMipsOptionRecords()1090b57cec5SDimitry Andric void MipsELFStreamer::EmitMipsOptionRecords() {
1100b57cec5SDimitry Andric   for (const auto &I : MipsOptionRecords)
1110b57cec5SDimitry Andric     I->EmitMipsOptionRecord();
1120b57cec5SDimitry Andric }
1130b57cec5SDimitry Andric 
114*0fca6ea1SDimitry Andric MCELFStreamer *
createMipsELFStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> MAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter)115*0fca6ea1SDimitry Andric llvm::createMipsELFStreamer(MCContext &Context,
116*0fca6ea1SDimitry Andric                             std::unique_ptr<MCAsmBackend> MAB,
117*0fca6ea1SDimitry Andric                             std::unique_ptr<MCObjectWriter> OW,
118*0fca6ea1SDimitry Andric                             std::unique_ptr<MCCodeEmitter> Emitter) {
1190b57cec5SDimitry Andric   return new MipsELFStreamer(Context, std::move(MAB), std::move(OW),
1200b57cec5SDimitry Andric                              std::move(Emitter));
1210b57cec5SDimitry Andric }
122