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:
RISCVDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,MCInstrInfo const * MCII)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
createRISCVDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)47 static MCDisassembler *createRISCVDisassembler(const Target &T,
48 const MCSubtargetInfo &STI,
49 MCContext &Ctx) {
50 return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo());
51 }
52
LLVMInitializeRISCVDisassembler()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
DecodeGPRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeFPR16RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeFPR32RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeFPR32CRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeFPR64RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeFPR64CRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeGPRNoX0RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeGPRNoX0X2RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeGPRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeVRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeVRM2RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeVRM4RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeVRM8RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
decodeVMaskReg(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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.
addImplySP(MCInst & Inst,int64_t Address,const void * Decoder)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>
decodeUImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)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>
decodeUImmNonZeroOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)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>
decodeSImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)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>
decodeSImmNonZeroOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)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>
decodeSImmOperandAndLsl1(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)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
decodeCLUIImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)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
decodeFRMArg(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)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
decodeRVCInstrSImm(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)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
decodeRVCInstrRdSImm(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)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
decodeRVCInstrRdRs1UImm(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)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
decodeRVCInstrRdRs2(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)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
decodeRVCInstrRdRs1Rs2(MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)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
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const414 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