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 "MipsOptionRecord.h"
12 #include "MipsTargetStreamer.h"
13 #include "llvm/BinaryFormat/ELF.h"
14 #include "llvm/MC/MCAssembler.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCInst.h"
17 #include "llvm/MC/MCSymbolELF.h"
18 #include "llvm/Support/Casting.h"
19 
20 using namespace llvm;
21 
22 void MipsELFStreamer::EmitInstruction(const MCInst &Inst,
23                                       const MCSubtargetInfo &STI, bool) {
24   MCELFStreamer::EmitInstruction(Inst, STI);
25 
26   MCContext &Context = getContext();
27   const MCRegisterInfo *MCRegInfo = Context.getRegisterInfo();
28 
29   for (unsigned OpIndex = 0; OpIndex < Inst.getNumOperands(); ++OpIndex) {
30     const MCOperand &Op = Inst.getOperand(OpIndex);
31 
32     if (!Op.isReg())
33       continue;
34 
35     unsigned Reg = Op.getReg();
36     RegInfoRecord->SetPhysRegUsed(Reg, MCRegInfo);
37   }
38 
39   createPendingLabelRelocs();
40 }
41 
42 void MipsELFStreamer::createPendingLabelRelocs() {
43   MipsTargetELFStreamer *ELFTargetStreamer =
44       static_cast<MipsTargetELFStreamer *>(getTargetStreamer());
45 
46   // FIXME: Also mark labels when in MIPS16 mode.
47   if (ELFTargetStreamer->isMicroMipsEnabled()) {
48     for (auto *L : Labels) {
49       auto *Label = cast<MCSymbolELF>(L);
50       getAssembler().registerSymbol(*Label);
51       Label->setOther(ELF::STO_MIPS_MICROMIPS);
52     }
53   }
54 
55   Labels.clear();
56 }
57 
58 void MipsELFStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
59   MCELFStreamer::EmitLabel(Symbol);
60   Labels.push_back(Symbol);
61 }
62 
63 void MipsELFStreamer::SwitchSection(MCSection *Section,
64                                     const MCExpr *Subsection) {
65   MCELFStreamer::SwitchSection(Section, Subsection);
66   Labels.clear();
67 }
68 
69 void MipsELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
70                                     SMLoc Loc) {
71   MCELFStreamer::EmitValueImpl(Value, Size, Loc);
72   Labels.clear();
73 }
74 
75 void MipsELFStreamer::EmitMipsOptionRecords() {
76   for (const auto &I : MipsOptionRecords)
77     I->EmitMipsOptionRecord();
78 }
79 
80 MCELFStreamer *llvm::createMipsELFStreamer(MCContext &Context,
81                                            MCAsmBackend &MAB,
82                                            raw_pwrite_stream &OS,
83                                            MCCodeEmitter *Emitter,
84                                            bool RelaxAll) {
85   return new MipsELFStreamer(Context, MAB, OS, Emitter);
86 }
87