blob: cdc95daa8061a95cb855daa365727c977fe09baf [file] [log] [blame]
Alex Bradbury8ab4a962017-09-17 14:36:28 +00001//===-- RISCVDisassembler.cpp - Disassembler for RISCV --------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Alex Bradbury8ab4a962017-09-17 14:36:28 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the RISCVDisassembler class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "MCTargetDesc/RISCVMCTargetDesc.h"
Richard Trieu51fc56d2019-05-15 00:24:15 +000014#include "TargetInfo/RISCVTargetInfo.h"
Ana Pazos9d6c5532018-10-04 21:50:54 +000015#include "Utils/RISCVBaseInfo.h"
Luis Marquesfa06e952019-08-16 14:27:50 +000016#include "llvm/CodeGen/Register.h"
Alex Bradbury8ab4a962017-09-17 14:36:28 +000017#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
26using namespace llvm;
27
28#define DEBUG_TYPE "riscv-disassembler"
29
30typedef MCDisassembler::DecodeStatus DecodeStatus;
31
32namespace {
33class RISCVDisassembler : public MCDisassembler {
34
35public:
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
46static MCDisassembler *createRISCVDisassembler(const Target &T,
47 const MCSubtargetInfo &STI,
48 MCContext &Ctx) {
49 return new RISCVDisassembler(STI, Ctx);
50}
51
Tom Stellard4b0b2612019-06-11 03:21:13 +000052extern "C" void LLVMInitializeRISCVDisassembler() {
Alex Bradbury8ab4a962017-09-17 14:36:28 +000053 // Register the disassembler for each target.
54 TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(),
55 createRISCVDisassembler);
56 TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(),
57 createRISCVDisassembler);
58}
59
Luis Marquesfa06e952019-08-16 14:27:50 +000060static const Register GPRDecoderTable[] = {
Alex Bradburyee7c7ec2017-10-19 14:29:03 +000061 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
Alex Bradbury8ab4a962017-09-17 14:36:28 +000069};
70
71static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
72 uint64_t Address,
73 const void *Decoder) {
Alex Bradburydab1f6f2019-03-22 11:21:40 +000074 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))
Alex Bradbury60714f92017-12-13 09:32:55 +000081 return MCDisassembler::Fail;
Alex Bradbury8ab4a962017-09-17 14:36:28 +000082
Alex Bradbury60714f92017-12-13 09:32:55 +000083 // 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.
Luis Marquesfa06e952019-08-16 14:27:50 +000086 Register Reg = GPRDecoderTable[RegNo];
Alex Bradbury60714f92017-12-13 09:32:55 +000087 Inst.addOperand(MCOperand::createReg(Reg));
88 return MCDisassembler::Success;
Alex Bradbury8ab4a962017-09-17 14:36:28 +000089}
90
Luis Marquesfa06e952019-08-16 14:27:50 +000091static const Register FPR32DecoderTable[] = {
Alex Bradbury0d6cf902017-12-07 10:26:05 +000092 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
102static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
103 uint64_t Address,
104 const void *Decoder) {
Alex Bradbury18f95e62019-03-13 09:22:57 +0000105 if (RegNo > array_lengthof(FPR32DecoderTable))
Alex Bradbury0d6cf902017-12-07 10:26:05 +0000106 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.
Luis Marquesfa06e952019-08-16 14:27:50 +0000111 Register Reg = FPR32DecoderTable[RegNo];
Alex Bradbury0d6cf902017-12-07 10:26:05 +0000112 Inst.addOperand(MCOperand::createReg(Reg));
113 return MCDisassembler::Success;
114}
115
Alex Bradbury60714f92017-12-13 09:32:55 +0000116static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo,
117 uint64_t Address,
118 const void *Decoder) {
119 if (RegNo > 8) {
120 return MCDisassembler::Fail;
121 }
Luis Marquesfa06e952019-08-16 14:27:50 +0000122 Register Reg = FPR32DecoderTable[RegNo + 8];
Alex Bradbury60714f92017-12-13 09:32:55 +0000123 Inst.addOperand(MCOperand::createReg(Reg));
124 return MCDisassembler::Success;
125}
126
Luis Marquesfa06e952019-08-16 14:27:50 +0000127static const Register FPR64DecoderTable[] = {
Alex Bradbury7bc2a952017-12-07 10:46:23 +0000128 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
138static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
139 uint64_t Address,
140 const void *Decoder) {
Alex Bradbury18f95e62019-03-13 09:22:57 +0000141 if (RegNo > array_lengthof(FPR64DecoderTable))
Alex Bradbury7bc2a952017-12-07 10:46:23 +0000142 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.
Luis Marquesfa06e952019-08-16 14:27:50 +0000147 Register Reg = FPR64DecoderTable[RegNo];
Alex Bradbury7bc2a952017-12-07 10:46:23 +0000148 Inst.addOperand(MCOperand::createReg(Reg));
149 return MCDisassembler::Success;
150}
151
Alex Bradbury60714f92017-12-13 09:32:55 +0000152static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo,
153 uint64_t Address,
154 const void *Decoder) {
155 if (RegNo > 8) {
156 return MCDisassembler::Fail;
157 }
Luis Marquesfa06e952019-08-16 14:27:50 +0000158 Register Reg = FPR64DecoderTable[RegNo + 8];
Alex Bradbury60714f92017-12-13 09:32:55 +0000159 Inst.addOperand(MCOperand::createReg(Reg));
160 return MCDisassembler::Success;
161}
162
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000163static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo,
164 uint64_t Address,
165 const void *Decoder) {
Alex Bradbury60714f92017-12-13 09:32:55 +0000166 if (RegNo == 0) {
167 return MCDisassembler::Fail;
168 }
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000169
Alex Bradbury60714f92017-12-13 09:32:55 +0000170 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
171}
172
173static 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);
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000181}
182
183static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
184 uint64_t Address,
185 const void *Decoder) {
186 if (RegNo > 8)
187 return MCDisassembler::Fail;
188
Luis Marquesfa06e952019-08-16 14:27:50 +0000189 Register Reg = GPRDecoderTable[RegNo + 8];
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000190 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.
196static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) {
Alex Bradbury19c93142017-12-13 09:57:25 +0000197 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) {
Alex Bradbury60714f92017-12-13 09:32:55 +0000204 DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
205 }
Alex Bradbury19c93142017-12-13 09:57:25 +0000206 if (Inst.getOpcode() == RISCV::C_ADDI16SP) {
Alex Bradbury60714f92017-12-13 09:32:55 +0000207 DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000208 DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
209 }
210}
211
Alex Bradbury8ab4a962017-09-17 14:36:28 +0000212template <unsigned N>
213static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
214 int64_t Address, const void *Decoder) {
215 assert(isUInt<N>(Imm) && "Invalid immediate");
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000216 addImplySP(Inst, Address, Decoder);
Alex Bradbury8ab4a962017-09-17 14:36:28 +0000217 Inst.addOperand(MCOperand::createImm(Imm));
218 return MCDisassembler::Success;
219}
220
221template <unsigned N>
Ana Pazosb0799dd2018-09-13 18:21:19 +0000222static 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
230template <unsigned N>
Alex Bradbury8ab4a962017-09-17 14:36:28 +0000231static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
232 int64_t Address, const void *Decoder) {
233 assert(isUInt<N>(Imm) && "Invalid immediate");
Alex Bradbury60714f92017-12-13 09:32:55 +0000234 addImplySP(Inst, Address, Decoder);
Alex Bradbury8ab4a962017-09-17 14:36:28 +0000235 // 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
240template <unsigned N>
Ana Pazosb0799dd2018-09-13 18:21:19 +0000241static 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
249template <unsigned N>
Alex Bradbury8ab4a962017-09-17 14:36:28 +0000250static 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
Shiva Chen7c172422018-02-22 15:02:28 +0000261static 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
Ana Pazosb2ed11a2018-09-07 18:43:43 +0000272static 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
Luis Marquesc3bf3d12019-08-21 14:00:58 +0000283static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
284 uint64_t Address, const void *Decoder);
285
286static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
287 uint64_t Address, const void *Decoder);
288
289static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
290 uint64_t Address,
291 const void *Decoder);
292
293static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
294 uint64_t Address, const void *Decoder);
295
296static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
297 uint64_t Address,
298 const void *Decoder);
299
Alex Bradbury8ab4a962017-09-17 14:36:28 +0000300#include "RISCVGenDisassemblerTables.inc"
301
Luis Marquesc3bf3d12019-08-21 14:00:58 +0000302static 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 assert(decodeSImmOperand<6>(Inst, SImm6, Address, Decoder) ==
307 MCDisassembler::Success && "Invalid immediate");
Richard Smithb73cd332019-08-21 20:42:37 +0000308 (void)SImm6;
Luis Marquesc3bf3d12019-08-21 14:00:58 +0000309 return MCDisassembler::Success;
310}
311
312static 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 assert(decodeSImmOperand<6>(Inst, SImm6, Address, Decoder) ==
319 MCDisassembler::Success && "Invalid immediate");
Richard Smithb73cd332019-08-21 20:42:37 +0000320 (void)SImm6;
Luis Marquesc3bf3d12019-08-21 14:00:58 +0000321 return MCDisassembler::Success;
322}
323
324static 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 assert(decodeUImmOperand<6>(Inst, UImm6, Address, Decoder) ==
332 MCDisassembler::Success && "Invalid immediate");
Richard Smithb73cd332019-08-21 20:42:37 +0000333 (void)UImm6;
Luis Marquesc3bf3d12019-08-21 14:00:58 +0000334 return MCDisassembler::Success;
335}
336
337static 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
346static 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
Alex Bradbury8ab4a962017-09-17 14:36:28 +0000357DecodeStatus 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 {
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000362 // 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) {
Ana Pazosb97d1892018-09-07 18:23:19 +0000369 if (Bytes.size() < 4) {
370 Size = 0;
371 return MCDisassembler::Fail;
372 }
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000373 Insn = support::endian::read32le(Bytes.data());
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000374 LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000375 Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
376 Size = 4;
377 } else {
Ana Pazosb97d1892018-09-07 18:23:19 +0000378 if (Bytes.size() < 2) {
379 Size = 0;
380 return MCDisassembler::Fail;
381 }
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000382 Insn = support::endian::read16le(Bytes.data());
Alex Bradbury60714f92017-12-13 09:32:55 +0000383
384 if (!STI.getFeatureBits()[RISCV::Feature64Bit]) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000385 LLVM_DEBUG(
386 dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n");
Alex Bradbury60714f92017-12-13 09:32:55 +0000387 // 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
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000396 LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n");
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000397 // Calling the auto-generated decoder function.
398 Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
399 Size = 2;
Alex Bradbury8ab4a962017-09-17 14:36:28 +0000400 }
401
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000402 return Result;
Alex Bradbury8ab4a962017-09-17 14:36:28 +0000403}