1 //===-- RISCVTargetStreamer.cpp - RISC-V 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 "RISCVTargetStreamer.h" 14 #include "RISCVBaseInfo.h" 15 #include "RISCVMCTargetDesc.h" 16 #include "llvm/MC/MCSymbol.h" 17 #include "llvm/Support/CommandLine.h" 18 #include "llvm/Support/FormattedStream.h" 19 #include "llvm/Support/RISCVAttributes.h" 20 #include "llvm/TargetParser/RISCVISAInfo.h" 21 22 using namespace llvm; 23 24 // This option controls wether or not we emit ELF attributes for ABI features, 25 // like RISC-V atomics or X3 usage. 26 static cl::opt<bool> RiscvAbiAttr( 27 "riscv-abi-attributes", 28 cl::desc("Enable emitting RISC-V ELF attributes for ABI features"), 29 cl::Hidden); 30 31 RISCVTargetStreamer::RISCVTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} 32 33 void RISCVTargetStreamer::finish() { finishAttributeSection(); } 34 void RISCVTargetStreamer::reset() {} 35 36 void RISCVTargetStreamer::emitDirectiveOptionPush() {} 37 void RISCVTargetStreamer::emitDirectiveOptionPop() {} 38 void RISCVTargetStreamer::emitDirectiveOptionPIC() {} 39 void RISCVTargetStreamer::emitDirectiveOptionNoPIC() {} 40 void RISCVTargetStreamer::emitDirectiveOptionRVC() {} 41 void RISCVTargetStreamer::emitDirectiveOptionNoRVC() {} 42 void RISCVTargetStreamer::emitDirectiveOptionRelax() {} 43 void RISCVTargetStreamer::emitDirectiveOptionNoRelax() {} 44 void RISCVTargetStreamer::emitDirectiveOptionArch( 45 ArrayRef<RISCVOptionArchArg> Args) {} 46 void RISCVTargetStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) {} 47 void RISCVTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {} 48 void RISCVTargetStreamer::finishAttributeSection() {} 49 void RISCVTargetStreamer::emitTextAttribute(unsigned Attribute, 50 StringRef String) {} 51 void RISCVTargetStreamer::emitIntTextAttribute(unsigned Attribute, 52 unsigned IntValue, 53 StringRef StringValue) {} 54 void RISCVTargetStreamer::setTargetABI(RISCVABI::ABI ABI) { 55 assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialized target ABI"); 56 TargetABI = ABI; 57 } 58 59 void RISCVTargetStreamer::setFlagsFromFeatures(const MCSubtargetInfo &STI) { 60 HasRVC = STI.hasFeature(RISCV::FeatureStdExtC) || 61 STI.hasFeature(RISCV::FeatureStdExtZca); 62 HasTSO = STI.hasFeature(RISCV::FeatureStdExtZtso); 63 } 64 65 void RISCVTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI, 66 bool EmitStackAlign) { 67 if (EmitStackAlign) { 68 unsigned StackAlign; 69 if (TargetABI == RISCVABI::ABI_ILP32E) 70 StackAlign = 4; 71 else if (TargetABI == RISCVABI::ABI_LP64E) 72 StackAlign = 8; 73 else 74 StackAlign = 16; 75 emitAttribute(RISCVAttrs::STACK_ALIGN, StackAlign); 76 } 77 78 auto ParseResult = RISCVFeatures::parseFeatureBits( 79 STI.hasFeature(RISCV::Feature64Bit), STI.getFeatureBits()); 80 if (!ParseResult) { 81 report_fatal_error(ParseResult.takeError()); 82 } else { 83 auto &ISAInfo = *ParseResult; 84 emitTextAttribute(RISCVAttrs::ARCH, ISAInfo->toString()); 85 } 86 87 if (RiscvAbiAttr && STI.hasFeature(RISCV::FeatureStdExtA)) { 88 unsigned AtomicABITag = static_cast<unsigned>( 89 STI.hasFeature(RISCV::FeatureNoTrailingSeqCstFence) 90 ? RISCVAttrs::RISCVAtomicAbiTag::A6C 91 : RISCVAttrs::RISCVAtomicAbiTag::A6S); 92 emitAttribute(RISCVAttrs::ATOMIC_ABI, AtomicABITag); 93 } 94 } 95 96 // This part is for ascii assembly output 97 RISCVTargetAsmStreamer::RISCVTargetAsmStreamer(MCStreamer &S, 98 formatted_raw_ostream &OS) 99 : RISCVTargetStreamer(S), OS(OS) {} 100 101 void RISCVTargetAsmStreamer::emitDirectiveOptionPush() { 102 OS << "\t.option\tpush\n"; 103 } 104 105 void RISCVTargetAsmStreamer::emitDirectiveOptionPop() { 106 OS << "\t.option\tpop\n"; 107 } 108 109 void RISCVTargetAsmStreamer::emitDirectiveOptionPIC() { 110 OS << "\t.option\tpic\n"; 111 } 112 113 void RISCVTargetAsmStreamer::emitDirectiveOptionNoPIC() { 114 OS << "\t.option\tnopic\n"; 115 } 116 117 void RISCVTargetAsmStreamer::emitDirectiveOptionRVC() { 118 OS << "\t.option\trvc\n"; 119 } 120 121 void RISCVTargetAsmStreamer::emitDirectiveOptionNoRVC() { 122 OS << "\t.option\tnorvc\n"; 123 } 124 125 void RISCVTargetAsmStreamer::emitDirectiveOptionRelax() { 126 OS << "\t.option\trelax\n"; 127 } 128 129 void RISCVTargetAsmStreamer::emitDirectiveOptionNoRelax() { 130 OS << "\t.option\tnorelax\n"; 131 } 132 133 void RISCVTargetAsmStreamer::emitDirectiveOptionArch( 134 ArrayRef<RISCVOptionArchArg> Args) { 135 OS << "\t.option\tarch"; 136 for (const auto &Arg : Args) { 137 OS << ", "; 138 switch (Arg.Type) { 139 case RISCVOptionArchArgType::Full: 140 break; 141 case RISCVOptionArchArgType::Plus: 142 OS << "+"; 143 break; 144 case RISCVOptionArchArgType::Minus: 145 OS << "-"; 146 break; 147 } 148 OS << Arg.Value; 149 } 150 OS << "\n"; 151 } 152 153 void RISCVTargetAsmStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) { 154 OS << "\t.variant_cc\t" << Symbol.getName() << "\n"; 155 } 156 157 void RISCVTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 158 OS << "\t.attribute\t" << Attribute << ", " << Twine(Value) << "\n"; 159 } 160 161 void RISCVTargetAsmStreamer::emitTextAttribute(unsigned Attribute, 162 StringRef String) { 163 OS << "\t.attribute\t" << Attribute << ", \"" << String << "\"\n"; 164 } 165 166 void RISCVTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute, 167 unsigned IntValue, 168 StringRef StringValue) {} 169 170 void RISCVTargetAsmStreamer::finishAttributeSection() {} 171