LLVM 22.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);
41
42#define Success MCDisassembler::Success
43#define Fail MCDisassembler::Fail
44#define SoftFail MCDisassembler::SoftFail
45
46template <unsigned RegClassID, unsigned FirstReg, unsigned NumRegsInClass>
47static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, unsigned RegNo,
48 uint64_t Address,
49 const MCDisassembler *Decoder) {
50 if (RegNo > NumRegsInClass - 1)
51 return Fail;
52
54 AArch64MCRegisterClasses[RegClassID].getRegister(RegNo + FirstReg);
56 return Success;
57}
58
59static DecodeStatus
60DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
61 const MCDisassembler *Decoder) {
62 if (RegNo > 22)
63 return Fail;
64 if (RegNo & 1)
65 return Fail;
66
68 AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].getRegister(
69 RegNo >> 1);
71 return Success;
72}
73
74template <unsigned Min, unsigned Max>
75static DecodeStatus DecodeZPRMul2_MinMax(MCInst &Inst, unsigned RegNo,
76 uint64_t Address,
77 const MCDisassembler *Decoder) {
78 unsigned Reg = (RegNo * 2) + Min;
79 if (Reg < Min || Reg > Max || (Reg & 1))
80 return Fail;
82 AArch64MCRegisterClasses[AArch64::ZPRRegClassID].getRegister(Reg);
84 return Success;
85}
86
87template <unsigned Min, unsigned Max>
88static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
89 uint64_t Address,
90 const void *Decoder) {
91 unsigned Reg = (RegNo * 2) + Min;
92 if (Reg < Min || Reg > Max || (Reg & 1))
93 return Fail;
94
96 AArch64MCRegisterClasses[AArch64::ZPR2RegClassID].getRegister(Reg);
98 return Success;
99}
100
101static DecodeStatus DecodeZK(MCInst &Inst, unsigned RegNo, uint64_t Address,
102 const MCDisassembler *Decoder) {
103 if (RegNo > 7)
104 return Fail;
105
107 AArch64MCRegisterClasses[AArch64::ZPR_KRegClassID].getRegister(RegNo);
109 return Success;
110}
111
113 uint64_t Address,
114 const void *Decoder) {
115 if (RegNo * 4 > 28)
116 return Fail;
118 AArch64MCRegisterClasses[AArch64::ZPR4RegClassID].getRegister(RegNo * 4);
120 return Success;
121}
122
123static DecodeStatus
125 uint64_t Address,
126 const MCDisassembler *Decoder) {
127 if (RegMask > 0xFF)
128 return Fail;
129 Inst.addOperand(MCOperand::createImm(RegMask));
130 return Success;
131}
132
133static const MCPhysReg MatrixZATileDecoderTable[5][16] = {
134 {AArch64::ZAB0},
135 {AArch64::ZAH0, AArch64::ZAH1},
136 {AArch64::ZAS0, AArch64::ZAS1, AArch64::ZAS2, AArch64::ZAS3},
137 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3, AArch64::ZAD4,
138 AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7},
139 {AArch64::ZAQ0, AArch64::ZAQ1, AArch64::ZAQ2, AArch64::ZAQ3, AArch64::ZAQ4,
140 AArch64::ZAQ5, AArch64::ZAQ6, AArch64::ZAQ7, AArch64::ZAQ8, AArch64::ZAQ9,
141 AArch64::ZAQ10, AArch64::ZAQ11, AArch64::ZAQ12, AArch64::ZAQ13,
142 AArch64::ZAQ14, AArch64::ZAQ15}};
143
144template <unsigned NumBitsForTile>
145static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo,
146 uint64_t Address,
147 const MCDisassembler *Decoder) {
148 unsigned LastReg = (1 << NumBitsForTile) - 1;
149 if (RegNo > LastReg)
150 return Fail;
151 Inst.addOperand(
152 MCOperand::createReg(MatrixZATileDecoderTable[NumBitsForTile][RegNo]));
153 return Success;
154}
155
157 uint64_t Address,
158 const void *Decoder) {
159 if ((RegNo * 2) > 14)
160 return Fail;
162 AArch64MCRegisterClasses[AArch64::PPR2RegClassID].getRegister(RegNo * 2);
164 return Success;
165}
166
168 uint64_t Addr,
169 const MCDisassembler *Decoder) {
170 // scale{5} is asserted as 1 in tblgen.
171 Imm |= 0x20;
172 Inst.addOperand(MCOperand::createImm(64 - Imm));
173 return Success;
174}
175
177 uint64_t Addr,
178 const MCDisassembler *Decoder) {
179 Inst.addOperand(MCOperand::createImm(64 - Imm));
180 return Success;
181}
182
183static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm,
184 uint64_t Addr,
185 const MCDisassembler *Decoder) {
186 // Immediate is encoded as the top 16-bits of an unsigned 18-bit negative
187 // PC-relative offset.
188 uint64_t ImmVal = Imm;
189 if (ImmVal > (1 << 16))
190 return Fail;
191 ImmVal = -ImmVal;
192 if (!Decoder->tryAddingSymbolicOperand(Inst, (ImmVal << 2), Addr,
193 /*IsBranch=*/false, 0, 0, 4))
194 Inst.addOperand(MCOperand::createImm(ImmVal));
195 return Success;
196}
197
198static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
199 uint64_t Addr,
200 const MCDisassembler *Decoder) {
201 int64_t ImmVal = SignExtend64<19>(Imm);
202
203 if (!Decoder->tryAddingSymbolicOperand(
204 Inst, ImmVal * 4, Addr, Inst.getOpcode() != AArch64::LDRXl, 0, 0, 4))
205 Inst.addOperand(MCOperand::createImm(ImmVal));
206 return Success;
207}
208
209static DecodeStatus DecodePCRelLabel9(MCInst &Inst, unsigned Imm, uint64_t Addr,
210 const MCDisassembler *Decoder) {
211 int64_t ImmVal = SignExtend64<9>(Imm);
212
213 if (!Decoder->tryAddingSymbolicOperand(Inst, (ImmVal * 4), Addr,
214 /*IsBranch=*/true, 0, 0, 4))
215 Inst.addOperand(MCOperand::createImm(ImmVal));
216 return Success;
217}
218
219static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
220 uint64_t Address,
221 const MCDisassembler *Decoder) {
222 Inst.addOperand(MCOperand::createImm((Imm >> 1) & 1));
223 Inst.addOperand(MCOperand::createImm(Imm & 1));
224 return Success;
225}
226
227static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm,
228 uint64_t Address,
229 const MCDisassembler *Decoder) {
231
232 // Every system register in the encoding space is valid with the syntax
233 // S<op0>_<op1>_<Cn>_<Cm>_<op2>, so decoding system registers always succeeds.
234 return Success;
235}
236
237static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm,
238 uint64_t Address,
239 const MCDisassembler *Decoder) {
241
242 return Success;
243}
244
246 uint64_t Address,
247 const MCDisassembler *Decoder) {
248 // This decoder exists to add the dummy Lane operand to the MCInst, which must
249 // be 1 in assembly but has no other real manifestation.
250 unsigned Rd = fieldFromInstruction(Insn, 0, 5);
251 unsigned Rn = fieldFromInstruction(Insn, 5, 5);
252 unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
253
254 if (IsToVec) {
256 Inst, Rd, Address, Decoder);
258 Inst, Rn, Address, Decoder);
259 } else {
261 Inst, Rd, Address, Decoder);
263 Inst, Rn, Address, Decoder);
264 }
265
266 // Add the lane
268
269 return Success;
270}
271
272static DecodeStatus DecodeVecShiftRImm(MCInst &Inst, unsigned Imm,
273 unsigned Add) {
275 return Success;
276}
277
278static DecodeStatus DecodeVecShiftLImm(MCInst &Inst, unsigned Imm,
279 unsigned Add) {
280 Inst.addOperand(MCOperand::createImm((Imm + Add) & (Add - 1)));
281 return Success;
282}
283
284static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm,
285 uint64_t Addr,
286 const MCDisassembler *Decoder) {
287 return DecodeVecShiftRImm(Inst, Imm, 64);
288}
289
291 uint64_t Addr,
292 const MCDisassembler *Decoder) {
293 return DecodeVecShiftRImm(Inst, Imm | 0x20, 64);
294}
295
296static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm,
297 uint64_t Addr,
298 const MCDisassembler *Decoder) {
299 return DecodeVecShiftRImm(Inst, Imm, 32);
300}
301
303 uint64_t Addr,
304 const MCDisassembler *Decoder) {
305 return DecodeVecShiftRImm(Inst, Imm | 0x10, 32);
306}
307
308static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm,
309 uint64_t Addr,
310 const MCDisassembler *Decoder) {
311 return DecodeVecShiftRImm(Inst, Imm, 16);
312}
313
315 uint64_t Addr,
316 const MCDisassembler *Decoder) {
317 return DecodeVecShiftRImm(Inst, Imm | 0x8, 16);
318}
319
320static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm,
321 uint64_t Addr,
322 const MCDisassembler *Decoder) {
323 return DecodeVecShiftRImm(Inst, Imm, 8);
324}
325
326static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm,
327 uint64_t Addr,
328 const MCDisassembler *Decoder) {
329 return DecodeVecShiftLImm(Inst, Imm, 64);
330}
331
332static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm,
333 uint64_t Addr,
334 const MCDisassembler *Decoder) {
335 return DecodeVecShiftLImm(Inst, Imm, 32);
336}
337
338static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm,
339 uint64_t Addr,
340 const MCDisassembler *Decoder) {
341 return DecodeVecShiftLImm(Inst, Imm, 16);
342}
343
344static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm,
345 uint64_t Addr,
346 const MCDisassembler *Decoder) {
347 return DecodeVecShiftLImm(Inst, Imm, 8);
348}
349
350static DecodeStatus
352 const MCDisassembler *Decoder) {
353 unsigned Rd = fieldFromInstruction(insn, 0, 5);
354 unsigned Rn = fieldFromInstruction(insn, 5, 5);
355 unsigned Rm = fieldFromInstruction(insn, 16, 5);
356 unsigned shiftHi = fieldFromInstruction(insn, 22, 2);
357 unsigned shiftLo = fieldFromInstruction(insn, 10, 6);
358 unsigned shift = (shiftHi << 6) | shiftLo;
359 switch (Inst.getOpcode()) {
360 default:
361 return Fail;
362 case AArch64::ADDWrs:
363 case AArch64::ADDSWrs:
364 case AArch64::SUBWrs:
365 case AArch64::SUBSWrs:
366 // if shift == '11' then ReservedValue()
367 if (shiftHi == 0x3)
368 return Fail;
369 [[fallthrough]];
370 case AArch64::ANDWrs:
371 case AArch64::ANDSWrs:
372 case AArch64::BICWrs:
373 case AArch64::BICSWrs:
374 case AArch64::ORRWrs:
375 case AArch64::ORNWrs:
376 case AArch64::EORWrs:
377 case AArch64::EONWrs: {
378 // if sf == '0' and imm6<5> == '1' then ReservedValue()
379 if (shiftLo >> 5 == 1)
380 return Fail;
382 Decoder);
384 Decoder);
386 Decoder);
387 break;
388 }
389 case AArch64::ADDXrs:
390 case AArch64::ADDSXrs:
391 case AArch64::SUBXrs:
392 case AArch64::SUBSXrs:
393 // if shift == '11' then ReservedValue()
394 if (shiftHi == 0x3)
395 return Fail;
396 [[fallthrough]];
397 case AArch64::ANDXrs:
398 case AArch64::ANDSXrs:
399 case AArch64::BICXrs:
400 case AArch64::BICSXrs:
401 case AArch64::ORRXrs:
402 case AArch64::ORNXrs:
403 case AArch64::EORXrs:
404 case AArch64::EONXrs:
406 Decoder);
408 Decoder);
410 Decoder);
411 break;
412 }
413
414 Inst.addOperand(MCOperand::createImm(shift));
415 return Success;
416}
417
419 uint64_t Addr,
420 const MCDisassembler *Decoder) {
421 unsigned Rd = fieldFromInstruction(insn, 0, 5);
422 unsigned imm = fieldFromInstruction(insn, 5, 16);
423 unsigned shift = fieldFromInstruction(insn, 21, 2);
424 shift <<= 4;
425 switch (Inst.getOpcode()) {
426 default:
427 return Fail;
428 case AArch64::MOVZWi:
429 case AArch64::MOVNWi:
430 case AArch64::MOVKWi:
431 if (shift & (1U << 5))
432 return Fail;
434 Decoder);
435 break;
436 case AArch64::MOVZXi:
437 case AArch64::MOVNXi:
438 case AArch64::MOVKXi:
440 Decoder);
441 break;
442 }
443
444 if (Inst.getOpcode() == AArch64::MOVKWi ||
445 Inst.getOpcode() == AArch64::MOVKXi)
446 Inst.addOperand(Inst.getOperand(0));
447
448 if (!Decoder->tryAddingSymbolicOperand(Inst, imm, Addr, /*IsBranch*/ false, 0,
449 0, 4))
451
452 Inst.addOperand(MCOperand::createImm(shift));
453 return Success;
454}
455
456static DecodeStatus
458 const MCDisassembler *Decoder) {
459 unsigned Rt = fieldFromInstruction(insn, 0, 5);
460 unsigned Rn = fieldFromInstruction(insn, 5, 5);
461 unsigned offset = fieldFromInstruction(insn, 10, 12);
462
463 switch (Inst.getOpcode()) {
464 default:
465 return Fail;
466 case AArch64::PRFMui:
467 // Rt is an immediate in prefetch.
469 break;
470 case AArch64::STRBBui:
471 case AArch64::LDRBBui:
472 case AArch64::LDRSBWui:
473 case AArch64::STRHHui:
474 case AArch64::LDRHHui:
475 case AArch64::LDRSHWui:
476 case AArch64::STRWui:
477 case AArch64::LDRWui:
479 Decoder);
480 break;
481 case AArch64::LDRSBXui:
482 case AArch64::LDRSHXui:
483 case AArch64::LDRSWui:
484 case AArch64::STRXui:
485 case AArch64::LDRXui:
487 Decoder);
488 break;
489 case AArch64::LDRQui:
490 case AArch64::STRQui:
492 Decoder);
493 break;
494 case AArch64::LDRDui:
495 case AArch64::STRDui:
497 Decoder);
498 break;
499 case AArch64::LDRSui:
500 case AArch64::STRSui:
502 Decoder);
503 break;
504 case AArch64::LDRHui:
505 case AArch64::STRHui:
507 Decoder);
508 break;
509 case AArch64::LDRBui:
510 case AArch64::STRBui:
512 Decoder);
513 break;
514 }
515
517 Decoder);
518 if (!Decoder->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 0, 4))
519 Inst.addOperand(MCOperand::createImm(offset));
520 return Success;
521}
522
524 uint64_t Addr,
525 const MCDisassembler *Decoder) {
526 unsigned Rt = fieldFromInstruction(insn, 0, 5);
527 unsigned Rn = fieldFromInstruction(insn, 5, 5);
528 int64_t offset = SignExtend64<9>(fieldFromInstruction(insn, 12, 9));
529
530 // First operand is always the writeback to the address register, if needed.
531 switch (Inst.getOpcode()) {
532 default:
533 break;
534 case AArch64::LDRSBWpre:
535 case AArch64::LDRSHWpre:
536 case AArch64::STRBBpre:
537 case AArch64::LDRBBpre:
538 case AArch64::STRHHpre:
539 case AArch64::LDRHHpre:
540 case AArch64::STRWpre:
541 case AArch64::LDRWpre:
542 case AArch64::LDRSBWpost:
543 case AArch64::LDRSHWpost:
544 case AArch64::STRBBpost:
545 case AArch64::LDRBBpost:
546 case AArch64::STRHHpost:
547 case AArch64::LDRHHpost:
548 case AArch64::STRWpost:
549 case AArch64::LDRWpost:
550 case AArch64::LDRSBXpre:
551 case AArch64::LDRSHXpre:
552 case AArch64::STRXpre:
553 case AArch64::LDRSWpre:
554 case AArch64::LDRXpre:
555 case AArch64::LDRSBXpost:
556 case AArch64::LDRSHXpost:
557 case AArch64::STRXpost:
558 case AArch64::LDRSWpost:
559 case AArch64::LDRXpost:
560 case AArch64::LDRQpre:
561 case AArch64::STRQpre:
562 case AArch64::LDRQpost:
563 case AArch64::STRQpost:
564 case AArch64::LDRDpre:
565 case AArch64::STRDpre:
566 case AArch64::LDRDpost:
567 case AArch64::STRDpost:
568 case AArch64::LDRSpre:
569 case AArch64::STRSpre:
570 case AArch64::LDRSpost:
571 case AArch64::STRSpost:
572 case AArch64::LDRHpre:
573 case AArch64::STRHpre:
574 case AArch64::LDRHpost:
575 case AArch64::STRHpost:
576 case AArch64::LDRBpre:
577 case AArch64::STRBpre:
578 case AArch64::LDRBpost:
579 case AArch64::STRBpost:
581 Decoder);
582 break;
583 }
584
585 switch (Inst.getOpcode()) {
586 default:
587 return Fail;
588 case AArch64::PRFUMi:
589 // Rt is an immediate in prefetch.
591 break;
592 case AArch64::STURBBi:
593 case AArch64::LDURBBi:
594 case AArch64::LDURSBWi:
595 case AArch64::STURHHi:
596 case AArch64::LDURHHi:
597 case AArch64::LDURSHWi:
598 case AArch64::STURWi:
599 case AArch64::LDURWi:
600 case AArch64::LDTRSBWi:
601 case AArch64::LDTRSHWi:
602 case AArch64::STTRWi:
603 case AArch64::LDTRWi:
604 case AArch64::STTRHi:
605 case AArch64::LDTRHi:
606 case AArch64::LDTRBi:
607 case AArch64::STTRBi:
608 case AArch64::LDRSBWpre:
609 case AArch64::LDRSHWpre:
610 case AArch64::STRBBpre:
611 case AArch64::LDRBBpre:
612 case AArch64::STRHHpre:
613 case AArch64::LDRHHpre:
614 case AArch64::STRWpre:
615 case AArch64::LDRWpre:
616 case AArch64::LDRSBWpost:
617 case AArch64::LDRSHWpost:
618 case AArch64::STRBBpost:
619 case AArch64::LDRBBpost:
620 case AArch64::STRHHpost:
621 case AArch64::LDRHHpost:
622 case AArch64::STRWpost:
623 case AArch64::LDRWpost:
624 case AArch64::STLURBi:
625 case AArch64::STLURHi:
626 case AArch64::STLURWi:
627 case AArch64::LDAPURBi:
628 case AArch64::LDAPURSBWi:
629 case AArch64::LDAPURHi:
630 case AArch64::LDAPURSHWi:
631 case AArch64::LDAPURi:
633 Decoder);
634 break;
635 case AArch64::LDURSBXi:
636 case AArch64::LDURSHXi:
637 case AArch64::LDURSWi:
638 case AArch64::STURXi:
639 case AArch64::LDURXi:
640 case AArch64::LDTRSBXi:
641 case AArch64::LDTRSHXi:
642 case AArch64::LDTRSWi:
643 case AArch64::STTRXi:
644 case AArch64::LDTRXi:
645 case AArch64::LDRSBXpre:
646 case AArch64::LDRSHXpre:
647 case AArch64::STRXpre:
648 case AArch64::LDRSWpre:
649 case AArch64::LDRXpre:
650 case AArch64::LDRSBXpost:
651 case AArch64::LDRSHXpost:
652 case AArch64::STRXpost:
653 case AArch64::LDRSWpost:
654 case AArch64::LDRXpost:
655 case AArch64::LDAPURSWi:
656 case AArch64::LDAPURSHXi:
657 case AArch64::LDAPURSBXi:
658 case AArch64::STLURXi:
659 case AArch64::LDAPURXi:
661 Decoder);
662 break;
663 case AArch64::LDURQi:
664 case AArch64::STURQi:
665 case AArch64::LDRQpre:
666 case AArch64::STRQpre:
667 case AArch64::LDRQpost:
668 case AArch64::STRQpost:
670 Decoder);
671 break;
672 case AArch64::LDURDi:
673 case AArch64::STURDi:
674 case AArch64::LDRDpre:
675 case AArch64::STRDpre:
676 case AArch64::LDRDpost:
677 case AArch64::STRDpost:
679 Decoder);
680 break;
681 case AArch64::LDURSi:
682 case AArch64::STURSi:
683 case AArch64::LDRSpre:
684 case AArch64::STRSpre:
685 case AArch64::LDRSpost:
686 case AArch64::STRSpost:
688 Decoder);
689 break;
690 case AArch64::LDURHi:
691 case AArch64::STURHi:
692 case AArch64::LDRHpre:
693 case AArch64::STRHpre:
694 case AArch64::LDRHpost:
695 case AArch64::STRHpost:
697 Decoder);
698 break;
699 case AArch64::LDURBi:
700 case AArch64::STURBi:
701 case AArch64::LDRBpre:
702 case AArch64::STRBpre:
703 case AArch64::LDRBpost:
704 case AArch64::STRBpost:
706 Decoder);
707 break;
708 }
709
711 Decoder);
712 Inst.addOperand(MCOperand::createImm(offset));
713
714 bool IsLoad = fieldFromInstruction(insn, 22, 1);
715 bool IsIndexed = fieldFromInstruction(insn, 10, 2) != 0;
716 bool IsFP = fieldFromInstruction(insn, 26, 1);
717
718 // Cannot write back to a transfer register (but xzr != sp).
719 if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn)
720 return SoftFail;
721
722 return Success;
723}
724
725static DecodeStatus
727 const MCDisassembler *Decoder) {
728 unsigned Rt = fieldFromInstruction(insn, 0, 5);
729 unsigned Rn = fieldFromInstruction(insn, 5, 5);
730 unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
731 unsigned Rs = fieldFromInstruction(insn, 16, 5);
732
733 unsigned Opcode = Inst.getOpcode();
734 switch (Opcode) {
735 default:
736 return Fail;
737 case AArch64::STLXRW:
738 case AArch64::STLXRB:
739 case AArch64::STLXRH:
740 case AArch64::STXRW:
741 case AArch64::STXRB:
742 case AArch64::STXRH:
744 Decoder);
745 [[fallthrough]];
746 case AArch64::LDARW:
747 case AArch64::LDARB:
748 case AArch64::LDARH:
749 case AArch64::LDAXRW:
750 case AArch64::LDAXRB:
751 case AArch64::LDAXRH:
752 case AArch64::LDXRW:
753 case AArch64::LDXRB:
754 case AArch64::LDXRH:
755 case AArch64::STLRW:
756 case AArch64::STLRB:
757 case AArch64::STLRH:
758 case AArch64::STLLRW:
759 case AArch64::STLLRB:
760 case AArch64::STLLRH:
761 case AArch64::LDLARW:
762 case AArch64::LDLARB:
763 case AArch64::LDLARH:
765 Decoder);
766 break;
767 case AArch64::STLXRX:
768 case AArch64::STXRX:
770 Decoder);
771 [[fallthrough]];
772 case AArch64::LDARX:
773 case AArch64::LDAXRX:
774 case AArch64::LDXRX:
775 case AArch64::STLRX:
776 case AArch64::LDLARX:
777 case AArch64::STLLRX:
779 Decoder);
780 break;
781 case AArch64::STLXPW:
782 case AArch64::STXPW:
784 Decoder);
785 [[fallthrough]];
786 case AArch64::LDAXPW:
787 case AArch64::LDXPW:
789 Decoder);
791 Decoder);
792 break;
793 case AArch64::STLXPX:
794 case AArch64::STXPX:
796 Decoder);
797 [[fallthrough]];
798 case AArch64::LDAXPX:
799 case AArch64::LDXPX:
801 Decoder);
803 Decoder);
804 break;
805 }
806
808 Decoder);
809
810 // You shouldn't load to the same register twice in an instruction...
811 if ((Opcode == AArch64::LDAXPW || Opcode == AArch64::LDXPW ||
812 Opcode == AArch64::LDAXPX || Opcode == AArch64::LDXPX) &&
813 Rt == Rt2)
814 return SoftFail;
815
816 return Success;
817}
818
820 uint64_t Addr,
821 const MCDisassembler *Decoder) {
822 unsigned Rt = fieldFromInstruction(insn, 0, 5);
823 unsigned Rn = fieldFromInstruction(insn, 5, 5);
824 unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
825 int64_t offset = SignExtend64<7>(fieldFromInstruction(insn, 15, 7));
826 bool IsLoad = fieldFromInstruction(insn, 22, 1);
827
828 unsigned Opcode = Inst.getOpcode();
829 bool NeedsDisjointWritebackTransfer = false;
830
831 // First operand is always writeback of base register.
832 switch (Opcode) {
833 default:
834 break;
835 case AArch64::LDPXpost:
836 case AArch64::STPXpost:
837 case AArch64::LDPSWpost:
838 case AArch64::LDPXpre:
839 case AArch64::STPXpre:
840 case AArch64::LDPSWpre:
841 case AArch64::LDPWpost:
842 case AArch64::STPWpost:
843 case AArch64::LDPWpre:
844 case AArch64::STPWpre:
845 case AArch64::LDPQpost:
846 case AArch64::STPQpost:
847 case AArch64::LDPQpre:
848 case AArch64::STPQpre:
849 case AArch64::LDPDpost:
850 case AArch64::STPDpost:
851 case AArch64::LDPDpre:
852 case AArch64::STPDpre:
853 case AArch64::LDPSpost:
854 case AArch64::STPSpost:
855 case AArch64::LDPSpre:
856 case AArch64::STPSpre:
857 case AArch64::STGPpre:
858 case AArch64::STGPpost:
859 case AArch64::LDTPpre:
860 case AArch64::LDTPpost:
861 case AArch64::LDTPQpost:
862 case AArch64::LDTPQpre:
863 case AArch64::STTPpost:
864 case AArch64::STTPpre:
865 case AArch64::STTPQpost:
866 case AArch64::STTPQpre:
868 Decoder);
869 break;
870 }
871
872 switch (Opcode) {
873 default:
874 return Fail;
875 case AArch64::LDPXpost:
876 case AArch64::STPXpost:
877 case AArch64::LDPSWpost:
878 case AArch64::LDPXpre:
879 case AArch64::STPXpre:
880 case AArch64::LDPSWpre:
881 case AArch64::STGPpre:
882 case AArch64::STGPpost:
883 case AArch64::LDTPpost:
884 case AArch64::LDTPpre:
885 case AArch64::STTPpost:
886 case AArch64::STTPpre:
887 NeedsDisjointWritebackTransfer = true;
888 [[fallthrough]];
889 case AArch64::LDNPXi:
890 case AArch64::STNPXi:
891 case AArch64::LDPXi:
892 case AArch64::STPXi:
893 case AArch64::LDPSWi:
894 case AArch64::STGPi:
895 case AArch64::LDTPi:
896 case AArch64::STTPi:
897 case AArch64::STTNPXi:
898 case AArch64::LDTNPXi:
900 Decoder);
902 Decoder);
903 break;
904 case AArch64::LDPWpost:
905 case AArch64::STPWpost:
906 case AArch64::LDPWpre:
907 case AArch64::STPWpre:
908 NeedsDisjointWritebackTransfer = true;
909 [[fallthrough]];
910 case AArch64::LDNPWi:
911 case AArch64::STNPWi:
912 case AArch64::LDPWi:
913 case AArch64::STPWi:
915 Decoder);
917 Decoder);
918 break;
919 case AArch64::LDNPQi:
920 case AArch64::STNPQi:
921 case AArch64::LDPQpost:
922 case AArch64::STPQpost:
923 case AArch64::LDPQi:
924 case AArch64::STPQi:
925 case AArch64::LDPQpre:
926 case AArch64::STPQpre:
927 case AArch64::LDTPQi:
928 case AArch64::LDTPQpost:
929 case AArch64::LDTPQpre:
930 case AArch64::LDTNPQi:
931 case AArch64::STTPQi:
932 case AArch64::STTPQpost:
933 case AArch64::STTPQpre:
934 case AArch64::STTNPQi:
936 Decoder);
938 Decoder);
939 break;
940 case AArch64::LDNPDi:
941 case AArch64::STNPDi:
942 case AArch64::LDPDpost:
943 case AArch64::STPDpost:
944 case AArch64::LDPDi:
945 case AArch64::STPDi:
946 case AArch64::LDPDpre:
947 case AArch64::STPDpre:
949 Decoder);
951 Decoder);
952 break;
953 case AArch64::LDNPSi:
954 case AArch64::STNPSi:
955 case AArch64::LDPSpost:
956 case AArch64::STPSpost:
957 case AArch64::LDPSi:
958 case AArch64::STPSi:
959 case AArch64::LDPSpre:
960 case AArch64::STPSpre:
962 Decoder);
964 Decoder);
965 break;
966 }
967
969 Decoder);
970 Inst.addOperand(MCOperand::createImm(offset));
971
972 // You shouldn't load to the same register twice in an instruction...
973 if (IsLoad && Rt == Rt2)
974 return SoftFail;
975
976 // ... or do any operation that writes-back to a transfer register. But note
977 // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.
978 if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn))
979 return SoftFail;
980
981 return Success;
982}
983
985 uint64_t Addr,
986 const MCDisassembler *Decoder) {
987 unsigned Rt = fieldFromInstruction(insn, 0, 5);
988 unsigned Rn = fieldFromInstruction(insn, 5, 5);
989 uint64_t offset = fieldFromInstruction(insn, 22, 1) << 9 |
990 fieldFromInstruction(insn, 12, 9);
991 unsigned writeback = fieldFromInstruction(insn, 11, 1);
992
993 switch (Inst.getOpcode()) {
994 default:
995 return Fail;
996 case AArch64::LDRAAwriteback:
997 case AArch64::LDRABwriteback:
999 Inst, Rn /* writeback register */, Addr, Decoder);
1000 break;
1001 case AArch64::LDRAAindexed:
1002 case AArch64::LDRABindexed:
1003 break;
1004 }
1005
1007 Decoder);
1009 Decoder);
1010 DecodeSImm<10>(Inst, offset, Addr, Decoder);
1011
1012 if (writeback && Rt == Rn && Rn != 31) {
1013 return SoftFail;
1014 }
1015
1016 return Success;
1017}
1018
1020 uint64_t Addr,
1021 const MCDisassembler *Decoder) {
1022 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1023 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1024 unsigned Rm = fieldFromInstruction(insn, 16, 5);
1025 unsigned extend = fieldFromInstruction(insn, 10, 6);
1026
1027 unsigned shift = extend & 0x7;
1028 if (shift > 4)
1029 return Fail;
1030
1031 switch (Inst.getOpcode()) {
1032 default:
1033 return Fail;
1034 case AArch64::ADDWrx:
1035 case AArch64::SUBWrx:
1037 Decoder);
1039 Decoder);
1041 Decoder);
1042 break;
1043 case AArch64::ADDSWrx:
1044 case AArch64::SUBSWrx:
1046 Decoder);
1048 Decoder);
1050 Decoder);
1051 break;
1052 case AArch64::ADDXrx:
1053 case AArch64::SUBXrx:
1055 Decoder);
1057 Decoder);
1059 Decoder);
1060 break;
1061 case AArch64::ADDSXrx:
1062 case AArch64::SUBSXrx:
1064 Decoder);
1066 Decoder);
1068 Decoder);
1069 break;
1070 case AArch64::ADDXrx64:
1071 case AArch64::SUBXrx64:
1073 Decoder);
1075 Decoder);
1077 Decoder);
1078 break;
1079 case AArch64::SUBSXrx64:
1080 case AArch64::ADDSXrx64:
1082 Decoder);
1084 Decoder);
1086 Decoder);
1087 break;
1088 }
1089
1090 Inst.addOperand(MCOperand::createImm(extend));
1091 return Success;
1092}
1093
1095 uint64_t Addr,
1096 const MCDisassembler *Decoder) {
1097 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1098 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1099 unsigned Datasize = fieldFromInstruction(insn, 31, 1);
1100 unsigned imm;
1101
1102 if (Datasize) {
1103 if (Inst.getOpcode() == AArch64::ANDSXri)
1105 Decoder);
1106 else
1108 Inst, Rd, Addr, Decoder);
1110 Decoder);
1111 imm = fieldFromInstruction(insn, 10, 13);
1113 return Fail;
1114 } else {
1115 if (Inst.getOpcode() == AArch64::ANDSWri)
1117 Decoder);
1118 else
1120 Inst, Rd, Addr, Decoder);
1122 Decoder);
1123 imm = fieldFromInstruction(insn, 10, 12);
1125 return Fail;
1126 }
1128 return Success;
1129}
1130
1132 uint64_t Addr,
1133 const MCDisassembler *Decoder) {
1134 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1135 unsigned cmode = fieldFromInstruction(insn, 12, 4);
1136 unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
1137 imm |= fieldFromInstruction(insn, 5, 5);
1138
1139 if (Inst.getOpcode() == AArch64::MOVID)
1141 Decoder);
1142 else
1144 Decoder);
1145
1147
1148 switch (Inst.getOpcode()) {
1149 default:
1150 break;
1151 case AArch64::MOVIv4i16:
1152 case AArch64::MOVIv8i16:
1153 case AArch64::MVNIv4i16:
1154 case AArch64::MVNIv8i16:
1155 case AArch64::MOVIv2i32:
1156 case AArch64::MOVIv4i32:
1157 case AArch64::MVNIv2i32:
1158 case AArch64::MVNIv4i32:
1159 Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
1160 break;
1161 case AArch64::MOVIv2s_msl:
1162 case AArch64::MOVIv4s_msl:
1163 case AArch64::MVNIv2s_msl:
1164 case AArch64::MVNIv4s_msl:
1165 Inst.addOperand(MCOperand::createImm((cmode & 1) ? 0x110 : 0x108));
1166 break;
1167 }
1168
1169 return Success;
1170}
1171
1173 uint64_t Addr,
1174 const MCDisassembler *Decoder) {
1175 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1176 unsigned cmode = fieldFromInstruction(insn, 12, 4);
1177 unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
1178 imm |= fieldFromInstruction(insn, 5, 5);
1179
1180 // Tied operands added twice.
1182 Decoder);
1184 Decoder);
1185
1187 Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
1188
1189 return Success;
1190}
1191
1193 uint64_t Addr,
1194 const MCDisassembler *Decoder) {
1195 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1196 int64_t imm = SignExtend64<21>((fieldFromInstruction(insn, 5, 19) << 2) |
1197 fieldFromInstruction(insn, 29, 2));
1198
1200 Decoder);
1201 if (!Decoder->tryAddingSymbolicOperand(Inst, imm, Addr, Fail, 0, 0, 4))
1203
1204 return Success;
1205}
1206
1208 uint64_t Addr,
1209 const MCDisassembler *Decoder) {
1210 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1211 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1212 unsigned Imm = fieldFromInstruction(insn, 10, 14);
1213 unsigned S = fieldFromInstruction(insn, 29, 1);
1214 unsigned Datasize = fieldFromInstruction(insn, 31, 1);
1215
1216 unsigned ShifterVal = (Imm >> 12) & 3;
1217 unsigned ImmVal = Imm & 0xFFF;
1218
1219 if (ShifterVal != 0 && ShifterVal != 1)
1220 return Fail;
1221
1222 if (Datasize) {
1223 if (Rd == 31 && !S)
1225 Inst, Rd, Addr, Decoder);
1226 else
1228 Decoder);
1230 Decoder);
1231 } else {
1232 if (Rd == 31 && !S)
1234 Inst, Rd, Addr, Decoder);
1235 else
1237 Decoder);
1239 Decoder);
1240 }
1241
1242 if (!Decoder->tryAddingSymbolicOperand(Inst, Imm, Addr, Fail, 0, 0, 4))
1243 Inst.addOperand(MCOperand::createImm(ImmVal));
1244 Inst.addOperand(MCOperand::createImm(12 * ShifterVal));
1245 return Success;
1246}
1247
1249 uint64_t Addr,
1250 const MCDisassembler *Decoder) {
1251 int64_t imm = SignExtend64<26>(fieldFromInstruction(insn, 0, 26));
1252
1253 if (!Decoder->tryAddingSymbolicOperand(Inst, imm * 4, Addr, true, 0, 0, 4))
1255
1256 return Success;
1257}
1258
1259static bool isInvalidPState(uint64_t Op1, uint64_t Op2) {
1260 return Op1 == 0b000 && (Op2 == 0b000 || // CFINV
1261 Op2 == 0b001 || // XAFlag
1262 Op2 == 0b010); // AXFlag
1263}
1264
1265static DecodeStatus
1267 const MCDisassembler *Decoder) {
1268 uint64_t op1 = fieldFromInstruction(insn, 16, 3);
1269 uint64_t op2 = fieldFromInstruction(insn, 5, 3);
1270 uint64_t imm = fieldFromInstruction(insn, 8, 4);
1271 uint64_t pstate_field = (op1 << 3) | op2;
1272
1273 if (isInvalidPState(op1, op2))
1274 return Fail;
1275
1276 Inst.addOperand(MCOperand::createImm(pstate_field));
1278
1279 auto PState = AArch64PState::lookupPStateImm0_15ByEncoding(pstate_field);
1280 if (PState &&
1281 PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits()))
1282 return Success;
1283 return Fail;
1284}
1285
1286static DecodeStatus
1288 const MCDisassembler *Decoder) {
1289 uint64_t op1 = fieldFromInstruction(insn, 16, 3);
1290 uint64_t op2 = fieldFromInstruction(insn, 5, 3);
1291 uint64_t crm_high = fieldFromInstruction(insn, 9, 3);
1292 uint64_t imm = fieldFromInstruction(insn, 8, 1);
1293 uint64_t pstate_field = (crm_high << 6) | (op1 << 3) | op2;
1294
1295 if (isInvalidPState(op1, op2))
1296 return Fail;
1297
1298 Inst.addOperand(MCOperand::createImm(pstate_field));
1300
1301 auto PState = AArch64PState::lookupPStateImm0_1ByEncoding(pstate_field);
1302 if (PState &&
1303 PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits()))
1304 return Success;
1305 return Fail;
1306}
1307
1309 uint64_t Addr,
1310 const MCDisassembler *Decoder) {
1311 uint64_t Rt = fieldFromInstruction(insn, 0, 5);
1312 uint64_t bit = fieldFromInstruction(insn, 31, 1) << 5;
1313 bit |= fieldFromInstruction(insn, 19, 5);
1314 int64_t dst = SignExtend64<14>(fieldFromInstruction(insn, 5, 14));
1315
1316 if (fieldFromInstruction(insn, 31, 1) == 0)
1318 Decoder);
1319 else
1321 Decoder);
1323 if (!Decoder->tryAddingSymbolicOperand(Inst, dst * 4, Addr, true, 0, 0, 4))
1325
1326 return Success;
1327}
1328
1329static DecodeStatus
1331 unsigned RegNo, uint64_t Addr,
1332 const MCDisassembler *Decoder) {
1333 // Register number must be even (see CASP instruction)
1334 if (RegNo & 0x1)
1335 return Fail;
1336
1337 MCRegister Reg = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo / 2);
1339 return Success;
1340}
1341
1342static DecodeStatus
1344 const MCDisassembler *Decoder) {
1346 Inst, AArch64::WSeqPairsClassRegClassID, RegNo, Addr, Decoder);
1347}
1348
1349static DecodeStatus
1351 const MCDisassembler *Decoder) {
1353 Inst, AArch64::XSeqPairsClassRegClassID, RegNo, Addr, Decoder);
1354}
1355
1357 uint64_t Addr,
1358 const MCDisassembler *Decoder) {
1359 unsigned op1 = fieldFromInstruction(insn, 16, 3);
1360 unsigned CRn = fieldFromInstruction(insn, 12, 4);
1361 unsigned CRm = fieldFromInstruction(insn, 8, 4);
1362 unsigned op2 = fieldFromInstruction(insn, 5, 3);
1363 unsigned Rt = fieldFromInstruction(insn, 0, 5);
1364 if (Rt != 0b11111)
1365 return Fail;
1366
1372 Decoder);
1373
1374 return Success;
1375}
1376
1377static DecodeStatus
1379 const MCDisassembler *Decoder) {
1380 unsigned Zdn = fieldFromInstruction(insn, 0, 5);
1381 unsigned imm = fieldFromInstruction(insn, 5, 13);
1383 return Fail;
1384
1385 // The same (tied) operand is added twice to the instruction.
1387 Decoder);
1388 if (Inst.getOpcode() != AArch64::DUPM_ZI)
1390 Decoder);
1392 return Success;
1393}
1394
1395template <int Bits>
1397 const MCDisassembler *Decoder) {
1398 if (Imm & ~((1LL << Bits) - 1))
1399 return Fail;
1400
1401 // Imm is a signed immediate, so sign extend it.
1402 if (Imm & (1 << (Bits - 1)))
1403 Imm |= ~((1LL << Bits) - 1);
1404
1406 return Success;
1407}
1408
1409// Decode 8-bit signed/unsigned immediate for a given element width.
1410template <int ElementWidth>
1411static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm, uint64_t Addr,
1412 const MCDisassembler *Decoder) {
1413 unsigned Val = (uint8_t)Imm;
1414 unsigned Shift = (Imm & 0x100) ? 8 : 0;
1415 if (ElementWidth == 8 && Shift)
1416 return Fail;
1418 Inst.addOperand(MCOperand::createImm(Shift));
1419 return Success;
1420}
1421
1422// Decode uimm4 ranged from 1-16.
1423static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,
1424 uint64_t Addr,
1425 const MCDisassembler *Decoder) {
1426 Inst.addOperand(MCOperand::createImm(Imm + 1));
1427 return Success;
1428}
1429
1430static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,
1431 const MCDisassembler *Decoder) {
1432 if (AArch64SVCR::lookupSVCRByEncoding(Imm)) {
1434 return Success;
1435 }
1436 return Fail;
1437}
1438
1440 uint64_t Addr,
1441 const MCDisassembler *Decoder) {
1442 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1443 unsigned Rs = fieldFromInstruction(insn, 16, 5);
1444 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1445
1446 // None of the registers may alias: if they do, then the instruction is not
1447 // merely unpredictable but actually entirely unallocated.
1448 if (Rd == Rs || Rs == Rn || Rd == Rn)
1449 return MCDisassembler::Fail;
1450
1451 // All three register operands are written back, so they all appear
1452 // twice in the operand list, once as outputs and once as inputs.
1454 Inst, Rd, Addr, Decoder) ||
1456 Inst, Rs, Addr, Decoder) ||
1458 Inst, Rn, Addr, Decoder) ||
1460 Inst, Rd, Addr, Decoder) ||
1462 Inst, Rs, Addr, Decoder) ||
1464 Inst, Rn, Addr, Decoder))
1465 return MCDisassembler::Fail;
1466
1468}
1469
1471 uint64_t Addr,
1472 const MCDisassembler *Decoder) {
1473 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1474 unsigned Rm = fieldFromInstruction(insn, 16, 5);
1475 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1476
1477 // None of the registers may alias: if they do, then the instruction is not
1478 // merely unpredictable but actually entirely unallocated.
1479 if (Rd == Rm || Rm == Rn || Rd == Rn)
1480 return MCDisassembler::Fail;
1481
1482 // Rd and Rn (not Rm) register operands are written back, so they appear
1483 // twice in the operand list, once as outputs and once as inputs.
1485 Inst, Rd, Addr, Decoder) ||
1487 Inst, Rn, Addr, Decoder) ||
1489 Inst, Rd, Addr, Decoder) ||
1491 Inst, Rn, Addr, Decoder) ||
1493 Inst, Rm, Addr, Decoder))
1494 return MCDisassembler::Fail;
1495
1497}
1498
1500 uint64_t Addr,
1501 const MCDisassembler *Decoder) {
1502 // PRFM with Rt = '11xxx' should be decoded as RPRFM.
1503 // Fail to decode and defer to fallback decoder table to decode RPRFM.
1504 unsigned Mask = 0x18;
1505 uint64_t Rt = fieldFromInstruction(insn, 0, 5);
1506 if ((Rt & Mask) == Mask)
1507 return Fail;
1508
1509 uint64_t Rn = fieldFromInstruction(insn, 5, 5);
1510 uint64_t Shift = fieldFromInstruction(insn, 12, 1);
1511 uint64_t Extend = fieldFromInstruction(insn, 15, 1);
1512 uint64_t Rm = fieldFromInstruction(insn, 16, 5);
1513
1516 Decoder);
1517
1518 switch (Inst.getOpcode()) {
1519 default:
1520 return Fail;
1521 case AArch64::PRFMroW:
1523 Decoder);
1524 break;
1525 case AArch64::PRFMroX:
1527 Decoder);
1528 break;
1529 }
1530
1531 DecodeMemExtend(Inst, (Extend << 1) | Shift, Addr, Decoder);
1532
1533 return Success;
1534}
1535
1536static DecodeStatus
1538 const MCDisassembler *Decoder) {
1539 unsigned RvBits = fieldFromInstruction(Bits, 13, 2);
1540 unsigned RnBits = fieldFromInstruction(Bits, 5, 5);
1541 unsigned Imm4Bits = fieldFromInstruction(Bits, 0, 4);
1542
1544 Inst, RvBits, Addr, Decoder);
1545 Inst.addOperand(MCOperand::createImm(Imm4Bits));
1547 Addr, Decoder);
1548 // Spill and fill instructions have a single immediate used for both
1549 // the vector select offset and optional memory offset. Replicate
1550 // the decoded immediate.
1551 Inst.addOperand(MCOperand::createImm(Imm4Bits));
1552 return Success;
1553}
1554
1555#include "AArch64GenDisassemblerTables.inc"
1556#include "AArch64GenInstrInfo.inc"
1557
1559 const MCSubtargetInfo &STI,
1560 MCContext &Ctx) {
1561
1562 return new AArch64Disassembler(STI, Ctx, T.createMCInstrInfo());
1563}
1564
1566 ArrayRef<uint8_t> Bytes,
1568 raw_ostream &CS) const {
1569 CommentStream = &CS;
1570
1571 Size = 0;
1572 // We want to read exactly 4 bytes of data.
1573 if (Bytes.size() < 4)
1574 return Fail;
1575 Size = 4;
1576
1577 // Encoded as a small-endian 32-bit word in the stream.
1578 uint32_t Insn =
1579 (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
1580
1581 const uint8_t *Tables[] = {DecoderTable32, DecoderTableFallback32};
1582
1583 for (const auto *Table : Tables) {
1584 DecodeStatus Result =
1585 decodeInstruction(Table, MI, Insn, Address, this, STI);
1586
1587 const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
1588
1589 // For Scalable Matrix Extension (SME) instructions that have an implicit
1590 // operand for the accumulator (ZA) or implicit immediate zero which isn't
1591 // encoded, manually insert operand.
1592 for (unsigned i = 0; i < Desc.getNumOperands(); i++) {
1593 if (Desc.operands()[i].OperandType == MCOI::OPERAND_REGISTER) {
1594 switch (Desc.operands()[i].RegClass) {
1595 default:
1596 break;
1597 case AArch64::MPRRegClassID:
1598 MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZA));
1599 break;
1600 case AArch64::MPR8RegClassID:
1601 MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZAB0));
1602 break;
1603 case AArch64::ZTRRegClassID:
1604 MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZT0));
1605 break;
1606 }
1607 } else if (Desc.operands()[i].OperandType ==
1609 MI.insert(MI.begin() + i, MCOperand::createImm(0));
1610 }
1611 }
1612
1613 if (Result != MCDisassembler::Fail)
1614 return Result;
1615 }
1616
1617 return MCDisassembler::Fail;
1618}
1619
1621 uint64_t Address) const {
1622 // AArch64 instructions are always 4 bytes wide, so there's no point
1623 // in skipping any smaller number of bytes if an instruction can't
1624 // be decoded.
1625 return 4;
1626}
1627
1628static MCSymbolizer *
1630 LLVMSymbolLookupCallback SymbolLookUp,
1631 void *DisInfo, MCContext *Ctx,
1632 std::unique_ptr<MCRelocationInfo> &&RelInfo) {
1633 return new AArch64ExternalSymbolizer(*Ctx, std::move(RelInfo), GetOpInfo,
1634 SymbolLookUp, DisInfo);
1635}
1636
1637extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn, uint64_t Addr, const MCDisassembler *Decoder)
static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm, uint64_t Addr, 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 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 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 const MCPhysReg MatrixZATileDecoderTable[5][16]
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)
#define SoftFail
static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder)
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 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 DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm, uint64_t Address, 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:41
size_t size() const
size - Get the array size.
Definition ArrayRef.h:147
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
Describe properties that are true of each instruction in the target description file.
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:33
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:19
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()
Op::Description Desc
Target & getTheAArch64leTarget()
Target & getTheAArch64_32Target()
Target & getTheARM64_32Target()
@ Add
Sum of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
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:583
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.