xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
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.
10 //
11 //===----------------------------------------------------------------------===//
12 
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/MCELFObjectWriter.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 
25 using namespace llvm;
26 
27 // This part is for ELF object output.
RISCVTargetELFStreamer(MCStreamer & S,const MCSubtargetInfo & STI)28 RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S,
29                                                const MCSubtargetInfo &STI)
30     : RISCVTargetStreamer(S), CurrentVendor("riscv") {
31   MCAssembler &MCA = getStreamer().getAssembler();
32   const FeatureBitset &Features = STI.getFeatureBits();
33   auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend());
34   setTargetABI(RISCVABI::computeTargetABI(STI.getTargetTriple(), Features,
35                                           MAB.getTargetOptions().getABIName()));
36   setFlagsFromFeatures(STI);
37 }
38 
getStreamer()39 RISCVELFStreamer &RISCVTargetELFStreamer::getStreamer() {
40   return static_cast<RISCVELFStreamer &>(Streamer);
41 }
42 
emitDirectiveOptionExact()43 void RISCVTargetELFStreamer::emitDirectiveOptionExact() {}
emitDirectiveOptionNoExact()44 void RISCVTargetELFStreamer::emitDirectiveOptionNoExact() {}
emitDirectiveOptionPIC()45 void RISCVTargetELFStreamer::emitDirectiveOptionPIC() {}
emitDirectiveOptionNoPIC()46 void RISCVTargetELFStreamer::emitDirectiveOptionNoPIC() {}
emitDirectiveOptionPop()47 void RISCVTargetELFStreamer::emitDirectiveOptionPop() {}
emitDirectiveOptionPush()48 void RISCVTargetELFStreamer::emitDirectiveOptionPush() {}
emitDirectiveOptionRelax()49 void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {}
emitDirectiveOptionNoRelax()50 void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {}
emitDirectiveOptionRVC()51 void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {}
emitDirectiveOptionNoRVC()52 void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {}
53 
emitAttribute(unsigned Attribute,unsigned Value)54 void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
55   getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);
56 }
57 
emitTextAttribute(unsigned Attribute,StringRef String)58 void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute,
59                                                StringRef String) {
60   getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
61 }
62 
emitIntTextAttribute(unsigned Attribute,unsigned IntValue,StringRef StringValue)63 void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
64                                                   unsigned IntValue,
65                                                   StringRef StringValue) {
66   getStreamer().setAttributeItems(Attribute, IntValue, StringValue,
67                                   /*OverwriteExisting=*/true);
68 }
69 
finishAttributeSection()70 void RISCVTargetELFStreamer::finishAttributeSection() {
71   RISCVELFStreamer &S = getStreamer();
72   if (S.Contents.empty())
73     return;
74 
75   S.emitAttributesSection(CurrentVendor, ".riscv.attributes",
76                           ELF::SHT_RISCV_ATTRIBUTES, AttributeSection);
77 }
78 
finish()79 void RISCVTargetELFStreamer::finish() {
80   RISCVTargetStreamer::finish();
81   ELFObjectWriter &W = getStreamer().getWriter();
82   RISCVABI::ABI ABI = getTargetABI();
83 
84   unsigned EFlags = W.getELFHeaderEFlags();
85 
86   if (hasRVC())
87     EFlags |= ELF::EF_RISCV_RVC;
88   if (hasTSO())
89     EFlags |= ELF::EF_RISCV_TSO;
90 
91   switch (ABI) {
92   case RISCVABI::ABI_ILP32:
93   case RISCVABI::ABI_LP64:
94     break;
95   case RISCVABI::ABI_ILP32F:
96   case RISCVABI::ABI_LP64F:
97     EFlags |= ELF::EF_RISCV_FLOAT_ABI_SINGLE;
98     break;
99   case RISCVABI::ABI_ILP32D:
100   case RISCVABI::ABI_LP64D:
101     EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE;
102     break;
103   case RISCVABI::ABI_ILP32E:
104   case RISCVABI::ABI_LP64E:
105     EFlags |= ELF::EF_RISCV_RVE;
106     break;
107   case RISCVABI::ABI_Unknown:
108     llvm_unreachable("Improperly initialised target ABI");
109   }
110 
111   W.setELFHeaderEFlags(EFlags);
112 }
113 
reset()114 void RISCVTargetELFStreamer::reset() {
115   AttributeSection = nullptr;
116 }
117 
emitDirectiveVariantCC(MCSymbol & Symbol)118 void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) {
119   getStreamer().getAssembler().registerSymbol(Symbol);
120   cast<MCSymbolELF>(Symbol).setOther(ELF::STO_RISCV_VARIANT_CC);
121 }
122 
reset()123 void RISCVELFStreamer::reset() {
124   static_cast<RISCVTargetStreamer *>(getTargetStreamer())->reset();
125   MCELFStreamer::reset();
126   LastMappingSymbols.clear();
127   LastEMS = EMS_None;
128 }
129 
emitDataMappingSymbol()130 void RISCVELFStreamer::emitDataMappingSymbol() {
131   if (LastEMS == EMS_Data)
132     return;
133   emitMappingSymbol("$d");
134   LastEMS = EMS_Data;
135 }
136 
emitInstructionsMappingSymbol()137 void RISCVELFStreamer::emitInstructionsMappingSymbol() {
138   if (LastEMS == EMS_Instructions)
139     return;
140   emitMappingSymbol("$x");
141   LastEMS = EMS_Instructions;
142 }
143 
emitMappingSymbol(StringRef Name)144 void RISCVELFStreamer::emitMappingSymbol(StringRef Name) {
145   auto *Symbol = cast<MCSymbolELF>(getContext().createLocalSymbol(Name));
146   emitLabel(Symbol);
147   Symbol->setType(ELF::STT_NOTYPE);
148   Symbol->setBinding(ELF::STB_LOCAL);
149 }
150 
changeSection(MCSection * Section,uint32_t Subsection)151 void RISCVELFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
152   // We have to keep track of the mapping symbol state of any sections we
153   // use. Each one should start off as EMS_None, which is provided as the
154   // default constructor by DenseMap::lookup.
155   LastMappingSymbols[getPreviousSection().first] = LastEMS;
156   LastEMS = LastMappingSymbols.lookup(Section);
157 
158   MCELFStreamer::changeSection(Section, Subsection);
159 }
160 
emitInstruction(const MCInst & Inst,const MCSubtargetInfo & STI)161 void RISCVELFStreamer::emitInstruction(const MCInst &Inst,
162                                        const MCSubtargetInfo &STI) {
163   emitInstructionsMappingSymbol();
164   MCELFStreamer::emitInstruction(Inst, STI);
165 }
166 
emitBytes(StringRef Data)167 void RISCVELFStreamer::emitBytes(StringRef Data) {
168   emitDataMappingSymbol();
169   MCELFStreamer::emitBytes(Data);
170 }
171 
emitFill(const MCExpr & NumBytes,uint64_t FillValue,SMLoc Loc)172 void RISCVELFStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
173                                 SMLoc Loc) {
174   emitDataMappingSymbol();
175   MCELFStreamer::emitFill(NumBytes, FillValue, Loc);
176 }
177 
emitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)178 void RISCVELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
179                                      SMLoc Loc) {
180   emitDataMappingSymbol();
181   MCELFStreamer::emitValueImpl(Value, Size, Loc);
182 }
183 
createRISCVELFStreamer(const Triple &,MCContext & C,std::unique_ptr<MCAsmBackend> && MAB,std::unique_ptr<MCObjectWriter> && MOW,std::unique_ptr<MCCodeEmitter> && MCE)184 MCStreamer *llvm::createRISCVELFStreamer(const Triple &, MCContext &C,
185                                          std::unique_ptr<MCAsmBackend> &&MAB,
186                                          std::unique_ptr<MCObjectWriter> &&MOW,
187                                          std::unique_ptr<MCCodeEmitter> &&MCE) {
188   return new RISCVELFStreamer(C, std::move(MAB), std::move(MOW),
189                               std::move(MCE));
190 }
191