1*9880d681SAndroid Build Coastguard Worker //===- AArch64Disassembler.cpp - Disassembler for AArch64 -------*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker //
11*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
12*9880d681SAndroid Build Coastguard Worker
13*9880d681SAndroid Build Coastguard Worker #include "AArch64Disassembler.h"
14*9880d681SAndroid Build Coastguard Worker #include "AArch64ExternalSymbolizer.h"
15*9880d681SAndroid Build Coastguard Worker #include "AArch64Subtarget.h"
16*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/AArch64AddressingModes.h"
17*9880d681SAndroid Build Coastguard Worker #include "Utils/AArch64BaseInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCFixedLenDisassembler.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker using namespace llvm;
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "aarch64-disassembler"
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker // Pull DecodeStatus and its enum values into the global namespace.
29*9880d681SAndroid Build Coastguard Worker typedef llvm::MCDisassembler::DecodeStatus DecodeStatus;
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker // Forward declare these because the autogenerated code will reference them.
32*9880d681SAndroid Build Coastguard Worker // Definitions are further down.
33*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFPR128RegisterClass(llvm::MCInst &Inst,
34*9880d681SAndroid Build Coastguard Worker unsigned RegNo, uint64_t Address,
35*9880d681SAndroid Build Coastguard Worker const void *Decoder);
36*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFPR128_loRegisterClass(llvm::MCInst &Inst,
37*9880d681SAndroid Build Coastguard Worker unsigned RegNo,
38*9880d681SAndroid Build Coastguard Worker uint64_t Address,
39*9880d681SAndroid Build Coastguard Worker const void *Decoder);
40*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
41*9880d681SAndroid Build Coastguard Worker uint64_t Address,
42*9880d681SAndroid Build Coastguard Worker const void *Decoder);
43*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
44*9880d681SAndroid Build Coastguard Worker uint64_t Address,
45*9880d681SAndroid Build Coastguard Worker const void *Decoder);
46*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFPR16RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
47*9880d681SAndroid Build Coastguard Worker uint64_t Address,
48*9880d681SAndroid Build Coastguard Worker const void *Decoder);
49*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFPR8RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
50*9880d681SAndroid Build Coastguard Worker uint64_t Address,
51*9880d681SAndroid Build Coastguard Worker const void *Decoder);
52*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeGPR64RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
53*9880d681SAndroid Build Coastguard Worker uint64_t Address,
54*9880d681SAndroid Build Coastguard Worker const void *Decoder);
55*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeGPR64spRegisterClass(llvm::MCInst &Inst,
56*9880d681SAndroid Build Coastguard Worker unsigned RegNo, uint64_t Address,
57*9880d681SAndroid Build Coastguard Worker const void *Decoder);
58*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeGPR32RegisterClass(llvm::MCInst &Inst, unsigned RegNo,
59*9880d681SAndroid Build Coastguard Worker uint64_t Address,
60*9880d681SAndroid Build Coastguard Worker const void *Decoder);
61*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeGPR32spRegisterClass(llvm::MCInst &Inst,
62*9880d681SAndroid Build Coastguard Worker unsigned RegNo, uint64_t Address,
63*9880d681SAndroid Build Coastguard Worker const void *Decoder);
64*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeQQRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
65*9880d681SAndroid Build Coastguard Worker uint64_t Address,
66*9880d681SAndroid Build Coastguard Worker const void *Decoder);
67*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeQQQRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
68*9880d681SAndroid Build Coastguard Worker uint64_t Address,
69*9880d681SAndroid Build Coastguard Worker const void *Decoder);
70*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeQQQQRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
71*9880d681SAndroid Build Coastguard Worker uint64_t Address,
72*9880d681SAndroid Build Coastguard Worker const void *Decoder);
73*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeDDRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
74*9880d681SAndroid Build Coastguard Worker uint64_t Address,
75*9880d681SAndroid Build Coastguard Worker const void *Decoder);
76*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeDDDRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
77*9880d681SAndroid Build Coastguard Worker uint64_t Address,
78*9880d681SAndroid Build Coastguard Worker const void *Decoder);
79*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeDDDDRegisterClass(llvm::MCInst &Inst, unsigned RegNo,
80*9880d681SAndroid Build Coastguard Worker uint64_t Address,
81*9880d681SAndroid Build Coastguard Worker const void *Decoder);
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFixedPointScaleImm32(llvm::MCInst &Inst, unsigned Imm,
84*9880d681SAndroid Build Coastguard Worker uint64_t Address,
85*9880d681SAndroid Build Coastguard Worker const void *Decoder);
86*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFixedPointScaleImm64(llvm::MCInst &Inst, unsigned Imm,
87*9880d681SAndroid Build Coastguard Worker uint64_t Address,
88*9880d681SAndroid Build Coastguard Worker const void *Decoder);
89*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodePCRelLabel19(llvm::MCInst &Inst, unsigned Imm,
90*9880d681SAndroid Build Coastguard Worker uint64_t Address, const void *Decoder);
91*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeMemExtend(llvm::MCInst &Inst, unsigned Imm,
92*9880d681SAndroid Build Coastguard Worker uint64_t Address, const void *Decoder);
93*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeMRSSystemRegister(llvm::MCInst &Inst, unsigned Imm,
94*9880d681SAndroid Build Coastguard Worker uint64_t Address, const void *Decoder);
95*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeMSRSystemRegister(llvm::MCInst &Inst, unsigned Imm,
96*9880d681SAndroid Build Coastguard Worker uint64_t Address, const void *Decoder);
97*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeThreeAddrSRegInstruction(llvm::MCInst &Inst,
98*9880d681SAndroid Build Coastguard Worker uint32_t insn,
99*9880d681SAndroid Build Coastguard Worker uint64_t Address,
100*9880d681SAndroid Build Coastguard Worker const void *Decoder);
101*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeMoveImmInstruction(llvm::MCInst &Inst, uint32_t insn,
102*9880d681SAndroid Build Coastguard Worker uint64_t Address,
103*9880d681SAndroid Build Coastguard Worker const void *Decoder);
104*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeUnsignedLdStInstruction(llvm::MCInst &Inst,
105*9880d681SAndroid Build Coastguard Worker uint32_t insn,
106*9880d681SAndroid Build Coastguard Worker uint64_t Address,
107*9880d681SAndroid Build Coastguard Worker const void *Decoder);
108*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeSignedLdStInstruction(llvm::MCInst &Inst,
109*9880d681SAndroid Build Coastguard Worker uint32_t insn, uint64_t Address,
110*9880d681SAndroid Build Coastguard Worker const void *Decoder);
111*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeExclusiveLdStInstruction(llvm::MCInst &Inst,
112*9880d681SAndroid Build Coastguard Worker uint32_t insn,
113*9880d681SAndroid Build Coastguard Worker uint64_t Address,
114*9880d681SAndroid Build Coastguard Worker const void *Decoder);
115*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodePairLdStInstruction(llvm::MCInst &Inst, uint32_t insn,
116*9880d681SAndroid Build Coastguard Worker uint64_t Address,
117*9880d681SAndroid Build Coastguard Worker const void *Decoder);
118*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeAddSubERegInstruction(llvm::MCInst &Inst,
119*9880d681SAndroid Build Coastguard Worker uint32_t insn, uint64_t Address,
120*9880d681SAndroid Build Coastguard Worker const void *Decoder);
121*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeLogicalImmInstruction(llvm::MCInst &Inst,
122*9880d681SAndroid Build Coastguard Worker uint32_t insn, uint64_t Address,
123*9880d681SAndroid Build Coastguard Worker const void *Decoder);
124*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeModImmInstruction(llvm::MCInst &Inst, uint32_t insn,
125*9880d681SAndroid Build Coastguard Worker uint64_t Address,
126*9880d681SAndroid Build Coastguard Worker const void *Decoder);
127*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeModImmTiedInstruction(llvm::MCInst &Inst,
128*9880d681SAndroid Build Coastguard Worker uint32_t insn, uint64_t Address,
129*9880d681SAndroid Build Coastguard Worker const void *Decoder);
130*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeAdrInstruction(llvm::MCInst &Inst, uint32_t insn,
131*9880d681SAndroid Build Coastguard Worker uint64_t Address, const void *Decoder);
132*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeBaseAddSubImm(llvm::MCInst &Inst, uint32_t insn,
133*9880d681SAndroid Build Coastguard Worker uint64_t Address, const void *Decoder);
134*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeUnconditionalBranch(llvm::MCInst &Inst, uint32_t insn,
135*9880d681SAndroid Build Coastguard Worker uint64_t Address,
136*9880d681SAndroid Build Coastguard Worker const void *Decoder);
137*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeSystemPStateInstruction(llvm::MCInst &Inst,
138*9880d681SAndroid Build Coastguard Worker uint32_t insn,
139*9880d681SAndroid Build Coastguard Worker uint64_t Address,
140*9880d681SAndroid Build Coastguard Worker const void *Decoder);
141*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeTestAndBranch(llvm::MCInst &Inst, uint32_t insn,
142*9880d681SAndroid Build Coastguard Worker uint64_t Address, const void *Decoder);
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,
145*9880d681SAndroid Build Coastguard Worker uint64_t Address,
146*9880d681SAndroid Build Coastguard Worker const void *Decoder);
147*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftR64Imm(llvm::MCInst &Inst, unsigned Imm,
148*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder);
149*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftR64ImmNarrow(llvm::MCInst &Inst, unsigned Imm,
150*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
151*9880d681SAndroid Build Coastguard Worker const void *Decoder);
152*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftR32Imm(llvm::MCInst &Inst, unsigned Imm,
153*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder);
154*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftR32ImmNarrow(llvm::MCInst &Inst, unsigned Imm,
155*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
156*9880d681SAndroid Build Coastguard Worker const void *Decoder);
157*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftR16Imm(llvm::MCInst &Inst, unsigned Imm,
158*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder);
159*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftR16ImmNarrow(llvm::MCInst &Inst, unsigned Imm,
160*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
161*9880d681SAndroid Build Coastguard Worker const void *Decoder);
162*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftR8Imm(llvm::MCInst &Inst, unsigned Imm,
163*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder);
164*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftL64Imm(llvm::MCInst &Inst, unsigned Imm,
165*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder);
166*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftL32Imm(llvm::MCInst &Inst, unsigned Imm,
167*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder);
168*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftL16Imm(llvm::MCInst &Inst, unsigned Imm,
169*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder);
170*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftL8Imm(llvm::MCInst &Inst, unsigned Imm,
171*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder);
172*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeWSeqPairsClassRegisterClass(MCInst &Inst,
173*9880d681SAndroid Build Coastguard Worker unsigned RegNo,
174*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
175*9880d681SAndroid Build Coastguard Worker const void *Decoder);
176*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeXSeqPairsClassRegisterClass(MCInst &Inst,
177*9880d681SAndroid Build Coastguard Worker unsigned RegNo,
178*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
179*9880d681SAndroid Build Coastguard Worker const void *Decoder);
180*9880d681SAndroid Build Coastguard Worker
Check(DecodeStatus & Out,DecodeStatus In)181*9880d681SAndroid Build Coastguard Worker static bool Check(DecodeStatus &Out, DecodeStatus In) {
182*9880d681SAndroid Build Coastguard Worker switch (In) {
183*9880d681SAndroid Build Coastguard Worker case MCDisassembler::Success:
184*9880d681SAndroid Build Coastguard Worker // Out stays the same.
185*9880d681SAndroid Build Coastguard Worker return true;
186*9880d681SAndroid Build Coastguard Worker case MCDisassembler::SoftFail:
187*9880d681SAndroid Build Coastguard Worker Out = In;
188*9880d681SAndroid Build Coastguard Worker return true;
189*9880d681SAndroid Build Coastguard Worker case MCDisassembler::Fail:
190*9880d681SAndroid Build Coastguard Worker Out = In;
191*9880d681SAndroid Build Coastguard Worker return false;
192*9880d681SAndroid Build Coastguard Worker }
193*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid DecodeStatus!");
194*9880d681SAndroid Build Coastguard Worker }
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Worker #include "AArch64GenDisassemblerTables.inc"
197*9880d681SAndroid Build Coastguard Worker #include "AArch64GenInstrInfo.inc"
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Worker #define Success llvm::MCDisassembler::Success
200*9880d681SAndroid Build Coastguard Worker #define Fail llvm::MCDisassembler::Fail
201*9880d681SAndroid Build Coastguard Worker #define SoftFail llvm::MCDisassembler::SoftFail
202*9880d681SAndroid Build Coastguard Worker
createAArch64Disassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)203*9880d681SAndroid Build Coastguard Worker static MCDisassembler *createAArch64Disassembler(const Target &T,
204*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
205*9880d681SAndroid Build Coastguard Worker MCContext &Ctx) {
206*9880d681SAndroid Build Coastguard Worker return new AArch64Disassembler(STI, Ctx);
207*9880d681SAndroid Build Coastguard Worker }
208*9880d681SAndroid Build Coastguard Worker
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,raw_ostream & CS) const209*9880d681SAndroid Build Coastguard Worker DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
210*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> Bytes,
211*9880d681SAndroid Build Coastguard Worker uint64_t Address,
212*9880d681SAndroid Build Coastguard Worker raw_ostream &OS,
213*9880d681SAndroid Build Coastguard Worker raw_ostream &CS) const {
214*9880d681SAndroid Build Coastguard Worker CommentStream = &CS;
215*9880d681SAndroid Build Coastguard Worker
216*9880d681SAndroid Build Coastguard Worker Size = 0;
217*9880d681SAndroid Build Coastguard Worker // We want to read exactly 4 bytes of data.
218*9880d681SAndroid Build Coastguard Worker if (Bytes.size() < 4)
219*9880d681SAndroid Build Coastguard Worker return Fail;
220*9880d681SAndroid Build Coastguard Worker Size = 4;
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker // Encoded as a small-endian 32-bit word in the stream.
223*9880d681SAndroid Build Coastguard Worker uint32_t Insn =
224*9880d681SAndroid Build Coastguard Worker (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
225*9880d681SAndroid Build Coastguard Worker
226*9880d681SAndroid Build Coastguard Worker // Calling the auto-generated decoder function.
227*9880d681SAndroid Build Coastguard Worker return decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
228*9880d681SAndroid Build Coastguard Worker }
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Worker static MCSymbolizer *
createAArch64ExternalSymbolizer(const Triple & TT,LLVMOpInfoCallback GetOpInfo,LLVMSymbolLookupCallback SymbolLookUp,void * DisInfo,MCContext * Ctx,std::unique_ptr<MCRelocationInfo> && RelInfo)231*9880d681SAndroid Build Coastguard Worker createAArch64ExternalSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,
232*9880d681SAndroid Build Coastguard Worker LLVMSymbolLookupCallback SymbolLookUp,
233*9880d681SAndroid Build Coastguard Worker void *DisInfo, MCContext *Ctx,
234*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCRelocationInfo> &&RelInfo) {
235*9880d681SAndroid Build Coastguard Worker return new llvm::AArch64ExternalSymbolizer(*Ctx, move(RelInfo), GetOpInfo,
236*9880d681SAndroid Build Coastguard Worker SymbolLookUp, DisInfo);
237*9880d681SAndroid Build Coastguard Worker }
238*9880d681SAndroid Build Coastguard Worker
LLVMInitializeAArch64Disassembler()239*9880d681SAndroid Build Coastguard Worker extern "C" void LLVMInitializeAArch64Disassembler() {
240*9880d681SAndroid Build Coastguard Worker TargetRegistry::RegisterMCDisassembler(TheAArch64leTarget,
241*9880d681SAndroid Build Coastguard Worker createAArch64Disassembler);
242*9880d681SAndroid Build Coastguard Worker TargetRegistry::RegisterMCDisassembler(TheAArch64beTarget,
243*9880d681SAndroid Build Coastguard Worker createAArch64Disassembler);
244*9880d681SAndroid Build Coastguard Worker TargetRegistry::RegisterMCSymbolizer(TheAArch64leTarget,
245*9880d681SAndroid Build Coastguard Worker createAArch64ExternalSymbolizer);
246*9880d681SAndroid Build Coastguard Worker TargetRegistry::RegisterMCSymbolizer(TheAArch64beTarget,
247*9880d681SAndroid Build Coastguard Worker createAArch64ExternalSymbolizer);
248*9880d681SAndroid Build Coastguard Worker
249*9880d681SAndroid Build Coastguard Worker TargetRegistry::RegisterMCDisassembler(TheARM64Target,
250*9880d681SAndroid Build Coastguard Worker createAArch64Disassembler);
251*9880d681SAndroid Build Coastguard Worker TargetRegistry::RegisterMCSymbolizer(TheARM64Target,
252*9880d681SAndroid Build Coastguard Worker createAArch64ExternalSymbolizer);
253*9880d681SAndroid Build Coastguard Worker }
254*9880d681SAndroid Build Coastguard Worker
255*9880d681SAndroid Build Coastguard Worker static const unsigned FPR128DecoderTable[] = {
256*9880d681SAndroid Build Coastguard Worker AArch64::Q0, AArch64::Q1, AArch64::Q2, AArch64::Q3, AArch64::Q4,
257*9880d681SAndroid Build Coastguard Worker AArch64::Q5, AArch64::Q6, AArch64::Q7, AArch64::Q8, AArch64::Q9,
258*9880d681SAndroid Build Coastguard Worker AArch64::Q10, AArch64::Q11, AArch64::Q12, AArch64::Q13, AArch64::Q14,
259*9880d681SAndroid Build Coastguard Worker AArch64::Q15, AArch64::Q16, AArch64::Q17, AArch64::Q18, AArch64::Q19,
260*9880d681SAndroid Build Coastguard Worker AArch64::Q20, AArch64::Q21, AArch64::Q22, AArch64::Q23, AArch64::Q24,
261*9880d681SAndroid Build Coastguard Worker AArch64::Q25, AArch64::Q26, AArch64::Q27, AArch64::Q28, AArch64::Q29,
262*9880d681SAndroid Build Coastguard Worker AArch64::Q30, AArch64::Q31
263*9880d681SAndroid Build Coastguard Worker };
264*9880d681SAndroid Build Coastguard Worker
DecodeFPR128RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)265*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, unsigned RegNo,
266*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
267*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
268*9880d681SAndroid Build Coastguard Worker if (RegNo > 31)
269*9880d681SAndroid Build Coastguard Worker return Fail;
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker unsigned Register = FPR128DecoderTable[RegNo];
272*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
273*9880d681SAndroid Build Coastguard Worker return Success;
274*9880d681SAndroid Build Coastguard Worker }
275*9880d681SAndroid Build Coastguard Worker
DecodeFPR128_loRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)276*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFPR128_loRegisterClass(MCInst &Inst, unsigned RegNo,
277*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
278*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
279*9880d681SAndroid Build Coastguard Worker if (RegNo > 15)
280*9880d681SAndroid Build Coastguard Worker return Fail;
281*9880d681SAndroid Build Coastguard Worker return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder);
282*9880d681SAndroid Build Coastguard Worker }
283*9880d681SAndroid Build Coastguard Worker
284*9880d681SAndroid Build Coastguard Worker static const unsigned FPR64DecoderTable[] = {
285*9880d681SAndroid Build Coastguard Worker AArch64::D0, AArch64::D1, AArch64::D2, AArch64::D3, AArch64::D4,
286*9880d681SAndroid Build Coastguard Worker AArch64::D5, AArch64::D6, AArch64::D7, AArch64::D8, AArch64::D9,
287*9880d681SAndroid Build Coastguard Worker AArch64::D10, AArch64::D11, AArch64::D12, AArch64::D13, AArch64::D14,
288*9880d681SAndroid Build Coastguard Worker AArch64::D15, AArch64::D16, AArch64::D17, AArch64::D18, AArch64::D19,
289*9880d681SAndroid Build Coastguard Worker AArch64::D20, AArch64::D21, AArch64::D22, AArch64::D23, AArch64::D24,
290*9880d681SAndroid Build Coastguard Worker AArch64::D25, AArch64::D26, AArch64::D27, AArch64::D28, AArch64::D29,
291*9880d681SAndroid Build Coastguard Worker AArch64::D30, AArch64::D31
292*9880d681SAndroid Build Coastguard Worker };
293*9880d681SAndroid Build Coastguard Worker
DecodeFPR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)294*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, unsigned RegNo,
295*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
296*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
297*9880d681SAndroid Build Coastguard Worker if (RegNo > 31)
298*9880d681SAndroid Build Coastguard Worker return Fail;
299*9880d681SAndroid Build Coastguard Worker
300*9880d681SAndroid Build Coastguard Worker unsigned Register = FPR64DecoderTable[RegNo];
301*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
302*9880d681SAndroid Build Coastguard Worker return Success;
303*9880d681SAndroid Build Coastguard Worker }
304*9880d681SAndroid Build Coastguard Worker
305*9880d681SAndroid Build Coastguard Worker static const unsigned FPR32DecoderTable[] = {
306*9880d681SAndroid Build Coastguard Worker AArch64::S0, AArch64::S1, AArch64::S2, AArch64::S3, AArch64::S4,
307*9880d681SAndroid Build Coastguard Worker AArch64::S5, AArch64::S6, AArch64::S7, AArch64::S8, AArch64::S9,
308*9880d681SAndroid Build Coastguard Worker AArch64::S10, AArch64::S11, AArch64::S12, AArch64::S13, AArch64::S14,
309*9880d681SAndroid Build Coastguard Worker AArch64::S15, AArch64::S16, AArch64::S17, AArch64::S18, AArch64::S19,
310*9880d681SAndroid Build Coastguard Worker AArch64::S20, AArch64::S21, AArch64::S22, AArch64::S23, AArch64::S24,
311*9880d681SAndroid Build Coastguard Worker AArch64::S25, AArch64::S26, AArch64::S27, AArch64::S28, AArch64::S29,
312*9880d681SAndroid Build Coastguard Worker AArch64::S30, AArch64::S31
313*9880d681SAndroid Build Coastguard Worker };
314*9880d681SAndroid Build Coastguard Worker
DecodeFPR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)315*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, unsigned RegNo,
316*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
317*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
318*9880d681SAndroid Build Coastguard Worker if (RegNo > 31)
319*9880d681SAndroid Build Coastguard Worker return Fail;
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Worker unsigned Register = FPR32DecoderTable[RegNo];
322*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
323*9880d681SAndroid Build Coastguard Worker return Success;
324*9880d681SAndroid Build Coastguard Worker }
325*9880d681SAndroid Build Coastguard Worker
326*9880d681SAndroid Build Coastguard Worker static const unsigned FPR16DecoderTable[] = {
327*9880d681SAndroid Build Coastguard Worker AArch64::H0, AArch64::H1, AArch64::H2, AArch64::H3, AArch64::H4,
328*9880d681SAndroid Build Coastguard Worker AArch64::H5, AArch64::H6, AArch64::H7, AArch64::H8, AArch64::H9,
329*9880d681SAndroid Build Coastguard Worker AArch64::H10, AArch64::H11, AArch64::H12, AArch64::H13, AArch64::H14,
330*9880d681SAndroid Build Coastguard Worker AArch64::H15, AArch64::H16, AArch64::H17, AArch64::H18, AArch64::H19,
331*9880d681SAndroid Build Coastguard Worker AArch64::H20, AArch64::H21, AArch64::H22, AArch64::H23, AArch64::H24,
332*9880d681SAndroid Build Coastguard Worker AArch64::H25, AArch64::H26, AArch64::H27, AArch64::H28, AArch64::H29,
333*9880d681SAndroid Build Coastguard Worker AArch64::H30, AArch64::H31
334*9880d681SAndroid Build Coastguard Worker };
335*9880d681SAndroid Build Coastguard Worker
DecodeFPR16RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)336*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, unsigned RegNo,
337*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
338*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
339*9880d681SAndroid Build Coastguard Worker if (RegNo > 31)
340*9880d681SAndroid Build Coastguard Worker return Fail;
341*9880d681SAndroid Build Coastguard Worker
342*9880d681SAndroid Build Coastguard Worker unsigned Register = FPR16DecoderTable[RegNo];
343*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
344*9880d681SAndroid Build Coastguard Worker return Success;
345*9880d681SAndroid Build Coastguard Worker }
346*9880d681SAndroid Build Coastguard Worker
347*9880d681SAndroid Build Coastguard Worker static const unsigned FPR8DecoderTable[] = {
348*9880d681SAndroid Build Coastguard Worker AArch64::B0, AArch64::B1, AArch64::B2, AArch64::B3, AArch64::B4,
349*9880d681SAndroid Build Coastguard Worker AArch64::B5, AArch64::B6, AArch64::B7, AArch64::B8, AArch64::B9,
350*9880d681SAndroid Build Coastguard Worker AArch64::B10, AArch64::B11, AArch64::B12, AArch64::B13, AArch64::B14,
351*9880d681SAndroid Build Coastguard Worker AArch64::B15, AArch64::B16, AArch64::B17, AArch64::B18, AArch64::B19,
352*9880d681SAndroid Build Coastguard Worker AArch64::B20, AArch64::B21, AArch64::B22, AArch64::B23, AArch64::B24,
353*9880d681SAndroid Build Coastguard Worker AArch64::B25, AArch64::B26, AArch64::B27, AArch64::B28, AArch64::B29,
354*9880d681SAndroid Build Coastguard Worker AArch64::B30, AArch64::B31
355*9880d681SAndroid Build Coastguard Worker };
356*9880d681SAndroid Build Coastguard Worker
DecodeFPR8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)357*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFPR8RegisterClass(MCInst &Inst, unsigned RegNo,
358*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
359*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
360*9880d681SAndroid Build Coastguard Worker if (RegNo > 31)
361*9880d681SAndroid Build Coastguard Worker return Fail;
362*9880d681SAndroid Build Coastguard Worker
363*9880d681SAndroid Build Coastguard Worker unsigned Register = FPR8DecoderTable[RegNo];
364*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
365*9880d681SAndroid Build Coastguard Worker return Success;
366*9880d681SAndroid Build Coastguard Worker }
367*9880d681SAndroid Build Coastguard Worker
368*9880d681SAndroid Build Coastguard Worker static const unsigned GPR64DecoderTable[] = {
369*9880d681SAndroid Build Coastguard Worker AArch64::X0, AArch64::X1, AArch64::X2, AArch64::X3, AArch64::X4,
370*9880d681SAndroid Build Coastguard Worker AArch64::X5, AArch64::X6, AArch64::X7, AArch64::X8, AArch64::X9,
371*9880d681SAndroid Build Coastguard Worker AArch64::X10, AArch64::X11, AArch64::X12, AArch64::X13, AArch64::X14,
372*9880d681SAndroid Build Coastguard Worker AArch64::X15, AArch64::X16, AArch64::X17, AArch64::X18, AArch64::X19,
373*9880d681SAndroid Build Coastguard Worker AArch64::X20, AArch64::X21, AArch64::X22, AArch64::X23, AArch64::X24,
374*9880d681SAndroid Build Coastguard Worker AArch64::X25, AArch64::X26, AArch64::X27, AArch64::X28, AArch64::FP,
375*9880d681SAndroid Build Coastguard Worker AArch64::LR, AArch64::XZR
376*9880d681SAndroid Build Coastguard Worker };
377*9880d681SAndroid Build Coastguard Worker
DecodeGPR64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)378*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
379*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
380*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
381*9880d681SAndroid Build Coastguard Worker if (RegNo > 31)
382*9880d681SAndroid Build Coastguard Worker return Fail;
383*9880d681SAndroid Build Coastguard Worker
384*9880d681SAndroid Build Coastguard Worker unsigned Register = GPR64DecoderTable[RegNo];
385*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
386*9880d681SAndroid Build Coastguard Worker return Success;
387*9880d681SAndroid Build Coastguard Worker }
388*9880d681SAndroid Build Coastguard Worker
DecodeGPR64spRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)389*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst, unsigned RegNo,
390*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
391*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
392*9880d681SAndroid Build Coastguard Worker if (RegNo > 31)
393*9880d681SAndroid Build Coastguard Worker return Fail;
394*9880d681SAndroid Build Coastguard Worker unsigned Register = GPR64DecoderTable[RegNo];
395*9880d681SAndroid Build Coastguard Worker if (Register == AArch64::XZR)
396*9880d681SAndroid Build Coastguard Worker Register = AArch64::SP;
397*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
398*9880d681SAndroid Build Coastguard Worker return Success;
399*9880d681SAndroid Build Coastguard Worker }
400*9880d681SAndroid Build Coastguard Worker
401*9880d681SAndroid Build Coastguard Worker static const unsigned GPR32DecoderTable[] = {
402*9880d681SAndroid Build Coastguard Worker AArch64::W0, AArch64::W1, AArch64::W2, AArch64::W3, AArch64::W4,
403*9880d681SAndroid Build Coastguard Worker AArch64::W5, AArch64::W6, AArch64::W7, AArch64::W8, AArch64::W9,
404*9880d681SAndroid Build Coastguard Worker AArch64::W10, AArch64::W11, AArch64::W12, AArch64::W13, AArch64::W14,
405*9880d681SAndroid Build Coastguard Worker AArch64::W15, AArch64::W16, AArch64::W17, AArch64::W18, AArch64::W19,
406*9880d681SAndroid Build Coastguard Worker AArch64::W20, AArch64::W21, AArch64::W22, AArch64::W23, AArch64::W24,
407*9880d681SAndroid Build Coastguard Worker AArch64::W25, AArch64::W26, AArch64::W27, AArch64::W28, AArch64::W29,
408*9880d681SAndroid Build Coastguard Worker AArch64::W30, AArch64::WZR
409*9880d681SAndroid Build Coastguard Worker };
410*9880d681SAndroid Build Coastguard Worker
DecodeGPR32RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)411*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
412*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
413*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
414*9880d681SAndroid Build Coastguard Worker if (RegNo > 31)
415*9880d681SAndroid Build Coastguard Worker return Fail;
416*9880d681SAndroid Build Coastguard Worker
417*9880d681SAndroid Build Coastguard Worker unsigned Register = GPR32DecoderTable[RegNo];
418*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
419*9880d681SAndroid Build Coastguard Worker return Success;
420*9880d681SAndroid Build Coastguard Worker }
421*9880d681SAndroid Build Coastguard Worker
DecodeGPR32spRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)422*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeGPR32spRegisterClass(MCInst &Inst, unsigned RegNo,
423*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
424*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
425*9880d681SAndroid Build Coastguard Worker if (RegNo > 31)
426*9880d681SAndroid Build Coastguard Worker return Fail;
427*9880d681SAndroid Build Coastguard Worker
428*9880d681SAndroid Build Coastguard Worker unsigned Register = GPR32DecoderTable[RegNo];
429*9880d681SAndroid Build Coastguard Worker if (Register == AArch64::WZR)
430*9880d681SAndroid Build Coastguard Worker Register = AArch64::WSP;
431*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
432*9880d681SAndroid Build Coastguard Worker return Success;
433*9880d681SAndroid Build Coastguard Worker }
434*9880d681SAndroid Build Coastguard Worker
435*9880d681SAndroid Build Coastguard Worker static const unsigned VectorDecoderTable[] = {
436*9880d681SAndroid Build Coastguard Worker AArch64::Q0, AArch64::Q1, AArch64::Q2, AArch64::Q3, AArch64::Q4,
437*9880d681SAndroid Build Coastguard Worker AArch64::Q5, AArch64::Q6, AArch64::Q7, AArch64::Q8, AArch64::Q9,
438*9880d681SAndroid Build Coastguard Worker AArch64::Q10, AArch64::Q11, AArch64::Q12, AArch64::Q13, AArch64::Q14,
439*9880d681SAndroid Build Coastguard Worker AArch64::Q15, AArch64::Q16, AArch64::Q17, AArch64::Q18, AArch64::Q19,
440*9880d681SAndroid Build Coastguard Worker AArch64::Q20, AArch64::Q21, AArch64::Q22, AArch64::Q23, AArch64::Q24,
441*9880d681SAndroid Build Coastguard Worker AArch64::Q25, AArch64::Q26, AArch64::Q27, AArch64::Q28, AArch64::Q29,
442*9880d681SAndroid Build Coastguard Worker AArch64::Q30, AArch64::Q31
443*9880d681SAndroid Build Coastguard Worker };
444*9880d681SAndroid Build Coastguard Worker
DecodeVectorRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)445*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVectorRegisterClass(MCInst &Inst, unsigned RegNo,
446*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
447*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
448*9880d681SAndroid Build Coastguard Worker if (RegNo > 31)
449*9880d681SAndroid Build Coastguard Worker return Fail;
450*9880d681SAndroid Build Coastguard Worker
451*9880d681SAndroid Build Coastguard Worker unsigned Register = VectorDecoderTable[RegNo];
452*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
453*9880d681SAndroid Build Coastguard Worker return Success;
454*9880d681SAndroid Build Coastguard Worker }
455*9880d681SAndroid Build Coastguard Worker
456*9880d681SAndroid Build Coastguard Worker static const unsigned QQDecoderTable[] = {
457*9880d681SAndroid Build Coastguard Worker AArch64::Q0_Q1, AArch64::Q1_Q2, AArch64::Q2_Q3, AArch64::Q3_Q4,
458*9880d681SAndroid Build Coastguard Worker AArch64::Q4_Q5, AArch64::Q5_Q6, AArch64::Q6_Q7, AArch64::Q7_Q8,
459*9880d681SAndroid Build Coastguard Worker AArch64::Q8_Q9, AArch64::Q9_Q10, AArch64::Q10_Q11, AArch64::Q11_Q12,
460*9880d681SAndroid Build Coastguard Worker AArch64::Q12_Q13, AArch64::Q13_Q14, AArch64::Q14_Q15, AArch64::Q15_Q16,
461*9880d681SAndroid Build Coastguard Worker AArch64::Q16_Q17, AArch64::Q17_Q18, AArch64::Q18_Q19, AArch64::Q19_Q20,
462*9880d681SAndroid Build Coastguard Worker AArch64::Q20_Q21, AArch64::Q21_Q22, AArch64::Q22_Q23, AArch64::Q23_Q24,
463*9880d681SAndroid Build Coastguard Worker AArch64::Q24_Q25, AArch64::Q25_Q26, AArch64::Q26_Q27, AArch64::Q27_Q28,
464*9880d681SAndroid Build Coastguard Worker AArch64::Q28_Q29, AArch64::Q29_Q30, AArch64::Q30_Q31, AArch64::Q31_Q0
465*9880d681SAndroid Build Coastguard Worker };
466*9880d681SAndroid Build Coastguard Worker
DecodeQQRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)467*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeQQRegisterClass(MCInst &Inst, unsigned RegNo,
468*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder) {
469*9880d681SAndroid Build Coastguard Worker if (RegNo > 31)
470*9880d681SAndroid Build Coastguard Worker return Fail;
471*9880d681SAndroid Build Coastguard Worker unsigned Register = QQDecoderTable[RegNo];
472*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
473*9880d681SAndroid Build Coastguard Worker return Success;
474*9880d681SAndroid Build Coastguard Worker }
475*9880d681SAndroid Build Coastguard Worker
476*9880d681SAndroid Build Coastguard Worker static const unsigned QQQDecoderTable[] = {
477*9880d681SAndroid Build Coastguard Worker AArch64::Q0_Q1_Q2, AArch64::Q1_Q2_Q3, AArch64::Q2_Q3_Q4,
478*9880d681SAndroid Build Coastguard Worker AArch64::Q3_Q4_Q5, AArch64::Q4_Q5_Q6, AArch64::Q5_Q6_Q7,
479*9880d681SAndroid Build Coastguard Worker AArch64::Q6_Q7_Q8, AArch64::Q7_Q8_Q9, AArch64::Q8_Q9_Q10,
480*9880d681SAndroid Build Coastguard Worker AArch64::Q9_Q10_Q11, AArch64::Q10_Q11_Q12, AArch64::Q11_Q12_Q13,
481*9880d681SAndroid Build Coastguard Worker AArch64::Q12_Q13_Q14, AArch64::Q13_Q14_Q15, AArch64::Q14_Q15_Q16,
482*9880d681SAndroid Build Coastguard Worker AArch64::Q15_Q16_Q17, AArch64::Q16_Q17_Q18, AArch64::Q17_Q18_Q19,
483*9880d681SAndroid Build Coastguard Worker AArch64::Q18_Q19_Q20, AArch64::Q19_Q20_Q21, AArch64::Q20_Q21_Q22,
484*9880d681SAndroid Build Coastguard Worker AArch64::Q21_Q22_Q23, AArch64::Q22_Q23_Q24, AArch64::Q23_Q24_Q25,
485*9880d681SAndroid Build Coastguard Worker AArch64::Q24_Q25_Q26, AArch64::Q25_Q26_Q27, AArch64::Q26_Q27_Q28,
486*9880d681SAndroid Build Coastguard Worker AArch64::Q27_Q28_Q29, AArch64::Q28_Q29_Q30, AArch64::Q29_Q30_Q31,
487*9880d681SAndroid Build Coastguard Worker AArch64::Q30_Q31_Q0, AArch64::Q31_Q0_Q1
488*9880d681SAndroid Build Coastguard Worker };
489*9880d681SAndroid Build Coastguard Worker
DecodeQQQRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)490*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeQQQRegisterClass(MCInst &Inst, unsigned RegNo,
491*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder) {
492*9880d681SAndroid Build Coastguard Worker if (RegNo > 31)
493*9880d681SAndroid Build Coastguard Worker return Fail;
494*9880d681SAndroid Build Coastguard Worker unsigned Register = QQQDecoderTable[RegNo];
495*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
496*9880d681SAndroid Build Coastguard Worker return Success;
497*9880d681SAndroid Build Coastguard Worker }
498*9880d681SAndroid Build Coastguard Worker
499*9880d681SAndroid Build Coastguard Worker static const unsigned QQQQDecoderTable[] = {
500*9880d681SAndroid Build Coastguard Worker AArch64::Q0_Q1_Q2_Q3, AArch64::Q1_Q2_Q3_Q4, AArch64::Q2_Q3_Q4_Q5,
501*9880d681SAndroid Build Coastguard Worker AArch64::Q3_Q4_Q5_Q6, AArch64::Q4_Q5_Q6_Q7, AArch64::Q5_Q6_Q7_Q8,
502*9880d681SAndroid Build Coastguard Worker AArch64::Q6_Q7_Q8_Q9, AArch64::Q7_Q8_Q9_Q10, AArch64::Q8_Q9_Q10_Q11,
503*9880d681SAndroid Build Coastguard Worker AArch64::Q9_Q10_Q11_Q12, AArch64::Q10_Q11_Q12_Q13, AArch64::Q11_Q12_Q13_Q14,
504*9880d681SAndroid Build Coastguard Worker AArch64::Q12_Q13_Q14_Q15, AArch64::Q13_Q14_Q15_Q16, AArch64::Q14_Q15_Q16_Q17,
505*9880d681SAndroid Build Coastguard Worker AArch64::Q15_Q16_Q17_Q18, AArch64::Q16_Q17_Q18_Q19, AArch64::Q17_Q18_Q19_Q20,
506*9880d681SAndroid Build Coastguard Worker AArch64::Q18_Q19_Q20_Q21, AArch64::Q19_Q20_Q21_Q22, AArch64::Q20_Q21_Q22_Q23,
507*9880d681SAndroid Build Coastguard Worker AArch64::Q21_Q22_Q23_Q24, AArch64::Q22_Q23_Q24_Q25, AArch64::Q23_Q24_Q25_Q26,
508*9880d681SAndroid Build Coastguard Worker AArch64::Q24_Q25_Q26_Q27, AArch64::Q25_Q26_Q27_Q28, AArch64::Q26_Q27_Q28_Q29,
509*9880d681SAndroid Build Coastguard Worker AArch64::Q27_Q28_Q29_Q30, AArch64::Q28_Q29_Q30_Q31, AArch64::Q29_Q30_Q31_Q0,
510*9880d681SAndroid Build Coastguard Worker AArch64::Q30_Q31_Q0_Q1, AArch64::Q31_Q0_Q1_Q2
511*9880d681SAndroid Build Coastguard Worker };
512*9880d681SAndroid Build Coastguard Worker
DecodeQQQQRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)513*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeQQQQRegisterClass(MCInst &Inst, unsigned RegNo,
514*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
515*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
516*9880d681SAndroid Build Coastguard Worker if (RegNo > 31)
517*9880d681SAndroid Build Coastguard Worker return Fail;
518*9880d681SAndroid Build Coastguard Worker unsigned Register = QQQQDecoderTable[RegNo];
519*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
520*9880d681SAndroid Build Coastguard Worker return Success;
521*9880d681SAndroid Build Coastguard Worker }
522*9880d681SAndroid Build Coastguard Worker
523*9880d681SAndroid Build Coastguard Worker static const unsigned DDDecoderTable[] = {
524*9880d681SAndroid Build Coastguard Worker AArch64::D0_D1, AArch64::D1_D2, AArch64::D2_D3, AArch64::D3_D4,
525*9880d681SAndroid Build Coastguard Worker AArch64::D4_D5, AArch64::D5_D6, AArch64::D6_D7, AArch64::D7_D8,
526*9880d681SAndroid Build Coastguard Worker AArch64::D8_D9, AArch64::D9_D10, AArch64::D10_D11, AArch64::D11_D12,
527*9880d681SAndroid Build Coastguard Worker AArch64::D12_D13, AArch64::D13_D14, AArch64::D14_D15, AArch64::D15_D16,
528*9880d681SAndroid Build Coastguard Worker AArch64::D16_D17, AArch64::D17_D18, AArch64::D18_D19, AArch64::D19_D20,
529*9880d681SAndroid Build Coastguard Worker AArch64::D20_D21, AArch64::D21_D22, AArch64::D22_D23, AArch64::D23_D24,
530*9880d681SAndroid Build Coastguard Worker AArch64::D24_D25, AArch64::D25_D26, AArch64::D26_D27, AArch64::D27_D28,
531*9880d681SAndroid Build Coastguard Worker AArch64::D28_D29, AArch64::D29_D30, AArch64::D30_D31, AArch64::D31_D0
532*9880d681SAndroid Build Coastguard Worker };
533*9880d681SAndroid Build Coastguard Worker
DecodeDDRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)534*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeDDRegisterClass(MCInst &Inst, unsigned RegNo,
535*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder) {
536*9880d681SAndroid Build Coastguard Worker if (RegNo > 31)
537*9880d681SAndroid Build Coastguard Worker return Fail;
538*9880d681SAndroid Build Coastguard Worker unsigned Register = DDDecoderTable[RegNo];
539*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
540*9880d681SAndroid Build Coastguard Worker return Success;
541*9880d681SAndroid Build Coastguard Worker }
542*9880d681SAndroid Build Coastguard Worker
543*9880d681SAndroid Build Coastguard Worker static const unsigned DDDDecoderTable[] = {
544*9880d681SAndroid Build Coastguard Worker AArch64::D0_D1_D2, AArch64::D1_D2_D3, AArch64::D2_D3_D4,
545*9880d681SAndroid Build Coastguard Worker AArch64::D3_D4_D5, AArch64::D4_D5_D6, AArch64::D5_D6_D7,
546*9880d681SAndroid Build Coastguard Worker AArch64::D6_D7_D8, AArch64::D7_D8_D9, AArch64::D8_D9_D10,
547*9880d681SAndroid Build Coastguard Worker AArch64::D9_D10_D11, AArch64::D10_D11_D12, AArch64::D11_D12_D13,
548*9880d681SAndroid Build Coastguard Worker AArch64::D12_D13_D14, AArch64::D13_D14_D15, AArch64::D14_D15_D16,
549*9880d681SAndroid Build Coastguard Worker AArch64::D15_D16_D17, AArch64::D16_D17_D18, AArch64::D17_D18_D19,
550*9880d681SAndroid Build Coastguard Worker AArch64::D18_D19_D20, AArch64::D19_D20_D21, AArch64::D20_D21_D22,
551*9880d681SAndroid Build Coastguard Worker AArch64::D21_D22_D23, AArch64::D22_D23_D24, AArch64::D23_D24_D25,
552*9880d681SAndroid Build Coastguard Worker AArch64::D24_D25_D26, AArch64::D25_D26_D27, AArch64::D26_D27_D28,
553*9880d681SAndroid Build Coastguard Worker AArch64::D27_D28_D29, AArch64::D28_D29_D30, AArch64::D29_D30_D31,
554*9880d681SAndroid Build Coastguard Worker AArch64::D30_D31_D0, AArch64::D31_D0_D1
555*9880d681SAndroid Build Coastguard Worker };
556*9880d681SAndroid Build Coastguard Worker
DecodeDDDRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)557*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeDDDRegisterClass(MCInst &Inst, unsigned RegNo,
558*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder) {
559*9880d681SAndroid Build Coastguard Worker if (RegNo > 31)
560*9880d681SAndroid Build Coastguard Worker return Fail;
561*9880d681SAndroid Build Coastguard Worker unsigned Register = DDDDecoderTable[RegNo];
562*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
563*9880d681SAndroid Build Coastguard Worker return Success;
564*9880d681SAndroid Build Coastguard Worker }
565*9880d681SAndroid Build Coastguard Worker
566*9880d681SAndroid Build Coastguard Worker static const unsigned DDDDDecoderTable[] = {
567*9880d681SAndroid Build Coastguard Worker AArch64::D0_D1_D2_D3, AArch64::D1_D2_D3_D4, AArch64::D2_D3_D4_D5,
568*9880d681SAndroid Build Coastguard Worker AArch64::D3_D4_D5_D6, AArch64::D4_D5_D6_D7, AArch64::D5_D6_D7_D8,
569*9880d681SAndroid Build Coastguard Worker AArch64::D6_D7_D8_D9, AArch64::D7_D8_D9_D10, AArch64::D8_D9_D10_D11,
570*9880d681SAndroid Build Coastguard Worker AArch64::D9_D10_D11_D12, AArch64::D10_D11_D12_D13, AArch64::D11_D12_D13_D14,
571*9880d681SAndroid Build Coastguard Worker AArch64::D12_D13_D14_D15, AArch64::D13_D14_D15_D16, AArch64::D14_D15_D16_D17,
572*9880d681SAndroid Build Coastguard Worker AArch64::D15_D16_D17_D18, AArch64::D16_D17_D18_D19, AArch64::D17_D18_D19_D20,
573*9880d681SAndroid Build Coastguard Worker AArch64::D18_D19_D20_D21, AArch64::D19_D20_D21_D22, AArch64::D20_D21_D22_D23,
574*9880d681SAndroid Build Coastguard Worker AArch64::D21_D22_D23_D24, AArch64::D22_D23_D24_D25, AArch64::D23_D24_D25_D26,
575*9880d681SAndroid Build Coastguard Worker AArch64::D24_D25_D26_D27, AArch64::D25_D26_D27_D28, AArch64::D26_D27_D28_D29,
576*9880d681SAndroid Build Coastguard Worker AArch64::D27_D28_D29_D30, AArch64::D28_D29_D30_D31, AArch64::D29_D30_D31_D0,
577*9880d681SAndroid Build Coastguard Worker AArch64::D30_D31_D0_D1, AArch64::D31_D0_D1_D2
578*9880d681SAndroid Build Coastguard Worker };
579*9880d681SAndroid Build Coastguard Worker
DecodeDDDDRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)580*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeDDDDRegisterClass(MCInst &Inst, unsigned RegNo,
581*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
582*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
583*9880d681SAndroid Build Coastguard Worker if (RegNo > 31)
584*9880d681SAndroid Build Coastguard Worker return Fail;
585*9880d681SAndroid Build Coastguard Worker unsigned Register = DDDDDecoderTable[RegNo];
586*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
587*9880d681SAndroid Build Coastguard Worker return Success;
588*9880d681SAndroid Build Coastguard Worker }
589*9880d681SAndroid Build Coastguard Worker
DecodeFixedPointScaleImm32(llvm::MCInst & Inst,unsigned Imm,uint64_t Addr,const void * Decoder)590*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFixedPointScaleImm32(llvm::MCInst &Inst, unsigned Imm,
591*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
592*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
593*9880d681SAndroid Build Coastguard Worker // scale{5} is asserted as 1 in tblgen.
594*9880d681SAndroid Build Coastguard Worker Imm |= 0x20;
595*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(64 - Imm));
596*9880d681SAndroid Build Coastguard Worker return Success;
597*9880d681SAndroid Build Coastguard Worker }
598*9880d681SAndroid Build Coastguard Worker
DecodeFixedPointScaleImm64(llvm::MCInst & Inst,unsigned Imm,uint64_t Addr,const void * Decoder)599*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFixedPointScaleImm64(llvm::MCInst &Inst, unsigned Imm,
600*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
601*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
602*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(64 - Imm));
603*9880d681SAndroid Build Coastguard Worker return Success;
604*9880d681SAndroid Build Coastguard Worker }
605*9880d681SAndroid Build Coastguard Worker
DecodePCRelLabel19(llvm::MCInst & Inst,unsigned Imm,uint64_t Addr,const void * Decoder)606*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodePCRelLabel19(llvm::MCInst &Inst, unsigned Imm,
607*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder) {
608*9880d681SAndroid Build Coastguard Worker int64_t ImmVal = Imm;
609*9880d681SAndroid Build Coastguard Worker const AArch64Disassembler *Dis =
610*9880d681SAndroid Build Coastguard Worker static_cast<const AArch64Disassembler *>(Decoder);
611*9880d681SAndroid Build Coastguard Worker
612*9880d681SAndroid Build Coastguard Worker // Sign-extend 19-bit immediate.
613*9880d681SAndroid Build Coastguard Worker if (ImmVal & (1 << (19 - 1)))
614*9880d681SAndroid Build Coastguard Worker ImmVal |= ~((1LL << 19) - 1);
615*9880d681SAndroid Build Coastguard Worker
616*9880d681SAndroid Build Coastguard Worker if (!Dis->tryAddingSymbolicOperand(Inst, ImmVal * 4, Addr,
617*9880d681SAndroid Build Coastguard Worker Inst.getOpcode() != AArch64::LDRXl, 0, 4))
618*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(ImmVal));
619*9880d681SAndroid Build Coastguard Worker return Success;
620*9880d681SAndroid Build Coastguard Worker }
621*9880d681SAndroid Build Coastguard Worker
DecodeMemExtend(llvm::MCInst & Inst,unsigned Imm,uint64_t Address,const void * Decoder)622*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeMemExtend(llvm::MCInst &Inst, unsigned Imm,
623*9880d681SAndroid Build Coastguard Worker uint64_t Address, const void *Decoder) {
624*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm((Imm >> 1) & 1));
625*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(Imm & 1));
626*9880d681SAndroid Build Coastguard Worker return Success;
627*9880d681SAndroid Build Coastguard Worker }
628*9880d681SAndroid Build Coastguard Worker
DecodeMRSSystemRegister(llvm::MCInst & Inst,unsigned Imm,uint64_t Address,const void * Decoder)629*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeMRSSystemRegister(llvm::MCInst &Inst, unsigned Imm,
630*9880d681SAndroid Build Coastguard Worker uint64_t Address,
631*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
632*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(Imm));
633*9880d681SAndroid Build Coastguard Worker
634*9880d681SAndroid Build Coastguard Worker // Every system register in the encoding space is valid with the syntax
635*9880d681SAndroid Build Coastguard Worker // S<op0>_<op1>_<Cn>_<Cm>_<op2>, so decoding system registers always succeeds.
636*9880d681SAndroid Build Coastguard Worker return Success;
637*9880d681SAndroid Build Coastguard Worker }
638*9880d681SAndroid Build Coastguard Worker
DecodeMSRSystemRegister(llvm::MCInst & Inst,unsigned Imm,uint64_t Address,const void * Decoder)639*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeMSRSystemRegister(llvm::MCInst &Inst, unsigned Imm,
640*9880d681SAndroid Build Coastguard Worker uint64_t Address,
641*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
642*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(Imm));
643*9880d681SAndroid Build Coastguard Worker
644*9880d681SAndroid Build Coastguard Worker return Success;
645*9880d681SAndroid Build Coastguard Worker }
646*9880d681SAndroid Build Coastguard Worker
DecodeFMOVLaneInstruction(llvm::MCInst & Inst,unsigned Insn,uint64_t Address,const void * Decoder)647*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,
648*9880d681SAndroid Build Coastguard Worker uint64_t Address,
649*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
650*9880d681SAndroid Build Coastguard Worker // This decoder exists to add the dummy Lane operand to the MCInst, which must
651*9880d681SAndroid Build Coastguard Worker // be 1 in assembly but has no other real manifestation.
652*9880d681SAndroid Build Coastguard Worker unsigned Rd = fieldFromInstruction(Insn, 0, 5);
653*9880d681SAndroid Build Coastguard Worker unsigned Rn = fieldFromInstruction(Insn, 5, 5);
654*9880d681SAndroid Build Coastguard Worker unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
655*9880d681SAndroid Build Coastguard Worker
656*9880d681SAndroid Build Coastguard Worker if (IsToVec) {
657*9880d681SAndroid Build Coastguard Worker DecodeFPR128RegisterClass(Inst, Rd, Address, Decoder);
658*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
659*9880d681SAndroid Build Coastguard Worker } else {
660*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
661*9880d681SAndroid Build Coastguard Worker DecodeFPR128RegisterClass(Inst, Rn, Address, Decoder);
662*9880d681SAndroid Build Coastguard Worker }
663*9880d681SAndroid Build Coastguard Worker
664*9880d681SAndroid Build Coastguard Worker // Add the lane
665*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(1));
666*9880d681SAndroid Build Coastguard Worker
667*9880d681SAndroid Build Coastguard Worker return Success;
668*9880d681SAndroid Build Coastguard Worker }
669*9880d681SAndroid Build Coastguard Worker
DecodeVecShiftRImm(llvm::MCInst & Inst,unsigned Imm,unsigned Add)670*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftRImm(llvm::MCInst &Inst, unsigned Imm,
671*9880d681SAndroid Build Coastguard Worker unsigned Add) {
672*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(Add - Imm));
673*9880d681SAndroid Build Coastguard Worker return Success;
674*9880d681SAndroid Build Coastguard Worker }
675*9880d681SAndroid Build Coastguard Worker
DecodeVecShiftLImm(llvm::MCInst & Inst,unsigned Imm,unsigned Add)676*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftLImm(llvm::MCInst &Inst, unsigned Imm,
677*9880d681SAndroid Build Coastguard Worker unsigned Add) {
678*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm((Imm + Add) & (Add - 1)));
679*9880d681SAndroid Build Coastguard Worker return Success;
680*9880d681SAndroid Build Coastguard Worker }
681*9880d681SAndroid Build Coastguard Worker
DecodeVecShiftR64Imm(llvm::MCInst & Inst,unsigned Imm,uint64_t Addr,const void * Decoder)682*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftR64Imm(llvm::MCInst &Inst, unsigned Imm,
683*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder) {
684*9880d681SAndroid Build Coastguard Worker return DecodeVecShiftRImm(Inst, Imm, 64);
685*9880d681SAndroid Build Coastguard Worker }
686*9880d681SAndroid Build Coastguard Worker
DecodeVecShiftR64ImmNarrow(llvm::MCInst & Inst,unsigned Imm,uint64_t Addr,const void * Decoder)687*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftR64ImmNarrow(llvm::MCInst &Inst, unsigned Imm,
688*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
689*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
690*9880d681SAndroid Build Coastguard Worker return DecodeVecShiftRImm(Inst, Imm | 0x20, 64);
691*9880d681SAndroid Build Coastguard Worker }
692*9880d681SAndroid Build Coastguard Worker
DecodeVecShiftR32Imm(llvm::MCInst & Inst,unsigned Imm,uint64_t Addr,const void * Decoder)693*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftR32Imm(llvm::MCInst &Inst, unsigned Imm,
694*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder) {
695*9880d681SAndroid Build Coastguard Worker return DecodeVecShiftRImm(Inst, Imm, 32);
696*9880d681SAndroid Build Coastguard Worker }
697*9880d681SAndroid Build Coastguard Worker
DecodeVecShiftR32ImmNarrow(llvm::MCInst & Inst,unsigned Imm,uint64_t Addr,const void * Decoder)698*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftR32ImmNarrow(llvm::MCInst &Inst, unsigned Imm,
699*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
700*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
701*9880d681SAndroid Build Coastguard Worker return DecodeVecShiftRImm(Inst, Imm | 0x10, 32);
702*9880d681SAndroid Build Coastguard Worker }
703*9880d681SAndroid Build Coastguard Worker
DecodeVecShiftR16Imm(llvm::MCInst & Inst,unsigned Imm,uint64_t Addr,const void * Decoder)704*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftR16Imm(llvm::MCInst &Inst, unsigned Imm,
705*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder) {
706*9880d681SAndroid Build Coastguard Worker return DecodeVecShiftRImm(Inst, Imm, 16);
707*9880d681SAndroid Build Coastguard Worker }
708*9880d681SAndroid Build Coastguard Worker
DecodeVecShiftR16ImmNarrow(llvm::MCInst & Inst,unsigned Imm,uint64_t Addr,const void * Decoder)709*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftR16ImmNarrow(llvm::MCInst &Inst, unsigned Imm,
710*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
711*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
712*9880d681SAndroid Build Coastguard Worker return DecodeVecShiftRImm(Inst, Imm | 0x8, 16);
713*9880d681SAndroid Build Coastguard Worker }
714*9880d681SAndroid Build Coastguard Worker
DecodeVecShiftR8Imm(llvm::MCInst & Inst,unsigned Imm,uint64_t Addr,const void * Decoder)715*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftR8Imm(llvm::MCInst &Inst, unsigned Imm,
716*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder) {
717*9880d681SAndroid Build Coastguard Worker return DecodeVecShiftRImm(Inst, Imm, 8);
718*9880d681SAndroid Build Coastguard Worker }
719*9880d681SAndroid Build Coastguard Worker
DecodeVecShiftL64Imm(llvm::MCInst & Inst,unsigned Imm,uint64_t Addr,const void * Decoder)720*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftL64Imm(llvm::MCInst &Inst, unsigned Imm,
721*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder) {
722*9880d681SAndroid Build Coastguard Worker return DecodeVecShiftLImm(Inst, Imm, 64);
723*9880d681SAndroid Build Coastguard Worker }
724*9880d681SAndroid Build Coastguard Worker
DecodeVecShiftL32Imm(llvm::MCInst & Inst,unsigned Imm,uint64_t Addr,const void * Decoder)725*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftL32Imm(llvm::MCInst &Inst, unsigned Imm,
726*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder) {
727*9880d681SAndroid Build Coastguard Worker return DecodeVecShiftLImm(Inst, Imm, 32);
728*9880d681SAndroid Build Coastguard Worker }
729*9880d681SAndroid Build Coastguard Worker
DecodeVecShiftL16Imm(llvm::MCInst & Inst,unsigned Imm,uint64_t Addr,const void * Decoder)730*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftL16Imm(llvm::MCInst &Inst, unsigned Imm,
731*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder) {
732*9880d681SAndroid Build Coastguard Worker return DecodeVecShiftLImm(Inst, Imm, 16);
733*9880d681SAndroid Build Coastguard Worker }
734*9880d681SAndroid Build Coastguard Worker
DecodeVecShiftL8Imm(llvm::MCInst & Inst,unsigned Imm,uint64_t Addr,const void * Decoder)735*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecShiftL8Imm(llvm::MCInst &Inst, unsigned Imm,
736*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder) {
737*9880d681SAndroid Build Coastguard Worker return DecodeVecShiftLImm(Inst, Imm, 8);
738*9880d681SAndroid Build Coastguard Worker }
739*9880d681SAndroid Build Coastguard Worker
DecodeThreeAddrSRegInstruction(llvm::MCInst & Inst,uint32_t insn,uint64_t Addr,const void * Decoder)740*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeThreeAddrSRegInstruction(llvm::MCInst &Inst,
741*9880d681SAndroid Build Coastguard Worker uint32_t insn, uint64_t Addr,
742*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
743*9880d681SAndroid Build Coastguard Worker unsigned Rd = fieldFromInstruction(insn, 0, 5);
744*9880d681SAndroid Build Coastguard Worker unsigned Rn = fieldFromInstruction(insn, 5, 5);
745*9880d681SAndroid Build Coastguard Worker unsigned Rm = fieldFromInstruction(insn, 16, 5);
746*9880d681SAndroid Build Coastguard Worker unsigned shiftHi = fieldFromInstruction(insn, 22, 2);
747*9880d681SAndroid Build Coastguard Worker unsigned shiftLo = fieldFromInstruction(insn, 10, 6);
748*9880d681SAndroid Build Coastguard Worker unsigned shift = (shiftHi << 6) | shiftLo;
749*9880d681SAndroid Build Coastguard Worker switch (Inst.getOpcode()) {
750*9880d681SAndroid Build Coastguard Worker default:
751*9880d681SAndroid Build Coastguard Worker return Fail;
752*9880d681SAndroid Build Coastguard Worker case AArch64::ADDWrs:
753*9880d681SAndroid Build Coastguard Worker case AArch64::ADDSWrs:
754*9880d681SAndroid Build Coastguard Worker case AArch64::SUBWrs:
755*9880d681SAndroid Build Coastguard Worker case AArch64::SUBSWrs:
756*9880d681SAndroid Build Coastguard Worker // if shift == '11' then ReservedValue()
757*9880d681SAndroid Build Coastguard Worker if (shiftHi == 0x3)
758*9880d681SAndroid Build Coastguard Worker return Fail;
759*9880d681SAndroid Build Coastguard Worker // Deliberate fallthrough
760*9880d681SAndroid Build Coastguard Worker case AArch64::ANDWrs:
761*9880d681SAndroid Build Coastguard Worker case AArch64::ANDSWrs:
762*9880d681SAndroid Build Coastguard Worker case AArch64::BICWrs:
763*9880d681SAndroid Build Coastguard Worker case AArch64::BICSWrs:
764*9880d681SAndroid Build Coastguard Worker case AArch64::ORRWrs:
765*9880d681SAndroid Build Coastguard Worker case AArch64::ORNWrs:
766*9880d681SAndroid Build Coastguard Worker case AArch64::EORWrs:
767*9880d681SAndroid Build Coastguard Worker case AArch64::EONWrs: {
768*9880d681SAndroid Build Coastguard Worker // if sf == '0' and imm6<5> == '1' then ReservedValue()
769*9880d681SAndroid Build Coastguard Worker if (shiftLo >> 5 == 1)
770*9880d681SAndroid Build Coastguard Worker return Fail;
771*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
772*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder);
773*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
774*9880d681SAndroid Build Coastguard Worker break;
775*9880d681SAndroid Build Coastguard Worker }
776*9880d681SAndroid Build Coastguard Worker case AArch64::ADDXrs:
777*9880d681SAndroid Build Coastguard Worker case AArch64::ADDSXrs:
778*9880d681SAndroid Build Coastguard Worker case AArch64::SUBXrs:
779*9880d681SAndroid Build Coastguard Worker case AArch64::SUBSXrs:
780*9880d681SAndroid Build Coastguard Worker // if shift == '11' then ReservedValue()
781*9880d681SAndroid Build Coastguard Worker if (shiftHi == 0x3)
782*9880d681SAndroid Build Coastguard Worker return Fail;
783*9880d681SAndroid Build Coastguard Worker // Deliberate fallthrough
784*9880d681SAndroid Build Coastguard Worker case AArch64::ANDXrs:
785*9880d681SAndroid Build Coastguard Worker case AArch64::ANDSXrs:
786*9880d681SAndroid Build Coastguard Worker case AArch64::BICXrs:
787*9880d681SAndroid Build Coastguard Worker case AArch64::BICSXrs:
788*9880d681SAndroid Build Coastguard Worker case AArch64::ORRXrs:
789*9880d681SAndroid Build Coastguard Worker case AArch64::ORNXrs:
790*9880d681SAndroid Build Coastguard Worker case AArch64::EORXrs:
791*9880d681SAndroid Build Coastguard Worker case AArch64::EONXrs:
792*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
793*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder);
794*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
795*9880d681SAndroid Build Coastguard Worker break;
796*9880d681SAndroid Build Coastguard Worker }
797*9880d681SAndroid Build Coastguard Worker
798*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(shift));
799*9880d681SAndroid Build Coastguard Worker return Success;
800*9880d681SAndroid Build Coastguard Worker }
801*9880d681SAndroid Build Coastguard Worker
DecodeMoveImmInstruction(llvm::MCInst & Inst,uint32_t insn,uint64_t Addr,const void * Decoder)802*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeMoveImmInstruction(llvm::MCInst &Inst, uint32_t insn,
803*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
804*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
805*9880d681SAndroid Build Coastguard Worker unsigned Rd = fieldFromInstruction(insn, 0, 5);
806*9880d681SAndroid Build Coastguard Worker unsigned imm = fieldFromInstruction(insn, 5, 16);
807*9880d681SAndroid Build Coastguard Worker unsigned shift = fieldFromInstruction(insn, 21, 2);
808*9880d681SAndroid Build Coastguard Worker shift <<= 4;
809*9880d681SAndroid Build Coastguard Worker switch (Inst.getOpcode()) {
810*9880d681SAndroid Build Coastguard Worker default:
811*9880d681SAndroid Build Coastguard Worker return Fail;
812*9880d681SAndroid Build Coastguard Worker case AArch64::MOVZWi:
813*9880d681SAndroid Build Coastguard Worker case AArch64::MOVNWi:
814*9880d681SAndroid Build Coastguard Worker case AArch64::MOVKWi:
815*9880d681SAndroid Build Coastguard Worker if (shift & (1U << 5))
816*9880d681SAndroid Build Coastguard Worker return Fail;
817*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
818*9880d681SAndroid Build Coastguard Worker break;
819*9880d681SAndroid Build Coastguard Worker case AArch64::MOVZXi:
820*9880d681SAndroid Build Coastguard Worker case AArch64::MOVNXi:
821*9880d681SAndroid Build Coastguard Worker case AArch64::MOVKXi:
822*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
823*9880d681SAndroid Build Coastguard Worker break;
824*9880d681SAndroid Build Coastguard Worker }
825*9880d681SAndroid Build Coastguard Worker
826*9880d681SAndroid Build Coastguard Worker if (Inst.getOpcode() == AArch64::MOVKWi ||
827*9880d681SAndroid Build Coastguard Worker Inst.getOpcode() == AArch64::MOVKXi)
828*9880d681SAndroid Build Coastguard Worker Inst.addOperand(Inst.getOperand(0));
829*9880d681SAndroid Build Coastguard Worker
830*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(imm));
831*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(shift));
832*9880d681SAndroid Build Coastguard Worker return Success;
833*9880d681SAndroid Build Coastguard Worker }
834*9880d681SAndroid Build Coastguard Worker
DecodeUnsignedLdStInstruction(llvm::MCInst & Inst,uint32_t insn,uint64_t Addr,const void * Decoder)835*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeUnsignedLdStInstruction(llvm::MCInst &Inst,
836*9880d681SAndroid Build Coastguard Worker uint32_t insn, uint64_t Addr,
837*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
838*9880d681SAndroid Build Coastguard Worker unsigned Rt = fieldFromInstruction(insn, 0, 5);
839*9880d681SAndroid Build Coastguard Worker unsigned Rn = fieldFromInstruction(insn, 5, 5);
840*9880d681SAndroid Build Coastguard Worker unsigned offset = fieldFromInstruction(insn, 10, 12);
841*9880d681SAndroid Build Coastguard Worker const AArch64Disassembler *Dis =
842*9880d681SAndroid Build Coastguard Worker static_cast<const AArch64Disassembler *>(Decoder);
843*9880d681SAndroid Build Coastguard Worker
844*9880d681SAndroid Build Coastguard Worker switch (Inst.getOpcode()) {
845*9880d681SAndroid Build Coastguard Worker default:
846*9880d681SAndroid Build Coastguard Worker return Fail;
847*9880d681SAndroid Build Coastguard Worker case AArch64::PRFMui:
848*9880d681SAndroid Build Coastguard Worker // Rt is an immediate in prefetch.
849*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(Rt));
850*9880d681SAndroid Build Coastguard Worker break;
851*9880d681SAndroid Build Coastguard Worker case AArch64::STRBBui:
852*9880d681SAndroid Build Coastguard Worker case AArch64::LDRBBui:
853*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSBWui:
854*9880d681SAndroid Build Coastguard Worker case AArch64::STRHHui:
855*9880d681SAndroid Build Coastguard Worker case AArch64::LDRHHui:
856*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSHWui:
857*9880d681SAndroid Build Coastguard Worker case AArch64::STRWui:
858*9880d681SAndroid Build Coastguard Worker case AArch64::LDRWui:
859*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
860*9880d681SAndroid Build Coastguard Worker break;
861*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSBXui:
862*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSHXui:
863*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSWui:
864*9880d681SAndroid Build Coastguard Worker case AArch64::STRXui:
865*9880d681SAndroid Build Coastguard Worker case AArch64::LDRXui:
866*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
867*9880d681SAndroid Build Coastguard Worker break;
868*9880d681SAndroid Build Coastguard Worker case AArch64::LDRQui:
869*9880d681SAndroid Build Coastguard Worker case AArch64::STRQui:
870*9880d681SAndroid Build Coastguard Worker DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
871*9880d681SAndroid Build Coastguard Worker break;
872*9880d681SAndroid Build Coastguard Worker case AArch64::LDRDui:
873*9880d681SAndroid Build Coastguard Worker case AArch64::STRDui:
874*9880d681SAndroid Build Coastguard Worker DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
875*9880d681SAndroid Build Coastguard Worker break;
876*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSui:
877*9880d681SAndroid Build Coastguard Worker case AArch64::STRSui:
878*9880d681SAndroid Build Coastguard Worker DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
879*9880d681SAndroid Build Coastguard Worker break;
880*9880d681SAndroid Build Coastguard Worker case AArch64::LDRHui:
881*9880d681SAndroid Build Coastguard Worker case AArch64::STRHui:
882*9880d681SAndroid Build Coastguard Worker DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
883*9880d681SAndroid Build Coastguard Worker break;
884*9880d681SAndroid Build Coastguard Worker case AArch64::LDRBui:
885*9880d681SAndroid Build Coastguard Worker case AArch64::STRBui:
886*9880d681SAndroid Build Coastguard Worker DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
887*9880d681SAndroid Build Coastguard Worker break;
888*9880d681SAndroid Build Coastguard Worker }
889*9880d681SAndroid Build Coastguard Worker
890*9880d681SAndroid Build Coastguard Worker DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
891*9880d681SAndroid Build Coastguard Worker if (!Dis->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 4))
892*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(offset));
893*9880d681SAndroid Build Coastguard Worker return Success;
894*9880d681SAndroid Build Coastguard Worker }
895*9880d681SAndroid Build Coastguard Worker
DecodeSignedLdStInstruction(llvm::MCInst & Inst,uint32_t insn,uint64_t Addr,const void * Decoder)896*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeSignedLdStInstruction(llvm::MCInst &Inst,
897*9880d681SAndroid Build Coastguard Worker uint32_t insn, uint64_t Addr,
898*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
899*9880d681SAndroid Build Coastguard Worker unsigned Rt = fieldFromInstruction(insn, 0, 5);
900*9880d681SAndroid Build Coastguard Worker unsigned Rn = fieldFromInstruction(insn, 5, 5);
901*9880d681SAndroid Build Coastguard Worker int64_t offset = fieldFromInstruction(insn, 12, 9);
902*9880d681SAndroid Build Coastguard Worker
903*9880d681SAndroid Build Coastguard Worker // offset is a 9-bit signed immediate, so sign extend it to
904*9880d681SAndroid Build Coastguard Worker // fill the unsigned.
905*9880d681SAndroid Build Coastguard Worker if (offset & (1 << (9 - 1)))
906*9880d681SAndroid Build Coastguard Worker offset |= ~((1LL << 9) - 1);
907*9880d681SAndroid Build Coastguard Worker
908*9880d681SAndroid Build Coastguard Worker // First operand is always the writeback to the address register, if needed.
909*9880d681SAndroid Build Coastguard Worker switch (Inst.getOpcode()) {
910*9880d681SAndroid Build Coastguard Worker default:
911*9880d681SAndroid Build Coastguard Worker break;
912*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSBWpre:
913*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSHWpre:
914*9880d681SAndroid Build Coastguard Worker case AArch64::STRBBpre:
915*9880d681SAndroid Build Coastguard Worker case AArch64::LDRBBpre:
916*9880d681SAndroid Build Coastguard Worker case AArch64::STRHHpre:
917*9880d681SAndroid Build Coastguard Worker case AArch64::LDRHHpre:
918*9880d681SAndroid Build Coastguard Worker case AArch64::STRWpre:
919*9880d681SAndroid Build Coastguard Worker case AArch64::LDRWpre:
920*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSBWpost:
921*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSHWpost:
922*9880d681SAndroid Build Coastguard Worker case AArch64::STRBBpost:
923*9880d681SAndroid Build Coastguard Worker case AArch64::LDRBBpost:
924*9880d681SAndroid Build Coastguard Worker case AArch64::STRHHpost:
925*9880d681SAndroid Build Coastguard Worker case AArch64::LDRHHpost:
926*9880d681SAndroid Build Coastguard Worker case AArch64::STRWpost:
927*9880d681SAndroid Build Coastguard Worker case AArch64::LDRWpost:
928*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSBXpre:
929*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSHXpre:
930*9880d681SAndroid Build Coastguard Worker case AArch64::STRXpre:
931*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSWpre:
932*9880d681SAndroid Build Coastguard Worker case AArch64::LDRXpre:
933*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSBXpost:
934*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSHXpost:
935*9880d681SAndroid Build Coastguard Worker case AArch64::STRXpost:
936*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSWpost:
937*9880d681SAndroid Build Coastguard Worker case AArch64::LDRXpost:
938*9880d681SAndroid Build Coastguard Worker case AArch64::LDRQpre:
939*9880d681SAndroid Build Coastguard Worker case AArch64::STRQpre:
940*9880d681SAndroid Build Coastguard Worker case AArch64::LDRQpost:
941*9880d681SAndroid Build Coastguard Worker case AArch64::STRQpost:
942*9880d681SAndroid Build Coastguard Worker case AArch64::LDRDpre:
943*9880d681SAndroid Build Coastguard Worker case AArch64::STRDpre:
944*9880d681SAndroid Build Coastguard Worker case AArch64::LDRDpost:
945*9880d681SAndroid Build Coastguard Worker case AArch64::STRDpost:
946*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSpre:
947*9880d681SAndroid Build Coastguard Worker case AArch64::STRSpre:
948*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSpost:
949*9880d681SAndroid Build Coastguard Worker case AArch64::STRSpost:
950*9880d681SAndroid Build Coastguard Worker case AArch64::LDRHpre:
951*9880d681SAndroid Build Coastguard Worker case AArch64::STRHpre:
952*9880d681SAndroid Build Coastguard Worker case AArch64::LDRHpost:
953*9880d681SAndroid Build Coastguard Worker case AArch64::STRHpost:
954*9880d681SAndroid Build Coastguard Worker case AArch64::LDRBpre:
955*9880d681SAndroid Build Coastguard Worker case AArch64::STRBpre:
956*9880d681SAndroid Build Coastguard Worker case AArch64::LDRBpost:
957*9880d681SAndroid Build Coastguard Worker case AArch64::STRBpost:
958*9880d681SAndroid Build Coastguard Worker DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
959*9880d681SAndroid Build Coastguard Worker break;
960*9880d681SAndroid Build Coastguard Worker }
961*9880d681SAndroid Build Coastguard Worker
962*9880d681SAndroid Build Coastguard Worker switch (Inst.getOpcode()) {
963*9880d681SAndroid Build Coastguard Worker default:
964*9880d681SAndroid Build Coastguard Worker return Fail;
965*9880d681SAndroid Build Coastguard Worker case AArch64::PRFUMi:
966*9880d681SAndroid Build Coastguard Worker // Rt is an immediate in prefetch.
967*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(Rt));
968*9880d681SAndroid Build Coastguard Worker break;
969*9880d681SAndroid Build Coastguard Worker case AArch64::STURBBi:
970*9880d681SAndroid Build Coastguard Worker case AArch64::LDURBBi:
971*9880d681SAndroid Build Coastguard Worker case AArch64::LDURSBWi:
972*9880d681SAndroid Build Coastguard Worker case AArch64::STURHHi:
973*9880d681SAndroid Build Coastguard Worker case AArch64::LDURHHi:
974*9880d681SAndroid Build Coastguard Worker case AArch64::LDURSHWi:
975*9880d681SAndroid Build Coastguard Worker case AArch64::STURWi:
976*9880d681SAndroid Build Coastguard Worker case AArch64::LDURWi:
977*9880d681SAndroid Build Coastguard Worker case AArch64::LDTRSBWi:
978*9880d681SAndroid Build Coastguard Worker case AArch64::LDTRSHWi:
979*9880d681SAndroid Build Coastguard Worker case AArch64::STTRWi:
980*9880d681SAndroid Build Coastguard Worker case AArch64::LDTRWi:
981*9880d681SAndroid Build Coastguard Worker case AArch64::STTRHi:
982*9880d681SAndroid Build Coastguard Worker case AArch64::LDTRHi:
983*9880d681SAndroid Build Coastguard Worker case AArch64::LDTRBi:
984*9880d681SAndroid Build Coastguard Worker case AArch64::STTRBi:
985*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSBWpre:
986*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSHWpre:
987*9880d681SAndroid Build Coastguard Worker case AArch64::STRBBpre:
988*9880d681SAndroid Build Coastguard Worker case AArch64::LDRBBpre:
989*9880d681SAndroid Build Coastguard Worker case AArch64::STRHHpre:
990*9880d681SAndroid Build Coastguard Worker case AArch64::LDRHHpre:
991*9880d681SAndroid Build Coastguard Worker case AArch64::STRWpre:
992*9880d681SAndroid Build Coastguard Worker case AArch64::LDRWpre:
993*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSBWpost:
994*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSHWpost:
995*9880d681SAndroid Build Coastguard Worker case AArch64::STRBBpost:
996*9880d681SAndroid Build Coastguard Worker case AArch64::LDRBBpost:
997*9880d681SAndroid Build Coastguard Worker case AArch64::STRHHpost:
998*9880d681SAndroid Build Coastguard Worker case AArch64::LDRHHpost:
999*9880d681SAndroid Build Coastguard Worker case AArch64::STRWpost:
1000*9880d681SAndroid Build Coastguard Worker case AArch64::LDRWpost:
1001*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
1002*9880d681SAndroid Build Coastguard Worker break;
1003*9880d681SAndroid Build Coastguard Worker case AArch64::LDURSBXi:
1004*9880d681SAndroid Build Coastguard Worker case AArch64::LDURSHXi:
1005*9880d681SAndroid Build Coastguard Worker case AArch64::LDURSWi:
1006*9880d681SAndroid Build Coastguard Worker case AArch64::STURXi:
1007*9880d681SAndroid Build Coastguard Worker case AArch64::LDURXi:
1008*9880d681SAndroid Build Coastguard Worker case AArch64::LDTRSBXi:
1009*9880d681SAndroid Build Coastguard Worker case AArch64::LDTRSHXi:
1010*9880d681SAndroid Build Coastguard Worker case AArch64::LDTRSWi:
1011*9880d681SAndroid Build Coastguard Worker case AArch64::STTRXi:
1012*9880d681SAndroid Build Coastguard Worker case AArch64::LDTRXi:
1013*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSBXpre:
1014*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSHXpre:
1015*9880d681SAndroid Build Coastguard Worker case AArch64::STRXpre:
1016*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSWpre:
1017*9880d681SAndroid Build Coastguard Worker case AArch64::LDRXpre:
1018*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSBXpost:
1019*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSHXpost:
1020*9880d681SAndroid Build Coastguard Worker case AArch64::STRXpost:
1021*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSWpost:
1022*9880d681SAndroid Build Coastguard Worker case AArch64::LDRXpost:
1023*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
1024*9880d681SAndroid Build Coastguard Worker break;
1025*9880d681SAndroid Build Coastguard Worker case AArch64::LDURQi:
1026*9880d681SAndroid Build Coastguard Worker case AArch64::STURQi:
1027*9880d681SAndroid Build Coastguard Worker case AArch64::LDRQpre:
1028*9880d681SAndroid Build Coastguard Worker case AArch64::STRQpre:
1029*9880d681SAndroid Build Coastguard Worker case AArch64::LDRQpost:
1030*9880d681SAndroid Build Coastguard Worker case AArch64::STRQpost:
1031*9880d681SAndroid Build Coastguard Worker DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
1032*9880d681SAndroid Build Coastguard Worker break;
1033*9880d681SAndroid Build Coastguard Worker case AArch64::LDURDi:
1034*9880d681SAndroid Build Coastguard Worker case AArch64::STURDi:
1035*9880d681SAndroid Build Coastguard Worker case AArch64::LDRDpre:
1036*9880d681SAndroid Build Coastguard Worker case AArch64::STRDpre:
1037*9880d681SAndroid Build Coastguard Worker case AArch64::LDRDpost:
1038*9880d681SAndroid Build Coastguard Worker case AArch64::STRDpost:
1039*9880d681SAndroid Build Coastguard Worker DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
1040*9880d681SAndroid Build Coastguard Worker break;
1041*9880d681SAndroid Build Coastguard Worker case AArch64::LDURSi:
1042*9880d681SAndroid Build Coastguard Worker case AArch64::STURSi:
1043*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSpre:
1044*9880d681SAndroid Build Coastguard Worker case AArch64::STRSpre:
1045*9880d681SAndroid Build Coastguard Worker case AArch64::LDRSpost:
1046*9880d681SAndroid Build Coastguard Worker case AArch64::STRSpost:
1047*9880d681SAndroid Build Coastguard Worker DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
1048*9880d681SAndroid Build Coastguard Worker break;
1049*9880d681SAndroid Build Coastguard Worker case AArch64::LDURHi:
1050*9880d681SAndroid Build Coastguard Worker case AArch64::STURHi:
1051*9880d681SAndroid Build Coastguard Worker case AArch64::LDRHpre:
1052*9880d681SAndroid Build Coastguard Worker case AArch64::STRHpre:
1053*9880d681SAndroid Build Coastguard Worker case AArch64::LDRHpost:
1054*9880d681SAndroid Build Coastguard Worker case AArch64::STRHpost:
1055*9880d681SAndroid Build Coastguard Worker DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
1056*9880d681SAndroid Build Coastguard Worker break;
1057*9880d681SAndroid Build Coastguard Worker case AArch64::LDURBi:
1058*9880d681SAndroid Build Coastguard Worker case AArch64::STURBi:
1059*9880d681SAndroid Build Coastguard Worker case AArch64::LDRBpre:
1060*9880d681SAndroid Build Coastguard Worker case AArch64::STRBpre:
1061*9880d681SAndroid Build Coastguard Worker case AArch64::LDRBpost:
1062*9880d681SAndroid Build Coastguard Worker case AArch64::STRBpost:
1063*9880d681SAndroid Build Coastguard Worker DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
1064*9880d681SAndroid Build Coastguard Worker break;
1065*9880d681SAndroid Build Coastguard Worker }
1066*9880d681SAndroid Build Coastguard Worker
1067*9880d681SAndroid Build Coastguard Worker DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1068*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(offset));
1069*9880d681SAndroid Build Coastguard Worker
1070*9880d681SAndroid Build Coastguard Worker bool IsLoad = fieldFromInstruction(insn, 22, 1);
1071*9880d681SAndroid Build Coastguard Worker bool IsIndexed = fieldFromInstruction(insn, 10, 2) != 0;
1072*9880d681SAndroid Build Coastguard Worker bool IsFP = fieldFromInstruction(insn, 26, 1);
1073*9880d681SAndroid Build Coastguard Worker
1074*9880d681SAndroid Build Coastguard Worker // Cannot write back to a transfer register (but xzr != sp).
1075*9880d681SAndroid Build Coastguard Worker if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn)
1076*9880d681SAndroid Build Coastguard Worker return SoftFail;
1077*9880d681SAndroid Build Coastguard Worker
1078*9880d681SAndroid Build Coastguard Worker return Success;
1079*9880d681SAndroid Build Coastguard Worker }
1080*9880d681SAndroid Build Coastguard Worker
DecodeExclusiveLdStInstruction(llvm::MCInst & Inst,uint32_t insn,uint64_t Addr,const void * Decoder)1081*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeExclusiveLdStInstruction(llvm::MCInst &Inst,
1082*9880d681SAndroid Build Coastguard Worker uint32_t insn, uint64_t Addr,
1083*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
1084*9880d681SAndroid Build Coastguard Worker unsigned Rt = fieldFromInstruction(insn, 0, 5);
1085*9880d681SAndroid Build Coastguard Worker unsigned Rn = fieldFromInstruction(insn, 5, 5);
1086*9880d681SAndroid Build Coastguard Worker unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
1087*9880d681SAndroid Build Coastguard Worker unsigned Rs = fieldFromInstruction(insn, 16, 5);
1088*9880d681SAndroid Build Coastguard Worker
1089*9880d681SAndroid Build Coastguard Worker unsigned Opcode = Inst.getOpcode();
1090*9880d681SAndroid Build Coastguard Worker switch (Opcode) {
1091*9880d681SAndroid Build Coastguard Worker default:
1092*9880d681SAndroid Build Coastguard Worker return Fail;
1093*9880d681SAndroid Build Coastguard Worker case AArch64::STLXRW:
1094*9880d681SAndroid Build Coastguard Worker case AArch64::STLXRB:
1095*9880d681SAndroid Build Coastguard Worker case AArch64::STLXRH:
1096*9880d681SAndroid Build Coastguard Worker case AArch64::STXRW:
1097*9880d681SAndroid Build Coastguard Worker case AArch64::STXRB:
1098*9880d681SAndroid Build Coastguard Worker case AArch64::STXRH:
1099*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
1100*9880d681SAndroid Build Coastguard Worker // FALLTHROUGH
1101*9880d681SAndroid Build Coastguard Worker case AArch64::LDARW:
1102*9880d681SAndroid Build Coastguard Worker case AArch64::LDARB:
1103*9880d681SAndroid Build Coastguard Worker case AArch64::LDARH:
1104*9880d681SAndroid Build Coastguard Worker case AArch64::LDAXRW:
1105*9880d681SAndroid Build Coastguard Worker case AArch64::LDAXRB:
1106*9880d681SAndroid Build Coastguard Worker case AArch64::LDAXRH:
1107*9880d681SAndroid Build Coastguard Worker case AArch64::LDXRW:
1108*9880d681SAndroid Build Coastguard Worker case AArch64::LDXRB:
1109*9880d681SAndroid Build Coastguard Worker case AArch64::LDXRH:
1110*9880d681SAndroid Build Coastguard Worker case AArch64::STLRW:
1111*9880d681SAndroid Build Coastguard Worker case AArch64::STLRB:
1112*9880d681SAndroid Build Coastguard Worker case AArch64::STLRH:
1113*9880d681SAndroid Build Coastguard Worker case AArch64::STLLRW:
1114*9880d681SAndroid Build Coastguard Worker case AArch64::STLLRB:
1115*9880d681SAndroid Build Coastguard Worker case AArch64::STLLRH:
1116*9880d681SAndroid Build Coastguard Worker case AArch64::LDLARW:
1117*9880d681SAndroid Build Coastguard Worker case AArch64::LDLARB:
1118*9880d681SAndroid Build Coastguard Worker case AArch64::LDLARH:
1119*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
1120*9880d681SAndroid Build Coastguard Worker break;
1121*9880d681SAndroid Build Coastguard Worker case AArch64::STLXRX:
1122*9880d681SAndroid Build Coastguard Worker case AArch64::STXRX:
1123*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
1124*9880d681SAndroid Build Coastguard Worker // FALLTHROUGH
1125*9880d681SAndroid Build Coastguard Worker case AArch64::LDARX:
1126*9880d681SAndroid Build Coastguard Worker case AArch64::LDAXRX:
1127*9880d681SAndroid Build Coastguard Worker case AArch64::LDXRX:
1128*9880d681SAndroid Build Coastguard Worker case AArch64::STLRX:
1129*9880d681SAndroid Build Coastguard Worker case AArch64::LDLARX:
1130*9880d681SAndroid Build Coastguard Worker case AArch64::STLLRX:
1131*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
1132*9880d681SAndroid Build Coastguard Worker break;
1133*9880d681SAndroid Build Coastguard Worker case AArch64::STLXPW:
1134*9880d681SAndroid Build Coastguard Worker case AArch64::STXPW:
1135*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
1136*9880d681SAndroid Build Coastguard Worker // FALLTHROUGH
1137*9880d681SAndroid Build Coastguard Worker case AArch64::LDAXPW:
1138*9880d681SAndroid Build Coastguard Worker case AArch64::LDXPW:
1139*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
1140*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);
1141*9880d681SAndroid Build Coastguard Worker break;
1142*9880d681SAndroid Build Coastguard Worker case AArch64::STLXPX:
1143*9880d681SAndroid Build Coastguard Worker case AArch64::STXPX:
1144*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
1145*9880d681SAndroid Build Coastguard Worker // FALLTHROUGH
1146*9880d681SAndroid Build Coastguard Worker case AArch64::LDAXPX:
1147*9880d681SAndroid Build Coastguard Worker case AArch64::LDXPX:
1148*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
1149*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);
1150*9880d681SAndroid Build Coastguard Worker break;
1151*9880d681SAndroid Build Coastguard Worker }
1152*9880d681SAndroid Build Coastguard Worker
1153*9880d681SAndroid Build Coastguard Worker DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1154*9880d681SAndroid Build Coastguard Worker
1155*9880d681SAndroid Build Coastguard Worker // You shouldn't load to the same register twice in an instruction...
1156*9880d681SAndroid Build Coastguard Worker if ((Opcode == AArch64::LDAXPW || Opcode == AArch64::LDXPW ||
1157*9880d681SAndroid Build Coastguard Worker Opcode == AArch64::LDAXPX || Opcode == AArch64::LDXPX) &&
1158*9880d681SAndroid Build Coastguard Worker Rt == Rt2)
1159*9880d681SAndroid Build Coastguard Worker return SoftFail;
1160*9880d681SAndroid Build Coastguard Worker
1161*9880d681SAndroid Build Coastguard Worker return Success;
1162*9880d681SAndroid Build Coastguard Worker }
1163*9880d681SAndroid Build Coastguard Worker
DecodePairLdStInstruction(llvm::MCInst & Inst,uint32_t insn,uint64_t Addr,const void * Decoder)1164*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodePairLdStInstruction(llvm::MCInst &Inst, uint32_t insn,
1165*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
1166*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
1167*9880d681SAndroid Build Coastguard Worker unsigned Rt = fieldFromInstruction(insn, 0, 5);
1168*9880d681SAndroid Build Coastguard Worker unsigned Rn = fieldFromInstruction(insn, 5, 5);
1169*9880d681SAndroid Build Coastguard Worker unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
1170*9880d681SAndroid Build Coastguard Worker int64_t offset = fieldFromInstruction(insn, 15, 7);
1171*9880d681SAndroid Build Coastguard Worker bool IsLoad = fieldFromInstruction(insn, 22, 1);
1172*9880d681SAndroid Build Coastguard Worker
1173*9880d681SAndroid Build Coastguard Worker // offset is a 7-bit signed immediate, so sign extend it to
1174*9880d681SAndroid Build Coastguard Worker // fill the unsigned.
1175*9880d681SAndroid Build Coastguard Worker if (offset & (1 << (7 - 1)))
1176*9880d681SAndroid Build Coastguard Worker offset |= ~((1LL << 7) - 1);
1177*9880d681SAndroid Build Coastguard Worker
1178*9880d681SAndroid Build Coastguard Worker unsigned Opcode = Inst.getOpcode();
1179*9880d681SAndroid Build Coastguard Worker bool NeedsDisjointWritebackTransfer = false;
1180*9880d681SAndroid Build Coastguard Worker
1181*9880d681SAndroid Build Coastguard Worker // First operand is always writeback of base register.
1182*9880d681SAndroid Build Coastguard Worker switch (Opcode) {
1183*9880d681SAndroid Build Coastguard Worker default:
1184*9880d681SAndroid Build Coastguard Worker break;
1185*9880d681SAndroid Build Coastguard Worker case AArch64::LDPXpost:
1186*9880d681SAndroid Build Coastguard Worker case AArch64::STPXpost:
1187*9880d681SAndroid Build Coastguard Worker case AArch64::LDPSWpost:
1188*9880d681SAndroid Build Coastguard Worker case AArch64::LDPXpre:
1189*9880d681SAndroid Build Coastguard Worker case AArch64::STPXpre:
1190*9880d681SAndroid Build Coastguard Worker case AArch64::LDPSWpre:
1191*9880d681SAndroid Build Coastguard Worker case AArch64::LDPWpost:
1192*9880d681SAndroid Build Coastguard Worker case AArch64::STPWpost:
1193*9880d681SAndroid Build Coastguard Worker case AArch64::LDPWpre:
1194*9880d681SAndroid Build Coastguard Worker case AArch64::STPWpre:
1195*9880d681SAndroid Build Coastguard Worker case AArch64::LDPQpost:
1196*9880d681SAndroid Build Coastguard Worker case AArch64::STPQpost:
1197*9880d681SAndroid Build Coastguard Worker case AArch64::LDPQpre:
1198*9880d681SAndroid Build Coastguard Worker case AArch64::STPQpre:
1199*9880d681SAndroid Build Coastguard Worker case AArch64::LDPDpost:
1200*9880d681SAndroid Build Coastguard Worker case AArch64::STPDpost:
1201*9880d681SAndroid Build Coastguard Worker case AArch64::LDPDpre:
1202*9880d681SAndroid Build Coastguard Worker case AArch64::STPDpre:
1203*9880d681SAndroid Build Coastguard Worker case AArch64::LDPSpost:
1204*9880d681SAndroid Build Coastguard Worker case AArch64::STPSpost:
1205*9880d681SAndroid Build Coastguard Worker case AArch64::LDPSpre:
1206*9880d681SAndroid Build Coastguard Worker case AArch64::STPSpre:
1207*9880d681SAndroid Build Coastguard Worker DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1208*9880d681SAndroid Build Coastguard Worker break;
1209*9880d681SAndroid Build Coastguard Worker }
1210*9880d681SAndroid Build Coastguard Worker
1211*9880d681SAndroid Build Coastguard Worker switch (Opcode) {
1212*9880d681SAndroid Build Coastguard Worker default:
1213*9880d681SAndroid Build Coastguard Worker return Fail;
1214*9880d681SAndroid Build Coastguard Worker case AArch64::LDPXpost:
1215*9880d681SAndroid Build Coastguard Worker case AArch64::STPXpost:
1216*9880d681SAndroid Build Coastguard Worker case AArch64::LDPSWpost:
1217*9880d681SAndroid Build Coastguard Worker case AArch64::LDPXpre:
1218*9880d681SAndroid Build Coastguard Worker case AArch64::STPXpre:
1219*9880d681SAndroid Build Coastguard Worker case AArch64::LDPSWpre:
1220*9880d681SAndroid Build Coastguard Worker NeedsDisjointWritebackTransfer = true;
1221*9880d681SAndroid Build Coastguard Worker // Fallthrough
1222*9880d681SAndroid Build Coastguard Worker case AArch64::LDNPXi:
1223*9880d681SAndroid Build Coastguard Worker case AArch64::STNPXi:
1224*9880d681SAndroid Build Coastguard Worker case AArch64::LDPXi:
1225*9880d681SAndroid Build Coastguard Worker case AArch64::STPXi:
1226*9880d681SAndroid Build Coastguard Worker case AArch64::LDPSWi:
1227*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
1228*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);
1229*9880d681SAndroid Build Coastguard Worker break;
1230*9880d681SAndroid Build Coastguard Worker case AArch64::LDPWpost:
1231*9880d681SAndroid Build Coastguard Worker case AArch64::STPWpost:
1232*9880d681SAndroid Build Coastguard Worker case AArch64::LDPWpre:
1233*9880d681SAndroid Build Coastguard Worker case AArch64::STPWpre:
1234*9880d681SAndroid Build Coastguard Worker NeedsDisjointWritebackTransfer = true;
1235*9880d681SAndroid Build Coastguard Worker // Fallthrough
1236*9880d681SAndroid Build Coastguard Worker case AArch64::LDNPWi:
1237*9880d681SAndroid Build Coastguard Worker case AArch64::STNPWi:
1238*9880d681SAndroid Build Coastguard Worker case AArch64::LDPWi:
1239*9880d681SAndroid Build Coastguard Worker case AArch64::STPWi:
1240*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
1241*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);
1242*9880d681SAndroid Build Coastguard Worker break;
1243*9880d681SAndroid Build Coastguard Worker case AArch64::LDNPQi:
1244*9880d681SAndroid Build Coastguard Worker case AArch64::STNPQi:
1245*9880d681SAndroid Build Coastguard Worker case AArch64::LDPQpost:
1246*9880d681SAndroid Build Coastguard Worker case AArch64::STPQpost:
1247*9880d681SAndroid Build Coastguard Worker case AArch64::LDPQi:
1248*9880d681SAndroid Build Coastguard Worker case AArch64::STPQi:
1249*9880d681SAndroid Build Coastguard Worker case AArch64::LDPQpre:
1250*9880d681SAndroid Build Coastguard Worker case AArch64::STPQpre:
1251*9880d681SAndroid Build Coastguard Worker DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
1252*9880d681SAndroid Build Coastguard Worker DecodeFPR128RegisterClass(Inst, Rt2, Addr, Decoder);
1253*9880d681SAndroid Build Coastguard Worker break;
1254*9880d681SAndroid Build Coastguard Worker case AArch64::LDNPDi:
1255*9880d681SAndroid Build Coastguard Worker case AArch64::STNPDi:
1256*9880d681SAndroid Build Coastguard Worker case AArch64::LDPDpost:
1257*9880d681SAndroid Build Coastguard Worker case AArch64::STPDpost:
1258*9880d681SAndroid Build Coastguard Worker case AArch64::LDPDi:
1259*9880d681SAndroid Build Coastguard Worker case AArch64::STPDi:
1260*9880d681SAndroid Build Coastguard Worker case AArch64::LDPDpre:
1261*9880d681SAndroid Build Coastguard Worker case AArch64::STPDpre:
1262*9880d681SAndroid Build Coastguard Worker DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
1263*9880d681SAndroid Build Coastguard Worker DecodeFPR64RegisterClass(Inst, Rt2, Addr, Decoder);
1264*9880d681SAndroid Build Coastguard Worker break;
1265*9880d681SAndroid Build Coastguard Worker case AArch64::LDNPSi:
1266*9880d681SAndroid Build Coastguard Worker case AArch64::STNPSi:
1267*9880d681SAndroid Build Coastguard Worker case AArch64::LDPSpost:
1268*9880d681SAndroid Build Coastguard Worker case AArch64::STPSpost:
1269*9880d681SAndroid Build Coastguard Worker case AArch64::LDPSi:
1270*9880d681SAndroid Build Coastguard Worker case AArch64::STPSi:
1271*9880d681SAndroid Build Coastguard Worker case AArch64::LDPSpre:
1272*9880d681SAndroid Build Coastguard Worker case AArch64::STPSpre:
1273*9880d681SAndroid Build Coastguard Worker DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
1274*9880d681SAndroid Build Coastguard Worker DecodeFPR32RegisterClass(Inst, Rt2, Addr, Decoder);
1275*9880d681SAndroid Build Coastguard Worker break;
1276*9880d681SAndroid Build Coastguard Worker }
1277*9880d681SAndroid Build Coastguard Worker
1278*9880d681SAndroid Build Coastguard Worker DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1279*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(offset));
1280*9880d681SAndroid Build Coastguard Worker
1281*9880d681SAndroid Build Coastguard Worker // You shouldn't load to the same register twice in an instruction...
1282*9880d681SAndroid Build Coastguard Worker if (IsLoad && Rt == Rt2)
1283*9880d681SAndroid Build Coastguard Worker return SoftFail;
1284*9880d681SAndroid Build Coastguard Worker
1285*9880d681SAndroid Build Coastguard Worker // ... or do any operation that writes-back to a transfer register. But note
1286*9880d681SAndroid Build Coastguard Worker // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.
1287*9880d681SAndroid Build Coastguard Worker if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn))
1288*9880d681SAndroid Build Coastguard Worker return SoftFail;
1289*9880d681SAndroid Build Coastguard Worker
1290*9880d681SAndroid Build Coastguard Worker return Success;
1291*9880d681SAndroid Build Coastguard Worker }
1292*9880d681SAndroid Build Coastguard Worker
DecodeAddSubERegInstruction(llvm::MCInst & Inst,uint32_t insn,uint64_t Addr,const void * Decoder)1293*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeAddSubERegInstruction(llvm::MCInst &Inst,
1294*9880d681SAndroid Build Coastguard Worker uint32_t insn, uint64_t Addr,
1295*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
1296*9880d681SAndroid Build Coastguard Worker unsigned Rd = fieldFromInstruction(insn, 0, 5);
1297*9880d681SAndroid Build Coastguard Worker unsigned Rn = fieldFromInstruction(insn, 5, 5);
1298*9880d681SAndroid Build Coastguard Worker unsigned Rm = fieldFromInstruction(insn, 16, 5);
1299*9880d681SAndroid Build Coastguard Worker unsigned extend = fieldFromInstruction(insn, 10, 6);
1300*9880d681SAndroid Build Coastguard Worker
1301*9880d681SAndroid Build Coastguard Worker unsigned shift = extend & 0x7;
1302*9880d681SAndroid Build Coastguard Worker if (shift > 4)
1303*9880d681SAndroid Build Coastguard Worker return Fail;
1304*9880d681SAndroid Build Coastguard Worker
1305*9880d681SAndroid Build Coastguard Worker switch (Inst.getOpcode()) {
1306*9880d681SAndroid Build Coastguard Worker default:
1307*9880d681SAndroid Build Coastguard Worker return Fail;
1308*9880d681SAndroid Build Coastguard Worker case AArch64::ADDWrx:
1309*9880d681SAndroid Build Coastguard Worker case AArch64::SUBWrx:
1310*9880d681SAndroid Build Coastguard Worker DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
1311*9880d681SAndroid Build Coastguard Worker DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
1312*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
1313*9880d681SAndroid Build Coastguard Worker break;
1314*9880d681SAndroid Build Coastguard Worker case AArch64::ADDSWrx:
1315*9880d681SAndroid Build Coastguard Worker case AArch64::SUBSWrx:
1316*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
1317*9880d681SAndroid Build Coastguard Worker DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
1318*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
1319*9880d681SAndroid Build Coastguard Worker break;
1320*9880d681SAndroid Build Coastguard Worker case AArch64::ADDXrx:
1321*9880d681SAndroid Build Coastguard Worker case AArch64::SUBXrx:
1322*9880d681SAndroid Build Coastguard Worker DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
1323*9880d681SAndroid Build Coastguard Worker DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1324*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
1325*9880d681SAndroid Build Coastguard Worker break;
1326*9880d681SAndroid Build Coastguard Worker case AArch64::ADDSXrx:
1327*9880d681SAndroid Build Coastguard Worker case AArch64::SUBSXrx:
1328*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
1329*9880d681SAndroid Build Coastguard Worker DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1330*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
1331*9880d681SAndroid Build Coastguard Worker break;
1332*9880d681SAndroid Build Coastguard Worker case AArch64::ADDXrx64:
1333*9880d681SAndroid Build Coastguard Worker case AArch64::SUBXrx64:
1334*9880d681SAndroid Build Coastguard Worker DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
1335*9880d681SAndroid Build Coastguard Worker DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1336*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
1337*9880d681SAndroid Build Coastguard Worker break;
1338*9880d681SAndroid Build Coastguard Worker case AArch64::SUBSXrx64:
1339*9880d681SAndroid Build Coastguard Worker case AArch64::ADDSXrx64:
1340*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
1341*9880d681SAndroid Build Coastguard Worker DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1342*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
1343*9880d681SAndroid Build Coastguard Worker break;
1344*9880d681SAndroid Build Coastguard Worker }
1345*9880d681SAndroid Build Coastguard Worker
1346*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(extend));
1347*9880d681SAndroid Build Coastguard Worker return Success;
1348*9880d681SAndroid Build Coastguard Worker }
1349*9880d681SAndroid Build Coastguard Worker
DecodeLogicalImmInstruction(llvm::MCInst & Inst,uint32_t insn,uint64_t Addr,const void * Decoder)1350*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeLogicalImmInstruction(llvm::MCInst &Inst,
1351*9880d681SAndroid Build Coastguard Worker uint32_t insn, uint64_t Addr,
1352*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
1353*9880d681SAndroid Build Coastguard Worker unsigned Rd = fieldFromInstruction(insn, 0, 5);
1354*9880d681SAndroid Build Coastguard Worker unsigned Rn = fieldFromInstruction(insn, 5, 5);
1355*9880d681SAndroid Build Coastguard Worker unsigned Datasize = fieldFromInstruction(insn, 31, 1);
1356*9880d681SAndroid Build Coastguard Worker unsigned imm;
1357*9880d681SAndroid Build Coastguard Worker
1358*9880d681SAndroid Build Coastguard Worker if (Datasize) {
1359*9880d681SAndroid Build Coastguard Worker if (Inst.getOpcode() == AArch64::ANDSXri)
1360*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
1361*9880d681SAndroid Build Coastguard Worker else
1362*9880d681SAndroid Build Coastguard Worker DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
1363*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder);
1364*9880d681SAndroid Build Coastguard Worker imm = fieldFromInstruction(insn, 10, 13);
1365*9880d681SAndroid Build Coastguard Worker if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 64))
1366*9880d681SAndroid Build Coastguard Worker return Fail;
1367*9880d681SAndroid Build Coastguard Worker } else {
1368*9880d681SAndroid Build Coastguard Worker if (Inst.getOpcode() == AArch64::ANDSWri)
1369*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
1370*9880d681SAndroid Build Coastguard Worker else
1371*9880d681SAndroid Build Coastguard Worker DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
1372*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder);
1373*9880d681SAndroid Build Coastguard Worker imm = fieldFromInstruction(insn, 10, 12);
1374*9880d681SAndroid Build Coastguard Worker if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 32))
1375*9880d681SAndroid Build Coastguard Worker return Fail;
1376*9880d681SAndroid Build Coastguard Worker }
1377*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(imm));
1378*9880d681SAndroid Build Coastguard Worker return Success;
1379*9880d681SAndroid Build Coastguard Worker }
1380*9880d681SAndroid Build Coastguard Worker
DecodeModImmInstruction(llvm::MCInst & Inst,uint32_t insn,uint64_t Addr,const void * Decoder)1381*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeModImmInstruction(llvm::MCInst &Inst, uint32_t insn,
1382*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
1383*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
1384*9880d681SAndroid Build Coastguard Worker unsigned Rd = fieldFromInstruction(insn, 0, 5);
1385*9880d681SAndroid Build Coastguard Worker unsigned cmode = fieldFromInstruction(insn, 12, 4);
1386*9880d681SAndroid Build Coastguard Worker unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
1387*9880d681SAndroid Build Coastguard Worker imm |= fieldFromInstruction(insn, 5, 5);
1388*9880d681SAndroid Build Coastguard Worker
1389*9880d681SAndroid Build Coastguard Worker if (Inst.getOpcode() == AArch64::MOVID)
1390*9880d681SAndroid Build Coastguard Worker DecodeFPR64RegisterClass(Inst, Rd, Addr, Decoder);
1391*9880d681SAndroid Build Coastguard Worker else
1392*9880d681SAndroid Build Coastguard Worker DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder);
1393*9880d681SAndroid Build Coastguard Worker
1394*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(imm));
1395*9880d681SAndroid Build Coastguard Worker
1396*9880d681SAndroid Build Coastguard Worker switch (Inst.getOpcode()) {
1397*9880d681SAndroid Build Coastguard Worker default:
1398*9880d681SAndroid Build Coastguard Worker break;
1399*9880d681SAndroid Build Coastguard Worker case AArch64::MOVIv4i16:
1400*9880d681SAndroid Build Coastguard Worker case AArch64::MOVIv8i16:
1401*9880d681SAndroid Build Coastguard Worker case AArch64::MVNIv4i16:
1402*9880d681SAndroid Build Coastguard Worker case AArch64::MVNIv8i16:
1403*9880d681SAndroid Build Coastguard Worker case AArch64::MOVIv2i32:
1404*9880d681SAndroid Build Coastguard Worker case AArch64::MOVIv4i32:
1405*9880d681SAndroid Build Coastguard Worker case AArch64::MVNIv2i32:
1406*9880d681SAndroid Build Coastguard Worker case AArch64::MVNIv4i32:
1407*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
1408*9880d681SAndroid Build Coastguard Worker break;
1409*9880d681SAndroid Build Coastguard Worker case AArch64::MOVIv2s_msl:
1410*9880d681SAndroid Build Coastguard Worker case AArch64::MOVIv4s_msl:
1411*9880d681SAndroid Build Coastguard Worker case AArch64::MVNIv2s_msl:
1412*9880d681SAndroid Build Coastguard Worker case AArch64::MVNIv4s_msl:
1413*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(cmode & 1 ? 0x110 : 0x108));
1414*9880d681SAndroid Build Coastguard Worker break;
1415*9880d681SAndroid Build Coastguard Worker }
1416*9880d681SAndroid Build Coastguard Worker
1417*9880d681SAndroid Build Coastguard Worker return Success;
1418*9880d681SAndroid Build Coastguard Worker }
1419*9880d681SAndroid Build Coastguard Worker
DecodeModImmTiedInstruction(llvm::MCInst & Inst,uint32_t insn,uint64_t Addr,const void * Decoder)1420*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeModImmTiedInstruction(llvm::MCInst &Inst,
1421*9880d681SAndroid Build Coastguard Worker uint32_t insn, uint64_t Addr,
1422*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
1423*9880d681SAndroid Build Coastguard Worker unsigned Rd = fieldFromInstruction(insn, 0, 5);
1424*9880d681SAndroid Build Coastguard Worker unsigned cmode = fieldFromInstruction(insn, 12, 4);
1425*9880d681SAndroid Build Coastguard Worker unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
1426*9880d681SAndroid Build Coastguard Worker imm |= fieldFromInstruction(insn, 5, 5);
1427*9880d681SAndroid Build Coastguard Worker
1428*9880d681SAndroid Build Coastguard Worker // Tied operands added twice.
1429*9880d681SAndroid Build Coastguard Worker DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder);
1430*9880d681SAndroid Build Coastguard Worker DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder);
1431*9880d681SAndroid Build Coastguard Worker
1432*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(imm));
1433*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
1434*9880d681SAndroid Build Coastguard Worker
1435*9880d681SAndroid Build Coastguard Worker return Success;
1436*9880d681SAndroid Build Coastguard Worker }
1437*9880d681SAndroid Build Coastguard Worker
DecodeAdrInstruction(llvm::MCInst & Inst,uint32_t insn,uint64_t Addr,const void * Decoder)1438*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeAdrInstruction(llvm::MCInst &Inst, uint32_t insn,
1439*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder) {
1440*9880d681SAndroid Build Coastguard Worker unsigned Rd = fieldFromInstruction(insn, 0, 5);
1441*9880d681SAndroid Build Coastguard Worker int64_t imm = fieldFromInstruction(insn, 5, 19) << 2;
1442*9880d681SAndroid Build Coastguard Worker imm |= fieldFromInstruction(insn, 29, 2);
1443*9880d681SAndroid Build Coastguard Worker const AArch64Disassembler *Dis =
1444*9880d681SAndroid Build Coastguard Worker static_cast<const AArch64Disassembler *>(Decoder);
1445*9880d681SAndroid Build Coastguard Worker
1446*9880d681SAndroid Build Coastguard Worker // Sign-extend the 21-bit immediate.
1447*9880d681SAndroid Build Coastguard Worker if (imm & (1 << (21 - 1)))
1448*9880d681SAndroid Build Coastguard Worker imm |= ~((1LL << 21) - 1);
1449*9880d681SAndroid Build Coastguard Worker
1450*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
1451*9880d681SAndroid Build Coastguard Worker if (!Dis->tryAddingSymbolicOperand(Inst, imm, Addr, Fail, 0, 4))
1452*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(imm));
1453*9880d681SAndroid Build Coastguard Worker
1454*9880d681SAndroid Build Coastguard Worker return Success;
1455*9880d681SAndroid Build Coastguard Worker }
1456*9880d681SAndroid Build Coastguard Worker
DecodeBaseAddSubImm(llvm::MCInst & Inst,uint32_t insn,uint64_t Addr,const void * Decoder)1457*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeBaseAddSubImm(llvm::MCInst &Inst, uint32_t insn,
1458*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder) {
1459*9880d681SAndroid Build Coastguard Worker unsigned Rd = fieldFromInstruction(insn, 0, 5);
1460*9880d681SAndroid Build Coastguard Worker unsigned Rn = fieldFromInstruction(insn, 5, 5);
1461*9880d681SAndroid Build Coastguard Worker unsigned Imm = fieldFromInstruction(insn, 10, 14);
1462*9880d681SAndroid Build Coastguard Worker unsigned S = fieldFromInstruction(insn, 29, 1);
1463*9880d681SAndroid Build Coastguard Worker unsigned Datasize = fieldFromInstruction(insn, 31, 1);
1464*9880d681SAndroid Build Coastguard Worker
1465*9880d681SAndroid Build Coastguard Worker unsigned ShifterVal = (Imm >> 12) & 3;
1466*9880d681SAndroid Build Coastguard Worker unsigned ImmVal = Imm & 0xFFF;
1467*9880d681SAndroid Build Coastguard Worker const AArch64Disassembler *Dis =
1468*9880d681SAndroid Build Coastguard Worker static_cast<const AArch64Disassembler *>(Decoder);
1469*9880d681SAndroid Build Coastguard Worker
1470*9880d681SAndroid Build Coastguard Worker if (ShifterVal != 0 && ShifterVal != 1)
1471*9880d681SAndroid Build Coastguard Worker return Fail;
1472*9880d681SAndroid Build Coastguard Worker
1473*9880d681SAndroid Build Coastguard Worker if (Datasize) {
1474*9880d681SAndroid Build Coastguard Worker if (Rd == 31 && !S)
1475*9880d681SAndroid Build Coastguard Worker DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
1476*9880d681SAndroid Build Coastguard Worker else
1477*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
1478*9880d681SAndroid Build Coastguard Worker DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1479*9880d681SAndroid Build Coastguard Worker } else {
1480*9880d681SAndroid Build Coastguard Worker if (Rd == 31 && !S)
1481*9880d681SAndroid Build Coastguard Worker DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
1482*9880d681SAndroid Build Coastguard Worker else
1483*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
1484*9880d681SAndroid Build Coastguard Worker DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
1485*9880d681SAndroid Build Coastguard Worker }
1486*9880d681SAndroid Build Coastguard Worker
1487*9880d681SAndroid Build Coastguard Worker if (!Dis->tryAddingSymbolicOperand(Inst, Imm, Addr, Fail, 0, 4))
1488*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(ImmVal));
1489*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(12 * ShifterVal));
1490*9880d681SAndroid Build Coastguard Worker return Success;
1491*9880d681SAndroid Build Coastguard Worker }
1492*9880d681SAndroid Build Coastguard Worker
DecodeUnconditionalBranch(llvm::MCInst & Inst,uint32_t insn,uint64_t Addr,const void * Decoder)1493*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeUnconditionalBranch(llvm::MCInst &Inst, uint32_t insn,
1494*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
1495*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
1496*9880d681SAndroid Build Coastguard Worker int64_t imm = fieldFromInstruction(insn, 0, 26);
1497*9880d681SAndroid Build Coastguard Worker const AArch64Disassembler *Dis =
1498*9880d681SAndroid Build Coastguard Worker static_cast<const AArch64Disassembler *>(Decoder);
1499*9880d681SAndroid Build Coastguard Worker
1500*9880d681SAndroid Build Coastguard Worker // Sign-extend the 26-bit immediate.
1501*9880d681SAndroid Build Coastguard Worker if (imm & (1 << (26 - 1)))
1502*9880d681SAndroid Build Coastguard Worker imm |= ~((1LL << 26) - 1);
1503*9880d681SAndroid Build Coastguard Worker
1504*9880d681SAndroid Build Coastguard Worker if (!Dis->tryAddingSymbolicOperand(Inst, imm * 4, Addr, true, 0, 4))
1505*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(imm));
1506*9880d681SAndroid Build Coastguard Worker
1507*9880d681SAndroid Build Coastguard Worker return Success;
1508*9880d681SAndroid Build Coastguard Worker }
1509*9880d681SAndroid Build Coastguard Worker
DecodeSystemPStateInstruction(llvm::MCInst & Inst,uint32_t insn,uint64_t Addr,const void * Decoder)1510*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeSystemPStateInstruction(llvm::MCInst &Inst,
1511*9880d681SAndroid Build Coastguard Worker uint32_t insn, uint64_t Addr,
1512*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
1513*9880d681SAndroid Build Coastguard Worker uint64_t op1 = fieldFromInstruction(insn, 16, 3);
1514*9880d681SAndroid Build Coastguard Worker uint64_t op2 = fieldFromInstruction(insn, 5, 3);
1515*9880d681SAndroid Build Coastguard Worker uint64_t crm = fieldFromInstruction(insn, 8, 4);
1516*9880d681SAndroid Build Coastguard Worker
1517*9880d681SAndroid Build Coastguard Worker uint64_t pstate_field = (op1 << 3) | op2;
1518*9880d681SAndroid Build Coastguard Worker
1519*9880d681SAndroid Build Coastguard Worker if ((pstate_field == AArch64PState::PAN ||
1520*9880d681SAndroid Build Coastguard Worker pstate_field == AArch64PState::UAO) && crm > 1)
1521*9880d681SAndroid Build Coastguard Worker return Fail;
1522*9880d681SAndroid Build Coastguard Worker
1523*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(pstate_field));
1524*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(crm));
1525*9880d681SAndroid Build Coastguard Worker
1526*9880d681SAndroid Build Coastguard Worker const AArch64Disassembler *Dis =
1527*9880d681SAndroid Build Coastguard Worker static_cast<const AArch64Disassembler *>(Decoder);
1528*9880d681SAndroid Build Coastguard Worker auto PState = AArch64PState::lookupPStateByEncoding(pstate_field);
1529*9880d681SAndroid Build Coastguard Worker if (PState && PState->haveFeatures(Dis->getSubtargetInfo().getFeatureBits()))
1530*9880d681SAndroid Build Coastguard Worker return Success;
1531*9880d681SAndroid Build Coastguard Worker return Fail;
1532*9880d681SAndroid Build Coastguard Worker }
1533*9880d681SAndroid Build Coastguard Worker
DecodeTestAndBranch(llvm::MCInst & Inst,uint32_t insn,uint64_t Addr,const void * Decoder)1534*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeTestAndBranch(llvm::MCInst &Inst, uint32_t insn,
1535*9880d681SAndroid Build Coastguard Worker uint64_t Addr, const void *Decoder) {
1536*9880d681SAndroid Build Coastguard Worker uint64_t Rt = fieldFromInstruction(insn, 0, 5);
1537*9880d681SAndroid Build Coastguard Worker uint64_t bit = fieldFromInstruction(insn, 31, 1) << 5;
1538*9880d681SAndroid Build Coastguard Worker bit |= fieldFromInstruction(insn, 19, 5);
1539*9880d681SAndroid Build Coastguard Worker int64_t dst = fieldFromInstruction(insn, 5, 14);
1540*9880d681SAndroid Build Coastguard Worker const AArch64Disassembler *Dis =
1541*9880d681SAndroid Build Coastguard Worker static_cast<const AArch64Disassembler *>(Decoder);
1542*9880d681SAndroid Build Coastguard Worker
1543*9880d681SAndroid Build Coastguard Worker // Sign-extend 14-bit immediate.
1544*9880d681SAndroid Build Coastguard Worker if (dst & (1 << (14 - 1)))
1545*9880d681SAndroid Build Coastguard Worker dst |= ~((1LL << 14) - 1);
1546*9880d681SAndroid Build Coastguard Worker
1547*9880d681SAndroid Build Coastguard Worker if (fieldFromInstruction(insn, 31, 1) == 0)
1548*9880d681SAndroid Build Coastguard Worker DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
1549*9880d681SAndroid Build Coastguard Worker else
1550*9880d681SAndroid Build Coastguard Worker DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
1551*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(bit));
1552*9880d681SAndroid Build Coastguard Worker if (!Dis->tryAddingSymbolicOperand(Inst, dst * 4, Addr, true, 0, 4))
1553*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(dst));
1554*9880d681SAndroid Build Coastguard Worker
1555*9880d681SAndroid Build Coastguard Worker return Success;
1556*9880d681SAndroid Build Coastguard Worker }
1557*9880d681SAndroid Build Coastguard Worker
DecodeGPRSeqPairsClassRegisterClass(MCInst & Inst,unsigned RegClassID,unsigned RegNo,uint64_t Addr,const void * Decoder)1558*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeGPRSeqPairsClassRegisterClass(MCInst &Inst,
1559*9880d681SAndroid Build Coastguard Worker unsigned RegClassID,
1560*9880d681SAndroid Build Coastguard Worker unsigned RegNo,
1561*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
1562*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
1563*9880d681SAndroid Build Coastguard Worker // Register number must be even (see CASP instruction)
1564*9880d681SAndroid Build Coastguard Worker if (RegNo & 0x1)
1565*9880d681SAndroid Build Coastguard Worker return Fail;
1566*9880d681SAndroid Build Coastguard Worker
1567*9880d681SAndroid Build Coastguard Worker unsigned Register = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo);
1568*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
1569*9880d681SAndroid Build Coastguard Worker return Success;
1570*9880d681SAndroid Build Coastguard Worker }
1571*9880d681SAndroid Build Coastguard Worker
DecodeWSeqPairsClassRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)1572*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeWSeqPairsClassRegisterClass(MCInst &Inst,
1573*9880d681SAndroid Build Coastguard Worker unsigned RegNo,
1574*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
1575*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
1576*9880d681SAndroid Build Coastguard Worker return DecodeGPRSeqPairsClassRegisterClass(Inst,
1577*9880d681SAndroid Build Coastguard Worker AArch64::WSeqPairsClassRegClassID,
1578*9880d681SAndroid Build Coastguard Worker RegNo, Addr, Decoder);
1579*9880d681SAndroid Build Coastguard Worker }
1580*9880d681SAndroid Build Coastguard Worker
DecodeXSeqPairsClassRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Addr,const void * Decoder)1581*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeXSeqPairsClassRegisterClass(MCInst &Inst,
1582*9880d681SAndroid Build Coastguard Worker unsigned RegNo,
1583*9880d681SAndroid Build Coastguard Worker uint64_t Addr,
1584*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
1585*9880d681SAndroid Build Coastguard Worker return DecodeGPRSeqPairsClassRegisterClass(Inst,
1586*9880d681SAndroid Build Coastguard Worker AArch64::XSeqPairsClassRegClassID,
1587*9880d681SAndroid Build Coastguard Worker RegNo, Addr, Decoder);
1588*9880d681SAndroid Build Coastguard Worker }
1589