1 /* Capstone Disassembly Engine */
2 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
3 
4 #ifdef CAPSTONE_HAS_ARM64
5 
6 #include <stdio.h>	// debug
7 #include <string.h>
8 
9 #include "../../utils.h"
10 
11 #include "AArch64Mapping.h"
12 
13 #define GET_INSTRINFO_ENUM
14 #include "AArch64GenInstrInfo.inc"
15 
16 #ifndef CAPSTONE_DIET
17 static const name_map reg_name_maps[] = {
18 	{ ARM64_REG_INVALID, NULL },
19 
20 	{ ARM64_REG_X29, "x29"},
21 	{ ARM64_REG_X30, "x30"},
22 	{ ARM64_REG_NZCV, "nzcv"},
23 	{ ARM64_REG_SP, "sp"},
24 	{ ARM64_REG_WSP, "wsp"},
25 	{ ARM64_REG_WZR, "wzr"},
26 	{ ARM64_REG_XZR, "xzr"},
27 	{ ARM64_REG_B0, "b0"},
28 	{ ARM64_REG_B1, "b1"},
29 	{ ARM64_REG_B2, "b2"},
30 	{ ARM64_REG_B3, "b3"},
31 	{ ARM64_REG_B4, "b4"},
32 	{ ARM64_REG_B5, "b5"},
33 	{ ARM64_REG_B6, "b6"},
34 	{ ARM64_REG_B7, "b7"},
35 	{ ARM64_REG_B8, "b8"},
36 	{ ARM64_REG_B9, "b9"},
37 	{ ARM64_REG_B10, "b10"},
38 	{ ARM64_REG_B11, "b11"},
39 	{ ARM64_REG_B12, "b12"},
40 	{ ARM64_REG_B13, "b13"},
41 	{ ARM64_REG_B14, "b14"},
42 	{ ARM64_REG_B15, "b15"},
43 	{ ARM64_REG_B16, "b16"},
44 	{ ARM64_REG_B17, "b17"},
45 	{ ARM64_REG_B18, "b18"},
46 	{ ARM64_REG_B19, "b19"},
47 	{ ARM64_REG_B20, "b20"},
48 	{ ARM64_REG_B21, "b21"},
49 	{ ARM64_REG_B22, "b22"},
50 	{ ARM64_REG_B23, "b23"},
51 	{ ARM64_REG_B24, "b24"},
52 	{ ARM64_REG_B25, "b25"},
53 	{ ARM64_REG_B26, "b26"},
54 	{ ARM64_REG_B27, "b27"},
55 	{ ARM64_REG_B28, "b28"},
56 	{ ARM64_REG_B29, "b29"},
57 	{ ARM64_REG_B30, "b30"},
58 	{ ARM64_REG_B31, "b31"},
59 	{ ARM64_REG_D0, "d0"},
60 	{ ARM64_REG_D1, "d1"},
61 	{ ARM64_REG_D2, "d2"},
62 	{ ARM64_REG_D3, "d3"},
63 	{ ARM64_REG_D4, "d4"},
64 	{ ARM64_REG_D5, "d5"},
65 	{ ARM64_REG_D6, "d6"},
66 	{ ARM64_REG_D7, "d7"},
67 	{ ARM64_REG_D8, "d8"},
68 	{ ARM64_REG_D9, "d9"},
69 	{ ARM64_REG_D10, "d10"},
70 	{ ARM64_REG_D11, "d11"},
71 	{ ARM64_REG_D12, "d12"},
72 	{ ARM64_REG_D13, "d13"},
73 	{ ARM64_REG_D14, "d14"},
74 	{ ARM64_REG_D15, "d15"},
75 	{ ARM64_REG_D16, "d16"},
76 	{ ARM64_REG_D17, "d17"},
77 	{ ARM64_REG_D18, "d18"},
78 	{ ARM64_REG_D19, "d19"},
79 	{ ARM64_REG_D20, "d20"},
80 	{ ARM64_REG_D21, "d21"},
81 	{ ARM64_REG_D22, "d22"},
82 	{ ARM64_REG_D23, "d23"},
83 	{ ARM64_REG_D24, "d24"},
84 	{ ARM64_REG_D25, "d25"},
85 	{ ARM64_REG_D26, "d26"},
86 	{ ARM64_REG_D27, "d27"},
87 	{ ARM64_REG_D28, "d28"},
88 	{ ARM64_REG_D29, "d29"},
89 	{ ARM64_REG_D30, "d30"},
90 	{ ARM64_REG_D31, "d31"},
91 	{ ARM64_REG_H0, "h0"},
92 	{ ARM64_REG_H1, "h1"},
93 	{ ARM64_REG_H2, "h2"},
94 	{ ARM64_REG_H3, "h3"},
95 	{ ARM64_REG_H4, "h4"},
96 	{ ARM64_REG_H5, "h5"},
97 	{ ARM64_REG_H6, "h6"},
98 	{ ARM64_REG_H7, "h7"},
99 	{ ARM64_REG_H8, "h8"},
100 	{ ARM64_REG_H9, "h9"},
101 	{ ARM64_REG_H10, "h10"},
102 	{ ARM64_REG_H11, "h11"},
103 	{ ARM64_REG_H12, "h12"},
104 	{ ARM64_REG_H13, "h13"},
105 	{ ARM64_REG_H14, "h14"},
106 	{ ARM64_REG_H15, "h15"},
107 	{ ARM64_REG_H16, "h16"},
108 	{ ARM64_REG_H17, "h17"},
109 	{ ARM64_REG_H18, "h18"},
110 	{ ARM64_REG_H19, "h19"},
111 	{ ARM64_REG_H20, "h20"},
112 	{ ARM64_REG_H21, "h21"},
113 	{ ARM64_REG_H22, "h22"},
114 	{ ARM64_REG_H23, "h23"},
115 	{ ARM64_REG_H24, "h24"},
116 	{ ARM64_REG_H25, "h25"},
117 	{ ARM64_REG_H26, "h26"},
118 	{ ARM64_REG_H27, "h27"},
119 	{ ARM64_REG_H28, "h28"},
120 	{ ARM64_REG_H29, "h29"},
121 	{ ARM64_REG_H30, "h30"},
122 	{ ARM64_REG_H31, "h31"},
123 	{ ARM64_REG_Q0, "q0"},
124 	{ ARM64_REG_Q1, "q1"},
125 	{ ARM64_REG_Q2, "q2"},
126 	{ ARM64_REG_Q3, "q3"},
127 	{ ARM64_REG_Q4, "q4"},
128 	{ ARM64_REG_Q5, "q5"},
129 	{ ARM64_REG_Q6, "q6"},
130 	{ ARM64_REG_Q7, "q7"},
131 	{ ARM64_REG_Q8, "q8"},
132 	{ ARM64_REG_Q9, "q9"},
133 	{ ARM64_REG_Q10, "q10"},
134 	{ ARM64_REG_Q11, "q11"},
135 	{ ARM64_REG_Q12, "q12"},
136 	{ ARM64_REG_Q13, "q13"},
137 	{ ARM64_REG_Q14, "q14"},
138 	{ ARM64_REG_Q15, "q15"},
139 	{ ARM64_REG_Q16, "q16"},
140 	{ ARM64_REG_Q17, "q17"},
141 	{ ARM64_REG_Q18, "q18"},
142 	{ ARM64_REG_Q19, "q19"},
143 	{ ARM64_REG_Q20, "q20"},
144 	{ ARM64_REG_Q21, "q21"},
145 	{ ARM64_REG_Q22, "q22"},
146 	{ ARM64_REG_Q23, "q23"},
147 	{ ARM64_REG_Q24, "q24"},
148 	{ ARM64_REG_Q25, "q25"},
149 	{ ARM64_REG_Q26, "q26"},
150 	{ ARM64_REG_Q27, "q27"},
151 	{ ARM64_REG_Q28, "q28"},
152 	{ ARM64_REG_Q29, "q29"},
153 	{ ARM64_REG_Q30, "q30"},
154 	{ ARM64_REG_Q31, "q31"},
155 	{ ARM64_REG_S0, "s0"},
156 	{ ARM64_REG_S1, "s1"},
157 	{ ARM64_REG_S2, "s2"},
158 	{ ARM64_REG_S3, "s3"},
159 	{ ARM64_REG_S4, "s4"},
160 	{ ARM64_REG_S5, "s5"},
161 	{ ARM64_REG_S6, "s6"},
162 	{ ARM64_REG_S7, "s7"},
163 	{ ARM64_REG_S8, "s8"},
164 	{ ARM64_REG_S9, "s9"},
165 	{ ARM64_REG_S10, "s10"},
166 	{ ARM64_REG_S11, "s11"},
167 	{ ARM64_REG_S12, "s12"},
168 	{ ARM64_REG_S13, "s13"},
169 	{ ARM64_REG_S14, "s14"},
170 	{ ARM64_REG_S15, "s15"},
171 	{ ARM64_REG_S16, "s16"},
172 	{ ARM64_REG_S17, "s17"},
173 	{ ARM64_REG_S18, "s18"},
174 	{ ARM64_REG_S19, "s19"},
175 	{ ARM64_REG_S20, "s20"},
176 	{ ARM64_REG_S21, "s21"},
177 	{ ARM64_REG_S22, "s22"},
178 	{ ARM64_REG_S23, "s23"},
179 	{ ARM64_REG_S24, "s24"},
180 	{ ARM64_REG_S25, "s25"},
181 	{ ARM64_REG_S26, "s26"},
182 	{ ARM64_REG_S27, "s27"},
183 	{ ARM64_REG_S28, "s28"},
184 	{ ARM64_REG_S29, "s29"},
185 	{ ARM64_REG_S30, "s30"},
186 	{ ARM64_REG_S31, "s31"},
187 	{ ARM64_REG_W0, "w0"},
188 	{ ARM64_REG_W1, "w1"},
189 	{ ARM64_REG_W2, "w2"},
190 	{ ARM64_REG_W3, "w3"},
191 	{ ARM64_REG_W4, "w4"},
192 	{ ARM64_REG_W5, "w5"},
193 	{ ARM64_REG_W6, "w6"},
194 	{ ARM64_REG_W7, "w7"},
195 	{ ARM64_REG_W8, "w8"},
196 	{ ARM64_REG_W9, "w9"},
197 	{ ARM64_REG_W10, "w10"},
198 	{ ARM64_REG_W11, "w11"},
199 	{ ARM64_REG_W12, "w12"},
200 	{ ARM64_REG_W13, "w13"},
201 	{ ARM64_REG_W14, "w14"},
202 	{ ARM64_REG_W15, "w15"},
203 	{ ARM64_REG_W16, "w16"},
204 	{ ARM64_REG_W17, "w17"},
205 	{ ARM64_REG_W18, "w18"},
206 	{ ARM64_REG_W19, "w19"},
207 	{ ARM64_REG_W20, "w20"},
208 	{ ARM64_REG_W21, "w21"},
209 	{ ARM64_REG_W22, "w22"},
210 	{ ARM64_REG_W23, "w23"},
211 	{ ARM64_REG_W24, "w24"},
212 	{ ARM64_REG_W25, "w25"},
213 	{ ARM64_REG_W26, "w26"},
214 	{ ARM64_REG_W27, "w27"},
215 	{ ARM64_REG_W28, "w28"},
216 	{ ARM64_REG_W29, "w29"},
217 	{ ARM64_REG_W30, "w30"},
218 	{ ARM64_REG_X0, "x0"},
219 	{ ARM64_REG_X1, "x1"},
220 	{ ARM64_REG_X2, "x2"},
221 	{ ARM64_REG_X3, "x3"},
222 	{ ARM64_REG_X4, "x4"},
223 	{ ARM64_REG_X5, "x5"},
224 	{ ARM64_REG_X6, "x6"},
225 	{ ARM64_REG_X7, "x7"},
226 	{ ARM64_REG_X8, "x8"},
227 	{ ARM64_REG_X9, "x9"},
228 	{ ARM64_REG_X10, "x10"},
229 	{ ARM64_REG_X11, "x11"},
230 	{ ARM64_REG_X12, "x12"},
231 	{ ARM64_REG_X13, "x13"},
232 	{ ARM64_REG_X14, "x14"},
233 	{ ARM64_REG_X15, "x15"},
234 	{ ARM64_REG_X16, "x16"},
235 	{ ARM64_REG_X17, "x17"},
236 	{ ARM64_REG_X18, "x18"},
237 	{ ARM64_REG_X19, "x19"},
238 	{ ARM64_REG_X20, "x20"},
239 	{ ARM64_REG_X21, "x21"},
240 	{ ARM64_REG_X22, "x22"},
241 	{ ARM64_REG_X23, "x23"},
242 	{ ARM64_REG_X24, "x24"},
243 	{ ARM64_REG_X25, "x25"},
244 	{ ARM64_REG_X26, "x26"},
245 	{ ARM64_REG_X27, "x27"},
246 	{ ARM64_REG_X28, "x28"},
247 
248 	{ ARM64_REG_V0, "v0"},
249 	{ ARM64_REG_V1, "v1"},
250 	{ ARM64_REG_V2, "v2"},
251 	{ ARM64_REG_V3, "v3"},
252 	{ ARM64_REG_V4, "v4"},
253 	{ ARM64_REG_V5, "v5"},
254 	{ ARM64_REG_V6, "v6"},
255 	{ ARM64_REG_V7, "v7"},
256 	{ ARM64_REG_V8, "v8"},
257 	{ ARM64_REG_V9, "v9"},
258 	{ ARM64_REG_V10, "v10"},
259 	{ ARM64_REG_V11, "v11"},
260 	{ ARM64_REG_V12, "v12"},
261 	{ ARM64_REG_V13, "v13"},
262 	{ ARM64_REG_V14, "v14"},
263 	{ ARM64_REG_V15, "v15"},
264 	{ ARM64_REG_V16, "v16"},
265 	{ ARM64_REG_V17, "v17"},
266 	{ ARM64_REG_V18, "v18"},
267 	{ ARM64_REG_V19, "v19"},
268 	{ ARM64_REG_V20, "v20"},
269 	{ ARM64_REG_V21, "v21"},
270 	{ ARM64_REG_V22, "v22"},
271 	{ ARM64_REG_V23, "v23"},
272 	{ ARM64_REG_V24, "v24"},
273 	{ ARM64_REG_V25, "v25"},
274 	{ ARM64_REG_V26, "v26"},
275 	{ ARM64_REG_V27, "v27"},
276 	{ ARM64_REG_V28, "v28"},
277 	{ ARM64_REG_V29, "v29"},
278 	{ ARM64_REG_V30, "v30"},
279 	{ ARM64_REG_V31, "v31"},
280 };
281 #endif
282 
AArch64_reg_name(csh handle,unsigned int reg)283 const char *AArch64_reg_name(csh handle, unsigned int reg)
284 {
285 #ifndef CAPSTONE_DIET
286 	if (reg >= ARR_SIZE(reg_name_maps))
287 		return NULL;
288 
289 	return reg_name_maps[reg].name;
290 #else
291 	return NULL;
292 #endif
293 }
294 
295 static const insn_map insns[] = {
296 	// dummy item
297 	{
298 		0, 0,
299 #ifndef CAPSTONE_DIET
300 		{ 0 }, { 0 }, { 0 }, 0, 0
301 #endif
302 	},
303 
304 #include "AArch64MappingInsn.inc"
305 };
306 
307 // given internal insn id, return public instruction info
AArch64_get_insn_id(cs_struct * h,cs_insn * insn,unsigned int id)308 void AArch64_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id)
309 {
310 	int i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache);
311 	if (i != 0) {
312 		insn->id = insns[i].mapid;
313 
314 		if (h->detail) {
315 #ifndef CAPSTONE_DIET
316 			cs_struct handle;
317 			handle.detail = h->detail;
318 
319 			memcpy(insn->detail->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use));
320 			insn->detail->regs_read_count = (uint8_t)count_positive(insns[i].regs_use);
321 
322 			memcpy(insn->detail->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod));
323 			insn->detail->regs_write_count = (uint8_t)count_positive(insns[i].regs_mod);
324 
325 			memcpy(insn->detail->groups, insns[i].groups, sizeof(insns[i].groups));
326 			insn->detail->groups_count = (uint8_t)count_positive8(insns[i].groups);
327 
328 			insn->detail->arm64.update_flags = cs_reg_write((csh)&handle, insn, ARM64_REG_NZCV);
329 #endif
330 		}
331 	}
332 }
333 
334 static const name_map insn_name_maps[] = {
335 	{ ARM64_INS_INVALID, NULL },
336 
337 	{ ARM64_INS_ABS, "abs" },
338 	{ ARM64_INS_ADC, "adc" },
339 	{ ARM64_INS_ADDHN, "addhn" },
340 	{ ARM64_INS_ADDHN2, "addhn2" },
341 	{ ARM64_INS_ADDP, "addp" },
342 	{ ARM64_INS_ADD, "add" },
343 	{ ARM64_INS_ADDV, "addv" },
344 	{ ARM64_INS_ADR, "adr" },
345 	{ ARM64_INS_ADRP, "adrp" },
346 	{ ARM64_INS_AESD, "aesd" },
347 	{ ARM64_INS_AESE, "aese" },
348 	{ ARM64_INS_AESIMC, "aesimc" },
349 	{ ARM64_INS_AESMC, "aesmc" },
350 	{ ARM64_INS_AND, "and" },
351 	{ ARM64_INS_ASR, "asr" },
352 	{ ARM64_INS_B, "b" },
353 	{ ARM64_INS_BFM, "bfm" },
354 	{ ARM64_INS_BIC, "bic" },
355 	{ ARM64_INS_BIF, "bif" },
356 	{ ARM64_INS_BIT, "bit" },
357 	{ ARM64_INS_BL, "bl" },
358 	{ ARM64_INS_BLR, "blr" },
359 	{ ARM64_INS_BR, "br" },
360 	{ ARM64_INS_BRK, "brk" },
361 	{ ARM64_INS_BSL, "bsl" },
362 	{ ARM64_INS_CBNZ, "cbnz" },
363 	{ ARM64_INS_CBZ, "cbz" },
364 	{ ARM64_INS_CCMN, "ccmn" },
365 	{ ARM64_INS_CCMP, "ccmp" },
366 	{ ARM64_INS_CLREX, "clrex" },
367 	{ ARM64_INS_CLS, "cls" },
368 	{ ARM64_INS_CLZ, "clz" },
369 	{ ARM64_INS_CMEQ, "cmeq" },
370 	{ ARM64_INS_CMGE, "cmge" },
371 	{ ARM64_INS_CMGT, "cmgt" },
372 	{ ARM64_INS_CMHI, "cmhi" },
373 	{ ARM64_INS_CMHS, "cmhs" },
374 	{ ARM64_INS_CMLE, "cmle" },
375 	{ ARM64_INS_CMLT, "cmlt" },
376 	{ ARM64_INS_CMTST, "cmtst" },
377 	{ ARM64_INS_CNT, "cnt" },
378 	{ ARM64_INS_MOV, "mov" },
379 	{ ARM64_INS_CRC32B, "crc32b" },
380 	{ ARM64_INS_CRC32CB, "crc32cb" },
381 	{ ARM64_INS_CRC32CH, "crc32ch" },
382 	{ ARM64_INS_CRC32CW, "crc32cw" },
383 	{ ARM64_INS_CRC32CX, "crc32cx" },
384 	{ ARM64_INS_CRC32H, "crc32h" },
385 	{ ARM64_INS_CRC32W, "crc32w" },
386 	{ ARM64_INS_CRC32X, "crc32x" },
387 	{ ARM64_INS_CSEL, "csel" },
388 	{ ARM64_INS_CSINC, "csinc" },
389 	{ ARM64_INS_CSINV, "csinv" },
390 	{ ARM64_INS_CSNEG, "csneg" },
391 	{ ARM64_INS_DCPS1, "dcps1" },
392 	{ ARM64_INS_DCPS2, "dcps2" },
393 	{ ARM64_INS_DCPS3, "dcps3" },
394 	{ ARM64_INS_DMB, "dmb" },
395 	{ ARM64_INS_DRPS, "drps" },
396 	{ ARM64_INS_DSB, "dsb" },
397 	{ ARM64_INS_DUP, "dup" },
398 	{ ARM64_INS_EON, "eon" },
399 	{ ARM64_INS_EOR, "eor" },
400 	{ ARM64_INS_ERET, "eret" },
401 	{ ARM64_INS_EXTR, "extr" },
402 	{ ARM64_INS_EXT, "ext" },
403 	{ ARM64_INS_FABD, "fabd" },
404 	{ ARM64_INS_FABS, "fabs" },
405 	{ ARM64_INS_FACGE, "facge" },
406 	{ ARM64_INS_FACGT, "facgt" },
407 	{ ARM64_INS_FADD, "fadd" },
408 	{ ARM64_INS_FADDP, "faddp" },
409 	{ ARM64_INS_FCCMP, "fccmp" },
410 	{ ARM64_INS_FCCMPE, "fccmpe" },
411 	{ ARM64_INS_FCMEQ, "fcmeq" },
412 	{ ARM64_INS_FCMGE, "fcmge" },
413 	{ ARM64_INS_FCMGT, "fcmgt" },
414 	{ ARM64_INS_FCMLE, "fcmle" },
415 	{ ARM64_INS_FCMLT, "fcmlt" },
416 	{ ARM64_INS_FCMP, "fcmp" },
417 	{ ARM64_INS_FCMPE, "fcmpe" },
418 	{ ARM64_INS_FCSEL, "fcsel" },
419 	{ ARM64_INS_FCVTAS, "fcvtas" },
420 	{ ARM64_INS_FCVTAU, "fcvtau" },
421 	{ ARM64_INS_FCVT, "fcvt" },
422 	{ ARM64_INS_FCVTL, "fcvtl" },
423 	{ ARM64_INS_FCVTL2, "fcvtl2" },
424 	{ ARM64_INS_FCVTMS, "fcvtms" },
425 	{ ARM64_INS_FCVTMU, "fcvtmu" },
426 	{ ARM64_INS_FCVTNS, "fcvtns" },
427 	{ ARM64_INS_FCVTNU, "fcvtnu" },
428 	{ ARM64_INS_FCVTN, "fcvtn" },
429 	{ ARM64_INS_FCVTN2, "fcvtn2" },
430 	{ ARM64_INS_FCVTPS, "fcvtps" },
431 	{ ARM64_INS_FCVTPU, "fcvtpu" },
432 	{ ARM64_INS_FCVTXN, "fcvtxn" },
433 	{ ARM64_INS_FCVTXN2, "fcvtxn2" },
434 	{ ARM64_INS_FCVTZS, "fcvtzs" },
435 	{ ARM64_INS_FCVTZU, "fcvtzu" },
436 	{ ARM64_INS_FDIV, "fdiv" },
437 	{ ARM64_INS_FMADD, "fmadd" },
438 	{ ARM64_INS_FMAX, "fmax" },
439 	{ ARM64_INS_FMAXNM, "fmaxnm" },
440 	{ ARM64_INS_FMAXNMP, "fmaxnmp" },
441 	{ ARM64_INS_FMAXNMV, "fmaxnmv" },
442 	{ ARM64_INS_FMAXP, "fmaxp" },
443 	{ ARM64_INS_FMAXV, "fmaxv" },
444 	{ ARM64_INS_FMIN, "fmin" },
445 	{ ARM64_INS_FMINNM, "fminnm" },
446 	{ ARM64_INS_FMINNMP, "fminnmp" },
447 	{ ARM64_INS_FMINNMV, "fminnmv" },
448 	{ ARM64_INS_FMINP, "fminp" },
449 	{ ARM64_INS_FMINV, "fminv" },
450 	{ ARM64_INS_FMLA, "fmla" },
451 	{ ARM64_INS_FMLS, "fmls" },
452 	{ ARM64_INS_FMOV, "fmov" },
453 	{ ARM64_INS_FMSUB, "fmsub" },
454 	{ ARM64_INS_FMUL, "fmul" },
455 	{ ARM64_INS_FMULX, "fmulx" },
456 	{ ARM64_INS_FNEG, "fneg" },
457 	{ ARM64_INS_FNMADD, "fnmadd" },
458 	{ ARM64_INS_FNMSUB, "fnmsub" },
459 	{ ARM64_INS_FNMUL, "fnmul" },
460 	{ ARM64_INS_FRECPE, "frecpe" },
461 	{ ARM64_INS_FRECPS, "frecps" },
462 	{ ARM64_INS_FRECPX, "frecpx" },
463 	{ ARM64_INS_FRINTA, "frinta" },
464 	{ ARM64_INS_FRINTI, "frinti" },
465 	{ ARM64_INS_FRINTM, "frintm" },
466 	{ ARM64_INS_FRINTN, "frintn" },
467 	{ ARM64_INS_FRINTP, "frintp" },
468 	{ ARM64_INS_FRINTX, "frintx" },
469 	{ ARM64_INS_FRINTZ, "frintz" },
470 	{ ARM64_INS_FRSQRTE, "frsqrte" },
471 	{ ARM64_INS_FRSQRTS, "frsqrts" },
472 	{ ARM64_INS_FSQRT, "fsqrt" },
473 	{ ARM64_INS_FSUB, "fsub" },
474 	{ ARM64_INS_HINT, "hint" },
475 	{ ARM64_INS_HLT, "hlt" },
476 	{ ARM64_INS_HVC, "hvc" },
477 	{ ARM64_INS_INS, "ins" },
478 	{ ARM64_INS_ISB, "isb" },
479 	{ ARM64_INS_LD1, "ld1" },
480 	{ ARM64_INS_LD1R, "ld1r" },
481 	{ ARM64_INS_LD2R, "ld2r" },
482 	{ ARM64_INS_LD2, "ld2" },
483 	{ ARM64_INS_LD3R, "ld3r" },
484 	{ ARM64_INS_LD3, "ld3" },
485 	{ ARM64_INS_LD4, "ld4" },
486 	{ ARM64_INS_LD4R, "ld4r" },
487 	{ ARM64_INS_LDARB, "ldarb" },
488 	{ ARM64_INS_LDARH, "ldarh" },
489 	{ ARM64_INS_LDAR, "ldar" },
490 	{ ARM64_INS_LDAXP, "ldaxp" },
491 	{ ARM64_INS_LDAXRB, "ldaxrb" },
492 	{ ARM64_INS_LDAXRH, "ldaxrh" },
493 	{ ARM64_INS_LDAXR, "ldaxr" },
494 	{ ARM64_INS_LDNP, "ldnp" },
495 	{ ARM64_INS_LDP, "ldp" },
496 	{ ARM64_INS_LDPSW, "ldpsw" },
497 	{ ARM64_INS_LDRB, "ldrb" },
498 	{ ARM64_INS_LDR, "ldr" },
499 	{ ARM64_INS_LDRH, "ldrh" },
500 	{ ARM64_INS_LDRSB, "ldrsb" },
501 	{ ARM64_INS_LDRSH, "ldrsh" },
502 	{ ARM64_INS_LDRSW, "ldrsw" },
503 	{ ARM64_INS_LDTRB, "ldtrb" },
504 	{ ARM64_INS_LDTRH, "ldtrh" },
505 	{ ARM64_INS_LDTRSB, "ldtrsb" },
506 	{ ARM64_INS_LDTRSH, "ldtrsh" },
507 	{ ARM64_INS_LDTRSW, "ldtrsw" },
508 	{ ARM64_INS_LDTR, "ldtr" },
509 	{ ARM64_INS_LDURB, "ldurb" },
510 	{ ARM64_INS_LDUR, "ldur" },
511 	{ ARM64_INS_LDURH, "ldurh" },
512 	{ ARM64_INS_LDURSB, "ldursb" },
513 	{ ARM64_INS_LDURSH, "ldursh" },
514 	{ ARM64_INS_LDURSW, "ldursw" },
515 	{ ARM64_INS_LDXP, "ldxp" },
516 	{ ARM64_INS_LDXRB, "ldxrb" },
517 	{ ARM64_INS_LDXRH, "ldxrh" },
518 	{ ARM64_INS_LDXR, "ldxr" },
519 	{ ARM64_INS_LSL, "lsl" },
520 	{ ARM64_INS_LSR, "lsr" },
521 	{ ARM64_INS_MADD, "madd" },
522 	{ ARM64_INS_MLA, "mla" },
523 	{ ARM64_INS_MLS, "mls" },
524 	{ ARM64_INS_MOVI, "movi" },
525 	{ ARM64_INS_MOVK, "movk" },
526 	{ ARM64_INS_MOVN, "movn" },
527 	{ ARM64_INS_MOVZ, "movz" },
528 	{ ARM64_INS_MRS, "mrs" },
529 	{ ARM64_INS_MSR, "msr" },
530 	{ ARM64_INS_MSUB, "msub" },
531 	{ ARM64_INS_MUL, "mul" },
532 	{ ARM64_INS_MVNI, "mvni" },
533 	{ ARM64_INS_NEG, "neg" },
534 	{ ARM64_INS_NOT, "not" },
535 	{ ARM64_INS_ORN, "orn" },
536 	{ ARM64_INS_ORR, "orr" },
537 	{ ARM64_INS_PMULL2, "pmull2" },
538 	{ ARM64_INS_PMULL, "pmull" },
539 	{ ARM64_INS_PMUL, "pmul" },
540 	{ ARM64_INS_PRFM, "prfm" },
541 	{ ARM64_INS_PRFUM, "prfum" },
542 	{ ARM64_INS_RADDHN, "raddhn" },
543 	{ ARM64_INS_RADDHN2, "raddhn2" },
544 	{ ARM64_INS_RBIT, "rbit" },
545 	{ ARM64_INS_RET, "ret" },
546 	{ ARM64_INS_REV16, "rev16" },
547 	{ ARM64_INS_REV32, "rev32" },
548 	{ ARM64_INS_REV64, "rev64" },
549 	{ ARM64_INS_REV, "rev" },
550 	{ ARM64_INS_ROR, "ror" },
551 	{ ARM64_INS_RSHRN2, "rshrn2" },
552 	{ ARM64_INS_RSHRN, "rshrn" },
553 	{ ARM64_INS_RSUBHN, "rsubhn" },
554 	{ ARM64_INS_RSUBHN2, "rsubhn2" },
555 	{ ARM64_INS_SABAL2, "sabal2" },
556 	{ ARM64_INS_SABAL, "sabal" },
557 	{ ARM64_INS_SABA, "saba" },
558 	{ ARM64_INS_SABDL2, "sabdl2" },
559 	{ ARM64_INS_SABDL, "sabdl" },
560 	{ ARM64_INS_SABD, "sabd" },
561 	{ ARM64_INS_SADALP, "sadalp" },
562 	{ ARM64_INS_SADDLP, "saddlp" },
563 	{ ARM64_INS_SADDLV, "saddlv" },
564 	{ ARM64_INS_SADDL2, "saddl2" },
565 	{ ARM64_INS_SADDL, "saddl" },
566 	{ ARM64_INS_SADDW2, "saddw2" },
567 	{ ARM64_INS_SADDW, "saddw" },
568 	{ ARM64_INS_SBC, "sbc" },
569 	{ ARM64_INS_SBFM, "sbfm" },
570 	{ ARM64_INS_SCVTF, "scvtf" },
571 	{ ARM64_INS_SDIV, "sdiv" },
572 	{ ARM64_INS_SHA1C, "sha1c" },
573 	{ ARM64_INS_SHA1H, "sha1h" },
574 	{ ARM64_INS_SHA1M, "sha1m" },
575 	{ ARM64_INS_SHA1P, "sha1p" },
576 	{ ARM64_INS_SHA1SU0, "sha1su0" },
577 	{ ARM64_INS_SHA1SU1, "sha1su1" },
578 	{ ARM64_INS_SHA256H2, "sha256h2" },
579 	{ ARM64_INS_SHA256H, "sha256h" },
580 	{ ARM64_INS_SHA256SU0, "sha256su0" },
581 	{ ARM64_INS_SHA256SU1, "sha256su1" },
582 	{ ARM64_INS_SHADD, "shadd" },
583 	{ ARM64_INS_SHLL2, "shll2" },
584 	{ ARM64_INS_SHLL, "shll" },
585 	{ ARM64_INS_SHL, "shl" },
586 	{ ARM64_INS_SHRN2, "shrn2" },
587 	{ ARM64_INS_SHRN, "shrn" },
588 	{ ARM64_INS_SHSUB, "shsub" },
589 	{ ARM64_INS_SLI, "sli" },
590 	{ ARM64_INS_SMADDL, "smaddl" },
591 	{ ARM64_INS_SMAXP, "smaxp" },
592 	{ ARM64_INS_SMAXV, "smaxv" },
593 	{ ARM64_INS_SMAX, "smax" },
594 	{ ARM64_INS_SMC, "smc" },
595 	{ ARM64_INS_SMINP, "sminp" },
596 	{ ARM64_INS_SMINV, "sminv" },
597 	{ ARM64_INS_SMIN, "smin" },
598 	{ ARM64_INS_SMLAL2, "smlal2" },
599 	{ ARM64_INS_SMLAL, "smlal" },
600 	{ ARM64_INS_SMLSL2, "smlsl2" },
601 	{ ARM64_INS_SMLSL, "smlsl" },
602 	{ ARM64_INS_SMOV, "smov" },
603 	{ ARM64_INS_SMSUBL, "smsubl" },
604 	{ ARM64_INS_SMULH, "smulh" },
605 	{ ARM64_INS_SMULL2, "smull2" },
606 	{ ARM64_INS_SMULL, "smull" },
607 	{ ARM64_INS_SQABS, "sqabs" },
608 	{ ARM64_INS_SQADD, "sqadd" },
609 	{ ARM64_INS_SQDMLAL, "sqdmlal" },
610 	{ ARM64_INS_SQDMLAL2, "sqdmlal2" },
611 	{ ARM64_INS_SQDMLSL, "sqdmlsl" },
612 	{ ARM64_INS_SQDMLSL2, "sqdmlsl2" },
613 	{ ARM64_INS_SQDMULH, "sqdmulh" },
614 	{ ARM64_INS_SQDMULL, "sqdmull" },
615 	{ ARM64_INS_SQDMULL2, "sqdmull2" },
616 	{ ARM64_INS_SQNEG, "sqneg" },
617 	{ ARM64_INS_SQRDMULH, "sqrdmulh" },
618 	{ ARM64_INS_SQRSHL, "sqrshl" },
619 	{ ARM64_INS_SQRSHRN, "sqrshrn" },
620 	{ ARM64_INS_SQRSHRN2, "sqrshrn2" },
621 	{ ARM64_INS_SQRSHRUN, "sqrshrun" },
622 	{ ARM64_INS_SQRSHRUN2, "sqrshrun2" },
623 	{ ARM64_INS_SQSHLU, "sqshlu" },
624 	{ ARM64_INS_SQSHL, "sqshl" },
625 	{ ARM64_INS_SQSHRN, "sqshrn" },
626 	{ ARM64_INS_SQSHRN2, "sqshrn2" },
627 	{ ARM64_INS_SQSHRUN, "sqshrun" },
628 	{ ARM64_INS_SQSHRUN2, "sqshrun2" },
629 	{ ARM64_INS_SQSUB, "sqsub" },
630 	{ ARM64_INS_SQXTN2, "sqxtn2" },
631 	{ ARM64_INS_SQXTN, "sqxtn" },
632 	{ ARM64_INS_SQXTUN2, "sqxtun2" },
633 	{ ARM64_INS_SQXTUN, "sqxtun" },
634 	{ ARM64_INS_SRHADD, "srhadd" },
635 	{ ARM64_INS_SRI, "sri" },
636 	{ ARM64_INS_SRSHL, "srshl" },
637 	{ ARM64_INS_SRSHR, "srshr" },
638 	{ ARM64_INS_SRSRA, "srsra" },
639 	{ ARM64_INS_SSHLL2, "sshll2" },
640 	{ ARM64_INS_SSHLL, "sshll" },
641 	{ ARM64_INS_SSHL, "sshl" },
642 	{ ARM64_INS_SSHR, "sshr" },
643 	{ ARM64_INS_SSRA, "ssra" },
644 	{ ARM64_INS_SSUBL2, "ssubl2" },
645 	{ ARM64_INS_SSUBL, "ssubl" },
646 	{ ARM64_INS_SSUBW2, "ssubw2" },
647 	{ ARM64_INS_SSUBW, "ssubw" },
648 	{ ARM64_INS_ST1, "st1" },
649 	{ ARM64_INS_ST2, "st2" },
650 	{ ARM64_INS_ST3, "st3" },
651 	{ ARM64_INS_ST4, "st4" },
652 	{ ARM64_INS_STLRB, "stlrb" },
653 	{ ARM64_INS_STLRH, "stlrh" },
654 	{ ARM64_INS_STLR, "stlr" },
655 	{ ARM64_INS_STLXP, "stlxp" },
656 	{ ARM64_INS_STLXRB, "stlxrb" },
657 	{ ARM64_INS_STLXRH, "stlxrh" },
658 	{ ARM64_INS_STLXR, "stlxr" },
659 	{ ARM64_INS_STNP, "stnp" },
660 	{ ARM64_INS_STP, "stp" },
661 	{ ARM64_INS_STRB, "strb" },
662 	{ ARM64_INS_STR, "str" },
663 	{ ARM64_INS_STRH, "strh" },
664 	{ ARM64_INS_STTRB, "sttrb" },
665 	{ ARM64_INS_STTRH, "sttrh" },
666 	{ ARM64_INS_STTR, "sttr" },
667 	{ ARM64_INS_STURB, "sturb" },
668 	{ ARM64_INS_STUR, "stur" },
669 	{ ARM64_INS_STURH, "sturh" },
670 	{ ARM64_INS_STXP, "stxp" },
671 	{ ARM64_INS_STXRB, "stxrb" },
672 	{ ARM64_INS_STXRH, "stxrh" },
673 	{ ARM64_INS_STXR, "stxr" },
674 	{ ARM64_INS_SUBHN, "subhn" },
675 	{ ARM64_INS_SUBHN2, "subhn2" },
676 	{ ARM64_INS_SUB, "sub" },
677 	{ ARM64_INS_SUQADD, "suqadd" },
678 	{ ARM64_INS_SVC, "svc" },
679 	{ ARM64_INS_SYSL, "sysl" },
680 	{ ARM64_INS_SYS, "sys" },
681 	{ ARM64_INS_TBL, "tbl" },
682 	{ ARM64_INS_TBNZ, "tbnz" },
683 	{ ARM64_INS_TBX, "tbx" },
684 	{ ARM64_INS_TBZ, "tbz" },
685 	{ ARM64_INS_TRN1, "trn1" },
686 	{ ARM64_INS_TRN2, "trn2" },
687 	{ ARM64_INS_UABAL2, "uabal2" },
688 	{ ARM64_INS_UABAL, "uabal" },
689 	{ ARM64_INS_UABA, "uaba" },
690 	{ ARM64_INS_UABDL2, "uabdl2" },
691 	{ ARM64_INS_UABDL, "uabdl" },
692 	{ ARM64_INS_UABD, "uabd" },
693 	{ ARM64_INS_UADALP, "uadalp" },
694 	{ ARM64_INS_UADDLP, "uaddlp" },
695 	{ ARM64_INS_UADDLV, "uaddlv" },
696 	{ ARM64_INS_UADDL2, "uaddl2" },
697 	{ ARM64_INS_UADDL, "uaddl" },
698 	{ ARM64_INS_UADDW2, "uaddw2" },
699 	{ ARM64_INS_UADDW, "uaddw" },
700 	{ ARM64_INS_UBFM, "ubfm" },
701 	{ ARM64_INS_UCVTF, "ucvtf" },
702 	{ ARM64_INS_UDIV, "udiv" },
703 	{ ARM64_INS_UHADD, "uhadd" },
704 	{ ARM64_INS_UHSUB, "uhsub" },
705 	{ ARM64_INS_UMADDL, "umaddl" },
706 	{ ARM64_INS_UMAXP, "umaxp" },
707 	{ ARM64_INS_UMAXV, "umaxv" },
708 	{ ARM64_INS_UMAX, "umax" },
709 	{ ARM64_INS_UMINP, "uminp" },
710 	{ ARM64_INS_UMINV, "uminv" },
711 	{ ARM64_INS_UMIN, "umin" },
712 	{ ARM64_INS_UMLAL2, "umlal2" },
713 	{ ARM64_INS_UMLAL, "umlal" },
714 	{ ARM64_INS_UMLSL2, "umlsl2" },
715 	{ ARM64_INS_UMLSL, "umlsl" },
716 	{ ARM64_INS_UMOV, "umov" },
717 	{ ARM64_INS_UMSUBL, "umsubl" },
718 	{ ARM64_INS_UMULH, "umulh" },
719 	{ ARM64_INS_UMULL2, "umull2" },
720 	{ ARM64_INS_UMULL, "umull" },
721 	{ ARM64_INS_UQADD, "uqadd" },
722 	{ ARM64_INS_UQRSHL, "uqrshl" },
723 	{ ARM64_INS_UQRSHRN, "uqrshrn" },
724 	{ ARM64_INS_UQRSHRN2, "uqrshrn2" },
725 	{ ARM64_INS_UQSHL, "uqshl" },
726 	{ ARM64_INS_UQSHRN, "uqshrn" },
727 	{ ARM64_INS_UQSHRN2, "uqshrn2" },
728 	{ ARM64_INS_UQSUB, "uqsub" },
729 	{ ARM64_INS_UQXTN2, "uqxtn2" },
730 	{ ARM64_INS_UQXTN, "uqxtn" },
731 	{ ARM64_INS_URECPE, "urecpe" },
732 	{ ARM64_INS_URHADD, "urhadd" },
733 	{ ARM64_INS_URSHL, "urshl" },
734 	{ ARM64_INS_URSHR, "urshr" },
735 	{ ARM64_INS_URSQRTE, "ursqrte" },
736 	{ ARM64_INS_URSRA, "ursra" },
737 	{ ARM64_INS_USHLL2, "ushll2" },
738 	{ ARM64_INS_USHLL, "ushll" },
739 	{ ARM64_INS_USHL, "ushl" },
740 	{ ARM64_INS_USHR, "ushr" },
741 	{ ARM64_INS_USQADD, "usqadd" },
742 	{ ARM64_INS_USRA, "usra" },
743 	{ ARM64_INS_USUBL2, "usubl2" },
744 	{ ARM64_INS_USUBL, "usubl" },
745 	{ ARM64_INS_USUBW2, "usubw2" },
746 	{ ARM64_INS_USUBW, "usubw" },
747 	{ ARM64_INS_UZP1, "uzp1" },
748 	{ ARM64_INS_UZP2, "uzp2" },
749 	{ ARM64_INS_XTN2, "xtn2" },
750 	{ ARM64_INS_XTN, "xtn" },
751 	{ ARM64_INS_ZIP1, "zip1" },
752 	{ ARM64_INS_ZIP2, "zip2" },
753 };
754 
755 // map *S & alias instructions back to original id
756 static const name_map alias_insn_name_maps[] = {
757 	{ ARM64_INS_ADC, "adcs" },
758 	{ ARM64_INS_AND, "ands" },
759 	{ ARM64_INS_ADD, "adds" },
760 	{ ARM64_INS_BIC, "bics" },
761 	{ ARM64_INS_SBC, "sbcs" },
762 	{ ARM64_INS_SUB, "subs" },
763 
764 	// alias insn
765 	{ ARM64_INS_MNEG, "mneg" },
766 	{ ARM64_INS_UMNEGL, "umnegl" },
767 	{ ARM64_INS_SMNEGL, "smnegl" },
768 	{ ARM64_INS_NOP, "nop" },
769 	{ ARM64_INS_YIELD, "yield" },
770 	{ ARM64_INS_WFE, "wfe" },
771 	{ ARM64_INS_WFI, "wfi" },
772 	{ ARM64_INS_SEV, "sev" },
773 	{ ARM64_INS_SEVL, "sevl" },
774 	{ ARM64_INS_NGC, "ngc" },
775 	{ ARM64_INS_NGCS, "ngcs" },
776 	{ ARM64_INS_NEGS, "negs" },
777 
778 	{ ARM64_INS_SBFIZ, "sbfiz" },
779 	{ ARM64_INS_UBFIZ, "ubfiz" },
780 	{ ARM64_INS_SBFX, "sbfx" },
781 	{ ARM64_INS_UBFX, "ubfx" },
782 	{ ARM64_INS_BFI, "bfi" },
783 	{ ARM64_INS_BFXIL, "bfxil" },
784 	{ ARM64_INS_CMN, "cmn" },
785 	{ ARM64_INS_MVN, "mvn" },
786 	{ ARM64_INS_TST, "tst" },
787 	{ ARM64_INS_CSET, "cset" },
788 	{ ARM64_INS_CINC, "cinc" },
789 	{ ARM64_INS_CSETM, "csetm" },
790 	{ ARM64_INS_CINV, "cinv" },
791 	{ ARM64_INS_CNEG, "cneg" },
792 	{ ARM64_INS_SXTB, "sxtb" },
793 	{ ARM64_INS_SXTH, "sxth" },
794 	{ ARM64_INS_SXTW, "sxtw" },
795 	{ ARM64_INS_CMP, "cmp" },
796 	{ ARM64_INS_UXTB, "uxtb" },
797 	{ ARM64_INS_UXTH, "uxth" },
798 	{ ARM64_INS_UXTW, "uxtw" },
799 
800 	{ ARM64_INS_IC, "ic" },
801 	{ ARM64_INS_DC, "dc" },
802 	{ ARM64_INS_AT, "at" },
803 	{ ARM64_INS_TLBI, "tlbi" },
804 };
805 
AArch64_insn_name(csh handle,unsigned int id)806 const char *AArch64_insn_name(csh handle, unsigned int id)
807 {
808 #ifndef CAPSTONE_DIET
809 	unsigned int i;
810 
811 	if (id >= ARM64_INS_ENDING)
812 		return NULL;
813 
814 	if (id < ARR_SIZE(insn_name_maps))
815 		return insn_name_maps[id].name;
816 
817 	// then find alias insn
818 	for (i = 0; i < ARR_SIZE(alias_insn_name_maps); i++) {
819 		if (alias_insn_name_maps[i].id == id)
820 			return alias_insn_name_maps[i].name;
821 	}
822 
823 	// not found
824 	return NULL;
825 #else
826 	return NULL;
827 #endif
828 }
829 
830 #ifndef CAPSTONE_DIET
831 static const name_map group_name_maps[] = {
832 	// generic groups
833 	{ ARM64_GRP_INVALID, NULL },
834 	{ ARM64_GRP_JUMP, "jump" },
835 	{ ARM64_GRP_CALL, "call" },
836 	{ ARM64_GRP_RET, "return" },
837 	{ ARM64_GRP_PRIVILEGE, "privilege" },
838 	{ ARM64_GRP_INT, "int" },
839 	{ ARM64_GRP_BRANCH_RELATIVE, "branch_relative" },
840 
841 	// architecture-specific groups
842 	{ ARM64_GRP_CRYPTO, "crypto" },
843 	{ ARM64_GRP_FPARMV8, "fparmv8" },
844 	{ ARM64_GRP_NEON, "neon" },
845 	{ ARM64_GRP_CRC, "crc" },
846 };
847 #endif
848 
AArch64_group_name(csh handle,unsigned int id)849 const char *AArch64_group_name(csh handle, unsigned int id)
850 {
851 #ifndef CAPSTONE_DIET
852 	return id2name(group_name_maps, ARR_SIZE(group_name_maps), id);
853 #else
854 	return NULL;
855 #endif
856 }
857 
858 // map instruction name to public instruction ID
AArch64_map_insn(const char * name)859 arm64_reg AArch64_map_insn(const char *name)
860 {
861 	// NOTE: skip first NULL name in insn_name_maps
862 	int i = name2id(&insn_name_maps[1], ARR_SIZE(insn_name_maps) - 1, name);
863 
864 	if (i == -1)
865 		// try again with 'special' insn that is not available in insn_name_maps
866 		i = name2id(alias_insn_name_maps, ARR_SIZE(alias_insn_name_maps), name);
867 
868 	return (i != -1)? i : ARM64_REG_INVALID;
869 }
870 
871 // map internal raw vregister to 'public' register
AArch64_map_vregister(unsigned int r)872 arm64_reg AArch64_map_vregister(unsigned int r)
873 {
874 	// for some reasons different Arm64 can map different register number to
875 	// the same register. this function handles the issue for exposing Mips
876 	// operands by mapping internal registers to 'public' register.
877 	static const unsigned int map[] = { 0,
878 		0, 0, 0, 0, 0,
879 		0, 0, 0, 0, 0,
880 		0, 0, 0, 0, 0,
881 		0, 0, 0, 0, 0,
882 		0, 0, 0, 0, 0,
883 		0, 0, 0, 0, 0,
884 		0, 0, 0, 0, 0,
885 		0, 0, 0, 0, ARM64_REG_V0,
886 		ARM64_REG_V1, ARM64_REG_V2, ARM64_REG_V3, ARM64_REG_V4, ARM64_REG_V5,
887 		ARM64_REG_V6, ARM64_REG_V7, ARM64_REG_V8, ARM64_REG_V9, ARM64_REG_V10,
888 		ARM64_REG_V11, ARM64_REG_V12, ARM64_REG_V13, ARM64_REG_V14, ARM64_REG_V15,
889 		ARM64_REG_V16, ARM64_REG_V17, ARM64_REG_V18, ARM64_REG_V19, ARM64_REG_V20,
890 		ARM64_REG_V21, ARM64_REG_V22, ARM64_REG_V23, ARM64_REG_V24, ARM64_REG_V25,
891 		ARM64_REG_V26, ARM64_REG_V27, ARM64_REG_V28, ARM64_REG_V29, ARM64_REG_V30,
892 		ARM64_REG_V31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
893 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
894 		0, 0, 0, ARM64_REG_V0, ARM64_REG_V1,
895 		ARM64_REG_V2, ARM64_REG_V3, ARM64_REG_V4, ARM64_REG_V5, ARM64_REG_V6,
896 		ARM64_REG_V7, ARM64_REG_V8, ARM64_REG_V9, ARM64_REG_V10, ARM64_REG_V11,
897 		ARM64_REG_V12, ARM64_REG_V13, ARM64_REG_V14, ARM64_REG_V15, ARM64_REG_V16,
898 		ARM64_REG_V17, ARM64_REG_V18, ARM64_REG_V19, ARM64_REG_V20, ARM64_REG_V21,
899 		ARM64_REG_V22, ARM64_REG_V23, ARM64_REG_V24, ARM64_REG_V25, ARM64_REG_V26,
900 		ARM64_REG_V27, ARM64_REG_V28, ARM64_REG_V29, ARM64_REG_V30, ARM64_REG_V31,
901 		0, 0, 0, 0, 0,
902 		0, 0, 0, 0, 0,
903 		0, 0, 0, 0, 0,
904 		0, 0, 0, 0, 0,
905 		0, 0, 0, 0, 0,
906 		0, 0, 0, 0, 0,
907 		0, 0, 0, 0, 0,
908 		0, 0, 0, 0, 0,
909 		0, 0, 0, 0, 0,
910 		0, 0, 0, 0, 0,
911 		0, 0, 0, 0, 0,
912 		0, 0, 0, 0, 0,
913 		0, 0, 0, 0, 0,
914 		0, 0, 0, 0, 0,
915 		0, 0, 0, 0, 0,
916 		0, 0, 0, 0, 0,
917 		0, 0, 0, 0, 0,
918 		0, 0, 0, 0, 0,
919 		0, 0, ARM64_REG_V0, ARM64_REG_V1, ARM64_REG_V2,
920 		ARM64_REG_V3, ARM64_REG_V4, ARM64_REG_V5, ARM64_REG_V6, ARM64_REG_V7,
921 		ARM64_REG_V8, ARM64_REG_V9, ARM64_REG_V10, ARM64_REG_V11, ARM64_REG_V12,
922 		ARM64_REG_V13, ARM64_REG_V14, ARM64_REG_V15, ARM64_REG_V16, ARM64_REG_V17,
923 		ARM64_REG_V18, ARM64_REG_V19, ARM64_REG_V20, ARM64_REG_V21, ARM64_REG_V22,
924 		ARM64_REG_V23, ARM64_REG_V24, ARM64_REG_V25, ARM64_REG_V26, ARM64_REG_V27,
925 		ARM64_REG_V28, ARM64_REG_V29, ARM64_REG_V30, ARM64_REG_V31, ARM64_REG_V0,
926 		ARM64_REG_V1, ARM64_REG_V2, ARM64_REG_V3, ARM64_REG_V4, ARM64_REG_V5,
927 		ARM64_REG_V6, ARM64_REG_V7, ARM64_REG_V8, ARM64_REG_V9, ARM64_REG_V10,
928 		ARM64_REG_V11, ARM64_REG_V12, ARM64_REG_V13, ARM64_REG_V14, ARM64_REG_V15,
929 		ARM64_REG_V16, ARM64_REG_V17, ARM64_REG_V18, ARM64_REG_V19, ARM64_REG_V20,
930 		ARM64_REG_V21, ARM64_REG_V22, ARM64_REG_V23, ARM64_REG_V24, ARM64_REG_V25,
931 		ARM64_REG_V26, ARM64_REG_V27, ARM64_REG_V28, ARM64_REG_V29, ARM64_REG_V30,
932 		ARM64_REG_V31, ARM64_REG_V0, ARM64_REG_V1, ARM64_REG_V2, ARM64_REG_V3,
933 		ARM64_REG_V4, ARM64_REG_V5, ARM64_REG_V6, ARM64_REG_V7, ARM64_REG_V8,
934 		ARM64_REG_V9, ARM64_REG_V10, ARM64_REG_V11, ARM64_REG_V12, ARM64_REG_V13,
935 		ARM64_REG_V14, ARM64_REG_V15, ARM64_REG_V16, ARM64_REG_V17, ARM64_REG_V18,
936 		ARM64_REG_V19, ARM64_REG_V20, ARM64_REG_V21, ARM64_REG_V22, ARM64_REG_V23,
937 		ARM64_REG_V24, ARM64_REG_V25, ARM64_REG_V26, ARM64_REG_V27, ARM64_REG_V28,
938 		ARM64_REG_V29, ARM64_REG_V30, ARM64_REG_V31, ARM64_REG_V0, ARM64_REG_V1,
939 		ARM64_REG_V2, ARM64_REG_V3, ARM64_REG_V4, ARM64_REG_V5, ARM64_REG_V6,
940 		ARM64_REG_V7, ARM64_REG_V8, ARM64_REG_V9, ARM64_REG_V10, ARM64_REG_V11,
941 		ARM64_REG_V12, ARM64_REG_V13, ARM64_REG_V14, ARM64_REG_V15, ARM64_REG_V16,
942 		ARM64_REG_V17, ARM64_REG_V18, ARM64_REG_V19, ARM64_REG_V20, ARM64_REG_V21,
943 		ARM64_REG_V22, ARM64_REG_V23, ARM64_REG_V24, ARM64_REG_V25, ARM64_REG_V26,
944 		ARM64_REG_V27, ARM64_REG_V28, ARM64_REG_V29, ARM64_REG_V30, ARM64_REG_V31,
945 		ARM64_REG_V0, ARM64_REG_V1, ARM64_REG_V2, ARM64_REG_V3, ARM64_REG_V4,
946 		ARM64_REG_V5, ARM64_REG_V6, ARM64_REG_V7, ARM64_REG_V8, ARM64_REG_V9,
947 		ARM64_REG_V10, ARM64_REG_V11, ARM64_REG_V12, ARM64_REG_V13, ARM64_REG_V14,
948 		ARM64_REG_V15, ARM64_REG_V16, ARM64_REG_V17, ARM64_REG_V18, ARM64_REG_V19,
949 		ARM64_REG_V20, ARM64_REG_V21, ARM64_REG_V22, ARM64_REG_V23, ARM64_REG_V24,
950 		ARM64_REG_V25, ARM64_REG_V26, ARM64_REG_V27, ARM64_REG_V28, ARM64_REG_V29,
951 		ARM64_REG_V30, ARM64_REG_V31, ARM64_REG_V0, ARM64_REG_V1, ARM64_REG_V2,
952 		ARM64_REG_V3, ARM64_REG_V4, ARM64_REG_V5, ARM64_REG_V6, ARM64_REG_V7,
953 		ARM64_REG_V8, ARM64_REG_V9, ARM64_REG_V10, ARM64_REG_V11, ARM64_REG_V12,
954 		ARM64_REG_V13, ARM64_REG_V14, ARM64_REG_V15, ARM64_REG_V16, ARM64_REG_V17,
955 		ARM64_REG_V18, ARM64_REG_V19, ARM64_REG_V20, ARM64_REG_V21, ARM64_REG_V22,
956 		ARM64_REG_V23, ARM64_REG_V24, ARM64_REG_V25, ARM64_REG_V26, ARM64_REG_V27,
957 		ARM64_REG_V28, ARM64_REG_V29, ARM64_REG_V30, ARM64_REG_V31, };
958 
959 	if (r < ARR_SIZE(map))
960 		return map[r];
961 
962 	// cannot find this register
963 	return 0;
964 }
965 
arm64_op_addVectorArrSpecifier(MCInst * MI,int sp)966 void arm64_op_addVectorArrSpecifier(MCInst * MI, int sp)
967 {
968 	if (MI->csh->detail) {
969 		MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].vas = sp;
970 	}
971 }
972 
arm64_op_addVectorElementSizeSpecifier(MCInst * MI,int sp)973 void arm64_op_addVectorElementSizeSpecifier(MCInst * MI, int sp)
974 {
975 	if (MI->csh->detail) {
976 		MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].vess = sp;
977 	}
978 }
979 
arm64_op_addFP(MCInst * MI,float fp)980 void arm64_op_addFP(MCInst *MI, float fp)
981 {
982 	if (MI->csh->detail) {
983 		MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_FP;
984 		MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].fp = fp;
985 		MI->flat_insn->detail->arm64.op_count++;
986 	}
987 }
988 
arm64_op_addImm(MCInst * MI,int64_t imm)989 void arm64_op_addImm(MCInst *MI, int64_t imm)
990 {
991 	if (MI->csh->detail) {
992 		MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
993 		MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (int)imm;
994 		MI->flat_insn->detail->arm64.op_count++;
995 	}
996 }
997 
998 #ifndef CAPSTONE_DIET
999 
1000 // map instruction to its characteristics
1001 typedef struct insn_op {
1002 	unsigned int eflags_update;	// how this instruction update status flags
1003 	uint8_t access[5];
1004 } insn_op;
1005 
1006 static insn_op insn_ops[] = {
1007     {
1008          /* NULL item */
1009         0, { 0 }
1010     },
1011 
1012 #include "AArch64MappingInsnOp.inc"
1013 };
1014 
1015 // given internal insn id, return operand access info
AArch64_get_op_access(cs_struct * h,unsigned int id)1016 uint8_t *AArch64_get_op_access(cs_struct *h, unsigned int id)
1017 {
1018 	int i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache);
1019 	if (i != 0) {
1020 		return insn_ops[i].access;
1021 	}
1022 
1023 	return NULL;
1024 }
1025 
AArch64_reg_access(const cs_insn * insn,cs_regs regs_read,uint8_t * regs_read_count,cs_regs regs_write,uint8_t * regs_write_count)1026 void AArch64_reg_access(const cs_insn *insn,
1027 		cs_regs regs_read, uint8_t *regs_read_count,
1028 		cs_regs regs_write, uint8_t *regs_write_count)
1029 {
1030 	uint8_t i;
1031 	uint8_t read_count, write_count;
1032 	cs_arm64 *arm64 = &(insn->detail->arm64);
1033 
1034 	read_count = insn->detail->regs_read_count;
1035 	write_count = insn->detail->regs_write_count;
1036 
1037 	// implicit registers
1038 	memcpy(regs_read, insn->detail->regs_read, read_count * sizeof(insn->detail->regs_read[0]));
1039 	memcpy(regs_write, insn->detail->regs_write, write_count * sizeof(insn->detail->regs_write[0]));
1040 
1041 	// explicit registers
1042 	for (i = 0; i < arm64->op_count; i++) {
1043 		cs_arm64_op *op = &(arm64->operands[i]);
1044 		switch((int)op->type) {
1045 			case ARM64_OP_REG:
1046 				if ((op->access & CS_AC_READ) && !arr_exist(regs_read, read_count, op->reg)) {
1047 					regs_read[read_count] = (uint16_t)op->reg;
1048 					read_count++;
1049 				}
1050 				if ((op->access & CS_AC_WRITE) && !arr_exist(regs_write, write_count, op->reg)) {
1051 					regs_write[write_count] = (uint16_t)op->reg;
1052 					write_count++;
1053 				}
1054 				break;
1055 			case ARM_OP_MEM:
1056 				// registers appeared in memory references always being read
1057 				if ((op->mem.base != ARM64_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.base)) {
1058 					regs_read[read_count] = (uint16_t)op->mem.base;
1059 					read_count++;
1060 				}
1061 				if ((op->mem.index != ARM64_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.index)) {
1062 					regs_read[read_count] = (uint16_t)op->mem.index;
1063 					read_count++;
1064 				}
1065 				if ((arm64->writeback) && (op->mem.base != ARM64_REG_INVALID) && !arr_exist(regs_write, write_count, op->mem.base)) {
1066 					regs_write[write_count] = (uint16_t)op->mem.base;
1067 					write_count++;
1068 				}
1069 			default:
1070 				break;
1071 		}
1072 	}
1073 
1074 	*regs_read_count = read_count;
1075 	*regs_write_count = write_count;
1076 }
1077 #endif
1078 
1079 #endif
1080