|  | //===-- RISCVTargetStreamer.cpp - RISC-V Target Streamer Methods ----------===// | 
|  | // | 
|  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | // See https://llvm.org/LICENSE.txt for license information. | 
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // This file provides RISC-V specific target streamer methods. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "RISCVTargetStreamer.h" | 
|  | #include "RISCVBaseInfo.h" | 
|  | #include "RISCVMCTargetDesc.h" | 
|  | #include "llvm/MC/MCSymbol.h" | 
|  | #include "llvm/Support/FormattedStream.h" | 
|  | #include "llvm/Support/RISCVAttributes.h" | 
|  | #include "llvm/TargetParser/RISCVISAInfo.h" | 
|  |  | 
|  | using namespace llvm; | 
|  |  | 
|  | RISCVTargetStreamer::RISCVTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} | 
|  |  | 
|  | void RISCVTargetStreamer::finish() { finishAttributeSection(); } | 
|  | void RISCVTargetStreamer::reset() {} | 
|  |  | 
|  | void RISCVTargetStreamer::emitDirectiveOptionPush() {} | 
|  | void RISCVTargetStreamer::emitDirectiveOptionPop() {} | 
|  | void RISCVTargetStreamer::emitDirectiveOptionPIC() {} | 
|  | void RISCVTargetStreamer::emitDirectiveOptionNoPIC() {} | 
|  | void RISCVTargetStreamer::emitDirectiveOptionRVC() {} | 
|  | void RISCVTargetStreamer::emitDirectiveOptionNoRVC() {} | 
|  | void RISCVTargetStreamer::emitDirectiveOptionRelax() {} | 
|  | void RISCVTargetStreamer::emitDirectiveOptionNoRelax() {} | 
|  | void RISCVTargetStreamer::emitDirectiveOptionArch( | 
|  | ArrayRef<RISCVOptionArchArg> Args) {} | 
|  | void RISCVTargetStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) {} | 
|  | void RISCVTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {} | 
|  | void RISCVTargetStreamer::finishAttributeSection() {} | 
|  | void RISCVTargetStreamer::emitTextAttribute(unsigned Attribute, | 
|  | StringRef String) {} | 
|  | void RISCVTargetStreamer::emitIntTextAttribute(unsigned Attribute, | 
|  | unsigned IntValue, | 
|  | StringRef StringValue) {} | 
|  | void RISCVTargetStreamer::setTargetABI(RISCVABI::ABI ABI) { | 
|  | assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialized target ABI"); | 
|  | TargetABI = ABI; | 
|  | } | 
|  |  | 
|  | void RISCVTargetStreamer::setFlagsFromFeatures(const MCSubtargetInfo &STI) { | 
|  | HasRVC = STI.hasFeature(RISCV::FeatureStdExtC) || | 
|  | STI.hasFeature(RISCV::FeatureStdExtZca); | 
|  | HasTSO = STI.hasFeature(RISCV::FeatureStdExtZtso); | 
|  | } | 
|  |  | 
|  | void RISCVTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI, | 
|  | bool EmitStackAlign) { | 
|  | if (EmitStackAlign) { | 
|  | unsigned StackAlign; | 
|  | if (TargetABI == RISCVABI::ABI_ILP32E) | 
|  | StackAlign = 4; | 
|  | else if (TargetABI == RISCVABI::ABI_LP64E) | 
|  | StackAlign = 8; | 
|  | else | 
|  | StackAlign = 16; | 
|  | emitAttribute(RISCVAttrs::STACK_ALIGN, StackAlign); | 
|  | } | 
|  |  | 
|  | auto ParseResult = RISCVFeatures::parseFeatureBits( | 
|  | STI.hasFeature(RISCV::Feature64Bit), STI.getFeatureBits()); | 
|  | if (!ParseResult) { | 
|  | report_fatal_error(ParseResult.takeError()); | 
|  | } else { | 
|  | auto &ISAInfo = *ParseResult; | 
|  | emitTextAttribute(RISCVAttrs::ARCH, ISAInfo->toString()); | 
|  | } | 
|  | } | 
|  |  | 
|  | // This part is for ascii assembly output | 
|  | RISCVTargetAsmStreamer::RISCVTargetAsmStreamer(MCStreamer &S, | 
|  | formatted_raw_ostream &OS) | 
|  | : RISCVTargetStreamer(S), OS(OS) {} | 
|  |  | 
|  | void RISCVTargetAsmStreamer::emitDirectiveOptionPush() { | 
|  | OS << "\t.option\tpush\n"; | 
|  | } | 
|  |  | 
|  | void RISCVTargetAsmStreamer::emitDirectiveOptionPop() { | 
|  | OS << "\t.option\tpop\n"; | 
|  | } | 
|  |  | 
|  | void RISCVTargetAsmStreamer::emitDirectiveOptionPIC() { | 
|  | OS << "\t.option\tpic\n"; | 
|  | } | 
|  |  | 
|  | void RISCVTargetAsmStreamer::emitDirectiveOptionNoPIC() { | 
|  | OS << "\t.option\tnopic\n"; | 
|  | } | 
|  |  | 
|  | void RISCVTargetAsmStreamer::emitDirectiveOptionRVC() { | 
|  | OS << "\t.option\trvc\n"; | 
|  | } | 
|  |  | 
|  | void RISCVTargetAsmStreamer::emitDirectiveOptionNoRVC() { | 
|  | OS << "\t.option\tnorvc\n"; | 
|  | } | 
|  |  | 
|  | void RISCVTargetAsmStreamer::emitDirectiveOptionRelax() { | 
|  | OS << "\t.option\trelax\n"; | 
|  | } | 
|  |  | 
|  | void RISCVTargetAsmStreamer::emitDirectiveOptionNoRelax() { | 
|  | OS << "\t.option\tnorelax\n"; | 
|  | } | 
|  |  | 
|  | void RISCVTargetAsmStreamer::emitDirectiveOptionArch( | 
|  | ArrayRef<RISCVOptionArchArg> Args) { | 
|  | OS << "\t.option\tarch"; | 
|  | for (const auto &Arg : Args) { | 
|  | OS << ", "; | 
|  | switch (Arg.Type) { | 
|  | case RISCVOptionArchArgType::Full: | 
|  | break; | 
|  | case RISCVOptionArchArgType::Plus: | 
|  | OS << "+"; | 
|  | break; | 
|  | case RISCVOptionArchArgType::Minus: | 
|  | OS << "-"; | 
|  | break; | 
|  | } | 
|  | OS << Arg.Value; | 
|  | } | 
|  | OS << "\n"; | 
|  | } | 
|  |  | 
|  | void RISCVTargetAsmStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) { | 
|  | OS << "\t.variant_cc\t" << Symbol.getName() << "\n"; | 
|  | } | 
|  |  | 
|  | void RISCVTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) { | 
|  | OS << "\t.attribute\t" << Attribute << ", " << Twine(Value) << "\n"; | 
|  | } | 
|  |  | 
|  | void RISCVTargetAsmStreamer::emitTextAttribute(unsigned Attribute, | 
|  | StringRef String) { | 
|  | OS << "\t.attribute\t" << Attribute << ", \"" << String << "\"\n"; | 
|  | } | 
|  |  | 
|  | void RISCVTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute, | 
|  | unsigned IntValue, | 
|  | StringRef StringValue) {} | 
|  |  | 
|  | void RISCVTargetAsmStreamer::finishAttributeSection() {} |