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