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/MC/TargetRegistry.h"
24 #include "llvm/Support/Endian.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 DecodeGPRPF64RegisterClass(MCInst &Inst, uint64_t RegNo,
166 const void *Decoder) {
167 if (RegNo >= 32 || RegNo & 1)
168 return MCDisassembler::Fail;
170 MCRegister Reg = RISCV::X0 + RegNo;
171 Inst.addOperand(MCOperand::createReg(Reg));
172 return MCDisassembler::Success;
175 static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint64_t RegNo,
177 const void *Decoder) {
179 return MCDisassembler::Fail;
181 MCRegister Reg = RISCV::V0 + RegNo;
182 Inst.addOperand(MCOperand::createReg(Reg));
183 return MCDisassembler::Success;
186 static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint64_t RegNo,
188 const void *Decoder) {
190 return MCDisassembler::Fail;
193 return MCDisassembler::Fail;
195 const RISCVDisassembler *Dis =
196 static_cast<const RISCVDisassembler *>(Decoder);
197 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
199 RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
200 &RISCVMCRegisterClasses[RISCV::VRM2RegClassID]);
202 Inst.addOperand(MCOperand::createReg(Reg));
203 return MCDisassembler::Success;
206 static DecodeStatus DecodeVRM4RegisterClass(MCInst &Inst, uint64_t RegNo,
208 const void *Decoder) {
210 return MCDisassembler::Fail;
213 return MCDisassembler::Fail;
215 const RISCVDisassembler *Dis =
216 static_cast<const RISCVDisassembler *>(Decoder);
217 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
219 RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
220 &RISCVMCRegisterClasses[RISCV::VRM4RegClassID]);
222 Inst.addOperand(MCOperand::createReg(Reg));
223 return MCDisassembler::Success;
226 static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint64_t RegNo,
228 const void *Decoder) {
230 return MCDisassembler::Fail;
233 return MCDisassembler::Fail;
235 const RISCVDisassembler *Dis =
236 static_cast<const RISCVDisassembler *>(Decoder);
237 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
239 RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
240 &RISCVMCRegisterClasses[RISCV::VRM8RegClassID]);
242 Inst.addOperand(MCOperand::createReg(Reg));
243 return MCDisassembler::Success;
246 static DecodeStatus decodeVMaskReg(MCInst &Inst, uint64_t RegNo,
247 uint64_t Address, const void *Decoder) {
248 MCRegister Reg = RISCV::NoRegister;
251 return MCDisassembler::Fail;
258 Inst.addOperand(MCOperand::createReg(Reg));
259 return MCDisassembler::Success;
262 // Add implied SP operand for instructions *SP compressed instructions. The SP
263 // operand isn't explicitly encoded in the instruction.
264 static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) {
265 if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP ||
266 Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP ||
267 Inst.getOpcode() == RISCV::C_FLWSP ||
268 Inst.getOpcode() == RISCV::C_FSWSP ||
269 Inst.getOpcode() == RISCV::C_FLDSP ||
270 Inst.getOpcode() == RISCV::C_FSDSP ||
271 Inst.getOpcode() == RISCV::C_ADDI4SPN) {
272 DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
274 if (Inst.getOpcode() == RISCV::C_ADDI16SP) {
275 DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
276 DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
280 template <unsigned N>
281 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
282 int64_t Address, const void *Decoder) {
283 assert(isUInt<N>(Imm) && "Invalid immediate");
284 addImplySP(Inst, Address, Decoder);
285 Inst.addOperand(MCOperand::createImm(Imm));
286 return MCDisassembler::Success;
289 template <unsigned N>
290 static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
292 const void *Decoder) {
294 return MCDisassembler::Fail;
295 return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
298 template <unsigned N>
299 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
300 int64_t Address, const void *Decoder) {
301 assert(isUInt<N>(Imm) && "Invalid immediate");
302 addImplySP(Inst, Address, Decoder);
303 // Sign-extend the number in the bottom N bits of Imm
304 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
305 return MCDisassembler::Success;
308 template <unsigned N>
309 static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
311 const void *Decoder) {
313 return MCDisassembler::Fail;
314 return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
317 template <unsigned N>
318 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm,
320 const void *Decoder) {
321 assert(isUInt<N>(Imm) && "Invalid immediate");
322 // Sign-extend the number in the bottom N bits of Imm after accounting for
323 // the fact that the N bit immediate is stored in N-1 bits (the LSB is
325 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
326 return MCDisassembler::Success;
329 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm,
331 const void *Decoder) {
332 assert(isUInt<6>(Imm) && "Invalid immediate");
334 Imm = (SignExtend64<6>(Imm) & 0xfffff);
336 Inst.addOperand(MCOperand::createImm(Imm));
337 return MCDisassembler::Success;
340 static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm,
342 const void *Decoder) {
343 assert(isUInt<3>(Imm) && "Invalid immediate");
344 if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm))
345 return MCDisassembler::Fail;
347 Inst.addOperand(MCOperand::createImm(Imm));
348 return MCDisassembler::Success;
351 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
352 uint64_t Address, const void *Decoder);
354 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
355 uint64_t Address, const void *Decoder);
357 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
359 const void *Decoder);
361 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
362 uint64_t Address, const void *Decoder);
364 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
366 const void *Decoder);
368 #include "RISCVGenDisassemblerTables.inc"
370 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
371 uint64_t Address, const void *Decoder) {
373 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
374 DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
376 assert(Result == MCDisassembler::Success && "Invalid immediate");
377 return MCDisassembler::Success;
380 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
382 const void *Decoder) {
383 DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
385 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
386 DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
388 assert(Result == MCDisassembler::Success && "Invalid immediate");
389 return MCDisassembler::Success;
392 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
394 const void *Decoder) {
395 DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
396 Inst.addOperand(Inst.getOperand(0));
398 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
399 DecodeStatus Result = decodeUImmOperand<6>(Inst, UImm6, Address, Decoder);
401 assert(Result == MCDisassembler::Success && "Invalid immediate");
402 return MCDisassembler::Success;
405 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
406 uint64_t Address, const void *Decoder) {
407 unsigned Rd = fieldFromInstruction(Insn, 7, 5);
408 unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
409 DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
410 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
411 return MCDisassembler::Success;
414 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
416 const void *Decoder) {
417 unsigned Rd = fieldFromInstruction(Insn, 7, 5);
418 unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
419 DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
420 Inst.addOperand(Inst.getOperand(0));
421 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
422 return MCDisassembler::Success;
425 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
426 ArrayRef<uint8_t> Bytes,
428 raw_ostream &CS) const {
429 // TODO: This will need modification when supporting instruction set
430 // extensions with instructions > 32-bits (up to 176 bits wide).
434 // It's a 32 bit instruction if bit 0 and 1 are 1.
435 if ((Bytes[0] & 0x3) == 0x3) {
436 if (Bytes.size() < 4) {
438 return MCDisassembler::Fail;
440 Insn = support::endian::read32le(Bytes.data());
441 if (STI.getFeatureBits()[RISCV::FeatureStdExtZdinx] &&
442 !STI.getFeatureBits()[RISCV::Feature64Bit]) {
443 LLVM_DEBUG(dbgs() << "Trying RV32Zdinx table (Double in Integer and"
445 Result = decodeInstruction(DecoderTableRV32Zdinx32, MI, Insn, Address,
447 if (Result != MCDisassembler::Fail) {
453 if (STI.getFeatureBits()[RISCV::FeatureStdExtZfinx]) {
454 LLVM_DEBUG(dbgs() << "Trying RVZfinx table (Float in Integer):\n");
455 Result = decodeInstruction(DecoderTableRVZfinx32, MI, Insn, Address, this,
457 if (Result != MCDisassembler::Fail) {
462 LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
463 Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
466 if (Bytes.size() < 2) {
468 return MCDisassembler::Fail;
470 Insn = support::endian::read16le(Bytes.data());
472 if (!STI.getFeatureBits()[RISCV::Feature64Bit]) {
474 dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n");
475 // Calling the auto-generated decoder function.
476 Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address,
478 if (Result != MCDisassembler::Fail) {
484 LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n");
485 // Calling the auto-generated decoder function.
486 Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);