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