xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (revision 6b96bb739548a8b8c2b13bd46234f70a29be12fb)
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