Home | History | Annotate | Download | only in MCTargetDesc
      1 //===-------- MipsELFStreamer.cpp - ELF Object Output ---------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "MipsELFStreamer.h"
     11 #include "MipsTargetStreamer.h"
     12 #include "llvm/MC/MCELF.h"
     13 #include "llvm/MC/MCInst.h"
     14 #include "llvm/Support/ELF.h"
     15 
     16 using namespace llvm;
     17 
     18 void MipsELFStreamer::EmitInstruction(const MCInst &Inst,
     19                                       const MCSubtargetInfo &STI) {
     20   MCELFStreamer::EmitInstruction(Inst, STI);
     21 
     22   MCContext &Context = getContext();
     23   const MCRegisterInfo *MCRegInfo = Context.getRegisterInfo();
     24 
     25   for (unsigned OpIndex = 0; OpIndex < Inst.getNumOperands(); ++OpIndex) {
     26     const MCOperand &Op = Inst.getOperand(OpIndex);
     27 
     28     if (!Op.isReg())
     29       continue;
     30 
     31     unsigned Reg = Op.getReg();
     32     RegInfoRecord->SetPhysRegUsed(Reg, MCRegInfo);
     33   }
     34 
     35   createPendingLabelRelocs();
     36 }
     37 
     38 void MipsELFStreamer::createPendingLabelRelocs() {
     39   MipsTargetELFStreamer *ELFTargetStreamer =
     40       static_cast<MipsTargetELFStreamer *>(getTargetStreamer());
     41 
     42   // FIXME: Also mark labels when in MIPS16 mode.
     43   if (ELFTargetStreamer->isMicroMipsEnabled()) {
     44     for (auto Label : Labels) {
     45       MCSymbolData &Data = getOrCreateSymbolData(Label);
     46       // The "other" values are stored in the last 6 bits of the second byte.
     47       // The traditional defines for STO values assume the full byte and thus
     48       // the shift to pack it.
     49       MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2);
     50     }
     51   }
     52 
     53   Labels.clear();
     54 }
     55 
     56 void MipsELFStreamer::EmitLabel(MCSymbol *Symbol) {
     57   MCELFStreamer::EmitLabel(Symbol);
     58   Labels.push_back(Symbol);
     59 }
     60 
     61 void MipsELFStreamer::SwitchSection(const MCSection * Section,
     62                                     const MCExpr *Subsection) {
     63   MCELFStreamer::SwitchSection(Section, Subsection);
     64   Labels.clear();
     65 }
     66 
     67 void MipsELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
     68                                     const SMLoc &Loc) {
     69   MCELFStreamer::EmitValueImpl(Value, Size, Loc);
     70   Labels.clear();
     71 }
     72 
     73 void MipsELFStreamer::EmitMipsOptionRecords() {
     74   for (const auto &I : MipsOptionRecords)
     75     I->EmitMipsOptionRecord();
     76 }
     77 
     78 MCELFStreamer *llvm::createMipsELFStreamer(MCContext &Context,
     79                                            MCAsmBackend &MAB,
     80                                            raw_pwrite_stream &OS,
     81                                            MCCodeEmitter *Emitter,
     82                                            bool RelaxAll) {
     83   return new MipsELFStreamer(Context, MAB, OS, Emitter);
     84 }
     85