10b57cec5SDimitry Andric //===- AArch64Disassembler.cpp - Disassembler for AArch64 -----------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //
100b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
110b57cec5SDimitry Andric 
120b57cec5SDimitry Andric #include "AArch64Disassembler.h"
130b57cec5SDimitry Andric #include "AArch64ExternalSymbolizer.h"
140b57cec5SDimitry Andric #include "MCTargetDesc/AArch64AddressingModes.h"
150b57cec5SDimitry Andric #include "MCTargetDesc/AArch64MCTargetDesc.h"
160b57cec5SDimitry Andric #include "TargetInfo/AArch64TargetInfo.h"
170b57cec5SDimitry Andric #include "Utils/AArch64BaseInfo.h"
180b57cec5SDimitry Andric #include "llvm-c/Disassembler.h"
1981ad6265SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
2281ad6265SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
25349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
260b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
270b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
280b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
290b57cec5SDimitry Andric #include <algorithm>
300b57cec5SDimitry Andric #include <memory>
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric using namespace llvm;
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric #define DEBUG_TYPE "aarch64-disassembler"
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric // Pull DecodeStatus and its enum values into the global namespace.
370b57cec5SDimitry Andric using DecodeStatus = MCDisassembler::DecodeStatus;
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric // Forward declare these because the autogenerated code will reference them.
400b57cec5SDimitry Andric // Definitions are further down.
4181ad6265SDimitry Andric static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, unsigned RegNo,
420b57cec5SDimitry Andric                                               uint64_t Address,
4381ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
4481ad6265SDimitry Andric static DecodeStatus DecodeFPR128_loRegisterClass(MCInst &Inst, unsigned RegNo,
4581ad6265SDimitry Andric                                                  uint64_t Address,
4681ad6265SDimitry Andric                                                  const MCDisassembler *Decoder);
475f757f3fSDimitry Andric static DecodeStatus
485f757f3fSDimitry Andric DecodeFPR128_0to7RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
495f757f3fSDimitry Andric                                const MCDisassembler *Decoder);
500b57cec5SDimitry Andric static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, unsigned RegNo,
510b57cec5SDimitry Andric                                              uint64_t Address,
5281ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
530b57cec5SDimitry Andric static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, unsigned RegNo,
540b57cec5SDimitry Andric                                              uint64_t Address,
5581ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
560b57cec5SDimitry Andric static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, unsigned RegNo,
570b57cec5SDimitry Andric                                              uint64_t Address,
5881ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
590b57cec5SDimitry Andric static DecodeStatus DecodeFPR8RegisterClass(MCInst &Inst, unsigned RegNo,
600b57cec5SDimitry Andric                                             uint64_t Address,
6181ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
6281ad6265SDimitry Andric static DecodeStatus
6381ad6265SDimitry Andric DecodeGPR64commonRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
6481ad6265SDimitry Andric                                const MCDisassembler *Decoder);
650b57cec5SDimitry Andric static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
660b57cec5SDimitry Andric                                              uint64_t Address,
6781ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
6881ad6265SDimitry Andric static DecodeStatus
6981ad6265SDimitry Andric DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
7081ad6265SDimitry Andric                                 const MCDisassembler *Decoder);
7181ad6265SDimitry Andric static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst, unsigned RegNo,
72e8d8bef9SDimitry Andric                                                uint64_t Address,
7381ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
7481ad6265SDimitry Andric static DecodeStatus
75bdd1243dSDimitry Andric DecodeMatrixIndexGPR32_8_11RegisterClass(MCInst &Inst, unsigned RegNo,
76bdd1243dSDimitry Andric                                          uint64_t Address, const void *Decoder);
77bdd1243dSDimitry Andric static DecodeStatus
7881ad6265SDimitry Andric DecodeMatrixIndexGPR32_12_15RegisterClass(MCInst &Inst, unsigned RegNo,
79fe6060f1SDimitry Andric                                           uint64_t Address,
8081ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
810b57cec5SDimitry Andric static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
820b57cec5SDimitry Andric                                              uint64_t Address,
8381ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
8481ad6265SDimitry Andric static DecodeStatus DecodeGPR32spRegisterClass(MCInst &Inst, unsigned RegNo,
8581ad6265SDimitry Andric                                                uint64_t Address,
8681ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
870b57cec5SDimitry Andric static DecodeStatus DecodeQQRegisterClass(MCInst &Inst, unsigned RegNo,
880b57cec5SDimitry Andric                                           uint64_t Address,
8981ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
900b57cec5SDimitry Andric static DecodeStatus DecodeQQQRegisterClass(MCInst &Inst, unsigned RegNo,
910b57cec5SDimitry Andric                                            uint64_t Address,
9281ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
930b57cec5SDimitry Andric static DecodeStatus DecodeQQQQRegisterClass(MCInst &Inst, unsigned RegNo,
940b57cec5SDimitry Andric                                             uint64_t Address,
9581ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
960b57cec5SDimitry Andric static DecodeStatus DecodeDDRegisterClass(MCInst &Inst, unsigned RegNo,
970b57cec5SDimitry Andric                                           uint64_t Address,
9881ad6265SDimitry Andric                                           const MCDisassembler *Decoder);
990b57cec5SDimitry Andric static DecodeStatus DecodeDDDRegisterClass(MCInst &Inst, unsigned RegNo,
1000b57cec5SDimitry Andric                                            uint64_t Address,
10181ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
1020b57cec5SDimitry Andric static DecodeStatus DecodeDDDDRegisterClass(MCInst &Inst, unsigned RegNo,
1030b57cec5SDimitry Andric                                             uint64_t Address,
10481ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
1050b57cec5SDimitry Andric static DecodeStatus DecodeZPRRegisterClass(MCInst &Inst, unsigned RegNo,
1060b57cec5SDimitry Andric                                            uint64_t Address,
10781ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
1080b57cec5SDimitry Andric static DecodeStatus DecodeZPR_4bRegisterClass(MCInst &Inst, unsigned RegNo,
1090b57cec5SDimitry Andric                                               uint64_t Address,
11081ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
1110b57cec5SDimitry Andric static DecodeStatus DecodeZPR_3bRegisterClass(MCInst &Inst, unsigned RegNo,
1120b57cec5SDimitry Andric                                               uint64_t Address,
11381ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
1140b57cec5SDimitry Andric static DecodeStatus DecodeZPR2RegisterClass(MCInst &Inst, unsigned RegNo,
1150b57cec5SDimitry Andric                                             uint64_t Address,
11681ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
1170b57cec5SDimitry Andric static DecodeStatus DecodeZPR3RegisterClass(MCInst &Inst, unsigned RegNo,
1180b57cec5SDimitry Andric                                             uint64_t Address,
11981ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
1200b57cec5SDimitry Andric static DecodeStatus DecodeZPR4RegisterClass(MCInst &Inst, unsigned RegNo,
1210b57cec5SDimitry Andric                                             uint64_t Address,
12281ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
123bdd1243dSDimitry Andric static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
124bdd1243dSDimitry Andric                                                 uint64_t Address,
125bdd1243dSDimitry Andric                                                 const void *Decoder);
126bdd1243dSDimitry Andric static DecodeStatus DecodeZPR4Mul4RegisterClass(MCInst &Inst, unsigned RegNo,
127bdd1243dSDimitry Andric                                                 uint64_t Address,
128bdd1243dSDimitry Andric                                                 const void *Decoder);
129bdd1243dSDimitry Andric static DecodeStatus DecodeZPR2StridedRegisterClass(MCInst &Inst, unsigned RegNo,
130bdd1243dSDimitry Andric                                                    uint64_t Address,
131bdd1243dSDimitry Andric                                                    const void *Decoder);
132bdd1243dSDimitry Andric static DecodeStatus DecodeZPR4StridedRegisterClass(MCInst &Inst, unsigned RegNo,
133bdd1243dSDimitry Andric                                                    uint64_t Address,
134bdd1243dSDimitry Andric                                                    const void *Decoder);
135fe6060f1SDimitry Andric template <unsigned NumBitsForTile>
136fe6060f1SDimitry Andric static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo,
137fe6060f1SDimitry Andric                                      uint64_t Address,
13881ad6265SDimitry Andric                                      const MCDisassembler *Decoder);
13981ad6265SDimitry Andric static DecodeStatus
14081ad6265SDimitry Andric DecodeMatrixTileListRegisterClass(MCInst &Inst, unsigned RegMask,
14181ad6265SDimitry Andric                                   uint64_t Address,
14281ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
1430b57cec5SDimitry Andric static DecodeStatus DecodePPRRegisterClass(MCInst &Inst, unsigned RegNo,
1440b57cec5SDimitry Andric                                            uint64_t Address,
14581ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
1465f757f3fSDimitry Andric static DecodeStatus DecodePNRRegisterClass(MCInst &Inst, unsigned RegNo,
1475f757f3fSDimitry Andric                                            uint64_t Address,
1485f757f3fSDimitry Andric                                            const MCDisassembler *Decoder);
1490b57cec5SDimitry Andric static DecodeStatus DecodePPR_3bRegisterClass(MCInst &Inst, unsigned RegNo,
1500b57cec5SDimitry Andric                                               uint64_t Address,
15181ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
152bdd1243dSDimitry Andric static DecodeStatus
1535f757f3fSDimitry Andric DecodePNR_p8to15RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
154bdd1243dSDimitry Andric                               const MCDisassembler *Decoder);
155bdd1243dSDimitry Andric static DecodeStatus DecodePPR2RegisterClass(MCInst &Inst, unsigned RegNo,
156bdd1243dSDimitry Andric                                             uint64_t Address,
157bdd1243dSDimitry Andric                                             const void *Decoder);
158bdd1243dSDimitry Andric static DecodeStatus DecodePPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
159bdd1243dSDimitry Andric                                                 uint64_t Address,
160bdd1243dSDimitry Andric                                                 const void *Decoder);
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm,
1630b57cec5SDimitry Andric                                                uint64_t Address,
16481ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1650b57cec5SDimitry Andric static DecodeStatus DecodeFixedPointScaleImm64(MCInst &Inst, unsigned Imm,
1660b57cec5SDimitry Andric                                                uint64_t Address,
16781ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
168cb14a3feSDimitry Andric static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm,
169cb14a3feSDimitry Andric                                        uint64_t Address,
170cb14a3feSDimitry Andric                                        const MCDisassembler *Decoder);
1710b57cec5SDimitry Andric static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
1720b57cec5SDimitry Andric                                        uint64_t Address,
17381ad6265SDimitry Andric                                        const MCDisassembler *Decoder);
17481ad6265SDimitry Andric static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
17581ad6265SDimitry Andric                                     uint64_t Address,
17681ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
17781ad6265SDimitry Andric static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm,
17881ad6265SDimitry Andric                                             uint64_t Address,
17981ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
18081ad6265SDimitry Andric static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm,
18181ad6265SDimitry Andric                                             uint64_t Address,
18281ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
18381ad6265SDimitry Andric static DecodeStatus
18481ad6265SDimitry Andric DecodeThreeAddrSRegInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
18581ad6265SDimitry Andric                                const MCDisassembler *Decoder);
1860b57cec5SDimitry Andric static DecodeStatus DecodeMoveImmInstruction(MCInst &Inst, uint32_t insn,
1870b57cec5SDimitry Andric                                              uint64_t Address,
18881ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
18981ad6265SDimitry Andric static DecodeStatus
19081ad6265SDimitry Andric DecodeUnsignedLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
19181ad6265SDimitry Andric                               const MCDisassembler *Decoder);
1920b57cec5SDimitry Andric static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
1930b57cec5SDimitry Andric                                                 uint64_t Address,
19481ad6265SDimitry Andric                                                 const MCDisassembler *Decoder);
19581ad6265SDimitry Andric static DecodeStatus
19681ad6265SDimitry Andric DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
19781ad6265SDimitry Andric                                const MCDisassembler *Decoder);
1980b57cec5SDimitry Andric static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,
1990b57cec5SDimitry Andric                                               uint64_t Address,
20081ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
2015ffd83dbSDimitry Andric static DecodeStatus DecodeAuthLoadInstruction(MCInst &Inst, uint32_t insn,
2025ffd83dbSDimitry Andric                                               uint64_t Address,
20381ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
2040b57cec5SDimitry Andric static DecodeStatus DecodeAddSubERegInstruction(MCInst &Inst, uint32_t insn,
2050b57cec5SDimitry Andric                                                 uint64_t Address,
20681ad6265SDimitry Andric                                                 const MCDisassembler *Decoder);
2070b57cec5SDimitry Andric static DecodeStatus DecodeLogicalImmInstruction(MCInst &Inst, uint32_t insn,
2080b57cec5SDimitry Andric                                                 uint64_t Address,
20981ad6265SDimitry Andric                                                 const MCDisassembler *Decoder);
2100b57cec5SDimitry Andric static DecodeStatus DecodeModImmInstruction(MCInst &Inst, uint32_t insn,
2110b57cec5SDimitry Andric                                             uint64_t Address,
21281ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
2130b57cec5SDimitry Andric static DecodeStatus DecodeModImmTiedInstruction(MCInst &Inst, uint32_t insn,
2140b57cec5SDimitry Andric                                                 uint64_t Address,
21581ad6265SDimitry Andric                                                 const MCDisassembler *Decoder);
2160b57cec5SDimitry Andric static DecodeStatus DecodeAdrInstruction(MCInst &Inst, uint32_t insn,
21781ad6265SDimitry Andric                                          uint64_t Address,
21881ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
2190b57cec5SDimitry Andric static DecodeStatus DecodeAddSubImmShift(MCInst &Inst, uint32_t insn,
22081ad6265SDimitry Andric                                          uint64_t Address,
22181ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
2220b57cec5SDimitry Andric static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn,
2230b57cec5SDimitry Andric                                               uint64_t Address,
22481ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
22581ad6265SDimitry Andric static DecodeStatus
226bdd1243dSDimitry Andric DecodeSystemPStateImm0_15Instruction(MCInst &Inst, uint32_t insn,
227bdd1243dSDimitry Andric                                      uint64_t Address,
228bdd1243dSDimitry Andric                                      const MCDisassembler *Decoder);
229bdd1243dSDimitry Andric static DecodeStatus
230bdd1243dSDimitry Andric DecodeSystemPStateImm0_1Instruction(MCInst &Inst, uint32_t insn,
231bdd1243dSDimitry Andric                                     uint64_t Address,
23281ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
2330b57cec5SDimitry Andric static DecodeStatus DecodeTestAndBranch(MCInst &Inst, uint32_t insn,
23481ad6265SDimitry Andric                                         uint64_t Address,
23581ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
2360b57cec5SDimitry Andric 
2370b57cec5SDimitry Andric static DecodeStatus DecodeFMOVLaneInstruction(MCInst &Inst, unsigned Insn,
2380b57cec5SDimitry Andric                                               uint64_t Address,
23981ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
2400b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm,
24181ad6265SDimitry Andric                                          uint64_t Addr,
24281ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
2430b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst &Inst, unsigned Imm,
2440b57cec5SDimitry Andric                                                uint64_t Addr,
24581ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
2460b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm,
24781ad6265SDimitry Andric                                          uint64_t Addr,
24881ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
2490b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst &Inst, unsigned Imm,
2500b57cec5SDimitry Andric                                                uint64_t Addr,
25181ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
2520b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm,
25381ad6265SDimitry Andric                                          uint64_t Addr,
25481ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
2550b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst &Inst, unsigned Imm,
2560b57cec5SDimitry Andric                                                uint64_t Addr,
25781ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
2580b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm,
25981ad6265SDimitry Andric                                         uint64_t Addr,
26081ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
2610b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm,
26281ad6265SDimitry Andric                                          uint64_t Addr,
26381ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
2640b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm,
26581ad6265SDimitry Andric                                          uint64_t Addr,
26681ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
2670b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm,
26881ad6265SDimitry Andric                                          uint64_t Addr,
26981ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
2700b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm,
2710b57cec5SDimitry Andric                                         uint64_t Addr,
27281ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
27381ad6265SDimitry Andric static DecodeStatus
27481ad6265SDimitry Andric DecodeWSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
27581ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
27681ad6265SDimitry Andric static DecodeStatus
27781ad6265SDimitry Andric DecodeXSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
27881ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
279bdd1243dSDimitry Andric static DecodeStatus DecodeSyspXzrInstruction(MCInst &Inst, uint32_t insn,
280bdd1243dSDimitry Andric                                              uint64_t Addr,
281bdd1243dSDimitry Andric                                              const MCDisassembler *Decoder);
28281ad6265SDimitry Andric static DecodeStatus
28381ad6265SDimitry Andric DecodeSVELogicalImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
28481ad6265SDimitry Andric                                const MCDisassembler *Decoder);
2850b57cec5SDimitry Andric template <int Bits>
286349cc55cSDimitry Andric static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
28781ad6265SDimitry Andric                                const MCDisassembler *Decoder);
2880b57cec5SDimitry Andric template <int ElementWidth>
28981ad6265SDimitry Andric static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm, uint64_t Addr,
29081ad6265SDimitry Andric                                      const MCDisassembler *Decoder);
2910b57cec5SDimitry Andric static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,
29281ad6265SDimitry Andric                                        uint64_t Addr,
29381ad6265SDimitry Andric                                        const MCDisassembler *Decoder);
294fe6060f1SDimitry Andric static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,
29581ad6265SDimitry Andric                                  const MCDisassembler *Decoder);
29604eeddc0SDimitry Andric static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn,
29704eeddc0SDimitry Andric                                               uint64_t Addr,
29881ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
29904eeddc0SDimitry Andric static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn,
30004eeddc0SDimitry Andric                                               uint64_t Addr,
30181ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
302bdd1243dSDimitry Andric static DecodeStatus DecodePRFMRegInstruction(MCInst &Inst, uint32_t insn,
303bdd1243dSDimitry Andric                                              uint64_t Address,
304bdd1243dSDimitry Andric                                              const MCDisassembler *Decoder);
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric #include "AArch64GenDisassemblerTables.inc"
3070b57cec5SDimitry Andric #include "AArch64GenInstrInfo.inc"
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric #define Success MCDisassembler::Success
3100b57cec5SDimitry Andric #define Fail MCDisassembler::Fail
3110b57cec5SDimitry Andric #define SoftFail MCDisassembler::SoftFail
3120b57cec5SDimitry Andric 
createAArch64Disassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)3130b57cec5SDimitry Andric static MCDisassembler *createAArch64Disassembler(const Target &T,
3140b57cec5SDimitry Andric                                                const MCSubtargetInfo &STI,
3150b57cec5SDimitry Andric                                                MCContext &Ctx) {
31681ad6265SDimitry Andric 
31781ad6265SDimitry Andric   return new AArch64Disassembler(STI, Ctx, T.createMCInstrInfo());
3180b57cec5SDimitry Andric }
3190b57cec5SDimitry Andric 
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const3200b57cec5SDimitry Andric DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
3210b57cec5SDimitry Andric                                                  ArrayRef<uint8_t> Bytes,
3220b57cec5SDimitry Andric                                                  uint64_t Address,
3230b57cec5SDimitry Andric                                                  raw_ostream &CS) const {
3240b57cec5SDimitry Andric   CommentStream = &CS;
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric   Size = 0;
3270b57cec5SDimitry Andric   // We want to read exactly 4 bytes of data.
3280b57cec5SDimitry Andric   if (Bytes.size() < 4)
3290b57cec5SDimitry Andric     return Fail;
3300b57cec5SDimitry Andric   Size = 4;
3310b57cec5SDimitry Andric 
3320b57cec5SDimitry Andric   // Encoded as a small-endian 32-bit word in the stream.
3330b57cec5SDimitry Andric   uint32_t Insn =
3340b57cec5SDimitry Andric       (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
3350b57cec5SDimitry Andric 
336e8d8bef9SDimitry Andric   const uint8_t *Tables[] = {DecoderTable32, DecoderTableFallback32};
337e8d8bef9SDimitry Andric 
338bdd1243dSDimitry Andric   for (const auto *Table : Tables) {
339e8d8bef9SDimitry Andric     DecodeStatus Result =
340e8d8bef9SDimitry Andric         decodeInstruction(Table, MI, Insn, Address, this, STI);
341fe6060f1SDimitry Andric 
34281ad6265SDimitry Andric     const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
34381ad6265SDimitry Andric 
34481ad6265SDimitry Andric     // For Scalable Matrix Extension (SME) instructions that have an implicit
34581ad6265SDimitry Andric     // operand for the accumulator (ZA) or implicit immediate zero which isn't
34681ad6265SDimitry Andric     // encoded, manually insert operand.
34781ad6265SDimitry Andric     for (unsigned i = 0; i < Desc.getNumOperands(); i++) {
348bdd1243dSDimitry Andric       if (Desc.operands()[i].OperandType == MCOI::OPERAND_REGISTER) {
349bdd1243dSDimitry Andric         switch (Desc.operands()[i].RegClass) {
350fe6060f1SDimitry Andric         default:
351fe6060f1SDimitry Andric           break;
35281ad6265SDimitry Andric         case AArch64::MPRRegClassID:
35381ad6265SDimitry Andric           MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZA));
35481ad6265SDimitry Andric           break;
35581ad6265SDimitry Andric         case AArch64::MPR8RegClassID:
35681ad6265SDimitry Andric           MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZAB0));
35781ad6265SDimitry Andric           break;
358bdd1243dSDimitry Andric         case AArch64::ZTRRegClassID:
359bdd1243dSDimitry Andric           MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZT0));
360bdd1243dSDimitry Andric           break;
36181ad6265SDimitry Andric         }
362bdd1243dSDimitry Andric       } else if (Desc.operands()[i].OperandType ==
36381ad6265SDimitry Andric                  AArch64::OPERAND_IMPLICIT_IMM_0) {
36481ad6265SDimitry Andric         MI.insert(MI.begin() + i, MCOperand::createImm(0));
36581ad6265SDimitry Andric       }
36681ad6265SDimitry Andric     }
36781ad6265SDimitry Andric 
36881ad6265SDimitry Andric     if (MI.getOpcode() == AArch64::LDR_ZA ||
36981ad6265SDimitry Andric         MI.getOpcode() == AArch64::STR_ZA) {
37081ad6265SDimitry Andric       // Spill and fill instructions have a single immediate used for both
37181ad6265SDimitry Andric       // the vector select offset and optional memory offset. Replicate
37281ad6265SDimitry Andric       // the decoded immediate.
373fe6060f1SDimitry Andric       const MCOperand &Imm4Op = MI.getOperand(2);
374fe6060f1SDimitry Andric       assert(Imm4Op.isImm() && "Unexpected operand type!");
375fe6060f1SDimitry Andric       MI.addOperand(Imm4Op);
376fe6060f1SDimitry Andric     }
377fe6060f1SDimitry Andric 
378e8d8bef9SDimitry Andric     if (Result != MCDisassembler::Fail)
379e8d8bef9SDimitry Andric       return Result;
380e8d8bef9SDimitry Andric   }
381e8d8bef9SDimitry Andric 
382e8d8bef9SDimitry Andric   return MCDisassembler::Fail;
3830b57cec5SDimitry Andric }
3840b57cec5SDimitry Andric 
suggestBytesToSkip(ArrayRef<uint8_t> Bytes,uint64_t Address) const385972a253aSDimitry Andric uint64_t AArch64Disassembler::suggestBytesToSkip(ArrayRef<uint8_t> Bytes,
386972a253aSDimitry Andric                                                  uint64_t Address) const {
387972a253aSDimitry Andric   // AArch64 instructions are always 4 bytes wide, so there's no point
388972a253aSDimitry Andric   // in skipping any smaller number of bytes if an instruction can't
389972a253aSDimitry Andric   // be decoded.
390972a253aSDimitry Andric   return 4;
391972a253aSDimitry Andric }
392972a253aSDimitry Andric 
3930b57cec5SDimitry Andric static MCSymbolizer *
createAArch64ExternalSymbolizer(const Triple & TT,LLVMOpInfoCallback GetOpInfo,LLVMSymbolLookupCallback SymbolLookUp,void * DisInfo,MCContext * Ctx,std::unique_ptr<MCRelocationInfo> && RelInfo)3940b57cec5SDimitry Andric createAArch64ExternalSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,
3950b57cec5SDimitry Andric                                 LLVMSymbolLookupCallback SymbolLookUp,
3960b57cec5SDimitry Andric                                 void *DisInfo, MCContext *Ctx,
3970b57cec5SDimitry Andric                                 std::unique_ptr<MCRelocationInfo> &&RelInfo) {
3980b57cec5SDimitry Andric   return new AArch64ExternalSymbolizer(*Ctx, std::move(RelInfo), GetOpInfo,
3990b57cec5SDimitry Andric                                        SymbolLookUp, DisInfo);
4000b57cec5SDimitry Andric }
4010b57cec5SDimitry Andric 
LLVMInitializeAArch64Disassembler()402480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Disassembler() {
4030b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheAArch64leTarget(),
4040b57cec5SDimitry Andric                                          createAArch64Disassembler);
4050b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheAArch64beTarget(),
4060b57cec5SDimitry Andric                                          createAArch64Disassembler);
4070b57cec5SDimitry Andric   TargetRegistry::RegisterMCSymbolizer(getTheAArch64leTarget(),
4080b57cec5SDimitry Andric                                        createAArch64ExternalSymbolizer);
4090b57cec5SDimitry Andric   TargetRegistry::RegisterMCSymbolizer(getTheAArch64beTarget(),
4100b57cec5SDimitry Andric                                        createAArch64ExternalSymbolizer);
4110b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheAArch64_32Target(),
4120b57cec5SDimitry Andric                                          createAArch64Disassembler);
4130b57cec5SDimitry Andric   TargetRegistry::RegisterMCSymbolizer(getTheAArch64_32Target(),
4140b57cec5SDimitry Andric                                        createAArch64ExternalSymbolizer);
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheARM64Target(),
4170b57cec5SDimitry Andric                                          createAArch64Disassembler);
4180b57cec5SDimitry Andric   TargetRegistry::RegisterMCSymbolizer(getTheARM64Target(),
4190b57cec5SDimitry Andric                                        createAArch64ExternalSymbolizer);
4200b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheARM64_32Target(),
4210b57cec5SDimitry Andric                                          createAArch64Disassembler);
4220b57cec5SDimitry Andric   TargetRegistry::RegisterMCSymbolizer(getTheARM64_32Target(),
4230b57cec5SDimitry Andric                                        createAArch64ExternalSymbolizer);
4240b57cec5SDimitry Andric }
4250b57cec5SDimitry Andric 
DecodeFPR128RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)4260b57cec5SDimitry Andric static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, unsigned RegNo,
4270b57cec5SDimitry Andric                                               uint64_t Addr,
42881ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
4290b57cec5SDimitry Andric   if (RegNo > 31)
4300b57cec5SDimitry Andric     return Fail;
4310b57cec5SDimitry Andric 
432349cc55cSDimitry Andric   unsigned Register =
433349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::FPR128RegClassID].getRegister(RegNo);
4340b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
4350b57cec5SDimitry Andric   return Success;
4360b57cec5SDimitry Andric }
4370b57cec5SDimitry Andric 
43881ad6265SDimitry Andric static DecodeStatus
DecodeFPR128_loRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)43981ad6265SDimitry Andric DecodeFPR128_loRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
44081ad6265SDimitry Andric                              const MCDisassembler *Decoder) {
4410b57cec5SDimitry Andric   if (RegNo > 15)
4420b57cec5SDimitry Andric     return Fail;
4430b57cec5SDimitry Andric   return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder);
4440b57cec5SDimitry Andric }
4450b57cec5SDimitry Andric 
4465f757f3fSDimitry Andric static DecodeStatus
DecodeFPR128_0to7RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)4475f757f3fSDimitry Andric DecodeFPR128_0to7RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
4485f757f3fSDimitry Andric                                const MCDisassembler *Decoder) {
4495f757f3fSDimitry Andric   if (RegNo > 7)
4505f757f3fSDimitry Andric     return Fail;
4515f757f3fSDimitry Andric   return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder);
4525f757f3fSDimitry Andric }
4535f757f3fSDimitry Andric 
DecodeFPR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)4540b57cec5SDimitry Andric static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, unsigned RegNo,
4550b57cec5SDimitry Andric                                              uint64_t Addr,
45681ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
4570b57cec5SDimitry Andric   if (RegNo > 31)
4580b57cec5SDimitry Andric     return Fail;
4590b57cec5SDimitry Andric 
460349cc55cSDimitry Andric   unsigned Register =
461349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::FPR64RegClassID].getRegister(RegNo);
4620b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
4630b57cec5SDimitry Andric   return Success;
4640b57cec5SDimitry Andric }
4650b57cec5SDimitry Andric 
DecodeFPR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)4660b57cec5SDimitry Andric static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, unsigned RegNo,
4670b57cec5SDimitry Andric                                              uint64_t Addr,
46881ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
4690b57cec5SDimitry Andric   if (RegNo > 31)
4700b57cec5SDimitry Andric     return Fail;
4710b57cec5SDimitry Andric 
472349cc55cSDimitry Andric   unsigned Register =
473349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::FPR32RegClassID].getRegister(RegNo);
4740b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
4750b57cec5SDimitry Andric   return Success;
4760b57cec5SDimitry Andric }
4770b57cec5SDimitry Andric 
DecodeFPR16RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)4780b57cec5SDimitry Andric static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, unsigned RegNo,
4790b57cec5SDimitry Andric                                              uint64_t Addr,
48081ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
4810b57cec5SDimitry Andric   if (RegNo > 31)
4820b57cec5SDimitry Andric     return Fail;
4830b57cec5SDimitry Andric 
484349cc55cSDimitry Andric   unsigned Register =
485349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::FPR16RegClassID].getRegister(RegNo);
4860b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
4870b57cec5SDimitry Andric   return Success;
4880b57cec5SDimitry Andric }
4890b57cec5SDimitry Andric 
DecodeFPR8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)4900b57cec5SDimitry Andric static DecodeStatus DecodeFPR8RegisterClass(MCInst &Inst, unsigned RegNo,
4910b57cec5SDimitry Andric                                             uint64_t Addr,
49281ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
4930b57cec5SDimitry Andric   if (RegNo > 31)
4940b57cec5SDimitry Andric     return Fail;
4950b57cec5SDimitry Andric 
496349cc55cSDimitry Andric   unsigned Register =
497349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::FPR8RegClassID].getRegister(RegNo);
4980b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
4990b57cec5SDimitry Andric   return Success;
5000b57cec5SDimitry Andric }
5010b57cec5SDimitry Andric 
50281ad6265SDimitry Andric static DecodeStatus
DecodeGPR64commonRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)50381ad6265SDimitry Andric DecodeGPR64commonRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
50481ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
5050b57cec5SDimitry Andric   if (RegNo > 30)
5060b57cec5SDimitry Andric     return Fail;
5070b57cec5SDimitry Andric 
508349cc55cSDimitry Andric   unsigned Register =
509349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::GPR64commonRegClassID].getRegister(
510349cc55cSDimitry Andric           RegNo);
5110b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
5120b57cec5SDimitry Andric   return Success;
5130b57cec5SDimitry Andric }
5140b57cec5SDimitry Andric 
DecodeGPR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)5150b57cec5SDimitry Andric static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
5160b57cec5SDimitry Andric                                              uint64_t Addr,
51781ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
5180b57cec5SDimitry Andric   if (RegNo > 31)
5190b57cec5SDimitry Andric     return Fail;
5200b57cec5SDimitry Andric 
521349cc55cSDimitry Andric   unsigned Register =
522349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::GPR64RegClassID].getRegister(RegNo);
5230b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
5240b57cec5SDimitry Andric   return Success;
5250b57cec5SDimitry Andric }
5260b57cec5SDimitry Andric 
52781ad6265SDimitry Andric static DecodeStatus
DecodeGPR64x8ClassRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)52881ad6265SDimitry Andric DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
52981ad6265SDimitry Andric                                 const MCDisassembler *Decoder) {
530e8d8bef9SDimitry Andric   if (RegNo > 22)
531e8d8bef9SDimitry Andric     return Fail;
532e8d8bef9SDimitry Andric   if (RegNo & 1)
533e8d8bef9SDimitry Andric     return Fail;
534e8d8bef9SDimitry Andric 
535349cc55cSDimitry Andric   unsigned Register =
536349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].getRegister(
537349cc55cSDimitry Andric           RegNo >> 1);
538e8d8bef9SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
539e8d8bef9SDimitry Andric   return Success;
540e8d8bef9SDimitry Andric }
541e8d8bef9SDimitry Andric 
DecodeGPR64spRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)5420b57cec5SDimitry Andric static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst, unsigned RegNo,
5430b57cec5SDimitry Andric                                                uint64_t Addr,
54481ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
5450b57cec5SDimitry Andric   if (RegNo > 31)
5460b57cec5SDimitry Andric     return Fail;
547349cc55cSDimitry Andric   unsigned Register =
548349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::GPR64spRegClassID].getRegister(RegNo);
5490b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
5500b57cec5SDimitry Andric   return Success;
5510b57cec5SDimitry Andric }
5520b57cec5SDimitry Andric 
55381ad6265SDimitry Andric static DecodeStatus
DecodeMatrixIndexGPR32_8_11RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)554bdd1243dSDimitry Andric DecodeMatrixIndexGPR32_8_11RegisterClass(MCInst &Inst, unsigned RegNo,
555bdd1243dSDimitry Andric                                          uint64_t Addr, const void *Decoder) {
556bdd1243dSDimitry Andric   if (RegNo > 3)
557bdd1243dSDimitry Andric     return Fail;
558bdd1243dSDimitry Andric 
559bdd1243dSDimitry Andric   unsigned Register =
560bdd1243dSDimitry Andric       AArch64MCRegisterClasses[AArch64::MatrixIndexGPR32_8_11RegClassID]
561bdd1243dSDimitry Andric           .getRegister(RegNo);
562bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
563bdd1243dSDimitry Andric   return Success;
564bdd1243dSDimitry Andric }
565bdd1243dSDimitry Andric 
566bdd1243dSDimitry Andric static DecodeStatus
DecodeMatrixIndexGPR32_12_15RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)56781ad6265SDimitry Andric DecodeMatrixIndexGPR32_12_15RegisterClass(MCInst &Inst, unsigned RegNo,
568fe6060f1SDimitry Andric                                           uint64_t Addr,
56981ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
570fe6060f1SDimitry Andric   if (RegNo > 3)
571fe6060f1SDimitry Andric     return Fail;
572fe6060f1SDimitry Andric 
573349cc55cSDimitry Andric   unsigned Register =
574349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::MatrixIndexGPR32_12_15RegClassID]
575349cc55cSDimitry Andric           .getRegister(RegNo);
576fe6060f1SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
577fe6060f1SDimitry Andric   return Success;
578fe6060f1SDimitry Andric }
579fe6060f1SDimitry Andric 
DecodeGPR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)5800b57cec5SDimitry Andric static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
5810b57cec5SDimitry Andric                                              uint64_t Addr,
58281ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
5830b57cec5SDimitry Andric   if (RegNo > 31)
5840b57cec5SDimitry Andric     return Fail;
5850b57cec5SDimitry Andric 
586349cc55cSDimitry Andric   unsigned Register =
587349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::GPR32RegClassID].getRegister(RegNo);
5880b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
5890b57cec5SDimitry Andric   return Success;
5900b57cec5SDimitry Andric }
5910b57cec5SDimitry Andric 
DecodeGPR32spRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)5920b57cec5SDimitry Andric static DecodeStatus DecodeGPR32spRegisterClass(MCInst &Inst, unsigned RegNo,
5930b57cec5SDimitry Andric                                                uint64_t Addr,
59481ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
5950b57cec5SDimitry Andric   if (RegNo > 31)
5960b57cec5SDimitry Andric     return Fail;
5970b57cec5SDimitry Andric 
598349cc55cSDimitry Andric   unsigned Register =
599349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::GPR32spRegClassID].getRegister(RegNo);
6000b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
6010b57cec5SDimitry Andric   return Success;
6020b57cec5SDimitry Andric }
6030b57cec5SDimitry Andric 
DecodeZPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6040b57cec5SDimitry Andric static DecodeStatus DecodeZPRRegisterClass(MCInst &Inst, unsigned RegNo,
6050b57cec5SDimitry Andric                                            uint64_t Address,
60681ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
6070b57cec5SDimitry Andric   if (RegNo > 31)
6080b57cec5SDimitry Andric     return Fail;
6090b57cec5SDimitry Andric 
610349cc55cSDimitry Andric   unsigned Register =
611349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::ZPRRegClassID].getRegister(RegNo);
6120b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
6130b57cec5SDimitry Andric   return Success;
6140b57cec5SDimitry Andric }
6150b57cec5SDimitry Andric 
DecodeZPR_4bRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6160b57cec5SDimitry Andric static DecodeStatus DecodeZPR_4bRegisterClass(MCInst &Inst, unsigned RegNo,
6170b57cec5SDimitry Andric                                               uint64_t Address,
61881ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
6190b57cec5SDimitry Andric   if (RegNo > 15)
6200b57cec5SDimitry Andric     return Fail;
6210b57cec5SDimitry Andric   return DecodeZPRRegisterClass(Inst, RegNo, Address, Decoder);
6220b57cec5SDimitry Andric }
6230b57cec5SDimitry Andric 
DecodeZPR_3bRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6240b57cec5SDimitry Andric static DecodeStatus DecodeZPR_3bRegisterClass(MCInst &Inst, unsigned RegNo,
6250b57cec5SDimitry Andric                                               uint64_t Address,
62681ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
6270b57cec5SDimitry Andric   if (RegNo > 7)
6280b57cec5SDimitry Andric     return Fail;
6290b57cec5SDimitry Andric   return DecodeZPRRegisterClass(Inst, RegNo, Address, Decoder);
6300b57cec5SDimitry Andric }
6310b57cec5SDimitry Andric 
DecodeZPR2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6320b57cec5SDimitry Andric static DecodeStatus DecodeZPR2RegisterClass(MCInst &Inst, unsigned RegNo,
6330b57cec5SDimitry Andric                                             uint64_t Address,
63481ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
6350b57cec5SDimitry Andric   if (RegNo > 31)
6360b57cec5SDimitry Andric     return Fail;
637349cc55cSDimitry Andric   unsigned Register =
638349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::ZPR2RegClassID].getRegister(RegNo);
6390b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
6400b57cec5SDimitry Andric   return Success;
6410b57cec5SDimitry Andric }
6420b57cec5SDimitry Andric 
DecodeZPR3RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6430b57cec5SDimitry Andric static DecodeStatus DecodeZPR3RegisterClass(MCInst &Inst, unsigned RegNo,
6440b57cec5SDimitry Andric                                             uint64_t Address,
64581ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
6460b57cec5SDimitry Andric   if (RegNo > 31)
6470b57cec5SDimitry Andric     return Fail;
648349cc55cSDimitry Andric   unsigned Register =
649349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::ZPR3RegClassID].getRegister(RegNo);
6500b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
6510b57cec5SDimitry Andric   return Success;
6520b57cec5SDimitry Andric }
6530b57cec5SDimitry Andric 
DecodeZPR4RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)6540b57cec5SDimitry Andric static DecodeStatus DecodeZPR4RegisterClass(MCInst &Inst, unsigned RegNo,
6550b57cec5SDimitry Andric                                             uint64_t Address,
65681ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
6570b57cec5SDimitry Andric   if (RegNo > 31)
6580b57cec5SDimitry Andric     return Fail;
659349cc55cSDimitry Andric   unsigned Register =
660349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::ZPR4RegClassID].getRegister(RegNo);
6610b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
6620b57cec5SDimitry Andric   return Success;
6630b57cec5SDimitry Andric }
6640b57cec5SDimitry Andric 
DecodeZPR2Mul2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)665bdd1243dSDimitry Andric static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
666bdd1243dSDimitry Andric                                                 uint64_t Address,
667bdd1243dSDimitry Andric                                                 const void *Decoder) {
668bdd1243dSDimitry Andric   if (RegNo * 2 > 30)
669bdd1243dSDimitry Andric     return Fail;
670bdd1243dSDimitry Andric   unsigned Register =
671bdd1243dSDimitry Andric       AArch64MCRegisterClasses[AArch64::ZPR2RegClassID].getRegister(RegNo * 2);
672bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
673bdd1243dSDimitry Andric   return Success;
674bdd1243dSDimitry Andric }
675bdd1243dSDimitry Andric 
DecodeZPR4Mul4RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)676bdd1243dSDimitry Andric static DecodeStatus DecodeZPR4Mul4RegisterClass(MCInst &Inst, unsigned RegNo,
677bdd1243dSDimitry Andric                                                 uint64_t Address,
678bdd1243dSDimitry Andric                                                 const void *Decoder) {
679bdd1243dSDimitry Andric   if (RegNo * 4 > 28)
680bdd1243dSDimitry Andric     return Fail;
681bdd1243dSDimitry Andric   unsigned Register =
682bdd1243dSDimitry Andric       AArch64MCRegisterClasses[AArch64::ZPR4RegClassID].getRegister(RegNo * 4);
683bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
684bdd1243dSDimitry Andric   return Success;
685bdd1243dSDimitry Andric }
686bdd1243dSDimitry Andric 
DecodeZPR2StridedRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)687bdd1243dSDimitry Andric static DecodeStatus DecodeZPR2StridedRegisterClass(MCInst &Inst, unsigned RegNo,
688bdd1243dSDimitry Andric                                                    uint64_t Address,
689bdd1243dSDimitry Andric                                                    const void *Decoder) {
690bdd1243dSDimitry Andric   if (RegNo > 15)
691bdd1243dSDimitry Andric     return Fail;
692bdd1243dSDimitry Andric   unsigned Register =
693bdd1243dSDimitry Andric       AArch64MCRegisterClasses[AArch64::ZPR2StridedRegClassID].getRegister(
694bdd1243dSDimitry Andric           RegNo);
695bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
696bdd1243dSDimitry Andric   return Success;
697bdd1243dSDimitry Andric }
698bdd1243dSDimitry Andric 
DecodeZPR4StridedRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)699bdd1243dSDimitry Andric static DecodeStatus DecodeZPR4StridedRegisterClass(MCInst &Inst, unsigned RegNo,
700bdd1243dSDimitry Andric                                                    uint64_t Address,
701bdd1243dSDimitry Andric                                                    const void *Decoder) {
702bdd1243dSDimitry Andric   if (RegNo > 7)
703bdd1243dSDimitry Andric     return Fail;
704bdd1243dSDimitry Andric   unsigned Register =
705bdd1243dSDimitry Andric       AArch64MCRegisterClasses[AArch64::ZPR4StridedRegClassID].getRegister(
706bdd1243dSDimitry Andric           RegNo);
707bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
708bdd1243dSDimitry Andric   return Success;
709bdd1243dSDimitry Andric }
710bdd1243dSDimitry Andric 
71181ad6265SDimitry Andric static DecodeStatus
DecodeMatrixTileListRegisterClass(MCInst & Inst,unsigned RegMask,uint64_t Address,const MCDisassembler * Decoder)71281ad6265SDimitry Andric DecodeMatrixTileListRegisterClass(MCInst &Inst, unsigned RegMask,
713fe6060f1SDimitry Andric                                   uint64_t Address,
71481ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
715fe6060f1SDimitry Andric   if (RegMask > 0xFF)
716fe6060f1SDimitry Andric     return Fail;
717fe6060f1SDimitry Andric   Inst.addOperand(MCOperand::createImm(RegMask));
718fe6060f1SDimitry Andric   return Success;
719fe6060f1SDimitry Andric }
720fe6060f1SDimitry Andric 
72106c3fb27SDimitry Andric static const MCPhysReg MatrixZATileDecoderTable[5][16] = {
722fe6060f1SDimitry Andric     {AArch64::ZAB0},
723fe6060f1SDimitry Andric     {AArch64::ZAH0, AArch64::ZAH1},
724fe6060f1SDimitry Andric     {AArch64::ZAS0, AArch64::ZAS1, AArch64::ZAS2, AArch64::ZAS3},
72506c3fb27SDimitry Andric     {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3, AArch64::ZAD4,
72606c3fb27SDimitry Andric      AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7},
72706c3fb27SDimitry Andric     {AArch64::ZAQ0, AArch64::ZAQ1, AArch64::ZAQ2, AArch64::ZAQ3, AArch64::ZAQ4,
72806c3fb27SDimitry Andric      AArch64::ZAQ5, AArch64::ZAQ6, AArch64::ZAQ7, AArch64::ZAQ8, AArch64::ZAQ9,
72906c3fb27SDimitry Andric      AArch64::ZAQ10, AArch64::ZAQ11, AArch64::ZAQ12, AArch64::ZAQ13,
73006c3fb27SDimitry Andric      AArch64::ZAQ14, AArch64::ZAQ15}};
731fe6060f1SDimitry Andric 
732fe6060f1SDimitry Andric template <unsigned NumBitsForTile>
DecodeMatrixTile(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)733fe6060f1SDimitry Andric static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo,
73481ad6265SDimitry Andric                                      uint64_t Address,
73581ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
736fe6060f1SDimitry Andric   unsigned LastReg = (1 << NumBitsForTile) - 1;
737fe6060f1SDimitry Andric   if (RegNo > LastReg)
738fe6060f1SDimitry Andric     return Fail;
739fe6060f1SDimitry Andric   Inst.addOperand(
740fe6060f1SDimitry Andric       MCOperand::createReg(MatrixZATileDecoderTable[NumBitsForTile][RegNo]));
741fe6060f1SDimitry Andric   return Success;
742fe6060f1SDimitry Andric }
743fe6060f1SDimitry Andric 
DecodePPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)7440b57cec5SDimitry Andric static DecodeStatus DecodePPRRegisterClass(MCInst &Inst, unsigned RegNo,
74581ad6265SDimitry Andric                                            uint64_t Addr,
74681ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
7470b57cec5SDimitry Andric   if (RegNo > 15)
7480b57cec5SDimitry Andric     return Fail;
7490b57cec5SDimitry Andric 
750349cc55cSDimitry Andric   unsigned Register =
751349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::PPRRegClassID].getRegister(RegNo);
7520b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
7530b57cec5SDimitry Andric   return Success;
7540b57cec5SDimitry Andric }
7550b57cec5SDimitry Andric 
DecodePNRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)7565f757f3fSDimitry Andric static DecodeStatus DecodePNRRegisterClass(MCInst &Inst, unsigned RegNo,
7575f757f3fSDimitry Andric                                            uint64_t Addr,
7585f757f3fSDimitry Andric                                            const MCDisassembler *Decoder) {
7595f757f3fSDimitry Andric   if (RegNo > 15)
7605f757f3fSDimitry Andric     return Fail;
7615f757f3fSDimitry Andric 
7625f757f3fSDimitry Andric   unsigned Register =
7635f757f3fSDimitry Andric       AArch64MCRegisterClasses[AArch64::PNRRegClassID].getRegister(RegNo);
7645f757f3fSDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
7655f757f3fSDimitry Andric   return Success;
7665f757f3fSDimitry Andric }
7675f757f3fSDimitry Andric 
DecodePPR_3bRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)7680b57cec5SDimitry Andric static DecodeStatus DecodePPR_3bRegisterClass(MCInst &Inst, unsigned RegNo,
7690b57cec5SDimitry Andric                                               uint64_t Addr,
77081ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
7710b57cec5SDimitry Andric   if (RegNo > 7)
7720b57cec5SDimitry Andric     return Fail;
7730b57cec5SDimitry Andric 
7740b57cec5SDimitry Andric   // Just reuse the PPR decode table
7750b57cec5SDimitry Andric   return DecodePPRRegisterClass(Inst, RegNo, Addr, Decoder);
7760b57cec5SDimitry Andric }
7770b57cec5SDimitry Andric 
778bdd1243dSDimitry Andric static DecodeStatus
DecodePNR_p8to15RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)7795f757f3fSDimitry Andric DecodePNR_p8to15RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
780bdd1243dSDimitry Andric                               const MCDisassembler *Decoder) {
781bdd1243dSDimitry Andric   if (RegNo > 7)
782bdd1243dSDimitry Andric     return Fail;
783bdd1243dSDimitry Andric 
784bdd1243dSDimitry Andric   // Just reuse the PPR decode table
7855f757f3fSDimitry Andric   return DecodePNRRegisterClass(Inst, RegNo + 8, Addr, Decoder);
786bdd1243dSDimitry Andric }
787bdd1243dSDimitry Andric 
DecodePPR2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)788bdd1243dSDimitry Andric static DecodeStatus DecodePPR2RegisterClass(MCInst &Inst, unsigned RegNo,
789bdd1243dSDimitry Andric                                             uint64_t Address,
790bdd1243dSDimitry Andric                                             const void *Decoder) {
791bdd1243dSDimitry Andric   if (RegNo > 15)
792bdd1243dSDimitry Andric     return Fail;
793bdd1243dSDimitry Andric 
794bdd1243dSDimitry Andric   unsigned Register =
795bdd1243dSDimitry Andric       AArch64MCRegisterClasses[AArch64::PPR2RegClassID].getRegister(RegNo);
796bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
797bdd1243dSDimitry Andric   return Success;
798bdd1243dSDimitry Andric }
799bdd1243dSDimitry Andric 
DecodePPR2Mul2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)800bdd1243dSDimitry Andric static DecodeStatus DecodePPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
801bdd1243dSDimitry Andric                                                 uint64_t Address,
802bdd1243dSDimitry Andric                                                 const void *Decoder) {
803bdd1243dSDimitry Andric   if ((RegNo * 2) > 14)
804bdd1243dSDimitry Andric     return Fail;
805bdd1243dSDimitry Andric   unsigned Register =
806bdd1243dSDimitry Andric       AArch64MCRegisterClasses[AArch64::PPR2RegClassID].getRegister(RegNo * 2);
807bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
808bdd1243dSDimitry Andric   return Success;
809bdd1243dSDimitry Andric }
810bdd1243dSDimitry Andric 
DecodeQQRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)8110b57cec5SDimitry Andric static DecodeStatus DecodeQQRegisterClass(MCInst &Inst, unsigned RegNo,
81281ad6265SDimitry Andric                                           uint64_t Addr,
81381ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
8140b57cec5SDimitry Andric   if (RegNo > 31)
8150b57cec5SDimitry Andric     return Fail;
816349cc55cSDimitry Andric   unsigned Register =
817349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::QQRegClassID].getRegister(RegNo);
8180b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
8190b57cec5SDimitry Andric   return Success;
8200b57cec5SDimitry Andric }
8210b57cec5SDimitry Andric 
DecodeQQQRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)8220b57cec5SDimitry Andric static DecodeStatus DecodeQQQRegisterClass(MCInst &Inst, unsigned RegNo,
82381ad6265SDimitry Andric                                            uint64_t Addr,
82481ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
8250b57cec5SDimitry Andric   if (RegNo > 31)
8260b57cec5SDimitry Andric     return Fail;
827349cc55cSDimitry Andric   unsigned Register =
828349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::QQQRegClassID].getRegister(RegNo);
8290b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
8300b57cec5SDimitry Andric   return Success;
8310b57cec5SDimitry Andric }
8320b57cec5SDimitry Andric 
DecodeQQQQRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)8330b57cec5SDimitry Andric static DecodeStatus DecodeQQQQRegisterClass(MCInst &Inst, unsigned RegNo,
8340b57cec5SDimitry Andric                                             uint64_t Addr,
83581ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
8360b57cec5SDimitry Andric   if (RegNo > 31)
8370b57cec5SDimitry Andric     return Fail;
838349cc55cSDimitry Andric   unsigned Register =
839349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::QQQQRegClassID].getRegister(RegNo);
8400b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
8410b57cec5SDimitry Andric   return Success;
8420b57cec5SDimitry Andric }
8430b57cec5SDimitry Andric 
DecodeDDRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)8440b57cec5SDimitry Andric static DecodeStatus DecodeDDRegisterClass(MCInst &Inst, unsigned RegNo,
84581ad6265SDimitry Andric                                           uint64_t Addr,
84681ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
8470b57cec5SDimitry Andric   if (RegNo > 31)
8480b57cec5SDimitry Andric     return Fail;
849349cc55cSDimitry Andric   unsigned Register =
850349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::DDRegClassID].getRegister(RegNo);
8510b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
8520b57cec5SDimitry Andric   return Success;
8530b57cec5SDimitry Andric }
8540b57cec5SDimitry Andric 
DecodeDDDRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)8550b57cec5SDimitry Andric static DecodeStatus DecodeDDDRegisterClass(MCInst &Inst, unsigned RegNo,
85681ad6265SDimitry Andric                                            uint64_t Addr,
85781ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
8580b57cec5SDimitry Andric   if (RegNo > 31)
8590b57cec5SDimitry Andric     return Fail;
860349cc55cSDimitry Andric   unsigned Register =
861349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::DDDRegClassID].getRegister(RegNo);
8620b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
8630b57cec5SDimitry Andric   return Success;
8640b57cec5SDimitry Andric }
8650b57cec5SDimitry Andric 
DecodeDDDDRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)8660b57cec5SDimitry Andric static DecodeStatus DecodeDDDDRegisterClass(MCInst &Inst, unsigned RegNo,
8670b57cec5SDimitry Andric                                             uint64_t Addr,
86881ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
8690b57cec5SDimitry Andric   if (RegNo > 31)
8700b57cec5SDimitry Andric     return Fail;
871349cc55cSDimitry Andric   unsigned Register =
872349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::DDDDRegClassID].getRegister(RegNo);
8730b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
8740b57cec5SDimitry Andric   return Success;
8750b57cec5SDimitry Andric }
8760b57cec5SDimitry Andric 
DecodeFixedPointScaleImm32(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)8770b57cec5SDimitry Andric static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm,
8780b57cec5SDimitry Andric                                                uint64_t Addr,
87981ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
8800b57cec5SDimitry Andric   // scale{5} is asserted as 1 in tblgen.
8810b57cec5SDimitry Andric   Imm |= 0x20;
8820b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - Imm));
8830b57cec5SDimitry Andric   return Success;
8840b57cec5SDimitry Andric }
8850b57cec5SDimitry Andric 
DecodeFixedPointScaleImm64(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)8860b57cec5SDimitry Andric static DecodeStatus DecodeFixedPointScaleImm64(MCInst &Inst, unsigned Imm,
8870b57cec5SDimitry Andric                                                uint64_t Addr,
88881ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
8890b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - Imm));
8900b57cec5SDimitry Andric   return Success;
8910b57cec5SDimitry Andric }
8920b57cec5SDimitry Andric 
DecodePCRelLabel16(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)893cb14a3feSDimitry Andric static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm,
894cb14a3feSDimitry Andric                                        uint64_t Addr,
895cb14a3feSDimitry Andric                                        const MCDisassembler *Decoder) {
896cb14a3feSDimitry Andric   // Immediate is encoded as the top 16-bits of an unsigned 18-bit negative
897cb14a3feSDimitry Andric   // PC-relative offset.
898cb14a3feSDimitry Andric   uint64_t ImmVal = Imm;
899647cbc5dSDimitry Andric   if (ImmVal > (1 << 16))
900cb14a3feSDimitry Andric     return Fail;
901cb14a3feSDimitry Andric   ImmVal = -ImmVal;
902cb14a3feSDimitry Andric   if (!Decoder->tryAddingSymbolicOperand(Inst, (ImmVal << 2), Addr,
903cb14a3feSDimitry Andric                                          /*IsBranch=*/false, 0, 0, 4))
904cb14a3feSDimitry Andric     Inst.addOperand(MCOperand::createImm(ImmVal));
905cb14a3feSDimitry Andric   return Success;
906cb14a3feSDimitry Andric }
907cb14a3feSDimitry Andric 
DecodePCRelLabel19(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)9080b57cec5SDimitry Andric static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
90981ad6265SDimitry Andric                                        uint64_t Addr,
91081ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
9110b57cec5SDimitry Andric   int64_t ImmVal = Imm;
9120b57cec5SDimitry Andric 
9130b57cec5SDimitry Andric   // Sign-extend 19-bit immediate.
9140b57cec5SDimitry Andric   if (ImmVal & (1 << (19 - 1)))
9150b57cec5SDimitry Andric     ImmVal |= ~((1LL << 19) - 1);
9160b57cec5SDimitry Andric 
91781ad6265SDimitry Andric   if (!Decoder->tryAddingSymbolicOperand(
91881ad6265SDimitry Andric           Inst, ImmVal * 4, Addr, Inst.getOpcode() != AArch64::LDRXl, 0, 0, 4))
9190b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ImmVal));
9200b57cec5SDimitry Andric   return Success;
9210b57cec5SDimitry Andric }
9220b57cec5SDimitry Andric 
DecodeMemExtend(MCInst & Inst,unsigned Imm,uint64_t Address,const MCDisassembler * Decoder)9230b57cec5SDimitry Andric static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
92481ad6265SDimitry Andric                                     uint64_t Address,
92581ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
9260b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm((Imm  >> 1) & 1));
9270b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm & 1));
9280b57cec5SDimitry Andric   return Success;
9290b57cec5SDimitry Andric }
9300b57cec5SDimitry Andric 
DecodeMRSSystemRegister(MCInst & Inst,unsigned Imm,uint64_t Address,const MCDisassembler * Decoder)9310b57cec5SDimitry Andric static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm,
9320b57cec5SDimitry Andric                                             uint64_t Address,
93381ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
9340b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
9350b57cec5SDimitry Andric 
9360b57cec5SDimitry Andric   // Every system register in the encoding space is valid with the syntax
9370b57cec5SDimitry Andric   // S<op0>_<op1>_<Cn>_<Cm>_<op2>, so decoding system registers always succeeds.
9380b57cec5SDimitry Andric   return Success;
9390b57cec5SDimitry Andric }
9400b57cec5SDimitry Andric 
DecodeMSRSystemRegister(MCInst & Inst,unsigned Imm,uint64_t Address,const MCDisassembler * Decoder)9410b57cec5SDimitry Andric static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm,
9420b57cec5SDimitry Andric                                             uint64_t Address,
94381ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
9440b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
9450b57cec5SDimitry Andric 
9460b57cec5SDimitry Andric   return Success;
9470b57cec5SDimitry Andric }
9480b57cec5SDimitry Andric 
DecodeFMOVLaneInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)9490b57cec5SDimitry Andric static DecodeStatus DecodeFMOVLaneInstruction(MCInst &Inst, unsigned Insn,
9500b57cec5SDimitry Andric                                               uint64_t Address,
95181ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
9520b57cec5SDimitry Andric   // This decoder exists to add the dummy Lane operand to the MCInst, which must
9530b57cec5SDimitry Andric   // be 1 in assembly but has no other real manifestation.
9540b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 0, 5);
9550b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 5, 5);
9560b57cec5SDimitry Andric   unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
9570b57cec5SDimitry Andric 
9580b57cec5SDimitry Andric   if (IsToVec) {
9590b57cec5SDimitry Andric     DecodeFPR128RegisterClass(Inst, Rd, Address, Decoder);
9600b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
9610b57cec5SDimitry Andric   } else {
9620b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
9630b57cec5SDimitry Andric     DecodeFPR128RegisterClass(Inst, Rn, Address, Decoder);
9640b57cec5SDimitry Andric   }
9650b57cec5SDimitry Andric 
9660b57cec5SDimitry Andric   // Add the lane
9670b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(1));
9680b57cec5SDimitry Andric 
9690b57cec5SDimitry Andric   return Success;
9700b57cec5SDimitry Andric }
9710b57cec5SDimitry Andric 
DecodeVecShiftRImm(MCInst & Inst,unsigned Imm,unsigned Add)9720b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftRImm(MCInst &Inst, unsigned Imm,
9730b57cec5SDimitry Andric                                        unsigned Add) {
9740b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Add - Imm));
9750b57cec5SDimitry Andric   return Success;
9760b57cec5SDimitry Andric }
9770b57cec5SDimitry Andric 
DecodeVecShiftLImm(MCInst & Inst,unsigned Imm,unsigned Add)9780b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftLImm(MCInst &Inst, unsigned Imm,
9790b57cec5SDimitry Andric                                        unsigned Add) {
9800b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm((Imm + Add) & (Add - 1)));
9810b57cec5SDimitry Andric   return Success;
9820b57cec5SDimitry Andric }
9830b57cec5SDimitry Andric 
DecodeVecShiftR64Imm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)9840b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm,
98581ad6265SDimitry Andric                                          uint64_t Addr,
98681ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
9870b57cec5SDimitry Andric   return DecodeVecShiftRImm(Inst, Imm, 64);
9880b57cec5SDimitry Andric }
9890b57cec5SDimitry Andric 
DecodeVecShiftR64ImmNarrow(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)9900b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst &Inst, unsigned Imm,
9910b57cec5SDimitry Andric                                                uint64_t Addr,
99281ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
9930b57cec5SDimitry Andric   return DecodeVecShiftRImm(Inst, Imm | 0x20, 64);
9940b57cec5SDimitry Andric }
9950b57cec5SDimitry Andric 
DecodeVecShiftR32Imm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)9960b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm,
99781ad6265SDimitry Andric                                          uint64_t Addr,
99881ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
9990b57cec5SDimitry Andric   return DecodeVecShiftRImm(Inst, Imm, 32);
10000b57cec5SDimitry Andric }
10010b57cec5SDimitry Andric 
DecodeVecShiftR32ImmNarrow(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)10020b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst &Inst, unsigned Imm,
10030b57cec5SDimitry Andric                                                uint64_t Addr,
100481ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
10050b57cec5SDimitry Andric   return DecodeVecShiftRImm(Inst, Imm | 0x10, 32);
10060b57cec5SDimitry Andric }
10070b57cec5SDimitry Andric 
DecodeVecShiftR16Imm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)10080b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm,
100981ad6265SDimitry Andric                                          uint64_t Addr,
101081ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
10110b57cec5SDimitry Andric   return DecodeVecShiftRImm(Inst, Imm, 16);
10120b57cec5SDimitry Andric }
10130b57cec5SDimitry Andric 
DecodeVecShiftR16ImmNarrow(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)10140b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst &Inst, unsigned Imm,
10150b57cec5SDimitry Andric                                                uint64_t Addr,
101681ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
10170b57cec5SDimitry Andric   return DecodeVecShiftRImm(Inst, Imm | 0x8, 16);
10180b57cec5SDimitry Andric }
10190b57cec5SDimitry Andric 
DecodeVecShiftR8Imm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)10200b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm,
102181ad6265SDimitry Andric                                         uint64_t Addr,
102281ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
10230b57cec5SDimitry Andric   return DecodeVecShiftRImm(Inst, Imm, 8);
10240b57cec5SDimitry Andric }
10250b57cec5SDimitry Andric 
DecodeVecShiftL64Imm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)10260b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm,
102781ad6265SDimitry Andric                                          uint64_t Addr,
102881ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
10290b57cec5SDimitry Andric   return DecodeVecShiftLImm(Inst, Imm, 64);
10300b57cec5SDimitry Andric }
10310b57cec5SDimitry Andric 
DecodeVecShiftL32Imm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)10320b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm,
103381ad6265SDimitry Andric                                          uint64_t Addr,
103481ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
10350b57cec5SDimitry Andric   return DecodeVecShiftLImm(Inst, Imm, 32);
10360b57cec5SDimitry Andric }
10370b57cec5SDimitry Andric 
DecodeVecShiftL16Imm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)10380b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm,
103981ad6265SDimitry Andric                                          uint64_t Addr,
104081ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
10410b57cec5SDimitry Andric   return DecodeVecShiftLImm(Inst, Imm, 16);
10420b57cec5SDimitry Andric }
10430b57cec5SDimitry Andric 
DecodeVecShiftL8Imm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)10440b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm,
104581ad6265SDimitry Andric                                         uint64_t Addr,
104681ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
10470b57cec5SDimitry Andric   return DecodeVecShiftLImm(Inst, Imm, 8);
10480b57cec5SDimitry Andric }
10490b57cec5SDimitry Andric 
105081ad6265SDimitry Andric static DecodeStatus
DecodeThreeAddrSRegInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)105181ad6265SDimitry Andric DecodeThreeAddrSRegInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
105281ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
10530b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
10540b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
10550b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(insn, 16, 5);
10560b57cec5SDimitry Andric   unsigned shiftHi = fieldFromInstruction(insn, 22, 2);
10570b57cec5SDimitry Andric   unsigned shiftLo = fieldFromInstruction(insn, 10, 6);
10580b57cec5SDimitry Andric   unsigned shift = (shiftHi << 6) | shiftLo;
10590b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
10600b57cec5SDimitry Andric   default:
10610b57cec5SDimitry Andric     return Fail;
10620b57cec5SDimitry Andric   case AArch64::ADDWrs:
10630b57cec5SDimitry Andric   case AArch64::ADDSWrs:
10640b57cec5SDimitry Andric   case AArch64::SUBWrs:
10650b57cec5SDimitry Andric   case AArch64::SUBSWrs:
10660b57cec5SDimitry Andric     // if shift == '11' then ReservedValue()
10670b57cec5SDimitry Andric     if (shiftHi == 0x3)
10680b57cec5SDimitry Andric       return Fail;
1069bdd1243dSDimitry Andric     [[fallthrough]];
10700b57cec5SDimitry Andric   case AArch64::ANDWrs:
10710b57cec5SDimitry Andric   case AArch64::ANDSWrs:
10720b57cec5SDimitry Andric   case AArch64::BICWrs:
10730b57cec5SDimitry Andric   case AArch64::BICSWrs:
10740b57cec5SDimitry Andric   case AArch64::ORRWrs:
10750b57cec5SDimitry Andric   case AArch64::ORNWrs:
10760b57cec5SDimitry Andric   case AArch64::EORWrs:
10770b57cec5SDimitry Andric   case AArch64::EONWrs: {
10780b57cec5SDimitry Andric     // if sf == '0' and imm6<5> == '1' then ReservedValue()
10790b57cec5SDimitry Andric     if (shiftLo >> 5 == 1)
10800b57cec5SDimitry Andric       return Fail;
10810b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
10820b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder);
10830b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
10840b57cec5SDimitry Andric     break;
10850b57cec5SDimitry Andric   }
10860b57cec5SDimitry Andric   case AArch64::ADDXrs:
10870b57cec5SDimitry Andric   case AArch64::ADDSXrs:
10880b57cec5SDimitry Andric   case AArch64::SUBXrs:
10890b57cec5SDimitry Andric   case AArch64::SUBSXrs:
10900b57cec5SDimitry Andric     // if shift == '11' then ReservedValue()
10910b57cec5SDimitry Andric     if (shiftHi == 0x3)
10920b57cec5SDimitry Andric       return Fail;
1093bdd1243dSDimitry Andric     [[fallthrough]];
10940b57cec5SDimitry Andric   case AArch64::ANDXrs:
10950b57cec5SDimitry Andric   case AArch64::ANDSXrs:
10960b57cec5SDimitry Andric   case AArch64::BICXrs:
10970b57cec5SDimitry Andric   case AArch64::BICSXrs:
10980b57cec5SDimitry Andric   case AArch64::ORRXrs:
10990b57cec5SDimitry Andric   case AArch64::ORNXrs:
11000b57cec5SDimitry Andric   case AArch64::EORXrs:
11010b57cec5SDimitry Andric   case AArch64::EONXrs:
11020b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
11030b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder);
11040b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
11050b57cec5SDimitry Andric     break;
11060b57cec5SDimitry Andric   }
11070b57cec5SDimitry Andric 
11080b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(shift));
11090b57cec5SDimitry Andric   return Success;
11100b57cec5SDimitry Andric }
11110b57cec5SDimitry Andric 
DecodeMoveImmInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)11120b57cec5SDimitry Andric static DecodeStatus DecodeMoveImmInstruction(MCInst &Inst, uint32_t insn,
11130b57cec5SDimitry Andric                                              uint64_t Addr,
111481ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
11150b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
11160b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(insn, 5, 16);
11170b57cec5SDimitry Andric   unsigned shift = fieldFromInstruction(insn, 21, 2);
11180b57cec5SDimitry Andric   shift <<= 4;
11190b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
11200b57cec5SDimitry Andric   default:
11210b57cec5SDimitry Andric     return Fail;
11220b57cec5SDimitry Andric   case AArch64::MOVZWi:
11230b57cec5SDimitry Andric   case AArch64::MOVNWi:
11240b57cec5SDimitry Andric   case AArch64::MOVKWi:
11250b57cec5SDimitry Andric     if (shift & (1U << 5))
11260b57cec5SDimitry Andric       return Fail;
11270b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
11280b57cec5SDimitry Andric     break;
11290b57cec5SDimitry Andric   case AArch64::MOVZXi:
11300b57cec5SDimitry Andric   case AArch64::MOVNXi:
11310b57cec5SDimitry Andric   case AArch64::MOVKXi:
11320b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
11330b57cec5SDimitry Andric     break;
11340b57cec5SDimitry Andric   }
11350b57cec5SDimitry Andric 
11360b57cec5SDimitry Andric   if (Inst.getOpcode() == AArch64::MOVKWi ||
11370b57cec5SDimitry Andric       Inst.getOpcode() == AArch64::MOVKXi)
11380b57cec5SDimitry Andric     Inst.addOperand(Inst.getOperand(0));
11390b57cec5SDimitry Andric 
11400b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
11410b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(shift));
11420b57cec5SDimitry Andric   return Success;
11430b57cec5SDimitry Andric }
11440b57cec5SDimitry Andric 
114581ad6265SDimitry Andric static DecodeStatus
DecodeUnsignedLdStInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)114681ad6265SDimitry Andric DecodeUnsignedLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
114781ad6265SDimitry Andric                               const MCDisassembler *Decoder) {
11480b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(insn, 0, 5);
11490b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
11500b57cec5SDimitry Andric   unsigned offset = fieldFromInstruction(insn, 10, 12);
11510b57cec5SDimitry Andric 
11520b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
11530b57cec5SDimitry Andric   default:
11540b57cec5SDimitry Andric     return Fail;
11550b57cec5SDimitry Andric   case AArch64::PRFMui:
11560b57cec5SDimitry Andric     // Rt is an immediate in prefetch.
11570b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Rt));
11580b57cec5SDimitry Andric     break;
11590b57cec5SDimitry Andric   case AArch64::STRBBui:
11600b57cec5SDimitry Andric   case AArch64::LDRBBui:
11610b57cec5SDimitry Andric   case AArch64::LDRSBWui:
11620b57cec5SDimitry Andric   case AArch64::STRHHui:
11630b57cec5SDimitry Andric   case AArch64::LDRHHui:
11640b57cec5SDimitry Andric   case AArch64::LDRSHWui:
11650b57cec5SDimitry Andric   case AArch64::STRWui:
11660b57cec5SDimitry Andric   case AArch64::LDRWui:
11670b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
11680b57cec5SDimitry Andric     break;
11690b57cec5SDimitry Andric   case AArch64::LDRSBXui:
11700b57cec5SDimitry Andric   case AArch64::LDRSHXui:
11710b57cec5SDimitry Andric   case AArch64::LDRSWui:
11720b57cec5SDimitry Andric   case AArch64::STRXui:
11730b57cec5SDimitry Andric   case AArch64::LDRXui:
11740b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
11750b57cec5SDimitry Andric     break;
11760b57cec5SDimitry Andric   case AArch64::LDRQui:
11770b57cec5SDimitry Andric   case AArch64::STRQui:
11780b57cec5SDimitry Andric     DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
11790b57cec5SDimitry Andric     break;
11800b57cec5SDimitry Andric   case AArch64::LDRDui:
11810b57cec5SDimitry Andric   case AArch64::STRDui:
11820b57cec5SDimitry Andric     DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
11830b57cec5SDimitry Andric     break;
11840b57cec5SDimitry Andric   case AArch64::LDRSui:
11850b57cec5SDimitry Andric   case AArch64::STRSui:
11860b57cec5SDimitry Andric     DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
11870b57cec5SDimitry Andric     break;
11880b57cec5SDimitry Andric   case AArch64::LDRHui:
11890b57cec5SDimitry Andric   case AArch64::STRHui:
11900b57cec5SDimitry Andric     DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
11910b57cec5SDimitry Andric     break;
11920b57cec5SDimitry Andric   case AArch64::LDRBui:
11930b57cec5SDimitry Andric   case AArch64::STRBui:
11940b57cec5SDimitry Andric     DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
11950b57cec5SDimitry Andric     break;
11960b57cec5SDimitry Andric   }
11970b57cec5SDimitry Andric 
11980b57cec5SDimitry Andric   DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
119981ad6265SDimitry Andric   if (!Decoder->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 0, 4))
12000b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(offset));
12010b57cec5SDimitry Andric   return Success;
12020b57cec5SDimitry Andric }
12030b57cec5SDimitry Andric 
DecodeSignedLdStInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)12040b57cec5SDimitry Andric static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
12050b57cec5SDimitry Andric                                                 uint64_t Addr,
120681ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
12070b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(insn, 0, 5);
12080b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
12090b57cec5SDimitry Andric   int64_t offset = fieldFromInstruction(insn, 12, 9);
12100b57cec5SDimitry Andric 
12110b57cec5SDimitry Andric   // offset is a 9-bit signed immediate, so sign extend it to
12120b57cec5SDimitry Andric   // fill the unsigned.
12130b57cec5SDimitry Andric   if (offset & (1 << (9 - 1)))
12140b57cec5SDimitry Andric     offset |= ~((1LL << 9) - 1);
12150b57cec5SDimitry Andric 
12160b57cec5SDimitry Andric   // First operand is always the writeback to the address register, if needed.
12170b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
12180b57cec5SDimitry Andric   default:
12190b57cec5SDimitry Andric     break;
12200b57cec5SDimitry Andric   case AArch64::LDRSBWpre:
12210b57cec5SDimitry Andric   case AArch64::LDRSHWpre:
12220b57cec5SDimitry Andric   case AArch64::STRBBpre:
12230b57cec5SDimitry Andric   case AArch64::LDRBBpre:
12240b57cec5SDimitry Andric   case AArch64::STRHHpre:
12250b57cec5SDimitry Andric   case AArch64::LDRHHpre:
12260b57cec5SDimitry Andric   case AArch64::STRWpre:
12270b57cec5SDimitry Andric   case AArch64::LDRWpre:
12280b57cec5SDimitry Andric   case AArch64::LDRSBWpost:
12290b57cec5SDimitry Andric   case AArch64::LDRSHWpost:
12300b57cec5SDimitry Andric   case AArch64::STRBBpost:
12310b57cec5SDimitry Andric   case AArch64::LDRBBpost:
12320b57cec5SDimitry Andric   case AArch64::STRHHpost:
12330b57cec5SDimitry Andric   case AArch64::LDRHHpost:
12340b57cec5SDimitry Andric   case AArch64::STRWpost:
12350b57cec5SDimitry Andric   case AArch64::LDRWpost:
12360b57cec5SDimitry Andric   case AArch64::LDRSBXpre:
12370b57cec5SDimitry Andric   case AArch64::LDRSHXpre:
12380b57cec5SDimitry Andric   case AArch64::STRXpre:
12390b57cec5SDimitry Andric   case AArch64::LDRSWpre:
12400b57cec5SDimitry Andric   case AArch64::LDRXpre:
12410b57cec5SDimitry Andric   case AArch64::LDRSBXpost:
12420b57cec5SDimitry Andric   case AArch64::LDRSHXpost:
12430b57cec5SDimitry Andric   case AArch64::STRXpost:
12440b57cec5SDimitry Andric   case AArch64::LDRSWpost:
12450b57cec5SDimitry Andric   case AArch64::LDRXpost:
12460b57cec5SDimitry Andric   case AArch64::LDRQpre:
12470b57cec5SDimitry Andric   case AArch64::STRQpre:
12480b57cec5SDimitry Andric   case AArch64::LDRQpost:
12490b57cec5SDimitry Andric   case AArch64::STRQpost:
12500b57cec5SDimitry Andric   case AArch64::LDRDpre:
12510b57cec5SDimitry Andric   case AArch64::STRDpre:
12520b57cec5SDimitry Andric   case AArch64::LDRDpost:
12530b57cec5SDimitry Andric   case AArch64::STRDpost:
12540b57cec5SDimitry Andric   case AArch64::LDRSpre:
12550b57cec5SDimitry Andric   case AArch64::STRSpre:
12560b57cec5SDimitry Andric   case AArch64::LDRSpost:
12570b57cec5SDimitry Andric   case AArch64::STRSpost:
12580b57cec5SDimitry Andric   case AArch64::LDRHpre:
12590b57cec5SDimitry Andric   case AArch64::STRHpre:
12600b57cec5SDimitry Andric   case AArch64::LDRHpost:
12610b57cec5SDimitry Andric   case AArch64::STRHpost:
12620b57cec5SDimitry Andric   case AArch64::LDRBpre:
12630b57cec5SDimitry Andric   case AArch64::STRBpre:
12640b57cec5SDimitry Andric   case AArch64::LDRBpost:
12650b57cec5SDimitry Andric   case AArch64::STRBpost:
12660b57cec5SDimitry Andric     DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
12670b57cec5SDimitry Andric     break;
12680b57cec5SDimitry Andric   }
12690b57cec5SDimitry Andric 
12700b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
12710b57cec5SDimitry Andric   default:
12720b57cec5SDimitry Andric     return Fail;
12730b57cec5SDimitry Andric   case AArch64::PRFUMi:
12740b57cec5SDimitry Andric     // Rt is an immediate in prefetch.
12750b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Rt));
12760b57cec5SDimitry Andric     break;
12770b57cec5SDimitry Andric   case AArch64::STURBBi:
12780b57cec5SDimitry Andric   case AArch64::LDURBBi:
12790b57cec5SDimitry Andric   case AArch64::LDURSBWi:
12800b57cec5SDimitry Andric   case AArch64::STURHHi:
12810b57cec5SDimitry Andric   case AArch64::LDURHHi:
12820b57cec5SDimitry Andric   case AArch64::LDURSHWi:
12830b57cec5SDimitry Andric   case AArch64::STURWi:
12840b57cec5SDimitry Andric   case AArch64::LDURWi:
12850b57cec5SDimitry Andric   case AArch64::LDTRSBWi:
12860b57cec5SDimitry Andric   case AArch64::LDTRSHWi:
12870b57cec5SDimitry Andric   case AArch64::STTRWi:
12880b57cec5SDimitry Andric   case AArch64::LDTRWi:
12890b57cec5SDimitry Andric   case AArch64::STTRHi:
12900b57cec5SDimitry Andric   case AArch64::LDTRHi:
12910b57cec5SDimitry Andric   case AArch64::LDTRBi:
12920b57cec5SDimitry Andric   case AArch64::STTRBi:
12930b57cec5SDimitry Andric   case AArch64::LDRSBWpre:
12940b57cec5SDimitry Andric   case AArch64::LDRSHWpre:
12950b57cec5SDimitry Andric   case AArch64::STRBBpre:
12960b57cec5SDimitry Andric   case AArch64::LDRBBpre:
12970b57cec5SDimitry Andric   case AArch64::STRHHpre:
12980b57cec5SDimitry Andric   case AArch64::LDRHHpre:
12990b57cec5SDimitry Andric   case AArch64::STRWpre:
13000b57cec5SDimitry Andric   case AArch64::LDRWpre:
13010b57cec5SDimitry Andric   case AArch64::LDRSBWpost:
13020b57cec5SDimitry Andric   case AArch64::LDRSHWpost:
13030b57cec5SDimitry Andric   case AArch64::STRBBpost:
13040b57cec5SDimitry Andric   case AArch64::LDRBBpost:
13050b57cec5SDimitry Andric   case AArch64::STRHHpost:
13060b57cec5SDimitry Andric   case AArch64::LDRHHpost:
13070b57cec5SDimitry Andric   case AArch64::STRWpost:
13080b57cec5SDimitry Andric   case AArch64::LDRWpost:
13090b57cec5SDimitry Andric   case AArch64::STLURBi:
13100b57cec5SDimitry Andric   case AArch64::STLURHi:
13110b57cec5SDimitry Andric   case AArch64::STLURWi:
13120b57cec5SDimitry Andric   case AArch64::LDAPURBi:
13130b57cec5SDimitry Andric   case AArch64::LDAPURSBWi:
13140b57cec5SDimitry Andric   case AArch64::LDAPURHi:
13150b57cec5SDimitry Andric   case AArch64::LDAPURSHWi:
13160b57cec5SDimitry Andric   case AArch64::LDAPURi:
13170b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
13180b57cec5SDimitry Andric     break;
13190b57cec5SDimitry Andric   case AArch64::LDURSBXi:
13200b57cec5SDimitry Andric   case AArch64::LDURSHXi:
13210b57cec5SDimitry Andric   case AArch64::LDURSWi:
13220b57cec5SDimitry Andric   case AArch64::STURXi:
13230b57cec5SDimitry Andric   case AArch64::LDURXi:
13240b57cec5SDimitry Andric   case AArch64::LDTRSBXi:
13250b57cec5SDimitry Andric   case AArch64::LDTRSHXi:
13260b57cec5SDimitry Andric   case AArch64::LDTRSWi:
13270b57cec5SDimitry Andric   case AArch64::STTRXi:
13280b57cec5SDimitry Andric   case AArch64::LDTRXi:
13290b57cec5SDimitry Andric   case AArch64::LDRSBXpre:
13300b57cec5SDimitry Andric   case AArch64::LDRSHXpre:
13310b57cec5SDimitry Andric   case AArch64::STRXpre:
13320b57cec5SDimitry Andric   case AArch64::LDRSWpre:
13330b57cec5SDimitry Andric   case AArch64::LDRXpre:
13340b57cec5SDimitry Andric   case AArch64::LDRSBXpost:
13350b57cec5SDimitry Andric   case AArch64::LDRSHXpost:
13360b57cec5SDimitry Andric   case AArch64::STRXpost:
13370b57cec5SDimitry Andric   case AArch64::LDRSWpost:
13380b57cec5SDimitry Andric   case AArch64::LDRXpost:
13390b57cec5SDimitry Andric   case AArch64::LDAPURSWi:
13400b57cec5SDimitry Andric   case AArch64::LDAPURSHXi:
13410b57cec5SDimitry Andric   case AArch64::LDAPURSBXi:
13420b57cec5SDimitry Andric   case AArch64::STLURXi:
13430b57cec5SDimitry Andric   case AArch64::LDAPURXi:
13440b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
13450b57cec5SDimitry Andric     break;
13460b57cec5SDimitry Andric   case AArch64::LDURQi:
13470b57cec5SDimitry Andric   case AArch64::STURQi:
13480b57cec5SDimitry Andric   case AArch64::LDRQpre:
13490b57cec5SDimitry Andric   case AArch64::STRQpre:
13500b57cec5SDimitry Andric   case AArch64::LDRQpost:
13510b57cec5SDimitry Andric   case AArch64::STRQpost:
13520b57cec5SDimitry Andric     DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
13530b57cec5SDimitry Andric     break;
13540b57cec5SDimitry Andric   case AArch64::LDURDi:
13550b57cec5SDimitry Andric   case AArch64::STURDi:
13560b57cec5SDimitry Andric   case AArch64::LDRDpre:
13570b57cec5SDimitry Andric   case AArch64::STRDpre:
13580b57cec5SDimitry Andric   case AArch64::LDRDpost:
13590b57cec5SDimitry Andric   case AArch64::STRDpost:
13600b57cec5SDimitry Andric     DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
13610b57cec5SDimitry Andric     break;
13620b57cec5SDimitry Andric   case AArch64::LDURSi:
13630b57cec5SDimitry Andric   case AArch64::STURSi:
13640b57cec5SDimitry Andric   case AArch64::LDRSpre:
13650b57cec5SDimitry Andric   case AArch64::STRSpre:
13660b57cec5SDimitry Andric   case AArch64::LDRSpost:
13670b57cec5SDimitry Andric   case AArch64::STRSpost:
13680b57cec5SDimitry Andric     DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
13690b57cec5SDimitry Andric     break;
13700b57cec5SDimitry Andric   case AArch64::LDURHi:
13710b57cec5SDimitry Andric   case AArch64::STURHi:
13720b57cec5SDimitry Andric   case AArch64::LDRHpre:
13730b57cec5SDimitry Andric   case AArch64::STRHpre:
13740b57cec5SDimitry Andric   case AArch64::LDRHpost:
13750b57cec5SDimitry Andric   case AArch64::STRHpost:
13760b57cec5SDimitry Andric     DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
13770b57cec5SDimitry Andric     break;
13780b57cec5SDimitry Andric   case AArch64::LDURBi:
13790b57cec5SDimitry Andric   case AArch64::STURBi:
13800b57cec5SDimitry Andric   case AArch64::LDRBpre:
13810b57cec5SDimitry Andric   case AArch64::STRBpre:
13820b57cec5SDimitry Andric   case AArch64::LDRBpost:
13830b57cec5SDimitry Andric   case AArch64::STRBpost:
13840b57cec5SDimitry Andric     DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
13850b57cec5SDimitry Andric     break;
13860b57cec5SDimitry Andric   }
13870b57cec5SDimitry Andric 
13880b57cec5SDimitry Andric   DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
13890b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(offset));
13900b57cec5SDimitry Andric 
13910b57cec5SDimitry Andric   bool IsLoad = fieldFromInstruction(insn, 22, 1);
13920b57cec5SDimitry Andric   bool IsIndexed = fieldFromInstruction(insn, 10, 2) != 0;
13930b57cec5SDimitry Andric   bool IsFP = fieldFromInstruction(insn, 26, 1);
13940b57cec5SDimitry Andric 
13950b57cec5SDimitry Andric   // Cannot write back to a transfer register (but xzr != sp).
13960b57cec5SDimitry Andric   if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn)
13970b57cec5SDimitry Andric     return SoftFail;
13980b57cec5SDimitry Andric 
13990b57cec5SDimitry Andric   return Success;
14000b57cec5SDimitry Andric }
14010b57cec5SDimitry Andric 
140281ad6265SDimitry Andric static DecodeStatus
DecodeExclusiveLdStInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)140381ad6265SDimitry Andric DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
140481ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
14050b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(insn, 0, 5);
14060b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
14070b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
14080b57cec5SDimitry Andric   unsigned Rs = fieldFromInstruction(insn, 16, 5);
14090b57cec5SDimitry Andric 
14100b57cec5SDimitry Andric   unsigned Opcode = Inst.getOpcode();
14110b57cec5SDimitry Andric   switch (Opcode) {
14120b57cec5SDimitry Andric   default:
14130b57cec5SDimitry Andric     return Fail;
14140b57cec5SDimitry Andric   case AArch64::STLXRW:
14150b57cec5SDimitry Andric   case AArch64::STLXRB:
14160b57cec5SDimitry Andric   case AArch64::STLXRH:
14170b57cec5SDimitry Andric   case AArch64::STXRW:
14180b57cec5SDimitry Andric   case AArch64::STXRB:
14190b57cec5SDimitry Andric   case AArch64::STXRH:
14200b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
1421bdd1243dSDimitry Andric     [[fallthrough]];
14220b57cec5SDimitry Andric   case AArch64::LDARW:
14230b57cec5SDimitry Andric   case AArch64::LDARB:
14240b57cec5SDimitry Andric   case AArch64::LDARH:
14250b57cec5SDimitry Andric   case AArch64::LDAXRW:
14260b57cec5SDimitry Andric   case AArch64::LDAXRB:
14270b57cec5SDimitry Andric   case AArch64::LDAXRH:
14280b57cec5SDimitry Andric   case AArch64::LDXRW:
14290b57cec5SDimitry Andric   case AArch64::LDXRB:
14300b57cec5SDimitry Andric   case AArch64::LDXRH:
14310b57cec5SDimitry Andric   case AArch64::STLRW:
14320b57cec5SDimitry Andric   case AArch64::STLRB:
14330b57cec5SDimitry Andric   case AArch64::STLRH:
14340b57cec5SDimitry Andric   case AArch64::STLLRW:
14350b57cec5SDimitry Andric   case AArch64::STLLRB:
14360b57cec5SDimitry Andric   case AArch64::STLLRH:
14370b57cec5SDimitry Andric   case AArch64::LDLARW:
14380b57cec5SDimitry Andric   case AArch64::LDLARB:
14390b57cec5SDimitry Andric   case AArch64::LDLARH:
14400b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
14410b57cec5SDimitry Andric     break;
14420b57cec5SDimitry Andric   case AArch64::STLXRX:
14430b57cec5SDimitry Andric   case AArch64::STXRX:
14440b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
1445bdd1243dSDimitry Andric     [[fallthrough]];
14460b57cec5SDimitry Andric   case AArch64::LDARX:
14470b57cec5SDimitry Andric   case AArch64::LDAXRX:
14480b57cec5SDimitry Andric   case AArch64::LDXRX:
14490b57cec5SDimitry Andric   case AArch64::STLRX:
14500b57cec5SDimitry Andric   case AArch64::LDLARX:
14510b57cec5SDimitry Andric   case AArch64::STLLRX:
14520b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
14530b57cec5SDimitry Andric     break;
14540b57cec5SDimitry Andric   case AArch64::STLXPW:
14550b57cec5SDimitry Andric   case AArch64::STXPW:
14560b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
1457bdd1243dSDimitry Andric     [[fallthrough]];
14580b57cec5SDimitry Andric   case AArch64::LDAXPW:
14590b57cec5SDimitry Andric   case AArch64::LDXPW:
14600b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
14610b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);
14620b57cec5SDimitry Andric     break;
14630b57cec5SDimitry Andric   case AArch64::STLXPX:
14640b57cec5SDimitry Andric   case AArch64::STXPX:
14650b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
1466bdd1243dSDimitry Andric     [[fallthrough]];
14670b57cec5SDimitry Andric   case AArch64::LDAXPX:
14680b57cec5SDimitry Andric   case AArch64::LDXPX:
14690b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
14700b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);
14710b57cec5SDimitry Andric     break;
14720b57cec5SDimitry Andric   }
14730b57cec5SDimitry Andric 
14740b57cec5SDimitry Andric   DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
14750b57cec5SDimitry Andric 
14760b57cec5SDimitry Andric   // You shouldn't load to the same register twice in an instruction...
14770b57cec5SDimitry Andric   if ((Opcode == AArch64::LDAXPW || Opcode == AArch64::LDXPW ||
14780b57cec5SDimitry Andric        Opcode == AArch64::LDAXPX || Opcode == AArch64::LDXPX) &&
14790b57cec5SDimitry Andric       Rt == Rt2)
14800b57cec5SDimitry Andric     return SoftFail;
14810b57cec5SDimitry Andric 
14820b57cec5SDimitry Andric   return Success;
14830b57cec5SDimitry Andric }
14840b57cec5SDimitry Andric 
DecodePairLdStInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)14850b57cec5SDimitry Andric static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,
14860b57cec5SDimitry Andric                                               uint64_t Addr,
148781ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
14880b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(insn, 0, 5);
14890b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
14900b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
14910b57cec5SDimitry Andric   int64_t offset = fieldFromInstruction(insn, 15, 7);
14920b57cec5SDimitry Andric   bool IsLoad = fieldFromInstruction(insn, 22, 1);
14930b57cec5SDimitry Andric 
14940b57cec5SDimitry Andric   // offset is a 7-bit signed immediate, so sign extend it to
14950b57cec5SDimitry Andric   // fill the unsigned.
14960b57cec5SDimitry Andric   if (offset & (1 << (7 - 1)))
14970b57cec5SDimitry Andric     offset |= ~((1LL << 7) - 1);
14980b57cec5SDimitry Andric 
14990b57cec5SDimitry Andric   unsigned Opcode = Inst.getOpcode();
15000b57cec5SDimitry Andric   bool NeedsDisjointWritebackTransfer = false;
15010b57cec5SDimitry Andric 
15020b57cec5SDimitry Andric   // First operand is always writeback of base register.
15030b57cec5SDimitry Andric   switch (Opcode) {
15040b57cec5SDimitry Andric   default:
15050b57cec5SDimitry Andric     break;
15060b57cec5SDimitry Andric   case AArch64::LDPXpost:
15070b57cec5SDimitry Andric   case AArch64::STPXpost:
15080b57cec5SDimitry Andric   case AArch64::LDPSWpost:
15090b57cec5SDimitry Andric   case AArch64::LDPXpre:
15100b57cec5SDimitry Andric   case AArch64::STPXpre:
15110b57cec5SDimitry Andric   case AArch64::LDPSWpre:
15120b57cec5SDimitry Andric   case AArch64::LDPWpost:
15130b57cec5SDimitry Andric   case AArch64::STPWpost:
15140b57cec5SDimitry Andric   case AArch64::LDPWpre:
15150b57cec5SDimitry Andric   case AArch64::STPWpre:
15160b57cec5SDimitry Andric   case AArch64::LDPQpost:
15170b57cec5SDimitry Andric   case AArch64::STPQpost:
15180b57cec5SDimitry Andric   case AArch64::LDPQpre:
15190b57cec5SDimitry Andric   case AArch64::STPQpre:
15200b57cec5SDimitry Andric   case AArch64::LDPDpost:
15210b57cec5SDimitry Andric   case AArch64::STPDpost:
15220b57cec5SDimitry Andric   case AArch64::LDPDpre:
15230b57cec5SDimitry Andric   case AArch64::STPDpre:
15240b57cec5SDimitry Andric   case AArch64::LDPSpost:
15250b57cec5SDimitry Andric   case AArch64::STPSpost:
15260b57cec5SDimitry Andric   case AArch64::LDPSpre:
15270b57cec5SDimitry Andric   case AArch64::STPSpre:
15280b57cec5SDimitry Andric   case AArch64::STGPpre:
15290b57cec5SDimitry Andric   case AArch64::STGPpost:
15300b57cec5SDimitry Andric     DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
15310b57cec5SDimitry Andric     break;
15320b57cec5SDimitry Andric   }
15330b57cec5SDimitry Andric 
15340b57cec5SDimitry Andric   switch (Opcode) {
15350b57cec5SDimitry Andric   default:
15360b57cec5SDimitry Andric     return Fail;
15370b57cec5SDimitry Andric   case AArch64::LDPXpost:
15380b57cec5SDimitry Andric   case AArch64::STPXpost:
15390b57cec5SDimitry Andric   case AArch64::LDPSWpost:
15400b57cec5SDimitry Andric   case AArch64::LDPXpre:
15410b57cec5SDimitry Andric   case AArch64::STPXpre:
15420b57cec5SDimitry Andric   case AArch64::LDPSWpre:
15430b57cec5SDimitry Andric   case AArch64::STGPpre:
15440b57cec5SDimitry Andric   case AArch64::STGPpost:
15450b57cec5SDimitry Andric     NeedsDisjointWritebackTransfer = true;
1546bdd1243dSDimitry Andric     [[fallthrough]];
15470b57cec5SDimitry Andric   case AArch64::LDNPXi:
15480b57cec5SDimitry Andric   case AArch64::STNPXi:
15490b57cec5SDimitry Andric   case AArch64::LDPXi:
15500b57cec5SDimitry Andric   case AArch64::STPXi:
15510b57cec5SDimitry Andric   case AArch64::LDPSWi:
15520b57cec5SDimitry Andric   case AArch64::STGPi:
15530b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
15540b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);
15550b57cec5SDimitry Andric     break;
15560b57cec5SDimitry Andric   case AArch64::LDPWpost:
15570b57cec5SDimitry Andric   case AArch64::STPWpost:
15580b57cec5SDimitry Andric   case AArch64::LDPWpre:
15590b57cec5SDimitry Andric   case AArch64::STPWpre:
15600b57cec5SDimitry Andric     NeedsDisjointWritebackTransfer = true;
1561bdd1243dSDimitry Andric     [[fallthrough]];
15620b57cec5SDimitry Andric   case AArch64::LDNPWi:
15630b57cec5SDimitry Andric   case AArch64::STNPWi:
15640b57cec5SDimitry Andric   case AArch64::LDPWi:
15650b57cec5SDimitry Andric   case AArch64::STPWi:
15660b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
15670b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);
15680b57cec5SDimitry Andric     break;
15690b57cec5SDimitry Andric   case AArch64::LDNPQi:
15700b57cec5SDimitry Andric   case AArch64::STNPQi:
15710b57cec5SDimitry Andric   case AArch64::LDPQpost:
15720b57cec5SDimitry Andric   case AArch64::STPQpost:
15730b57cec5SDimitry Andric   case AArch64::LDPQi:
15740b57cec5SDimitry Andric   case AArch64::STPQi:
15750b57cec5SDimitry Andric   case AArch64::LDPQpre:
15760b57cec5SDimitry Andric   case AArch64::STPQpre:
15770b57cec5SDimitry Andric     DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
15780b57cec5SDimitry Andric     DecodeFPR128RegisterClass(Inst, Rt2, Addr, Decoder);
15790b57cec5SDimitry Andric     break;
15800b57cec5SDimitry Andric   case AArch64::LDNPDi:
15810b57cec5SDimitry Andric   case AArch64::STNPDi:
15820b57cec5SDimitry Andric   case AArch64::LDPDpost:
15830b57cec5SDimitry Andric   case AArch64::STPDpost:
15840b57cec5SDimitry Andric   case AArch64::LDPDi:
15850b57cec5SDimitry Andric   case AArch64::STPDi:
15860b57cec5SDimitry Andric   case AArch64::LDPDpre:
15870b57cec5SDimitry Andric   case AArch64::STPDpre:
15880b57cec5SDimitry Andric     DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
15890b57cec5SDimitry Andric     DecodeFPR64RegisterClass(Inst, Rt2, Addr, Decoder);
15900b57cec5SDimitry Andric     break;
15910b57cec5SDimitry Andric   case AArch64::LDNPSi:
15920b57cec5SDimitry Andric   case AArch64::STNPSi:
15930b57cec5SDimitry Andric   case AArch64::LDPSpost:
15940b57cec5SDimitry Andric   case AArch64::STPSpost:
15950b57cec5SDimitry Andric   case AArch64::LDPSi:
15960b57cec5SDimitry Andric   case AArch64::STPSi:
15970b57cec5SDimitry Andric   case AArch64::LDPSpre:
15980b57cec5SDimitry Andric   case AArch64::STPSpre:
15990b57cec5SDimitry Andric     DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
16000b57cec5SDimitry Andric     DecodeFPR32RegisterClass(Inst, Rt2, Addr, Decoder);
16010b57cec5SDimitry Andric     break;
16020b57cec5SDimitry Andric   }
16030b57cec5SDimitry Andric 
16040b57cec5SDimitry Andric   DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
16050b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(offset));
16060b57cec5SDimitry Andric 
16070b57cec5SDimitry Andric   // You shouldn't load to the same register twice in an instruction...
16080b57cec5SDimitry Andric   if (IsLoad && Rt == Rt2)
16090b57cec5SDimitry Andric     return SoftFail;
16100b57cec5SDimitry Andric 
16110b57cec5SDimitry Andric   // ... or do any operation that writes-back to a transfer register. But note
16120b57cec5SDimitry Andric   // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.
16130b57cec5SDimitry Andric   if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn))
16140b57cec5SDimitry Andric     return SoftFail;
16150b57cec5SDimitry Andric 
16160b57cec5SDimitry Andric   return Success;
16170b57cec5SDimitry Andric }
16180b57cec5SDimitry Andric 
DecodeAuthLoadInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)16195ffd83dbSDimitry Andric static DecodeStatus DecodeAuthLoadInstruction(MCInst &Inst, uint32_t insn,
16205ffd83dbSDimitry Andric                                               uint64_t Addr,
162181ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
16225ffd83dbSDimitry Andric   unsigned Rt = fieldFromInstruction(insn, 0, 5);
16235ffd83dbSDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
16245ffd83dbSDimitry Andric   uint64_t offset = fieldFromInstruction(insn, 22, 1) << 9 |
16255ffd83dbSDimitry Andric                     fieldFromInstruction(insn, 12, 9);
16265ffd83dbSDimitry Andric   unsigned writeback = fieldFromInstruction(insn, 11, 1);
16275ffd83dbSDimitry Andric 
16285ffd83dbSDimitry Andric   switch (Inst.getOpcode()) {
16295ffd83dbSDimitry Andric   default:
16305ffd83dbSDimitry Andric     return Fail;
16315ffd83dbSDimitry Andric   case AArch64::LDRAAwriteback:
16325ffd83dbSDimitry Andric   case AArch64::LDRABwriteback:
16335ffd83dbSDimitry Andric     DecodeGPR64spRegisterClass(Inst, Rn /* writeback register */, Addr,
16345ffd83dbSDimitry Andric                                Decoder);
16355ffd83dbSDimitry Andric     break;
16365ffd83dbSDimitry Andric   case AArch64::LDRAAindexed:
16375ffd83dbSDimitry Andric   case AArch64::LDRABindexed:
16385ffd83dbSDimitry Andric     break;
16395ffd83dbSDimitry Andric   }
16405ffd83dbSDimitry Andric 
16415ffd83dbSDimitry Andric   DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
16425ffd83dbSDimitry Andric   DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
16435ffd83dbSDimitry Andric   DecodeSImm<10>(Inst, offset, Addr, Decoder);
16445ffd83dbSDimitry Andric 
16455ffd83dbSDimitry Andric   if (writeback && Rt == Rn && Rn != 31) {
16465ffd83dbSDimitry Andric     return SoftFail;
16475ffd83dbSDimitry Andric   }
16485ffd83dbSDimitry Andric 
16495ffd83dbSDimitry Andric   return Success;
16505ffd83dbSDimitry Andric }
16515ffd83dbSDimitry Andric 
DecodeAddSubERegInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)16520b57cec5SDimitry Andric static DecodeStatus DecodeAddSubERegInstruction(MCInst &Inst, uint32_t insn,
16530b57cec5SDimitry Andric                                                 uint64_t Addr,
165481ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
16550b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
16560b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
16570b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(insn, 16, 5);
16580b57cec5SDimitry Andric   unsigned extend = fieldFromInstruction(insn, 10, 6);
16590b57cec5SDimitry Andric 
16600b57cec5SDimitry Andric   unsigned shift = extend & 0x7;
16610b57cec5SDimitry Andric   if (shift > 4)
16620b57cec5SDimitry Andric     return Fail;
16630b57cec5SDimitry Andric 
16640b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
16650b57cec5SDimitry Andric   default:
16660b57cec5SDimitry Andric     return Fail;
16670b57cec5SDimitry Andric   case AArch64::ADDWrx:
16680b57cec5SDimitry Andric   case AArch64::SUBWrx:
16690b57cec5SDimitry Andric     DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
16700b57cec5SDimitry Andric     DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
16710b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
16720b57cec5SDimitry Andric     break;
16730b57cec5SDimitry Andric   case AArch64::ADDSWrx:
16740b57cec5SDimitry Andric   case AArch64::SUBSWrx:
16750b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
16760b57cec5SDimitry Andric     DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
16770b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
16780b57cec5SDimitry Andric     break;
16790b57cec5SDimitry Andric   case AArch64::ADDXrx:
16800b57cec5SDimitry Andric   case AArch64::SUBXrx:
16810b57cec5SDimitry Andric     DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
16820b57cec5SDimitry Andric     DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
16830b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
16840b57cec5SDimitry Andric     break;
16850b57cec5SDimitry Andric   case AArch64::ADDSXrx:
16860b57cec5SDimitry Andric   case AArch64::SUBSXrx:
16870b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
16880b57cec5SDimitry Andric     DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
16890b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
16900b57cec5SDimitry Andric     break;
16910b57cec5SDimitry Andric   case AArch64::ADDXrx64:
16920b57cec5SDimitry Andric   case AArch64::SUBXrx64:
16930b57cec5SDimitry Andric     DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
16940b57cec5SDimitry Andric     DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
16950b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
16960b57cec5SDimitry Andric     break;
16970b57cec5SDimitry Andric   case AArch64::SUBSXrx64:
16980b57cec5SDimitry Andric   case AArch64::ADDSXrx64:
16990b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
17000b57cec5SDimitry Andric     DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
17010b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
17020b57cec5SDimitry Andric     break;
17030b57cec5SDimitry Andric   }
17040b57cec5SDimitry Andric 
17050b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(extend));
17060b57cec5SDimitry Andric   return Success;
17070b57cec5SDimitry Andric }
17080b57cec5SDimitry Andric 
DecodeLogicalImmInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)17090b57cec5SDimitry Andric static DecodeStatus DecodeLogicalImmInstruction(MCInst &Inst, uint32_t insn,
17100b57cec5SDimitry Andric                                                 uint64_t Addr,
171181ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
17120b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
17130b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
17140b57cec5SDimitry Andric   unsigned Datasize = fieldFromInstruction(insn, 31, 1);
17150b57cec5SDimitry Andric   unsigned imm;
17160b57cec5SDimitry Andric 
17170b57cec5SDimitry Andric   if (Datasize) {
17180b57cec5SDimitry Andric     if (Inst.getOpcode() == AArch64::ANDSXri)
17190b57cec5SDimitry Andric       DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
17200b57cec5SDimitry Andric     else
17210b57cec5SDimitry Andric       DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
17220b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder);
17230b57cec5SDimitry Andric     imm = fieldFromInstruction(insn, 10, 13);
17240b57cec5SDimitry Andric     if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 64))
17250b57cec5SDimitry Andric       return Fail;
17260b57cec5SDimitry Andric   } else {
17270b57cec5SDimitry Andric     if (Inst.getOpcode() == AArch64::ANDSWri)
17280b57cec5SDimitry Andric       DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
17290b57cec5SDimitry Andric     else
17300b57cec5SDimitry Andric       DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
17310b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder);
17320b57cec5SDimitry Andric     imm = fieldFromInstruction(insn, 10, 12);
17330b57cec5SDimitry Andric     if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 32))
17340b57cec5SDimitry Andric       return Fail;
17350b57cec5SDimitry Andric   }
17360b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
17370b57cec5SDimitry Andric   return Success;
17380b57cec5SDimitry Andric }
17390b57cec5SDimitry Andric 
DecodeModImmInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)17400b57cec5SDimitry Andric static DecodeStatus DecodeModImmInstruction(MCInst &Inst, uint32_t insn,
17410b57cec5SDimitry Andric                                             uint64_t Addr,
174281ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
17430b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
17440b57cec5SDimitry Andric   unsigned cmode = fieldFromInstruction(insn, 12, 4);
17450b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
17460b57cec5SDimitry Andric   imm |= fieldFromInstruction(insn, 5, 5);
17470b57cec5SDimitry Andric 
17480b57cec5SDimitry Andric   if (Inst.getOpcode() == AArch64::MOVID)
17490b57cec5SDimitry Andric     DecodeFPR64RegisterClass(Inst, Rd, Addr, Decoder);
17500b57cec5SDimitry Andric   else
1751349cc55cSDimitry Andric     DecodeFPR128RegisterClass(Inst, Rd, Addr, Decoder);
17520b57cec5SDimitry Andric 
17530b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
17540b57cec5SDimitry Andric 
17550b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
17560b57cec5SDimitry Andric   default:
17570b57cec5SDimitry Andric     break;
17580b57cec5SDimitry Andric   case AArch64::MOVIv4i16:
17590b57cec5SDimitry Andric   case AArch64::MOVIv8i16:
17600b57cec5SDimitry Andric   case AArch64::MVNIv4i16:
17610b57cec5SDimitry Andric   case AArch64::MVNIv8i16:
17620b57cec5SDimitry Andric   case AArch64::MOVIv2i32:
17630b57cec5SDimitry Andric   case AArch64::MOVIv4i32:
17640b57cec5SDimitry Andric   case AArch64::MVNIv2i32:
17650b57cec5SDimitry Andric   case AArch64::MVNIv4i32:
17660b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
17670b57cec5SDimitry Andric     break;
17680b57cec5SDimitry Andric   case AArch64::MOVIv2s_msl:
17690b57cec5SDimitry Andric   case AArch64::MOVIv4s_msl:
17700b57cec5SDimitry Andric   case AArch64::MVNIv2s_msl:
17710b57cec5SDimitry Andric   case AArch64::MVNIv4s_msl:
17720b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm((cmode & 1) ? 0x110 : 0x108));
17730b57cec5SDimitry Andric     break;
17740b57cec5SDimitry Andric   }
17750b57cec5SDimitry Andric 
17760b57cec5SDimitry Andric   return Success;
17770b57cec5SDimitry Andric }
17780b57cec5SDimitry Andric 
DecodeModImmTiedInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)17790b57cec5SDimitry Andric static DecodeStatus DecodeModImmTiedInstruction(MCInst &Inst, uint32_t insn,
17800b57cec5SDimitry Andric                                                 uint64_t Addr,
178181ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
17820b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
17830b57cec5SDimitry Andric   unsigned cmode = fieldFromInstruction(insn, 12, 4);
17840b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
17850b57cec5SDimitry Andric   imm |= fieldFromInstruction(insn, 5, 5);
17860b57cec5SDimitry Andric 
17870b57cec5SDimitry Andric   // Tied operands added twice.
1788349cc55cSDimitry Andric   DecodeFPR128RegisterClass(Inst, Rd, Addr, Decoder);
1789349cc55cSDimitry Andric   DecodeFPR128RegisterClass(Inst, Rd, Addr, Decoder);
17900b57cec5SDimitry Andric 
17910b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
17920b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
17930b57cec5SDimitry Andric 
17940b57cec5SDimitry Andric   return Success;
17950b57cec5SDimitry Andric }
17960b57cec5SDimitry Andric 
DecodeAdrInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)17970b57cec5SDimitry Andric static DecodeStatus DecodeAdrInstruction(MCInst &Inst, uint32_t insn,
179881ad6265SDimitry Andric                                          uint64_t Addr,
179981ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
18000b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
18010b57cec5SDimitry Andric   int64_t imm = fieldFromInstruction(insn, 5, 19) << 2;
18020b57cec5SDimitry Andric   imm |= fieldFromInstruction(insn, 29, 2);
18030b57cec5SDimitry Andric 
18040b57cec5SDimitry Andric   // Sign-extend the 21-bit immediate.
18050b57cec5SDimitry Andric   if (imm & (1 << (21 - 1)))
18060b57cec5SDimitry Andric     imm |= ~((1LL << 21) - 1);
18070b57cec5SDimitry Andric 
18080b57cec5SDimitry Andric   DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
180981ad6265SDimitry Andric   if (!Decoder->tryAddingSymbolicOperand(Inst, imm, Addr, Fail, 0, 0, 4))
18100b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
18110b57cec5SDimitry Andric 
18120b57cec5SDimitry Andric   return Success;
18130b57cec5SDimitry Andric }
18140b57cec5SDimitry Andric 
DecodeAddSubImmShift(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)18150b57cec5SDimitry Andric static DecodeStatus DecodeAddSubImmShift(MCInst &Inst, uint32_t insn,
181681ad6265SDimitry Andric                                          uint64_t Addr,
181781ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
18180b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
18190b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
18200b57cec5SDimitry Andric   unsigned Imm = fieldFromInstruction(insn, 10, 14);
18210b57cec5SDimitry Andric   unsigned S = fieldFromInstruction(insn, 29, 1);
18220b57cec5SDimitry Andric   unsigned Datasize = fieldFromInstruction(insn, 31, 1);
18230b57cec5SDimitry Andric 
18240b57cec5SDimitry Andric   unsigned ShifterVal = (Imm >> 12) & 3;
18250b57cec5SDimitry Andric   unsigned ImmVal = Imm & 0xFFF;
18260b57cec5SDimitry Andric 
18270b57cec5SDimitry Andric   if (ShifterVal != 0 && ShifterVal != 1)
18280b57cec5SDimitry Andric     return Fail;
18290b57cec5SDimitry Andric 
18300b57cec5SDimitry Andric   if (Datasize) {
18310b57cec5SDimitry Andric     if (Rd == 31 && !S)
18320b57cec5SDimitry Andric       DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
18330b57cec5SDimitry Andric     else
18340b57cec5SDimitry Andric       DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
18350b57cec5SDimitry Andric     DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
18360b57cec5SDimitry Andric   } else {
18370b57cec5SDimitry Andric     if (Rd == 31 && !S)
18380b57cec5SDimitry Andric       DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
18390b57cec5SDimitry Andric     else
18400b57cec5SDimitry Andric       DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
18410b57cec5SDimitry Andric     DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
18420b57cec5SDimitry Andric   }
18430b57cec5SDimitry Andric 
184481ad6265SDimitry Andric   if (!Decoder->tryAddingSymbolicOperand(Inst, Imm, Addr, Fail, 0, 0, 4))
18450b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ImmVal));
18460b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(12 * ShifterVal));
18470b57cec5SDimitry Andric   return Success;
18480b57cec5SDimitry Andric }
18490b57cec5SDimitry Andric 
DecodeUnconditionalBranch(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)18500b57cec5SDimitry Andric static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn,
18510b57cec5SDimitry Andric                                               uint64_t Addr,
185281ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
18530b57cec5SDimitry Andric   int64_t imm = fieldFromInstruction(insn, 0, 26);
18540b57cec5SDimitry Andric 
18550b57cec5SDimitry Andric   // Sign-extend the 26-bit immediate.
18560b57cec5SDimitry Andric   if (imm & (1 << (26 - 1)))
18570b57cec5SDimitry Andric     imm |= ~((1LL << 26) - 1);
18580b57cec5SDimitry Andric 
185981ad6265SDimitry Andric   if (!Decoder->tryAddingSymbolicOperand(Inst, imm * 4, Addr, true, 0, 0, 4))
18600b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
18610b57cec5SDimitry Andric 
18620b57cec5SDimitry Andric   return Success;
18630b57cec5SDimitry Andric }
18640b57cec5SDimitry Andric 
isInvalidPState(uint64_t Op1,uint64_t Op2)1865bdd1243dSDimitry Andric static bool isInvalidPState(uint64_t Op1, uint64_t Op2) {
1866bdd1243dSDimitry Andric   return Op1 == 0b000 && (Op2 == 0b000 || // CFINV
1867bdd1243dSDimitry Andric                           Op2 == 0b001 || // XAFlag
1868bdd1243dSDimitry Andric                           Op2 == 0b010);  // AXFlag
1869bdd1243dSDimitry Andric }
1870bdd1243dSDimitry Andric 
187181ad6265SDimitry Andric static DecodeStatus
DecodeSystemPStateImm0_15Instruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)1872bdd1243dSDimitry Andric DecodeSystemPStateImm0_15Instruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
187381ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
18740b57cec5SDimitry Andric   uint64_t op1 = fieldFromInstruction(insn, 16, 3);
18750b57cec5SDimitry Andric   uint64_t op2 = fieldFromInstruction(insn, 5, 3);
1876bdd1243dSDimitry Andric   uint64_t imm = fieldFromInstruction(insn, 8, 4);
18770b57cec5SDimitry Andric   uint64_t pstate_field = (op1 << 3) | op2;
18780b57cec5SDimitry Andric 
1879bdd1243dSDimitry Andric   if (isInvalidPState(op1, op2))
18800b57cec5SDimitry Andric     return Fail;
18810b57cec5SDimitry Andric 
18820b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(pstate_field));
1883bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
18840b57cec5SDimitry Andric 
1885bdd1243dSDimitry Andric   auto PState = AArch64PState::lookupPStateImm0_15ByEncoding(pstate_field);
1886bdd1243dSDimitry Andric   if (PState &&
1887bdd1243dSDimitry Andric       PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits()))
1888bdd1243dSDimitry Andric     return Success;
1889bdd1243dSDimitry Andric   return Fail;
1890bdd1243dSDimitry Andric }
1891bdd1243dSDimitry Andric 
1892bdd1243dSDimitry Andric static DecodeStatus
DecodeSystemPStateImm0_1Instruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)1893bdd1243dSDimitry Andric DecodeSystemPStateImm0_1Instruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
1894bdd1243dSDimitry Andric                                     const MCDisassembler *Decoder) {
1895bdd1243dSDimitry Andric   uint64_t op1 = fieldFromInstruction(insn, 16, 3);
1896bdd1243dSDimitry Andric   uint64_t op2 = fieldFromInstruction(insn, 5, 3);
1897bdd1243dSDimitry Andric   uint64_t crm_high = fieldFromInstruction(insn, 9, 3);
1898bdd1243dSDimitry Andric   uint64_t imm = fieldFromInstruction(insn, 8, 1);
1899bdd1243dSDimitry Andric   uint64_t pstate_field = (crm_high << 6) | (op1 << 3) | op2;
1900bdd1243dSDimitry Andric 
1901bdd1243dSDimitry Andric   if (isInvalidPState(op1, op2))
1902bdd1243dSDimitry Andric     return Fail;
1903bdd1243dSDimitry Andric 
1904bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(pstate_field));
1905bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
1906bdd1243dSDimitry Andric 
1907bdd1243dSDimitry Andric   auto PState = AArch64PState::lookupPStateImm0_1ByEncoding(pstate_field);
190881ad6265SDimitry Andric   if (PState &&
190981ad6265SDimitry Andric       PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits()))
19100b57cec5SDimitry Andric     return Success;
19110b57cec5SDimitry Andric   return Fail;
19120b57cec5SDimitry Andric }
19130b57cec5SDimitry Andric 
DecodeTestAndBranch(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)19140b57cec5SDimitry Andric static DecodeStatus DecodeTestAndBranch(MCInst &Inst, uint32_t insn,
191581ad6265SDimitry Andric                                         uint64_t Addr,
191681ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
19170b57cec5SDimitry Andric   uint64_t Rt = fieldFromInstruction(insn, 0, 5);
19180b57cec5SDimitry Andric   uint64_t bit = fieldFromInstruction(insn, 31, 1) << 5;
19190b57cec5SDimitry Andric   bit |= fieldFromInstruction(insn, 19, 5);
19200b57cec5SDimitry Andric   int64_t dst = fieldFromInstruction(insn, 5, 14);
19210b57cec5SDimitry Andric 
19220b57cec5SDimitry Andric   // Sign-extend 14-bit immediate.
19230b57cec5SDimitry Andric   if (dst & (1 << (14 - 1)))
19240b57cec5SDimitry Andric     dst |= ~((1LL << 14) - 1);
19250b57cec5SDimitry Andric 
19260b57cec5SDimitry Andric   if (fieldFromInstruction(insn, 31, 1) == 0)
19270b57cec5SDimitry Andric     DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
19280b57cec5SDimitry Andric   else
19290b57cec5SDimitry Andric     DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
19300b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(bit));
193181ad6265SDimitry Andric   if (!Decoder->tryAddingSymbolicOperand(Inst, dst * 4, Addr, true, 0, 0, 4))
19320b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(dst));
19330b57cec5SDimitry Andric 
19340b57cec5SDimitry Andric   return Success;
19350b57cec5SDimitry Andric }
19360b57cec5SDimitry Andric 
193781ad6265SDimitry Andric static DecodeStatus
DecodeGPRSeqPairsClassRegisterClass(MCInst & Inst,unsigned RegClassID,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)193881ad6265SDimitry Andric DecodeGPRSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegClassID,
193981ad6265SDimitry Andric                                     unsigned RegNo, uint64_t Addr,
194081ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
19410b57cec5SDimitry Andric   // Register number must be even (see CASP instruction)
19420b57cec5SDimitry Andric   if (RegNo & 0x1)
19430b57cec5SDimitry Andric     return Fail;
19440b57cec5SDimitry Andric 
19450b57cec5SDimitry Andric   unsigned Reg = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo / 2);
19460b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
19470b57cec5SDimitry Andric   return Success;
19480b57cec5SDimitry Andric }
19490b57cec5SDimitry Andric 
195081ad6265SDimitry Andric static DecodeStatus
DecodeWSeqPairsClassRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)195181ad6265SDimitry Andric DecodeWSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
195281ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
19530b57cec5SDimitry Andric   return DecodeGPRSeqPairsClassRegisterClass(Inst,
19540b57cec5SDimitry Andric                                              AArch64::WSeqPairsClassRegClassID,
19550b57cec5SDimitry Andric                                              RegNo, Addr, Decoder);
19560b57cec5SDimitry Andric }
19570b57cec5SDimitry Andric 
195881ad6265SDimitry Andric static DecodeStatus
DecodeXSeqPairsClassRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)195981ad6265SDimitry Andric DecodeXSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
196081ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
19610b57cec5SDimitry Andric   return DecodeGPRSeqPairsClassRegisterClass(Inst,
19620b57cec5SDimitry Andric                                              AArch64::XSeqPairsClassRegClassID,
19630b57cec5SDimitry Andric                                              RegNo, Addr, Decoder);
19640b57cec5SDimitry Andric }
19650b57cec5SDimitry Andric 
DecodeSyspXzrInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)1966bdd1243dSDimitry Andric static DecodeStatus DecodeSyspXzrInstruction(MCInst &Inst, uint32_t insn,
1967bdd1243dSDimitry Andric                                              uint64_t Addr,
1968bdd1243dSDimitry Andric                                              const MCDisassembler *Decoder) {
1969bdd1243dSDimitry Andric   unsigned op1 = fieldFromInstruction(insn, 16, 3);
1970bdd1243dSDimitry Andric   unsigned CRn = fieldFromInstruction(insn, 12, 4);
1971bdd1243dSDimitry Andric   unsigned CRm = fieldFromInstruction(insn, 8, 4);
1972bdd1243dSDimitry Andric   unsigned op2 = fieldFromInstruction(insn, 5, 3);
1973bdd1243dSDimitry Andric   unsigned Rt = fieldFromInstruction(insn, 0, 5);
1974bdd1243dSDimitry Andric   if (Rt != 0b11111)
1975bdd1243dSDimitry Andric     return Fail;
1976bdd1243dSDimitry Andric 
1977bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(op1));
1978bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(CRn));
1979bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(CRm));
1980bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(op2));
1981bdd1243dSDimitry Andric   DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
1982bdd1243dSDimitry Andric 
1983bdd1243dSDimitry Andric   return Success;
1984bdd1243dSDimitry Andric }
1985bdd1243dSDimitry Andric 
198681ad6265SDimitry Andric static DecodeStatus
DecodeSVELogicalImmInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)198781ad6265SDimitry Andric DecodeSVELogicalImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
198881ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
19890b57cec5SDimitry Andric   unsigned Zdn = fieldFromInstruction(insn, 0, 5);
19900b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(insn, 5, 13);
19910b57cec5SDimitry Andric   if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 64))
19920b57cec5SDimitry Andric     return Fail;
19930b57cec5SDimitry Andric 
19940b57cec5SDimitry Andric   // The same (tied) operand is added twice to the instruction.
19950b57cec5SDimitry Andric   DecodeZPRRegisterClass(Inst, Zdn, Addr, Decoder);
19960b57cec5SDimitry Andric   if (Inst.getOpcode() != AArch64::DUPM_ZI)
19970b57cec5SDimitry Andric     DecodeZPRRegisterClass(Inst, Zdn, Addr, Decoder);
19980b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
19990b57cec5SDimitry Andric   return Success;
20000b57cec5SDimitry Andric }
20010b57cec5SDimitry Andric 
20020b57cec5SDimitry Andric template <int Bits>
DecodeSImm(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)2003349cc55cSDimitry Andric static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
200481ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
20050b57cec5SDimitry Andric   if (Imm & ~((1LL << Bits) - 1))
20060b57cec5SDimitry Andric       return Fail;
20070b57cec5SDimitry Andric 
20080b57cec5SDimitry Andric   // Imm is a signed immediate, so sign extend it.
20090b57cec5SDimitry Andric   if (Imm & (1 << (Bits - 1)))
20100b57cec5SDimitry Andric     Imm |= ~((1LL << Bits) - 1);
20110b57cec5SDimitry Andric 
20120b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
20130b57cec5SDimitry Andric   return Success;
20140b57cec5SDimitry Andric }
20150b57cec5SDimitry Andric 
20160b57cec5SDimitry Andric // Decode 8-bit signed/unsigned immediate for a given element width.
20170b57cec5SDimitry Andric template <int ElementWidth>
DecodeImm8OptLsl(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)201881ad6265SDimitry Andric static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm, uint64_t Addr,
201981ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
20200b57cec5SDimitry Andric   unsigned Val = (uint8_t)Imm;
20210b57cec5SDimitry Andric   unsigned Shift = (Imm & 0x100) ? 8 : 0;
20220b57cec5SDimitry Andric   if (ElementWidth == 8 && Shift)
20230b57cec5SDimitry Andric     return Fail;
20240b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
20250b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Shift));
20260b57cec5SDimitry Andric   return Success;
20270b57cec5SDimitry Andric }
20280b57cec5SDimitry Andric 
20290b57cec5SDimitry Andric // Decode uimm4 ranged from 1-16.
DecodeSVEIncDecImm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)20300b57cec5SDimitry Andric static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,
203181ad6265SDimitry Andric                                        uint64_t Addr,
203281ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
20330b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm + 1));
20340b57cec5SDimitry Andric   return Success;
20350b57cec5SDimitry Andric }
2036fe6060f1SDimitry Andric 
DecodeSVCROp(MCInst & Inst,unsigned Imm,uint64_t Address,const MCDisassembler * Decoder)2037fe6060f1SDimitry Andric static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,
203881ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
2039fe6060f1SDimitry Andric   if (AArch64SVCR::lookupSVCRByEncoding(Imm)) {
2040fe6060f1SDimitry Andric     Inst.addOperand(MCOperand::createImm(Imm));
2041fe6060f1SDimitry Andric     return Success;
2042fe6060f1SDimitry Andric   }
2043fe6060f1SDimitry Andric   return Fail;
2044fe6060f1SDimitry Andric }
204504eeddc0SDimitry Andric 
DecodeCPYMemOpInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)204604eeddc0SDimitry Andric static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn,
204704eeddc0SDimitry Andric                                               uint64_t Addr,
204881ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
204904eeddc0SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
205004eeddc0SDimitry Andric   unsigned Rs = fieldFromInstruction(insn, 16, 5);
205104eeddc0SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
205204eeddc0SDimitry Andric 
205304eeddc0SDimitry Andric   // None of the registers may alias: if they do, then the instruction is not
205404eeddc0SDimitry Andric   // merely unpredictable but actually entirely unallocated.
205504eeddc0SDimitry Andric   if (Rd == Rs || Rs == Rn || Rd == Rn)
205604eeddc0SDimitry Andric     return MCDisassembler::Fail;
205704eeddc0SDimitry Andric 
205804eeddc0SDimitry Andric   // All three register operands are written back, so they all appear
205904eeddc0SDimitry Andric   // twice in the operand list, once as outputs and once as inputs.
206004eeddc0SDimitry Andric   if (!DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) ||
206104eeddc0SDimitry Andric       !DecodeGPR64commonRegisterClass(Inst, Rs, Addr, Decoder) ||
206204eeddc0SDimitry Andric       !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) ||
206304eeddc0SDimitry Andric       !DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) ||
206404eeddc0SDimitry Andric       !DecodeGPR64commonRegisterClass(Inst, Rs, Addr, Decoder) ||
206504eeddc0SDimitry Andric       !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder))
206604eeddc0SDimitry Andric     return MCDisassembler::Fail;
206704eeddc0SDimitry Andric 
206804eeddc0SDimitry Andric   return MCDisassembler::Success;
206904eeddc0SDimitry Andric }
207004eeddc0SDimitry Andric 
DecodeSETMemOpInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)207104eeddc0SDimitry Andric static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn,
207204eeddc0SDimitry Andric                                               uint64_t Addr,
207381ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
207404eeddc0SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
207504eeddc0SDimitry Andric   unsigned Rm = fieldFromInstruction(insn, 16, 5);
207604eeddc0SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
207704eeddc0SDimitry Andric 
207804eeddc0SDimitry Andric   // None of the registers may alias: if they do, then the instruction is not
207904eeddc0SDimitry Andric   // merely unpredictable but actually entirely unallocated.
208004eeddc0SDimitry Andric   if (Rd == Rm || Rm == Rn || Rd == Rn)
208104eeddc0SDimitry Andric     return MCDisassembler::Fail;
208204eeddc0SDimitry Andric 
208304eeddc0SDimitry Andric   // Rd and Rn (not Rm) register operands are written back, so they appear
208404eeddc0SDimitry Andric   // twice in the operand list, once as outputs and once as inputs.
208504eeddc0SDimitry Andric   if (!DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) ||
208604eeddc0SDimitry Andric       !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) ||
208704eeddc0SDimitry Andric       !DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) ||
208804eeddc0SDimitry Andric       !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) ||
208904eeddc0SDimitry Andric       !DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder))
209004eeddc0SDimitry Andric     return MCDisassembler::Fail;
209104eeddc0SDimitry Andric 
209204eeddc0SDimitry Andric   return MCDisassembler::Success;
209304eeddc0SDimitry Andric }
2094bdd1243dSDimitry Andric 
DecodePRFMRegInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)2095bdd1243dSDimitry Andric static DecodeStatus DecodePRFMRegInstruction(MCInst &Inst, uint32_t insn,
2096bdd1243dSDimitry Andric                                              uint64_t Addr,
2097bdd1243dSDimitry Andric                                              const MCDisassembler *Decoder) {
2098bdd1243dSDimitry Andric   // PRFM with Rt = '11xxx' should be decoded as RPRFM.
2099bdd1243dSDimitry Andric   // Fail to decode and defer to fallback decoder table to decode RPRFM.
2100bdd1243dSDimitry Andric   unsigned Mask = 0x18;
2101bdd1243dSDimitry Andric   uint64_t Rt = fieldFromInstruction(insn, 0, 5);
2102bdd1243dSDimitry Andric   if ((Rt & Mask) == Mask)
2103bdd1243dSDimitry Andric     return Fail;
2104bdd1243dSDimitry Andric 
2105bdd1243dSDimitry Andric   uint64_t Rn = fieldFromInstruction(insn, 5, 5);
2106bdd1243dSDimitry Andric   uint64_t Shift = fieldFromInstruction(insn, 12, 1);
2107bdd1243dSDimitry Andric   uint64_t Extend = fieldFromInstruction(insn, 15, 1);
2108bdd1243dSDimitry Andric   uint64_t Rm = fieldFromInstruction(insn, 16, 5);
2109bdd1243dSDimitry Andric 
2110bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(Rt));
2111bdd1243dSDimitry Andric   DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
2112bdd1243dSDimitry Andric 
2113bdd1243dSDimitry Andric   switch (Inst.getOpcode()) {
2114bdd1243dSDimitry Andric   default:
2115bdd1243dSDimitry Andric     return Fail;
2116bdd1243dSDimitry Andric   case AArch64::PRFMroW:
2117bdd1243dSDimitry Andric     DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
2118bdd1243dSDimitry Andric     break;
2119bdd1243dSDimitry Andric   case AArch64::PRFMroX:
2120bdd1243dSDimitry Andric     DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
2121bdd1243dSDimitry Andric     break;
2122bdd1243dSDimitry Andric   }
2123bdd1243dSDimitry Andric 
2124bdd1243dSDimitry Andric   DecodeMemExtend(Inst, (Extend << 1) | Shift, Addr, Decoder);
2125bdd1243dSDimitry Andric 
2126bdd1243dSDimitry Andric   return Success;
2127bdd1243dSDimitry Andric }
2128