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