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/CodeGen/Register.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
19 #include "llvm/MC/MCFixedLenDisassembler.h"
20 #include "llvm/MC/MCInst.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 
35 public:
36   RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
37       : MCDisassembler(STI, Ctx) {}
38 
39   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
40                               ArrayRef<uint8_t> Bytes, uint64_t Address,
41                               raw_ostream &VStream,
42                               raw_ostream &CStream) const override;
43 };
44 } // end anonymous namespace
45 
46 static MCDisassembler *createRISCVDisassembler(const Target &T,
47                                                const MCSubtargetInfo &STI,
48                                                MCContext &Ctx) {
49   return new RISCVDisassembler(STI, Ctx);
50 }
51 
52 extern "C" void LLVMInitializeRISCVDisassembler() {
53   // Register the disassembler for each target.
54   TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(),
55                                          createRISCVDisassembler);
56   TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(),
57                                          createRISCVDisassembler);
58 }
59 
60 static const Register GPRDecoderTable[] = {
61   RISCV::X0,  RISCV::X1,  RISCV::X2,  RISCV::X3,
62   RISCV::X4,  RISCV::X5,  RISCV::X6,  RISCV::X7,
63   RISCV::X8,  RISCV::X9,  RISCV::X10, RISCV::X11,
64   RISCV::X12, RISCV::X13, RISCV::X14, RISCV::X15,
65   RISCV::X16, RISCV::X17, RISCV::X18, RISCV::X19,
66   RISCV::X20, RISCV::X21, RISCV::X22, RISCV::X23,
67   RISCV::X24, RISCV::X25, RISCV::X26, RISCV::X27,
68   RISCV::X28, RISCV::X29, RISCV::X30, RISCV::X31
69 };
70 
71 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
72                                            uint64_t Address,
73                                            const void *Decoder) {
74   const FeatureBitset &FeatureBits =
75       static_cast<const MCDisassembler *>(Decoder)
76           ->getSubtargetInfo()
77           .getFeatureBits();
78   bool IsRV32E = FeatureBits[RISCV::FeatureRV32E];
79 
80   if (RegNo > array_lengthof(GPRDecoderTable) || (IsRV32E && RegNo > 15))
81     return MCDisassembler::Fail;
82 
83   // We must define our own mapping from RegNo to register identifier.
84   // Accessing index RegNo in the register class will work in the case that
85   // registers were added in ascending order, but not in general.
86   Register Reg = GPRDecoderTable[RegNo];
87   Inst.addOperand(MCOperand::createReg(Reg));
88   return MCDisassembler::Success;
89 }
90 
91 static const Register FPR32DecoderTable[] = {
92   RISCV::F0_32,  RISCV::F1_32,  RISCV::F2_32,  RISCV::F3_32,
93   RISCV::F4_32,  RISCV::F5_32,  RISCV::F6_32,  RISCV::F7_32,
94   RISCV::F8_32,  RISCV::F9_32,  RISCV::F10_32, RISCV::F11_32,
95   RISCV::F12_32, RISCV::F13_32, RISCV::F14_32, RISCV::F15_32,
96   RISCV::F16_32, RISCV::F17_32, RISCV::F18_32, RISCV::F19_32,
97   RISCV::F20_32, RISCV::F21_32, RISCV::F22_32, RISCV::F23_32,
98   RISCV::F24_32, RISCV::F25_32, RISCV::F26_32, RISCV::F27_32,
99   RISCV::F28_32, RISCV::F29_32, RISCV::F30_32, RISCV::F31_32
100 };
101 
102 static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
103                                              uint64_t Address,
104                                              const void *Decoder) {
105   if (RegNo > array_lengthof(FPR32DecoderTable))
106     return MCDisassembler::Fail;
107 
108   // We must define our own mapping from RegNo to register identifier.
109   // Accessing index RegNo in the register class will work in the case that
110   // registers were added in ascending order, but not in general.
111   Register Reg = FPR32DecoderTable[RegNo];
112   Inst.addOperand(MCOperand::createReg(Reg));
113   return MCDisassembler::Success;
114 }
115 
116 static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo,
117                                               uint64_t Address,
118                                               const void *Decoder) {
119   if (RegNo > 8) {
120     return MCDisassembler::Fail;
121   }
122   Register Reg = FPR32DecoderTable[RegNo + 8];
123   Inst.addOperand(MCOperand::createReg(Reg));
124   return MCDisassembler::Success;
125 }
126 
127 static const Register FPR64DecoderTable[] = {
128   RISCV::F0_64,  RISCV::F1_64,  RISCV::F2_64,  RISCV::F3_64,
129   RISCV::F4_64,  RISCV::F5_64,  RISCV::F6_64,  RISCV::F7_64,
130   RISCV::F8_64,  RISCV::F9_64,  RISCV::F10_64, RISCV::F11_64,
131   RISCV::F12_64, RISCV::F13_64, RISCV::F14_64, RISCV::F15_64,
132   RISCV::F16_64, RISCV::F17_64, RISCV::F18_64, RISCV::F19_64,
133   RISCV::F20_64, RISCV::F21_64, RISCV::F22_64, RISCV::F23_64,
134   RISCV::F24_64, RISCV::F25_64, RISCV::F26_64, RISCV::F27_64,
135   RISCV::F28_64, RISCV::F29_64, RISCV::F30_64, RISCV::F31_64
136 };
137 
138 static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
139                                              uint64_t Address,
140                                              const void *Decoder) {
141   if (RegNo > array_lengthof(FPR64DecoderTable))
142     return MCDisassembler::Fail;
143 
144   // We must define our own mapping from RegNo to register identifier.
145   // Accessing index RegNo in the register class will work in the case that
146   // registers were added in ascending order, but not in general.
147   Register Reg = FPR64DecoderTable[RegNo];
148   Inst.addOperand(MCOperand::createReg(Reg));
149   return MCDisassembler::Success;
150 }
151 
152 static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo,
153                                               uint64_t Address,
154                                               const void *Decoder) {
155   if (RegNo > 8) {
156     return MCDisassembler::Fail;
157   }
158   Register Reg = FPR64DecoderTable[RegNo + 8];
159   Inst.addOperand(MCOperand::createReg(Reg));
160   return MCDisassembler::Success;
161 }
162 
163 static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo,
164                                                uint64_t Address,
165                                                const void *Decoder) {
166   if (RegNo == 0) {
167     return MCDisassembler::Fail;
168   }
169 
170   return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
171 }
172 
173 static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo,
174                                                  uint64_t Address,
175                                                  const void *Decoder) {
176   if (RegNo == 2) {
177     return MCDisassembler::Fail;
178   }
179 
180   return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
181 }
182 
183 static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
184                                             uint64_t Address,
185                                             const void *Decoder) {
186   if (RegNo > 8)
187     return MCDisassembler::Fail;
188 
189   Register Reg = GPRDecoderTable[RegNo + 8];
190   Inst.addOperand(MCOperand::createReg(Reg));
191   return MCDisassembler::Success;
192 }
193 
194 // Add implied SP operand for instructions *SP compressed instructions. The SP
195 // operand isn't explicitly encoded in the instruction.
196 static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) {
197   if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP ||
198       Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP ||
199       Inst.getOpcode() == RISCV::C_FLWSP ||
200       Inst.getOpcode() == RISCV::C_FSWSP ||
201       Inst.getOpcode() == RISCV::C_FLDSP ||
202       Inst.getOpcode() == RISCV::C_FSDSP ||
203       Inst.getOpcode() == RISCV::C_ADDI4SPN) {
204     DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
205   }
206   if (Inst.getOpcode() == RISCV::C_ADDI16SP) {
207     DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
208     DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
209   }
210 }
211 
212 template <unsigned N>
213 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
214                                       int64_t Address, const void *Decoder) {
215   assert(isUInt<N>(Imm) && "Invalid immediate");
216   addImplySP(Inst, Address, Decoder);
217   Inst.addOperand(MCOperand::createImm(Imm));
218   return MCDisassembler::Success;
219 }
220 
221 template <unsigned N>
222 static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
223                                              int64_t Address,
224                                              const void *Decoder) {
225   if (Imm == 0)
226     return MCDisassembler::Fail;
227   return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
228 }
229 
230 template <unsigned N>
231 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
232                                       int64_t Address, const void *Decoder) {
233   assert(isUInt<N>(Imm) && "Invalid immediate");
234   addImplySP(Inst, Address, Decoder);
235   // Sign-extend the number in the bottom N bits of Imm
236   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
237   return MCDisassembler::Success;
238 }
239 
240 template <unsigned N>
241 static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
242                                              int64_t Address,
243                                              const void *Decoder) {
244   if (Imm == 0)
245     return MCDisassembler::Fail;
246   return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
247 }
248 
249 template <unsigned N>
250 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm,
251                                              int64_t Address,
252                                              const void *Decoder) {
253   assert(isUInt<N>(Imm) && "Invalid immediate");
254   // Sign-extend the number in the bottom N bits of Imm after accounting for
255   // the fact that the N bit immediate is stored in N-1 bits (the LSB is
256   // always zero)
257   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
258   return MCDisassembler::Success;
259 }
260 
261 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm,
262                                          int64_t Address,
263                                          const void *Decoder) {
264   assert(isUInt<6>(Imm) && "Invalid immediate");
265   if (Imm > 31) {
266     Imm = (SignExtend64<6>(Imm) & 0xfffff);
267   }
268   Inst.addOperand(MCOperand::createImm(Imm));
269   return MCDisassembler::Success;
270 }
271 
272 static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm,
273                                  int64_t Address,
274                                  const void *Decoder) {
275   assert(isUInt<3>(Imm) && "Invalid immediate");
276   if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm))
277     return MCDisassembler::Fail;
278 
279   Inst.addOperand(MCOperand::createImm(Imm));
280   return MCDisassembler::Success;
281 }
282 
283 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
284                                        uint64_t Address, const void *Decoder);
285 
286 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
287                                          uint64_t Address, const void *Decoder);
288 
289 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
290                                             uint64_t Address,
291                                             const void *Decoder);
292 
293 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
294                                         uint64_t Address, const void *Decoder);
295 
296 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
297                                            uint64_t Address,
298                                            const void *Decoder);
299 
300 #include "RISCVGenDisassemblerTables.inc"
301 
302 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
303                                        uint64_t Address, const void *Decoder) {
304   uint64_t SImm6 =
305       fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
306   DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
307   (void)Result;
308   assert(Result == MCDisassembler::Success && "Invalid immediate");
309   return MCDisassembler::Success;
310 }
311 
312 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
313                                          uint64_t Address,
314                                          const void *Decoder) {
315   DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
316   uint64_t SImm6 =
317       fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
318   DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
319   (void)Result;
320   assert(Result == MCDisassembler::Success && "Invalid immediate");
321   return MCDisassembler::Success;
322 }
323 
324 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
325                                             uint64_t Address,
326                                             const void *Decoder) {
327   DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
328   Inst.addOperand(Inst.getOperand(0));
329   uint64_t UImm6 =
330       fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
331   DecodeStatus Result = decodeUImmOperand<6>(Inst, UImm6, Address, Decoder);
332   (void)Result;
333   assert(Result == MCDisassembler::Success && "Invalid immediate");
334   return MCDisassembler::Success;
335 }
336 
337 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
338                                         uint64_t Address, const void *Decoder) {
339   unsigned Rd = fieldFromInstruction(Insn, 7, 5);
340   unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
341   DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
342   DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
343   return MCDisassembler::Success;
344 }
345 
346 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
347                                            uint64_t Address,
348                                            const void *Decoder) {
349   unsigned Rd = fieldFromInstruction(Insn, 7, 5);
350   unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
351   DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
352   Inst.addOperand(Inst.getOperand(0));
353   DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
354   return MCDisassembler::Success;
355 }
356 
357 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
358                                                ArrayRef<uint8_t> Bytes,
359                                                uint64_t Address,
360                                                raw_ostream &OS,
361                                                raw_ostream &CS) const {
362   // TODO: This will need modification when supporting instruction set
363   // extensions with instructions > 32-bits (up to 176 bits wide).
364   uint32_t Insn;
365   DecodeStatus Result;
366 
367   // It's a 32 bit instruction if bit 0 and 1 are 1.
368   if ((Bytes[0] & 0x3) == 0x3) {
369     if (Bytes.size() < 4) {
370       Size = 0;
371       return MCDisassembler::Fail;
372     }
373     Insn = support::endian::read32le(Bytes.data());
374     LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
375     Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
376     Size = 4;
377   } else {
378     if (Bytes.size() < 2) {
379       Size = 0;
380       return MCDisassembler::Fail;
381     }
382     Insn = support::endian::read16le(Bytes.data());
383 
384     if (!STI.getFeatureBits()[RISCV::Feature64Bit]) {
385       LLVM_DEBUG(
386           dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n");
387       // Calling the auto-generated decoder function.
388       Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address,
389                                  this, STI);
390       if (Result != MCDisassembler::Fail) {
391         Size = 2;
392         return Result;
393       }
394     }
395 
396     LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n");
397     // Calling the auto-generated decoder function.
398     Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
399     Size = 2;
400   }
401 
402   return Result;
403 }
404