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