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