1 | //===-- RISCVDisassembler.cpp - Disassembler for RISC-V -------------------===// |
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/MCDecoderOps.h" |
18 | #include "llvm/MC/MCDisassembler/MCDisassembler.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/MC/TargetRegistry.h" |
24 | #include "llvm/Support/Compiler.h" |
25 | #include "llvm/Support/Endian.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 | private: |
47 | void addSPOperands(MCInst &MI) const; |
48 | |
49 | DecodeStatus getInstruction48(MCInst &Instr, uint64_t &Size, |
50 | ArrayRef<uint8_t> Bytes, uint64_t Address, |
51 | raw_ostream &CStream) const; |
52 | |
53 | DecodeStatus getInstruction32(MCInst &Instr, uint64_t &Size, |
54 | ArrayRef<uint8_t> Bytes, uint64_t Address, |
55 | raw_ostream &CStream) const; |
56 | DecodeStatus getInstruction16(MCInst &Instr, uint64_t &Size, |
57 | ArrayRef<uint8_t> Bytes, uint64_t Address, |
58 | raw_ostream &CStream) const; |
59 | }; |
60 | } // end anonymous namespace |
61 | |
62 | static MCDisassembler *createRISCVDisassembler(const Target &T, |
63 | const MCSubtargetInfo &STI, |
64 | MCContext &Ctx) { |
65 | return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo()); |
66 | } |
67 | |
68 | extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void |
69 | LLVMInitializeRISCVDisassembler() { |
70 | // Register the disassembler for each target. |
71 | TargetRegistry::RegisterMCDisassembler(T&: getTheRISCV32Target(), |
72 | Fn: createRISCVDisassembler); |
73 | TargetRegistry::RegisterMCDisassembler(T&: getTheRISCV64Target(), |
74 | Fn: createRISCVDisassembler); |
75 | } |
76 | |
77 | static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo, |
78 | uint64_t Address, |
79 | const MCDisassembler *Decoder) { |
80 | bool IsRVE = Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::FeatureStdExtE); |
81 | |
82 | if (RegNo >= 32 || (IsRVE && RegNo >= 16)) |
83 | return MCDisassembler::Fail; |
84 | |
85 | MCRegister Reg = RISCV::X0 + RegNo; |
86 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
87 | return MCDisassembler::Success; |
88 | } |
89 | |
90 | static DecodeStatus DecodeGPRF16RegisterClass(MCInst &Inst, uint32_t RegNo, |
91 | uint64_t Address, |
92 | const MCDisassembler *Decoder) { |
93 | bool IsRVE = Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::FeatureStdExtE); |
94 | |
95 | if (RegNo >= 32 || (IsRVE && RegNo >= 16)) |
96 | return MCDisassembler::Fail; |
97 | |
98 | MCRegister Reg = RISCV::X0_H + RegNo; |
99 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
100 | return MCDisassembler::Success; |
101 | } |
102 | |
103 | static DecodeStatus DecodeGPRF32RegisterClass(MCInst &Inst, uint32_t RegNo, |
104 | uint64_t Address, |
105 | const MCDisassembler *Decoder) { |
106 | bool IsRVE = Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::FeatureStdExtE); |
107 | |
108 | if (RegNo >= 32 || (IsRVE && RegNo >= 16)) |
109 | return MCDisassembler::Fail; |
110 | |
111 | MCRegister Reg = RISCV::X0_W + RegNo; |
112 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
113 | return MCDisassembler::Success; |
114 | } |
115 | |
116 | static DecodeStatus DecodeGPRX1X5RegisterClass(MCInst &Inst, uint32_t RegNo, |
117 | uint64_t Address, |
118 | const MCDisassembler *Decoder) { |
119 | MCRegister Reg = RISCV::X0 + RegNo; |
120 | if (Reg != RISCV::X1 && Reg != RISCV::X5) |
121 | return MCDisassembler::Fail; |
122 | |
123 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
124 | return MCDisassembler::Success; |
125 | } |
126 | |
127 | static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, uint32_t RegNo, |
128 | uint64_t Address, |
129 | const MCDisassembler *Decoder) { |
130 | if (RegNo >= 32) |
131 | return MCDisassembler::Fail; |
132 | |
133 | MCRegister Reg = RISCV::F0_H + RegNo; |
134 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
135 | return MCDisassembler::Success; |
136 | } |
137 | |
138 | static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint32_t RegNo, |
139 | uint64_t Address, |
140 | const MCDisassembler *Decoder) { |
141 | if (RegNo >= 32) |
142 | return MCDisassembler::Fail; |
143 | |
144 | MCRegister Reg = RISCV::F0_F + RegNo; |
145 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
146 | return MCDisassembler::Success; |
147 | } |
148 | |
149 | static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint32_t RegNo, |
150 | uint64_t Address, |
151 | const MCDisassembler *Decoder) { |
152 | if (RegNo >= 8) { |
153 | return MCDisassembler::Fail; |
154 | } |
155 | MCRegister Reg = RISCV::F8_F + RegNo; |
156 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
157 | return MCDisassembler::Success; |
158 | } |
159 | |
160 | static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint32_t RegNo, |
161 | uint64_t Address, |
162 | const MCDisassembler *Decoder) { |
163 | if (RegNo >= 32) |
164 | return MCDisassembler::Fail; |
165 | |
166 | MCRegister Reg = RISCV::F0_D + RegNo; |
167 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
168 | return MCDisassembler::Success; |
169 | } |
170 | |
171 | static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint32_t RegNo, |
172 | uint64_t Address, |
173 | const MCDisassembler *Decoder) { |
174 | if (RegNo >= 8) { |
175 | return MCDisassembler::Fail; |
176 | } |
177 | MCRegister Reg = RISCV::F8_D + RegNo; |
178 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
179 | return MCDisassembler::Success; |
180 | } |
181 | |
182 | static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, uint32_t RegNo, |
183 | uint64_t Address, |
184 | const MCDisassembler *Decoder) { |
185 | if (RegNo >= 32) |
186 | return MCDisassembler::Fail; |
187 | |
188 | MCRegister Reg = RISCV::F0_Q + RegNo; |
189 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
190 | return MCDisassembler::Success; |
191 | } |
192 | |
193 | static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint32_t RegNo, |
194 | uint64_t Address, |
195 | const MCDisassembler *Decoder) { |
196 | if (RegNo == 0) { |
197 | return MCDisassembler::Fail; |
198 | } |
199 | |
200 | return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); |
201 | } |
202 | |
203 | static DecodeStatus |
204 | DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, uint32_t Address, |
205 | const MCDisassembler *Decoder) { |
206 | if (RegNo == 2) { |
207 | return MCDisassembler::Fail; |
208 | } |
209 | |
210 | return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder); |
211 | } |
212 | |
213 | static DecodeStatus DecodeGPRNoX31RegisterClass(MCInst &Inst, uint32_t RegNo, |
214 | uint64_t Address, |
215 | const MCDisassembler *Decoder) { |
216 | if (RegNo == 31) { |
217 | return MCDisassembler::Fail; |
218 | } |
219 | |
220 | return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); |
221 | } |
222 | |
223 | static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint32_t RegNo, |
224 | uint64_t Address, |
225 | const MCDisassembler *Decoder) { |
226 | if (RegNo >= 8) |
227 | return MCDisassembler::Fail; |
228 | |
229 | MCRegister Reg = RISCV::X8 + RegNo; |
230 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
231 | return MCDisassembler::Success; |
232 | } |
233 | |
234 | static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint32_t RegNo, |
235 | uint64_t Address, |
236 | const MCDisassembler *Decoder) { |
237 | if (RegNo >= 32 || RegNo % 2) |
238 | return MCDisassembler::Fail; |
239 | |
240 | const RISCVDisassembler *Dis = |
241 | static_cast<const RISCVDisassembler *>(Decoder); |
242 | const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo(); |
243 | MCRegister Reg = RI->getMatchingSuperReg( |
244 | Reg: RISCV::X0 + RegNo, SubIdx: RISCV::sub_gpr_even, |
245 | RC: &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]); |
246 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
247 | return MCDisassembler::Success; |
248 | } |
249 | |
250 | static DecodeStatus DecodeGPRPairCRegisterClass(MCInst &Inst, uint32_t RegNo, |
251 | uint64_t Address, |
252 | const MCDisassembler *Decoder) { |
253 | if (RegNo >= 8 || RegNo % 2) |
254 | return MCDisassembler::Fail; |
255 | |
256 | const RISCVDisassembler *Dis = |
257 | static_cast<const RISCVDisassembler *>(Decoder); |
258 | const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo(); |
259 | MCRegister Reg = RI->getMatchingSuperReg( |
260 | Reg: RISCV::X8 + RegNo, SubIdx: RISCV::sub_gpr_even, |
261 | RC: &RISCVMCRegisterClasses[RISCV::GPRPairCRegClassID]); |
262 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
263 | return MCDisassembler::Success; |
264 | } |
265 | |
266 | static DecodeStatus DecodeSR07RegisterClass(MCInst &Inst, uint32_t RegNo, |
267 | uint64_t Address, |
268 | const void *Decoder) { |
269 | if (RegNo >= 8) |
270 | return MCDisassembler::Fail; |
271 | |
272 | MCRegister Reg = (RegNo < 2) ? (RegNo + RISCV::X8) : (RegNo - 2 + RISCV::X18); |
273 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
274 | return MCDisassembler::Success; |
275 | } |
276 | |
277 | static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint32_t RegNo, |
278 | uint64_t Address, |
279 | const MCDisassembler *Decoder) { |
280 | if (RegNo >= 32) |
281 | return MCDisassembler::Fail; |
282 | |
283 | MCRegister Reg = RISCV::V0 + RegNo; |
284 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
285 | return MCDisassembler::Success; |
286 | } |
287 | |
288 | static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint32_t RegNo, |
289 | uint64_t Address, |
290 | const MCDisassembler *Decoder) { |
291 | if (RegNo >= 32 || RegNo % 2) |
292 | return MCDisassembler::Fail; |
293 | |
294 | const RISCVDisassembler *Dis = |
295 | static_cast<const RISCVDisassembler *>(Decoder); |
296 | const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo(); |
297 | MCRegister Reg = |
298 | RI->getMatchingSuperReg(Reg: RISCV::V0 + RegNo, SubIdx: RISCV::sub_vrm1_0, |
299 | RC: &RISCVMCRegisterClasses[RISCV::VRM2RegClassID]); |
300 | |
301 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
302 | return MCDisassembler::Success; |
303 | } |
304 | |
305 | static DecodeStatus DecodeVRM4RegisterClass(MCInst &Inst, uint32_t RegNo, |
306 | uint64_t Address, |
307 | const MCDisassembler *Decoder) { |
308 | if (RegNo >= 32 || RegNo % 4) |
309 | return MCDisassembler::Fail; |
310 | |
311 | const RISCVDisassembler *Dis = |
312 | static_cast<const RISCVDisassembler *>(Decoder); |
313 | const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo(); |
314 | MCRegister Reg = |
315 | RI->getMatchingSuperReg(Reg: RISCV::V0 + RegNo, SubIdx: RISCV::sub_vrm1_0, |
316 | RC: &RISCVMCRegisterClasses[RISCV::VRM4RegClassID]); |
317 | |
318 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
319 | return MCDisassembler::Success; |
320 | } |
321 | |
322 | static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint32_t RegNo, |
323 | uint64_t Address, |
324 | const MCDisassembler *Decoder) { |
325 | if (RegNo >= 32 || RegNo % 8) |
326 | return MCDisassembler::Fail; |
327 | |
328 | const RISCVDisassembler *Dis = |
329 | static_cast<const RISCVDisassembler *>(Decoder); |
330 | const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo(); |
331 | MCRegister Reg = |
332 | RI->getMatchingSuperReg(Reg: RISCV::V0 + RegNo, SubIdx: RISCV::sub_vrm1_0, |
333 | RC: &RISCVMCRegisterClasses[RISCV::VRM8RegClassID]); |
334 | |
335 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
336 | return MCDisassembler::Success; |
337 | } |
338 | |
339 | static DecodeStatus DecodeVMV0RegisterClass(MCInst &Inst, uint32_t RegNo, |
340 | uint64_t Address, |
341 | const MCDisassembler *Decoder) { |
342 | if (RegNo) |
343 | return MCDisassembler::Fail; |
344 | |
345 | Inst.addOperand(Op: MCOperand::createReg(Reg: RISCV::V0)); |
346 | return MCDisassembler::Success; |
347 | } |
348 | |
349 | static DecodeStatus DecodeTRRegisterClass(MCInst &Inst, uint32_t RegNo, |
350 | uint64_t Address, |
351 | const MCDisassembler *Decoder) { |
352 | if (RegNo > 15) |
353 | return MCDisassembler::Fail; |
354 | |
355 | MCRegister Reg = RISCV::T0 + RegNo; |
356 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
357 | return MCDisassembler::Success; |
358 | } |
359 | |
360 | static DecodeStatus DecodeTRM2RegisterClass(MCInst &Inst, uint32_t RegNo, |
361 | uint64_t Address, |
362 | const MCDisassembler *Decoder) { |
363 | if (RegNo > 15 || RegNo % 2) |
364 | return MCDisassembler::Fail; |
365 | |
366 | MCRegister Reg = RISCV::T0 + RegNo; |
367 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
368 | return MCDisassembler::Success; |
369 | } |
370 | |
371 | static DecodeStatus DecodeTRM4RegisterClass(MCInst &Inst, uint32_t RegNo, |
372 | uint64_t Address, |
373 | const MCDisassembler *Decoder) { |
374 | if (RegNo > 15 || RegNo % 4) |
375 | return MCDisassembler::Fail; |
376 | |
377 | MCRegister Reg = RISCV::T0 + RegNo; |
378 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
379 | return MCDisassembler::Success; |
380 | } |
381 | |
382 | static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo, |
383 | uint64_t Address, |
384 | const MCDisassembler *Decoder) { |
385 | if (RegNo >= 2) |
386 | return MCDisassembler::Fail; |
387 | |
388 | MCRegister Reg = (RegNo == 0) ? RISCV::V0 : RISCV::NoRegister; |
389 | |
390 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
391 | return MCDisassembler::Success; |
392 | } |
393 | |
394 | template <unsigned N> |
395 | static DecodeStatus decodeUImmOperand(MCInst &Inst, uint32_t Imm, |
396 | int64_t Address, |
397 | const MCDisassembler *Decoder) { |
398 | assert(isUInt<N>(Imm) && "Invalid immediate" ); |
399 | Inst.addOperand(Op: MCOperand::createImm(Val: Imm)); |
400 | return MCDisassembler::Success; |
401 | } |
402 | |
403 | template <unsigned Width, unsigned LowerBound> |
404 | static DecodeStatus decodeUImmOperandGE(MCInst &Inst, uint32_t Imm, |
405 | int64_t Address, |
406 | const MCDisassembler *Decoder) { |
407 | assert(isUInt<Width>(Imm) && "Invalid immediate" ); |
408 | |
409 | if (Imm < LowerBound) |
410 | return MCDisassembler::Fail; |
411 | |
412 | Inst.addOperand(Op: MCOperand::createImm(Val: Imm)); |
413 | return MCDisassembler::Success; |
414 | } |
415 | |
416 | template <unsigned Width, unsigned LowerBound> |
417 | static DecodeStatus decodeUImmPlus1OperandGE(MCInst &Inst, uint32_t Imm, |
418 | int64_t Address, |
419 | const MCDisassembler *Decoder) { |
420 | assert(isUInt<Width>(Imm) && "Invalid immediate" ); |
421 | |
422 | if ((Imm + 1) < LowerBound) |
423 | return MCDisassembler::Fail; |
424 | |
425 | Inst.addOperand(Op: MCOperand::createImm(Val: Imm + 1)); |
426 | return MCDisassembler::Success; |
427 | } |
428 | |
429 | static DecodeStatus decodeUImmSlistOperand(MCInst &Inst, uint32_t Imm, |
430 | int64_t Address, |
431 | const MCDisassembler *Decoder) { |
432 | assert(isUInt<3>(Imm) && "Invalid Slist immediate" ); |
433 | const uint8_t Slist[] = {0, 1, 2, 4, 8, 16, 15, 31}; |
434 | Inst.addOperand(Op: MCOperand::createImm(Val: Slist[Imm])); |
435 | return MCDisassembler::Success; |
436 | } |
437 | |
438 | static DecodeStatus decodeUImmLog2XLenOperand(MCInst &Inst, uint32_t Imm, |
439 | int64_t Address, |
440 | const MCDisassembler *Decoder) { |
441 | assert(isUInt<6>(Imm) && "Invalid immediate" ); |
442 | |
443 | if (!Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::Feature64Bit) && |
444 | !isUInt<5>(x: Imm)) |
445 | return MCDisassembler::Fail; |
446 | |
447 | Inst.addOperand(Op: MCOperand::createImm(Val: Imm)); |
448 | return MCDisassembler::Success; |
449 | } |
450 | |
451 | template <unsigned N> |
452 | static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm, |
453 | int64_t Address, |
454 | const MCDisassembler *Decoder) { |
455 | if (Imm == 0) |
456 | return MCDisassembler::Fail; |
457 | return decodeUImmOperand<N>(Inst, Imm, Address, Decoder); |
458 | } |
459 | |
460 | static DecodeStatus |
461 | decodeUImmLog2XLenNonZeroOperand(MCInst &Inst, uint32_t Imm, int64_t Address, |
462 | const MCDisassembler *Decoder) { |
463 | if (Imm == 0) |
464 | return MCDisassembler::Fail; |
465 | return decodeUImmLog2XLenOperand(Inst, Imm, Address, Decoder); |
466 | } |
467 | |
468 | template <unsigned N> |
469 | static DecodeStatus decodeUImmPlus1Operand(MCInst &Inst, uint32_t Imm, |
470 | int64_t Address, |
471 | const MCDisassembler *Decoder) { |
472 | assert(isUInt<N>(Imm) && "Invalid immediate" ); |
473 | Inst.addOperand(Op: MCOperand::createImm(Val: Imm + 1)); |
474 | return MCDisassembler::Success; |
475 | } |
476 | |
477 | template <unsigned N> |
478 | static DecodeStatus decodeSImmOperand(MCInst &Inst, uint32_t Imm, |
479 | int64_t Address, |
480 | const MCDisassembler *Decoder) { |
481 | assert(isUInt<N>(Imm) && "Invalid immediate" ); |
482 | // Sign-extend the number in the bottom N bits of Imm |
483 | Inst.addOperand(Op: MCOperand::createImm(Val: SignExtend64<N>(Imm))); |
484 | return MCDisassembler::Success; |
485 | } |
486 | |
487 | template <unsigned N> |
488 | static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint32_t Imm, |
489 | int64_t Address, |
490 | const MCDisassembler *Decoder) { |
491 | if (Imm == 0) |
492 | return MCDisassembler::Fail; |
493 | return decodeSImmOperand<N>(Inst, Imm, Address, Decoder); |
494 | } |
495 | |
496 | template <unsigned T, unsigned N> |
497 | static DecodeStatus decodeSImmOperandAndLslN(MCInst &Inst, uint32_t Imm, |
498 | int64_t Address, |
499 | const MCDisassembler *Decoder) { |
500 | assert(isUInt<T - N + 1>(Imm) && "Invalid immediate" ); |
501 | // Sign-extend the number in the bottom T bits of Imm after accounting for |
502 | // the fact that the T bit immediate is stored in T-N bits (the LSB is |
503 | // always zero) |
504 | Inst.addOperand(Op: MCOperand::createImm(Val: SignExtend64<T>(Imm << N))); |
505 | return MCDisassembler::Success; |
506 | } |
507 | |
508 | static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint32_t Imm, |
509 | int64_t Address, |
510 | const MCDisassembler *Decoder) { |
511 | assert(isUInt<6>(Imm) && "Invalid immediate" ); |
512 | if (Imm == 0) |
513 | return MCDisassembler::Fail; |
514 | Imm = SignExtend64<6>(x: Imm) & 0xfffff; |
515 | Inst.addOperand(Op: MCOperand::createImm(Val: Imm)); |
516 | return MCDisassembler::Success; |
517 | } |
518 | |
519 | static DecodeStatus decodeFRMArg(MCInst &Inst, uint32_t Imm, int64_t Address, |
520 | const MCDisassembler *Decoder) { |
521 | assert(isUInt<3>(Imm) && "Invalid immediate" ); |
522 | if (!llvm::RISCVFPRndMode::isValidRoundingMode(Mode: Imm)) |
523 | return MCDisassembler::Fail; |
524 | |
525 | Inst.addOperand(Op: MCOperand::createImm(Val: Imm)); |
526 | return MCDisassembler::Success; |
527 | } |
528 | |
529 | static DecodeStatus decodeRTZArg(MCInst &Inst, uint32_t Imm, int64_t Address, |
530 | const MCDisassembler *Decoder) { |
531 | assert(isUInt<3>(Imm) && "Invalid immediate" ); |
532 | if (Imm != RISCVFPRndMode::RTZ) |
533 | return MCDisassembler::Fail; |
534 | |
535 | Inst.addOperand(Op: MCOperand::createImm(Val: Imm)); |
536 | return MCDisassembler::Success; |
537 | } |
538 | |
539 | static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn, |
540 | uint64_t Address, |
541 | const MCDisassembler *Decoder); |
542 | |
543 | static DecodeStatus decodeRVCInstrRdSImm6(MCInst &Inst, uint32_t Insn, |
544 | uint64_t Address, |
545 | const MCDisassembler *Decoder); |
546 | |
547 | static DecodeStatus decodeRVCInstrRdCLUIImm(MCInst &Inst, uint32_t Insn, |
548 | uint64_t Address, |
549 | const MCDisassembler *Decoder); |
550 | |
551 | static DecodeStatus |
552 | decodeRVCInstrRdRs1UImmLog2XLenNonZero(MCInst &Inst, uint32_t Insn, |
553 | uint64_t Address, |
554 | const MCDisassembler *Decoder); |
555 | |
556 | static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn, |
557 | uint64_t Address, |
558 | const MCDisassembler *Decoder); |
559 | |
560 | static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn, |
561 | uint64_t Address, |
562 | const MCDisassembler *Decoder); |
563 | |
564 | static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn, |
565 | uint64_t Address, |
566 | const MCDisassembler *Decoder); |
567 | |
568 | static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm, |
569 | uint64_t Address, |
570 | const MCDisassembler *Decoder); |
571 | |
572 | static DecodeStatus decodeXqccmpRlistS0(MCInst &Inst, uint32_t Imm, |
573 | uint64_t Address, |
574 | const MCDisassembler *Decoder); |
575 | |
576 | static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn, |
577 | uint64_t Address, |
578 | const MCDisassembler *Decoder); |
579 | |
580 | #include "RISCVGenDisassemblerTables.inc" |
581 | |
582 | static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn, |
583 | uint64_t Address, |
584 | const MCDisassembler *Decoder) { |
585 | DecodeStatus S = MCDisassembler::Success; |
586 | uint32_t Rd = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5); |
587 | if (!Check(Out&: S, In: DecodeGPRNoX0RegisterClass(Inst, RegNo: Rd, Address, Decoder))) |
588 | return MCDisassembler::Fail; |
589 | Inst.addOperand(Op: Inst.getOperand(i: 0)); |
590 | Inst.addOperand(Op: MCOperand::createImm(Val: 0)); |
591 | return S; |
592 | } |
593 | |
594 | static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn, |
595 | uint64_t Address, |
596 | const MCDisassembler *Decoder) { |
597 | uint32_t Rs1 = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5); |
598 | [[maybe_unused]] DecodeStatus Result = |
599 | DecodeGPRX1X5RegisterClass(Inst, RegNo: Rs1, Address, Decoder); |
600 | assert(Result == MCDisassembler::Success && "Invalid register" ); |
601 | return MCDisassembler::Success; |
602 | } |
603 | |
604 | static DecodeStatus decodeRVCInstrRdSImm6(MCInst &Inst, uint32_t Insn, |
605 | uint64_t Address, |
606 | const MCDisassembler *Decoder) { |
607 | Inst.addOperand(Op: MCOperand::createReg(Reg: RISCV::X0)); |
608 | uint32_t Imm = |
609 | fieldFromInstruction(insn: Insn, startBit: 12, numBits: 1) << 5 | fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5); |
610 | [[maybe_unused]] DecodeStatus Result = |
611 | decodeSImmOperand<6>(Inst, Imm, Address, Decoder); |
612 | assert(Result == MCDisassembler::Success && "Invalid immediate" ); |
613 | return MCDisassembler::Success; |
614 | } |
615 | |
616 | static DecodeStatus decodeRVCInstrRdCLUIImm(MCInst &Inst, uint32_t Insn, |
617 | uint64_t Address, |
618 | const MCDisassembler *Decoder) { |
619 | Inst.addOperand(Op: MCOperand::createReg(Reg: RISCV::X0)); |
620 | uint32_t Imm = |
621 | fieldFromInstruction(insn: Insn, startBit: 12, numBits: 1) << 5 | fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5); |
622 | return decodeCLUIImmOperand(Inst, Imm, Address, Decoder); |
623 | } |
624 | |
625 | static DecodeStatus |
626 | decodeRVCInstrRdRs1UImmLog2XLenNonZero(MCInst &Inst, uint32_t Insn, |
627 | uint64_t Address, |
628 | const MCDisassembler *Decoder) { |
629 | Inst.addOperand(Op: MCOperand::createReg(Reg: RISCV::X0)); |
630 | Inst.addOperand(Op: Inst.getOperand(i: 0)); |
631 | |
632 | uint32_t UImm6 = |
633 | fieldFromInstruction(insn: Insn, startBit: 12, numBits: 1) << 5 | fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5); |
634 | return decodeUImmLog2XLenNonZeroOperand(Inst, Imm: UImm6, Address, Decoder); |
635 | } |
636 | |
637 | static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn, |
638 | uint64_t Address, |
639 | const MCDisassembler *Decoder) { |
640 | DecodeStatus S = MCDisassembler::Success; |
641 | uint32_t Rd = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5); |
642 | uint32_t Rs2 = fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5); |
643 | if (!Check(Out&: S, In: DecodeGPRRegisterClass(Inst, RegNo: Rd, Address, Decoder))) |
644 | return MCDisassembler::Fail; |
645 | if (!Check(Out&: S, In: DecodeGPRRegisterClass(Inst, RegNo: Rs2, Address, Decoder))) |
646 | return MCDisassembler::Fail; |
647 | return S; |
648 | } |
649 | |
650 | static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn, |
651 | uint64_t Address, |
652 | const MCDisassembler *Decoder) { |
653 | DecodeStatus S = MCDisassembler::Success; |
654 | uint32_t Rd = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5); |
655 | uint32_t Rs2 = fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5); |
656 | if (!Check(Out&: S, In: DecodeGPRRegisterClass(Inst, RegNo: Rd, Address, Decoder))) |
657 | return MCDisassembler::Fail; |
658 | Inst.addOperand(Op: Inst.getOperand(i: 0)); |
659 | if (!Check(Out&: S, In: DecodeGPRRegisterClass(Inst, RegNo: Rs2, Address, Decoder))) |
660 | return MCDisassembler::Fail; |
661 | return S; |
662 | } |
663 | |
664 | static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn, |
665 | uint64_t Address, |
666 | const MCDisassembler *Decoder) { |
667 | DecodeStatus S = MCDisassembler::Success; |
668 | uint32_t Rd1 = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5); |
669 | uint32_t Rs1 = fieldFromInstruction(insn: Insn, startBit: 15, numBits: 5); |
670 | uint32_t Rd2 = fieldFromInstruction(insn: Insn, startBit: 20, numBits: 5); |
671 | uint32_t UImm2 = fieldFromInstruction(insn: Insn, startBit: 25, numBits: 2); |
672 | if (!Check(Out&: S, In: DecodeGPRRegisterClass(Inst, RegNo: Rd1, Address, Decoder))) |
673 | return MCDisassembler::Fail; |
674 | if (!Check(Out&: S, In: DecodeGPRRegisterClass(Inst, RegNo: Rd2, Address, Decoder))) |
675 | return MCDisassembler::Fail; |
676 | if (!Check(Out&: S, In: DecodeGPRRegisterClass(Inst, RegNo: Rs1, Address, Decoder))) |
677 | return MCDisassembler::Fail; |
678 | [[maybe_unused]] DecodeStatus Result = |
679 | decodeUImmOperand<2>(Inst, Imm: UImm2, Address, Decoder); |
680 | assert(Result == MCDisassembler::Success && "Invalid immediate" ); |
681 | |
682 | // Disassemble the final operand which is implicit. |
683 | unsigned Opcode = Inst.getOpcode(); |
684 | bool IsWordOp = (Opcode == RISCV::TH_LWD || Opcode == RISCV::TH_LWUD || |
685 | Opcode == RISCV::TH_SWD); |
686 | if (IsWordOp) |
687 | Inst.addOperand(Op: MCOperand::createImm(Val: 3)); |
688 | else |
689 | Inst.addOperand(Op: MCOperand::createImm(Val: 4)); |
690 | |
691 | return S; |
692 | } |
693 | |
694 | static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm, |
695 | uint64_t Address, |
696 | const MCDisassembler *Decoder) { |
697 | bool IsRVE = Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::FeatureStdExtE); |
698 | if (Imm < RISCVZC::RA || (IsRVE && Imm >= RISCVZC::RA_S0_S2)) |
699 | return MCDisassembler::Fail; |
700 | Inst.addOperand(Op: MCOperand::createImm(Val: Imm)); |
701 | return MCDisassembler::Success; |
702 | } |
703 | |
704 | static DecodeStatus decodeXqccmpRlistS0(MCInst &Inst, uint32_t Imm, |
705 | uint64_t Address, |
706 | const MCDisassembler *Decoder) { |
707 | if (Imm < RISCVZC::RA_S0) |
708 | return MCDisassembler::Fail; |
709 | return decodeZcmpRlist(Inst, Imm, Address, Decoder); |
710 | } |
711 | |
712 | // Add implied SP operand for C.*SP compressed instructions. The SP operand |
713 | // isn't explicitly encoded in the instruction. |
714 | void RISCVDisassembler::addSPOperands(MCInst &MI) const { |
715 | const MCInstrDesc &MCID = MCII->get(Opcode: MI.getOpcode()); |
716 | for (unsigned i = 0; i < MCID.getNumOperands(); i++) |
717 | if (MCID.operands()[i].RegClass == RISCV::SPRegClassID) |
718 | MI.insert(I: MI.begin() + i, Op: MCOperand::createReg(Reg: RISCV::X2)); |
719 | } |
720 | |
721 | namespace { |
722 | |
723 | struct DecoderListEntry { |
724 | const uint8_t *Table; |
725 | FeatureBitset ContainedFeatures; |
726 | const char *Desc; |
727 | |
728 | bool haveContainedFeatures(const FeatureBitset &ActiveFeatures) const { |
729 | return ContainedFeatures.none() || |
730 | (ContainedFeatures & ActiveFeatures).any(); |
731 | } |
732 | }; |
733 | |
734 | } // end anonymous namespace |
735 | |
736 | static constexpr FeatureBitset XCVFeatureGroup = { |
737 | RISCV::FeatureVendorXCVbitmanip, RISCV::FeatureVendorXCVelw, |
738 | RISCV::FeatureVendorXCVmac, RISCV::FeatureVendorXCVmem, |
739 | RISCV::FeatureVendorXCValu, RISCV::FeatureVendorXCVsimd, |
740 | RISCV::FeatureVendorXCVbi}; |
741 | |
742 | static constexpr FeatureBitset XRivosFeatureGroup = { |
743 | RISCV::FeatureVendorXRivosVisni, |
744 | RISCV::FeatureVendorXRivosVizip, |
745 | }; |
746 | |
747 | static constexpr FeatureBitset XqciFeatureGroup = { |
748 | RISCV::FeatureVendorXqcia, RISCV::FeatureVendorXqciac, |
749 | RISCV::FeatureVendorXqcibi, RISCV::FeatureVendorXqcibm, |
750 | RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm, |
751 | RISCV::FeatureVendorXqcics, RISCV::FeatureVendorXqcicsr, |
752 | RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqciio, |
753 | RISCV::FeatureVendorXqcilb, RISCV::FeatureVendorXqcili, |
754 | RISCV::FeatureVendorXqcilia, RISCV::FeatureVendorXqcilo, |
755 | RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisim, |
756 | RISCV::FeatureVendorXqcisls, RISCV::FeatureVendorXqcisync, |
757 | }; |
758 | |
759 | static constexpr FeatureBitset XSfVectorGroup = { |
760 | RISCV::FeatureVendorXSfvcp, RISCV::FeatureVendorXSfvqmaccdod, |
761 | RISCV::FeatureVendorXSfvqmaccqoq, RISCV::FeatureVendorXSfvfwmaccqqq, |
762 | RISCV::FeatureVendorXSfvfnrclipxfqf, RISCV::FeatureVendorXSfmmbase}; |
763 | static constexpr FeatureBitset XSfSystemGroup = { |
764 | RISCV::FeatureVendorXSiFivecdiscarddlone, |
765 | RISCV::FeatureVendorXSiFivecflushdlone, |
766 | }; |
767 | |
768 | static constexpr FeatureBitset XTHeadGroup = { |
769 | RISCV::FeatureVendorXTHeadBa, RISCV::FeatureVendorXTHeadBb, |
770 | RISCV::FeatureVendorXTHeadBs, RISCV::FeatureVendorXTHeadCondMov, |
771 | RISCV::FeatureVendorXTHeadCmo, RISCV::FeatureVendorXTHeadFMemIdx, |
772 | RISCV::FeatureVendorXTHeadMac, RISCV::FeatureVendorXTHeadMemIdx, |
773 | RISCV::FeatureVendorXTHeadMemPair, RISCV::FeatureVendorXTHeadSync, |
774 | RISCV::FeatureVendorXTHeadVdot}; |
775 | |
776 | static constexpr FeatureBitset XAndesGroup = { |
777 | RISCV::FeatureVendorXAndesPerf, RISCV::FeatureVendorXAndesVBFHCvt, |
778 | RISCV::FeatureVendorXAndesVPackFPH, RISCV::FeatureVendorXAndesVDot}; |
779 | |
780 | static constexpr DecoderListEntry DecoderList32[]{ |
781 | // Vendor Extensions |
782 | {.Table: DecoderTableXVentana32, |
783 | .ContainedFeatures: {RISCV::FeatureVendorXVentanaCondOps}, |
784 | .Desc: "XVentanaCondOps" }, |
785 | {.Table: DecoderTableXTHead32, .ContainedFeatures: XTHeadGroup, .Desc: "T-Head extensions" }, |
786 | {.Table: DecoderTableXSfvector32, .ContainedFeatures: XSfVectorGroup, .Desc: "SiFive vector extensions" }, |
787 | {.Table: DecoderTableXSfsystem32, .ContainedFeatures: XSfSystemGroup, .Desc: "SiFive system extensions" }, |
788 | {.Table: DecoderTableXSfcease32, .ContainedFeatures: {RISCV::FeatureVendorXSfcease}, .Desc: "SiFive sf.cease" }, |
789 | {.Table: DecoderTableXmipslsp32, .ContainedFeatures: {RISCV::FeatureVendorXMIPSLSP}, .Desc: "MIPS mips.lsp" }, |
790 | {.Table: DecoderTableXmipscmov32, |
791 | .ContainedFeatures: {RISCV::FeatureVendorXMIPSCMov}, |
792 | .Desc: "MIPS mips.ccmov" }, |
793 | {.Table: DecoderTableXmipscbop32, |
794 | .ContainedFeatures: {RISCV::FeatureVendorXMIPSCBOP}, |
795 | .Desc: "MIPS mips.pref" }, |
796 | {.Table: DecoderTableXAndes32, .ContainedFeatures: XAndesGroup, .Desc: "Andes extensions" }, |
797 | // Standard Extensions |
798 | {.Table: DecoderTableXCV32, .ContainedFeatures: XCVFeatureGroup, .Desc: "CORE-V extensions" }, |
799 | {.Table: DecoderTableXqci32, .ContainedFeatures: XqciFeatureGroup, .Desc: "Qualcomm uC Extensions" }, |
800 | {.Table: DecoderTableXRivos32, .ContainedFeatures: XRivosFeatureGroup, .Desc: "Rivos" }, |
801 | {.Table: DecoderTable32, .ContainedFeatures: {}, .Desc: "standard 32-bit instructions" }, |
802 | {.Table: DecoderTableRV32Only32, .ContainedFeatures: {}, .Desc: "RV32-only standard 32-bit instructions" }, |
803 | {.Table: DecoderTableZfinx32, .ContainedFeatures: {}, .Desc: "Zfinx (Float in Integer)" }, |
804 | {.Table: DecoderTableZdinxRV32Only32, .ContainedFeatures: {}, .Desc: "RV32-only Zdinx (Double in Integer)" }, |
805 | }; |
806 | |
807 | DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size, |
808 | ArrayRef<uint8_t> Bytes, |
809 | uint64_t Address, |
810 | raw_ostream &CS) const { |
811 | if (Bytes.size() < 4) { |
812 | Size = 0; |
813 | return MCDisassembler::Fail; |
814 | } |
815 | Size = 4; |
816 | |
817 | // Use uint64_t to match getInstruction48. decodeInstruction is templated |
818 | // on the Insn type. |
819 | uint64_t Insn = support::endian::read32le(P: Bytes.data()); |
820 | |
821 | for (const DecoderListEntry &Entry : DecoderList32) { |
822 | if (!Entry.haveContainedFeatures(ActiveFeatures: STI.getFeatureBits())) |
823 | continue; |
824 | |
825 | LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n" ); |
826 | DecodeStatus Result = |
827 | decodeInstruction(DecodeTable: Entry.Table, MI, insn: Insn, Address, DisAsm: this, STI); |
828 | if (Result == MCDisassembler::Fail) |
829 | continue; |
830 | |
831 | return Result; |
832 | } |
833 | |
834 | return MCDisassembler::Fail; |
835 | } |
836 | |
837 | static constexpr DecoderListEntry DecoderList16[]{ |
838 | // Vendor Extensions |
839 | {.Table: DecoderTableXqci16, .ContainedFeatures: XqciFeatureGroup, .Desc: "Qualcomm uC 16-bit" }, |
840 | {.Table: DecoderTableXqccmp16, |
841 | .ContainedFeatures: {RISCV::FeatureVendorXqccmp}, |
842 | .Desc: "Xqccmp (Qualcomm 16-bit Push/Pop & Double Move Instructions)" }, |
843 | {.Table: DecoderTableXwchc16, .ContainedFeatures: {RISCV::FeatureVendorXwchc}, .Desc: "WCH QingKe XW" }, |
844 | // Standard Extensions |
845 | // DecoderTableZicfiss16 must be checked before DecoderTable16. |
846 | {.Table: DecoderTableZicfiss16, .ContainedFeatures: {}, .Desc: "Zicfiss (Shadow Stack 16-bit)" }, |
847 | {.Table: DecoderTable16, .ContainedFeatures: {}, .Desc: "standard 16-bit instructions" }, |
848 | {.Table: DecoderTableRV32Only16, .ContainedFeatures: {}, .Desc: "RV32-only 16-bit instructions" }, |
849 | // Zc* instructions incompatible with Zcf or Zcd |
850 | {.Table: DecoderTableZcOverlap16, |
851 | .ContainedFeatures: {}, |
852 | .Desc: "ZcOverlap (16-bit Instructions overlapping with Zcf/Zcd)" }, |
853 | }; |
854 | |
855 | DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size, |
856 | ArrayRef<uint8_t> Bytes, |
857 | uint64_t Address, |
858 | raw_ostream &CS) const { |
859 | if (Bytes.size() < 2) { |
860 | Size = 0; |
861 | return MCDisassembler::Fail; |
862 | } |
863 | Size = 2; |
864 | |
865 | // Use uint64_t to match getInstruction48. decodeInstruction is templated |
866 | // on the Insn type. |
867 | uint64_t Insn = support::endian::read16le(P: Bytes.data()); |
868 | |
869 | for (const DecoderListEntry &Entry : DecoderList16) { |
870 | if (!Entry.haveContainedFeatures(ActiveFeatures: STI.getFeatureBits())) |
871 | continue; |
872 | |
873 | LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n" ); |
874 | DecodeStatus Result = |
875 | decodeInstruction(DecodeTable: Entry.Table, MI, insn: Insn, Address, DisAsm: this, STI); |
876 | if (Result == MCDisassembler::Fail) |
877 | continue; |
878 | |
879 | addSPOperands(MI); |
880 | |
881 | return Result; |
882 | } |
883 | |
884 | return MCDisassembler::Fail; |
885 | } |
886 | |
887 | static constexpr DecoderListEntry DecoderList48[]{ |
888 | {.Table: DecoderTableXqci48, .ContainedFeatures: XqciFeatureGroup, .Desc: "Qualcomm uC 48bit" }, |
889 | }; |
890 | |
891 | DecodeStatus RISCVDisassembler::getInstruction48(MCInst &MI, uint64_t &Size, |
892 | ArrayRef<uint8_t> Bytes, |
893 | uint64_t Address, |
894 | raw_ostream &CS) const { |
895 | if (Bytes.size() < 6) { |
896 | Size = 0; |
897 | return MCDisassembler::Fail; |
898 | } |
899 | Size = 6; |
900 | |
901 | uint64_t Insn = 0; |
902 | for (size_t i = Size; i-- != 0;) |
903 | Insn += (static_cast<uint64_t>(Bytes[i]) << 8 * i); |
904 | |
905 | for (const DecoderListEntry &Entry : DecoderList48) { |
906 | if (!Entry.haveContainedFeatures(ActiveFeatures: STI.getFeatureBits())) |
907 | continue; |
908 | |
909 | LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n" ); |
910 | DecodeStatus Result = |
911 | decodeInstruction(DecodeTable: Entry.Table, MI, insn: Insn, Address, DisAsm: this, STI); |
912 | if (Result == MCDisassembler::Fail) |
913 | continue; |
914 | |
915 | return Result; |
916 | } |
917 | |
918 | return MCDisassembler::Fail; |
919 | } |
920 | |
921 | DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, |
922 | ArrayRef<uint8_t> Bytes, |
923 | uint64_t Address, |
924 | raw_ostream &CS) const { |
925 | CommentStream = &CS; |
926 | // It's a 16 bit instruction if bit 0 and 1 are not 0b11. |
927 | if ((Bytes[0] & 0b11) != 0b11) |
928 | return getInstruction16(MI, Size, Bytes, Address, CS); |
929 | |
930 | // It's a 32 bit instruction if bit 1:0 are 0b11(checked above) and bits 4:2 |
931 | // are not 0b111. |
932 | if ((Bytes[0] & 0b1'1100) != 0b1'1100) |
933 | return getInstruction32(MI, Size, Bytes, Address, CS); |
934 | |
935 | // 48-bit instructions are encoded as 0bxx011111. |
936 | if ((Bytes[0] & 0b11'1111) == 0b01'1111) { |
937 | return getInstruction48(MI, Size, Bytes, Address, CS); |
938 | } |
939 | |
940 | // 64-bit instructions are encoded as 0x0111111. |
941 | if ((Bytes[0] & 0b111'1111) == 0b011'1111) { |
942 | Size = Bytes.size() >= 8 ? 8 : 0; |
943 | return MCDisassembler::Fail; |
944 | } |
945 | |
946 | // Remaining cases need to check a second byte. |
947 | if (Bytes.size() < 2) { |
948 | Size = 0; |
949 | return MCDisassembler::Fail; |
950 | } |
951 | |
952 | // 80-bit through 176-bit instructions are encoded as 0bxnnnxxxx_x1111111. |
953 | // Where the number of bits is (80 + (nnn * 16)) for nnn != 0b111. |
954 | unsigned nnn = (Bytes[1] >> 4) & 0b111; |
955 | if (nnn != 0b111) { |
956 | Size = 10 + (nnn * 2); |
957 | if (Bytes.size() < Size) |
958 | Size = 0; |
959 | return MCDisassembler::Fail; |
960 | } |
961 | |
962 | // Remaining encodings are reserved for > 176-bit instructions. |
963 | Size = 0; |
964 | return MCDisassembler::Fail; |
965 | } |
966 | |