xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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