xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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.
41*0fca6ea1SDimitry Andric template <unsigned RegClassID, unsigned FirstReg, unsigned NumRegsInClass>
42*0fca6ea1SDimitry Andric static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, unsigned RegNo,
430b57cec5SDimitry Andric                                               uint64_t Address,
4481ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
4581ad6265SDimitry Andric static DecodeStatus
4681ad6265SDimitry Andric DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
4781ad6265SDimitry Andric                                 const MCDisassembler *Decoder);
48bdd1243dSDimitry Andric static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
49bdd1243dSDimitry Andric                                                 uint64_t Address,
50bdd1243dSDimitry Andric                                                 const void *Decoder);
51bdd1243dSDimitry Andric static DecodeStatus DecodeZPR4Mul4RegisterClass(MCInst &Inst, unsigned RegNo,
52bdd1243dSDimitry Andric                                                 uint64_t Address,
53bdd1243dSDimitry Andric                                                 const void *Decoder);
54fe6060f1SDimitry Andric template <unsigned NumBitsForTile>
55fe6060f1SDimitry Andric static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo,
56fe6060f1SDimitry Andric                                      uint64_t Address,
5781ad6265SDimitry Andric                                      const MCDisassembler *Decoder);
5881ad6265SDimitry Andric static DecodeStatus
5981ad6265SDimitry Andric DecodeMatrixTileListRegisterClass(MCInst &Inst, unsigned RegMask,
6081ad6265SDimitry Andric                                   uint64_t Address,
6181ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
62bdd1243dSDimitry Andric static DecodeStatus DecodePPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
63bdd1243dSDimitry Andric                                                 uint64_t Address,
64bdd1243dSDimitry Andric                                                 const void *Decoder);
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm,
670b57cec5SDimitry Andric                                                uint64_t Address,
6881ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
690b57cec5SDimitry Andric static DecodeStatus DecodeFixedPointScaleImm64(MCInst &Inst, unsigned Imm,
700b57cec5SDimitry Andric                                                uint64_t Address,
7181ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
72cb14a3feSDimitry Andric static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm,
73cb14a3feSDimitry Andric                                        uint64_t Address,
74cb14a3feSDimitry Andric                                        const MCDisassembler *Decoder);
750b57cec5SDimitry Andric static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
760b57cec5SDimitry Andric                                        uint64_t Address,
7781ad6265SDimitry Andric                                        const MCDisassembler *Decoder);
7881ad6265SDimitry Andric static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
7981ad6265SDimitry Andric                                     uint64_t Address,
8081ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
8181ad6265SDimitry Andric static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm,
8281ad6265SDimitry Andric                                             uint64_t Address,
8381ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
8481ad6265SDimitry Andric static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm,
8581ad6265SDimitry Andric                                             uint64_t Address,
8681ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
8781ad6265SDimitry Andric static DecodeStatus
8881ad6265SDimitry Andric DecodeThreeAddrSRegInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
8981ad6265SDimitry Andric                                const MCDisassembler *Decoder);
900b57cec5SDimitry Andric static DecodeStatus DecodeMoveImmInstruction(MCInst &Inst, uint32_t insn,
910b57cec5SDimitry Andric                                              uint64_t Address,
9281ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
9381ad6265SDimitry Andric static DecodeStatus
9481ad6265SDimitry Andric DecodeUnsignedLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
9581ad6265SDimitry Andric                               const MCDisassembler *Decoder);
960b57cec5SDimitry Andric static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
970b57cec5SDimitry Andric                                                 uint64_t Address,
9881ad6265SDimitry Andric                                                 const MCDisassembler *Decoder);
9981ad6265SDimitry Andric static DecodeStatus
10081ad6265SDimitry Andric DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
10181ad6265SDimitry Andric                                const MCDisassembler *Decoder);
1020b57cec5SDimitry Andric static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,
1030b57cec5SDimitry Andric                                               uint64_t Address,
10481ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
1055ffd83dbSDimitry Andric static DecodeStatus DecodeAuthLoadInstruction(MCInst &Inst, uint32_t insn,
1065ffd83dbSDimitry Andric                                               uint64_t Address,
10781ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
1080b57cec5SDimitry Andric static DecodeStatus DecodeAddSubERegInstruction(MCInst &Inst, uint32_t insn,
1090b57cec5SDimitry Andric                                                 uint64_t Address,
11081ad6265SDimitry Andric                                                 const MCDisassembler *Decoder);
1110b57cec5SDimitry Andric static DecodeStatus DecodeLogicalImmInstruction(MCInst &Inst, uint32_t insn,
1120b57cec5SDimitry Andric                                                 uint64_t Address,
11381ad6265SDimitry Andric                                                 const MCDisassembler *Decoder);
1140b57cec5SDimitry Andric static DecodeStatus DecodeModImmInstruction(MCInst &Inst, uint32_t insn,
1150b57cec5SDimitry Andric                                             uint64_t Address,
11681ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
1170b57cec5SDimitry Andric static DecodeStatus DecodeModImmTiedInstruction(MCInst &Inst, uint32_t insn,
1180b57cec5SDimitry Andric                                                 uint64_t Address,
11981ad6265SDimitry Andric                                                 const MCDisassembler *Decoder);
1200b57cec5SDimitry Andric static DecodeStatus DecodeAdrInstruction(MCInst &Inst, uint32_t insn,
12181ad6265SDimitry Andric                                          uint64_t Address,
12281ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
1230b57cec5SDimitry Andric static DecodeStatus DecodeAddSubImmShift(MCInst &Inst, uint32_t insn,
12481ad6265SDimitry Andric                                          uint64_t Address,
12581ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
1260b57cec5SDimitry Andric static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn,
1270b57cec5SDimitry Andric                                               uint64_t Address,
12881ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
12981ad6265SDimitry Andric static DecodeStatus
130bdd1243dSDimitry Andric DecodeSystemPStateImm0_15Instruction(MCInst &Inst, uint32_t insn,
131bdd1243dSDimitry Andric                                      uint64_t Address,
132bdd1243dSDimitry Andric                                      const MCDisassembler *Decoder);
133bdd1243dSDimitry Andric static DecodeStatus
134bdd1243dSDimitry Andric DecodeSystemPStateImm0_1Instruction(MCInst &Inst, uint32_t insn,
135bdd1243dSDimitry Andric                                     uint64_t Address,
13681ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
1370b57cec5SDimitry Andric static DecodeStatus DecodeTestAndBranch(MCInst &Inst, uint32_t insn,
13881ad6265SDimitry Andric                                         uint64_t Address,
13981ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric static DecodeStatus DecodeFMOVLaneInstruction(MCInst &Inst, unsigned Insn,
1420b57cec5SDimitry Andric                                               uint64_t Address,
14381ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
1440b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm,
14581ad6265SDimitry Andric                                          uint64_t Addr,
14681ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
1470b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst &Inst, unsigned Imm,
1480b57cec5SDimitry Andric                                                uint64_t Addr,
14981ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1500b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm,
15181ad6265SDimitry Andric                                          uint64_t Addr,
15281ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
1530b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst &Inst, unsigned Imm,
1540b57cec5SDimitry Andric                                                uint64_t Addr,
15581ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1560b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm,
15781ad6265SDimitry Andric                                          uint64_t Addr,
15881ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
1590b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst &Inst, unsigned Imm,
1600b57cec5SDimitry Andric                                                uint64_t Addr,
16181ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1620b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm,
16381ad6265SDimitry Andric                                         uint64_t Addr,
16481ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
1650b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm,
16681ad6265SDimitry Andric                                          uint64_t Addr,
16781ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
1680b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm,
16981ad6265SDimitry Andric                                          uint64_t Addr,
17081ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
1710b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm,
17281ad6265SDimitry Andric                                          uint64_t Addr,
17381ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
1740b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm,
1750b57cec5SDimitry Andric                                         uint64_t Addr,
17681ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
17781ad6265SDimitry Andric static DecodeStatus
17881ad6265SDimitry Andric DecodeWSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
17981ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
18081ad6265SDimitry Andric static DecodeStatus
18181ad6265SDimitry Andric DecodeXSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
18281ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
183bdd1243dSDimitry Andric static DecodeStatus DecodeSyspXzrInstruction(MCInst &Inst, uint32_t insn,
184bdd1243dSDimitry Andric                                              uint64_t Addr,
185bdd1243dSDimitry Andric                                              const MCDisassembler *Decoder);
18681ad6265SDimitry Andric static DecodeStatus
18781ad6265SDimitry Andric DecodeSVELogicalImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
18881ad6265SDimitry Andric                                const MCDisassembler *Decoder);
1890b57cec5SDimitry Andric template <int Bits>
190349cc55cSDimitry Andric static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
19181ad6265SDimitry Andric                                const MCDisassembler *Decoder);
1920b57cec5SDimitry Andric template <int ElementWidth>
19381ad6265SDimitry Andric static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm, uint64_t Addr,
19481ad6265SDimitry Andric                                      const MCDisassembler *Decoder);
1950b57cec5SDimitry Andric static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,
19681ad6265SDimitry Andric                                        uint64_t Addr,
19781ad6265SDimitry Andric                                        const MCDisassembler *Decoder);
198fe6060f1SDimitry Andric static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,
19981ad6265SDimitry Andric                                  const MCDisassembler *Decoder);
20004eeddc0SDimitry Andric static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn,
20104eeddc0SDimitry Andric                                               uint64_t Addr,
20281ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
20304eeddc0SDimitry Andric static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn,
20404eeddc0SDimitry Andric                                               uint64_t Addr,
20581ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
206bdd1243dSDimitry Andric static DecodeStatus DecodePRFMRegInstruction(MCInst &Inst, uint32_t insn,
207bdd1243dSDimitry Andric                                              uint64_t Address,
208bdd1243dSDimitry Andric                                              const MCDisassembler *Decoder);
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric #include "AArch64GenDisassemblerTables.inc"
2110b57cec5SDimitry Andric #include "AArch64GenInstrInfo.inc"
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric #define Success MCDisassembler::Success
2140b57cec5SDimitry Andric #define Fail MCDisassembler::Fail
2150b57cec5SDimitry Andric #define SoftFail MCDisassembler::SoftFail
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric static MCDisassembler *createAArch64Disassembler(const Target &T,
2180b57cec5SDimitry Andric                                                  const MCSubtargetInfo &STI,
2190b57cec5SDimitry Andric                                                  MCContext &Ctx) {
22081ad6265SDimitry Andric 
22181ad6265SDimitry Andric   return new AArch64Disassembler(STI, Ctx, T.createMCInstrInfo());
2220b57cec5SDimitry Andric }
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
2250b57cec5SDimitry Andric                                                  ArrayRef<uint8_t> Bytes,
2260b57cec5SDimitry Andric                                                  uint64_t Address,
2270b57cec5SDimitry Andric                                                  raw_ostream &CS) const {
2280b57cec5SDimitry Andric   CommentStream = &CS;
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric   Size = 0;
2310b57cec5SDimitry Andric   // We want to read exactly 4 bytes of data.
2320b57cec5SDimitry Andric   if (Bytes.size() < 4)
2330b57cec5SDimitry Andric     return Fail;
2340b57cec5SDimitry Andric   Size = 4;
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric   // Encoded as a small-endian 32-bit word in the stream.
2370b57cec5SDimitry Andric   uint32_t Insn =
2380b57cec5SDimitry Andric       (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
2390b57cec5SDimitry Andric 
240e8d8bef9SDimitry Andric   const uint8_t *Tables[] = {DecoderTable32, DecoderTableFallback32};
241e8d8bef9SDimitry Andric 
242bdd1243dSDimitry Andric   for (const auto *Table : Tables) {
243e8d8bef9SDimitry Andric     DecodeStatus Result =
244e8d8bef9SDimitry Andric         decodeInstruction(Table, MI, Insn, Address, this, STI);
245fe6060f1SDimitry Andric 
24681ad6265SDimitry Andric     const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
24781ad6265SDimitry Andric 
24881ad6265SDimitry Andric     // For Scalable Matrix Extension (SME) instructions that have an implicit
24981ad6265SDimitry Andric     // operand for the accumulator (ZA) or implicit immediate zero which isn't
25081ad6265SDimitry Andric     // encoded, manually insert operand.
25181ad6265SDimitry Andric     for (unsigned i = 0; i < Desc.getNumOperands(); i++) {
252bdd1243dSDimitry Andric       if (Desc.operands()[i].OperandType == MCOI::OPERAND_REGISTER) {
253bdd1243dSDimitry Andric         switch (Desc.operands()[i].RegClass) {
254fe6060f1SDimitry Andric         default:
255fe6060f1SDimitry Andric           break;
25681ad6265SDimitry Andric         case AArch64::MPRRegClassID:
25781ad6265SDimitry Andric           MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZA));
25881ad6265SDimitry Andric           break;
25981ad6265SDimitry Andric         case AArch64::MPR8RegClassID:
26081ad6265SDimitry Andric           MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZAB0));
26181ad6265SDimitry Andric           break;
262bdd1243dSDimitry Andric         case AArch64::ZTRRegClassID:
263bdd1243dSDimitry Andric           MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZT0));
264bdd1243dSDimitry Andric           break;
26581ad6265SDimitry Andric         }
266bdd1243dSDimitry Andric       } else if (Desc.operands()[i].OperandType ==
26781ad6265SDimitry Andric                  AArch64::OPERAND_IMPLICIT_IMM_0) {
26881ad6265SDimitry Andric         MI.insert(MI.begin() + i, MCOperand::createImm(0));
26981ad6265SDimitry Andric       }
27081ad6265SDimitry Andric     }
27181ad6265SDimitry Andric 
27281ad6265SDimitry Andric     if (MI.getOpcode() == AArch64::LDR_ZA ||
27381ad6265SDimitry Andric         MI.getOpcode() == AArch64::STR_ZA) {
27481ad6265SDimitry Andric       // Spill and fill instructions have a single immediate used for both
27581ad6265SDimitry Andric       // the vector select offset and optional memory offset. Replicate
27681ad6265SDimitry Andric       // the decoded immediate.
277fe6060f1SDimitry Andric       const MCOperand &Imm4Op = MI.getOperand(2);
278fe6060f1SDimitry Andric       assert(Imm4Op.isImm() && "Unexpected operand type!");
279fe6060f1SDimitry Andric       MI.addOperand(Imm4Op);
280fe6060f1SDimitry Andric     }
281fe6060f1SDimitry Andric 
282e8d8bef9SDimitry Andric     if (Result != MCDisassembler::Fail)
283e8d8bef9SDimitry Andric       return Result;
284e8d8bef9SDimitry Andric   }
285e8d8bef9SDimitry Andric 
286e8d8bef9SDimitry Andric   return MCDisassembler::Fail;
2870b57cec5SDimitry Andric }
2880b57cec5SDimitry Andric 
289972a253aSDimitry Andric uint64_t AArch64Disassembler::suggestBytesToSkip(ArrayRef<uint8_t> Bytes,
290972a253aSDimitry Andric                                                  uint64_t Address) const {
291972a253aSDimitry Andric   // AArch64 instructions are always 4 bytes wide, so there's no point
292972a253aSDimitry Andric   // in skipping any smaller number of bytes if an instruction can't
293972a253aSDimitry Andric   // be decoded.
294972a253aSDimitry Andric   return 4;
295972a253aSDimitry Andric }
296972a253aSDimitry Andric 
2970b57cec5SDimitry Andric static MCSymbolizer *
2980b57cec5SDimitry Andric createAArch64ExternalSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,
2990b57cec5SDimitry Andric                                 LLVMSymbolLookupCallback SymbolLookUp,
3000b57cec5SDimitry Andric                                 void *DisInfo, MCContext *Ctx,
3010b57cec5SDimitry Andric                                 std::unique_ptr<MCRelocationInfo> &&RelInfo) {
3020b57cec5SDimitry Andric   return new AArch64ExternalSymbolizer(*Ctx, std::move(RelInfo), GetOpInfo,
3030b57cec5SDimitry Andric                                        SymbolLookUp, DisInfo);
3040b57cec5SDimitry Andric }
3050b57cec5SDimitry Andric 
306480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Disassembler() {
3070b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheAArch64leTarget(),
3080b57cec5SDimitry Andric                                          createAArch64Disassembler);
3090b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheAArch64beTarget(),
3100b57cec5SDimitry Andric                                          createAArch64Disassembler);
3110b57cec5SDimitry Andric   TargetRegistry::RegisterMCSymbolizer(getTheAArch64leTarget(),
3120b57cec5SDimitry Andric                                        createAArch64ExternalSymbolizer);
3130b57cec5SDimitry Andric   TargetRegistry::RegisterMCSymbolizer(getTheAArch64beTarget(),
3140b57cec5SDimitry Andric                                        createAArch64ExternalSymbolizer);
3150b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheAArch64_32Target(),
3160b57cec5SDimitry Andric                                          createAArch64Disassembler);
3170b57cec5SDimitry Andric   TargetRegistry::RegisterMCSymbolizer(getTheAArch64_32Target(),
3180b57cec5SDimitry Andric                                        createAArch64ExternalSymbolizer);
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheARM64Target(),
3210b57cec5SDimitry Andric                                          createAArch64Disassembler);
3220b57cec5SDimitry Andric   TargetRegistry::RegisterMCSymbolizer(getTheARM64Target(),
3230b57cec5SDimitry Andric                                        createAArch64ExternalSymbolizer);
3240b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheARM64_32Target(),
3250b57cec5SDimitry Andric                                          createAArch64Disassembler);
3260b57cec5SDimitry Andric   TargetRegistry::RegisterMCSymbolizer(getTheARM64_32Target(),
3270b57cec5SDimitry Andric                                        createAArch64ExternalSymbolizer);
3280b57cec5SDimitry Andric }
3290b57cec5SDimitry Andric 
330*0fca6ea1SDimitry Andric template <unsigned RegClassID, unsigned FirstReg, unsigned NumRegsInClass>
331*0fca6ea1SDimitry Andric static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, unsigned RegNo,
332*0fca6ea1SDimitry Andric                                               uint64_t Address,
33381ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
334*0fca6ea1SDimitry Andric   if (RegNo > NumRegsInClass - 1)
3350b57cec5SDimitry Andric     return Fail;
3360b57cec5SDimitry Andric 
337349cc55cSDimitry Andric   unsigned Register =
338*0fca6ea1SDimitry Andric       AArch64MCRegisterClasses[RegClassID].getRegister(RegNo + FirstReg);
3390b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
3400b57cec5SDimitry Andric   return Success;
3410b57cec5SDimitry Andric }
3420b57cec5SDimitry Andric 
34381ad6265SDimitry Andric static DecodeStatus
34481ad6265SDimitry Andric DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
34581ad6265SDimitry Andric                                 const MCDisassembler *Decoder) {
346e8d8bef9SDimitry Andric   if (RegNo > 22)
347e8d8bef9SDimitry Andric     return Fail;
348e8d8bef9SDimitry Andric   if (RegNo & 1)
349e8d8bef9SDimitry Andric     return Fail;
350e8d8bef9SDimitry Andric 
351349cc55cSDimitry Andric   unsigned Register =
352349cc55cSDimitry Andric       AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].getRegister(
353349cc55cSDimitry Andric           RegNo >> 1);
354e8d8bef9SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
355e8d8bef9SDimitry Andric   return Success;
356e8d8bef9SDimitry Andric }
357e8d8bef9SDimitry Andric 
358bdd1243dSDimitry Andric static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
359bdd1243dSDimitry Andric                                                 uint64_t Address,
360bdd1243dSDimitry Andric                                                 const void *Decoder) {
361bdd1243dSDimitry Andric   if (RegNo * 2 > 30)
362bdd1243dSDimitry Andric     return Fail;
363bdd1243dSDimitry Andric   unsigned Register =
364bdd1243dSDimitry Andric       AArch64MCRegisterClasses[AArch64::ZPR2RegClassID].getRegister(RegNo * 2);
365bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
366bdd1243dSDimitry Andric   return Success;
367bdd1243dSDimitry Andric }
368bdd1243dSDimitry Andric 
369bdd1243dSDimitry Andric static DecodeStatus DecodeZPR4Mul4RegisterClass(MCInst &Inst, unsigned RegNo,
370bdd1243dSDimitry Andric                                                 uint64_t Address,
371bdd1243dSDimitry Andric                                                 const void *Decoder) {
372bdd1243dSDimitry Andric   if (RegNo * 4 > 28)
373bdd1243dSDimitry Andric     return Fail;
374bdd1243dSDimitry Andric   unsigned Register =
375bdd1243dSDimitry Andric       AArch64MCRegisterClasses[AArch64::ZPR4RegClassID].getRegister(RegNo * 4);
376bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
377bdd1243dSDimitry Andric   return Success;
378bdd1243dSDimitry Andric }
379bdd1243dSDimitry Andric 
38081ad6265SDimitry Andric static DecodeStatus
38181ad6265SDimitry Andric DecodeMatrixTileListRegisterClass(MCInst &Inst, unsigned RegMask,
382fe6060f1SDimitry Andric                                   uint64_t Address,
38381ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
384fe6060f1SDimitry Andric   if (RegMask > 0xFF)
385fe6060f1SDimitry Andric     return Fail;
386fe6060f1SDimitry Andric   Inst.addOperand(MCOperand::createImm(RegMask));
387fe6060f1SDimitry Andric   return Success;
388fe6060f1SDimitry Andric }
389fe6060f1SDimitry Andric 
39006c3fb27SDimitry Andric static const MCPhysReg MatrixZATileDecoderTable[5][16] = {
391fe6060f1SDimitry Andric     {AArch64::ZAB0},
392fe6060f1SDimitry Andric     {AArch64::ZAH0, AArch64::ZAH1},
393fe6060f1SDimitry Andric     {AArch64::ZAS0, AArch64::ZAS1, AArch64::ZAS2, AArch64::ZAS3},
39406c3fb27SDimitry Andric     {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3, AArch64::ZAD4,
39506c3fb27SDimitry Andric      AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7},
39606c3fb27SDimitry Andric     {AArch64::ZAQ0, AArch64::ZAQ1, AArch64::ZAQ2, AArch64::ZAQ3, AArch64::ZAQ4,
39706c3fb27SDimitry Andric      AArch64::ZAQ5, AArch64::ZAQ6, AArch64::ZAQ7, AArch64::ZAQ8, AArch64::ZAQ9,
39806c3fb27SDimitry Andric      AArch64::ZAQ10, AArch64::ZAQ11, AArch64::ZAQ12, AArch64::ZAQ13,
39906c3fb27SDimitry Andric      AArch64::ZAQ14, AArch64::ZAQ15}};
400fe6060f1SDimitry Andric 
401fe6060f1SDimitry Andric template <unsigned NumBitsForTile>
402fe6060f1SDimitry Andric static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo,
40381ad6265SDimitry Andric                                      uint64_t Address,
40481ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
405fe6060f1SDimitry Andric   unsigned LastReg = (1 << NumBitsForTile) - 1;
406fe6060f1SDimitry Andric   if (RegNo > LastReg)
407fe6060f1SDimitry Andric     return Fail;
408fe6060f1SDimitry Andric   Inst.addOperand(
409fe6060f1SDimitry Andric       MCOperand::createReg(MatrixZATileDecoderTable[NumBitsForTile][RegNo]));
410fe6060f1SDimitry Andric   return Success;
411fe6060f1SDimitry Andric }
412fe6060f1SDimitry Andric 
413bdd1243dSDimitry Andric static DecodeStatus DecodePPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
414bdd1243dSDimitry Andric                                                 uint64_t Address,
415bdd1243dSDimitry Andric                                                 const void *Decoder) {
416bdd1243dSDimitry Andric   if ((RegNo * 2) > 14)
417bdd1243dSDimitry Andric     return Fail;
418bdd1243dSDimitry Andric   unsigned Register =
419bdd1243dSDimitry Andric       AArch64MCRegisterClasses[AArch64::PPR2RegClassID].getRegister(RegNo * 2);
420bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
421bdd1243dSDimitry Andric   return Success;
422bdd1243dSDimitry Andric }
423bdd1243dSDimitry Andric 
4240b57cec5SDimitry Andric static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm,
4250b57cec5SDimitry Andric                                                uint64_t Addr,
42681ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
4270b57cec5SDimitry Andric   // scale{5} is asserted as 1 in tblgen.
4280b57cec5SDimitry Andric   Imm |= 0x20;
4290b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - Imm));
4300b57cec5SDimitry Andric   return Success;
4310b57cec5SDimitry Andric }
4320b57cec5SDimitry Andric 
4330b57cec5SDimitry Andric static DecodeStatus DecodeFixedPointScaleImm64(MCInst &Inst, unsigned Imm,
4340b57cec5SDimitry Andric                                                uint64_t Addr,
43581ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
4360b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(64 - Imm));
4370b57cec5SDimitry Andric   return Success;
4380b57cec5SDimitry Andric }
4390b57cec5SDimitry Andric 
440cb14a3feSDimitry Andric static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm,
441cb14a3feSDimitry Andric                                        uint64_t Addr,
442cb14a3feSDimitry Andric                                        const MCDisassembler *Decoder) {
443cb14a3feSDimitry Andric   // Immediate is encoded as the top 16-bits of an unsigned 18-bit negative
444cb14a3feSDimitry Andric   // PC-relative offset.
445cb14a3feSDimitry Andric   uint64_t ImmVal = Imm;
446647cbc5dSDimitry Andric   if (ImmVal > (1 << 16))
447cb14a3feSDimitry Andric     return Fail;
448cb14a3feSDimitry Andric   ImmVal = -ImmVal;
449cb14a3feSDimitry Andric   if (!Decoder->tryAddingSymbolicOperand(Inst, (ImmVal << 2), Addr,
450cb14a3feSDimitry Andric                                          /*IsBranch=*/false, 0, 0, 4))
451cb14a3feSDimitry Andric     Inst.addOperand(MCOperand::createImm(ImmVal));
452cb14a3feSDimitry Andric   return Success;
453cb14a3feSDimitry Andric }
454cb14a3feSDimitry Andric 
4550b57cec5SDimitry Andric static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
45681ad6265SDimitry Andric                                        uint64_t Addr,
45781ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
4580b57cec5SDimitry Andric   int64_t ImmVal = Imm;
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric   // Sign-extend 19-bit immediate.
4610b57cec5SDimitry Andric   if (ImmVal & (1 << (19 - 1)))
4620b57cec5SDimitry Andric     ImmVal |= ~((1LL << 19) - 1);
4630b57cec5SDimitry Andric 
46481ad6265SDimitry Andric   if (!Decoder->tryAddingSymbolicOperand(
46581ad6265SDimitry Andric           Inst, ImmVal * 4, Addr, Inst.getOpcode() != AArch64::LDRXl, 0, 0, 4))
4660b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ImmVal));
4670b57cec5SDimitry Andric   return Success;
4680b57cec5SDimitry Andric }
4690b57cec5SDimitry Andric 
4700b57cec5SDimitry Andric static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
47181ad6265SDimitry Andric                                     uint64_t Address,
47281ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
4730b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm((Imm >> 1) & 1));
4740b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm & 1));
4750b57cec5SDimitry Andric   return Success;
4760b57cec5SDimitry Andric }
4770b57cec5SDimitry Andric 
4780b57cec5SDimitry Andric static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm,
4790b57cec5SDimitry Andric                                             uint64_t Address,
48081ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
4810b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
4820b57cec5SDimitry Andric 
4830b57cec5SDimitry Andric   // Every system register in the encoding space is valid with the syntax
4840b57cec5SDimitry Andric   // S<op0>_<op1>_<Cn>_<Cm>_<op2>, so decoding system registers always succeeds.
4850b57cec5SDimitry Andric   return Success;
4860b57cec5SDimitry Andric }
4870b57cec5SDimitry Andric 
4880b57cec5SDimitry Andric static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm,
4890b57cec5SDimitry Andric                                             uint64_t Address,
49081ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
4910b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
4920b57cec5SDimitry Andric 
4930b57cec5SDimitry Andric   return Success;
4940b57cec5SDimitry Andric }
4950b57cec5SDimitry Andric 
4960b57cec5SDimitry Andric static DecodeStatus DecodeFMOVLaneInstruction(MCInst &Inst, unsigned Insn,
4970b57cec5SDimitry Andric                                               uint64_t Address,
49881ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
4990b57cec5SDimitry Andric   // This decoder exists to add the dummy Lane operand to the MCInst, which must
5000b57cec5SDimitry Andric   // be 1 in assembly but has no other real manifestation.
5010b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(Insn, 0, 5);
5020b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(Insn, 5, 5);
5030b57cec5SDimitry Andric   unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
5040b57cec5SDimitry Andric 
5050b57cec5SDimitry Andric   if (IsToVec) {
506*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(
507*0fca6ea1SDimitry Andric         Inst, Rd, Address, Decoder);
508*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
509*0fca6ea1SDimitry Andric         Inst, Rn, Address, Decoder);
5100b57cec5SDimitry Andric   } else {
511*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
512*0fca6ea1SDimitry Andric         Inst, Rd, Address, Decoder);
513*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(
514*0fca6ea1SDimitry Andric         Inst, Rn, Address, Decoder);
5150b57cec5SDimitry Andric   }
5160b57cec5SDimitry Andric 
5170b57cec5SDimitry Andric   // Add the lane
5180b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(1));
5190b57cec5SDimitry Andric 
5200b57cec5SDimitry Andric   return Success;
5210b57cec5SDimitry Andric }
5220b57cec5SDimitry Andric 
5230b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftRImm(MCInst &Inst, unsigned Imm,
5240b57cec5SDimitry Andric                                        unsigned Add) {
5250b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Add - Imm));
5260b57cec5SDimitry Andric   return Success;
5270b57cec5SDimitry Andric }
5280b57cec5SDimitry Andric 
5290b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftLImm(MCInst &Inst, unsigned Imm,
5300b57cec5SDimitry Andric                                        unsigned Add) {
5310b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm((Imm + Add) & (Add - 1)));
5320b57cec5SDimitry Andric   return Success;
5330b57cec5SDimitry Andric }
5340b57cec5SDimitry Andric 
5350b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm,
53681ad6265SDimitry Andric                                          uint64_t Addr,
53781ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
5380b57cec5SDimitry Andric   return DecodeVecShiftRImm(Inst, Imm, 64);
5390b57cec5SDimitry Andric }
5400b57cec5SDimitry Andric 
5410b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst &Inst, unsigned Imm,
5420b57cec5SDimitry Andric                                                uint64_t Addr,
54381ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
5440b57cec5SDimitry Andric   return DecodeVecShiftRImm(Inst, Imm | 0x20, 64);
5450b57cec5SDimitry Andric }
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm,
54881ad6265SDimitry Andric                                          uint64_t Addr,
54981ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
5500b57cec5SDimitry Andric   return DecodeVecShiftRImm(Inst, Imm, 32);
5510b57cec5SDimitry Andric }
5520b57cec5SDimitry Andric 
5530b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst &Inst, unsigned Imm,
5540b57cec5SDimitry Andric                                                uint64_t Addr,
55581ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
5560b57cec5SDimitry Andric   return DecodeVecShiftRImm(Inst, Imm | 0x10, 32);
5570b57cec5SDimitry Andric }
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm,
56081ad6265SDimitry Andric                                          uint64_t Addr,
56181ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
5620b57cec5SDimitry Andric   return DecodeVecShiftRImm(Inst, Imm, 16);
5630b57cec5SDimitry Andric }
5640b57cec5SDimitry Andric 
5650b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst &Inst, unsigned Imm,
5660b57cec5SDimitry Andric                                                uint64_t Addr,
56781ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
5680b57cec5SDimitry Andric   return DecodeVecShiftRImm(Inst, Imm | 0x8, 16);
5690b57cec5SDimitry Andric }
5700b57cec5SDimitry Andric 
5710b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm,
57281ad6265SDimitry Andric                                         uint64_t Addr,
57381ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
5740b57cec5SDimitry Andric   return DecodeVecShiftRImm(Inst, Imm, 8);
5750b57cec5SDimitry Andric }
5760b57cec5SDimitry Andric 
5770b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm,
57881ad6265SDimitry Andric                                          uint64_t Addr,
57981ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
5800b57cec5SDimitry Andric   return DecodeVecShiftLImm(Inst, Imm, 64);
5810b57cec5SDimitry Andric }
5820b57cec5SDimitry Andric 
5830b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm,
58481ad6265SDimitry Andric                                          uint64_t Addr,
58581ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
5860b57cec5SDimitry Andric   return DecodeVecShiftLImm(Inst, Imm, 32);
5870b57cec5SDimitry Andric }
5880b57cec5SDimitry Andric 
5890b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm,
59081ad6265SDimitry Andric                                          uint64_t Addr,
59181ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
5920b57cec5SDimitry Andric   return DecodeVecShiftLImm(Inst, Imm, 16);
5930b57cec5SDimitry Andric }
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm,
59681ad6265SDimitry Andric                                         uint64_t Addr,
59781ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
5980b57cec5SDimitry Andric   return DecodeVecShiftLImm(Inst, Imm, 8);
5990b57cec5SDimitry Andric }
6000b57cec5SDimitry Andric 
60181ad6265SDimitry Andric static DecodeStatus
60281ad6265SDimitry Andric DecodeThreeAddrSRegInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
60381ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
6040b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
6050b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
6060b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(insn, 16, 5);
6070b57cec5SDimitry Andric   unsigned shiftHi = fieldFromInstruction(insn, 22, 2);
6080b57cec5SDimitry Andric   unsigned shiftLo = fieldFromInstruction(insn, 10, 6);
6090b57cec5SDimitry Andric   unsigned shift = (shiftHi << 6) | shiftLo;
6100b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
6110b57cec5SDimitry Andric   default:
6120b57cec5SDimitry Andric     return Fail;
6130b57cec5SDimitry Andric   case AArch64::ADDWrs:
6140b57cec5SDimitry Andric   case AArch64::ADDSWrs:
6150b57cec5SDimitry Andric   case AArch64::SUBWrs:
6160b57cec5SDimitry Andric   case AArch64::SUBSWrs:
6170b57cec5SDimitry Andric     // if shift == '11' then ReservedValue()
6180b57cec5SDimitry Andric     if (shiftHi == 0x3)
6190b57cec5SDimitry Andric       return Fail;
620bdd1243dSDimitry Andric     [[fallthrough]];
6210b57cec5SDimitry Andric   case AArch64::ANDWrs:
6220b57cec5SDimitry Andric   case AArch64::ANDSWrs:
6230b57cec5SDimitry Andric   case AArch64::BICWrs:
6240b57cec5SDimitry Andric   case AArch64::BICSWrs:
6250b57cec5SDimitry Andric   case AArch64::ORRWrs:
6260b57cec5SDimitry Andric   case AArch64::ORNWrs:
6270b57cec5SDimitry Andric   case AArch64::EORWrs:
6280b57cec5SDimitry Andric   case AArch64::EONWrs: {
6290b57cec5SDimitry Andric     // if sf == '0' and imm6<5> == '1' then ReservedValue()
6300b57cec5SDimitry Andric     if (shiftLo >> 5 == 1)
6310b57cec5SDimitry Andric       return Fail;
632*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr,
633*0fca6ea1SDimitry Andric                                                                Decoder);
634*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rn, Addr,
635*0fca6ea1SDimitry Andric                                                                Decoder);
636*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,
637*0fca6ea1SDimitry Andric                                                                Decoder);
6380b57cec5SDimitry Andric     break;
6390b57cec5SDimitry Andric   }
6400b57cec5SDimitry Andric   case AArch64::ADDXrs:
6410b57cec5SDimitry Andric   case AArch64::ADDSXrs:
6420b57cec5SDimitry Andric   case AArch64::SUBXrs:
6430b57cec5SDimitry Andric   case AArch64::SUBSXrs:
6440b57cec5SDimitry Andric     // if shift == '11' then ReservedValue()
6450b57cec5SDimitry Andric     if (shiftHi == 0x3)
6460b57cec5SDimitry Andric       return Fail;
647bdd1243dSDimitry Andric     [[fallthrough]];
6480b57cec5SDimitry Andric   case AArch64::ANDXrs:
6490b57cec5SDimitry Andric   case AArch64::ANDSXrs:
6500b57cec5SDimitry Andric   case AArch64::BICXrs:
6510b57cec5SDimitry Andric   case AArch64::BICSXrs:
6520b57cec5SDimitry Andric   case AArch64::ORRXrs:
6530b57cec5SDimitry Andric   case AArch64::ORNXrs:
6540b57cec5SDimitry Andric   case AArch64::EORXrs:
6550b57cec5SDimitry Andric   case AArch64::EONXrs:
656*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,
657*0fca6ea1SDimitry Andric                                                                Decoder);
658*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rn, Addr,
659*0fca6ea1SDimitry Andric                                                                Decoder);
660*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rm, Addr,
661*0fca6ea1SDimitry Andric                                                                Decoder);
6620b57cec5SDimitry Andric     break;
6630b57cec5SDimitry Andric   }
6640b57cec5SDimitry Andric 
6650b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(shift));
6660b57cec5SDimitry Andric   return Success;
6670b57cec5SDimitry Andric }
6680b57cec5SDimitry Andric 
6690b57cec5SDimitry Andric static DecodeStatus DecodeMoveImmInstruction(MCInst &Inst, uint32_t insn,
6700b57cec5SDimitry Andric                                              uint64_t Addr,
67181ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
6720b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
6730b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(insn, 5, 16);
6740b57cec5SDimitry Andric   unsigned shift = fieldFromInstruction(insn, 21, 2);
6750b57cec5SDimitry Andric   shift <<= 4;
6760b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
6770b57cec5SDimitry Andric   default:
6780b57cec5SDimitry Andric     return Fail;
6790b57cec5SDimitry Andric   case AArch64::MOVZWi:
6800b57cec5SDimitry Andric   case AArch64::MOVNWi:
6810b57cec5SDimitry Andric   case AArch64::MOVKWi:
6820b57cec5SDimitry Andric     if (shift & (1U << 5))
6830b57cec5SDimitry Andric       return Fail;
684*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr,
685*0fca6ea1SDimitry Andric                                                                Decoder);
6860b57cec5SDimitry Andric     break;
6870b57cec5SDimitry Andric   case AArch64::MOVZXi:
6880b57cec5SDimitry Andric   case AArch64::MOVNXi:
6890b57cec5SDimitry Andric   case AArch64::MOVKXi:
690*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,
691*0fca6ea1SDimitry Andric                                                                Decoder);
6920b57cec5SDimitry Andric     break;
6930b57cec5SDimitry Andric   }
6940b57cec5SDimitry Andric 
6950b57cec5SDimitry Andric   if (Inst.getOpcode() == AArch64::MOVKWi ||
6960b57cec5SDimitry Andric       Inst.getOpcode() == AArch64::MOVKXi)
6970b57cec5SDimitry Andric     Inst.addOperand(Inst.getOperand(0));
6980b57cec5SDimitry Andric 
6990b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
7000b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(shift));
7010b57cec5SDimitry Andric   return Success;
7020b57cec5SDimitry Andric }
7030b57cec5SDimitry Andric 
70481ad6265SDimitry Andric static DecodeStatus
70581ad6265SDimitry Andric DecodeUnsignedLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
70681ad6265SDimitry Andric                               const MCDisassembler *Decoder) {
7070b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(insn, 0, 5);
7080b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
7090b57cec5SDimitry Andric   unsigned offset = fieldFromInstruction(insn, 10, 12);
7100b57cec5SDimitry Andric 
7110b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
7120b57cec5SDimitry Andric   default:
7130b57cec5SDimitry Andric     return Fail;
7140b57cec5SDimitry Andric   case AArch64::PRFMui:
7150b57cec5SDimitry Andric     // Rt is an immediate in prefetch.
7160b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Rt));
7170b57cec5SDimitry Andric     break;
7180b57cec5SDimitry Andric   case AArch64::STRBBui:
7190b57cec5SDimitry Andric   case AArch64::LDRBBui:
7200b57cec5SDimitry Andric   case AArch64::LDRSBWui:
7210b57cec5SDimitry Andric   case AArch64::STRHHui:
7220b57cec5SDimitry Andric   case AArch64::LDRHHui:
7230b57cec5SDimitry Andric   case AArch64::LDRSHWui:
7240b57cec5SDimitry Andric   case AArch64::STRWui:
7250b57cec5SDimitry Andric   case AArch64::LDRWui:
726*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,
727*0fca6ea1SDimitry Andric                                                                Decoder);
7280b57cec5SDimitry Andric     break;
7290b57cec5SDimitry Andric   case AArch64::LDRSBXui:
7300b57cec5SDimitry Andric   case AArch64::LDRSHXui:
7310b57cec5SDimitry Andric   case AArch64::LDRSWui:
7320b57cec5SDimitry Andric   case AArch64::STRXui:
7330b57cec5SDimitry Andric   case AArch64::LDRXui:
734*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,
735*0fca6ea1SDimitry Andric                                                                Decoder);
7360b57cec5SDimitry Andric     break;
7370b57cec5SDimitry Andric   case AArch64::LDRQui:
7380b57cec5SDimitry Andric   case AArch64::STRQui:
739*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rt, Addr,
740*0fca6ea1SDimitry Andric                                                                 Decoder);
7410b57cec5SDimitry Andric     break;
7420b57cec5SDimitry Andric   case AArch64::LDRDui:
7430b57cec5SDimitry Andric   case AArch64::STRDui:
744*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rt, Addr,
745*0fca6ea1SDimitry Andric                                                                Decoder);
7460b57cec5SDimitry Andric     break;
7470b57cec5SDimitry Andric   case AArch64::LDRSui:
7480b57cec5SDimitry Andric   case AArch64::STRSui:
749*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, Rt, Addr,
750*0fca6ea1SDimitry Andric                                                                Decoder);
7510b57cec5SDimitry Andric     break;
7520b57cec5SDimitry Andric   case AArch64::LDRHui:
7530b57cec5SDimitry Andric   case AArch64::STRHui:
754*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR16RegClassID, 0, 32>(Inst, Rt, Addr,
755*0fca6ea1SDimitry Andric                                                                Decoder);
7560b57cec5SDimitry Andric     break;
7570b57cec5SDimitry Andric   case AArch64::LDRBui:
7580b57cec5SDimitry Andric   case AArch64::STRBui:
759*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR8RegClassID, 0, 32>(Inst, Rt, Addr,
760*0fca6ea1SDimitry Andric                                                               Decoder);
7610b57cec5SDimitry Andric     break;
7620b57cec5SDimitry Andric   }
7630b57cec5SDimitry Andric 
764*0fca6ea1SDimitry Andric   DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
765*0fca6ea1SDimitry Andric                                                                Decoder);
76681ad6265SDimitry Andric   if (!Decoder->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 0, 4))
7670b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(offset));
7680b57cec5SDimitry Andric   return Success;
7690b57cec5SDimitry Andric }
7700b57cec5SDimitry Andric 
7710b57cec5SDimitry Andric static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
7720b57cec5SDimitry Andric                                                 uint64_t Addr,
77381ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
7740b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(insn, 0, 5);
7750b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
7760b57cec5SDimitry Andric   int64_t offset = fieldFromInstruction(insn, 12, 9);
7770b57cec5SDimitry Andric 
7780b57cec5SDimitry Andric   // offset is a 9-bit signed immediate, so sign extend it to
7790b57cec5SDimitry Andric   // fill the unsigned.
7800b57cec5SDimitry Andric   if (offset & (1 << (9 - 1)))
7810b57cec5SDimitry Andric     offset |= ~((1LL << 9) - 1);
7820b57cec5SDimitry Andric 
7830b57cec5SDimitry Andric   // First operand is always the writeback to the address register, if needed.
7840b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
7850b57cec5SDimitry Andric   default:
7860b57cec5SDimitry Andric     break;
7870b57cec5SDimitry Andric   case AArch64::LDRSBWpre:
7880b57cec5SDimitry Andric   case AArch64::LDRSHWpre:
7890b57cec5SDimitry Andric   case AArch64::STRBBpre:
7900b57cec5SDimitry Andric   case AArch64::LDRBBpre:
7910b57cec5SDimitry Andric   case AArch64::STRHHpre:
7920b57cec5SDimitry Andric   case AArch64::LDRHHpre:
7930b57cec5SDimitry Andric   case AArch64::STRWpre:
7940b57cec5SDimitry Andric   case AArch64::LDRWpre:
7950b57cec5SDimitry Andric   case AArch64::LDRSBWpost:
7960b57cec5SDimitry Andric   case AArch64::LDRSHWpost:
7970b57cec5SDimitry Andric   case AArch64::STRBBpost:
7980b57cec5SDimitry Andric   case AArch64::LDRBBpost:
7990b57cec5SDimitry Andric   case AArch64::STRHHpost:
8000b57cec5SDimitry Andric   case AArch64::LDRHHpost:
8010b57cec5SDimitry Andric   case AArch64::STRWpost:
8020b57cec5SDimitry Andric   case AArch64::LDRWpost:
8030b57cec5SDimitry Andric   case AArch64::LDRSBXpre:
8040b57cec5SDimitry Andric   case AArch64::LDRSHXpre:
8050b57cec5SDimitry Andric   case AArch64::STRXpre:
8060b57cec5SDimitry Andric   case AArch64::LDRSWpre:
8070b57cec5SDimitry Andric   case AArch64::LDRXpre:
8080b57cec5SDimitry Andric   case AArch64::LDRSBXpost:
8090b57cec5SDimitry Andric   case AArch64::LDRSHXpost:
8100b57cec5SDimitry Andric   case AArch64::STRXpost:
8110b57cec5SDimitry Andric   case AArch64::LDRSWpost:
8120b57cec5SDimitry Andric   case AArch64::LDRXpost:
8130b57cec5SDimitry Andric   case AArch64::LDRQpre:
8140b57cec5SDimitry Andric   case AArch64::STRQpre:
8150b57cec5SDimitry Andric   case AArch64::LDRQpost:
8160b57cec5SDimitry Andric   case AArch64::STRQpost:
8170b57cec5SDimitry Andric   case AArch64::LDRDpre:
8180b57cec5SDimitry Andric   case AArch64::STRDpre:
8190b57cec5SDimitry Andric   case AArch64::LDRDpost:
8200b57cec5SDimitry Andric   case AArch64::STRDpost:
8210b57cec5SDimitry Andric   case AArch64::LDRSpre:
8220b57cec5SDimitry Andric   case AArch64::STRSpre:
8230b57cec5SDimitry Andric   case AArch64::LDRSpost:
8240b57cec5SDimitry Andric   case AArch64::STRSpost:
8250b57cec5SDimitry Andric   case AArch64::LDRHpre:
8260b57cec5SDimitry Andric   case AArch64::STRHpre:
8270b57cec5SDimitry Andric   case AArch64::LDRHpost:
8280b57cec5SDimitry Andric   case AArch64::STRHpost:
8290b57cec5SDimitry Andric   case AArch64::LDRBpre:
8300b57cec5SDimitry Andric   case AArch64::STRBpre:
8310b57cec5SDimitry Andric   case AArch64::LDRBpost:
8320b57cec5SDimitry Andric   case AArch64::STRBpost:
833*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
834*0fca6ea1SDimitry Andric                                                                  Decoder);
8350b57cec5SDimitry Andric     break;
8360b57cec5SDimitry Andric   }
8370b57cec5SDimitry Andric 
8380b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
8390b57cec5SDimitry Andric   default:
8400b57cec5SDimitry Andric     return Fail;
8410b57cec5SDimitry Andric   case AArch64::PRFUMi:
8420b57cec5SDimitry Andric     // Rt is an immediate in prefetch.
8430b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Rt));
8440b57cec5SDimitry Andric     break;
8450b57cec5SDimitry Andric   case AArch64::STURBBi:
8460b57cec5SDimitry Andric   case AArch64::LDURBBi:
8470b57cec5SDimitry Andric   case AArch64::LDURSBWi:
8480b57cec5SDimitry Andric   case AArch64::STURHHi:
8490b57cec5SDimitry Andric   case AArch64::LDURHHi:
8500b57cec5SDimitry Andric   case AArch64::LDURSHWi:
8510b57cec5SDimitry Andric   case AArch64::STURWi:
8520b57cec5SDimitry Andric   case AArch64::LDURWi:
8530b57cec5SDimitry Andric   case AArch64::LDTRSBWi:
8540b57cec5SDimitry Andric   case AArch64::LDTRSHWi:
8550b57cec5SDimitry Andric   case AArch64::STTRWi:
8560b57cec5SDimitry Andric   case AArch64::LDTRWi:
8570b57cec5SDimitry Andric   case AArch64::STTRHi:
8580b57cec5SDimitry Andric   case AArch64::LDTRHi:
8590b57cec5SDimitry Andric   case AArch64::LDTRBi:
8600b57cec5SDimitry Andric   case AArch64::STTRBi:
8610b57cec5SDimitry Andric   case AArch64::LDRSBWpre:
8620b57cec5SDimitry Andric   case AArch64::LDRSHWpre:
8630b57cec5SDimitry Andric   case AArch64::STRBBpre:
8640b57cec5SDimitry Andric   case AArch64::LDRBBpre:
8650b57cec5SDimitry Andric   case AArch64::STRHHpre:
8660b57cec5SDimitry Andric   case AArch64::LDRHHpre:
8670b57cec5SDimitry Andric   case AArch64::STRWpre:
8680b57cec5SDimitry Andric   case AArch64::LDRWpre:
8690b57cec5SDimitry Andric   case AArch64::LDRSBWpost:
8700b57cec5SDimitry Andric   case AArch64::LDRSHWpost:
8710b57cec5SDimitry Andric   case AArch64::STRBBpost:
8720b57cec5SDimitry Andric   case AArch64::LDRBBpost:
8730b57cec5SDimitry Andric   case AArch64::STRHHpost:
8740b57cec5SDimitry Andric   case AArch64::LDRHHpost:
8750b57cec5SDimitry Andric   case AArch64::STRWpost:
8760b57cec5SDimitry Andric   case AArch64::LDRWpost:
8770b57cec5SDimitry Andric   case AArch64::STLURBi:
8780b57cec5SDimitry Andric   case AArch64::STLURHi:
8790b57cec5SDimitry Andric   case AArch64::STLURWi:
8800b57cec5SDimitry Andric   case AArch64::LDAPURBi:
8810b57cec5SDimitry Andric   case AArch64::LDAPURSBWi:
8820b57cec5SDimitry Andric   case AArch64::LDAPURHi:
8830b57cec5SDimitry Andric   case AArch64::LDAPURSHWi:
8840b57cec5SDimitry Andric   case AArch64::LDAPURi:
885*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,
886*0fca6ea1SDimitry Andric                                                                Decoder);
8870b57cec5SDimitry Andric     break;
8880b57cec5SDimitry Andric   case AArch64::LDURSBXi:
8890b57cec5SDimitry Andric   case AArch64::LDURSHXi:
8900b57cec5SDimitry Andric   case AArch64::LDURSWi:
8910b57cec5SDimitry Andric   case AArch64::STURXi:
8920b57cec5SDimitry Andric   case AArch64::LDURXi:
8930b57cec5SDimitry Andric   case AArch64::LDTRSBXi:
8940b57cec5SDimitry Andric   case AArch64::LDTRSHXi:
8950b57cec5SDimitry Andric   case AArch64::LDTRSWi:
8960b57cec5SDimitry Andric   case AArch64::STTRXi:
8970b57cec5SDimitry Andric   case AArch64::LDTRXi:
8980b57cec5SDimitry Andric   case AArch64::LDRSBXpre:
8990b57cec5SDimitry Andric   case AArch64::LDRSHXpre:
9000b57cec5SDimitry Andric   case AArch64::STRXpre:
9010b57cec5SDimitry Andric   case AArch64::LDRSWpre:
9020b57cec5SDimitry Andric   case AArch64::LDRXpre:
9030b57cec5SDimitry Andric   case AArch64::LDRSBXpost:
9040b57cec5SDimitry Andric   case AArch64::LDRSHXpost:
9050b57cec5SDimitry Andric   case AArch64::STRXpost:
9060b57cec5SDimitry Andric   case AArch64::LDRSWpost:
9070b57cec5SDimitry Andric   case AArch64::LDRXpost:
9080b57cec5SDimitry Andric   case AArch64::LDAPURSWi:
9090b57cec5SDimitry Andric   case AArch64::LDAPURSHXi:
9100b57cec5SDimitry Andric   case AArch64::LDAPURSBXi:
9110b57cec5SDimitry Andric   case AArch64::STLURXi:
9120b57cec5SDimitry Andric   case AArch64::LDAPURXi:
913*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,
914*0fca6ea1SDimitry Andric                                                                Decoder);
9150b57cec5SDimitry Andric     break;
9160b57cec5SDimitry Andric   case AArch64::LDURQi:
9170b57cec5SDimitry Andric   case AArch64::STURQi:
9180b57cec5SDimitry Andric   case AArch64::LDRQpre:
9190b57cec5SDimitry Andric   case AArch64::STRQpre:
9200b57cec5SDimitry Andric   case AArch64::LDRQpost:
9210b57cec5SDimitry Andric   case AArch64::STRQpost:
922*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rt, Addr,
923*0fca6ea1SDimitry Andric                                                                 Decoder);
9240b57cec5SDimitry Andric     break;
9250b57cec5SDimitry Andric   case AArch64::LDURDi:
9260b57cec5SDimitry Andric   case AArch64::STURDi:
9270b57cec5SDimitry Andric   case AArch64::LDRDpre:
9280b57cec5SDimitry Andric   case AArch64::STRDpre:
9290b57cec5SDimitry Andric   case AArch64::LDRDpost:
9300b57cec5SDimitry Andric   case AArch64::STRDpost:
931*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rt, Addr,
932*0fca6ea1SDimitry Andric                                                                Decoder);
9330b57cec5SDimitry Andric     break;
9340b57cec5SDimitry Andric   case AArch64::LDURSi:
9350b57cec5SDimitry Andric   case AArch64::STURSi:
9360b57cec5SDimitry Andric   case AArch64::LDRSpre:
9370b57cec5SDimitry Andric   case AArch64::STRSpre:
9380b57cec5SDimitry Andric   case AArch64::LDRSpost:
9390b57cec5SDimitry Andric   case AArch64::STRSpost:
940*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, Rt, Addr,
941*0fca6ea1SDimitry Andric                                                                Decoder);
9420b57cec5SDimitry Andric     break;
9430b57cec5SDimitry Andric   case AArch64::LDURHi:
9440b57cec5SDimitry Andric   case AArch64::STURHi:
9450b57cec5SDimitry Andric   case AArch64::LDRHpre:
9460b57cec5SDimitry Andric   case AArch64::STRHpre:
9470b57cec5SDimitry Andric   case AArch64::LDRHpost:
9480b57cec5SDimitry Andric   case AArch64::STRHpost:
949*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR16RegClassID, 0, 32>(Inst, Rt, Addr,
950*0fca6ea1SDimitry Andric                                                                Decoder);
9510b57cec5SDimitry Andric     break;
9520b57cec5SDimitry Andric   case AArch64::LDURBi:
9530b57cec5SDimitry Andric   case AArch64::STURBi:
9540b57cec5SDimitry Andric   case AArch64::LDRBpre:
9550b57cec5SDimitry Andric   case AArch64::STRBpre:
9560b57cec5SDimitry Andric   case AArch64::LDRBpost:
9570b57cec5SDimitry Andric   case AArch64::STRBpost:
958*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR8RegClassID, 0, 32>(Inst, Rt, Addr,
959*0fca6ea1SDimitry Andric                                                               Decoder);
9600b57cec5SDimitry Andric     break;
9610b57cec5SDimitry Andric   }
9620b57cec5SDimitry Andric 
963*0fca6ea1SDimitry Andric   DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
964*0fca6ea1SDimitry Andric                                                                Decoder);
9650b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(offset));
9660b57cec5SDimitry Andric 
9670b57cec5SDimitry Andric   bool IsLoad = fieldFromInstruction(insn, 22, 1);
9680b57cec5SDimitry Andric   bool IsIndexed = fieldFromInstruction(insn, 10, 2) != 0;
9690b57cec5SDimitry Andric   bool IsFP = fieldFromInstruction(insn, 26, 1);
9700b57cec5SDimitry Andric 
9710b57cec5SDimitry Andric   // Cannot write back to a transfer register (but xzr != sp).
9720b57cec5SDimitry Andric   if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn)
9730b57cec5SDimitry Andric     return SoftFail;
9740b57cec5SDimitry Andric 
9750b57cec5SDimitry Andric   return Success;
9760b57cec5SDimitry Andric }
9770b57cec5SDimitry Andric 
97881ad6265SDimitry Andric static DecodeStatus
97981ad6265SDimitry Andric DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
98081ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
9810b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(insn, 0, 5);
9820b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
9830b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
9840b57cec5SDimitry Andric   unsigned Rs = fieldFromInstruction(insn, 16, 5);
9850b57cec5SDimitry Andric 
9860b57cec5SDimitry Andric   unsigned Opcode = Inst.getOpcode();
9870b57cec5SDimitry Andric   switch (Opcode) {
9880b57cec5SDimitry Andric   default:
9890b57cec5SDimitry Andric     return Fail;
9900b57cec5SDimitry Andric   case AArch64::STLXRW:
9910b57cec5SDimitry Andric   case AArch64::STLXRB:
9920b57cec5SDimitry Andric   case AArch64::STLXRH:
9930b57cec5SDimitry Andric   case AArch64::STXRW:
9940b57cec5SDimitry Andric   case AArch64::STXRB:
9950b57cec5SDimitry Andric   case AArch64::STXRH:
996*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rs, Addr,
997*0fca6ea1SDimitry Andric                                                                Decoder);
998bdd1243dSDimitry Andric     [[fallthrough]];
9990b57cec5SDimitry Andric   case AArch64::LDARW:
10000b57cec5SDimitry Andric   case AArch64::LDARB:
10010b57cec5SDimitry Andric   case AArch64::LDARH:
10020b57cec5SDimitry Andric   case AArch64::LDAXRW:
10030b57cec5SDimitry Andric   case AArch64::LDAXRB:
10040b57cec5SDimitry Andric   case AArch64::LDAXRH:
10050b57cec5SDimitry Andric   case AArch64::LDXRW:
10060b57cec5SDimitry Andric   case AArch64::LDXRB:
10070b57cec5SDimitry Andric   case AArch64::LDXRH:
10080b57cec5SDimitry Andric   case AArch64::STLRW:
10090b57cec5SDimitry Andric   case AArch64::STLRB:
10100b57cec5SDimitry Andric   case AArch64::STLRH:
10110b57cec5SDimitry Andric   case AArch64::STLLRW:
10120b57cec5SDimitry Andric   case AArch64::STLLRB:
10130b57cec5SDimitry Andric   case AArch64::STLLRH:
10140b57cec5SDimitry Andric   case AArch64::LDLARW:
10150b57cec5SDimitry Andric   case AArch64::LDLARB:
10160b57cec5SDimitry Andric   case AArch64::LDLARH:
1017*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,
1018*0fca6ea1SDimitry Andric                                                                Decoder);
10190b57cec5SDimitry Andric     break;
10200b57cec5SDimitry Andric   case AArch64::STLXRX:
10210b57cec5SDimitry Andric   case AArch64::STXRX:
1022*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rs, Addr,
1023*0fca6ea1SDimitry Andric                                                                Decoder);
1024bdd1243dSDimitry Andric     [[fallthrough]];
10250b57cec5SDimitry Andric   case AArch64::LDARX:
10260b57cec5SDimitry Andric   case AArch64::LDAXRX:
10270b57cec5SDimitry Andric   case AArch64::LDXRX:
10280b57cec5SDimitry Andric   case AArch64::STLRX:
10290b57cec5SDimitry Andric   case AArch64::LDLARX:
10300b57cec5SDimitry Andric   case AArch64::STLLRX:
1031*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,
1032*0fca6ea1SDimitry Andric                                                                Decoder);
10330b57cec5SDimitry Andric     break;
10340b57cec5SDimitry Andric   case AArch64::STLXPW:
10350b57cec5SDimitry Andric   case AArch64::STXPW:
1036*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rs, Addr,
1037*0fca6ea1SDimitry Andric                                                                Decoder);
1038bdd1243dSDimitry Andric     [[fallthrough]];
10390b57cec5SDimitry Andric   case AArch64::LDAXPW:
10400b57cec5SDimitry Andric   case AArch64::LDXPW:
1041*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,
1042*0fca6ea1SDimitry Andric                                                                Decoder);
1043*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt2, Addr,
1044*0fca6ea1SDimitry Andric                                                                Decoder);
10450b57cec5SDimitry Andric     break;
10460b57cec5SDimitry Andric   case AArch64::STLXPX:
10470b57cec5SDimitry Andric   case AArch64::STXPX:
1048*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rs, Addr,
1049*0fca6ea1SDimitry Andric                                                                Decoder);
1050bdd1243dSDimitry Andric     [[fallthrough]];
10510b57cec5SDimitry Andric   case AArch64::LDAXPX:
10520b57cec5SDimitry Andric   case AArch64::LDXPX:
1053*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,
1054*0fca6ea1SDimitry Andric                                                                Decoder);
1055*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt2, Addr,
1056*0fca6ea1SDimitry Andric                                                                Decoder);
10570b57cec5SDimitry Andric     break;
10580b57cec5SDimitry Andric   }
10590b57cec5SDimitry Andric 
1060*0fca6ea1SDimitry Andric   DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
1061*0fca6ea1SDimitry Andric                                                                Decoder);
10620b57cec5SDimitry Andric 
10630b57cec5SDimitry Andric   // You shouldn't load to the same register twice in an instruction...
10640b57cec5SDimitry Andric   if ((Opcode == AArch64::LDAXPW || Opcode == AArch64::LDXPW ||
10650b57cec5SDimitry Andric        Opcode == AArch64::LDAXPX || Opcode == AArch64::LDXPX) &&
10660b57cec5SDimitry Andric       Rt == Rt2)
10670b57cec5SDimitry Andric     return SoftFail;
10680b57cec5SDimitry Andric 
10690b57cec5SDimitry Andric   return Success;
10700b57cec5SDimitry Andric }
10710b57cec5SDimitry Andric 
10720b57cec5SDimitry Andric static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,
10730b57cec5SDimitry Andric                                               uint64_t Addr,
107481ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
10750b57cec5SDimitry Andric   unsigned Rt = fieldFromInstruction(insn, 0, 5);
10760b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
10770b57cec5SDimitry Andric   unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
10780b57cec5SDimitry Andric   int64_t offset = fieldFromInstruction(insn, 15, 7);
10790b57cec5SDimitry Andric   bool IsLoad = fieldFromInstruction(insn, 22, 1);
10800b57cec5SDimitry Andric 
10810b57cec5SDimitry Andric   // offset is a 7-bit signed immediate, so sign extend it to
10820b57cec5SDimitry Andric   // fill the unsigned.
10830b57cec5SDimitry Andric   if (offset & (1 << (7 - 1)))
10840b57cec5SDimitry Andric     offset |= ~((1LL << 7) - 1);
10850b57cec5SDimitry Andric 
10860b57cec5SDimitry Andric   unsigned Opcode = Inst.getOpcode();
10870b57cec5SDimitry Andric   bool NeedsDisjointWritebackTransfer = false;
10880b57cec5SDimitry Andric 
10890b57cec5SDimitry Andric   // First operand is always writeback of base register.
10900b57cec5SDimitry Andric   switch (Opcode) {
10910b57cec5SDimitry Andric   default:
10920b57cec5SDimitry Andric     break;
10930b57cec5SDimitry Andric   case AArch64::LDPXpost:
10940b57cec5SDimitry Andric   case AArch64::STPXpost:
10950b57cec5SDimitry Andric   case AArch64::LDPSWpost:
10960b57cec5SDimitry Andric   case AArch64::LDPXpre:
10970b57cec5SDimitry Andric   case AArch64::STPXpre:
10980b57cec5SDimitry Andric   case AArch64::LDPSWpre:
10990b57cec5SDimitry Andric   case AArch64::LDPWpost:
11000b57cec5SDimitry Andric   case AArch64::STPWpost:
11010b57cec5SDimitry Andric   case AArch64::LDPWpre:
11020b57cec5SDimitry Andric   case AArch64::STPWpre:
11030b57cec5SDimitry Andric   case AArch64::LDPQpost:
11040b57cec5SDimitry Andric   case AArch64::STPQpost:
11050b57cec5SDimitry Andric   case AArch64::LDPQpre:
11060b57cec5SDimitry Andric   case AArch64::STPQpre:
11070b57cec5SDimitry Andric   case AArch64::LDPDpost:
11080b57cec5SDimitry Andric   case AArch64::STPDpost:
11090b57cec5SDimitry Andric   case AArch64::LDPDpre:
11100b57cec5SDimitry Andric   case AArch64::STPDpre:
11110b57cec5SDimitry Andric   case AArch64::LDPSpost:
11120b57cec5SDimitry Andric   case AArch64::STPSpost:
11130b57cec5SDimitry Andric   case AArch64::LDPSpre:
11140b57cec5SDimitry Andric   case AArch64::STPSpre:
11150b57cec5SDimitry Andric   case AArch64::STGPpre:
11160b57cec5SDimitry Andric   case AArch64::STGPpost:
1117*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
1118*0fca6ea1SDimitry Andric                                                                  Decoder);
11190b57cec5SDimitry Andric     break;
11200b57cec5SDimitry Andric   }
11210b57cec5SDimitry Andric 
11220b57cec5SDimitry Andric   switch (Opcode) {
11230b57cec5SDimitry Andric   default:
11240b57cec5SDimitry Andric     return Fail;
11250b57cec5SDimitry Andric   case AArch64::LDPXpost:
11260b57cec5SDimitry Andric   case AArch64::STPXpost:
11270b57cec5SDimitry Andric   case AArch64::LDPSWpost:
11280b57cec5SDimitry Andric   case AArch64::LDPXpre:
11290b57cec5SDimitry Andric   case AArch64::STPXpre:
11300b57cec5SDimitry Andric   case AArch64::LDPSWpre:
11310b57cec5SDimitry Andric   case AArch64::STGPpre:
11320b57cec5SDimitry Andric   case AArch64::STGPpost:
11330b57cec5SDimitry Andric     NeedsDisjointWritebackTransfer = true;
1134bdd1243dSDimitry Andric     [[fallthrough]];
11350b57cec5SDimitry Andric   case AArch64::LDNPXi:
11360b57cec5SDimitry Andric   case AArch64::STNPXi:
11370b57cec5SDimitry Andric   case AArch64::LDPXi:
11380b57cec5SDimitry Andric   case AArch64::STPXi:
11390b57cec5SDimitry Andric   case AArch64::LDPSWi:
11400b57cec5SDimitry Andric   case AArch64::STGPi:
1141*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,
1142*0fca6ea1SDimitry Andric                                                                Decoder);
1143*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt2, Addr,
1144*0fca6ea1SDimitry Andric                                                                Decoder);
11450b57cec5SDimitry Andric     break;
11460b57cec5SDimitry Andric   case AArch64::LDPWpost:
11470b57cec5SDimitry Andric   case AArch64::STPWpost:
11480b57cec5SDimitry Andric   case AArch64::LDPWpre:
11490b57cec5SDimitry Andric   case AArch64::STPWpre:
11500b57cec5SDimitry Andric     NeedsDisjointWritebackTransfer = true;
1151bdd1243dSDimitry Andric     [[fallthrough]];
11520b57cec5SDimitry Andric   case AArch64::LDNPWi:
11530b57cec5SDimitry Andric   case AArch64::STNPWi:
11540b57cec5SDimitry Andric   case AArch64::LDPWi:
11550b57cec5SDimitry Andric   case AArch64::STPWi:
1156*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,
1157*0fca6ea1SDimitry Andric                                                                Decoder);
1158*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt2, Addr,
1159*0fca6ea1SDimitry Andric                                                                Decoder);
11600b57cec5SDimitry Andric     break;
11610b57cec5SDimitry Andric   case AArch64::LDNPQi:
11620b57cec5SDimitry Andric   case AArch64::STNPQi:
11630b57cec5SDimitry Andric   case AArch64::LDPQpost:
11640b57cec5SDimitry Andric   case AArch64::STPQpost:
11650b57cec5SDimitry Andric   case AArch64::LDPQi:
11660b57cec5SDimitry Andric   case AArch64::STPQi:
11670b57cec5SDimitry Andric   case AArch64::LDPQpre:
11680b57cec5SDimitry Andric   case AArch64::STPQpre:
1169*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rt, Addr,
1170*0fca6ea1SDimitry Andric                                                                 Decoder);
1171*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rt2, Addr,
1172*0fca6ea1SDimitry Andric                                                                 Decoder);
11730b57cec5SDimitry Andric     break;
11740b57cec5SDimitry Andric   case AArch64::LDNPDi:
11750b57cec5SDimitry Andric   case AArch64::STNPDi:
11760b57cec5SDimitry Andric   case AArch64::LDPDpost:
11770b57cec5SDimitry Andric   case AArch64::STPDpost:
11780b57cec5SDimitry Andric   case AArch64::LDPDi:
11790b57cec5SDimitry Andric   case AArch64::STPDi:
11800b57cec5SDimitry Andric   case AArch64::LDPDpre:
11810b57cec5SDimitry Andric   case AArch64::STPDpre:
1182*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rt, Addr,
1183*0fca6ea1SDimitry Andric                                                                Decoder);
1184*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rt2, Addr,
1185*0fca6ea1SDimitry Andric                                                                Decoder);
11860b57cec5SDimitry Andric     break;
11870b57cec5SDimitry Andric   case AArch64::LDNPSi:
11880b57cec5SDimitry Andric   case AArch64::STNPSi:
11890b57cec5SDimitry Andric   case AArch64::LDPSpost:
11900b57cec5SDimitry Andric   case AArch64::STPSpost:
11910b57cec5SDimitry Andric   case AArch64::LDPSi:
11920b57cec5SDimitry Andric   case AArch64::STPSi:
11930b57cec5SDimitry Andric   case AArch64::LDPSpre:
11940b57cec5SDimitry Andric   case AArch64::STPSpre:
1195*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, Rt, Addr,
1196*0fca6ea1SDimitry Andric                                                                Decoder);
1197*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, Rt2, Addr,
1198*0fca6ea1SDimitry Andric                                                                Decoder);
11990b57cec5SDimitry Andric     break;
12000b57cec5SDimitry Andric   }
12010b57cec5SDimitry Andric 
1202*0fca6ea1SDimitry Andric   DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
1203*0fca6ea1SDimitry Andric                                                                Decoder);
12040b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(offset));
12050b57cec5SDimitry Andric 
12060b57cec5SDimitry Andric   // You shouldn't load to the same register twice in an instruction...
12070b57cec5SDimitry Andric   if (IsLoad && Rt == Rt2)
12080b57cec5SDimitry Andric     return SoftFail;
12090b57cec5SDimitry Andric 
12100b57cec5SDimitry Andric   // ... or do any operation that writes-back to a transfer register. But note
12110b57cec5SDimitry Andric   // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.
12120b57cec5SDimitry Andric   if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn))
12130b57cec5SDimitry Andric     return SoftFail;
12140b57cec5SDimitry Andric 
12150b57cec5SDimitry Andric   return Success;
12160b57cec5SDimitry Andric }
12170b57cec5SDimitry Andric 
12185ffd83dbSDimitry Andric static DecodeStatus DecodeAuthLoadInstruction(MCInst &Inst, uint32_t insn,
12195ffd83dbSDimitry Andric                                               uint64_t Addr,
122081ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
12215ffd83dbSDimitry Andric   unsigned Rt = fieldFromInstruction(insn, 0, 5);
12225ffd83dbSDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
12235ffd83dbSDimitry Andric   uint64_t offset = fieldFromInstruction(insn, 22, 1) << 9 |
12245ffd83dbSDimitry Andric                     fieldFromInstruction(insn, 12, 9);
12255ffd83dbSDimitry Andric   unsigned writeback = fieldFromInstruction(insn, 11, 1);
12265ffd83dbSDimitry Andric 
12275ffd83dbSDimitry Andric   switch (Inst.getOpcode()) {
12285ffd83dbSDimitry Andric   default:
12295ffd83dbSDimitry Andric     return Fail;
12305ffd83dbSDimitry Andric   case AArch64::LDRAAwriteback:
12315ffd83dbSDimitry Andric   case AArch64::LDRABwriteback:
1232*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(
1233*0fca6ea1SDimitry Andric         Inst, Rn /* writeback register */, Addr, Decoder);
12345ffd83dbSDimitry Andric     break;
12355ffd83dbSDimitry Andric   case AArch64::LDRAAindexed:
12365ffd83dbSDimitry Andric   case AArch64::LDRABindexed:
12375ffd83dbSDimitry Andric     break;
12385ffd83dbSDimitry Andric   }
12395ffd83dbSDimitry Andric 
1240*0fca6ea1SDimitry Andric   DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,
1241*0fca6ea1SDimitry Andric                                                              Decoder);
1242*0fca6ea1SDimitry Andric   DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
1243*0fca6ea1SDimitry Andric                                                                Decoder);
12445ffd83dbSDimitry Andric   DecodeSImm<10>(Inst, offset, Addr, Decoder);
12455ffd83dbSDimitry Andric 
12465ffd83dbSDimitry Andric   if (writeback && Rt == Rn && Rn != 31) {
12475ffd83dbSDimitry Andric     return SoftFail;
12485ffd83dbSDimitry Andric   }
12495ffd83dbSDimitry Andric 
12505ffd83dbSDimitry Andric   return Success;
12515ffd83dbSDimitry Andric }
12525ffd83dbSDimitry Andric 
12530b57cec5SDimitry Andric static DecodeStatus DecodeAddSubERegInstruction(MCInst &Inst, uint32_t insn,
12540b57cec5SDimitry Andric                                                 uint64_t Addr,
125581ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
12560b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
12570b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
12580b57cec5SDimitry Andric   unsigned Rm = fieldFromInstruction(insn, 16, 5);
12590b57cec5SDimitry Andric   unsigned extend = fieldFromInstruction(insn, 10, 6);
12600b57cec5SDimitry Andric 
12610b57cec5SDimitry Andric   unsigned shift = extend & 0x7;
12620b57cec5SDimitry Andric   if (shift > 4)
12630b57cec5SDimitry Andric     return Fail;
12640b57cec5SDimitry Andric 
12650b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
12660b57cec5SDimitry Andric   default:
12670b57cec5SDimitry Andric     return Fail;
12680b57cec5SDimitry Andric   case AArch64::ADDWrx:
12690b57cec5SDimitry Andric   case AArch64::SUBWrx:
1270*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, Rd, Addr,
1271*0fca6ea1SDimitry Andric                                                                  Decoder);
1272*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, Rn, Addr,
1273*0fca6ea1SDimitry Andric                                                                  Decoder);
1274*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,
1275*0fca6ea1SDimitry Andric                                                                Decoder);
12760b57cec5SDimitry Andric     break;
12770b57cec5SDimitry Andric   case AArch64::ADDSWrx:
12780b57cec5SDimitry Andric   case AArch64::SUBSWrx:
1279*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr,
1280*0fca6ea1SDimitry Andric                                                                Decoder);
1281*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, Rn, Addr,
1282*0fca6ea1SDimitry Andric                                                                  Decoder);
1283*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,
1284*0fca6ea1SDimitry Andric                                                                Decoder);
12850b57cec5SDimitry Andric     break;
12860b57cec5SDimitry Andric   case AArch64::ADDXrx:
12870b57cec5SDimitry Andric   case AArch64::SUBXrx:
1288*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rd, Addr,
1289*0fca6ea1SDimitry Andric                                                                  Decoder);
1290*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
1291*0fca6ea1SDimitry Andric                                                                  Decoder);
1292*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,
1293*0fca6ea1SDimitry Andric                                                                Decoder);
12940b57cec5SDimitry Andric     break;
12950b57cec5SDimitry Andric   case AArch64::ADDSXrx:
12960b57cec5SDimitry Andric   case AArch64::SUBSXrx:
1297*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,
1298*0fca6ea1SDimitry Andric                                                                Decoder);
1299*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
1300*0fca6ea1SDimitry Andric                                                                  Decoder);
1301*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,
1302*0fca6ea1SDimitry Andric                                                                Decoder);
13030b57cec5SDimitry Andric     break;
13040b57cec5SDimitry Andric   case AArch64::ADDXrx64:
13050b57cec5SDimitry Andric   case AArch64::SUBXrx64:
1306*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rd, Addr,
1307*0fca6ea1SDimitry Andric                                                                  Decoder);
1308*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
1309*0fca6ea1SDimitry Andric                                                                  Decoder);
1310*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rm, Addr,
1311*0fca6ea1SDimitry Andric                                                                Decoder);
13120b57cec5SDimitry Andric     break;
13130b57cec5SDimitry Andric   case AArch64::SUBSXrx64:
13140b57cec5SDimitry Andric   case AArch64::ADDSXrx64:
1315*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,
1316*0fca6ea1SDimitry Andric                                                                Decoder);
1317*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
1318*0fca6ea1SDimitry Andric                                                                  Decoder);
1319*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rm, Addr,
1320*0fca6ea1SDimitry Andric                                                                Decoder);
13210b57cec5SDimitry Andric     break;
13220b57cec5SDimitry Andric   }
13230b57cec5SDimitry Andric 
13240b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(extend));
13250b57cec5SDimitry Andric   return Success;
13260b57cec5SDimitry Andric }
13270b57cec5SDimitry Andric 
13280b57cec5SDimitry Andric static DecodeStatus DecodeLogicalImmInstruction(MCInst &Inst, uint32_t insn,
13290b57cec5SDimitry Andric                                                 uint64_t Addr,
133081ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
13310b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
13320b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
13330b57cec5SDimitry Andric   unsigned Datasize = fieldFromInstruction(insn, 31, 1);
13340b57cec5SDimitry Andric   unsigned imm;
13350b57cec5SDimitry Andric 
13360b57cec5SDimitry Andric   if (Datasize) {
13370b57cec5SDimitry Andric     if (Inst.getOpcode() == AArch64::ANDSXri)
1338*0fca6ea1SDimitry Andric       DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,
1339*0fca6ea1SDimitry Andric                                                                  Decoder);
13400b57cec5SDimitry Andric     else
1341*0fca6ea1SDimitry Andric       DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(
1342*0fca6ea1SDimitry Andric           Inst, Rd, Addr, Decoder);
1343*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rn, Addr,
1344*0fca6ea1SDimitry Andric                                                                Decoder);
13450b57cec5SDimitry Andric     imm = fieldFromInstruction(insn, 10, 13);
13460b57cec5SDimitry Andric     if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 64))
13470b57cec5SDimitry Andric       return Fail;
13480b57cec5SDimitry Andric   } else {
13490b57cec5SDimitry Andric     if (Inst.getOpcode() == AArch64::ANDSWri)
1350*0fca6ea1SDimitry Andric       DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr,
1351*0fca6ea1SDimitry Andric                                                                  Decoder);
13520b57cec5SDimitry Andric     else
1353*0fca6ea1SDimitry Andric       DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(
1354*0fca6ea1SDimitry Andric           Inst, Rd, Addr, Decoder);
1355*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rn, Addr,
1356*0fca6ea1SDimitry Andric                                                                Decoder);
13570b57cec5SDimitry Andric     imm = fieldFromInstruction(insn, 10, 12);
13580b57cec5SDimitry Andric     if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 32))
13590b57cec5SDimitry Andric       return Fail;
13600b57cec5SDimitry Andric   }
13610b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
13620b57cec5SDimitry Andric   return Success;
13630b57cec5SDimitry Andric }
13640b57cec5SDimitry Andric 
13650b57cec5SDimitry Andric static DecodeStatus DecodeModImmInstruction(MCInst &Inst, uint32_t insn,
13660b57cec5SDimitry Andric                                             uint64_t Addr,
136781ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
13680b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
13690b57cec5SDimitry Andric   unsigned cmode = fieldFromInstruction(insn, 12, 4);
13700b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
13710b57cec5SDimitry Andric   imm |= fieldFromInstruction(insn, 5, 5);
13720b57cec5SDimitry Andric 
13730b57cec5SDimitry Andric   if (Inst.getOpcode() == AArch64::MOVID)
1374*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, Rd, Addr,
1375*0fca6ea1SDimitry Andric                                                                Decoder);
13760b57cec5SDimitry Andric   else
1377*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rd, Addr,
1378*0fca6ea1SDimitry Andric                                                                 Decoder);
13790b57cec5SDimitry Andric 
13800b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
13810b57cec5SDimitry Andric 
13820b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
13830b57cec5SDimitry Andric   default:
13840b57cec5SDimitry Andric     break;
13850b57cec5SDimitry Andric   case AArch64::MOVIv4i16:
13860b57cec5SDimitry Andric   case AArch64::MOVIv8i16:
13870b57cec5SDimitry Andric   case AArch64::MVNIv4i16:
13880b57cec5SDimitry Andric   case AArch64::MVNIv8i16:
13890b57cec5SDimitry Andric   case AArch64::MOVIv2i32:
13900b57cec5SDimitry Andric   case AArch64::MOVIv4i32:
13910b57cec5SDimitry Andric   case AArch64::MVNIv2i32:
13920b57cec5SDimitry Andric   case AArch64::MVNIv4i32:
13930b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
13940b57cec5SDimitry Andric     break;
13950b57cec5SDimitry Andric   case AArch64::MOVIv2s_msl:
13960b57cec5SDimitry Andric   case AArch64::MOVIv4s_msl:
13970b57cec5SDimitry Andric   case AArch64::MVNIv2s_msl:
13980b57cec5SDimitry Andric   case AArch64::MVNIv4s_msl:
13990b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm((cmode & 1) ? 0x110 : 0x108));
14000b57cec5SDimitry Andric     break;
14010b57cec5SDimitry Andric   }
14020b57cec5SDimitry Andric 
14030b57cec5SDimitry Andric   return Success;
14040b57cec5SDimitry Andric }
14050b57cec5SDimitry Andric 
14060b57cec5SDimitry Andric static DecodeStatus DecodeModImmTiedInstruction(MCInst &Inst, uint32_t insn,
14070b57cec5SDimitry Andric                                                 uint64_t Addr,
140881ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
14090b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
14100b57cec5SDimitry Andric   unsigned cmode = fieldFromInstruction(insn, 12, 4);
14110b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
14120b57cec5SDimitry Andric   imm |= fieldFromInstruction(insn, 5, 5);
14130b57cec5SDimitry Andric 
14140b57cec5SDimitry Andric   // Tied operands added twice.
1415*0fca6ea1SDimitry Andric   DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rd, Addr,
1416*0fca6ea1SDimitry Andric                                                               Decoder);
1417*0fca6ea1SDimitry Andric   DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, Rd, Addr,
1418*0fca6ea1SDimitry Andric                                                               Decoder);
14190b57cec5SDimitry Andric 
14200b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
14210b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
14220b57cec5SDimitry Andric 
14230b57cec5SDimitry Andric   return Success;
14240b57cec5SDimitry Andric }
14250b57cec5SDimitry Andric 
14260b57cec5SDimitry Andric static DecodeStatus DecodeAdrInstruction(MCInst &Inst, uint32_t insn,
142781ad6265SDimitry Andric                                          uint64_t Addr,
142881ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
14290b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
14300b57cec5SDimitry Andric   int64_t imm = fieldFromInstruction(insn, 5, 19) << 2;
14310b57cec5SDimitry Andric   imm |= fieldFromInstruction(insn, 29, 2);
14320b57cec5SDimitry Andric 
14330b57cec5SDimitry Andric   // Sign-extend the 21-bit immediate.
14340b57cec5SDimitry Andric   if (imm & (1 << (21 - 1)))
14350b57cec5SDimitry Andric     imm |= ~((1LL << 21) - 1);
14360b57cec5SDimitry Andric 
1437*0fca6ea1SDimitry Andric   DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,
1438*0fca6ea1SDimitry Andric                                                              Decoder);
143981ad6265SDimitry Andric   if (!Decoder->tryAddingSymbolicOperand(Inst, imm, Addr, Fail, 0, 0, 4))
14400b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
14410b57cec5SDimitry Andric 
14420b57cec5SDimitry Andric   return Success;
14430b57cec5SDimitry Andric }
14440b57cec5SDimitry Andric 
14450b57cec5SDimitry Andric static DecodeStatus DecodeAddSubImmShift(MCInst &Inst, uint32_t insn,
144681ad6265SDimitry Andric                                          uint64_t Addr,
144781ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
14480b57cec5SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
14490b57cec5SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
14500b57cec5SDimitry Andric   unsigned Imm = fieldFromInstruction(insn, 10, 14);
14510b57cec5SDimitry Andric   unsigned S = fieldFromInstruction(insn, 29, 1);
14520b57cec5SDimitry Andric   unsigned Datasize = fieldFromInstruction(insn, 31, 1);
14530b57cec5SDimitry Andric 
14540b57cec5SDimitry Andric   unsigned ShifterVal = (Imm >> 12) & 3;
14550b57cec5SDimitry Andric   unsigned ImmVal = Imm & 0xFFF;
14560b57cec5SDimitry Andric 
14570b57cec5SDimitry Andric   if (ShifterVal != 0 && ShifterVal != 1)
14580b57cec5SDimitry Andric     return Fail;
14590b57cec5SDimitry Andric 
14600b57cec5SDimitry Andric   if (Datasize) {
14610b57cec5SDimitry Andric     if (Rd == 31 && !S)
1462*0fca6ea1SDimitry Andric       DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(
1463*0fca6ea1SDimitry Andric           Inst, Rd, Addr, Decoder);
14640b57cec5SDimitry Andric     else
1465*0fca6ea1SDimitry Andric       DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rd, Addr,
1466*0fca6ea1SDimitry Andric                                                                  Decoder);
1467*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
1468*0fca6ea1SDimitry Andric                                                                  Decoder);
14690b57cec5SDimitry Andric   } else {
14700b57cec5SDimitry Andric     if (Rd == 31 && !S)
1471*0fca6ea1SDimitry Andric       DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(
1472*0fca6ea1SDimitry Andric           Inst, Rd, Addr, Decoder);
14730b57cec5SDimitry Andric     else
1474*0fca6ea1SDimitry Andric       DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rd, Addr,
1475*0fca6ea1SDimitry Andric                                                                  Decoder);
1476*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, Rn, Addr,
1477*0fca6ea1SDimitry Andric                                                                  Decoder);
14780b57cec5SDimitry Andric   }
14790b57cec5SDimitry Andric 
148081ad6265SDimitry Andric   if (!Decoder->tryAddingSymbolicOperand(Inst, Imm, Addr, Fail, 0, 0, 4))
14810b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(ImmVal));
14820b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(12 * ShifterVal));
14830b57cec5SDimitry Andric   return Success;
14840b57cec5SDimitry Andric }
14850b57cec5SDimitry Andric 
14860b57cec5SDimitry Andric static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn,
14870b57cec5SDimitry Andric                                               uint64_t Addr,
148881ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
14890b57cec5SDimitry Andric   int64_t imm = fieldFromInstruction(insn, 0, 26);
14900b57cec5SDimitry Andric 
14910b57cec5SDimitry Andric   // Sign-extend the 26-bit immediate.
14920b57cec5SDimitry Andric   if (imm & (1 << (26 - 1)))
14930b57cec5SDimitry Andric     imm |= ~((1LL << 26) - 1);
14940b57cec5SDimitry Andric 
149581ad6265SDimitry Andric   if (!Decoder->tryAddingSymbolicOperand(Inst, imm * 4, Addr, true, 0, 0, 4))
14960b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(imm));
14970b57cec5SDimitry Andric 
14980b57cec5SDimitry Andric   return Success;
14990b57cec5SDimitry Andric }
15000b57cec5SDimitry Andric 
1501bdd1243dSDimitry Andric static bool isInvalidPState(uint64_t Op1, uint64_t Op2) {
1502bdd1243dSDimitry Andric   return Op1 == 0b000 && (Op2 == 0b000 || // CFINV
1503bdd1243dSDimitry Andric                           Op2 == 0b001 || // XAFlag
1504bdd1243dSDimitry Andric                           Op2 == 0b010);  // AXFlag
1505bdd1243dSDimitry Andric }
1506bdd1243dSDimitry Andric 
150781ad6265SDimitry Andric static DecodeStatus
1508bdd1243dSDimitry Andric DecodeSystemPStateImm0_15Instruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
150981ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
15100b57cec5SDimitry Andric   uint64_t op1 = fieldFromInstruction(insn, 16, 3);
15110b57cec5SDimitry Andric   uint64_t op2 = fieldFromInstruction(insn, 5, 3);
1512bdd1243dSDimitry Andric   uint64_t imm = fieldFromInstruction(insn, 8, 4);
15130b57cec5SDimitry Andric   uint64_t pstate_field = (op1 << 3) | op2;
15140b57cec5SDimitry Andric 
1515bdd1243dSDimitry Andric   if (isInvalidPState(op1, op2))
15160b57cec5SDimitry Andric     return Fail;
15170b57cec5SDimitry Andric 
15180b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(pstate_field));
1519bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
15200b57cec5SDimitry Andric 
1521bdd1243dSDimitry Andric   auto PState = AArch64PState::lookupPStateImm0_15ByEncoding(pstate_field);
1522bdd1243dSDimitry Andric   if (PState &&
1523bdd1243dSDimitry Andric       PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits()))
1524bdd1243dSDimitry Andric     return Success;
1525bdd1243dSDimitry Andric   return Fail;
1526bdd1243dSDimitry Andric }
1527bdd1243dSDimitry Andric 
1528bdd1243dSDimitry Andric static DecodeStatus
1529bdd1243dSDimitry Andric DecodeSystemPStateImm0_1Instruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
1530bdd1243dSDimitry Andric                                     const MCDisassembler *Decoder) {
1531bdd1243dSDimitry Andric   uint64_t op1 = fieldFromInstruction(insn, 16, 3);
1532bdd1243dSDimitry Andric   uint64_t op2 = fieldFromInstruction(insn, 5, 3);
1533bdd1243dSDimitry Andric   uint64_t crm_high = fieldFromInstruction(insn, 9, 3);
1534bdd1243dSDimitry Andric   uint64_t imm = fieldFromInstruction(insn, 8, 1);
1535bdd1243dSDimitry Andric   uint64_t pstate_field = (crm_high << 6) | (op1 << 3) | op2;
1536bdd1243dSDimitry Andric 
1537bdd1243dSDimitry Andric   if (isInvalidPState(op1, op2))
1538bdd1243dSDimitry Andric     return Fail;
1539bdd1243dSDimitry Andric 
1540bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(pstate_field));
1541bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
1542bdd1243dSDimitry Andric 
1543bdd1243dSDimitry Andric   auto PState = AArch64PState::lookupPStateImm0_1ByEncoding(pstate_field);
154481ad6265SDimitry Andric   if (PState &&
154581ad6265SDimitry Andric       PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits()))
15460b57cec5SDimitry Andric     return Success;
15470b57cec5SDimitry Andric   return Fail;
15480b57cec5SDimitry Andric }
15490b57cec5SDimitry Andric 
15500b57cec5SDimitry Andric static DecodeStatus DecodeTestAndBranch(MCInst &Inst, uint32_t insn,
155181ad6265SDimitry Andric                                         uint64_t Addr,
155281ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
15530b57cec5SDimitry Andric   uint64_t Rt = fieldFromInstruction(insn, 0, 5);
15540b57cec5SDimitry Andric   uint64_t bit = fieldFromInstruction(insn, 31, 1) << 5;
15550b57cec5SDimitry Andric   bit |= fieldFromInstruction(insn, 19, 5);
15560b57cec5SDimitry Andric   int64_t dst = fieldFromInstruction(insn, 5, 14);
15570b57cec5SDimitry Andric 
15580b57cec5SDimitry Andric   // Sign-extend 14-bit immediate.
15590b57cec5SDimitry Andric   if (dst & (1 << (14 - 1)))
15600b57cec5SDimitry Andric     dst |= ~((1LL << 14) - 1);
15610b57cec5SDimitry Andric 
15620b57cec5SDimitry Andric   if (fieldFromInstruction(insn, 31, 1) == 0)
1563*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rt, Addr,
1564*0fca6ea1SDimitry Andric                                                                Decoder);
15650b57cec5SDimitry Andric   else
1566*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,
1567*0fca6ea1SDimitry Andric                                                                Decoder);
15680b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(bit));
156981ad6265SDimitry Andric   if (!Decoder->tryAddingSymbolicOperand(Inst, dst * 4, Addr, true, 0, 0, 4))
15700b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(dst));
15710b57cec5SDimitry Andric 
15720b57cec5SDimitry Andric   return Success;
15730b57cec5SDimitry Andric }
15740b57cec5SDimitry Andric 
157581ad6265SDimitry Andric static DecodeStatus
157681ad6265SDimitry Andric DecodeGPRSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegClassID,
157781ad6265SDimitry Andric                                     unsigned RegNo, uint64_t Addr,
157881ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
15790b57cec5SDimitry Andric   // Register number must be even (see CASP instruction)
15800b57cec5SDimitry Andric   if (RegNo & 0x1)
15810b57cec5SDimitry Andric     return Fail;
15820b57cec5SDimitry Andric 
15830b57cec5SDimitry Andric   unsigned Reg = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo / 2);
15840b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
15850b57cec5SDimitry Andric   return Success;
15860b57cec5SDimitry Andric }
15870b57cec5SDimitry Andric 
158881ad6265SDimitry Andric static DecodeStatus
158981ad6265SDimitry Andric DecodeWSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
159081ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
1591*0fca6ea1SDimitry Andric   return DecodeGPRSeqPairsClassRegisterClass(
1592*0fca6ea1SDimitry Andric       Inst, AArch64::WSeqPairsClassRegClassID, RegNo, Addr, Decoder);
15930b57cec5SDimitry Andric }
15940b57cec5SDimitry Andric 
159581ad6265SDimitry Andric static DecodeStatus
159681ad6265SDimitry Andric DecodeXSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
159781ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
1598*0fca6ea1SDimitry Andric   return DecodeGPRSeqPairsClassRegisterClass(
1599*0fca6ea1SDimitry Andric       Inst, AArch64::XSeqPairsClassRegClassID, RegNo, Addr, Decoder);
16000b57cec5SDimitry Andric }
16010b57cec5SDimitry Andric 
1602bdd1243dSDimitry Andric static DecodeStatus DecodeSyspXzrInstruction(MCInst &Inst, uint32_t insn,
1603bdd1243dSDimitry Andric                                              uint64_t Addr,
1604bdd1243dSDimitry Andric                                              const MCDisassembler *Decoder) {
1605bdd1243dSDimitry Andric   unsigned op1 = fieldFromInstruction(insn, 16, 3);
1606bdd1243dSDimitry Andric   unsigned CRn = fieldFromInstruction(insn, 12, 4);
1607bdd1243dSDimitry Andric   unsigned CRm = fieldFromInstruction(insn, 8, 4);
1608bdd1243dSDimitry Andric   unsigned op2 = fieldFromInstruction(insn, 5, 3);
1609bdd1243dSDimitry Andric   unsigned Rt = fieldFromInstruction(insn, 0, 5);
1610bdd1243dSDimitry Andric   if (Rt != 0b11111)
1611bdd1243dSDimitry Andric     return Fail;
1612bdd1243dSDimitry Andric 
1613bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(op1));
1614bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(CRn));
1615bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(CRm));
1616bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(op2));
1617*0fca6ea1SDimitry Andric   DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rt, Addr,
1618*0fca6ea1SDimitry Andric                                                              Decoder);
1619bdd1243dSDimitry Andric 
1620bdd1243dSDimitry Andric   return Success;
1621bdd1243dSDimitry Andric }
1622bdd1243dSDimitry Andric 
162381ad6265SDimitry Andric static DecodeStatus
162481ad6265SDimitry Andric DecodeSVELogicalImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
162581ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
16260b57cec5SDimitry Andric   unsigned Zdn = fieldFromInstruction(insn, 0, 5);
16270b57cec5SDimitry Andric   unsigned imm = fieldFromInstruction(insn, 5, 13);
16280b57cec5SDimitry Andric   if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 64))
16290b57cec5SDimitry Andric     return Fail;
16300b57cec5SDimitry Andric 
16310b57cec5SDimitry Andric   // The same (tied) operand is added twice to the instruction.
1632*0fca6ea1SDimitry Andric   DecodeSimpleRegisterClass<AArch64::ZPRRegClassID, 0, 32>(Inst, Zdn, Addr,
1633*0fca6ea1SDimitry Andric                                                            Decoder);
16340b57cec5SDimitry Andric   if (Inst.getOpcode() != AArch64::DUPM_ZI)
1635*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::ZPRRegClassID, 0, 32>(Inst, Zdn, Addr,
1636*0fca6ea1SDimitry Andric                                                              Decoder);
16370b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(imm));
16380b57cec5SDimitry Andric   return Success;
16390b57cec5SDimitry Andric }
16400b57cec5SDimitry Andric 
16410b57cec5SDimitry Andric template <int Bits>
1642349cc55cSDimitry Andric static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
164381ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
16440b57cec5SDimitry Andric   if (Imm & ~((1LL << Bits) - 1))
16450b57cec5SDimitry Andric     return Fail;
16460b57cec5SDimitry Andric 
16470b57cec5SDimitry Andric   // Imm is a signed immediate, so sign extend it.
16480b57cec5SDimitry Andric   if (Imm & (1 << (Bits - 1)))
16490b57cec5SDimitry Andric     Imm |= ~((1LL << Bits) - 1);
16500b57cec5SDimitry Andric 
16510b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
16520b57cec5SDimitry Andric   return Success;
16530b57cec5SDimitry Andric }
16540b57cec5SDimitry Andric 
16550b57cec5SDimitry Andric // Decode 8-bit signed/unsigned immediate for a given element width.
16560b57cec5SDimitry Andric template <int ElementWidth>
165781ad6265SDimitry Andric static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm, uint64_t Addr,
165881ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
16590b57cec5SDimitry Andric   unsigned Val = (uint8_t)Imm;
16600b57cec5SDimitry Andric   unsigned Shift = (Imm & 0x100) ? 8 : 0;
16610b57cec5SDimitry Andric   if (ElementWidth == 8 && Shift)
16620b57cec5SDimitry Andric     return Fail;
16630b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Val));
16640b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Shift));
16650b57cec5SDimitry Andric   return Success;
16660b57cec5SDimitry Andric }
16670b57cec5SDimitry Andric 
16680b57cec5SDimitry Andric // Decode uimm4 ranged from 1-16.
16690b57cec5SDimitry Andric static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,
167081ad6265SDimitry Andric                                        uint64_t Addr,
167181ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
16720b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm + 1));
16730b57cec5SDimitry Andric   return Success;
16740b57cec5SDimitry Andric }
1675fe6060f1SDimitry Andric 
1676fe6060f1SDimitry Andric static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,
167781ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
1678fe6060f1SDimitry Andric   if (AArch64SVCR::lookupSVCRByEncoding(Imm)) {
1679fe6060f1SDimitry Andric     Inst.addOperand(MCOperand::createImm(Imm));
1680fe6060f1SDimitry Andric     return Success;
1681fe6060f1SDimitry Andric   }
1682fe6060f1SDimitry Andric   return Fail;
1683fe6060f1SDimitry Andric }
168404eeddc0SDimitry Andric 
168504eeddc0SDimitry Andric static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn,
168604eeddc0SDimitry Andric                                               uint64_t Addr,
168781ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
168804eeddc0SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
168904eeddc0SDimitry Andric   unsigned Rs = fieldFromInstruction(insn, 16, 5);
169004eeddc0SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
169104eeddc0SDimitry Andric 
169204eeddc0SDimitry Andric   // None of the registers may alias: if they do, then the instruction is not
169304eeddc0SDimitry Andric   // merely unpredictable but actually entirely unallocated.
169404eeddc0SDimitry Andric   if (Rd == Rs || Rs == Rn || Rd == Rn)
169504eeddc0SDimitry Andric     return MCDisassembler::Fail;
169604eeddc0SDimitry Andric 
169704eeddc0SDimitry Andric   // All three register operands are written back, so they all appear
169804eeddc0SDimitry Andric   // twice in the operand list, once as outputs and once as inputs.
1699*0fca6ea1SDimitry Andric   if (!DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
1700*0fca6ea1SDimitry Andric           Inst, Rd, Addr, Decoder) ||
1701*0fca6ea1SDimitry Andric       !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
1702*0fca6ea1SDimitry Andric           Inst, Rs, Addr, Decoder) ||
1703*0fca6ea1SDimitry Andric       !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
1704*0fca6ea1SDimitry Andric           Inst, Rn, Addr, Decoder) ||
1705*0fca6ea1SDimitry Andric       !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
1706*0fca6ea1SDimitry Andric           Inst, Rd, Addr, Decoder) ||
1707*0fca6ea1SDimitry Andric       !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
1708*0fca6ea1SDimitry Andric           Inst, Rs, Addr, Decoder) ||
1709*0fca6ea1SDimitry Andric       !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
1710*0fca6ea1SDimitry Andric           Inst, Rn, Addr, Decoder))
171104eeddc0SDimitry Andric     return MCDisassembler::Fail;
171204eeddc0SDimitry Andric 
171304eeddc0SDimitry Andric   return MCDisassembler::Success;
171404eeddc0SDimitry Andric }
171504eeddc0SDimitry Andric 
171604eeddc0SDimitry Andric static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn,
171704eeddc0SDimitry Andric                                               uint64_t Addr,
171881ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
171904eeddc0SDimitry Andric   unsigned Rd = fieldFromInstruction(insn, 0, 5);
172004eeddc0SDimitry Andric   unsigned Rm = fieldFromInstruction(insn, 16, 5);
172104eeddc0SDimitry Andric   unsigned Rn = fieldFromInstruction(insn, 5, 5);
172204eeddc0SDimitry Andric 
172304eeddc0SDimitry Andric   // None of the registers may alias: if they do, then the instruction is not
172404eeddc0SDimitry Andric   // merely unpredictable but actually entirely unallocated.
172504eeddc0SDimitry Andric   if (Rd == Rm || Rm == Rn || Rd == Rn)
172604eeddc0SDimitry Andric     return MCDisassembler::Fail;
172704eeddc0SDimitry Andric 
172804eeddc0SDimitry Andric   // Rd and Rn (not Rm) register operands are written back, so they appear
172904eeddc0SDimitry Andric   // twice in the operand list, once as outputs and once as inputs.
1730*0fca6ea1SDimitry Andric   if (!DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
1731*0fca6ea1SDimitry Andric           Inst, Rd, Addr, Decoder) ||
1732*0fca6ea1SDimitry Andric       !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
1733*0fca6ea1SDimitry Andric           Inst, Rn, Addr, Decoder) ||
1734*0fca6ea1SDimitry Andric       !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
1735*0fca6ea1SDimitry Andric           Inst, Rd, Addr, Decoder) ||
1736*0fca6ea1SDimitry Andric       !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
1737*0fca6ea1SDimitry Andric           Inst, Rn, Addr, Decoder) ||
1738*0fca6ea1SDimitry Andric       !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
1739*0fca6ea1SDimitry Andric           Inst, Rm, Addr, Decoder))
174004eeddc0SDimitry Andric     return MCDisassembler::Fail;
174104eeddc0SDimitry Andric 
174204eeddc0SDimitry Andric   return MCDisassembler::Success;
174304eeddc0SDimitry Andric }
1744bdd1243dSDimitry Andric 
1745bdd1243dSDimitry Andric static DecodeStatus DecodePRFMRegInstruction(MCInst &Inst, uint32_t insn,
1746bdd1243dSDimitry Andric                                              uint64_t Addr,
1747bdd1243dSDimitry Andric                                              const MCDisassembler *Decoder) {
1748bdd1243dSDimitry Andric   // PRFM with Rt = '11xxx' should be decoded as RPRFM.
1749bdd1243dSDimitry Andric   // Fail to decode and defer to fallback decoder table to decode RPRFM.
1750bdd1243dSDimitry Andric   unsigned Mask = 0x18;
1751bdd1243dSDimitry Andric   uint64_t Rt = fieldFromInstruction(insn, 0, 5);
1752bdd1243dSDimitry Andric   if ((Rt & Mask) == Mask)
1753bdd1243dSDimitry Andric     return Fail;
1754bdd1243dSDimitry Andric 
1755bdd1243dSDimitry Andric   uint64_t Rn = fieldFromInstruction(insn, 5, 5);
1756bdd1243dSDimitry Andric   uint64_t Shift = fieldFromInstruction(insn, 12, 1);
1757bdd1243dSDimitry Andric   uint64_t Extend = fieldFromInstruction(insn, 15, 1);
1758bdd1243dSDimitry Andric   uint64_t Rm = fieldFromInstruction(insn, 16, 5);
1759bdd1243dSDimitry Andric 
1760bdd1243dSDimitry Andric   Inst.addOperand(MCOperand::createImm(Rt));
1761*0fca6ea1SDimitry Andric   DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, Rn, Addr,
1762*0fca6ea1SDimitry Andric                                                                Decoder);
1763bdd1243dSDimitry Andric 
1764bdd1243dSDimitry Andric   switch (Inst.getOpcode()) {
1765bdd1243dSDimitry Andric   default:
1766bdd1243dSDimitry Andric     return Fail;
1767bdd1243dSDimitry Andric   case AArch64::PRFMroW:
1768*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, Rm, Addr,
1769*0fca6ea1SDimitry Andric                                                                Decoder);
1770bdd1243dSDimitry Andric     break;
1771bdd1243dSDimitry Andric   case AArch64::PRFMroX:
1772*0fca6ea1SDimitry Andric     DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, Rm, Addr,
1773*0fca6ea1SDimitry Andric                                                                Decoder);
1774bdd1243dSDimitry Andric     break;
1775bdd1243dSDimitry Andric   }
1776bdd1243dSDimitry Andric 
1777bdd1243dSDimitry Andric   DecodeMemExtend(Inst, (Extend << 1) | Shift, Addr, Decoder);
1778bdd1243dSDimitry Andric 
1779bdd1243dSDimitry Andric   return Success;
1780bdd1243dSDimitry Andric }
1781