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