1//===- AArch64Disassembler.cpp - Disassembler for AArch64 -----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//
10//===----------------------------------------------------------------------===//
11
12#include "AArch64Disassembler.h"
13#include "AArch64ExternalSymbolizer.h"
14#include "MCTargetDesc/AArch64AddressingModes.h"
15#include "MCTargetDesc/AArch64MCTargetDesc.h"
16#include "TargetInfo/AArch64TargetInfo.h"
17#include "Utils/AArch64BaseInfo.h"
18#include "llvm/MC/MCDecoder.h"
19#include "llvm/MC/MCDecoderOps.h"
20#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
21#include "llvm/MC/MCInst.h"
22#include "llvm/MC/MCInstrDesc.h"
23#include "llvm/MC/MCRegisterInfo.h"
24#include "llvm/MC/MCSubtargetInfo.h"
25#include "llvm/MC/TargetRegistry.h"
26#include "llvm/Support/Compiler.h"
27#include "llvm/Support/Debug.h"
28#include <memory>
29
30using namespace llvm;
31using namespace llvm::MCD;
32
33#define DEBUG_TYPE "aarch64-disassembler"
34
35// Pull DecodeStatus and its enum values into the global namespace.
36using DecodeStatus = MCDisassembler::DecodeStatus;
37
38template <int Bits>
39static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
40 const MCDisassembler *Decoder);
41template <int Bits>
42static DecodeStatus DecodeUImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
43 const MCDisassembler *Decoder);
44
45#define Success MCDisassembler::Success
46#define Fail MCDisassembler::Fail
47#define SoftFail MCDisassembler::SoftFail
48
49template <unsigned RegClassID, unsigned FirstReg, unsigned NumRegsInClass>
50static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, unsigned RegNo,
51 uint64_t Address,
52 const MCDisassembler *Decoder) {
53 if (RegNo > NumRegsInClass - 1)
54 return Fail;
55
56 MCRegister Register =
57 AArch64MCRegisterClasses[RegClassID].getRegister(i: RegNo + FirstReg);
58 Inst.addOperand(Op: MCOperand::createReg(Reg: Register));
59 return Success;
60}
61
62static DecodeStatus
63DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
64 const MCDisassembler *Decoder) {
65 if (RegNo > 22)
66 return Fail;
67 if (RegNo & 1)
68 return Fail;
69
70 MCRegister Register =
71 AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].getRegister(
72 i: RegNo >> 1);
73 Inst.addOperand(Op: MCOperand::createReg(Reg: Register));
74 return Success;
75}
76
77template <unsigned Min, unsigned Max>
78static DecodeStatus DecodeZPRMul2_MinMax(MCInst &Inst, unsigned RegNo,
79 uint64_t Address,
80 const MCDisassembler *Decoder) {
81 unsigned Reg = (RegNo * 2) + Min;
82 if (Reg < Min || Reg > Max || (Reg & 1))
83 return Fail;
84 MCRegister Register =
85 AArch64MCRegisterClasses[AArch64::ZPRRegClassID].getRegister(i: Reg);
86 Inst.addOperand(Op: MCOperand::createReg(Reg: Register));
87 return Success;
88}
89
90template <unsigned Min, unsigned Max>
91static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
92 uint64_t Address,
93 const void *Decoder) {
94 unsigned Reg = (RegNo * 2) + Min;
95 if (Reg < Min || Reg > Max || (Reg & 1))
96 return Fail;
97
98 MCRegister Register =
99 AArch64MCRegisterClasses[AArch64::ZPR2RegClassID].getRegister(i: Reg);
100 Inst.addOperand(Op: MCOperand::createReg(Reg: Register));
101 return Success;
102}
103
104static DecodeStatus DecodeZK(MCInst &Inst, unsigned RegNo, uint64_t Address,
105 const MCDisassembler *Decoder) {
106 if (RegNo > 7)
107 return Fail;
108
109 MCRegister Register =
110 AArch64MCRegisterClasses[AArch64::ZPR_KRegClassID].getRegister(i: RegNo);
111 Inst.addOperand(Op: MCOperand::createReg(Reg: Register));
112 return Success;
113}
114
115static DecodeStatus DecodeZPR4Mul4RegisterClass(MCInst &Inst, unsigned RegNo,
116 uint64_t Address,
117 const void *Decoder) {
118 if (RegNo * 4 > 28)
119 return Fail;
120 MCRegister Register =
121 AArch64MCRegisterClasses[AArch64::ZPR4RegClassID].getRegister(i: RegNo * 4);
122 Inst.addOperand(Op: MCOperand::createReg(Reg: Register));
123 return Success;
124}
125
126static DecodeStatus
127DecodeMatrixTileListRegisterClass(MCInst &Inst, unsigned RegMask,
128 uint64_t Address,
129 const MCDisassembler *Decoder) {
130 if (RegMask > 0xFF)
131 return Fail;
132 Inst.addOperand(Op: MCOperand::createImm(Val: RegMask));
133 return Success;
134}
135
136static DecodeStatus DecodeZTRRegisterClass(MCInst &Inst,
137 const MCDisassembler *Decoder) {
138 Inst.addOperand(Op: MCOperand::createReg(Reg: AArch64::ZT0));
139 return Success;
140}
141
142static DecodeStatus DecodeMPRRegisterClass(MCInst &Inst,
143 const MCDisassembler *Decoder) {
144 Inst.addOperand(Op: MCOperand::createReg(Reg: AArch64::ZA));
145 return Success;
146}
147
148static DecodeStatus DecodeMPR8RegisterClass(MCInst &Inst,
149 const MCDisassembler *Decoder) {
150 Inst.addOperand(Op: MCOperand::createReg(Reg: AArch64::ZAB0));
151 return Success;
152}
153
154static DecodeStatus DecodeMPR16RegisterClass(MCInst &Inst, unsigned RegNo,
155 uint64_t Address,
156 const MCDisassembler *Decoder) {
157 MCRegister Reg =
158 AArch64MCRegisterClasses[AArch64::MPR16RegClassID].getRegister(i: RegNo);
159 Inst.addOperand(Op: MCOperand::createReg(Reg));
160 return Success;
161}
162
163static DecodeStatus DecodeMPR32RegisterClass(MCInst &Inst, unsigned RegNo,
164 uint64_t Address,
165 const MCDisassembler *Decoder) {
166 MCRegister Reg =
167 AArch64MCRegisterClasses[AArch64::MPR32RegClassID].getRegister(i: RegNo);
168 Inst.addOperand(Op: MCOperand::createReg(Reg));
169 return Success;
170}
171
172static DecodeStatus DecodeMPR64RegisterClass(MCInst &Inst, unsigned RegNo,
173 uint64_t Address,
174 const MCDisassembler *Decoder) {
175 MCRegister Reg =
176 AArch64MCRegisterClasses[AArch64::MPR64RegClassID].getRegister(i: RegNo);
177 Inst.addOperand(Op: MCOperand::createReg(Reg));
178 return Success;
179}
180
181static DecodeStatus DecodeMPR128RegisterClass(MCInst &Inst, unsigned RegNo,
182 uint64_t Address,
183 const MCDisassembler *Decoder) {
184 MCRegister Reg =
185 AArch64MCRegisterClasses[AArch64::MPR128RegClassID].getRegister(i: RegNo);
186 Inst.addOperand(Op: MCOperand::createReg(Reg));
187 return Success;
188}
189
190static DecodeStatus DecodePPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo,
191 uint64_t Address,
192 const void *Decoder) {
193 if ((RegNo * 2) > 14)
194 return Fail;
195 MCRegister Register =
196 AArch64MCRegisterClasses[AArch64::PPR2RegClassID].getRegister(i: RegNo * 2);
197 Inst.addOperand(Op: MCOperand::createReg(Reg: Register));
198 return Success;
199}
200
201static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm,
202 uint64_t Addr,
203 const MCDisassembler *Decoder) {
204 // scale{5} is asserted as 1 in tblgen.
205 Imm |= 0x20;
206 Inst.addOperand(Op: MCOperand::createImm(Val: 64 - Imm));
207 return Success;
208}
209
210static DecodeStatus DecodeFixedPointScaleImm64(MCInst &Inst, unsigned Imm,
211 uint64_t Addr,
212 const MCDisassembler *Decoder) {
213 Inst.addOperand(Op: MCOperand::createImm(Val: 64 - Imm));
214 return Success;
215}
216
217static DecodeStatus DecodePCRelLabel16(MCInst &Inst, unsigned Imm,
218 uint64_t Addr,
219 const MCDisassembler *Decoder) {
220 // Immediate is encoded as the top 16-bits of an unsigned 18-bit negative
221 // PC-relative offset.
222 uint64_t ImmVal = Imm;
223 if (ImmVal > (1 << 16))
224 return Fail;
225 ImmVal = -ImmVal;
226 if (!Decoder->tryAddingSymbolicOperand(Inst, Value: (ImmVal << 2), Address: Addr,
227 /*IsBranch=*/false, Offset: 0, OpSize: 0, InstSize: 4))
228 Inst.addOperand(Op: MCOperand::createImm(Val: ImmVal));
229 return Success;
230}
231
232static DecodeStatus DecodePCRelLabel19(MCInst &Inst, unsigned Imm,
233 uint64_t Addr,
234 const MCDisassembler *Decoder) {
235 int64_t ImmVal = SignExtend64<19>(x: Imm);
236
237 if (!Decoder->tryAddingSymbolicOperand(
238 Inst, Value: ImmVal * 4, Address: Addr, IsBranch: Inst.getOpcode() != AArch64::LDRXl, Offset: 0, OpSize: 0, InstSize: 4))
239 Inst.addOperand(Op: MCOperand::createImm(Val: ImmVal));
240 return Success;
241}
242
243static DecodeStatus DecodePCRelLabel9(MCInst &Inst, unsigned Imm, uint64_t Addr,
244 const MCDisassembler *Decoder) {
245 int64_t ImmVal = SignExtend64<9>(x: Imm);
246
247 if (!Decoder->tryAddingSymbolicOperand(Inst, Value: (ImmVal * 4), Address: Addr,
248 /*IsBranch=*/true, Offset: 0, OpSize: 0, InstSize: 4))
249 Inst.addOperand(Op: MCOperand::createImm(Val: ImmVal));
250 return Success;
251}
252
253static DecodeStatus DecodeMemExtend(MCInst &Inst, unsigned Imm,
254 uint64_t Address,
255 const MCDisassembler *Decoder) {
256 Inst.addOperand(Op: MCOperand::createImm(Val: (Imm >> 1) & 1));
257 Inst.addOperand(Op: MCOperand::createImm(Val: Imm & 1));
258 return Success;
259}
260
261static DecodeStatus DecodeMRSSystemRegister(MCInst &Inst, unsigned Imm,
262 uint64_t Address,
263 const MCDisassembler *Decoder) {
264 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
265
266 // Every system register in the encoding space is valid with the syntax
267 // S<op0>_<op1>_<Cn>_<Cm>_<op2>, so decoding system registers always succeeds.
268 return Success;
269}
270
271static DecodeStatus DecodeMSRSystemRegister(MCInst &Inst, unsigned Imm,
272 uint64_t Address,
273 const MCDisassembler *Decoder) {
274 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
275
276 return Success;
277}
278
279static DecodeStatus DecodeFMOVLaneInstruction(MCInst &Inst, unsigned Insn,
280 uint64_t Address,
281 const MCDisassembler *Decoder) {
282 // This decoder exists to add the dummy Lane operand to the MCInst, which must
283 // be 1 in assembly but has no other real manifestation.
284 unsigned Rd = fieldFromInstruction(Insn, StartBit: 0, NumBits: 5);
285 unsigned Rn = fieldFromInstruction(Insn, StartBit: 5, NumBits: 5);
286 unsigned IsToVec = fieldFromInstruction(Insn, StartBit: 16, NumBits: 1);
287
288 if (IsToVec) {
289 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(
290 Inst, RegNo: Rd, Address, Decoder);
291 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
292 Inst, RegNo: Rn, Address, Decoder);
293 } else {
294 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
295 Inst, RegNo: Rd, Address, Decoder);
296 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(
297 Inst, RegNo: Rn, Address, Decoder);
298 }
299
300 // Add the lane
301 Inst.addOperand(Op: MCOperand::createImm(Val: 1));
302
303 return Success;
304}
305
306static DecodeStatus DecodeVecShiftRImm(MCInst &Inst, unsigned Imm,
307 unsigned Add) {
308 Inst.addOperand(Op: MCOperand::createImm(Val: Add - Imm));
309 return Success;
310}
311
312static DecodeStatus DecodeVecShiftLImm(MCInst &Inst, unsigned Imm,
313 unsigned Add) {
314 Inst.addOperand(Op: MCOperand::createImm(Val: (Imm + Add) & (Add - 1)));
315 return Success;
316}
317
318static DecodeStatus DecodeVecShiftR64Imm(MCInst &Inst, unsigned Imm,
319 uint64_t Addr,
320 const MCDisassembler *Decoder) {
321 return DecodeVecShiftRImm(Inst, Imm, Add: 64);
322}
323
324static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst &Inst, unsigned Imm,
325 uint64_t Addr,
326 const MCDisassembler *Decoder) {
327 return DecodeVecShiftRImm(Inst, Imm: Imm | 0x20, Add: 64);
328}
329
330static DecodeStatus DecodeVecShiftR32Imm(MCInst &Inst, unsigned Imm,
331 uint64_t Addr,
332 const MCDisassembler *Decoder) {
333 return DecodeVecShiftRImm(Inst, Imm, Add: 32);
334}
335
336static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst &Inst, unsigned Imm,
337 uint64_t Addr,
338 const MCDisassembler *Decoder) {
339 return DecodeVecShiftRImm(Inst, Imm: Imm | 0x10, Add: 32);
340}
341
342static DecodeStatus DecodeVecShiftR16Imm(MCInst &Inst, unsigned Imm,
343 uint64_t Addr,
344 const MCDisassembler *Decoder) {
345 return DecodeVecShiftRImm(Inst, Imm, Add: 16);
346}
347
348static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst &Inst, unsigned Imm,
349 uint64_t Addr,
350 const MCDisassembler *Decoder) {
351 return DecodeVecShiftRImm(Inst, Imm: Imm | 0x8, Add: 16);
352}
353
354static DecodeStatus DecodeVecShiftR8Imm(MCInst &Inst, unsigned Imm,
355 uint64_t Addr,
356 const MCDisassembler *Decoder) {
357 return DecodeVecShiftRImm(Inst, Imm, Add: 8);
358}
359
360static DecodeStatus DecodeVecShiftL64Imm(MCInst &Inst, unsigned Imm,
361 uint64_t Addr,
362 const MCDisassembler *Decoder) {
363 return DecodeVecShiftLImm(Inst, Imm, Add: 64);
364}
365
366static DecodeStatus DecodeVecShiftL32Imm(MCInst &Inst, unsigned Imm,
367 uint64_t Addr,
368 const MCDisassembler *Decoder) {
369 return DecodeVecShiftLImm(Inst, Imm, Add: 32);
370}
371
372static DecodeStatus DecodeVecShiftL16Imm(MCInst &Inst, unsigned Imm,
373 uint64_t Addr,
374 const MCDisassembler *Decoder) {
375 return DecodeVecShiftLImm(Inst, Imm, Add: 16);
376}
377
378static DecodeStatus DecodeVecShiftL8Imm(MCInst &Inst, unsigned Imm,
379 uint64_t Addr,
380 const MCDisassembler *Decoder) {
381 return DecodeVecShiftLImm(Inst, Imm, Add: 8);
382}
383
384static DecodeStatus
385DecodeThreeAddrSRegInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
386 const MCDisassembler *Decoder) {
387 unsigned Rd = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
388 unsigned Rn = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 5);
389 unsigned Rm = fieldFromInstruction(Insn: insn, StartBit: 16, NumBits: 5);
390 unsigned shiftHi = fieldFromInstruction(Insn: insn, StartBit: 22, NumBits: 2);
391 unsigned shiftLo = fieldFromInstruction(Insn: insn, StartBit: 10, NumBits: 6);
392 unsigned shift = (shiftHi << 6) | shiftLo;
393 switch (Inst.getOpcode()) {
394 default:
395 return Fail;
396 case AArch64::ADDWrs:
397 case AArch64::ADDSWrs:
398 case AArch64::SUBWrs:
399 case AArch64::SUBSWrs:
400 // if shift == '11' then ReservedValue()
401 if (shiftHi == 0x3)
402 return Fail;
403 [[fallthrough]];
404 case AArch64::ANDWrs:
405 case AArch64::ANDSWrs:
406 case AArch64::BICWrs:
407 case AArch64::BICSWrs:
408 case AArch64::ORRWrs:
409 case AArch64::ORNWrs:
410 case AArch64::EORWrs:
411 case AArch64::EONWrs: {
412 // if sf == '0' and imm6<5> == '1' then ReservedValue()
413 if (shiftLo >> 5 == 1)
414 return Fail;
415 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
416 Decoder);
417 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
418 Decoder);
419 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rm, Address: Addr,
420 Decoder);
421 break;
422 }
423 case AArch64::ADDXrs:
424 case AArch64::ADDSXrs:
425 case AArch64::SUBXrs:
426 case AArch64::SUBSXrs:
427 // if shift == '11' then ReservedValue()
428 if (shiftHi == 0x3)
429 return Fail;
430 [[fallthrough]];
431 case AArch64::ANDXrs:
432 case AArch64::ANDSXrs:
433 case AArch64::BICXrs:
434 case AArch64::BICSXrs:
435 case AArch64::ORRXrs:
436 case AArch64::ORNXrs:
437 case AArch64::EORXrs:
438 case AArch64::EONXrs:
439 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
440 Decoder);
441 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
442 Decoder);
443 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rm, Address: Addr,
444 Decoder);
445 break;
446 }
447
448 Inst.addOperand(Op: MCOperand::createImm(Val: shift));
449 return Success;
450}
451
452static DecodeStatus DecodeMoveImmInstruction(MCInst &Inst, uint32_t insn,
453 uint64_t Addr,
454 const MCDisassembler *Decoder) {
455 unsigned Rd = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
456 unsigned imm = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 16);
457 unsigned shift = fieldFromInstruction(Insn: insn, StartBit: 21, NumBits: 2);
458 shift <<= 4;
459 switch (Inst.getOpcode()) {
460 default:
461 return Fail;
462 case AArch64::MOVZWi:
463 case AArch64::MOVNWi:
464 case AArch64::MOVKWi:
465 if (shift & (1U << 5))
466 return Fail;
467 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
468 Decoder);
469 break;
470 case AArch64::MOVZXi:
471 case AArch64::MOVNXi:
472 case AArch64::MOVKXi:
473 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
474 Decoder);
475 break;
476 }
477
478 if (Inst.getOpcode() == AArch64::MOVKWi ||
479 Inst.getOpcode() == AArch64::MOVKXi)
480 Inst.addOperand(Op: Inst.getOperand(i: 0));
481
482 if (!Decoder->tryAddingSymbolicOperand(Inst, Value: imm, Address: Addr, /*IsBranch*/ false, Offset: 0,
483 OpSize: 0, InstSize: 4))
484 Inst.addOperand(Op: MCOperand::createImm(Val: imm));
485
486 Inst.addOperand(Op: MCOperand::createImm(Val: shift));
487 return Success;
488}
489
490static DecodeStatus
491DecodeUnsignedLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
492 const MCDisassembler *Decoder) {
493 unsigned Rt = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
494 unsigned Rn = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 5);
495 unsigned offset = fieldFromInstruction(Insn: insn, StartBit: 10, NumBits: 12);
496
497 switch (Inst.getOpcode()) {
498 default:
499 return Fail;
500 case AArch64::PRFMui:
501 // Rt is an immediate in prefetch.
502 Inst.addOperand(Op: MCOperand::createImm(Val: Rt));
503 break;
504 case AArch64::STRBBui:
505 case AArch64::LDRBBui:
506 case AArch64::LDRSBWui:
507 case AArch64::STRHHui:
508 case AArch64::LDRHHui:
509 case AArch64::LDRSHWui:
510 case AArch64::STRWui:
511 case AArch64::LDRWui:
512 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
513 Decoder);
514 break;
515 case AArch64::LDRSBXui:
516 case AArch64::LDRSHXui:
517 case AArch64::LDRSWui:
518 case AArch64::STRXui:
519 case AArch64::LDRXui:
520 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
521 Decoder);
522 break;
523 case AArch64::LDRQui:
524 case AArch64::STRQui:
525 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
526 Decoder);
527 break;
528 case AArch64::LDRDui:
529 case AArch64::STRDui:
530 DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
531 Decoder);
532 break;
533 case AArch64::LDRSui:
534 case AArch64::STRSui:
535 DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
536 Decoder);
537 break;
538 case AArch64::LDRHui:
539 case AArch64::STRHui:
540 DecodeSimpleRegisterClass<AArch64::FPR16RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
541 Decoder);
542 break;
543 case AArch64::LDRBui:
544 case AArch64::STRBui:
545 DecodeSimpleRegisterClass<AArch64::FPR8RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
546 Decoder);
547 break;
548 }
549
550 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
551 Decoder);
552 if (!Decoder->tryAddingSymbolicOperand(Inst, Value: offset, Address: Addr, Fail, Offset: 0, OpSize: 0, InstSize: 4))
553 Inst.addOperand(Op: MCOperand::createImm(Val: offset));
554 return Success;
555}
556
557static DecodeStatus DecodeSignedLdStInstruction(MCInst &Inst, uint32_t insn,
558 uint64_t Addr,
559 const MCDisassembler *Decoder) {
560 unsigned Rt = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
561 unsigned Rn = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 5);
562 int64_t offset = SignExtend64<9>(x: fieldFromInstruction(Insn: insn, StartBit: 12, NumBits: 9));
563
564 // First operand is always the writeback to the address register, if needed.
565 switch (Inst.getOpcode()) {
566 default:
567 break;
568 case AArch64::LDRSBWpre:
569 case AArch64::LDRSHWpre:
570 case AArch64::STRBBpre:
571 case AArch64::LDRBBpre:
572 case AArch64::STRHHpre:
573 case AArch64::LDRHHpre:
574 case AArch64::STRWpre:
575 case AArch64::LDRWpre:
576 case AArch64::LDRSBWpost:
577 case AArch64::LDRSHWpost:
578 case AArch64::STRBBpost:
579 case AArch64::LDRBBpost:
580 case AArch64::STRHHpost:
581 case AArch64::LDRHHpost:
582 case AArch64::STRWpost:
583 case AArch64::LDRWpost:
584 case AArch64::LDRSBXpre:
585 case AArch64::LDRSHXpre:
586 case AArch64::STRXpre:
587 case AArch64::LDRSWpre:
588 case AArch64::LDRXpre:
589 case AArch64::LDRSBXpost:
590 case AArch64::LDRSHXpost:
591 case AArch64::STRXpost:
592 case AArch64::LDRSWpost:
593 case AArch64::LDRXpost:
594 case AArch64::LDRQpre:
595 case AArch64::STRQpre:
596 case AArch64::LDRQpost:
597 case AArch64::STRQpost:
598 case AArch64::LDRDpre:
599 case AArch64::STRDpre:
600 case AArch64::LDRDpost:
601 case AArch64::STRDpost:
602 case AArch64::LDRSpre:
603 case AArch64::STRSpre:
604 case AArch64::LDRSpost:
605 case AArch64::STRSpost:
606 case AArch64::LDRHpre:
607 case AArch64::STRHpre:
608 case AArch64::LDRHpost:
609 case AArch64::STRHpost:
610 case AArch64::LDRBpre:
611 case AArch64::STRBpre:
612 case AArch64::LDRBpost:
613 case AArch64::STRBpost:
614 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
615 Decoder);
616 break;
617 }
618
619 switch (Inst.getOpcode()) {
620 default:
621 return Fail;
622 case AArch64::PRFUMi:
623 // Rt is an immediate in prefetch.
624 Inst.addOperand(Op: MCOperand::createImm(Val: Rt));
625 break;
626 case AArch64::STURBBi:
627 case AArch64::LDURBBi:
628 case AArch64::LDURSBWi:
629 case AArch64::STURHHi:
630 case AArch64::LDURHHi:
631 case AArch64::LDURSHWi:
632 case AArch64::STURWi:
633 case AArch64::LDURWi:
634 case AArch64::LDTRSBWi:
635 case AArch64::LDTRSHWi:
636 case AArch64::STTRWi:
637 case AArch64::LDTRWi:
638 case AArch64::STTRHi:
639 case AArch64::LDTRHi:
640 case AArch64::LDTRBi:
641 case AArch64::STTRBi:
642 case AArch64::LDRSBWpre:
643 case AArch64::LDRSHWpre:
644 case AArch64::STRBBpre:
645 case AArch64::LDRBBpre:
646 case AArch64::STRHHpre:
647 case AArch64::LDRHHpre:
648 case AArch64::STRWpre:
649 case AArch64::LDRWpre:
650 case AArch64::LDRSBWpost:
651 case AArch64::LDRSHWpost:
652 case AArch64::STRBBpost:
653 case AArch64::LDRBBpost:
654 case AArch64::STRHHpost:
655 case AArch64::LDRHHpost:
656 case AArch64::STRWpost:
657 case AArch64::LDRWpost:
658 case AArch64::STLURBi:
659 case AArch64::STLURHi:
660 case AArch64::STLURWi:
661 case AArch64::LDAPURBi:
662 case AArch64::LDAPURSBWi:
663 case AArch64::LDAPURHi:
664 case AArch64::LDAPURSHWi:
665 case AArch64::LDAPURi:
666 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
667 Decoder);
668 break;
669 case AArch64::LDURSBXi:
670 case AArch64::LDURSHXi:
671 case AArch64::LDURSWi:
672 case AArch64::STURXi:
673 case AArch64::LDURXi:
674 case AArch64::LDTRSBXi:
675 case AArch64::LDTRSHXi:
676 case AArch64::LDTRSWi:
677 case AArch64::STTRXi:
678 case AArch64::LDTRXi:
679 case AArch64::LDRSBXpre:
680 case AArch64::LDRSHXpre:
681 case AArch64::STRXpre:
682 case AArch64::LDRSWpre:
683 case AArch64::LDRXpre:
684 case AArch64::LDRSBXpost:
685 case AArch64::LDRSHXpost:
686 case AArch64::STRXpost:
687 case AArch64::LDRSWpost:
688 case AArch64::LDRXpost:
689 case AArch64::LDAPURSWi:
690 case AArch64::LDAPURSHXi:
691 case AArch64::LDAPURSBXi:
692 case AArch64::STLURXi:
693 case AArch64::LDAPURXi:
694 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
695 Decoder);
696 break;
697 case AArch64::LDURQi:
698 case AArch64::STURQi:
699 case AArch64::LDRQpre:
700 case AArch64::STRQpre:
701 case AArch64::LDRQpost:
702 case AArch64::STRQpost:
703 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
704 Decoder);
705 break;
706 case AArch64::LDURDi:
707 case AArch64::STURDi:
708 case AArch64::LDRDpre:
709 case AArch64::STRDpre:
710 case AArch64::LDRDpost:
711 case AArch64::STRDpost:
712 DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
713 Decoder);
714 break;
715 case AArch64::LDURSi:
716 case AArch64::STURSi:
717 case AArch64::LDRSpre:
718 case AArch64::STRSpre:
719 case AArch64::LDRSpost:
720 case AArch64::STRSpost:
721 DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
722 Decoder);
723 break;
724 case AArch64::LDURHi:
725 case AArch64::STURHi:
726 case AArch64::LDRHpre:
727 case AArch64::STRHpre:
728 case AArch64::LDRHpost:
729 case AArch64::STRHpost:
730 DecodeSimpleRegisterClass<AArch64::FPR16RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
731 Decoder);
732 break;
733 case AArch64::LDURBi:
734 case AArch64::STURBi:
735 case AArch64::LDRBpre:
736 case AArch64::STRBpre:
737 case AArch64::LDRBpost:
738 case AArch64::STRBpost:
739 DecodeSimpleRegisterClass<AArch64::FPR8RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
740 Decoder);
741 break;
742 }
743
744 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
745 Decoder);
746 Inst.addOperand(Op: MCOperand::createImm(Val: offset));
747
748 bool IsLoad = fieldFromInstruction(Insn: insn, StartBit: 22, NumBits: 1);
749 bool IsIndexed = fieldFromInstruction(Insn: insn, StartBit: 10, NumBits: 2) != 0;
750 bool IsFP = fieldFromInstruction(Insn: insn, StartBit: 26, NumBits: 1);
751
752 // Cannot write back to a transfer register (but xzr != sp).
753 if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn)
754 return SoftFail;
755
756 return Success;
757}
758
759static DecodeStatus
760DecodeExclusiveLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
761 const MCDisassembler *Decoder) {
762 unsigned Rt = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
763 unsigned Rn = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 5);
764 unsigned Rt2 = fieldFromInstruction(Insn: insn, StartBit: 10, NumBits: 5);
765 unsigned Rs = fieldFromInstruction(Insn: insn, StartBit: 16, NumBits: 5);
766
767 unsigned Opcode = Inst.getOpcode();
768 switch (Opcode) {
769 default:
770 return Fail;
771 case AArch64::STLXRW:
772 case AArch64::STLXRB:
773 case AArch64::STLXRH:
774 case AArch64::STXRW:
775 case AArch64::STXRB:
776 case AArch64::STXRH:
777 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rs, Address: Addr,
778 Decoder);
779 [[fallthrough]];
780 case AArch64::LDARW:
781 case AArch64::LDARB:
782 case AArch64::LDARH:
783 case AArch64::LDAXRW:
784 case AArch64::LDAXRB:
785 case AArch64::LDAXRH:
786 case AArch64::LDXRW:
787 case AArch64::LDXRB:
788 case AArch64::LDXRH:
789 case AArch64::STLRW:
790 case AArch64::STLRB:
791 case AArch64::STLRH:
792 case AArch64::STLLRW:
793 case AArch64::STLLRB:
794 case AArch64::STLLRH:
795 case AArch64::LDLARW:
796 case AArch64::LDLARB:
797 case AArch64::LDLARH:
798 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
799 Decoder);
800 break;
801 case AArch64::STLXRX:
802 case AArch64::STXRX:
803 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rs, Address: Addr,
804 Decoder);
805 [[fallthrough]];
806 case AArch64::LDARX:
807 case AArch64::LDAXRX:
808 case AArch64::LDXRX:
809 case AArch64::STLRX:
810 case AArch64::LDLARX:
811 case AArch64::STLLRX:
812 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
813 Decoder);
814 break;
815 case AArch64::STLXPW:
816 case AArch64::STXPW:
817 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rs, Address: Addr,
818 Decoder);
819 [[fallthrough]];
820 case AArch64::LDAXPW:
821 case AArch64::LDXPW:
822 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
823 Decoder);
824 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rt2, Address: Addr,
825 Decoder);
826 break;
827 case AArch64::STLXPX:
828 case AArch64::STXPX:
829 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rs, Address: Addr,
830 Decoder);
831 [[fallthrough]];
832 case AArch64::LDAXPX:
833 case AArch64::LDXPX:
834 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
835 Decoder);
836 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rt2, Address: Addr,
837 Decoder);
838 break;
839 }
840
841 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
842 Decoder);
843
844 // You shouldn't load to the same register twice in an instruction...
845 if ((Opcode == AArch64::LDAXPW || Opcode == AArch64::LDXPW ||
846 Opcode == AArch64::LDAXPX || Opcode == AArch64::LDXPX) &&
847 Rt == Rt2)
848 return SoftFail;
849
850 return Success;
851}
852
853static DecodeStatus DecodePairLdStInstruction(MCInst &Inst, uint32_t insn,
854 uint64_t Addr,
855 const MCDisassembler *Decoder) {
856 unsigned Rt = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
857 unsigned Rn = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 5);
858 unsigned Rt2 = fieldFromInstruction(Insn: insn, StartBit: 10, NumBits: 5);
859 int64_t offset = SignExtend64<7>(x: fieldFromInstruction(Insn: insn, StartBit: 15, NumBits: 7));
860 bool IsLoad = fieldFromInstruction(Insn: insn, StartBit: 22, NumBits: 1);
861
862 unsigned Opcode = Inst.getOpcode();
863 bool NeedsDisjointWritebackTransfer = false;
864
865 // First operand is always writeback of base register.
866 switch (Opcode) {
867 default:
868 break;
869 case AArch64::LDPXpost:
870 case AArch64::STPXpost:
871 case AArch64::LDPSWpost:
872 case AArch64::LDPXpre:
873 case AArch64::STPXpre:
874 case AArch64::LDPSWpre:
875 case AArch64::LDPWpost:
876 case AArch64::STPWpost:
877 case AArch64::LDPWpre:
878 case AArch64::STPWpre:
879 case AArch64::LDPQpost:
880 case AArch64::STPQpost:
881 case AArch64::LDPQpre:
882 case AArch64::STPQpre:
883 case AArch64::LDPDpost:
884 case AArch64::STPDpost:
885 case AArch64::LDPDpre:
886 case AArch64::STPDpre:
887 case AArch64::LDPSpost:
888 case AArch64::STPSpost:
889 case AArch64::LDPSpre:
890 case AArch64::STPSpre:
891 case AArch64::STGPpre:
892 case AArch64::STGPpost:
893 case AArch64::LDTPpre:
894 case AArch64::LDTPpost:
895 case AArch64::LDTPQpost:
896 case AArch64::LDTPQpre:
897 case AArch64::STTPpost:
898 case AArch64::STTPpre:
899 case AArch64::STTPQpost:
900 case AArch64::STTPQpre:
901 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
902 Decoder);
903 break;
904 }
905
906 switch (Opcode) {
907 default:
908 return Fail;
909 case AArch64::LDPXpost:
910 case AArch64::STPXpost:
911 case AArch64::LDPSWpost:
912 case AArch64::LDPXpre:
913 case AArch64::STPXpre:
914 case AArch64::LDPSWpre:
915 case AArch64::STGPpre:
916 case AArch64::STGPpost:
917 case AArch64::LDTPpost:
918 case AArch64::LDTPpre:
919 case AArch64::STTPpost:
920 case AArch64::STTPpre:
921 NeedsDisjointWritebackTransfer = true;
922 [[fallthrough]];
923 case AArch64::LDNPXi:
924 case AArch64::STNPXi:
925 case AArch64::LDPXi:
926 case AArch64::STPXi:
927 case AArch64::LDPSWi:
928 case AArch64::STGPi:
929 case AArch64::LDTPi:
930 case AArch64::STTPi:
931 case AArch64::STTNPXi:
932 case AArch64::LDTNPXi:
933 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
934 Decoder);
935 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rt2, Address: Addr,
936 Decoder);
937 break;
938 case AArch64::LDPWpost:
939 case AArch64::STPWpost:
940 case AArch64::LDPWpre:
941 case AArch64::STPWpre:
942 NeedsDisjointWritebackTransfer = true;
943 [[fallthrough]];
944 case AArch64::LDNPWi:
945 case AArch64::STNPWi:
946 case AArch64::LDPWi:
947 case AArch64::STPWi:
948 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
949 Decoder);
950 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rt2, Address: Addr,
951 Decoder);
952 break;
953 case AArch64::LDNPQi:
954 case AArch64::STNPQi:
955 case AArch64::LDPQpost:
956 case AArch64::STPQpost:
957 case AArch64::LDPQi:
958 case AArch64::STPQi:
959 case AArch64::LDPQpre:
960 case AArch64::STPQpre:
961 case AArch64::LDTPQi:
962 case AArch64::LDTPQpost:
963 case AArch64::LDTPQpre:
964 case AArch64::LDTNPQi:
965 case AArch64::STTPQi:
966 case AArch64::STTPQpost:
967 case AArch64::STTPQpre:
968 case AArch64::STTNPQi:
969 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
970 Decoder);
971 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, RegNo: Rt2, Address: Addr,
972 Decoder);
973 break;
974 case AArch64::LDNPDi:
975 case AArch64::STNPDi:
976 case AArch64::LDPDpost:
977 case AArch64::STPDpost:
978 case AArch64::LDPDi:
979 case AArch64::STPDi:
980 case AArch64::LDPDpre:
981 case AArch64::STPDpre:
982 DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
983 Decoder);
984 DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, RegNo: Rt2, Address: Addr,
985 Decoder);
986 break;
987 case AArch64::LDNPSi:
988 case AArch64::STNPSi:
989 case AArch64::LDPSpost:
990 case AArch64::STPSpost:
991 case AArch64::LDPSi:
992 case AArch64::STPSi:
993 case AArch64::LDPSpre:
994 case AArch64::STPSpre:
995 DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
996 Decoder);
997 DecodeSimpleRegisterClass<AArch64::FPR32RegClassID, 0, 32>(Inst, RegNo: Rt2, Address: Addr,
998 Decoder);
999 break;
1000 }
1001
1002 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
1003 Decoder);
1004 Inst.addOperand(Op: MCOperand::createImm(Val: offset));
1005
1006 // You shouldn't load to the same register twice in an instruction...
1007 if (IsLoad && Rt == Rt2)
1008 return SoftFail;
1009
1010 // ... or do any operation that writes-back to a transfer register. But note
1011 // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different.
1012 if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn))
1013 return SoftFail;
1014
1015 return Success;
1016}
1017
1018static DecodeStatus DecodeAuthLoadInstruction(MCInst &Inst, uint32_t insn,
1019 uint64_t Addr,
1020 const MCDisassembler *Decoder) {
1021 unsigned Rt = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
1022 unsigned Rn = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 5);
1023 uint64_t offset = fieldFromInstruction(Insn: insn, StartBit: 22, NumBits: 1) << 9 |
1024 fieldFromInstruction(Insn: insn, StartBit: 12, NumBits: 9);
1025 unsigned writeback = fieldFromInstruction(Insn: insn, StartBit: 11, NumBits: 1);
1026
1027 switch (Inst.getOpcode()) {
1028 default:
1029 return Fail;
1030 case AArch64::LDRAAwriteback:
1031 case AArch64::LDRABwriteback:
1032 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(
1033 Inst, RegNo: Rn /* writeback register */, Address: Addr, Decoder);
1034 break;
1035 case AArch64::LDRAAindexed:
1036 case AArch64::LDRABindexed:
1037 break;
1038 }
1039
1040 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
1041 Decoder);
1042 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
1043 Decoder);
1044 DecodeSImm<10>(Inst, Imm: offset, Address: Addr, Decoder);
1045
1046 if (writeback && Rt == Rn && Rn != 31) {
1047 return SoftFail;
1048 }
1049
1050 return Success;
1051}
1052
1053static DecodeStatus DecodeAddSubERegInstruction(MCInst &Inst, uint32_t insn,
1054 uint64_t Addr,
1055 const MCDisassembler *Decoder) {
1056 unsigned Rd = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
1057 unsigned Rn = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 5);
1058 unsigned Rm = fieldFromInstruction(Insn: insn, StartBit: 16, NumBits: 5);
1059 unsigned extend = fieldFromInstruction(Insn: insn, StartBit: 10, NumBits: 6);
1060
1061 unsigned shift = extend & 0x7;
1062 if (shift > 4)
1063 return Fail;
1064
1065 switch (Inst.getOpcode()) {
1066 default:
1067 return Fail;
1068 case AArch64::ADDWrx:
1069 case AArch64::SUBWrx:
1070 DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
1071 Decoder);
1072 DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
1073 Decoder);
1074 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rm, Address: Addr,
1075 Decoder);
1076 break;
1077 case AArch64::ADDSWrx:
1078 case AArch64::SUBSWrx:
1079 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
1080 Decoder);
1081 DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
1082 Decoder);
1083 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rm, Address: Addr,
1084 Decoder);
1085 break;
1086 case AArch64::ADDXrx:
1087 case AArch64::SUBXrx:
1088 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
1089 Decoder);
1090 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
1091 Decoder);
1092 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rm, Address: Addr,
1093 Decoder);
1094 break;
1095 case AArch64::ADDSXrx:
1096 case AArch64::SUBSXrx:
1097 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
1098 Decoder);
1099 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
1100 Decoder);
1101 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rm, Address: Addr,
1102 Decoder);
1103 break;
1104 case AArch64::ADDXrx64:
1105 case AArch64::SUBXrx64:
1106 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
1107 Decoder);
1108 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
1109 Decoder);
1110 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rm, Address: Addr,
1111 Decoder);
1112 break;
1113 case AArch64::SUBSXrx64:
1114 case AArch64::ADDSXrx64:
1115 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
1116 Decoder);
1117 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
1118 Decoder);
1119 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rm, Address: Addr,
1120 Decoder);
1121 break;
1122 }
1123
1124 Inst.addOperand(Op: MCOperand::createImm(Val: extend));
1125 return Success;
1126}
1127
1128static DecodeStatus DecodeLogicalImmInstruction(MCInst &Inst, uint32_t insn,
1129 uint64_t Addr,
1130 const MCDisassembler *Decoder) {
1131 unsigned Rd = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
1132 unsigned Rn = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 5);
1133 unsigned Datasize = fieldFromInstruction(Insn: insn, StartBit: 31, NumBits: 1);
1134 unsigned imm;
1135
1136 if (Datasize) {
1137 if (Inst.getOpcode() == AArch64::ANDSXri)
1138 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
1139 Decoder);
1140 else
1141 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(
1142 Inst, RegNo: Rd, Address: Addr, Decoder);
1143 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
1144 Decoder);
1145 imm = fieldFromInstruction(Insn: insn, StartBit: 10, NumBits: 13);
1146 if (!AArch64_AM::isValidDecodeLogicalImmediate(val: imm, regSize: 64))
1147 return Fail;
1148 } else {
1149 if (Inst.getOpcode() == AArch64::ANDSWri)
1150 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
1151 Decoder);
1152 else
1153 DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(
1154 Inst, RegNo: Rd, Address: Addr, Decoder);
1155 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
1156 Decoder);
1157 imm = fieldFromInstruction(Insn: insn, StartBit: 10, NumBits: 12);
1158 if (!AArch64_AM::isValidDecodeLogicalImmediate(val: imm, regSize: 32))
1159 return Fail;
1160 }
1161 Inst.addOperand(Op: MCOperand::createImm(Val: imm));
1162 return Success;
1163}
1164
1165static DecodeStatus DecodeModImmInstruction(MCInst &Inst, uint32_t insn,
1166 uint64_t Addr,
1167 const MCDisassembler *Decoder) {
1168 unsigned Rd = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
1169 unsigned cmode = fieldFromInstruction(Insn: insn, StartBit: 12, NumBits: 4);
1170 unsigned imm = fieldFromInstruction(Insn: insn, StartBit: 16, NumBits: 3) << 5;
1171 imm |= fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 5);
1172
1173 if (Inst.getOpcode() == AArch64::MOVID)
1174 DecodeSimpleRegisterClass<AArch64::FPR64RegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
1175 Decoder);
1176 else
1177 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
1178 Decoder);
1179
1180 Inst.addOperand(Op: MCOperand::createImm(Val: imm));
1181
1182 switch (Inst.getOpcode()) {
1183 default:
1184 break;
1185 case AArch64::MOVIv4i16:
1186 case AArch64::MOVIv8i16:
1187 case AArch64::MVNIv4i16:
1188 case AArch64::MVNIv8i16:
1189 case AArch64::MOVIv2i32:
1190 case AArch64::MOVIv4i32:
1191 case AArch64::MVNIv2i32:
1192 case AArch64::MVNIv4i32:
1193 Inst.addOperand(Op: MCOperand::createImm(Val: (cmode & 6) << 2));
1194 break;
1195 case AArch64::MOVIv2s_msl:
1196 case AArch64::MOVIv4s_msl:
1197 case AArch64::MVNIv2s_msl:
1198 case AArch64::MVNIv4s_msl:
1199 Inst.addOperand(Op: MCOperand::createImm(Val: (cmode & 1) ? 0x110 : 0x108));
1200 break;
1201 }
1202
1203 return Success;
1204}
1205
1206static DecodeStatus DecodeModImmTiedInstruction(MCInst &Inst, uint32_t insn,
1207 uint64_t Addr,
1208 const MCDisassembler *Decoder) {
1209 unsigned Rd = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
1210 unsigned cmode = fieldFromInstruction(Insn: insn, StartBit: 12, NumBits: 4);
1211 unsigned imm = fieldFromInstruction(Insn: insn, StartBit: 16, NumBits: 3) << 5;
1212 imm |= fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 5);
1213
1214 // Tied operands added twice.
1215 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
1216 Decoder);
1217 DecodeSimpleRegisterClass<AArch64::FPR128RegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
1218 Decoder);
1219
1220 Inst.addOperand(Op: MCOperand::createImm(Val: imm));
1221 Inst.addOperand(Op: MCOperand::createImm(Val: (cmode & 6) << 2));
1222
1223 return Success;
1224}
1225
1226static DecodeStatus DecodeAdrInstruction(MCInst &Inst, uint32_t insn,
1227 uint64_t Addr,
1228 const MCDisassembler *Decoder) {
1229 unsigned Rd = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
1230 int64_t imm = SignExtend64<21>(x: (fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 19) << 2) |
1231 fieldFromInstruction(Insn: insn, StartBit: 29, NumBits: 2));
1232
1233 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
1234 Decoder);
1235 if (!Decoder->tryAddingSymbolicOperand(Inst, Value: imm, Address: Addr, Fail, Offset: 0, OpSize: 0, InstSize: 4))
1236 Inst.addOperand(Op: MCOperand::createImm(Val: imm));
1237
1238 return Success;
1239}
1240
1241static DecodeStatus DecodeAddSubImmShift(MCInst &Inst, uint32_t insn,
1242 uint64_t Addr,
1243 const MCDisassembler *Decoder) {
1244 unsigned Rd = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
1245 unsigned Rn = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 5);
1246 unsigned Imm = fieldFromInstruction(Insn: insn, StartBit: 10, NumBits: 14);
1247 unsigned S = fieldFromInstruction(Insn: insn, StartBit: 29, NumBits: 1);
1248 unsigned Datasize = fieldFromInstruction(Insn: insn, StartBit: 31, NumBits: 1);
1249
1250 unsigned ShifterVal = (Imm >> 12) & 3;
1251 unsigned ImmVal = Imm & 0xFFF;
1252
1253 if (ShifterVal != 0 && ShifterVal != 1)
1254 return Fail;
1255
1256 if (Datasize) {
1257 if (Rd == 31 && !S)
1258 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(
1259 Inst, RegNo: Rd, Address: Addr, Decoder);
1260 else
1261 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
1262 Decoder);
1263 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
1264 Decoder);
1265 } else {
1266 if (Rd == 31 && !S)
1267 DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(
1268 Inst, RegNo: Rd, Address: Addr, Decoder);
1269 else
1270 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rd, Address: Addr,
1271 Decoder);
1272 DecodeSimpleRegisterClass<AArch64::GPR32spRegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
1273 Decoder);
1274 }
1275
1276 if (!Decoder->tryAddingSymbolicOperand(Inst, Value: Imm, Address: Addr, Fail, Offset: 0, OpSize: 0, InstSize: 4))
1277 Inst.addOperand(Op: MCOperand::createImm(Val: ImmVal));
1278 Inst.addOperand(Op: MCOperand::createImm(Val: 12 * ShifterVal));
1279 return Success;
1280}
1281
1282static DecodeStatus DecodeUnconditionalBranch(MCInst &Inst, uint32_t insn,
1283 uint64_t Addr,
1284 const MCDisassembler *Decoder) {
1285 int64_t imm = SignExtend64<26>(x: fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 26));
1286
1287 if (!Decoder->tryAddingSymbolicOperand(Inst, Value: imm * 4, Address: Addr, IsBranch: true, Offset: 0, OpSize: 0, InstSize: 4))
1288 Inst.addOperand(Op: MCOperand::createImm(Val: imm));
1289
1290 return Success;
1291}
1292
1293static bool isInvalidPState(uint64_t Op1, uint64_t Op2) {
1294 return Op1 == 0b000 && (Op2 == 0b000 || // CFINV
1295 Op2 == 0b001 || // XAFlag
1296 Op2 == 0b010); // AXFlag
1297}
1298
1299static DecodeStatus
1300DecodeSystemPStateImm0_15Instruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
1301 const MCDisassembler *Decoder) {
1302 uint64_t op1 = fieldFromInstruction(Insn: insn, StartBit: 16, NumBits: 3);
1303 uint64_t op2 = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 3);
1304 uint64_t imm = fieldFromInstruction(Insn: insn, StartBit: 8, NumBits: 4);
1305 uint64_t pstate_field = (op1 << 3) | op2;
1306
1307 if (isInvalidPState(Op1: op1, Op2: op2))
1308 return Fail;
1309
1310 Inst.addOperand(Op: MCOperand::createImm(Val: pstate_field));
1311 Inst.addOperand(Op: MCOperand::createImm(Val: imm));
1312
1313 auto PState = AArch64PState::lookupPStateImm0_15ByEncoding(Encoding: pstate_field);
1314 if (PState &&
1315 PState->haveFeatures(ActiveFeatures: Decoder->getSubtargetInfo().getFeatureBits()))
1316 return Success;
1317 return Fail;
1318}
1319
1320static DecodeStatus
1321DecodeSystemPStateImm0_1Instruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
1322 const MCDisassembler *Decoder) {
1323 uint64_t op1 = fieldFromInstruction(Insn: insn, StartBit: 16, NumBits: 3);
1324 uint64_t op2 = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 3);
1325 uint64_t crm_high = fieldFromInstruction(Insn: insn, StartBit: 9, NumBits: 3);
1326 uint64_t imm = fieldFromInstruction(Insn: insn, StartBit: 8, NumBits: 1);
1327 uint64_t pstate_field = (crm_high << 6) | (op1 << 3) | op2;
1328
1329 if (isInvalidPState(Op1: op1, Op2: op2))
1330 return Fail;
1331
1332 Inst.addOperand(Op: MCOperand::createImm(Val: pstate_field));
1333 Inst.addOperand(Op: MCOperand::createImm(Val: imm));
1334
1335 auto PState = AArch64PState::lookupPStateImm0_1ByEncoding(Encoding: pstate_field);
1336 if (PState &&
1337 PState->haveFeatures(ActiveFeatures: Decoder->getSubtargetInfo().getFeatureBits()))
1338 return Success;
1339 return Fail;
1340}
1341
1342static DecodeStatus DecodeTestAndBranch(MCInst &Inst, uint32_t insn,
1343 uint64_t Addr,
1344 const MCDisassembler *Decoder) {
1345 uint64_t Rt = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
1346 uint64_t bit = fieldFromInstruction(Insn: insn, StartBit: 31, NumBits: 1) << 5;
1347 bit |= fieldFromInstruction(Insn: insn, StartBit: 19, NumBits: 5);
1348 int64_t dst = SignExtend64<14>(x: fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 14));
1349
1350 if (fieldFromInstruction(Insn: insn, StartBit: 31, NumBits: 1) == 0)
1351 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
1352 Decoder);
1353 else
1354 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
1355 Decoder);
1356 Inst.addOperand(Op: MCOperand::createImm(Val: bit));
1357 if (!Decoder->tryAddingSymbolicOperand(Inst, Value: dst * 4, Address: Addr, IsBranch: true, Offset: 0, OpSize: 0, InstSize: 4))
1358 Inst.addOperand(Op: MCOperand::createImm(Val: dst));
1359
1360 return Success;
1361}
1362
1363static DecodeStatus
1364DecodeGPRSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegClassID,
1365 unsigned RegNo, uint64_t Addr,
1366 const MCDisassembler *Decoder) {
1367 // Register number must be even (see CASP instruction)
1368 if (RegNo & 0x1)
1369 return Fail;
1370
1371 MCRegister Reg = AArch64MCRegisterClasses[RegClassID].getRegister(i: RegNo / 2);
1372 Inst.addOperand(Op: MCOperand::createReg(Reg));
1373 return Success;
1374}
1375
1376static DecodeStatus
1377DecodeWSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
1378 const MCDisassembler *Decoder) {
1379 return DecodeGPRSeqPairsClassRegisterClass(
1380 Inst, RegClassID: AArch64::WSeqPairsClassRegClassID, RegNo, Addr, Decoder);
1381}
1382
1383static DecodeStatus
1384DecodeXSeqPairsClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
1385 const MCDisassembler *Decoder) {
1386 return DecodeGPRSeqPairsClassRegisterClass(
1387 Inst, RegClassID: AArch64::XSeqPairsClassRegClassID, RegNo, Addr, Decoder);
1388}
1389
1390static DecodeStatus DecodeSyspXzrInstruction(MCInst &Inst, uint32_t insn,
1391 uint64_t Addr,
1392 const MCDisassembler *Decoder) {
1393 unsigned op1 = fieldFromInstruction(Insn: insn, StartBit: 16, NumBits: 3);
1394 unsigned CRn = fieldFromInstruction(Insn: insn, StartBit: 12, NumBits: 4);
1395 unsigned CRm = fieldFromInstruction(Insn: insn, StartBit: 8, NumBits: 4);
1396 unsigned op2 = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 3);
1397 unsigned Rt = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
1398 if (Rt != 0b11111)
1399 return Fail;
1400
1401 Inst.addOperand(Op: MCOperand::createImm(Val: op1));
1402 Inst.addOperand(Op: MCOperand::createImm(Val: CRn));
1403 Inst.addOperand(Op: MCOperand::createImm(Val: CRm));
1404 Inst.addOperand(Op: MCOperand::createImm(Val: op2));
1405 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rt, Address: Addr,
1406 Decoder);
1407
1408 return Success;
1409}
1410
1411static DecodeStatus
1412DecodeSVELogicalImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
1413 const MCDisassembler *Decoder) {
1414 unsigned Zdn = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
1415 unsigned imm = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 13);
1416 if (!AArch64_AM::isValidDecodeLogicalImmediate(val: imm, regSize: 64))
1417 return Fail;
1418
1419 // The same (tied) operand is added twice to the instruction.
1420 DecodeSimpleRegisterClass<AArch64::ZPRRegClassID, 0, 32>(Inst, RegNo: Zdn, Address: Addr,
1421 Decoder);
1422 if (Inst.getOpcode() != AArch64::DUPM_ZI)
1423 DecodeSimpleRegisterClass<AArch64::ZPRRegClassID, 0, 32>(Inst, RegNo: Zdn, Address: Addr,
1424 Decoder);
1425 Inst.addOperand(Op: MCOperand::createImm(Val: imm));
1426 return Success;
1427}
1428
1429static DecodeStatus DecodeZeroImm(MCInst &Inst, const MCDisassembler *Decoder) {
1430 Inst.addOperand(Op: MCOperand::createImm(Val: 0));
1431 return Success;
1432}
1433
1434template <int Bits>
1435static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
1436 const MCDisassembler *Decoder) {
1437 if (Imm & ~((1LL << Bits) - 1))
1438 return Fail;
1439
1440 // Imm is a signed immediate, so sign extend it.
1441 if (Imm & (1 << (Bits - 1)))
1442 Imm |= ~((1LL << Bits) - 1);
1443
1444 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
1445 return Success;
1446}
1447
1448template <int Bits>
1449static DecodeStatus DecodeUImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
1450 const MCDisassembler *Decoder) {
1451 if (Imm & ~((1ULL << Bits) - 1))
1452 return Fail;
1453
1454 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
1455 return Success;
1456}
1457
1458// Decode 8-bit signed/unsigned immediate for a given element width.
1459template <int ElementWidth>
1460static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm, uint64_t Addr,
1461 const MCDisassembler *Decoder) {
1462 unsigned Val = (uint8_t)Imm;
1463 unsigned Shift = (Imm & 0x100) ? 8 : 0;
1464 if (ElementWidth == 8 && Shift)
1465 return Fail;
1466 Inst.addOperand(Op: MCOperand::createImm(Val));
1467 Inst.addOperand(Op: MCOperand::createImm(Val: Shift));
1468 return Success;
1469}
1470
1471// Decode uimm4 ranged from 1-16.
1472static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,
1473 uint64_t Addr,
1474 const MCDisassembler *Decoder) {
1475 Inst.addOperand(Op: MCOperand::createImm(Val: Imm + 1));
1476 return Success;
1477}
1478
1479static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,
1480 const MCDisassembler *Decoder) {
1481 if (AArch64SVCR::lookupSVCRByEncoding(Encoding: Imm)) {
1482 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
1483 return Success;
1484 }
1485 return Fail;
1486}
1487
1488static DecodeStatus DecodeCPYMemOpInstruction(MCInst &Inst, uint32_t insn,
1489 uint64_t Addr,
1490 const MCDisassembler *Decoder) {
1491 unsigned Rd = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
1492 unsigned Rs = fieldFromInstruction(Insn: insn, StartBit: 16, NumBits: 5);
1493 unsigned Rn = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 5);
1494
1495 // None of the registers may alias: if they do, then the instruction is not
1496 // merely unpredictable but actually entirely unallocated.
1497 if (Rd == Rs || Rs == Rn || Rd == Rn)
1498 return MCDisassembler::Fail;
1499
1500 // All three register operands are written back, so they all appear
1501 // twice in the operand list, once as outputs and once as inputs.
1502 if (!DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
1503 Inst, RegNo: Rd, Address: Addr, Decoder) ||
1504 !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
1505 Inst, RegNo: Rs, Address: Addr, Decoder) ||
1506 !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
1507 Inst, RegNo: Rn, Address: Addr, Decoder) ||
1508 !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
1509 Inst, RegNo: Rd, Address: Addr, Decoder) ||
1510 !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
1511 Inst, RegNo: Rs, Address: Addr, Decoder) ||
1512 !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
1513 Inst, RegNo: Rn, Address: Addr, Decoder))
1514 return MCDisassembler::Fail;
1515
1516 return MCDisassembler::Success;
1517}
1518
1519static DecodeStatus DecodeSETMemOpInstruction(MCInst &Inst, uint32_t insn,
1520 uint64_t Addr,
1521 const MCDisassembler *Decoder) {
1522 unsigned Rd = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
1523 unsigned Rm = fieldFromInstruction(Insn: insn, StartBit: 16, NumBits: 5);
1524 unsigned Rn = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 5);
1525
1526 // None of the registers may alias: if they do, then the instruction is not
1527 // merely unpredictable but actually entirely unallocated.
1528 if (Rd == Rm || Rm == Rn || Rd == Rn)
1529 return MCDisassembler::Fail;
1530
1531 // Rd and Rn (not Rm) register operands are written back, so they appear
1532 // twice in the operand list, once as outputs and once as inputs.
1533 if (!DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
1534 Inst, RegNo: Rd, Address: Addr, Decoder) ||
1535 !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
1536 Inst, RegNo: Rn, Address: Addr, Decoder) ||
1537 !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
1538 Inst, RegNo: Rd, Address: Addr, Decoder) ||
1539 !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
1540 Inst, RegNo: Rn, Address: Addr, Decoder) ||
1541 !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
1542 Inst, RegNo: Rm, Address: Addr, Decoder))
1543 return MCDisassembler::Fail;
1544
1545 return MCDisassembler::Success;
1546}
1547
1548static DecodeStatus DecodeSETMemGoOpInstruction(MCInst &Inst, uint32_t insn,
1549 uint64_t Addr,
1550 const MCDisassembler *Decoder) {
1551 unsigned Rd = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
1552 unsigned Rn = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 5);
1553
1554 // None of the registers may alias: if they do, then the instruction is not
1555 // merely unpredictable but actually entirely unallocated.
1556 if (Rd == Rn)
1557 return MCDisassembler::Fail;
1558
1559 // Rd and Rn register operands are written back, so they appear
1560 // twice in the operand list, once as outputs and once as inputs.
1561 if (!DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
1562 Inst, RegNo: Rd, Address: Addr, Decoder) ||
1563 !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
1564 Inst, RegNo: Rn, Address: Addr, Decoder) ||
1565 !DecodeSimpleRegisterClass<AArch64::GPR64commonRegClassID, 0, 31>(
1566 Inst, RegNo: Rd, Address: Addr, Decoder) ||
1567 !DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(
1568 Inst, RegNo: Rn, Address: Addr, Decoder))
1569 return MCDisassembler::Fail;
1570
1571 return MCDisassembler::Success;
1572}
1573
1574static DecodeStatus DecodePRFMRegInstruction(MCInst &Inst, uint32_t insn,
1575 uint64_t Addr,
1576 const MCDisassembler *Decoder) {
1577 // PRFM with Rt = '11xxx' should be decoded as RPRFM.
1578 // Fail to decode and defer to fallback decoder table to decode RPRFM.
1579 unsigned Mask = 0x18;
1580 uint64_t Rt = fieldFromInstruction(Insn: insn, StartBit: 0, NumBits: 5);
1581 if ((Rt & Mask) == Mask)
1582 return Fail;
1583
1584 uint64_t Rn = fieldFromInstruction(Insn: insn, StartBit: 5, NumBits: 5);
1585 uint64_t Shift = fieldFromInstruction(Insn: insn, StartBit: 12, NumBits: 1);
1586 uint64_t Extend = fieldFromInstruction(Insn: insn, StartBit: 15, NumBits: 1);
1587 uint64_t Rm = fieldFromInstruction(Insn: insn, StartBit: 16, NumBits: 5);
1588
1589 Inst.addOperand(Op: MCOperand::createImm(Val: Rt));
1590 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RegNo: Rn, Address: Addr,
1591 Decoder);
1592
1593 switch (Inst.getOpcode()) {
1594 default:
1595 return Fail;
1596 case AArch64::PRFMroW:
1597 DecodeSimpleRegisterClass<AArch64::GPR32RegClassID, 0, 32>(Inst, RegNo: Rm, Address: Addr,
1598 Decoder);
1599 break;
1600 case AArch64::PRFMroX:
1601 DecodeSimpleRegisterClass<AArch64::GPR64RegClassID, 0, 32>(Inst, RegNo: Rm, Address: Addr,
1602 Decoder);
1603 break;
1604 }
1605
1606 DecodeMemExtend(Inst, Imm: (Extend << 1) | Shift, Address: Addr, Decoder);
1607
1608 return Success;
1609}
1610
1611static DecodeStatus
1612DecodeSMESpillFillInstruction(MCInst &Inst, uint32_t Bits, uint64_t Addr,
1613 const MCDisassembler *Decoder) {
1614 unsigned RvBits = fieldFromInstruction(Insn: Bits, StartBit: 13, NumBits: 2);
1615 unsigned RnBits = fieldFromInstruction(Insn: Bits, StartBit: 5, NumBits: 5);
1616 unsigned Imm4Bits = fieldFromInstruction(Insn: Bits, StartBit: 0, NumBits: 4);
1617
1618 DecodeMPRRegisterClass(Inst, Decoder);
1619 DecodeSimpleRegisterClass<AArch64::MatrixIndexGPR32_12_15RegClassID, 0, 4>(
1620 Inst, RegNo: RvBits, Address: Addr, Decoder);
1621 Inst.addOperand(Op: MCOperand::createImm(Val: Imm4Bits));
1622 DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RegNo: RnBits,
1623 Address: Addr, Decoder);
1624 // Spill and fill instructions have a single immediate used for both
1625 // the vector select offset and optional memory offset. Replicate
1626 // the decoded immediate.
1627 Inst.addOperand(Op: MCOperand::createImm(Val: Imm4Bits));
1628 return Success;
1629}
1630
1631#include "AArch64GenDisassemblerTables.inc"
1632#include "AArch64GenInstrInfo.inc"
1633
1634static MCDisassembler *createAArch64Disassembler(const Target &T,
1635 const MCSubtargetInfo &STI,
1636 MCContext &Ctx) {
1637
1638 return new AArch64Disassembler(STI, Ctx, T.createMCInstrInfo());
1639}
1640
1641DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
1642 ArrayRef<uint8_t> Bytes,
1643 uint64_t Address,
1644 raw_ostream &CS) const {
1645 CommentStream = &CS;
1646
1647 Size = 0;
1648 // We want to read exactly 4 bytes of data.
1649 if (Bytes.size() < 4)
1650 return Fail;
1651 Size = 4;
1652
1653 // Encoded as a small-endian 32-bit word in the stream.
1654 uint32_t Insn =
1655 (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
1656
1657 const uint8_t *Tables[] = {DecoderTable32, DecoderTableFallback32};
1658
1659 for (const auto *Table : Tables) {
1660 DecodeStatus Result =
1661 decodeInstruction(DecodeTable: Table, MI, insn: Insn, Address, DisAsm: this, STI);
1662 if (Result != MCDisassembler::Fail)
1663 return Result;
1664 }
1665
1666 return MCDisassembler::Fail;
1667}
1668
1669uint64_t AArch64Disassembler::suggestBytesToSkip(ArrayRef<uint8_t> Bytes,
1670 uint64_t Address) const {
1671 // AArch64 instructions are always 4 bytes wide, so there's no point
1672 // in skipping any smaller number of bytes if an instruction can't
1673 // be decoded.
1674 return 4;
1675}
1676
1677static MCSymbolizer *
1678createAArch64ExternalSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,
1679 LLVMSymbolLookupCallback SymbolLookUp,
1680 void *DisInfo, MCContext *Ctx,
1681 std::unique_ptr<MCRelocationInfo> &&RelInfo) {
1682 return new AArch64ExternalSymbolizer(*Ctx, std::move(RelInfo), GetOpInfo,
1683 SymbolLookUp, DisInfo);
1684}
1685
1686extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
1687LLVMInitializeAArch64Disassembler() {
1688 TargetRegistry::RegisterMCDisassembler(T&: getTheAArch64leTarget(),
1689 Fn: createAArch64Disassembler);
1690 TargetRegistry::RegisterMCDisassembler(T&: getTheAArch64beTarget(),
1691 Fn: createAArch64Disassembler);
1692 TargetRegistry::RegisterMCSymbolizer(T&: getTheAArch64leTarget(),
1693 Fn: createAArch64ExternalSymbolizer);
1694 TargetRegistry::RegisterMCSymbolizer(T&: getTheAArch64beTarget(),
1695 Fn: createAArch64ExternalSymbolizer);
1696 TargetRegistry::RegisterMCDisassembler(T&: getTheAArch64_32Target(),
1697 Fn: createAArch64Disassembler);
1698 TargetRegistry::RegisterMCSymbolizer(T&: getTheAArch64_32Target(),
1699 Fn: createAArch64ExternalSymbolizer);
1700
1701 TargetRegistry::RegisterMCDisassembler(T&: getTheARM64Target(),
1702 Fn: createAArch64Disassembler);
1703 TargetRegistry::RegisterMCSymbolizer(T&: getTheARM64Target(),
1704 Fn: createAArch64ExternalSymbolizer);
1705 TargetRegistry::RegisterMCDisassembler(T&: getTheARM64_32Target(),
1706 Fn: createAArch64Disassembler);
1707 TargetRegistry::RegisterMCSymbolizer(T&: getTheARM64_32Target(),
1708 Fn: createAArch64ExternalSymbolizer);
1709}
1710