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/Endian.h"
25
26 using namespace llvm;
27
28 #define DEBUG_TYPE "riscv-disassembler"
29
30 typedef MCDisassembler::DecodeStatus DecodeStatus;
31
32 namespace {
33 class RISCVDisassembler : public MCDisassembler {
34 std::unique_ptr<MCInstrInfo const> const MCII;
35
36 public:
RISCVDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,MCInstrInfo const * MCII)37 RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
38 MCInstrInfo const *MCII)
39 : MCDisassembler(STI, Ctx), MCII(MCII) {}
40
41 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
42 ArrayRef<uint8_t> Bytes, uint64_t Address,
43 raw_ostream &CStream) const override;
44
45 private:
46 void addSPOperands(MCInst &MI) const;
47
48 DecodeStatus getInstruction32(MCInst &Instr, uint64_t &Size,
49 ArrayRef<uint8_t> Bytes, uint64_t Address,
50 raw_ostream &CStream) const;
51 DecodeStatus getInstruction16(MCInst &Instr, uint64_t &Size,
52 ArrayRef<uint8_t> Bytes, uint64_t Address,
53 raw_ostream &CStream) const;
54 };
55 } // end anonymous namespace
56
createRISCVDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)57 static MCDisassembler *createRISCVDisassembler(const Target &T,
58 const MCSubtargetInfo &STI,
59 MCContext &Ctx) {
60 return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo());
61 }
62
LLVMInitializeRISCVDisassembler()63 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVDisassembler() {
64 // Register the disassembler for each target.
65 TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(),
66 createRISCVDisassembler);
67 TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(),
68 createRISCVDisassembler);
69 }
70
DecodeGPRRegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)71 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo,
72 uint64_t Address,
73 const MCDisassembler *Decoder) {
74 bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE);
75
76 if (RegNo >= 32 || (IsRVE && RegNo >= 16))
77 return MCDisassembler::Fail;
78
79 MCRegister Reg = RISCV::X0 + RegNo;
80 Inst.addOperand(MCOperand::createReg(Reg));
81 return MCDisassembler::Success;
82 }
83
DecodeGPRX1X5RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)84 static DecodeStatus DecodeGPRX1X5RegisterClass(MCInst &Inst, uint32_t RegNo,
85 uint64_t Address,
86 const MCDisassembler *Decoder) {
87 MCRegister Reg = RISCV::X0 + RegNo;
88 if (Reg != RISCV::X1 && Reg != RISCV::X5)
89 return MCDisassembler::Fail;
90
91 Inst.addOperand(MCOperand::createReg(Reg));
92 return MCDisassembler::Success;
93 }
94
DecodeFPR16RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)95 static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, uint32_t RegNo,
96 uint64_t Address,
97 const MCDisassembler *Decoder) {
98 if (RegNo >= 32)
99 return MCDisassembler::Fail;
100
101 MCRegister Reg = RISCV::F0_H + RegNo;
102 Inst.addOperand(MCOperand::createReg(Reg));
103 return MCDisassembler::Success;
104 }
105
DecodeFPR32RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)106 static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint32_t RegNo,
107 uint64_t Address,
108 const MCDisassembler *Decoder) {
109 if (RegNo >= 32)
110 return MCDisassembler::Fail;
111
112 MCRegister Reg = RISCV::F0_F + RegNo;
113 Inst.addOperand(MCOperand::createReg(Reg));
114 return MCDisassembler::Success;
115 }
116
DecodeFPR32CRegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)117 static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint32_t RegNo,
118 uint64_t Address,
119 const MCDisassembler *Decoder) {
120 if (RegNo >= 8) {
121 return MCDisassembler::Fail;
122 }
123 MCRegister Reg = RISCV::F8_F + RegNo;
124 Inst.addOperand(MCOperand::createReg(Reg));
125 return MCDisassembler::Success;
126 }
127
DecodeFPR64RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)128 static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint32_t RegNo,
129 uint64_t Address,
130 const MCDisassembler *Decoder) {
131 if (RegNo >= 32)
132 return MCDisassembler::Fail;
133
134 MCRegister Reg = RISCV::F0_D + RegNo;
135 Inst.addOperand(MCOperand::createReg(Reg));
136 return MCDisassembler::Success;
137 }
138
DecodeFPR64CRegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)139 static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint32_t RegNo,
140 uint64_t Address,
141 const MCDisassembler *Decoder) {
142 if (RegNo >= 8) {
143 return MCDisassembler::Fail;
144 }
145 MCRegister Reg = RISCV::F8_D + RegNo;
146 Inst.addOperand(MCOperand::createReg(Reg));
147 return MCDisassembler::Success;
148 }
149
DecodeGPRNoX0RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)150 static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint32_t RegNo,
151 uint64_t Address,
152 const MCDisassembler *Decoder) {
153 if (RegNo == 0) {
154 return MCDisassembler::Fail;
155 }
156
157 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
158 }
159
160 static DecodeStatus
DecodeGPRNoX0X2RegisterClass(MCInst & Inst,uint64_t RegNo,uint32_t Address,const MCDisassembler * Decoder)161 DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, uint32_t Address,
162 const MCDisassembler *Decoder) {
163 if (RegNo == 2) {
164 return MCDisassembler::Fail;
165 }
166
167 return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
168 }
169
DecodeGPRCRegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)170 static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint32_t RegNo,
171 uint64_t Address,
172 const MCDisassembler *Decoder) {
173 if (RegNo >= 8)
174 return MCDisassembler::Fail;
175
176 MCRegister Reg = RISCV::X8 + RegNo;
177 Inst.addOperand(MCOperand::createReg(Reg));
178 return MCDisassembler::Success;
179 }
180
DecodeGPRPairRegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)181 static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint32_t RegNo,
182 uint64_t Address,
183 const MCDisassembler *Decoder) {
184 if (RegNo >= 32 || RegNo & 1)
185 return MCDisassembler::Fail;
186
187 MCRegister Reg = RISCV::X0 + RegNo;
188 Inst.addOperand(MCOperand::createReg(Reg));
189 return MCDisassembler::Success;
190 }
191
DecodeSR07RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const void * Decoder)192 static DecodeStatus DecodeSR07RegisterClass(MCInst &Inst, uint32_t RegNo,
193 uint64_t Address,
194 const void *Decoder) {
195 if (RegNo >= 8)
196 return MCDisassembler::Fail;
197
198 MCRegister Reg = (RegNo < 2) ? (RegNo + RISCV::X8) : (RegNo - 2 + RISCV::X18);
199 Inst.addOperand(MCOperand::createReg(Reg));
200 return MCDisassembler::Success;
201 }
202
DecodeVRRegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)203 static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint32_t RegNo,
204 uint64_t Address,
205 const MCDisassembler *Decoder) {
206 if (RegNo >= 32)
207 return MCDisassembler::Fail;
208
209 MCRegister Reg = RISCV::V0 + RegNo;
210 Inst.addOperand(MCOperand::createReg(Reg));
211 return MCDisassembler::Success;
212 }
213
DecodeVRM2RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)214 static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint32_t RegNo,
215 uint64_t Address,
216 const MCDisassembler *Decoder) {
217 if (RegNo >= 32 || RegNo % 2)
218 return MCDisassembler::Fail;
219
220 const RISCVDisassembler *Dis =
221 static_cast<const RISCVDisassembler *>(Decoder);
222 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
223 MCRegister Reg =
224 RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
225 &RISCVMCRegisterClasses[RISCV::VRM2RegClassID]);
226
227 Inst.addOperand(MCOperand::createReg(Reg));
228 return MCDisassembler::Success;
229 }
230
DecodeVRM4RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)231 static DecodeStatus DecodeVRM4RegisterClass(MCInst &Inst, uint32_t RegNo,
232 uint64_t Address,
233 const MCDisassembler *Decoder) {
234 if (RegNo >= 32 || RegNo % 4)
235 return MCDisassembler::Fail;
236
237 const RISCVDisassembler *Dis =
238 static_cast<const RISCVDisassembler *>(Decoder);
239 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
240 MCRegister Reg =
241 RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
242 &RISCVMCRegisterClasses[RISCV::VRM4RegClassID]);
243
244 Inst.addOperand(MCOperand::createReg(Reg));
245 return MCDisassembler::Success;
246 }
247
DecodeVRM8RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)248 static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint32_t RegNo,
249 uint64_t Address,
250 const MCDisassembler *Decoder) {
251 if (RegNo >= 32 || RegNo % 8)
252 return MCDisassembler::Fail;
253
254 const RISCVDisassembler *Dis =
255 static_cast<const RISCVDisassembler *>(Decoder);
256 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
257 MCRegister Reg =
258 RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
259 &RISCVMCRegisterClasses[RISCV::VRM8RegClassID]);
260
261 Inst.addOperand(MCOperand::createReg(Reg));
262 return MCDisassembler::Success;
263 }
264
decodeVMaskReg(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)265 static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo,
266 uint64_t Address,
267 const MCDisassembler *Decoder) {
268 if (RegNo >= 2)
269 return MCDisassembler::Fail;
270
271 MCRegister Reg = (RegNo == 0) ? RISCV::V0 : RISCV::NoRegister;
272
273 Inst.addOperand(MCOperand::createReg(Reg));
274 return MCDisassembler::Success;
275 }
276
277 template <unsigned N>
decodeUImmOperand(MCInst & Inst,uint32_t Imm,int64_t Address,const MCDisassembler * Decoder)278 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint32_t Imm,
279 int64_t Address,
280 const MCDisassembler *Decoder) {
281 assert(isUInt<N>(Imm) && "Invalid immediate");
282 Inst.addOperand(MCOperand::createImm(Imm));
283 return MCDisassembler::Success;
284 }
285
286 template <unsigned N>
decodeUImmNonZeroOperand(MCInst & Inst,uint32_t Imm,int64_t Address,const MCDisassembler * Decoder)287 static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
288 int64_t Address,
289 const MCDisassembler *Decoder) {
290 if (Imm == 0)
291 return MCDisassembler::Fail;
292 return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
293 }
294
295 template <unsigned N>
decodeSImmOperand(MCInst & Inst,uint32_t Imm,int64_t Address,const MCDisassembler * Decoder)296 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint32_t Imm,
297 int64_t Address,
298 const MCDisassembler *Decoder) {
299 assert(isUInt<N>(Imm) && "Invalid immediate");
300 // Sign-extend the number in the bottom N bits of Imm
301 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
302 return MCDisassembler::Success;
303 }
304
305 template <unsigned N>
decodeSImmNonZeroOperand(MCInst & Inst,uint32_t Imm,int64_t Address,const MCDisassembler * Decoder)306 static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
307 int64_t Address,
308 const MCDisassembler *Decoder) {
309 if (Imm == 0)
310 return MCDisassembler::Fail;
311 return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
312 }
313
314 template <unsigned N>
decodeSImmOperandAndLsl1(MCInst & Inst,uint32_t Imm,int64_t Address,const MCDisassembler * Decoder)315 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint32_t Imm,
316 int64_t Address,
317 const MCDisassembler *Decoder) {
318 assert(isUInt<N>(Imm) && "Invalid immediate");
319 // Sign-extend the number in the bottom N bits of Imm after accounting for
320 // the fact that the N bit immediate is stored in N-1 bits (the LSB is
321 // always zero)
322 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
323 return MCDisassembler::Success;
324 }
325
decodeCLUIImmOperand(MCInst & Inst,uint32_t Imm,int64_t Address,const MCDisassembler * Decoder)326 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint32_t Imm,
327 int64_t Address,
328 const MCDisassembler *Decoder) {
329 assert(isUInt<6>(Imm) && "Invalid immediate");
330 if (Imm > 31) {
331 Imm = (SignExtend64<6>(Imm) & 0xfffff);
332 }
333 Inst.addOperand(MCOperand::createImm(Imm));
334 return MCDisassembler::Success;
335 }
336
decodeFRMArg(MCInst & Inst,uint32_t Imm,int64_t Address,const MCDisassembler * Decoder)337 static DecodeStatus decodeFRMArg(MCInst &Inst, uint32_t Imm, int64_t Address,
338 const MCDisassembler *Decoder) {
339 assert(isUInt<3>(Imm) && "Invalid immediate");
340 if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm))
341 return MCDisassembler::Fail;
342
343 Inst.addOperand(MCOperand::createImm(Imm));
344 return MCDisassembler::Success;
345 }
346
347 static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
348 uint64_t Address,
349 const MCDisassembler *Decoder);
350
351 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn,
352 uint64_t Address,
353 const MCDisassembler *Decoder);
354
355 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, uint32_t Insn,
356 uint64_t Address,
357 const MCDisassembler *Decoder);
358
359 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn,
360 uint64_t Address,
361 const MCDisassembler *Decoder);
362
363 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn,
364 uint64_t Address,
365 const MCDisassembler *Decoder);
366
367 static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,
368 uint64_t Address,
369 const MCDisassembler *Decoder);
370
371 static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,
372 uint64_t Address, const void *Decoder);
373
374 static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address,
375 const MCDisassembler *Decoder);
376
377 static DecodeStatus decodeZcmpSpimm(MCInst &Inst, uint32_t Imm,
378 uint64_t Address, const void *Decoder);
379
380 static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn,
381 uint64_t Address,
382 const MCDisassembler *Decoder);
383
384 #include "RISCVGenDisassemblerTables.inc"
385
decodeRVCInstrRdRs1ImmZero(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)386 static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
387 uint64_t Address,
388 const MCDisassembler *Decoder) {
389 uint32_t Rd = fieldFromInstruction(Insn, 7, 5);
390 [[maybe_unused]] DecodeStatus Result =
391 DecodeGPRNoX0RegisterClass(Inst, Rd, Address, Decoder);
392 assert(Result == MCDisassembler::Success && "Invalid register");
393 Inst.addOperand(Inst.getOperand(0));
394 Inst.addOperand(MCOperand::createImm(0));
395 return MCDisassembler::Success;
396 }
397
decodeCSSPushPopchk(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)398 static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn,
399 uint64_t Address,
400 const MCDisassembler *Decoder) {
401 uint32_t Rs1 = fieldFromInstruction(Insn, 7, 5);
402 [[maybe_unused]] DecodeStatus Result =
403 DecodeGPRX1X5RegisterClass(Inst, Rs1, Address, Decoder);
404 assert(Result == MCDisassembler::Success && "Invalid register");
405 return MCDisassembler::Success;
406 }
407
decodeRVCInstrRdSImm(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)408 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn,
409 uint64_t Address,
410 const MCDisassembler *Decoder) {
411 Inst.addOperand(MCOperand::createReg(RISCV::X0));
412 uint32_t SImm6 =
413 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
414 [[maybe_unused]] DecodeStatus Result =
415 decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
416 assert(Result == MCDisassembler::Success && "Invalid immediate");
417 return MCDisassembler::Success;
418 }
419
decodeRVCInstrRdRs1UImm(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)420 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, uint32_t Insn,
421 uint64_t Address,
422 const MCDisassembler *Decoder) {
423 Inst.addOperand(MCOperand::createReg(RISCV::X0));
424 Inst.addOperand(Inst.getOperand(0));
425 uint32_t UImm6 =
426 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
427 [[maybe_unused]] DecodeStatus Result =
428 decodeUImmOperand<6>(Inst, UImm6, Address, Decoder);
429 assert(Result == MCDisassembler::Success && "Invalid immediate");
430 return MCDisassembler::Success;
431 }
432
decodeRVCInstrRdRs2(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)433 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn,
434 uint64_t Address,
435 const MCDisassembler *Decoder) {
436 uint32_t Rd = fieldFromInstruction(Insn, 7, 5);
437 uint32_t Rs2 = fieldFromInstruction(Insn, 2, 5);
438 DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
439 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
440 return MCDisassembler::Success;
441 }
442
decodeRVCInstrRdRs1Rs2(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)443 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn,
444 uint64_t Address,
445 const MCDisassembler *Decoder) {
446 uint32_t Rd = fieldFromInstruction(Insn, 7, 5);
447 uint32_t Rs2 = fieldFromInstruction(Insn, 2, 5);
448 DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
449 Inst.addOperand(Inst.getOperand(0));
450 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
451 return MCDisassembler::Success;
452 }
453
decodeXTHeadMemPair(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)454 static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,
455 uint64_t Address,
456 const MCDisassembler *Decoder) {
457 uint32_t Rd1 = fieldFromInstruction(Insn, 7, 5);
458 uint32_t Rs1 = fieldFromInstruction(Insn, 15, 5);
459 uint32_t Rd2 = fieldFromInstruction(Insn, 20, 5);
460 uint32_t UImm2 = fieldFromInstruction(Insn, 25, 2);
461 DecodeGPRRegisterClass(Inst, Rd1, Address, Decoder);
462 DecodeGPRRegisterClass(Inst, Rd2, Address, Decoder);
463 DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder);
464 [[maybe_unused]] DecodeStatus Result =
465 decodeUImmOperand<2>(Inst, UImm2, Address, Decoder);
466 assert(Result == MCDisassembler::Success && "Invalid immediate");
467
468 // Disassemble the final operand which is implicit.
469 unsigned Opcode = Inst.getOpcode();
470 bool IsWordOp = (Opcode == RISCV::TH_LWD || Opcode == RISCV::TH_LWUD ||
471 Opcode == RISCV::TH_SWD);
472 if (IsWordOp)
473 Inst.addOperand(MCOperand::createImm(3));
474 else
475 Inst.addOperand(MCOperand::createImm(4));
476
477 return MCDisassembler::Success;
478 }
479
decodeZcmpRlist(MCInst & Inst,uint32_t Imm,uint64_t Address,const void * Decoder)480 static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,
481 uint64_t Address, const void *Decoder) {
482 if (Imm <= 3)
483 return MCDisassembler::Fail;
484 Inst.addOperand(MCOperand::createImm(Imm));
485 return MCDisassembler::Success;
486 }
487
decodeRegReg(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)488 static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address,
489 const MCDisassembler *Decoder) {
490 uint32_t Rs1 = fieldFromInstruction(Insn, 0, 5);
491 uint32_t Rs2 = fieldFromInstruction(Insn, 5, 5);
492 DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder);
493 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
494 return MCDisassembler::Success;
495 }
496
decodeZcmpSpimm(MCInst & Inst,uint32_t Imm,uint64_t Address,const void * Decoder)497 static DecodeStatus decodeZcmpSpimm(MCInst &Inst, uint32_t Imm,
498 uint64_t Address, const void *Decoder) {
499 Inst.addOperand(MCOperand::createImm(Imm));
500 return MCDisassembler::Success;
501 }
502
503 // Add implied SP operand for C.*SP compressed instructions. The SP operand
504 // isn't explicitly encoded in the instruction.
addSPOperands(MCInst & MI) const505 void RISCVDisassembler::addSPOperands(MCInst &MI) const {
506 const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
507 for (unsigned i = 0; i < MCID.getNumOperands(); i++)
508 if (MCID.operands()[i].RegClass == RISCV::SPRegClassID)
509 MI.insert(MI.begin() + i, MCOperand::createReg(RISCV::X2));
510 }
511
512 #define TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, \
513 DESC, ADDITIONAL_OPERATION) \
514 do { \
515 if (FEATURE_CHECKS) { \
516 LLVM_DEBUG(dbgs() << "Trying " DESC ":\n"); \
517 DecodeStatus Result = \
518 decodeInstruction(DECODER_TABLE, MI, Insn, Address, this, STI); \
519 if (Result != MCDisassembler::Fail) { \
520 ADDITIONAL_OPERATION; \
521 return Result; \
522 } \
523 } \
524 } while (false)
525 #define TRY_TO_DECODE_AND_ADD_SP(FEATURE_CHECKS, DECODER_TABLE, DESC) \
526 TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, DESC, \
527 addSPOperands(MI))
528 #define TRY_TO_DECODE(FEATURE_CHECKS, DECODER_TABLE, DESC) \
529 TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, DESC, \
530 (void)nullptr)
531 #define TRY_TO_DECODE_FEATURE(FEATURE, DECODER_TABLE, DESC) \
532 TRY_TO_DECODE(STI.hasFeature(FEATURE), DECODER_TABLE, DESC)
533
getInstruction32(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const534 DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
535 ArrayRef<uint8_t> Bytes,
536 uint64_t Address,
537 raw_ostream &CS) const {
538 if (Bytes.size() < 4) {
539 Size = 0;
540 return MCDisassembler::Fail;
541 }
542 Size = 4;
543
544 uint32_t Insn = support::endian::read32le(Bytes.data());
545
546 TRY_TO_DECODE(STI.hasFeature(RISCV::FeatureStdExtZdinx) &&
547 !STI.hasFeature(RISCV::Feature64Bit),
548 DecoderTableRV32Zdinx32,
549 "RV32Zdinx table (Double in Integer and rv32)");
550 TRY_TO_DECODE(STI.hasFeature(RISCV::FeatureStdExtZacas) &&
551 !STI.hasFeature(RISCV::Feature64Bit),
552 DecoderTableRV32Zacas32,
553 "RV32Zacas table (Compare-And-Swap and rv32)");
554 TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZfinx, DecoderTableRVZfinx32,
555 "RVZfinx table (Float in Integer)");
556 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXVentanaCondOps,
557 DecoderTableXVentana32, "Ventana custom opcode table");
558 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBa, DecoderTableXTHeadBa32,
559 "XTHeadBa custom opcode table");
560 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBb, DecoderTableXTHeadBb32,
561 "XTHeadBb custom opcode table");
562 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBs, DecoderTableXTHeadBs32,
563 "XTHeadBs custom opcode table");
564 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadCondMov,
565 DecoderTableXTHeadCondMov32,
566 "XTHeadCondMov custom opcode table");
567 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadCmo, DecoderTableXTHeadCmo32,
568 "XTHeadCmo custom opcode table");
569 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadFMemIdx,
570 DecoderTableXTHeadFMemIdx32,
571 "XTHeadFMemIdx custom opcode table");
572 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMac, DecoderTableXTHeadMac32,
573 "XTHeadMac custom opcode table");
574 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMemIdx,
575 DecoderTableXTHeadMemIdx32,
576 "XTHeadMemIdx custom opcode table");
577 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMemPair,
578 DecoderTableXTHeadMemPair32,
579 "XTHeadMemPair custom opcode table");
580 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadSync,
581 DecoderTableXTHeadSync32,
582 "XTHeadSync custom opcode table");
583 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadVdot,
584 DecoderTableXTHeadVdot32,
585 "XTHeadVdot custom opcode table");
586 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfvcp, DecoderTableXSfvcp32,
587 "SiFive VCIX custom opcode table");
588 TRY_TO_DECODE_FEATURE(
589 RISCV::FeatureVendorXSfvqmaccdod, DecoderTableXSfvqmaccdod32,
590 "SiFive Matrix Multiplication (2x8 and 8x2) Instruction opcode table");
591 TRY_TO_DECODE_FEATURE(
592 RISCV::FeatureVendorXSfvqmaccqoq, DecoderTableXSfvqmaccqoq32,
593 "SiFive Matrix Multiplication (4x8 and 8x4) Instruction opcode table");
594 TRY_TO_DECODE_FEATURE(
595 RISCV::FeatureVendorXSfvfwmaccqqq, DecoderTableXSfvfwmaccqqq32,
596 "SiFive Matrix Multiplication Instruction opcode table");
597 TRY_TO_DECODE_FEATURE(
598 RISCV::FeatureVendorXSfvfnrclipxfqf, DecoderTableXSfvfnrclipxfqf32,
599 "SiFive FP32-to-int8 Ranged Clip Instructions opcode table");
600 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSiFivecdiscarddlone,
601 DecoderTableXSiFivecdiscarddlone32,
602 "SiFive sf.cdiscard.d.l1 custom opcode table");
603 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSiFivecflushdlone,
604 DecoderTableXSiFivecflushdlone32,
605 "SiFive sf.cflush.d.l1 custom opcode table");
606 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfcease, DecoderTableXSfcease32,
607 "SiFive sf.cease custom opcode table");
608 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbitmanip,
609 DecoderTableXCVbitmanip32,
610 "CORE-V Bit Manipulation custom opcode table");
611 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVelw, DecoderTableXCVelw32,
612 "CORE-V Event load custom opcode table");
613 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmac, DecoderTableXCVmac32,
614 "CORE-V MAC custom opcode table");
615 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmem, DecoderTableXCVmem32,
616 "CORE-V MEM custom opcode table");
617 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCValu, DecoderTableXCValu32,
618 "CORE-V ALU custom opcode table");
619 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVsimd, DecoderTableXCVsimd32,
620 "CORE-V SIMD extensions custom opcode table");
621 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbi, DecoderTableXCVbi32,
622 "CORE-V Immediate Branching custom opcode table");
623 TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
624
625 return MCDisassembler::Fail;
626 }
627
getInstruction16(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const628 DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,
629 ArrayRef<uint8_t> Bytes,
630 uint64_t Address,
631 raw_ostream &CS) const {
632 if (Bytes.size() < 2) {
633 Size = 0;
634 return MCDisassembler::Fail;
635 }
636 Size = 2;
637
638 uint32_t Insn = support::endian::read16le(Bytes.data());
639 TRY_TO_DECODE_AND_ADD_SP(!STI.hasFeature(RISCV::Feature64Bit),
640 DecoderTableRISCV32Only_16,
641 "RISCV32Only_16 table (16-bit Instruction)");
642 TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZicfiss, DecoderTableZicfiss16,
643 "RVZicfiss table (Shadow Stack)");
644 TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZcmt, DecoderTableRVZcmt16,
645 "Zcmt table (16-bit Table Jump Instructions)");
646 TRY_TO_DECODE_FEATURE(
647 RISCV::FeatureStdExtZcmp, DecoderTableRVZcmp16,
648 "Zcmp table (16-bit Push/Pop & Double Move Instructions)");
649 TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc),
650 DecoderTableXwchc16,
651 "WCH QingKe XW custom opcode table");
652 TRY_TO_DECODE_AND_ADD_SP(true, DecoderTable16,
653 "RISCV_C table (16-bit Instruction)");
654
655 return MCDisassembler::Fail;
656 }
657
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const658 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
659 ArrayRef<uint8_t> Bytes,
660 uint64_t Address,
661 raw_ostream &CS) const {
662 // It's a 16 bit instruction if bit 0 and 1 are not 0b11.
663 if ((Bytes[0] & 0b11) != 0b11)
664 return getInstruction16(MI, Size, Bytes, Address, CS);
665
666 // It's a 32 bit instruction if bit 1:0 are 0b11(checked above) and bits 4:2
667 // are not 0b111.
668 if ((Bytes[0] & 0b1'1100) != 0b1'1100)
669 return getInstruction32(MI, Size, Bytes, Address, CS);
670
671 // 48-bit instructions are encoded as 0bxx011111.
672 if ((Bytes[0] & 0b11'1111) == 0b01'1111) {
673 Size = Bytes.size() >= 6 ? 6 : 0;
674 return MCDisassembler::Fail;
675 }
676
677 // 64-bit instructions are encoded as 0x0111111.
678 if ((Bytes[0] & 0b111'1111) == 0b011'1111) {
679 Size = Bytes.size() >= 8 ? 8 : 0;
680 return MCDisassembler::Fail;
681 }
682
683 // Remaining cases need to check a second byte.
684 if (Bytes.size() < 2) {
685 Size = 0;
686 return MCDisassembler::Fail;
687 }
688
689 // 80-bit through 176-bit instructions are encoded as 0bxnnnxxxx_x1111111.
690 // Where the number of bits is (80 + (nnn * 16)) for nnn != 0b111.
691 unsigned nnn = (Bytes[1] >> 4) & 0b111;
692 if (nnn != 0b111) {
693 Size = 10 + (nnn * 2);
694 if (Bytes.size() < Size)
695 Size = 0;
696 return MCDisassembler::Fail;
697 }
698
699 // Remaining encodings are reserved for > 176-bit instructions.
700 Size = 0;
701 return MCDisassembler::Fail;
702 }
703