1 //===-- RISCVELFStreamer.cpp - RISC-V ELF 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 "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/MCObjectWriter.h"
23 #include "llvm/MC/MCSectionELF.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/MC/MCValue.h"
26 #include "llvm/Support/LEB128.h"
27 #include "llvm/Support/RISCVAttributes.h"
31 // This part is for ELF object output.
32 RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer
&S
,
33 const MCSubtargetInfo
&STI
)
34 : RISCVTargetStreamer(S
), CurrentVendor("riscv"), STI(STI
) {
35 MCAssembler
&MCA
= getStreamer().getAssembler();
36 const FeatureBitset
&Features
= STI
.getFeatureBits();
37 auto &MAB
= static_cast<RISCVAsmBackend
&>(MCA
.getBackend());
38 setTargetABI(RISCVABI::computeTargetABI(STI
.getTargetTriple(), Features
,
39 MAB
.getTargetOptions().getABIName()));
42 RISCVELFStreamer
&RISCVTargetELFStreamer::getStreamer() {
43 return static_cast<RISCVELFStreamer
&>(Streamer
);
46 void RISCVTargetELFStreamer::emitDirectiveOptionPush() {}
47 void RISCVTargetELFStreamer::emitDirectiveOptionPop() {}
48 void RISCVTargetELFStreamer::emitDirectiveOptionPIC() {}
49 void RISCVTargetELFStreamer::emitDirectiveOptionNoPIC() {}
50 void RISCVTargetELFStreamer::emitDirectiveOptionRVC() {}
51 void RISCVTargetELFStreamer::emitDirectiveOptionNoRVC() {}
52 void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {}
53 void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {}
55 void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute
, unsigned Value
) {
56 getStreamer().setAttributeItem(Attribute
, Value
, /*OverwriteExisting=*/true);
59 void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute
,
61 getStreamer().setAttributeItem(Attribute
, String
, /*OverwriteExisting=*/true);
64 void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute
,
66 StringRef StringValue
) {
67 getStreamer().setAttributeItems(Attribute
, IntValue
, StringValue
,
68 /*OverwriteExisting=*/true);
71 void RISCVTargetELFStreamer::finishAttributeSection() {
72 RISCVELFStreamer
&S
= getStreamer();
73 if (S
.Contents
.empty())
76 S
.emitAttributesSection(CurrentVendor
, ".riscv.attributes",
77 ELF::SHT_RISCV_ATTRIBUTES
, AttributeSection
);
80 void RISCVTargetELFStreamer::finish() {
81 RISCVTargetStreamer::finish();
82 MCAssembler
&MCA
= getStreamer().getAssembler();
83 const FeatureBitset
&Features
= STI
.getFeatureBits();
84 RISCVABI::ABI ABI
= getTargetABI();
86 unsigned EFlags
= MCA
.getELFHeaderEFlags();
88 if (Features
[RISCV::FeatureStdExtC
])
89 EFlags
|= ELF::EF_RISCV_RVC
;
90 if (Features
[RISCV::FeatureStdExtZtso
])
91 EFlags
|= ELF::EF_RISCV_TSO
;
94 case RISCVABI::ABI_ILP32
:
95 case RISCVABI::ABI_LP64
:
97 case RISCVABI::ABI_ILP32F
:
98 case RISCVABI::ABI_LP64F
:
99 EFlags
|= ELF::EF_RISCV_FLOAT_ABI_SINGLE
;
101 case RISCVABI::ABI_ILP32D
:
102 case RISCVABI::ABI_LP64D
:
103 EFlags
|= ELF::EF_RISCV_FLOAT_ABI_DOUBLE
;
105 case RISCVABI::ABI_ILP32E
:
106 case RISCVABI::ABI_LP64E
:
107 EFlags
|= ELF::EF_RISCV_RVE
;
109 case RISCVABI::ABI_Unknown
:
110 llvm_unreachable("Improperly initialised target ABI");
113 MCA
.setELFHeaderEFlags(EFlags
);
116 void RISCVTargetELFStreamer::reset() {
117 AttributeSection
= nullptr;
120 void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol
&Symbol
) {
121 getStreamer().getAssembler().registerSymbol(Symbol
);
122 cast
<MCSymbolELF
>(Symbol
).setOther(ELF::STO_RISCV_VARIANT_CC
);
125 void RISCVELFStreamer::reset() {
126 static_cast<RISCVTargetStreamer
*>(getTargetStreamer())->reset();
127 MCELFStreamer::reset();
128 MappingSymbolCounter
= 0;
129 LastMappingSymbols
.clear();
133 void RISCVELFStreamer::emitDataMappingSymbol() {
134 if (LastEMS
== EMS_Data
)
136 emitMappingSymbol("$d");
140 void RISCVELFStreamer::emitInstructionsMappingSymbol() {
141 if (LastEMS
== EMS_Instructions
)
143 emitMappingSymbol("$x");
144 LastEMS
= EMS_Instructions
;
147 void RISCVELFStreamer::emitMappingSymbol(StringRef Name
) {
148 auto *Symbol
= cast
<MCSymbolELF
>(getContext().getOrCreateSymbol(
149 Name
+ "." + Twine(MappingSymbolCounter
++)));
151 Symbol
->setType(ELF::STT_NOTYPE
);
152 Symbol
->setBinding(ELF::STB_LOCAL
);
155 void RISCVELFStreamer::changeSection(MCSection
*Section
,
156 const MCExpr
*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
,
179 emitDataMappingSymbol();
180 MCELFStreamer::emitFill(NumBytes
, FillValue
, Loc
);
183 void RISCVELFStreamer::emitValueImpl(const MCExpr
*Value
, unsigned Size
,
185 emitDataMappingSymbol();
186 MCELFStreamer::emitValueImpl(Value
, Size
, Loc
);
190 MCELFStreamer
*createRISCVELFStreamer(MCContext
&C
,
191 std::unique_ptr
<MCAsmBackend
> MAB
,
192 std::unique_ptr
<MCObjectWriter
> MOW
,
193 std::unique_ptr
<MCCodeEmitter
> MCE
,
195 RISCVELFStreamer
*S
=
196 new RISCVELFStreamer(C
, std::move(MAB
), std::move(MOW
), std::move(MCE
));
197 S
->getAssembler().setRelaxAll(RelaxAll
);