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/Endian.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: |
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 | private: |
46 | void addSPOperands(MCInst &MI) const; |
47 | |
48 | DecodeStatus getInstruction32(MCInst &Instr, uint64_t &Size, |
49 | ArrayRef<uint8_t> Bytes, uint64_t Address, |
50 | raw_ostream &CStream) const; |
51 | DecodeStatus getInstruction16(MCInst &Instr, uint64_t &Size, |
52 | ArrayRef<uint8_t> Bytes, uint64_t Address, |
53 | raw_ostream &CStream) const; |
54 | }; |
55 | } // end anonymous namespace |
56 | |
57 | static MCDisassembler *createRISCVDisassembler(const Target &T, |
58 | const MCSubtargetInfo &STI, |
59 | MCContext &Ctx) { |
60 | return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo()); |
61 | } |
62 | |
63 | extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVDisassembler() { |
64 | // Register the disassembler for each target. |
65 | TargetRegistry::RegisterMCDisassembler(T&: getTheRISCV32Target(), |
66 | Fn: createRISCVDisassembler); |
67 | TargetRegistry::RegisterMCDisassembler(T&: getTheRISCV64Target(), |
68 | Fn: createRISCVDisassembler); |
69 | } |
70 | |
71 | static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo, |
72 | uint64_t Address, |
73 | const MCDisassembler *Decoder) { |
74 | bool IsRVE = Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::FeatureStdExtE); |
75 | |
76 | if (RegNo >= 32 || (IsRVE && RegNo >= 16)) |
77 | return MCDisassembler::Fail; |
78 | |
79 | MCRegister Reg = RISCV::X0 + RegNo; |
80 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
81 | return MCDisassembler::Success; |
82 | } |
83 | |
84 | static DecodeStatus DecodeGPRX1X5RegisterClass(MCInst &Inst, uint32_t RegNo, |
85 | uint64_t Address, |
86 | const MCDisassembler *Decoder) { |
87 | MCRegister Reg = RISCV::X0 + RegNo; |
88 | if (Reg != RISCV::X1 && Reg != RISCV::X5) |
89 | return MCDisassembler::Fail; |
90 | |
91 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
92 | return MCDisassembler::Success; |
93 | } |
94 | |
95 | static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, uint32_t RegNo, |
96 | uint64_t Address, |
97 | const MCDisassembler *Decoder) { |
98 | if (RegNo >= 32) |
99 | return MCDisassembler::Fail; |
100 | |
101 | MCRegister Reg = RISCV::F0_H + RegNo; |
102 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
103 | return MCDisassembler::Success; |
104 | } |
105 | |
106 | static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint32_t RegNo, |
107 | uint64_t Address, |
108 | const MCDisassembler *Decoder) { |
109 | if (RegNo >= 32) |
110 | return MCDisassembler::Fail; |
111 | |
112 | MCRegister Reg = RISCV::F0_F + RegNo; |
113 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
114 | return MCDisassembler::Success; |
115 | } |
116 | |
117 | static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint32_t RegNo, |
118 | uint64_t Address, |
119 | const MCDisassembler *Decoder) { |
120 | if (RegNo >= 8) { |
121 | return MCDisassembler::Fail; |
122 | } |
123 | MCRegister Reg = RISCV::F8_F + RegNo; |
124 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
125 | return MCDisassembler::Success; |
126 | } |
127 | |
128 | static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint32_t RegNo, |
129 | uint64_t Address, |
130 | const MCDisassembler *Decoder) { |
131 | if (RegNo >= 32) |
132 | return MCDisassembler::Fail; |
133 | |
134 | MCRegister Reg = RISCV::F0_D + RegNo; |
135 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
136 | return MCDisassembler::Success; |
137 | } |
138 | |
139 | static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint32_t RegNo, |
140 | uint64_t Address, |
141 | const MCDisassembler *Decoder) { |
142 | if (RegNo >= 8) { |
143 | return MCDisassembler::Fail; |
144 | } |
145 | MCRegister Reg = RISCV::F8_D + RegNo; |
146 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
147 | return MCDisassembler::Success; |
148 | } |
149 | |
150 | static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint32_t RegNo, |
151 | uint64_t Address, |
152 | const MCDisassembler *Decoder) { |
153 | if (RegNo == 0) { |
154 | return MCDisassembler::Fail; |
155 | } |
156 | |
157 | return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); |
158 | } |
159 | |
160 | static DecodeStatus |
161 | DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, uint32_t Address, |
162 | const MCDisassembler *Decoder) { |
163 | if (RegNo == 2) { |
164 | return MCDisassembler::Fail; |
165 | } |
166 | |
167 | return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder); |
168 | } |
169 | |
170 | static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint32_t RegNo, |
171 | uint64_t Address, |
172 | const MCDisassembler *Decoder) { |
173 | if (RegNo >= 8) |
174 | return MCDisassembler::Fail; |
175 | |
176 | MCRegister Reg = RISCV::X8 + RegNo; |
177 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
178 | return MCDisassembler::Success; |
179 | } |
180 | |
181 | static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint32_t RegNo, |
182 | uint64_t Address, |
183 | const MCDisassembler *Decoder) { |
184 | if (RegNo >= 32 || RegNo & 1) |
185 | return MCDisassembler::Fail; |
186 | |
187 | MCRegister Reg = RISCV::X0 + RegNo; |
188 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
189 | return MCDisassembler::Success; |
190 | } |
191 | |
192 | static DecodeStatus DecodeSR07RegisterClass(MCInst &Inst, uint32_t RegNo, |
193 | uint64_t Address, |
194 | const void *Decoder) { |
195 | if (RegNo >= 8) |
196 | return MCDisassembler::Fail; |
197 | |
198 | MCRegister Reg = (RegNo < 2) ? (RegNo + RISCV::X8) : (RegNo - 2 + RISCV::X18); |
199 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
200 | return MCDisassembler::Success; |
201 | } |
202 | |
203 | static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint32_t RegNo, |
204 | uint64_t Address, |
205 | const MCDisassembler *Decoder) { |
206 | if (RegNo >= 32) |
207 | return MCDisassembler::Fail; |
208 | |
209 | MCRegister Reg = RISCV::V0 + RegNo; |
210 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
211 | return MCDisassembler::Success; |
212 | } |
213 | |
214 | static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint32_t RegNo, |
215 | uint64_t Address, |
216 | const MCDisassembler *Decoder) { |
217 | if (RegNo >= 32 || RegNo % 2) |
218 | return MCDisassembler::Fail; |
219 | |
220 | const RISCVDisassembler *Dis = |
221 | static_cast<const RISCVDisassembler *>(Decoder); |
222 | const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo(); |
223 | MCRegister Reg = |
224 | RI->getMatchingSuperReg(Reg: RISCV::V0 + RegNo, SubIdx: RISCV::sub_vrm1_0, |
225 | RC: &RISCVMCRegisterClasses[RISCV::VRM2RegClassID]); |
226 | |
227 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
228 | return MCDisassembler::Success; |
229 | } |
230 | |
231 | static DecodeStatus DecodeVRM4RegisterClass(MCInst &Inst, uint32_t RegNo, |
232 | uint64_t Address, |
233 | const MCDisassembler *Decoder) { |
234 | if (RegNo >= 32 || RegNo % 4) |
235 | return MCDisassembler::Fail; |
236 | |
237 | const RISCVDisassembler *Dis = |
238 | static_cast<const RISCVDisassembler *>(Decoder); |
239 | const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo(); |
240 | MCRegister Reg = |
241 | RI->getMatchingSuperReg(Reg: RISCV::V0 + RegNo, SubIdx: RISCV::sub_vrm1_0, |
242 | RC: &RISCVMCRegisterClasses[RISCV::VRM4RegClassID]); |
243 | |
244 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
245 | return MCDisassembler::Success; |
246 | } |
247 | |
248 | static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint32_t RegNo, |
249 | uint64_t Address, |
250 | const MCDisassembler *Decoder) { |
251 | if (RegNo >= 32 || RegNo % 8) |
252 | return MCDisassembler::Fail; |
253 | |
254 | const RISCVDisassembler *Dis = |
255 | static_cast<const RISCVDisassembler *>(Decoder); |
256 | const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo(); |
257 | MCRegister Reg = |
258 | RI->getMatchingSuperReg(Reg: RISCV::V0 + RegNo, SubIdx: RISCV::sub_vrm1_0, |
259 | RC: &RISCVMCRegisterClasses[RISCV::VRM8RegClassID]); |
260 | |
261 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
262 | return MCDisassembler::Success; |
263 | } |
264 | |
265 | static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo, |
266 | uint64_t Address, |
267 | const MCDisassembler *Decoder) { |
268 | if (RegNo >= 2) |
269 | return MCDisassembler::Fail; |
270 | |
271 | MCRegister Reg = (RegNo == 0) ? RISCV::V0 : RISCV::NoRegister; |
272 | |
273 | Inst.addOperand(Op: MCOperand::createReg(Reg)); |
274 | return MCDisassembler::Success; |
275 | } |
276 | |
277 | template <unsigned N> |
278 | static DecodeStatus decodeUImmOperand(MCInst &Inst, uint32_t Imm, |
279 | int64_t Address, |
280 | const MCDisassembler *Decoder) { |
281 | assert(isUInt<N>(Imm) && "Invalid immediate" ); |
282 | Inst.addOperand(Op: MCOperand::createImm(Val: Imm)); |
283 | return MCDisassembler::Success; |
284 | } |
285 | |
286 | template <unsigned N> |
287 | static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm, |
288 | int64_t Address, |
289 | const MCDisassembler *Decoder) { |
290 | if (Imm == 0) |
291 | return MCDisassembler::Fail; |
292 | return decodeUImmOperand<N>(Inst, Imm, Address, Decoder); |
293 | } |
294 | |
295 | template <unsigned N> |
296 | static DecodeStatus decodeSImmOperand(MCInst &Inst, uint32_t Imm, |
297 | int64_t Address, |
298 | const MCDisassembler *Decoder) { |
299 | assert(isUInt<N>(Imm) && "Invalid immediate" ); |
300 | // Sign-extend the number in the bottom N bits of Imm |
301 | Inst.addOperand(Op: MCOperand::createImm(Val: SignExtend64<N>(Imm))); |
302 | return MCDisassembler::Success; |
303 | } |
304 | |
305 | template <unsigned N> |
306 | static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint32_t Imm, |
307 | int64_t Address, |
308 | const MCDisassembler *Decoder) { |
309 | if (Imm == 0) |
310 | return MCDisassembler::Fail; |
311 | return decodeSImmOperand<N>(Inst, Imm, Address, Decoder); |
312 | } |
313 | |
314 | template <unsigned N> |
315 | static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint32_t Imm, |
316 | int64_t Address, |
317 | const MCDisassembler *Decoder) { |
318 | assert(isUInt<N>(Imm) && "Invalid immediate" ); |
319 | // Sign-extend the number in the bottom N bits of Imm after accounting for |
320 | // the fact that the N bit immediate is stored in N-1 bits (the LSB is |
321 | // always zero) |
322 | Inst.addOperand(Op: MCOperand::createImm(Val: SignExtend64<N>(Imm << 1))); |
323 | return MCDisassembler::Success; |
324 | } |
325 | |
326 | static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint32_t Imm, |
327 | int64_t Address, |
328 | const MCDisassembler *Decoder) { |
329 | assert(isUInt<6>(Imm) && "Invalid immediate" ); |
330 | if (Imm > 31) { |
331 | Imm = (SignExtend64<6>(x: Imm) & 0xfffff); |
332 | } |
333 | Inst.addOperand(Op: MCOperand::createImm(Val: Imm)); |
334 | return MCDisassembler::Success; |
335 | } |
336 | |
337 | static DecodeStatus decodeFRMArg(MCInst &Inst, uint32_t Imm, int64_t Address, |
338 | const MCDisassembler *Decoder) { |
339 | assert(isUInt<3>(Imm) && "Invalid immediate" ); |
340 | if (!llvm::RISCVFPRndMode::isValidRoundingMode(Mode: Imm)) |
341 | return MCDisassembler::Fail; |
342 | |
343 | Inst.addOperand(Op: MCOperand::createImm(Val: Imm)); |
344 | return MCDisassembler::Success; |
345 | } |
346 | |
347 | static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn, |
348 | uint64_t Address, |
349 | const MCDisassembler *Decoder); |
350 | |
351 | static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn, |
352 | uint64_t Address, |
353 | const MCDisassembler *Decoder); |
354 | |
355 | static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, uint32_t Insn, |
356 | uint64_t Address, |
357 | const MCDisassembler *Decoder); |
358 | |
359 | static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn, |
360 | uint64_t Address, |
361 | const MCDisassembler *Decoder); |
362 | |
363 | static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn, |
364 | uint64_t Address, |
365 | const MCDisassembler *Decoder); |
366 | |
367 | static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn, |
368 | uint64_t Address, |
369 | const MCDisassembler *Decoder); |
370 | |
371 | static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm, |
372 | uint64_t Address, const void *Decoder); |
373 | |
374 | static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address, |
375 | const MCDisassembler *Decoder); |
376 | |
377 | static DecodeStatus decodeZcmpSpimm(MCInst &Inst, uint32_t Imm, |
378 | uint64_t Address, const void *Decoder); |
379 | |
380 | static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn, |
381 | uint64_t Address, |
382 | const MCDisassembler *Decoder); |
383 | |
384 | #include "RISCVGenDisassemblerTables.inc" |
385 | |
386 | static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn, |
387 | uint64_t Address, |
388 | const MCDisassembler *Decoder) { |
389 | uint32_t Rd = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5); |
390 | [[maybe_unused]] DecodeStatus Result = |
391 | DecodeGPRNoX0RegisterClass(Inst, RegNo: Rd, Address, Decoder); |
392 | assert(Result == MCDisassembler::Success && "Invalid register" ); |
393 | Inst.addOperand(Op: Inst.getOperand(i: 0)); |
394 | Inst.addOperand(Op: MCOperand::createImm(Val: 0)); |
395 | return MCDisassembler::Success; |
396 | } |
397 | |
398 | static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn, |
399 | uint64_t Address, |
400 | const MCDisassembler *Decoder) { |
401 | uint32_t Rs1 = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5); |
402 | [[maybe_unused]] DecodeStatus Result = |
403 | DecodeGPRX1X5RegisterClass(Inst, RegNo: Rs1, Address, Decoder); |
404 | assert(Result == MCDisassembler::Success && "Invalid register" ); |
405 | return MCDisassembler::Success; |
406 | } |
407 | |
408 | static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn, |
409 | uint64_t Address, |
410 | const MCDisassembler *Decoder) { |
411 | Inst.addOperand(Op: MCOperand::createReg(Reg: RISCV::X0)); |
412 | uint32_t SImm6 = |
413 | fieldFromInstruction(insn: Insn, startBit: 12, numBits: 1) << 5 | fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5); |
414 | [[maybe_unused]] DecodeStatus Result = |
415 | decodeSImmOperand<6>(Inst, Imm: SImm6, Address, Decoder); |
416 | assert(Result == MCDisassembler::Success && "Invalid immediate" ); |
417 | return MCDisassembler::Success; |
418 | } |
419 | |
420 | static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, uint32_t Insn, |
421 | uint64_t Address, |
422 | const MCDisassembler *Decoder) { |
423 | Inst.addOperand(Op: MCOperand::createReg(Reg: RISCV::X0)); |
424 | Inst.addOperand(Op: Inst.getOperand(i: 0)); |
425 | uint32_t UImm6 = |
426 | fieldFromInstruction(insn: Insn, startBit: 12, numBits: 1) << 5 | fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5); |
427 | [[maybe_unused]] DecodeStatus Result = |
428 | decodeUImmOperand<6>(Inst, Imm: UImm6, Address, Decoder); |
429 | assert(Result == MCDisassembler::Success && "Invalid immediate" ); |
430 | return MCDisassembler::Success; |
431 | } |
432 | |
433 | static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn, |
434 | uint64_t Address, |
435 | const MCDisassembler *Decoder) { |
436 | uint32_t Rd = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5); |
437 | uint32_t Rs2 = fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5); |
438 | DecodeGPRRegisterClass(Inst, RegNo: Rd, Address, Decoder); |
439 | DecodeGPRRegisterClass(Inst, RegNo: Rs2, Address, Decoder); |
440 | return MCDisassembler::Success; |
441 | } |
442 | |
443 | static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn, |
444 | uint64_t Address, |
445 | const MCDisassembler *Decoder) { |
446 | uint32_t Rd = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5); |
447 | uint32_t Rs2 = fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5); |
448 | DecodeGPRRegisterClass(Inst, RegNo: Rd, Address, Decoder); |
449 | Inst.addOperand(Op: Inst.getOperand(i: 0)); |
450 | DecodeGPRRegisterClass(Inst, RegNo: Rs2, Address, Decoder); |
451 | return MCDisassembler::Success; |
452 | } |
453 | |
454 | static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn, |
455 | uint64_t Address, |
456 | const MCDisassembler *Decoder) { |
457 | uint32_t Rd1 = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5); |
458 | uint32_t Rs1 = fieldFromInstruction(insn: Insn, startBit: 15, numBits: 5); |
459 | uint32_t Rd2 = fieldFromInstruction(insn: Insn, startBit: 20, numBits: 5); |
460 | uint32_t UImm2 = fieldFromInstruction(insn: Insn, startBit: 25, numBits: 2); |
461 | DecodeGPRRegisterClass(Inst, RegNo: Rd1, Address, Decoder); |
462 | DecodeGPRRegisterClass(Inst, RegNo: Rd2, Address, Decoder); |
463 | DecodeGPRRegisterClass(Inst, RegNo: Rs1, Address, Decoder); |
464 | [[maybe_unused]] DecodeStatus Result = |
465 | decodeUImmOperand<2>(Inst, Imm: UImm2, Address, Decoder); |
466 | assert(Result == MCDisassembler::Success && "Invalid immediate" ); |
467 | |
468 | // Disassemble the final operand which is implicit. |
469 | unsigned Opcode = Inst.getOpcode(); |
470 | bool IsWordOp = (Opcode == RISCV::TH_LWD || Opcode == RISCV::TH_LWUD || |
471 | Opcode == RISCV::TH_SWD); |
472 | if (IsWordOp) |
473 | Inst.addOperand(Op: MCOperand::createImm(Val: 3)); |
474 | else |
475 | Inst.addOperand(Op: MCOperand::createImm(Val: 4)); |
476 | |
477 | return MCDisassembler::Success; |
478 | } |
479 | |
480 | static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm, |
481 | uint64_t Address, const void *Decoder) { |
482 | if (Imm <= 3) |
483 | return MCDisassembler::Fail; |
484 | Inst.addOperand(Op: MCOperand::createImm(Val: Imm)); |
485 | return MCDisassembler::Success; |
486 | } |
487 | |
488 | static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address, |
489 | const MCDisassembler *Decoder) { |
490 | uint32_t Rs1 = fieldFromInstruction(insn: Insn, startBit: 0, numBits: 5); |
491 | uint32_t Rs2 = fieldFromInstruction(insn: Insn, startBit: 5, numBits: 5); |
492 | DecodeGPRRegisterClass(Inst, RegNo: Rs1, Address, Decoder); |
493 | DecodeGPRRegisterClass(Inst, RegNo: Rs2, Address, Decoder); |
494 | return MCDisassembler::Success; |
495 | } |
496 | |
497 | static DecodeStatus decodeZcmpSpimm(MCInst &Inst, uint32_t Imm, |
498 | uint64_t Address, const void *Decoder) { |
499 | Inst.addOperand(Op: MCOperand::createImm(Val: Imm)); |
500 | return MCDisassembler::Success; |
501 | } |
502 | |
503 | // Add implied SP operand for C.*SP compressed instructions. The SP operand |
504 | // isn't explicitly encoded in the instruction. |
505 | void RISCVDisassembler::addSPOperands(MCInst &MI) const { |
506 | const MCInstrDesc &MCID = MCII->get(Opcode: MI.getOpcode()); |
507 | for (unsigned i = 0; i < MCID.getNumOperands(); i++) |
508 | if (MCID.operands()[i].RegClass == RISCV::SPRegClassID) |
509 | MI.insert(I: MI.begin() + i, Op: MCOperand::createReg(Reg: RISCV::X2)); |
510 | } |
511 | |
512 | #define TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, \ |
513 | DESC, ADDITIONAL_OPERATION) \ |
514 | do { \ |
515 | if (FEATURE_CHECKS) { \ |
516 | LLVM_DEBUG(dbgs() << "Trying " DESC ":\n"); \ |
517 | DecodeStatus Result = \ |
518 | decodeInstruction(DECODER_TABLE, MI, Insn, Address, this, STI); \ |
519 | if (Result != MCDisassembler::Fail) { \ |
520 | ADDITIONAL_OPERATION; \ |
521 | return Result; \ |
522 | } \ |
523 | } \ |
524 | } while (false) |
525 | #define TRY_TO_DECODE_AND_ADD_SP(FEATURE_CHECKS, DECODER_TABLE, DESC) \ |
526 | TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, DESC, \ |
527 | addSPOperands(MI)) |
528 | #define TRY_TO_DECODE(FEATURE_CHECKS, DECODER_TABLE, DESC) \ |
529 | TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, DESC, \ |
530 | (void)nullptr) |
531 | #define TRY_TO_DECODE_FEATURE(FEATURE, DECODER_TABLE, DESC) \ |
532 | TRY_TO_DECODE(STI.hasFeature(FEATURE), DECODER_TABLE, DESC) |
533 | |
534 | DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size, |
535 | ArrayRef<uint8_t> Bytes, |
536 | uint64_t Address, |
537 | raw_ostream &CS) const { |
538 | if (Bytes.size() < 4) { |
539 | Size = 0; |
540 | return MCDisassembler::Fail; |
541 | } |
542 | Size = 4; |
543 | |
544 | uint32_t Insn = support::endian::read32le(P: Bytes.data()); |
545 | |
546 | TRY_TO_DECODE(STI.hasFeature(RISCV::FeatureStdExtZdinx) && |
547 | !STI.hasFeature(RISCV::Feature64Bit), |
548 | DecoderTableRV32Zdinx32, |
549 | "RV32Zdinx table (Double in Integer and rv32)" ); |
550 | TRY_TO_DECODE(STI.hasFeature(RISCV::FeatureStdExtZacas) && |
551 | !STI.hasFeature(RISCV::Feature64Bit), |
552 | DecoderTableRV32Zacas32, |
553 | "RV32Zacas table (Compare-And-Swap and rv32)" ); |
554 | TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZfinx, DecoderTableRVZfinx32, |
555 | "RVZfinx table (Float in Integer)" ); |
556 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXVentanaCondOps, |
557 | DecoderTableXVentana32, "Ventana custom opcode table" ); |
558 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBa, DecoderTableXTHeadBa32, |
559 | "XTHeadBa custom opcode table" ); |
560 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBb, DecoderTableXTHeadBb32, |
561 | "XTHeadBb custom opcode table" ); |
562 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBs, DecoderTableXTHeadBs32, |
563 | "XTHeadBs custom opcode table" ); |
564 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadCondMov, |
565 | DecoderTableXTHeadCondMov32, |
566 | "XTHeadCondMov custom opcode table" ); |
567 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadCmo, DecoderTableXTHeadCmo32, |
568 | "XTHeadCmo custom opcode table" ); |
569 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadFMemIdx, |
570 | DecoderTableXTHeadFMemIdx32, |
571 | "XTHeadFMemIdx custom opcode table" ); |
572 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMac, DecoderTableXTHeadMac32, |
573 | "XTHeadMac custom opcode table" ); |
574 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMemIdx, |
575 | DecoderTableXTHeadMemIdx32, |
576 | "XTHeadMemIdx custom opcode table" ); |
577 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMemPair, |
578 | DecoderTableXTHeadMemPair32, |
579 | "XTHeadMemPair custom opcode table" ); |
580 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadSync, |
581 | DecoderTableXTHeadSync32, |
582 | "XTHeadSync custom opcode table" ); |
583 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadVdot, |
584 | DecoderTableXTHeadVdot32, |
585 | "XTHeadVdot custom opcode table" ); |
586 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfvcp, DecoderTableXSfvcp32, |
587 | "SiFive VCIX custom opcode table" ); |
588 | TRY_TO_DECODE_FEATURE( |
589 | RISCV::FeatureVendorXSfvqmaccdod, DecoderTableXSfvqmaccdod32, |
590 | "SiFive Matrix Multiplication (2x8 and 8x2) Instruction opcode table" ); |
591 | TRY_TO_DECODE_FEATURE( |
592 | RISCV::FeatureVendorXSfvqmaccqoq, DecoderTableXSfvqmaccqoq32, |
593 | "SiFive Matrix Multiplication (4x8 and 8x4) Instruction opcode table" ); |
594 | TRY_TO_DECODE_FEATURE( |
595 | RISCV::FeatureVendorXSfvfwmaccqqq, DecoderTableXSfvfwmaccqqq32, |
596 | "SiFive Matrix Multiplication Instruction opcode table" ); |
597 | TRY_TO_DECODE_FEATURE( |
598 | RISCV::FeatureVendorXSfvfnrclipxfqf, DecoderTableXSfvfnrclipxfqf32, |
599 | "SiFive FP32-to-int8 Ranged Clip Instructions opcode table" ); |
600 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSiFivecdiscarddlone, |
601 | DecoderTableXSiFivecdiscarddlone32, |
602 | "SiFive sf.cdiscard.d.l1 custom opcode table" ); |
603 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSiFivecflushdlone, |
604 | DecoderTableXSiFivecflushdlone32, |
605 | "SiFive sf.cflush.d.l1 custom opcode table" ); |
606 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfcease, DecoderTableXSfcease32, |
607 | "SiFive sf.cease custom opcode table" ); |
608 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbitmanip, |
609 | DecoderTableXCVbitmanip32, |
610 | "CORE-V Bit Manipulation custom opcode table" ); |
611 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVelw, DecoderTableXCVelw32, |
612 | "CORE-V Event load custom opcode table" ); |
613 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmac, DecoderTableXCVmac32, |
614 | "CORE-V MAC custom opcode table" ); |
615 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmem, DecoderTableXCVmem32, |
616 | "CORE-V MEM custom opcode table" ); |
617 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCValu, DecoderTableXCValu32, |
618 | "CORE-V ALU custom opcode table" ); |
619 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVsimd, DecoderTableXCVsimd32, |
620 | "CORE-V SIMD extensions custom opcode table" ); |
621 | TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbi, DecoderTableXCVbi32, |
622 | "CORE-V Immediate Branching custom opcode table" ); |
623 | TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table" ); |
624 | |
625 | return MCDisassembler::Fail; |
626 | } |
627 | |
628 | DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size, |
629 | ArrayRef<uint8_t> Bytes, |
630 | uint64_t Address, |
631 | raw_ostream &CS) const { |
632 | if (Bytes.size() < 2) { |
633 | Size = 0; |
634 | return MCDisassembler::Fail; |
635 | } |
636 | Size = 2; |
637 | |
638 | uint32_t Insn = support::endian::read16le(P: Bytes.data()); |
639 | TRY_TO_DECODE_AND_ADD_SP(!STI.hasFeature(RISCV::Feature64Bit), |
640 | DecoderTableRISCV32Only_16, |
641 | "RISCV32Only_16 table (16-bit Instruction)" ); |
642 | TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZicfiss, DecoderTableZicfiss16, |
643 | "RVZicfiss table (Shadow Stack)" ); |
644 | TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZcmt, DecoderTableRVZcmt16, |
645 | "Zcmt table (16-bit Table Jump Instructions)" ); |
646 | TRY_TO_DECODE_FEATURE( |
647 | RISCV::FeatureStdExtZcmp, DecoderTableRVZcmp16, |
648 | "Zcmp table (16-bit Push/Pop & Double Move Instructions)" ); |
649 | TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc), |
650 | DecoderTableXwchc16, |
651 | "WCH QingKe XW custom opcode table" ); |
652 | TRY_TO_DECODE_AND_ADD_SP(true, DecoderTable16, |
653 | "RISCV_C table (16-bit Instruction)" ); |
654 | |
655 | return MCDisassembler::Fail; |
656 | } |
657 | |
658 | DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, |
659 | ArrayRef<uint8_t> Bytes, |
660 | uint64_t Address, |
661 | raw_ostream &CS) const { |
662 | // It's a 16 bit instruction if bit 0 and 1 are not 0b11. |
663 | if ((Bytes[0] & 0b11) != 0b11) |
664 | return getInstruction16(MI, Size, Bytes, Address, CS); |
665 | |
666 | // It's a 32 bit instruction if bit 1:0 are 0b11(checked above) and bits 4:2 |
667 | // are not 0b111. |
668 | if ((Bytes[0] & 0b1'1100) != 0b1'1100) |
669 | return getInstruction32(MI, Size, Bytes, Address, CS); |
670 | |
671 | // 48-bit instructions are encoded as 0bxx011111. |
672 | if ((Bytes[0] & 0b11'1111) == 0b01'1111) { |
673 | Size = Bytes.size() >= 6 ? 6 : 0; |
674 | return MCDisassembler::Fail; |
675 | } |
676 | |
677 | // 64-bit instructions are encoded as 0x0111111. |
678 | if ((Bytes[0] & 0b111'1111) == 0b011'1111) { |
679 | Size = Bytes.size() >= 8 ? 8 : 0; |
680 | return MCDisassembler::Fail; |
681 | } |
682 | |
683 | // Remaining cases need to check a second byte. |
684 | if (Bytes.size() < 2) { |
685 | Size = 0; |
686 | return MCDisassembler::Fail; |
687 | } |
688 | |
689 | // 80-bit through 176-bit instructions are encoded as 0bxnnnxxxx_x1111111. |
690 | // Where the number of bits is (80 + (nnn * 16)) for nnn != 0b111. |
691 | unsigned nnn = (Bytes[1] >> 4) & 0b111; |
692 | if (nnn != 0b111) { |
693 | Size = 10 + (nnn * 2); |
694 | if (Bytes.size() < Size) |
695 | Size = 0; |
696 | return MCDisassembler::Fail; |
697 | } |
698 | |
699 | // Remaining encodings are reserved for > 176-bit instructions. |
700 | Size = 0; |
701 | return MCDisassembler::Fail; |
702 | } |
703 | |