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 decodeVMaskReg(MCInst &Inst, uint64_t RegNo,
176                                    uint64_t Address, const void *Decoder) {
177   MCRegister Reg = RISCV::NoRegister;
178   switch (RegNo) {
179   default:
180     return MCDisassembler::Fail;
181   case 0:
182     Reg = RISCV::V0;
183     break;
184   case 1:
185     break;
186   }
187   Inst.addOperand(MCOperand::createReg(Reg));
188   return MCDisassembler::Success;
189 }
190 
191 // Add implied SP operand for instructions *SP compressed instructions. The SP
192 // operand isn't explicitly encoded in the instruction.
193 static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) {
194   if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP ||
195       Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP ||
196       Inst.getOpcode() == RISCV::C_FLWSP ||
197       Inst.getOpcode() == RISCV::C_FSWSP ||
198       Inst.getOpcode() == RISCV::C_FLDSP ||
199       Inst.getOpcode() == RISCV::C_FSDSP ||
200       Inst.getOpcode() == RISCV::C_ADDI4SPN) {
201     DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
202   }
203   if (Inst.getOpcode() == RISCV::C_ADDI16SP) {
204     DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
205     DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
206   }
207 }
208 
209 template <unsigned N>
210 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
211                                       int64_t Address, const void *Decoder) {
212   assert(isUInt<N>(Imm) && "Invalid immediate");
213   addImplySP(Inst, Address, Decoder);
214   Inst.addOperand(MCOperand::createImm(Imm));
215   return MCDisassembler::Success;
216 }
217 
218 template <unsigned N>
219 static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
220                                              int64_t Address,
221                                              const void *Decoder) {
222   if (Imm == 0)
223     return MCDisassembler::Fail;
224   return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
225 }
226 
227 template <unsigned N>
228 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
229                                       int64_t Address, const void *Decoder) {
230   assert(isUInt<N>(Imm) && "Invalid immediate");
231   addImplySP(Inst, Address, Decoder);
232   // Sign-extend the number in the bottom N bits of Imm
233   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
234   return MCDisassembler::Success;
235 }
236 
237 template <unsigned N>
238 static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
239                                              int64_t Address,
240                                              const void *Decoder) {
241   if (Imm == 0)
242     return MCDisassembler::Fail;
243   return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
244 }
245 
246 template <unsigned N>
247 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm,
248                                              int64_t Address,
249                                              const void *Decoder) {
250   assert(isUInt<N>(Imm) && "Invalid immediate");
251   // Sign-extend the number in the bottom N bits of Imm after accounting for
252   // the fact that the N bit immediate is stored in N-1 bits (the LSB is
253   // always zero)
254   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
255   return MCDisassembler::Success;
256 }
257 
258 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm,
259                                          int64_t Address,
260                                          const void *Decoder) {
261   assert(isUInt<6>(Imm) && "Invalid immediate");
262   if (Imm > 31) {
263     Imm = (SignExtend64<6>(Imm) & 0xfffff);
264   }
265   Inst.addOperand(MCOperand::createImm(Imm));
266   return MCDisassembler::Success;
267 }
268 
269 static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm,
270                                  int64_t Address,
271                                  const void *Decoder) {
272   assert(isUInt<3>(Imm) && "Invalid immediate");
273   if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm))
274     return MCDisassembler::Fail;
275 
276   Inst.addOperand(MCOperand::createImm(Imm));
277   return MCDisassembler::Success;
278 }
279 
280 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
281                                        uint64_t Address, const void *Decoder);
282 
283 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
284                                          uint64_t Address, const void *Decoder);
285 
286 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
287                                             uint64_t Address,
288                                             const void *Decoder);
289 
290 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
291                                         uint64_t Address, const void *Decoder);
292 
293 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
294                                            uint64_t Address,
295                                            const void *Decoder);
296 
297 #include "RISCVGenDisassemblerTables.inc"
298 
299 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
300                                        uint64_t Address, const void *Decoder) {
301   uint64_t SImm6 =
302       fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
303   DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
304   (void)Result;
305   assert(Result == MCDisassembler::Success && "Invalid immediate");
306   return MCDisassembler::Success;
307 }
308 
309 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
310                                          uint64_t Address,
311                                          const void *Decoder) {
312   DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
313   uint64_t SImm6 =
314       fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
315   DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
316   (void)Result;
317   assert(Result == MCDisassembler::Success && "Invalid immediate");
318   return MCDisassembler::Success;
319 }
320 
321 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
322                                             uint64_t Address,
323                                             const void *Decoder) {
324   DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
325   Inst.addOperand(Inst.getOperand(0));
326   uint64_t UImm6 =
327       fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
328   DecodeStatus Result = decodeUImmOperand<6>(Inst, UImm6, Address, Decoder);
329   (void)Result;
330   assert(Result == MCDisassembler::Success && "Invalid immediate");
331   return MCDisassembler::Success;
332 }
333 
334 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
335                                         uint64_t Address, const void *Decoder) {
336   unsigned Rd = fieldFromInstruction(Insn, 7, 5);
337   unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
338   DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
339   DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
340   return MCDisassembler::Success;
341 }
342 
343 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
344                                            uint64_t Address,
345                                            const void *Decoder) {
346   unsigned Rd = fieldFromInstruction(Insn, 7, 5);
347   unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
348   DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
349   Inst.addOperand(Inst.getOperand(0));
350   DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
351   return MCDisassembler::Success;
352 }
353 
354 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
355                                                ArrayRef<uint8_t> Bytes,
356                                                uint64_t Address,
357                                                raw_ostream &CS) const {
358   // TODO: This will need modification when supporting instruction set
359   // extensions with instructions > 32-bits (up to 176 bits wide).
360   uint32_t Insn;
361   DecodeStatus Result;
362 
363   // It's a 32 bit instruction if bit 0 and 1 are 1.
364   if ((Bytes[0] & 0x3) == 0x3) {
365     if (Bytes.size() < 4) {
366       Size = 0;
367       return MCDisassembler::Fail;
368     }
369     Insn = support::endian::read32le(Bytes.data());
370     LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
371     Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
372     Size = 4;
373   } else {
374     if (Bytes.size() < 2) {
375       Size = 0;
376       return MCDisassembler::Fail;
377     }
378     Insn = support::endian::read16le(Bytes.data());
379 
380     if (!STI.getFeatureBits()[RISCV::Feature64Bit]) {
381       LLVM_DEBUG(
382           dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n");
383       // Calling the auto-generated decoder function.
384       Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address,
385                                  this, STI);
386       if (Result != MCDisassembler::Fail) {
387         Size = 2;
388         return Result;
389       }
390     }
391 
392     if (STI.getFeatureBits()[RISCV::FeatureExtZbproposedc] &&
393         STI.getFeatureBits()[RISCV::FeatureStdExtC]) {
394       LLVM_DEBUG(
395           dbgs() << "Trying RVBC32 table (BitManip 16-bit Instruction):\n");
396       // Calling the auto-generated decoder function.
397       Result = decodeInstruction(DecoderTableRVBC16, MI, Insn, Address,
398                                  this, STI);
399       if (Result != MCDisassembler::Fail) {
400         Size = 2;
401         return Result;
402       }
403     }
404 
405     LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n");
406     // Calling the auto-generated decoder function.
407     Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
408     Size = 2;
409   }
410 
411   return Result;
412 }
413