1274955Ssvnmir//===-------- MipsELFStreamer.h - ELF Object Output -----------------------===// 2274955Ssvnmir// 3274955Ssvnmir// The LLVM Compiler Infrastructure 4274955Ssvnmir// 5274955Ssvnmir// This file is distributed under the University of Illinois Open Source 6274955Ssvnmir// License. See LICENSE.TXT for details. 7274955Ssvnmir// 8274955Ssvnmir//===----------------------------------------------------------------------===// 9274955Ssvnmir// 10274955Ssvnmir// This is a custom MCELFStreamer which allows us to insert some hooks before 11274955Ssvnmir// emitting data into an actual object file. 12274955Ssvnmir// 13274955Ssvnmir//===----------------------------------------------------------------------===// 14274955Ssvnmir 15280031Sdim#ifndef LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSELFSTREAMER_H 16280031Sdim#define LLVM_LIB_TARGET_MIPS_MCTARGETDESC_MIPSELFSTREAMER_H 17274955Ssvnmir 18274955Ssvnmir#include "MipsOptionRecord.h" 19274955Ssvnmir#include "llvm/ADT/SmallVector.h" 20274955Ssvnmir#include "llvm/MC/MCELFStreamer.h" 21274955Ssvnmir#include <memory> 22274955Ssvnmir 23274955Ssvnmirnamespace llvm { 24274955Ssvnmirclass MCAsmBackend; 25274955Ssvnmirclass MCCodeEmitter; 26274955Ssvnmirclass MCContext; 27274955Ssvnmirclass MCSubtargetInfo; 28274955Ssvnmir 29274955Ssvnmirclass MipsELFStreamer : public MCELFStreamer { 30274955Ssvnmir SmallVector<std::unique_ptr<MipsOptionRecord>, 8> MipsOptionRecords; 31274955Ssvnmir MipsRegInfoRecord *RegInfoRecord; 32280031Sdim SmallVector<MCSymbol*, 4> Labels; 33274955Ssvnmir 34280031Sdim 35274955Ssvnmirpublic: 36288943Sdim MipsELFStreamer(MCContext &Context, MCAsmBackend &MAB, raw_pwrite_stream &OS, 37288943Sdim MCCodeEmitter *Emitter) 38274955Ssvnmir : MCELFStreamer(Context, MAB, OS, Emitter) { 39274955Ssvnmir 40288943Sdim RegInfoRecord = new MipsRegInfoRecord(this, Context); 41274955Ssvnmir MipsOptionRecords.push_back( 42274955Ssvnmir std::unique_ptr<MipsRegInfoRecord>(RegInfoRecord)); 43274955Ssvnmir } 44274955Ssvnmir 45274955Ssvnmir /// Overriding this function allows us to add arbitrary behaviour before the 46274955Ssvnmir /// \p Inst is actually emitted. For example, we can inspect the operands and 47274955Ssvnmir /// gather sufficient information that allows us to reason about the register 48274955Ssvnmir /// usage for the translation unit. 49274955Ssvnmir void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override; 50274955Ssvnmir 51280031Sdim /// Overriding this function allows us to record all labels that should be 52280031Sdim /// marked as microMIPS. Based on this data marking is done in 53280031Sdim /// EmitInstruction. 54280031Sdim void EmitLabel(MCSymbol *Symbol) override; 55280031Sdim 56280031Sdim /// Overriding this function allows us to dismiss all labels that are 57280031Sdim /// candidates for marking as microMIPS when .section directive is processed. 58288943Sdim void SwitchSection(MCSection *Section, 59280031Sdim const MCExpr *Subsection = nullptr) override; 60280031Sdim 61280031Sdim /// Overriding this function allows us to dismiss all labels that are 62280031Sdim /// candidates for marking as microMIPS when .word directive is emitted. 63296417Sdim void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override; 64280031Sdim 65274955Ssvnmir /// Emits all the option records stored up until the point it's called. 66274955Ssvnmir void EmitMipsOptionRecords(); 67288943Sdim 68288943Sdim /// Mark labels as microMIPS, if necessary for the subtarget. 69288943Sdim void createPendingLabelRelocs(); 70274955Ssvnmir}; 71274955Ssvnmir 72274955SsvnmirMCELFStreamer *createMipsELFStreamer(MCContext &Context, MCAsmBackend &MAB, 73288943Sdim raw_pwrite_stream &OS, 74288943Sdim MCCodeEmitter *Emitter, bool RelaxAll); 75274955Ssvnmir} // namespace llvm. 76274955Ssvnmir#endif 77