1 //===-- RISCVTargetStreamer.cpp - RISC-V Target Streamer Methods ----------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file provides RISC-V specific target streamer methods.
11 //===----------------------------------------------------------------------===//
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"
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"),
31 RISCVTargetStreamer::RISCVTargetStreamer(MCStreamer
&S
) : MCTargetStreamer(S
) {}
33 void RISCVTargetStreamer::finish() { finishAttributeSection(); }
34 void RISCVTargetStreamer::reset() {}
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
,
51 void RISCVTargetStreamer::emitIntTextAttribute(unsigned Attribute
,
53 StringRef StringValue
) {}
54 void RISCVTargetStreamer::setTargetABI(RISCVABI::ABI ABI
) {
55 assert(ABI
!= RISCVABI::ABI_Unknown
&& "Improperly initialized target ABI");
59 void RISCVTargetStreamer::setFlagsFromFeatures(const MCSubtargetInfo
&STI
) {
60 HasRVC
= STI
.hasFeature(RISCV::FeatureStdExtC
) ||
61 STI
.hasFeature(RISCV::FeatureStdExtZca
);
62 HasTSO
= STI
.hasFeature(RISCV::FeatureStdExtZtso
);
65 void RISCVTargetStreamer::emitTargetAttributes(const MCSubtargetInfo
&STI
,
66 bool EmitStackAlign
) {
69 if (TargetABI
== RISCVABI::ABI_ILP32E
)
71 else if (TargetABI
== RISCVABI::ABI_LP64E
)
75 emitAttribute(RISCVAttrs::STACK_ALIGN
, StackAlign
);
78 auto ParseResult
= RISCVFeatures::parseFeatureBits(
79 STI
.hasFeature(RISCV::Feature64Bit
), STI
.getFeatureBits());
81 report_fatal_error(ParseResult
.takeError());
83 auto &ISAInfo
= *ParseResult
;
84 emitTextAttribute(RISCVAttrs::ARCH
, ISAInfo
->toString());
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
);
96 // This part is for ascii assembly output
97 RISCVTargetAsmStreamer::RISCVTargetAsmStreamer(MCStreamer
&S
,
98 formatted_raw_ostream
&OS
)
99 : RISCVTargetStreamer(S
), OS(OS
) {}
101 void RISCVTargetAsmStreamer::emitDirectiveOptionPush() {
102 OS
<< "\t.option\tpush\n";
105 void RISCVTargetAsmStreamer::emitDirectiveOptionPop() {
106 OS
<< "\t.option\tpop\n";
109 void RISCVTargetAsmStreamer::emitDirectiveOptionPIC() {
110 OS
<< "\t.option\tpic\n";
113 void RISCVTargetAsmStreamer::emitDirectiveOptionNoPIC() {
114 OS
<< "\t.option\tnopic\n";
117 void RISCVTargetAsmStreamer::emitDirectiveOptionRVC() {
118 OS
<< "\t.option\trvc\n";
121 void RISCVTargetAsmStreamer::emitDirectiveOptionNoRVC() {
122 OS
<< "\t.option\tnorvc\n";
125 void RISCVTargetAsmStreamer::emitDirectiveOptionRelax() {
126 OS
<< "\t.option\trelax\n";
129 void RISCVTargetAsmStreamer::emitDirectiveOptionNoRelax() {
130 OS
<< "\t.option\tnorelax\n";
133 void RISCVTargetAsmStreamer::emitDirectiveOptionArch(
134 ArrayRef
<RISCVOptionArchArg
> Args
) {
135 OS
<< "\t.option\tarch";
136 for (const auto &Arg
: Args
) {
139 case RISCVOptionArchArgType::Full
:
141 case RISCVOptionArchArgType::Plus
:
144 case RISCVOptionArchArgType::Minus
:
153 void RISCVTargetAsmStreamer::emitDirectiveVariantCC(MCSymbol
&Symbol
) {
154 OS
<< "\t.variant_cc\t" << Symbol
.getName() << "\n";
157 void RISCVTargetAsmStreamer::emitAttribute(unsigned Attribute
, unsigned Value
) {
158 OS
<< "\t.attribute\t" << Attribute
<< ", " << Twine(Value
) << "\n";
161 void RISCVTargetAsmStreamer::emitTextAttribute(unsigned Attribute
,
163 OS
<< "\t.attribute\t" << Attribute
<< ", \"" << String
<< "\"\n";
166 void RISCVTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute
,
168 StringRef StringValue
) {}
170 void RISCVTargetAsmStreamer::finishAttributeSection() {}