xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- MipsELFStreamer.h - ELF Object Output --------------------*- C++ -*-===//
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 // This is a custom MCELFStreamer which allows us to insert some hooks before
100b57cec5SDimitry Andric // emitting data into an actual object file.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSELFSTREAMER_H
150b57cec5SDimitry Andric #define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSELFSTREAMER_H
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #include "MipsOptionRecord.h"
180b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCELFStreamer.h"
200b57cec5SDimitry Andric #include <memory>
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric namespace llvm {
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric class MCAsmBackend;
250b57cec5SDimitry Andric class MCCodeEmitter;
260b57cec5SDimitry Andric class MCContext;
270b57cec5SDimitry Andric class MCSubtargetInfo;
280b57cec5SDimitry Andric struct MCDwarfFrameInfo;
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric class MipsELFStreamer : public MCELFStreamer {
310b57cec5SDimitry Andric   SmallVector<std::unique_ptr<MipsOptionRecord>, 8> MipsOptionRecords;
320b57cec5SDimitry Andric   MipsRegInfoRecord *RegInfoRecord;
330b57cec5SDimitry Andric   SmallVector<MCSymbol*, 4> Labels;
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric public:
360b57cec5SDimitry Andric   MipsELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
370b57cec5SDimitry Andric                   std::unique_ptr<MCObjectWriter> OW,
380b57cec5SDimitry Andric                   std::unique_ptr<MCCodeEmitter> Emitter);
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric   /// Overriding this function allows us to add arbitrary behaviour before the
410b57cec5SDimitry Andric   /// \p Inst is actually emitted. For example, we can inspect the operands and
420b57cec5SDimitry Andric   /// gather sufficient information that allows us to reason about the register
430b57cec5SDimitry Andric   /// usage for the translation unit.
445ffd83dbSDimitry Andric   void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric   /// Overriding this function allows us to record all labels that should be
470b57cec5SDimitry Andric   /// marked as microMIPS. Based on this data marking is done in
480b57cec5SDimitry Andric   /// EmitInstruction.
495ffd83dbSDimitry Andric   void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   /// Overriding this function allows us to dismiss all labels that are
520b57cec5SDimitry Andric   /// candidates for marking as microMIPS when .section directive is processed.
53*0fca6ea1SDimitry Andric   void switchSection(MCSection *Section, uint32_t Subsection = 0) override;
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric   /// Overriding these functions allows us to dismiss all labels that are
560b57cec5SDimitry Andric   /// candidates for marking as microMIPS when .word/.long/.4byte etc
570b57cec5SDimitry Andric   /// directives are emitted.
585ffd83dbSDimitry Andric   void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override;
595ffd83dbSDimitry Andric   void emitIntValue(uint64_t Value, unsigned Size) override;
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric   // Overriding these functions allows us to avoid recording of these labels
620b57cec5SDimitry Andric   // in EmitLabel and later marking them as microMIPS.
635ffd83dbSDimitry Andric   void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
645ffd83dbSDimitry Andric   void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
655ffd83dbSDimitry Andric   MCSymbol *emitCFILabel() override;
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric   /// Emits all the option records stored up until the point it's called.
680b57cec5SDimitry Andric   void EmitMipsOptionRecords();
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   /// Mark labels as microMIPS, if necessary for the subtarget.
710b57cec5SDimitry Andric   void createPendingLabelRelocs();
720b57cec5SDimitry Andric };
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric MCELFStreamer *createMipsELFStreamer(MCContext &Context,
750b57cec5SDimitry Andric                                      std::unique_ptr<MCAsmBackend> MAB,
760b57cec5SDimitry Andric                                      std::unique_ptr<MCObjectWriter> OW,
77*0fca6ea1SDimitry Andric                                      std::unique_ptr<MCCodeEmitter> Emitter);
780b57cec5SDimitry Andric } // end namespace llvm
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSELFSTREAMER_H
81