blob: 4389df7fa53c75698334b5701b7f6bb55765cf79 [file] [log] [blame]
Eugene Zelenko96d933d2017-07-25 23:51:02 +00001//===- AArch64Disassembler.cpp - Disassembler for AArch64 -----------------===//
Tim Northover3b0846e2014-05-24 12:50:23 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//
11//===----------------------------------------------------------------------===//
12
13#include "AArch64Disassembler.h"
14#include "AArch64ExternalSymbolizer.h"
15#include "AArch64Subtarget.h"
16#include "MCTargetDesc/AArch64AddressingModes.h"
Eugene Zelenko96d933d2017-07-25 23:51:02 +000017#include "MCTargetDesc/AArch64MCTargetDesc.h"
Tim Northover3b0846e2014-05-24 12:50:23 +000018#include "Utils/AArch64BaseInfo.h"
Eugene Zelenko96d933d2017-07-25 23:51:02 +000019#include "llvm-c/Disassembler.h"
20#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
Tim Northover3b0846e2014-05-24 12:50:23 +000021#include "llvm/MC/MCFixedLenDisassembler.h"
Benjamin Kramer1f8930e2014-07-25 11:42:14 +000022#include "llvm/MC/MCInst.h"
Eugene Zelenko96d933d2017-07-25 23:51:02 +000023#include "llvm/Support/Compiler.h"
Tim Northover3b0846e2014-05-24 12:50:23 +000024#include "llvm/Support/Debug.h"
Benjamin Kramer1f8930e2014-07-25 11:42:14 +000025#include "llvm/Support/ErrorHandling.h"
Tim Northover3b0846e2014-05-24 12:50:23 +000026#include "llvm/Support/TargetRegistry.h"
Eugene Zelenko96d933d2017-07-25 23:51:02 +000027#include <algorithm>
28#include <memory>
Tim Northover3b0846e2014-05-24 12:50:23 +000029
30using namespace llvm;
31
32#define DEBUG_TYPE "aarch64-disassembler"
33
34// Pull DecodeStatus and its enum values into the global namespace.
Eugene Zelenko96d933d2017-07-25 23:51:02 +000035using DecodeStatus = MCDisassembler::DecodeStatus;
Tim Northover3b0846e2014-05-24 12:50:23 +000036
37// Forward declare these because the autogenerated code will reference them.
38// Definitions are further down.
Eugene Zelenko96d933d2017-07-25 23:51:02 +000039static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst,
Tim Northover3b0846e2014-05-24 12:50:23 +000040 unsigned RegNo, uint64_t Address,
41 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000042static DecodeStatus DecodeFPR128_loRegisterClass(MCInst &Inst,
Tim Northover3b0846e2014-05-24 12:50:23 +000043 unsigned RegNo,
44 uint64_t Address,
45 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000046static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, unsigned RegNo,
Tim Northover3b0846e2014-05-24 12:50:23 +000047 uint64_t Address,
48 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000049static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, unsigned RegNo,
Tim Northover3b0846e2014-05-24 12:50:23 +000050 uint64_t Address,
51 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000052static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, unsigned RegNo,
Tim Northover3b0846e2014-05-24 12:50:23 +000053 uint64_t Address,
54 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000055static DecodeStatus DecodeFPR8RegisterClass(MCInst &Inst, unsigned RegNo,
Tim Northover3b0846e2014-05-24 12:50:23 +000056 uint64_t Address,
57 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000058static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
Tim Northover3b0846e2014-05-24 12:50:23 +000059 uint64_t Address,
60 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000061static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst,
Tim Northover3b0846e2014-05-24 12:50:23 +000062 unsigned RegNo, uint64_t Address,
63 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000064static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
Tim Northover3b0846e2014-05-24 12:50:23 +000065 uint64_t Address,
66 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000067static DecodeStatus DecodeGPR32spRegisterClass(MCInst &Inst,
Tim Northover3b0846e2014-05-24 12:50:23 +000068 unsigned RegNo, uint64_t Address,
69 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000070static DecodeStatus DecodeQQRegisterClass(MCInst &Inst, unsigned RegNo,
Tim Northover3b0846e2014-05-24 12:50:23 +000071 uint64_t Address,
72 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000073static DecodeStatus DecodeQQQRegisterClass(MCInst &Inst, unsigned RegNo,
Tim Northover3b0846e2014-05-24 12:50:23 +000074 uint64_t Address,
75 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000076static DecodeStatus DecodeQQQQRegisterClass(MCInst &Inst, unsigned RegNo,
Tim Northover3b0846e2014-05-24 12:50:23 +000077 uint64_t Address,
78 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000079static DecodeStatus DecodeDDRegisterClass(MCInst &Inst, unsigned RegNo,
Tim Northover3b0846e2014-05-24 12:50:23 +000080 uint64_t Address,
81 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000082static DecodeStatus DecodeDDDRegisterClass(MCInst &Inst, unsigned RegNo,
Tim Northover3b0846e2014-05-24 12:50:23 +000083 uint64_t Address,
84 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000085static DecodeStatus DecodeDDDDRegisterClass(MCInst &Inst, unsigned RegNo,
Tim Northover3b0846e2014-05-24 12:50:23 +000086 uint64_t Address,
87 const void *Decoder);
88
Eugene Zelenko96d933d2017-07-25 23:51:02 +000089static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +000090 uint64_t Address,
91 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000092static DecodeStatus DecodeFixedPointScaleImm64(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +000093 uint64_t Address,
94 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000095static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +000096 uint64_t Address, const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000097static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +000098 uint64_t Address, const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +000099static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000100 uint64_t Address, const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000101static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000102 uint64_t Address, const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000103static DecodeStatus DecodeThreeAddrSRegInstruction(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +0000104 uint64_t Address,
105 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000106static DecodeStatus DecodeMoveImmInstruction(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +0000107 uint64_t Address,
108 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000109static DecodeStatus DecodeUnsignedLdStInstruction(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +0000110 uint64_t Address,
111 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000112static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
113 uint64_t Address,
Tim Northover3b0846e2014-05-24 12:50:23 +0000114 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000115static DecodeStatus DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +0000116 uint64_t Address,
117 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000118static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +0000119 uint64_t Address,
120 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000121static DecodeStatus DecodeAddSubERegInstruction(MCInst &Inst, uint32_t insn,
122 uint64_t Address,
Tim Northover3b0846e2014-05-24 12:50:23 +0000123 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000124static DecodeStatus DecodeLogicalImmInstruction(MCInst &Inst, uint32_t insn,
125 uint64_t Address,
Tim Northover3b0846e2014-05-24 12:50:23 +0000126 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000127static DecodeStatus DecodeModImmInstruction(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +0000128 uint64_t Address,
129 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000130static DecodeStatus DecodeModImmTiedInstruction(MCInst &Inst, uint32_t insn,
131 uint64_t Address,
Tim Northover3b0846e2014-05-24 12:50:23 +0000132 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000133static DecodeStatus DecodeAdrInstruction(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +0000134 uint64_t Address, const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000135static DecodeStatus DecodeBaseAddSubImm(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +0000136 uint64_t Address, const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000137static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +0000138 uint64_t Address,
139 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000140static DecodeStatus DecodeSystemPStateInstruction(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +0000141 uint64_t Address,
142 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000143static DecodeStatus DecodeTestAndBranch(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +0000144 uint64_t Address, const void *Decoder);
145
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000146static DecodeStatus DecodeFMOVLaneInstruction(MCInst &Inst, unsigned Insn,
Tim Northover3b0846e2014-05-24 12:50:23 +0000147 uint64_t Address,
148 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000149static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000150 uint64_t Addr, const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000151static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000152 uint64_t Addr,
153 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000154static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000155 uint64_t Addr, const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000156static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000157 uint64_t Addr,
158 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000159static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000160 uint64_t Addr, const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000161static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000162 uint64_t Addr,
163 const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000164static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000165 uint64_t Addr, const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000166static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000167 uint64_t Addr, const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000168static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000169 uint64_t Addr, const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000170static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000171 uint64_t Addr, const void *Decoder);
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000172static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000173 uint64_t Addr, const void *Decoder);
Vladimir Sukharev5f6f60d2015-06-02 10:58:41 +0000174static DecodeStatus DecodeWSeqPairsClassRegisterClass(MCInst &Inst,
175 unsigned RegNo,
176 uint64_t Addr,
177 const void *Decoder);
178static DecodeStatus DecodeXSeqPairsClassRegisterClass(MCInst &Inst,
179 unsigned RegNo,
180 uint64_t Addr,
181 const void *Decoder);
Sam Parker6d42de72017-08-11 13:14:00 +0000182template<int Bits>
183static DecodeStatus DecodeSImm(llvm::MCInst &Inst, uint64_t Imm,
184 uint64_t Address, const void *Decoder);
185static DecodeStatus DecodeAuthLoadWriteback(llvm::MCInst &Inst, uint32_t insn,
186 uint64_t Address,
187 const void *Decoder);
Tim Northover3b0846e2014-05-24 12:50:23 +0000188
189static bool Check(DecodeStatus &Out, DecodeStatus In) {
190 switch (In) {
191 case MCDisassembler::Success:
192 // Out stays the same.
193 return true;
194 case MCDisassembler::SoftFail:
195 Out = In;
196 return true;
197 case MCDisassembler::Fail:
198 Out = In;
199 return false;
200 }
201 llvm_unreachable("Invalid DecodeStatus!");
202}
203
204#include "AArch64GenDisassemblerTables.inc"
205#include "AArch64GenInstrInfo.inc"
206
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000207#define Success MCDisassembler::Success
208#define Fail MCDisassembler::Fail
209#define SoftFail MCDisassembler::SoftFail
Tim Northover3b0846e2014-05-24 12:50:23 +0000210
211static MCDisassembler *createAArch64Disassembler(const Target &T,
212 const MCSubtargetInfo &STI,
213 MCContext &Ctx) {
214 return new AArch64Disassembler(STI, Ctx);
215}
216
217DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000218 ArrayRef<uint8_t> Bytes,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000219 uint64_t Address,
220 raw_ostream &OS,
221 raw_ostream &CS) const {
222 CommentStream = &CS;
Tim Northover3b0846e2014-05-24 12:50:23 +0000223
Tim Northover3b0846e2014-05-24 12:50:23 +0000224 Size = 0;
225 // We want to read exactly 4 bytes of data.
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000226 if (Bytes.size() < 4)
Tim Northover3b0846e2014-05-24 12:50:23 +0000227 return Fail;
228 Size = 4;
229
230 // Encoded as a small-endian 32-bit word in the stream.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000231 uint32_t Insn =
232 (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
Tim Northover3b0846e2014-05-24 12:50:23 +0000233
234 // Calling the auto-generated decoder function.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000235 return decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
Tim Northover3b0846e2014-05-24 12:50:23 +0000236}
237
Daniel Sanders50f17232015-09-15 16:17:27 +0000238static MCSymbolizer *
239createAArch64ExternalSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,
240 LLVMSymbolLookupCallback SymbolLookUp,
241 void *DisInfo, MCContext *Ctx,
242 std::unique_ptr<MCRelocationInfo> &&RelInfo) {
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000243 return new AArch64ExternalSymbolizer(*Ctx, std::move(RelInfo), GetOpInfo,
244 SymbolLookUp, DisInfo);
Tim Northover3b0846e2014-05-24 12:50:23 +0000245}
246
247extern "C" void LLVMInitializeAArch64Disassembler() {
Mehdi Aminif42454b2016-10-09 23:00:34 +0000248 TargetRegistry::RegisterMCDisassembler(getTheAArch64leTarget(),
Tim Northover3b0846e2014-05-24 12:50:23 +0000249 createAArch64Disassembler);
Mehdi Aminif42454b2016-10-09 23:00:34 +0000250 TargetRegistry::RegisterMCDisassembler(getTheAArch64beTarget(),
Tim Northover3b0846e2014-05-24 12:50:23 +0000251 createAArch64Disassembler);
Mehdi Aminif42454b2016-10-09 23:00:34 +0000252 TargetRegistry::RegisterMCSymbolizer(getTheAArch64leTarget(),
Tim Northover3b0846e2014-05-24 12:50:23 +0000253 createAArch64ExternalSymbolizer);
Mehdi Aminif42454b2016-10-09 23:00:34 +0000254 TargetRegistry::RegisterMCSymbolizer(getTheAArch64beTarget(),
Tim Northover3b0846e2014-05-24 12:50:23 +0000255 createAArch64ExternalSymbolizer);
256
Mehdi Aminif42454b2016-10-09 23:00:34 +0000257 TargetRegistry::RegisterMCDisassembler(getTheARM64Target(),
Tim Northover3b0846e2014-05-24 12:50:23 +0000258 createAArch64Disassembler);
Mehdi Aminif42454b2016-10-09 23:00:34 +0000259 TargetRegistry::RegisterMCSymbolizer(getTheARM64Target(),
Tim Northover3b0846e2014-05-24 12:50:23 +0000260 createAArch64ExternalSymbolizer);
261}
262
263static const unsigned FPR128DecoderTable[] = {
264 AArch64::Q0, AArch64::Q1, AArch64::Q2, AArch64::Q3, AArch64::Q4,
265 AArch64::Q5, AArch64::Q6, AArch64::Q7, AArch64::Q8, AArch64::Q9,
266 AArch64::Q10, AArch64::Q11, AArch64::Q12, AArch64::Q13, AArch64::Q14,
267 AArch64::Q15, AArch64::Q16, AArch64::Q17, AArch64::Q18, AArch64::Q19,
268 AArch64::Q20, AArch64::Q21, AArch64::Q22, AArch64::Q23, AArch64::Q24,
269 AArch64::Q25, AArch64::Q26, AArch64::Q27, AArch64::Q28, AArch64::Q29,
270 AArch64::Q30, AArch64::Q31
271};
272
273static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, unsigned RegNo,
274 uint64_t Addr,
275 const void *Decoder) {
276 if (RegNo > 31)
277 return Fail;
278
279 unsigned Register = FPR128DecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000280 Inst.addOperand(MCOperand::createReg(Register));
Tim Northover3b0846e2014-05-24 12:50:23 +0000281 return Success;
282}
283
284static DecodeStatus DecodeFPR128_loRegisterClass(MCInst &Inst, unsigned RegNo,
285 uint64_t Addr,
286 const void *Decoder) {
287 if (RegNo > 15)
288 return Fail;
289 return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder);
290}
291
292static const unsigned FPR64DecoderTable[] = {
293 AArch64::D0, AArch64::D1, AArch64::D2, AArch64::D3, AArch64::D4,
294 AArch64::D5, AArch64::D6, AArch64::D7, AArch64::D8, AArch64::D9,
295 AArch64::D10, AArch64::D11, AArch64::D12, AArch64::D13, AArch64::D14,
296 AArch64::D15, AArch64::D16, AArch64::D17, AArch64::D18, AArch64::D19,
297 AArch64::D20, AArch64::D21, AArch64::D22, AArch64::D23, AArch64::D24,
298 AArch64::D25, AArch64::D26, AArch64::D27, AArch64::D28, AArch64::D29,
299 AArch64::D30, AArch64::D31
300};
301
302static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, unsigned RegNo,
303 uint64_t Addr,
304 const void *Decoder) {
305 if (RegNo > 31)
306 return Fail;
307
308 unsigned Register = FPR64DecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000309 Inst.addOperand(MCOperand::createReg(Register));
Tim Northover3b0846e2014-05-24 12:50:23 +0000310 return Success;
311}
312
313static const unsigned FPR32DecoderTable[] = {
314 AArch64::S0, AArch64::S1, AArch64::S2, AArch64::S3, AArch64::S4,
315 AArch64::S5, AArch64::S6, AArch64::S7, AArch64::S8, AArch64::S9,
316 AArch64::S10, AArch64::S11, AArch64::S12, AArch64::S13, AArch64::S14,
317 AArch64::S15, AArch64::S16, AArch64::S17, AArch64::S18, AArch64::S19,
318 AArch64::S20, AArch64::S21, AArch64::S22, AArch64::S23, AArch64::S24,
319 AArch64::S25, AArch64::S26, AArch64::S27, AArch64::S28, AArch64::S29,
320 AArch64::S30, AArch64::S31
321};
322
323static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, unsigned RegNo,
324 uint64_t Addr,
325 const void *Decoder) {
326 if (RegNo > 31)
327 return Fail;
328
329 unsigned Register = FPR32DecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000330 Inst.addOperand(MCOperand::createReg(Register));
Tim Northover3b0846e2014-05-24 12:50:23 +0000331 return Success;
332}
333
334static const unsigned FPR16DecoderTable[] = {
335 AArch64::H0, AArch64::H1, AArch64::H2, AArch64::H3, AArch64::H4,
336 AArch64::H5, AArch64::H6, AArch64::H7, AArch64::H8, AArch64::H9,
337 AArch64::H10, AArch64::H11, AArch64::H12, AArch64::H13, AArch64::H14,
338 AArch64::H15, AArch64::H16, AArch64::H17, AArch64::H18, AArch64::H19,
339 AArch64::H20, AArch64::H21, AArch64::H22, AArch64::H23, AArch64::H24,
340 AArch64::H25, AArch64::H26, AArch64::H27, AArch64::H28, AArch64::H29,
341 AArch64::H30, AArch64::H31
342};
343
344static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, unsigned RegNo,
345 uint64_t Addr,
346 const void *Decoder) {
347 if (RegNo > 31)
348 return Fail;
349
350 unsigned Register = FPR16DecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000351 Inst.addOperand(MCOperand::createReg(Register));
Tim Northover3b0846e2014-05-24 12:50:23 +0000352 return Success;
353}
354
355static const unsigned FPR8DecoderTable[] = {
356 AArch64::B0, AArch64::B1, AArch64::B2, AArch64::B3, AArch64::B4,
357 AArch64::B5, AArch64::B6, AArch64::B7, AArch64::B8, AArch64::B9,
358 AArch64::B10, AArch64::B11, AArch64::B12, AArch64::B13, AArch64::B14,
359 AArch64::B15, AArch64::B16, AArch64::B17, AArch64::B18, AArch64::B19,
360 AArch64::B20, AArch64::B21, AArch64::B22, AArch64::B23, AArch64::B24,
361 AArch64::B25, AArch64::B26, AArch64::B27, AArch64::B28, AArch64::B29,
362 AArch64::B30, AArch64::B31
363};
364
365static DecodeStatus DecodeFPR8RegisterClass(MCInst &Inst, unsigned RegNo,
366 uint64_t Addr,
367 const void *Decoder) {
368 if (RegNo > 31)
369 return Fail;
370
371 unsigned Register = FPR8DecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000372 Inst.addOperand(MCOperand::createReg(Register));
Tim Northover3b0846e2014-05-24 12:50:23 +0000373 return Success;
374}
375
376static const unsigned GPR64DecoderTable[] = {
377 AArch64::X0, AArch64::X1, AArch64::X2, AArch64::X3, AArch64::X4,
378 AArch64::X5, AArch64::X6, AArch64::X7, AArch64::X8, AArch64::X9,
379 AArch64::X10, AArch64::X11, AArch64::X12, AArch64::X13, AArch64::X14,
380 AArch64::X15, AArch64::X16, AArch64::X17, AArch64::X18, AArch64::X19,
381 AArch64::X20, AArch64::X21, AArch64::X22, AArch64::X23, AArch64::X24,
382 AArch64::X25, AArch64::X26, AArch64::X27, AArch64::X28, AArch64::FP,
383 AArch64::LR, AArch64::XZR
384};
385
386static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo,
387 uint64_t Addr,
388 const void *Decoder) {
389 if (RegNo > 31)
390 return Fail;
391
392 unsigned Register = GPR64DecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000393 Inst.addOperand(MCOperand::createReg(Register));
Tim Northover3b0846e2014-05-24 12:50:23 +0000394 return Success;
395}
396
397static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst, unsigned RegNo,
398 uint64_t Addr,
399 const void *Decoder) {
400 if (RegNo > 31)
401 return Fail;
402 unsigned Register = GPR64DecoderTable[RegNo];
403 if (Register == AArch64::XZR)
404 Register = AArch64::SP;
Jim Grosbache9119e42015-05-13 18:37:00 +0000405 Inst.addOperand(MCOperand::createReg(Register));
Tim Northover3b0846e2014-05-24 12:50:23 +0000406 return Success;
407}
408
409static const unsigned GPR32DecoderTable[] = {
410 AArch64::W0, AArch64::W1, AArch64::W2, AArch64::W3, AArch64::W4,
411 AArch64::W5, AArch64::W6, AArch64::W7, AArch64::W8, AArch64::W9,
412 AArch64::W10, AArch64::W11, AArch64::W12, AArch64::W13, AArch64::W14,
413 AArch64::W15, AArch64::W16, AArch64::W17, AArch64::W18, AArch64::W19,
414 AArch64::W20, AArch64::W21, AArch64::W22, AArch64::W23, AArch64::W24,
415 AArch64::W25, AArch64::W26, AArch64::W27, AArch64::W28, AArch64::W29,
416 AArch64::W30, AArch64::WZR
417};
418
419static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
420 uint64_t Addr,
421 const void *Decoder) {
422 if (RegNo > 31)
423 return Fail;
424
425 unsigned Register = GPR32DecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000426 Inst.addOperand(MCOperand::createReg(Register));
Tim Northover3b0846e2014-05-24 12:50:23 +0000427 return Success;
428}
429
430static DecodeStatus DecodeGPR32spRegisterClass(MCInst &Inst, unsigned RegNo,
431 uint64_t Addr,
432 const void *Decoder) {
433 if (RegNo > 31)
434 return Fail;
435
436 unsigned Register = GPR32DecoderTable[RegNo];
437 if (Register == AArch64::WZR)
438 Register = AArch64::WSP;
Jim Grosbache9119e42015-05-13 18:37:00 +0000439 Inst.addOperand(MCOperand::createReg(Register));
Tim Northover3b0846e2014-05-24 12:50:23 +0000440 return Success;
441}
442
443static const unsigned VectorDecoderTable[] = {
444 AArch64::Q0, AArch64::Q1, AArch64::Q2, AArch64::Q3, AArch64::Q4,
445 AArch64::Q5, AArch64::Q6, AArch64::Q7, AArch64::Q8, AArch64::Q9,
446 AArch64::Q10, AArch64::Q11, AArch64::Q12, AArch64::Q13, AArch64::Q14,
447 AArch64::Q15, AArch64::Q16, AArch64::Q17, AArch64::Q18, AArch64::Q19,
448 AArch64::Q20, AArch64::Q21, AArch64::Q22, AArch64::Q23, AArch64::Q24,
449 AArch64::Q25, AArch64::Q26, AArch64::Q27, AArch64::Q28, AArch64::Q29,
450 AArch64::Q30, AArch64::Q31
451};
452
453static DecodeStatus DecodeVectorRegisterClass(MCInst &Inst, unsigned RegNo,
454 uint64_t Addr,
455 const void *Decoder) {
456 if (RegNo > 31)
457 return Fail;
458
459 unsigned Register = VectorDecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000460 Inst.addOperand(MCOperand::createReg(Register));
Tim Northover3b0846e2014-05-24 12:50:23 +0000461 return Success;
462}
463
464static const unsigned QQDecoderTable[] = {
465 AArch64::Q0_Q1, AArch64::Q1_Q2, AArch64::Q2_Q3, AArch64::Q3_Q4,
466 AArch64::Q4_Q5, AArch64::Q5_Q6, AArch64::Q6_Q7, AArch64::Q7_Q8,
467 AArch64::Q8_Q9, AArch64::Q9_Q10, AArch64::Q10_Q11, AArch64::Q11_Q12,
468 AArch64::Q12_Q13, AArch64::Q13_Q14, AArch64::Q14_Q15, AArch64::Q15_Q16,
469 AArch64::Q16_Q17, AArch64::Q17_Q18, AArch64::Q18_Q19, AArch64::Q19_Q20,
470 AArch64::Q20_Q21, AArch64::Q21_Q22, AArch64::Q22_Q23, AArch64::Q23_Q24,
471 AArch64::Q24_Q25, AArch64::Q25_Q26, AArch64::Q26_Q27, AArch64::Q27_Q28,
472 AArch64::Q28_Q29, AArch64::Q29_Q30, AArch64::Q30_Q31, AArch64::Q31_Q0
473};
474
475static DecodeStatus DecodeQQRegisterClass(MCInst &Inst, unsigned RegNo,
476 uint64_t Addr, const void *Decoder) {
477 if (RegNo > 31)
478 return Fail;
479 unsigned Register = QQDecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000480 Inst.addOperand(MCOperand::createReg(Register));
Tim Northover3b0846e2014-05-24 12:50:23 +0000481 return Success;
482}
483
484static const unsigned QQQDecoderTable[] = {
485 AArch64::Q0_Q1_Q2, AArch64::Q1_Q2_Q3, AArch64::Q2_Q3_Q4,
486 AArch64::Q3_Q4_Q5, AArch64::Q4_Q5_Q6, AArch64::Q5_Q6_Q7,
487 AArch64::Q6_Q7_Q8, AArch64::Q7_Q8_Q9, AArch64::Q8_Q9_Q10,
488 AArch64::Q9_Q10_Q11, AArch64::Q10_Q11_Q12, AArch64::Q11_Q12_Q13,
489 AArch64::Q12_Q13_Q14, AArch64::Q13_Q14_Q15, AArch64::Q14_Q15_Q16,
490 AArch64::Q15_Q16_Q17, AArch64::Q16_Q17_Q18, AArch64::Q17_Q18_Q19,
491 AArch64::Q18_Q19_Q20, AArch64::Q19_Q20_Q21, AArch64::Q20_Q21_Q22,
492 AArch64::Q21_Q22_Q23, AArch64::Q22_Q23_Q24, AArch64::Q23_Q24_Q25,
493 AArch64::Q24_Q25_Q26, AArch64::Q25_Q26_Q27, AArch64::Q26_Q27_Q28,
494 AArch64::Q27_Q28_Q29, AArch64::Q28_Q29_Q30, AArch64::Q29_Q30_Q31,
495 AArch64::Q30_Q31_Q0, AArch64::Q31_Q0_Q1
496};
497
498static DecodeStatus DecodeQQQRegisterClass(MCInst &Inst, unsigned RegNo,
499 uint64_t Addr, const void *Decoder) {
500 if (RegNo > 31)
501 return Fail;
502 unsigned Register = QQQDecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000503 Inst.addOperand(MCOperand::createReg(Register));
Tim Northover3b0846e2014-05-24 12:50:23 +0000504 return Success;
505}
506
507static const unsigned QQQQDecoderTable[] = {
508 AArch64::Q0_Q1_Q2_Q3, AArch64::Q1_Q2_Q3_Q4, AArch64::Q2_Q3_Q4_Q5,
509 AArch64::Q3_Q4_Q5_Q6, AArch64::Q4_Q5_Q6_Q7, AArch64::Q5_Q6_Q7_Q8,
510 AArch64::Q6_Q7_Q8_Q9, AArch64::Q7_Q8_Q9_Q10, AArch64::Q8_Q9_Q10_Q11,
511 AArch64::Q9_Q10_Q11_Q12, AArch64::Q10_Q11_Q12_Q13, AArch64::Q11_Q12_Q13_Q14,
512 AArch64::Q12_Q13_Q14_Q15, AArch64::Q13_Q14_Q15_Q16, AArch64::Q14_Q15_Q16_Q17,
513 AArch64::Q15_Q16_Q17_Q18, AArch64::Q16_Q17_Q18_Q19, AArch64::Q17_Q18_Q19_Q20,
514 AArch64::Q18_Q19_Q20_Q21, AArch64::Q19_Q20_Q21_Q22, AArch64::Q20_Q21_Q22_Q23,
515 AArch64::Q21_Q22_Q23_Q24, AArch64::Q22_Q23_Q24_Q25, AArch64::Q23_Q24_Q25_Q26,
516 AArch64::Q24_Q25_Q26_Q27, AArch64::Q25_Q26_Q27_Q28, AArch64::Q26_Q27_Q28_Q29,
517 AArch64::Q27_Q28_Q29_Q30, AArch64::Q28_Q29_Q30_Q31, AArch64::Q29_Q30_Q31_Q0,
518 AArch64::Q30_Q31_Q0_Q1, AArch64::Q31_Q0_Q1_Q2
519};
520
521static DecodeStatus DecodeQQQQRegisterClass(MCInst &Inst, unsigned RegNo,
522 uint64_t Addr,
523 const void *Decoder) {
524 if (RegNo > 31)
525 return Fail;
526 unsigned Register = QQQQDecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000527 Inst.addOperand(MCOperand::createReg(Register));
Tim Northover3b0846e2014-05-24 12:50:23 +0000528 return Success;
529}
530
531static const unsigned DDDecoderTable[] = {
532 AArch64::D0_D1, AArch64::D1_D2, AArch64::D2_D3, AArch64::D3_D4,
533 AArch64::D4_D5, AArch64::D5_D6, AArch64::D6_D7, AArch64::D7_D8,
534 AArch64::D8_D9, AArch64::D9_D10, AArch64::D10_D11, AArch64::D11_D12,
535 AArch64::D12_D13, AArch64::D13_D14, AArch64::D14_D15, AArch64::D15_D16,
536 AArch64::D16_D17, AArch64::D17_D18, AArch64::D18_D19, AArch64::D19_D20,
537 AArch64::D20_D21, AArch64::D21_D22, AArch64::D22_D23, AArch64::D23_D24,
538 AArch64::D24_D25, AArch64::D25_D26, AArch64::D26_D27, AArch64::D27_D28,
539 AArch64::D28_D29, AArch64::D29_D30, AArch64::D30_D31, AArch64::D31_D0
540};
541
542static DecodeStatus DecodeDDRegisterClass(MCInst &Inst, unsigned RegNo,
543 uint64_t Addr, const void *Decoder) {
544 if (RegNo > 31)
545 return Fail;
546 unsigned Register = DDDecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000547 Inst.addOperand(MCOperand::createReg(Register));
Tim Northover3b0846e2014-05-24 12:50:23 +0000548 return Success;
549}
550
551static const unsigned DDDDecoderTable[] = {
552 AArch64::D0_D1_D2, AArch64::D1_D2_D3, AArch64::D2_D3_D4,
553 AArch64::D3_D4_D5, AArch64::D4_D5_D6, AArch64::D5_D6_D7,
554 AArch64::D6_D7_D8, AArch64::D7_D8_D9, AArch64::D8_D9_D10,
555 AArch64::D9_D10_D11, AArch64::D10_D11_D12, AArch64::D11_D12_D13,
556 AArch64::D12_D13_D14, AArch64::D13_D14_D15, AArch64::D14_D15_D16,
557 AArch64::D15_D16_D17, AArch64::D16_D17_D18, AArch64::D17_D18_D19,
558 AArch64::D18_D19_D20, AArch64::D19_D20_D21, AArch64::D20_D21_D22,
559 AArch64::D21_D22_D23, AArch64::D22_D23_D24, AArch64::D23_D24_D25,
560 AArch64::D24_D25_D26, AArch64::D25_D26_D27, AArch64::D26_D27_D28,
561 AArch64::D27_D28_D29, AArch64::D28_D29_D30, AArch64::D29_D30_D31,
562 AArch64::D30_D31_D0, AArch64::D31_D0_D1
563};
564
565static DecodeStatus DecodeDDDRegisterClass(MCInst &Inst, unsigned RegNo,
566 uint64_t Addr, const void *Decoder) {
567 if (RegNo > 31)
568 return Fail;
569 unsigned Register = DDDDecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000570 Inst.addOperand(MCOperand::createReg(Register));
Tim Northover3b0846e2014-05-24 12:50:23 +0000571 return Success;
572}
573
574static const unsigned DDDDDecoderTable[] = {
575 AArch64::D0_D1_D2_D3, AArch64::D1_D2_D3_D4, AArch64::D2_D3_D4_D5,
576 AArch64::D3_D4_D5_D6, AArch64::D4_D5_D6_D7, AArch64::D5_D6_D7_D8,
577 AArch64::D6_D7_D8_D9, AArch64::D7_D8_D9_D10, AArch64::D8_D9_D10_D11,
578 AArch64::D9_D10_D11_D12, AArch64::D10_D11_D12_D13, AArch64::D11_D12_D13_D14,
579 AArch64::D12_D13_D14_D15, AArch64::D13_D14_D15_D16, AArch64::D14_D15_D16_D17,
580 AArch64::D15_D16_D17_D18, AArch64::D16_D17_D18_D19, AArch64::D17_D18_D19_D20,
581 AArch64::D18_D19_D20_D21, AArch64::D19_D20_D21_D22, AArch64::D20_D21_D22_D23,
582 AArch64::D21_D22_D23_D24, AArch64::D22_D23_D24_D25, AArch64::D23_D24_D25_D26,
583 AArch64::D24_D25_D26_D27, AArch64::D25_D26_D27_D28, AArch64::D26_D27_D28_D29,
584 AArch64::D27_D28_D29_D30, AArch64::D28_D29_D30_D31, AArch64::D29_D30_D31_D0,
585 AArch64::D30_D31_D0_D1, AArch64::D31_D0_D1_D2
586};
587
588static DecodeStatus DecodeDDDDRegisterClass(MCInst &Inst, unsigned RegNo,
589 uint64_t Addr,
590 const void *Decoder) {
591 if (RegNo > 31)
592 return Fail;
593 unsigned Register = DDDDDecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000594 Inst.addOperand(MCOperand::createReg(Register));
Tim Northover3b0846e2014-05-24 12:50:23 +0000595 return Success;
596}
597
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000598static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000599 uint64_t Addr,
600 const void *Decoder) {
601 // scale{5} is asserted as 1 in tblgen.
Tom Coxon2c13e712014-09-30 16:23:16 +0000602 Imm |= 0x20;
Jim Grosbache9119e42015-05-13 18:37:00 +0000603 Inst.addOperand(MCOperand::createImm(64 - Imm));
Tim Northover3b0846e2014-05-24 12:50:23 +0000604 return Success;
605}
606
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000607static DecodeStatus DecodeFixedPointScaleImm64(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000608 uint64_t Addr,
609 const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +0000610 Inst.addOperand(MCOperand::createImm(64 - Imm));
Tim Northover3b0846e2014-05-24 12:50:23 +0000611 return Success;
612}
613
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000614static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000615 uint64_t Addr, const void *Decoder) {
616 int64_t ImmVal = Imm;
617 const AArch64Disassembler *Dis =
618 static_cast<const AArch64Disassembler *>(Decoder);
619
620 // Sign-extend 19-bit immediate.
621 if (ImmVal & (1 << (19 - 1)))
622 ImmVal |= ~((1LL << 19) - 1);
623
Alexey Samsonov729b12e2014-09-02 16:19:41 +0000624 if (!Dis->tryAddingSymbolicOperand(Inst, ImmVal * 4, Addr,
Tim Northover3b0846e2014-05-24 12:50:23 +0000625 Inst.getOpcode() != AArch64::LDRXl, 0, 4))
Jim Grosbache9119e42015-05-13 18:37:00 +0000626 Inst.addOperand(MCOperand::createImm(ImmVal));
Tim Northover3b0846e2014-05-24 12:50:23 +0000627 return Success;
628}
629
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000630static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000631 uint64_t Address, const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +0000632 Inst.addOperand(MCOperand::createImm((Imm >> 1) & 1));
633 Inst.addOperand(MCOperand::createImm(Imm & 1));
Tim Northover3b0846e2014-05-24 12:50:23 +0000634 return Success;
635}
636
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000637static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000638 uint64_t Address,
639 const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +0000640 Inst.addOperand(MCOperand::createImm(Imm));
Tim Northover3b0846e2014-05-24 12:50:23 +0000641
Tom Coxone493f172014-10-01 10:13:59 +0000642 // Every system register in the encoding space is valid with the syntax
643 // S<op0>_<op1>_<Cn>_<Cm>_<op2>, so decoding system registers always succeeds.
644 return Success;
Tim Northover3b0846e2014-05-24 12:50:23 +0000645}
646
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000647static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000648 uint64_t Address,
649 const void *Decoder) {
Jim Grosbache9119e42015-05-13 18:37:00 +0000650 Inst.addOperand(MCOperand::createImm(Imm));
Tim Northover3b0846e2014-05-24 12:50:23 +0000651
Tom Coxone493f172014-10-01 10:13:59 +0000652 return Success;
Tim Northover3b0846e2014-05-24 12:50:23 +0000653}
654
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000655static DecodeStatus DecodeFMOVLaneInstruction(MCInst &Inst, unsigned Insn,
Tim Northover3b0846e2014-05-24 12:50:23 +0000656 uint64_t Address,
657 const void *Decoder) {
658 // This decoder exists to add the dummy Lane operand to the MCInst, which must
659 // be 1 in assembly but has no other real manifestation.
660 unsigned Rd = fieldFromInstruction(Insn, 0, 5);
661 unsigned Rn = fieldFromInstruction(Insn, 5, 5);
662 unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
663
664 if (IsToVec) {
665 DecodeFPR128RegisterClass(Inst, Rd, Address, Decoder);
666 DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
667 } else {
668 DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
669 DecodeFPR128RegisterClass(Inst, Rn, Address, Decoder);
670 }
671
672 // Add the lane
Jim Grosbache9119e42015-05-13 18:37:00 +0000673 Inst.addOperand(MCOperand::createImm(1));
Tim Northover3b0846e2014-05-24 12:50:23 +0000674
675 return Success;
676}
677
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000678static DecodeStatus DecodeVecShiftRImm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000679 unsigned Add) {
Jim Grosbache9119e42015-05-13 18:37:00 +0000680 Inst.addOperand(MCOperand::createImm(Add - Imm));
Tim Northover3b0846e2014-05-24 12:50:23 +0000681 return Success;
682}
683
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000684static DecodeStatus DecodeVecShiftLImm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000685 unsigned Add) {
Jim Grosbache9119e42015-05-13 18:37:00 +0000686 Inst.addOperand(MCOperand::createImm((Imm + Add) & (Add - 1)));
Tim Northover3b0846e2014-05-24 12:50:23 +0000687 return Success;
688}
689
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000690static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000691 uint64_t Addr, const void *Decoder) {
692 return DecodeVecShiftRImm(Inst, Imm, 64);
693}
694
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000695static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000696 uint64_t Addr,
697 const void *Decoder) {
698 return DecodeVecShiftRImm(Inst, Imm | 0x20, 64);
699}
700
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000701static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000702 uint64_t Addr, const void *Decoder) {
703 return DecodeVecShiftRImm(Inst, Imm, 32);
704}
705
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000706static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000707 uint64_t Addr,
708 const void *Decoder) {
709 return DecodeVecShiftRImm(Inst, Imm | 0x10, 32);
710}
711
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000712static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000713 uint64_t Addr, const void *Decoder) {
714 return DecodeVecShiftRImm(Inst, Imm, 16);
715}
716
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000717static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000718 uint64_t Addr,
719 const void *Decoder) {
720 return DecodeVecShiftRImm(Inst, Imm | 0x8, 16);
721}
722
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000723static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000724 uint64_t Addr, const void *Decoder) {
725 return DecodeVecShiftRImm(Inst, Imm, 8);
726}
727
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000728static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000729 uint64_t Addr, const void *Decoder) {
730 return DecodeVecShiftLImm(Inst, Imm, 64);
731}
732
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000733static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000734 uint64_t Addr, const void *Decoder) {
735 return DecodeVecShiftLImm(Inst, Imm, 32);
736}
737
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000738static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000739 uint64_t Addr, const void *Decoder) {
740 return DecodeVecShiftLImm(Inst, Imm, 16);
741}
742
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000743static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm,
Tim Northover3b0846e2014-05-24 12:50:23 +0000744 uint64_t Addr, const void *Decoder) {
745 return DecodeVecShiftLImm(Inst, Imm, 8);
746}
747
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000748static DecodeStatus DecodeThreeAddrSRegInstruction(MCInst &Inst, uint32_t insn,
749 uint64_t Addr,
Tim Northover3b0846e2014-05-24 12:50:23 +0000750 const void *Decoder) {
751 unsigned Rd = fieldFromInstruction(insn, 0, 5);
752 unsigned Rn = fieldFromInstruction(insn, 5, 5);
753 unsigned Rm = fieldFromInstruction(insn, 16, 5);
754 unsigned shiftHi = fieldFromInstruction(insn, 22, 2);
755 unsigned shiftLo = fieldFromInstruction(insn, 10, 6);
756 unsigned shift = (shiftHi << 6) | shiftLo;
757 switch (Inst.getOpcode()) {
758 default:
759 return Fail;
760 case AArch64::ADDWrs:
761 case AArch64::ADDSWrs:
762 case AArch64::SUBWrs:
763 case AArch64::SUBSWrs:
764 // if shift == '11' then ReservedValue()
765 if (shiftHi == 0x3)
766 return Fail;
Simon Pilgrimcb07d672017-07-07 16:40:06 +0000767 LLVM_FALLTHROUGH;
Tim Northover3b0846e2014-05-24 12:50:23 +0000768 case AArch64::ANDWrs:
769 case AArch64::ANDSWrs:
770 case AArch64::BICWrs:
771 case AArch64::BICSWrs:
772 case AArch64::ORRWrs:
773 case AArch64::ORNWrs:
774 case AArch64::EORWrs:
775 case AArch64::EONWrs: {
776 // if sf == '0' and imm6<5> == '1' then ReservedValue()
777 if (shiftLo >> 5 == 1)
778 return Fail;
779 DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
780 DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder);
781 DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
782 break;
783 }
784 case AArch64::ADDXrs:
785 case AArch64::ADDSXrs:
786 case AArch64::SUBXrs:
787 case AArch64::SUBSXrs:
788 // if shift == '11' then ReservedValue()
789 if (shiftHi == 0x3)
790 return Fail;
Simon Pilgrimcb07d672017-07-07 16:40:06 +0000791 LLVM_FALLTHROUGH;
Tim Northover3b0846e2014-05-24 12:50:23 +0000792 case AArch64::ANDXrs:
793 case AArch64::ANDSXrs:
794 case AArch64::BICXrs:
795 case AArch64::BICSXrs:
796 case AArch64::ORRXrs:
797 case AArch64::ORNXrs:
798 case AArch64::EORXrs:
799 case AArch64::EONXrs:
800 DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
801 DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder);
802 DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
803 break;
804 }
805
Jim Grosbache9119e42015-05-13 18:37:00 +0000806 Inst.addOperand(MCOperand::createImm(shift));
Tim Northover3b0846e2014-05-24 12:50:23 +0000807 return Success;
808}
809
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000810static DecodeStatus DecodeMoveImmInstruction(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +0000811 uint64_t Addr,
812 const void *Decoder) {
813 unsigned Rd = fieldFromInstruction(insn, 0, 5);
814 unsigned imm = fieldFromInstruction(insn, 5, 16);
815 unsigned shift = fieldFromInstruction(insn, 21, 2);
816 shift <<= 4;
817 switch (Inst.getOpcode()) {
818 default:
819 return Fail;
820 case AArch64::MOVZWi:
821 case AArch64::MOVNWi:
822 case AArch64::MOVKWi:
823 if (shift & (1U << 5))
824 return Fail;
825 DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
826 break;
827 case AArch64::MOVZXi:
828 case AArch64::MOVNXi:
829 case AArch64::MOVKXi:
830 DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
831 break;
832 }
833
834 if (Inst.getOpcode() == AArch64::MOVKWi ||
835 Inst.getOpcode() == AArch64::MOVKXi)
836 Inst.addOperand(Inst.getOperand(0));
837
Jim Grosbache9119e42015-05-13 18:37:00 +0000838 Inst.addOperand(MCOperand::createImm(imm));
839 Inst.addOperand(MCOperand::createImm(shift));
Tim Northover3b0846e2014-05-24 12:50:23 +0000840 return Success;
841}
842
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000843static DecodeStatus DecodeUnsignedLdStInstruction(MCInst &Inst, uint32_t insn,
844 uint64_t Addr,
Tim Northover3b0846e2014-05-24 12:50:23 +0000845 const void *Decoder) {
846 unsigned Rt = fieldFromInstruction(insn, 0, 5);
847 unsigned Rn = fieldFromInstruction(insn, 5, 5);
848 unsigned offset = fieldFromInstruction(insn, 10, 12);
849 const AArch64Disassembler *Dis =
850 static_cast<const AArch64Disassembler *>(Decoder);
851
852 switch (Inst.getOpcode()) {
853 default:
854 return Fail;
855 case AArch64::PRFMui:
856 // Rt is an immediate in prefetch.
Jim Grosbache9119e42015-05-13 18:37:00 +0000857 Inst.addOperand(MCOperand::createImm(Rt));
Tim Northover3b0846e2014-05-24 12:50:23 +0000858 break;
859 case AArch64::STRBBui:
860 case AArch64::LDRBBui:
861 case AArch64::LDRSBWui:
862 case AArch64::STRHHui:
863 case AArch64::LDRHHui:
864 case AArch64::LDRSHWui:
865 case AArch64::STRWui:
866 case AArch64::LDRWui:
867 DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
868 break;
869 case AArch64::LDRSBXui:
870 case AArch64::LDRSHXui:
871 case AArch64::LDRSWui:
872 case AArch64::STRXui:
873 case AArch64::LDRXui:
874 DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
875 break;
876 case AArch64::LDRQui:
877 case AArch64::STRQui:
878 DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
879 break;
880 case AArch64::LDRDui:
881 case AArch64::STRDui:
882 DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
883 break;
884 case AArch64::LDRSui:
885 case AArch64::STRSui:
886 DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
887 break;
888 case AArch64::LDRHui:
889 case AArch64::STRHui:
890 DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
891 break;
892 case AArch64::LDRBui:
893 case AArch64::STRBui:
894 DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
895 break;
896 }
897
898 DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
899 if (!Dis->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 4))
Jim Grosbache9119e42015-05-13 18:37:00 +0000900 Inst.addOperand(MCOperand::createImm(offset));
Tim Northover3b0846e2014-05-24 12:50:23 +0000901 return Success;
902}
903
Eugene Zelenko96d933d2017-07-25 23:51:02 +0000904static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
905 uint64_t Addr,
Tim Northover3b0846e2014-05-24 12:50:23 +0000906 const void *Decoder) {
907 unsigned Rt = fieldFromInstruction(insn, 0, 5);
908 unsigned Rn = fieldFromInstruction(insn, 5, 5);
909 int64_t offset = fieldFromInstruction(insn, 12, 9);
910
911 // offset is a 9-bit signed immediate, so sign extend it to
912 // fill the unsigned.
913 if (offset & (1 << (9 - 1)))
914 offset |= ~((1LL << 9) - 1);
915
916 // First operand is always the writeback to the address register, if needed.
917 switch (Inst.getOpcode()) {
918 default:
919 break;
920 case AArch64::LDRSBWpre:
921 case AArch64::LDRSHWpre:
922 case AArch64::STRBBpre:
923 case AArch64::LDRBBpre:
924 case AArch64::STRHHpre:
925 case AArch64::LDRHHpre:
926 case AArch64::STRWpre:
927 case AArch64::LDRWpre:
928 case AArch64::LDRSBWpost:
929 case AArch64::LDRSHWpost:
930 case AArch64::STRBBpost:
931 case AArch64::LDRBBpost:
932 case AArch64::STRHHpost:
933 case AArch64::LDRHHpost:
934 case AArch64::STRWpost:
935 case AArch64::LDRWpost:
936 case AArch64::LDRSBXpre:
937 case AArch64::LDRSHXpre:
938 case AArch64::STRXpre:
939 case AArch64::LDRSWpre:
940 case AArch64::LDRXpre:
941 case AArch64::LDRSBXpost:
942 case AArch64::LDRSHXpost:
943 case AArch64::STRXpost:
944 case AArch64::LDRSWpost:
945 case AArch64::LDRXpost:
946 case AArch64::LDRQpre:
947 case AArch64::STRQpre:
948 case AArch64::LDRQpost:
949 case AArch64::STRQpost:
950 case AArch64::LDRDpre:
951 case AArch64::STRDpre:
952 case AArch64::LDRDpost:
953 case AArch64::STRDpost:
954 case AArch64::LDRSpre:
955 case AArch64::STRSpre:
956 case AArch64::LDRSpost:
957 case AArch64::STRSpost:
958 case AArch64::LDRHpre:
959 case AArch64::STRHpre:
960 case AArch64::LDRHpost:
961 case AArch64::STRHpost:
962 case AArch64::LDRBpre:
963 case AArch64::STRBpre:
964 case AArch64::LDRBpost:
965 case AArch64::STRBpost:
966 DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
967 break;
968 }
969
970 switch (Inst.getOpcode()) {
971 default:
972 return Fail;
973 case AArch64::PRFUMi:
974 // Rt is an immediate in prefetch.
Jim Grosbache9119e42015-05-13 18:37:00 +0000975 Inst.addOperand(MCOperand::createImm(Rt));
Tim Northover3b0846e2014-05-24 12:50:23 +0000976 break;
977 case AArch64::STURBBi:
978 case AArch64::LDURBBi:
979 case AArch64::LDURSBWi:
980 case AArch64::STURHHi:
981 case AArch64::LDURHHi:
982 case AArch64::LDURSHWi:
983 case AArch64::STURWi:
984 case AArch64::LDURWi:
985 case AArch64::LDTRSBWi:
986 case AArch64::LDTRSHWi:
987 case AArch64::STTRWi:
988 case AArch64::LDTRWi:
989 case AArch64::STTRHi:
990 case AArch64::LDTRHi:
991 case AArch64::LDTRBi:
992 case AArch64::STTRBi:
993 case AArch64::LDRSBWpre:
994 case AArch64::LDRSHWpre:
995 case AArch64::STRBBpre:
996 case AArch64::LDRBBpre:
997 case AArch64::STRHHpre:
998 case AArch64::LDRHHpre:
999 case AArch64::STRWpre:
1000 case AArch64::LDRWpre:
1001 case AArch64::LDRSBWpost:
1002 case AArch64::LDRSHWpost:
1003 case AArch64::STRBBpost:
1004 case AArch64::LDRBBpost:
1005 case AArch64::STRHHpost:
1006 case AArch64::LDRHHpost:
1007 case AArch64::STRWpost:
1008 case AArch64::LDRWpost:
1009 DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
1010 break;
1011 case AArch64::LDURSBXi:
1012 case AArch64::LDURSHXi:
1013 case AArch64::LDURSWi:
1014 case AArch64::STURXi:
1015 case AArch64::LDURXi:
1016 case AArch64::LDTRSBXi:
1017 case AArch64::LDTRSHXi:
1018 case AArch64::LDTRSWi:
1019 case AArch64::STTRXi:
1020 case AArch64::LDTRXi:
1021 case AArch64::LDRSBXpre:
1022 case AArch64::LDRSHXpre:
1023 case AArch64::STRXpre:
1024 case AArch64::LDRSWpre:
1025 case AArch64::LDRXpre:
1026 case AArch64::LDRSBXpost:
1027 case AArch64::LDRSHXpost:
1028 case AArch64::STRXpost:
1029 case AArch64::LDRSWpost:
1030 case AArch64::LDRXpost:
1031 DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
1032 break;
1033 case AArch64::LDURQi:
1034 case AArch64::STURQi:
1035 case AArch64::LDRQpre:
1036 case AArch64::STRQpre:
1037 case AArch64::LDRQpost:
1038 case AArch64::STRQpost:
1039 DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
1040 break;
1041 case AArch64::LDURDi:
1042 case AArch64::STURDi:
1043 case AArch64::LDRDpre:
1044 case AArch64::STRDpre:
1045 case AArch64::LDRDpost:
1046 case AArch64::STRDpost:
1047 DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
1048 break;
1049 case AArch64::LDURSi:
1050 case AArch64::STURSi:
1051 case AArch64::LDRSpre:
1052 case AArch64::STRSpre:
1053 case AArch64::LDRSpost:
1054 case AArch64::STRSpost:
1055 DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
1056 break;
1057 case AArch64::LDURHi:
1058 case AArch64::STURHi:
1059 case AArch64::LDRHpre:
1060 case AArch64::STRHpre:
1061 case AArch64::LDRHpost:
1062 case AArch64::STRHpost:
1063 DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder);
1064 break;
1065 case AArch64::LDURBi:
1066 case AArch64::STURBi:
1067 case AArch64::LDRBpre:
1068 case AArch64::STRBpre:
1069 case AArch64::LDRBpost:
1070 case AArch64::STRBpost:
1071 DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder);
1072 break;
1073 }
1074
1075 DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
Jim Grosbache9119e42015-05-13 18:37:00 +00001076 Inst.addOperand(MCOperand::createImm(offset));
Tim Northover3b0846e2014-05-24 12:50:23 +00001077
1078 bool IsLoad = fieldFromInstruction(insn, 22, 1);
1079 bool IsIndexed = fieldFromInstruction(insn, 10, 2) != 0;
1080 bool IsFP = fieldFromInstruction(insn, 26, 1);
1081
1082 // Cannot write back to a transfer register (but xzr != sp).
1083 if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn)
1084 return SoftFail;
1085
1086 return Success;
1087}
1088
Eugene Zelenko96d933d2017-07-25 23:51:02 +00001089static DecodeStatus DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn,
1090 uint64_t Addr,
Tim Northover3b0846e2014-05-24 12:50:23 +00001091 const void *Decoder) {
1092 unsigned Rt = fieldFromInstruction(insn, 0, 5);
1093 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1094 unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
1095 unsigned Rs = fieldFromInstruction(insn, 16, 5);
1096
1097 unsigned Opcode = Inst.getOpcode();
1098 switch (Opcode) {
1099 default:
1100 return Fail;
1101 case AArch64::STLXRW:
1102 case AArch64::STLXRB:
1103 case AArch64::STLXRH:
1104 case AArch64::STXRW:
1105 case AArch64::STXRB:
1106 case AArch64::STXRH:
1107 DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
Justin Bognerb03fd122016-08-17 05:10:15 +00001108 LLVM_FALLTHROUGH;
Tim Northover3b0846e2014-05-24 12:50:23 +00001109 case AArch64::LDARW:
1110 case AArch64::LDARB:
1111 case AArch64::LDARH:
1112 case AArch64::LDAXRW:
1113 case AArch64::LDAXRB:
1114 case AArch64::LDAXRH:
1115 case AArch64::LDXRW:
1116 case AArch64::LDXRB:
1117 case AArch64::LDXRH:
1118 case AArch64::STLRW:
1119 case AArch64::STLRB:
1120 case AArch64::STLRH:
Vladimir Sukharevd49cb8f2015-04-16 15:30:43 +00001121 case AArch64::STLLRW:
1122 case AArch64::STLLRB:
1123 case AArch64::STLLRH:
1124 case AArch64::LDLARW:
1125 case AArch64::LDLARB:
1126 case AArch64::LDLARH:
Tim Northover3b0846e2014-05-24 12:50:23 +00001127 DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
1128 break;
1129 case AArch64::STLXRX:
1130 case AArch64::STXRX:
1131 DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
Justin Bognerb03fd122016-08-17 05:10:15 +00001132 LLVM_FALLTHROUGH;
Tim Northover3b0846e2014-05-24 12:50:23 +00001133 case AArch64::LDARX:
1134 case AArch64::LDAXRX:
1135 case AArch64::LDXRX:
1136 case AArch64::STLRX:
Vladimir Sukharevd49cb8f2015-04-16 15:30:43 +00001137 case AArch64::LDLARX:
1138 case AArch64::STLLRX:
Tim Northover3b0846e2014-05-24 12:50:23 +00001139 DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
1140 break;
1141 case AArch64::STLXPW:
1142 case AArch64::STXPW:
1143 DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
Justin Bognerb03fd122016-08-17 05:10:15 +00001144 LLVM_FALLTHROUGH;
Tim Northover3b0846e2014-05-24 12:50:23 +00001145 case AArch64::LDAXPW:
1146 case AArch64::LDXPW:
1147 DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
1148 DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);
1149 break;
1150 case AArch64::STLXPX:
1151 case AArch64::STXPX:
1152 DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder);
Justin Bognerb03fd122016-08-17 05:10:15 +00001153 LLVM_FALLTHROUGH;
Tim Northover3b0846e2014-05-24 12:50:23 +00001154 case AArch64::LDAXPX:
1155 case AArch64::LDXPX:
1156 DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
1157 DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);
1158 break;
1159 }
1160
1161 DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1162
1163 // You shouldn't load to the same register twice in an instruction...
1164 if ((Opcode == AArch64::LDAXPW || Opcode == AArch64::LDXPW ||
1165 Opcode == AArch64::LDAXPX || Opcode == AArch64::LDXPX) &&
1166 Rt == Rt2)
1167 return SoftFail;
1168
1169 return Success;
1170}
1171
Eugene Zelenko96d933d2017-07-25 23:51:02 +00001172static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +00001173 uint64_t Addr,
1174 const void *Decoder) {
1175 unsigned Rt = fieldFromInstruction(insn, 0, 5);
1176 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1177 unsigned Rt2 = fieldFromInstruction(insn, 10, 5);
1178 int64_t offset = fieldFromInstruction(insn, 15, 7);
1179 bool IsLoad = fieldFromInstruction(insn, 22, 1);
1180
1181 // offset is a 7-bit signed immediate, so sign extend it to
1182 // fill the unsigned.
1183 if (offset & (1 << (7 - 1)))
1184 offset |= ~((1LL << 7) - 1);
1185
1186 unsigned Opcode = Inst.getOpcode();
1187 bool NeedsDisjointWritebackTransfer = false;
1188
1189 // First operand is always writeback of base register.
1190 switch (Opcode) {
1191 default:
1192 break;
1193 case AArch64::LDPXpost:
1194 case AArch64::STPXpost:
1195 case AArch64::LDPSWpost:
1196 case AArch64::LDPXpre:
1197 case AArch64::STPXpre:
1198 case AArch64::LDPSWpre:
1199 case AArch64::LDPWpost:
1200 case AArch64::STPWpost:
1201 case AArch64::LDPWpre:
1202 case AArch64::STPWpre:
1203 case AArch64::LDPQpost:
1204 case AArch64::STPQpost:
1205 case AArch64::LDPQpre:
1206 case AArch64::STPQpre:
1207 case AArch64::LDPDpost:
1208 case AArch64::STPDpost:
1209 case AArch64::LDPDpre:
1210 case AArch64::STPDpre:
1211 case AArch64::LDPSpost:
1212 case AArch64::STPSpost:
1213 case AArch64::LDPSpre:
1214 case AArch64::STPSpre:
1215 DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1216 break;
1217 }
1218
1219 switch (Opcode) {
1220 default:
1221 return Fail;
1222 case AArch64::LDPXpost:
1223 case AArch64::STPXpost:
1224 case AArch64::LDPSWpost:
1225 case AArch64::LDPXpre:
1226 case AArch64::STPXpre:
1227 case AArch64::LDPSWpre:
1228 NeedsDisjointWritebackTransfer = true;
Justin Bognerb03fd122016-08-17 05:10:15 +00001229 LLVM_FALLTHROUGH;
Tim Northover3b0846e2014-05-24 12:50:23 +00001230 case AArch64::LDNPXi:
1231 case AArch64::STNPXi:
1232 case AArch64::LDPXi:
1233 case AArch64::STPXi:
1234 case AArch64::LDPSWi:
1235 DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
1236 DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder);
1237 break;
1238 case AArch64::LDPWpost:
1239 case AArch64::STPWpost:
1240 case AArch64::LDPWpre:
1241 case AArch64::STPWpre:
1242 NeedsDisjointWritebackTransfer = true;
Justin Bognerb03fd122016-08-17 05:10:15 +00001243 LLVM_FALLTHROUGH;
Tim Northover3b0846e2014-05-24 12:50:23 +00001244 case AArch64::LDNPWi:
1245 case AArch64::STNPWi:
1246 case AArch64::LDPWi:
1247 case AArch64::STPWi:
1248 DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
1249 DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder);
1250 break;
1251 case AArch64::LDNPQi:
1252 case AArch64::STNPQi:
1253 case AArch64::LDPQpost:
1254 case AArch64::STPQpost:
1255 case AArch64::LDPQi:
1256 case AArch64::STPQi:
1257 case AArch64::LDPQpre:
1258 case AArch64::STPQpre:
1259 DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder);
1260 DecodeFPR128RegisterClass(Inst, Rt2, Addr, Decoder);
1261 break;
1262 case AArch64::LDNPDi:
1263 case AArch64::STNPDi:
1264 case AArch64::LDPDpost:
1265 case AArch64::STPDpost:
1266 case AArch64::LDPDi:
1267 case AArch64::STPDi:
1268 case AArch64::LDPDpre:
1269 case AArch64::STPDpre:
1270 DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder);
1271 DecodeFPR64RegisterClass(Inst, Rt2, Addr, Decoder);
1272 break;
1273 case AArch64::LDNPSi:
1274 case AArch64::STNPSi:
1275 case AArch64::LDPSpost:
1276 case AArch64::STPSpost:
1277 case AArch64::LDPSi:
1278 case AArch64::STPSi:
1279 case AArch64::LDPSpre:
1280 case AArch64::STPSpre:
1281 DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder);
1282 DecodeFPR32RegisterClass(Inst, Rt2, Addr, Decoder);
1283 break;
1284 }
1285
1286 DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
Jim Grosbache9119e42015-05-13 18:37:00 +00001287 Inst.addOperand(MCOperand::createImm(offset));
Tim Northover3b0846e2014-05-24 12:50:23 +00001288
1289 // You shouldn't load to the same register twice in an instruction...
1290 if (IsLoad && Rt == Rt2)
1291 return SoftFail;
1292
1293 // ... or do any operation that writes-back to a transfer register. But note
1294 // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.
1295 if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn))
1296 return SoftFail;
1297
1298 return Success;
1299}
1300
Eugene Zelenko96d933d2017-07-25 23:51:02 +00001301static DecodeStatus DecodeAddSubERegInstruction(MCInst &Inst, uint32_t insn,
1302 uint64_t Addr,
Tim Northover3b0846e2014-05-24 12:50:23 +00001303 const void *Decoder) {
1304 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1305 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1306 unsigned Rm = fieldFromInstruction(insn, 16, 5);
1307 unsigned extend = fieldFromInstruction(insn, 10, 6);
1308
1309 unsigned shift = extend & 0x7;
1310 if (shift > 4)
1311 return Fail;
1312
1313 switch (Inst.getOpcode()) {
1314 default:
1315 return Fail;
1316 case AArch64::ADDWrx:
1317 case AArch64::SUBWrx:
1318 DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
1319 DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
1320 DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
1321 break;
1322 case AArch64::ADDSWrx:
1323 case AArch64::SUBSWrx:
1324 DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
1325 DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
1326 DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
1327 break;
1328 case AArch64::ADDXrx:
1329 case AArch64::SUBXrx:
1330 DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
1331 DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1332 DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
1333 break;
1334 case AArch64::ADDSXrx:
1335 case AArch64::SUBSXrx:
1336 DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
1337 DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1338 DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder);
1339 break;
1340 case AArch64::ADDXrx64:
1341 case AArch64::SUBXrx64:
1342 DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
1343 DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1344 DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
1345 break;
1346 case AArch64::SUBSXrx64:
1347 case AArch64::ADDSXrx64:
1348 DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
1349 DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1350 DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder);
1351 break;
1352 }
1353
Jim Grosbache9119e42015-05-13 18:37:00 +00001354 Inst.addOperand(MCOperand::createImm(extend));
Tim Northover3b0846e2014-05-24 12:50:23 +00001355 return Success;
1356}
1357
Eugene Zelenko96d933d2017-07-25 23:51:02 +00001358static DecodeStatus DecodeLogicalImmInstruction(MCInst &Inst, uint32_t insn,
1359 uint64_t Addr,
Tim Northover3b0846e2014-05-24 12:50:23 +00001360 const void *Decoder) {
1361 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1362 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1363 unsigned Datasize = fieldFromInstruction(insn, 31, 1);
1364 unsigned imm;
1365
1366 if (Datasize) {
1367 if (Inst.getOpcode() == AArch64::ANDSXri)
1368 DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
1369 else
1370 DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
1371 DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder);
1372 imm = fieldFromInstruction(insn, 10, 13);
1373 if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 64))
1374 return Fail;
1375 } else {
1376 if (Inst.getOpcode() == AArch64::ANDSWri)
1377 DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
1378 else
1379 DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
1380 DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder);
1381 imm = fieldFromInstruction(insn, 10, 12);
1382 if (!AArch64_AM::isValidDecodeLogicalImmediate(imm, 32))
1383 return Fail;
1384 }
Jim Grosbache9119e42015-05-13 18:37:00 +00001385 Inst.addOperand(MCOperand::createImm(imm));
Tim Northover3b0846e2014-05-24 12:50:23 +00001386 return Success;
1387}
1388
Eugene Zelenko96d933d2017-07-25 23:51:02 +00001389static DecodeStatus DecodeModImmInstruction(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +00001390 uint64_t Addr,
1391 const void *Decoder) {
1392 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1393 unsigned cmode = fieldFromInstruction(insn, 12, 4);
1394 unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
1395 imm |= fieldFromInstruction(insn, 5, 5);
1396
1397 if (Inst.getOpcode() == AArch64::MOVID)
1398 DecodeFPR64RegisterClass(Inst, Rd, Addr, Decoder);
1399 else
1400 DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder);
1401
Jim Grosbache9119e42015-05-13 18:37:00 +00001402 Inst.addOperand(MCOperand::createImm(imm));
Tim Northover3b0846e2014-05-24 12:50:23 +00001403
1404 switch (Inst.getOpcode()) {
1405 default:
1406 break;
1407 case AArch64::MOVIv4i16:
1408 case AArch64::MOVIv8i16:
1409 case AArch64::MVNIv4i16:
1410 case AArch64::MVNIv8i16:
1411 case AArch64::MOVIv2i32:
1412 case AArch64::MOVIv4i32:
1413 case AArch64::MVNIv2i32:
1414 case AArch64::MVNIv4i32:
Jim Grosbache9119e42015-05-13 18:37:00 +00001415 Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
Tim Northover3b0846e2014-05-24 12:50:23 +00001416 break;
1417 case AArch64::MOVIv2s_msl:
1418 case AArch64::MOVIv4s_msl:
1419 case AArch64::MVNIv2s_msl:
1420 case AArch64::MVNIv4s_msl:
Jim Grosbache9119e42015-05-13 18:37:00 +00001421 Inst.addOperand(MCOperand::createImm(cmode & 1 ? 0x110 : 0x108));
Tim Northover3b0846e2014-05-24 12:50:23 +00001422 break;
1423 }
1424
1425 return Success;
1426}
1427
Eugene Zelenko96d933d2017-07-25 23:51:02 +00001428static DecodeStatus DecodeModImmTiedInstruction(MCInst &Inst, uint32_t insn,
1429 uint64_t Addr,
Tim Northover3b0846e2014-05-24 12:50:23 +00001430 const void *Decoder) {
1431 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1432 unsigned cmode = fieldFromInstruction(insn, 12, 4);
1433 unsigned imm = fieldFromInstruction(insn, 16, 3) << 5;
1434 imm |= fieldFromInstruction(insn, 5, 5);
1435
1436 // Tied operands added twice.
1437 DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder);
1438 DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder);
1439
Jim Grosbache9119e42015-05-13 18:37:00 +00001440 Inst.addOperand(MCOperand::createImm(imm));
1441 Inst.addOperand(MCOperand::createImm((cmode & 6) << 2));
Tim Northover3b0846e2014-05-24 12:50:23 +00001442
1443 return Success;
1444}
1445
Eugene Zelenko96d933d2017-07-25 23:51:02 +00001446static DecodeStatus DecodeAdrInstruction(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +00001447 uint64_t Addr, const void *Decoder) {
1448 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1449 int64_t imm = fieldFromInstruction(insn, 5, 19) << 2;
1450 imm |= fieldFromInstruction(insn, 29, 2);
1451 const AArch64Disassembler *Dis =
1452 static_cast<const AArch64Disassembler *>(Decoder);
1453
1454 // Sign-extend the 21-bit immediate.
1455 if (imm & (1 << (21 - 1)))
1456 imm |= ~((1LL << 21) - 1);
1457
1458 DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
1459 if (!Dis->tryAddingSymbolicOperand(Inst, imm, Addr, Fail, 0, 4))
Jim Grosbache9119e42015-05-13 18:37:00 +00001460 Inst.addOperand(MCOperand::createImm(imm));
Tim Northover3b0846e2014-05-24 12:50:23 +00001461
1462 return Success;
1463}
1464
Eugene Zelenko96d933d2017-07-25 23:51:02 +00001465static DecodeStatus DecodeBaseAddSubImm(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +00001466 uint64_t Addr, const void *Decoder) {
1467 unsigned Rd = fieldFromInstruction(insn, 0, 5);
1468 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1469 unsigned Imm = fieldFromInstruction(insn, 10, 14);
1470 unsigned S = fieldFromInstruction(insn, 29, 1);
1471 unsigned Datasize = fieldFromInstruction(insn, 31, 1);
1472
1473 unsigned ShifterVal = (Imm >> 12) & 3;
1474 unsigned ImmVal = Imm & 0xFFF;
1475 const AArch64Disassembler *Dis =
1476 static_cast<const AArch64Disassembler *>(Decoder);
1477
1478 if (ShifterVal != 0 && ShifterVal != 1)
1479 return Fail;
1480
1481 if (Datasize) {
1482 if (Rd == 31 && !S)
1483 DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder);
1484 else
1485 DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder);
1486 DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder);
1487 } else {
1488 if (Rd == 31 && !S)
1489 DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder);
1490 else
1491 DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder);
1492 DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder);
1493 }
1494
1495 if (!Dis->tryAddingSymbolicOperand(Inst, Imm, Addr, Fail, 0, 4))
Jim Grosbache9119e42015-05-13 18:37:00 +00001496 Inst.addOperand(MCOperand::createImm(ImmVal));
1497 Inst.addOperand(MCOperand::createImm(12 * ShifterVal));
Tim Northover3b0846e2014-05-24 12:50:23 +00001498 return Success;
1499}
1500
Eugene Zelenko96d933d2017-07-25 23:51:02 +00001501static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +00001502 uint64_t Addr,
1503 const void *Decoder) {
1504 int64_t imm = fieldFromInstruction(insn, 0, 26);
1505 const AArch64Disassembler *Dis =
1506 static_cast<const AArch64Disassembler *>(Decoder);
1507
1508 // Sign-extend the 26-bit immediate.
1509 if (imm & (1 << (26 - 1)))
1510 imm |= ~((1LL << 26) - 1);
1511
Alexey Samsonov729b12e2014-09-02 16:19:41 +00001512 if (!Dis->tryAddingSymbolicOperand(Inst, imm * 4, Addr, true, 0, 4))
Jim Grosbache9119e42015-05-13 18:37:00 +00001513 Inst.addOperand(MCOperand::createImm(imm));
Tim Northover3b0846e2014-05-24 12:50:23 +00001514
1515 return Success;
1516}
1517
Eugene Zelenko96d933d2017-07-25 23:51:02 +00001518static DecodeStatus DecodeSystemPStateInstruction(MCInst &Inst, uint32_t insn,
1519 uint64_t Addr,
Tim Northover3b0846e2014-05-24 12:50:23 +00001520 const void *Decoder) {
1521 uint64_t op1 = fieldFromInstruction(insn, 16, 3);
1522 uint64_t op2 = fieldFromInstruction(insn, 5, 3);
1523 uint64_t crm = fieldFromInstruction(insn, 8, 4);
1524
1525 uint64_t pstate_field = (op1 << 3) | op2;
1526
Oliver Stannard911ea202015-11-26 15:32:30 +00001527 if ((pstate_field == AArch64PState::PAN ||
1528 pstate_field == AArch64PState::UAO) && crm > 1)
Alexandros Lamprineas1bab1912015-10-05 13:42:31 +00001529 return Fail;
1530
Jim Grosbache9119e42015-05-13 18:37:00 +00001531 Inst.addOperand(MCOperand::createImm(pstate_field));
1532 Inst.addOperand(MCOperand::createImm(crm));
Tim Northover3b0846e2014-05-24 12:50:23 +00001533
Tim Northovere6ae6762016-07-05 21:23:04 +00001534 const AArch64Disassembler *Dis =
Vladimir Sukhareva98f6892015-04-16 12:15:27 +00001535 static_cast<const AArch64Disassembler *>(Decoder);
Tim Northovere6ae6762016-07-05 21:23:04 +00001536 auto PState = AArch64PState::lookupPStateByEncoding(pstate_field);
1537 if (PState && PState->haveFeatures(Dis->getSubtargetInfo().getFeatureBits()))
1538 return Success;
1539 return Fail;
Tim Northover3b0846e2014-05-24 12:50:23 +00001540}
1541
Eugene Zelenko96d933d2017-07-25 23:51:02 +00001542static DecodeStatus DecodeTestAndBranch(MCInst &Inst, uint32_t insn,
Tim Northover3b0846e2014-05-24 12:50:23 +00001543 uint64_t Addr, const void *Decoder) {
1544 uint64_t Rt = fieldFromInstruction(insn, 0, 5);
1545 uint64_t bit = fieldFromInstruction(insn, 31, 1) << 5;
1546 bit |= fieldFromInstruction(insn, 19, 5);
1547 int64_t dst = fieldFromInstruction(insn, 5, 14);
1548 const AArch64Disassembler *Dis =
1549 static_cast<const AArch64Disassembler *>(Decoder);
1550
1551 // Sign-extend 14-bit immediate.
1552 if (dst & (1 << (14 - 1)))
1553 dst |= ~((1LL << 14) - 1);
1554
1555 if (fieldFromInstruction(insn, 31, 1) == 0)
1556 DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder);
1557 else
1558 DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder);
Jim Grosbache9119e42015-05-13 18:37:00 +00001559 Inst.addOperand(MCOperand::createImm(bit));
Alexey Samsonov729b12e2014-09-02 16:19:41 +00001560 if (!Dis->tryAddingSymbolicOperand(Inst, dst * 4, Addr, true, 0, 4))
Jim Grosbache9119e42015-05-13 18:37:00 +00001561 Inst.addOperand(MCOperand::createImm(dst));
Tim Northover3b0846e2014-05-24 12:50:23 +00001562
1563 return Success;
1564}
Vladimir Sukharev5f6f60d2015-06-02 10:58:41 +00001565
1566static DecodeStatus DecodeGPRSeqPairsClassRegisterClass(MCInst &Inst,
1567 unsigned RegClassID,
1568 unsigned RegNo,
1569 uint64_t Addr,
1570 const void *Decoder) {
1571 // Register number must be even (see CASP instruction)
1572 if (RegNo & 0x1)
1573 return Fail;
1574
1575 unsigned Register = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo);
1576 Inst.addOperand(MCOperand::createReg(Register));
1577 return Success;
1578}
1579
1580static DecodeStatus DecodeWSeqPairsClassRegisterClass(MCInst &Inst,
1581 unsigned RegNo,
1582 uint64_t Addr,
1583 const void *Decoder) {
Junmo Park45513a82016-07-15 22:42:52 +00001584 return DecodeGPRSeqPairsClassRegisterClass(Inst,
Vladimir Sukharev5f6f60d2015-06-02 10:58:41 +00001585 AArch64::WSeqPairsClassRegClassID,
1586 RegNo, Addr, Decoder);
1587}
1588
1589static DecodeStatus DecodeXSeqPairsClassRegisterClass(MCInst &Inst,
1590 unsigned RegNo,
1591 uint64_t Addr,
1592 const void *Decoder) {
Junmo Park45513a82016-07-15 22:42:52 +00001593 return DecodeGPRSeqPairsClassRegisterClass(Inst,
Vladimir Sukharev5f6f60d2015-06-02 10:58:41 +00001594 AArch64::XSeqPairsClassRegClassID,
1595 RegNo, Addr, Decoder);
1596}
Sam Parker6d42de72017-08-11 13:14:00 +00001597
1598template<int Bits>
1599static DecodeStatus DecodeSImm(llvm::MCInst &Inst, uint64_t Imm,
1600 uint64_t Address, const void *Decoder) {
1601 if (Imm & ~((1LL << Bits) - 1))
1602 return Fail;
1603
1604 // Imm is a signed immediate, so sign extend it.
1605 if (Imm & (1 << (Bits - 1)))
1606 Imm |= ~((1LL << Bits) - 1);
1607
1608 Inst.addOperand(MCOperand::createImm(Imm));
1609 return Success;
1610}
1611
1612static DecodeStatus DecodeAuthLoadWriteback(llvm::MCInst &Inst, uint32_t insn,
1613 uint64_t Address,
1614 const void *Decoder) {
1615 unsigned Rt = fieldFromInstruction(insn, 0, 5);
1616 unsigned Rn = fieldFromInstruction(insn, 5, 5);
1617 unsigned Imm9 = fieldFromInstruction(insn, 12, 9);
1618 unsigned S = fieldFromInstruction(insn, 22, 1);
1619
1620 unsigned Imm = Imm9 | (S << 9);
1621
1622 // Address writeback
1623 DecodeGPR64spRegisterClass(Inst, Rn, Address, Decoder);
1624 // Destination
1625 DecodeGPR64RegisterClass(Inst, Rt, Address, Decoder);
1626 // Address
1627 DecodeGPR64spRegisterClass(Inst, Rn, Address, Decoder);
1628 // Offset
1629 DecodeSImm<10>(Inst, Imm, Address, Decoder);
1630
1631 return Success;
1632}