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