xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
106c3fb27SDimitry Andric //===-- RISCVTargetStreamer.cpp - RISC-V Target Streamer Methods ----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
906c3fb27SDimitry Andric // This file provides RISC-V specific target streamer methods.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "RISCVTargetStreamer.h"
14349cc55cSDimitry Andric #include "RISCVBaseInfo.h"
15e8d8bef9SDimitry Andric #include "RISCVMCTargetDesc.h"
16bdd1243dSDimitry Andric #include "llvm/MC/MCSymbol.h"
17*0fca6ea1SDimitry Andric #include "llvm/Support/CommandLine.h"
180b57cec5SDimitry Andric #include "llvm/Support/FormattedStream.h"
195ffd83dbSDimitry Andric #include "llvm/Support/RISCVAttributes.h"
20*0fca6ea1SDimitry Andric #include "llvm/TargetParser/RISCVISAInfo.h"
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric using namespace llvm;
230b57cec5SDimitry Andric 
24*0fca6ea1SDimitry Andric // This option controls wether or not we emit ELF attributes for ABI features,
25*0fca6ea1SDimitry Andric // like RISC-V atomics or X3 usage.
26*0fca6ea1SDimitry Andric static cl::opt<bool> RiscvAbiAttr(
27*0fca6ea1SDimitry Andric     "riscv-abi-attributes",
28*0fca6ea1SDimitry Andric     cl::desc("Enable emitting RISC-V ELF attributes for ABI features"),
29*0fca6ea1SDimitry Andric     cl::Hidden);
30*0fca6ea1SDimitry Andric 
RISCVTargetStreamer(MCStreamer & S)310b57cec5SDimitry Andric RISCVTargetStreamer::RISCVTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
320b57cec5SDimitry Andric 
finish()335ffd83dbSDimitry Andric void RISCVTargetStreamer::finish() { finishAttributeSection(); }
reset()3481ad6265SDimitry Andric void RISCVTargetStreamer::reset() {}
355ffd83dbSDimitry Andric 
emitDirectiveOptionPush()365ffd83dbSDimitry Andric void RISCVTargetStreamer::emitDirectiveOptionPush() {}
emitDirectiveOptionPop()375ffd83dbSDimitry Andric void RISCVTargetStreamer::emitDirectiveOptionPop() {}
emitDirectiveOptionPIC()385ffd83dbSDimitry Andric void RISCVTargetStreamer::emitDirectiveOptionPIC() {}
emitDirectiveOptionNoPIC()395ffd83dbSDimitry Andric void RISCVTargetStreamer::emitDirectiveOptionNoPIC() {}
emitDirectiveOptionRVC()405ffd83dbSDimitry Andric void RISCVTargetStreamer::emitDirectiveOptionRVC() {}
emitDirectiveOptionNoRVC()415ffd83dbSDimitry Andric void RISCVTargetStreamer::emitDirectiveOptionNoRVC() {}
emitDirectiveOptionRelax()425ffd83dbSDimitry Andric void RISCVTargetStreamer::emitDirectiveOptionRelax() {}
emitDirectiveOptionNoRelax()435ffd83dbSDimitry Andric void RISCVTargetStreamer::emitDirectiveOptionNoRelax() {}
emitDirectiveOptionArch(ArrayRef<RISCVOptionArchArg> Args)4406c3fb27SDimitry Andric void RISCVTargetStreamer::emitDirectiveOptionArch(
4506c3fb27SDimitry Andric     ArrayRef<RISCVOptionArchArg> Args) {}
emitDirectiveVariantCC(MCSymbol & Symbol)46bdd1243dSDimitry Andric void RISCVTargetStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) {}
emitAttribute(unsigned Attribute,unsigned Value)475ffd83dbSDimitry Andric void RISCVTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {}
finishAttributeSection()485ffd83dbSDimitry Andric void RISCVTargetStreamer::finishAttributeSection() {}
emitTextAttribute(unsigned Attribute,StringRef String)495ffd83dbSDimitry Andric void RISCVTargetStreamer::emitTextAttribute(unsigned Attribute,
505ffd83dbSDimitry Andric                                             StringRef String) {}
emitIntTextAttribute(unsigned Attribute,unsigned IntValue,StringRef StringValue)515ffd83dbSDimitry Andric void RISCVTargetStreamer::emitIntTextAttribute(unsigned Attribute,
525ffd83dbSDimitry Andric                                                unsigned IntValue,
535ffd83dbSDimitry Andric                                                StringRef StringValue) {}
setTargetABI(RISCVABI::ABI ABI)5481ad6265SDimitry Andric void RISCVTargetStreamer::setTargetABI(RISCVABI::ABI ABI) {
5581ad6265SDimitry Andric   assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialized target ABI");
5681ad6265SDimitry Andric   TargetABI = ABI;
5781ad6265SDimitry Andric }
585ffd83dbSDimitry Andric 
setFlagsFromFeatures(const MCSubtargetInfo & STI)593a079333SDimitry Andric void RISCVTargetStreamer::setFlagsFromFeatures(const MCSubtargetInfo &STI) {
60*0fca6ea1SDimitry Andric   HasRVC = STI.hasFeature(RISCV::FeatureStdExtC) ||
61*0fca6ea1SDimitry Andric            STI.hasFeature(RISCV::FeatureStdExtZca);
623a079333SDimitry Andric   HasTSO = STI.hasFeature(RISCV::FeatureStdExtZtso);
633a079333SDimitry Andric }
643a079333SDimitry Andric 
emitTargetAttributes(const MCSubtargetInfo & STI,bool EmitStackAlign)6506c3fb27SDimitry Andric void RISCVTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI,
6606c3fb27SDimitry Andric                                                bool EmitStackAlign) {
677a6dacacSDimitry Andric   if (EmitStackAlign) {
68*0fca6ea1SDimitry Andric     unsigned StackAlign;
697a6dacacSDimitry Andric     if (TargetABI == RISCVABI::ABI_ILP32E)
70*0fca6ea1SDimitry Andric       StackAlign = 4;
717a6dacacSDimitry Andric     else if (TargetABI == RISCVABI::ABI_LP64E)
72*0fca6ea1SDimitry Andric       StackAlign = 8;
737a6dacacSDimitry Andric     else
74*0fca6ea1SDimitry Andric       StackAlign = 16;
75*0fca6ea1SDimitry Andric     emitAttribute(RISCVAttrs::STACK_ALIGN, StackAlign);
767a6dacacSDimitry Andric   }
775ffd83dbSDimitry Andric 
7881ad6265SDimitry Andric   auto ParseResult = RISCVFeatures::parseFeatureBits(
7981ad6265SDimitry Andric       STI.hasFeature(RISCV::Feature64Bit), STI.getFeatureBits());
80349cc55cSDimitry Andric   if (!ParseResult) {
8181ad6265SDimitry Andric     report_fatal_error(ParseResult.takeError());
82349cc55cSDimitry Andric   } else {
83349cc55cSDimitry Andric     auto &ISAInfo = *ParseResult;
84349cc55cSDimitry Andric     emitTextAttribute(RISCVAttrs::ARCH, ISAInfo->toString());
85349cc55cSDimitry Andric   }
86*0fca6ea1SDimitry Andric 
87*0fca6ea1SDimitry Andric   if (RiscvAbiAttr && STI.hasFeature(RISCV::FeatureStdExtA)) {
88*0fca6ea1SDimitry Andric     unsigned AtomicABITag = static_cast<unsigned>(
89*0fca6ea1SDimitry Andric         STI.hasFeature(RISCV::FeatureNoTrailingSeqCstFence)
90*0fca6ea1SDimitry Andric             ? RISCVAttrs::RISCVAtomicAbiTag::A6C
91*0fca6ea1SDimitry Andric             : RISCVAttrs::RISCVAtomicAbiTag::A6S);
92*0fca6ea1SDimitry Andric     emitAttribute(RISCVAttrs::ATOMIC_ABI, AtomicABITag);
93*0fca6ea1SDimitry Andric   }
945ffd83dbSDimitry Andric }
955ffd83dbSDimitry Andric 
960b57cec5SDimitry Andric // This part is for ascii assembly output
RISCVTargetAsmStreamer(MCStreamer & S,formatted_raw_ostream & OS)970b57cec5SDimitry Andric RISCVTargetAsmStreamer::RISCVTargetAsmStreamer(MCStreamer &S,
980b57cec5SDimitry Andric                                                formatted_raw_ostream &OS)
990b57cec5SDimitry Andric     : RISCVTargetStreamer(S), OS(OS) {}
1000b57cec5SDimitry Andric 
emitDirectiveOptionPush()1010b57cec5SDimitry Andric void RISCVTargetAsmStreamer::emitDirectiveOptionPush() {
1020b57cec5SDimitry Andric   OS << "\t.option\tpush\n";
1030b57cec5SDimitry Andric }
1040b57cec5SDimitry Andric 
emitDirectiveOptionPop()1050b57cec5SDimitry Andric void RISCVTargetAsmStreamer::emitDirectiveOptionPop() {
1060b57cec5SDimitry Andric   OS << "\t.option\tpop\n";
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric 
emitDirectiveOptionPIC()1095ffd83dbSDimitry Andric void RISCVTargetAsmStreamer::emitDirectiveOptionPIC() {
1105ffd83dbSDimitry Andric   OS << "\t.option\tpic\n";
1115ffd83dbSDimitry Andric }
1125ffd83dbSDimitry Andric 
emitDirectiveOptionNoPIC()1135ffd83dbSDimitry Andric void RISCVTargetAsmStreamer::emitDirectiveOptionNoPIC() {
1145ffd83dbSDimitry Andric   OS << "\t.option\tnopic\n";
1155ffd83dbSDimitry Andric }
1165ffd83dbSDimitry Andric 
emitDirectiveOptionRVC()1170b57cec5SDimitry Andric void RISCVTargetAsmStreamer::emitDirectiveOptionRVC() {
1180b57cec5SDimitry Andric   OS << "\t.option\trvc\n";
1190b57cec5SDimitry Andric }
1200b57cec5SDimitry Andric 
emitDirectiveOptionNoRVC()1210b57cec5SDimitry Andric void RISCVTargetAsmStreamer::emitDirectiveOptionNoRVC() {
1220b57cec5SDimitry Andric   OS << "\t.option\tnorvc\n";
1230b57cec5SDimitry Andric }
1240b57cec5SDimitry Andric 
emitDirectiveOptionRelax()1250b57cec5SDimitry Andric void RISCVTargetAsmStreamer::emitDirectiveOptionRelax() {
1260b57cec5SDimitry Andric   OS << "\t.option\trelax\n";
1270b57cec5SDimitry Andric }
1280b57cec5SDimitry Andric 
emitDirectiveOptionNoRelax()1290b57cec5SDimitry Andric void RISCVTargetAsmStreamer::emitDirectiveOptionNoRelax() {
1300b57cec5SDimitry Andric   OS << "\t.option\tnorelax\n";
1310b57cec5SDimitry Andric }
1325ffd83dbSDimitry Andric 
emitDirectiveOptionArch(ArrayRef<RISCVOptionArchArg> Args)13306c3fb27SDimitry Andric void RISCVTargetAsmStreamer::emitDirectiveOptionArch(
13406c3fb27SDimitry Andric     ArrayRef<RISCVOptionArchArg> Args) {
13506c3fb27SDimitry Andric   OS << "\t.option\tarch";
13606c3fb27SDimitry Andric   for (const auto &Arg : Args) {
13706c3fb27SDimitry Andric     OS << ", ";
13806c3fb27SDimitry Andric     switch (Arg.Type) {
13906c3fb27SDimitry Andric     case RISCVOptionArchArgType::Full:
14006c3fb27SDimitry Andric       break;
14106c3fb27SDimitry Andric     case RISCVOptionArchArgType::Plus:
14206c3fb27SDimitry Andric       OS << "+";
14306c3fb27SDimitry Andric       break;
14406c3fb27SDimitry Andric     case RISCVOptionArchArgType::Minus:
14506c3fb27SDimitry Andric       OS << "-";
14606c3fb27SDimitry Andric       break;
14706c3fb27SDimitry Andric     }
14806c3fb27SDimitry Andric     OS << Arg.Value;
14906c3fb27SDimitry Andric   }
15006c3fb27SDimitry Andric   OS << "\n";
15106c3fb27SDimitry Andric }
15206c3fb27SDimitry Andric 
emitDirectiveVariantCC(MCSymbol & Symbol)153bdd1243dSDimitry Andric void RISCVTargetAsmStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) {
154bdd1243dSDimitry Andric   OS << "\t.variant_cc\t" << Symbol.getName() << "\n";
155bdd1243dSDimitry Andric }
156bdd1243dSDimitry Andric 
emitAttribute(unsigned Attribute,unsigned Value)1575ffd83dbSDimitry Andric void RISCVTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
1585ffd83dbSDimitry Andric   OS << "\t.attribute\t" << Attribute << ", " << Twine(Value) << "\n";
1595ffd83dbSDimitry Andric }
1605ffd83dbSDimitry Andric 
emitTextAttribute(unsigned Attribute,StringRef String)1615ffd83dbSDimitry Andric void RISCVTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
1625ffd83dbSDimitry Andric                                                StringRef String) {
1635ffd83dbSDimitry Andric   OS << "\t.attribute\t" << Attribute << ", \"" << String << "\"\n";
1645ffd83dbSDimitry Andric }
1655ffd83dbSDimitry Andric 
emitIntTextAttribute(unsigned Attribute,unsigned IntValue,StringRef StringValue)1665ffd83dbSDimitry Andric void RISCVTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute,
1675ffd83dbSDimitry Andric                                                   unsigned IntValue,
1685ffd83dbSDimitry Andric                                                   StringRef StringValue) {}
1695ffd83dbSDimitry Andric 
finishAttributeSection()1705ffd83dbSDimitry Andric void RISCVTargetAsmStreamer::finishAttributeSection() {}
171