LLVM 23.0.0git
AArch64Disassembler.cpp
Go to the documentation of this file.
1//===- AArch64Disassembler.cpp - Disassembler for AArch64 -----------------===//
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//
10//===----------------------------------------------------------------------===//
11
12#include "AArch64Disassembler.h"
18#include "llvm/MC/MCDecoder.h"
21#include "llvm/MC/MCInst.h"
22#include "llvm/MC/MCInstrDesc.h"
27#include "llvm/Support/Debug.h"
28#include <memory>
29
30using namespace llvm;
31using namespace llvm::MCD;
32
33#define DEBUG_TYPE "aarch64-disassembler"
34
35// Pull DecodeStatus and its enum values into the global namespace.
37
38template <int Bits>
39static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
40 const MCDisassembler *Decoder);
41template <int Bits>
42static DecodeStatus DecodeUImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
43 const MCDisassembler *Decoder);
44
45#define Success MCDisassembler::Success
46#define Fail MCDisassembler::Fail
47#define SoftFail MCDisassembler::SoftFail
48
49template <unsigned RegClassID, unsigned FirstReg, unsigned NumRegsInClass>
50static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, unsigned RegNo,
51 uint64_t Address,
52 const MCDisassembler *Decoder) {
53 if (RegNo > NumRegsInClass - 1)
54 return Fail;
55
57 getAArch64MCRegisterClass(RegClassID).getRegister(RegNo + FirstReg);
59 return Success;
60}
61
62static DecodeStatus
63DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
64 const MCDisassembler *Decoder) {
65 if (RegNo > 22)
66 return Fail;
67 if (RegNo & 1)
68 return Fail;
69
71 getAArch64MCRegisterClass(AArch64::GPR64x8ClassRegClassID)
72 .getRegister(RegNo >> 1);
74 return Success;
75}
76
77template <unsigned RegClassID, unsigned Multiple, unsigned Min, unsigned Max>
78static DecodeStatus
79DecodeMulMinMaxRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
80 const MCDisassembler *Decoder) {
81 unsigned Reg = (RegNo * Multiple) + Min;
82 if (Reg < Min || Reg > Max || (Reg % Multiple))
83 return Fail;
84 MCRegister Register = getAArch64MCRegisterClass(RegClassID).getRegister(Reg);
86 return Success;
87}
88
89template <unsigned Min, unsigned Max>
90static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
91 uint64_t Address,
92 const void *Decoder) {
93 unsigned Reg = (RegNo * 2) + Min;
94 if (Reg < Min || Reg > Max || (Reg & 1))
95 return Fail;
96
98 getAArch64MCRegisterClass(AArch64::ZPR2RegClassID).getRegister(Reg);
100 return Success;
101}
102
103static DecodeStatus DecodeZK(MCInst &Inst, unsigned RegNo, uint64_t Address,
104 const MCDisassembler *Decoder) {
105 if (RegNo > 7)
106 return Fail;
107
109 getAArch64MCRegisterClass(AArch64::ZPR_KRegClassID).getRegister(RegNo);
111 return Success;
112}
113
115 uint64_t Address,
116 const void *Decoder) {
117 if (RegNo * 4 > 28)
118 return Fail;
120 getAArch64MCRegisterClass(AArch64::ZPR4RegClassID).getRegister(RegNo * 4);
122 return Success;
123}
124
125static DecodeStatus
127 uint64_t Address,
128 const MCDisassembler *Decoder) {
129 if (RegMask > 0xFF)
130 return Fail;
131 Inst.addOperand(MCOperand::createImm(RegMask));
132 return Success;
133}
134
136 const MCDisassembler *Decoder) {
137 Inst.addOperand(MCOperand::createReg(AArch64::ZT0));
138 return Success;
139}
140
142 const MCDisassembler *Decoder) {
143 Inst.addOperand(MCOperand::createReg(AArch64::ZA));
144 return Success;
145}
146
148 const MCDisassembler *Decoder) {
149 Inst.addOperand(MCOperand::createReg(AArch64::ZAB0));
150 return Success;
151}
152
153static DecodeStatus DecodeMPR16RegisterClass(MCInst &Inst, unsigned RegNo,
154 uint64_t Address,
155 const MCDisassembler *Decoder) {
157 getAArch64MCRegisterClass(AArch64::MPR16RegClassID).getRegister(RegNo);
159 return Success;
160}
161
162static DecodeStatus DecodeMPR32RegisterClass(MCInst &Inst, unsigned RegNo,
163 uint64_t Address,
164 const MCDisassembler *Decoder) {
166 getAArch64MCRegisterClass(AArch64::MPR32RegClassID).getRegister(RegNo);
168 return Success;
169}
170
171static DecodeStatus DecodeMPR64RegisterClass(MCInst &Inst, unsigned RegNo,
172 uint64_t Address,
173 const MCDisassembler *Decoder) {
175 getAArch64MCRegisterClass(AArch64::MPR64RegClassID).getRegister(RegNo);
177 return Success;
178}
179
180static DecodeStatus DecodeMPR128RegisterClass(MCInst &Inst, unsigned RegNo,
181 uint64_t Address,
182 const MCDisassembler *Decoder) {
184 getAArch64MCRegisterClass(AArch64::MPR128RegClassID).getRegister(RegNo);
186 return Success;
187}
188
190 uint64_t Address,
191 const void *Decoder) {
192 if ((RegNo * 2) > 14)
193 return Fail;
195 getAArch64MCRegisterClass(AArch64::PPR2RegClassID).getRegister(RegNo * 2);
197 return Success;
198}
199
201 uint64_t Addr,
202 const MCDisassembler *Decoder) {
203 // scale{5} is asserted as 1 in tblgen.
204 Imm |= 0x20;
205 Inst.addOperand(MCOperand::createImm(64 - Imm));
206 return Success;
207}
208
210 uint64_t Addr,
211 const MCDisassembler *Decoder) {
212 Inst.addOperand(MCOperand::createImm(64 - Imm));
213 return Success;
214}
215
216static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm,
217 uint64_t Addr,
218 const MCDisassembler *Decoder) {
219 // Immediate is encoded as the top 16-bits of an unsigned 18-bit negative
220 // PC-relative offset.
221 uint64_t ImmVal = Imm;
222 if (ImmVal > (1 << 16))
223 return Fail;
224 ImmVal = -ImmVal;
225 if (!Decoder->tryAddingSymbolicOperand(Inst, (ImmVal << 2), Addr,
226 /*IsBranch=*/false, 0, 0, 4))
227 Inst.addOperand(MCOperand::createImm(ImmVal));
228 return Success;
229}
230
231static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
232 uint64_t Addr,
233 const MCDisassembler *Decoder) {
234 int64_t ImmVal = SignExtend64<19>(Imm);
235
236 if (!Decoder->tryAddingSymbolicOperand(
237 Inst, ImmVal * 4, Addr, Inst.getOpcode() != AArch64::LDRXl, 0, 0, 4))
238 Inst.addOperand(MCOperand::createImm(ImmVal));
239 return Success;
240}
241
242static DecodeStatus DecodePCRelLabel9(MCInst &Inst, unsigned Imm, uint64_t Addr,
243 const MCDisassembler *Decoder) {
244 int64_t ImmVal = SignExtend64<9>(Imm);
245
246 if (!Decoder->tryAddingSymbolicOperand(Inst, (ImmVal * 4), Addr,
247 /*IsBranch=*/true, 0, 0, 4))
248 Inst.addOperand(MCOperand::createImm(ImmVal));
249 return Success;
250}
251
252static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
253 uint64_t Address,
254 const MCDisassembler *Decoder) {
255 Inst.addOperand(MCOperand::createImm((Imm >> 1) & 1));
256 Inst.addOperand(MCOperand::createImm(Imm & 1));
257 return Success;
258}
259
260static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm,
261 uint64_t Address,
262 const MCDisassembler *Decoder) {
264
265 // Every system register in the encoding space is valid with the syntax
266 // S<op0>_<op1>_<Cn>_<Cm>_<op2>, so decoding system registers always succeeds.
267 return Success;
268}
269
270static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm,
271 uint64_t Address,
272 const MCDisassembler *Decoder) {
274
275 return Success;
276}
277
279 uint64_t Address,
280 const MCDisassembler *Decoder) {
281 // This decoder exists to add the dummy Lane operand to the MCInst, which must
282 // be 1 in assembly but has no other real manifestation.
283 unsigned Rd = fieldFromInstruction(Insn, 0, 5);
284 unsigned Rn = fieldFromInstruction(Insn, 5, 5);
285 unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
286
287 if (IsToVec) {
289 Inst, Rd, Address, Decoder);
291 Inst, Rn, Address, Decoder);
292 } else {
294 Inst, Rd, Address, Decoder);
296 Inst, Rn, Address, Decoder);
297 }
298
299 // Add the lane
301
302 return Success;
303}
304
305static DecodeStatus DecodeVecShiftRImm(MCInst &Inst, unsigned Imm,
306 unsigned Add) {
308 return Success;
309}
310
311static DecodeStatus DecodeVecShiftLImm(MCInst &Inst, unsigned Imm,
312 unsigned Add) {
313 Inst.addOperand(MCOperand::createImm((Imm + Add) & (Add - 1)));
314 return Success;
315}
316
317static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm,
318 uint64_t Addr,
319 const MCDisassembler *Decoder) {
320 return DecodeVecShiftRImm(Inst, Imm, 64);
321}
322
324 uint64_t Addr,
325 const MCDisassembler *Decoder) {
326 return DecodeVecShiftRImm(Inst, Imm | 0x20, 64);
327}
328
329static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm,
330 uint64_t Addr,
331 const MCDisassembler *Decoder) {
332 return DecodeVecShiftRImm(Inst, Imm, 32);
333}
334
336 uint64_t Addr,
337 const MCDisassembler *Decoder) {
338 return DecodeVecShiftRImm(Inst, Imm | 0x10, 32);
339}
340
341static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm,
342 uint64_t Addr,
343 const MCDisassembler *Decoder) {
344 return DecodeVecShiftRImm(Inst, Imm, 16);
345}
346
348 uint64_t Addr,
349 const MCDisassembler *Decoder) {
350 return DecodeVecShiftRImm(Inst, Imm | 0x8, 16);
351}
352
353static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm,
354 uint64_t Addr,
355 const MCDisassembler *Decoder) {
356 return DecodeVecShiftRImm(Inst, Imm, 8);
357}
358
359static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm,
360 uint64_t Addr,
361 const MCDisassembler *Decoder) {
362 return DecodeVecShiftLImm(Inst, Imm, 64);
363}
364
365static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm,
366 uint64_t Addr,
367 const MCDisassembler *Decoder) {
368 return DecodeVecShiftLImm(Inst, Imm, 32);
369}
370
371static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm,
372 uint64_t Addr,
373 const MCDisassembler *Decoder) {
374 return DecodeVecShiftLImm(Inst, Imm, 16);
375}
376
377static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm,
378 uint64_t Addr,
379 const MCDisassembler *Decoder) {
380 return DecodeVecShiftLImm(Inst, Imm, 8);
381}
382
383static DecodeStatus
385 const MCDisassembler *Decoder) {
386 unsigned Rd = fieldFromInstruction(insn, 0, 5);
387 unsigned Rn = fieldFromInstruction(insn, 5, 5);
388 unsigned Rm = fieldFromInstruction(insn, 16, 5);
389 unsigned shiftHi = fieldFromInstruction(insn, 22, 2);
390 unsigned shiftLo = fieldFromInstruction(insn, 10, 6);
391 unsigned shift = (shiftHi << 6) | shiftLo;
392 switch (Inst.getOpcode()) {
393 default:
394 return Fail;
395 case AArch64::ADDWrs:
396 case AArch64::ADDSWrs:
397 case AArch64::SUBWrs:
398 case AArch64::SUBSWrs:
399 // if shift == '11' then ReservedValue()
400 if (shiftHi == 0x3)
401 return Fail;
402 [[fallthrough]];
403 case AArch64::ANDWrs:
404 case AArch64::ANDSWrs:
405 case AArch64::BICWrs:
406 case AArch64::BICSWrs:
407 case AArch64::ORRWrs:
408 case AArch64::ORNWrs:
409 case AArch64::EORWrs:
410 case AArch64::EONWrs: {
411 // if sf == '0' and imm6<5> == '1' then ReservedValue()
412 if (shiftLo >> 5 == 1)
413 return Fail;
415 Decoder);
417 Decoder);
419 Decoder);
420 break;
421 }
422 case AArch64::ADDXrs:
423 case AArch64::ADDSXrs:
424 case AArch64::SUBXrs:
425 case AArch64::SUBSXrs:
426 // if shift == '11' then ReservedValue()
427 if (shiftHi == 0x3)
428 return Fail;
429 [[fallthrough]];
430 case AArch64::ANDXrs:
431 case AArch64::ANDSXrs:
432 case AArch64::BICXrs:
433 case AArch64::BICSXrs:
434 case AArch64::ORRXrs:
435 case AArch64::ORNXrs:
436 case AArch64::EORXrs:
437 case AArch64::EONXrs:
439 Decoder);
441 Decoder);
443 Decoder);
444 break;
445 }
446
447 Inst.addOperand(MCOperand::createImm(shift));
448 return Success;
449}
450
452 uint64_t Addr,
453 const MCDisassembler *Decoder) {
454 unsigned Rd = fieldFromInstruction(insn, 0, 5);
455 unsigned imm = fieldFromInstruction(insn, 5, 16);
456 unsigned shift = fieldFromInstruction(insn, 21, 2);
457 shift <<= 4;
458 switch (Inst.getOpcode()) {
459 default:
460 return Fail;
461 case AArch64::MOVZWi:
462 case AArch64::MOVNWi:
463 case AArch64::MOVKWi:
464 if (shift & (1U << 5))
465 return Fail;
467 Decoder);
468 break;
469 case AArch64::MOVZXi:
470 case AArch64::MOVNXi:
471 case AArch64::MOVKXi:
473 Decoder);
474 break;
475 }
476
477 if (Inst.getOpcode() == AArch64::MOVKWi ||
478 Inst.getOpcode() == AArch64::MOVKXi)
479 Inst.addOperand(Inst.getOperand(0));
480
481 if (!Decoder->tryAddingSymbolicOperand(Inst, imm, Addr, /*IsBranch*/ false, 0,
482 0, 4))
484
485 Inst.addOperand(MCOperand::createImm(shift));
486 return Success;
487}
488
489static DecodeStatus
491 const MCDisassembler *Decoder) {
492 unsigned Rt = fieldFromInstruction(insn, 0, 5);
493 unsigned Rn = fieldFromInstruction(insn, 5, 5);
494 unsigned offset = fieldFromInstruction(insn, 10, 12);
495
496 switch (Inst.getOpcode()) {
497 default:
498 return Fail;
499 case AArch64::PRFMui:
500 // Rt is an immediate in prefetch.
502 break;
503 case AArch64::STRBBui:
504 case AArch64::LDRBBui:
505 case AArch64::LDRSBWui:
506 case AArch64::STRHHui:
507 case AArch64::LDRHHui:
508 case AArch64::LDRSHWui:
509 case AArch64::STRWui:
510 case AArch64::LDRWui:
512 Decoder);
513 break;
514 case AArch64::LDRSBXui:
515 case AArch64::LDRSHXui:
516 case AArch64::LDRSWui:
517 case AArch64::STRXui:
518 case AArch64::LDRXui:
520 Decoder);
521 break;
522 case AArch64::LDRQui:
523 case AArch64::STRQui:
525 Decoder);
526 break;
527 case AArch64::LDRDui:
528 case AArch64::STRDui:
530 Decoder);
531 break;
532 case AArch64::LDRSui:
533 case AArch64::STRSui:
535 Decoder);
536 break;
537 case AArch64::LDRHui:
538 case AArch64::STRHui:
540 Decoder);
541 break;
542 case AArch64::LDRBui:
543 case AArch64::STRBui:
545 Decoder);
546 break;
547 }
548
550 Decoder);
551 if (!Decoder->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 0, 4))
552 Inst.addOperand(MCOperand::createImm(offset));
553 return Success;
554}
555
557 uint64_t Addr,
558 const MCDisassembler *Decoder) {
559 unsigned Rt = fieldFromInstruction(insn, 0, 5);
560 unsigned Rn = fieldFromInstruction(insn, 5, 5);
561 int64_t offset = SignExtend64<9>(fieldFromInstruction(insn, 12, 9));
562
563 // First operand is always the writeback to the address register, if needed.
564 switch (Inst.getOpcode()) {
565 default:
566 break;
567 case AArch64::LDRSBWpre:
568 case AArch64::LDRSHWpre:
569 case AArch64::STRBBpre:
570 case AArch64::LDRBBpre:
571 case AArch64::STRHHpre:
572 case AArch64::LDRHHpre:
573 case AArch64::STRWpre:
574 case AArch64::LDRWpre:
575 case AArch64::LDRSBWpost:
576 case AArch64::LDRSHWpost:
577 case AArch64::STRBBpost:
578 case AArch64::LDRBBpost:
579 case AArch64::STRHHpost:
580 case AArch64::LDRHHpost:
581 case AArch64::STRWpost:
582 case AArch64::LDRWpost:
583 case AArch64::LDRSBXpre:
584 case AArch64::LDRSHXpre:
585 case AArch64::STRXpre:
586 case AArch64::LDRSWpre:
587 case AArch64::LDRXpre:
588 case AArch64::LDRSBXpost:
589 case AArch64::LDRSHXpost:
590 case AArch64::STRXpost:
591 case AArch64::LDRSWpost:
592 case AArch64::LDRXpost:
593 case AArch64::LDRQpre:
594 case AArch64::STRQpre:
595 case AArch64::LDRQpost:
596 case AArch64::STRQpost:
597 case AArch64::LDRDpre:
598 case AArch64::STRDpre:
599 case AArch64::LDRDpost:
600 case AArch64::STRDpost:
601 case AArch64::LDRSpre:
602 case AArch64::STRSpre:
603 case AArch64::LDRSpost:
604 case AArch64::STRSpost:
605 case AArch64::LDRHpre:
606 case AArch64::STRHpre:
607 case AArch64::LDRHpost:
608 case AArch64::STRHpost:
609 case AArch64::LDRBpre:
610 case AArch64::STRBpre:
611 case AArch64::LDRBpost:
612 case AArch64::STRBpost:
614 Decoder);
615 break;
616 }
617
618 switch (Inst.getOpcode()) {
619 default:
620 return Fail;
621 case AArch64::PRFUMi:
622 // Rt is an immediate in prefetch.
624 break;
625 case AArch64::STURBBi:
626 case AArch64::LDURBBi:
627 case AArch64::LDURSBWi:
628 case AArch64::STURHHi:
629 case AArch64::LDURHHi:
630 case AArch64::LDURSHWi:
631 case AArch64::STURWi:
632 case AArch64::LDURWi:
633 case AArch64::LDTRSBWi:
634 case AArch64::LDTRSHWi:
635 case AArch64::STTRWi:
636 case AArch64::LDTRWi:
637 case AArch64::STTRHi:
638 case AArch64::LDTRHi:
639 case AArch64::LDTRBi:
640 case AArch64::STTRBi:
641 case AArch64::LDRSBWpre:
642 case AArch64::LDRSHWpre:
643 case AArch64::STRBBpre:
644 case AArch64::LDRBBpre:
645 case AArch64::STRHHpre:
646 case AArch64::LDRHHpre:
647 case AArch64::STRWpre:
648 case AArch64::LDRWpre:
649 case AArch64::LDRSBWpost:
650 case AArch64::LDRSHWpost:
651 case AArch64::STRBBpost:
652 case AArch64::LDRBBpost:
653 case AArch64::STRHHpost:
654 case AArch64::LDRHHpost:
655 case AArch64::STRWpost:
656 case AArch64::LDRWpost:
657 case AArch64::STLURBi:
658 case AArch64::STLURHi:
659 case AArch64::STLURWi:
660 case AArch64::LDAPURBi:
661 case AArch64::LDAPURSBWi:
662 case AArch64::LDAPURHi:
663 case AArch64::LDAPURSHWi:
664 case AArch64::LDAPURi:
666 Decoder);
667 break;
668 case AArch64::LDURSBXi:
669 case AArch64::LDURSHXi:
670 case AArch64::LDURSWi:
671 case AArch64::STURXi:
672 case AArch64::LDURXi:
673 case AArch64::LDTRSBXi:
674 case AArch64::LDTRSHXi:
675 case AArch64::LDTRSWi:
676 case AArch64::STTRXi:
677 case AArch64::LDTRXi:
678 case AArch64::LDRSBXpre:
679 case AArch64::LDRSHXpre:
680 case AArch64::STRXpre:
681 case AArch64::LDRSWpre:
682 case AArch64::LDRXpre:
683 case AArch64::LDRSBXpost:
684 case AArch64::LDRSHXpost:
685 case AArch64::STRXpost:
686 case AArch64::LDRSWpost:
687 case AArch64::LDRXpost:
688 case AArch64::LDAPURSWi:
689 case AArch64::LDAPURSHXi:
690 case AArch64::LDAPURSBXi:
691 case AArch64::STLURXi:
692 case AArch64::LDAPURXi:
694 Decoder);
695 break;
696 case AArch64::LDURQi:
697 case AArch64::STURQi:
698 case AArch64::LDRQpre:
699 case AArch64::STRQpre:
700 case AArch64::LDRQpost:
701 case AArch64::STRQpost:
703 Decoder);
704 break;
705 case AArch64::LDURDi:
706 case AArch64::STURDi:
707 case AArch64::LDRDpre:
708 case AArch64::STRDpre:
709 case AArch64::LDRDpost:
710 case AArch64::STRDpost:
712 Decoder);
713 break;
714 case AArch64::LDURSi:
715 case AArch64::STURSi:
716 case AArch64::LDRSpre:
717 case AArch64::STRSpre:
718 case AArch64::LDRSpost:
719 case AArch64::STRSpost:
721 Decoder);
722 break;
723 case AArch64::LDURHi:
724 case AArch64::STURHi:
725 case AArch64::LDRHpre:
726 case AArch64::STRHpre:
727 case AArch64::LDRHpost:
728 case AArch64::STRHpost:
730 Decoder);
731 break;
732 case AArch64::LDURBi:
733 case AArch64::STURBi:
734 case AArch64::LDRBpre:
735 case AArch64::STRBpre:
736 case AArch64::LDRBpost:
737 case AArch64::STRBpost:
739 Decoder);
740 break;
741 }
742
744 Decoder);
745 Inst.addOperand(MCOperand::createImm(offset));
746
747 bool IsLoad = fieldFromInstruction(insn, 22, 1);
748 bool IsIndexed = fieldFromInstruction(insn, 10, 2) != 0;
749 bool IsFP = fieldFromInstruction(insn, 26, 1);
750
751 // Cannot write back to a transfer register (but xzr != sp).
752 if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn)
753 return SoftFail;
754
755 return Success;
756}
757
758static DecodeStatus
760 const MCDisassembler *Decoder) {
761 unsigned Rt = fieldFromInstruction(insn, 0, 5);
762 unsigned Rn = fieldFromInstruction(insn, 5, 5);
763 unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
764 unsigned Rs = fieldFromInstruction(insn, 16, 5);
765
766 unsigned Opcode = Inst.getOpcode();
767 switch (Opcode) {
768 default:
769 return Fail;
770 case AArch64::STLXRW:
771 case AArch64::STLXRB:
772 case AArch64::STLXRH:
773 case AArch64::STXRW:
774 case AArch64::STXRB:
775 case AArch64::STXRH:
777 Decoder);
778 [[fallthrough]];
779 case AArch64::LDARW:
780 case AArch64::LDARB:
781 case AArch64::LDARH:
782 case AArch64::LDAXRW:
783 case AArch64::LDAXRB:
784 case AArch64::LDAXRH:
785 case AArch64::LDXRW:
786 case AArch64::LDXRB:
787 case AArch64::LDXRH:
788 case AArch64::STLRW:
789 case AArch64::STLRB:
790 case AArch64::STLRH:
791 case AArch64::STLLRW:
792 case AArch64::STLLRB:
793 case AArch64::STLLRH:
794 case AArch64::LDLARW:
795 case AArch64::LDLARB:
796 case AArch64::LDLARH:
798 Decoder);
799 break;
800 case AArch64::STLXRX:
801 case AArch64::STXRX:
803 Decoder);
804 [[fallthrough]];
805 case AArch64::LDARX:
806 case AArch64::LDAXRX:
807 case AArch64::LDXRX:
808 case AArch64::STLRX:
809 case AArch64::LDLARX:
810 case AArch64::STLLRX:
812 Decoder);
813 break;
814 case AArch64::STLXPW:
815 case AArch64::STXPW:
817 Decoder);
818 [[fallthrough]];
819 case AArch64::LDAXPW:
820 case AArch64::LDXPW:
822 Decoder);
824 Decoder);
825 break;
826 case AArch64::STLXPX:
827 case AArch64::STXPX:
829 Decoder);
830 [[fallthrough]];
831 case AArch64::LDAXPX:
832 case AArch64::LDXPX:
834 Decoder);
836 Decoder);
837 break;
838 }
839
841 Decoder);
842
843 // You shouldn't load to the same register twice in an instruction...
844 if ((Opcode == AArch64::LDAXPW || Opcode == AArch64::LDXPW ||
845 Opcode == AArch64::LDAXPX || Opcode == AArch64::LDXPX) &&
846 Rt == Rt2)
847 return SoftFail;
848
849 return Success;
850}
851
853 uint64_t Addr,
854 const MCDisassembler *Decoder) {
855 unsigned Rt = fieldFromInstruction(insn, 0, 5);
856 unsigned Rn = fieldFromInstruction(insn, 5, 5);
857 unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
858 int64_t offset = SignExtend64<7>(fieldFromInstruction(insn, 15, 7));
859 bool IsLoad = fieldFromInstruction(insn, 22, 1);
860
861 unsigned Opcode = Inst.getOpcode();
862 bool NeedsDisjointWritebackTransfer = false;
863
864 // First operand is always writeback of base register.
865 switch (Opcode) {
866 default:
867 break;
868 case AArch64::LDPXpost:
869 case AArch64::STPXpost:
870 case AArch64::LDPSWpost:
871 case AArch64::LDPXpre:
872 case AArch64::STPXpre:
873 case AArch64::LDPSWpre:
874 case AArch64::LDPWpost:
875 case AArch64::STPWpost:
876 case AArch64::LDPWpre:
877 case AArch64::STPWpre:
878 case AArch64::LDPQpost:
879 case AArch64::STPQpost:
880 case AArch64::LDPQpre:
881 case AArch64::STPQpre:
882 case AArch64::LDPDpost:
883 case AArch64::STPDpost:
884 case AArch64::LDPDpre:
885 case AArch64::STPDpre:
886 case AArch64::LDPSpost:
887 case AArch64::STPSpost:
888 case AArch64::LDPSpre:
889 case AArch64::STPSpre:
890 case AArch64::STGPpre:
891 case AArch64::STGPpost:
892 case AArch64::LDTPpre:
893 case AArch64::LDTPpost:
894 case AArch64::LDTPQpost:
895 case AArch64::LDTPQpre:
896 case AArch64::STTPpost:
897 case AArch64::STTPpre:
898 case AArch64::STTPQpost:
899 case AArch64::STTPQpre:
901 Decoder);
902 break;
903 }
904
905 switch (Opcode) {
906 default:
907 return Fail;
908 case AArch64::LDPXpost:
909 case AArch64::STPXpost:
910 case AArch64::LDPSWpost:
911 case AArch64::LDPXpre:
912 case AArch64::STPXpre:
913 case AArch64::LDPSWpre:
914 case AArch64::STGPpre:
915 case AArch64::STGPpost:
916 case AArch64::LDTPpost:
917 case AArch64::LDTPpre:
918 case AArch64::STTPpost:
919 case AArch64::STTPpre:
920 NeedsDisjointWritebackTransfer = true;
921 [[fallthrough]];
922 case AArch64::LDNPXi:
923 case AArch64::STNPXi:
924 case AArch64::LDPXi:
925 case AArch64::STPXi:
926 case AArch64::LDPSWi:
927 case AArch64::STGPi:
928 case AArch64::LDTPi:
929 case AArch64::STTPi:
930 case AArch64::STTNPXi:
931 case AArch64::LDTNPXi:
933 Decoder);
935 Decoder);
936 break;
937 case AArch64::LDPWpost:
938 case AArch64::STPWpost:
939 case AArch64::LDPWpre:
940 case AArch64::STPWpre:
941 NeedsDisjointWritebackTransfer = true;
942 [[fallthrough]];
943 case AArch64::LDNPWi:
944 case AArch64::STNPWi:
945 case AArch64::LDPWi:
946 case AArch64::STPWi:
948 Decoder);
950 Decoder);
951 break;
952 case AArch64::LDNPQi:
953 case AArch64::STNPQi:
954 case AArch64::LDPQpost:
955 case AArch64::STPQpost:
956 case AArch64::LDPQi:
957 case AArch64::STPQi:
958 case AArch64::LDPQpre:
959 case AArch64::STPQpre:
960 case AArch64::LDTPQi:
961 case AArch64::LDTPQpost:
962 case AArch64::LDTPQpre:
963 case AArch64::LDTNPQi:
964 case AArch64::STTPQi:
965 case AArch64::STTPQpost:
966 case AArch64::STTPQpre:
967 case AArch64::STTNPQi:
969 Decoder);
971 Decoder);
972 break;
973 case AArch64::LDNPDi:
974 case AArch64::STNPDi:
975 case AArch64::LDPDpost:
976 case AArch64::STPDpost:
977 case AArch64::LDPDi:
978 case AArch64::STPDi:
979 case AArch64::LDPDpre:
980 case AArch64::STPDpre:
982 Decoder);
984 Decoder);
985 break;
986 case AArch64::LDNPSi:
987 case AArch64::STNPSi:
988 case AArch64::LDPSpost:
989 case AArch64::STPSpost:
990 case AArch64::LDPSi:
991 case AArch64::STPSi:
992 case AArch64::LDPSpre:
993 case AArch64::STPSpre:
995 Decoder);
997 Decoder);
998 break;
999 }
1000
1002 Decoder);
1003 Inst.addOperand(MCOperand::createImm(offset));
1004
1005 // You shouldn't load to the same register twice in an instruction...
1006 if (IsLoad && Rt == Rt2)
1007 return SoftFail;
1008
1009 // ... or do any operation that writes-back to a transfer register. But note
1010 // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.
1011 if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn))
1012 return SoftFail;
1013
1014 return Success;
1015}
1016
1018 uint64_t Addr,
1019 const MCDisassembler *Decoder) {
1020 unsigned Rt = fieldFromInstruction(insn, 0, 5);
1021 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1022 uint64_t offset = fieldFromInstruction(insn, 22, 1) << 9 |
1023 fieldFromInstruction(insn, 12, 9);
1024 unsigned writeback = fieldFromInstruction(insn, 11, 1);
1025
1026 switch (Inst.getOpcode()) {
1027 default:
1028 return Fail;
1029 case AArch64::LDRAAwriteback:
1030 case AArch64::LDRABwriteback:
1032 Inst, Rn /* writeback register */, Addr, Decoder);
1033 break;
1034 case AArch64::LDRAAindexed:
1035 case AArch64::LDRABindexed:
1036 break;
1037 }
1038
1040 Decoder);
1042 Decoder);
1043 DecodeSImm<10>(Inst, offset, Addr, Decoder);
1044
1045 if (writeback && Rt == Rn && Rn != 31) {
1046 return SoftFail;
1047 }
1048
1049 return Success;
1050}
1051
1053 uint64_t Addr,
1054 const MCDisassembler *Decoder) {
1055 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1056 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1057 unsigned Rm = fieldFromInstruction(insn, 16, 5);
1058 unsigned extend = fieldFromInstruction(insn, 10, 6);
1059
1060 unsigned shift = extend & 0x7;
1061 if (shift > 4)
1062 return Fail;
1063
1064 switch (Inst.getOpcode()) {
1065 default:
1066 return Fail;
1067 case AArch64::ADDWrx:
1068 case AArch64::SUBWrx:
1070 Decoder);
1072 Decoder);
1074 Decoder);
1075 break;
1076 case AArch64::ADDSWrx:
1077 case AArch64::SUBSWrx:
1079 Decoder);
1081 Decoder);
1083 Decoder);
1084 break;
1085 case AArch64::ADDXrx:
1086 case AArch64::SUBXrx:
1088 Decoder);
1090 Decoder);
1092 Decoder);
1093 break;
1094 case AArch64::ADDSXrx:
1095 case AArch64::SUBSXrx:
1097 Decoder);
1099 Decoder);
1101 Decoder);
1102 break;
1103 case AArch64::ADDXrx64:
1104 case AArch64::SUBXrx64:
1106 Decoder);
1108 Decoder);
1110 Decoder);
1111 break;
1112 case AArch64::SUBSXrx64:
1113 case AArch64::ADDSXrx64:
1115 Decoder);
1117 Decoder);
1119 Decoder);
1120 break;
1121 }
1122
1123 Inst.addOperand(MCOperand::createImm(extend));
1124 return Success;
1125}
1126
1128 uint64_t Addr,
1129 const MCDisassembler *Decoder) {
1130 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1131 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1132 unsigned Datasize = fieldFromInstruction(insn, 31, 1);
1133 unsigned imm;
1134
1135 if (Datasize) {
1136 if (Inst.getOpcode() == AArch64::ANDSXri)
1138 Decoder);
1139 else
1141 Inst, Rd, Addr, Decoder);
1143 Decoder);
1144 imm = fieldFromInstruction(insn, 10, 13);
1146 return Fail;
1147 } else {
1148 if (Inst.getOpcode() == AArch64::ANDSWri)
1150 Decoder);
1151 else
1153 Inst, Rd, Addr, Decoder);
1155 Decoder);
1156 imm = fieldFromInstruction(insn, 10, 12);
1158 return Fail;
1159 }
1161 return Success;
1162}
1163
1165 uint64_t Addr,
1166 const MCDisassembler *Decoder) {
1167 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1168 unsigned cmode = fieldFromInstruction(insn, 12, 4);
1169 unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
1170 imm |= fieldFromInstruction(insn, 5, 5);
1171
1172 if (Inst.getOpcode() == AArch64::MOVID)
1174 Decoder);
1175 else
1177 Decoder);
1178
1180
1181 switch (Inst.getOpcode()) {
1182 default:
1183 break;
1184 case AArch64::MOVIv4i16:
1185 case AArch64::MOVIv8i16:
1186 case AArch64::MVNIv4i16:
1187 case AArch64::MVNIv8i16:
1188 case AArch64::MOVIv2i32:
1189 case AArch64::MOVIv4i32:
1190 case AArch64::MVNIv2i32:
1191 case AArch64::MVNIv4i32:
1192 Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
1193 break;
1194 case AArch64::MOVIv2s_msl:
1195 case AArch64::MOVIv4s_msl:
1196 case AArch64::MVNIv2s_msl:
1197 case AArch64::MVNIv4s_msl:
1198 Inst.addOperand(MCOperand::createImm((cmode & 1) ? 0x110 : 0x108));
1199 break;
1200 }
1201
1202 return Success;
1203}
1204
1206 uint64_t Addr,
1207 const MCDisassembler *Decoder) {
1208 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1209 unsigned cmode = fieldFromInstruction(insn, 12, 4);
1210 unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
1211 imm |= fieldFromInstruction(insn, 5, 5);
1212
1213 // Tied operands added twice.
1215 Decoder);
1217 Decoder);
1218
1220 Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
1221
1222 return Success;
1223}
1224
1226 uint64_t Addr,
1227 const MCDisassembler *Decoder) {
1228 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1229 int64_t imm = SignExtend64<21>((fieldFromInstruction(insn, 5, 19) << 2) |
1230 fieldFromInstruction(insn, 29, 2));
1231
1233 Decoder);
1234 if (!Decoder->tryAddingSymbolicOperand(Inst, imm, Addr, Fail, 0, 0, 4))
1236
1237 return Success;
1238}
1239
1241 uint64_t Addr,
1242 const MCDisassembler *Decoder) {
1243 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1244 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1245 unsigned Imm = fieldFromInstruction(insn, 10, 14);
1246 unsigned S = fieldFromInstruction(insn, 29, 1);
1247 unsigned Datasize = fieldFromInstruction(insn, 31, 1);
1248
1249 unsigned ShifterVal = (Imm >> 12) & 3;
1250 unsigned ImmVal = Imm & 0xFFF;
1251
1252 if (ShifterVal != 0 && ShifterVal != 1)
1253 return Fail;
1254
1255 if (Datasize) {
1256 if (Rd == 31 && !S)
1258 Inst, Rd, Addr, Decoder);
1259 else
1261 Decoder);
1263 Decoder);
1264 } else {
1265 if (Rd == 31 && !S)
1267 Inst, Rd, Addr, Decoder);
1268 else
1270 Decoder);
1272 Decoder);
1273 }
1274
1275 if (!Decoder->tryAddingSymbolicOperand(Inst, Imm, Addr, Fail, 0, 0, 4))
1276 Inst.addOperand(MCOperand::createImm(ImmVal));
1277 Inst.addOperand(MCOperand::createImm(12 * ShifterVal));
1278 return Success;
1279}
1280
1282 uint64_t Addr,
1283 const MCDisassembler *Decoder) {
1284 int64_t imm = SignExtend64<26>(fieldFromInstruction(insn, 0, 26));
1285
1286 if (!Decoder->tryAddingSymbolicOperand(Inst, imm * 4, Addr, true, 0, 0, 4))
1288
1289 return Success;
1290}
1291
1292static bool isInvalidPState(uint64_t Op1, uint64_t Op2) {
1293 return Op1 == 0b000 && (Op2 == 0b000 || // CFINV
1294 Op2 == 0b001 || // XAFlag
1295 Op2 == 0b010); // AXFlag
1296}
1297
1298static DecodeStatus
1300 const MCDisassembler *Decoder) {
1301 uint64_t op1 = fieldFromInstruction(insn, 16, 3);
1302 uint64_t op2 = fieldFromInstruction(insn, 5, 3);
1303 uint64_t imm = fieldFromInstruction(insn, 8, 4);
1304 uint64_t pstate_field = (op1 << 3) | op2;
1305
1306 if (isInvalidPState(op1, op2))
1307 return Fail;
1308
1309 Inst.addOperand(MCOperand::createImm(pstate_field));
1311
1312 auto PState = AArch64PState::lookupPStateImm0_15ByEncoding(pstate_field);
1313 if (PState &&
1314 PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits()))
1315 return Success;
1316 return Fail;
1317}
1318
1319static DecodeStatus
1321 const MCDisassembler *Decoder) {
1322 uint64_t op1 = fieldFromInstruction(insn, 16, 3);
1323 uint64_t op2 = fieldFromInstruction(insn, 5, 3);
1324 uint64_t crm_high = fieldFromInstruction(insn, 9, 3);
1325 uint64_t imm = fieldFromInstruction(insn, 8, 1);
1326 uint64_t pstate_field = (crm_high << 6) | (op1 << 3) | op2;
1327
1328 if (isInvalidPState(op1, op2))
1329 return Fail;
1330
1331 Inst.addOperand(MCOperand::createImm(pstate_field));
1333
1334 auto PState = AArch64PState::lookupPStateImm0_1ByEncoding(pstate_field);
1335 if (PState &&
1336 PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits()))
1337 return Success;
1338 return Fail;
1339}
1340
1342 uint64_t Addr,
1343 const MCDisassembler *Decoder) {
1344 uint64_t Rt = fieldFromInstruction(insn, 0, 5);
1345 uint64_t bit = fieldFromInstruction(insn, 31, 1) << 5;
1346 bit |= fieldFromInstruction(insn, 19, 5);
1347 int64_t dst = SignExtend64<14>(fieldFromInstruction(insn, 5, 14));
1348
1349 if (fieldFromInstruction(insn, 31, 1) == 0)
1351 Decoder);
1352 else
1354 Decoder);
1356 if (!Decoder->tryAddingSymbolicOperand(Inst, dst * 4, Addr, true, 0, 0, 4))
1358
1359 return Success;
1360}
1361
1362static DecodeStatus
1364 unsigned RegNo, uint64_t Addr,
1365 const MCDisassembler *Decoder) {
1366 // Register number must be even (see CASP instruction)
1367 if (RegNo & 0x1)
1368 return Fail;
1369
1370 MCRegister Reg = getAArch64MCRegisterClass(RegClassID).getRegister(RegNo / 2);
1372 return Success;
1373}
1374
1375static DecodeStatus
1377 const MCDisassembler *Decoder) {
1379 Inst, AArch64::WSeqPairsClassRegClassID, RegNo, Addr, Decoder);
1380}
1381
1382static DecodeStatus
1384 const MCDisassembler *Decoder) {
1386 Inst, AArch64::XSeqPairsClassRegClassID, RegNo, Addr, Decoder);
1387}
1388
1390 uint64_t Addr,
1391 const MCDisassembler *Decoder) {
1392 unsigned op1 = fieldFromInstruction(insn, 16, 3);
1393 unsigned CRn = fieldFromInstruction(insn, 12, 4);
1394 unsigned CRm = fieldFromInstruction(insn, 8, 4);
1395 unsigned op2 = fieldFromInstruction(insn, 5, 3);
1396 unsigned Rt = fieldFromInstruction(insn, 0, 5);
1397 if (Rt != 0b11111)
1398 return Fail;
1399
1405 Decoder);
1406
1407 return Success;
1408}
1409
1410static DecodeStatus
1412 const MCDisassembler *Decoder) {
1413 unsigned Zdn = fieldFromInstruction(insn, 0, 5);
1414 unsigned imm = fieldFromInstruction(insn, 5, 13);
1416 return Fail;
1417
1418 // The same (tied) operand is added twice to the instruction.
1420 Decoder);
1421 if (Inst.getOpcode() != AArch64::DUPM_ZI)
1423 Decoder);
1425 return Success;
1426}
1427
1428static DecodeStatus DecodeZeroImm(MCInst &Inst, const MCDisassembler *Decoder) {
1430 return Success;
1431}
1432
1433template <int Bits>
1435 const MCDisassembler *Decoder) {
1436 if (Imm & ~((1LL << Bits) - 1))
1437 return Fail;
1438
1439 // Imm is a signed immediate, so sign extend it.
1440 if (Imm & (1 << (Bits - 1)))
1441 Imm |= ~((1LL << Bits) - 1);
1442
1444 return Success;
1445}
1446
1447template <int Bits>
1449 const MCDisassembler *Decoder) {
1450 if (Imm & ~((1ULL << Bits) - 1))
1451 return Fail;
1452
1454 return Success;
1455}
1456
1457// Decode 8-bit signed/unsigned immediate for a given element width.
1458template <int ElementWidth>
1459static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm, uint64_t Addr,
1460 const MCDisassembler *Decoder) {
1461 unsigned Val = (uint8_t)Imm;
1462 unsigned Shift = (Imm & 0x100) ? 8 : 0;
1463 if (ElementWidth == 8 && Shift)
1464 return Fail;
1466 Inst.addOperand(MCOperand::createImm(Shift));
1467 return Success;
1468}
1469
1470static DecodeStatus DecodeHinteUImm16(MCInst &Inst, unsigned Imm, uint64_t Addr,
1471 const MCDisassembler *Decoder) {
1472 if (Imm > 65535 ||
1473 (Imm >= 12319 && Imm <= 16383 && ((Imm - 12319) % 32) == 0))
1474 return Fail;
1475
1477 return Success;
1478}
1479
1480// Decode uimm4 ranged from 1-16.
1481static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,
1482 uint64_t Addr,
1483 const MCDisassembler *Decoder) {
1484 Inst.addOperand(MCOperand::createImm(Imm + 1));
1485 return Success;
1486}
1487
1488static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,
1489 const MCDisassembler *Decoder) {
1490 if (AArch64SVCR::lookupSVCRByEncoding(Imm)) {
1492 return Success;
1493 }
1494 return Fail;
1495}
1496
1498 uint64_t Addr,
1499 const MCDisassembler *Decoder) {
1500 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1501 unsigned Rs = fieldFromInstruction(insn, 16, 5);
1502 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1503
1504 // None of the registers may alias: if they do, then the instruction is not
1505 // merely unpredictable but actually entirely unallocated.
1506 if (Rd == Rs || Rs == Rn || Rd == Rn)
1507 return MCDisassembler::Fail;
1508
1509 // All three register operands are written back, so they all appear
1510 // twice in the operand list, once as outputs and once as inputs.
1512 Inst, Rd, Addr, Decoder) ||
1514 Inst, Rs, Addr, Decoder) ||
1516 Inst, Rn, Addr, Decoder) ||
1518 Inst, Rd, Addr, Decoder) ||
1520 Inst, Rs, Addr, Decoder) ||
1522 Inst, Rn, Addr, Decoder))
1523 return MCDisassembler::Fail;
1524
1526}
1527
1529 uint64_t Addr,
1530 const MCDisassembler *Decoder) {
1531 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1532 unsigned Rm = fieldFromInstruction(insn, 16, 5);
1533 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1534
1535 // None of the registers may alias: if they do, then the instruction is not
1536 // merely unpredictable but actually entirely unallocated.
1537 if (Rd == Rm || Rm == Rn || Rd == Rn)
1538 return MCDisassembler::Fail;
1539
1540 // Rd and Rn (not Rm) register operands are written back, so they appear
1541 // twice in the operand list, once as outputs and once as inputs.
1543 Inst, Rd, Addr, Decoder) ||
1545 Inst, Rn, Addr, Decoder) ||
1547 Inst, Rd, Addr, Decoder) ||
1549 Inst, Rn, Addr, Decoder) ||
1551 Inst, Rm, Addr, Decoder))
1552 return MCDisassembler::Fail;
1553
1555}
1556
1558 uint64_t Addr,
1559 const MCDisassembler *Decoder) {
1560 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1561 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1562
1563 // None of the registers may alias: if they do, then the instruction is not
1564 // merely unpredictable but actually entirely unallocated.
1565 if (Rd == Rn)
1566 return MCDisassembler::Fail;
1567
1568 // Rd and Rn register operands are written back, so they appear
1569 // twice in the operand list, once as outputs and once as inputs.
1571 Inst, Rd, Addr, Decoder) ||
1573 Inst, Rn, Addr, Decoder) ||
1575 Inst, Rd, Addr, Decoder) ||
1577 Inst, Rn, Addr, Decoder))
1578 return MCDisassembler::Fail;
1579
1581}
1582
1584 uint64_t Addr,
1585 const MCDisassembler *Decoder) {
1586 // PRFM with Rt = '11xxx' should be decoded as RPRFM.
1587 // Fail to decode and defer to fallback decoder table to decode RPRFM.
1588 unsigned Mask = 0x18;
1589 uint64_t Rt = fieldFromInstruction(insn, 0, 5);
1590 if ((Rt & Mask) == Mask)
1591 return Fail;
1592
1593 uint64_t Rn = fieldFromInstruction(insn, 5, 5);
1594 uint64_t Shift = fieldFromInstruction(insn, 12, 1);
1595 uint64_t Extend = fieldFromInstruction(insn, 15, 1);
1596 uint64_t Rm = fieldFromInstruction(insn, 16, 5);
1597
1600 Decoder);
1601
1602 switch (Inst.getOpcode()) {
1603 default:
1604 return Fail;
1605 case AArch64::PRFMroW:
1607 Decoder);
1608 break;
1609 case AArch64::PRFMroX:
1611 Decoder);
1612 break;
1613 }
1614
1615 DecodeMemExtend(Inst, (Extend << 1) | Shift, Addr, Decoder);
1616
1617 return Success;
1618}
1619
1620static DecodeStatus
1622 const MCDisassembler *Decoder) {
1623 unsigned RvBits = fieldFromInstruction(Bits, 13, 2);
1624 unsigned RnBits = fieldFromInstruction(Bits, 5, 5);
1625 unsigned Imm4Bits = fieldFromInstruction(Bits, 0, 4);
1626
1627 DecodeMPRRegisterClass(Inst, Decoder);
1629 Inst, RvBits, Addr, Decoder);
1630 Inst.addOperand(MCOperand::createImm(Imm4Bits));
1632 Addr, Decoder);
1633 // Spill and fill instructions have a single immediate used for both
1634 // the vector select offset and optional memory offset. Replicate
1635 // the decoded immediate.
1636 Inst.addOperand(MCOperand::createImm(Imm4Bits));
1637 return Success;
1638}
1639
1640#include "AArch64GenDisassemblerTables.inc"
1641#include "AArch64GenInstrInfo.inc"
1642
1644 const MCSubtargetInfo &STI,
1645 MCContext &Ctx) {
1646
1647 return new AArch64Disassembler(STI, Ctx, T.createMCInstrInfo());
1648}
1649
1651 ArrayRef<uint8_t> Bytes,
1653 raw_ostream &CS) const {
1654 CommentStream = &CS;
1655
1656 Size = 0;
1657 // We want to read exactly 4 bytes of data.
1658 if (Bytes.size() < 4)
1659 return Fail;
1660 Size = 4;
1661
1662 // Encoded as a small-endian 32-bit word in the stream.
1663 uint32_t Insn =
1664 (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
1665
1666 const uint8_t *Tables[] = {DecoderTable32, DecoderTableFallback32};
1667
1668 for (const auto *Table : Tables) {
1669 DecodeStatus Result =
1670 decodeInstruction(Table, MI, Insn, Address, this, STI);
1671 if (Result != MCDisassembler::Fail)
1672 return Result;
1673 }
1674
1675 return MCDisassembler::Fail;
1676}
1677
1679 uint64_t Address) const {
1680 // AArch64 instructions are always 4 bytes wide, so there's no point
1681 // in skipping any smaller number of bytes if an instruction can't
1682 // be decoded.
1683 return 4;
1684}
1685
1686static MCSymbolizer *
1688 LLVMSymbolLookupCallback SymbolLookUp,
1689 void *DisInfo, MCContext *Ctx,
1690 std::unique_ptr<MCRelocationInfo> &&RelInfo) {
1691 return new AArch64ExternalSymbolizer(*Ctx, std::move(RelInfo), GetOpInfo,
1692 SymbolLookUp, DisInfo);
1693}
1694
1695extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeMPR32RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeMPR8RegisterClass(MCInst &Inst, const MCDisassembler *Decoder)
static DecodeStatus DecodeSystemPStateImm0_1Instruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeMPR64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeHinteUImm16(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static MCSymbolizer * createAArch64ExternalSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx, std::unique_ptr< MCRelocationInfo > &&RelInfo)
static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeUnsignedLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeMPRRegisterClass(MCInst &Inst, const MCDisassembler *Decoder)
static DecodeStatus DecodeMulMinMaxRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeModImmTiedInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeFixedPointScaleImm64(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeSystemPStateImm0_15Instruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeModImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static MCDisassembler * createAArch64Disassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
static DecodeStatus DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeThreeAddrSRegInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeSETMemGoOpInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeUImm(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeXSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeTestAndBranch(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeZeroImm(MCInst &Inst, const MCDisassembler *Decoder)
#define SoftFail
static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeZK(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeAdrInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodePPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeMPR16RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeVecShiftRImm(MCInst &Inst, unsigned Imm, unsigned Add)
static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeMoveImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodePCRelLabel9(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeVecShiftLImm(MCInst &Inst, unsigned Imm, unsigned Add)
static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeWSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeZPR4Mul4RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeSMESpillFillInstruction(MCInst &Inst, uint32_t Bits, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeLogicalImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
#define Fail
MCDisassembler::DecodeStatus DecodeStatus
static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Disassembler()
#define Success
static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeSVELogicalImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeAuthLoadInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeSyspXzrInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeFMOVLaneInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeAddSubERegInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static bool isInvalidPState(uint64_t Op1, uint64_t Op2)
static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeMatrixTileListRegisterClass(MCInst &Inst, unsigned RegMask, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodePRFMRegInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeAddSubImmShift(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeGPRSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegClassID, unsigned RegNo, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodeMPR128RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeZTRRegisterClass(MCInst &Inst, const MCDisassembler *Decoder)
static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm, uint64_t Addr, const MCDisassembler *Decoder)
#define LLVM_ABI
Definition Compiler.h:215
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
IRTranslator LLVM IR MI
Register Reg
#define T
MCDisassembler::DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef< uint8_t > Bytes, uint64_t Address, raw_ostream &CStream) const override
Returns the disassembly of a single instruction.
uint64_t suggestBytesToSkip(ArrayRef< uint8_t > Bytes, uint64_t Address) const override
Suggest a distance to skip in a buffer of data to find the next place to look for the start of an ins...
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
Context object for machine code objects.
Definition MCContext.h:83
Superclass for all disassemblers.
bool tryAddingSymbolicOperand(MCInst &Inst, int64_t Value, uint64_t Address, bool IsBranch, uint64_t Offset, uint64_t OpSize, uint64_t InstSize) const
const MCSubtargetInfo & getSubtargetInfo() const
const MCSubtargetInfo & STI
raw_ostream * CommentStream
DecodeStatus
Ternary decode status.
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
unsigned getOpcode() const
Definition MCInst.h:202
void addOperand(const MCOperand Op)
Definition MCInst.h:215
const MCOperand & getOperand(unsigned i) const
Definition MCInst.h:210
static MCOperand createReg(MCRegister Reg)
Definition MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition MCInst.h:145
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
Symbolize and annotate disassembled instructions.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
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.
static bool isValidDecodeLogicalImmediate(uint64_t val, unsigned regSize)
isValidDecodeLogicalImmediate - Check to see if the logical immediate value in the form "N:immr:imms"...
std::enable_if_t< std::is_integral_v< IntType >, IntType > fieldFromInstruction(const IntType &Insn, unsigned StartBit, unsigned NumBits)
Definition MCDecoder.h:37
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheAArch64beTarget()
Target & getTheAArch64leTarget()
Target & getTheAArch64_32Target()
Target & getTheARM64_32Target()
@ Add
Sum of integers.
Target & getTheARM64Target()
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
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.