LLVM 17.0.0git
RISCVDisassembler.cpp
Go to the documentation of this file.
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
16#include "llvm/MC/MCContext.h"
19#include "llvm/MC/MCInst.h"
20#include "llvm/MC/MCInstrInfo.h"
24#include "llvm/Support/Endian.h"
25
26using namespace llvm;
27
28#define DEBUG_TYPE "riscv-disassembler"
29
31
32namespace {
33class RISCVDisassembler : public MCDisassembler {
34 std::unique_ptr<MCInstrInfo const> const MCII;
35
36public:
37 RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
38 MCInstrInfo const *MCII)
39 : MCDisassembler(STI, Ctx), MCII(MCII) {}
40
42 ArrayRef<uint8_t> Bytes, uint64_t Address,
43 raw_ostream &CStream) const override;
44};
45} // end anonymous namespace
46
48 const MCSubtargetInfo &STI,
49 MCContext &Ctx) {
50 return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo());
51}
52
54 // Register the disassembler for each target.
59}
60
62 uint64_t Address,
63 const MCDisassembler *Decoder) {
64 const FeatureBitset &FeatureBits =
66 bool IsRV32E = FeatureBits[RISCV::FeatureRV32E];
67
68 if (RegNo >= 32 || (IsRV32E && RegNo >= 16))
70
71 MCRegister Reg = RISCV::X0 + RegNo;
74}
75
77 uint64_t Address,
78 const MCDisassembler *Decoder) {
79 if (RegNo >= 32)
81
82 MCRegister Reg = RISCV::F0_H + RegNo;
85}
86
88 uint64_t Address,
89 const MCDisassembler *Decoder) {
90 if (RegNo >= 32)
92
93 MCRegister Reg = RISCV::F0_F + RegNo;
96}
97
99 uint64_t Address,
100 const MCDisassembler *Decoder) {
101 if (RegNo >= 8) {
103 }
104 MCRegister Reg = RISCV::F8_F + RegNo;
107}
108
110 uint64_t Address,
111 const MCDisassembler *Decoder) {
112 if (RegNo >= 32)
114
115 MCRegister Reg = RISCV::F0_D + RegNo;
118}
119
121 uint64_t Address,
122 const MCDisassembler *Decoder) {
123 if (RegNo >= 8) {
125 }
126 MCRegister Reg = RISCV::F8_D + RegNo;
129}
130
132 uint64_t Address,
133 const MCDisassembler *Decoder) {
134 if (RegNo == 0) {
136 }
137
138 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
139}
140
141static DecodeStatus
143 const MCDisassembler *Decoder) {
144 if (RegNo == 2) {
146 }
147
148 return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
149}
150
152 uint64_t Address,
153 const MCDisassembler *Decoder) {
154 if (RegNo >= 8)
156
157 MCRegister Reg = RISCV::X8 + RegNo;
160}
161
163 uint64_t Address,
164 const MCDisassembler *Decoder) {
165 if (RegNo >= 32 || RegNo & 1)
167
168 MCRegister Reg = RISCV::X0 + RegNo;
171}
172
174 uint64_t Address,
175 const MCDisassembler *Decoder) {
176 if (RegNo >= 32)
178
179 MCRegister Reg = RISCV::V0 + RegNo;
182}
183
185 uint64_t Address,
186 const MCDisassembler *Decoder) {
187 if (RegNo >= 32)
189
190 if (RegNo % 2)
192
193 const RISCVDisassembler *Dis =
194 static_cast<const RISCVDisassembler *>(Decoder);
195 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
196 MCRegister Reg =
197 RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
198 &RISCVMCRegisterClasses[RISCV::VRM2RegClassID]);
199
202}
203
205 uint64_t Address,
206 const MCDisassembler *Decoder) {
207 if (RegNo >= 32)
209
210 if (RegNo % 4)
212
213 const RISCVDisassembler *Dis =
214 static_cast<const RISCVDisassembler *>(Decoder);
215 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
216 MCRegister Reg =
217 RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
218 &RISCVMCRegisterClasses[RISCV::VRM4RegClassID]);
219
222}
223
225 uint64_t Address,
226 const MCDisassembler *Decoder) {
227 if (RegNo >= 32)
229
230 if (RegNo % 8)
232
233 const RISCVDisassembler *Dis =
234 static_cast<const RISCVDisassembler *>(Decoder);
235 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
236 MCRegister Reg =
237 RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
238 &RISCVMCRegisterClasses[RISCV::VRM8RegClassID]);
239
242}
243
245 uint64_t Address,
246 const MCDisassembler *Decoder) {
247 MCRegister Reg = RISCV::NoRegister;
248 switch (RegNo) {
249 default:
251 case 0:
252 Reg = RISCV::V0;
253 break;
254 case 1:
255 break;
256 }
259}
260
261// Add implied SP operand for instructions *SP compressed instructions. The SP
262// operand isn't explicitly encoded in the instruction.
263static void addImplySP(MCInst &Inst, int64_t Address,
264 const MCDisassembler *Decoder) {
265 if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP ||
266 Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP ||
267 Inst.getOpcode() == RISCV::C_FLWSP ||
268 Inst.getOpcode() == RISCV::C_FSWSP ||
269 Inst.getOpcode() == RISCV::C_FLDSP ||
270 Inst.getOpcode() == RISCV::C_FSDSP ||
271 Inst.getOpcode() == RISCV::C_ADDI4SPN) {
272 DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
273 }
274 if (Inst.getOpcode() == RISCV::C_ADDI16SP) {
275 DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
276 DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
277 }
278}
279
280template <unsigned N>
282 int64_t Address,
283 const MCDisassembler *Decoder) {
284 assert(isUInt<N>(Imm) && "Invalid immediate");
285 addImplySP(Inst, Address, Decoder);
288}
289
290template <unsigned N>
292 int64_t Address,
293 const MCDisassembler *Decoder) {
294 if (Imm == 0)
296 return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
297}
298
299template <unsigned N>
301 int64_t Address,
302 const MCDisassembler *Decoder) {
303 assert(isUInt<N>(Imm) && "Invalid immediate");
304 addImplySP(Inst, Address, Decoder);
305 // Sign-extend the number in the bottom N bits of Imm
306 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
308}
309
310template <unsigned N>
312 int64_t Address,
313 const MCDisassembler *Decoder) {
314 if (Imm == 0)
316 return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
317}
318
319template <unsigned N>
321 int64_t Address,
322 const MCDisassembler *Decoder) {
323 assert(isUInt<N>(Imm) && "Invalid immediate");
324 // Sign-extend the number in the bottom N bits of Imm after accounting for
325 // the fact that the N bit immediate is stored in N-1 bits (the LSB is
326 // always zero)
327 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
329}
330
332 int64_t Address,
333 const MCDisassembler *Decoder) {
334 assert(isUInt<6>(Imm) && "Invalid immediate");
335 if (Imm > 31) {
336 Imm = (SignExtend64<6>(Imm) & 0xfffff);
337 }
340}
341
342static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm, int64_t Address,
343 const MCDisassembler *Decoder) {
344 assert(isUInt<3>(Imm) && "Invalid immediate");
347
350}
351
352static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
353 uint64_t Address,
354 const MCDisassembler *Decoder);
355
356static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
357 uint64_t Address,
358 const MCDisassembler *Decoder);
359
360static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
361 uint64_t Address,
362 const MCDisassembler *Decoder);
363
364static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
365 uint64_t Address,
366 const MCDisassembler *Decoder);
367
368static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
369 uint64_t Address,
370 const MCDisassembler *Decoder);
371
372#include "RISCVGenDisassemblerTables.inc"
373
375 uint64_t Address,
376 const MCDisassembler *Decoder) {
377 uint64_t SImm6 =
378 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
379 DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
380 (void)Result;
381 assert(Result == MCDisassembler::Success && "Invalid immediate");
383}
384
386 uint64_t Address,
387 const MCDisassembler *Decoder) {
388 DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
389 uint64_t SImm6 =
390 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
391 DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
392 (void)Result;
393 assert(Result == MCDisassembler::Success && "Invalid immediate");
395}
396
398 uint64_t Address,
399 const MCDisassembler *Decoder) {
400 DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
401 Inst.addOperand(Inst.getOperand(0));
402 uint64_t UImm6 =
403 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
404 DecodeStatus Result = decodeUImmOperand<6>(Inst, UImm6, Address, Decoder);
405 (void)Result;
406 assert(Result == MCDisassembler::Success && "Invalid immediate");
408}
409
411 uint64_t Address,
412 const MCDisassembler *Decoder) {
413 unsigned Rd = fieldFromInstruction(Insn, 7, 5);
414 unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
415 DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
416 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
418}
419
421 uint64_t Address,
422 const MCDisassembler *Decoder) {
423 unsigned Rd = fieldFromInstruction(Insn, 7, 5);
424 unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
425 DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
426 Inst.addOperand(Inst.getOperand(0));
427 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
429}
430
431DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
432 ArrayRef<uint8_t> Bytes,
433 uint64_t Address,
434 raw_ostream &CS) const {
435 // TODO: This will need modification when supporting instruction set
436 // extensions with instructions > 32-bits (up to 176 bits wide).
439
440 // It's a 32 bit instruction if bit 0 and 1 are 1.
441 if ((Bytes[0] & 0x3) == 0x3) {
442 if (Bytes.size() < 4) {
443 Size = 0;
445 }
447 if (STI.getFeatureBits()[RISCV::FeatureStdExtZdinx] &&
448 !STI.getFeatureBits()[RISCV::Feature64Bit]) {
449 LLVM_DEBUG(dbgs() << "Trying RV32Zdinx table (Double in Integer and"
450 "rv32)\n");
451 Result = decodeInstruction(DecoderTableRV32Zdinx32, MI, Insn, Address,
452 this, STI);
453 if (Result != MCDisassembler::Fail) {
454 Size = 4;
455 return Result;
456 }
457 }
458
459 if (STI.getFeatureBits()[RISCV::FeatureStdExtZfinx]) {
460 LLVM_DEBUG(dbgs() << "Trying RVZfinx table (Float in Integer):\n");
461 Result = decodeInstruction(DecoderTableRVZfinx32, MI, Insn, Address, this,
462 STI);
463 if (Result != MCDisassembler::Fail) {
464 Size = 4;
465 return Result;
466 }
467 }
468 if (STI.getFeatureBits()[RISCV::FeatureVendorXVentanaCondOps]) {
469 LLVM_DEBUG(dbgs() << "Trying Ventana custom opcode table:\n");
470 Result = decodeInstruction(DecoderTableVentana32, MI, Insn, Address, this,
471 STI);
472 if (Result != MCDisassembler::Fail) {
473 Size = 4;
474 return Result;
475 }
476 }
477 if (STI.getFeatureBits()[RISCV::FeatureVendorXTHeadVdot]) {
478 LLVM_DEBUG(dbgs() << "Trying T-Head custom opcode table:\n");
479 Result =
480 decodeInstruction(DecoderTableTHeadV32, MI, Insn, Address, this, STI);
481 if (Result != MCDisassembler::Fail) {
482 Size = 4;
483 return Result;
484 }
485 }
486
487 LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
488 Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
489 Size = 4;
490 } else {
491 if (Bytes.size() < 2) {
492 Size = 0;
494 }
496
497 if (!STI.getFeatureBits()[RISCV::Feature64Bit]) {
499 dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n");
500 // Calling the auto-generated decoder function.
501 Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address,
502 this, STI);
503 if (Result != MCDisassembler::Fail) {
504 Size = 2;
505 return Result;
506 }
507 }
508
509 LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n");
510 // Calling the auto-generated decoder function.
511 Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
512 Size = 2;
513 }
514
515 return Result;
516}
SmallVector< AArch64_IMM::ImmInsnModel, 4 > Insn
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:127
#define LLVM_DEBUG(X)
Definition: Debug.h:101
uint64_t Size
IRTranslator LLVM IR MI
static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeGPRPF64RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
MCDisassembler::DecodeStatus DecodeStatus
static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeVRM4RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static MCDisassembler * createRISCVDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeVMaskReg(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static void addImplySP(MCInst &Inst, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVDisassembler()
static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
const T * data() const
Definition: ArrayRef.h:160
Container class for subtarget features.
Context object for machine code objects.
Definition: MCContext.h:76
Superclass for all disassemblers.
const MCSubtargetInfo & getSubtargetInfo() const
DecodeStatus
Ternary decode status.
virtual DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef< uint8_t > Bytes, uint64_t Address, raw_ostream &CStream) const =0
Returns the disassembly of a single instruction.
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
unsigned getOpcode() const
Definition: MCInst.h:198
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:206
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:24
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
Target - Wrapper for Target specific information.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
static bool isValidRoundingMode(unsigned Mode)
uint16_t read16le(const void *P)
Definition: Endian.h:380
uint32_t read32le(const void *P)
Definition: Endian.h:381
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Target & getTheRISCV32Target()
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
Target & getTheRISCV64Target()
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.