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/RISCVMCTargetDesc.h"
14 #include "TargetInfo/RISCVTargetInfo.h"
15 #include "Utils/RISCVBaseInfo.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 DecodeFPR32RegisterClass(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_F + RegNo;
85   Inst.addOperand(MCOperand::createReg(Reg));
86   return MCDisassembler::Success;
87 }
88 
89 static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo,
90                                               uint64_t Address,
91                                               const void *Decoder) {
92   if (RegNo >= 8) {
93     return MCDisassembler::Fail;
94   }
95   MCRegister Reg = RISCV::F8_F + RegNo;
96   Inst.addOperand(MCOperand::createReg(Reg));
97   return MCDisassembler::Success;
98 }
99 
100 static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
101                                              uint64_t Address,
102                                              const void *Decoder) {
103   if (RegNo >= 32)
104     return MCDisassembler::Fail;
105 
106   MCRegister Reg = RISCV::F0_D + RegNo;
107   Inst.addOperand(MCOperand::createReg(Reg));
108   return MCDisassembler::Success;
109 }
110 
111 static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo,
112                                               uint64_t Address,
113                                               const void *Decoder) {
114   if (RegNo >= 8) {
115     return MCDisassembler::Fail;
116   }
117   MCRegister Reg = RISCV::F8_D + RegNo;
118   Inst.addOperand(MCOperand::createReg(Reg));
119   return MCDisassembler::Success;
120 }
121 
122 static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo,
123                                                uint64_t Address,
124                                                const void *Decoder) {
125   if (RegNo == 0) {
126     return MCDisassembler::Fail;
127   }
128 
129   return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
130 }
131 
132 static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo,
133                                                  uint64_t Address,
134                                                  const void *Decoder) {
135   if (RegNo == 2) {
136     return MCDisassembler::Fail;
137   }
138 
139   return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
140 }
141 
142 static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
143                                             uint64_t Address,
144                                             const void *Decoder) {
145   if (RegNo >= 8)
146     return MCDisassembler::Fail;
147 
148   MCRegister Reg = RISCV::X8 + RegNo;
149   Inst.addOperand(MCOperand::createReg(Reg));
150   return MCDisassembler::Success;
151 }
152 
153 static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint64_t RegNo,
154                                           uint64_t Address,
155                                           const void *Decoder) {
156   if (RegNo >= 32)
157     return MCDisassembler::Fail;
158 
159   MCRegister Reg = RISCV::V0 + RegNo;
160   Inst.addOperand(MCOperand::createReg(Reg));
161   return MCDisassembler::Success;
162 }
163 
164 static DecodeStatus decodeVMaskReg(MCInst &Inst, uint64_t RegNo,
165                                    uint64_t Address, const void *Decoder) {
166   MCRegister Reg = RISCV::NoRegister;
167   switch (RegNo) {
168   default:
169     return MCDisassembler::Fail;
170   case 0:
171     Reg = RISCV::V0;
172     break;
173   case 1:
174     break;
175   }
176   Inst.addOperand(MCOperand::createReg(Reg));
177   return MCDisassembler::Success;
178 }
179 
180 // Add implied SP operand for instructions *SP compressed instructions. The SP
181 // operand isn't explicitly encoded in the instruction.
182 static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) {
183   if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP ||
184       Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP ||
185       Inst.getOpcode() == RISCV::C_FLWSP ||
186       Inst.getOpcode() == RISCV::C_FSWSP ||
187       Inst.getOpcode() == RISCV::C_FLDSP ||
188       Inst.getOpcode() == RISCV::C_FSDSP ||
189       Inst.getOpcode() == RISCV::C_ADDI4SPN) {
190     DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
191   }
192   if (Inst.getOpcode() == RISCV::C_ADDI16SP) {
193     DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
194     DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
195   }
196 }
197 
198 template <unsigned N>
199 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
200                                       int64_t Address, const void *Decoder) {
201   assert(isUInt<N>(Imm) && "Invalid immediate");
202   addImplySP(Inst, Address, Decoder);
203   Inst.addOperand(MCOperand::createImm(Imm));
204   return MCDisassembler::Success;
205 }
206 
207 template <unsigned N>
208 static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
209                                              int64_t Address,
210                                              const void *Decoder) {
211   if (Imm == 0)
212     return MCDisassembler::Fail;
213   return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
214 }
215 
216 template <unsigned N>
217 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
218                                       int64_t Address, const void *Decoder) {
219   assert(isUInt<N>(Imm) && "Invalid immediate");
220   addImplySP(Inst, Address, Decoder);
221   // Sign-extend the number in the bottom N bits of Imm
222   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
223   return MCDisassembler::Success;
224 }
225 
226 template <unsigned N>
227 static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
228                                              int64_t Address,
229                                              const void *Decoder) {
230   if (Imm == 0)
231     return MCDisassembler::Fail;
232   return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
233 }
234 
235 template <unsigned N>
236 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm,
237                                              int64_t Address,
238                                              const void *Decoder) {
239   assert(isUInt<N>(Imm) && "Invalid immediate");
240   // Sign-extend the number in the bottom N bits of Imm after accounting for
241   // the fact that the N bit immediate is stored in N-1 bits (the LSB is
242   // always zero)
243   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
244   return MCDisassembler::Success;
245 }
246 
247 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm,
248                                          int64_t Address,
249                                          const void *Decoder) {
250   assert(isUInt<6>(Imm) && "Invalid immediate");
251   if (Imm > 31) {
252     Imm = (SignExtend64<6>(Imm) & 0xfffff);
253   }
254   Inst.addOperand(MCOperand::createImm(Imm));
255   return MCDisassembler::Success;
256 }
257 
258 static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm,
259                                  int64_t Address,
260                                  const void *Decoder) {
261   assert(isUInt<3>(Imm) && "Invalid immediate");
262   if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm))
263     return MCDisassembler::Fail;
264 
265   Inst.addOperand(MCOperand::createImm(Imm));
266   return MCDisassembler::Success;
267 }
268 
269 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
270                                        uint64_t Address, const void *Decoder);
271 
272 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
273                                          uint64_t Address, const void *Decoder);
274 
275 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
276                                             uint64_t Address,
277                                             const void *Decoder);
278 
279 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
280                                         uint64_t Address, const void *Decoder);
281 
282 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
283                                            uint64_t Address,
284                                            const void *Decoder);
285 
286 #include "RISCVGenDisassemblerTables.inc"
287 
288 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
289                                        uint64_t Address, const void *Decoder) {
290   uint64_t SImm6 =
291       fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
292   DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
293   (void)Result;
294   assert(Result == MCDisassembler::Success && "Invalid immediate");
295   return MCDisassembler::Success;
296 }
297 
298 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
299                                          uint64_t Address,
300                                          const void *Decoder) {
301   DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
302   uint64_t SImm6 =
303       fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
304   DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
305   (void)Result;
306   assert(Result == MCDisassembler::Success && "Invalid immediate");
307   return MCDisassembler::Success;
308 }
309 
310 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
311                                             uint64_t Address,
312                                             const void *Decoder) {
313   DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
314   Inst.addOperand(Inst.getOperand(0));
315   uint64_t UImm6 =
316       fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
317   DecodeStatus Result = decodeUImmOperand<6>(Inst, UImm6, Address, Decoder);
318   (void)Result;
319   assert(Result == MCDisassembler::Success && "Invalid immediate");
320   return MCDisassembler::Success;
321 }
322 
323 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
324                                         uint64_t Address, const void *Decoder) {
325   unsigned Rd = fieldFromInstruction(Insn, 7, 5);
326   unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
327   DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
328   DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
329   return MCDisassembler::Success;
330 }
331 
332 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
333                                            uint64_t Address,
334                                            const void *Decoder) {
335   unsigned Rd = fieldFromInstruction(Insn, 7, 5);
336   unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
337   DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
338   Inst.addOperand(Inst.getOperand(0));
339   DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
340   return MCDisassembler::Success;
341 }
342 
343 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
344                                                ArrayRef<uint8_t> Bytes,
345                                                uint64_t Address,
346                                                raw_ostream &CS) const {
347   // TODO: This will need modification when supporting instruction set
348   // extensions with instructions > 32-bits (up to 176 bits wide).
349   uint32_t Insn;
350   DecodeStatus Result;
351 
352   // It's a 32 bit instruction if bit 0 and 1 are 1.
353   if ((Bytes[0] & 0x3) == 0x3) {
354     if (Bytes.size() < 4) {
355       Size = 0;
356       return MCDisassembler::Fail;
357     }
358     Insn = support::endian::read32le(Bytes.data());
359     LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
360     Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
361     Size = 4;
362   } else {
363     if (Bytes.size() < 2) {
364       Size = 0;
365       return MCDisassembler::Fail;
366     }
367     Insn = support::endian::read16le(Bytes.data());
368 
369     if (!STI.getFeatureBits()[RISCV::Feature64Bit]) {
370       LLVM_DEBUG(
371           dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n");
372       // Calling the auto-generated decoder function.
373       Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address,
374                                  this, STI);
375       if (Result != MCDisassembler::Fail) {
376         Size = 2;
377         return Result;
378       }
379     }
380 
381     if (STI.getFeatureBits()[RISCV::FeatureExtZbproposedc] &&
382         STI.getFeatureBits()[RISCV::FeatureStdExtC]) {
383       LLVM_DEBUG(
384           dbgs() << "Trying RVBC32 table (BitManip 16-bit Instruction):\n");
385       // Calling the auto-generated decoder function.
386       Result = decodeInstruction(DecoderTableRVBC16, MI, Insn, Address,
387                                  this, STI);
388       if (Result != MCDisassembler::Fail) {
389         Size = 2;
390         return Result;
391       }
392     }
393 
394     LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n");
395     // Calling the auto-generated decoder function.
396     Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
397     Size = 2;
398   }
399 
400   return Result;
401 }
402