1 //===-- RISCVMCTargetDesc.cpp - RISC-V Target Descriptions ----------------===//
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 descriptions.
11 //===----------------------------------------------------------------------===//
13 #include "RISCVMCTargetDesc.h"
14 #include "RISCVELFStreamer.h"
15 #include "RISCVInstPrinter.h"
16 #include "RISCVMCAsmInfo.h"
17 #include "RISCVMCObjectFileInfo.h"
18 #include "RISCVTargetStreamer.h"
19 #include "TargetInfo/RISCVTargetInfo.h"
20 #include "llvm/MC/MCAsmBackend.h"
21 #include "llvm/MC/MCAsmInfo.h"
22 #include "llvm/MC/MCCodeEmitter.h"
23 #include "llvm/MC/MCInstrAnalysis.h"
24 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/MC/MCObjectFileInfo.h"
26 #include "llvm/MC/MCObjectWriter.h"
27 #include "llvm/MC/MCRegisterInfo.h"
28 #include "llvm/MC/MCStreamer.h"
29 #include "llvm/MC/MCSubtargetInfo.h"
30 #include "llvm/MC/TargetRegistry.h"
31 #include "llvm/Support/ErrorHandling.h"
34 #define GET_INSTRINFO_MC_DESC
35 #define ENABLE_INSTR_PREDICATE_VERIFIER
36 #include "RISCVGenInstrInfo.inc"
38 #define GET_REGINFO_MC_DESC
39 #include "RISCVGenRegisterInfo.inc"
41 #define GET_SUBTARGETINFO_MC_DESC
42 #include "RISCVGenSubtargetInfo.inc"
44 namespace llvm::RISCVVInversePseudosTable
{
46 using namespace RISCV
;
48 #define GET_RISCVVInversePseudosTable_IMPL
49 #include "RISCVGenSearchableTables.inc"
51 } // namespace llvm::RISCVVInversePseudosTable
55 static MCInstrInfo
*createRISCVMCInstrInfo() {
56 MCInstrInfo
*X
= new MCInstrInfo();
57 InitRISCVMCInstrInfo(X
);
61 static MCRegisterInfo
*createRISCVMCRegisterInfo(const Triple
&TT
) {
62 MCRegisterInfo
*X
= new MCRegisterInfo();
63 InitRISCVMCRegisterInfo(X
, RISCV::X1
);
67 static MCAsmInfo
*createRISCVMCAsmInfo(const MCRegisterInfo
&MRI
,
69 const MCTargetOptions
&Options
) {
70 MCAsmInfo
*MAI
= new RISCVMCAsmInfo(TT
);
72 unsigned SP
= MRI
.getDwarfRegNum(RISCV::X2
, true);
73 MCCFIInstruction Inst
= MCCFIInstruction::cfiDefCfa(nullptr, SP
, 0);
74 MAI
->addInitialFrameState(Inst
);
79 static MCObjectFileInfo
*
80 createRISCVMCObjectFileInfo(MCContext
&Ctx
, bool PIC
,
81 bool LargeCodeModel
= false) {
82 MCObjectFileInfo
*MOFI
= new RISCVMCObjectFileInfo();
83 MOFI
->initMCObjectFileInfo(Ctx
, PIC
, LargeCodeModel
);
87 static MCSubtargetInfo
*createRISCVMCSubtargetInfo(const Triple
&TT
,
88 StringRef CPU
, StringRef FS
) {
89 if (CPU
.empty() || CPU
== "generic")
90 CPU
= TT
.isArch64Bit() ? "generic-rv64" : "generic-rv32";
92 return createRISCVMCSubtargetInfoImpl(TT
, CPU
, /*TuneCPU*/ CPU
, FS
);
95 static MCInstPrinter
*createRISCVMCInstPrinter(const Triple
&T
,
96 unsigned SyntaxVariant
,
98 const MCInstrInfo
&MII
,
99 const MCRegisterInfo
&MRI
) {
100 return new RISCVInstPrinter(MAI
, MII
, MRI
);
103 static MCTargetStreamer
*
104 createRISCVObjectTargetStreamer(MCStreamer
&S
, const MCSubtargetInfo
&STI
) {
105 const Triple
&TT
= STI
.getTargetTriple();
106 if (TT
.isOSBinFormatELF())
107 return new RISCVTargetELFStreamer(S
, STI
);
111 static MCTargetStreamer
*
112 createRISCVAsmTargetStreamer(MCStreamer
&S
, formatted_raw_ostream
&OS
,
113 MCInstPrinter
*InstPrint
) {
114 return new RISCVTargetAsmStreamer(S
, OS
);
117 static MCTargetStreamer
*createRISCVNullTargetStreamer(MCStreamer
&S
) {
118 return new RISCVTargetStreamer(S
);
123 class RISCVMCInstrAnalysis
: public MCInstrAnalysis
{
124 int64_t GPRState
[31] = {};
125 std::bitset
<31> GPRValidMask
;
127 static bool isGPR(MCRegister Reg
) {
128 return Reg
>= RISCV::X0
&& Reg
<= RISCV::X31
;
131 static unsigned getRegIndex(MCRegister Reg
) {
132 assert(isGPR(Reg
) && Reg
!= RISCV::X0
&& "Invalid GPR reg");
133 return Reg
- RISCV::X1
;
136 void setGPRState(MCRegister Reg
, std::optional
<int64_t> Value
) {
137 if (Reg
== RISCV::X0
)
140 auto Index
= getRegIndex(Reg
);
143 GPRState
[Index
] = *Value
;
144 GPRValidMask
.set(Index
);
146 GPRValidMask
.reset(Index
);
150 std::optional
<int64_t> getGPRState(MCRegister Reg
) const {
151 if (Reg
== RISCV::X0
)
154 auto Index
= getRegIndex(Reg
);
156 if (GPRValidMask
.test(Index
))
157 return GPRState
[Index
];
162 explicit RISCVMCInstrAnalysis(const MCInstrInfo
*Info
)
163 : MCInstrAnalysis(Info
) {}
165 void resetState() override
{ GPRValidMask
.reset(); }
167 void updateState(const MCInst
&Inst
, uint64_t Addr
) override
{
168 // Terminators mark the end of a basic block which means the sequentially
169 // next instruction will be the first of another basic block and the current
170 // state will typically not be valid anymore. For calls, we assume all
171 // registers may be clobbered by the callee (TODO: should we take the
172 // calling convention into account?).
173 if (isTerminator(Inst
) || isCall(Inst
)) {
178 switch (Inst
.getOpcode()) {
180 // Clear the state of all defined registers for instructions that we don't
181 // explicitly support.
182 auto NumDefs
= Info
->get(Inst
.getOpcode()).getNumDefs();
183 for (unsigned I
= 0; I
< NumDefs
; ++I
) {
184 auto DefReg
= Inst
.getOperand(I
).getReg();
186 setGPRState(DefReg
, std::nullopt
);
191 setGPRState(Inst
.getOperand(0).getReg(),
192 Addr
+ (Inst
.getOperand(1).getImm() << 12));
197 bool evaluateBranch(const MCInst
&Inst
, uint64_t Addr
, uint64_t Size
,
198 uint64_t &Target
) const override
{
199 if (isConditionalBranch(Inst
)) {
202 Imm
= Inst
.getOperand(1).getImm();
204 Imm
= Inst
.getOperand(2).getImm();
209 if (Inst
.getOpcode() == RISCV::C_JAL
|| Inst
.getOpcode() == RISCV::C_J
) {
210 Target
= Addr
+ Inst
.getOperand(0).getImm();
214 if (Inst
.getOpcode() == RISCV::JAL
) {
215 Target
= Addr
+ Inst
.getOperand(1).getImm();
219 if (Inst
.getOpcode() == RISCV::JALR
) {
220 if (auto TargetRegState
= getGPRState(Inst
.getOperand(1).getReg())) {
221 Target
= *TargetRegState
+ Inst
.getOperand(2).getImm();
231 bool isTerminator(const MCInst
&Inst
) const override
{
232 if (MCInstrAnalysis::isTerminator(Inst
))
235 switch (Inst
.getOpcode()) {
240 return Inst
.getOperand(0).getReg() == RISCV::X0
;
244 bool isCall(const MCInst
&Inst
) const override
{
245 if (MCInstrAnalysis::isCall(Inst
))
248 switch (Inst
.getOpcode()) {
253 return Inst
.getOperand(0).getReg() != RISCV::X0
;
257 bool isReturn(const MCInst
&Inst
) const override
{
258 if (MCInstrAnalysis::isReturn(Inst
))
261 switch (Inst
.getOpcode()) {
265 return Inst
.getOperand(0).getReg() == RISCV::X0
&&
266 maybeReturnAddress(Inst
.getOperand(1).getReg());
268 return maybeReturnAddress(Inst
.getOperand(0).getReg());
272 bool isBranch(const MCInst
&Inst
) const override
{
273 if (MCInstrAnalysis::isBranch(Inst
))
276 return isBranchImpl(Inst
);
279 bool isUnconditionalBranch(const MCInst
&Inst
) const override
{
280 if (MCInstrAnalysis::isUnconditionalBranch(Inst
))
283 return isBranchImpl(Inst
);
286 bool isIndirectBranch(const MCInst
&Inst
) const override
{
287 if (MCInstrAnalysis::isIndirectBranch(Inst
))
290 switch (Inst
.getOpcode()) {
294 return Inst
.getOperand(0).getReg() == RISCV::X0
&&
295 !maybeReturnAddress(Inst
.getOperand(1).getReg());
297 return !maybeReturnAddress(Inst
.getOperand(0).getReg());
302 static bool maybeReturnAddress(MCRegister Reg
) {
303 // X1 is used for normal returns, X5 for returns from outlined functions.
304 return Reg
== RISCV::X1
|| Reg
== RISCV::X5
;
307 static bool isBranchImpl(const MCInst
&Inst
) {
308 switch (Inst
.getOpcode()) {
312 return Inst
.getOperand(0).getReg() == RISCV::X0
;
314 return Inst
.getOperand(0).getReg() == RISCV::X0
&&
315 !maybeReturnAddress(Inst
.getOperand(1).getReg());
317 return !maybeReturnAddress(Inst
.getOperand(0).getReg());
322 } // end anonymous namespace
324 static MCInstrAnalysis
*createRISCVInstrAnalysis(const MCInstrInfo
*Info
) {
325 return new RISCVMCInstrAnalysis(Info
);
329 MCStreamer
*createRISCVELFStreamer(const Triple
&T
, MCContext
&Context
,
330 std::unique_ptr
<MCAsmBackend
> &&MAB
,
331 std::unique_ptr
<MCObjectWriter
> &&MOW
,
332 std::unique_ptr
<MCCodeEmitter
> &&MCE
) {
333 return createRISCVELFStreamer(Context
, std::move(MAB
), std::move(MOW
),
336 } // end anonymous namespace
338 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeRISCVTargetMC() {
339 for (Target
*T
: {&getTheRISCV32Target(), &getTheRISCV64Target()}) {
340 TargetRegistry::RegisterMCAsmInfo(*T
, createRISCVMCAsmInfo
);
341 TargetRegistry::RegisterMCObjectFileInfo(*T
, createRISCVMCObjectFileInfo
);
342 TargetRegistry::RegisterMCInstrInfo(*T
, createRISCVMCInstrInfo
);
343 TargetRegistry::RegisterMCRegInfo(*T
, createRISCVMCRegisterInfo
);
344 TargetRegistry::RegisterMCAsmBackend(*T
, createRISCVAsmBackend
);
345 TargetRegistry::RegisterMCCodeEmitter(*T
, createRISCVMCCodeEmitter
);
346 TargetRegistry::RegisterMCInstPrinter(*T
, createRISCVMCInstPrinter
);
347 TargetRegistry::RegisterMCSubtargetInfo(*T
, createRISCVMCSubtargetInfo
);
348 TargetRegistry::RegisterELFStreamer(*T
, createRISCVELFStreamer
);
349 TargetRegistry::RegisterObjectTargetStreamer(
350 *T
, createRISCVObjectTargetStreamer
);
351 TargetRegistry::RegisterMCInstrAnalysis(*T
, createRISCVInstrAnalysis
);
353 // Register the asm target streamer.
354 TargetRegistry::RegisterAsmTargetStreamer(*T
, createRISCVAsmTargetStreamer
);
355 // Register the null target streamer.
356 TargetRegistry::RegisterNullTargetStreamer(*T
,
357 createRISCVNullTargetStreamer
);