LLVM 24.0.0git
RISCVDisassembler.cpp
Go to the documentation of this file.
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
16#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCDecoder.h"
20#include "llvm/MC/MCInst.h"
21#include "llvm/MC/MCInstrInfo.h"
26#include "llvm/Support/Endian.h"
27
28using namespace llvm;
29using namespace llvm::MCD;
30
31#define DEBUG_TYPE "riscv-disassembler"
32
34
35namespace {
36class RISCVDisassembler : public MCDisassembler {
37 std::unique_ptr<MCInstrInfo const> const MCII;
38
39public:
40 RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
41 MCInstrInfo const *MCII)
42 : MCDisassembler(STI, Ctx), MCII(MCII) {}
43
44 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
45 ArrayRef<uint8_t> Bytes, uint64_t Address,
46 raw_ostream &CStream) const override;
47
48private:
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
63 const MCSubtargetInfo &STI,
64 MCContext &Ctx) {
65 return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo());
66}
67
68static MCSymbolizer *
70 LLVMSymbolLookupCallback /*SymbolLookUp*/,
71 void *DisInfo, MCContext *Ctx,
72 std::unique_ptr<MCRelocationInfo> &&RelInfo) {
73 // RISC-V only asks MCSymbolizer to decode HI20/LO12 address fragments. They
74 // require relocation information and cannot be looked up as absolute
75 // addresses when GetOpInfo fails.
76 return llvm::createMCSymbolizer(TT, GetOpInfo, /*SymbolLookUp=*/nullptr,
77 DisInfo, Ctx, std::move(RelInfo));
78}
79
100
101template <unsigned FirstReg, unsigned NumRegsInClass, unsigned RVELimit = 0>
103 uint64_t Address,
104 const MCDisassembler *Decoder) {
105 bool CheckRVE = RVELimit != 0 &&
106 Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE);
107
108 if (RegNo >= NumRegsInClass || (CheckRVE && RegNo >= RVELimit))
110
111 MCRegister Reg = FirstReg + RegNo;
114}
115
116template <unsigned PhysReg, unsigned Encoding>
118 uint64_t Address,
119 const MCDisassembler *Decoder) {
120 assert(RegNo == Encoding);
121 Inst.addOperand(MCOperand::createReg(PhysReg));
123}
124
125template <unsigned PhysReg, unsigned Encoding>
131
133 DecodeSimpleRegisterClass<RISCV::X0, 32, /*RVELimit=*/16>;
135 DecodeSimpleRegisterClass<RISCV::X0_Y, 32, /*RVELimit=*/16>;
136
137template <auto DecodeFn, auto PredicateFn>
139 uint64_t Address,
140 const MCDisassembler *Decoder) {
141 if (!PredicateFn(RegNo))
143 return DecodeFn(Inst, RegNo, Address, Decoder);
144}
145
146constexpr bool PredNoX0(uint32_t RegNo) { return RegNo != 0; }
147constexpr bool PredNoX2(uint32_t RegNo) { return RegNo != 2; }
148constexpr bool PredNoX31(uint32_t RegNo) { return RegNo != 31; }
149constexpr bool PredX1OrX5(uint32_t RegNo) { return RegNo == 1 || RegNo == 5; }
150
161
163 uint64_t Address,
164 const MCDisassembler *Decoder) {
165 const DecodeStatus Result =
166 DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
167 if (Result != MCDisassembler::Success)
168 return Result;
169 const MCRegister Rd = Inst.getOperand(0).getReg();
170 const MCRegister Rs1 = Inst.getOperand(Inst.getNumOperands() - 1).getReg();
171 if (Rd == Rs1)
173 return Result;
174}
175
177 uint64_t Address,
178 const MCDisassembler *Decoder) {
179 const DecodeStatus Result =
180 DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
181 if (Result != MCDisassembler::Success)
182 return Result;
183 const MCRegister Rd1 = Inst.getOperand(0).getReg();
184 const MCRegister Rd2 = Inst.getOperand(1).getReg();
185 const MCRegister Rs1 = Inst.getOperand(Inst.getNumOperands() - 1).getReg();
186 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2)
188 return Result;
189}
190
192 uint64_t Address,
193 const MCDisassembler *Decoder) {
194 if (RegNo >= 32 || RegNo % 2)
196
197 bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE);
198 if (IsRVE && RegNo >= 16)
200
201 const RISCVDisassembler *Dis =
202 static_cast<const RISCVDisassembler *>(Decoder);
203 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
205 RISCV::X0 + RegNo, RISCV::sub_gpr_even,
206 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
209}
210
213
215 uint64_t Address,
216 const MCDisassembler *Decoder) {
217 if (RegNo >= 8 || RegNo % 2)
219
220 return DecodeGPRPairRegisterClass(Inst, RegNo + 8, Address, Decoder);
221}
222
224 uint64_t Address,
225 const MCDisassembler *Decoder) {
226 // Only s0 and s1 exist on RVE, so sreg values above 1 are reserved.
227 bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE);
228 if (RegNo >= 8 || (IsRVE && RegNo > 1))
230
231 MCRegister Reg = (RegNo < 2) ? (RegNo + RISCV::X8) : (RegNo - 2 + RISCV::X18);
234}
235
236template <unsigned RegisterClass, unsigned NumRegsInClass, unsigned LMul>
238 uint64_t Address,
239 const MCDisassembler *Decoder) {
240 if (RegNo >= NumRegsInClass || RegNo % LMul)
242
243 const RISCVDisassembler *Dis =
244 static_cast<const RISCVDisassembler *>(Decoder);
245 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
247 RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
248 &getRISCVMCRegisterClass(RegisterClass));
249
252}
253
255 uint64_t Address,
256 const MCDisassembler *Decoder) {
257 if (RegNo > 15 || RegNo % 2)
259
260 MCRegister Reg = RISCV::T0 + RegNo;
263}
264
266 uint64_t Address,
267 const MCDisassembler *Decoder) {
268 if (RegNo > 15 || RegNo % 4)
270
271 MCRegister Reg = RISCV::T0 + RegNo;
274}
275
276static DecodeStatus DecodeYBNDSWImm(MCInst &Inst, uint64_t Imm, int64_t Address,
277 const MCDisassembler *Decoder) {
278 assert(isUInt<9>(Imm) && "Invalid immediate");
279 uint64_t Result;
280 if (Imm == 0) {
281 // If imm[8:0] == 0, result is 4096.
282 Result = 4096;
283 } else if (Imm <= 255) {
284 // If imm[8] == 0 and imm[7:0] != 0, result is imm[7:0].
285 Result = Imm;
286 } else {
287 uint64_t Imm7To0 = Imm & 0xFF;
288 if (Imm7To0 <= 31) {
289 // If imm[8] == 1 and imm[7:5] == 0 (i.e. imm[7:0] <= 31), result is
290 // `256 | (imm[3:0] << 4) | (imm[4] << 3)`.
291 Result = 256 + ((Imm & 0xF) << 4) + (((Imm >> 4) & 1) << 3);
292 } else {
293 // Otherwise, result is imm[7:0] << 4.
294 Result = Imm7To0 << 4;
295 }
296 }
297 Inst.addOperand(MCOperand::createImm(Result));
299}
300
302 uint64_t Address,
303 const MCDisassembler *Decoder) {
304 if (RegNo >= 2)
306
307 MCRegister Reg = (RegNo == 0) ? RISCV::V0 : RISCV::NoRegister;
308
311}
312
313template <int64_t Imm>
319
320template <unsigned N, unsigned LowerBound = 0>
322 int64_t Address,
323 const MCDisassembler *Decoder) {
324 assert(isUInt<N>(Imm) && "Invalid immediate");
325
326 if (Imm < LowerBound)
328
331}
332
334 int64_t Address,
335 const MCDisassembler *Decoder) {
336 assert(isUInt<3>(Imm) && "Invalid Slist immediate");
337 const uint8_t Slist[] = {0, 1, 2, 4, 8, 16, 15, 31};
338 Inst.addOperand(MCOperand::createImm(Slist[Imm]));
340}
341
343 int64_t Address,
344 const MCDisassembler *Decoder) {
345 assert(isUInt<6>(Imm) && "Invalid immediate");
346
347 if (!Decoder->getSubtargetInfo().hasFeature(RISCV::Feature64Bit) &&
348 !isUInt<5>(Imm))
350
353}
354
355template <unsigned N>
357 int64_t Address,
358 const MCDisassembler *Decoder) {
359 if (Imm == 0)
361 return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
362}
363
364static DecodeStatus
366 const MCDisassembler *Decoder) {
367 if (Imm == 0)
369 return decodeUImmLog2XLenOperand(Inst, Imm, Address, Decoder);
370}
371
372template <unsigned N, unsigned LowerBound = 1>
374 int64_t Address,
375 const MCDisassembler *Decoder) {
376 assert(isUInt<N>(Imm) && "Invalid immediate");
377
378 if ((Imm + 1) < LowerBound)
380
383}
384
386 int64_t Address,
387 const MCDisassembler *Decoder) {
388 assert(isUInt<5>(Imm) && "Invalid immediate");
389 Inst.addOperand(MCOperand::createImm(Imm ? Imm : -1LL));
391}
392
393template <unsigned N>
395 int64_t Address,
396 const MCDisassembler *Decoder) {
397 assert(isUInt<N>(Imm) && "Invalid immediate");
398 // Sign-extend the number in the bottom N bits of Imm
401}
402
404 int64_t Address,
405 const MCDisassembler *Decoder) {
406 assert(isUInt<12>(Imm) && "Invalid immediate");
407 const int64_t Value = SignExtend64<12>(Imm);
408 if (!Decoder->tryAddingSymbolicOperand(Inst, Value, Address,
409 /*IsBranch=*/false,
410 /*Offset=*/0, /*OpSize=*/4,
411 /*InstSize=*/4))
414}
415
417 int64_t Address,
418 const MCDisassembler *Decoder) {
419 assert(isUInt<20>(Imm) && "Invalid immediate");
420 const int64_t Value = SignExtend64<32>(Imm << 12);
421 if (!Decoder->tryAddingSymbolicOperand(Inst, Value, Address,
422 /*IsBranch=*/false,
423 /*Offset=*/0, /*OpSize=*/4,
424 /*InstSize=*/4))
427}
428
429template <unsigned N>
431 int64_t Address,
432 const MCDisassembler *Decoder) {
433 if (Imm == 0)
435 return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
436}
437
438template <unsigned T, unsigned N>
440 int64_t Address,
441 const MCDisassembler *Decoder) {
442 assert(isUInt<T - N + 1>(Imm) && "Invalid immediate");
443 // Sign-extend the number in the bottom T bits of Imm after accounting for
444 // the fact that the T bit immediate is stored in T-N bits (the LSB is
445 // always zero)
448}
449
451 int64_t Address,
452 const MCDisassembler *Decoder) {
453 assert(isUInt<6>(Imm) && "Invalid immediate");
454 if (Imm == 0)
456 Imm = SignExtend64<6>(Imm) & 0xfffff;
459}
460
461static DecodeStatus decodeFRMArg(MCInst &Inst, uint32_t Imm, int64_t Address,
462 const MCDisassembler *Decoder) {
463 assert(isUInt<3>(Imm) && "Invalid immediate");
466
469}
470
472 int64_t Address,
473 const MCDisassembler *Decoder) {
474 const int64_t Is3 = Inst.getOperand(Inst.getNumOperands() - 1).getImm();
475 if (Is3 + Imm >= 32)
477 return decodeUImmOperand<5>(Inst, Imm, Address, Decoder);
478}
479
481 uint64_t Address,
482 const MCDisassembler *Decoder) {
483 bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE);
484 if (Imm < RISCVZC::RA || (IsRVE && Imm >= RISCVZC::RA_S0_S2))
488}
489
491 uint64_t Address,
492 const MCDisassembler *Decoder) {
493 if (Imm < RISCVZC::RA_S0)
495 return decodeZcmpRlist(Inst, Imm, Address, Decoder);
496}
497
499 uint64_t Address,
500 const MCDisassembler *Decoder) {
501 const DecodeStatus Result =
502 DecodeGPRS07RegisterClass(Inst, RegNo, Address, Decoder);
503 if (Result != MCDisassembler::Success)
504 return Result;
505 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
508}
509
510#include "RISCVGenDisassemblerTables.inc"
511
512namespace {
513
514struct DecoderListEntry {
515 const uint8_t *Table;
516 FeatureBitset ContainedFeatures;
517 const char *Desc;
518
519 bool haveContainedFeatures(const FeatureBitset &ActiveFeatures) const {
520 return ContainedFeatures.none() ||
521 (ContainedFeatures & ActiveFeatures).any();
522 }
523};
524
525} // end anonymous namespace
526
527static constexpr FeatureBitset XCVFeatureGroup = {
528 RISCV::FeatureVendorXCVbitmanip, RISCV::FeatureVendorXCVelw,
529 RISCV::FeatureVendorXCVmac, RISCV::FeatureVendorXCVmem,
530 RISCV::FeatureVendorXCValu, RISCV::FeatureVendorXCVsimd,
531 RISCV::FeatureVendorXCVbi};
532
533static constexpr FeatureBitset XqciFeatureGroup = {
534 RISCV::FeatureVendorXqcia, RISCV::FeatureVendorXqciac,
535 RISCV::FeatureVendorXqcibi, RISCV::FeatureVendorXqcibm,
536 RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm,
537 RISCV::FeatureVendorXqcics, RISCV::FeatureVendorXqcicsr,
538 RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqciio,
539 RISCV::FeatureVendorXqcilb, RISCV::FeatureVendorXqcili,
540 RISCV::FeatureVendorXqcilia, RISCV::FeatureVendorXqcilo,
541 RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisim,
542 RISCV::FeatureVendorXqcisls, RISCV::FeatureVendorXqcisync,
543};
544
545static constexpr FeatureBitset XSfVectorGroup = {
546 RISCV::FeatureVendorXSfvcp, RISCV::FeatureVendorXSfvqmaccdod,
547 RISCV::FeatureVendorXSfvqmaccqoq, RISCV::FeatureVendorXSfvfwmaccqqq,
548 RISCV::FeatureVendorXSfvfnrclipxfqf, RISCV::FeatureVendorXSfmmbase,
549 RISCV::FeatureVendorXSfvfexpa, RISCV::FeatureVendorXSfvfexpa64e,
550 RISCV::FeatureVendorXSfvfbfexp16e, RISCV::FeatureVendorXSfvfexp16e,
551 RISCV::FeatureVendorXSfvfexp32e};
552static constexpr FeatureBitset XSfSystemGroup = {
553 RISCV::FeatureVendorXSiFivecdiscarddlone,
554 RISCV::FeatureVendorXSiFivecflushdlone,
555};
556
557static constexpr FeatureBitset XMIPSGroup = {
558 RISCV::FeatureVendorXMIPSLSP,
559 RISCV::FeatureVendorXMIPSCMov,
560 RISCV::FeatureVendorXMIPSCBOP,
561 RISCV::FeatureVendorXMIPSEXECTL,
562};
563
564static constexpr FeatureBitset XTHeadGroup = {
565 RISCV::FeatureVendorXTHeadBa, RISCV::FeatureVendorXTHeadBb,
566 RISCV::FeatureVendorXTHeadBs, RISCV::FeatureVendorXTHeadCondMov,
567 RISCV::FeatureVendorXTHeadCmo, RISCV::FeatureVendorXTHeadFMemIdx,
568 RISCV::FeatureVendorXTHeadMac, RISCV::FeatureVendorXTHeadMemIdx,
569 RISCV::FeatureVendorXTHeadMemPair, RISCV::FeatureVendorXTHeadSync,
570 RISCV::FeatureVendorXTHeadVdot};
571
572static constexpr FeatureBitset XAndesGroup = {
573 RISCV::FeatureVendorXAndesPerf, RISCV::FeatureVendorXAndesBFHCvt,
574 RISCV::FeatureVendorXAndesVBFHCvt, RISCV::FeatureVendorXAndesVSIntH,
575 RISCV::FeatureVendorXAndesVSIntLoad, RISCV::FeatureVendorXAndesVPackFPH,
576 RISCV::FeatureVendorXAndesVDot};
577
578static constexpr FeatureBitset XSMTGroup = {RISCV::FeatureVendorXSMTVDot,
579 RISCV::FeatureVendorXSMTVDotII};
580
581static constexpr FeatureBitset XAIFGroup = {RISCV::FeatureVendorXAIFET};
582
583static constexpr DecoderListEntry DecoderList32[]{
584 // Vendor Extensions
585 {DecoderTableXCV32, XCVFeatureGroup, "CORE-V extensions"},
586 {DecoderTableXqci32, XqciFeatureGroup, "Qualcomm uC Extensions"},
587 {DecoderTableXTHead32, XTHeadGroup, "T-Head extensions"},
588 {DecoderTableXSfvector32, XSfVectorGroup, "SiFive vector extensions"},
589 {DecoderTableXSfsystem32, XSfSystemGroup, "SiFive system extensions"},
590 {DecoderTableXSfcease32, {RISCV::FeatureVendorXSfcease}, "SiFive sf.cease"},
591 {DecoderTableXMIPS32, XMIPSGroup, "Mips extensions"},
592 {DecoderTableXAndes32, XAndesGroup, "Andes extensions"},
593 {DecoderTableXSMT32, XSMTGroup, "SpacemiT extensions"},
594 {DecoderTableXAIF32, XAIFGroup, "AI Foundry extensions"},
595 // Standard Extensions
596 {DecoderTable32, {}, "standard 32-bit instructions"},
597 {DecoderTableRV32Only32, {}, "RV32-only standard 32-bit instructions"},
598 {DecoderTableZfinx32, {}, "Zfinx (Float in Integer)"},
599 {DecoderTableZdinxRV32Only32, {}, "RV32-only Zdinx (Double in Integer)"},
600};
601
602namespace {
603// Define bitwidths for various types used to instantiate the decoder.
604template <> constexpr uint32_t InsnBitWidth<uint16_t> = 16;
605template <> constexpr uint32_t InsnBitWidth<uint32_t> = 32;
606// Use uint64_t to represent 48 bit instructions.
607template <> constexpr uint32_t InsnBitWidth<uint64_t> = 48;
608} // namespace
609
610DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
611 ArrayRef<uint8_t> Bytes,
612 uint64_t Address,
613 raw_ostream &CS) const {
614 if (Bytes.size() < 4) {
615 Size = 0;
617 }
618 Size = 4;
619
620 uint32_t Insn = support::endian::read32le(Bytes.data());
621
622 for (const DecoderListEntry &Entry : DecoderList32) {
623 if (!Entry.haveContainedFeatures(STI.getFeatureBits()))
624 continue;
625
626 LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n");
628 decodeInstruction(Entry.Table, MI, Insn, Address, this, STI);
629 if (Result == MCDisassembler::Fail)
630 continue;
631
632 return Result;
633 }
634
636}
637
638static constexpr DecoderListEntry DecoderList16[]{
639 // Vendor Extensions
640 {DecoderTableXqci16, XqciFeatureGroup, "Qualcomm uC 16-bit"},
641 {DecoderTableXqccmp16,
642 {RISCV::FeatureVendorXqccmp},
643 "Xqccmp (Qualcomm 16-bit Push/Pop & Double Move Instructions)"},
644 {DecoderTableXqccmi16,
645 {RISCV::FeatureVendorXqccmi},
646 "Xqccmi (Qualcomm 16-bit Instruction Lookup Table)"},
647 {DecoderTableXqccmt16,
648 {RISCV::FeatureVendorXqccmt},
649 "Xqccmt (Qualcomm 16-bit Table Jump Instructions)"},
650 {DecoderTableXwchc16, {RISCV::FeatureVendorXwchc}, "WCH QingKe XW"},
651 // Standard Extensions
652 {DecoderTable16, {}, "standard 16-bit instructions"},
653 {DecoderTableRV32Only16, {}, "RV32-only 16-bit instructions"},
654 // Zc* instructions incompatible with Zcf or Zcd
655 {DecoderTableZcOverlap16,
656 {},
657 "ZcOverlap (16-bit Instructions overlapping with Zcf/Zcd)"},
658};
659
660DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,
661 ArrayRef<uint8_t> Bytes,
663 raw_ostream &CS) const {
664 if (Bytes.size() < 2) {
665 Size = 0;
667 }
668 Size = 2;
669
670 uint16_t Insn = support::endian::read16le(Bytes.data());
671
672 for (const DecoderListEntry &Entry : DecoderList16) {
673 if (!Entry.haveContainedFeatures(STI.getFeatureBits()))
674 continue;
675
676 LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n");
678 decodeInstruction(Entry.Table, MI, Insn, Address, this, STI);
679 if (Result != MCDisassembler::Fail)
680 return Result;
681 }
682
684}
685
686static constexpr DecoderListEntry DecoderList48[]{
687 {DecoderTableXqci48, XqciFeatureGroup, "Qualcomm uC 48bit"},
688};
689
690DecodeStatus RISCVDisassembler::getInstruction48(MCInst &MI, uint64_t &Size,
691 ArrayRef<uint8_t> Bytes,
693 raw_ostream &CS) const {
694 if (Bytes.size() < 6) {
695 Size = 0;
697 }
698 Size = 6;
699
700 uint64_t Insn = 0;
701 for (size_t i = Size; i-- != 0;)
702 Insn += (static_cast<uint64_t>(Bytes[i]) << 8 * i);
703
704 for (const DecoderListEntry &Entry : DecoderList48) {
705 if (!Entry.haveContainedFeatures(STI.getFeatureBits()))
706 continue;
707
708 LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n");
710 decodeInstruction(Entry.Table, MI, Insn, Address, this, STI);
711 if (Result == MCDisassembler::Fail)
712 continue;
713
714 return Result;
715 }
716
718}
719
720DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
721 ArrayRef<uint8_t> Bytes,
723 raw_ostream &CS) const {
724 CommentStream = &CS;
725 // It's a 16 bit instruction if bit 0 and 1 are not 0b11.
726 if ((Bytes[0] & 0b11) != 0b11)
727 return getInstruction16(MI, Size, Bytes, Address, CS);
728
729 // Try to decode as a 32-bit instruction first.
730 DecodeStatus Result = getInstruction32(MI, Size, Bytes, Address, CS);
731 if (Result != MCDisassembler::Fail)
732 return Result;
733
734 // If bits [4:2] are 0b111 this might be a 48-bit or larger instruction,
735 // otherwise assume it's an unknown 32-bit instruction.
736 if ((Bytes[0] & 0b1'1100) != 0b1'1100) {
737 Size = Bytes.size() >= 4 ? 4 : 0;
739 }
740
741 // 48-bit instructions are encoded as 0bxx011111.
742 if ((Bytes[0] & 0b11'1111) == 0b01'1111)
743 return getInstruction48(MI, Size, Bytes, Address, CS);
744
745 // 64-bit instructions are encoded as 0x0111111.
746 if ((Bytes[0] & 0b111'1111) == 0b011'1111) {
747 Size = Bytes.size() >= 8 ? 8 : 0;
749 }
750
751 // Remaining cases need to check a second byte.
752 if (Bytes.size() < 2) {
753 Size = 0;
755 }
756
757 // 80-bit through 176-bit instructions are encoded as 0bxnnnxxxx_x1111111.
758 // Where the number of bits is (80 + (nnn * 16)) for nnn != 0b111.
759 unsigned nnn = (Bytes[1] >> 4) & 0b111;
760 if (nnn != 0b111) {
761 Size = 10 + (nnn * 2);
762 if (Bytes.size() < Size)
763 Size = 0;
765 }
766
767 // Remaining encodings are reserved for > 176-bit instructions.
768 Size = 0;
770}
MCDisassembler::DecodeStatus DecodeStatus
static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
uint64_t Imm
uint64_t const MCDisassembler * Decoder
#define LLVM_ABI
Definition Compiler.h:211
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
IRTranslator LLVM IR MI
Register Reg
#define T
static constexpr FeatureBitset XqciFeatureGroup
static DecodeStatus decodeUImmSlistOperand(MCInst &Inst, uint32_t Imm, int64_t Address, const MCDisassembler *Decoder)
static constexpr FeatureBitset XAIFGroup
static DecodeStatus decodeFixedImmOperand(MCInst &Inst, const MCDisassembler *Decoder)
constexpr auto DecodeGPRNoX31RegisterClass
static constexpr FeatureBitset XSMTGroup
static DecodeStatus decodeUImmLog2XLenOperand(MCInst &Inst, uint32_t Imm, int64_t Address, const MCDisassembler *Decoder)
constexpr auto DecodeGPRPairNoX0RegisterClass
constexpr bool PredNoX2(uint32_t RegNo)
static constexpr FeatureBitset XCVFeatureGroup
static constexpr DecoderListEntry DecoderList48[]
static DecodeStatus decodeSImmOperand(MCInst &Inst, uint32_t Imm, int64_t Address, const MCDisassembler *Decoder)
static constexpr DecoderListEntry DecoderList16[]
constexpr auto DecodeYGPRNoX0RegisterClass
constexpr auto DecodeGPRX1X5RegisterClass
static DecodeStatus decodeCVInsertIs2Operand(MCInst &Inst, uint32_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeUImmLog2XLenNonZeroOperand(MCInst &Inst, uint32_t Imm, int64_t Address, const MCDisassembler *Decoder)
static MCDisassembler * createRISCVDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
static DecodeStatus DecodeTRM2RegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeVectorRegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeTHMemPairRs1Operand(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeSImmOperandAndLslN(MCInst &Inst, uint32_t Imm, int64_t Address, const MCDisassembler *Decoder)
static constexpr FeatureBitset XSfVectorGroup
static constexpr DecoderListEntry DecoderList32[]
constexpr bool PredNoX0(uint32_t RegNo)
static DecodeStatus decodeXqccmpRlistS0(MCInst &Inst, uint32_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static MCSymbolizer * createRISCVMCSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback, void *DisInfo, MCContext *Ctx, std::unique_ptr< MCRelocationInfo > &&RelInfo)
static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint32_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm, uint64_t Address, const MCDisassembler *Decoder)
constexpr auto DecodeYGPRRegisterClass
static DecodeStatus decodeUImmPlus1Operand(MCInst &Inst, uint32_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeUImm20Operand(MCInst &Inst, uint32_t Imm, int64_t Address, const MCDisassembler *Decoder)
constexpr bool PredX1OrX5(uint32_t RegNo)
static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeSImm12LoOperand(MCInst &Inst, uint32_t Imm, int64_t Address, const MCDisassembler *Decoder)
constexpr auto DecodeGPRNoX2RegisterClass
static DecodeStatus decodeImmZibiOperand(MCInst &Inst, uint32_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeUImmOperand(MCInst &Inst, uint32_t Imm, int64_t Address, const MCDisassembler *Decoder)
static constexpr FeatureBitset XMIPSGroup
constexpr auto DecodeGPRRegisterClass
static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint32_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeFilteredRegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static constexpr FeatureBitset XAndesGroup
static DecodeStatus DecodeTRM4RegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeYBNDSWImm(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
constexpr bool PredNoX31(uint32_t RegNo)
static DecodeStatus decodeTHMemIdxRs1Operand(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeMvsa01Rs2Operand(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeFRMArg(MCInst &Inst, uint32_t Imm, int64_t Address, const MCDisassembler *Decoder)
static constexpr FeatureBitset XTHeadGroup
static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeSingleRegister(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeGPRS07RegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVDisassembler()
static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
constexpr auto DecodeGPRNoX0RegisterClass
static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm, int64_t Address, const MCDisassembler *Decoder)
static constexpr FeatureBitset XSfSystemGroup
static DecodeStatus DecodeGPRPairCRegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
#define LLVM_DEBUG(...)
Definition Debug.h:119
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
const T * data() const
Definition ArrayRef.h:138
Container class for subtarget features.
Context object for machine code objects.
Definition MCContext.h:83
Superclass for all disassemblers.
DecodeStatus
Ternary decode status.
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
unsigned getNumOperands() const
Definition MCInst.h:212
void addOperand(const MCOperand Op)
Definition MCInst.h:215
const MCOperand & getOperand(unsigned i) const
Definition MCInst.h:210
Interface to description of machine instruction set.
Definition MCInstrInfo.h:27
int64_t getImm() const
Definition MCInst.h:84
static MCOperand createReg(MCRegister Reg)
Definition MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition MCInst.h:145
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Generic base class for all target subtargets.
Symbolize and annotate disassembled instructions.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
LLVM Value Representation.
Definition Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
const char *(* LLVMSymbolLookupCallback)(void *DisInfo, uint64_t ReferenceValue, uint64_t *ReferenceType, uint64_t ReferencePC, const char **ReferenceName)
The type for the symbol lookup function.
int(* LLVMOpInfoCallback)(void *DisInfo, uint64_t PC, uint64_t Offset, uint64_t OpSize, uint64_t InstSize, int TagType, void *TagBuf)
The type for the operand information call back function.
constexpr bool any(E Val)
@ Entry
Definition COFF.h:862
static bool isValidRoundingMode(unsigned Mode)
uint16_t read16le(const void *P)
Definition Endian.h:409
uint32_t read32le(const void *P)
Definition Endian.h:412
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheRISCV32Target()
Target & getTheRISCV64beTarget()
LLVM_ABI MCSymbolizer * createMCSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx, std::unique_ptr< MCRelocationInfo > &&RelInfo)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
Target & getTheRISCV64Target()
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition MathExtras.h:572
Target & getTheRISCV32beTarget()
#define N
static void RegisterMCSymbolizer(Target &T, Target::MCSymbolizerCtorTy Fn)
RegisterMCSymbolizer - Register an MCSymbolizer implementation for the given target.
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.