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 AArch64MCRegisterClasses[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 AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].getRegister(
72 RegNo >> 1);
74 return Success;
75}
76
77template <unsigned Min, unsigned Max>
78static DecodeStatus DecodeZPRMul2_MinMax(MCInst &Inst, unsigned RegNo,
79 uint64_t Address,
80 const MCDisassembler *Decoder) {
81 unsigned Reg = (RegNo * 2) + Min;
82 if (Reg < Min || Reg > Max || (Reg & 1))
83 return Fail;
85 AArch64MCRegisterClasses[AArch64::ZPRRegClassID].getRegister(Reg);
87 return Success;
88}
89
90template <unsigned Min, unsigned Max>
91static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
92 uint64_t Address,
93 const void *Decoder) {
94 unsigned Reg = (RegNo * 2) + Min;
95 if (Reg < Min || Reg > Max || (Reg & 1))
96 return Fail;
97
99 AArch64MCRegisterClasses[AArch64::ZPR2RegClassID].getRegister(Reg);
101 return Success;
102}
103
104static DecodeStatus DecodeZK(MCInst &Inst, unsigned RegNo, uint64_t Address,
105 const MCDisassembler *Decoder) {
106 if (RegNo > 7)
107 return Fail;
108
110 AArch64MCRegisterClasses[AArch64::ZPR_KRegClassID].getRegister(RegNo);
112 return Success;
113}
114
116 uint64_t Address,
117 const void *Decoder) {
118 if (RegNo * 4 > 28)
119 return Fail;
121 AArch64MCRegisterClasses[AArch64::ZPR4RegClassID].getRegister(RegNo * 4);
123 return Success;
124}
125
126static DecodeStatus
128 uint64_t Address,
129 const MCDisassembler *Decoder) {
130 if (RegMask > 0xFF)
131 return Fail;
132 Inst.addOperand(MCOperand::createImm(RegMask));
133 return Success;
134}
135
137 const MCDisassembler *Decoder) {
138 Inst.addOperand(MCOperand::createReg(AArch64::ZT0));
139 return Success;
140}
141
143 const MCDisassembler *Decoder) {
144 Inst.addOperand(MCOperand::createReg(AArch64::ZA));
145 return Success;
146}
147
149 const MCDisassembler *Decoder) {
150 Inst.addOperand(MCOperand::createReg(AArch64::ZAB0));
151 return Success;
152}
153
154static DecodeStatus DecodeMPR16RegisterClass(MCInst &Inst, unsigned RegNo,
155 uint64_t Address,
156 const MCDisassembler *Decoder) {
158 AArch64MCRegisterClasses[AArch64::MPR16RegClassID].getRegister(RegNo);
160 return Success;
161}
162
163static DecodeStatus DecodeMPR32RegisterClass(MCInst &Inst, unsigned RegNo,
164 uint64_t Address,
165 const MCDisassembler *Decoder) {
167 AArch64MCRegisterClasses[AArch64::MPR32RegClassID].getRegister(RegNo);
169 return Success;
170}
171
172static DecodeStatus DecodeMPR64RegisterClass(MCInst &Inst, unsigned RegNo,
173 uint64_t Address,
174 const MCDisassembler *Decoder) {
176 AArch64MCRegisterClasses[AArch64::MPR64RegClassID].getRegister(RegNo);
178 return Success;
179}
180
181static DecodeStatus DecodeMPR128RegisterClass(MCInst &Inst, unsigned RegNo,
182 uint64_t Address,
183 const MCDisassembler *Decoder) {
185 AArch64MCRegisterClasses[AArch64::MPR128RegClassID].getRegister(RegNo);
187 return Success;
188}
189
191 uint64_t Address,
192 const void *Decoder) {
193 if ((RegNo * 2) > 14)
194 return Fail;
196 AArch64MCRegisterClasses[AArch64::PPR2RegClassID].getRegister(RegNo * 2);
198 return Success;
199}
200
202 uint64_t Addr,
203 const MCDisassembler *Decoder) {
204 // scale{5} is asserted as 1 in tblgen.
205 Imm |= 0x20;
206 Inst.addOperand(MCOperand::createImm(64 - Imm));
207 return Success;
208}
209
211 uint64_t Addr,
212 const MCDisassembler *Decoder) {
213 Inst.addOperand(MCOperand::createImm(64 - Imm));
214 return Success;
215}
216
217static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm,
218 uint64_t Addr,
219 const MCDisassembler *Decoder) {
220 // Immediate is encoded as the top 16-bits of an unsigned 18-bit negative
221 // PC-relative offset.
222 uint64_t ImmVal = Imm;
223 if (ImmVal > (1 << 16))
224 return Fail;
225 ImmVal = -ImmVal;
226 if (!Decoder->tryAddingSymbolicOperand(Inst, (ImmVal << 2), Addr,
227 /*IsBranch=*/false, 0, 0, 4))
228 Inst.addOperand(MCOperand::createImm(ImmVal));
229 return Success;
230}
231
232static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
233 uint64_t Addr,
234 const MCDisassembler *Decoder) {
235 int64_t ImmVal = SignExtend64<19>(Imm);
236
237 if (!Decoder->tryAddingSymbolicOperand(
238 Inst, ImmVal * 4, Addr, Inst.getOpcode() != AArch64::LDRXl, 0, 0, 4))
239 Inst.addOperand(MCOperand::createImm(ImmVal));
240 return Success;
241}
242
243static DecodeStatus DecodePCRelLabel9(MCInst &Inst, unsigned Imm, uint64_t Addr,
244 const MCDisassembler *Decoder) {
245 int64_t ImmVal = SignExtend64<9>(Imm);
246
247 if (!Decoder->tryAddingSymbolicOperand(Inst, (ImmVal * 4), Addr,
248 /*IsBranch=*/true, 0, 0, 4))
249 Inst.addOperand(MCOperand::createImm(ImmVal));
250 return Success;
251}
252
253static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
254 uint64_t Address,
255 const MCDisassembler *Decoder) {
256 Inst.addOperand(MCOperand::createImm((Imm >> 1) & 1));
257 Inst.addOperand(MCOperand::createImm(Imm & 1));
258 return Success;
259}
260
261static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm,
262 uint64_t Address,
263 const MCDisassembler *Decoder) {
265
266 // Every system register in the encoding space is valid with the syntax
267 // S<op0>_<op1>_<Cn>_<Cm>_<op2>, so decoding system registers always succeeds.
268 return Success;
269}
270
271static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm,
272 uint64_t Address,
273 const MCDisassembler *Decoder) {
275
276 return Success;
277}
278
280 uint64_t Address,
281 const MCDisassembler *Decoder) {
282 // This decoder exists to add the dummy Lane operand to the MCInst, which must
283 // be 1 in assembly but has no other real manifestation.
284 unsigned Rd = fieldFromInstruction(Insn, 0, 5);
285 unsigned Rn = fieldFromInstruction(Insn, 5, 5);
286 unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
287
288 if (IsToVec) {
290 Inst, Rd, Address, Decoder);
292 Inst, Rn, Address, Decoder);
293 } else {
295 Inst, Rd, Address, Decoder);
297 Inst, Rn, Address, Decoder);
298 }
299
300 // Add the lane
302
303 return Success;
304}
305
306static DecodeStatus DecodeVecShiftRImm(MCInst &Inst, unsigned Imm,
307 unsigned Add) {
309 return Success;
310}
311
312static DecodeStatus DecodeVecShiftLImm(MCInst &Inst, unsigned Imm,
313 unsigned Add) {
314 Inst.addOperand(MCOperand::createImm((Imm + Add) & (Add - 1)));
315 return Success;
316}
317
318static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm,
319 uint64_t Addr,
320 const MCDisassembler *Decoder) {
321 return DecodeVecShiftRImm(Inst, Imm, 64);
322}
323
325 uint64_t Addr,
326 const MCDisassembler *Decoder) {
327 return DecodeVecShiftRImm(Inst, Imm | 0x20, 64);
328}
329
330static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm,
331 uint64_t Addr,
332 const MCDisassembler *Decoder) {
333 return DecodeVecShiftRImm(Inst, Imm, 32);
334}
335
337 uint64_t Addr,
338 const MCDisassembler *Decoder) {
339 return DecodeVecShiftRImm(Inst, Imm | 0x10, 32);
340}
341
342static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm,
343 uint64_t Addr,
344 const MCDisassembler *Decoder) {
345 return DecodeVecShiftRImm(Inst, Imm, 16);
346}
347
349 uint64_t Addr,
350 const MCDisassembler *Decoder) {
351 return DecodeVecShiftRImm(Inst, Imm | 0x8, 16);
352}
353
354static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm,
355 uint64_t Addr,
356 const MCDisassembler *Decoder) {
357 return DecodeVecShiftRImm(Inst, Imm, 8);
358}
359
360static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm,
361 uint64_t Addr,
362 const MCDisassembler *Decoder) {
363 return DecodeVecShiftLImm(Inst, Imm, 64);
364}
365
366static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm,
367 uint64_t Addr,
368 const MCDisassembler *Decoder) {
369 return DecodeVecShiftLImm(Inst, Imm, 32);
370}
371
372static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm,
373 uint64_t Addr,
374 const MCDisassembler *Decoder) {
375 return DecodeVecShiftLImm(Inst, Imm, 16);
376}
377
378static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm,
379 uint64_t Addr,
380 const MCDisassembler *Decoder) {
381 return DecodeVecShiftLImm(Inst, Imm, 8);
382}
383
384static DecodeStatus
386 const MCDisassembler *Decoder) {
387 unsigned Rd = fieldFromInstruction(insn, 0, 5);
388 unsigned Rn = fieldFromInstruction(insn, 5, 5);
389 unsigned Rm = fieldFromInstruction(insn, 16, 5);
390 unsigned shiftHi = fieldFromInstruction(insn, 22, 2);
391 unsigned shiftLo = fieldFromInstruction(insn, 10, 6);
392 unsigned shift = (shiftHi << 6) | shiftLo;
393 switch (Inst.getOpcode()) {
394 default:
395 return Fail;
396 case AArch64::ADDWrs:
397 case AArch64::ADDSWrs:
398 case AArch64::SUBWrs:
399 case AArch64::SUBSWrs:
400 // if shift == '11' then ReservedValue()
401 if (shiftHi == 0x3)
402 return Fail;
403 [[fallthrough]];
404 case AArch64::ANDWrs:
405 case AArch64::ANDSWrs:
406 case AArch64::BICWrs:
407 case AArch64::BICSWrs:
408 case AArch64::ORRWrs:
409 case AArch64::ORNWrs:
410 case AArch64::EORWrs:
411 case AArch64::EONWrs: {
412 // if sf == '0' and imm6<5> == '1' then ReservedValue()
413 if (shiftLo >> 5 == 1)
414 return Fail;
416 Decoder);
418 Decoder);
420 Decoder);
421 break;
422 }
423 case AArch64::ADDXrs:
424 case AArch64::ADDSXrs:
425 case AArch64::SUBXrs:
426 case AArch64::SUBSXrs:
427 // if shift == '11' then ReservedValue()
428 if (shiftHi == 0x3)
429 return Fail;
430 [[fallthrough]];
431 case AArch64::ANDXrs:
432 case AArch64::ANDSXrs:
433 case AArch64::BICXrs:
434 case AArch64::BICSXrs:
435 case AArch64::ORRXrs:
436 case AArch64::ORNXrs:
437 case AArch64::EORXrs:
438 case AArch64::EONXrs:
440 Decoder);
442 Decoder);
444 Decoder);
445 break;
446 }
447
448 Inst.addOperand(MCOperand::createImm(shift));
449 return Success;
450}
451
453 uint64_t Addr,
454 const MCDisassembler *Decoder) {
455 unsigned Rd = fieldFromInstruction(insn, 0, 5);
456 unsigned imm = fieldFromInstruction(insn, 5, 16);
457 unsigned shift = fieldFromInstruction(insn, 21, 2);
458 shift <<= 4;
459 switch (Inst.getOpcode()) {
460 default:
461 return Fail;
462 case AArch64::MOVZWi:
463 case AArch64::MOVNWi:
464 case AArch64::MOVKWi:
465 if (shift & (1U << 5))
466 return Fail;
468 Decoder);
469 break;
470 case AArch64::MOVZXi:
471 case AArch64::MOVNXi:
472 case AArch64::MOVKXi:
474 Decoder);
475 break;
476 }
477
478 if (Inst.getOpcode() == AArch64::MOVKWi ||
479 Inst.getOpcode() == AArch64::MOVKXi)
480 Inst.addOperand(Inst.getOperand(0));
481
482 if (!Decoder->tryAddingSymbolicOperand(Inst, imm, Addr, /*IsBranch*/ false, 0,
483 0, 4))
485
486 Inst.addOperand(MCOperand::createImm(shift));
487 return Success;
488}
489
490static DecodeStatus
492 const MCDisassembler *Decoder) {
493 unsigned Rt = fieldFromInstruction(insn, 0, 5);
494 unsigned Rn = fieldFromInstruction(insn, 5, 5);
495 unsigned offset = fieldFromInstruction(insn, 10, 12);
496
497 switch (Inst.getOpcode()) {
498 default:
499 return Fail;
500 case AArch64::PRFMui:
501 // Rt is an immediate in prefetch.
503 break;
504 case AArch64::STRBBui:
505 case AArch64::LDRBBui:
506 case AArch64::LDRSBWui:
507 case AArch64::STRHHui:
508 case AArch64::LDRHHui:
509 case AArch64::LDRSHWui:
510 case AArch64::STRWui:
511 case AArch64::LDRWui:
513 Decoder);
514 break;
515 case AArch64::LDRSBXui:
516 case AArch64::LDRSHXui:
517 case AArch64::LDRSWui:
518 case AArch64::STRXui:
519 case AArch64::LDRXui:
521 Decoder);
522 break;
523 case AArch64::LDRQui:
524 case AArch64::STRQui:
526 Decoder);
527 break;
528 case AArch64::LDRDui:
529 case AArch64::STRDui:
531 Decoder);
532 break;
533 case AArch64::LDRSui:
534 case AArch64::STRSui:
536 Decoder);
537 break;
538 case AArch64::LDRHui:
539 case AArch64::STRHui:
541 Decoder);
542 break;
543 case AArch64::LDRBui:
544 case AArch64::STRBui:
546 Decoder);
547 break;
548 }
549
551 Decoder);
552 if (!Decoder->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 0, 4))
553 Inst.addOperand(MCOperand::createImm(offset));
554 return Success;
555}
556
558 uint64_t Addr,
559 const MCDisassembler *Decoder) {
560 unsigned Rt = fieldFromInstruction(insn, 0, 5);
561 unsigned Rn = fieldFromInstruction(insn, 5, 5);
562 int64_t offset = SignExtend64<9>(fieldFromInstruction(insn, 12, 9));
563
564 // First operand is always the writeback to the address register, if needed.
565 switch (Inst.getOpcode()) {
566 default:
567 break;
568 case AArch64::LDRSBWpre:
569 case AArch64::LDRSHWpre:
570 case AArch64::STRBBpre:
571 case AArch64::LDRBBpre:
572 case AArch64::STRHHpre:
573 case AArch64::LDRHHpre:
574 case AArch64::STRWpre:
575 case AArch64::LDRWpre:
576 case AArch64::LDRSBWpost:
577 case AArch64::LDRSHWpost:
578 case AArch64::STRBBpost:
579 case AArch64::LDRBBpost:
580 case AArch64::STRHHpost:
581 case AArch64::LDRHHpost:
582 case AArch64::STRWpost:
583 case AArch64::LDRWpost:
584 case AArch64::LDRSBXpre:
585 case AArch64::LDRSHXpre:
586 case AArch64::STRXpre:
587 case AArch64::LDRSWpre:
588 case AArch64::LDRXpre:
589 case AArch64::LDRSBXpost:
590 case AArch64::LDRSHXpost:
591 case AArch64::STRXpost:
592 case AArch64::LDRSWpost:
593 case AArch64::LDRXpost:
594 case AArch64::LDRQpre:
595 case AArch64::STRQpre:
596 case AArch64::LDRQpost:
597 case AArch64::STRQpost:
598 case AArch64::LDRDpre:
599 case AArch64::STRDpre:
600 case AArch64::LDRDpost:
601 case AArch64::STRDpost:
602 case AArch64::LDRSpre:
603 case AArch64::STRSpre:
604 case AArch64::LDRSpost:
605 case AArch64::STRSpost:
606 case AArch64::LDRHpre:
607 case AArch64::STRHpre:
608 case AArch64::LDRHpost:
609 case AArch64::STRHpost:
610 case AArch64::LDRBpre:
611 case AArch64::STRBpre:
612 case AArch64::LDRBpost:
613 case AArch64::STRBpost:
615 Decoder);
616 break;
617 }
618
619 switch (Inst.getOpcode()) {
620 default:
621 return Fail;
622 case AArch64::PRFUMi:
623 // Rt is an immediate in prefetch.
625 break;
626 case AArch64::STURBBi:
627 case AArch64::LDURBBi:
628 case AArch64::LDURSBWi:
629 case AArch64::STURHHi:
630 case AArch64::LDURHHi:
631 case AArch64::LDURSHWi:
632 case AArch64::STURWi:
633 case AArch64::LDURWi:
634 case AArch64::LDTRSBWi:
635 case AArch64::LDTRSHWi:
636 case AArch64::STTRWi:
637 case AArch64::LDTRWi:
638 case AArch64::STTRHi:
639 case AArch64::LDTRHi:
640 case AArch64::LDTRBi:
641 case AArch64::STTRBi:
642 case AArch64::LDRSBWpre:
643 case AArch64::LDRSHWpre:
644 case AArch64::STRBBpre:
645 case AArch64::LDRBBpre:
646 case AArch64::STRHHpre:
647 case AArch64::LDRHHpre:
648 case AArch64::STRWpre:
649 case AArch64::LDRWpre:
650 case AArch64::LDRSBWpost:
651 case AArch64::LDRSHWpost:
652 case AArch64::STRBBpost:
653 case AArch64::LDRBBpost:
654 case AArch64::STRHHpost:
655 case AArch64::LDRHHpost:
656 case AArch64::STRWpost:
657 case AArch64::LDRWpost:
658 case AArch64::STLURBi:
659 case AArch64::STLURHi:
660 case AArch64::STLURWi:
661 case AArch64::LDAPURBi:
662 case AArch64::LDAPURSBWi:
663 case AArch64::LDAPURHi:
664 case AArch64::LDAPURSHWi:
665 case AArch64::LDAPURi:
667 Decoder);
668 break;
669 case AArch64::LDURSBXi:
670 case AArch64::LDURSHXi:
671 case AArch64::LDURSWi:
672 case AArch64::STURXi:
673 case AArch64::LDURXi:
674 case AArch64::LDTRSBXi:
675 case AArch64::LDTRSHXi:
676 case AArch64::LDTRSWi:
677 case AArch64::STTRXi:
678 case AArch64::LDTRXi:
679 case AArch64::LDRSBXpre:
680 case AArch64::LDRSHXpre:
681 case AArch64::STRXpre:
682 case AArch64::LDRSWpre:
683 case AArch64::LDRXpre:
684 case AArch64::LDRSBXpost:
685 case AArch64::LDRSHXpost:
686 case AArch64::STRXpost:
687 case AArch64::LDRSWpost:
688 case AArch64::LDRXpost:
689 case AArch64::LDAPURSWi:
690 case AArch64::LDAPURSHXi:
691 case AArch64::LDAPURSBXi:
692 case AArch64::STLURXi:
693 case AArch64::LDAPURXi:
695 Decoder);
696 break;
697 case AArch64::LDURQi:
698 case AArch64::STURQi:
699 case AArch64::LDRQpre:
700 case AArch64::STRQpre:
701 case AArch64::LDRQpost:
702 case AArch64::STRQpost:
704 Decoder);
705 break;
706 case AArch64::LDURDi:
707 case AArch64::STURDi:
708 case AArch64::LDRDpre:
709 case AArch64::STRDpre:
710 case AArch64::LDRDpost:
711 case AArch64::STRDpost:
713 Decoder);
714 break;
715 case AArch64::LDURSi:
716 case AArch64::STURSi:
717 case AArch64::LDRSpre:
718 case AArch64::STRSpre:
719 case AArch64::LDRSpost:
720 case AArch64::STRSpost:
722 Decoder);
723 break;
724 case AArch64::LDURHi:
725 case AArch64::STURHi:
726 case AArch64::LDRHpre:
727 case AArch64::STRHpre:
728 case AArch64::LDRHpost:
729 case AArch64::STRHpost:
731 Decoder);
732 break;
733 case AArch64::LDURBi:
734 case AArch64::STURBi:
735 case AArch64::LDRBpre:
736 case AArch64::STRBpre:
737 case AArch64::LDRBpost:
738 case AArch64::STRBpost:
740 Decoder);
741 break;
742 }
743
745 Decoder);
746 Inst.addOperand(MCOperand::createImm(offset));
747
748 bool IsLoad = fieldFromInstruction(insn, 22, 1);
749 bool IsIndexed = fieldFromInstruction(insn, 10, 2) != 0;
750 bool IsFP = fieldFromInstruction(insn, 26, 1);
751
752 // Cannot write back to a transfer register (but xzr != sp).
753 if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn)
754 return SoftFail;
755
756 return Success;
757}
758
759static DecodeStatus
761 const MCDisassembler *Decoder) {
762 unsigned Rt = fieldFromInstruction(insn, 0, 5);
763 unsigned Rn = fieldFromInstruction(insn, 5, 5);
764 unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
765 unsigned Rs = fieldFromInstruction(insn, 16, 5);
766
767 unsigned Opcode = Inst.getOpcode();
768 switch (Opcode) {
769 default:
770 return Fail;
771 case AArch64::STLXRW:
772 case AArch64::STLXRB:
773 case AArch64::STLXRH:
774 case AArch64::STXRW:
775 case AArch64::STXRB:
776 case AArch64::STXRH:
778 Decoder);
779 [[fallthrough]];
780 case AArch64::LDARW:
781 case AArch64::LDARB:
782 case AArch64::LDARH:
783 case AArch64::LDAXRW:
784 case AArch64::LDAXRB:
785 case AArch64::LDAXRH:
786 case AArch64::LDXRW:
787 case AArch64::LDXRB:
788 case AArch64::LDXRH:
789 case AArch64::STLRW:
790 case AArch64::STLRB:
791 case AArch64::STLRH:
792 case AArch64::STLLRW:
793 case AArch64::STLLRB:
794 case AArch64::STLLRH:
795 case AArch64::LDLARW:
796 case AArch64::LDLARB:
797 case AArch64::LDLARH:
799 Decoder);
800 break;
801 case AArch64::STLXRX:
802 case AArch64::STXRX:
804 Decoder);
805 [[fallthrough]];
806 case AArch64::LDARX:
807 case AArch64::LDAXRX:
808 case AArch64::LDXRX:
809 case AArch64::STLRX:
810 case AArch64::LDLARX:
811 case AArch64::STLLRX:
813 Decoder);
814 break;
815 case AArch64::STLXPW:
816 case AArch64::STXPW:
818 Decoder);
819 [[fallthrough]];
820 case AArch64::LDAXPW:
821 case AArch64::LDXPW:
823 Decoder);
825 Decoder);
826 break;
827 case AArch64::STLXPX:
828 case AArch64::STXPX:
830 Decoder);
831 [[fallthrough]];
832 case AArch64::LDAXPX:
833 case AArch64::LDXPX:
835 Decoder);
837 Decoder);
838 break;
839 }
840
842 Decoder);
843
844 // You shouldn't load to the same register twice in an instruction...
845 if ((Opcode == AArch64::LDAXPW || Opcode == AArch64::LDXPW ||
846 Opcode == AArch64::LDAXPX || Opcode == AArch64::LDXPX) &&
847 Rt == Rt2)
848 return SoftFail;
849
850 return Success;
851}
852
854 uint64_t Addr,
855 const MCDisassembler *Decoder) {
856 unsigned Rt = fieldFromInstruction(insn, 0, 5);
857 unsigned Rn = fieldFromInstruction(insn, 5, 5);
858 unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
859 int64_t offset = SignExtend64<7>(fieldFromInstruction(insn, 15, 7));
860 bool IsLoad = fieldFromInstruction(insn, 22, 1);
861
862 unsigned Opcode = Inst.getOpcode();
863 bool NeedsDisjointWritebackTransfer = false;
864
865 // First operand is always writeback of base register.
866 switch (Opcode) {
867 default:
868 break;
869 case AArch64::LDPXpost:
870 case AArch64::STPXpost:
871 case AArch64::LDPSWpost:
872 case AArch64::LDPXpre:
873 case AArch64::STPXpre:
874 case AArch64::LDPSWpre:
875 case AArch64::LDPWpost:
876 case AArch64::STPWpost:
877 case AArch64::LDPWpre:
878 case AArch64::STPWpre:
879 case AArch64::LDPQpost:
880 case AArch64::STPQpost:
881 case AArch64::LDPQpre:
882 case AArch64::STPQpre:
883 case AArch64::LDPDpost:
884 case AArch64::STPDpost:
885 case AArch64::LDPDpre:
886 case AArch64::STPDpre:
887 case AArch64::LDPSpost:
888 case AArch64::STPSpost:
889 case AArch64::LDPSpre:
890 case AArch64::STPSpre:
891 case AArch64::STGPpre:
892 case AArch64::STGPpost:
893 case AArch64::LDTPpre:
894 case AArch64::LDTPpost:
895 case AArch64::LDTPQpost:
896 case AArch64::LDTPQpre:
897 case AArch64::STTPpost:
898 case AArch64::STTPpre:
899 case AArch64::STTPQpost:
900 case AArch64::STTPQpre:
902 Decoder);
903 break;
904 }
905
906 switch (Opcode) {
907 default:
908 return Fail;
909 case AArch64::LDPXpost:
910 case AArch64::STPXpost:
911 case AArch64::LDPSWpost:
912 case AArch64::LDPXpre:
913 case AArch64::STPXpre:
914 case AArch64::LDPSWpre:
915 case AArch64::STGPpre:
916 case AArch64::STGPpost:
917 case AArch64::LDTPpost:
918 case AArch64::LDTPpre:
919 case AArch64::STTPpost:
920 case AArch64::STTPpre:
921 NeedsDisjointWritebackTransfer = true;
922 [[fallthrough]];
923 case AArch64::LDNPXi:
924 case AArch64::STNPXi:
925 case AArch64::LDPXi:
926 case AArch64::STPXi:
927 case AArch64::LDPSWi:
928 case AArch64::STGPi:
929 case AArch64::LDTPi:
930 case AArch64::STTPi:
931 case AArch64::STTNPXi:
932 case AArch64::LDTNPXi:
934 Decoder);
936 Decoder);
937 break;
938 case AArch64::LDPWpost:
939 case AArch64::STPWpost:
940 case AArch64::LDPWpre:
941 case AArch64::STPWpre:
942 NeedsDisjointWritebackTransfer = true;
943 [[fallthrough]];
944 case AArch64::LDNPWi:
945 case AArch64::STNPWi:
946 case AArch64::LDPWi:
947 case AArch64::STPWi:
949 Decoder);
951 Decoder);
952 break;
953 case AArch64::LDNPQi:
954 case AArch64::STNPQi:
955 case AArch64::LDPQpost:
956 case AArch64::STPQpost:
957 case AArch64::LDPQi:
958 case AArch64::STPQi:
959 case AArch64::LDPQpre:
960 case AArch64::STPQpre:
961 case AArch64::LDTPQi:
962 case AArch64::LDTPQpost:
963 case AArch64::LDTPQpre:
964 case AArch64::LDTNPQi:
965 case AArch64::STTPQi:
966 case AArch64::STTPQpost:
967 case AArch64::STTPQpre:
968 case AArch64::STTNPQi:
970 Decoder);
972 Decoder);
973 break;
974 case AArch64::LDNPDi:
975 case AArch64::STNPDi:
976 case AArch64::LDPDpost:
977 case AArch64::STPDpost:
978 case AArch64::LDPDi:
979 case AArch64::STPDi:
980 case AArch64::LDPDpre:
981 case AArch64::STPDpre:
983 Decoder);
985 Decoder);
986 break;
987 case AArch64::LDNPSi:
988 case AArch64::STNPSi:
989 case AArch64::LDPSpost:
990 case AArch64::STPSpost:
991 case AArch64::LDPSi:
992 case AArch64::STPSi:
993 case AArch64::LDPSpre:
994 case AArch64::STPSpre:
996 Decoder);
998 Decoder);
999 break;
1000 }
1001
1003 Decoder);
1004 Inst.addOperand(MCOperand::createImm(offset));
1005
1006 // You shouldn't load to the same register twice in an instruction...
1007 if (IsLoad && Rt == Rt2)
1008 return SoftFail;
1009
1010 // ... or do any operation that writes-back to a transfer register. But note
1011 // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.
1012 if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn))
1013 return SoftFail;
1014
1015 return Success;
1016}
1017
1019 uint64_t Addr,
1020 const MCDisassembler *Decoder) {
1021 unsigned Rt = fieldFromInstruction(insn, 0, 5);
1022 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1023 uint64_t offset = fieldFromInstruction(insn, 22, 1) << 9 |
1024 fieldFromInstruction(insn, 12, 9);
1025 unsigned writeback = fieldFromInstruction(insn, 11, 1);
1026
1027 switch (Inst.getOpcode()) {
1028 default:
1029 return Fail;
1030 case AArch64::LDRAAwriteback:
1031 case AArch64::LDRABwriteback:
1033 Inst, Rn /* writeback register */, Addr, Decoder);
1034 break;
1035 case AArch64::LDRAAindexed:
1036 case AArch64::LDRABindexed:
1037 break;
1038 }
1039
1041 Decoder);
1043 Decoder);
1044 DecodeSImm<10>(Inst, offset, Addr, Decoder);
1045
1046 if (writeback && Rt == Rn && Rn != 31) {
1047 return SoftFail;
1048 }
1049
1050 return Success;
1051}
1052
1054 uint64_t Addr,
1055 const MCDisassembler *Decoder) {
1056 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1057 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1058 unsigned Rm = fieldFromInstruction(insn, 16, 5);
1059 unsigned extend = fieldFromInstruction(insn, 10, 6);
1060
1061 unsigned shift = extend & 0x7;
1062 if (shift > 4)
1063 return Fail;
1064
1065 switch (Inst.getOpcode()) {
1066 default:
1067 return Fail;
1068 case AArch64::ADDWrx:
1069 case AArch64::SUBWrx:
1071 Decoder);
1073 Decoder);
1075 Decoder);
1076 break;
1077 case AArch64::ADDSWrx:
1078 case AArch64::SUBSWrx:
1080 Decoder);
1082 Decoder);
1084 Decoder);
1085 break;
1086 case AArch64::ADDXrx:
1087 case AArch64::SUBXrx:
1089 Decoder);
1091 Decoder);
1093 Decoder);
1094 break;
1095 case AArch64::ADDSXrx:
1096 case AArch64::SUBSXrx:
1098 Decoder);
1100 Decoder);
1102 Decoder);
1103 break;
1104 case AArch64::ADDXrx64:
1105 case AArch64::SUBXrx64:
1107 Decoder);
1109 Decoder);
1111 Decoder);
1112 break;
1113 case AArch64::SUBSXrx64:
1114 case AArch64::ADDSXrx64:
1116 Decoder);
1118 Decoder);
1120 Decoder);
1121 break;
1122 }
1123
1124 Inst.addOperand(MCOperand::createImm(extend));
1125 return Success;
1126}
1127
1129 uint64_t Addr,
1130 const MCDisassembler *Decoder) {
1131 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1132 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1133 unsigned Datasize = fieldFromInstruction(insn, 31, 1);
1134 unsigned imm;
1135
1136 if (Datasize) {
1137 if (Inst.getOpcode() == AArch64::ANDSXri)
1139 Decoder);
1140 else
1142 Inst, Rd, Addr, Decoder);
1144 Decoder);
1145 imm = fieldFromInstruction(insn, 10, 13);
1147 return Fail;
1148 } else {
1149 if (Inst.getOpcode() == AArch64::ANDSWri)
1151 Decoder);
1152 else
1154 Inst, Rd, Addr, Decoder);
1156 Decoder);
1157 imm = fieldFromInstruction(insn, 10, 12);
1159 return Fail;
1160 }
1162 return Success;
1163}
1164
1166 uint64_t Addr,
1167 const MCDisassembler *Decoder) {
1168 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1169 unsigned cmode = fieldFromInstruction(insn, 12, 4);
1170 unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
1171 imm |= fieldFromInstruction(insn, 5, 5);
1172
1173 if (Inst.getOpcode() == AArch64::MOVID)
1175 Decoder);
1176 else
1178 Decoder);
1179
1181
1182 switch (Inst.getOpcode()) {
1183 default:
1184 break;
1185 case AArch64::MOVIv4i16:
1186 case AArch64::MOVIv8i16:
1187 case AArch64::MVNIv4i16:
1188 case AArch64::MVNIv8i16:
1189 case AArch64::MOVIv2i32:
1190 case AArch64::MOVIv4i32:
1191 case AArch64::MVNIv2i32:
1192 case AArch64::MVNIv4i32:
1193 Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
1194 break;
1195 case AArch64::MOVIv2s_msl:
1196 case AArch64::MOVIv4s_msl:
1197 case AArch64::MVNIv2s_msl:
1198 case AArch64::MVNIv4s_msl:
1199 Inst.addOperand(MCOperand::createImm((cmode & 1) ? 0x110 : 0x108));
1200 break;
1201 }
1202
1203 return Success;
1204}
1205
1207 uint64_t Addr,
1208 const MCDisassembler *Decoder) {
1209 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1210 unsigned cmode = fieldFromInstruction(insn, 12, 4);
1211 unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
1212 imm |= fieldFromInstruction(insn, 5, 5);
1213
1214 // Tied operands added twice.
1216 Decoder);
1218 Decoder);
1219
1221 Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
1222
1223 return Success;
1224}
1225
1227 uint64_t Addr,
1228 const MCDisassembler *Decoder) {
1229 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1230 int64_t imm = SignExtend64<21>((fieldFromInstruction(insn, 5, 19) << 2) |
1231 fieldFromInstruction(insn, 29, 2));
1232
1234 Decoder);
1235 if (!Decoder->tryAddingSymbolicOperand(Inst, imm, Addr, Fail, 0, 0, 4))
1237
1238 return Success;
1239}
1240
1242 uint64_t Addr,
1243 const MCDisassembler *Decoder) {
1244 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1245 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1246 unsigned Imm = fieldFromInstruction(insn, 10, 14);
1247 unsigned S = fieldFromInstruction(insn, 29, 1);
1248 unsigned Datasize = fieldFromInstruction(insn, 31, 1);
1249
1250 unsigned ShifterVal = (Imm >> 12) & 3;
1251 unsigned ImmVal = Imm & 0xFFF;
1252
1253 if (ShifterVal != 0 && ShifterVal != 1)
1254 return Fail;
1255
1256 if (Datasize) {
1257 if (Rd == 31 && !S)
1259 Inst, Rd, Addr, Decoder);
1260 else
1262 Decoder);
1264 Decoder);
1265 } else {
1266 if (Rd == 31 && !S)
1268 Inst, Rd, Addr, Decoder);
1269 else
1271 Decoder);
1273 Decoder);
1274 }
1275
1276 if (!Decoder->tryAddingSymbolicOperand(Inst, Imm, Addr, Fail, 0, 0, 4))
1277 Inst.addOperand(MCOperand::createImm(ImmVal));
1278 Inst.addOperand(MCOperand::createImm(12 * ShifterVal));
1279 return Success;
1280}
1281
1283 uint64_t Addr,
1284 const MCDisassembler *Decoder) {
1285 int64_t imm = SignExtend64<26>(fieldFromInstruction(insn, 0, 26));
1286
1287 if (!Decoder->tryAddingSymbolicOperand(Inst, imm * 4, Addr, true, 0, 0, 4))
1289
1290 return Success;
1291}
1292
1293static bool isInvalidPState(uint64_t Op1, uint64_t Op2) {
1294 return Op1 == 0b000 && (Op2 == 0b000 || // CFINV
1295 Op2 == 0b001 || // XAFlag
1296 Op2 == 0b010); // AXFlag
1297}
1298
1299static DecodeStatus
1301 const MCDisassembler *Decoder) {
1302 uint64_t op1 = fieldFromInstruction(insn, 16, 3);
1303 uint64_t op2 = fieldFromInstruction(insn, 5, 3);
1304 uint64_t imm = fieldFromInstruction(insn, 8, 4);
1305 uint64_t pstate_field = (op1 << 3) | op2;
1306
1307 if (isInvalidPState(op1, op2))
1308 return Fail;
1309
1310 Inst.addOperand(MCOperand::createImm(pstate_field));
1312
1313 auto PState = AArch64PState::lookupPStateImm0_15ByEncoding(pstate_field);
1314 if (PState &&
1315 PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits()))
1316 return Success;
1317 return Fail;
1318}
1319
1320static DecodeStatus
1322 const MCDisassembler *Decoder) {
1323 uint64_t op1 = fieldFromInstruction(insn, 16, 3);
1324 uint64_t op2 = fieldFromInstruction(insn, 5, 3);
1325 uint64_t crm_high = fieldFromInstruction(insn, 9, 3);
1326 uint64_t imm = fieldFromInstruction(insn, 8, 1);
1327 uint64_t pstate_field = (crm_high << 6) | (op1 << 3) | op2;
1328
1329 if (isInvalidPState(op1, op2))
1330 return Fail;
1331
1332 Inst.addOperand(MCOperand::createImm(pstate_field));
1334
1335 auto PState = AArch64PState::lookupPStateImm0_1ByEncoding(pstate_field);
1336 if (PState &&
1337 PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits()))
1338 return Success;
1339 return Fail;
1340}
1341
1343 uint64_t Addr,
1344 const MCDisassembler *Decoder) {
1345 uint64_t Rt = fieldFromInstruction(insn, 0, 5);
1346 uint64_t bit = fieldFromInstruction(insn, 31, 1) << 5;
1347 bit |= fieldFromInstruction(insn, 19, 5);
1348 int64_t dst = SignExtend64<14>(fieldFromInstruction(insn, 5, 14));
1349
1350 if (fieldFromInstruction(insn, 31, 1) == 0)
1352 Decoder);
1353 else
1355 Decoder);
1357 if (!Decoder->tryAddingSymbolicOperand(Inst, dst * 4, Addr, true, 0, 0, 4))
1359
1360 return Success;
1361}
1362
1363static DecodeStatus
1365 unsigned RegNo, uint64_t Addr,
1366 const MCDisassembler *Decoder) {
1367 // Register number must be even (see CASP instruction)
1368 if (RegNo & 0x1)
1369 return Fail;
1370
1371 MCRegister Reg = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo / 2);
1373 return Success;
1374}
1375
1376static DecodeStatus
1378 const MCDisassembler *Decoder) {
1380 Inst, AArch64::WSeqPairsClassRegClassID, RegNo, Addr, Decoder);
1381}
1382
1383static DecodeStatus
1385 const MCDisassembler *Decoder) {
1387 Inst, AArch64::XSeqPairsClassRegClassID, RegNo, Addr, Decoder);
1388}
1389
1391 uint64_t Addr,
1392 const MCDisassembler *Decoder) {
1393 unsigned op1 = fieldFromInstruction(insn, 16, 3);
1394 unsigned CRn = fieldFromInstruction(insn, 12, 4);
1395 unsigned CRm = fieldFromInstruction(insn, 8, 4);
1396 unsigned op2 = fieldFromInstruction(insn, 5, 3);
1397 unsigned Rt = fieldFromInstruction(insn, 0, 5);
1398 if (Rt != 0b11111)
1399 return Fail;
1400
1406 Decoder);
1407
1408 return Success;
1409}
1410
1411static DecodeStatus
1413 const MCDisassembler *Decoder) {
1414 unsigned Zdn = fieldFromInstruction(insn, 0, 5);
1415 unsigned imm = fieldFromInstruction(insn, 5, 13);
1417 return Fail;
1418
1419 // The same (tied) operand is added twice to the instruction.
1421 Decoder);
1422 if (Inst.getOpcode() != AArch64::DUPM_ZI)
1424 Decoder);
1426 return Success;
1427}
1428
1429static DecodeStatus DecodeZeroImm(MCInst &Inst, const MCDisassembler *Decoder) {
1431 return Success;
1432}
1433
1434template <int Bits>
1436 const MCDisassembler *Decoder) {
1437 if (Imm & ~((1LL << Bits) - 1))
1438 return Fail;
1439
1440 // Imm is a signed immediate, so sign extend it.
1441 if (Imm & (1 << (Bits - 1)))
1442 Imm |= ~((1LL << Bits) - 1);
1443
1445 return Success;
1446}
1447
1448template <int Bits>
1450 const MCDisassembler *Decoder) {
1451 if (Imm & ~((1ULL << Bits) - 1))
1452 return Fail;
1453
1455 return Success;
1456}
1457
1458// Decode 8-bit signed/unsigned immediate for a given element width.
1459template <int ElementWidth>
1460static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm, uint64_t Addr,
1461 const MCDisassembler *Decoder) {
1462 unsigned Val = (uint8_t)Imm;
1463 unsigned Shift = (Imm & 0x100) ? 8 : 0;
1464 if (ElementWidth == 8 && Shift)
1465 return Fail;
1467 Inst.addOperand(MCOperand::createImm(Shift));
1468 return Success;
1469}
1470
1471// Decode uimm4 ranged from 1-16.
1472static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,
1473 uint64_t Addr,
1474 const MCDisassembler *Decoder) {
1475 Inst.addOperand(MCOperand::createImm(Imm + 1));
1476 return Success;
1477}
1478
1479static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,
1480 const MCDisassembler *Decoder) {
1481 if (AArch64SVCR::lookupSVCRByEncoding(Imm)) {
1483 return Success;
1484 }
1485 return Fail;
1486}
1487
1489 uint64_t Addr,
1490 const MCDisassembler *Decoder) {
1491 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1492 unsigned Rs = fieldFromInstruction(insn, 16, 5);
1493 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1494
1495 // None of the registers may alias: if they do, then the instruction is not
1496 // merely unpredictable but actually entirely unallocated.
1497 if (Rd == Rs || Rs == Rn || Rd == Rn)
1498 return MCDisassembler::Fail;
1499
1500 // All three register operands are written back, so they all appear
1501 // twice in the operand list, once as outputs and once as inputs.
1503 Inst, Rd, Addr, Decoder) ||
1505 Inst, Rs, Addr, Decoder) ||
1507 Inst, Rn, Addr, Decoder) ||
1509 Inst, Rd, Addr, Decoder) ||
1511 Inst, Rs, Addr, Decoder) ||
1513 Inst, Rn, Addr, Decoder))
1514 return MCDisassembler::Fail;
1515
1517}
1518
1520 uint64_t Addr,
1521 const MCDisassembler *Decoder) {
1522 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1523 unsigned Rm = fieldFromInstruction(insn, 16, 5);
1524 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1525
1526 // None of the registers may alias: if they do, then the instruction is not
1527 // merely unpredictable but actually entirely unallocated.
1528 if (Rd == Rm || Rm == Rn || Rd == Rn)
1529 return MCDisassembler::Fail;
1530
1531 // Rd and Rn (not Rm) register operands are written back, so they appear
1532 // twice in the operand list, once as outputs and once as inputs.
1534 Inst, Rd, Addr, Decoder) ||
1536 Inst, Rn, Addr, Decoder) ||
1538 Inst, Rd, Addr, Decoder) ||
1540 Inst, Rn, Addr, Decoder) ||
1542 Inst, Rm, Addr, Decoder))
1543 return MCDisassembler::Fail;
1544
1546}
1547
1549 uint64_t Addr,
1550 const MCDisassembler *Decoder) {
1551 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1552 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1553
1554 // None of the registers may alias: if they do, then the instruction is not
1555 // merely unpredictable but actually entirely unallocated.
1556 if (Rd == Rn)
1557 return MCDisassembler::Fail;
1558
1559 // Rd and Rn register operands are written back, so they appear
1560 // twice in the operand list, once as outputs and once as inputs.
1562 Inst, Rd, Addr, Decoder) ||
1564 Inst, Rn, Addr, Decoder) ||
1566 Inst, Rd, Addr, Decoder) ||
1568 Inst, Rn, Addr, Decoder))
1569 return MCDisassembler::Fail;
1570
1572}
1573
1575 uint64_t Addr,
1576 const MCDisassembler *Decoder) {
1577 // PRFM with Rt = '11xxx' should be decoded as RPRFM.
1578 // Fail to decode and defer to fallback decoder table to decode RPRFM.
1579 unsigned Mask = 0x18;
1580 uint64_t Rt = fieldFromInstruction(insn, 0, 5);
1581 if ((Rt & Mask) == Mask)
1582 return Fail;
1583
1584 uint64_t Rn = fieldFromInstruction(insn, 5, 5);
1585 uint64_t Shift = fieldFromInstruction(insn, 12, 1);
1586 uint64_t Extend = fieldFromInstruction(insn, 15, 1);
1587 uint64_t Rm = fieldFromInstruction(insn, 16, 5);
1588
1591 Decoder);
1592
1593 switch (Inst.getOpcode()) {
1594 default:
1595 return Fail;
1596 case AArch64::PRFMroW:
1598 Decoder);
1599 break;
1600 case AArch64::PRFMroX:
1602 Decoder);
1603 break;
1604 }
1605
1606 DecodeMemExtend(Inst, (Extend << 1) | Shift, Addr, Decoder);
1607
1608 return Success;
1609}
1610
1611static DecodeStatus
1613 const MCDisassembler *Decoder) {
1614 unsigned RvBits = fieldFromInstruction(Bits, 13, 2);
1615 unsigned RnBits = fieldFromInstruction(Bits, 5, 5);
1616 unsigned Imm4Bits = fieldFromInstruction(Bits, 0, 4);
1617
1618 DecodeMPRRegisterClass(Inst, Decoder);
1620 Inst, RvBits, Addr, Decoder);
1621 Inst.addOperand(MCOperand::createImm(Imm4Bits));
1623 Addr, Decoder);
1624 // Spill and fill instructions have a single immediate used for both
1625 // the vector select offset and optional memory offset. Replicate
1626 // the decoded immediate.
1627 Inst.addOperand(MCOperand::createImm(Imm4Bits));
1628 return Success;
1629}
1630
1631#include "AArch64GenDisassemblerTables.inc"
1632#include "AArch64GenInstrInfo.inc"
1633
1635 const MCSubtargetInfo &STI,
1636 MCContext &Ctx) {
1637
1638 return new AArch64Disassembler(STI, Ctx, T.createMCInstrInfo());
1639}
1640
1642 ArrayRef<uint8_t> Bytes,
1644 raw_ostream &CS) const {
1645 CommentStream = &CS;
1646
1647 Size = 0;
1648 // We want to read exactly 4 bytes of data.
1649 if (Bytes.size() < 4)
1650 return Fail;
1651 Size = 4;
1652
1653 // Encoded as a small-endian 32-bit word in the stream.
1654 uint32_t Insn =
1655 (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
1656
1657 const uint8_t *Tables[] = {DecoderTable32, DecoderTableFallback32};
1658
1659 for (const auto *Table : Tables) {
1660 DecodeStatus Result =
1661 decodeInstruction(Table, MI, Insn, Address, this, STI);
1662 if (Result != MCDisassembler::Fail)
1663 return Result;
1664 }
1665
1666 return MCDisassembler::Fail;
1667}
1668
1670 uint64_t Address) const {
1671 // AArch64 instructions are always 4 bytes wide, so there's no point
1672 // in skipping any smaller number of bytes if an instruction can't
1673 // be decoded.
1674 return 4;
1675}
1676
1677static MCSymbolizer *
1679 LLVMSymbolLookupCallback SymbolLookUp,
1680 void *DisInfo, MCContext *Ctx,
1681 std::unique_ptr<MCRelocationInfo> &&RelInfo) {
1682 return new AArch64ExternalSymbolizer(*Ctx, std::move(RelInfo), GetOpInfo,
1683 SymbolLookUp, DisInfo);
1684}
1685
1686extern "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 DecodeZPRMul2_MinMax(MCInst &Inst, unsigned RegNo, uint64_t Address, 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 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 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:213
#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...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
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.
Definition Types.h:26
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.