Path: blob/main/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYELFStreamer.cpp
35294 views
//===-- CSKYELFStreamer.cpp - CSKY ELF Target Streamer Methods ------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file provides CSKY specific target streamer methods.9//10//===----------------------------------------------------------------------===//1112#include "CSKYELFStreamer.h"13#include "CSKYMCTargetDesc.h"14#include "MCTargetDesc/CSKYAsmBackend.h"15#include "MCTargetDesc/CSKYBaseInfo.h"16#include "llvm/BinaryFormat/ELF.h"17#include "llvm/MC/MCAssembler.h"18#include "llvm/MC/MCContext.h"19#include "llvm/MC/MCSectionELF.h"20#include "llvm/MC/MCSubtargetInfo.h"21#include "llvm/MC/MCSymbolELF.h"22#include "llvm/Support/CSKYAttributes.h"23#include "llvm/Support/Casting.h"24#include "llvm/Support/LEB128.h"25#include "llvm/TargetParser/CSKYTargetParser.h"2627using namespace llvm;2829// This part is for ELF object output.30CSKYTargetELFStreamer::CSKYTargetELFStreamer(MCStreamer &S,31const MCSubtargetInfo &STI)32: CSKYTargetStreamer(S), CurrentVendor("csky") {33ELFObjectWriter &W = getStreamer().getWriter();34const FeatureBitset &Features = STI.getFeatureBits();3536unsigned EFlags = W.getELFHeaderEFlags();3738EFlags |= ELF::EF_CSKY_ABIV2;3940if (Features[CSKY::ProcCK801])41EFlags |= ELF::EF_CSKY_801;42else if (Features[CSKY::ProcCK802])43EFlags |= ELF::EF_CSKY_802;44else if (Features[CSKY::ProcCK803])45EFlags |= ELF::EF_CSKY_803;46else if (Features[CSKY::ProcCK804])47EFlags |= ELF::EF_CSKY_803;48else if (Features[CSKY::ProcCK805])49EFlags |= ELF::EF_CSKY_805;50else if (Features[CSKY::ProcCK807])51EFlags |= ELF::EF_CSKY_807;52else if (Features[CSKY::ProcCK810])53EFlags |= ELF::EF_CSKY_810;54else if (Features[CSKY::ProcCK860])55EFlags |= ELF::EF_CSKY_860;56else57EFlags |= ELF::EF_CSKY_810;5859if (Features[CSKY::FeatureFPUV2_SF] || Features[CSKY::FeatureFPUV3_SF])60EFlags |= ELF::EF_CSKY_FLOAT;6162EFlags |= ELF::EF_CSKY_EFV1;6364W.setELFHeaderEFlags(EFlags);65}6667MCELFStreamer &CSKYTargetELFStreamer::getStreamer() {68return static_cast<MCELFStreamer &>(Streamer);69}7071void CSKYTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {72setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);73}7475void CSKYTargetELFStreamer::emitTextAttribute(unsigned Attribute,76StringRef String) {77setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);78}7980void CSKYTargetELFStreamer::finishAttributeSection() {81if (Contents.empty())82return;8384if (AttributeSection) {85Streamer.switchSection(AttributeSection);86} else {87MCAssembler &MCA = getStreamer().getAssembler();88AttributeSection = MCA.getContext().getELFSection(89".csky.attributes", ELF::SHT_CSKY_ATTRIBUTES, 0);90Streamer.switchSection(AttributeSection);91Streamer.emitInt8(ELFAttrs::Format_Version);92}9394// Vendor size + Vendor name + '\0'95const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;9697// Tag + Tag Size98const size_t TagHeaderSize = 1 + 4;99100const size_t ContentsSize = calculateContentSize();101102Streamer.emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize);103Streamer.emitBytes(CurrentVendor);104Streamer.emitInt8(0); // '\0'105106Streamer.emitInt8(ELFAttrs::File);107Streamer.emitInt32(TagHeaderSize + ContentsSize);108109// Size should have been accounted for already, now110// emit each field as its type (ULEB or String).111for (AttributeItem item : Contents) {112Streamer.emitULEB128IntValue(item.Tag);113switch (item.Type) {114default:115llvm_unreachable("Invalid attribute type");116case AttributeType::Numeric:117Streamer.emitULEB128IntValue(item.IntValue);118break;119case AttributeType::Text:120Streamer.emitBytes(item.StringValue);121Streamer.emitInt8(0); // '\0'122break;123case AttributeType::NumericAndText:124Streamer.emitULEB128IntValue(item.IntValue);125Streamer.emitBytes(item.StringValue);126Streamer.emitInt8(0); // '\0'127break;128}129}130131Contents.clear();132}133134size_t CSKYTargetELFStreamer::calculateContentSize() const {135size_t Result = 0;136for (AttributeItem item : Contents) {137switch (item.Type) {138case AttributeType::Hidden:139break;140case AttributeType::Numeric:141Result += getULEB128Size(item.Tag);142Result += getULEB128Size(item.IntValue);143break;144case AttributeType::Text:145Result += getULEB128Size(item.Tag);146Result += item.StringValue.size() + 1; // string + '\0'147break;148case AttributeType::NumericAndText:149Result += getULEB128Size(item.Tag);150Result += getULEB128Size(item.IntValue);151Result += item.StringValue.size() + 1; // string + '\0';152break;153}154}155return Result;156}157158void CSKYELFStreamer::EmitMappingSymbol(StringRef Name) {159if (Name == "$d" && State == EMS_Data)160return;161if (Name == "$t" && State == EMS_Text)162return;163if (Name == "$t" && State == EMS_None) {164State = EMS_Text;165return;166}167168State = (Name == "$t" ? EMS_Text : EMS_Data);169170auto *Symbol = cast<MCSymbolELF>(getContext().createLocalSymbol(Name));171emitLabel(Symbol);172173Symbol->setType(ELF::STT_NOTYPE);174Symbol->setBinding(ELF::STB_LOCAL);175}176177void CSKYTargetELFStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {178StringRef CPU = STI.getCPU();179CSKY::ArchKind ArchID = CSKY::parseCPUArch(CPU);180181if (ArchID == CSKY::ArchKind::CK804)182ArchID = CSKY::ArchKind::CK803;183184StringRef CPU_ARCH = CSKY::getArchName(ArchID);185186if (ArchID == CSKY::ArchKind::INVALID) {187CPU = "ck810";188CPU_ARCH = "ck810";189}190emitTextAttribute(CSKYAttrs::CSKY_ARCH_NAME, CPU_ARCH);191emitTextAttribute(CSKYAttrs::CSKY_CPU_NAME, CPU);192193unsigned ISAFlag = 0;194if (STI.hasFeature(CSKY::HasE1))195ISAFlag |= CSKYAttrs::V2_ISA_E1;196197if (STI.hasFeature(CSKY::HasE2))198ISAFlag |= CSKYAttrs::V2_ISA_1E2;199200if (STI.hasFeature(CSKY::Has2E3))201ISAFlag |= CSKYAttrs::V2_ISA_2E3;202203if (STI.hasFeature(CSKY::HasMP))204ISAFlag |= CSKYAttrs::ISA_MP;205206if (STI.hasFeature(CSKY::Has3E3r1))207ISAFlag |= CSKYAttrs::V2_ISA_3E3R1;208209if (STI.hasFeature(CSKY::Has3r1E3r2))210ISAFlag |= CSKYAttrs::V2_ISA_3E3R2;211212if (STI.hasFeature(CSKY::Has3r2E3r3))213ISAFlag |= CSKYAttrs::V2_ISA_3E3R3;214215if (STI.hasFeature(CSKY::Has3E7))216ISAFlag |= CSKYAttrs::V2_ISA_3E7;217218if (STI.hasFeature(CSKY::HasMP1E2))219ISAFlag |= CSKYAttrs::ISA_MP_1E2;220221if (STI.hasFeature(CSKY::Has7E10))222ISAFlag |= CSKYAttrs::V2_ISA_7E10;223224if (STI.hasFeature(CSKY::Has10E60))225ISAFlag |= CSKYAttrs::V2_ISA_10E60;226227if (STI.hasFeature(CSKY::FeatureTrust))228ISAFlag |= CSKYAttrs::ISA_TRUST;229230if (STI.hasFeature(CSKY::FeatureJAVA))231ISAFlag |= CSKYAttrs::ISA_JAVA;232233if (STI.hasFeature(CSKY::FeatureCache))234ISAFlag |= CSKYAttrs::ISA_CACHE;235236if (STI.hasFeature(CSKY::FeatureNVIC))237ISAFlag |= CSKYAttrs::ISA_NVIC;238239if (STI.hasFeature(CSKY::FeatureDSP))240ISAFlag |= CSKYAttrs::ISA_DSP;241242if (STI.hasFeature(CSKY::HasDSP1E2))243ISAFlag |= CSKYAttrs::ISA_DSP_1E2;244245if (STI.hasFeature(CSKY::HasDSPE60))246ISAFlag |= CSKYAttrs::V2_ISA_DSPE60;247248if (STI.hasFeature(CSKY::FeatureDSPV2))249ISAFlag |= CSKYAttrs::ISA_DSP_ENHANCE;250251if (STI.hasFeature(CSKY::FeatureDSP_Silan))252ISAFlag |= CSKYAttrs::ISA_DSP_SILAN;253254if (STI.hasFeature(CSKY::FeatureVDSPV1_128))255ISAFlag |= CSKYAttrs::ISA_VDSP;256257if (STI.hasFeature(CSKY::FeatureVDSPV2))258ISAFlag |= CSKYAttrs::ISA_VDSP_2;259260if (STI.hasFeature(CSKY::HasVDSP2E3))261ISAFlag |= CSKYAttrs::ISA_VDSP_2E3;262263if (STI.hasFeature(CSKY::HasVDSP2E60F))264ISAFlag |= CSKYAttrs::ISA_VDSP_2E60F;265266emitAttribute(CSKYAttrs::CSKY_ISA_FLAGS, ISAFlag);267268unsigned ISAExtFlag = 0;269if (STI.hasFeature(CSKY::HasFLOATE1))270ISAExtFlag |= CSKYAttrs::ISA_FLOAT_E1;271272if (STI.hasFeature(CSKY::HasFLOAT1E2))273ISAExtFlag |= CSKYAttrs::ISA_FLOAT_1E2;274275if (STI.hasFeature(CSKY::HasFLOAT1E3))276ISAExtFlag |= CSKYAttrs::ISA_FLOAT_1E3;277278if (STI.hasFeature(CSKY::HasFLOAT3E4))279ISAExtFlag |= CSKYAttrs::ISA_FLOAT_3E4;280281if (STI.hasFeature(CSKY::HasFLOAT7E60))282ISAExtFlag |= CSKYAttrs::ISA_FLOAT_7E60;283284emitAttribute(CSKYAttrs::CSKY_ISA_EXT_FLAGS, ISAExtFlag);285286if (STI.hasFeature(CSKY::FeatureDSP))287emitAttribute(CSKYAttrs::CSKY_DSP_VERSION,288CSKYAttrs::DSP_VERSION_EXTENSION);289if (STI.hasFeature(CSKY::FeatureDSPV2))290emitAttribute(CSKYAttrs::CSKY_DSP_VERSION, CSKYAttrs::DSP_VERSION_2);291292if (STI.hasFeature(CSKY::FeatureVDSPV2))293emitAttribute(CSKYAttrs::CSKY_VDSP_VERSION, CSKYAttrs::VDSP_VERSION_2);294295if (STI.hasFeature(CSKY::FeatureFPUV2_SF) ||296STI.hasFeature(CSKY::FeatureFPUV2_DF))297emitAttribute(CSKYAttrs::CSKY_FPU_VERSION, CSKYAttrs::FPU_VERSION_2);298else if (STI.hasFeature(CSKY::FeatureFPUV3_HF) ||299STI.hasFeature(CSKY::FeatureFPUV3_SF) ||300STI.hasFeature(CSKY::FeatureFPUV3_DF))301emitAttribute(CSKYAttrs::CSKY_FPU_VERSION, CSKYAttrs::FPU_VERSION_3);302303bool hasAnyFloatExt = STI.hasFeature(CSKY::FeatureFPUV2_SF) ||304STI.hasFeature(CSKY::FeatureFPUV2_DF) ||305STI.hasFeature(CSKY::FeatureFPUV3_HF) ||306STI.hasFeature(CSKY::FeatureFPUV3_SF) ||307STI.hasFeature(CSKY::FeatureFPUV3_DF);308309if (hasAnyFloatExt && STI.hasFeature(CSKY::ModeHardFloat) &&310STI.hasFeature(CSKY::ModeHardFloatABI))311emitAttribute(CSKYAttrs::CSKY_FPU_ABI, CSKYAttrs::FPU_ABI_HARD);312else if (hasAnyFloatExt && STI.hasFeature(CSKY::ModeHardFloat))313emitAttribute(CSKYAttrs::CSKY_FPU_ABI, CSKYAttrs::FPU_ABI_SOFTFP);314else315emitAttribute(CSKYAttrs::CSKY_FPU_ABI, CSKYAttrs::FPU_ABI_SOFT);316317unsigned HardFPFlag = 0;318if (STI.hasFeature(CSKY::FeatureFPUV3_HF))319HardFPFlag |= CSKYAttrs::FPU_HARDFP_HALF;320if (STI.hasFeature(CSKY::FeatureFPUV2_SF) ||321STI.hasFeature(CSKY::FeatureFPUV3_SF))322HardFPFlag |= CSKYAttrs::FPU_HARDFP_SINGLE;323if (STI.hasFeature(CSKY::FeatureFPUV2_DF) ||324STI.hasFeature(CSKY::FeatureFPUV3_DF))325HardFPFlag |= CSKYAttrs::FPU_HARDFP_DOUBLE;326327if (HardFPFlag != 0) {328emitAttribute(CSKYAttrs::CSKY_FPU_DENORMAL, CSKYAttrs::NEEDED);329emitAttribute(CSKYAttrs::CSKY_FPU_EXCEPTION, CSKYAttrs::NEEDED);330emitTextAttribute(CSKYAttrs::CSKY_FPU_NUMBER_MODULE, "IEEE 754");331emitAttribute(CSKYAttrs::CSKY_FPU_HARDFP, HardFPFlag);332}333}334335336