xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (revision 9f23cbd6cae82fd77edfad7173432fa8dccd0a95)
1 //===-- RISCVDisassembler.cpp - Disassembler for RISCV --------------------===//
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:
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 } // end anonymous namespace
46 
47 static MCDisassembler *createRISCVDisassembler(const Target &T,
48                                                const MCSubtargetInfo &STI,
49                                                MCContext &Ctx) {
50   return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo());
51 }
52 
53 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVDisassembler() {
54   // Register the disassembler for each target.
55   TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(),
56                                          createRISCVDisassembler);
57   TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(),
58                                          createRISCVDisassembler);
59 }
60 
61 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
62                                            uint64_t Address,
63                                            const MCDisassembler *Decoder) {
64   const FeatureBitset &FeatureBits =
65       Decoder->getSubtargetInfo().getFeatureBits();
66   bool IsRV32E = FeatureBits[RISCV::FeatureRV32E];
67 
68   if (RegNo >= 32 || (IsRV32E && RegNo >= 16))
69     return MCDisassembler::Fail;
70 
71   MCRegister Reg = RISCV::X0 + RegNo;
72   Inst.addOperand(MCOperand::createReg(Reg));
73   return MCDisassembler::Success;
74 }
75 
76 static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, uint64_t RegNo,
77                                              uint64_t Address,
78                                              const MCDisassembler *Decoder) {
79   if (RegNo >= 32)
80     return MCDisassembler::Fail;
81 
82   MCRegister Reg = RISCV::F0_H + RegNo;
83   Inst.addOperand(MCOperand::createReg(Reg));
84   return MCDisassembler::Success;
85 }
86 
87 static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
88                                              uint64_t Address,
89                                              const MCDisassembler *Decoder) {
90   if (RegNo >= 32)
91     return MCDisassembler::Fail;
92 
93   MCRegister Reg = RISCV::F0_F + RegNo;
94   Inst.addOperand(MCOperand::createReg(Reg));
95   return MCDisassembler::Success;
96 }
97 
98 static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo,
99                                               uint64_t Address,
100                                               const MCDisassembler *Decoder) {
101   if (RegNo >= 8) {
102     return MCDisassembler::Fail;
103   }
104   MCRegister Reg = RISCV::F8_F + RegNo;
105   Inst.addOperand(MCOperand::createReg(Reg));
106   return MCDisassembler::Success;
107 }
108 
109 static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
110                                              uint64_t Address,
111                                              const MCDisassembler *Decoder) {
112   if (RegNo >= 32)
113     return MCDisassembler::Fail;
114 
115   MCRegister Reg = RISCV::F0_D + RegNo;
116   Inst.addOperand(MCOperand::createReg(Reg));
117   return MCDisassembler::Success;
118 }
119 
120 static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo,
121                                               uint64_t Address,
122                                               const MCDisassembler *Decoder) {
123   if (RegNo >= 8) {
124     return MCDisassembler::Fail;
125   }
126   MCRegister Reg = RISCV::F8_D + RegNo;
127   Inst.addOperand(MCOperand::createReg(Reg));
128   return MCDisassembler::Success;
129 }
130 
131 static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo,
132                                                uint64_t Address,
133                                                const MCDisassembler *Decoder) {
134   if (RegNo == 0) {
135     return MCDisassembler::Fail;
136   }
137 
138   return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
139 }
140 
141 static DecodeStatus
142 DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address,
143                              const MCDisassembler *Decoder) {
144   if (RegNo == 2) {
145     return MCDisassembler::Fail;
146   }
147 
148   return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
149 }
150 
151 static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
152                                             uint64_t Address,
153                                             const MCDisassembler *Decoder) {
154   if (RegNo >= 8)
155     return MCDisassembler::Fail;
156 
157   MCRegister Reg = RISCV::X8 + RegNo;
158   Inst.addOperand(MCOperand::createReg(Reg));
159   return MCDisassembler::Success;
160 }
161 
162 static DecodeStatus DecodeGPRPF64RegisterClass(MCInst &Inst, uint64_t RegNo,
163                                                uint64_t Address,
164                                                const MCDisassembler *Decoder) {
165   if (RegNo >= 32 || RegNo & 1)
166     return MCDisassembler::Fail;
167 
168   MCRegister Reg = RISCV::X0 + RegNo;
169   Inst.addOperand(MCOperand::createReg(Reg));
170   return MCDisassembler::Success;
171 }
172 
173 static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint64_t RegNo,
174                                           uint64_t Address,
175                                           const MCDisassembler *Decoder) {
176   if (RegNo >= 32)
177     return MCDisassembler::Fail;
178 
179   MCRegister Reg = RISCV::V0 + RegNo;
180   Inst.addOperand(MCOperand::createReg(Reg));
181   return MCDisassembler::Success;
182 }
183 
184 static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint64_t RegNo,
185                                             uint64_t Address,
186                                             const MCDisassembler *Decoder) {
187   if (RegNo >= 32)
188     return MCDisassembler::Fail;
189 
190   if (RegNo % 2)
191     return MCDisassembler::Fail;
192 
193   const RISCVDisassembler *Dis =
194       static_cast<const RISCVDisassembler *>(Decoder);
195   const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
196   MCRegister Reg =
197       RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
198                               &RISCVMCRegisterClasses[RISCV::VRM2RegClassID]);
199 
200   Inst.addOperand(MCOperand::createReg(Reg));
201   return MCDisassembler::Success;
202 }
203 
204 static DecodeStatus DecodeVRM4RegisterClass(MCInst &Inst, uint64_t RegNo,
205                                             uint64_t Address,
206                                             const MCDisassembler *Decoder) {
207   if (RegNo >= 32)
208     return MCDisassembler::Fail;
209 
210   if (RegNo % 4)
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::VRM4RegClassID]);
219 
220   Inst.addOperand(MCOperand::createReg(Reg));
221   return MCDisassembler::Success;
222 }
223 
224 static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint64_t RegNo,
225                                             uint64_t Address,
226                                             const MCDisassembler *Decoder) {
227   if (RegNo >= 32)
228     return MCDisassembler::Fail;
229 
230   if (RegNo % 8)
231     return MCDisassembler::Fail;
232 
233   const RISCVDisassembler *Dis =
234       static_cast<const RISCVDisassembler *>(Decoder);
235   const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
236   MCRegister Reg =
237       RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
238                               &RISCVMCRegisterClasses[RISCV::VRM8RegClassID]);
239 
240   Inst.addOperand(MCOperand::createReg(Reg));
241   return MCDisassembler::Success;
242 }
243 
244 static DecodeStatus decodeVMaskReg(MCInst &Inst, uint64_t RegNo,
245                                    uint64_t Address,
246                                    const MCDisassembler *Decoder) {
247   MCRegister Reg = RISCV::NoRegister;
248   switch (RegNo) {
249   default:
250     return MCDisassembler::Fail;
251   case 0:
252     Reg = RISCV::V0;
253     break;
254   case 1:
255     break;
256   }
257   Inst.addOperand(MCOperand::createReg(Reg));
258   return MCDisassembler::Success;
259 }
260 
261 // Add implied SP operand for instructions *SP compressed instructions. The SP
262 // operand isn't explicitly encoded in the instruction.
263 static void addImplySP(MCInst &Inst, int64_t Address,
264                        const MCDisassembler *Decoder) {
265   if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP ||
266       Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP ||
267       Inst.getOpcode() == RISCV::C_FLWSP ||
268       Inst.getOpcode() == RISCV::C_FSWSP ||
269       Inst.getOpcode() == RISCV::C_FLDSP ||
270       Inst.getOpcode() == RISCV::C_FSDSP ||
271       Inst.getOpcode() == RISCV::C_ADDI4SPN) {
272     DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
273   }
274   if (Inst.getOpcode() == RISCV::C_ADDI16SP) {
275     DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
276     DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
277   }
278 }
279 
280 template <unsigned N>
281 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
282                                       int64_t Address,
283                                       const MCDisassembler *Decoder) {
284   assert(isUInt<N>(Imm) && "Invalid immediate");
285   addImplySP(Inst, Address, Decoder);
286   Inst.addOperand(MCOperand::createImm(Imm));
287   return MCDisassembler::Success;
288 }
289 
290 template <unsigned N>
291 static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
292                                              int64_t Address,
293                                              const MCDisassembler *Decoder) {
294   if (Imm == 0)
295     return MCDisassembler::Fail;
296   return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
297 }
298 
299 template <unsigned N>
300 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
301                                       int64_t Address,
302                                       const MCDisassembler *Decoder) {
303   assert(isUInt<N>(Imm) && "Invalid immediate");
304   addImplySP(Inst, Address, Decoder);
305   // Sign-extend the number in the bottom N bits of Imm
306   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
307   return MCDisassembler::Success;
308 }
309 
310 template <unsigned N>
311 static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
312                                              int64_t Address,
313                                              const MCDisassembler *Decoder) {
314   if (Imm == 0)
315     return MCDisassembler::Fail;
316   return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
317 }
318 
319 template <unsigned N>
320 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm,
321                                              int64_t Address,
322                                              const MCDisassembler *Decoder) {
323   assert(isUInt<N>(Imm) && "Invalid immediate");
324   // Sign-extend the number in the bottom N bits of Imm after accounting for
325   // the fact that the N bit immediate is stored in N-1 bits (the LSB is
326   // always zero)
327   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
328   return MCDisassembler::Success;
329 }
330 
331 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm,
332                                          int64_t Address,
333                                          const MCDisassembler *Decoder) {
334   assert(isUInt<6>(Imm) && "Invalid immediate");
335   if (Imm > 31) {
336     Imm = (SignExtend64<6>(Imm) & 0xfffff);
337   }
338   Inst.addOperand(MCOperand::createImm(Imm));
339   return MCDisassembler::Success;
340 }
341 
342 static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm, int64_t Address,
343                                  const MCDisassembler *Decoder) {
344   assert(isUInt<3>(Imm) && "Invalid immediate");
345   if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm))
346     return MCDisassembler::Fail;
347 
348   Inst.addOperand(MCOperand::createImm(Imm));
349   return MCDisassembler::Success;
350 }
351 
352 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
353                                        uint64_t Address,
354                                        const MCDisassembler *Decoder);
355 
356 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
357                                          uint64_t Address,
358                                          const MCDisassembler *Decoder);
359 
360 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
361                                             uint64_t Address,
362                                             const MCDisassembler *Decoder);
363 
364 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
365                                         uint64_t Address,
366                                         const MCDisassembler *Decoder);
367 
368 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
369                                            uint64_t Address,
370                                            const MCDisassembler *Decoder);
371 
372 #include "RISCVGenDisassemblerTables.inc"
373 
374 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
375                                        uint64_t Address,
376                                        const MCDisassembler *Decoder) {
377   uint64_t SImm6 =
378       fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
379   DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
380   (void)Result;
381   assert(Result == MCDisassembler::Success && "Invalid immediate");
382   return MCDisassembler::Success;
383 }
384 
385 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
386                                          uint64_t Address,
387                                          const MCDisassembler *Decoder) {
388   DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
389   uint64_t SImm6 =
390       fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
391   DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
392   (void)Result;
393   assert(Result == MCDisassembler::Success && "Invalid immediate");
394   return MCDisassembler::Success;
395 }
396 
397 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
398                                             uint64_t Address,
399                                             const MCDisassembler *Decoder) {
400   DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
401   Inst.addOperand(Inst.getOperand(0));
402   uint64_t UImm6 =
403       fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
404   DecodeStatus Result = decodeUImmOperand<6>(Inst, UImm6, Address, Decoder);
405   (void)Result;
406   assert(Result == MCDisassembler::Success && "Invalid immediate");
407   return MCDisassembler::Success;
408 }
409 
410 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
411                                         uint64_t Address,
412                                         const MCDisassembler *Decoder) {
413   unsigned Rd = fieldFromInstruction(Insn, 7, 5);
414   unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
415   DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
416   DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
417   return MCDisassembler::Success;
418 }
419 
420 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
421                                            uint64_t Address,
422                                            const MCDisassembler *Decoder) {
423   unsigned Rd = fieldFromInstruction(Insn, 7, 5);
424   unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
425   DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
426   Inst.addOperand(Inst.getOperand(0));
427   DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
428   return MCDisassembler::Success;
429 }
430 
431 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
432                                                ArrayRef<uint8_t> Bytes,
433                                                uint64_t Address,
434                                                raw_ostream &CS) const {
435   // TODO: This will need modification when supporting instruction set
436   // extensions with instructions > 32-bits (up to 176 bits wide).
437   uint32_t Insn;
438   DecodeStatus Result;
439 
440   // It's a 32 bit instruction if bit 0 and 1 are 1.
441   if ((Bytes[0] & 0x3) == 0x3) {
442     if (Bytes.size() < 4) {
443       Size = 0;
444       return MCDisassembler::Fail;
445     }
446     Insn = support::endian::read32le(Bytes.data());
447     if (STI.getFeatureBits()[RISCV::FeatureStdExtZdinx] &&
448         !STI.getFeatureBits()[RISCV::Feature64Bit]) {
449       LLVM_DEBUG(dbgs() << "Trying RV32Zdinx table (Double in Integer and"
450                            "rv32)\n");
451       Result = decodeInstruction(DecoderTableRV32Zdinx32, MI, Insn, Address,
452                                  this, STI);
453       if (Result != MCDisassembler::Fail) {
454         Size = 4;
455         return Result;
456       }
457     }
458 
459     if (STI.getFeatureBits()[RISCV::FeatureStdExtZfinx]) {
460       LLVM_DEBUG(dbgs() << "Trying RVZfinx table (Float in Integer):\n");
461       Result = decodeInstruction(DecoderTableRVZfinx32, MI, Insn, Address, this,
462                                  STI);
463       if (Result != MCDisassembler::Fail) {
464         Size = 4;
465         return Result;
466       }
467     }
468     if (STI.getFeatureBits()[RISCV::FeatureVendorXVentanaCondOps]) {
469       LLVM_DEBUG(dbgs() << "Trying Ventana custom opcode table:\n");
470       Result = decodeInstruction(DecoderTableVentana32, MI, Insn, Address, this,
471                                  STI);
472       if (Result != MCDisassembler::Fail) {
473         Size = 4;
474         return Result;
475       }
476     }
477     if (STI.getFeatureBits()[RISCV::FeatureVendorXTHeadVdot]) {
478       LLVM_DEBUG(dbgs() << "Trying T-Head custom opcode table:\n");
479       Result =
480           decodeInstruction(DecoderTableTHeadV32, MI, Insn, Address, this, STI);
481       if (Result != MCDisassembler::Fail) {
482         Size = 4;
483         return Result;
484       }
485     }
486 
487     LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
488     Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
489     Size = 4;
490   } else {
491     if (Bytes.size() < 2) {
492       Size = 0;
493       return MCDisassembler::Fail;
494     }
495     Insn = support::endian::read16le(Bytes.data());
496 
497     if (!STI.getFeatureBits()[RISCV::Feature64Bit]) {
498       LLVM_DEBUG(
499           dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n");
500       // Calling the auto-generated decoder function.
501       Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address,
502                                  this, STI);
503       if (Result != MCDisassembler::Fail) {
504         Size = 2;
505         return Result;
506       }
507     }
508 
509     LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n");
510     // Calling the auto-generated decoder function.
511     Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
512     Size = 2;
513   }
514 
515   return Result;
516 }
517