/src/capstonev5/arch/AArch64/AArch64Disassembler.c
Line | Count | Source (jump to first uncovered line) |
1 | | //===- AArch64Disassembler.cpp - Disassembler for AArch64 ISA -------------===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file contains the functions necessary to decode AArch64 instruction |
11 | | // bitpatterns into MCInsts (with the help of TableGenerated information from |
12 | | // the instruction definitions). |
13 | | // |
14 | | //===----------------------------------------------------------------------===// |
15 | | |
16 | | /* Capstone Disassembly Engine */ |
17 | | /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */ |
18 | | |
19 | | #ifdef CAPSTONE_HAS_ARM64 |
20 | | |
21 | | #include <stdio.h> // DEBUG |
22 | | #include <stdlib.h> |
23 | | |
24 | | #include "../../cs_priv.h" |
25 | | #include "../../utils.h" |
26 | | |
27 | | #include "AArch64Disassembler.h" |
28 | | |
29 | | #include "../../MCDisassembler.h" |
30 | | #include "../../MCFixedLenDisassembler.h" |
31 | | #include "../../MCInst.h" |
32 | | #include "../../MCInstrDesc.h" |
33 | | #include "../../MCRegisterInfo.h" |
34 | | |
35 | | #include "AArch64AddressingModes.h" |
36 | | #include "AArch64BaseInfo.h" |
37 | | |
38 | | // Forward declare these because the autogenerated code will reference them. |
39 | | // Definitions are further down. |
40 | | static DecodeStatus DecodeFPR128RegisterClass(MCInst *Inst, |
41 | | unsigned RegNo, uint64_t Address, const void *Decoder); |
42 | | static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, unsigned RegNo, |
43 | | uint64_t Address, const void *Decoder); |
44 | | static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, unsigned RegNo, |
45 | | uint64_t Address, const void *Decoder); |
46 | | static DecodeStatus DecodeFPR16RegisterClass(MCInst *Inst, unsigned RegNo, |
47 | | uint64_t Address, const void *Decoder); |
48 | | static DecodeStatus DecodeFPR8RegisterClass(MCInst *Inst, unsigned RegNo, |
49 | | uint64_t Address, const void *Decoder); |
50 | | static DecodeStatus DecodeGPR64RegisterClass(MCInst *Inst, unsigned RegNo, |
51 | | uint64_t Address, const void *Decoder); |
52 | | static DecodeStatus DecodeGPR64x8ClassRegisterClass(MCInst *Inst, unsigned RegNo, |
53 | | uint64_t Address, const void *Decoder); |
54 | | static DecodeStatus DecodeGPR64spRegisterClass(MCInst *Inst, |
55 | | unsigned RegNo, uint64_t Address, const void *Decoder); |
56 | | static DecodeStatus DecodeMatrixIndexGPR32_12_15RegisterClass(MCInst *Inst, |
57 | | unsigned RegNo, uint64_t Address, const void *Decoder); |
58 | | static DecodeStatus DecodeGPR32RegisterClass(MCInst *Inst, unsigned RegNo, |
59 | | uint64_t Address, const void *Decoder); |
60 | | static DecodeStatus DecodeGPR32spRegisterClass(MCInst *Inst, |
61 | | unsigned RegNo, uint64_t Address, const void *Decoder); |
62 | | static DecodeStatus DecodeQQRegisterClass(MCInst *Inst, unsigned RegNo, |
63 | | uint64_t Address, const void *Decoder); |
64 | | static DecodeStatus DecodeQQQRegisterClass(MCInst *Inst, unsigned RegNo, |
65 | | uint64_t Address, const void *Decoder); |
66 | | static DecodeStatus DecodeQQQQRegisterClass(MCInst *Inst, unsigned RegNo, |
67 | | uint64_t Address, const void *Decoder); |
68 | | static DecodeStatus DecodeDDRegisterClass(MCInst *Inst, unsigned RegNo, |
69 | | uint64_t Address, const void *Decoder); |
70 | | static DecodeStatus DecodeDDDRegisterClass(MCInst *Inst, unsigned RegNo, |
71 | | uint64_t Address, const void *Decoder); |
72 | | static DecodeStatus DecodeDDDDRegisterClass(MCInst *Inst, unsigned RegNo, |
73 | | uint64_t Address, const void *Decoder); |
74 | | static DecodeStatus DecodeZPRRegisterClass(MCInst *Inst, unsigned RegNo, |
75 | | uint64_t Address, const void *Decoder); |
76 | | static DecodeStatus DecodeZPR_4bRegisterClass(MCInst *Inst, unsigned RegNo, |
77 | | uint64_t Address, const void *Decoder); |
78 | | static DecodeStatus DecodeZPR_3bRegisterClass(MCInst *Inst, unsigned RegNo, |
79 | | uint64_t Address, const void *Decoder); |
80 | | static DecodeStatus DecodeZPR2RegisterClass(MCInst *Inst, unsigned RegNo, |
81 | | uint64_t Address, const void *Decoder); |
82 | | static DecodeStatus DecodeZPR3RegisterClass(MCInst *Inst, unsigned RegNo, |
83 | | uint64_t Address, const void *Decoder); |
84 | | static DecodeStatus DecodeZPR4RegisterClass(MCInst *Inst, unsigned RegNo, |
85 | | uint64_t Address, const void *Decoder); |
86 | | static DecodeStatus DecodeMatrixTile(MCInst *Inst, unsigned RegNo, |
87 | | uint64_t Address, const void *Decoder, unsigned NumBitsForTile); |
88 | | static DecodeStatus DecodeMatrixTileListRegisterClass(MCInst *Inst, |
89 | | unsigned RegMask, uint64_t Address, const void *Decoder); |
90 | | static DecodeStatus DecodePPRRegisterClass(MCInst *Inst, unsigned RegNo, |
91 | | uint64_t Address, const void *Decoder); |
92 | | static DecodeStatus DecodePPR_3bRegisterClass(MCInst *Inst, unsigned RegNo, |
93 | | uint64_t Address, const void *Decoder); |
94 | | static DecodeStatus DecodeFixedPointScaleImm32(MCInst *Inst, unsigned Imm, |
95 | | uint64_t Address, const void *Decoder); |
96 | | static DecodeStatus DecodeFixedPointScaleImm64(MCInst *Inst, unsigned Imm, |
97 | | uint64_t Address, const void *Decoder); |
98 | | static DecodeStatus DecodePCRelLabel19(MCInst *Inst, unsigned Imm, |
99 | | uint64_t Address, const void *Decoder); |
100 | | static DecodeStatus DecodeMemExtend(MCInst *Inst, unsigned Imm, |
101 | | uint64_t Address, const void *Decoder); |
102 | | static DecodeStatus DecodeMRSSystemRegister(MCInst *Inst, unsigned Imm, |
103 | | uint64_t Address, const void *Decoder); |
104 | | static DecodeStatus DecodeMSRSystemRegister(MCInst *Inst, unsigned Imm, |
105 | | uint64_t Address, const void *Decoder); |
106 | | static DecodeStatus DecodeMoveImmInstruction(MCInst *Inst, uint32_t insn, |
107 | | uint64_t Address, const void *Decoder); |
108 | | static DecodeStatus DecodeUnsignedLdStInstruction(MCInst *Inst, |
109 | | uint32_t insn, uint64_t Address, const void *Decoder); |
110 | | static DecodeStatus DecodeSignedLdStInstruction(MCInst *Inst, |
111 | | uint32_t insn, uint64_t Address, const void *Decoder); |
112 | | static DecodeStatus DecodeExclusiveLdStInstruction(MCInst *Inst, |
113 | | uint32_t insn, uint64_t Address, const void *Decoder); |
114 | | static DecodeStatus DecodePairLdStInstruction(MCInst *Inst, uint32_t insn, |
115 | | uint64_t Address, const void *Decoder); |
116 | | static DecodeStatus DecodeAuthLoadInstruction(MCInst *Inst, uint32_t insn, |
117 | | uint64_t Address, const void *Decoder); |
118 | | static DecodeStatus DecodeAddSubERegInstruction(MCInst *Inst, |
119 | | uint32_t insn, uint64_t Address, const void *Decoder); |
120 | | static DecodeStatus DecodeLogicalImmInstruction(MCInst *Inst, |
121 | | uint32_t insn, uint64_t Address, const void *Decoder); |
122 | | static DecodeStatus DecodeModImmInstruction(MCInst *Inst, uint32_t insn, |
123 | | uint64_t Address, const void *Decoder); |
124 | | static DecodeStatus DecodeModImmTiedInstruction(MCInst *Inst, |
125 | | uint32_t insn, uint64_t Address, const void *Decoder); |
126 | | static DecodeStatus DecodeAdrInstruction(MCInst *Inst, uint32_t insn, |
127 | | uint64_t Address, const void *Decoder); |
128 | | static DecodeStatus DecodeAddSubImmShift(MCInst *Inst, uint32_t insn, |
129 | | uint64_t Address, const void *Decoder); |
130 | | static DecodeStatus DecodeUnconditionalBranch(MCInst *Inst, uint32_t insn, |
131 | | uint64_t Address, const void *Decoder); |
132 | | static DecodeStatus DecodeSystemPStateInstruction(MCInst *Inst, |
133 | | uint32_t insn, uint64_t Address, const void *Decoder); |
134 | | static DecodeStatus DecodeTestAndBranch(MCInst *Inst, uint32_t insn, |
135 | | uint64_t Address, const void *Decoder); |
136 | | static DecodeStatus DecodeFMOVLaneInstruction(MCInst *Inst, unsigned Insn, |
137 | | uint64_t Address, const void *Decoder); |
138 | | static DecodeStatus DecodeVecShiftR64Imm(MCInst *Inst, unsigned Imm, |
139 | | uint64_t Addr, const void *Decoder); |
140 | | static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst *Inst, unsigned Imm, |
141 | | uint64_t Addr, const void *Decoder); |
142 | | static DecodeStatus DecodeVecShiftR32Imm(MCInst *Inst, unsigned Imm, |
143 | | uint64_t Addr, const void *Decoder); |
144 | | static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst *Inst, unsigned Imm, |
145 | | uint64_t Addr, const void *Decoder); |
146 | | static DecodeStatus DecodeVecShiftR16Imm(MCInst *Inst, unsigned Imm, |
147 | | uint64_t Addr, const void *Decoder); |
148 | | static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst *Inst, unsigned Imm, |
149 | | uint64_t Addr, const void *Decoder); |
150 | | static DecodeStatus DecodeVecShiftR8Imm(MCInst *Inst, unsigned Imm, |
151 | | uint64_t Addr, const void *Decoder); |
152 | | static DecodeStatus DecodeVecShiftL64Imm(MCInst *Inst, unsigned Imm, |
153 | | uint64_t Addr, const void *Decoder); |
154 | | static DecodeStatus DecodeVecShiftL32Imm(MCInst *Inst, unsigned Imm, |
155 | | uint64_t Addr, const void *Decoder); |
156 | | static DecodeStatus DecodeVecShiftL16Imm(MCInst *Inst, unsigned Imm, |
157 | | uint64_t Addr, const void *Decoder); |
158 | | static DecodeStatus DecodeVecShiftL8Imm(MCInst *Inst, unsigned Imm, |
159 | | uint64_t Addr, const void *Decoder); |
160 | | static DecodeStatus DecodeWSeqPairsClassRegisterClass(MCInst *Inst, |
161 | | unsigned RegNo, uint64_t Addr, const void *Decoder); |
162 | | static DecodeStatus DecodeXSeqPairsClassRegisterClass(MCInst *Inst, |
163 | | unsigned RegNo, uint64_t Addr, const void *Decoder); |
164 | | static DecodeStatus DecodeSVELogicalImmInstruction(MCInst *Inst, uint32_t insn, |
165 | | uint64_t Address, const void *Decoder); |
166 | | static DecodeStatus DecodeSImm(MCInst *Inst, uint64_t Imm, uint64_t Address, |
167 | | const void *Decoder, int Bits); |
168 | | static DecodeStatus DecodeImm8OptLsl(MCInst *Inst, unsigned Imm, uint64_t Addr, |
169 | | const void *Decoder, int ElementWidth); |
170 | | static DecodeStatus DecodeSVEIncDecImm(MCInst *Inst, unsigned Imm, |
171 | | uint64_t Addr, const void *Decoder); |
172 | | static DecodeStatus DecodeThreeAddrSRegInstruction(MCInst *Inst, |
173 | | uint32_t insn, uint64_t Addr, const void *Decoder); |
174 | | static DecodeStatus DecodeGPR64commonRegisterClass(MCInst *Inst, unsigned RegNo, |
175 | | uint64_t Addr, const void *Decoder); |
176 | | static DecodeStatus DecodeFPR128_loRegisterClass(MCInst *Inst, unsigned RegNo, |
177 | | uint64_t Addr, const void *Decoder); |
178 | | static DecodeStatus DecodeSVCROp(MCInst *Inst, unsigned Imm, uint64_t Address, |
179 | | const void *Decoder); |
180 | | static DecodeStatus DecodeCPYMemOpInstruction(MCInst *Inst, uint32_t insn, |
181 | | uint64_t Addr, const void *Decoder); |
182 | | static DecodeStatus DecodeSETMemOpInstruction(MCInst *Inst, uint32_t insn, |
183 | | uint64_t Addr, const void *Decoder); |
184 | | |
185 | | |
186 | | static bool Check(DecodeStatus *Out, DecodeStatus In) |
187 | 539k | { |
188 | 539k | switch (In) { |
189 | 0 | default: // never reach |
190 | 0 | return true; |
191 | | |
192 | 539k | case MCDisassembler_Success: |
193 | | // Out stays the same. |
194 | 539k | return true; |
195 | | |
196 | 13 | case MCDisassembler_SoftFail: |
197 | 13 | *Out = In; |
198 | 13 | return true; |
199 | | |
200 | 353 | case MCDisassembler_Fail: |
201 | 353 | *Out = In; |
202 | 353 | return false; |
203 | 539k | } |
204 | | // llvm_unreachable("Invalid DecodeStatus!"); |
205 | 539k | } |
206 | | |
207 | | // Hacky: enable all features for disassembler |
208 | | uint64_t AArch64_getFeatureBits(int feature) |
209 | 140k | { |
210 | | // enable all features |
211 | 140k | return (uint64_t)-1; |
212 | 140k | } |
213 | | |
214 | | #define GET_SUBTARGETINFO_ENUM |
215 | | #include "AArch64GenSubtargetInfo.inc" |
216 | | |
217 | | #include "AArch64GenDisassemblerTables.inc" |
218 | | |
219 | | #define GET_INSTRINFO_ENUM |
220 | | #include "AArch64GenInstrInfo.inc" |
221 | | |
222 | | #define GET_REGINFO_ENUM |
223 | | #define GET_REGINFO_MC_DESC |
224 | | #include "AArch64GenRegisterInfo.inc" |
225 | | |
226 | 1.07M | #define Success MCDisassembler_Success |
227 | 1.37k | #define Fail MCDisassembler_Fail |
228 | 111 | #define SoftFail MCDisassembler_SoftFail |
229 | | |
230 | | static DecodeStatus _getInstruction(cs_struct *ud, MCInst *MI, |
231 | | const uint8_t *code, size_t code_len, |
232 | | uint16_t *Size, |
233 | | uint64_t Address, MCRegisterInfo *MRI) |
234 | 222k | { |
235 | 222k | uint32_t insn; |
236 | 222k | DecodeStatus result; |
237 | 222k | size_t i; |
238 | | |
239 | 222k | if (code_len < 4) { |
240 | | // not enough data |
241 | 2.38k | *Size = 0; |
242 | 2.38k | return MCDisassembler_Fail; |
243 | 2.38k | } |
244 | | |
245 | 219k | if (MI->flat_insn->detail) { |
246 | 219k | memset(MI->flat_insn->detail, 0, offsetof(cs_detail, arm64)+sizeof(cs_arm64)); |
247 | 1.97M | for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm64.operands); i++) |
248 | 1.75M | MI->flat_insn->detail->arm64.operands[i].vector_index = -1; |
249 | 219k | } |
250 | | |
251 | 219k | if (MODE_IS_BIG_ENDIAN(ud->mode)) |
252 | 0 | insn = (code[3] << 0) | (code[2] << 8) | |
253 | 0 | (code[1] << 16) | ((uint32_t) code[0] << 24); |
254 | 219k | else |
255 | 219k | insn = ((uint32_t) code[3] << 24) | (code[2] << 16) | |
256 | 219k | (code[1] << 8) | (code[0] << 0); |
257 | | |
258 | | // Calling the auto-generated decoder function. |
259 | 219k | result = decodeInstruction_4(DecoderTable32, MI, insn, Address); |
260 | | // If Decoding fails initially, try Fallback table. |
261 | 219k | if(result == MCDisassembler_Fail){ |
262 | 4.28k | result = decodeInstruction_4(DecoderTableFallback32, MI, insn, Address); |
263 | 4.28k | } |
264 | | |
265 | | // Init new MCOperand to be used in switch below. |
266 | | // Kind RegVal set inside a case when needed. |
267 | 219k | MCOperand op_storage; |
268 | 219k | MCOperand *Op = &op_storage; |
269 | 219k | switch (MCInst_getOpcode(MI)) { |
270 | 215k | default: |
271 | 215k | break; |
272 | | // For Scalable Matrix Extension (SME) instructions that have an implicit |
273 | | // operand for the accumulator (ZA) which isn't encoded, manually insert |
274 | | // operand. |
275 | 215k | case AArch64_LDR_ZA: |
276 | 192 | case AArch64_STR_ZA: { |
277 | 192 | Op->Kind = kRegister; |
278 | 192 | Op->RegVal = AArch64_ZA; |
279 | 192 | MCInst_insert0(MI, 0, Op); |
280 | | // Spill and fill instructions have a single immediate used for both the |
281 | | // vector select offset and optional memory offset. Replicate the decoded |
282 | | // immediate. |
283 | 192 | MCOperand *Imm4Op = MCInst_getOperand(MI, 2); |
284 | | // assert(MCOperand_isImm(Imm4Op) && "Unexpected operand type!"); |
285 | 192 | MCInst_addOperand2(MI, Imm4Op); |
286 | 192 | break; |
287 | 111 | } |
288 | 348 | case AArch64_LD1_MXIPXX_H_B: |
289 | 601 | case AArch64_LD1_MXIPXX_V_B: |
290 | 741 | case AArch64_ST1_MXIPXX_H_B: |
291 | 773 | case AArch64_ST1_MXIPXX_V_B: |
292 | 1.15k | case AArch64_INSERT_MXIPZ_H_B: |
293 | 1.20k | case AArch64_INSERT_MXIPZ_V_B: |
294 | | // e.g. |
295 | | // MOVA ZA0<HV>.B[<Ws>, <imm>], <Pg>/M, <Zn>.B |
296 | | // ^ insert implicit 8-bit element tile |
297 | 1.20k | Op->Kind = kRegister; |
298 | 1.20k | Op->RegVal = AArch64_ZAB0; |
299 | 1.20k | MCInst_insert0(MI, 0, Op); |
300 | 1.20k | break; |
301 | 18 | case AArch64_EXTRACT_ZPMXI_H_B: |
302 | 26 | case AArch64_EXTRACT_ZPMXI_V_B: |
303 | | // MOVA <Zd>.B, <Pg>/M, ZA0<HV>.B[<Ws>, <imm>] |
304 | | // ^ insert implicit 8-bit element tile |
305 | 26 | Op->Kind = kRegister; |
306 | 26 | Op->RegVal = AArch64_ZAB0; |
307 | 26 | MCInst_insert0(MI, 2, Op); |
308 | 26 | break; |
309 | 55 | case AArch64_LD1_MXIPXX_H_Q: |
310 | 89 | case AArch64_LD1_MXIPXX_V_Q: |
311 | 371 | case AArch64_ST1_MXIPXX_H_Q: |
312 | 941 | case AArch64_ST1_MXIPXX_V_Q: |
313 | | // 128-bit load/store have implicit zero vector index. |
314 | 941 | Op->Kind = kImmediate; |
315 | 941 | Op->ImmVal = 0; |
316 | 941 | MCInst_insert0(MI, 2, Op); |
317 | 941 | break; |
318 | | // 128-bit mova have implicit zero vector index. |
319 | 155 | case AArch64_INSERT_MXIPZ_H_Q: |
320 | 218 | case AArch64_INSERT_MXIPZ_V_Q: |
321 | 218 | Op->Kind = kImmediate; |
322 | 218 | Op->ImmVal = 0; |
323 | 218 | MCInst_insert0(MI, 2, Op); |
324 | 218 | break; |
325 | 450 | case AArch64_EXTRACT_ZPMXI_H_Q: |
326 | 1.10k | case AArch64_EXTRACT_ZPMXI_V_Q: |
327 | 1.10k | Op->Kind = kImmediate; |
328 | 1.10k | Op->ImmVal = 0; |
329 | 1.10k | MCInst_addOperand2(MI, Op); |
330 | 1.10k | break; |
331 | 14 | case AArch64_SMOVvi8to32_idx0: |
332 | 24 | case AArch64_SMOVvi8to64_idx0: |
333 | 63 | case AArch64_SMOVvi16to32_idx0: |
334 | 251 | case AArch64_SMOVvi16to64_idx0: |
335 | 308 | case AArch64_SMOVvi32to64_idx0: |
336 | 623 | case AArch64_UMOVvi8_idx0: |
337 | 886 | case AArch64_UMOVvi16_idx0: |
338 | 899 | case AArch64_UMOVvi32_idx0: |
339 | 946 | case AArch64_UMOVvi64_idx0: |
340 | 946 | Op->Kind = kImmediate; |
341 | 946 | Op->ImmVal = 0; |
342 | 946 | MCInst_addOperand2(MI, Op); |
343 | 946 | break; |
344 | 219k | } |
345 | | |
346 | 219k | if (result != MCDisassembler_Fail) { |
347 | 218k | *Size = 4; |
348 | | |
349 | 218k | return result; |
350 | 218k | } |
351 | | |
352 | | // invalid code |
353 | 1.36k | MCInst_clear(MI); |
354 | 1.36k | *Size = 0; |
355 | | |
356 | 1.36k | return MCDisassembler_Fail; |
357 | 219k | } |
358 | | |
359 | | bool AArch64_getInstruction(csh ud, const uint8_t *code, size_t code_len, |
360 | | MCInst *instr, uint16_t *size, uint64_t address, void *info) |
361 | 222k | { |
362 | 222k | DecodeStatus status = _getInstruction((cs_struct *)ud, instr, |
363 | 222k | code, code_len, |
364 | 222k | size, |
365 | 222k | address, (MCRegisterInfo *)info); |
366 | | |
367 | 222k | return status == MCDisassembler_Success; |
368 | 222k | } |
369 | | |
370 | | static const unsigned FPR128DecoderTable[] = { |
371 | | AArch64_Q0, AArch64_Q1, AArch64_Q2, AArch64_Q3, AArch64_Q4, |
372 | | AArch64_Q5, AArch64_Q6, AArch64_Q7, AArch64_Q8, AArch64_Q9, |
373 | | AArch64_Q10, AArch64_Q11, AArch64_Q12, AArch64_Q13, AArch64_Q14, |
374 | | AArch64_Q15, AArch64_Q16, AArch64_Q17, AArch64_Q18, AArch64_Q19, |
375 | | AArch64_Q20, AArch64_Q21, AArch64_Q22, AArch64_Q23, AArch64_Q24, |
376 | | AArch64_Q25, AArch64_Q26, AArch64_Q27, AArch64_Q28, AArch64_Q29, |
377 | | AArch64_Q30, AArch64_Q31 |
378 | | }; |
379 | | |
380 | | static DecodeStatus DecodeFPR128RegisterClass(MCInst *Inst, unsigned RegNo, |
381 | | uint64_t Addr, const void *Decoder) |
382 | 71.2k | { |
383 | 71.2k | unsigned Register; |
384 | | |
385 | 71.2k | if (RegNo > 31) |
386 | 0 | return Fail; |
387 | | |
388 | 71.2k | Register = FPR128DecoderTable[RegNo]; |
389 | 71.2k | MCOperand_CreateReg0(Inst, Register); |
390 | | |
391 | 71.2k | return Success; |
392 | 71.2k | } |
393 | | |
394 | | static DecodeStatus DecodeFPR128_loRegisterClass(MCInst *Inst, unsigned RegNo, |
395 | | uint64_t Addr, const void *Decoder) |
396 | 1.65k | { |
397 | 1.65k | if (RegNo > 15) |
398 | 0 | return Fail; |
399 | | |
400 | 1.65k | return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder); |
401 | 1.65k | } |
402 | | |
403 | | static const unsigned FPR64DecoderTable[] = { |
404 | | AArch64_D0, AArch64_D1, AArch64_D2, AArch64_D3, AArch64_D4, |
405 | | AArch64_D5, AArch64_D6, AArch64_D7, AArch64_D8, AArch64_D9, |
406 | | AArch64_D10, AArch64_D11, AArch64_D12, AArch64_D13, AArch64_D14, |
407 | | AArch64_D15, AArch64_D16, AArch64_D17, AArch64_D18, AArch64_D19, |
408 | | AArch64_D20, AArch64_D21, AArch64_D22, AArch64_D23, AArch64_D24, |
409 | | AArch64_D25, AArch64_D26, AArch64_D27, AArch64_D28, AArch64_D29, |
410 | | AArch64_D30, AArch64_D31 |
411 | | }; |
412 | | |
413 | | static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, unsigned RegNo, |
414 | | uint64_t Addr, const void *Decoder) |
415 | 47.9k | { |
416 | 47.9k | unsigned Register; |
417 | | |
418 | 47.9k | if (RegNo > 31) |
419 | 0 | return Fail; |
420 | | |
421 | 47.9k | Register = FPR64DecoderTable[RegNo]; |
422 | 47.9k | MCOperand_CreateReg0(Inst, Register); |
423 | | |
424 | 47.9k | return Success; |
425 | 47.9k | } |
426 | | |
427 | | static const unsigned FPR32DecoderTable[] = { |
428 | | AArch64_S0, AArch64_S1, AArch64_S2, AArch64_S3, AArch64_S4, |
429 | | AArch64_S5, AArch64_S6, AArch64_S7, AArch64_S8, AArch64_S9, |
430 | | AArch64_S10, AArch64_S11, AArch64_S12, AArch64_S13, AArch64_S14, |
431 | | AArch64_S15, AArch64_S16, AArch64_S17, AArch64_S18, AArch64_S19, |
432 | | AArch64_S20, AArch64_S21, AArch64_S22, AArch64_S23, AArch64_S24, |
433 | | AArch64_S25, AArch64_S26, AArch64_S27, AArch64_S28, AArch64_S29, |
434 | | AArch64_S30, AArch64_S31 |
435 | | }; |
436 | | |
437 | | static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, unsigned RegNo, |
438 | | uint64_t Addr, const void *Decoder) |
439 | 21.4k | { |
440 | 21.4k | unsigned Register; |
441 | | |
442 | 21.4k | if (RegNo > 31) |
443 | 0 | return Fail; |
444 | | |
445 | 21.4k | Register = FPR32DecoderTable[RegNo]; |
446 | 21.4k | MCOperand_CreateReg0(Inst, Register); |
447 | | |
448 | 21.4k | return Success; |
449 | 21.4k | } |
450 | | |
451 | | static const unsigned FPR16DecoderTable[] = { |
452 | | AArch64_H0, AArch64_H1, AArch64_H2, AArch64_H3, AArch64_H4, |
453 | | AArch64_H5, AArch64_H6, AArch64_H7, AArch64_H8, AArch64_H9, |
454 | | AArch64_H10, AArch64_H11, AArch64_H12, AArch64_H13, AArch64_H14, |
455 | | AArch64_H15, AArch64_H16, AArch64_H17, AArch64_H18, AArch64_H19, |
456 | | AArch64_H20, AArch64_H21, AArch64_H22, AArch64_H23, AArch64_H24, |
457 | | AArch64_H25, AArch64_H26, AArch64_H27, AArch64_H28, AArch64_H29, |
458 | | AArch64_H30, AArch64_H31 |
459 | | }; |
460 | | |
461 | | static DecodeStatus DecodeFPR16RegisterClass(MCInst *Inst, unsigned RegNo, |
462 | | uint64_t Addr, const void *Decoder) |
463 | 14.0k | { |
464 | 14.0k | unsigned Register; |
465 | | |
466 | 14.0k | if (RegNo > 31) |
467 | 0 | return Fail; |
468 | | |
469 | 14.0k | Register = FPR16DecoderTable[RegNo]; |
470 | 14.0k | MCOperand_CreateReg0(Inst, Register); |
471 | | |
472 | 14.0k | return Success; |
473 | 14.0k | } |
474 | | |
475 | | static const unsigned FPR8DecoderTable[] = { |
476 | | AArch64_B0, AArch64_B1, AArch64_B2, AArch64_B3, AArch64_B4, |
477 | | AArch64_B5, AArch64_B6, AArch64_B7, AArch64_B8, AArch64_B9, |
478 | | AArch64_B10, AArch64_B11, AArch64_B12, AArch64_B13, AArch64_B14, |
479 | | AArch64_B15, AArch64_B16, AArch64_B17, AArch64_B18, AArch64_B19, |
480 | | AArch64_B20, AArch64_B21, AArch64_B22, AArch64_B23, AArch64_B24, |
481 | | AArch64_B25, AArch64_B26, AArch64_B27, AArch64_B28, AArch64_B29, |
482 | | AArch64_B30, AArch64_B31 |
483 | | }; |
484 | | |
485 | | static DecodeStatus DecodeFPR8RegisterClass(MCInst *Inst, unsigned RegNo, |
486 | | uint64_t Addr, const void *Decoder) |
487 | 8.64k | { |
488 | 8.64k | unsigned Register; |
489 | | |
490 | 8.64k | if (RegNo > 31) |
491 | 0 | return Fail; |
492 | | |
493 | 8.64k | Register = FPR8DecoderTable[RegNo]; |
494 | 8.64k | MCOperand_CreateReg0(Inst, Register); |
495 | | |
496 | 8.64k | return Success; |
497 | 8.64k | } |
498 | | |
499 | | static const unsigned GPR64DecoderTable[] = { |
500 | | AArch64_X0, AArch64_X1, AArch64_X2, AArch64_X3, AArch64_X4, |
501 | | AArch64_X5, AArch64_X6, AArch64_X7, AArch64_X8, AArch64_X9, |
502 | | AArch64_X10, AArch64_X11, AArch64_X12, AArch64_X13, AArch64_X14, |
503 | | AArch64_X15, AArch64_X16, AArch64_X17, AArch64_X18, AArch64_X19, |
504 | | AArch64_X20, AArch64_X21, AArch64_X22, AArch64_X23, AArch64_X24, |
505 | | AArch64_X25, AArch64_X26, AArch64_X27, AArch64_X28, AArch64_FP, |
506 | | AArch64_LR, AArch64_XZR |
507 | | }; |
508 | | |
509 | | static DecodeStatus DecodeGPR64commonRegisterClass(MCInst *Inst, unsigned RegNo, |
510 | | uint64_t Addr, const void *Decoder) |
511 | 5.20k | { |
512 | 5.20k | unsigned Register; |
513 | | |
514 | 5.20k | if (RegNo > 30) |
515 | 23 | return Fail; |
516 | | |
517 | 5.17k | Register = GPR64DecoderTable[RegNo]; |
518 | 5.17k | MCOperand_CreateReg0(Inst, Register); |
519 | | |
520 | 5.17k | return Success; |
521 | 5.20k | } |
522 | | |
523 | | static DecodeStatus DecodeGPR64RegisterClass(MCInst *Inst, unsigned RegNo, |
524 | | uint64_t Addr, const void *Decoder) |
525 | 173k | { |
526 | 173k | unsigned Register; |
527 | | |
528 | 173k | if (RegNo > 31) |
529 | 0 | return Fail; |
530 | | |
531 | 173k | Register = GPR64DecoderTable[RegNo]; |
532 | 173k | MCOperand_CreateReg0(Inst, Register); |
533 | | |
534 | 173k | return Success; |
535 | 173k | } |
536 | | |
537 | | static const unsigned GPR64x8DecoderTable[] = { |
538 | | AArch64_X0_X1_X2_X3_X4_X5_X6_X7, AArch64_X2_X3_X4_X5_X6_X7_X8_X9, |
539 | | AArch64_X4_X5_X6_X7_X8_X9_X10_X11, AArch64_X6_X7_X8_X9_X10_X11_X12_X13, |
540 | | AArch64_X8_X9_X10_X11_X12_X13_X14_X15, AArch64_X10_X11_X12_X13_X14_X15_X16_X17, |
541 | | AArch64_X12_X13_X14_X15_X16_X17_X18_X19, AArch64_X14_X15_X16_X17_X18_X19_X20_X21, |
542 | | AArch64_X16_X17_X18_X19_X20_X21_X22_X23, AArch64_X18_X19_X20_X21_X22_X23_X24_X25, |
543 | | AArch64_X20_X21_X22_X23_X24_X25_X26_X27, AArch64_X22_X23_X24_X25_X26_X27_X28_FP |
544 | | }; |
545 | | |
546 | | static DecodeStatus DecodeGPR64x8ClassRegisterClass(MCInst *Inst, unsigned RegNo, |
547 | | uint64_t Address, const void *Decoder) |
548 | 909 | { |
549 | 909 | if (RegNo > 22) |
550 | 4 | return Fail; |
551 | 905 | if (RegNo & 1) |
552 | 4 | return Fail; |
553 | | |
554 | 901 | unsigned Register = GPR64x8DecoderTable[RegNo >> 1]; |
555 | 901 | MCOperand_CreateReg0(Inst, Register); |
556 | | |
557 | 901 | return Success; |
558 | 905 | } |
559 | | |
560 | | static DecodeStatus DecodeGPR64spRegisterClass(MCInst *Inst, unsigned RegNo, |
561 | | uint64_t Addr, const void *Decoder) |
562 | 151k | { |
563 | 151k | unsigned Register; |
564 | | |
565 | 151k | if (RegNo > 31) |
566 | 0 | return Fail; |
567 | | |
568 | 151k | Register = GPR64DecoderTable[RegNo]; |
569 | 151k | if (Register == AArch64_XZR) |
570 | 37.4k | Register = AArch64_SP; |
571 | | |
572 | 151k | MCOperand_CreateReg0(Inst, Register); |
573 | | |
574 | 151k | return Success; |
575 | 151k | } |
576 | | |
577 | | |
578 | | static const unsigned MatrixIndexGPR32_12_15DecoderTable[] = { |
579 | | AArch64_W12, AArch64_W13, AArch64_W14, AArch64_W15 |
580 | | }; |
581 | | |
582 | | static DecodeStatus DecodeMatrixIndexGPR32_12_15RegisterClass(MCInst *Inst, |
583 | | unsigned RegNo, uint64_t Addr, const void *Decoder) |
584 | 10.3k | { |
585 | 10.3k | unsigned Register; |
586 | | |
587 | 10.3k | if (RegNo > 3) |
588 | 0 | return Fail; |
589 | | |
590 | 10.3k | Register = MatrixIndexGPR32_12_15DecoderTable[RegNo]; |
591 | 10.3k | MCOperand_CreateReg0(Inst, Register); |
592 | | |
593 | 10.3k | return Success; |
594 | 10.3k | } |
595 | | |
596 | | static const unsigned GPR32DecoderTable[] = { |
597 | | AArch64_W0, AArch64_W1, AArch64_W2, AArch64_W3, AArch64_W4, |
598 | | AArch64_W5, AArch64_W6, AArch64_W7, AArch64_W8, AArch64_W9, |
599 | | AArch64_W10, AArch64_W11, AArch64_W12, AArch64_W13, AArch64_W14, |
600 | | AArch64_W15, AArch64_W16, AArch64_W17, AArch64_W18, AArch64_W19, |
601 | | AArch64_W20, AArch64_W21, AArch64_W22, AArch64_W23, AArch64_W24, |
602 | | AArch64_W25, AArch64_W26, AArch64_W27, AArch64_W28, AArch64_W29, |
603 | | AArch64_W30, AArch64_WZR |
604 | | }; |
605 | | |
606 | | static DecodeStatus DecodeGPR32RegisterClass(MCInst *Inst, unsigned RegNo, |
607 | | uint64_t Addr, const void *Decoder) |
608 | 83.4k | { |
609 | 83.4k | unsigned Register; |
610 | | |
611 | 83.4k | if (RegNo > 31) |
612 | 0 | return Fail; |
613 | | |
614 | 83.4k | Register = GPR32DecoderTable[RegNo]; |
615 | 83.4k | MCOperand_CreateReg0(Inst, Register); |
616 | | |
617 | 83.4k | return Success; |
618 | 83.4k | } |
619 | | |
620 | | static DecodeStatus DecodeGPR32spRegisterClass(MCInst *Inst, unsigned RegNo, |
621 | | uint64_t Addr, const void *Decoder) |
622 | 4.85k | { |
623 | 4.85k | unsigned Register; |
624 | | |
625 | 4.85k | if (RegNo > 31) |
626 | 0 | return Fail; |
627 | | |
628 | 4.85k | Register = GPR32DecoderTable[RegNo]; |
629 | 4.85k | if (Register == AArch64_WZR) |
630 | 1.13k | Register = AArch64_WSP; |
631 | | |
632 | 4.85k | MCOperand_CreateReg0(Inst, Register); |
633 | | |
634 | 4.85k | return Success; |
635 | 4.85k | } |
636 | | |
637 | | static const unsigned ZPRDecoderTable[] = { |
638 | | AArch64_Z0, AArch64_Z1, AArch64_Z2, AArch64_Z3, |
639 | | AArch64_Z4, AArch64_Z5, AArch64_Z6, AArch64_Z7, |
640 | | AArch64_Z8, AArch64_Z9, AArch64_Z10, AArch64_Z11, |
641 | | AArch64_Z12, AArch64_Z13, AArch64_Z14, AArch64_Z15, |
642 | | AArch64_Z16, AArch64_Z17, AArch64_Z18, AArch64_Z19, |
643 | | AArch64_Z20, AArch64_Z21, AArch64_Z22, AArch64_Z23, |
644 | | AArch64_Z24, AArch64_Z25, AArch64_Z26, AArch64_Z27, |
645 | | AArch64_Z28, AArch64_Z29, AArch64_Z30, AArch64_Z31 |
646 | | }; |
647 | | |
648 | | static DecodeStatus DecodeZPRRegisterClass(MCInst *Inst, unsigned RegNo, |
649 | | uint64_t Address, const void *Decoder) |
650 | 168k | { |
651 | 168k | unsigned Register; |
652 | | |
653 | 168k | if (RegNo > 31) |
654 | 0 | return Fail; |
655 | | |
656 | 168k | Register = ZPRDecoderTable[RegNo]; |
657 | 168k | MCOperand_CreateReg0(Inst, Register); |
658 | | |
659 | 168k | return Success; |
660 | 168k | } |
661 | | |
662 | | static DecodeStatus DecodeZPR_4bRegisterClass(MCInst *Inst, unsigned RegNo, |
663 | | uint64_t Address, const void *Decoder) |
664 | 5.66k | { |
665 | 5.66k | if (RegNo > 15) |
666 | 0 | return Fail; |
667 | | |
668 | 5.66k | return DecodeZPRRegisterClass(Inst, RegNo, Address, Decoder); |
669 | 5.66k | } |
670 | | |
671 | | static DecodeStatus DecodeZPR_3bRegisterClass(MCInst *Inst, unsigned RegNo, |
672 | | uint64_t Address, const void *Decoder) |
673 | 1.78k | { |
674 | 1.78k | if (RegNo > 7) |
675 | 0 | return Fail; |
676 | | |
677 | 1.78k | return DecodeZPRRegisterClass(Inst, RegNo, Address, Decoder); |
678 | 1.78k | } |
679 | | |
680 | | static const unsigned ZZDecoderTable[] = { |
681 | | AArch64_Z0_Z1, AArch64_Z1_Z2, AArch64_Z2_Z3, AArch64_Z3_Z4, |
682 | | AArch64_Z4_Z5, AArch64_Z5_Z6, AArch64_Z6_Z7, AArch64_Z7_Z8, |
683 | | AArch64_Z8_Z9, AArch64_Z9_Z10, AArch64_Z10_Z11, AArch64_Z11_Z12, |
684 | | AArch64_Z12_Z13, AArch64_Z13_Z14, AArch64_Z14_Z15, AArch64_Z15_Z16, |
685 | | AArch64_Z16_Z17, AArch64_Z17_Z18, AArch64_Z18_Z19, AArch64_Z19_Z20, |
686 | | AArch64_Z20_Z21, AArch64_Z21_Z22, AArch64_Z22_Z23, AArch64_Z23_Z24, |
687 | | AArch64_Z24_Z25, AArch64_Z25_Z26, AArch64_Z26_Z27, AArch64_Z27_Z28, |
688 | | AArch64_Z28_Z29, AArch64_Z29_Z30, AArch64_Z30_Z31, AArch64_Z31_Z0 |
689 | | }; |
690 | | |
691 | | static DecodeStatus DecodeZPR2RegisterClass(MCInst *Inst, unsigned RegNo, |
692 | | uint64_t Address, const void *Decoder) |
693 | 2.13k | { |
694 | 2.13k | unsigned Register; |
695 | | |
696 | 2.13k | if (RegNo > 31) |
697 | 0 | return Fail; |
698 | | |
699 | 2.13k | Register = ZZDecoderTable[RegNo]; |
700 | 2.13k | MCOperand_CreateReg0(Inst, Register); |
701 | | |
702 | 2.13k | return Success; |
703 | 2.13k | } |
704 | | |
705 | | static const unsigned ZZZDecoderTable[] = { |
706 | | AArch64_Z0_Z1_Z2, AArch64_Z1_Z2_Z3, AArch64_Z2_Z3_Z4, |
707 | | AArch64_Z3_Z4_Z5, AArch64_Z4_Z5_Z6, AArch64_Z5_Z6_Z7, |
708 | | AArch64_Z6_Z7_Z8, AArch64_Z7_Z8_Z9, AArch64_Z8_Z9_Z10, |
709 | | AArch64_Z9_Z10_Z11, AArch64_Z10_Z11_Z12, AArch64_Z11_Z12_Z13, |
710 | | AArch64_Z12_Z13_Z14, AArch64_Z13_Z14_Z15, AArch64_Z14_Z15_Z16, |
711 | | AArch64_Z15_Z16_Z17, AArch64_Z16_Z17_Z18, AArch64_Z17_Z18_Z19, |
712 | | AArch64_Z18_Z19_Z20, AArch64_Z19_Z20_Z21, AArch64_Z20_Z21_Z22, |
713 | | AArch64_Z21_Z22_Z23, AArch64_Z22_Z23_Z24, AArch64_Z23_Z24_Z25, |
714 | | AArch64_Z24_Z25_Z26, AArch64_Z25_Z26_Z27, AArch64_Z26_Z27_Z28, |
715 | | AArch64_Z27_Z28_Z29, AArch64_Z28_Z29_Z30, AArch64_Z29_Z30_Z31, |
716 | | AArch64_Z30_Z31_Z0, AArch64_Z31_Z0_Z1 |
717 | | }; |
718 | | |
719 | | static DecodeStatus DecodeZPR3RegisterClass(MCInst *Inst, unsigned RegNo, |
720 | | uint64_t Address, const void *Decoder) |
721 | 875 | { |
722 | 875 | unsigned Register; |
723 | | |
724 | 875 | if (RegNo > 31) |
725 | 0 | return Fail; |
726 | | |
727 | 875 | Register = ZZZDecoderTable[RegNo]; |
728 | 875 | MCOperand_CreateReg0(Inst, Register); |
729 | | |
730 | 875 | return Success; |
731 | 875 | } |
732 | | |
733 | | static const unsigned ZZZZDecoderTable[] = { |
734 | | AArch64_Z0_Z1_Z2_Z3, AArch64_Z1_Z2_Z3_Z4, AArch64_Z2_Z3_Z4_Z5, |
735 | | AArch64_Z3_Z4_Z5_Z6, AArch64_Z4_Z5_Z6_Z7, AArch64_Z5_Z6_Z7_Z8, |
736 | | AArch64_Z6_Z7_Z8_Z9, AArch64_Z7_Z8_Z9_Z10, AArch64_Z8_Z9_Z10_Z11, |
737 | | AArch64_Z9_Z10_Z11_Z12, AArch64_Z10_Z11_Z12_Z13, AArch64_Z11_Z12_Z13_Z14, |
738 | | AArch64_Z12_Z13_Z14_Z15, AArch64_Z13_Z14_Z15_Z16, AArch64_Z14_Z15_Z16_Z17, |
739 | | AArch64_Z15_Z16_Z17_Z18, AArch64_Z16_Z17_Z18_Z19, AArch64_Z17_Z18_Z19_Z20, |
740 | | AArch64_Z18_Z19_Z20_Z21, AArch64_Z19_Z20_Z21_Z22, AArch64_Z20_Z21_Z22_Z23, |
741 | | AArch64_Z21_Z22_Z23_Z24, AArch64_Z22_Z23_Z24_Z25, AArch64_Z23_Z24_Z25_Z26, |
742 | | AArch64_Z24_Z25_Z26_Z27, AArch64_Z25_Z26_Z27_Z28, AArch64_Z26_Z27_Z28_Z29, |
743 | | AArch64_Z27_Z28_Z29_Z30, AArch64_Z28_Z29_Z30_Z31, AArch64_Z29_Z30_Z31_Z0, |
744 | | AArch64_Z30_Z31_Z0_Z1, AArch64_Z31_Z0_Z1_Z2 |
745 | | }; |
746 | | |
747 | | static DecodeStatus DecodeZPR4RegisterClass(MCInst *Inst, unsigned RegNo, |
748 | | uint64_t Address, const void *Decoder) |
749 | 1.55k | { |
750 | 1.55k | unsigned Register; |
751 | | |
752 | 1.55k | if (RegNo > 31) |
753 | 0 | return Fail; |
754 | | |
755 | 1.55k | Register = ZZZZDecoderTable[RegNo]; |
756 | 1.55k | MCOperand_CreateReg0(Inst, Register); |
757 | | |
758 | 1.55k | return Success; |
759 | 1.55k | } |
760 | | |
761 | | static DecodeStatus DecodeMatrixTileListRegisterClass(MCInst *Inst, |
762 | 1.39k | unsigned RegMask, uint64_t Address, const void *Decoder) { |
763 | 1.39k | if (RegMask > 0xFF) |
764 | 0 | return Fail; |
765 | | |
766 | 1.39k | MCOperand_CreateImm0(Inst, RegMask); |
767 | 1.39k | return Success; |
768 | 1.39k | } |
769 | | |
770 | | static const unsigned MatrixZATileDecoderTable[] = { |
771 | | AArch64_ZAB0, |
772 | | AArch64_ZAH0, AArch64_ZAH1, |
773 | | AArch64_ZAS0, AArch64_ZAS1, AArch64_ZAS2, AArch64_ZAS3, |
774 | | AArch64_ZAD0, AArch64_ZAD1, AArch64_ZAD2, AArch64_ZAD3, |
775 | | AArch64_ZAD4, AArch64_ZAD5, AArch64_ZAD6, AArch64_ZAD7, |
776 | | AArch64_ZAQ0, AArch64_ZAQ1, AArch64_ZAQ2, AArch64_ZAQ3, |
777 | | AArch64_ZAQ4, AArch64_ZAQ5, AArch64_ZAQ6, AArch64_ZAQ7, |
778 | | AArch64_ZAQ8, AArch64_ZAQ9, AArch64_ZAQ10, AArch64_ZAQ11, |
779 | | AArch64_ZAQ12, AArch64_ZAQ13, AArch64_ZAQ14, AArch64_ZAQ15 |
780 | | }; |
781 | | |
782 | | static DecodeStatus DecodeMatrixTile(MCInst *Inst, unsigned RegNo, |
783 | 6.26k | uint64_t Address, const void *Decoder, unsigned NumBitsForTile) { |
784 | 6.26k | unsigned LastReg = (1 << NumBitsForTile) - 1; |
785 | 6.26k | if (RegNo > LastReg) |
786 | 0 | return Fail; |
787 | | |
788 | | // Convert original 2D indexes into 1D table index |
789 | 6.26k | unsigned index = 0; |
790 | 6.26k | switch (NumBitsForTile) |
791 | 6.26k | { |
792 | 0 | case 0: |
793 | | // Only a single Byte tile at beginning of list so index = 0 |
794 | 0 | break; |
795 | 133 | case 1: |
796 | 133 | index = 1 + RegNo; |
797 | 133 | break; |
798 | 1.92k | case 2: |
799 | 1.92k | index = 3 + RegNo; |
800 | 1.92k | break; |
801 | 1.94k | case 3: |
802 | 1.94k | index = 7 + RegNo; |
803 | 1.94k | break; |
804 | 2.26k | case 4: |
805 | 2.26k | index = 15 + RegNo; |
806 | 2.26k | break; |
807 | 0 | default: |
808 | 0 | break; |
809 | 6.26k | } |
810 | | |
811 | 6.26k | MCOperand_CreateReg0(Inst, MatrixZATileDecoderTable[index]); |
812 | 6.26k | return Success; |
813 | 6.26k | } |
814 | | |
815 | | |
816 | | static const unsigned PPRDecoderTable[] = { |
817 | | AArch64_P0, AArch64_P1, AArch64_P2, AArch64_P3, |
818 | | AArch64_P4, AArch64_P5, AArch64_P6, AArch64_P7, |
819 | | AArch64_P8, AArch64_P9, AArch64_P10, AArch64_P11, |
820 | | AArch64_P12, AArch64_P13, AArch64_P14, AArch64_P15 |
821 | | }; |
822 | | |
823 | | static DecodeStatus DecodePPRRegisterClass(MCInst *Inst, unsigned RegNo, |
824 | | uint64_t Addr, const void *Decoder) |
825 | 76.9k | { |
826 | 76.9k | unsigned Register; |
827 | | |
828 | 76.9k | if (RegNo > 15) |
829 | 0 | return Fail; |
830 | | |
831 | 76.9k | Register = PPRDecoderTable[RegNo]; |
832 | 76.9k | MCOperand_CreateReg0(Inst, Register); |
833 | | |
834 | 76.9k | return Success; |
835 | 76.9k | } |
836 | | |
837 | | static DecodeStatus DecodePPR_3bRegisterClass(MCInst *Inst, unsigned RegNo, |
838 | | uint64_t Addr, const void *Decoder) |
839 | 53.8k | { |
840 | 53.8k | if (RegNo > 7) |
841 | 0 | return Fail; |
842 | | |
843 | | // Just reuse the PPR decode table |
844 | 53.8k | return DecodePPRRegisterClass(Inst, RegNo, Addr, Decoder); |
845 | 53.8k | } |
846 | | |
847 | | static const unsigned VectorDecoderTable[] = { |
848 | | AArch64_Q0, AArch64_Q1, AArch64_Q2, AArch64_Q3, AArch64_Q4, |
849 | | AArch64_Q5, AArch64_Q6, AArch64_Q7, AArch64_Q8, AArch64_Q9, |
850 | | AArch64_Q10, AArch64_Q11, AArch64_Q12, AArch64_Q13, AArch64_Q14, |
851 | | AArch64_Q15, AArch64_Q16, AArch64_Q17, AArch64_Q18, AArch64_Q19, |
852 | | AArch64_Q20, AArch64_Q21, AArch64_Q22, AArch64_Q23, AArch64_Q24, |
853 | | AArch64_Q25, AArch64_Q26, AArch64_Q27, AArch64_Q28, AArch64_Q29, |
854 | | AArch64_Q30, AArch64_Q31 |
855 | | }; |
856 | | |
857 | | static DecodeStatus DecodeVectorRegisterClass(MCInst *Inst, unsigned RegNo, |
858 | | uint64_t Addr, const void *Decoder) |
859 | 2.08k | { |
860 | 2.08k | unsigned Register; |
861 | | |
862 | 2.08k | if (RegNo > 31) |
863 | 0 | return Fail; |
864 | | |
865 | 2.08k | Register = VectorDecoderTable[RegNo]; |
866 | 2.08k | MCOperand_CreateReg0(Inst, Register); |
867 | | |
868 | 2.08k | return Success; |
869 | 2.08k | } |
870 | | |
871 | | static const unsigned QQDecoderTable[] = { |
872 | | AArch64_Q0_Q1, AArch64_Q1_Q2, AArch64_Q2_Q3, AArch64_Q3_Q4, |
873 | | AArch64_Q4_Q5, AArch64_Q5_Q6, AArch64_Q6_Q7, AArch64_Q7_Q8, |
874 | | AArch64_Q8_Q9, AArch64_Q9_Q10, AArch64_Q10_Q11, AArch64_Q11_Q12, |
875 | | AArch64_Q12_Q13, AArch64_Q13_Q14, AArch64_Q14_Q15, AArch64_Q15_Q16, |
876 | | AArch64_Q16_Q17, AArch64_Q17_Q18, AArch64_Q18_Q19, AArch64_Q19_Q20, |
877 | | AArch64_Q20_Q21, AArch64_Q21_Q22, AArch64_Q22_Q23, AArch64_Q23_Q24, |
878 | | AArch64_Q24_Q25, AArch64_Q25_Q26, AArch64_Q26_Q27, AArch64_Q27_Q28, |
879 | | AArch64_Q28_Q29, AArch64_Q29_Q30, AArch64_Q30_Q31, AArch64_Q31_Q0 |
880 | | }; |
881 | | |
882 | | static DecodeStatus DecodeQQRegisterClass(MCInst *Inst, unsigned RegNo, |
883 | | uint64_t Addr, const void *Decoder) |
884 | 14.5k | { |
885 | 14.5k | unsigned Register; |
886 | | |
887 | 14.5k | if (RegNo > 31) |
888 | 0 | return Fail; |
889 | | |
890 | 14.5k | Register = QQDecoderTable[RegNo]; |
891 | 14.5k | MCOperand_CreateReg0(Inst, Register); |
892 | | |
893 | 14.5k | return Success; |
894 | 14.5k | } |
895 | | |
896 | | static const unsigned QQQDecoderTable[] = { |
897 | | AArch64_Q0_Q1_Q2, AArch64_Q1_Q2_Q3, AArch64_Q2_Q3_Q4, |
898 | | AArch64_Q3_Q4_Q5, AArch64_Q4_Q5_Q6, AArch64_Q5_Q6_Q7, |
899 | | AArch64_Q6_Q7_Q8, AArch64_Q7_Q8_Q9, AArch64_Q8_Q9_Q10, |
900 | | AArch64_Q9_Q10_Q11, AArch64_Q10_Q11_Q12, AArch64_Q11_Q12_Q13, |
901 | | AArch64_Q12_Q13_Q14, AArch64_Q13_Q14_Q15, AArch64_Q14_Q15_Q16, |
902 | | AArch64_Q15_Q16_Q17, AArch64_Q16_Q17_Q18, AArch64_Q17_Q18_Q19, |
903 | | AArch64_Q18_Q19_Q20, AArch64_Q19_Q20_Q21, AArch64_Q20_Q21_Q22, |
904 | | AArch64_Q21_Q22_Q23, AArch64_Q22_Q23_Q24, AArch64_Q23_Q24_Q25, |
905 | | AArch64_Q24_Q25_Q26, AArch64_Q25_Q26_Q27, AArch64_Q26_Q27_Q28, |
906 | | AArch64_Q27_Q28_Q29, AArch64_Q28_Q29_Q30, AArch64_Q29_Q30_Q31, |
907 | | AArch64_Q30_Q31_Q0, AArch64_Q31_Q0_Q1 |
908 | | }; |
909 | | |
910 | | static DecodeStatus DecodeQQQRegisterClass(MCInst *Inst, unsigned RegNo, |
911 | | uint64_t Addr, const void *Decoder) |
912 | 20.6k | { |
913 | 20.6k | unsigned Register; |
914 | | |
915 | 20.6k | if (RegNo > 31) |
916 | 0 | return Fail; |
917 | | |
918 | 20.6k | Register = QQQDecoderTable[RegNo]; |
919 | 20.6k | MCOperand_CreateReg0(Inst, Register); |
920 | | |
921 | 20.6k | return Success; |
922 | 20.6k | } |
923 | | |
924 | | static const unsigned QQQQDecoderTable[] = { |
925 | | AArch64_Q0_Q1_Q2_Q3, AArch64_Q1_Q2_Q3_Q4, AArch64_Q2_Q3_Q4_Q5, |
926 | | AArch64_Q3_Q4_Q5_Q6, AArch64_Q4_Q5_Q6_Q7, AArch64_Q5_Q6_Q7_Q8, |
927 | | AArch64_Q6_Q7_Q8_Q9, AArch64_Q7_Q8_Q9_Q10, AArch64_Q8_Q9_Q10_Q11, |
928 | | AArch64_Q9_Q10_Q11_Q12, AArch64_Q10_Q11_Q12_Q13, AArch64_Q11_Q12_Q13_Q14, |
929 | | AArch64_Q12_Q13_Q14_Q15, AArch64_Q13_Q14_Q15_Q16, AArch64_Q14_Q15_Q16_Q17, |
930 | | AArch64_Q15_Q16_Q17_Q18, AArch64_Q16_Q17_Q18_Q19, AArch64_Q17_Q18_Q19_Q20, |
931 | | AArch64_Q18_Q19_Q20_Q21, AArch64_Q19_Q20_Q21_Q22, AArch64_Q20_Q21_Q22_Q23, |
932 | | AArch64_Q21_Q22_Q23_Q24, AArch64_Q22_Q23_Q24_Q25, AArch64_Q23_Q24_Q25_Q26, |
933 | | AArch64_Q24_Q25_Q26_Q27, AArch64_Q25_Q26_Q27_Q28, AArch64_Q26_Q27_Q28_Q29, |
934 | | AArch64_Q27_Q28_Q29_Q30, AArch64_Q28_Q29_Q30_Q31, AArch64_Q29_Q30_Q31_Q0, |
935 | | AArch64_Q30_Q31_Q0_Q1, AArch64_Q31_Q0_Q1_Q2 |
936 | | }; |
937 | | |
938 | | static DecodeStatus DecodeQQQQRegisterClass(MCInst *Inst, unsigned RegNo, |
939 | | uint64_t Addr, const void *Decoder) |
940 | 18.8k | { |
941 | 18.8k | unsigned Register; |
942 | | |
943 | 18.8k | if (RegNo > 31) |
944 | 0 | return Fail; |
945 | | |
946 | 18.8k | Register = QQQQDecoderTable[RegNo]; |
947 | 18.8k | MCOperand_CreateReg0(Inst, Register); |
948 | | |
949 | 18.8k | return Success; |
950 | 18.8k | } |
951 | | |
952 | | static const unsigned DDDecoderTable[] = { |
953 | | AArch64_D0_D1, AArch64_D1_D2, AArch64_D2_D3, AArch64_D3_D4, |
954 | | AArch64_D4_D5, AArch64_D5_D6, AArch64_D6_D7, AArch64_D7_D8, |
955 | | AArch64_D8_D9, AArch64_D9_D10, AArch64_D10_D11, AArch64_D11_D12, |
956 | | AArch64_D12_D13, AArch64_D13_D14, AArch64_D14_D15, AArch64_D15_D16, |
957 | | AArch64_D16_D17, AArch64_D17_D18, AArch64_D18_D19, AArch64_D19_D20, |
958 | | AArch64_D20_D21, AArch64_D21_D22, AArch64_D22_D23, AArch64_D23_D24, |
959 | | AArch64_D24_D25, AArch64_D25_D26, AArch64_D26_D27, AArch64_D27_D28, |
960 | | AArch64_D28_D29, AArch64_D29_D30, AArch64_D30_D31, AArch64_D31_D0 |
961 | | }; |
962 | | |
963 | | static DecodeStatus DecodeDDRegisterClass(MCInst *Inst, unsigned RegNo, |
964 | | uint64_t Addr, const void *Decoder) |
965 | 2.12k | { |
966 | 2.12k | unsigned Register; |
967 | | |
968 | 2.12k | if (RegNo > 31) |
969 | 0 | return Fail; |
970 | | |
971 | 2.12k | Register = DDDecoderTable[RegNo]; |
972 | 2.12k | MCOperand_CreateReg0(Inst, Register); |
973 | | |
974 | 2.12k | return Success; |
975 | 2.12k | } |
976 | | |
977 | | static const unsigned DDDDecoderTable[] = { |
978 | | AArch64_D0_D1_D2, AArch64_D1_D2_D3, AArch64_D2_D3_D4, |
979 | | AArch64_D3_D4_D5, AArch64_D4_D5_D6, AArch64_D5_D6_D7, |
980 | | AArch64_D6_D7_D8, AArch64_D7_D8_D9, AArch64_D8_D9_D10, |
981 | | AArch64_D9_D10_D11, AArch64_D10_D11_D12, AArch64_D11_D12_D13, |
982 | | AArch64_D12_D13_D14, AArch64_D13_D14_D15, AArch64_D14_D15_D16, |
983 | | AArch64_D15_D16_D17, AArch64_D16_D17_D18, AArch64_D17_D18_D19, |
984 | | AArch64_D18_D19_D20, AArch64_D19_D20_D21, AArch64_D20_D21_D22, |
985 | | AArch64_D21_D22_D23, AArch64_D22_D23_D24, AArch64_D23_D24_D25, |
986 | | AArch64_D24_D25_D26, AArch64_D25_D26_D27, AArch64_D26_D27_D28, |
987 | | AArch64_D27_D28_D29, AArch64_D28_D29_D30, AArch64_D29_D30_D31, |
988 | | AArch64_D30_D31_D0, AArch64_D31_D0_D1 |
989 | | }; |
990 | | |
991 | | static DecodeStatus DecodeDDDRegisterClass(MCInst *Inst, unsigned RegNo, |
992 | | uint64_t Addr, const void *Decoder) |
993 | 3.10k | { |
994 | 3.10k | unsigned Register; |
995 | | |
996 | 3.10k | if (RegNo > 31) |
997 | 0 | return Fail; |
998 | | |
999 | 3.10k | Register = DDDDecoderTable[RegNo]; |
1000 | 3.10k | MCOperand_CreateReg0(Inst, Register); |
1001 | | |
1002 | 3.10k | return Success; |
1003 | 3.10k | } |
1004 | | |
1005 | | static const unsigned DDDDDecoderTable[] = { |
1006 | | AArch64_D0_D1_D2_D3, AArch64_D1_D2_D3_D4, AArch64_D2_D3_D4_D5, |
1007 | | AArch64_D3_D4_D5_D6, AArch64_D4_D5_D6_D7, AArch64_D5_D6_D7_D8, |
1008 | | AArch64_D6_D7_D8_D9, AArch64_D7_D8_D9_D10, AArch64_D8_D9_D10_D11, |
1009 | | AArch64_D9_D10_D11_D12, AArch64_D10_D11_D12_D13, AArch64_D11_D12_D13_D14, |
1010 | | AArch64_D12_D13_D14_D15, AArch64_D13_D14_D15_D16, AArch64_D14_D15_D16_D17, |
1011 | | AArch64_D15_D16_D17_D18, AArch64_D16_D17_D18_D19, AArch64_D17_D18_D19_D20, |
1012 | | AArch64_D18_D19_D20_D21, AArch64_D19_D20_D21_D22, AArch64_D20_D21_D22_D23, |
1013 | | AArch64_D21_D22_D23_D24, AArch64_D22_D23_D24_D25, AArch64_D23_D24_D25_D26, |
1014 | | AArch64_D24_D25_D26_D27, AArch64_D25_D26_D27_D28, AArch64_D26_D27_D28_D29, |
1015 | | AArch64_D27_D28_D29_D30, AArch64_D28_D29_D30_D31, AArch64_D29_D30_D31_D0, |
1016 | | AArch64_D30_D31_D0_D1, AArch64_D31_D0_D1_D2 |
1017 | | }; |
1018 | | |
1019 | | static DecodeStatus DecodeDDDDRegisterClass(MCInst *Inst, unsigned RegNo, |
1020 | | uint64_t Addr, const void *Decoder) |
1021 | 4.04k | { |
1022 | 4.04k | unsigned Register; |
1023 | | |
1024 | 4.04k | if (RegNo > 31) |
1025 | 0 | return Fail; |
1026 | | |
1027 | 4.04k | Register = DDDDDecoderTable[RegNo]; |
1028 | 4.04k | MCOperand_CreateReg0(Inst, Register); |
1029 | | |
1030 | 4.04k | return Success; |
1031 | 4.04k | } |
1032 | | |
1033 | | static DecodeStatus DecodeFixedPointScaleImm32(MCInst *Inst, unsigned Imm, |
1034 | | uint64_t Addr, const void *Decoder) |
1035 | 283 | { |
1036 | | // scale{5} is asserted as 1 in tblgen. |
1037 | 283 | Imm |= 0x20; |
1038 | 283 | MCOperand_CreateImm0(Inst, 64 - Imm); |
1039 | | |
1040 | 283 | return Success; |
1041 | 283 | } |
1042 | | |
1043 | | static DecodeStatus DecodeFixedPointScaleImm64(MCInst *Inst, unsigned Imm, |
1044 | | uint64_t Addr, const void *Decoder) |
1045 | 371 | { |
1046 | 371 | MCOperand_CreateImm0(Inst, 64 - Imm); |
1047 | | |
1048 | 371 | return Success; |
1049 | 371 | } |
1050 | | |
1051 | | static DecodeStatus DecodePCRelLabel19(MCInst *Inst, unsigned Imm, |
1052 | | uint64_t Addr, const void *Decoder) |
1053 | 10.3k | { |
1054 | 10.3k | int64_t ImmVal = Imm; |
1055 | | |
1056 | | // Sign-extend 19-bit immediate. |
1057 | 10.3k | if (ImmVal & (1 << (19 - 1))) |
1058 | 4.43k | ImmVal |= ~((1LL << 19) - 1); |
1059 | | |
1060 | 10.3k | MCOperand_CreateImm0(Inst, ImmVal); |
1061 | | |
1062 | 10.3k | return Success; |
1063 | 10.3k | } |
1064 | | |
1065 | | static DecodeStatus DecodeMemExtend(MCInst *Inst, unsigned Imm, |
1066 | | uint64_t Address, const void *Decoder) |
1067 | 7.62k | { |
1068 | 7.62k | MCOperand_CreateImm0(Inst, (Imm >> 1) & 1); |
1069 | 7.62k | MCOperand_CreateImm0(Inst, Imm & 1); |
1070 | | |
1071 | 7.62k | return Success; |
1072 | 7.62k | } |
1073 | | |
1074 | | static DecodeStatus DecodeMRSSystemRegister(MCInst *Inst, unsigned Imm, |
1075 | | uint64_t Address, const void *Decoder) |
1076 | 2.75k | { |
1077 | 2.75k | MCOperand_CreateImm0(Inst, Imm); |
1078 | | |
1079 | | // Every system register in the encoding space is valid with the syntax |
1080 | | // S<op0>_<op1>_<Cn>_<Cm>_<op2>, so decoding system registers always succeeds. |
1081 | 2.75k | return Success; |
1082 | 2.75k | } |
1083 | | |
1084 | | static DecodeStatus DecodeMSRSystemRegister(MCInst *Inst, unsigned Imm, |
1085 | | uint64_t Address, const void *Decoder) |
1086 | 4.23k | { |
1087 | 4.23k | MCOperand_CreateImm0(Inst, Imm); |
1088 | | |
1089 | 4.23k | return Success; |
1090 | 4.23k | } |
1091 | | |
1092 | | static DecodeStatus DecodeFMOVLaneInstruction(MCInst *Inst, unsigned Insn, |
1093 | | uint64_t Address, const void *Decoder) |
1094 | 469 | { |
1095 | | // This decoder exists to add the dummy Lane operand to the MCInst, which must |
1096 | | // be 1 in assembly but has no other real manifestation. |
1097 | 469 | unsigned Rd = fieldFromInstruction_4(Insn, 0, 5); |
1098 | 469 | unsigned Rn = fieldFromInstruction_4(Insn, 5, 5); |
1099 | 469 | unsigned IsToVec = fieldFromInstruction_4(Insn, 16, 1); |
1100 | | |
1101 | 469 | if (IsToVec) { |
1102 | 286 | DecodeFPR128RegisterClass(Inst, Rd, Address, Decoder); |
1103 | 286 | DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder); |
1104 | 286 | } else { |
1105 | 183 | DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder); |
1106 | 183 | DecodeFPR128RegisterClass(Inst, Rn, Address, Decoder); |
1107 | 183 | } |
1108 | | |
1109 | | // Add the lane |
1110 | 469 | MCOperand_CreateImm0(Inst, 1); |
1111 | | |
1112 | 469 | return Success; |
1113 | 469 | } |
1114 | | |
1115 | | static DecodeStatus DecodeVecShiftRImm(MCInst *Inst, unsigned Imm, |
1116 | | unsigned Add) |
1117 | 5.36k | { |
1118 | 5.36k | MCOperand_CreateImm0(Inst, Add - Imm); |
1119 | | |
1120 | 5.36k | return Success; |
1121 | 5.36k | } |
1122 | | |
1123 | | static DecodeStatus DecodeVecShiftLImm(MCInst *Inst, unsigned Imm, |
1124 | | unsigned Add) |
1125 | 7.09k | { |
1126 | 7.09k | MCOperand_CreateImm0(Inst, (Imm + Add) & (Add - 1)); |
1127 | | |
1128 | 7.09k | return Success; |
1129 | 7.09k | } |
1130 | | |
1131 | | static DecodeStatus DecodeVecShiftR64Imm(MCInst *Inst, unsigned Imm, |
1132 | | uint64_t Addr, const void *Decoder) |
1133 | 547 | { |
1134 | 547 | return DecodeVecShiftRImm(Inst, Imm, 64); |
1135 | 547 | } |
1136 | | |
1137 | | static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst *Inst, unsigned Imm, |
1138 | | uint64_t Addr, const void *Decoder) |
1139 | 612 | { |
1140 | 612 | return DecodeVecShiftRImm(Inst, Imm | 0x20, 64); |
1141 | 612 | } |
1142 | | |
1143 | | static DecodeStatus DecodeVecShiftR32Imm(MCInst *Inst, unsigned Imm, |
1144 | | uint64_t Addr, const void *Decoder) |
1145 | 1.32k | { |
1146 | 1.32k | return DecodeVecShiftRImm(Inst, Imm, 32); |
1147 | 1.32k | } |
1148 | | |
1149 | | static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst *Inst, unsigned Imm, |
1150 | | uint64_t Addr, const void *Decoder) |
1151 | 56 | { |
1152 | 56 | return DecodeVecShiftRImm(Inst, Imm | 0x10, 32); |
1153 | 56 | } |
1154 | | |
1155 | | static DecodeStatus DecodeVecShiftR16Imm(MCInst *Inst, unsigned Imm, |
1156 | | uint64_t Addr, const void *Decoder) |
1157 | 1.46k | { |
1158 | 1.46k | return DecodeVecShiftRImm(Inst, Imm, 16); |
1159 | 1.46k | } |
1160 | | |
1161 | | static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst *Inst, unsigned Imm, |
1162 | | uint64_t Addr, const void *Decoder) |
1163 | 109 | { |
1164 | 109 | return DecodeVecShiftRImm(Inst, Imm | 0x8, 16); |
1165 | 109 | } |
1166 | | |
1167 | | static DecodeStatus DecodeVecShiftR8Imm(MCInst *Inst, unsigned Imm, |
1168 | | uint64_t Addr, const void *Decoder) |
1169 | 1.25k | { |
1170 | 1.25k | return DecodeVecShiftRImm(Inst, Imm, 8); |
1171 | 1.25k | } |
1172 | | |
1173 | | static DecodeStatus DecodeVecShiftL64Imm(MCInst *Inst, unsigned Imm, |
1174 | | uint64_t Addr, const void *Decoder) |
1175 | 832 | { |
1176 | 832 | return DecodeVecShiftLImm(Inst, Imm, 64); |
1177 | 832 | } |
1178 | | |
1179 | | static DecodeStatus DecodeVecShiftL32Imm(MCInst *Inst, unsigned Imm, |
1180 | | uint64_t Addr, const void *Decoder) |
1181 | 1.53k | { |
1182 | 1.53k | return DecodeVecShiftLImm(Inst, Imm, 32); |
1183 | 1.53k | } |
1184 | | |
1185 | | static DecodeStatus DecodeVecShiftL16Imm(MCInst *Inst, unsigned Imm, |
1186 | | uint64_t Addr, const void *Decoder) |
1187 | 2.08k | { |
1188 | 2.08k | return DecodeVecShiftLImm(Inst, Imm, 16); |
1189 | 2.08k | } |
1190 | | |
1191 | | static DecodeStatus DecodeVecShiftL8Imm(MCInst *Inst, unsigned Imm, |
1192 | | uint64_t Addr, const void *Decoder) |
1193 | 2.64k | { |
1194 | 2.64k | return DecodeVecShiftLImm(Inst, Imm, 8); |
1195 | 2.64k | } |
1196 | | |
1197 | | static DecodeStatus DecodeThreeAddrSRegInstruction(MCInst *Inst, |
1198 | | uint32_t insn, uint64_t Addr, const void *Decoder) |
1199 | 11.1k | { |
1200 | 11.1k | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
1201 | 11.1k | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
1202 | 11.1k | unsigned Rm = fieldFromInstruction_4(insn, 16, 5); |
1203 | 11.1k | unsigned shiftHi = fieldFromInstruction_4(insn, 22, 2); |
1204 | 11.1k | unsigned shiftLo = fieldFromInstruction_4(insn, 10, 6); |
1205 | 11.1k | unsigned shift = (shiftHi << 6) | shiftLo; |
1206 | | |
1207 | 11.1k | switch (MCInst_getOpcode(Inst)) { |
1208 | 0 | default: |
1209 | 0 | return Fail; |
1210 | | |
1211 | 320 | case AArch64_ADDWrs: |
1212 | 535 | case AArch64_ADDSWrs: |
1213 | 1.40k | case AArch64_SUBWrs: |
1214 | 1.50k | case AArch64_SUBSWrs: |
1215 | | // if shift == '11' then ReservedValue() |
1216 | 1.50k | if (shiftHi == 0x3) |
1217 | 6 | return Fail; |
1218 | | // Deliberate fallthrough |
1219 | | |
1220 | 2.13k | case AArch64_ANDWrs: |
1221 | 2.40k | case AArch64_ANDSWrs: |
1222 | 2.49k | case AArch64_BICWrs: |
1223 | 3.00k | case AArch64_BICSWrs: |
1224 | 3.28k | case AArch64_ORRWrs: |
1225 | 3.91k | case AArch64_ORNWrs: |
1226 | 4.49k | case AArch64_EORWrs: |
1227 | 4.68k | case AArch64_EONWrs: { |
1228 | | // if sf == '0' and imm6<5> == '1' then ReservedValue() |
1229 | 4.68k | if (shiftLo >> 5 == 1) |
1230 | 32 | return Fail; |
1231 | | |
1232 | 4.65k | DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
1233 | 4.65k | DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder); |
1234 | 4.65k | DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
1235 | 4.65k | break; |
1236 | 4.68k | } |
1237 | | |
1238 | 466 | case AArch64_ADDXrs: |
1239 | 655 | case AArch64_ADDSXrs: |
1240 | 818 | case AArch64_SUBXrs: |
1241 | 1.18k | case AArch64_SUBSXrs: |
1242 | | // if shift == '11' then ReservedValue() |
1243 | 1.18k | if (shiftHi == 0x3) |
1244 | 10 | return Fail; |
1245 | | // Deliberate fallthrough |
1246 | | |
1247 | 1.91k | case AArch64_ANDXrs: |
1248 | 2.48k | case AArch64_ANDSXrs: |
1249 | 2.88k | case AArch64_BICXrs: |
1250 | 3.89k | case AArch64_BICSXrs: |
1251 | 4.17k | case AArch64_ORRXrs: |
1252 | 5.12k | case AArch64_ORNXrs: |
1253 | 6.11k | case AArch64_EORXrs: |
1254 | 6.44k | case AArch64_EONXrs: |
1255 | 6.44k | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1256 | 6.44k | DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder); |
1257 | 6.44k | DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder); |
1258 | 6.44k | break; |
1259 | 11.1k | } |
1260 | | |
1261 | 11.1k | MCOperand_CreateImm0(Inst, shift); |
1262 | | |
1263 | 11.1k | return Success; |
1264 | 11.1k | } |
1265 | | |
1266 | | static DecodeStatus DecodeMoveImmInstruction(MCInst *Inst, uint32_t insn, |
1267 | | uint64_t Addr, const void *Decoder) |
1268 | 4.51k | { |
1269 | 4.51k | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
1270 | 4.51k | unsigned imm = fieldFromInstruction_4(insn, 5, 16); |
1271 | 4.51k | unsigned shift = fieldFromInstruction_4(insn, 21, 2); |
1272 | | |
1273 | 4.51k | shift <<= 4; |
1274 | | |
1275 | 4.51k | switch (MCInst_getOpcode(Inst)) { |
1276 | 0 | default: |
1277 | 0 | return Fail; |
1278 | | |
1279 | 119 | case AArch64_MOVZWi: |
1280 | 555 | case AArch64_MOVNWi: |
1281 | 661 | case AArch64_MOVKWi: |
1282 | 661 | if (shift & (1U << 5)) |
1283 | 12 | return Fail; |
1284 | 649 | DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
1285 | 649 | break; |
1286 | | |
1287 | 1.02k | case AArch64_MOVZXi: |
1288 | 2.49k | case AArch64_MOVNXi: |
1289 | 3.85k | case AArch64_MOVKXi: |
1290 | 3.85k | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1291 | 3.85k | break; |
1292 | 4.51k | } |
1293 | | |
1294 | 4.50k | if (MCInst_getOpcode(Inst) == AArch64_MOVKWi || |
1295 | 4.50k | MCInst_getOpcode(Inst) == AArch64_MOVKXi) |
1296 | 1.45k | MCInst_addOperand2(Inst, MCInst_getOperand(Inst, 0)); |
1297 | | |
1298 | 4.50k | MCOperand_CreateImm0(Inst, imm); |
1299 | 4.50k | MCOperand_CreateImm0(Inst, shift); |
1300 | | |
1301 | 4.50k | return Success; |
1302 | 4.51k | } |
1303 | | |
1304 | | static DecodeStatus DecodeUnsignedLdStInstruction(MCInst *Inst, |
1305 | | uint32_t insn, uint64_t Addr, const void *Decoder) |
1306 | 11.0k | { |
1307 | 11.0k | unsigned Rt = fieldFromInstruction_4(insn, 0, 5); |
1308 | 11.0k | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
1309 | 11.0k | unsigned offset = fieldFromInstruction_4(insn, 10, 12); |
1310 | | |
1311 | 11.0k | switch (MCInst_getOpcode(Inst)) { |
1312 | 0 | default: |
1313 | 0 | return Fail; |
1314 | | |
1315 | 185 | case AArch64_PRFMui: |
1316 | | // Rt is an immediate in prefetch. |
1317 | 185 | MCOperand_CreateImm0(Inst, Rt); |
1318 | 185 | break; |
1319 | | |
1320 | 1.14k | case AArch64_STRBBui: |
1321 | 1.57k | case AArch64_LDRBBui: |
1322 | 1.99k | case AArch64_LDRSBWui: |
1323 | 2.61k | case AArch64_STRHHui: |
1324 | 3.61k | case AArch64_LDRHHui: |
1325 | 3.73k | case AArch64_LDRSHWui: |
1326 | 3.83k | case AArch64_STRWui: |
1327 | 3.99k | case AArch64_LDRWui: |
1328 | 3.99k | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1329 | 3.99k | break; |
1330 | | |
1331 | 97 | case AArch64_LDRSBXui: |
1332 | 368 | case AArch64_LDRSHXui: |
1333 | 948 | case AArch64_LDRSWui: |
1334 | 1.47k | case AArch64_STRXui: |
1335 | 1.91k | case AArch64_LDRXui: |
1336 | 1.91k | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1337 | 1.91k | break; |
1338 | | |
1339 | 511 | case AArch64_LDRQui: |
1340 | 869 | case AArch64_STRQui: |
1341 | 869 | DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder); |
1342 | 869 | break; |
1343 | | |
1344 | 89 | case AArch64_LDRDui: |
1345 | 368 | case AArch64_STRDui: |
1346 | 368 | DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1347 | 368 | break; |
1348 | | |
1349 | 240 | case AArch64_LDRSui: |
1350 | 517 | case AArch64_STRSui: |
1351 | 517 | DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1352 | 517 | break; |
1353 | | |
1354 | 322 | case AArch64_LDRHui: |
1355 | 536 | case AArch64_STRHui: |
1356 | 536 | DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder); |
1357 | 536 | break; |
1358 | | |
1359 | 790 | case AArch64_LDRBui: |
1360 | 2.71k | case AArch64_STRBui: |
1361 | 2.71k | DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder); |
1362 | 2.71k | break; |
1363 | 11.0k | } |
1364 | | |
1365 | 11.0k | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1366 | | |
1367 | | //if (!Dis->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 4)) |
1368 | 11.0k | MCOperand_CreateImm0(Inst, offset); |
1369 | | |
1370 | 11.0k | return Success; |
1371 | 11.0k | } |
1372 | | |
1373 | | static DecodeStatus DecodeSignedLdStInstruction(MCInst *Inst, |
1374 | | uint32_t insn, uint64_t Addr, const void *Decoder) |
1375 | 8.70k | { |
1376 | 8.70k | bool IsLoad, IsIndexed, IsFP; |
1377 | 8.70k | unsigned Rt = fieldFromInstruction_4(insn, 0, 5); |
1378 | 8.70k | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
1379 | 8.70k | int64_t offset = fieldFromInstruction_4(insn, 12, 9); |
1380 | | |
1381 | | // offset is a 9-bit signed immediate, so sign extend it to |
1382 | | // fill the unsigned. |
1383 | 8.70k | if (offset & (1 << (9 - 1))) |
1384 | 5.00k | offset |= ~((1LL << 9) - 1); |
1385 | | |
1386 | | // First operand is always the writeback to the address register, if needed. |
1387 | 8.70k | switch (MCInst_getOpcode(Inst)) { |
1388 | 5.30k | default: |
1389 | 5.30k | break; |
1390 | | |
1391 | 5.30k | case AArch64_LDRSBWpre: |
1392 | 384 | case AArch64_LDRSHWpre: |
1393 | 455 | case AArch64_STRBBpre: |
1394 | 642 | case AArch64_LDRBBpre: |
1395 | 813 | case AArch64_STRHHpre: |
1396 | 872 | case AArch64_LDRHHpre: |
1397 | 966 | case AArch64_STRWpre: |
1398 | 999 | case AArch64_LDRWpre: |
1399 | 1.04k | case AArch64_LDRSBWpost: |
1400 | 1.10k | case AArch64_LDRSHWpost: |
1401 | 1.11k | case AArch64_STRBBpost: |
1402 | 1.20k | case AArch64_LDRBBpost: |
1403 | 1.47k | case AArch64_STRHHpost: |
1404 | 1.64k | case AArch64_LDRHHpost: |
1405 | 1.69k | case AArch64_STRWpost: |
1406 | 1.70k | case AArch64_LDRWpost: |
1407 | 1.72k | case AArch64_LDRSBXpre: |
1408 | 1.75k | case AArch64_LDRSHXpre: |
1409 | 1.81k | case AArch64_STRXpre: |
1410 | 1.86k | case AArch64_LDRSWpre: |
1411 | 1.98k | case AArch64_LDRXpre: |
1412 | 2.17k | case AArch64_LDRSBXpost: |
1413 | 2.22k | case AArch64_LDRSHXpost: |
1414 | 2.25k | case AArch64_STRXpost: |
1415 | 2.26k | case AArch64_LDRSWpost: |
1416 | 2.47k | case AArch64_LDRXpost: |
1417 | 2.53k | case AArch64_LDRQpre: |
1418 | 2.55k | case AArch64_STRQpre: |
1419 | 2.59k | case AArch64_LDRQpost: |
1420 | 2.64k | case AArch64_STRQpost: |
1421 | 2.72k | case AArch64_LDRDpre: |
1422 | 2.80k | case AArch64_STRDpre: |
1423 | 2.84k | case AArch64_LDRDpost: |
1424 | 2.87k | case AArch64_STRDpost: |
1425 | 2.89k | case AArch64_LDRSpre: |
1426 | 2.93k | case AArch64_STRSpre: |
1427 | 2.96k | case AArch64_LDRSpost: |
1428 | 2.97k | case AArch64_STRSpost: |
1429 | 3.02k | case AArch64_LDRHpre: |
1430 | 3.05k | case AArch64_STRHpre: |
1431 | 3.09k | case AArch64_LDRHpost: |
1432 | 3.15k | case AArch64_STRHpost: |
1433 | 3.19k | case AArch64_LDRBpre: |
1434 | 3.31k | case AArch64_STRBpre: |
1435 | 3.37k | case AArch64_LDRBpost: |
1436 | 3.39k | case AArch64_STRBpost: |
1437 | 3.39k | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1438 | 3.39k | break; |
1439 | 8.70k | } |
1440 | | |
1441 | 8.70k | switch (MCInst_getOpcode(Inst)) { |
1442 | 0 | default: |
1443 | 0 | return Fail; |
1444 | | |
1445 | 57 | case AArch64_PRFUMi: |
1446 | | // Rt is an immediate in prefetch. |
1447 | 57 | MCOperand_CreateImm0(Inst, Rt); |
1448 | 57 | break; |
1449 | | |
1450 | 115 | case AArch64_STURBBi: |
1451 | 193 | case AArch64_LDURBBi: |
1452 | 381 | case AArch64_LDURSBWi: |
1453 | 814 | case AArch64_STURHHi: |
1454 | 1.04k | case AArch64_LDURHHi: |
1455 | 1.31k | case AArch64_LDURSHWi: |
1456 | 1.51k | case AArch64_STURWi: |
1457 | 1.52k | case AArch64_LDURWi: |
1458 | 1.55k | case AArch64_LDTRSBWi: |
1459 | 1.65k | case AArch64_LDTRSHWi: |
1460 | 1.75k | case AArch64_STTRWi: |
1461 | 1.77k | case AArch64_LDTRWi: |
1462 | 2.06k | case AArch64_STTRHi: |
1463 | 2.38k | case AArch64_LDTRHi: |
1464 | 2.48k | case AArch64_LDTRBi: |
1465 | 2.55k | case AArch64_STTRBi: |
1466 | 2.69k | case AArch64_LDRSBWpre: |
1467 | 2.93k | case AArch64_LDRSHWpre: |
1468 | 3.00k | case AArch64_STRBBpre: |
1469 | 3.19k | case AArch64_LDRBBpre: |
1470 | 3.36k | case AArch64_STRHHpre: |
1471 | 3.42k | case AArch64_LDRHHpre: |
1472 | 3.51k | case AArch64_STRWpre: |
1473 | 3.55k | case AArch64_LDRWpre: |
1474 | 3.59k | case AArch64_LDRSBWpost: |
1475 | 3.65k | case AArch64_LDRSHWpost: |
1476 | 3.66k | case AArch64_STRBBpost: |
1477 | 3.75k | case AArch64_LDRBBpost: |
1478 | 4.02k | case AArch64_STRHHpost: |
1479 | 4.19k | case AArch64_LDRHHpost: |
1480 | 4.24k | case AArch64_STRWpost: |
1481 | 4.25k | case AArch64_LDRWpost: |
1482 | 4.26k | case AArch64_STLURBi: |
1483 | 4.33k | case AArch64_STLURHi: |
1484 | 4.39k | case AArch64_STLURWi: |
1485 | 4.45k | case AArch64_LDAPURBi: |
1486 | 4.51k | case AArch64_LDAPURSBWi: |
1487 | 4.54k | case AArch64_LDAPURHi: |
1488 | 4.71k | case AArch64_LDAPURSHWi: |
1489 | 4.75k | case AArch64_LDAPURi: |
1490 | 4.75k | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1491 | 4.75k | break; |
1492 | | |
1493 | 38 | case AArch64_LDURSBXi: |
1494 | 148 | case AArch64_LDURSHXi: |
1495 | 160 | case AArch64_LDURSWi: |
1496 | 427 | case AArch64_STURXi: |
1497 | 461 | case AArch64_LDURXi: |
1498 | 642 | case AArch64_LDTRSBXi: |
1499 | 728 | case AArch64_LDTRSHXi: |
1500 | 783 | case AArch64_LDTRSWi: |
1501 | 948 | case AArch64_STTRXi: |
1502 | 1.10k | case AArch64_LDTRXi: |
1503 | 1.12k | case AArch64_LDRSBXpre: |
1504 | 1.14k | case AArch64_LDRSHXpre: |
1505 | 1.20k | case AArch64_STRXpre: |
1506 | 1.25k | case AArch64_LDRSWpre: |
1507 | 1.37k | case AArch64_LDRXpre: |
1508 | 1.56k | case AArch64_LDRSBXpost: |
1509 | 1.61k | case AArch64_LDRSHXpost: |
1510 | 1.64k | case AArch64_STRXpost: |
1511 | 1.65k | case AArch64_LDRSWpost: |
1512 | 1.86k | case AArch64_LDRXpost: |
1513 | 1.88k | case AArch64_LDAPURSWi: |
1514 | 1.90k | case AArch64_LDAPURSHXi: |
1515 | 2.05k | case AArch64_LDAPURSBXi: |
1516 | 2.13k | case AArch64_STLURXi: |
1517 | 2.17k | case AArch64_LDAPURXi: |
1518 | 2.17k | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1519 | 2.17k | break; |
1520 | | |
1521 | 30 | case AArch64_LDURQi: |
1522 | 57 | case AArch64_STURQi: |
1523 | 124 | case AArch64_LDRQpre: |
1524 | 143 | case AArch64_STRQpre: |
1525 | 182 | case AArch64_LDRQpost: |
1526 | 228 | case AArch64_STRQpost: |
1527 | 228 | DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder); |
1528 | 228 | break; |
1529 | | |
1530 | 25 | case AArch64_LDURDi: |
1531 | 232 | case AArch64_STURDi: |
1532 | 313 | case AArch64_LDRDpre: |
1533 | 394 | case AArch64_STRDpre: |
1534 | 430 | case AArch64_LDRDpost: |
1535 | 462 | case AArch64_STRDpost: |
1536 | 462 | DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1537 | 462 | break; |
1538 | | |
1539 | 174 | case AArch64_LDURSi: |
1540 | 218 | case AArch64_STURSi: |
1541 | 236 | case AArch64_LDRSpre: |
1542 | 283 | case AArch64_STRSpre: |
1543 | 313 | case AArch64_LDRSpost: |
1544 | 324 | case AArch64_STRSpost: |
1545 | 324 | DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1546 | 324 | break; |
1547 | | |
1548 | 42 | case AArch64_LDURHi: |
1549 | 82 | case AArch64_STURHi: |
1550 | 129 | case AArch64_LDRHpre: |
1551 | 156 | case AArch64_STRHpre: |
1552 | 194 | case AArch64_LDRHpost: |
1553 | 256 | case AArch64_STRHpost: |
1554 | 256 | DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder); |
1555 | 256 | break; |
1556 | | |
1557 | 178 | case AArch64_LDURBi: |
1558 | 197 | case AArch64_STURBi: |
1559 | 234 | case AArch64_LDRBpre: |
1560 | 362 | case AArch64_STRBpre: |
1561 | 415 | case AArch64_LDRBpost: |
1562 | 442 | case AArch64_STRBpost: |
1563 | 442 | DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder); |
1564 | 442 | break; |
1565 | 8.70k | } |
1566 | | |
1567 | 8.70k | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1568 | 8.70k | MCOperand_CreateImm0(Inst, offset); |
1569 | | |
1570 | 8.70k | IsLoad = fieldFromInstruction_4(insn, 22, 1) != 0; |
1571 | 8.70k | IsIndexed = fieldFromInstruction_4(insn, 10, 2) != 0; |
1572 | 8.70k | IsFP = fieldFromInstruction_4(insn, 26, 1) != 0; |
1573 | | |
1574 | | // Cannot write back to a transfer register (but xzr != sp). |
1575 | 8.70k | if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn) |
1576 | 2 | return SoftFail; |
1577 | | |
1578 | 8.69k | return Success; |
1579 | 8.70k | } |
1580 | | |
1581 | | static DecodeStatus DecodeExclusiveLdStInstruction(MCInst *Inst, |
1582 | | uint32_t insn, uint64_t Addr, const void *Decoder) |
1583 | 11.7k | { |
1584 | 11.7k | unsigned Rt = fieldFromInstruction_4(insn, 0, 5); |
1585 | 11.7k | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
1586 | 11.7k | unsigned Rt2 = fieldFromInstruction_4(insn, 10, 5); |
1587 | 11.7k | unsigned Rs = fieldFromInstruction_4(insn, 16, 5); |
1588 | 11.7k | unsigned Opcode = MCInst_getOpcode(Inst); |
1589 | | |
1590 | 11.7k | switch (Opcode) { |
1591 | 0 | default: |
1592 | 0 | return Fail; |
1593 | | |
1594 | 116 | case AArch64_STLXRW: |
1595 | 709 | case AArch64_STLXRB: |
1596 | 1.01k | case AArch64_STLXRH: |
1597 | 1.14k | case AArch64_STXRW: |
1598 | 2.41k | case AArch64_STXRB: |
1599 | 2.52k | case AArch64_STXRH: |
1600 | 2.52k | DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); |
1601 | | // FALLTHROUGH |
1602 | 2.69k | case AArch64_LDARW: |
1603 | 2.85k | case AArch64_LDARB: |
1604 | 2.94k | case AArch64_LDARH: |
1605 | 3.21k | case AArch64_LDAXRW: |
1606 | 3.26k | case AArch64_LDAXRB: |
1607 | 3.43k | case AArch64_LDAXRH: |
1608 | 4.23k | case AArch64_LDXRW: |
1609 | 4.26k | case AArch64_LDXRB: |
1610 | 4.54k | case AArch64_LDXRH: |
1611 | 5.16k | case AArch64_STLRW: |
1612 | 5.22k | case AArch64_STLRB: |
1613 | 5.32k | case AArch64_STLRH: |
1614 | 5.42k | case AArch64_STLLRW: |
1615 | 5.54k | case AArch64_STLLRB: |
1616 | 5.65k | case AArch64_STLLRH: |
1617 | 5.78k | case AArch64_LDLARW: |
1618 | 5.96k | case AArch64_LDLARB: |
1619 | 6.06k | case AArch64_LDLARH: |
1620 | 6.06k | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1621 | 6.06k | break; |
1622 | | |
1623 | 229 | case AArch64_STLXRX: |
1624 | 334 | case AArch64_STXRX: |
1625 | 334 | DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); |
1626 | | // FALLTHROUGH |
1627 | 1.51k | case AArch64_LDARX: |
1628 | 2.01k | case AArch64_LDAXRX: |
1629 | 2.47k | case AArch64_LDXRX: |
1630 | 3.35k | case AArch64_STLRX: |
1631 | 3.51k | case AArch64_LDLARX: |
1632 | 3.52k | case AArch64_STLLRX: |
1633 | 3.52k | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1634 | 3.52k | break; |
1635 | | |
1636 | 160 | case AArch64_STLXPW: |
1637 | 442 | case AArch64_STXPW: |
1638 | 442 | DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); |
1639 | | // FALLTHROUGH |
1640 | 666 | case AArch64_LDAXPW: |
1641 | 770 | case AArch64_LDXPW: |
1642 | 770 | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1643 | 770 | DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder); |
1644 | 770 | break; |
1645 | | |
1646 | 736 | case AArch64_STLXPX: |
1647 | 916 | case AArch64_STXPX: |
1648 | 916 | DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); |
1649 | | // FALLTHROUGH |
1650 | 1.07k | case AArch64_LDAXPX: |
1651 | 1.40k | case AArch64_LDXPX: |
1652 | 1.40k | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1653 | 1.40k | DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder); |
1654 | 1.40k | break; |
1655 | 11.7k | } |
1656 | | |
1657 | 11.7k | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1658 | | |
1659 | | // You shouldn't load to the same register twice in an instruction... |
1660 | 11.7k | if ((Opcode == AArch64_LDAXPW || Opcode == AArch64_LDXPW || |
1661 | 11.7k | Opcode == AArch64_LDAXPX || Opcode == AArch64_LDXPX) && |
1662 | 11.7k | Rt == Rt2) |
1663 | 38 | return SoftFail; |
1664 | | |
1665 | 11.7k | return Success; |
1666 | 11.7k | } |
1667 | | |
1668 | | static DecodeStatus DecodePairLdStInstruction(MCInst *Inst, uint32_t insn, |
1669 | | uint64_t Addr, const void *Decoder) |
1670 | 10.2k | { |
1671 | 10.2k | unsigned Rt = fieldFromInstruction_4(insn, 0, 5); |
1672 | 10.2k | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
1673 | 10.2k | unsigned Rt2 = fieldFromInstruction_4(insn, 10, 5); |
1674 | 10.2k | int32_t offset = fieldFromInstruction_4(insn, 15, 7); |
1675 | 10.2k | bool IsLoad = fieldFromInstruction_4(insn, 22, 1) != 0; |
1676 | 10.2k | unsigned Opcode = MCInst_getOpcode(Inst); |
1677 | 10.2k | bool NeedsDisjointWritebackTransfer = false; |
1678 | | |
1679 | | // offset is a 7-bit signed immediate, so sign extend it to |
1680 | | // fill the unsigned. |
1681 | 10.2k | if (offset & (1 << (7 - 1))) |
1682 | 6.19k | offset |= ~((1LL << 7) - 1); |
1683 | | |
1684 | | // First operand is always writeback of base register. |
1685 | 10.2k | switch (Opcode) { |
1686 | 5.98k | default: |
1687 | 5.98k | break; |
1688 | | |
1689 | 5.98k | case AArch64_LDPXpost: |
1690 | 574 | case AArch64_STPXpost: |
1691 | 634 | case AArch64_LDPSWpost: |
1692 | 877 | case AArch64_LDPXpre: |
1693 | 1.37k | case AArch64_STPXpre: |
1694 | 1.41k | case AArch64_LDPSWpre: |
1695 | 1.51k | case AArch64_LDPWpost: |
1696 | 1.73k | case AArch64_STPWpost: |
1697 | 1.81k | case AArch64_LDPWpre: |
1698 | 1.99k | case AArch64_STPWpre: |
1699 | 2.13k | case AArch64_LDPQpost: |
1700 | 2.67k | case AArch64_STPQpost: |
1701 | 2.73k | case AArch64_LDPQpre: |
1702 | 3.19k | case AArch64_STPQpre: |
1703 | 3.23k | case AArch64_LDPDpost: |
1704 | 3.52k | case AArch64_STPDpost: |
1705 | 3.64k | case AArch64_LDPDpre: |
1706 | 3.72k | case AArch64_STPDpre: |
1707 | 3.79k | case AArch64_LDPSpost: |
1708 | 3.84k | case AArch64_STPSpost: |
1709 | 4.05k | case AArch64_LDPSpre: |
1710 | 4.22k | case AArch64_STPSpre: |
1711 | 4.22k | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1712 | 4.22k | break; |
1713 | 10.2k | } |
1714 | | |
1715 | 10.2k | switch (Opcode) { |
1716 | 6 | default: |
1717 | 6 | return Fail; |
1718 | | |
1719 | 95 | case AArch64_LDPXpost: |
1720 | 574 | case AArch64_STPXpost: |
1721 | 634 | case AArch64_LDPSWpost: |
1722 | 877 | case AArch64_LDPXpre: |
1723 | 1.37k | case AArch64_STPXpre: |
1724 | 1.41k | case AArch64_LDPSWpre: |
1725 | 1.41k | NeedsDisjointWritebackTransfer = true; |
1726 | | // Fallthrough |
1727 | 1.52k | case AArch64_LDNPXi: |
1728 | 1.59k | case AArch64_STNPXi: |
1729 | 2.16k | case AArch64_LDPXi: |
1730 | 2.51k | case AArch64_STPXi: |
1731 | 2.98k | case AArch64_LDPSWi: |
1732 | 2.98k | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1733 | 2.98k | DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder); |
1734 | 2.98k | break; |
1735 | | |
1736 | 97 | case AArch64_LDPWpost: |
1737 | 316 | case AArch64_STPWpost: |
1738 | 399 | case AArch64_LDPWpre: |
1739 | 577 | case AArch64_STPWpre: |
1740 | 577 | NeedsDisjointWritebackTransfer = true; |
1741 | | // Fallthrough |
1742 | 824 | case AArch64_LDNPWi: |
1743 | 1.06k | case AArch64_STNPWi: |
1744 | 1.15k | case AArch64_LDPWi: |
1745 | 1.66k | case AArch64_STPWi: |
1746 | 1.66k | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1747 | 1.66k | DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder); |
1748 | 1.66k | break; |
1749 | | |
1750 | 93 | case AArch64_LDNPQi: |
1751 | 173 | case AArch64_STNPQi: |
1752 | 313 | case AArch64_LDPQpost: |
1753 | 856 | case AArch64_STPQpost: |
1754 | 1.04k | case AArch64_LDPQi: |
1755 | 1.46k | case AArch64_STPQi: |
1756 | 1.52k | case AArch64_LDPQpre: |
1757 | 1.98k | case AArch64_STPQpre: |
1758 | 1.98k | DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder); |
1759 | 1.98k | DecodeFPR128RegisterClass(Inst, Rt2, Addr, Decoder); |
1760 | 1.98k | break; |
1761 | | |
1762 | 502 | case AArch64_LDNPDi: |
1763 | 634 | case AArch64_STNPDi: |
1764 | 673 | case AArch64_LDPDpost: |
1765 | 966 | case AArch64_STPDpost: |
1766 | 1.67k | case AArch64_LDPDi: |
1767 | 1.98k | case AArch64_STPDi: |
1768 | 2.10k | case AArch64_LDPDpre: |
1769 | 2.18k | case AArch64_STPDpre: |
1770 | 2.18k | DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1771 | 2.18k | DecodeFPR64RegisterClass(Inst, Rt2, Addr, Decoder); |
1772 | 2.18k | break; |
1773 | | |
1774 | 51 | case AArch64_LDNPSi: |
1775 | 422 | case AArch64_STNPSi: |
1776 | 493 | case AArch64_LDPSpost: |
1777 | 536 | case AArch64_STPSpost: |
1778 | 689 | case AArch64_LDPSi: |
1779 | 996 | case AArch64_STPSi: |
1780 | 1.20k | case AArch64_LDPSpre: |
1781 | 1.37k | case AArch64_STPSpre: |
1782 | 1.37k | DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1783 | 1.37k | DecodeFPR32RegisterClass(Inst, Rt2, Addr, Decoder); |
1784 | 1.37k | break; |
1785 | 10.2k | } |
1786 | | |
1787 | 10.2k | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1788 | 10.2k | MCOperand_CreateImm0(Inst, offset); |
1789 | | |
1790 | | // You shouldn't load to the same register twice in an instruction... |
1791 | 10.2k | if (IsLoad && Rt == Rt2) |
1792 | 4 | return SoftFail; |
1793 | | |
1794 | | // ... or do any operation that writes-back to a transfer register. But note |
1795 | | // that "stp xzr, xzr, [sp], #4" is fine because xzr and sp are different. |
1796 | 10.1k | if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn)) |
1797 | 4 | return SoftFail; |
1798 | | |
1799 | 10.1k | return Success; |
1800 | 10.1k | } |
1801 | | |
1802 | | static DecodeStatus DecodeAuthLoadInstruction(MCInst *Inst, uint32_t insn, |
1803 | | uint64_t Addr, const void *Decoder) |
1804 | 1.90k | { |
1805 | 1.90k | unsigned Rt = fieldFromInstruction_4(insn, 0, 5); |
1806 | 1.90k | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
1807 | 1.90k | uint64_t offset = fieldFromInstruction_4(insn, 22, 1) << 9 | |
1808 | 1.90k | fieldFromInstruction_4(insn, 12, 9); |
1809 | 1.90k | unsigned writeback = fieldFromInstruction_4(insn, 11, 1); |
1810 | | |
1811 | 1.90k | switch (MCInst_getOpcode(Inst)) { |
1812 | 0 | default: |
1813 | 0 | return Fail; |
1814 | 340 | case AArch64_LDRAAwriteback: |
1815 | 1.19k | case AArch64_LDRABwriteback: |
1816 | 1.19k | DecodeGPR64spRegisterClass(Inst, Rn /* writeback register */, Addr, |
1817 | 1.19k | Decoder); |
1818 | 1.19k | break; |
1819 | 325 | case AArch64_LDRAAindexed: |
1820 | 716 | case AArch64_LDRABindexed: |
1821 | 716 | break; |
1822 | 1.90k | } |
1823 | | |
1824 | 1.90k | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1825 | 1.90k | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1826 | 1.90k | DecodeSImm(Inst, offset, Addr, Decoder, 10); |
1827 | | |
1828 | 1.90k | if (writeback && Rt == Rn && Rn != 31) { |
1829 | 63 | return SoftFail; |
1830 | 63 | } |
1831 | | |
1832 | 1.84k | return Success; |
1833 | 1.90k | } |
1834 | | |
1835 | | static DecodeStatus DecodeAddSubERegInstruction(MCInst *Inst, |
1836 | | uint32_t insn, uint64_t Addr, const void *Decoder) |
1837 | 3.94k | { |
1838 | 3.94k | unsigned Rd, Rn, Rm; |
1839 | 3.94k | unsigned extend = fieldFromInstruction_4(insn, 10, 6); |
1840 | 3.94k | unsigned shift = extend & 0x7; |
1841 | | |
1842 | 3.94k | if (shift > 4) |
1843 | 7 | return Fail; |
1844 | | |
1845 | 3.93k | Rd = fieldFromInstruction_4(insn, 0, 5); |
1846 | 3.93k | Rn = fieldFromInstruction_4(insn, 5, 5); |
1847 | 3.93k | Rm = fieldFromInstruction_4(insn, 16, 5); |
1848 | | |
1849 | 3.93k | switch (MCInst_getOpcode(Inst)) { |
1850 | 0 | default: |
1851 | 0 | return Fail; |
1852 | | |
1853 | 514 | case AArch64_ADDWrx: |
1854 | 693 | case AArch64_SUBWrx: |
1855 | 693 | DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder); |
1856 | 693 | DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder); |
1857 | 693 | DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
1858 | 693 | break; |
1859 | | |
1860 | 947 | case AArch64_ADDSWrx: |
1861 | 1.05k | case AArch64_SUBSWrx: |
1862 | 1.05k | DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
1863 | 1.05k | DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder); |
1864 | 1.05k | DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
1865 | 1.05k | break; |
1866 | | |
1867 | 254 | case AArch64_ADDXrx: |
1868 | 523 | case AArch64_SUBXrx: |
1869 | 523 | DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); |
1870 | 523 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1871 | 523 | DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
1872 | 523 | break; |
1873 | | |
1874 | 563 | case AArch64_ADDSXrx: |
1875 | 628 | case AArch64_SUBSXrx: |
1876 | 628 | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1877 | 628 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1878 | 628 | DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
1879 | 628 | break; |
1880 | | |
1881 | 462 | case AArch64_ADDXrx64: |
1882 | 525 | case AArch64_SUBXrx64: |
1883 | 525 | DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); |
1884 | 525 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1885 | 525 | DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder); |
1886 | 525 | break; |
1887 | | |
1888 | 229 | case AArch64_SUBSXrx64: |
1889 | 516 | case AArch64_ADDSXrx64: |
1890 | 516 | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1891 | 516 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1892 | 516 | DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder); |
1893 | 516 | break; |
1894 | 3.93k | } |
1895 | | |
1896 | 3.93k | MCOperand_CreateImm0(Inst, extend); |
1897 | | |
1898 | 3.93k | return Success; |
1899 | 3.93k | } |
1900 | | |
1901 | | static DecodeStatus DecodeLogicalImmInstruction(MCInst *Inst, |
1902 | | uint32_t insn, uint64_t Addr, const void *Decoder) |
1903 | 5.42k | { |
1904 | 5.42k | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
1905 | 5.42k | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
1906 | 5.42k | unsigned Datasize = fieldFromInstruction_4(insn, 31, 1); |
1907 | 5.42k | unsigned imm; |
1908 | | |
1909 | 5.42k | if (Datasize) { |
1910 | 3.18k | if (MCInst_getOpcode(Inst) == AArch64_ANDSXri) |
1911 | 763 | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1912 | 2.42k | else |
1913 | 2.42k | DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); |
1914 | | |
1915 | 3.18k | DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder); |
1916 | | |
1917 | 3.18k | imm = fieldFromInstruction_4(insn, 10, 13); |
1918 | 3.18k | if (!AArch64_AM_isValidDecodeLogicalImmediate(imm, 64)) |
1919 | 6 | return Fail; |
1920 | 3.18k | } else { |
1921 | 2.24k | if (MCInst_getOpcode(Inst) == AArch64_ANDSWri) |
1922 | 517 | DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
1923 | 1.72k | else |
1924 | 1.72k | DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder); |
1925 | | |
1926 | 2.24k | DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder); |
1927 | | |
1928 | 2.24k | imm = fieldFromInstruction_4(insn, 10, 12); |
1929 | 2.24k | if (!AArch64_AM_isValidDecodeLogicalImmediate(imm, 32)) |
1930 | 8 | return Fail; |
1931 | 2.24k | } |
1932 | | |
1933 | 5.41k | MCOperand_CreateImm0(Inst, imm); |
1934 | | |
1935 | 5.41k | return Success; |
1936 | 5.42k | } |
1937 | | |
1938 | | static DecodeStatus DecodeModImmInstruction(MCInst *Inst, uint32_t insn, |
1939 | | uint64_t Addr, const void *Decoder) |
1940 | 3.65k | { |
1941 | 3.65k | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
1942 | 3.65k | unsigned cmode = fieldFromInstruction_4(insn, 12, 4); |
1943 | 3.65k | unsigned imm = fieldFromInstruction_4(insn, 16, 3) << 5; |
1944 | 3.65k | imm |= fieldFromInstruction_4(insn, 5, 5); |
1945 | | |
1946 | 3.65k | if (MCInst_getOpcode(Inst) == AArch64_MOVID) |
1947 | 656 | DecodeFPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1948 | 2.99k | else |
1949 | 2.99k | DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder); |
1950 | | |
1951 | 3.65k | MCOperand_CreateImm0(Inst, imm); |
1952 | | |
1953 | 3.65k | switch (MCInst_getOpcode(Inst)) { |
1954 | 1.70k | default: |
1955 | 1.70k | break; |
1956 | | |
1957 | 1.70k | case AArch64_MOVIv4i16: |
1958 | 197 | case AArch64_MOVIv8i16: |
1959 | 273 | case AArch64_MVNIv4i16: |
1960 | 304 | case AArch64_MVNIv8i16: |
1961 | 542 | case AArch64_MOVIv2i32: |
1962 | 952 | case AArch64_MOVIv4i32: |
1963 | 1.01k | case AArch64_MVNIv2i32: |
1964 | 1.35k | case AArch64_MVNIv4i32: |
1965 | 1.35k | MCOperand_CreateImm0(Inst, (cmode & 6) << 2); |
1966 | 1.35k | break; |
1967 | | |
1968 | 164 | case AArch64_MOVIv2s_msl: |
1969 | 351 | case AArch64_MOVIv4s_msl: |
1970 | 412 | case AArch64_MVNIv2s_msl: |
1971 | 589 | case AArch64_MVNIv4s_msl: |
1972 | 589 | MCOperand_CreateImm0(Inst, cmode & 1 ? 0x110 : 0x108); |
1973 | 589 | break; |
1974 | 3.65k | } |
1975 | | |
1976 | 3.65k | return Success; |
1977 | 3.65k | } |
1978 | | |
1979 | | static DecodeStatus DecodeModImmTiedInstruction(MCInst *Inst, |
1980 | | uint32_t insn, uint64_t Addr, const void *Decoder) |
1981 | 117 | { |
1982 | 117 | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
1983 | 117 | unsigned cmode = fieldFromInstruction_4(insn, 12, 4); |
1984 | 117 | unsigned imm = fieldFromInstruction_4(insn, 16, 3) << 5; |
1985 | 117 | imm |= fieldFromInstruction_4(insn, 5, 5); |
1986 | | |
1987 | | // Tied operands added twice. |
1988 | 117 | DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder); |
1989 | 117 | DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder); |
1990 | | |
1991 | 117 | MCOperand_CreateImm0(Inst, imm); |
1992 | 117 | MCOperand_CreateImm0(Inst, (cmode & 6) << 2); |
1993 | | |
1994 | 117 | return Success; |
1995 | 117 | } |
1996 | | |
1997 | | static DecodeStatus DecodeAdrInstruction(MCInst *Inst, uint32_t insn, |
1998 | | uint64_t Addr, const void *Decoder) |
1999 | 7.18k | { |
2000 | 7.18k | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
2001 | 7.18k | int64_t imm = fieldFromInstruction_4(insn, 5, 19) << 2; |
2002 | 7.18k | imm |= fieldFromInstruction_4(insn, 29, 2); |
2003 | | |
2004 | | // Sign-extend the 21-bit immediate. |
2005 | 7.18k | if (imm & (1 << (21 - 1))) |
2006 | 2.82k | imm |= ~((1LL << 21) - 1); |
2007 | | |
2008 | 7.18k | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
2009 | | //if (!Dis->tryAddingSymbolicOperand(Inst, imm, Addr, Fail, 0, 4)) |
2010 | 7.18k | MCOperand_CreateImm0(Inst, imm); |
2011 | | |
2012 | 7.18k | return Success; |
2013 | 7.18k | } |
2014 | | |
2015 | | static DecodeStatus DecodeAddSubImmShift(MCInst *Inst, uint32_t insn, |
2016 | | uint64_t Addr, const void *Decoder) |
2017 | 4.28k | { |
2018 | 4.28k | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
2019 | 4.28k | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
2020 | 4.28k | unsigned Imm = fieldFromInstruction_4(insn, 10, 14); |
2021 | 4.28k | unsigned S = fieldFromInstruction_4(insn, 29, 1); |
2022 | 4.28k | unsigned Datasize = fieldFromInstruction_4(insn, 31, 1); |
2023 | | |
2024 | 4.28k | unsigned ShifterVal = (Imm >> 12) & 3; |
2025 | 4.28k | unsigned ImmVal = Imm & 0xFFF; |
2026 | | // const AArch64Disassembler *Dis = |
2027 | | // static_cast<const AArch64Disassembler *>(Decoder); |
2028 | | |
2029 | 4.28k | if (ShifterVal != 0 && ShifterVal != 1) |
2030 | 30 | return Fail; |
2031 | | |
2032 | 4.25k | if (Datasize) { |
2033 | 1.18k | if (Rd == 31 && !S) |
2034 | 284 | DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); |
2035 | 904 | else |
2036 | 904 | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
2037 | 1.18k | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
2038 | 3.06k | } else { |
2039 | 3.06k | if (Rd == 31 && !S) |
2040 | 394 | DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder); |
2041 | 2.66k | else |
2042 | 2.66k | DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
2043 | 3.06k | DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder); |
2044 | 3.06k | } |
2045 | | |
2046 | | // if (!Dis->tryAddingSymbolicOperand(Inst, Imm, Addr, Fail, 0, 4)) |
2047 | 4.25k | MCOperand_CreateImm0(Inst, ImmVal); |
2048 | | |
2049 | 4.25k | MCOperand_CreateImm0(Inst, (12 * ShifterVal)); |
2050 | 4.25k | return Success; |
2051 | 4.28k | } |
2052 | | |
2053 | | static DecodeStatus DecodeUnconditionalBranch(MCInst *Inst, uint32_t insn, |
2054 | | uint64_t Addr, const void *Decoder) |
2055 | 4.09k | { |
2056 | 4.09k | int64_t imm = fieldFromInstruction_4(insn, 0, 26); |
2057 | | |
2058 | | // Sign-extend the 26-bit immediate. |
2059 | 4.09k | if (imm & (1 << (26 - 1))) |
2060 | 2.05k | imm |= ~((1LL << 26) - 1); |
2061 | | |
2062 | | // if (!Dis->tryAddingSymbolicOperand(Inst, imm << 2, Addr, true, 0, 4)) |
2063 | 4.09k | MCOperand_CreateImm0(Inst, imm); |
2064 | | |
2065 | 4.09k | return Success; |
2066 | 4.09k | } |
2067 | | |
2068 | | static DecodeStatus DecodeSystemPStateInstruction(MCInst *Inst, |
2069 | | uint32_t insn, uint64_t Addr, const void *Decoder) |
2070 | 576 | { |
2071 | 576 | uint32_t op1 = fieldFromInstruction_4(insn, 16, 3); |
2072 | 576 | uint32_t op2 = fieldFromInstruction_4(insn, 5, 3); |
2073 | 576 | uint32_t crm = fieldFromInstruction_4(insn, 8, 4); |
2074 | 576 | uint32_t pstate_field = (op1 << 3) | op2; |
2075 | | |
2076 | 576 | if ((pstate_field == AArch64PState_PAN || |
2077 | 576 | pstate_field == AArch64PState_UAO) && crm > 1) |
2078 | 204 | return Fail; |
2079 | | |
2080 | 372 | MCOperand_CreateImm0(Inst, pstate_field); |
2081 | 372 | MCOperand_CreateImm0(Inst, crm); |
2082 | | |
2083 | 372 | if (lookupPStateByEncoding(pstate_field)) |
2084 | 346 | return Success; |
2085 | | |
2086 | 26 | return Fail; |
2087 | 372 | } |
2088 | | |
2089 | | static DecodeStatus DecodeTestAndBranch(MCInst *Inst, uint32_t insn, |
2090 | | uint64_t Addr, const void *Decoder) |
2091 | 3.14k | { |
2092 | 3.14k | uint32_t Rt = fieldFromInstruction_4(insn, 0, 5); |
2093 | 3.14k | uint32_t bit = fieldFromInstruction_4(insn, 31, 1) << 5; |
2094 | 3.14k | uint64_t dst = fieldFromInstruction_4(insn, 5, 14); |
2095 | | |
2096 | 3.14k | bit |= fieldFromInstruction_4(insn, 19, 5); |
2097 | | |
2098 | | // Sign-extend 14-bit immediate. |
2099 | 3.14k | if (dst & (1 << (14 - 1))) |
2100 | 2.08k | dst |= ~((1LL << 14) - 1); |
2101 | | |
2102 | 3.14k | if (fieldFromInstruction_4(insn, 31, 1) == 0) |
2103 | 2.02k | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
2104 | 1.11k | else |
2105 | 1.11k | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
2106 | | |
2107 | 3.14k | MCOperand_CreateImm0(Inst, bit); |
2108 | | |
2109 | | //if (!Dis->tryAddingSymbolicOperand(Inst, dst << 2, Addr, true, 0, 4)) |
2110 | 3.14k | MCOperand_CreateImm0(Inst, dst); |
2111 | | |
2112 | 3.14k | return Success; |
2113 | 3.14k | } |
2114 | | |
2115 | | static DecodeStatus DecodeGPRSeqPairsClassRegisterClass(MCInst *Inst, |
2116 | | unsigned RegClassID, unsigned RegNo, uint64_t Addr, const void *Decoder) |
2117 | 4.34k | { |
2118 | 4.34k | unsigned Register; |
2119 | | |
2120 | | // Register number must be even (see CASP instruction) |
2121 | 4.34k | if (RegNo & 0x1) |
2122 | 14 | return Fail; |
2123 | | |
2124 | 4.33k | Register = AArch64MCRegisterClasses[RegClassID].RegsBegin[RegNo / 2]; |
2125 | 4.33k | MCOperand_CreateReg0(Inst, Register); |
2126 | | |
2127 | 4.33k | return Success; |
2128 | 4.34k | } |
2129 | | |
2130 | | static DecodeStatus DecodeWSeqPairsClassRegisterClass(MCInst *Inst, |
2131 | | unsigned RegNo, uint64_t Addr, const void *Decoder) |
2132 | 767 | { |
2133 | 767 | return DecodeGPRSeqPairsClassRegisterClass(Inst, |
2134 | 767 | AArch64_WSeqPairsClassRegClassID, RegNo, Addr, Decoder); |
2135 | 767 | } |
2136 | | |
2137 | | static DecodeStatus DecodeXSeqPairsClassRegisterClass(MCInst *Inst, |
2138 | | unsigned RegNo, uint64_t Addr, const void *Decoder) |
2139 | 3.57k | { |
2140 | 3.57k | return DecodeGPRSeqPairsClassRegisterClass(Inst, |
2141 | 3.57k | AArch64_XSeqPairsClassRegClassID, RegNo, Addr, Decoder); |
2142 | 3.57k | } |
2143 | | |
2144 | | static DecodeStatus DecodeSVELogicalImmInstruction(MCInst *Inst, uint32_t insn, |
2145 | | uint64_t Addr, const void *Decoder) |
2146 | 8.49k | { |
2147 | 8.49k | unsigned Zdn = fieldFromInstruction_4(insn, 0, 5); |
2148 | 8.49k | unsigned imm = fieldFromInstruction_4(insn, 5, 13); |
2149 | | |
2150 | 8.49k | if (!AArch64_AM_isValidDecodeLogicalImmediate(imm, 64)) |
2151 | 5 | return Fail; |
2152 | | |
2153 | | // The same (tied) operand is added twice to the instruction. |
2154 | 8.48k | DecodeZPRRegisterClass(Inst, Zdn, Addr, Decoder); |
2155 | 8.48k | if (MCInst_getOpcode(Inst) != AArch64_DUPM_ZI) |
2156 | 1.07k | DecodeZPRRegisterClass(Inst, Zdn, Addr, Decoder); |
2157 | | |
2158 | 8.48k | MCOperand_CreateImm0(Inst, imm); |
2159 | | |
2160 | 8.48k | return Success; |
2161 | 8.49k | } |
2162 | | |
2163 | | static DecodeStatus DecodeSImm(MCInst *Inst, uint64_t Imm, uint64_t Address, |
2164 | | const void *Decoder, int Bits) |
2165 | 12.5k | { |
2166 | 12.5k | if (Imm & ~((1LL << Bits) - 1)) |
2167 | 0 | return Fail; |
2168 | | |
2169 | | // Imm is a signed immediate, so sign extend it. |
2170 | 12.5k | if (Imm & (1 << (Bits - 1))) |
2171 | 6.51k | Imm |= ~((1LL << Bits) - 1); |
2172 | | |
2173 | 12.5k | MCOperand_CreateImm0(Inst, Imm); |
2174 | | |
2175 | 12.5k | return Success; |
2176 | 12.5k | } |
2177 | | |
2178 | | // Decode 8-bit signed/unsigned immediate for a given element width. |
2179 | | static DecodeStatus DecodeImm8OptLsl(MCInst *Inst, unsigned Imm, uint64_t Addr, |
2180 | | const void *Decoder, int ElementWidth) |
2181 | 2.08k | { |
2182 | 2.08k | unsigned Val = (uint8_t)Imm; |
2183 | 2.08k | unsigned Shift = (Imm & 0x100) ? 8 : 0; |
2184 | | |
2185 | 2.08k | if (ElementWidth == 8 && Shift) |
2186 | 5 | return Fail; |
2187 | | |
2188 | 2.07k | MCOperand_CreateImm0(Inst, Val); |
2189 | 2.07k | MCOperand_CreateImm0(Inst, Shift); |
2190 | | |
2191 | 2.07k | return Success; |
2192 | 2.08k | } |
2193 | | |
2194 | | // Decode uimm4 ranged from 1-16. |
2195 | | static DecodeStatus DecodeSVEIncDecImm(MCInst *Inst, unsigned Imm, |
2196 | | uint64_t Addr, const void *Decoder) |
2197 | 4.88k | { |
2198 | 4.88k | MCOperand_CreateImm0(Inst, Imm + 1); |
2199 | | |
2200 | 4.88k | return Success; |
2201 | 4.88k | } |
2202 | | |
2203 | | static DecodeStatus DecodeSVCROp(MCInst *Inst, unsigned Imm, uint64_t Address, |
2204 | 1.18k | const void *Decoder) { |
2205 | 1.18k | if (lookupSVCRByEncoding(Imm)) { |
2206 | 240 | MCOperand_CreateImm0(Inst, Imm); |
2207 | 240 | return Success; |
2208 | 240 | } |
2209 | 948 | return Fail; |
2210 | 1.18k | } |
2211 | | |
2212 | | static DecodeStatus DecodeCPYMemOpInstruction(MCInst *Inst, uint32_t insn, |
2213 | 540 | uint64_t Addr, const void *Decoder) { |
2214 | 540 | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
2215 | 540 | unsigned Rs = fieldFromInstruction_4(insn, 16, 5); |
2216 | 540 | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
2217 | | |
2218 | | // None of the registers may alias: if they do, then the instruction is not |
2219 | | // merely unpredictable but actually entirely unallocated. |
2220 | 540 | if (Rd == Rs || Rs == Rn || Rd == Rn) |
2221 | 7 | return Fail; |
2222 | | |
2223 | | // All three register operands are written back, so they all appear |
2224 | | // twice in the operand list, once as outputs and once as inputs. |
2225 | 533 | if (!DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) || |
2226 | 533 | !DecodeGPR64commonRegisterClass(Inst, Rs, Addr, Decoder) || |
2227 | 533 | !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) || |
2228 | 533 | !DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) || |
2229 | 533 | !DecodeGPR64commonRegisterClass(Inst, Rs, Addr, Decoder) || |
2230 | 533 | !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder)) |
2231 | 4 | return Fail; |
2232 | | |
2233 | 529 | return Success; |
2234 | 533 | } |
2235 | | |
2236 | | static DecodeStatus DecodeSETMemOpInstruction(MCInst *Inst, uint32_t insn, |
2237 | 237 | uint64_t Addr, const void *Decoder) { |
2238 | 237 | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
2239 | 237 | unsigned Rm = fieldFromInstruction_4(insn, 16, 5); |
2240 | 237 | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
2241 | | |
2242 | | // None of the registers may alias: if they do, then the instruction is not |
2243 | | // merely unpredictable but actually entirely unallocated. |
2244 | 237 | if (Rd == Rm || Rm == Rn || Rd == Rn) |
2245 | 6 | return Fail; |
2246 | | |
2247 | | // Rd and Rn (not Rm) register operands are written back, so they appear |
2248 | | // twice in the operand list, once as outputs and once as inputs. |
2249 | 231 | if (!DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) || |
2250 | 231 | !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) || |
2251 | 231 | !DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) || |
2252 | 231 | !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) || |
2253 | 231 | !DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder)) |
2254 | 3 | return Fail; |
2255 | | |
2256 | 228 | return Success; |
2257 | 231 | } |
2258 | | |
2259 | | void AArch64_init(MCRegisterInfo *MRI) |
2260 | 8.12k | { |
2261 | | /* |
2262 | | InitMCRegisterInfo(AArch64RegDesc, 661, |
2263 | | RA, PC, |
2264 | | AArch64MCRegisterClasses, 100, |
2265 | | AArch64RegUnitRoots, 115, AArch64RegDiffLists, |
2266 | | AArch64LaneMaskLists, AArch64RegStrings, AArch64RegClassStrings, |
2267 | | AArch64SubRegIdxLists, 100, |
2268 | | AArch64SubRegIdxRanges, AArch64RegEncodingTable); |
2269 | | */ |
2270 | | |
2271 | 8.12k | MCRegisterInfo_InitMCRegisterInfo(MRI, AArch64RegDesc, 674, |
2272 | 8.12k | 0, 0, |
2273 | 8.12k | AArch64MCRegisterClasses, 202, |
2274 | 8.12k | 0, 0, AArch64RegDiffLists, |
2275 | 8.12k | 0, |
2276 | 8.12k | AArch64SubRegIdxLists, 100, |
2277 | 8.12k | 0); |
2278 | 8.12k | } |
2279 | | |
2280 | | #endif |