191bc56edSDimitry Andric //===-------- MipsELFStreamer.cpp - ELF Object Output ---------------------===//
291bc56edSDimitry Andric //
391bc56edSDimitry Andric // The LLVM Compiler Infrastructure
491bc56edSDimitry Andric //
591bc56edSDimitry Andric // This file is distributed under the University of Illinois Open Source
691bc56edSDimitry Andric // License. See LICENSE.TXT for details.
791bc56edSDimitry Andric //
891bc56edSDimitry Andric //===----------------------------------------------------------------------===//
991bc56edSDimitry Andric
1091bc56edSDimitry Andric #include "MipsELFStreamer.h"
117a7e6055SDimitry Andric #include "MipsOptionRecord.h"
1239d628a0SDimitry Andric #include "MipsTargetStreamer.h"
13db17bf38SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
142cab237bSDimitry Andric #include "llvm/MC/MCAsmBackend.h"
157a7e6055SDimitry Andric #include "llvm/MC/MCAssembler.h"
162cab237bSDimitry Andric #include "llvm/MC/MCCodeEmitter.h"
177a7e6055SDimitry Andric #include "llvm/MC/MCContext.h"
18*4ba319b5SDimitry Andric #include "llvm/MC/MCDwarf.h"
1991bc56edSDimitry Andric #include "llvm/MC/MCInst.h"
20*4ba319b5SDimitry Andric #include "llvm/MC/MCObjectWriter.h"
2197bc6c73SDimitry Andric #include "llvm/MC/MCSymbolELF.h"
227a7e6055SDimitry Andric #include "llvm/Support/Casting.h"
2339d628a0SDimitry Andric
2439d628a0SDimitry Andric using namespace llvm;
2591bc56edSDimitry Andric
MipsELFStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> MAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter)262cab237bSDimitry Andric MipsELFStreamer::MipsELFStreamer(MCContext &Context,
272cab237bSDimitry Andric std::unique_ptr<MCAsmBackend> MAB,
28*4ba319b5SDimitry Andric std::unique_ptr<MCObjectWriter> OW,
292cab237bSDimitry Andric std::unique_ptr<MCCodeEmitter> Emitter)
30*4ba319b5SDimitry Andric : MCELFStreamer(Context, std::move(MAB), std::move(OW),
31*4ba319b5SDimitry Andric std::move(Emitter)) {
322cab237bSDimitry Andric RegInfoRecord = new MipsRegInfoRecord(this, Context);
332cab237bSDimitry Andric MipsOptionRecords.push_back(
342cab237bSDimitry Andric std::unique_ptr<MipsRegInfoRecord>(RegInfoRecord));
352cab237bSDimitry Andric }
362cab237bSDimitry Andric
EmitInstruction(const MCInst & Inst,const MCSubtargetInfo & STI,bool)3791bc56edSDimitry Andric void MipsELFStreamer::EmitInstruction(const MCInst &Inst,
387a7e6055SDimitry Andric const MCSubtargetInfo &STI, bool) {
3991bc56edSDimitry Andric MCELFStreamer::EmitInstruction(Inst, STI);
4091bc56edSDimitry Andric
4191bc56edSDimitry Andric MCContext &Context = getContext();
4291bc56edSDimitry Andric const MCRegisterInfo *MCRegInfo = Context.getRegisterInfo();
4391bc56edSDimitry Andric
4491bc56edSDimitry Andric for (unsigned OpIndex = 0; OpIndex < Inst.getNumOperands(); ++OpIndex) {
4591bc56edSDimitry Andric const MCOperand &Op = Inst.getOperand(OpIndex);
4691bc56edSDimitry Andric
4791bc56edSDimitry Andric if (!Op.isReg())
4891bc56edSDimitry Andric continue;
4991bc56edSDimitry Andric
5091bc56edSDimitry Andric unsigned Reg = Op.getReg();
5191bc56edSDimitry Andric RegInfoRecord->SetPhysRegUsed(Reg, MCRegInfo);
5291bc56edSDimitry Andric }
5339d628a0SDimitry Andric
54ff0cc061SDimitry Andric createPendingLabelRelocs();
55ff0cc061SDimitry Andric }
56ff0cc061SDimitry Andric
EmitCFIStartProcImpl(MCDwarfFrameInfo & Frame)57*4ba319b5SDimitry Andric void MipsELFStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
58*4ba319b5SDimitry Andric Frame.Begin = getContext().createTempSymbol();
59*4ba319b5SDimitry Andric MCELFStreamer::EmitLabel(Frame.Begin);
60*4ba319b5SDimitry Andric }
61*4ba319b5SDimitry Andric
EmitCFILabel()62*4ba319b5SDimitry Andric MCSymbol *MipsELFStreamer::EmitCFILabel() {
63*4ba319b5SDimitry Andric MCSymbol *Label = getContext().createTempSymbol("cfi", true);
64*4ba319b5SDimitry Andric MCELFStreamer::EmitLabel(Label);
65*4ba319b5SDimitry Andric return Label;
66*4ba319b5SDimitry Andric }
67*4ba319b5SDimitry Andric
EmitCFIEndProcImpl(MCDwarfFrameInfo & Frame)68*4ba319b5SDimitry Andric void MipsELFStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
69*4ba319b5SDimitry Andric Frame.End = getContext().createTempSymbol();
70*4ba319b5SDimitry Andric MCELFStreamer::EmitLabel(Frame.End);
71*4ba319b5SDimitry Andric }
72*4ba319b5SDimitry Andric
createPendingLabelRelocs()73ff0cc061SDimitry Andric void MipsELFStreamer::createPendingLabelRelocs() {
74ff0cc061SDimitry Andric MipsTargetELFStreamer *ELFTargetStreamer =
75ff0cc061SDimitry Andric static_cast<MipsTargetELFStreamer *>(getTargetStreamer());
76ff0cc061SDimitry Andric
77ff0cc061SDimitry Andric // FIXME: Also mark labels when in MIPS16 mode.
7839d628a0SDimitry Andric if (ELFTargetStreamer->isMicroMipsEnabled()) {
7997bc6c73SDimitry Andric for (auto *L : Labels) {
8097bc6c73SDimitry Andric auto *Label = cast<MCSymbolELF>(L);
8197bc6c73SDimitry Andric getAssembler().registerSymbol(*Label);
8297bc6c73SDimitry Andric Label->setOther(ELF::STO_MIPS_MICROMIPS);
8339d628a0SDimitry Andric }
8439d628a0SDimitry Andric }
8539d628a0SDimitry Andric
8639d628a0SDimitry Andric Labels.clear();
8739d628a0SDimitry Andric }
8839d628a0SDimitry Andric
EmitLabel(MCSymbol * Symbol,SMLoc Loc)897a7e6055SDimitry Andric void MipsELFStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
9039d628a0SDimitry Andric MCELFStreamer::EmitLabel(Symbol);
9139d628a0SDimitry Andric Labels.push_back(Symbol);
9239d628a0SDimitry Andric }
9339d628a0SDimitry Andric
SwitchSection(MCSection * Section,const MCExpr * Subsection)94ff0cc061SDimitry Andric void MipsELFStreamer::SwitchSection(MCSection *Section,
9539d628a0SDimitry Andric const MCExpr *Subsection) {
9639d628a0SDimitry Andric MCELFStreamer::SwitchSection(Section, Subsection);
9739d628a0SDimitry Andric Labels.clear();
9839d628a0SDimitry Andric }
9939d628a0SDimitry Andric
EmitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)10039d628a0SDimitry Andric void MipsELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
1017d523365SDimitry Andric SMLoc Loc) {
10239d628a0SDimitry Andric MCELFStreamer::EmitValueImpl(Value, Size, Loc);
10339d628a0SDimitry Andric Labels.clear();
10491bc56edSDimitry Andric }
10591bc56edSDimitry Andric
EmitIntValue(uint64_t Value,unsigned Size)106*4ba319b5SDimitry Andric void MipsELFStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
107*4ba319b5SDimitry Andric MCELFStreamer::EmitIntValue(Value, Size);
108*4ba319b5SDimitry Andric Labels.clear();
109*4ba319b5SDimitry Andric }
110*4ba319b5SDimitry Andric
EmitMipsOptionRecords()11191bc56edSDimitry Andric void MipsELFStreamer::EmitMipsOptionRecords() {
11291bc56edSDimitry Andric for (const auto &I : MipsOptionRecords)
11391bc56edSDimitry Andric I->EmitMipsOptionRecord();
11491bc56edSDimitry Andric }
11591bc56edSDimitry Andric
createMipsELFStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> MAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter,bool RelaxAll)1162cab237bSDimitry Andric MCELFStreamer *llvm::createMipsELFStreamer(
1172cab237bSDimitry Andric MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
118*4ba319b5SDimitry Andric std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter,
11939d628a0SDimitry Andric bool RelaxAll) {
120*4ba319b5SDimitry Andric return new MipsELFStreamer(Context, std::move(MAB), std::move(OW),
121*4ba319b5SDimitry Andric std::move(Emitter));
12291bc56edSDimitry Andric }
123