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