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