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/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"
28 
29 using namespace llvm;
30 
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()));
40 }
41 
42 RISCVELFStreamer &RISCVTargetELFStreamer::getStreamer() {
43   return static_cast<RISCVELFStreamer &>(Streamer);
44 }
45 
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() {}
54 
55 void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
56   getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);
57 }
58 
59 void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute,
60                                                StringRef String) {
61   getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
62 }
63 
64 void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
65                                                   unsigned IntValue,
66                                                   StringRef StringValue) {
67   getStreamer().setAttributeItems(Attribute, IntValue, StringValue,
68                                   /*OverwriteExisting=*/true);
69 }
70 
71 void RISCVTargetELFStreamer::finishAttributeSection() {
72   RISCVELFStreamer &S = getStreamer();
73   if (S.Contents.empty())
74     return;
75 
76   S.emitAttributesSection(CurrentVendor, ".riscv.attributes",
77                           ELF::SHT_RISCV_ATTRIBUTES, AttributeSection);
78 }
79 
80 void RISCVTargetELFStreamer::finish() {
81   RISCVTargetStreamer::finish();
82   MCAssembler &MCA = getStreamer().getAssembler();
83   const FeatureBitset &Features = STI.getFeatureBits();
84   RISCVABI::ABI ABI = getTargetABI();
85 
86   unsigned EFlags = MCA.getELFHeaderEFlags();
87 
88   if (Features[RISCV::FeatureStdExtC])
89     EFlags |= ELF::EF_RISCV_RVC;
90   if (Features[RISCV::FeatureStdExtZtso])
91     EFlags |= ELF::EF_RISCV_TSO;
92 
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");
111   }
112 
113   MCA.setELFHeaderEFlags(EFlags);
114 }
115 
116 void RISCVTargetELFStreamer::reset() {
117   AttributeSection = nullptr;
118 }
119 
120 void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) {
121   getStreamer().getAssembler().registerSymbol(Symbol);
122   cast<MCSymbolELF>(Symbol).setOther(ELF::STO_RISCV_VARIANT_CC);
123 }
124 
125 void RISCVELFStreamer::reset() {
126   static_cast<RISCVTargetStreamer *>(getTargetStreamer())->reset();
127   MCELFStreamer::reset();
128 }
129 
130 namespace llvm {
131 MCELFStreamer *createRISCVELFStreamer(MCContext &C,
132                                       std::unique_ptr<MCAsmBackend> MAB,
133                                       std::unique_ptr<MCObjectWriter> MOW,
134                                       std::unique_ptr<MCCodeEmitter> MCE,
135                                       bool RelaxAll) {
136   RISCVELFStreamer *S =
137       new RISCVELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE));
138   S->getAssembler().setRelaxAll(RelaxAll);
139   return S;
140 }
141 } // namespace llvm
142