1//===-- RISCVDisassembler.cpp - Disassembler for RISC-V -------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the RISCVDisassembler class.
10//
11//===----------------------------------------------------------------------===//
12
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/MCDecoderOps.h"
18#include "llvm/MC/MCDisassembler/MCDisassembler.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/Compiler.h"
25#include "llvm/Support/Endian.h"
26
27using namespace llvm;
28
29#define DEBUG_TYPE "riscv-disassembler"
30
31typedef MCDisassembler::DecodeStatus DecodeStatus;
32
33namespace {
34class RISCVDisassembler : public MCDisassembler {
35 std::unique_ptr<MCInstrInfo const> const MCII;
36
37public:
38 RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
39 MCInstrInfo const *MCII)
40 : MCDisassembler(STI, Ctx), MCII(MCII) {}
41
42 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
43 ArrayRef<uint8_t> Bytes, uint64_t Address,
44 raw_ostream &CStream) const override;
45
46private:
47 void addSPOperands(MCInst &MI) const;
48
49 DecodeStatus getInstruction48(MCInst &Instr, uint64_t &Size,
50 ArrayRef<uint8_t> Bytes, uint64_t Address,
51 raw_ostream &CStream) const;
52
53 DecodeStatus getInstruction32(MCInst &Instr, uint64_t &Size,
54 ArrayRef<uint8_t> Bytes, uint64_t Address,
55 raw_ostream &CStream) const;
56 DecodeStatus getInstruction16(MCInst &Instr, uint64_t &Size,
57 ArrayRef<uint8_t> Bytes, uint64_t Address,
58 raw_ostream &CStream) const;
59};
60} // end anonymous namespace
61
62static MCDisassembler *createRISCVDisassembler(const Target &T,
63 const MCSubtargetInfo &STI,
64 MCContext &Ctx) {
65 return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo());
66}
67
68extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
69LLVMInitializeRISCVDisassembler() {
70 // Register the disassembler for each target.
71 TargetRegistry::RegisterMCDisassembler(T&: getTheRISCV32Target(),
72 Fn: createRISCVDisassembler);
73 TargetRegistry::RegisterMCDisassembler(T&: getTheRISCV64Target(),
74 Fn: createRISCVDisassembler);
75}
76
77static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo,
78 uint64_t Address,
79 const MCDisassembler *Decoder) {
80 bool IsRVE = Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::FeatureStdExtE);
81
82 if (RegNo >= 32 || (IsRVE && RegNo >= 16))
83 return MCDisassembler::Fail;
84
85 MCRegister Reg = RISCV::X0 + RegNo;
86 Inst.addOperand(Op: MCOperand::createReg(Reg));
87 return MCDisassembler::Success;
88}
89
90static DecodeStatus DecodeGPRF16RegisterClass(MCInst &Inst, uint32_t RegNo,
91 uint64_t Address,
92 const MCDisassembler *Decoder) {
93 bool IsRVE = Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::FeatureStdExtE);
94
95 if (RegNo >= 32 || (IsRVE && RegNo >= 16))
96 return MCDisassembler::Fail;
97
98 MCRegister Reg = RISCV::X0_H + RegNo;
99 Inst.addOperand(Op: MCOperand::createReg(Reg));
100 return MCDisassembler::Success;
101}
102
103static DecodeStatus DecodeGPRF32RegisterClass(MCInst &Inst, uint32_t RegNo,
104 uint64_t Address,
105 const MCDisassembler *Decoder) {
106 bool IsRVE = Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::FeatureStdExtE);
107
108 if (RegNo >= 32 || (IsRVE && RegNo >= 16))
109 return MCDisassembler::Fail;
110
111 MCRegister Reg = RISCV::X0_W + RegNo;
112 Inst.addOperand(Op: MCOperand::createReg(Reg));
113 return MCDisassembler::Success;
114}
115
116static DecodeStatus DecodeGPRX1X5RegisterClass(MCInst &Inst, uint32_t RegNo,
117 uint64_t Address,
118 const MCDisassembler *Decoder) {
119 MCRegister Reg = RISCV::X0 + RegNo;
120 if (Reg != RISCV::X1 && Reg != RISCV::X5)
121 return MCDisassembler::Fail;
122
123 Inst.addOperand(Op: MCOperand::createReg(Reg));
124 return MCDisassembler::Success;
125}
126
127static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, uint32_t RegNo,
128 uint64_t Address,
129 const MCDisassembler *Decoder) {
130 if (RegNo >= 32)
131 return MCDisassembler::Fail;
132
133 MCRegister Reg = RISCV::F0_H + RegNo;
134 Inst.addOperand(Op: MCOperand::createReg(Reg));
135 return MCDisassembler::Success;
136}
137
138static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint32_t RegNo,
139 uint64_t Address,
140 const MCDisassembler *Decoder) {
141 if (RegNo >= 32)
142 return MCDisassembler::Fail;
143
144 MCRegister Reg = RISCV::F0_F + RegNo;
145 Inst.addOperand(Op: MCOperand::createReg(Reg));
146 return MCDisassembler::Success;
147}
148
149static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint32_t RegNo,
150 uint64_t Address,
151 const MCDisassembler *Decoder) {
152 if (RegNo >= 8) {
153 return MCDisassembler::Fail;
154 }
155 MCRegister Reg = RISCV::F8_F + RegNo;
156 Inst.addOperand(Op: MCOperand::createReg(Reg));
157 return MCDisassembler::Success;
158}
159
160static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint32_t RegNo,
161 uint64_t Address,
162 const MCDisassembler *Decoder) {
163 if (RegNo >= 32)
164 return MCDisassembler::Fail;
165
166 MCRegister Reg = RISCV::F0_D + RegNo;
167 Inst.addOperand(Op: MCOperand::createReg(Reg));
168 return MCDisassembler::Success;
169}
170
171static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint32_t RegNo,
172 uint64_t Address,
173 const MCDisassembler *Decoder) {
174 if (RegNo >= 8) {
175 return MCDisassembler::Fail;
176 }
177 MCRegister Reg = RISCV::F8_D + RegNo;
178 Inst.addOperand(Op: MCOperand::createReg(Reg));
179 return MCDisassembler::Success;
180}
181
182static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, uint32_t RegNo,
183 uint64_t Address,
184 const MCDisassembler *Decoder) {
185 if (RegNo >= 32)
186 return MCDisassembler::Fail;
187
188 MCRegister Reg = RISCV::F0_Q + RegNo;
189 Inst.addOperand(Op: MCOperand::createReg(Reg));
190 return MCDisassembler::Success;
191}
192
193static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint32_t RegNo,
194 uint64_t Address,
195 const MCDisassembler *Decoder) {
196 if (RegNo == 0) {
197 return MCDisassembler::Fail;
198 }
199
200 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
201}
202
203static DecodeStatus
204DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, uint32_t Address,
205 const MCDisassembler *Decoder) {
206 if (RegNo == 2) {
207 return MCDisassembler::Fail;
208 }
209
210 return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
211}
212
213static DecodeStatus DecodeGPRNoX31RegisterClass(MCInst &Inst, uint32_t RegNo,
214 uint64_t Address,
215 const MCDisassembler *Decoder) {
216 if (RegNo == 31) {
217 return MCDisassembler::Fail;
218 }
219
220 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
221}
222
223static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint32_t RegNo,
224 uint64_t Address,
225 const MCDisassembler *Decoder) {
226 if (RegNo >= 8)
227 return MCDisassembler::Fail;
228
229 MCRegister Reg = RISCV::X8 + RegNo;
230 Inst.addOperand(Op: MCOperand::createReg(Reg));
231 return MCDisassembler::Success;
232}
233
234static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint32_t RegNo,
235 uint64_t Address,
236 const MCDisassembler *Decoder) {
237 if (RegNo >= 32 || RegNo % 2)
238 return MCDisassembler::Fail;
239
240 const RISCVDisassembler *Dis =
241 static_cast<const RISCVDisassembler *>(Decoder);
242 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
243 MCRegister Reg = RI->getMatchingSuperReg(
244 Reg: RISCV::X0 + RegNo, SubIdx: RISCV::sub_gpr_even,
245 RC: &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
246 Inst.addOperand(Op: MCOperand::createReg(Reg));
247 return MCDisassembler::Success;
248}
249
250static DecodeStatus DecodeGPRPairCRegisterClass(MCInst &Inst, uint32_t RegNo,
251 uint64_t Address,
252 const MCDisassembler *Decoder) {
253 if (RegNo >= 8 || RegNo % 2)
254 return MCDisassembler::Fail;
255
256 const RISCVDisassembler *Dis =
257 static_cast<const RISCVDisassembler *>(Decoder);
258 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
259 MCRegister Reg = RI->getMatchingSuperReg(
260 Reg: RISCV::X8 + RegNo, SubIdx: RISCV::sub_gpr_even,
261 RC: &RISCVMCRegisterClasses[RISCV::GPRPairCRegClassID]);
262 Inst.addOperand(Op: MCOperand::createReg(Reg));
263 return MCDisassembler::Success;
264}
265
266static DecodeStatus DecodeSR07RegisterClass(MCInst &Inst, uint32_t RegNo,
267 uint64_t Address,
268 const void *Decoder) {
269 if (RegNo >= 8)
270 return MCDisassembler::Fail;
271
272 MCRegister Reg = (RegNo < 2) ? (RegNo + RISCV::X8) : (RegNo - 2 + RISCV::X18);
273 Inst.addOperand(Op: MCOperand::createReg(Reg));
274 return MCDisassembler::Success;
275}
276
277static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint32_t RegNo,
278 uint64_t Address,
279 const MCDisassembler *Decoder) {
280 if (RegNo >= 32)
281 return MCDisassembler::Fail;
282
283 MCRegister Reg = RISCV::V0 + RegNo;
284 Inst.addOperand(Op: MCOperand::createReg(Reg));
285 return MCDisassembler::Success;
286}
287
288static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint32_t RegNo,
289 uint64_t Address,
290 const MCDisassembler *Decoder) {
291 if (RegNo >= 32 || RegNo % 2)
292 return MCDisassembler::Fail;
293
294 const RISCVDisassembler *Dis =
295 static_cast<const RISCVDisassembler *>(Decoder);
296 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
297 MCRegister Reg =
298 RI->getMatchingSuperReg(Reg: RISCV::V0 + RegNo, SubIdx: RISCV::sub_vrm1_0,
299 RC: &RISCVMCRegisterClasses[RISCV::VRM2RegClassID]);
300
301 Inst.addOperand(Op: MCOperand::createReg(Reg));
302 return MCDisassembler::Success;
303}
304
305static DecodeStatus DecodeVRM4RegisterClass(MCInst &Inst, uint32_t RegNo,
306 uint64_t Address,
307 const MCDisassembler *Decoder) {
308 if (RegNo >= 32 || RegNo % 4)
309 return MCDisassembler::Fail;
310
311 const RISCVDisassembler *Dis =
312 static_cast<const RISCVDisassembler *>(Decoder);
313 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
314 MCRegister Reg =
315 RI->getMatchingSuperReg(Reg: RISCV::V0 + RegNo, SubIdx: RISCV::sub_vrm1_0,
316 RC: &RISCVMCRegisterClasses[RISCV::VRM4RegClassID]);
317
318 Inst.addOperand(Op: MCOperand::createReg(Reg));
319 return MCDisassembler::Success;
320}
321
322static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint32_t RegNo,
323 uint64_t Address,
324 const MCDisassembler *Decoder) {
325 if (RegNo >= 32 || RegNo % 8)
326 return MCDisassembler::Fail;
327
328 const RISCVDisassembler *Dis =
329 static_cast<const RISCVDisassembler *>(Decoder);
330 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
331 MCRegister Reg =
332 RI->getMatchingSuperReg(Reg: RISCV::V0 + RegNo, SubIdx: RISCV::sub_vrm1_0,
333 RC: &RISCVMCRegisterClasses[RISCV::VRM8RegClassID]);
334
335 Inst.addOperand(Op: MCOperand::createReg(Reg));
336 return MCDisassembler::Success;
337}
338
339static DecodeStatus DecodeVMV0RegisterClass(MCInst &Inst, uint32_t RegNo,
340 uint64_t Address,
341 const MCDisassembler *Decoder) {
342 if (RegNo)
343 return MCDisassembler::Fail;
344
345 Inst.addOperand(Op: MCOperand::createReg(Reg: RISCV::V0));
346 return MCDisassembler::Success;
347}
348
349static DecodeStatus DecodeTRRegisterClass(MCInst &Inst, uint32_t RegNo,
350 uint64_t Address,
351 const MCDisassembler *Decoder) {
352 if (RegNo > 15)
353 return MCDisassembler::Fail;
354
355 MCRegister Reg = RISCV::T0 + RegNo;
356 Inst.addOperand(Op: MCOperand::createReg(Reg));
357 return MCDisassembler::Success;
358}
359
360static DecodeStatus DecodeTRM2RegisterClass(MCInst &Inst, uint32_t RegNo,
361 uint64_t Address,
362 const MCDisassembler *Decoder) {
363 if (RegNo > 15 || RegNo % 2)
364 return MCDisassembler::Fail;
365
366 MCRegister Reg = RISCV::T0 + RegNo;
367 Inst.addOperand(Op: MCOperand::createReg(Reg));
368 return MCDisassembler::Success;
369}
370
371static DecodeStatus DecodeTRM4RegisterClass(MCInst &Inst, uint32_t RegNo,
372 uint64_t Address,
373 const MCDisassembler *Decoder) {
374 if (RegNo > 15 || RegNo % 4)
375 return MCDisassembler::Fail;
376
377 MCRegister Reg = RISCV::T0 + RegNo;
378 Inst.addOperand(Op: MCOperand::createReg(Reg));
379 return MCDisassembler::Success;
380}
381
382static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo,
383 uint64_t Address,
384 const MCDisassembler *Decoder) {
385 if (RegNo >= 2)
386 return MCDisassembler::Fail;
387
388 MCRegister Reg = (RegNo == 0) ? RISCV::V0 : RISCV::NoRegister;
389
390 Inst.addOperand(Op: MCOperand::createReg(Reg));
391 return MCDisassembler::Success;
392}
393
394template <unsigned N>
395static DecodeStatus decodeUImmOperand(MCInst &Inst, uint32_t Imm,
396 int64_t Address,
397 const MCDisassembler *Decoder) {
398 assert(isUInt<N>(Imm) && "Invalid immediate");
399 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
400 return MCDisassembler::Success;
401}
402
403template <unsigned Width, unsigned LowerBound>
404static DecodeStatus decodeUImmOperandGE(MCInst &Inst, uint32_t Imm,
405 int64_t Address,
406 const MCDisassembler *Decoder) {
407 assert(isUInt<Width>(Imm) && "Invalid immediate");
408
409 if (Imm < LowerBound)
410 return MCDisassembler::Fail;
411
412 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
413 return MCDisassembler::Success;
414}
415
416template <unsigned Width, unsigned LowerBound>
417static DecodeStatus decodeUImmPlus1OperandGE(MCInst &Inst, uint32_t Imm,
418 int64_t Address,
419 const MCDisassembler *Decoder) {
420 assert(isUInt<Width>(Imm) && "Invalid immediate");
421
422 if ((Imm + 1) < LowerBound)
423 return MCDisassembler::Fail;
424
425 Inst.addOperand(Op: MCOperand::createImm(Val: Imm + 1));
426 return MCDisassembler::Success;
427}
428
429static DecodeStatus decodeUImmSlistOperand(MCInst &Inst, uint32_t Imm,
430 int64_t Address,
431 const MCDisassembler *Decoder) {
432 assert(isUInt<3>(Imm) && "Invalid Slist immediate");
433 const uint8_t Slist[] = {0, 1, 2, 4, 8, 16, 15, 31};
434 Inst.addOperand(Op: MCOperand::createImm(Val: Slist[Imm]));
435 return MCDisassembler::Success;
436}
437
438static DecodeStatus decodeUImmLog2XLenOperand(MCInst &Inst, uint32_t Imm,
439 int64_t Address,
440 const MCDisassembler *Decoder) {
441 assert(isUInt<6>(Imm) && "Invalid immediate");
442
443 if (!Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::Feature64Bit) &&
444 !isUInt<5>(x: Imm))
445 return MCDisassembler::Fail;
446
447 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
448 return MCDisassembler::Success;
449}
450
451template <unsigned N>
452static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
453 int64_t Address,
454 const MCDisassembler *Decoder) {
455 if (Imm == 0)
456 return MCDisassembler::Fail;
457 return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
458}
459
460static DecodeStatus
461decodeUImmLog2XLenNonZeroOperand(MCInst &Inst, uint32_t Imm, int64_t Address,
462 const MCDisassembler *Decoder) {
463 if (Imm == 0)
464 return MCDisassembler::Fail;
465 return decodeUImmLog2XLenOperand(Inst, Imm, Address, Decoder);
466}
467
468template <unsigned N>
469static DecodeStatus decodeUImmPlus1Operand(MCInst &Inst, uint32_t Imm,
470 int64_t Address,
471 const MCDisassembler *Decoder) {
472 assert(isUInt<N>(Imm) && "Invalid immediate");
473 Inst.addOperand(Op: MCOperand::createImm(Val: Imm + 1));
474 return MCDisassembler::Success;
475}
476
477template <unsigned N>
478static DecodeStatus decodeSImmOperand(MCInst &Inst, uint32_t Imm,
479 int64_t Address,
480 const MCDisassembler *Decoder) {
481 assert(isUInt<N>(Imm) && "Invalid immediate");
482 // Sign-extend the number in the bottom N bits of Imm
483 Inst.addOperand(Op: MCOperand::createImm(Val: SignExtend64<N>(Imm)));
484 return MCDisassembler::Success;
485}
486
487template <unsigned N>
488static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
489 int64_t Address,
490 const MCDisassembler *Decoder) {
491 if (Imm == 0)
492 return MCDisassembler::Fail;
493 return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
494}
495
496template <unsigned T, unsigned N>
497static DecodeStatus decodeSImmOperandAndLslN(MCInst &Inst, uint32_t Imm,
498 int64_t Address,
499 const MCDisassembler *Decoder) {
500 assert(isUInt<T - N + 1>(Imm) && "Invalid immediate");
501 // Sign-extend the number in the bottom T bits of Imm after accounting for
502 // the fact that the T bit immediate is stored in T-N bits (the LSB is
503 // always zero)
504 Inst.addOperand(Op: MCOperand::createImm(Val: SignExtend64<T>(Imm << N)));
505 return MCDisassembler::Success;
506}
507
508static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint32_t Imm,
509 int64_t Address,
510 const MCDisassembler *Decoder) {
511 assert(isUInt<6>(Imm) && "Invalid immediate");
512 if (Imm == 0)
513 return MCDisassembler::Fail;
514 Imm = SignExtend64<6>(x: Imm) & 0xfffff;
515 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
516 return MCDisassembler::Success;
517}
518
519static DecodeStatus decodeFRMArg(MCInst &Inst, uint32_t Imm, int64_t Address,
520 const MCDisassembler *Decoder) {
521 assert(isUInt<3>(Imm) && "Invalid immediate");
522 if (!llvm::RISCVFPRndMode::isValidRoundingMode(Mode: Imm))
523 return MCDisassembler::Fail;
524
525 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
526 return MCDisassembler::Success;
527}
528
529static DecodeStatus decodeRTZArg(MCInst &Inst, uint32_t Imm, int64_t Address,
530 const MCDisassembler *Decoder) {
531 assert(isUInt<3>(Imm) && "Invalid immediate");
532 if (Imm != RISCVFPRndMode::RTZ)
533 return MCDisassembler::Fail;
534
535 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
536 return MCDisassembler::Success;
537}
538
539static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
540 uint64_t Address,
541 const MCDisassembler *Decoder);
542
543static DecodeStatus decodeRVCInstrRdSImm6(MCInst &Inst, uint32_t Insn,
544 uint64_t Address,
545 const MCDisassembler *Decoder);
546
547static DecodeStatus decodeRVCInstrRdCLUIImm(MCInst &Inst, uint32_t Insn,
548 uint64_t Address,
549 const MCDisassembler *Decoder);
550
551static DecodeStatus
552decodeRVCInstrRdRs1UImmLog2XLenNonZero(MCInst &Inst, uint32_t Insn,
553 uint64_t Address,
554 const MCDisassembler *Decoder);
555
556static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn,
557 uint64_t Address,
558 const MCDisassembler *Decoder);
559
560static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn,
561 uint64_t Address,
562 const MCDisassembler *Decoder);
563
564static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,
565 uint64_t Address,
566 const MCDisassembler *Decoder);
567
568static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,
569 uint64_t Address,
570 const MCDisassembler *Decoder);
571
572static DecodeStatus decodeXqccmpRlistS0(MCInst &Inst, uint32_t Imm,
573 uint64_t Address,
574 const MCDisassembler *Decoder);
575
576static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn,
577 uint64_t Address,
578 const MCDisassembler *Decoder);
579
580#include "RISCVGenDisassemblerTables.inc"
581
582static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
583 uint64_t Address,
584 const MCDisassembler *Decoder) {
585 DecodeStatus S = MCDisassembler::Success;
586 uint32_t Rd = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5);
587 if (!Check(Out&: S, In: DecodeGPRNoX0RegisterClass(Inst, RegNo: Rd, Address, Decoder)))
588 return MCDisassembler::Fail;
589 Inst.addOperand(Op: Inst.getOperand(i: 0));
590 Inst.addOperand(Op: MCOperand::createImm(Val: 0));
591 return S;
592}
593
594static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn,
595 uint64_t Address,
596 const MCDisassembler *Decoder) {
597 uint32_t Rs1 = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5);
598 [[maybe_unused]] DecodeStatus Result =
599 DecodeGPRX1X5RegisterClass(Inst, RegNo: Rs1, Address, Decoder);
600 assert(Result == MCDisassembler::Success && "Invalid register");
601 return MCDisassembler::Success;
602}
603
604static DecodeStatus decodeRVCInstrRdSImm6(MCInst &Inst, uint32_t Insn,
605 uint64_t Address,
606 const MCDisassembler *Decoder) {
607 Inst.addOperand(Op: MCOperand::createReg(Reg: RISCV::X0));
608 uint32_t Imm =
609 fieldFromInstruction(insn: Insn, startBit: 12, numBits: 1) << 5 | fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5);
610 [[maybe_unused]] DecodeStatus Result =
611 decodeSImmOperand<6>(Inst, Imm, Address, Decoder);
612 assert(Result == MCDisassembler::Success && "Invalid immediate");
613 return MCDisassembler::Success;
614}
615
616static DecodeStatus decodeRVCInstrRdCLUIImm(MCInst &Inst, uint32_t Insn,
617 uint64_t Address,
618 const MCDisassembler *Decoder) {
619 Inst.addOperand(Op: MCOperand::createReg(Reg: RISCV::X0));
620 uint32_t Imm =
621 fieldFromInstruction(insn: Insn, startBit: 12, numBits: 1) << 5 | fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5);
622 return decodeCLUIImmOperand(Inst, Imm, Address, Decoder);
623}
624
625static DecodeStatus
626decodeRVCInstrRdRs1UImmLog2XLenNonZero(MCInst &Inst, uint32_t Insn,
627 uint64_t Address,
628 const MCDisassembler *Decoder) {
629 Inst.addOperand(Op: MCOperand::createReg(Reg: RISCV::X0));
630 Inst.addOperand(Op: Inst.getOperand(i: 0));
631
632 uint32_t UImm6 =
633 fieldFromInstruction(insn: Insn, startBit: 12, numBits: 1) << 5 | fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5);
634 return decodeUImmLog2XLenNonZeroOperand(Inst, Imm: UImm6, Address, Decoder);
635}
636
637static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn,
638 uint64_t Address,
639 const MCDisassembler *Decoder) {
640 DecodeStatus S = MCDisassembler::Success;
641 uint32_t Rd = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5);
642 uint32_t Rs2 = fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5);
643 if (!Check(Out&: S, In: DecodeGPRRegisterClass(Inst, RegNo: Rd, Address, Decoder)))
644 return MCDisassembler::Fail;
645 if (!Check(Out&: S, In: DecodeGPRRegisterClass(Inst, RegNo: Rs2, Address, Decoder)))
646 return MCDisassembler::Fail;
647 return S;
648}
649
650static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn,
651 uint64_t Address,
652 const MCDisassembler *Decoder) {
653 DecodeStatus S = MCDisassembler::Success;
654 uint32_t Rd = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5);
655 uint32_t Rs2 = fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5);
656 if (!Check(Out&: S, In: DecodeGPRRegisterClass(Inst, RegNo: Rd, Address, Decoder)))
657 return MCDisassembler::Fail;
658 Inst.addOperand(Op: Inst.getOperand(i: 0));
659 if (!Check(Out&: S, In: DecodeGPRRegisterClass(Inst, RegNo: Rs2, Address, Decoder)))
660 return MCDisassembler::Fail;
661 return S;
662}
663
664static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,
665 uint64_t Address,
666 const MCDisassembler *Decoder) {
667 DecodeStatus S = MCDisassembler::Success;
668 uint32_t Rd1 = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5);
669 uint32_t Rs1 = fieldFromInstruction(insn: Insn, startBit: 15, numBits: 5);
670 uint32_t Rd2 = fieldFromInstruction(insn: Insn, startBit: 20, numBits: 5);
671 uint32_t UImm2 = fieldFromInstruction(insn: Insn, startBit: 25, numBits: 2);
672 if (!Check(Out&: S, In: DecodeGPRRegisterClass(Inst, RegNo: Rd1, Address, Decoder)))
673 return MCDisassembler::Fail;
674 if (!Check(Out&: S, In: DecodeGPRRegisterClass(Inst, RegNo: Rd2, Address, Decoder)))
675 return MCDisassembler::Fail;
676 if (!Check(Out&: S, In: DecodeGPRRegisterClass(Inst, RegNo: Rs1, Address, Decoder)))
677 return MCDisassembler::Fail;
678 [[maybe_unused]] DecodeStatus Result =
679 decodeUImmOperand<2>(Inst, Imm: UImm2, Address, Decoder);
680 assert(Result == MCDisassembler::Success && "Invalid immediate");
681
682 // Disassemble the final operand which is implicit.
683 unsigned Opcode = Inst.getOpcode();
684 bool IsWordOp = (Opcode == RISCV::TH_LWD || Opcode == RISCV::TH_LWUD ||
685 Opcode == RISCV::TH_SWD);
686 if (IsWordOp)
687 Inst.addOperand(Op: MCOperand::createImm(Val: 3));
688 else
689 Inst.addOperand(Op: MCOperand::createImm(Val: 4));
690
691 return S;
692}
693
694static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,
695 uint64_t Address,
696 const MCDisassembler *Decoder) {
697 bool IsRVE = Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::FeatureStdExtE);
698 if (Imm < RISCVZC::RA || (IsRVE && Imm >= RISCVZC::RA_S0_S2))
699 return MCDisassembler::Fail;
700 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
701 return MCDisassembler::Success;
702}
703
704static DecodeStatus decodeXqccmpRlistS0(MCInst &Inst, uint32_t Imm,
705 uint64_t Address,
706 const MCDisassembler *Decoder) {
707 if (Imm < RISCVZC::RA_S0)
708 return MCDisassembler::Fail;
709 return decodeZcmpRlist(Inst, Imm, Address, Decoder);
710}
711
712// Add implied SP operand for C.*SP compressed instructions. The SP operand
713// isn't explicitly encoded in the instruction.
714void RISCVDisassembler::addSPOperands(MCInst &MI) const {
715 const MCInstrDesc &MCID = MCII->get(Opcode: MI.getOpcode());
716 for (unsigned i = 0; i < MCID.getNumOperands(); i++)
717 if (MCID.operands()[i].RegClass == RISCV::SPRegClassID)
718 MI.insert(I: MI.begin() + i, Op: MCOperand::createReg(Reg: RISCV::X2));
719}
720
721namespace {
722
723struct DecoderListEntry {
724 const uint8_t *Table;
725 FeatureBitset ContainedFeatures;
726 const char *Desc;
727
728 bool haveContainedFeatures(const FeatureBitset &ActiveFeatures) const {
729 return ContainedFeatures.none() ||
730 (ContainedFeatures & ActiveFeatures).any();
731 }
732};
733
734} // end anonymous namespace
735
736static constexpr FeatureBitset XCVFeatureGroup = {
737 RISCV::FeatureVendorXCVbitmanip, RISCV::FeatureVendorXCVelw,
738 RISCV::FeatureVendorXCVmac, RISCV::FeatureVendorXCVmem,
739 RISCV::FeatureVendorXCValu, RISCV::FeatureVendorXCVsimd,
740 RISCV::FeatureVendorXCVbi};
741
742static constexpr FeatureBitset XRivosFeatureGroup = {
743 RISCV::FeatureVendorXRivosVisni,
744 RISCV::FeatureVendorXRivosVizip,
745};
746
747static constexpr FeatureBitset XqciFeatureGroup = {
748 RISCV::FeatureVendorXqcia, RISCV::FeatureVendorXqciac,
749 RISCV::FeatureVendorXqcibi, RISCV::FeatureVendorXqcibm,
750 RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm,
751 RISCV::FeatureVendorXqcics, RISCV::FeatureVendorXqcicsr,
752 RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqciio,
753 RISCV::FeatureVendorXqcilb, RISCV::FeatureVendorXqcili,
754 RISCV::FeatureVendorXqcilia, RISCV::FeatureVendorXqcilo,
755 RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisim,
756 RISCV::FeatureVendorXqcisls, RISCV::FeatureVendorXqcisync,
757};
758
759static constexpr FeatureBitset XSfVectorGroup = {
760 RISCV::FeatureVendorXSfvcp, RISCV::FeatureVendorXSfvqmaccdod,
761 RISCV::FeatureVendorXSfvqmaccqoq, RISCV::FeatureVendorXSfvfwmaccqqq,
762 RISCV::FeatureVendorXSfvfnrclipxfqf, RISCV::FeatureVendorXSfmmbase};
763static constexpr FeatureBitset XSfSystemGroup = {
764 RISCV::FeatureVendorXSiFivecdiscarddlone,
765 RISCV::FeatureVendorXSiFivecflushdlone,
766};
767
768static constexpr FeatureBitset XTHeadGroup = {
769 RISCV::FeatureVendorXTHeadBa, RISCV::FeatureVendorXTHeadBb,
770 RISCV::FeatureVendorXTHeadBs, RISCV::FeatureVendorXTHeadCondMov,
771 RISCV::FeatureVendorXTHeadCmo, RISCV::FeatureVendorXTHeadFMemIdx,
772 RISCV::FeatureVendorXTHeadMac, RISCV::FeatureVendorXTHeadMemIdx,
773 RISCV::FeatureVendorXTHeadMemPair, RISCV::FeatureVendorXTHeadSync,
774 RISCV::FeatureVendorXTHeadVdot};
775
776static constexpr FeatureBitset XAndesGroup = {
777 RISCV::FeatureVendorXAndesPerf, RISCV::FeatureVendorXAndesVBFHCvt,
778 RISCV::FeatureVendorXAndesVPackFPH, RISCV::FeatureVendorXAndesVDot};
779
780static constexpr DecoderListEntry DecoderList32[]{
781 // Vendor Extensions
782 {.Table: DecoderTableXVentana32,
783 .ContainedFeatures: {RISCV::FeatureVendorXVentanaCondOps},
784 .Desc: "XVentanaCondOps"},
785 {.Table: DecoderTableXTHead32, .ContainedFeatures: XTHeadGroup, .Desc: "T-Head extensions"},
786 {.Table: DecoderTableXSfvector32, .ContainedFeatures: XSfVectorGroup, .Desc: "SiFive vector extensions"},
787 {.Table: DecoderTableXSfsystem32, .ContainedFeatures: XSfSystemGroup, .Desc: "SiFive system extensions"},
788 {.Table: DecoderTableXSfcease32, .ContainedFeatures: {RISCV::FeatureVendorXSfcease}, .Desc: "SiFive sf.cease"},
789 {.Table: DecoderTableXmipslsp32, .ContainedFeatures: {RISCV::FeatureVendorXMIPSLSP}, .Desc: "MIPS mips.lsp"},
790 {.Table: DecoderTableXmipscmov32,
791 .ContainedFeatures: {RISCV::FeatureVendorXMIPSCMov},
792 .Desc: "MIPS mips.ccmov"},
793 {.Table: DecoderTableXmipscbop32,
794 .ContainedFeatures: {RISCV::FeatureVendorXMIPSCBOP},
795 .Desc: "MIPS mips.pref"},
796 {.Table: DecoderTableXAndes32, .ContainedFeatures: XAndesGroup, .Desc: "Andes extensions"},
797 // Standard Extensions
798 {.Table: DecoderTableXCV32, .ContainedFeatures: XCVFeatureGroup, .Desc: "CORE-V extensions"},
799 {.Table: DecoderTableXqci32, .ContainedFeatures: XqciFeatureGroup, .Desc: "Qualcomm uC Extensions"},
800 {.Table: DecoderTableXRivos32, .ContainedFeatures: XRivosFeatureGroup, .Desc: "Rivos"},
801 {.Table: DecoderTable32, .ContainedFeatures: {}, .Desc: "standard 32-bit instructions"},
802 {.Table: DecoderTableRV32Only32, .ContainedFeatures: {}, .Desc: "RV32-only standard 32-bit instructions"},
803 {.Table: DecoderTableZfinx32, .ContainedFeatures: {}, .Desc: "Zfinx (Float in Integer)"},
804 {.Table: DecoderTableZdinxRV32Only32, .ContainedFeatures: {}, .Desc: "RV32-only Zdinx (Double in Integer)"},
805};
806
807DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
808 ArrayRef<uint8_t> Bytes,
809 uint64_t Address,
810 raw_ostream &CS) const {
811 if (Bytes.size() < 4) {
812 Size = 0;
813 return MCDisassembler::Fail;
814 }
815 Size = 4;
816
817 // Use uint64_t to match getInstruction48. decodeInstruction is templated
818 // on the Insn type.
819 uint64_t Insn = support::endian::read32le(P: Bytes.data());
820
821 for (const DecoderListEntry &Entry : DecoderList32) {
822 if (!Entry.haveContainedFeatures(ActiveFeatures: STI.getFeatureBits()))
823 continue;
824
825 LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n");
826 DecodeStatus Result =
827 decodeInstruction(DecodeTable: Entry.Table, MI, insn: Insn, Address, DisAsm: this, STI);
828 if (Result == MCDisassembler::Fail)
829 continue;
830
831 return Result;
832 }
833
834 return MCDisassembler::Fail;
835}
836
837static constexpr DecoderListEntry DecoderList16[]{
838 // Vendor Extensions
839 {.Table: DecoderTableXqci16, .ContainedFeatures: XqciFeatureGroup, .Desc: "Qualcomm uC 16-bit"},
840 {.Table: DecoderTableXqccmp16,
841 .ContainedFeatures: {RISCV::FeatureVendorXqccmp},
842 .Desc: "Xqccmp (Qualcomm 16-bit Push/Pop & Double Move Instructions)"},
843 {.Table: DecoderTableXwchc16, .ContainedFeatures: {RISCV::FeatureVendorXwchc}, .Desc: "WCH QingKe XW"},
844 // Standard Extensions
845 // DecoderTableZicfiss16 must be checked before DecoderTable16.
846 {.Table: DecoderTableZicfiss16, .ContainedFeatures: {}, .Desc: "Zicfiss (Shadow Stack 16-bit)"},
847 {.Table: DecoderTable16, .ContainedFeatures: {}, .Desc: "standard 16-bit instructions"},
848 {.Table: DecoderTableRV32Only16, .ContainedFeatures: {}, .Desc: "RV32-only 16-bit instructions"},
849 // Zc* instructions incompatible with Zcf or Zcd
850 {.Table: DecoderTableZcOverlap16,
851 .ContainedFeatures: {},
852 .Desc: "ZcOverlap (16-bit Instructions overlapping with Zcf/Zcd)"},
853};
854
855DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,
856 ArrayRef<uint8_t> Bytes,
857 uint64_t Address,
858 raw_ostream &CS) const {
859 if (Bytes.size() < 2) {
860 Size = 0;
861 return MCDisassembler::Fail;
862 }
863 Size = 2;
864
865 // Use uint64_t to match getInstruction48. decodeInstruction is templated
866 // on the Insn type.
867 uint64_t Insn = support::endian::read16le(P: Bytes.data());
868
869 for (const DecoderListEntry &Entry : DecoderList16) {
870 if (!Entry.haveContainedFeatures(ActiveFeatures: STI.getFeatureBits()))
871 continue;
872
873 LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n");
874 DecodeStatus Result =
875 decodeInstruction(DecodeTable: Entry.Table, MI, insn: Insn, Address, DisAsm: this, STI);
876 if (Result == MCDisassembler::Fail)
877 continue;
878
879 addSPOperands(MI);
880
881 return Result;
882 }
883
884 return MCDisassembler::Fail;
885}
886
887static constexpr DecoderListEntry DecoderList48[]{
888 {.Table: DecoderTableXqci48, .ContainedFeatures: XqciFeatureGroup, .Desc: "Qualcomm uC 48bit"},
889};
890
891DecodeStatus RISCVDisassembler::getInstruction48(MCInst &MI, uint64_t &Size,
892 ArrayRef<uint8_t> Bytes,
893 uint64_t Address,
894 raw_ostream &CS) const {
895 if (Bytes.size() < 6) {
896 Size = 0;
897 return MCDisassembler::Fail;
898 }
899 Size = 6;
900
901 uint64_t Insn = 0;
902 for (size_t i = Size; i-- != 0;)
903 Insn += (static_cast<uint64_t>(Bytes[i]) << 8 * i);
904
905 for (const DecoderListEntry &Entry : DecoderList48) {
906 if (!Entry.haveContainedFeatures(ActiveFeatures: STI.getFeatureBits()))
907 continue;
908
909 LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n");
910 DecodeStatus Result =
911 decodeInstruction(DecodeTable: Entry.Table, MI, insn: Insn, Address, DisAsm: this, STI);
912 if (Result == MCDisassembler::Fail)
913 continue;
914
915 return Result;
916 }
917
918 return MCDisassembler::Fail;
919}
920
921DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
922 ArrayRef<uint8_t> Bytes,
923 uint64_t Address,
924 raw_ostream &CS) const {
925 CommentStream = &CS;
926 // It's a 16 bit instruction if bit 0 and 1 are not 0b11.
927 if ((Bytes[0] & 0b11) != 0b11)
928 return getInstruction16(MI, Size, Bytes, Address, CS);
929
930 // It's a 32 bit instruction if bit 1:0 are 0b11(checked above) and bits 4:2
931 // are not 0b111.
932 if ((Bytes[0] & 0b1'1100) != 0b1'1100)
933 return getInstruction32(MI, Size, Bytes, Address, CS);
934
935 // 48-bit instructions are encoded as 0bxx011111.
936 if ((Bytes[0] & 0b11'1111) == 0b01'1111) {
937 return getInstruction48(MI, Size, Bytes, Address, CS);
938 }
939
940 // 64-bit instructions are encoded as 0x0111111.
941 if ((Bytes[0] & 0b111'1111) == 0b011'1111) {
942 Size = Bytes.size() >= 8 ? 8 : 0;
943 return MCDisassembler::Fail;
944 }
945
946 // Remaining cases need to check a second byte.
947 if (Bytes.size() < 2) {
948 Size = 0;
949 return MCDisassembler::Fail;
950 }
951
952 // 80-bit through 176-bit instructions are encoded as 0bxnnnxxxx_x1111111.
953 // Where the number of bits is (80 + (nnn * 16)) for nnn != 0b111.
954 unsigned nnn = (Bytes[1] >> 4) & 0b111;
955 if (nnn != 0b111) {
956 Size = 10 + (nnn * 2);
957 if (Bytes.size() < Size)
958 Size = 0;
959 return MCDisassembler::Fail;
960 }
961
962 // Remaining encodings are reserved for > 176-bit instructions.
963 Size = 0;
964 return MCDisassembler::Fail;
965}
966