/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp
Line | Count | Source |
1 | | //===-------- MipsELFStreamer.cpp - ELF Object Output ---------------------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #include "MipsELFStreamer.h" |
10 | | #include "MipsOptionRecord.h" |
11 | | #include "MipsTargetStreamer.h" |
12 | | #include "llvm/BinaryFormat/ELF.h" |
13 | | #include "llvm/MC/MCAsmBackend.h" |
14 | | #include "llvm/MC/MCAssembler.h" |
15 | | #include "llvm/MC/MCCodeEmitter.h" |
16 | | #include "llvm/MC/MCContext.h" |
17 | | #include "llvm/MC/MCDwarf.h" |
18 | | #include "llvm/MC/MCInst.h" |
19 | | #include "llvm/MC/MCObjectWriter.h" |
20 | | #include "llvm/MC/MCSymbolELF.h" |
21 | | #include "llvm/Support/Casting.h" |
22 | | |
23 | | using namespace llvm; |
24 | | |
25 | | MipsELFStreamer::MipsELFStreamer(MCContext &Context, |
26 | | std::unique_ptr<MCAsmBackend> MAB, |
27 | | std::unique_ptr<MCObjectWriter> OW, |
28 | | std::unique_ptr<MCCodeEmitter> Emitter) |
29 | | : MCELFStreamer(Context, std::move(MAB), std::move(OW), |
30 | 546 | std::move(Emitter)) { |
31 | 546 | RegInfoRecord = new MipsRegInfoRecord(this, Context); |
32 | 546 | MipsOptionRecords.push_back( |
33 | 546 | std::unique_ptr<MipsRegInfoRecord>(RegInfoRecord)); |
34 | 546 | } |
35 | | |
36 | | void MipsELFStreamer::EmitInstruction(const MCInst &Inst, |
37 | 23.0k | const MCSubtargetInfo &STI) { |
38 | 23.0k | MCELFStreamer::EmitInstruction(Inst, STI); |
39 | 23.0k | |
40 | 23.0k | MCContext &Context = getContext(); |
41 | 23.0k | const MCRegisterInfo *MCRegInfo = Context.getRegisterInfo(); |
42 | 23.0k | |
43 | 91.1k | for (unsigned OpIndex = 0; OpIndex < Inst.getNumOperands(); ++OpIndex68.1k ) { |
44 | 68.1k | const MCOperand &Op = Inst.getOperand(OpIndex); |
45 | 68.1k | |
46 | 68.1k | if (!Op.isReg()) |
47 | 22.5k | continue; |
48 | 45.5k | |
49 | 45.5k | unsigned Reg = Op.getReg(); |
50 | 45.5k | RegInfoRecord->SetPhysRegUsed(Reg, MCRegInfo); |
51 | 45.5k | } |
52 | 23.0k | |
53 | 23.0k | createPendingLabelRelocs(); |
54 | 23.0k | } |
55 | | |
56 | 79 | void MipsELFStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { |
57 | 79 | Frame.Begin = getContext().createTempSymbol(); |
58 | 79 | MCELFStreamer::EmitLabel(Frame.Begin); |
59 | 79 | } |
60 | | |
61 | 43 | MCSymbol *MipsELFStreamer::EmitCFILabel() { |
62 | 43 | MCSymbol *Label = getContext().createTempSymbol("cfi", true); |
63 | 43 | MCELFStreamer::EmitLabel(Label); |
64 | 43 | return Label; |
65 | 43 | } |
66 | | |
67 | 79 | void MipsELFStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { |
68 | 79 | Frame.End = getContext().createTempSymbol(); |
69 | 79 | MCELFStreamer::EmitLabel(Frame.End); |
70 | 79 | } |
71 | | |
72 | 23.0k | void MipsELFStreamer::createPendingLabelRelocs() { |
73 | 23.0k | MipsTargetELFStreamer *ELFTargetStreamer = |
74 | 23.0k | static_cast<MipsTargetELFStreamer *>(getTargetStreamer()); |
75 | 23.0k | |
76 | 23.0k | // FIXME: Also mark labels when in MIPS16 mode. |
77 | 23.0k | if (ELFTargetStreamer->isMicroMipsEnabled()) { |
78 | 522 | for (auto *L : Labels) { |
79 | 132 | auto *Label = cast<MCSymbolELF>(L); |
80 | 132 | getAssembler().registerSymbol(*Label); |
81 | 132 | Label->setOther(ELF::STO_MIPS_MICROMIPS); |
82 | 132 | } |
83 | 522 | } |
84 | 23.0k | |
85 | 23.0k | Labels.clear(); |
86 | 23.0k | } |
87 | | |
88 | 11.9k | void MipsELFStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) { |
89 | 11.9k | MCELFStreamer::EmitLabel(Symbol); |
90 | 11.9k | Labels.push_back(Symbol); |
91 | 11.9k | } |
92 | | |
93 | | void MipsELFStreamer::SwitchSection(MCSection *Section, |
94 | 12.7k | const MCExpr *Subsection) { |
95 | 12.7k | MCELFStreamer::SwitchSection(Section, Subsection); |
96 | 12.7k | Labels.clear(); |
97 | 12.7k | } |
98 | | |
99 | | void MipsELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, |
100 | 917 | SMLoc Loc) { |
101 | 917 | MCELFStreamer::EmitValueImpl(Value, Size, Loc); |
102 | 917 | Labels.clear(); |
103 | 917 | } |
104 | | |
105 | 406k | void MipsELFStreamer::EmitIntValue(uint64_t Value, unsigned Size) { |
106 | 406k | MCELFStreamer::EmitIntValue(Value, Size); |
107 | 406k | Labels.clear(); |
108 | 406k | } |
109 | | |
110 | 542 | void MipsELFStreamer::EmitMipsOptionRecords() { |
111 | 542 | for (const auto &I : MipsOptionRecords) |
112 | 542 | I->EmitMipsOptionRecord(); |
113 | 542 | } |
114 | | |
115 | | MCELFStreamer *llvm::createMipsELFStreamer( |
116 | | MCContext &Context, std::unique_ptr<MCAsmBackend> MAB, |
117 | | std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter, |
118 | 545 | bool RelaxAll) { |
119 | 545 | return new MipsELFStreamer(Context, std::move(MAB), std::move(OW), |
120 | 545 | std::move(Emitter)); |
121 | 545 | } |