109467b48Spatrick //===- AArch64Disassembler.cpp - Disassembler for AArch64 -----------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick //
1009467b48Spatrick //===----------------------------------------------------------------------===//
1109467b48Spatrick
1209467b48Spatrick #include "AArch64Disassembler.h"
1309467b48Spatrick #include "AArch64ExternalSymbolizer.h"
1409467b48Spatrick #include "MCTargetDesc/AArch64AddressingModes.h"
1509467b48Spatrick #include "MCTargetDesc/AArch64MCTargetDesc.h"
1609467b48Spatrick #include "TargetInfo/AArch64TargetInfo.h"
1709467b48Spatrick #include "Utils/AArch64BaseInfo.h"
1809467b48Spatrick #include "llvm-c/Disassembler.h"
19*d415bd75Srobert #include "llvm/MC/MCDecoderOps.h"
2009467b48Spatrick #include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
2109467b48Spatrick #include "llvm/MC/MCInst.h"
22*d415bd75Srobert #include "llvm/MC/MCInstrDesc.h"
2309467b48Spatrick #include "llvm/MC/MCRegisterInfo.h"
2409467b48Spatrick #include "llvm/MC/MCSubtargetInfo.h"
25*d415bd75Srobert #include "llvm/MC/TargetRegistry.h"
2609467b48Spatrick #include "llvm/Support/Compiler.h"
2709467b48Spatrick #include "llvm/Support/Debug.h"
2809467b48Spatrick #include "llvm/Support/ErrorHandling.h"
2909467b48Spatrick #include <algorithm>
3009467b48Spatrick #include <memory>
3109467b48Spatrick
3209467b48Spatrick using namespace llvm;
3309467b48Spatrick
3409467b48Spatrick #define DEBUG_TYPE "aarch64-disassembler"
3509467b48Spatrick
3609467b48Spatrick // Pull DecodeStatus and its enum values into the global namespace.
3709467b48Spatrick using DecodeStatus = MCDisassembler::DecodeStatus;
3809467b48Spatrick
3909467b48Spatrick // Forward declare these because the autogenerated code will reference them.
4009467b48Spatrick // Definitions are further down.
41*d415bd75Srobert static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, unsigned RegNo,
4209467b48Spatrick uint64_t Address,
43*d415bd75Srobert const MCDisassembler *Decoder);
44*d415bd75Srobert static DecodeStatus DecodeFPR128_loRegisterClass(MCInst &Inst, unsigned RegNo,
45*d415bd75Srobert uint64_t Address,
46*d415bd75Srobert const MCDisassembler *Decoder);
4709467b48Spatrick static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, unsigned RegNo,
4809467b48Spatrick uint64_t Address,
49*d415bd75Srobert const MCDisassembler *Decoder);
5009467b48Spatrick static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, unsigned RegNo,
5109467b48Spatrick uint64_t Address,
52*d415bd75Srobert const MCDisassembler *Decoder);
5309467b48Spatrick static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, unsigned RegNo,
5409467b48Spatrick uint64_t Address,
55*d415bd75Srobert const MCDisassembler *Decoder);
5609467b48Spatrick static DecodeStatus DecodeFPR8RegisterClass(MCInst &Inst, unsigned RegNo,
5709467b48Spatrick uint64_t Address,
58*d415bd75Srobert const MCDisassembler *Decoder);
59*d415bd75Srobert static DecodeStatus
60*d415bd75Srobert DecodeGPR64commonRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
61*d415bd75Srobert const MCDisassembler *Decoder);
6209467b48Spatrick static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
6309467b48Spatrick uint64_t Address,
64*d415bd75Srobert const MCDisassembler *Decoder);
65*d415bd75Srobert static DecodeStatus
66*d415bd75Srobert DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
67*d415bd75Srobert const MCDisassembler *Decoder);
68*d415bd75Srobert static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst, unsigned RegNo,
6973471bf0Spatrick uint64_t Address,
70*d415bd75Srobert const MCDisassembler *Decoder);
71*d415bd75Srobert static DecodeStatus
72*d415bd75Srobert DecodeMatrixIndexGPR32_8_11RegisterClass(MCInst &Inst, unsigned RegNo,
73*d415bd75Srobert uint64_t Address, const void *Decoder);
74*d415bd75Srobert static DecodeStatus
75*d415bd75Srobert DecodeMatrixIndexGPR32_12_15RegisterClass(MCInst &Inst, unsigned RegNo,
7673471bf0Spatrick uint64_t Address,
77*d415bd75Srobert const MCDisassembler *Decoder);
7809467b48Spatrick static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
7909467b48Spatrick uint64_t Address,
80*d415bd75Srobert const MCDisassembler *Decoder);
81*d415bd75Srobert static DecodeStatus DecodeGPR32spRegisterClass(MCInst &Inst, unsigned RegNo,
82*d415bd75Srobert uint64_t Address,
83*d415bd75Srobert const MCDisassembler *Decoder);
8409467b48Spatrick static DecodeStatus DecodeQQRegisterClass(MCInst &Inst, unsigned RegNo,
8509467b48Spatrick uint64_t Address,
86*d415bd75Srobert const MCDisassembler *Decoder);
8709467b48Spatrick static DecodeStatus DecodeQQQRegisterClass(MCInst &Inst, unsigned RegNo,
8809467b48Spatrick uint64_t Address,
89*d415bd75Srobert const MCDisassembler *Decoder);
9009467b48Spatrick static DecodeStatus DecodeQQQQRegisterClass(MCInst &Inst, unsigned RegNo,
9109467b48Spatrick uint64_t Address,
92*d415bd75Srobert const MCDisassembler *Decoder);
9309467b48Spatrick static DecodeStatus DecodeDDRegisterClass(MCInst &Inst, unsigned RegNo,
9409467b48Spatrick uint64_t Address,
95*d415bd75Srobert const MCDisassembler *Decoder);
9609467b48Spatrick static DecodeStatus DecodeDDDRegisterClass(MCInst &Inst, unsigned RegNo,
9709467b48Spatrick uint64_t Address,
98*d415bd75Srobert const MCDisassembler *Decoder);
9909467b48Spatrick static DecodeStatus DecodeDDDDRegisterClass(MCInst &Inst, unsigned RegNo,
10009467b48Spatrick uint64_t Address,
101*d415bd75Srobert const MCDisassembler *Decoder);
10209467b48Spatrick static DecodeStatus DecodeZPRRegisterClass(MCInst &Inst, unsigned RegNo,
10309467b48Spatrick uint64_t Address,
104*d415bd75Srobert const MCDisassembler *Decoder);
10509467b48Spatrick static DecodeStatus DecodeZPR_4bRegisterClass(MCInst &Inst, unsigned RegNo,
10609467b48Spatrick uint64_t Address,
107*d415bd75Srobert const MCDisassembler *Decoder);
10809467b48Spatrick static DecodeStatus DecodeZPR_3bRegisterClass(MCInst &Inst, unsigned RegNo,
10909467b48Spatrick uint64_t Address,
110*d415bd75Srobert const MCDisassembler *Decoder);
11109467b48Spatrick static DecodeStatus DecodeZPR2RegisterClass(MCInst &Inst, unsigned RegNo,
11209467b48Spatrick uint64_t Address,
113*d415bd75Srobert const MCDisassembler *Decoder);
11409467b48Spatrick static DecodeStatus DecodeZPR3RegisterClass(MCInst &Inst, unsigned RegNo,
11509467b48Spatrick uint64_t Address,
116*d415bd75Srobert const MCDisassembler *Decoder);
11709467b48Spatrick static DecodeStatus DecodeZPR4RegisterClass(MCInst &Inst, unsigned RegNo,
11809467b48Spatrick uint64_t Address,
119*d415bd75Srobert const MCDisassembler *Decoder);
120*d415bd75Srobert static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
121*d415bd75Srobert uint64_t Address,
122*d415bd75Srobert const void *Decoder);
123*d415bd75Srobert static DecodeStatus DecodeZPR4Mul4RegisterClass(MCInst &Inst, unsigned RegNo,
124*d415bd75Srobert uint64_t Address,
125*d415bd75Srobert const void *Decoder);
126*d415bd75Srobert static DecodeStatus DecodeZPR2StridedRegisterClass(MCInst &Inst, unsigned RegNo,
127*d415bd75Srobert uint64_t Address,
128*d415bd75Srobert const void *Decoder);
129*d415bd75Srobert static DecodeStatus DecodeZPR4StridedRegisterClass(MCInst &Inst, unsigned RegNo,
130*d415bd75Srobert uint64_t Address,
13109467b48Spatrick const void *Decoder);
13273471bf0Spatrick template <unsigned NumBitsForTile>
13373471bf0Spatrick static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo,
13473471bf0Spatrick uint64_t Address,
135*d415bd75Srobert const MCDisassembler *Decoder);
136*d415bd75Srobert static DecodeStatus
137*d415bd75Srobert DecodeMatrixTileListRegisterClass(MCInst &Inst, unsigned RegMask,
138*d415bd75Srobert uint64_t Address,
139*d415bd75Srobert const MCDisassembler *Decoder);
14009467b48Spatrick static DecodeStatus DecodePPRRegisterClass(MCInst &Inst, unsigned RegNo,
14109467b48Spatrick uint64_t Address,
142*d415bd75Srobert const MCDisassembler *Decoder);
14309467b48Spatrick static DecodeStatus DecodePPR_3bRegisterClass(MCInst &Inst, unsigned RegNo,
14409467b48Spatrick uint64_t Address,
145*d415bd75Srobert const MCDisassembler *Decoder);
146*d415bd75Srobert static DecodeStatus
147*d415bd75Srobert DecodePPR_p8to15RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
148*d415bd75Srobert const MCDisassembler *Decoder);
149*d415bd75Srobert static DecodeStatus DecodePPR2RegisterClass(MCInst &Inst, unsigned RegNo,
150*d415bd75Srobert uint64_t Address,
151*d415bd75Srobert const void *Decoder);
152*d415bd75Srobert static DecodeStatus DecodePPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
153*d415bd75Srobert uint64_t Address,
15409467b48Spatrick const void *Decoder);
15509467b48Spatrick
15609467b48Spatrick static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm,
15709467b48Spatrick uint64_t Address,
158*d415bd75Srobert const MCDisassembler *Decoder);
15909467b48Spatrick static DecodeStatus DecodeFixedPointScaleImm64(MCInst &Inst, unsigned Imm,
16009467b48Spatrick uint64_t Address,
161*d415bd75Srobert const MCDisassembler *Decoder);
16209467b48Spatrick static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
16309467b48Spatrick uint64_t Address,
164*d415bd75Srobert const MCDisassembler *Decoder);
165*d415bd75Srobert static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
166*d415bd75Srobert uint64_t Address,
167*d415bd75Srobert const MCDisassembler *Decoder);
168*d415bd75Srobert static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm,
169*d415bd75Srobert uint64_t Address,
170*d415bd75Srobert const MCDisassembler *Decoder);
171*d415bd75Srobert static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm,
172*d415bd75Srobert uint64_t Address,
173*d415bd75Srobert const MCDisassembler *Decoder);
174*d415bd75Srobert static DecodeStatus
175*d415bd75Srobert DecodeThreeAddrSRegInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
176*d415bd75Srobert const MCDisassembler *Decoder);
17709467b48Spatrick static DecodeStatus DecodeMoveImmInstruction(MCInst &Inst, uint32_t insn,
17809467b48Spatrick uint64_t Address,
179*d415bd75Srobert const MCDisassembler *Decoder);
180*d415bd75Srobert static DecodeStatus
181*d415bd75Srobert DecodeUnsignedLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
182*d415bd75Srobert const MCDisassembler *Decoder);
18309467b48Spatrick static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
18409467b48Spatrick uint64_t Address,
185*d415bd75Srobert const MCDisassembler *Decoder);
186*d415bd75Srobert static DecodeStatus
187*d415bd75Srobert DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
188*d415bd75Srobert const MCDisassembler *Decoder);
18909467b48Spatrick static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,
19009467b48Spatrick uint64_t Address,
191*d415bd75Srobert const MCDisassembler *Decoder);
192097a140dSpatrick static DecodeStatus DecodeAuthLoadInstruction(MCInst &Inst, uint32_t insn,
193097a140dSpatrick uint64_t Address,
194*d415bd75Srobert const MCDisassembler *Decoder);
19509467b48Spatrick static DecodeStatus DecodeAddSubERegInstruction(MCInst &Inst, uint32_t insn,
19609467b48Spatrick uint64_t Address,
197*d415bd75Srobert const MCDisassembler *Decoder);
19809467b48Spatrick static DecodeStatus DecodeLogicalImmInstruction(MCInst &Inst, uint32_t insn,
19909467b48Spatrick uint64_t Address,
200*d415bd75Srobert const MCDisassembler *Decoder);
20109467b48Spatrick static DecodeStatus DecodeModImmInstruction(MCInst &Inst, uint32_t insn,
20209467b48Spatrick uint64_t Address,
203*d415bd75Srobert const MCDisassembler *Decoder);
20409467b48Spatrick static DecodeStatus DecodeModImmTiedInstruction(MCInst &Inst, uint32_t insn,
20509467b48Spatrick uint64_t Address,
206*d415bd75Srobert const MCDisassembler *Decoder);
20709467b48Spatrick static DecodeStatus DecodeAdrInstruction(MCInst &Inst, uint32_t insn,
208*d415bd75Srobert uint64_t Address,
209*d415bd75Srobert const MCDisassembler *Decoder);
21009467b48Spatrick static DecodeStatus DecodeAddSubImmShift(MCInst &Inst, uint32_t insn,
211*d415bd75Srobert uint64_t Address,
212*d415bd75Srobert const MCDisassembler *Decoder);
21309467b48Spatrick static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn,
21409467b48Spatrick uint64_t Address,
215*d415bd75Srobert const MCDisassembler *Decoder);
216*d415bd75Srobert static DecodeStatus
217*d415bd75Srobert DecodeSystemPStateImm0_15Instruction(MCInst &Inst, uint32_t insn,
21809467b48Spatrick uint64_t Address,
219*d415bd75Srobert const MCDisassembler *Decoder);
220*d415bd75Srobert static DecodeStatus
221*d415bd75Srobert DecodeSystemPStateImm0_1Instruction(MCInst &Inst, uint32_t insn,
222*d415bd75Srobert uint64_t Address,
223*d415bd75Srobert const MCDisassembler *Decoder);
22409467b48Spatrick static DecodeStatus DecodeTestAndBranch(MCInst &Inst, uint32_t insn,
225*d415bd75Srobert uint64_t Address,
226*d415bd75Srobert const MCDisassembler *Decoder);
22709467b48Spatrick
22809467b48Spatrick static DecodeStatus DecodeFMOVLaneInstruction(MCInst &Inst, unsigned Insn,
22909467b48Spatrick uint64_t Address,
230*d415bd75Srobert const MCDisassembler *Decoder);
23109467b48Spatrick static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm,
232*d415bd75Srobert uint64_t Addr,
233*d415bd75Srobert const MCDisassembler *Decoder);
23409467b48Spatrick static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst &Inst, unsigned Imm,
23509467b48Spatrick uint64_t Addr,
236*d415bd75Srobert const MCDisassembler *Decoder);
23709467b48Spatrick static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm,
238*d415bd75Srobert uint64_t Addr,
239*d415bd75Srobert const MCDisassembler *Decoder);
24009467b48Spatrick static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst &Inst, unsigned Imm,
24109467b48Spatrick uint64_t Addr,
242*d415bd75Srobert const MCDisassembler *Decoder);
24309467b48Spatrick static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm,
244*d415bd75Srobert uint64_t Addr,
245*d415bd75Srobert const MCDisassembler *Decoder);
24609467b48Spatrick static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst &Inst, unsigned Imm,
24709467b48Spatrick uint64_t Addr,
248*d415bd75Srobert const MCDisassembler *Decoder);
24909467b48Spatrick static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm,
250*d415bd75Srobert uint64_t Addr,
251*d415bd75Srobert const MCDisassembler *Decoder);
25209467b48Spatrick static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm,
253*d415bd75Srobert uint64_t Addr,
254*d415bd75Srobert const MCDisassembler *Decoder);
25509467b48Spatrick static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm,
256*d415bd75Srobert uint64_t Addr,
257*d415bd75Srobert const MCDisassembler *Decoder);
25809467b48Spatrick static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm,
259*d415bd75Srobert uint64_t Addr,
260*d415bd75Srobert const MCDisassembler *Decoder);
26109467b48Spatrick static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm,
26209467b48Spatrick uint64_t Addr,
263*d415bd75Srobert const MCDisassembler *Decoder);
264*d415bd75Srobert static DecodeStatus
265*d415bd75Srobert DecodeWSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
266*d415bd75Srobert const MCDisassembler *Decoder);
267*d415bd75Srobert static DecodeStatus
268*d415bd75Srobert DecodeXSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
269*d415bd75Srobert const MCDisassembler *Decoder);
270*d415bd75Srobert static DecodeStatus DecodeSyspXzrInstruction(MCInst &Inst, uint32_t insn,
27109467b48Spatrick uint64_t Addr,
272*d415bd75Srobert const MCDisassembler *Decoder);
273*d415bd75Srobert static DecodeStatus
274*d415bd75Srobert DecodeSVELogicalImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Address,
275*d415bd75Srobert const MCDisassembler *Decoder);
27609467b48Spatrick template <int Bits>
277*d415bd75Srobert static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
278*d415bd75Srobert const MCDisassembler *Decoder);
27909467b48Spatrick template <int ElementWidth>
280*d415bd75Srobert static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm, uint64_t Addr,
281*d415bd75Srobert const MCDisassembler *Decoder);
28209467b48Spatrick static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,
283*d415bd75Srobert uint64_t Addr,
284*d415bd75Srobert const MCDisassembler *Decoder);
28573471bf0Spatrick static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,
286*d415bd75Srobert const MCDisassembler *Decoder);
287*d415bd75Srobert static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn,
288*d415bd75Srobert uint64_t Addr,
289*d415bd75Srobert const MCDisassembler *Decoder);
290*d415bd75Srobert static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn,
291*d415bd75Srobert uint64_t Addr,
292*d415bd75Srobert const MCDisassembler *Decoder);
293*d415bd75Srobert static DecodeStatus DecodePRFMRegInstruction(MCInst &Inst, uint32_t insn,
294*d415bd75Srobert uint64_t Address,
295*d415bd75Srobert const MCDisassembler *Decoder);
29609467b48Spatrick
29709467b48Spatrick #include "AArch64GenDisassemblerTables.inc"
29809467b48Spatrick #include "AArch64GenInstrInfo.inc"
29909467b48Spatrick
30009467b48Spatrick #define Success MCDisassembler::Success
30109467b48Spatrick #define Fail MCDisassembler::Fail
30209467b48Spatrick #define SoftFail MCDisassembler::SoftFail
30309467b48Spatrick
createAArch64Disassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)30409467b48Spatrick static MCDisassembler *createAArch64Disassembler(const Target &T,
30509467b48Spatrick const MCSubtargetInfo &STI,
30609467b48Spatrick MCContext &Ctx) {
307*d415bd75Srobert
308*d415bd75Srobert return new AArch64Disassembler(STI, Ctx, T.createMCInstrInfo());
30909467b48Spatrick }
31009467b48Spatrick
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const31109467b48Spatrick DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
31209467b48Spatrick ArrayRef<uint8_t> Bytes,
31309467b48Spatrick uint64_t Address,
31409467b48Spatrick raw_ostream &CS) const {
31509467b48Spatrick CommentStream = &CS;
31609467b48Spatrick
31709467b48Spatrick Size = 0;
31809467b48Spatrick // We want to read exactly 4 bytes of data.
31909467b48Spatrick if (Bytes.size() < 4)
32009467b48Spatrick return Fail;
32109467b48Spatrick Size = 4;
32209467b48Spatrick
32309467b48Spatrick // Encoded as a small-endian 32-bit word in the stream.
32409467b48Spatrick uint32_t Insn =
32509467b48Spatrick (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
32609467b48Spatrick
32773471bf0Spatrick const uint8_t *Tables[] = {DecoderTable32, DecoderTableFallback32};
32873471bf0Spatrick
329*d415bd75Srobert for (const auto *Table : Tables) {
33073471bf0Spatrick DecodeStatus Result =
33173471bf0Spatrick decodeInstruction(Table, MI, Insn, Address, this, STI);
33273471bf0Spatrick
333*d415bd75Srobert const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
334*d415bd75Srobert
335*d415bd75Srobert // For Scalable Matrix Extension (SME) instructions that have an implicit
336*d415bd75Srobert // operand for the accumulator (ZA) or implicit immediate zero which isn't
337*d415bd75Srobert // encoded, manually insert operand.
338*d415bd75Srobert for (unsigned i = 0; i < Desc.getNumOperands(); i++) {
339*d415bd75Srobert if (Desc.operands()[i].OperandType == MCOI::OPERAND_REGISTER) {
340*d415bd75Srobert switch (Desc.operands()[i].RegClass) {
34173471bf0Spatrick default:
34273471bf0Spatrick break;
343*d415bd75Srobert case AArch64::MPRRegClassID:
344*d415bd75Srobert MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZA));
345*d415bd75Srobert break;
346*d415bd75Srobert case AArch64::MPR8RegClassID:
347*d415bd75Srobert MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZAB0));
348*d415bd75Srobert break;
349*d415bd75Srobert case AArch64::ZTRRegClassID:
350*d415bd75Srobert MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZT0));
351*d415bd75Srobert break;
352*d415bd75Srobert }
353*d415bd75Srobert } else if (Desc.operands()[i].OperandType ==
354*d415bd75Srobert AArch64::OPERAND_IMPLICIT_IMM_0) {
355*d415bd75Srobert MI.insert(MI.begin() + i, MCOperand::createImm(0));
356*d415bd75Srobert }
357*d415bd75Srobert }
358*d415bd75Srobert
359*d415bd75Srobert if (MI.getOpcode() == AArch64::LDR_ZA ||
360*d415bd75Srobert MI.getOpcode() == AArch64::STR_ZA) {
361*d415bd75Srobert // Spill and fill instructions have a single immediate used for both
362*d415bd75Srobert // the vector select offset and optional memory offset. Replicate
363*d415bd75Srobert // the decoded immediate.
36473471bf0Spatrick const MCOperand &Imm4Op = MI.getOperand(2);
36573471bf0Spatrick assert(Imm4Op.isImm() && "Unexpected operand type!");
36673471bf0Spatrick MI.addOperand(Imm4Op);
36773471bf0Spatrick }
36873471bf0Spatrick
36973471bf0Spatrick if (Result != MCDisassembler::Fail)
37073471bf0Spatrick return Result;
37173471bf0Spatrick }
37273471bf0Spatrick
37373471bf0Spatrick return MCDisassembler::Fail;
37409467b48Spatrick }
37509467b48Spatrick
suggestBytesToSkip(ArrayRef<uint8_t> Bytes,uint64_t Address) const376*d415bd75Srobert uint64_t AArch64Disassembler::suggestBytesToSkip(ArrayRef<uint8_t> Bytes,
377*d415bd75Srobert uint64_t Address) const {
378*d415bd75Srobert // AArch64 instructions are always 4 bytes wide, so there's no point
379*d415bd75Srobert // in skipping any smaller number of bytes if an instruction can't
380*d415bd75Srobert // be decoded.
381*d415bd75Srobert return 4;
382*d415bd75Srobert }
383*d415bd75Srobert
38409467b48Spatrick static MCSymbolizer *
createAArch64ExternalSymbolizer(const Triple & TT,LLVMOpInfoCallback GetOpInfo,LLVMSymbolLookupCallback SymbolLookUp,void * DisInfo,MCContext * Ctx,std::unique_ptr<MCRelocationInfo> && RelInfo)38509467b48Spatrick createAArch64ExternalSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,
38609467b48Spatrick LLVMSymbolLookupCallback SymbolLookUp,
38709467b48Spatrick void *DisInfo, MCContext *Ctx,
38809467b48Spatrick std::unique_ptr<MCRelocationInfo> &&RelInfo) {
38909467b48Spatrick return new AArch64ExternalSymbolizer(*Ctx, std::move(RelInfo), GetOpInfo,
39009467b48Spatrick SymbolLookUp, DisInfo);
39109467b48Spatrick }
39209467b48Spatrick
LLVMInitializeAArch64Disassembler()39309467b48Spatrick extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64Disassembler() {
39409467b48Spatrick TargetRegistry::RegisterMCDisassembler(getTheAArch64leTarget(),
39509467b48Spatrick createAArch64Disassembler);
39609467b48Spatrick TargetRegistry::RegisterMCDisassembler(getTheAArch64beTarget(),
39709467b48Spatrick createAArch64Disassembler);
39809467b48Spatrick TargetRegistry::RegisterMCSymbolizer(getTheAArch64leTarget(),
39909467b48Spatrick createAArch64ExternalSymbolizer);
40009467b48Spatrick TargetRegistry::RegisterMCSymbolizer(getTheAArch64beTarget(),
40109467b48Spatrick createAArch64ExternalSymbolizer);
40209467b48Spatrick TargetRegistry::RegisterMCDisassembler(getTheAArch64_32Target(),
40309467b48Spatrick createAArch64Disassembler);
40409467b48Spatrick TargetRegistry::RegisterMCSymbolizer(getTheAArch64_32Target(),
40509467b48Spatrick createAArch64ExternalSymbolizer);
40609467b48Spatrick
40709467b48Spatrick TargetRegistry::RegisterMCDisassembler(getTheARM64Target(),
40809467b48Spatrick createAArch64Disassembler);
40909467b48Spatrick TargetRegistry::RegisterMCSymbolizer(getTheARM64Target(),
41009467b48Spatrick createAArch64ExternalSymbolizer);
41109467b48Spatrick TargetRegistry::RegisterMCDisassembler(getTheARM64_32Target(),
41209467b48Spatrick createAArch64Disassembler);
41309467b48Spatrick TargetRegistry::RegisterMCSymbolizer(getTheARM64_32Target(),
41409467b48Spatrick createAArch64ExternalSymbolizer);
41509467b48Spatrick }
41609467b48Spatrick
DecodeFPR128RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)41709467b48Spatrick static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, unsigned RegNo,
41809467b48Spatrick uint64_t Addr,
419*d415bd75Srobert const MCDisassembler *Decoder) {
42009467b48Spatrick if (RegNo > 31)
42109467b48Spatrick return Fail;
42209467b48Spatrick
423*d415bd75Srobert unsigned Register =
424*d415bd75Srobert AArch64MCRegisterClasses[AArch64::FPR128RegClassID].getRegister(RegNo);
42509467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
42609467b48Spatrick return Success;
42709467b48Spatrick }
42809467b48Spatrick
429*d415bd75Srobert static DecodeStatus
DecodeFPR128_loRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)430*d415bd75Srobert DecodeFPR128_loRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
431*d415bd75Srobert const MCDisassembler *Decoder) {
43209467b48Spatrick if (RegNo > 15)
43309467b48Spatrick return Fail;
43409467b48Spatrick return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder);
43509467b48Spatrick }
43609467b48Spatrick
DecodeFPR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)43709467b48Spatrick static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, unsigned RegNo,
43809467b48Spatrick uint64_t Addr,
439*d415bd75Srobert const MCDisassembler *Decoder) {
44009467b48Spatrick if (RegNo > 31)
44109467b48Spatrick return Fail;
44209467b48Spatrick
443*d415bd75Srobert unsigned Register =
444*d415bd75Srobert AArch64MCRegisterClasses[AArch64::FPR64RegClassID].getRegister(RegNo);
44509467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
44609467b48Spatrick return Success;
44709467b48Spatrick }
44809467b48Spatrick
DecodeFPR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)44909467b48Spatrick static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, unsigned RegNo,
45009467b48Spatrick uint64_t Addr,
451*d415bd75Srobert const MCDisassembler *Decoder) {
45209467b48Spatrick if (RegNo > 31)
45309467b48Spatrick return Fail;
45409467b48Spatrick
455*d415bd75Srobert unsigned Register =
456*d415bd75Srobert AArch64MCRegisterClasses[AArch64::FPR32RegClassID].getRegister(RegNo);
45709467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
45809467b48Spatrick return Success;
45909467b48Spatrick }
46009467b48Spatrick
DecodeFPR16RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)46109467b48Spatrick static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, unsigned RegNo,
46209467b48Spatrick uint64_t Addr,
463*d415bd75Srobert const MCDisassembler *Decoder) {
46409467b48Spatrick if (RegNo > 31)
46509467b48Spatrick return Fail;
46609467b48Spatrick
467*d415bd75Srobert unsigned Register =
468*d415bd75Srobert AArch64MCRegisterClasses[AArch64::FPR16RegClassID].getRegister(RegNo);
46909467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
47009467b48Spatrick return Success;
47109467b48Spatrick }
47209467b48Spatrick
DecodeFPR8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)47309467b48Spatrick static DecodeStatus DecodeFPR8RegisterClass(MCInst &Inst, unsigned RegNo,
47409467b48Spatrick uint64_t Addr,
475*d415bd75Srobert const MCDisassembler *Decoder) {
47609467b48Spatrick if (RegNo > 31)
47709467b48Spatrick return Fail;
47809467b48Spatrick
479*d415bd75Srobert unsigned Register =
480*d415bd75Srobert AArch64MCRegisterClasses[AArch64::FPR8RegClassID].getRegister(RegNo);
48109467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
48209467b48Spatrick return Success;
48309467b48Spatrick }
48409467b48Spatrick
485*d415bd75Srobert static DecodeStatus
DecodeGPR64commonRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)486*d415bd75Srobert DecodeGPR64commonRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
487*d415bd75Srobert const MCDisassembler *Decoder) {
48809467b48Spatrick if (RegNo > 30)
48909467b48Spatrick return Fail;
49009467b48Spatrick
491*d415bd75Srobert unsigned Register =
492*d415bd75Srobert AArch64MCRegisterClasses[AArch64::GPR64commonRegClassID].getRegister(
493*d415bd75Srobert RegNo);
49409467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
49509467b48Spatrick return Success;
49609467b48Spatrick }
49709467b48Spatrick
DecodeGPR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)49809467b48Spatrick static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
49909467b48Spatrick uint64_t Addr,
500*d415bd75Srobert const MCDisassembler *Decoder) {
50109467b48Spatrick if (RegNo > 31)
50209467b48Spatrick return Fail;
50309467b48Spatrick
504*d415bd75Srobert unsigned Register =
505*d415bd75Srobert AArch64MCRegisterClasses[AArch64::GPR64RegClassID].getRegister(RegNo);
50609467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
50709467b48Spatrick return Success;
50809467b48Spatrick }
50909467b48Spatrick
510*d415bd75Srobert static DecodeStatus
DecodeGPR64x8ClassRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)511*d415bd75Srobert DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
512*d415bd75Srobert const MCDisassembler *Decoder) {
51373471bf0Spatrick if (RegNo > 22)
51473471bf0Spatrick return Fail;
51573471bf0Spatrick if (RegNo & 1)
51673471bf0Spatrick return Fail;
51773471bf0Spatrick
518*d415bd75Srobert unsigned Register =
519*d415bd75Srobert AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].getRegister(
520*d415bd75Srobert RegNo >> 1);
52173471bf0Spatrick Inst.addOperand(MCOperand::createReg(Register));
52273471bf0Spatrick return Success;
52373471bf0Spatrick }
52473471bf0Spatrick
DecodeGPR64spRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)52509467b48Spatrick static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst, unsigned RegNo,
52609467b48Spatrick uint64_t Addr,
527*d415bd75Srobert const MCDisassembler *Decoder) {
52809467b48Spatrick if (RegNo > 31)
52909467b48Spatrick return Fail;
530*d415bd75Srobert unsigned Register =
531*d415bd75Srobert AArch64MCRegisterClasses[AArch64::GPR64spRegClassID].getRegister(RegNo);
53209467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
53309467b48Spatrick return Success;
53409467b48Spatrick }
53509467b48Spatrick
536*d415bd75Srobert static DecodeStatus
DecodeMatrixIndexGPR32_8_11RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)537*d415bd75Srobert DecodeMatrixIndexGPR32_8_11RegisterClass(MCInst &Inst, unsigned RegNo,
538*d415bd75Srobert uint64_t Addr, const void *Decoder) {
53973471bf0Spatrick if (RegNo > 3)
54073471bf0Spatrick return Fail;
54173471bf0Spatrick
542*d415bd75Srobert unsigned Register =
543*d415bd75Srobert AArch64MCRegisterClasses[AArch64::MatrixIndexGPR32_8_11RegClassID]
544*d415bd75Srobert .getRegister(RegNo);
54573471bf0Spatrick Inst.addOperand(MCOperand::createReg(Register));
54673471bf0Spatrick return Success;
54773471bf0Spatrick }
54873471bf0Spatrick
549*d415bd75Srobert static DecodeStatus
DecodeMatrixIndexGPR32_12_15RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)550*d415bd75Srobert DecodeMatrixIndexGPR32_12_15RegisterClass(MCInst &Inst, unsigned RegNo,
551*d415bd75Srobert uint64_t Addr,
552*d415bd75Srobert const MCDisassembler *Decoder) {
553*d415bd75Srobert if (RegNo > 3)
554*d415bd75Srobert return Fail;
555*d415bd75Srobert
556*d415bd75Srobert unsigned Register =
557*d415bd75Srobert AArch64MCRegisterClasses[AArch64::MatrixIndexGPR32_12_15RegClassID]
558*d415bd75Srobert .getRegister(RegNo);
559*d415bd75Srobert Inst.addOperand(MCOperand::createReg(Register));
560*d415bd75Srobert return Success;
561*d415bd75Srobert }
56209467b48Spatrick
DecodeGPR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)56309467b48Spatrick static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
56409467b48Spatrick uint64_t Addr,
565*d415bd75Srobert const MCDisassembler *Decoder) {
56609467b48Spatrick if (RegNo > 31)
56709467b48Spatrick return Fail;
56809467b48Spatrick
569*d415bd75Srobert unsigned Register =
570*d415bd75Srobert AArch64MCRegisterClasses[AArch64::GPR32RegClassID].getRegister(RegNo);
57109467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
57209467b48Spatrick return Success;
57309467b48Spatrick }
57409467b48Spatrick
DecodeGPR32spRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)57509467b48Spatrick static DecodeStatus DecodeGPR32spRegisterClass(MCInst &Inst, unsigned RegNo,
57609467b48Spatrick uint64_t Addr,
577*d415bd75Srobert const MCDisassembler *Decoder) {
57809467b48Spatrick if (RegNo > 31)
57909467b48Spatrick return Fail;
58009467b48Spatrick
581*d415bd75Srobert unsigned Register =
582*d415bd75Srobert AArch64MCRegisterClasses[AArch64::GPR32spRegClassID].getRegister(RegNo);
58309467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
58409467b48Spatrick return Success;
58509467b48Spatrick }
58609467b48Spatrick
DecodeZPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)58709467b48Spatrick static DecodeStatus DecodeZPRRegisterClass(MCInst &Inst, unsigned RegNo,
58809467b48Spatrick uint64_t Address,
589*d415bd75Srobert const MCDisassembler *Decoder) {
59009467b48Spatrick if (RegNo > 31)
59109467b48Spatrick return Fail;
59209467b48Spatrick
593*d415bd75Srobert unsigned Register =
594*d415bd75Srobert AArch64MCRegisterClasses[AArch64::ZPRRegClassID].getRegister(RegNo);
59509467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
59609467b48Spatrick return Success;
59709467b48Spatrick }
59809467b48Spatrick
DecodeZPR_4bRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)59909467b48Spatrick static DecodeStatus DecodeZPR_4bRegisterClass(MCInst &Inst, unsigned RegNo,
60009467b48Spatrick uint64_t Address,
601*d415bd75Srobert const MCDisassembler *Decoder) {
60209467b48Spatrick if (RegNo > 15)
60309467b48Spatrick return Fail;
60409467b48Spatrick return DecodeZPRRegisterClass(Inst, RegNo, Address, Decoder);
60509467b48Spatrick }
60609467b48Spatrick
DecodeZPR_3bRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)60709467b48Spatrick static DecodeStatus DecodeZPR_3bRegisterClass(MCInst &Inst, unsigned RegNo,
60809467b48Spatrick uint64_t Address,
609*d415bd75Srobert const MCDisassembler *Decoder) {
61009467b48Spatrick if (RegNo > 7)
61109467b48Spatrick return Fail;
61209467b48Spatrick return DecodeZPRRegisterClass(Inst, RegNo, Address, Decoder);
61309467b48Spatrick }
61409467b48Spatrick
DecodeZPR2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)61509467b48Spatrick static DecodeStatus DecodeZPR2RegisterClass(MCInst &Inst, unsigned RegNo,
61609467b48Spatrick uint64_t Address,
617*d415bd75Srobert const MCDisassembler *Decoder) {
61809467b48Spatrick if (RegNo > 31)
61909467b48Spatrick return Fail;
620*d415bd75Srobert unsigned Register =
621*d415bd75Srobert AArch64MCRegisterClasses[AArch64::ZPR2RegClassID].getRegister(RegNo);
62209467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
62309467b48Spatrick return Success;
62409467b48Spatrick }
62509467b48Spatrick
DecodeZPR3RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)62609467b48Spatrick static DecodeStatus DecodeZPR3RegisterClass(MCInst &Inst, unsigned RegNo,
62709467b48Spatrick uint64_t Address,
628*d415bd75Srobert const MCDisassembler *Decoder) {
62909467b48Spatrick if (RegNo > 31)
63009467b48Spatrick return Fail;
631*d415bd75Srobert unsigned Register =
632*d415bd75Srobert AArch64MCRegisterClasses[AArch64::ZPR3RegClassID].getRegister(RegNo);
63309467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
63409467b48Spatrick return Success;
63509467b48Spatrick }
63609467b48Spatrick
DecodeZPR4RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)63709467b48Spatrick static DecodeStatus DecodeZPR4RegisterClass(MCInst &Inst, unsigned RegNo,
63809467b48Spatrick uint64_t Address,
639*d415bd75Srobert const MCDisassembler *Decoder) {
64009467b48Spatrick if (RegNo > 31)
64109467b48Spatrick return Fail;
642*d415bd75Srobert unsigned Register =
643*d415bd75Srobert AArch64MCRegisterClasses[AArch64::ZPR4RegClassID].getRegister(RegNo);
64409467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
64509467b48Spatrick return Success;
64609467b48Spatrick }
64709467b48Spatrick
DecodeZPR2Mul2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)648*d415bd75Srobert static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
64973471bf0Spatrick uint64_t Address,
65073471bf0Spatrick const void *Decoder) {
651*d415bd75Srobert if (RegNo * 2 > 30)
652*d415bd75Srobert return Fail;
653*d415bd75Srobert unsigned Register =
654*d415bd75Srobert AArch64MCRegisterClasses[AArch64::ZPR2RegClassID].getRegister(RegNo * 2);
655*d415bd75Srobert Inst.addOperand(MCOperand::createReg(Register));
656*d415bd75Srobert return Success;
657*d415bd75Srobert }
658*d415bd75Srobert
DecodeZPR4Mul4RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)659*d415bd75Srobert static DecodeStatus DecodeZPR4Mul4RegisterClass(MCInst &Inst, unsigned RegNo,
660*d415bd75Srobert uint64_t Address,
661*d415bd75Srobert const void *Decoder) {
662*d415bd75Srobert if (RegNo * 4 > 28)
663*d415bd75Srobert return Fail;
664*d415bd75Srobert unsigned Register =
665*d415bd75Srobert AArch64MCRegisterClasses[AArch64::ZPR4RegClassID].getRegister(RegNo * 4);
666*d415bd75Srobert Inst.addOperand(MCOperand::createReg(Register));
667*d415bd75Srobert return Success;
668*d415bd75Srobert }
669*d415bd75Srobert
DecodeZPR2StridedRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)670*d415bd75Srobert static DecodeStatus DecodeZPR2StridedRegisterClass(MCInst &Inst, unsigned RegNo,
671*d415bd75Srobert uint64_t Address,
672*d415bd75Srobert const void *Decoder) {
673*d415bd75Srobert if (RegNo > 15)
674*d415bd75Srobert return Fail;
675*d415bd75Srobert unsigned Register =
676*d415bd75Srobert AArch64MCRegisterClasses[AArch64::ZPR2StridedRegClassID].getRegister(
677*d415bd75Srobert RegNo);
678*d415bd75Srobert Inst.addOperand(MCOperand::createReg(Register));
679*d415bd75Srobert return Success;
680*d415bd75Srobert }
681*d415bd75Srobert
DecodeZPR4StridedRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)682*d415bd75Srobert static DecodeStatus DecodeZPR4StridedRegisterClass(MCInst &Inst, unsigned RegNo,
683*d415bd75Srobert uint64_t Address,
684*d415bd75Srobert const void *Decoder) {
685*d415bd75Srobert if (RegNo > 7)
686*d415bd75Srobert return Fail;
687*d415bd75Srobert unsigned Register =
688*d415bd75Srobert AArch64MCRegisterClasses[AArch64::ZPR4StridedRegClassID].getRegister(
689*d415bd75Srobert RegNo);
690*d415bd75Srobert Inst.addOperand(MCOperand::createReg(Register));
691*d415bd75Srobert return Success;
692*d415bd75Srobert }
693*d415bd75Srobert
694*d415bd75Srobert static DecodeStatus
DecodeMatrixTileListRegisterClass(MCInst & Inst,unsigned RegMask,uint64_t Address,const MCDisassembler * Decoder)695*d415bd75Srobert DecodeMatrixTileListRegisterClass(MCInst &Inst, unsigned RegMask,
696*d415bd75Srobert uint64_t Address,
697*d415bd75Srobert const MCDisassembler *Decoder) {
69873471bf0Spatrick if (RegMask > 0xFF)
69973471bf0Spatrick return Fail;
70073471bf0Spatrick Inst.addOperand(MCOperand::createImm(RegMask));
70173471bf0Spatrick return Success;
70273471bf0Spatrick }
70373471bf0Spatrick
70473471bf0Spatrick static const SmallVector<SmallVector<unsigned, 16>, 5>
70573471bf0Spatrick MatrixZATileDecoderTable = {
70673471bf0Spatrick {AArch64::ZAB0},
70773471bf0Spatrick {AArch64::ZAH0, AArch64::ZAH1},
70873471bf0Spatrick {AArch64::ZAS0, AArch64::ZAS1, AArch64::ZAS2, AArch64::ZAS3},
70973471bf0Spatrick {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
71073471bf0Spatrick AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7},
71173471bf0Spatrick {AArch64::ZAQ0, AArch64::ZAQ1, AArch64::ZAQ2, AArch64::ZAQ3,
71273471bf0Spatrick AArch64::ZAQ4, AArch64::ZAQ5, AArch64::ZAQ6, AArch64::ZAQ7,
71373471bf0Spatrick AArch64::ZAQ8, AArch64::ZAQ9, AArch64::ZAQ10, AArch64::ZAQ11,
71473471bf0Spatrick AArch64::ZAQ12, AArch64::ZAQ13, AArch64::ZAQ14, AArch64::ZAQ15}};
71573471bf0Spatrick
71673471bf0Spatrick template <unsigned NumBitsForTile>
DecodeMatrixTile(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)71773471bf0Spatrick static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo,
718*d415bd75Srobert uint64_t Address,
719*d415bd75Srobert const MCDisassembler *Decoder) {
72073471bf0Spatrick unsigned LastReg = (1 << NumBitsForTile) - 1;
72173471bf0Spatrick if (RegNo > LastReg)
72273471bf0Spatrick return Fail;
72373471bf0Spatrick Inst.addOperand(
72473471bf0Spatrick MCOperand::createReg(MatrixZATileDecoderTable[NumBitsForTile][RegNo]));
72573471bf0Spatrick return Success;
72673471bf0Spatrick }
72773471bf0Spatrick
DecodePPRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)72809467b48Spatrick static DecodeStatus DecodePPRRegisterClass(MCInst &Inst, unsigned RegNo,
729*d415bd75Srobert uint64_t Addr,
730*d415bd75Srobert const MCDisassembler *Decoder) {
73109467b48Spatrick if (RegNo > 15)
73209467b48Spatrick return Fail;
73309467b48Spatrick
734*d415bd75Srobert unsigned Register =
735*d415bd75Srobert AArch64MCRegisterClasses[AArch64::PPRRegClassID].getRegister(RegNo);
73609467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
73709467b48Spatrick return Success;
73809467b48Spatrick }
73909467b48Spatrick
DecodePPR_3bRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)74009467b48Spatrick static DecodeStatus DecodePPR_3bRegisterClass(MCInst &Inst, unsigned RegNo,
74109467b48Spatrick uint64_t Addr,
742*d415bd75Srobert const MCDisassembler *Decoder) {
74309467b48Spatrick if (RegNo > 7)
74409467b48Spatrick return Fail;
74509467b48Spatrick
74609467b48Spatrick // Just reuse the PPR decode table
74709467b48Spatrick return DecodePPRRegisterClass(Inst, RegNo, Addr, Decoder);
74809467b48Spatrick }
74909467b48Spatrick
750*d415bd75Srobert static DecodeStatus
DecodePPR_p8to15RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)751*d415bd75Srobert DecodePPR_p8to15RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
752*d415bd75Srobert const MCDisassembler *Decoder) {
753*d415bd75Srobert if (RegNo > 7)
75409467b48Spatrick return Fail;
75509467b48Spatrick
756*d415bd75Srobert // Just reuse the PPR decode table
757*d415bd75Srobert return DecodePPRRegisterClass(Inst, RegNo + 8, Addr, Decoder);
758*d415bd75Srobert }
759*d415bd75Srobert
DecodePPR2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)760*d415bd75Srobert static DecodeStatus DecodePPR2RegisterClass(MCInst &Inst, unsigned RegNo,
761*d415bd75Srobert uint64_t Address,
762*d415bd75Srobert const void *Decoder) {
763*d415bd75Srobert if (RegNo > 15)
764*d415bd75Srobert return Fail;
765*d415bd75Srobert
766*d415bd75Srobert unsigned Register =
767*d415bd75Srobert AArch64MCRegisterClasses[AArch64::PPR2RegClassID].getRegister(RegNo);
76809467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
76909467b48Spatrick return Success;
77009467b48Spatrick }
77109467b48Spatrick
DecodePPR2Mul2RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)772*d415bd75Srobert static DecodeStatus DecodePPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
773*d415bd75Srobert uint64_t Address,
774*d415bd75Srobert const void *Decoder) {
775*d415bd75Srobert if ((RegNo * 2) > 14)
776*d415bd75Srobert return Fail;
777*d415bd75Srobert unsigned Register =
778*d415bd75Srobert AArch64MCRegisterClasses[AArch64::PPR2RegClassID].getRegister(RegNo * 2);
779*d415bd75Srobert Inst.addOperand(MCOperand::createReg(Register));
780*d415bd75Srobert return Success;
781*d415bd75Srobert }
78209467b48Spatrick
DecodeQQRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)78309467b48Spatrick static DecodeStatus DecodeQQRegisterClass(MCInst &Inst, unsigned RegNo,
784*d415bd75Srobert uint64_t Addr,
785*d415bd75Srobert const MCDisassembler *Decoder) {
78609467b48Spatrick if (RegNo > 31)
78709467b48Spatrick return Fail;
788*d415bd75Srobert unsigned Register =
789*d415bd75Srobert AArch64MCRegisterClasses[AArch64::QQRegClassID].getRegister(RegNo);
79009467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
79109467b48Spatrick return Success;
79209467b48Spatrick }
79309467b48Spatrick
DecodeQQQRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)79409467b48Spatrick static DecodeStatus DecodeQQQRegisterClass(MCInst &Inst, unsigned RegNo,
795*d415bd75Srobert uint64_t Addr,
796*d415bd75Srobert const MCDisassembler *Decoder) {
79709467b48Spatrick if (RegNo > 31)
79809467b48Spatrick return Fail;
799*d415bd75Srobert unsigned Register =
800*d415bd75Srobert AArch64MCRegisterClasses[AArch64::QQQRegClassID].getRegister(RegNo);
80109467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
80209467b48Spatrick return Success;
80309467b48Spatrick }
80409467b48Spatrick
DecodeQQQQRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)80509467b48Spatrick static DecodeStatus DecodeQQQQRegisterClass(MCInst &Inst, unsigned RegNo,
80609467b48Spatrick uint64_t Addr,
807*d415bd75Srobert const MCDisassembler *Decoder) {
80809467b48Spatrick if (RegNo > 31)
80909467b48Spatrick return Fail;
810*d415bd75Srobert unsigned Register =
811*d415bd75Srobert AArch64MCRegisterClasses[AArch64::QQQQRegClassID].getRegister(RegNo);
81209467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
81309467b48Spatrick return Success;
81409467b48Spatrick }
81509467b48Spatrick
DecodeDDRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)81609467b48Spatrick static DecodeStatus DecodeDDRegisterClass(MCInst &Inst, unsigned RegNo,
817*d415bd75Srobert uint64_t Addr,
818*d415bd75Srobert const MCDisassembler *Decoder) {
81909467b48Spatrick if (RegNo > 31)
82009467b48Spatrick return Fail;
821*d415bd75Srobert unsigned Register =
822*d415bd75Srobert AArch64MCRegisterClasses[AArch64::DDRegClassID].getRegister(RegNo);
82309467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
82409467b48Spatrick return Success;
82509467b48Spatrick }
82609467b48Spatrick
DecodeDDDRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)82709467b48Spatrick static DecodeStatus DecodeDDDRegisterClass(MCInst &Inst, unsigned RegNo,
828*d415bd75Srobert uint64_t Addr,
829*d415bd75Srobert const MCDisassembler *Decoder) {
83009467b48Spatrick if (RegNo > 31)
83109467b48Spatrick return Fail;
832*d415bd75Srobert unsigned Register =
833*d415bd75Srobert AArch64MCRegisterClasses[AArch64::DDDRegClassID].getRegister(RegNo);
83409467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
83509467b48Spatrick return Success;
83609467b48Spatrick }
83709467b48Spatrick
DecodeDDDDRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)83809467b48Spatrick static DecodeStatus DecodeDDDDRegisterClass(MCInst &Inst, unsigned RegNo,
83909467b48Spatrick uint64_t Addr,
840*d415bd75Srobert const MCDisassembler *Decoder) {
84109467b48Spatrick if (RegNo > 31)
84209467b48Spatrick return Fail;
843*d415bd75Srobert unsigned Register =
844*d415bd75Srobert AArch64MCRegisterClasses[AArch64::DDDDRegClassID].getRegister(RegNo);
84509467b48Spatrick Inst.addOperand(MCOperand::createReg(Register));
84609467b48Spatrick return Success;
84709467b48Spatrick }
84809467b48Spatrick
DecodeFixedPointScaleImm32(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)84909467b48Spatrick static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm,
85009467b48Spatrick uint64_t Addr,
851*d415bd75Srobert const MCDisassembler *Decoder) {
85209467b48Spatrick // scale{5} is asserted as 1 in tblgen.
85309467b48Spatrick Imm |= 0x20;
85409467b48Spatrick Inst.addOperand(MCOperand::createImm(64 - Imm));
85509467b48Spatrick return Success;
85609467b48Spatrick }
85709467b48Spatrick
DecodeFixedPointScaleImm64(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)85809467b48Spatrick static DecodeStatus DecodeFixedPointScaleImm64(MCInst &Inst, unsigned Imm,
85909467b48Spatrick uint64_t Addr,
860*d415bd75Srobert const MCDisassembler *Decoder) {
86109467b48Spatrick Inst.addOperand(MCOperand::createImm(64 - Imm));
86209467b48Spatrick return Success;
86309467b48Spatrick }
86409467b48Spatrick
DecodePCRelLabel19(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)86509467b48Spatrick static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
866*d415bd75Srobert uint64_t Addr,
867*d415bd75Srobert const MCDisassembler *Decoder) {
86809467b48Spatrick int64_t ImmVal = Imm;
86909467b48Spatrick
87009467b48Spatrick // Sign-extend 19-bit immediate.
87109467b48Spatrick if (ImmVal & (1 << (19 - 1)))
87209467b48Spatrick ImmVal |= ~((1LL << 19) - 1);
87309467b48Spatrick
874*d415bd75Srobert if (!Decoder->tryAddingSymbolicOperand(
875*d415bd75Srobert Inst, ImmVal * 4, Addr, Inst.getOpcode() != AArch64::LDRXl, 0, 0, 4))
87609467b48Spatrick Inst.addOperand(MCOperand::createImm(ImmVal));
87709467b48Spatrick return Success;
87809467b48Spatrick }
87909467b48Spatrick
DecodeMemExtend(MCInst & Inst,unsigned Imm,uint64_t Address,const MCDisassembler * Decoder)88009467b48Spatrick static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
881*d415bd75Srobert uint64_t Address,
882*d415bd75Srobert const MCDisassembler *Decoder) {
88309467b48Spatrick Inst.addOperand(MCOperand::createImm((Imm >> 1) & 1));
88409467b48Spatrick Inst.addOperand(MCOperand::createImm(Imm & 1));
88509467b48Spatrick return Success;
88609467b48Spatrick }
88709467b48Spatrick
DecodeMRSSystemRegister(MCInst & Inst,unsigned Imm,uint64_t Address,const MCDisassembler * Decoder)88809467b48Spatrick static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm,
88909467b48Spatrick uint64_t Address,
890*d415bd75Srobert const MCDisassembler *Decoder) {
89109467b48Spatrick Inst.addOperand(MCOperand::createImm(Imm));
89209467b48Spatrick
89309467b48Spatrick // Every system register in the encoding space is valid with the syntax
89409467b48Spatrick // S<op0>_<op1>_<Cn>_<Cm>_<op2>, so decoding system registers always succeeds.
89509467b48Spatrick return Success;
89609467b48Spatrick }
89709467b48Spatrick
DecodeMSRSystemRegister(MCInst & Inst,unsigned Imm,uint64_t Address,const MCDisassembler * Decoder)89809467b48Spatrick static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm,
89909467b48Spatrick uint64_t Address,
900*d415bd75Srobert const MCDisassembler *Decoder) {
90109467b48Spatrick Inst.addOperand(MCOperand::createImm(Imm));
90209467b48Spatrick
90309467b48Spatrick return Success;
90409467b48Spatrick }
90509467b48Spatrick
DecodeFMOVLaneInstruction(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)90609467b48Spatrick static DecodeStatus DecodeFMOVLaneInstruction(MCInst &Inst, unsigned Insn,
90709467b48Spatrick uint64_t Address,
908*d415bd75Srobert const MCDisassembler *Decoder) {
90909467b48Spatrick // This decoder exists to add the dummy Lane operand to the MCInst, which must
91009467b48Spatrick // be 1 in assembly but has no other real manifestation.
91109467b48Spatrick unsigned Rd = fieldFromInstruction(Insn, 0, 5);
91209467b48Spatrick unsigned Rn = fieldFromInstruction(Insn, 5, 5);
91309467b48Spatrick unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
91409467b48Spatrick
91509467b48Spatrick if (IsToVec) {
91609467b48Spatrick DecodeFPR128RegisterClass(Inst, Rd, Address, Decoder);
91709467b48Spatrick DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
91809467b48Spatrick } else {
91909467b48Spatrick DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
92009467b48Spatrick DecodeFPR128RegisterClass(Inst, Rn, Address, Decoder);
92109467b48Spatrick }
92209467b48Spatrick
92309467b48Spatrick // Add the lane
92409467b48Spatrick Inst.addOperand(MCOperand::createImm(1));
92509467b48Spatrick
92609467b48Spatrick return Success;
92709467b48Spatrick }
92809467b48Spatrick
DecodeVecShiftRImm(MCInst & Inst,unsigned Imm,unsigned Add)92909467b48Spatrick static DecodeStatus DecodeVecShiftRImm(MCInst &Inst, unsigned Imm,
93009467b48Spatrick unsigned Add) {
93109467b48Spatrick Inst.addOperand(MCOperand::createImm(Add - Imm));
93209467b48Spatrick return Success;
93309467b48Spatrick }
93409467b48Spatrick
DecodeVecShiftLImm(MCInst & Inst,unsigned Imm,unsigned Add)93509467b48Spatrick static DecodeStatus DecodeVecShiftLImm(MCInst &Inst, unsigned Imm,
93609467b48Spatrick unsigned Add) {
93709467b48Spatrick Inst.addOperand(MCOperand::createImm((Imm + Add) & (Add - 1)));
93809467b48Spatrick return Success;
93909467b48Spatrick }
94009467b48Spatrick
DecodeVecShiftR64Imm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)94109467b48Spatrick static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm,
942*d415bd75Srobert uint64_t Addr,
943*d415bd75Srobert const MCDisassembler *Decoder) {
94409467b48Spatrick return DecodeVecShiftRImm(Inst, Imm, 64);
94509467b48Spatrick }
94609467b48Spatrick
DecodeVecShiftR64ImmNarrow(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)94709467b48Spatrick static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst &Inst, unsigned Imm,
94809467b48Spatrick uint64_t Addr,
949*d415bd75Srobert const MCDisassembler *Decoder) {
95009467b48Spatrick return DecodeVecShiftRImm(Inst, Imm | 0x20, 64);
95109467b48Spatrick }
95209467b48Spatrick
DecodeVecShiftR32Imm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)95309467b48Spatrick static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm,
954*d415bd75Srobert uint64_t Addr,
955*d415bd75Srobert const MCDisassembler *Decoder) {
95609467b48Spatrick return DecodeVecShiftRImm(Inst, Imm, 32);
95709467b48Spatrick }
95809467b48Spatrick
DecodeVecShiftR32ImmNarrow(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)95909467b48Spatrick static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst &Inst, unsigned Imm,
96009467b48Spatrick uint64_t Addr,
961*d415bd75Srobert const MCDisassembler *Decoder) {
96209467b48Spatrick return DecodeVecShiftRImm(Inst, Imm | 0x10, 32);
96309467b48Spatrick }
96409467b48Spatrick
DecodeVecShiftR16Imm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)96509467b48Spatrick static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm,
966*d415bd75Srobert uint64_t Addr,
967*d415bd75Srobert const MCDisassembler *Decoder) {
96809467b48Spatrick return DecodeVecShiftRImm(Inst, Imm, 16);
96909467b48Spatrick }
97009467b48Spatrick
DecodeVecShiftR16ImmNarrow(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)97109467b48Spatrick static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst &Inst, unsigned Imm,
97209467b48Spatrick uint64_t Addr,
973*d415bd75Srobert const MCDisassembler *Decoder) {
97409467b48Spatrick return DecodeVecShiftRImm(Inst, Imm | 0x8, 16);
97509467b48Spatrick }
97609467b48Spatrick
DecodeVecShiftR8Imm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)97709467b48Spatrick static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm,
978*d415bd75Srobert uint64_t Addr,
979*d415bd75Srobert const MCDisassembler *Decoder) {
98009467b48Spatrick return DecodeVecShiftRImm(Inst, Imm, 8);
98109467b48Spatrick }
98209467b48Spatrick
DecodeVecShiftL64Imm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)98309467b48Spatrick static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm,
984*d415bd75Srobert uint64_t Addr,
985*d415bd75Srobert const MCDisassembler *Decoder) {
98609467b48Spatrick return DecodeVecShiftLImm(Inst, Imm, 64);
98709467b48Spatrick }
98809467b48Spatrick
DecodeVecShiftL32Imm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)98909467b48Spatrick static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm,
990*d415bd75Srobert uint64_t Addr,
991*d415bd75Srobert const MCDisassembler *Decoder) {
99209467b48Spatrick return DecodeVecShiftLImm(Inst, Imm, 32);
99309467b48Spatrick }
99409467b48Spatrick
DecodeVecShiftL16Imm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)99509467b48Spatrick static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm,
996*d415bd75Srobert uint64_t Addr,
997*d415bd75Srobert const MCDisassembler *Decoder) {
99809467b48Spatrick return DecodeVecShiftLImm(Inst, Imm, 16);
99909467b48Spatrick }
100009467b48Spatrick
DecodeVecShiftL8Imm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)100109467b48Spatrick static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm,
1002*d415bd75Srobert uint64_t Addr,
1003*d415bd75Srobert const MCDisassembler *Decoder) {
100409467b48Spatrick return DecodeVecShiftLImm(Inst, Imm, 8);
100509467b48Spatrick }
100609467b48Spatrick
1007*d415bd75Srobert static DecodeStatus
DecodeThreeAddrSRegInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)1008*d415bd75Srobert DecodeThreeAddrSRegInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
1009*d415bd75Srobert const MCDisassembler *Decoder) {
101009467b48Spatrick unsigned Rd = fieldFromInstruction(insn, 0, 5);
101109467b48Spatrick unsigned Rn = fieldFromInstruction(insn, 5, 5);
101209467b48Spatrick unsigned Rm = fieldFromInstruction(insn, 16, 5);
101309467b48Spatrick unsigned shiftHi = fieldFromInstruction(insn, 22, 2);
101409467b48Spatrick unsigned shiftLo = fieldFromInstruction(insn, 10, 6);
101509467b48Spatrick unsigned shift = (shiftHi << 6) | shiftLo;
101609467b48Spatrick switch (Inst.getOpcode()) {
101709467b48Spatrick default:
101809467b48Spatrick return Fail;
101909467b48Spatrick case AArch64::ADDWrs:
102009467b48Spatrick case AArch64::ADDSWrs:
102109467b48Spatrick case AArch64::SUBWrs:
102209467b48Spatrick case AArch64::SUBSWrs:
102309467b48Spatrick // if shift == '11' then ReservedValue()
102409467b48Spatrick if (shiftHi == 0x3)
102509467b48Spatrick return Fail;
1026*d415bd75Srobert [[fallthrough]];
102709467b48Spatrick case AArch64::ANDWrs:
102809467b48Spatrick case AArch64::ANDSWrs:
102909467b48Spatrick case AArch64::BICWrs:
103009467b48Spatrick case AArch64::BICSWrs:
103109467b48Spatrick case AArch64::ORRWrs:
103209467b48Spatrick case AArch64::ORNWrs:
103309467b48Spatrick case AArch64::EORWrs:
103409467b48Spatrick case AArch64::EONWrs: {
103509467b48Spatrick // if sf == '0' and imm6<5> == '1' then ReservedValue()
103609467b48Spatrick if (shiftLo >> 5 == 1)
103709467b48Spatrick return Fail;
103809467b48Spatrick DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
103909467b48Spatrick DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder);
104009467b48Spatrick DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
104109467b48Spatrick break;
104209467b48Spatrick }
104309467b48Spatrick case AArch64::ADDXrs:
104409467b48Spatrick case AArch64::ADDSXrs:
104509467b48Spatrick case AArch64::SUBXrs:
104609467b48Spatrick case AArch64::SUBSXrs:
104709467b48Spatrick // if shift == '11' then ReservedValue()
104809467b48Spatrick if (shiftHi == 0x3)
104909467b48Spatrick return Fail;
1050*d415bd75Srobert [[fallthrough]];
105109467b48Spatrick case AArch64::ANDXrs:
105209467b48Spatrick case AArch64::ANDSXrs:
105309467b48Spatrick case AArch64::BICXrs:
105409467b48Spatrick case AArch64::BICSXrs:
105509467b48Spatrick case AArch64::ORRXrs:
105609467b48Spatrick case AArch64::ORNXrs:
105709467b48Spatrick case AArch64::EORXrs:
105809467b48Spatrick case AArch64::EONXrs:
105909467b48Spatrick DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
106009467b48Spatrick DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder);
106109467b48Spatrick DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
106209467b48Spatrick break;
106309467b48Spatrick }
106409467b48Spatrick
106509467b48Spatrick Inst.addOperand(MCOperand::createImm(shift));
106609467b48Spatrick return Success;
106709467b48Spatrick }
106809467b48Spatrick
DecodeMoveImmInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)106909467b48Spatrick static DecodeStatus DecodeMoveImmInstruction(MCInst &Inst, uint32_t insn,
107009467b48Spatrick uint64_t Addr,
1071*d415bd75Srobert const MCDisassembler *Decoder) {
107209467b48Spatrick unsigned Rd = fieldFromInstruction(insn, 0, 5);
107309467b48Spatrick unsigned imm = fieldFromInstruction(insn, 5, 16);
107409467b48Spatrick unsigned shift = fieldFromInstruction(insn, 21, 2);
107509467b48Spatrick shift <<= 4;
107609467b48Spatrick switch (Inst.getOpcode()) {
107709467b48Spatrick default:
107809467b48Spatrick return Fail;
107909467b48Spatrick case AArch64::MOVZWi:
108009467b48Spatrick case AArch64::MOVNWi:
108109467b48Spatrick case AArch64::MOVKWi:
108209467b48Spatrick if (shift & (1U << 5))
108309467b48Spatrick return Fail;
108409467b48Spatrick DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
108509467b48Spatrick break;
108609467b48Spatrick case AArch64::MOVZXi:
108709467b48Spatrick case AArch64::MOVNXi:
108809467b48Spatrick case AArch64::MOVKXi:
108909467b48Spatrick DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
109009467b48Spatrick break;
109109467b48Spatrick }
109209467b48Spatrick
109309467b48Spatrick if (Inst.getOpcode() == AArch64::MOVKWi ||
109409467b48Spatrick Inst.getOpcode() == AArch64::MOVKXi)
109509467b48Spatrick Inst.addOperand(Inst.getOperand(0));
109609467b48Spatrick
109709467b48Spatrick Inst.addOperand(MCOperand::createImm(imm));
109809467b48Spatrick Inst.addOperand(MCOperand::createImm(shift));
109909467b48Spatrick return Success;
110009467b48Spatrick }
110109467b48Spatrick
1102*d415bd75Srobert static DecodeStatus
DecodeUnsignedLdStInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)1103*d415bd75Srobert DecodeUnsignedLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
1104*d415bd75Srobert const MCDisassembler *Decoder) {
110509467b48Spatrick unsigned Rt = fieldFromInstruction(insn, 0, 5);
110609467b48Spatrick unsigned Rn = fieldFromInstruction(insn, 5, 5);
110709467b48Spatrick unsigned offset = fieldFromInstruction(insn, 10, 12);
110809467b48Spatrick
110909467b48Spatrick switch (Inst.getOpcode()) {
111009467b48Spatrick default:
111109467b48Spatrick return Fail;
111209467b48Spatrick case AArch64::PRFMui:
111309467b48Spatrick // Rt is an immediate in prefetch.
111409467b48Spatrick Inst.addOperand(MCOperand::createImm(Rt));
111509467b48Spatrick break;
111609467b48Spatrick case AArch64::STRBBui:
111709467b48Spatrick case AArch64::LDRBBui:
111809467b48Spatrick case AArch64::LDRSBWui:
111909467b48Spatrick case AArch64::STRHHui:
112009467b48Spatrick case AArch64::LDRHHui:
112109467b48Spatrick case AArch64::LDRSHWui:
112209467b48Spatrick case AArch64::STRWui:
112309467b48Spatrick case AArch64::LDRWui:
112409467b48Spatrick DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
112509467b48Spatrick break;
112609467b48Spatrick case AArch64::LDRSBXui:
112709467b48Spatrick case AArch64::LDRSHXui:
112809467b48Spatrick case AArch64::LDRSWui:
112909467b48Spatrick case AArch64::STRXui:
113009467b48Spatrick case AArch64::LDRXui:
113109467b48Spatrick DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
113209467b48Spatrick break;
113309467b48Spatrick case AArch64::LDRQui:
113409467b48Spatrick case AArch64::STRQui:
113509467b48Spatrick DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
113609467b48Spatrick break;
113709467b48Spatrick case AArch64::LDRDui:
113809467b48Spatrick case AArch64::STRDui:
113909467b48Spatrick DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
114009467b48Spatrick break;
114109467b48Spatrick case AArch64::LDRSui:
114209467b48Spatrick case AArch64::STRSui:
114309467b48Spatrick DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
114409467b48Spatrick break;
114509467b48Spatrick case AArch64::LDRHui:
114609467b48Spatrick case AArch64::STRHui:
114709467b48Spatrick DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
114809467b48Spatrick break;
114909467b48Spatrick case AArch64::LDRBui:
115009467b48Spatrick case AArch64::STRBui:
115109467b48Spatrick DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
115209467b48Spatrick break;
115309467b48Spatrick }
115409467b48Spatrick
115509467b48Spatrick DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1156*d415bd75Srobert if (!Decoder->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 0, 4))
115709467b48Spatrick Inst.addOperand(MCOperand::createImm(offset));
115809467b48Spatrick return Success;
115909467b48Spatrick }
116009467b48Spatrick
DecodeSignedLdStInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)116109467b48Spatrick static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
116209467b48Spatrick uint64_t Addr,
1163*d415bd75Srobert const MCDisassembler *Decoder) {
116409467b48Spatrick unsigned Rt = fieldFromInstruction(insn, 0, 5);
116509467b48Spatrick unsigned Rn = fieldFromInstruction(insn, 5, 5);
116609467b48Spatrick int64_t offset = fieldFromInstruction(insn, 12, 9);
116709467b48Spatrick
116809467b48Spatrick // offset is a 9-bit signed immediate, so sign extend it to
116909467b48Spatrick // fill the unsigned.
117009467b48Spatrick if (offset & (1 << (9 - 1)))
117109467b48Spatrick offset |= ~((1LL << 9) - 1);
117209467b48Spatrick
117309467b48Spatrick // First operand is always the writeback to the address register, if needed.
117409467b48Spatrick switch (Inst.getOpcode()) {
117509467b48Spatrick default:
117609467b48Spatrick break;
117709467b48Spatrick case AArch64::LDRSBWpre:
117809467b48Spatrick case AArch64::LDRSHWpre:
117909467b48Spatrick case AArch64::STRBBpre:
118009467b48Spatrick case AArch64::LDRBBpre:
118109467b48Spatrick case AArch64::STRHHpre:
118209467b48Spatrick case AArch64::LDRHHpre:
118309467b48Spatrick case AArch64::STRWpre:
118409467b48Spatrick case AArch64::LDRWpre:
118509467b48Spatrick case AArch64::LDRSBWpost:
118609467b48Spatrick case AArch64::LDRSHWpost:
118709467b48Spatrick case AArch64::STRBBpost:
118809467b48Spatrick case AArch64::LDRBBpost:
118909467b48Spatrick case AArch64::STRHHpost:
119009467b48Spatrick case AArch64::LDRHHpost:
119109467b48Spatrick case AArch64::STRWpost:
119209467b48Spatrick case AArch64::LDRWpost:
119309467b48Spatrick case AArch64::LDRSBXpre:
119409467b48Spatrick case AArch64::LDRSHXpre:
119509467b48Spatrick case AArch64::STRXpre:
119609467b48Spatrick case AArch64::LDRSWpre:
119709467b48Spatrick case AArch64::LDRXpre:
119809467b48Spatrick case AArch64::LDRSBXpost:
119909467b48Spatrick case AArch64::LDRSHXpost:
120009467b48Spatrick case AArch64::STRXpost:
120109467b48Spatrick case AArch64::LDRSWpost:
120209467b48Spatrick case AArch64::LDRXpost:
120309467b48Spatrick case AArch64::LDRQpre:
120409467b48Spatrick case AArch64::STRQpre:
120509467b48Spatrick case AArch64::LDRQpost:
120609467b48Spatrick case AArch64::STRQpost:
120709467b48Spatrick case AArch64::LDRDpre:
120809467b48Spatrick case AArch64::STRDpre:
120909467b48Spatrick case AArch64::LDRDpost:
121009467b48Spatrick case AArch64::STRDpost:
121109467b48Spatrick case AArch64::LDRSpre:
121209467b48Spatrick case AArch64::STRSpre:
121309467b48Spatrick case AArch64::LDRSpost:
121409467b48Spatrick case AArch64::STRSpost:
121509467b48Spatrick case AArch64::LDRHpre:
121609467b48Spatrick case AArch64::STRHpre:
121709467b48Spatrick case AArch64::LDRHpost:
121809467b48Spatrick case AArch64::STRHpost:
121909467b48Spatrick case AArch64::LDRBpre:
122009467b48Spatrick case AArch64::STRBpre:
122109467b48Spatrick case AArch64::LDRBpost:
122209467b48Spatrick case AArch64::STRBpost:
122309467b48Spatrick DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
122409467b48Spatrick break;
122509467b48Spatrick }
122609467b48Spatrick
122709467b48Spatrick switch (Inst.getOpcode()) {
122809467b48Spatrick default:
122909467b48Spatrick return Fail;
123009467b48Spatrick case AArch64::PRFUMi:
123109467b48Spatrick // Rt is an immediate in prefetch.
123209467b48Spatrick Inst.addOperand(MCOperand::createImm(Rt));
123309467b48Spatrick break;
123409467b48Spatrick case AArch64::STURBBi:
123509467b48Spatrick case AArch64::LDURBBi:
123609467b48Spatrick case AArch64::LDURSBWi:
123709467b48Spatrick case AArch64::STURHHi:
123809467b48Spatrick case AArch64::LDURHHi:
123909467b48Spatrick case AArch64::LDURSHWi:
124009467b48Spatrick case AArch64::STURWi:
124109467b48Spatrick case AArch64::LDURWi:
124209467b48Spatrick case AArch64::LDTRSBWi:
124309467b48Spatrick case AArch64::LDTRSHWi:
124409467b48Spatrick case AArch64::STTRWi:
124509467b48Spatrick case AArch64::LDTRWi:
124609467b48Spatrick case AArch64::STTRHi:
124709467b48Spatrick case AArch64::LDTRHi:
124809467b48Spatrick case AArch64::LDTRBi:
124909467b48Spatrick case AArch64::STTRBi:
125009467b48Spatrick case AArch64::LDRSBWpre:
125109467b48Spatrick case AArch64::LDRSHWpre:
125209467b48Spatrick case AArch64::STRBBpre:
125309467b48Spatrick case AArch64::LDRBBpre:
125409467b48Spatrick case AArch64::STRHHpre:
125509467b48Spatrick case AArch64::LDRHHpre:
125609467b48Spatrick case AArch64::STRWpre:
125709467b48Spatrick case AArch64::LDRWpre:
125809467b48Spatrick case AArch64::LDRSBWpost:
125909467b48Spatrick case AArch64::LDRSHWpost:
126009467b48Spatrick case AArch64::STRBBpost:
126109467b48Spatrick case AArch64::LDRBBpost:
126209467b48Spatrick case AArch64::STRHHpost:
126309467b48Spatrick case AArch64::LDRHHpost:
126409467b48Spatrick case AArch64::STRWpost:
126509467b48Spatrick case AArch64::LDRWpost:
126609467b48Spatrick case AArch64::STLURBi:
126709467b48Spatrick case AArch64::STLURHi:
126809467b48Spatrick case AArch64::STLURWi:
126909467b48Spatrick case AArch64::LDAPURBi:
127009467b48Spatrick case AArch64::LDAPURSBWi:
127109467b48Spatrick case AArch64::LDAPURHi:
127209467b48Spatrick case AArch64::LDAPURSHWi:
127309467b48Spatrick case AArch64::LDAPURi:
127409467b48Spatrick DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
127509467b48Spatrick break;
127609467b48Spatrick case AArch64::LDURSBXi:
127709467b48Spatrick case AArch64::LDURSHXi:
127809467b48Spatrick case AArch64::LDURSWi:
127909467b48Spatrick case AArch64::STURXi:
128009467b48Spatrick case AArch64::LDURXi:
128109467b48Spatrick case AArch64::LDTRSBXi:
128209467b48Spatrick case AArch64::LDTRSHXi:
128309467b48Spatrick case AArch64::LDTRSWi:
128409467b48Spatrick case AArch64::STTRXi:
128509467b48Spatrick case AArch64::LDTRXi:
128609467b48Spatrick case AArch64::LDRSBXpre:
128709467b48Spatrick case AArch64::LDRSHXpre:
128809467b48Spatrick case AArch64::STRXpre:
128909467b48Spatrick case AArch64::LDRSWpre:
129009467b48Spatrick case AArch64::LDRXpre:
129109467b48Spatrick case AArch64::LDRSBXpost:
129209467b48Spatrick case AArch64::LDRSHXpost:
129309467b48Spatrick case AArch64::STRXpost:
129409467b48Spatrick case AArch64::LDRSWpost:
129509467b48Spatrick case AArch64::LDRXpost:
129609467b48Spatrick case AArch64::LDAPURSWi:
129709467b48Spatrick case AArch64::LDAPURSHXi:
129809467b48Spatrick case AArch64::LDAPURSBXi:
129909467b48Spatrick case AArch64::STLURXi:
130009467b48Spatrick case AArch64::LDAPURXi:
130109467b48Spatrick DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
130209467b48Spatrick break;
130309467b48Spatrick case AArch64::LDURQi:
130409467b48Spatrick case AArch64::STURQi:
130509467b48Spatrick case AArch64::LDRQpre:
130609467b48Spatrick case AArch64::STRQpre:
130709467b48Spatrick case AArch64::LDRQpost:
130809467b48Spatrick case AArch64::STRQpost:
130909467b48Spatrick DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
131009467b48Spatrick break;
131109467b48Spatrick case AArch64::LDURDi:
131209467b48Spatrick case AArch64::STURDi:
131309467b48Spatrick case AArch64::LDRDpre:
131409467b48Spatrick case AArch64::STRDpre:
131509467b48Spatrick case AArch64::LDRDpost:
131609467b48Spatrick case AArch64::STRDpost:
131709467b48Spatrick DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
131809467b48Spatrick break;
131909467b48Spatrick case AArch64::LDURSi:
132009467b48Spatrick case AArch64::STURSi:
132109467b48Spatrick case AArch64::LDRSpre:
132209467b48Spatrick case AArch64::STRSpre:
132309467b48Spatrick case AArch64::LDRSpost:
132409467b48Spatrick case AArch64::STRSpost:
132509467b48Spatrick DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
132609467b48Spatrick break;
132709467b48Spatrick case AArch64::LDURHi:
132809467b48Spatrick case AArch64::STURHi:
132909467b48Spatrick case AArch64::LDRHpre:
133009467b48Spatrick case AArch64::STRHpre:
133109467b48Spatrick case AArch64::LDRHpost:
133209467b48Spatrick case AArch64::STRHpost:
133309467b48Spatrick DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
133409467b48Spatrick break;
133509467b48Spatrick case AArch64::LDURBi:
133609467b48Spatrick case AArch64::STURBi:
133709467b48Spatrick case AArch64::LDRBpre:
133809467b48Spatrick case AArch64::STRBpre:
133909467b48Spatrick case AArch64::LDRBpost:
134009467b48Spatrick case AArch64::STRBpost:
134109467b48Spatrick DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
134209467b48Spatrick break;
134309467b48Spatrick }
134409467b48Spatrick
134509467b48Spatrick DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
134609467b48Spatrick Inst.addOperand(MCOperand::createImm(offset));
134709467b48Spatrick
134809467b48Spatrick bool IsLoad = fieldFromInstruction(insn, 22, 1);
134909467b48Spatrick bool IsIndexed = fieldFromInstruction(insn, 10, 2) != 0;
135009467b48Spatrick bool IsFP = fieldFromInstruction(insn, 26, 1);
135109467b48Spatrick
135209467b48Spatrick // Cannot write back to a transfer register (but xzr != sp).
135309467b48Spatrick if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn)
135409467b48Spatrick return SoftFail;
135509467b48Spatrick
135609467b48Spatrick return Success;
135709467b48Spatrick }
135809467b48Spatrick
1359*d415bd75Srobert static DecodeStatus
DecodeExclusiveLdStInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)1360*d415bd75Srobert DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
1361*d415bd75Srobert const MCDisassembler *Decoder) {
136209467b48Spatrick unsigned Rt = fieldFromInstruction(insn, 0, 5);
136309467b48Spatrick unsigned Rn = fieldFromInstruction(insn, 5, 5);
136409467b48Spatrick unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
136509467b48Spatrick unsigned Rs = fieldFromInstruction(insn, 16, 5);
136609467b48Spatrick
136709467b48Spatrick unsigned Opcode = Inst.getOpcode();
136809467b48Spatrick switch (Opcode) {
136909467b48Spatrick default:
137009467b48Spatrick return Fail;
137109467b48Spatrick case AArch64::STLXRW:
137209467b48Spatrick case AArch64::STLXRB:
137309467b48Spatrick case AArch64::STLXRH:
137409467b48Spatrick case AArch64::STXRW:
137509467b48Spatrick case AArch64::STXRB:
137609467b48Spatrick case AArch64::STXRH:
137709467b48Spatrick DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
1378*d415bd75Srobert [[fallthrough]];
137909467b48Spatrick case AArch64::LDARW:
138009467b48Spatrick case AArch64::LDARB:
138109467b48Spatrick case AArch64::LDARH:
138209467b48Spatrick case AArch64::LDAXRW:
138309467b48Spatrick case AArch64::LDAXRB:
138409467b48Spatrick case AArch64::LDAXRH:
138509467b48Spatrick case AArch64::LDXRW:
138609467b48Spatrick case AArch64::LDXRB:
138709467b48Spatrick case AArch64::LDXRH:
138809467b48Spatrick case AArch64::STLRW:
138909467b48Spatrick case AArch64::STLRB:
139009467b48Spatrick case AArch64::STLRH:
139109467b48Spatrick case AArch64::STLLRW:
139209467b48Spatrick case AArch64::STLLRB:
139309467b48Spatrick case AArch64::STLLRH:
139409467b48Spatrick case AArch64::LDLARW:
139509467b48Spatrick case AArch64::LDLARB:
139609467b48Spatrick case AArch64::LDLARH:
139709467b48Spatrick DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
139809467b48Spatrick break;
139909467b48Spatrick case AArch64::STLXRX:
140009467b48Spatrick case AArch64::STXRX:
140109467b48Spatrick DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
1402*d415bd75Srobert [[fallthrough]];
140309467b48Spatrick case AArch64::LDARX:
140409467b48Spatrick case AArch64::LDAXRX:
140509467b48Spatrick case AArch64::LDXRX:
140609467b48Spatrick case AArch64::STLRX:
140709467b48Spatrick case AArch64::LDLARX:
140809467b48Spatrick case AArch64::STLLRX:
140909467b48Spatrick DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
141009467b48Spatrick break;
141109467b48Spatrick case AArch64::STLXPW:
141209467b48Spatrick case AArch64::STXPW:
141309467b48Spatrick DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
1414*d415bd75Srobert [[fallthrough]];
141509467b48Spatrick case AArch64::LDAXPW:
141609467b48Spatrick case AArch64::LDXPW:
141709467b48Spatrick DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
141809467b48Spatrick DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);
141909467b48Spatrick break;
142009467b48Spatrick case AArch64::STLXPX:
142109467b48Spatrick case AArch64::STXPX:
142209467b48Spatrick DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
1423*d415bd75Srobert [[fallthrough]];
142409467b48Spatrick case AArch64::LDAXPX:
142509467b48Spatrick case AArch64::LDXPX:
142609467b48Spatrick DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
142709467b48Spatrick DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);
142809467b48Spatrick break;
142909467b48Spatrick }
143009467b48Spatrick
143109467b48Spatrick DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
143209467b48Spatrick
143309467b48Spatrick // You shouldn't load to the same register twice in an instruction...
143409467b48Spatrick if ((Opcode == AArch64::LDAXPW || Opcode == AArch64::LDXPW ||
143509467b48Spatrick Opcode == AArch64::LDAXPX || Opcode == AArch64::LDXPX) &&
143609467b48Spatrick Rt == Rt2)
143709467b48Spatrick return SoftFail;
143809467b48Spatrick
143909467b48Spatrick return Success;
144009467b48Spatrick }
144109467b48Spatrick
DecodePairLdStInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)144209467b48Spatrick static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,
144309467b48Spatrick uint64_t Addr,
1444*d415bd75Srobert const MCDisassembler *Decoder) {
144509467b48Spatrick unsigned Rt = fieldFromInstruction(insn, 0, 5);
144609467b48Spatrick unsigned Rn = fieldFromInstruction(insn, 5, 5);
144709467b48Spatrick unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
144809467b48Spatrick int64_t offset = fieldFromInstruction(insn, 15, 7);
144909467b48Spatrick bool IsLoad = fieldFromInstruction(insn, 22, 1);
145009467b48Spatrick
145109467b48Spatrick // offset is a 7-bit signed immediate, so sign extend it to
145209467b48Spatrick // fill the unsigned.
145309467b48Spatrick if (offset & (1 << (7 - 1)))
145409467b48Spatrick offset |= ~((1LL << 7) - 1);
145509467b48Spatrick
145609467b48Spatrick unsigned Opcode = Inst.getOpcode();
145709467b48Spatrick bool NeedsDisjointWritebackTransfer = false;
145809467b48Spatrick
145909467b48Spatrick // First operand is always writeback of base register.
146009467b48Spatrick switch (Opcode) {
146109467b48Spatrick default:
146209467b48Spatrick break;
146309467b48Spatrick case AArch64::LDPXpost:
146409467b48Spatrick case AArch64::STPXpost:
146509467b48Spatrick case AArch64::LDPSWpost:
146609467b48Spatrick case AArch64::LDPXpre:
146709467b48Spatrick case AArch64::STPXpre:
146809467b48Spatrick case AArch64::LDPSWpre:
146909467b48Spatrick case AArch64::LDPWpost:
147009467b48Spatrick case AArch64::STPWpost:
147109467b48Spatrick case AArch64::LDPWpre:
147209467b48Spatrick case AArch64::STPWpre:
147309467b48Spatrick case AArch64::LDPQpost:
147409467b48Spatrick case AArch64::STPQpost:
147509467b48Spatrick case AArch64::LDPQpre:
147609467b48Spatrick case AArch64::STPQpre:
147709467b48Spatrick case AArch64::LDPDpost:
147809467b48Spatrick case AArch64::STPDpost:
147909467b48Spatrick case AArch64::LDPDpre:
148009467b48Spatrick case AArch64::STPDpre:
148109467b48Spatrick case AArch64::LDPSpost:
148209467b48Spatrick case AArch64::STPSpost:
148309467b48Spatrick case AArch64::LDPSpre:
148409467b48Spatrick case AArch64::STPSpre:
148509467b48Spatrick case AArch64::STGPpre:
148609467b48Spatrick case AArch64::STGPpost:
148709467b48Spatrick DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
148809467b48Spatrick break;
148909467b48Spatrick }
149009467b48Spatrick
149109467b48Spatrick switch (Opcode) {
149209467b48Spatrick default:
149309467b48Spatrick return Fail;
149409467b48Spatrick case AArch64::LDPXpost:
149509467b48Spatrick case AArch64::STPXpost:
149609467b48Spatrick case AArch64::LDPSWpost:
149709467b48Spatrick case AArch64::LDPXpre:
149809467b48Spatrick case AArch64::STPXpre:
149909467b48Spatrick case AArch64::LDPSWpre:
150009467b48Spatrick case AArch64::STGPpre:
150109467b48Spatrick case AArch64::STGPpost:
150209467b48Spatrick NeedsDisjointWritebackTransfer = true;
1503*d415bd75Srobert [[fallthrough]];
150409467b48Spatrick case AArch64::LDNPXi:
150509467b48Spatrick case AArch64::STNPXi:
150609467b48Spatrick case AArch64::LDPXi:
150709467b48Spatrick case AArch64::STPXi:
150809467b48Spatrick case AArch64::LDPSWi:
150909467b48Spatrick case AArch64::STGPi:
151009467b48Spatrick DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
151109467b48Spatrick DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);
151209467b48Spatrick break;
151309467b48Spatrick case AArch64::LDPWpost:
151409467b48Spatrick case AArch64::STPWpost:
151509467b48Spatrick case AArch64::LDPWpre:
151609467b48Spatrick case AArch64::STPWpre:
151709467b48Spatrick NeedsDisjointWritebackTransfer = true;
1518*d415bd75Srobert [[fallthrough]];
151909467b48Spatrick case AArch64::LDNPWi:
152009467b48Spatrick case AArch64::STNPWi:
152109467b48Spatrick case AArch64::LDPWi:
152209467b48Spatrick case AArch64::STPWi:
152309467b48Spatrick DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
152409467b48Spatrick DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);
152509467b48Spatrick break;
152609467b48Spatrick case AArch64::LDNPQi:
152709467b48Spatrick case AArch64::STNPQi:
152809467b48Spatrick case AArch64::LDPQpost:
152909467b48Spatrick case AArch64::STPQpost:
153009467b48Spatrick case AArch64::LDPQi:
153109467b48Spatrick case AArch64::STPQi:
153209467b48Spatrick case AArch64::LDPQpre:
153309467b48Spatrick case AArch64::STPQpre:
153409467b48Spatrick DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
153509467b48Spatrick DecodeFPR128RegisterClass(Inst, Rt2, Addr, Decoder);
153609467b48Spatrick break;
153709467b48Spatrick case AArch64::LDNPDi:
153809467b48Spatrick case AArch64::STNPDi:
153909467b48Spatrick case AArch64::LDPDpost:
154009467b48Spatrick case AArch64::STPDpost:
154109467b48Spatrick case AArch64::LDPDi:
154209467b48Spatrick case AArch64::STPDi:
154309467b48Spatrick case AArch64::LDPDpre:
154409467b48Spatrick case AArch64::STPDpre:
154509467b48Spatrick DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
154609467b48Spatrick DecodeFPR64RegisterClass(Inst, Rt2, Addr, Decoder);
154709467b48Spatrick break;
154809467b48Spatrick case AArch64::LDNPSi:
154909467b48Spatrick case AArch64::STNPSi:
155009467b48Spatrick case AArch64::LDPSpost:
155109467b48Spatrick case AArch64::STPSpost:
155209467b48Spatrick case AArch64::LDPSi:
155309467b48Spatrick case AArch64::STPSi:
155409467b48Spatrick case AArch64::LDPSpre:
155509467b48Spatrick case AArch64::STPSpre:
155609467b48Spatrick DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
155709467b48Spatrick DecodeFPR32RegisterClass(Inst, Rt2, Addr, Decoder);
155809467b48Spatrick break;
155909467b48Spatrick }
156009467b48Spatrick
156109467b48Spatrick DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
156209467b48Spatrick Inst.addOperand(MCOperand::createImm(offset));
156309467b48Spatrick
156409467b48Spatrick // You shouldn't load to the same register twice in an instruction...
156509467b48Spatrick if (IsLoad && Rt == Rt2)
156609467b48Spatrick return SoftFail;
156709467b48Spatrick
156809467b48Spatrick // ... or do any operation that writes-back to a transfer register. But note
156909467b48Spatrick // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.
157009467b48Spatrick if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn))
157109467b48Spatrick return SoftFail;
157209467b48Spatrick
157309467b48Spatrick return Success;
157409467b48Spatrick }
157509467b48Spatrick
DecodeAuthLoadInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)1576097a140dSpatrick static DecodeStatus DecodeAuthLoadInstruction(MCInst &Inst, uint32_t insn,
1577097a140dSpatrick uint64_t Addr,
1578*d415bd75Srobert const MCDisassembler *Decoder) {
1579097a140dSpatrick unsigned Rt = fieldFromInstruction(insn, 0, 5);
1580097a140dSpatrick unsigned Rn = fieldFromInstruction(insn, 5, 5);
1581097a140dSpatrick uint64_t offset = fieldFromInstruction(insn, 22, 1) << 9 |
1582097a140dSpatrick fieldFromInstruction(insn, 12, 9);
1583097a140dSpatrick unsigned writeback = fieldFromInstruction(insn, 11, 1);
1584097a140dSpatrick
1585097a140dSpatrick switch (Inst.getOpcode()) {
1586097a140dSpatrick default:
1587097a140dSpatrick return Fail;
1588097a140dSpatrick case AArch64::LDRAAwriteback:
1589097a140dSpatrick case AArch64::LDRABwriteback:
1590097a140dSpatrick DecodeGPR64spRegisterClass(Inst, Rn /* writeback register */, Addr,
1591097a140dSpatrick Decoder);
1592097a140dSpatrick break;
1593097a140dSpatrick case AArch64::LDRAAindexed:
1594097a140dSpatrick case AArch64::LDRABindexed:
1595097a140dSpatrick break;
1596097a140dSpatrick }
1597097a140dSpatrick
1598097a140dSpatrick DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
1599097a140dSpatrick DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1600097a140dSpatrick DecodeSImm<10>(Inst, offset, Addr, Decoder);
1601097a140dSpatrick
1602097a140dSpatrick if (writeback && Rt == Rn && Rn != 31) {
1603097a140dSpatrick return SoftFail;
1604097a140dSpatrick }
1605097a140dSpatrick
1606097a140dSpatrick return Success;
1607097a140dSpatrick }
1608097a140dSpatrick
DecodeAddSubERegInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)160909467b48Spatrick static DecodeStatus DecodeAddSubERegInstruction(MCInst &Inst, uint32_t insn,
161009467b48Spatrick uint64_t Addr,
1611*d415bd75Srobert const MCDisassembler *Decoder) {
161209467b48Spatrick unsigned Rd = fieldFromInstruction(insn, 0, 5);
161309467b48Spatrick unsigned Rn = fieldFromInstruction(insn, 5, 5);
161409467b48Spatrick unsigned Rm = fieldFromInstruction(insn, 16, 5);
161509467b48Spatrick unsigned extend = fieldFromInstruction(insn, 10, 6);
161609467b48Spatrick
161709467b48Spatrick unsigned shift = extend & 0x7;
161809467b48Spatrick if (shift > 4)
161909467b48Spatrick return Fail;
162009467b48Spatrick
162109467b48Spatrick switch (Inst.getOpcode()) {
162209467b48Spatrick default:
162309467b48Spatrick return Fail;
162409467b48Spatrick case AArch64::ADDWrx:
162509467b48Spatrick case AArch64::SUBWrx:
162609467b48Spatrick DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
162709467b48Spatrick DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
162809467b48Spatrick DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
162909467b48Spatrick break;
163009467b48Spatrick case AArch64::ADDSWrx:
163109467b48Spatrick case AArch64::SUBSWrx:
163209467b48Spatrick DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
163309467b48Spatrick DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
163409467b48Spatrick DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
163509467b48Spatrick break;
163609467b48Spatrick case AArch64::ADDXrx:
163709467b48Spatrick case AArch64::SUBXrx:
163809467b48Spatrick DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
163909467b48Spatrick DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
164009467b48Spatrick DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
164109467b48Spatrick break;
164209467b48Spatrick case AArch64::ADDSXrx:
164309467b48Spatrick case AArch64::SUBSXrx:
164409467b48Spatrick DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
164509467b48Spatrick DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
164609467b48Spatrick DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
164709467b48Spatrick break;
164809467b48Spatrick case AArch64::ADDXrx64:
164909467b48Spatrick case AArch64::SUBXrx64:
165009467b48Spatrick DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
165109467b48Spatrick DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
165209467b48Spatrick DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
165309467b48Spatrick break;
165409467b48Spatrick case AArch64::SUBSXrx64:
165509467b48Spatrick case AArch64::ADDSXrx64:
165609467b48Spatrick DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
165709467b48Spatrick DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
165809467b48Spatrick DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
165909467b48Spatrick break;
166009467b48Spatrick }
166109467b48Spatrick
166209467b48Spatrick Inst.addOperand(MCOperand::createImm(extend));
166309467b48Spatrick return Success;
166409467b48Spatrick }
166509467b48Spatrick
DecodeLogicalImmInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)166609467b48Spatrick static DecodeStatus DecodeLogicalImmInstruction(MCInst &Inst, uint32_t insn,
166709467b48Spatrick uint64_t Addr,
1668*d415bd75Srobert const MCDisassembler *Decoder) {
166909467b48Spatrick unsigned Rd = fieldFromInstruction(insn, 0, 5);
167009467b48Spatrick unsigned Rn = fieldFromInstruction(insn, 5, 5);
167109467b48Spatrick unsigned Datasize = fieldFromInstruction(insn, 31, 1);
167209467b48Spatrick unsigned imm;
167309467b48Spatrick
167409467b48Spatrick if (Datasize) {
167509467b48Spatrick if (Inst.getOpcode() == AArch64::ANDSXri)
167609467b48Spatrick DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
167709467b48Spatrick else
167809467b48Spatrick DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
167909467b48Spatrick DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder);
168009467b48Spatrick imm = fieldFromInstruction(insn, 10, 13);
168109467b48Spatrick if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 64))
168209467b48Spatrick return Fail;
168309467b48Spatrick } else {
168409467b48Spatrick if (Inst.getOpcode() == AArch64::ANDSWri)
168509467b48Spatrick DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
168609467b48Spatrick else
168709467b48Spatrick DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
168809467b48Spatrick DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder);
168909467b48Spatrick imm = fieldFromInstruction(insn, 10, 12);
169009467b48Spatrick if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 32))
169109467b48Spatrick return Fail;
169209467b48Spatrick }
169309467b48Spatrick Inst.addOperand(MCOperand::createImm(imm));
169409467b48Spatrick return Success;
169509467b48Spatrick }
169609467b48Spatrick
DecodeModImmInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)169709467b48Spatrick static DecodeStatus DecodeModImmInstruction(MCInst &Inst, uint32_t insn,
169809467b48Spatrick uint64_t Addr,
1699*d415bd75Srobert const MCDisassembler *Decoder) {
170009467b48Spatrick unsigned Rd = fieldFromInstruction(insn, 0, 5);
170109467b48Spatrick unsigned cmode = fieldFromInstruction(insn, 12, 4);
170209467b48Spatrick unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
170309467b48Spatrick imm |= fieldFromInstruction(insn, 5, 5);
170409467b48Spatrick
170509467b48Spatrick if (Inst.getOpcode() == AArch64::MOVID)
170609467b48Spatrick DecodeFPR64RegisterClass(Inst, Rd, Addr, Decoder);
170709467b48Spatrick else
1708*d415bd75Srobert DecodeFPR128RegisterClass(Inst, Rd, Addr, Decoder);
170909467b48Spatrick
171009467b48Spatrick Inst.addOperand(MCOperand::createImm(imm));
171109467b48Spatrick
171209467b48Spatrick switch (Inst.getOpcode()) {
171309467b48Spatrick default:
171409467b48Spatrick break;
171509467b48Spatrick case AArch64::MOVIv4i16:
171609467b48Spatrick case AArch64::MOVIv8i16:
171709467b48Spatrick case AArch64::MVNIv4i16:
171809467b48Spatrick case AArch64::MVNIv8i16:
171909467b48Spatrick case AArch64::MOVIv2i32:
172009467b48Spatrick case AArch64::MOVIv4i32:
172109467b48Spatrick case AArch64::MVNIv2i32:
172209467b48Spatrick case AArch64::MVNIv4i32:
172309467b48Spatrick Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
172409467b48Spatrick break;
172509467b48Spatrick case AArch64::MOVIv2s_msl:
172609467b48Spatrick case AArch64::MOVIv4s_msl:
172709467b48Spatrick case AArch64::MVNIv2s_msl:
172809467b48Spatrick case AArch64::MVNIv4s_msl:
172909467b48Spatrick Inst.addOperand(MCOperand::createImm((cmode & 1) ? 0x110 : 0x108));
173009467b48Spatrick break;
173109467b48Spatrick }
173209467b48Spatrick
173309467b48Spatrick return Success;
173409467b48Spatrick }
173509467b48Spatrick
DecodeModImmTiedInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)173609467b48Spatrick static DecodeStatus DecodeModImmTiedInstruction(MCInst &Inst, uint32_t insn,
173709467b48Spatrick uint64_t Addr,
1738*d415bd75Srobert const MCDisassembler *Decoder) {
173909467b48Spatrick unsigned Rd = fieldFromInstruction(insn, 0, 5);
174009467b48Spatrick unsigned cmode = fieldFromInstruction(insn, 12, 4);
174109467b48Spatrick unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
174209467b48Spatrick imm |= fieldFromInstruction(insn, 5, 5);
174309467b48Spatrick
174409467b48Spatrick // Tied operands added twice.
1745*d415bd75Srobert DecodeFPR128RegisterClass(Inst, Rd, Addr, Decoder);
1746*d415bd75Srobert DecodeFPR128RegisterClass(Inst, Rd, Addr, Decoder);
174709467b48Spatrick
174809467b48Spatrick Inst.addOperand(MCOperand::createImm(imm));
174909467b48Spatrick Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
175009467b48Spatrick
175109467b48Spatrick return Success;
175209467b48Spatrick }
175309467b48Spatrick
DecodeAdrInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)175409467b48Spatrick static DecodeStatus DecodeAdrInstruction(MCInst &Inst, uint32_t insn,
1755*d415bd75Srobert uint64_t Addr,
1756*d415bd75Srobert const MCDisassembler *Decoder) {
175709467b48Spatrick unsigned Rd = fieldFromInstruction(insn, 0, 5);
175809467b48Spatrick int64_t imm = fieldFromInstruction(insn, 5, 19) << 2;
175909467b48Spatrick imm |= fieldFromInstruction(insn, 29, 2);
176009467b48Spatrick
176109467b48Spatrick // Sign-extend the 21-bit immediate.
176209467b48Spatrick if (imm & (1 << (21 - 1)))
176309467b48Spatrick imm |= ~((1LL << 21) - 1);
176409467b48Spatrick
176509467b48Spatrick DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
1766*d415bd75Srobert if (!Decoder->tryAddingSymbolicOperand(Inst, imm, Addr, Fail, 0, 0, 4))
176709467b48Spatrick Inst.addOperand(MCOperand::createImm(imm));
176809467b48Spatrick
176909467b48Spatrick return Success;
177009467b48Spatrick }
177109467b48Spatrick
DecodeAddSubImmShift(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)177209467b48Spatrick static DecodeStatus DecodeAddSubImmShift(MCInst &Inst, uint32_t insn,
1773*d415bd75Srobert uint64_t Addr,
1774*d415bd75Srobert const MCDisassembler *Decoder) {
177509467b48Spatrick unsigned Rd = fieldFromInstruction(insn, 0, 5);
177609467b48Spatrick unsigned Rn = fieldFromInstruction(insn, 5, 5);
177709467b48Spatrick unsigned Imm = fieldFromInstruction(insn, 10, 14);
177809467b48Spatrick unsigned S = fieldFromInstruction(insn, 29, 1);
177909467b48Spatrick unsigned Datasize = fieldFromInstruction(insn, 31, 1);
178009467b48Spatrick
178109467b48Spatrick unsigned ShifterVal = (Imm >> 12) & 3;
178209467b48Spatrick unsigned ImmVal = Imm & 0xFFF;
178309467b48Spatrick
178409467b48Spatrick if (ShifterVal != 0 && ShifterVal != 1)
178509467b48Spatrick return Fail;
178609467b48Spatrick
178709467b48Spatrick if (Datasize) {
178809467b48Spatrick if (Rd == 31 && !S)
178909467b48Spatrick DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
179009467b48Spatrick else
179109467b48Spatrick DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
179209467b48Spatrick DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
179309467b48Spatrick } else {
179409467b48Spatrick if (Rd == 31 && !S)
179509467b48Spatrick DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
179609467b48Spatrick else
179709467b48Spatrick DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
179809467b48Spatrick DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
179909467b48Spatrick }
180009467b48Spatrick
1801*d415bd75Srobert if (!Decoder->tryAddingSymbolicOperand(Inst, Imm, Addr, Fail, 0, 0, 4))
180209467b48Spatrick Inst.addOperand(MCOperand::createImm(ImmVal));
180309467b48Spatrick Inst.addOperand(MCOperand::createImm(12 * ShifterVal));
180409467b48Spatrick return Success;
180509467b48Spatrick }
180609467b48Spatrick
DecodeUnconditionalBranch(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)180709467b48Spatrick static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn,
180809467b48Spatrick uint64_t Addr,
1809*d415bd75Srobert const MCDisassembler *Decoder) {
181009467b48Spatrick int64_t imm = fieldFromInstruction(insn, 0, 26);
181109467b48Spatrick
181209467b48Spatrick // Sign-extend the 26-bit immediate.
181309467b48Spatrick if (imm & (1 << (26 - 1)))
181409467b48Spatrick imm |= ~((1LL << 26) - 1);
181509467b48Spatrick
1816*d415bd75Srobert if (!Decoder->tryAddingSymbolicOperand(Inst, imm * 4, Addr, true, 0, 0, 4))
181709467b48Spatrick Inst.addOperand(MCOperand::createImm(imm));
181809467b48Spatrick
181909467b48Spatrick return Success;
182009467b48Spatrick }
182109467b48Spatrick
isInvalidPState(uint64_t Op1,uint64_t Op2)1822*d415bd75Srobert static bool isInvalidPState(uint64_t Op1, uint64_t Op2) {
1823*d415bd75Srobert return Op1 == 0b000 && (Op2 == 0b000 || // CFINV
1824*d415bd75Srobert Op2 == 0b001 || // XAFlag
1825*d415bd75Srobert Op2 == 0b010); // AXFlag
182609467b48Spatrick }
182709467b48Spatrick
1828*d415bd75Srobert static DecodeStatus
DecodeSystemPStateImm0_15Instruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)1829*d415bd75Srobert DecodeSystemPStateImm0_15Instruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
1830*d415bd75Srobert const MCDisassembler *Decoder) {
1831*d415bd75Srobert uint64_t op1 = fieldFromInstruction(insn, 16, 3);
1832*d415bd75Srobert uint64_t op2 = fieldFromInstruction(insn, 5, 3);
1833*d415bd75Srobert uint64_t imm = fieldFromInstruction(insn, 8, 4);
1834*d415bd75Srobert uint64_t pstate_field = (op1 << 3) | op2;
1835*d415bd75Srobert
1836*d415bd75Srobert if (isInvalidPState(op1, op2))
183709467b48Spatrick return Fail;
183809467b48Spatrick
183909467b48Spatrick Inst.addOperand(MCOperand::createImm(pstate_field));
1840*d415bd75Srobert Inst.addOperand(MCOperand::createImm(imm));
184109467b48Spatrick
1842*d415bd75Srobert auto PState = AArch64PState::lookupPStateImm0_15ByEncoding(pstate_field);
1843*d415bd75Srobert if (PState &&
1844*d415bd75Srobert PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits()))
1845*d415bd75Srobert return Success;
1846*d415bd75Srobert return Fail;
1847*d415bd75Srobert }
1848*d415bd75Srobert
1849*d415bd75Srobert static DecodeStatus
DecodeSystemPStateImm0_1Instruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)1850*d415bd75Srobert DecodeSystemPStateImm0_1Instruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
1851*d415bd75Srobert const MCDisassembler *Decoder) {
1852*d415bd75Srobert uint64_t op1 = fieldFromInstruction(insn, 16, 3);
1853*d415bd75Srobert uint64_t op2 = fieldFromInstruction(insn, 5, 3);
1854*d415bd75Srobert uint64_t crm_high = fieldFromInstruction(insn, 9, 3);
1855*d415bd75Srobert uint64_t imm = fieldFromInstruction(insn, 8, 1);
1856*d415bd75Srobert uint64_t pstate_field = (crm_high << 6) | (op1 << 3) | op2;
1857*d415bd75Srobert
1858*d415bd75Srobert if (isInvalidPState(op1, op2))
1859*d415bd75Srobert return Fail;
1860*d415bd75Srobert
1861*d415bd75Srobert Inst.addOperand(MCOperand::createImm(pstate_field));
1862*d415bd75Srobert Inst.addOperand(MCOperand::createImm(imm));
1863*d415bd75Srobert
1864*d415bd75Srobert auto PState = AArch64PState::lookupPStateImm0_1ByEncoding(pstate_field);
1865*d415bd75Srobert if (PState &&
1866*d415bd75Srobert PState->haveFeatures(Decoder->getSubtargetInfo().getFeatureBits()))
186709467b48Spatrick return Success;
186809467b48Spatrick return Fail;
186909467b48Spatrick }
187009467b48Spatrick
DecodeTestAndBranch(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)187109467b48Spatrick static DecodeStatus DecodeTestAndBranch(MCInst &Inst, uint32_t insn,
1872*d415bd75Srobert uint64_t Addr,
1873*d415bd75Srobert const MCDisassembler *Decoder) {
187409467b48Spatrick uint64_t Rt = fieldFromInstruction(insn, 0, 5);
187509467b48Spatrick uint64_t bit = fieldFromInstruction(insn, 31, 1) << 5;
187609467b48Spatrick bit |= fieldFromInstruction(insn, 19, 5);
187709467b48Spatrick int64_t dst = fieldFromInstruction(insn, 5, 14);
187809467b48Spatrick
187909467b48Spatrick // Sign-extend 14-bit immediate.
188009467b48Spatrick if (dst & (1 << (14 - 1)))
188109467b48Spatrick dst |= ~((1LL << 14) - 1);
188209467b48Spatrick
188309467b48Spatrick if (fieldFromInstruction(insn, 31, 1) == 0)
188409467b48Spatrick DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
188509467b48Spatrick else
188609467b48Spatrick DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
188709467b48Spatrick Inst.addOperand(MCOperand::createImm(bit));
1888*d415bd75Srobert if (!Decoder->tryAddingSymbolicOperand(Inst, dst * 4, Addr, true, 0, 0, 4))
188909467b48Spatrick Inst.addOperand(MCOperand::createImm(dst));
189009467b48Spatrick
189109467b48Spatrick return Success;
189209467b48Spatrick }
189309467b48Spatrick
1894*d415bd75Srobert static DecodeStatus
DecodeGPRSeqPairsClassRegisterClass(MCInst & Inst,unsigned RegClassID,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)1895*d415bd75Srobert DecodeGPRSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegClassID,
1896*d415bd75Srobert unsigned RegNo, uint64_t Addr,
1897*d415bd75Srobert const MCDisassembler *Decoder) {
189809467b48Spatrick // Register number must be even (see CASP instruction)
189909467b48Spatrick if (RegNo & 0x1)
190009467b48Spatrick return Fail;
190109467b48Spatrick
190209467b48Spatrick unsigned Reg = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo / 2);
190309467b48Spatrick Inst.addOperand(MCOperand::createReg(Reg));
190409467b48Spatrick return Success;
190509467b48Spatrick }
190609467b48Spatrick
1907*d415bd75Srobert static DecodeStatus
DecodeWSeqPairsClassRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)1908*d415bd75Srobert DecodeWSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
1909*d415bd75Srobert const MCDisassembler *Decoder) {
191009467b48Spatrick return DecodeGPRSeqPairsClassRegisterClass(Inst,
191109467b48Spatrick AArch64::WSeqPairsClassRegClassID,
191209467b48Spatrick RegNo, Addr, Decoder);
191309467b48Spatrick }
191409467b48Spatrick
1915*d415bd75Srobert static DecodeStatus
DecodeXSeqPairsClassRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const MCDisassembler * Decoder)1916*d415bd75Srobert DecodeXSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
1917*d415bd75Srobert const MCDisassembler *Decoder) {
191809467b48Spatrick return DecodeGPRSeqPairsClassRegisterClass(Inst,
191909467b48Spatrick AArch64::XSeqPairsClassRegClassID,
192009467b48Spatrick RegNo, Addr, Decoder);
192109467b48Spatrick }
192209467b48Spatrick
DecodeSyspXzrInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)1923*d415bd75Srobert static DecodeStatus DecodeSyspXzrInstruction(MCInst &Inst, uint32_t insn,
192409467b48Spatrick uint64_t Addr,
1925*d415bd75Srobert const MCDisassembler *Decoder) {
1926*d415bd75Srobert unsigned op1 = fieldFromInstruction(insn, 16, 3);
1927*d415bd75Srobert unsigned CRn = fieldFromInstruction(insn, 12, 4);
1928*d415bd75Srobert unsigned CRm = fieldFromInstruction(insn, 8, 4);
1929*d415bd75Srobert unsigned op2 = fieldFromInstruction(insn, 5, 3);
1930*d415bd75Srobert unsigned Rt = fieldFromInstruction(insn, 0, 5);
1931*d415bd75Srobert if (Rt != 0b11111)
1932*d415bd75Srobert return Fail;
1933*d415bd75Srobert
1934*d415bd75Srobert Inst.addOperand(MCOperand::createImm(op1));
1935*d415bd75Srobert Inst.addOperand(MCOperand::createImm(CRn));
1936*d415bd75Srobert Inst.addOperand(MCOperand::createImm(CRm));
1937*d415bd75Srobert Inst.addOperand(MCOperand::createImm(op2));
1938*d415bd75Srobert DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
1939*d415bd75Srobert
1940*d415bd75Srobert return Success;
1941*d415bd75Srobert }
1942*d415bd75Srobert
1943*d415bd75Srobert static DecodeStatus
DecodeSVELogicalImmInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)1944*d415bd75Srobert DecodeSVELogicalImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
1945*d415bd75Srobert const MCDisassembler *Decoder) {
194609467b48Spatrick unsigned Zdn = fieldFromInstruction(insn, 0, 5);
194709467b48Spatrick unsigned imm = fieldFromInstruction(insn, 5, 13);
194809467b48Spatrick if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 64))
194909467b48Spatrick return Fail;
195009467b48Spatrick
195109467b48Spatrick // The same (tied) operand is added twice to the instruction.
195209467b48Spatrick DecodeZPRRegisterClass(Inst, Zdn, Addr, Decoder);
195309467b48Spatrick if (Inst.getOpcode() != AArch64::DUPM_ZI)
195409467b48Spatrick DecodeZPRRegisterClass(Inst, Zdn, Addr, Decoder);
195509467b48Spatrick Inst.addOperand(MCOperand::createImm(imm));
195609467b48Spatrick return Success;
195709467b48Spatrick }
195809467b48Spatrick
195909467b48Spatrick template <int Bits>
DecodeSImm(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)1960*d415bd75Srobert static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
1961*d415bd75Srobert const MCDisassembler *Decoder) {
196209467b48Spatrick if (Imm & ~((1LL << Bits) - 1))
196309467b48Spatrick return Fail;
196409467b48Spatrick
196509467b48Spatrick // Imm is a signed immediate, so sign extend it.
196609467b48Spatrick if (Imm & (1 << (Bits - 1)))
196709467b48Spatrick Imm |= ~((1LL << Bits) - 1);
196809467b48Spatrick
196909467b48Spatrick Inst.addOperand(MCOperand::createImm(Imm));
197009467b48Spatrick return Success;
197109467b48Spatrick }
197209467b48Spatrick
197309467b48Spatrick // Decode 8-bit signed/unsigned immediate for a given element width.
197409467b48Spatrick template <int ElementWidth>
DecodeImm8OptLsl(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)1975*d415bd75Srobert static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm, uint64_t Addr,
1976*d415bd75Srobert const MCDisassembler *Decoder) {
197709467b48Spatrick unsigned Val = (uint8_t)Imm;
197809467b48Spatrick unsigned Shift = (Imm & 0x100) ? 8 : 0;
197909467b48Spatrick if (ElementWidth == 8 && Shift)
198009467b48Spatrick return Fail;
198109467b48Spatrick Inst.addOperand(MCOperand::createImm(Val));
198209467b48Spatrick Inst.addOperand(MCOperand::createImm(Shift));
198309467b48Spatrick return Success;
198409467b48Spatrick }
198509467b48Spatrick
198609467b48Spatrick // Decode uimm4 ranged from 1-16.
DecodeSVEIncDecImm(MCInst & Inst,unsigned Imm,uint64_t Addr,const MCDisassembler * Decoder)198709467b48Spatrick static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,
1988*d415bd75Srobert uint64_t Addr,
1989*d415bd75Srobert const MCDisassembler *Decoder) {
199009467b48Spatrick Inst.addOperand(MCOperand::createImm(Imm + 1));
199109467b48Spatrick return Success;
199209467b48Spatrick }
199373471bf0Spatrick
DecodeSVCROp(MCInst & Inst,unsigned Imm,uint64_t Address,const MCDisassembler * Decoder)199473471bf0Spatrick static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,
1995*d415bd75Srobert const MCDisassembler *Decoder) {
199673471bf0Spatrick if (AArch64SVCR::lookupSVCRByEncoding(Imm)) {
199773471bf0Spatrick Inst.addOperand(MCOperand::createImm(Imm));
199873471bf0Spatrick return Success;
199973471bf0Spatrick }
200073471bf0Spatrick return Fail;
200173471bf0Spatrick }
2002*d415bd75Srobert
DecodeCPYMemOpInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)2003*d415bd75Srobert static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn,
2004*d415bd75Srobert uint64_t Addr,
2005*d415bd75Srobert const MCDisassembler *Decoder) {
2006*d415bd75Srobert unsigned Rd = fieldFromInstruction(insn, 0, 5);
2007*d415bd75Srobert unsigned Rs = fieldFromInstruction(insn, 16, 5);
2008*d415bd75Srobert unsigned Rn = fieldFromInstruction(insn, 5, 5);
2009*d415bd75Srobert
2010*d415bd75Srobert // None of the registers may alias: if they do, then the instruction is not
2011*d415bd75Srobert // merely unpredictable but actually entirely unallocated.
2012*d415bd75Srobert if (Rd == Rs || Rs == Rn || Rd == Rn)
2013*d415bd75Srobert return MCDisassembler::Fail;
2014*d415bd75Srobert
2015*d415bd75Srobert // All three register operands are written back, so they all appear
2016*d415bd75Srobert // twice in the operand list, once as outputs and once as inputs.
2017*d415bd75Srobert if (!DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) ||
2018*d415bd75Srobert !DecodeGPR64commonRegisterClass(Inst, Rs, Addr, Decoder) ||
2019*d415bd75Srobert !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) ||
2020*d415bd75Srobert !DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) ||
2021*d415bd75Srobert !DecodeGPR64commonRegisterClass(Inst, Rs, Addr, Decoder) ||
2022*d415bd75Srobert !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder))
2023*d415bd75Srobert return MCDisassembler::Fail;
2024*d415bd75Srobert
2025*d415bd75Srobert return MCDisassembler::Success;
2026*d415bd75Srobert }
2027*d415bd75Srobert
DecodeSETMemOpInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)2028*d415bd75Srobert static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn,
2029*d415bd75Srobert uint64_t Addr,
2030*d415bd75Srobert const MCDisassembler *Decoder) {
2031*d415bd75Srobert unsigned Rd = fieldFromInstruction(insn, 0, 5);
2032*d415bd75Srobert unsigned Rm = fieldFromInstruction(insn, 16, 5);
2033*d415bd75Srobert unsigned Rn = fieldFromInstruction(insn, 5, 5);
2034*d415bd75Srobert
2035*d415bd75Srobert // None of the registers may alias: if they do, then the instruction is not
2036*d415bd75Srobert // merely unpredictable but actually entirely unallocated.
2037*d415bd75Srobert if (Rd == Rm || Rm == Rn || Rd == Rn)
2038*d415bd75Srobert return MCDisassembler::Fail;
2039*d415bd75Srobert
2040*d415bd75Srobert // Rd and Rn (not Rm) register operands are written back, so they appear
2041*d415bd75Srobert // twice in the operand list, once as outputs and once as inputs.
2042*d415bd75Srobert if (!DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) ||
2043*d415bd75Srobert !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) ||
2044*d415bd75Srobert !DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) ||
2045*d415bd75Srobert !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) ||
2046*d415bd75Srobert !DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder))
2047*d415bd75Srobert return MCDisassembler::Fail;
2048*d415bd75Srobert
2049*d415bd75Srobert return MCDisassembler::Success;
2050*d415bd75Srobert }
2051*d415bd75Srobert
DecodePRFMRegInstruction(MCInst & Inst,uint32_t insn,uint64_t Addr,const MCDisassembler * Decoder)2052*d415bd75Srobert static DecodeStatus DecodePRFMRegInstruction(MCInst &Inst, uint32_t insn,
2053*d415bd75Srobert uint64_t Addr,
2054*d415bd75Srobert const MCDisassembler *Decoder) {
2055*d415bd75Srobert // PRFM with Rt = '11xxx' should be decoded as RPRFM.
2056*d415bd75Srobert // Fail to decode and defer to fallback decoder table to decode RPRFM.
2057*d415bd75Srobert unsigned Mask = 0x18;
2058*d415bd75Srobert uint64_t Rt = fieldFromInstruction(insn, 0, 5);
2059*d415bd75Srobert if ((Rt & Mask) == Mask)
2060*d415bd75Srobert return Fail;
2061*d415bd75Srobert
2062*d415bd75Srobert uint64_t Rn = fieldFromInstruction(insn, 5, 5);
2063*d415bd75Srobert uint64_t Shift = fieldFromInstruction(insn, 12, 1);
2064*d415bd75Srobert uint64_t Extend = fieldFromInstruction(insn, 15, 1);
2065*d415bd75Srobert uint64_t Rm = fieldFromInstruction(insn, 16, 5);
2066*d415bd75Srobert
2067*d415bd75Srobert Inst.addOperand(MCOperand::createImm(Rt));
2068*d415bd75Srobert DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
2069*d415bd75Srobert
2070*d415bd75Srobert switch (Inst.getOpcode()) {
2071*d415bd75Srobert default:
2072*d415bd75Srobert return Fail;
2073*d415bd75Srobert case AArch64::PRFMroW:
2074*d415bd75Srobert DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
2075*d415bd75Srobert break;
2076*d415bd75Srobert case AArch64::PRFMroX:
2077*d415bd75Srobert DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
2078*d415bd75Srobert break;
2079*d415bd75Srobert }
2080*d415bd75Srobert
2081*d415bd75Srobert DecodeMemExtend(Inst, (Extend << 1) | Shift, Addr, Decoder);
2082*d415bd75Srobert
2083*d415bd75Srobert return Success;
2084*d415bd75Srobert }
2085