1 //===-- RISCVDisassembler.cpp - Disassembler for RISCV --------------------===//
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 implements the RISCVDisassembler class.
11 //===----------------------------------------------------------------------===//
13 #include "MCTargetDesc/RISCVBaseInfo.h"
14 #include "MCTargetDesc/RISCVMCTargetDesc.h"
15 #include "TargetInfo/RISCVTargetInfo.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
18 #include "llvm/MC/MCFixedLenDisassembler.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/MC/MCSubtargetInfo.h"
23 #include "llvm/Support/Endian.h"
24 #include "llvm/Support/TargetRegistry.h"
28 #define DEBUG_TYPE "riscv-disassembler"
30 typedef MCDisassembler::DecodeStatus DecodeStatus
;
33 class RISCVDisassembler
: public MCDisassembler
{
34 std::unique_ptr
<MCInstrInfo
const> const MCII
;
37 RISCVDisassembler(const MCSubtargetInfo
&STI
, MCContext
&Ctx
,
38 MCInstrInfo
const *MCII
)
39 : MCDisassembler(STI
, Ctx
), MCII(MCII
) {}
41 DecodeStatus
getInstruction(MCInst
&Instr
, uint64_t &Size
,
42 ArrayRef
<uint8_t> Bytes
, uint64_t Address
,
43 raw_ostream
&CStream
) const override
;
45 } // end anonymous namespace
47 static MCDisassembler
*createRISCVDisassembler(const Target
&T
,
48 const MCSubtargetInfo
&STI
,
50 return new RISCVDisassembler(STI
, Ctx
, T
.createMCInstrInfo());
53 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeRISCVDisassembler() {
54 // Register the disassembler for each target.
55 TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(),
56 createRISCVDisassembler
);
57 TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(),
58 createRISCVDisassembler
);
61 static DecodeStatus
DecodeGPRRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
63 const void *Decoder
) {
64 const FeatureBitset
&FeatureBits
=
65 static_cast<const MCDisassembler
*>(Decoder
)
68 bool IsRV32E
= FeatureBits
[RISCV::FeatureRV32E
];
70 if (RegNo
>= 32 || (IsRV32E
&& RegNo
>= 16))
71 return MCDisassembler::Fail
;
73 MCRegister Reg
= RISCV::X0
+ RegNo
;
74 Inst
.addOperand(MCOperand::createReg(Reg
));
75 return MCDisassembler::Success
;
78 static DecodeStatus
DecodeFPR16RegisterClass(MCInst
&Inst
, uint64_t RegNo
,
80 const void *Decoder
) {
82 return MCDisassembler::Fail
;
84 MCRegister Reg
= RISCV::F0_H
+ RegNo
;
85 Inst
.addOperand(MCOperand::createReg(Reg
));
86 return MCDisassembler::Success
;
89 static DecodeStatus
DecodeFPR32RegisterClass(MCInst
&Inst
, uint64_t RegNo
,
91 const void *Decoder
) {
93 return MCDisassembler::Fail
;
95 MCRegister Reg
= RISCV::F0_F
+ RegNo
;
96 Inst
.addOperand(MCOperand::createReg(Reg
));
97 return MCDisassembler::Success
;
100 static DecodeStatus
DecodeFPR32CRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
102 const void *Decoder
) {
104 return MCDisassembler::Fail
;
106 MCRegister Reg
= RISCV::F8_F
+ RegNo
;
107 Inst
.addOperand(MCOperand::createReg(Reg
));
108 return MCDisassembler::Success
;
111 static DecodeStatus
DecodeFPR64RegisterClass(MCInst
&Inst
, uint64_t RegNo
,
113 const void *Decoder
) {
115 return MCDisassembler::Fail
;
117 MCRegister Reg
= RISCV::F0_D
+ RegNo
;
118 Inst
.addOperand(MCOperand::createReg(Reg
));
119 return MCDisassembler::Success
;
122 static DecodeStatus
DecodeFPR64CRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
124 const void *Decoder
) {
126 return MCDisassembler::Fail
;
128 MCRegister Reg
= RISCV::F8_D
+ RegNo
;
129 Inst
.addOperand(MCOperand::createReg(Reg
));
130 return MCDisassembler::Success
;
133 static DecodeStatus
DecodeGPRNoX0RegisterClass(MCInst
&Inst
, uint64_t RegNo
,
135 const void *Decoder
) {
137 return MCDisassembler::Fail
;
140 return DecodeGPRRegisterClass(Inst
, RegNo
, Address
, Decoder
);
143 static DecodeStatus
DecodeGPRNoX0X2RegisterClass(MCInst
&Inst
, uint64_t RegNo
,
145 const void *Decoder
) {
147 return MCDisassembler::Fail
;
150 return DecodeGPRNoX0RegisterClass(Inst
, RegNo
, Address
, Decoder
);
153 static DecodeStatus
DecodeGPRCRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
155 const void *Decoder
) {
157 return MCDisassembler::Fail
;
159 MCRegister Reg
= RISCV::X8
+ RegNo
;
160 Inst
.addOperand(MCOperand::createReg(Reg
));
161 return MCDisassembler::Success
;
164 static DecodeStatus
DecodeVRRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
166 const void *Decoder
) {
168 return MCDisassembler::Fail
;
170 MCRegister Reg
= RISCV::V0
+ RegNo
;
171 Inst
.addOperand(MCOperand::createReg(Reg
));
172 return MCDisassembler::Success
;
175 static DecodeStatus
DecodeVRM2RegisterClass(MCInst
&Inst
, uint64_t RegNo
,
177 const void *Decoder
) {
179 return MCDisassembler::Fail
;
182 return MCDisassembler::Fail
;
184 const RISCVDisassembler
*Dis
=
185 static_cast<const RISCVDisassembler
*>(Decoder
);
186 const MCRegisterInfo
*RI
= Dis
->getContext().getRegisterInfo();
188 RI
->getMatchingSuperReg(RISCV::V0
+ RegNo
, RISCV::sub_vrm1_0
,
189 &RISCVMCRegisterClasses
[RISCV::VRM2RegClassID
]);
191 Inst
.addOperand(MCOperand::createReg(Reg
));
192 return MCDisassembler::Success
;
195 static DecodeStatus
DecodeVRM4RegisterClass(MCInst
&Inst
, uint64_t RegNo
,
197 const void *Decoder
) {
199 return MCDisassembler::Fail
;
202 return MCDisassembler::Fail
;
204 const RISCVDisassembler
*Dis
=
205 static_cast<const RISCVDisassembler
*>(Decoder
);
206 const MCRegisterInfo
*RI
= Dis
->getContext().getRegisterInfo();
208 RI
->getMatchingSuperReg(RISCV::V0
+ RegNo
, RISCV::sub_vrm1_0
,
209 &RISCVMCRegisterClasses
[RISCV::VRM4RegClassID
]);
211 Inst
.addOperand(MCOperand::createReg(Reg
));
212 return MCDisassembler::Success
;
215 static DecodeStatus
DecodeVRM8RegisterClass(MCInst
&Inst
, uint64_t RegNo
,
217 const void *Decoder
) {
219 return MCDisassembler::Fail
;
222 return MCDisassembler::Fail
;
224 const RISCVDisassembler
*Dis
=
225 static_cast<const RISCVDisassembler
*>(Decoder
);
226 const MCRegisterInfo
*RI
= Dis
->getContext().getRegisterInfo();
228 RI
->getMatchingSuperReg(RISCV::V0
+ RegNo
, RISCV::sub_vrm1_0
,
229 &RISCVMCRegisterClasses
[RISCV::VRM8RegClassID
]);
231 Inst
.addOperand(MCOperand::createReg(Reg
));
232 return MCDisassembler::Success
;
235 static DecodeStatus
decodeVMaskReg(MCInst
&Inst
, uint64_t RegNo
,
236 uint64_t Address
, const void *Decoder
) {
237 MCRegister Reg
= RISCV::NoRegister
;
240 return MCDisassembler::Fail
;
247 Inst
.addOperand(MCOperand::createReg(Reg
));
248 return MCDisassembler::Success
;
251 // Add implied SP operand for instructions *SP compressed instructions. The SP
252 // operand isn't explicitly encoded in the instruction.
253 static void addImplySP(MCInst
&Inst
, int64_t Address
, const void *Decoder
) {
254 if (Inst
.getOpcode() == RISCV::C_LWSP
|| Inst
.getOpcode() == RISCV::C_SWSP
||
255 Inst
.getOpcode() == RISCV::C_LDSP
|| Inst
.getOpcode() == RISCV::C_SDSP
||
256 Inst
.getOpcode() == RISCV::C_FLWSP
||
257 Inst
.getOpcode() == RISCV::C_FSWSP
||
258 Inst
.getOpcode() == RISCV::C_FLDSP
||
259 Inst
.getOpcode() == RISCV::C_FSDSP
||
260 Inst
.getOpcode() == RISCV::C_ADDI4SPN
) {
261 DecodeGPRRegisterClass(Inst
, 2, Address
, Decoder
);
263 if (Inst
.getOpcode() == RISCV::C_ADDI16SP
) {
264 DecodeGPRRegisterClass(Inst
, 2, Address
, Decoder
);
265 DecodeGPRRegisterClass(Inst
, 2, Address
, Decoder
);
269 template <unsigned N
>
270 static DecodeStatus
decodeUImmOperand(MCInst
&Inst
, uint64_t Imm
,
271 int64_t Address
, const void *Decoder
) {
272 assert(isUInt
<N
>(Imm
) && "Invalid immediate");
273 addImplySP(Inst
, Address
, Decoder
);
274 Inst
.addOperand(MCOperand::createImm(Imm
));
275 return MCDisassembler::Success
;
278 template <unsigned N
>
279 static DecodeStatus
decodeUImmNonZeroOperand(MCInst
&Inst
, uint64_t Imm
,
281 const void *Decoder
) {
283 return MCDisassembler::Fail
;
284 return decodeUImmOperand
<N
>(Inst
, Imm
, Address
, Decoder
);
287 template <unsigned N
>
288 static DecodeStatus
decodeSImmOperand(MCInst
&Inst
, uint64_t Imm
,
289 int64_t Address
, const void *Decoder
) {
290 assert(isUInt
<N
>(Imm
) && "Invalid immediate");
291 addImplySP(Inst
, Address
, Decoder
);
292 // Sign-extend the number in the bottom N bits of Imm
293 Inst
.addOperand(MCOperand::createImm(SignExtend64
<N
>(Imm
)));
294 return MCDisassembler::Success
;
297 template <unsigned N
>
298 static DecodeStatus
decodeSImmNonZeroOperand(MCInst
&Inst
, uint64_t Imm
,
300 const void *Decoder
) {
302 return MCDisassembler::Fail
;
303 return decodeSImmOperand
<N
>(Inst
, Imm
, Address
, Decoder
);
306 template <unsigned N
>
307 static DecodeStatus
decodeSImmOperandAndLsl1(MCInst
&Inst
, uint64_t Imm
,
309 const void *Decoder
) {
310 assert(isUInt
<N
>(Imm
) && "Invalid immediate");
311 // Sign-extend the number in the bottom N bits of Imm after accounting for
312 // the fact that the N bit immediate is stored in N-1 bits (the LSB is
314 Inst
.addOperand(MCOperand::createImm(SignExtend64
<N
>(Imm
<< 1)));
315 return MCDisassembler::Success
;
318 static DecodeStatus
decodeCLUIImmOperand(MCInst
&Inst
, uint64_t Imm
,
320 const void *Decoder
) {
321 assert(isUInt
<6>(Imm
) && "Invalid immediate");
323 Imm
= (SignExtend64
<6>(Imm
) & 0xfffff);
325 Inst
.addOperand(MCOperand::createImm(Imm
));
326 return MCDisassembler::Success
;
329 static DecodeStatus
decodeFRMArg(MCInst
&Inst
, uint64_t Imm
,
331 const void *Decoder
) {
332 assert(isUInt
<3>(Imm
) && "Invalid immediate");
333 if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm
))
334 return MCDisassembler::Fail
;
336 Inst
.addOperand(MCOperand::createImm(Imm
));
337 return MCDisassembler::Success
;
340 static DecodeStatus
decodeRVCInstrSImm(MCInst
&Inst
, unsigned Insn
,
341 uint64_t Address
, const void *Decoder
);
343 static DecodeStatus
decodeRVCInstrRdSImm(MCInst
&Inst
, unsigned Insn
,
344 uint64_t Address
, const void *Decoder
);
346 static DecodeStatus
decodeRVCInstrRdRs1UImm(MCInst
&Inst
, unsigned Insn
,
348 const void *Decoder
);
350 static DecodeStatus
decodeRVCInstrRdRs2(MCInst
&Inst
, unsigned Insn
,
351 uint64_t Address
, const void *Decoder
);
353 static DecodeStatus
decodeRVCInstrRdRs1Rs2(MCInst
&Inst
, unsigned Insn
,
355 const void *Decoder
);
357 #include "RISCVGenDisassemblerTables.inc"
359 static DecodeStatus
decodeRVCInstrSImm(MCInst
&Inst
, unsigned Insn
,
360 uint64_t Address
, const void *Decoder
) {
362 fieldFromInstruction(Insn
, 12, 1) << 5 | fieldFromInstruction(Insn
, 2, 5);
363 DecodeStatus Result
= decodeSImmOperand
<6>(Inst
, SImm6
, Address
, Decoder
);
365 assert(Result
== MCDisassembler::Success
&& "Invalid immediate");
366 return MCDisassembler::Success
;
369 static DecodeStatus
decodeRVCInstrRdSImm(MCInst
&Inst
, unsigned Insn
,
371 const void *Decoder
) {
372 DecodeGPRRegisterClass(Inst
, 0, Address
, Decoder
);
374 fieldFromInstruction(Insn
, 12, 1) << 5 | fieldFromInstruction(Insn
, 2, 5);
375 DecodeStatus Result
= decodeSImmOperand
<6>(Inst
, SImm6
, Address
, Decoder
);
377 assert(Result
== MCDisassembler::Success
&& "Invalid immediate");
378 return MCDisassembler::Success
;
381 static DecodeStatus
decodeRVCInstrRdRs1UImm(MCInst
&Inst
, unsigned Insn
,
383 const void *Decoder
) {
384 DecodeGPRRegisterClass(Inst
, 0, Address
, Decoder
);
385 Inst
.addOperand(Inst
.getOperand(0));
387 fieldFromInstruction(Insn
, 12, 1) << 5 | fieldFromInstruction(Insn
, 2, 5);
388 DecodeStatus Result
= decodeUImmOperand
<6>(Inst
, UImm6
, Address
, Decoder
);
390 assert(Result
== MCDisassembler::Success
&& "Invalid immediate");
391 return MCDisassembler::Success
;
394 static DecodeStatus
decodeRVCInstrRdRs2(MCInst
&Inst
, unsigned Insn
,
395 uint64_t Address
, const void *Decoder
) {
396 unsigned Rd
= fieldFromInstruction(Insn
, 7, 5);
397 unsigned Rs2
= fieldFromInstruction(Insn
, 2, 5);
398 DecodeGPRRegisterClass(Inst
, Rd
, Address
, Decoder
);
399 DecodeGPRRegisterClass(Inst
, Rs2
, Address
, Decoder
);
400 return MCDisassembler::Success
;
403 static DecodeStatus
decodeRVCInstrRdRs1Rs2(MCInst
&Inst
, unsigned Insn
,
405 const void *Decoder
) {
406 unsigned Rd
= fieldFromInstruction(Insn
, 7, 5);
407 unsigned Rs2
= fieldFromInstruction(Insn
, 2, 5);
408 DecodeGPRRegisterClass(Inst
, Rd
, Address
, Decoder
);
409 Inst
.addOperand(Inst
.getOperand(0));
410 DecodeGPRRegisterClass(Inst
, Rs2
, Address
, Decoder
);
411 return MCDisassembler::Success
;
414 DecodeStatus
RISCVDisassembler::getInstruction(MCInst
&MI
, uint64_t &Size
,
415 ArrayRef
<uint8_t> Bytes
,
417 raw_ostream
&CS
) const {
418 // TODO: This will need modification when supporting instruction set
419 // extensions with instructions > 32-bits (up to 176 bits wide).
423 // It's a 32 bit instruction if bit 0 and 1 are 1.
424 if ((Bytes
[0] & 0x3) == 0x3) {
425 if (Bytes
.size() < 4) {
427 return MCDisassembler::Fail
;
429 Insn
= support::endian::read32le(Bytes
.data());
430 LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
431 Result
= decodeInstruction(DecoderTable32
, MI
, Insn
, Address
, this, STI
);
434 if (Bytes
.size() < 2) {
436 return MCDisassembler::Fail
;
438 Insn
= support::endian::read16le(Bytes
.data());
440 if (!STI
.getFeatureBits()[RISCV::Feature64Bit
]) {
442 dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n");
443 // Calling the auto-generated decoder function.
444 Result
= decodeInstruction(DecoderTableRISCV32Only_16
, MI
, Insn
, Address
,
446 if (Result
!= MCDisassembler::Fail
) {
452 if (STI
.getFeatureBits()[RISCV::FeatureExtZbproposedc
] &&
453 STI
.getFeatureBits()[RISCV::FeatureStdExtC
]) {
455 dbgs() << "Trying RVBC32 table (BitManip 16-bit Instruction):\n");
456 // Calling the auto-generated decoder function.
457 Result
= decodeInstruction(DecoderTableRVBC16
, MI
, Insn
, Address
,
459 if (Result
!= MCDisassembler::Fail
) {
465 LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n");
466 // Calling the auto-generated decoder function.
467 Result
= decodeInstruction(DecoderTable16
, MI
, Insn
, Address
, this, STI
);