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 "RISCVBaseInfo.h"
15 #include "RISCVELFStreamer.h"
16 #include "RISCVInstPrinter.h"
17 #include "RISCVMCAsmInfo.h"
18 #include "RISCVMCObjectFileInfo.h"
19 #include "RISCVTargetStreamer.h"
20 #include "TargetInfo/RISCVTargetInfo.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/MC/MCAsmBackend.h"
23 #include "llvm/MC/MCAsmInfo.h"
24 #include "llvm/MC/MCCodeEmitter.h"
25 #include "llvm/MC/MCInstrAnalysis.h"
26 #include "llvm/MC/MCInstrInfo.h"
27 #include "llvm/MC/MCObjectFileInfo.h"
28 #include "llvm/MC/MCObjectWriter.h"
29 #include "llvm/MC/MCRegisterInfo.h"
30 #include "llvm/MC/MCStreamer.h"
31 #include "llvm/MC/MCSubtargetInfo.h"
32 #include "llvm/MC/TargetRegistry.h"
33 #include "llvm/Support/ErrorHandling.h"
36 #define GET_INSTRINFO_MC_DESC
37 #define ENABLE_INSTR_PREDICATE_VERIFIER
38 #include "RISCVGenInstrInfo.inc"
40 #define GET_REGINFO_MC_DESC
41 #include "RISCVGenRegisterInfo.inc"
43 #define GET_SUBTARGETINFO_MC_DESC
44 #include "RISCVGenSubtargetInfo.inc"
48 static MCInstrInfo
*createRISCVMCInstrInfo() {
49 MCInstrInfo
*X
= new MCInstrInfo();
50 InitRISCVMCInstrInfo(X
);
54 static MCRegisterInfo
*createRISCVMCRegisterInfo(const Triple
&TT
) {
55 MCRegisterInfo
*X
= new MCRegisterInfo();
56 InitRISCVMCRegisterInfo(X
, RISCV::X1
);
60 static MCAsmInfo
*createRISCVMCAsmInfo(const MCRegisterInfo
&MRI
,
62 const MCTargetOptions
&Options
) {
63 MCAsmInfo
*MAI
= new RISCVMCAsmInfo(TT
);
65 MCRegister SP
= MRI
.getDwarfRegNum(RISCV::X2
, true);
66 MCCFIInstruction Inst
= MCCFIInstruction::cfiDefCfa(nullptr, SP
, 0);
67 MAI
->addInitialFrameState(Inst
);
72 static MCObjectFileInfo
*
73 createRISCVMCObjectFileInfo(MCContext
&Ctx
, bool PIC
,
74 bool LargeCodeModel
= false) {
75 MCObjectFileInfo
*MOFI
= new RISCVMCObjectFileInfo();
76 MOFI
->initMCObjectFileInfo(Ctx
, PIC
, LargeCodeModel
);
80 static MCSubtargetInfo
*createRISCVMCSubtargetInfo(const Triple
&TT
,
81 StringRef CPU
, StringRef FS
) {
82 if (CPU
.empty() || CPU
== "generic")
83 CPU
= TT
.isArch64Bit() ? "generic-rv64" : "generic-rv32";
85 return createRISCVMCSubtargetInfoImpl(TT
, CPU
, /*TuneCPU*/ CPU
, FS
);
88 static MCInstPrinter
*createRISCVMCInstPrinter(const Triple
&T
,
89 unsigned SyntaxVariant
,
91 const MCInstrInfo
&MII
,
92 const MCRegisterInfo
&MRI
) {
93 return new RISCVInstPrinter(MAI
, MII
, MRI
);
96 static MCTargetStreamer
*
97 createRISCVObjectTargetStreamer(MCStreamer
&S
, const MCSubtargetInfo
&STI
) {
98 const Triple
&TT
= STI
.getTargetTriple();
99 if (TT
.isOSBinFormatELF())
100 return new RISCVTargetELFStreamer(S
, STI
);
104 static MCTargetStreamer
*createRISCVAsmTargetStreamer(MCStreamer
&S
,
105 formatted_raw_ostream
&OS
,
106 MCInstPrinter
*InstPrint
,
108 return new RISCVTargetAsmStreamer(S
, OS
);
111 static MCTargetStreamer
*createRISCVNullTargetStreamer(MCStreamer
&S
) {
112 return new RISCVTargetStreamer(S
);
117 class RISCVMCInstrAnalysis
: public MCInstrAnalysis
{
118 int64_t GPRState
[31] = {};
119 std::bitset
<31> GPRValidMask
;
121 static bool isGPR(unsigned Reg
) {
122 return Reg
>= RISCV::X0
&& Reg
<= RISCV::X31
;
125 static unsigned getRegIndex(unsigned Reg
) {
126 assert(isGPR(Reg
) && Reg
!= RISCV::X0
&& "Invalid GPR reg");
127 return Reg
- RISCV::X1
;
130 void setGPRState(unsigned Reg
, std::optional
<int64_t> Value
) {
131 if (Reg
== RISCV::X0
)
134 auto Index
= getRegIndex(Reg
);
137 GPRState
[Index
] = *Value
;
138 GPRValidMask
.set(Index
);
140 GPRValidMask
.reset(Index
);
144 std::optional
<int64_t> getGPRState(unsigned Reg
) const {
145 if (Reg
== RISCV::X0
)
148 auto Index
= getRegIndex(Reg
);
150 if (GPRValidMask
.test(Index
))
151 return GPRState
[Index
];
156 explicit RISCVMCInstrAnalysis(const MCInstrInfo
*Info
)
157 : MCInstrAnalysis(Info
) {}
159 void resetState() override
{ GPRValidMask
.reset(); }
161 void updateState(const MCInst
&Inst
, uint64_t Addr
) override
{
162 // Terminators mark the end of a basic block which means the sequentially
163 // next instruction will be the first of another basic block and the current
164 // state will typically not be valid anymore. For calls, we assume all
165 // registers may be clobbered by the callee (TODO: should we take the
166 // calling convention into account?).
167 if (isTerminator(Inst
) || isCall(Inst
)) {
172 switch (Inst
.getOpcode()) {
174 // Clear the state of all defined registers for instructions that we don't
175 // explicitly support.
176 auto NumDefs
= Info
->get(Inst
.getOpcode()).getNumDefs();
177 for (unsigned I
= 0; I
< NumDefs
; ++I
) {
178 auto DefReg
= Inst
.getOperand(I
).getReg();
180 setGPRState(DefReg
, std::nullopt
);
185 setGPRState(Inst
.getOperand(0).getReg(),
186 Addr
+ (Inst
.getOperand(1).getImm() << 12));
191 bool evaluateBranch(const MCInst
&Inst
, uint64_t Addr
, uint64_t Size
,
192 uint64_t &Target
) const override
{
193 if (isConditionalBranch(Inst
)) {
196 Imm
= Inst
.getOperand(1).getImm();
198 Imm
= Inst
.getOperand(2).getImm();
203 if (Inst
.getOpcode() == RISCV::C_JAL
|| Inst
.getOpcode() == RISCV::C_J
) {
204 Target
= Addr
+ Inst
.getOperand(0).getImm();
208 if (Inst
.getOpcode() == RISCV::JAL
) {
209 Target
= Addr
+ Inst
.getOperand(1).getImm();
213 if (Inst
.getOpcode() == RISCV::JALR
) {
214 if (auto TargetRegState
= getGPRState(Inst
.getOperand(1).getReg())) {
215 Target
= *TargetRegState
+ Inst
.getOperand(2).getImm();
225 bool isTerminator(const MCInst
&Inst
) const override
{
226 if (MCInstrAnalysis::isTerminator(Inst
))
229 switch (Inst
.getOpcode()) {
234 return Inst
.getOperand(0).getReg() == RISCV::X0
;
238 bool isCall(const MCInst
&Inst
) const override
{
239 if (MCInstrAnalysis::isCall(Inst
))
242 switch (Inst
.getOpcode()) {
247 return Inst
.getOperand(0).getReg() != RISCV::X0
;
251 bool isReturn(const MCInst
&Inst
) const override
{
252 if (MCInstrAnalysis::isReturn(Inst
))
255 switch (Inst
.getOpcode()) {
259 return Inst
.getOperand(0).getReg() == RISCV::X0
&&
260 maybeReturnAddress(Inst
.getOperand(1).getReg());
262 return maybeReturnAddress(Inst
.getOperand(0).getReg());
266 bool isBranch(const MCInst
&Inst
) const override
{
267 if (MCInstrAnalysis::isBranch(Inst
))
270 return isBranchImpl(Inst
);
273 bool isUnconditionalBranch(const MCInst
&Inst
) const override
{
274 if (MCInstrAnalysis::isUnconditionalBranch(Inst
))
277 return isBranchImpl(Inst
);
280 bool isIndirectBranch(const MCInst
&Inst
) const override
{
281 if (MCInstrAnalysis::isIndirectBranch(Inst
))
284 switch (Inst
.getOpcode()) {
288 return Inst
.getOperand(0).getReg() == RISCV::X0
&&
289 !maybeReturnAddress(Inst
.getOperand(1).getReg());
291 return !maybeReturnAddress(Inst
.getOperand(0).getReg());
296 static bool maybeReturnAddress(unsigned Reg
) {
297 // X1 is used for normal returns, X5 for returns from outlined functions.
298 return Reg
== RISCV::X1
|| Reg
== RISCV::X5
;
301 static bool isBranchImpl(const MCInst
&Inst
) {
302 switch (Inst
.getOpcode()) {
306 return Inst
.getOperand(0).getReg() == RISCV::X0
;
308 return Inst
.getOperand(0).getReg() == RISCV::X0
&&
309 !maybeReturnAddress(Inst
.getOperand(1).getReg());
311 return !maybeReturnAddress(Inst
.getOperand(0).getReg());
316 } // end anonymous namespace
318 static MCInstrAnalysis
*createRISCVInstrAnalysis(const MCInstrInfo
*Info
) {
319 return new RISCVMCInstrAnalysis(Info
);
323 MCStreamer
*createRISCVELFStreamer(const Triple
&T
, MCContext
&Context
,
324 std::unique_ptr
<MCAsmBackend
> &&MAB
,
325 std::unique_ptr
<MCObjectWriter
> &&MOW
,
326 std::unique_ptr
<MCCodeEmitter
> &&MCE
,
328 return createRISCVELFStreamer(Context
, std::move(MAB
), std::move(MOW
),
329 std::move(MCE
), RelaxAll
);
331 } // end anonymous namespace
333 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeRISCVTargetMC() {
334 for (Target
*T
: {&getTheRISCV32Target(), &getTheRISCV64Target()}) {
335 TargetRegistry::RegisterMCAsmInfo(*T
, createRISCVMCAsmInfo
);
336 TargetRegistry::RegisterMCObjectFileInfo(*T
, createRISCVMCObjectFileInfo
);
337 TargetRegistry::RegisterMCInstrInfo(*T
, createRISCVMCInstrInfo
);
338 TargetRegistry::RegisterMCRegInfo(*T
, createRISCVMCRegisterInfo
);
339 TargetRegistry::RegisterMCAsmBackend(*T
, createRISCVAsmBackend
);
340 TargetRegistry::RegisterMCCodeEmitter(*T
, createRISCVMCCodeEmitter
);
341 TargetRegistry::RegisterMCInstPrinter(*T
, createRISCVMCInstPrinter
);
342 TargetRegistry::RegisterMCSubtargetInfo(*T
, createRISCVMCSubtargetInfo
);
343 TargetRegistry::RegisterELFStreamer(*T
, createRISCVELFStreamer
);
344 TargetRegistry::RegisterObjectTargetStreamer(
345 *T
, createRISCVObjectTargetStreamer
);
346 TargetRegistry::RegisterMCInstrAnalysis(*T
, createRISCVInstrAnalysis
);
348 // Register the asm target streamer.
349 TargetRegistry::RegisterAsmTargetStreamer(*T
, createRISCVAsmTargetStreamer
);
350 // Register the null target streamer.
351 TargetRegistry::RegisterNullTargetStreamer(*T
,
352 createRISCVNullTargetStreamer
);