/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 | 692k | { |
188 | 692k | switch (In) { |
189 | 0 | default: // never reach |
190 | 0 | return true; |
191 | | |
192 | 690k | case MCDisassembler_Success: |
193 | | // Out stays the same. |
194 | 690k | return true; |
195 | | |
196 | 18 | case MCDisassembler_SoftFail: |
197 | 18 | *Out = In; |
198 | 18 | return true; |
199 | | |
200 | 1.73k | case MCDisassembler_Fail: |
201 | 1.73k | *Out = In; |
202 | 1.73k | return false; |
203 | 692k | } |
204 | | // llvm_unreachable("Invalid DecodeStatus!"); |
205 | 692k | } |
206 | | |
207 | | // Hacky: enable all features for disassembler |
208 | | uint64_t AArch64_getFeatureBits(int feature) |
209 | 182k | { |
210 | | // enable all features |
211 | 182k | return (uint64_t)-1; |
212 | 182k | } |
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 | 887k | #define Success MCDisassembler_Success |
227 | 1.73k | #define Fail MCDisassembler_Fail |
228 | 18 | #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 | 290k | { |
235 | 290k | uint32_t insn; |
236 | 290k | DecodeStatus result; |
237 | 290k | size_t i; |
238 | | |
239 | 290k | if (code_len < 4) { |
240 | | // not enough data |
241 | 3.43k | *Size = 0; |
242 | 3.43k | return MCDisassembler_Fail; |
243 | 3.43k | } |
244 | | |
245 | 287k | if (MI->flat_insn->detail) { |
246 | 287k | memset(MI->flat_insn->detail, 0, offsetof(cs_detail, arm64)+sizeof(cs_arm64)); |
247 | 2.58M | for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm64.operands); i++) |
248 | 2.29M | MI->flat_insn->detail->arm64.operands[i].vector_index = -1; |
249 | 287k | } |
250 | | |
251 | 287k | 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 | 287k | else |
255 | 287k | insn = ((uint32_t) code[3] << 24) | (code[2] << 16) | |
256 | 287k | (code[1] << 8) | (code[0] << 0); |
257 | | |
258 | | // Calling the auto-generated decoder function. |
259 | 287k | result = decodeInstruction_4(DecoderTable32, MI, insn, Address); |
260 | | // If Decoding fails initially, try Fallback table. |
261 | 287k | if(result == MCDisassembler_Fail){ |
262 | 7.83k | result = decodeInstruction_4(DecoderTableFallback32, MI, insn, Address); |
263 | 7.83k | } |
264 | | |
265 | | // Init new MCOperand to be used in switch below. |
266 | | // Kind RegVal set inside a case when needed. |
267 | 287k | MCOperand op_storage; |
268 | 287k | MCOperand *Op = &op_storage; |
269 | 287k | switch (MCInst_getOpcode(MI)) { |
270 | 284k | default: |
271 | 284k | 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 | 284k | case AArch64_LDR_ZA: |
276 | 109 | case AArch64_STR_ZA: { |
277 | 109 | Op->Kind = kRegister; |
278 | 109 | Op->RegVal = AArch64_ZA; |
279 | 109 | 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 | 109 | MCOperand *Imm4Op = MCInst_getOperand(MI, 2); |
284 | | // assert(MCOperand_isImm(Imm4Op) && "Unexpected operand type!"); |
285 | 109 | MCInst_addOperand2(MI, Imm4Op); |
286 | 109 | break; |
287 | 99 | } |
288 | 126 | case AArch64_LD1_MXIPXX_H_B: |
289 | 212 | case AArch64_LD1_MXIPXX_V_B: |
290 | 329 | case AArch64_ST1_MXIPXX_H_B: |
291 | 409 | case AArch64_ST1_MXIPXX_V_B: |
292 | 543 | case AArch64_INSERT_MXIPZ_H_B: |
293 | 580 | 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 | 580 | Op->Kind = kRegister; |
298 | 580 | Op->RegVal = AArch64_ZAB0; |
299 | 580 | MCInst_insert0(MI, 0, Op); |
300 | 580 | break; |
301 | 269 | case AArch64_EXTRACT_ZPMXI_H_B: |
302 | 565 | 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 | 565 | Op->Kind = kRegister; |
306 | 565 | Op->RegVal = AArch64_ZAB0; |
307 | 565 | MCInst_insert0(MI, 2, Op); |
308 | 565 | break; |
309 | 164 | case AArch64_LD1_MXIPXX_H_Q: |
310 | 273 | case AArch64_LD1_MXIPXX_V_Q: |
311 | 333 | case AArch64_ST1_MXIPXX_H_Q: |
312 | 705 | case AArch64_ST1_MXIPXX_V_Q: |
313 | | // 128-bit load/store have implicit zero vector index. |
314 | 705 | Op->Kind = kImmediate; |
315 | 705 | Op->ImmVal = 0; |
316 | 705 | MCInst_insert0(MI, 2, Op); |
317 | 705 | break; |
318 | | // 128-bit mova have implicit zero vector index. |
319 | 39 | case AArch64_INSERT_MXIPZ_H_Q: |
320 | 73 | case AArch64_INSERT_MXIPZ_V_Q: |
321 | 73 | Op->Kind = kImmediate; |
322 | 73 | Op->ImmVal = 0; |
323 | 73 | MCInst_insert0(MI, 2, Op); |
324 | 73 | break; |
325 | 18 | case AArch64_EXTRACT_ZPMXI_H_Q: |
326 | 52 | case AArch64_EXTRACT_ZPMXI_V_Q: |
327 | 52 | Op->Kind = kImmediate; |
328 | 52 | Op->ImmVal = 0; |
329 | 52 | MCInst_addOperand2(MI, Op); |
330 | 52 | break; |
331 | 35 | case AArch64_SMOVvi8to32_idx0: |
332 | 72 | case AArch64_SMOVvi8to64_idx0: |
333 | 87 | case AArch64_SMOVvi16to32_idx0: |
334 | 105 | case AArch64_SMOVvi16to64_idx0: |
335 | 139 | case AArch64_SMOVvi32to64_idx0: |
336 | 149 | case AArch64_UMOVvi8_idx0: |
337 | 167 | case AArch64_UMOVvi16_idx0: |
338 | 195 | case AArch64_UMOVvi32_idx0: |
339 | 274 | case AArch64_UMOVvi64_idx0: |
340 | 274 | Op->Kind = kImmediate; |
341 | 274 | Op->ImmVal = 0; |
342 | 274 | MCInst_addOperand2(MI, Op); |
343 | 274 | break; |
344 | 287k | } |
345 | | |
346 | 287k | if (result != MCDisassembler_Fail) { |
347 | 285k | *Size = 4; |
348 | | |
349 | 285k | return result; |
350 | 285k | } |
351 | | |
352 | | // invalid code |
353 | 2.28k | MCInst_clear(MI); |
354 | 2.28k | *Size = 0; |
355 | | |
356 | 2.28k | return MCDisassembler_Fail; |
357 | 287k | } |
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 | 290k | { |
362 | 290k | DecodeStatus status = _getInstruction((cs_struct *)ud, instr, |
363 | 290k | code, code_len, |
364 | 290k | size, |
365 | 290k | address, (MCRegisterInfo *)info); |
366 | | |
367 | 290k | return status == MCDisassembler_Success; |
368 | 290k | } |
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 | 50.7k | { |
383 | 50.7k | unsigned Register; |
384 | | |
385 | 50.7k | if (RegNo > 31) |
386 | 0 | return Fail; |
387 | | |
388 | 50.7k | Register = FPR128DecoderTable[RegNo]; |
389 | 50.7k | MCOperand_CreateReg0(Inst, Register); |
390 | | |
391 | 50.7k | return Success; |
392 | 50.7k | } |
393 | | |
394 | | static DecodeStatus DecodeFPR128_loRegisterClass(MCInst *Inst, unsigned RegNo, |
395 | | uint64_t Addr, const void *Decoder) |
396 | 1.12k | { |
397 | 1.12k | if (RegNo > 15) |
398 | 0 | return Fail; |
399 | | |
400 | 1.12k | return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder); |
401 | 1.12k | } |
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 | 32.0k | { |
416 | 32.0k | unsigned Register; |
417 | | |
418 | 32.0k | if (RegNo > 31) |
419 | 0 | return Fail; |
420 | | |
421 | 32.0k | Register = FPR64DecoderTable[RegNo]; |
422 | 32.0k | MCOperand_CreateReg0(Inst, Register); |
423 | | |
424 | 32.0k | return Success; |
425 | 32.0k | } |
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 | 12.9k | { |
440 | 12.9k | unsigned Register; |
441 | | |
442 | 12.9k | if (RegNo > 31) |
443 | 0 | return Fail; |
444 | | |
445 | 12.9k | Register = FPR32DecoderTable[RegNo]; |
446 | 12.9k | MCOperand_CreateReg0(Inst, Register); |
447 | | |
448 | 12.9k | return Success; |
449 | 12.9k | } |
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 | 6.87k | { |
464 | 6.87k | unsigned Register; |
465 | | |
466 | 6.87k | if (RegNo > 31) |
467 | 0 | return Fail; |
468 | | |
469 | 6.87k | Register = FPR16DecoderTable[RegNo]; |
470 | 6.87k | MCOperand_CreateReg0(Inst, Register); |
471 | | |
472 | 6.87k | return Success; |
473 | 6.87k | } |
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 | 5.56k | { |
488 | 5.56k | unsigned Register; |
489 | | |
490 | 5.56k | if (RegNo > 31) |
491 | 0 | return Fail; |
492 | | |
493 | 5.56k | Register = FPR8DecoderTable[RegNo]; |
494 | 5.56k | MCOperand_CreateReg0(Inst, Register); |
495 | | |
496 | 5.56k | return Success; |
497 | 5.56k | } |
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 | 4.23k | { |
512 | 4.23k | unsigned Register; |
513 | | |
514 | 4.23k | if (RegNo > 30) |
515 | 10 | return Fail; |
516 | | |
517 | 4.22k | Register = GPR64DecoderTable[RegNo]; |
518 | 4.22k | MCOperand_CreateReg0(Inst, Register); |
519 | | |
520 | 4.22k | return Success; |
521 | 4.23k | } |
522 | | |
523 | | static DecodeStatus DecodeGPR64RegisterClass(MCInst *Inst, unsigned RegNo, |
524 | | uint64_t Addr, const void *Decoder) |
525 | 143k | { |
526 | 143k | unsigned Register; |
527 | | |
528 | 143k | if (RegNo > 31) |
529 | 0 | return Fail; |
530 | | |
531 | 143k | Register = GPR64DecoderTable[RegNo]; |
532 | 143k | MCOperand_CreateReg0(Inst, Register); |
533 | | |
534 | 143k | return Success; |
535 | 143k | } |
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 | 194 | { |
549 | 194 | if (RegNo > 22) |
550 | 2 | return Fail; |
551 | 192 | if (RegNo & 1) |
552 | 2 | return Fail; |
553 | | |
554 | 190 | unsigned Register = GPR64x8DecoderTable[RegNo >> 1]; |
555 | 190 | MCOperand_CreateReg0(Inst, Register); |
556 | | |
557 | 190 | return Success; |
558 | 192 | } |
559 | | |
560 | | static DecodeStatus DecodeGPR64spRegisterClass(MCInst *Inst, unsigned RegNo, |
561 | | uint64_t Addr, const void *Decoder) |
562 | 190k | { |
563 | 190k | unsigned Register; |
564 | | |
565 | 190k | if (RegNo > 31) |
566 | 0 | return Fail; |
567 | | |
568 | 190k | Register = GPR64DecoderTable[RegNo]; |
569 | 190k | if (Register == AArch64_XZR) |
570 | 44.2k | Register = AArch64_SP; |
571 | | |
572 | 190k | MCOperand_CreateReg0(Inst, Register); |
573 | | |
574 | 190k | return Success; |
575 | 190k | } |
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 | 4.58k | { |
585 | 4.58k | unsigned Register; |
586 | | |
587 | 4.58k | if (RegNo > 3) |
588 | 0 | return Fail; |
589 | | |
590 | 4.58k | Register = MatrixIndexGPR32_12_15DecoderTable[RegNo]; |
591 | 4.58k | MCOperand_CreateReg0(Inst, Register); |
592 | | |
593 | 4.58k | return Success; |
594 | 4.58k | } |
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 | 60.9k | { |
609 | 60.9k | unsigned Register; |
610 | | |
611 | 60.9k | if (RegNo > 31) |
612 | 0 | return Fail; |
613 | | |
614 | 60.9k | Register = GPR32DecoderTable[RegNo]; |
615 | 60.9k | MCOperand_CreateReg0(Inst, Register); |
616 | | |
617 | 60.9k | return Success; |
618 | 60.9k | } |
619 | | |
620 | | static DecodeStatus DecodeGPR32spRegisterClass(MCInst *Inst, unsigned RegNo, |
621 | | uint64_t Addr, const void *Decoder) |
622 | 6.29k | { |
623 | 6.29k | unsigned Register; |
624 | | |
625 | 6.29k | if (RegNo > 31) |
626 | 0 | return Fail; |
627 | | |
628 | 6.29k | Register = GPR32DecoderTable[RegNo]; |
629 | 6.29k | if (Register == AArch64_WZR) |
630 | 1.69k | Register = AArch64_WSP; |
631 | | |
632 | 6.29k | MCOperand_CreateReg0(Inst, Register); |
633 | | |
634 | 6.29k | return Success; |
635 | 6.29k | } |
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 | 114k | { |
651 | 114k | unsigned Register; |
652 | | |
653 | 114k | if (RegNo > 31) |
654 | 0 | return Fail; |
655 | | |
656 | 114k | Register = ZPRDecoderTable[RegNo]; |
657 | 114k | MCOperand_CreateReg0(Inst, Register); |
658 | | |
659 | 114k | return Success; |
660 | 114k | } |
661 | | |
662 | | static DecodeStatus DecodeZPR_4bRegisterClass(MCInst *Inst, unsigned RegNo, |
663 | | uint64_t Address, const void *Decoder) |
664 | 385 | { |
665 | 385 | if (RegNo > 15) |
666 | 0 | return Fail; |
667 | | |
668 | 385 | return DecodeZPRRegisterClass(Inst, RegNo, Address, Decoder); |
669 | 385 | } |
670 | | |
671 | | static DecodeStatus DecodeZPR_3bRegisterClass(MCInst *Inst, unsigned RegNo, |
672 | | uint64_t Address, const void *Decoder) |
673 | 939 | { |
674 | 939 | if (RegNo > 7) |
675 | 0 | return Fail; |
676 | | |
677 | 939 | return DecodeZPRRegisterClass(Inst, RegNo, Address, Decoder); |
678 | 939 | } |
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.06k | { |
694 | 2.06k | unsigned Register; |
695 | | |
696 | 2.06k | if (RegNo > 31) |
697 | 0 | return Fail; |
698 | | |
699 | 2.06k | Register = ZZDecoderTable[RegNo]; |
700 | 2.06k | MCOperand_CreateReg0(Inst, Register); |
701 | | |
702 | 2.06k | return Success; |
703 | 2.06k | } |
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 | 1.22k | { |
722 | 1.22k | unsigned Register; |
723 | | |
724 | 1.22k | if (RegNo > 31) |
725 | 0 | return Fail; |
726 | | |
727 | 1.22k | Register = ZZZDecoderTable[RegNo]; |
728 | 1.22k | MCOperand_CreateReg0(Inst, Register); |
729 | | |
730 | 1.22k | return Success; |
731 | 1.22k | } |
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 | 756 | { |
750 | 756 | unsigned Register; |
751 | | |
752 | 756 | if (RegNo > 31) |
753 | 0 | return Fail; |
754 | | |
755 | 756 | Register = ZZZZDecoderTable[RegNo]; |
756 | 756 | MCOperand_CreateReg0(Inst, Register); |
757 | | |
758 | 756 | return Success; |
759 | 756 | } |
760 | | |
761 | | static DecodeStatus DecodeMatrixTileListRegisterClass(MCInst *Inst, |
762 | 557 | unsigned RegMask, uint64_t Address, const void *Decoder) { |
763 | 557 | if (RegMask > 0xFF) |
764 | 0 | return Fail; |
765 | | |
766 | 557 | MCOperand_CreateImm0(Inst, RegMask); |
767 | 557 | return Success; |
768 | 557 | } |
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 | 4.38k | uint64_t Address, const void *Decoder, unsigned NumBitsForTile) { |
784 | 4.38k | unsigned LastReg = (1 << NumBitsForTile) - 1; |
785 | 4.38k | if (RegNo > LastReg) |
786 | 0 | return Fail; |
787 | | |
788 | | // Convert original 2D indexes into 1D table index |
789 | 4.38k | unsigned index = 0; |
790 | 4.38k | switch (NumBitsForTile) |
791 | 4.38k | { |
792 | 0 | case 0: |
793 | | // Only a single Byte tile at beginning of list so index = 0 |
794 | 0 | break; |
795 | 490 | case 1: |
796 | 490 | index = 1 + RegNo; |
797 | 490 | break; |
798 | 1.68k | case 2: |
799 | 1.68k | index = 3 + RegNo; |
800 | 1.68k | break; |
801 | 1.38k | case 3: |
802 | 1.38k | index = 7 + RegNo; |
803 | 1.38k | break; |
804 | 830 | case 4: |
805 | 830 | index = 15 + RegNo; |
806 | 830 | break; |
807 | 0 | default: |
808 | 0 | break; |
809 | 4.38k | } |
810 | | |
811 | 4.38k | MCOperand_CreateReg0(Inst, MatrixZATileDecoderTable[index]); |
812 | 4.38k | return Success; |
813 | 4.38k | } |
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 | 57.6k | { |
826 | 57.6k | unsigned Register; |
827 | | |
828 | 57.6k | if (RegNo > 15) |
829 | 0 | return Fail; |
830 | | |
831 | 57.6k | Register = PPRDecoderTable[RegNo]; |
832 | 57.6k | MCOperand_CreateReg0(Inst, Register); |
833 | | |
834 | 57.6k | return Success; |
835 | 57.6k | } |
836 | | |
837 | | static DecodeStatus DecodePPR_3bRegisterClass(MCInst *Inst, unsigned RegNo, |
838 | | uint64_t Addr, const void *Decoder) |
839 | 43.7k | { |
840 | 43.7k | if (RegNo > 7) |
841 | 0 | return Fail; |
842 | | |
843 | | // Just reuse the PPR decode table |
844 | 43.7k | return DecodePPRRegisterClass(Inst, RegNo, Addr, Decoder); |
845 | 43.7k | } |
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 | 1.19k | { |
860 | 1.19k | unsigned Register; |
861 | | |
862 | 1.19k | if (RegNo > 31) |
863 | 0 | return Fail; |
864 | | |
865 | 1.19k | Register = VectorDecoderTable[RegNo]; |
866 | 1.19k | MCOperand_CreateReg0(Inst, Register); |
867 | | |
868 | 1.19k | return Success; |
869 | 1.19k | } |
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 | 16.7k | { |
885 | 16.7k | unsigned Register; |
886 | | |
887 | 16.7k | if (RegNo > 31) |
888 | 0 | return Fail; |
889 | | |
890 | 16.7k | Register = QQDecoderTable[RegNo]; |
891 | 16.7k | MCOperand_CreateReg0(Inst, Register); |
892 | | |
893 | 16.7k | return Success; |
894 | 16.7k | } |
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 | 11.6k | { |
913 | 11.6k | unsigned Register; |
914 | | |
915 | 11.6k | if (RegNo > 31) |
916 | 0 | return Fail; |
917 | | |
918 | 11.6k | Register = QQQDecoderTable[RegNo]; |
919 | 11.6k | MCOperand_CreateReg0(Inst, Register); |
920 | | |
921 | 11.6k | return Success; |
922 | 11.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 | 14.5k | { |
941 | 14.5k | unsigned Register; |
942 | | |
943 | 14.5k | if (RegNo > 31) |
944 | 0 | return Fail; |
945 | | |
946 | 14.5k | Register = QQQQDecoderTable[RegNo]; |
947 | 14.5k | MCOperand_CreateReg0(Inst, Register); |
948 | | |
949 | 14.5k | return Success; |
950 | 14.5k | } |
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.26k | { |
966 | 2.26k | unsigned Register; |
967 | | |
968 | 2.26k | if (RegNo > 31) |
969 | 0 | return Fail; |
970 | | |
971 | 2.26k | Register = DDDecoderTable[RegNo]; |
972 | 2.26k | MCOperand_CreateReg0(Inst, Register); |
973 | | |
974 | 2.26k | return Success; |
975 | 2.26k | } |
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.05k | { |
994 | 3.05k | unsigned Register; |
995 | | |
996 | 3.05k | if (RegNo > 31) |
997 | 0 | return Fail; |
998 | | |
999 | 3.05k | Register = DDDDecoderTable[RegNo]; |
1000 | 3.05k | MCOperand_CreateReg0(Inst, Register); |
1001 | | |
1002 | 3.05k | return Success; |
1003 | 3.05k | } |
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 | 3.45k | { |
1022 | 3.45k | unsigned Register; |
1023 | | |
1024 | 3.45k | if (RegNo > 31) |
1025 | 0 | return Fail; |
1026 | | |
1027 | 3.45k | Register = DDDDDecoderTable[RegNo]; |
1028 | 3.45k | MCOperand_CreateReg0(Inst, Register); |
1029 | | |
1030 | 3.45k | return Success; |
1031 | 3.45k | } |
1032 | | |
1033 | | static DecodeStatus DecodeFixedPointScaleImm32(MCInst *Inst, unsigned Imm, |
1034 | | uint64_t Addr, const void *Decoder) |
1035 | 192 | { |
1036 | | // scale{5} is asserted as 1 in tblgen. |
1037 | 192 | Imm |= 0x20; |
1038 | 192 | MCOperand_CreateImm0(Inst, 64 - Imm); |
1039 | | |
1040 | 192 | return Success; |
1041 | 192 | } |
1042 | | |
1043 | | static DecodeStatus DecodeFixedPointScaleImm64(MCInst *Inst, unsigned Imm, |
1044 | | uint64_t Addr, const void *Decoder) |
1045 | 365 | { |
1046 | 365 | MCOperand_CreateImm0(Inst, 64 - Imm); |
1047 | | |
1048 | 365 | return Success; |
1049 | 365 | } |
1050 | | |
1051 | | static DecodeStatus DecodePCRelLabel19(MCInst *Inst, unsigned Imm, |
1052 | | uint64_t Addr, const void *Decoder) |
1053 | 7.30k | { |
1054 | 7.30k | int64_t ImmVal = Imm; |
1055 | | |
1056 | | // Sign-extend 19-bit immediate. |
1057 | 7.30k | if (ImmVal & (1 << (19 - 1))) |
1058 | 3.53k | ImmVal |= ~((1LL << 19) - 1); |
1059 | | |
1060 | 7.30k | MCOperand_CreateImm0(Inst, ImmVal); |
1061 | | |
1062 | 7.30k | return Success; |
1063 | 7.30k | } |
1064 | | |
1065 | | static DecodeStatus DecodeMemExtend(MCInst *Inst, unsigned Imm, |
1066 | | uint64_t Address, const void *Decoder) |
1067 | 2.96k | { |
1068 | 2.96k | MCOperand_CreateImm0(Inst, (Imm >> 1) & 1); |
1069 | 2.96k | MCOperand_CreateImm0(Inst, Imm & 1); |
1070 | | |
1071 | 2.96k | return Success; |
1072 | 2.96k | } |
1073 | | |
1074 | | static DecodeStatus DecodeMRSSystemRegister(MCInst *Inst, unsigned Imm, |
1075 | | uint64_t Address, const void *Decoder) |
1076 | 1.86k | { |
1077 | 1.86k | 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 | 1.86k | return Success; |
1082 | 1.86k | } |
1083 | | |
1084 | | static DecodeStatus DecodeMSRSystemRegister(MCInst *Inst, unsigned Imm, |
1085 | | uint64_t Address, const void *Decoder) |
1086 | 3.68k | { |
1087 | 3.68k | MCOperand_CreateImm0(Inst, Imm); |
1088 | | |
1089 | 3.68k | return Success; |
1090 | 3.68k | } |
1091 | | |
1092 | | static DecodeStatus DecodeFMOVLaneInstruction(MCInst *Inst, unsigned Insn, |
1093 | | uint64_t Address, const void *Decoder) |
1094 | 74 | { |
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 | 74 | unsigned Rd = fieldFromInstruction_4(Insn, 0, 5); |
1098 | 74 | unsigned Rn = fieldFromInstruction_4(Insn, 5, 5); |
1099 | 74 | unsigned IsToVec = fieldFromInstruction_4(Insn, 16, 1); |
1100 | | |
1101 | 74 | if (IsToVec) { |
1102 | 37 | DecodeFPR128RegisterClass(Inst, Rd, Address, Decoder); |
1103 | 37 | DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder); |
1104 | 37 | } else { |
1105 | 37 | DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder); |
1106 | 37 | DecodeFPR128RegisterClass(Inst, Rn, Address, Decoder); |
1107 | 37 | } |
1108 | | |
1109 | | // Add the lane |
1110 | 74 | MCOperand_CreateImm0(Inst, 1); |
1111 | | |
1112 | 74 | return Success; |
1113 | 74 | } |
1114 | | |
1115 | | static DecodeStatus DecodeVecShiftRImm(MCInst *Inst, unsigned Imm, |
1116 | | unsigned Add) |
1117 | 3.40k | { |
1118 | 3.40k | MCOperand_CreateImm0(Inst, Add - Imm); |
1119 | | |
1120 | 3.40k | return Success; |
1121 | 3.40k | } |
1122 | | |
1123 | | static DecodeStatus DecodeVecShiftLImm(MCInst *Inst, unsigned Imm, |
1124 | | unsigned Add) |
1125 | 1.96k | { |
1126 | 1.96k | MCOperand_CreateImm0(Inst, (Imm + Add) & (Add - 1)); |
1127 | | |
1128 | 1.96k | return Success; |
1129 | 1.96k | } |
1130 | | |
1131 | | static DecodeStatus DecodeVecShiftR64Imm(MCInst *Inst, unsigned Imm, |
1132 | | uint64_t Addr, const void *Decoder) |
1133 | 460 | { |
1134 | 460 | return DecodeVecShiftRImm(Inst, Imm, 64); |
1135 | 460 | } |
1136 | | |
1137 | | static DecodeStatus DecodeVecShiftR64ImmNarrow(MCInst *Inst, unsigned Imm, |
1138 | | uint64_t Addr, const void *Decoder) |
1139 | 369 | { |
1140 | 369 | return DecodeVecShiftRImm(Inst, Imm | 0x20, 64); |
1141 | 369 | } |
1142 | | |
1143 | | static DecodeStatus DecodeVecShiftR32Imm(MCInst *Inst, unsigned Imm, |
1144 | | uint64_t Addr, const void *Decoder) |
1145 | 529 | { |
1146 | 529 | return DecodeVecShiftRImm(Inst, Imm, 32); |
1147 | 529 | } |
1148 | | |
1149 | | static DecodeStatus DecodeVecShiftR32ImmNarrow(MCInst *Inst, unsigned Imm, |
1150 | | uint64_t Addr, const void *Decoder) |
1151 | 57 | { |
1152 | 57 | return DecodeVecShiftRImm(Inst, Imm | 0x10, 32); |
1153 | 57 | } |
1154 | | |
1155 | | static DecodeStatus DecodeVecShiftR16Imm(MCInst *Inst, unsigned Imm, |
1156 | | uint64_t Addr, const void *Decoder) |
1157 | 1.27k | { |
1158 | 1.27k | return DecodeVecShiftRImm(Inst, Imm, 16); |
1159 | 1.27k | } |
1160 | | |
1161 | | static DecodeStatus DecodeVecShiftR16ImmNarrow(MCInst *Inst, unsigned Imm, |
1162 | | uint64_t Addr, const void *Decoder) |
1163 | 38 | { |
1164 | 38 | return DecodeVecShiftRImm(Inst, Imm | 0x8, 16); |
1165 | 38 | } |
1166 | | |
1167 | | static DecodeStatus DecodeVecShiftR8Imm(MCInst *Inst, unsigned Imm, |
1168 | | uint64_t Addr, const void *Decoder) |
1169 | 676 | { |
1170 | 676 | return DecodeVecShiftRImm(Inst, Imm, 8); |
1171 | 676 | } |
1172 | | |
1173 | | static DecodeStatus DecodeVecShiftL64Imm(MCInst *Inst, unsigned Imm, |
1174 | | uint64_t Addr, const void *Decoder) |
1175 | 517 | { |
1176 | 517 | return DecodeVecShiftLImm(Inst, Imm, 64); |
1177 | 517 | } |
1178 | | |
1179 | | static DecodeStatus DecodeVecShiftL32Imm(MCInst *Inst, unsigned Imm, |
1180 | | uint64_t Addr, const void *Decoder) |
1181 | 360 | { |
1182 | 360 | return DecodeVecShiftLImm(Inst, Imm, 32); |
1183 | 360 | } |
1184 | | |
1185 | | static DecodeStatus DecodeVecShiftL16Imm(MCInst *Inst, unsigned Imm, |
1186 | | uint64_t Addr, const void *Decoder) |
1187 | 566 | { |
1188 | 566 | return DecodeVecShiftLImm(Inst, Imm, 16); |
1189 | 566 | } |
1190 | | |
1191 | | static DecodeStatus DecodeVecShiftL8Imm(MCInst *Inst, unsigned Imm, |
1192 | | uint64_t Addr, const void *Decoder) |
1193 | 522 | { |
1194 | 522 | return DecodeVecShiftLImm(Inst, Imm, 8); |
1195 | 522 | } |
1196 | | |
1197 | | static DecodeStatus DecodeThreeAddrSRegInstruction(MCInst *Inst, |
1198 | | uint32_t insn, uint64_t Addr, const void *Decoder) |
1199 | 10.0k | { |
1200 | 10.0k | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
1201 | 10.0k | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
1202 | 10.0k | unsigned Rm = fieldFromInstruction_4(insn, 16, 5); |
1203 | 10.0k | unsigned shiftHi = fieldFromInstruction_4(insn, 22, 2); |
1204 | 10.0k | unsigned shiftLo = fieldFromInstruction_4(insn, 10, 6); |
1205 | 10.0k | unsigned shift = (shiftHi << 6) | shiftLo; |
1206 | | |
1207 | 10.0k | switch (MCInst_getOpcode(Inst)) { |
1208 | 0 | default: |
1209 | 0 | return Fail; |
1210 | | |
1211 | 329 | case AArch64_ADDWrs: |
1212 | 771 | case AArch64_ADDSWrs: |
1213 | 1.09k | case AArch64_SUBWrs: |
1214 | 1.38k | case AArch64_SUBSWrs: |
1215 | | // if shift == '11' then ReservedValue() |
1216 | 1.38k | if (shiftHi == 0x3) |
1217 | 9 | return Fail; |
1218 | | // Deliberate fallthrough |
1219 | | |
1220 | 1.80k | case AArch64_ANDWrs: |
1221 | 2.03k | case AArch64_ANDSWrs: |
1222 | 2.42k | case AArch64_BICWrs: |
1223 | 2.69k | case AArch64_BICSWrs: |
1224 | 2.97k | case AArch64_ORRWrs: |
1225 | 3.38k | case AArch64_ORNWrs: |
1226 | 4.33k | case AArch64_EORWrs: |
1227 | 4.67k | case AArch64_EONWrs: { |
1228 | | // if sf == '0' and imm6<5> == '1' then ReservedValue() |
1229 | 4.67k | if (shiftLo >> 5 == 1) |
1230 | 32 | return Fail; |
1231 | | |
1232 | 4.64k | DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
1233 | 4.64k | DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder); |
1234 | 4.64k | DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
1235 | 4.64k | break; |
1236 | 4.67k | } |
1237 | | |
1238 | 243 | case AArch64_ADDXrs: |
1239 | 1.53k | case AArch64_ADDSXrs: |
1240 | 1.58k | case AArch64_SUBXrs: |
1241 | 1.82k | case AArch64_SUBSXrs: |
1242 | | // if shift == '11' then ReservedValue() |
1243 | 1.82k | if (shiftHi == 0x3) |
1244 | 8 | return Fail; |
1245 | | // Deliberate fallthrough |
1246 | | |
1247 | 2.14k | case AArch64_ANDXrs: |
1248 | 2.44k | case AArch64_ANDSXrs: |
1249 | 2.85k | case AArch64_BICXrs: |
1250 | 3.88k | case AArch64_BICSXrs: |
1251 | 4.11k | case AArch64_ORRXrs: |
1252 | 4.40k | case AArch64_ORNXrs: |
1253 | 5.18k | case AArch64_EORXrs: |
1254 | 5.34k | case AArch64_EONXrs: |
1255 | 5.34k | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1256 | 5.34k | DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder); |
1257 | 5.34k | DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder); |
1258 | 5.34k | break; |
1259 | 10.0k | } |
1260 | | |
1261 | 9.99k | MCOperand_CreateImm0(Inst, shift); |
1262 | | |
1263 | 9.99k | return Success; |
1264 | 10.0k | } |
1265 | | |
1266 | | static DecodeStatus DecodeMoveImmInstruction(MCInst *Inst, uint32_t insn, |
1267 | | uint64_t Addr, const void *Decoder) |
1268 | 4.50k | { |
1269 | 4.50k | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
1270 | 4.50k | unsigned imm = fieldFromInstruction_4(insn, 5, 16); |
1271 | 4.50k | unsigned shift = fieldFromInstruction_4(insn, 21, 2); |
1272 | | |
1273 | 4.50k | shift <<= 4; |
1274 | | |
1275 | 4.50k | switch (MCInst_getOpcode(Inst)) { |
1276 | 0 | default: |
1277 | 0 | return Fail; |
1278 | | |
1279 | 214 | case AArch64_MOVZWi: |
1280 | 2.03k | case AArch64_MOVNWi: |
1281 | 2.09k | case AArch64_MOVKWi: |
1282 | 2.09k | if (shift & (1U << 5)) |
1283 | 6 | return Fail; |
1284 | 2.08k | DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
1285 | 2.08k | break; |
1286 | | |
1287 | 1.03k | case AArch64_MOVZXi: |
1288 | 1.50k | case AArch64_MOVNXi: |
1289 | 2.41k | case AArch64_MOVKXi: |
1290 | 2.41k | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1291 | 2.41k | break; |
1292 | 4.50k | } |
1293 | | |
1294 | 4.49k | if (MCInst_getOpcode(Inst) == AArch64_MOVKWi || |
1295 | 4.49k | MCInst_getOpcode(Inst) == AArch64_MOVKXi) |
1296 | 952 | MCInst_addOperand2(Inst, MCInst_getOperand(Inst, 0)); |
1297 | | |
1298 | 4.49k | MCOperand_CreateImm0(Inst, imm); |
1299 | 4.49k | MCOperand_CreateImm0(Inst, shift); |
1300 | | |
1301 | 4.49k | return Success; |
1302 | 4.50k | } |
1303 | | |
1304 | | static DecodeStatus DecodeUnsignedLdStInstruction(MCInst *Inst, |
1305 | | uint32_t insn, uint64_t Addr, const void *Decoder) |
1306 | 7.15k | { |
1307 | 7.15k | unsigned Rt = fieldFromInstruction_4(insn, 0, 5); |
1308 | 7.15k | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
1309 | 7.15k | unsigned offset = fieldFromInstruction_4(insn, 10, 12); |
1310 | | |
1311 | 7.15k | switch (MCInst_getOpcode(Inst)) { |
1312 | 0 | default: |
1313 | 0 | return Fail; |
1314 | | |
1315 | 237 | case AArch64_PRFMui: |
1316 | | // Rt is an immediate in prefetch. |
1317 | 237 | MCOperand_CreateImm0(Inst, Rt); |
1318 | 237 | break; |
1319 | | |
1320 | 361 | case AArch64_STRBBui: |
1321 | 467 | case AArch64_LDRBBui: |
1322 | 525 | case AArch64_LDRSBWui: |
1323 | 943 | case AArch64_STRHHui: |
1324 | 1.30k | case AArch64_LDRHHui: |
1325 | 1.43k | case AArch64_LDRSHWui: |
1326 | 1.69k | case AArch64_STRWui: |
1327 | 1.90k | case AArch64_LDRWui: |
1328 | 1.90k | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1329 | 1.90k | break; |
1330 | | |
1331 | 136 | case AArch64_LDRSBXui: |
1332 | 186 | case AArch64_LDRSHXui: |
1333 | 610 | case AArch64_LDRSWui: |
1334 | 1.46k | case AArch64_STRXui: |
1335 | 1.81k | case AArch64_LDRXui: |
1336 | 1.81k | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1337 | 1.81k | break; |
1338 | | |
1339 | 473 | case AArch64_LDRQui: |
1340 | 949 | case AArch64_STRQui: |
1341 | 949 | DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder); |
1342 | 949 | break; |
1343 | | |
1344 | 216 | case AArch64_LDRDui: |
1345 | 563 | case AArch64_STRDui: |
1346 | 563 | DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1347 | 563 | break; |
1348 | | |
1349 | 52 | case AArch64_LDRSui: |
1350 | 152 | case AArch64_STRSui: |
1351 | 152 | DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1352 | 152 | break; |
1353 | | |
1354 | 630 | case AArch64_LDRHui: |
1355 | 700 | case AArch64_STRHui: |
1356 | 700 | DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder); |
1357 | 700 | break; |
1358 | | |
1359 | 279 | case AArch64_LDRBui: |
1360 | 842 | case AArch64_STRBui: |
1361 | 842 | DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder); |
1362 | 842 | break; |
1363 | 7.15k | } |
1364 | | |
1365 | 7.15k | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1366 | | |
1367 | | //if (!Dis->tryAddingSymbolicOperand(Inst, offset, Addr, Fail, 0, 4)) |
1368 | 7.15k | MCOperand_CreateImm0(Inst, offset); |
1369 | | |
1370 | 7.15k | return Success; |
1371 | 7.15k | } |
1372 | | |
1373 | | static DecodeStatus DecodeSignedLdStInstruction(MCInst *Inst, |
1374 | | uint32_t insn, uint64_t Addr, const void *Decoder) |
1375 | 11.7k | { |
1376 | 11.7k | bool IsLoad, IsIndexed, IsFP; |
1377 | 11.7k | unsigned Rt = fieldFromInstruction_4(insn, 0, 5); |
1378 | 11.7k | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
1379 | 11.7k | 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 | 11.7k | if (offset & (1 << (9 - 1))) |
1384 | 3.87k | offset |= ~((1LL << 9) - 1); |
1385 | | |
1386 | | // First operand is always the writeback to the address register, if needed. |
1387 | 11.7k | switch (MCInst_getOpcode(Inst)) { |
1388 | 5.10k | default: |
1389 | 5.10k | break; |
1390 | | |
1391 | 5.10k | case AArch64_LDRSBWpre: |
1392 | 58 | case AArch64_LDRSHWpre: |
1393 | 95 | case AArch64_STRBBpre: |
1394 | 259 | case AArch64_LDRBBpre: |
1395 | 547 | case AArch64_STRHHpre: |
1396 | 620 | case AArch64_LDRHHpre: |
1397 | 659 | case AArch64_STRWpre: |
1398 | 877 | case AArch64_LDRWpre: |
1399 | 1.03k | case AArch64_LDRSBWpost: |
1400 | 1.10k | case AArch64_LDRSHWpost: |
1401 | 1.13k | case AArch64_STRBBpost: |
1402 | 1.14k | case AArch64_LDRBBpost: |
1403 | 1.28k | case AArch64_STRHHpost: |
1404 | 1.32k | case AArch64_LDRHHpost: |
1405 | 1.38k | case AArch64_STRWpost: |
1406 | 1.45k | case AArch64_LDRWpost: |
1407 | 1.57k | case AArch64_LDRSBXpre: |
1408 | 1.61k | case AArch64_LDRSHXpre: |
1409 | 1.65k | case AArch64_STRXpre: |
1410 | 1.69k | case AArch64_LDRSWpre: |
1411 | 1.77k | case AArch64_LDRXpre: |
1412 | 2.37k | case AArch64_LDRSBXpost: |
1413 | 2.58k | case AArch64_LDRSHXpost: |
1414 | 2.79k | case AArch64_STRXpost: |
1415 | 2.88k | case AArch64_LDRSWpost: |
1416 | 2.93k | case AArch64_LDRXpost: |
1417 | 3.08k | case AArch64_LDRQpre: |
1418 | 3.11k | case AArch64_STRQpre: |
1419 | 3.13k | case AArch64_LDRQpost: |
1420 | 3.16k | case AArch64_STRQpost: |
1421 | 3.23k | case AArch64_LDRDpre: |
1422 | 3.28k | case AArch64_STRDpre: |
1423 | 3.35k | case AArch64_LDRDpost: |
1424 | 3.44k | case AArch64_STRDpost: |
1425 | 3.66k | case AArch64_LDRSpre: |
1426 | 3.79k | case AArch64_STRSpre: |
1427 | 3.83k | case AArch64_LDRSpost: |
1428 | 3.98k | case AArch64_STRSpost: |
1429 | 4.02k | case AArch64_LDRHpre: |
1430 | 4.23k | case AArch64_STRHpre: |
1431 | 4.25k | case AArch64_LDRHpost: |
1432 | 4.29k | case AArch64_STRHpost: |
1433 | 4.32k | case AArch64_LDRBpre: |
1434 | 5.66k | case AArch64_STRBpre: |
1435 | 6.08k | case AArch64_LDRBpost: |
1436 | 6.67k | case AArch64_STRBpost: |
1437 | 6.67k | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1438 | 6.67k | break; |
1439 | 11.7k | } |
1440 | | |
1441 | 11.7k | switch (MCInst_getOpcode(Inst)) { |
1442 | 0 | default: |
1443 | 0 | return Fail; |
1444 | | |
1445 | 21 | case AArch64_PRFUMi: |
1446 | | // Rt is an immediate in prefetch. |
1447 | 21 | MCOperand_CreateImm0(Inst, Rt); |
1448 | 21 | break; |
1449 | | |
1450 | 77 | case AArch64_STURBBi: |
1451 | 106 | case AArch64_LDURBBi: |
1452 | 197 | case AArch64_LDURSBWi: |
1453 | 470 | case AArch64_STURHHi: |
1454 | 543 | case AArch64_LDURHHi: |
1455 | 746 | case AArch64_LDURSHWi: |
1456 | 781 | case AArch64_STURWi: |
1457 | 865 | case AArch64_LDURWi: |
1458 | 944 | case AArch64_LDTRSBWi: |
1459 | 1.07k | case AArch64_LDTRSHWi: |
1460 | 1.30k | case AArch64_STTRWi: |
1461 | 1.32k | case AArch64_LDTRWi: |
1462 | 1.52k | case AArch64_STTRHi: |
1463 | 1.59k | case AArch64_LDTRHi: |
1464 | 1.63k | case AArch64_LDTRBi: |
1465 | 1.66k | case AArch64_STTRBi: |
1466 | 1.68k | case AArch64_LDRSBWpre: |
1467 | 1.72k | case AArch64_LDRSHWpre: |
1468 | 1.76k | case AArch64_STRBBpre: |
1469 | 1.92k | case AArch64_LDRBBpre: |
1470 | 2.21k | case AArch64_STRHHpre: |
1471 | 2.28k | case AArch64_LDRHHpre: |
1472 | 2.32k | case AArch64_STRWpre: |
1473 | 2.54k | case AArch64_LDRWpre: |
1474 | 2.70k | case AArch64_LDRSBWpost: |
1475 | 2.77k | case AArch64_LDRSHWpost: |
1476 | 2.80k | case AArch64_STRBBpost: |
1477 | 2.81k | case AArch64_LDRBBpost: |
1478 | 2.95k | case AArch64_STRHHpost: |
1479 | 2.98k | case AArch64_LDRHHpost: |
1480 | 3.05k | case AArch64_STRWpost: |
1481 | 3.12k | case AArch64_LDRWpost: |
1482 | 3.28k | case AArch64_STLURBi: |
1483 | 3.35k | case AArch64_STLURHi: |
1484 | 3.43k | case AArch64_STLURWi: |
1485 | 3.54k | case AArch64_LDAPURBi: |
1486 | 3.68k | case AArch64_LDAPURSBWi: |
1487 | 3.73k | case AArch64_LDAPURHi: |
1488 | 3.87k | case AArch64_LDAPURSHWi: |
1489 | 4.07k | case AArch64_LDAPURi: |
1490 | 4.07k | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1491 | 4.07k | break; |
1492 | | |
1493 | 32 | case AArch64_LDURSBXi: |
1494 | 89 | case AArch64_LDURSHXi: |
1495 | 131 | case AArch64_LDURSWi: |
1496 | 231 | case AArch64_STURXi: |
1497 | 313 | case AArch64_LDURXi: |
1498 | 332 | case AArch64_LDTRSBXi: |
1499 | 371 | case AArch64_LDTRSHXi: |
1500 | 408 | case AArch64_LDTRSWi: |
1501 | 565 | case AArch64_STTRXi: |
1502 | 638 | case AArch64_LDTRXi: |
1503 | 761 | case AArch64_LDRSBXpre: |
1504 | 797 | case AArch64_LDRSHXpre: |
1505 | 841 | case AArch64_STRXpre: |
1506 | 881 | case AArch64_LDRSWpre: |
1507 | 962 | case AArch64_LDRXpre: |
1508 | 1.55k | case AArch64_LDRSBXpost: |
1509 | 1.76k | case AArch64_LDRSHXpost: |
1510 | 1.97k | case AArch64_STRXpost: |
1511 | 2.07k | case AArch64_LDRSWpost: |
1512 | 2.12k | case AArch64_LDRXpost: |
1513 | 2.21k | case AArch64_LDAPURSWi: |
1514 | 2.25k | case AArch64_LDAPURSHXi: |
1515 | 2.27k | case AArch64_LDAPURSBXi: |
1516 | 2.57k | case AArch64_STLURXi: |
1517 | 3.00k | case AArch64_LDAPURXi: |
1518 | 3.00k | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1519 | 3.00k | break; |
1520 | | |
1521 | 116 | case AArch64_LDURQi: |
1522 | 254 | case AArch64_STURQi: |
1523 | 404 | case AArch64_LDRQpre: |
1524 | 430 | case AArch64_STRQpre: |
1525 | 448 | case AArch64_LDRQpost: |
1526 | 484 | case AArch64_STRQpost: |
1527 | 484 | DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder); |
1528 | 484 | break; |
1529 | | |
1530 | 75 | case AArch64_LDURDi: |
1531 | 161 | case AArch64_STURDi: |
1532 | 231 | case AArch64_LDRDpre: |
1533 | 274 | case AArch64_STRDpre: |
1534 | 343 | case AArch64_LDRDpost: |
1535 | 436 | case AArch64_STRDpost: |
1536 | 436 | DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1537 | 436 | break; |
1538 | | |
1539 | 21 | case AArch64_LDURSi: |
1540 | 92 | case AArch64_STURSi: |
1541 | 313 | case AArch64_LDRSpre: |
1542 | 447 | case AArch64_STRSpre: |
1543 | 485 | case AArch64_LDRSpost: |
1544 | 635 | case AArch64_STRSpost: |
1545 | 635 | DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1546 | 635 | break; |
1547 | | |
1548 | 42 | case AArch64_LDURHi: |
1549 | 87 | case AArch64_STURHi: |
1550 | 127 | case AArch64_LDRHpre: |
1551 | 332 | case AArch64_STRHpre: |
1552 | 355 | case AArch64_LDRHpost: |
1553 | 395 | case AArch64_STRHpost: |
1554 | 395 | DecodeFPR16RegisterClass(Inst, Rt, Addr, Decoder); |
1555 | 395 | break; |
1556 | | |
1557 | 281 | case AArch64_LDURBi: |
1558 | 347 | case AArch64_STURBi: |
1559 | 379 | case AArch64_LDRBpre: |
1560 | 1.72k | case AArch64_STRBpre: |
1561 | 2.13k | case AArch64_LDRBpost: |
1562 | 2.72k | case AArch64_STRBpost: |
1563 | 2.72k | DecodeFPR8RegisterClass(Inst, Rt, Addr, Decoder); |
1564 | 2.72k | break; |
1565 | 11.7k | } |
1566 | | |
1567 | 11.7k | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1568 | 11.7k | MCOperand_CreateImm0(Inst, offset); |
1569 | | |
1570 | 11.7k | IsLoad = fieldFromInstruction_4(insn, 22, 1) != 0; |
1571 | 11.7k | IsIndexed = fieldFromInstruction_4(insn, 10, 2) != 0; |
1572 | 11.7k | IsFP = fieldFromInstruction_4(insn, 26, 1) != 0; |
1573 | | |
1574 | | // Cannot write back to a transfer register (but xzr != sp). |
1575 | 11.7k | if (IsLoad && IsIndexed && !IsFP && Rn != 31 && Rt == Rn) |
1576 | 1 | return SoftFail; |
1577 | | |
1578 | 11.7k | return Success; |
1579 | 11.7k | } |
1580 | | |
1581 | | static DecodeStatus DecodeExclusiveLdStInstruction(MCInst *Inst, |
1582 | | uint32_t insn, uint64_t Addr, const void *Decoder) |
1583 | 5.72k | { |
1584 | 5.72k | unsigned Rt = fieldFromInstruction_4(insn, 0, 5); |
1585 | 5.72k | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
1586 | 5.72k | unsigned Rt2 = fieldFromInstruction_4(insn, 10, 5); |
1587 | 5.72k | unsigned Rs = fieldFromInstruction_4(insn, 16, 5); |
1588 | 5.72k | unsigned Opcode = MCInst_getOpcode(Inst); |
1589 | | |
1590 | 5.72k | switch (Opcode) { |
1591 | 0 | default: |
1592 | 0 | return Fail; |
1593 | | |
1594 | 172 | case AArch64_STLXRW: |
1595 | 424 | case AArch64_STLXRB: |
1596 | 483 | case AArch64_STLXRH: |
1597 | 686 | case AArch64_STXRW: |
1598 | 1.27k | case AArch64_STXRB: |
1599 | 1.36k | case AArch64_STXRH: |
1600 | 1.36k | DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); |
1601 | | // FALLTHROUGH |
1602 | 1.38k | case AArch64_LDARW: |
1603 | 1.79k | case AArch64_LDARB: |
1604 | 1.86k | case AArch64_LDARH: |
1605 | 2.11k | case AArch64_LDAXRW: |
1606 | 2.15k | case AArch64_LDAXRB: |
1607 | 2.17k | case AArch64_LDAXRH: |
1608 | 3.29k | case AArch64_LDXRW: |
1609 | 3.34k | case AArch64_LDXRB: |
1610 | 3.36k | case AArch64_LDXRH: |
1611 | 3.37k | case AArch64_STLRW: |
1612 | 3.52k | case AArch64_STLRB: |
1613 | 3.54k | case AArch64_STLRH: |
1614 | 3.55k | case AArch64_STLLRW: |
1615 | 3.59k | case AArch64_STLLRB: |
1616 | 3.80k | case AArch64_STLLRH: |
1617 | 3.87k | case AArch64_LDLARW: |
1618 | 3.89k | case AArch64_LDLARB: |
1619 | 3.99k | case AArch64_LDLARH: |
1620 | 3.99k | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1621 | 3.99k | break; |
1622 | | |
1623 | 38 | case AArch64_STLXRX: |
1624 | 80 | case AArch64_STXRX: |
1625 | 80 | DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); |
1626 | | // FALLTHROUGH |
1627 | 115 | case AArch64_LDARX: |
1628 | 137 | case AArch64_LDAXRX: |
1629 | 157 | case AArch64_LDXRX: |
1630 | 167 | case AArch64_STLRX: |
1631 | 178 | case AArch64_LDLARX: |
1632 | 188 | case AArch64_STLLRX: |
1633 | 188 | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1634 | 188 | break; |
1635 | | |
1636 | 73 | case AArch64_STLXPW: |
1637 | 420 | case AArch64_STXPW: |
1638 | 420 | DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); |
1639 | | // FALLTHROUGH |
1640 | 615 | case AArch64_LDAXPW: |
1641 | 780 | case AArch64_LDXPW: |
1642 | 780 | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1643 | 780 | DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder); |
1644 | 780 | break; |
1645 | | |
1646 | 114 | case AArch64_STLXPX: |
1647 | 326 | case AArch64_STXPX: |
1648 | 326 | DecodeGPR32RegisterClass(Inst, Rs, Addr, Decoder); |
1649 | | // FALLTHROUGH |
1650 | 674 | case AArch64_LDAXPX: |
1651 | 759 | case AArch64_LDXPX: |
1652 | 759 | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1653 | 759 | DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder); |
1654 | 759 | break; |
1655 | 5.72k | } |
1656 | | |
1657 | 5.72k | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1658 | | |
1659 | | // You shouldn't load to the same register twice in an instruction... |
1660 | 5.72k | if ((Opcode == AArch64_LDAXPW || Opcode == AArch64_LDXPW || |
1661 | 5.72k | Opcode == AArch64_LDAXPX || Opcode == AArch64_LDXPX) && |
1662 | 5.72k | Rt == Rt2) |
1663 | 1 | return SoftFail; |
1664 | | |
1665 | 5.72k | return Success; |
1666 | 5.72k | } |
1667 | | |
1668 | | static DecodeStatus DecodePairLdStInstruction(MCInst *Inst, uint32_t insn, |
1669 | | uint64_t Addr, const void *Decoder) |
1670 | 14.2k | { |
1671 | 14.2k | unsigned Rt = fieldFromInstruction_4(insn, 0, 5); |
1672 | 14.2k | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
1673 | 14.2k | unsigned Rt2 = fieldFromInstruction_4(insn, 10, 5); |
1674 | 14.2k | int32_t offset = fieldFromInstruction_4(insn, 15, 7); |
1675 | 14.2k | bool IsLoad = fieldFromInstruction_4(insn, 22, 1) != 0; |
1676 | 14.2k | unsigned Opcode = MCInst_getOpcode(Inst); |
1677 | 14.2k | bool NeedsDisjointWritebackTransfer = false; |
1678 | | |
1679 | | // offset is a 7-bit signed immediate, so sign extend it to |
1680 | | // fill the unsigned. |
1681 | 14.2k | if (offset & (1 << (7 - 1))) |
1682 | 9.33k | offset |= ~((1LL << 7) - 1); |
1683 | | |
1684 | | // First operand is always writeback of base register. |
1685 | 14.2k | switch (Opcode) { |
1686 | 8.37k | default: |
1687 | 8.37k | break; |
1688 | | |
1689 | 8.37k | case AArch64_LDPXpost: |
1690 | 566 | case AArch64_STPXpost: |
1691 | 1.01k | case AArch64_LDPSWpost: |
1692 | 1.47k | case AArch64_LDPXpre: |
1693 | 2.34k | case AArch64_STPXpre: |
1694 | 2.59k | case AArch64_LDPSWpre: |
1695 | 2.84k | case AArch64_LDPWpost: |
1696 | 3.11k | case AArch64_STPWpost: |
1697 | 3.17k | case AArch64_LDPWpre: |
1698 | 3.44k | case AArch64_STPWpre: |
1699 | 3.67k | case AArch64_LDPQpost: |
1700 | 3.90k | case AArch64_STPQpost: |
1701 | 3.99k | case AArch64_LDPQpre: |
1702 | 4.24k | case AArch64_STPQpre: |
1703 | 4.37k | case AArch64_LDPDpost: |
1704 | 4.43k | case AArch64_STPDpost: |
1705 | 4.75k | case AArch64_LDPDpre: |
1706 | 4.86k | case AArch64_STPDpre: |
1707 | 5.08k | case AArch64_LDPSpost: |
1708 | 5.21k | case AArch64_STPSpost: |
1709 | 5.40k | case AArch64_LDPSpre: |
1710 | 5.82k | case AArch64_STPSpre: |
1711 | 5.82k | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1712 | 5.82k | break; |
1713 | 14.2k | } |
1714 | | |
1715 | 14.2k | switch (Opcode) { |
1716 | 2 | default: |
1717 | 2 | return Fail; |
1718 | | |
1719 | 83 | case AArch64_LDPXpost: |
1720 | 566 | case AArch64_STPXpost: |
1721 | 1.01k | case AArch64_LDPSWpost: |
1722 | 1.47k | case AArch64_LDPXpre: |
1723 | 2.34k | case AArch64_STPXpre: |
1724 | 2.59k | case AArch64_LDPSWpre: |
1725 | 2.59k | NeedsDisjointWritebackTransfer = true; |
1726 | | // Fallthrough |
1727 | 2.79k | case AArch64_LDNPXi: |
1728 | 3.37k | case AArch64_STNPXi: |
1729 | 3.65k | case AArch64_LDPXi: |
1730 | 4.47k | case AArch64_STPXi: |
1731 | 4.86k | case AArch64_LDPSWi: |
1732 | 4.86k | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1733 | 4.86k | DecodeGPR64RegisterClass(Inst, Rt2, Addr, Decoder); |
1734 | 4.86k | break; |
1735 | | |
1736 | 253 | case AArch64_LDPWpost: |
1737 | 519 | case AArch64_STPWpost: |
1738 | 580 | case AArch64_LDPWpre: |
1739 | 848 | case AArch64_STPWpre: |
1740 | 848 | NeedsDisjointWritebackTransfer = true; |
1741 | | // Fallthrough |
1742 | 959 | case AArch64_LDNPWi: |
1743 | 1.51k | case AArch64_STNPWi: |
1744 | 1.66k | case AArch64_LDPWi: |
1745 | 2.04k | case AArch64_STPWi: |
1746 | 2.04k | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1747 | 2.04k | DecodeGPR32RegisterClass(Inst, Rt2, Addr, Decoder); |
1748 | 2.04k | break; |
1749 | | |
1750 | 110 | case AArch64_LDNPQi: |
1751 | 908 | case AArch64_STNPQi: |
1752 | 1.13k | case AArch64_LDPQpost: |
1753 | 1.37k | case AArch64_STPQpost: |
1754 | 1.60k | case AArch64_LDPQi: |
1755 | 1.75k | case AArch64_STPQi: |
1756 | 1.83k | case AArch64_LDPQpre: |
1757 | 2.08k | case AArch64_STPQpre: |
1758 | 2.08k | DecodeFPR128RegisterClass(Inst, Rt, Addr, Decoder); |
1759 | 2.08k | DecodeFPR128RegisterClass(Inst, Rt2, Addr, Decoder); |
1760 | 2.08k | break; |
1761 | | |
1762 | 1.12k | case AArch64_LDNPDi: |
1763 | 1.47k | case AArch64_STNPDi: |
1764 | 1.60k | case AArch64_LDPDpost: |
1765 | 1.67k | case AArch64_STPDpost: |
1766 | 2.32k | case AArch64_LDPDi: |
1767 | 2.41k | case AArch64_STPDi: |
1768 | 2.73k | case AArch64_LDPDpre: |
1769 | 2.84k | case AArch64_STPDpre: |
1770 | 2.84k | DecodeFPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1771 | 2.84k | DecodeFPR64RegisterClass(Inst, Rt2, Addr, Decoder); |
1772 | 2.84k | break; |
1773 | | |
1774 | 270 | case AArch64_LDNPSi: |
1775 | 725 | case AArch64_STNPSi: |
1776 | 942 | case AArch64_LDPSpost: |
1777 | 1.07k | case AArch64_STPSpost: |
1778 | 1.44k | case AArch64_LDPSi: |
1779 | 1.75k | case AArch64_STPSi: |
1780 | 1.94k | case AArch64_LDPSpre: |
1781 | 2.36k | case AArch64_STPSpre: |
1782 | 2.36k | DecodeFPR32RegisterClass(Inst, Rt, Addr, Decoder); |
1783 | 2.36k | DecodeFPR32RegisterClass(Inst, Rt2, Addr, Decoder); |
1784 | 2.36k | break; |
1785 | 14.2k | } |
1786 | | |
1787 | 14.2k | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1788 | 14.2k | MCOperand_CreateImm0(Inst, offset); |
1789 | | |
1790 | | // You shouldn't load to the same register twice in an instruction... |
1791 | 14.2k | if (IsLoad && Rt == Rt2) |
1792 | 7 | 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 | 14.1k | if (NeedsDisjointWritebackTransfer && Rn != 31 && (Rt == Rn || Rt2 == Rn)) |
1797 | 6 | return SoftFail; |
1798 | | |
1799 | 14.1k | return Success; |
1800 | 14.1k | } |
1801 | | |
1802 | | static DecodeStatus DecodeAuthLoadInstruction(MCInst *Inst, uint32_t insn, |
1803 | | uint64_t Addr, const void *Decoder) |
1804 | 2.48k | { |
1805 | 2.48k | unsigned Rt = fieldFromInstruction_4(insn, 0, 5); |
1806 | 2.48k | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
1807 | 2.48k | uint64_t offset = fieldFromInstruction_4(insn, 22, 1) << 9 | |
1808 | 2.48k | fieldFromInstruction_4(insn, 12, 9); |
1809 | 2.48k | unsigned writeback = fieldFromInstruction_4(insn, 11, 1); |
1810 | | |
1811 | 2.48k | switch (MCInst_getOpcode(Inst)) { |
1812 | 0 | default: |
1813 | 0 | return Fail; |
1814 | 98 | case AArch64_LDRAAwriteback: |
1815 | 1.93k | case AArch64_LDRABwriteback: |
1816 | 1.93k | DecodeGPR64spRegisterClass(Inst, Rn /* writeback register */, Addr, |
1817 | 1.93k | Decoder); |
1818 | 1.93k | break; |
1819 | 41 | case AArch64_LDRAAindexed: |
1820 | 542 | case AArch64_LDRABindexed: |
1821 | 542 | break; |
1822 | 2.48k | } |
1823 | | |
1824 | 2.48k | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
1825 | 2.48k | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1826 | 2.48k | DecodeSImm(Inst, offset, Addr, Decoder, 10); |
1827 | | |
1828 | 2.48k | if (writeback && Rt == Rn && Rn != 31) { |
1829 | 3 | return SoftFail; |
1830 | 3 | } |
1831 | | |
1832 | 2.47k | return Success; |
1833 | 2.48k | } |
1834 | | |
1835 | | static DecodeStatus DecodeAddSubERegInstruction(MCInst *Inst, |
1836 | | uint32_t insn, uint64_t Addr, const void *Decoder) |
1837 | 2.86k | { |
1838 | 2.86k | unsigned Rd, Rn, Rm; |
1839 | 2.86k | unsigned extend = fieldFromInstruction_4(insn, 10, 6); |
1840 | 2.86k | unsigned shift = extend & 0x7; |
1841 | | |
1842 | 2.86k | if (shift > 4) |
1843 | 3 | return Fail; |
1844 | | |
1845 | 2.86k | Rd = fieldFromInstruction_4(insn, 0, 5); |
1846 | 2.86k | Rn = fieldFromInstruction_4(insn, 5, 5); |
1847 | 2.86k | Rm = fieldFromInstruction_4(insn, 16, 5); |
1848 | | |
1849 | 2.86k | switch (MCInst_getOpcode(Inst)) { |
1850 | 0 | default: |
1851 | 0 | return Fail; |
1852 | | |
1853 | 110 | case AArch64_ADDWrx: |
1854 | 312 | case AArch64_SUBWrx: |
1855 | 312 | DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder); |
1856 | 312 | DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder); |
1857 | 312 | DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
1858 | 312 | break; |
1859 | | |
1860 | 1.02k | case AArch64_ADDSWrx: |
1861 | 1.15k | case AArch64_SUBSWrx: |
1862 | 1.15k | DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
1863 | 1.15k | DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder); |
1864 | 1.15k | DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
1865 | 1.15k | break; |
1866 | | |
1867 | 287 | case AArch64_ADDXrx: |
1868 | 389 | case AArch64_SUBXrx: |
1869 | 389 | DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); |
1870 | 389 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1871 | 389 | DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
1872 | 389 | break; |
1873 | | |
1874 | 595 | case AArch64_ADDSXrx: |
1875 | 760 | case AArch64_SUBSXrx: |
1876 | 760 | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1877 | 760 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1878 | 760 | DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); |
1879 | 760 | break; |
1880 | | |
1881 | 22 | case AArch64_ADDXrx64: |
1882 | 92 | case AArch64_SUBXrx64: |
1883 | 92 | DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); |
1884 | 92 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1885 | 92 | DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder); |
1886 | 92 | break; |
1887 | | |
1888 | 129 | case AArch64_SUBSXrx64: |
1889 | 153 | case AArch64_ADDSXrx64: |
1890 | 153 | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1891 | 153 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
1892 | 153 | DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder); |
1893 | 153 | break; |
1894 | 2.86k | } |
1895 | | |
1896 | 2.86k | MCOperand_CreateImm0(Inst, extend); |
1897 | | |
1898 | 2.86k | return Success; |
1899 | 2.86k | } |
1900 | | |
1901 | | static DecodeStatus DecodeLogicalImmInstruction(MCInst *Inst, |
1902 | | uint32_t insn, uint64_t Addr, const void *Decoder) |
1903 | 4.15k | { |
1904 | 4.15k | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
1905 | 4.15k | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
1906 | 4.15k | unsigned Datasize = fieldFromInstruction_4(insn, 31, 1); |
1907 | 4.15k | unsigned imm; |
1908 | | |
1909 | 4.15k | if (Datasize) { |
1910 | 2.86k | if (MCInst_getOpcode(Inst) == AArch64_ANDSXri) |
1911 | 1.99k | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1912 | 867 | else |
1913 | 867 | DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); |
1914 | | |
1915 | 2.86k | DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder); |
1916 | | |
1917 | 2.86k | imm = fieldFromInstruction_4(insn, 10, 13); |
1918 | 2.86k | if (!AArch64_AM_isValidDecodeLogicalImmediate(imm, 64)) |
1919 | 5 | return Fail; |
1920 | 2.86k | } else { |
1921 | 1.29k | if (MCInst_getOpcode(Inst) == AArch64_ANDSWri) |
1922 | 376 | DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
1923 | 917 | else |
1924 | 917 | DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder); |
1925 | | |
1926 | 1.29k | DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder); |
1927 | | |
1928 | 1.29k | imm = fieldFromInstruction_4(insn, 10, 12); |
1929 | 1.29k | if (!AArch64_AM_isValidDecodeLogicalImmediate(imm, 32)) |
1930 | 5 | return Fail; |
1931 | 1.29k | } |
1932 | | |
1933 | 4.14k | MCOperand_CreateImm0(Inst, imm); |
1934 | | |
1935 | 4.14k | return Success; |
1936 | 4.15k | } |
1937 | | |
1938 | | static DecodeStatus DecodeModImmInstruction(MCInst *Inst, uint32_t insn, |
1939 | | uint64_t Addr, const void *Decoder) |
1940 | 1.27k | { |
1941 | 1.27k | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
1942 | 1.27k | unsigned cmode = fieldFromInstruction_4(insn, 12, 4); |
1943 | 1.27k | unsigned imm = fieldFromInstruction_4(insn, 16, 3) << 5; |
1944 | 1.27k | imm |= fieldFromInstruction_4(insn, 5, 5); |
1945 | | |
1946 | 1.27k | if (MCInst_getOpcode(Inst) == AArch64_MOVID) |
1947 | 195 | DecodeFPR64RegisterClass(Inst, Rd, Addr, Decoder); |
1948 | 1.07k | else |
1949 | 1.07k | DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder); |
1950 | | |
1951 | 1.27k | MCOperand_CreateImm0(Inst, imm); |
1952 | | |
1953 | 1.27k | switch (MCInst_getOpcode(Inst)) { |
1954 | 258 | default: |
1955 | 258 | break; |
1956 | | |
1957 | 258 | case AArch64_MOVIv4i16: |
1958 | 255 | case AArch64_MOVIv8i16: |
1959 | 265 | case AArch64_MVNIv4i16: |
1960 | 304 | case AArch64_MVNIv8i16: |
1961 | 501 | case AArch64_MOVIv2i32: |
1962 | 896 | case AArch64_MOVIv4i32: |
1963 | 915 | case AArch64_MVNIv2i32: |
1964 | 926 | case AArch64_MVNIv4i32: |
1965 | 926 | MCOperand_CreateImm0(Inst, (cmode & 6) << 2); |
1966 | 926 | break; |
1967 | | |
1968 | 35 | case AArch64_MOVIv2s_msl: |
1969 | 53 | case AArch64_MOVIv4s_msl: |
1970 | 72 | case AArch64_MVNIv2s_msl: |
1971 | 88 | case AArch64_MVNIv4s_msl: |
1972 | 88 | MCOperand_CreateImm0(Inst, cmode & 1 ? 0x110 : 0x108); |
1973 | 88 | break; |
1974 | 1.27k | } |
1975 | | |
1976 | 1.27k | return Success; |
1977 | 1.27k | } |
1978 | | |
1979 | | static DecodeStatus DecodeModImmTiedInstruction(MCInst *Inst, |
1980 | | uint32_t insn, uint64_t Addr, const void *Decoder) |
1981 | 57 | { |
1982 | 57 | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
1983 | 57 | unsigned cmode = fieldFromInstruction_4(insn, 12, 4); |
1984 | 57 | unsigned imm = fieldFromInstruction_4(insn, 16, 3) << 5; |
1985 | 57 | imm |= fieldFromInstruction_4(insn, 5, 5); |
1986 | | |
1987 | | // Tied operands added twice. |
1988 | 57 | DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder); |
1989 | 57 | DecodeVectorRegisterClass(Inst, Rd, Addr, Decoder); |
1990 | | |
1991 | 57 | MCOperand_CreateImm0(Inst, imm); |
1992 | 57 | MCOperand_CreateImm0(Inst, (cmode & 6) << 2); |
1993 | | |
1994 | 57 | return Success; |
1995 | 57 | } |
1996 | | |
1997 | | static DecodeStatus DecodeAdrInstruction(MCInst *Inst, uint32_t insn, |
1998 | | uint64_t Addr, const void *Decoder) |
1999 | 5.01k | { |
2000 | 5.01k | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
2001 | 5.01k | int64_t imm = fieldFromInstruction_4(insn, 5, 19) << 2; |
2002 | 5.01k | imm |= fieldFromInstruction_4(insn, 29, 2); |
2003 | | |
2004 | | // Sign-extend the 21-bit immediate. |
2005 | 5.01k | if (imm & (1 << (21 - 1))) |
2006 | 1.82k | imm |= ~((1LL << 21) - 1); |
2007 | | |
2008 | 5.01k | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
2009 | | //if (!Dis->tryAddingSymbolicOperand(Inst, imm, Addr, Fail, 0, 4)) |
2010 | 5.01k | MCOperand_CreateImm0(Inst, imm); |
2011 | | |
2012 | 5.01k | return Success; |
2013 | 5.01k | } |
2014 | | |
2015 | | static DecodeStatus DecodeAddSubImmShift(MCInst *Inst, uint32_t insn, |
2016 | | uint64_t Addr, const void *Decoder) |
2017 | 2.54k | { |
2018 | 2.54k | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
2019 | 2.54k | unsigned Rn = fieldFromInstruction_4(insn, 5, 5); |
2020 | 2.54k | unsigned Imm = fieldFromInstruction_4(insn, 10, 14); |
2021 | 2.54k | unsigned S = fieldFromInstruction_4(insn, 29, 1); |
2022 | 2.54k | unsigned Datasize = fieldFromInstruction_4(insn, 31, 1); |
2023 | | |
2024 | 2.54k | unsigned ShifterVal = (Imm >> 12) & 3; |
2025 | 2.54k | unsigned ImmVal = Imm & 0xFFF; |
2026 | | // const AArch64Disassembler *Dis = |
2027 | | // static_cast<const AArch64Disassembler *>(Decoder); |
2028 | | |
2029 | 2.54k | if (ShifterVal != 0 && ShifterVal != 1) |
2030 | 32 | return Fail; |
2031 | | |
2032 | 2.51k | if (Datasize) { |
2033 | 796 | if (Rd == 31 && !S) |
2034 | 22 | DecodeGPR64spRegisterClass(Inst, Rd, Addr, Decoder); |
2035 | 774 | else |
2036 | 774 | DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); |
2037 | 796 | DecodeGPR64spRegisterClass(Inst, Rn, Addr, Decoder); |
2038 | 1.71k | } else { |
2039 | 1.71k | if (Rd == 31 && !S) |
2040 | 280 | DecodeGPR32spRegisterClass(Inst, Rd, Addr, Decoder); |
2041 | 1.43k | else |
2042 | 1.43k | DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); |
2043 | 1.71k | DecodeGPR32spRegisterClass(Inst, Rn, Addr, Decoder); |
2044 | 1.71k | } |
2045 | | |
2046 | | // if (!Dis->tryAddingSymbolicOperand(Inst, Imm, Addr, Fail, 0, 4)) |
2047 | 2.51k | MCOperand_CreateImm0(Inst, ImmVal); |
2048 | | |
2049 | 2.51k | MCOperand_CreateImm0(Inst, (12 * ShifterVal)); |
2050 | 2.51k | return Success; |
2051 | 2.54k | } |
2052 | | |
2053 | | static DecodeStatus DecodeUnconditionalBranch(MCInst *Inst, uint32_t insn, |
2054 | | uint64_t Addr, const void *Decoder) |
2055 | 1.96k | { |
2056 | 1.96k | int64_t imm = fieldFromInstruction_4(insn, 0, 26); |
2057 | | |
2058 | | // Sign-extend the 26-bit immediate. |
2059 | 1.96k | if (imm & (1 << (26 - 1))) |
2060 | 1.24k | imm |= ~((1LL << 26) - 1); |
2061 | | |
2062 | | // if (!Dis->tryAddingSymbolicOperand(Inst, imm << 2, Addr, true, 0, 4)) |
2063 | 1.96k | MCOperand_CreateImm0(Inst, imm); |
2064 | | |
2065 | 1.96k | return Success; |
2066 | 1.96k | } |
2067 | | |
2068 | | static DecodeStatus DecodeSystemPStateInstruction(MCInst *Inst, |
2069 | | uint32_t insn, uint64_t Addr, const void *Decoder) |
2070 | 1.42k | { |
2071 | 1.42k | uint32_t op1 = fieldFromInstruction_4(insn, 16, 3); |
2072 | 1.42k | uint32_t op2 = fieldFromInstruction_4(insn, 5, 3); |
2073 | 1.42k | uint32_t crm = fieldFromInstruction_4(insn, 8, 4); |
2074 | 1.42k | uint32_t pstate_field = (op1 << 3) | op2; |
2075 | | |
2076 | 1.42k | if ((pstate_field == AArch64PState_PAN || |
2077 | 1.42k | pstate_field == AArch64PState_UAO) && crm > 1) |
2078 | 837 | return Fail; |
2079 | | |
2080 | 584 | MCOperand_CreateImm0(Inst, pstate_field); |
2081 | 584 | MCOperand_CreateImm0(Inst, crm); |
2082 | | |
2083 | 584 | if (lookupPStateByEncoding(pstate_field)) |
2084 | 201 | return Success; |
2085 | | |
2086 | 383 | return Fail; |
2087 | 584 | } |
2088 | | |
2089 | | static DecodeStatus DecodeTestAndBranch(MCInst *Inst, uint32_t insn, |
2090 | | uint64_t Addr, const void *Decoder) |
2091 | 2.07k | { |
2092 | 2.07k | uint32_t Rt = fieldFromInstruction_4(insn, 0, 5); |
2093 | 2.07k | uint32_t bit = fieldFromInstruction_4(insn, 31, 1) << 5; |
2094 | 2.07k | uint64_t dst = fieldFromInstruction_4(insn, 5, 14); |
2095 | | |
2096 | 2.07k | bit |= fieldFromInstruction_4(insn, 19, 5); |
2097 | | |
2098 | | // Sign-extend 14-bit immediate. |
2099 | 2.07k | if (dst & (1 << (14 - 1))) |
2100 | 1.49k | dst |= ~((1LL << 14) - 1); |
2101 | | |
2102 | 2.07k | if (fieldFromInstruction_4(insn, 31, 1) == 0) |
2103 | 1.06k | DecodeGPR32RegisterClass(Inst, Rt, Addr, Decoder); |
2104 | 1.00k | else |
2105 | 1.00k | DecodeGPR64RegisterClass(Inst, Rt, Addr, Decoder); |
2106 | | |
2107 | 2.07k | MCOperand_CreateImm0(Inst, bit); |
2108 | | |
2109 | | //if (!Dis->tryAddingSymbolicOperand(Inst, dst << 2, Addr, true, 0, 4)) |
2110 | 2.07k | MCOperand_CreateImm0(Inst, dst); |
2111 | | |
2112 | 2.07k | return Success; |
2113 | 2.07k | } |
2114 | | |
2115 | | static DecodeStatus DecodeGPRSeqPairsClassRegisterClass(MCInst *Inst, |
2116 | | unsigned RegClassID, unsigned RegNo, uint64_t Addr, const void *Decoder) |
2117 | 943 | { |
2118 | 943 | unsigned Register; |
2119 | | |
2120 | | // Register number must be even (see CASP instruction) |
2121 | 943 | if (RegNo & 0x1) |
2122 | 6 | return Fail; |
2123 | | |
2124 | 937 | Register = AArch64MCRegisterClasses[RegClassID].RegsBegin[RegNo / 2]; |
2125 | 937 | MCOperand_CreateReg0(Inst, Register); |
2126 | | |
2127 | 937 | return Success; |
2128 | 943 | } |
2129 | | |
2130 | | static DecodeStatus DecodeWSeqPairsClassRegisterClass(MCInst *Inst, |
2131 | | unsigned RegNo, uint64_t Addr, const void *Decoder) |
2132 | 146 | { |
2133 | 146 | return DecodeGPRSeqPairsClassRegisterClass(Inst, |
2134 | 146 | AArch64_WSeqPairsClassRegClassID, RegNo, Addr, Decoder); |
2135 | 146 | } |
2136 | | |
2137 | | static DecodeStatus DecodeXSeqPairsClassRegisterClass(MCInst *Inst, |
2138 | | unsigned RegNo, uint64_t Addr, const void *Decoder) |
2139 | 797 | { |
2140 | 797 | return DecodeGPRSeqPairsClassRegisterClass(Inst, |
2141 | 797 | AArch64_XSeqPairsClassRegClassID, RegNo, Addr, Decoder); |
2142 | 797 | } |
2143 | | |
2144 | | static DecodeStatus DecodeSVELogicalImmInstruction(MCInst *Inst, uint32_t insn, |
2145 | | uint64_t Addr, const void *Decoder) |
2146 | 11.1k | { |
2147 | 11.1k | unsigned Zdn = fieldFromInstruction_4(insn, 0, 5); |
2148 | 11.1k | unsigned imm = fieldFromInstruction_4(insn, 5, 13); |
2149 | | |
2150 | 11.1k | if (!AArch64_AM_isValidDecodeLogicalImmediate(imm, 64)) |
2151 | 2 | return Fail; |
2152 | | |
2153 | | // The same (tied) operand is added twice to the instruction. |
2154 | 11.1k | DecodeZPRRegisterClass(Inst, Zdn, Addr, Decoder); |
2155 | 11.1k | if (MCInst_getOpcode(Inst) != AArch64_DUPM_ZI) |
2156 | 3.44k | DecodeZPRRegisterClass(Inst, Zdn, Addr, Decoder); |
2157 | | |
2158 | 11.1k | MCOperand_CreateImm0(Inst, imm); |
2159 | | |
2160 | 11.1k | return Success; |
2161 | 11.1k | } |
2162 | | |
2163 | | static DecodeStatus DecodeSImm(MCInst *Inst, uint64_t Imm, uint64_t Address, |
2164 | | const void *Decoder, int Bits) |
2165 | 15.5k | { |
2166 | 15.5k | if (Imm & ~((1LL << Bits) - 1)) |
2167 | 0 | return Fail; |
2168 | | |
2169 | | // Imm is a signed immediate, so sign extend it. |
2170 | 15.5k | if (Imm & (1 << (Bits - 1))) |
2171 | 6.72k | Imm |= ~((1LL << Bits) - 1); |
2172 | | |
2173 | 15.5k | MCOperand_CreateImm0(Inst, Imm); |
2174 | | |
2175 | 15.5k | return Success; |
2176 | 15.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 | 1.93k | { |
2182 | 1.93k | unsigned Val = (uint8_t)Imm; |
2183 | 1.93k | unsigned Shift = (Imm & 0x100) ? 8 : 0; |
2184 | | |
2185 | 1.93k | if (ElementWidth == 8 && Shift) |
2186 | 5 | return Fail; |
2187 | | |
2188 | 1.92k | MCOperand_CreateImm0(Inst, Val); |
2189 | 1.92k | MCOperand_CreateImm0(Inst, Shift); |
2190 | | |
2191 | 1.92k | return Success; |
2192 | 1.93k | } |
2193 | | |
2194 | | // Decode uimm4 ranged from 1-16. |
2195 | | static DecodeStatus DecodeSVEIncDecImm(MCInst *Inst, unsigned Imm, |
2196 | | uint64_t Addr, const void *Decoder) |
2197 | 7.39k | { |
2198 | 7.39k | MCOperand_CreateImm0(Inst, Imm + 1); |
2199 | | |
2200 | 7.39k | return Success; |
2201 | 7.39k | } |
2202 | | |
2203 | | static DecodeStatus DecodeSVCROp(MCInst *Inst, unsigned Imm, uint64_t Address, |
2204 | 727 | const void *Decoder) { |
2205 | 727 | if (lookupSVCRByEncoding(Imm)) { |
2206 | 348 | MCOperand_CreateImm0(Inst, Imm); |
2207 | 348 | return Success; |
2208 | 348 | } |
2209 | 379 | return Fail; |
2210 | 727 | } |
2211 | | |
2212 | | static DecodeStatus DecodeCPYMemOpInstruction(MCInst *Inst, uint32_t insn, |
2213 | 27 | uint64_t Addr, const void *Decoder) { |
2214 | 27 | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
2215 | 27 | unsigned Rs = fieldFromInstruction_4(insn, 16, 5); |
2216 | 27 | 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 | 27 | if (Rd == Rs || Rs == Rn || Rd == Rn) |
2221 | 4 | 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 | 23 | if (!DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) || |
2226 | 23 | !DecodeGPR64commonRegisterClass(Inst, Rs, Addr, Decoder) || |
2227 | 23 | !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) || |
2228 | 23 | !DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) || |
2229 | 23 | !DecodeGPR64commonRegisterClass(Inst, Rs, Addr, Decoder) || |
2230 | 23 | !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder)) |
2231 | 2 | return Fail; |
2232 | | |
2233 | 21 | return Success; |
2234 | 23 | } |
2235 | | |
2236 | | static DecodeStatus DecodeSETMemOpInstruction(MCInst *Inst, uint32_t insn, |
2237 | 48 | uint64_t Addr, const void *Decoder) { |
2238 | 48 | unsigned Rd = fieldFromInstruction_4(insn, 0, 5); |
2239 | 48 | unsigned Rm = fieldFromInstruction_4(insn, 16, 5); |
2240 | 48 | 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 | 48 | if (Rd == Rm || Rm == Rn || Rd == Rn) |
2245 | 4 | 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 | 44 | if (!DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) || |
2250 | 44 | !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) || |
2251 | 44 | !DecodeGPR64commonRegisterClass(Inst, Rd, Addr, Decoder) || |
2252 | 44 | !DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder) || |
2253 | 44 | !DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder)) |
2254 | 1 | return Fail; |
2255 | | |
2256 | 43 | return Success; |
2257 | 44 | } |
2258 | | |
2259 | | void AArch64_init(MCRegisterInfo *MRI) |
2260 | 10.1k | { |
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 | 10.1k | MCRegisterInfo_InitMCRegisterInfo(MRI, AArch64RegDesc, 674, |
2272 | 10.1k | 0, 0, |
2273 | 10.1k | AArch64MCRegisterClasses, 202, |
2274 | 10.1k | 0, 0, AArch64RegDiffLists, |
2275 | 10.1k | 0, |
2276 | 10.1k | AArch64SubRegIdxLists, 100, |
2277 | 10.1k | 0); |
2278 | 10.1k | } |
2279 | | |
2280 | | #endif |