Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / lib / Target / RISCV / MCTargetDesc / RISCVELFStreamer.cpp
blob9db5148208b3ec0d7bf53e144c0db291d4dacb99
1 //===-- RISCVELFStreamer.cpp - RISC-V ELF Target Streamer Methods ---------===//
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 // This file provides RISC-V specific target streamer methods.
11 //===----------------------------------------------------------------------===//
13 #include "RISCVELFStreamer.h"
14 #include "RISCVAsmBackend.h"
15 #include "RISCVBaseInfo.h"
16 #include "RISCVMCTargetDesc.h"
17 #include "llvm/BinaryFormat/ELF.h"
18 #include "llvm/MC/MCAsmBackend.h"
19 #include "llvm/MC/MCAssembler.h"
20 #include "llvm/MC/MCCodeEmitter.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCObjectWriter.h"
23 #include "llvm/MC/MCSectionELF.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/MC/MCValue.h"
26 #include "llvm/Support/LEB128.h"
27 #include "llvm/Support/RISCVAttributes.h"
29 using namespace llvm;
31 // This part is for ELF object output.
32 RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S,
33 const MCSubtargetInfo &STI)
34 : RISCVTargetStreamer(S), CurrentVendor("riscv"), STI(STI) {
35 MCAssembler &MCA = getStreamer().getAssembler();
36 const FeatureBitset &Features = STI.getFeatureBits();
37 auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend());
38 setTargetABI(RISCVABI::computeTargetABI(STI.getTargetTriple(), Features,
39 MAB.getTargetOptions().getABIName()));
42 RISCVELFStreamer &RISCVTargetELFStreamer::getStreamer() {
43 return static_cast<RISCVELFStreamer &>(Streamer);
46 void RISCVTargetELFStreamer::emitDirectiveOptionPush() {}
47 void RISCVTargetELFStreamer::emitDirectiveOptionPop() {}
48 void RISCVTargetELFStreamer::emitDirectiveOptionPIC() {}
49 void RISCVTargetELFStreamer::emitDirectiveOptionNoPIC() {}
50 void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {}
51 void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {}
52 void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {}
53 void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {}
55 void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
56 getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);
59 void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute,
60 StringRef String) {
61 getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
64 void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
65 unsigned IntValue,
66 StringRef StringValue) {
67 getStreamer().setAttributeItems(Attribute, IntValue, StringValue,
68 /*OverwriteExisting=*/true);
71 void RISCVTargetELFStreamer::finishAttributeSection() {
72 RISCVELFStreamer &S = getStreamer();
73 if (S.Contents.empty())
74 return;
76 S.emitAttributesSection(CurrentVendor, ".riscv.attributes",
77 ELF::SHT_RISCV_ATTRIBUTES, AttributeSection);
80 void RISCVTargetELFStreamer::finish() {
81 RISCVTargetStreamer::finish();
82 MCAssembler &MCA = getStreamer().getAssembler();
83 const FeatureBitset &Features = STI.getFeatureBits();
84 RISCVABI::ABI ABI = getTargetABI();
86 unsigned EFlags = MCA.getELFHeaderEFlags();
88 if (Features[RISCV::FeatureStdExtC])
89 EFlags |= ELF::EF_RISCV_RVC;
90 if (Features[RISCV::FeatureStdExtZtso])
91 EFlags |= ELF::EF_RISCV_TSO;
93 switch (ABI) {
94 case RISCVABI::ABI_ILP32:
95 case RISCVABI::ABI_LP64:
96 break;
97 case RISCVABI::ABI_ILP32F:
98 case RISCVABI::ABI_LP64F:
99 EFlags |= ELF::EF_RISCV_FLOAT_ABI_SINGLE;
100 break;
101 case RISCVABI::ABI_ILP32D:
102 case RISCVABI::ABI_LP64D:
103 EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE;
104 break;
105 case RISCVABI::ABI_ILP32E:
106 case RISCVABI::ABI_LP64E:
107 EFlags |= ELF::EF_RISCV_RVE;
108 break;
109 case RISCVABI::ABI_Unknown:
110 llvm_unreachable("Improperly initialised target ABI");
113 MCA.setELFHeaderEFlags(EFlags);
116 void RISCVTargetELFStreamer::reset() {
117 AttributeSection = nullptr;
120 void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) {
121 getStreamer().getAssembler().registerSymbol(Symbol);
122 cast<MCSymbolELF>(Symbol).setOther(ELF::STO_RISCV_VARIANT_CC);
125 void RISCVELFStreamer::reset() {
126 static_cast<RISCVTargetStreamer *>(getTargetStreamer())->reset();
127 MCELFStreamer::reset();
128 MappingSymbolCounter = 0;
129 LastMappingSymbols.clear();
130 LastEMS = EMS_None;
133 void RISCVELFStreamer::emitDataMappingSymbol() {
134 if (LastEMS == EMS_Data)
135 return;
136 emitMappingSymbol("$d");
137 LastEMS = EMS_Data;
140 void RISCVELFStreamer::emitInstructionsMappingSymbol() {
141 if (LastEMS == EMS_Instructions)
142 return;
143 emitMappingSymbol("$x");
144 LastEMS = EMS_Instructions;
147 void RISCVELFStreamer::emitMappingSymbol(StringRef Name) {
148 auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
149 Name + "." + Twine(MappingSymbolCounter++)));
150 emitLabel(Symbol);
151 Symbol->setType(ELF::STT_NOTYPE);
152 Symbol->setBinding(ELF::STB_LOCAL);
155 void RISCVELFStreamer::changeSection(MCSection *Section,
156 const MCExpr *Subsection) {
157 // We have to keep track of the mapping symbol state of any sections we
158 // use. Each one should start off as EMS_None, which is provided as the
159 // default constructor by DenseMap::lookup.
160 LastMappingSymbols[getPreviousSection().first] = LastEMS;
161 LastEMS = LastMappingSymbols.lookup(Section);
163 MCELFStreamer::changeSection(Section, Subsection);
166 void RISCVELFStreamer::emitInstruction(const MCInst &Inst,
167 const MCSubtargetInfo &STI) {
168 emitInstructionsMappingSymbol();
169 MCELFStreamer::emitInstruction(Inst, STI);
172 void RISCVELFStreamer::emitBytes(StringRef Data) {
173 emitDataMappingSymbol();
174 MCELFStreamer::emitBytes(Data);
177 void RISCVELFStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
178 SMLoc Loc) {
179 emitDataMappingSymbol();
180 MCELFStreamer::emitFill(NumBytes, FillValue, Loc);
183 void RISCVELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
184 SMLoc Loc) {
185 emitDataMappingSymbol();
186 MCELFStreamer::emitValueImpl(Value, Size, Loc);
189 namespace llvm {
190 MCELFStreamer *createRISCVELFStreamer(MCContext &C,
191 std::unique_ptr<MCAsmBackend> MAB,
192 std::unique_ptr<MCObjectWriter> MOW,
193 std::unique_ptr<MCCodeEmitter> MCE,
194 bool RelaxAll) {
195 RISCVELFStreamer *S =
196 new RISCVELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE));
197 S->getAssembler().setRelaxAll(RelaxAll);
198 return S;
200 } // namespace llvm