brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.8 KiB · 37fe325 Raw
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