136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===-------- MipsELFStreamer.cpp - ELF Object Output ---------------------===//
236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//                     The LLVM Compiler Infrastructure
436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file is distributed under the University of Illinois Open Source
636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// License. See LICENSE.TXT for details.
736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "MipsELFStreamer.h"
1137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "MipsTargetStreamer.h"
1237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/MC/MCInst.h"
136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/MC/MCSymbolELF.h"
1437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/ELF.h"
1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesusing namespace llvm;
1737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid MipsELFStreamer::EmitInstruction(const MCInst &Inst,
1937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                      const MCSubtargetInfo &STI) {
2037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCELFStreamer::EmitInstruction(Inst, STI);
2137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
2237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCContext &Context = getContext();
2337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const MCRegisterInfo *MCRegInfo = Context.getRegisterInfo();
2437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
2537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (unsigned OpIndex = 0; OpIndex < Inst.getNumOperands(); ++OpIndex) {
2637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const MCOperand &Op = Inst.getOperand(OpIndex);
2737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
2837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!Op.isReg())
2937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      continue;
3037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
3137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    unsigned Reg = Op.getReg();
3237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    RegInfoRecord->SetPhysRegUsed(Reg, MCRegInfo);
3337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
3437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  createPendingLabelRelocs();
360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
370c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
380c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarvoid MipsELFStreamer::createPendingLabelRelocs() {
390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  MipsTargetELFStreamer *ELFTargetStreamer =
400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      static_cast<MipsTargetELFStreamer *>(getTargetStreamer());
410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // FIXME: Also mark labels when in MIPS16 mode.
4337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (ELFTargetStreamer->isMicroMipsEnabled()) {
446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    for (auto *L : Labels) {
456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      auto *Label = cast<MCSymbolELF>(L);
466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      getAssembler().registerSymbol(*Label);
476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Label->setOther(ELF::STO_MIPS_MICROMIPS);
4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
4937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
5037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
5137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Labels.clear();
5237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
5337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
5437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid MipsELFStreamer::EmitLabel(MCSymbol *Symbol) {
5537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCELFStreamer::EmitLabel(Symbol);
5637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Labels.push_back(Symbol);
5737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
5837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid MipsELFStreamer::SwitchSection(MCSection *Section,
6037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                    const MCExpr *Subsection) {
6137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCELFStreamer::SwitchSection(Section, Subsection);
6237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Labels.clear();
6337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
6437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
6537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid MipsELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
66f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                    SMLoc Loc) {
6737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCELFStreamer::EmitValueImpl(Value, Size, Loc);
6837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Labels.clear();
6937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
7037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
7137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid MipsELFStreamer::EmitMipsOptionRecords() {
7237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (const auto &I : MipsOptionRecords)
7337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    I->EmitMipsOptionRecord();
7437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarMCELFStreamer *llvm::createMipsELFStreamer(MCContext &Context,
770c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                           MCAsmBackend &MAB,
780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                           raw_pwrite_stream &OS,
794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                           MCCodeEmitter *Emitter,
804c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                           bool RelaxAll) {
814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  return new MipsELFStreamer(Context, MAB, OS, Emitter);
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
83