[RISCV] Add RVVConstraint to SiFive custom matrix multiply instructions. (#124055)
[llvm-project.git] / llvm / lib / Target / RISCV / MCTargetDesc / RISCVELFStreamer.cpp
blobea0e9fcde21cf9911760482f2316762c91925f82
1 //===-- RISCVELFStreamer.cpp - RISC-V ELF 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.
11 //===----------------------------------------------------------------------===//
13 #include "RISCVELFStreamer.h"
14 #include "RISCVAsmBackend.h"
15 #include "RISCVBaseInfo.h"
16 #include "RISCVMCTargetDesc.h"
17 #include "llvm/BinaryFormat/ELF.h"
18 #include "llvm/MC/MCAsmBackend.h"
19 #include "llvm/MC/MCAssembler.h"
20 #include "llvm/MC/MCCodeEmitter.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCELFObjectWriter.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
25 using namespace llvm;
27 // This part is for ELF object output.
28 RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S,
29 const MCSubtargetInfo &STI)
30 : RISCVTargetStreamer(S), CurrentVendor("riscv") {
31 MCAssembler &MCA = getStreamer().getAssembler();
32 const FeatureBitset &Features = STI.getFeatureBits();
33 auto &MAB = static_cast<RISCVAsmBackend &>(MCA.getBackend());
34 setTargetABI(RISCVABI::computeTargetABI(STI.getTargetTriple(), Features,
35 MAB.getTargetOptions().getABIName()));
36 setFlagsFromFeatures(STI);
37 // `j label` in `.option norelax; j label; .option relax; ...; label:` needs a
38 // relocation to ensure the jump target is correct after linking. This is due
39 // to a limitation that shouldForceRelocation has to make the decision upfront
40 // without knowing a possibly future .option relax. When RISCVAsmParser is used,
41 // its ParseInstruction may call setForceRelocs as well.
42 if (STI.hasFeature(RISCV::FeatureRelax))
43 static_cast<RISCVAsmBackend &>(MAB).setForceRelocs();
46 RISCVELFStreamer &RISCVTargetELFStreamer::getStreamer() {
47 return static_cast<RISCVELFStreamer &>(Streamer);
50 void RISCVTargetELFStreamer::emitDirectiveOptionPush() {}
51 void RISCVTargetELFStreamer::emitDirectiveOptionPop() {}
52 void RISCVTargetELFStreamer::emitDirectiveOptionPIC() {}
53 void RISCVTargetELFStreamer::emitDirectiveOptionNoPIC() {}
54 void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {}
55 void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {}
56 void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {}
57 void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {}
59 void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
60 getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true);
63 void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute,
64 StringRef String) {
65 getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true);
68 void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
69 unsigned IntValue,
70 StringRef StringValue) {
71 getStreamer().setAttributeItems(Attribute, IntValue, StringValue,
72 /*OverwriteExisting=*/true);
75 void RISCVTargetELFStreamer::finishAttributeSection() {
76 RISCVELFStreamer &S = getStreamer();
77 if (S.Contents.empty())
78 return;
80 S.emitAttributesSection(CurrentVendor, ".riscv.attributes",
81 ELF::SHT_RISCV_ATTRIBUTES, AttributeSection);
84 void RISCVTargetELFStreamer::finish() {
85 RISCVTargetStreamer::finish();
86 ELFObjectWriter &W = getStreamer().getWriter();
87 RISCVABI::ABI ABI = getTargetABI();
89 unsigned EFlags = W.getELFHeaderEFlags();
91 if (hasRVC())
92 EFlags |= ELF::EF_RISCV_RVC;
93 if (hasTSO())
94 EFlags |= ELF::EF_RISCV_TSO;
96 switch (ABI) {
97 case RISCVABI::ABI_ILP32:
98 case RISCVABI::ABI_LP64:
99 break;
100 case RISCVABI::ABI_ILP32F:
101 case RISCVABI::ABI_LP64F:
102 EFlags |= ELF::EF_RISCV_FLOAT_ABI_SINGLE;
103 break;
104 case RISCVABI::ABI_ILP32D:
105 case RISCVABI::ABI_LP64D:
106 EFlags |= ELF::EF_RISCV_FLOAT_ABI_DOUBLE;
107 break;
108 case RISCVABI::ABI_ILP32E:
109 case RISCVABI::ABI_LP64E:
110 EFlags |= ELF::EF_RISCV_RVE;
111 break;
112 case RISCVABI::ABI_Unknown:
113 llvm_unreachable("Improperly initialised target ABI");
116 W.setELFHeaderEFlags(EFlags);
119 void RISCVTargetELFStreamer::reset() {
120 AttributeSection = nullptr;
123 void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) {
124 getStreamer().getAssembler().registerSymbol(Symbol);
125 cast<MCSymbolELF>(Symbol).setOther(ELF::STO_RISCV_VARIANT_CC);
128 void RISCVELFStreamer::reset() {
129 static_cast<RISCVTargetStreamer *>(getTargetStreamer())->reset();
130 MCELFStreamer::reset();
131 LastMappingSymbols.clear();
132 LastEMS = EMS_None;
135 void RISCVELFStreamer::emitDataMappingSymbol() {
136 if (LastEMS == EMS_Data)
137 return;
138 emitMappingSymbol("$d");
139 LastEMS = EMS_Data;
142 void RISCVELFStreamer::emitInstructionsMappingSymbol() {
143 if (LastEMS == EMS_Instructions)
144 return;
145 emitMappingSymbol("$x");
146 LastEMS = EMS_Instructions;
149 void RISCVELFStreamer::emitMappingSymbol(StringRef Name) {
150 auto *Symbol = cast<MCSymbolELF>(getContext().createLocalSymbol(Name));
151 emitLabel(Symbol);
152 Symbol->setType(ELF::STT_NOTYPE);
153 Symbol->setBinding(ELF::STB_LOCAL);
156 void RISCVELFStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
157 // We have to keep track of the mapping symbol state of any sections we
158 // use. Each one should start off as EMS_None, which is provided as the
159 // default constructor by DenseMap::lookup.
160 LastMappingSymbols[getPreviousSection().first] = LastEMS;
161 LastEMS = LastMappingSymbols.lookup(Section);
163 MCELFStreamer::changeSection(Section, Subsection);
166 void RISCVELFStreamer::emitInstruction(const MCInst &Inst,
167 const MCSubtargetInfo &STI) {
168 emitInstructionsMappingSymbol();
169 MCELFStreamer::emitInstruction(Inst, STI);
172 void RISCVELFStreamer::emitBytes(StringRef Data) {
173 emitDataMappingSymbol();
174 MCELFStreamer::emitBytes(Data);
177 void RISCVELFStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
178 SMLoc Loc) {
179 emitDataMappingSymbol();
180 MCELFStreamer::emitFill(NumBytes, FillValue, Loc);
183 void RISCVELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
184 SMLoc Loc) {
185 emitDataMappingSymbol();
186 MCELFStreamer::emitValueImpl(Value, Size, Loc);
189 namespace llvm {
190 MCELFStreamer *createRISCVELFStreamer(MCContext &C,
191 std::unique_ptr<MCAsmBackend> MAB,
192 std::unique_ptr<MCObjectWriter> MOW,
193 std::unique_ptr<MCCodeEmitter> MCE) {
194 RISCVELFStreamer *S =
195 new RISCVELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE));
196 return S;
198 } // namespace llvm