/src/capstonev5/arch/AArch64/AArch64Mapping.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Capstone Disassembly Engine */ |
2 | | /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */ |
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 | | // NOTE: this reg_name_maps[] reflects the order of registers in arm64_reg |
18 | | static const char * const reg_name_maps[] = { |
19 | | NULL, /* ARM64_REG_INVALID */ |
20 | | |
21 | | "ffr", |
22 | | "fp", |
23 | | "lr", |
24 | | "nzcv", |
25 | | "sp", |
26 | | "vg", |
27 | | "wsp", |
28 | | "wzr", |
29 | | "xzr", |
30 | | |
31 | | "za", |
32 | | |
33 | | "b0", |
34 | | "b1", |
35 | | "b2", |
36 | | "b3", |
37 | | "b4", |
38 | | "b5", |
39 | | "b6", |
40 | | "b7", |
41 | | "b8", |
42 | | "b9", |
43 | | "b10", |
44 | | "b11", |
45 | | "b12", |
46 | | "b13", |
47 | | "b14", |
48 | | "b15", |
49 | | "b16", |
50 | | "b17", |
51 | | "b18", |
52 | | "b19", |
53 | | "b20", |
54 | | "b21", |
55 | | "b22", |
56 | | "b23", |
57 | | "b24", |
58 | | "b25", |
59 | | "b26", |
60 | | "b27", |
61 | | "b28", |
62 | | "b29", |
63 | | "b30", |
64 | | "b31", |
65 | | |
66 | | "d0", |
67 | | "d1", |
68 | | "d2", |
69 | | "d3", |
70 | | "d4", |
71 | | "d5", |
72 | | "d6", |
73 | | "d7", |
74 | | "d8", |
75 | | "d9", |
76 | | "d10", |
77 | | "d11", |
78 | | "d12", |
79 | | "d13", |
80 | | "d14", |
81 | | "d15", |
82 | | "d16", |
83 | | "d17", |
84 | | "d18", |
85 | | "d19", |
86 | | "d20", |
87 | | "d21", |
88 | | "d22", |
89 | | "d23", |
90 | | "d24", |
91 | | "d25", |
92 | | "d26", |
93 | | "d27", |
94 | | "d28", |
95 | | "d29", |
96 | | "d30", |
97 | | "d31", |
98 | | |
99 | | "h0", |
100 | | "h1", |
101 | | "h2", |
102 | | "h3", |
103 | | "h4", |
104 | | "h5", |
105 | | "h6", |
106 | | "h7", |
107 | | "h8", |
108 | | "h9", |
109 | | "h10", |
110 | | "h11", |
111 | | "h12", |
112 | | "h13", |
113 | | "h14", |
114 | | "h15", |
115 | | "h16", |
116 | | "h17", |
117 | | "h18", |
118 | | "h19", |
119 | | "h20", |
120 | | "h21", |
121 | | "h22", |
122 | | "h23", |
123 | | "h24", |
124 | | "h25", |
125 | | "h26", |
126 | | "h27", |
127 | | "h28", |
128 | | "h29", |
129 | | "h30", |
130 | | "h31", |
131 | | |
132 | | "p0", |
133 | | "p1", |
134 | | "p2", |
135 | | "p3", |
136 | | "p4", |
137 | | "p5", |
138 | | "p6", |
139 | | "p7", |
140 | | "p8", |
141 | | "p9", |
142 | | "p10", |
143 | | "p11", |
144 | | "p12", |
145 | | "p13", |
146 | | "p14", |
147 | | "p15", |
148 | | |
149 | | "q0", |
150 | | "q1", |
151 | | "q2", |
152 | | "q3", |
153 | | "q4", |
154 | | "q5", |
155 | | "q6", |
156 | | "q7", |
157 | | "q8", |
158 | | "q9", |
159 | | "q10", |
160 | | "q11", |
161 | | "q12", |
162 | | "q13", |
163 | | "q14", |
164 | | "q15", |
165 | | "q16", |
166 | | "q17", |
167 | | "q18", |
168 | | "q19", |
169 | | "q20", |
170 | | "q21", |
171 | | "q22", |
172 | | "q23", |
173 | | "q24", |
174 | | "q25", |
175 | | "q26", |
176 | | "q27", |
177 | | "q28", |
178 | | "q29", |
179 | | "q30", |
180 | | "q31", |
181 | | |
182 | | "s0", |
183 | | "s1", |
184 | | "s2", |
185 | | "s3", |
186 | | "s4", |
187 | | "s5", |
188 | | "s6", |
189 | | "s7", |
190 | | "s8", |
191 | | "s9", |
192 | | "s10", |
193 | | "s11", |
194 | | "s12", |
195 | | "s13", |
196 | | "s14", |
197 | | "s15", |
198 | | "s16", |
199 | | "s17", |
200 | | "s18", |
201 | | "s19", |
202 | | "s20", |
203 | | "s21", |
204 | | "s22", |
205 | | "s23", |
206 | | "s24", |
207 | | "s25", |
208 | | "s26", |
209 | | "s27", |
210 | | "s28", |
211 | | "s29", |
212 | | "s30", |
213 | | "s31", |
214 | | |
215 | | "w0", |
216 | | "w1", |
217 | | "w2", |
218 | | "w3", |
219 | | "w4", |
220 | | "w5", |
221 | | "w6", |
222 | | "w7", |
223 | | "w8", |
224 | | "w9", |
225 | | "w10", |
226 | | "w11", |
227 | | "w12", |
228 | | "w13", |
229 | | "w14", |
230 | | "w15", |
231 | | "w16", |
232 | | "w17", |
233 | | "w18", |
234 | | "w19", |
235 | | "w20", |
236 | | "w21", |
237 | | "w22", |
238 | | "w23", |
239 | | "w24", |
240 | | "w25", |
241 | | "w26", |
242 | | "w27", |
243 | | "w28", |
244 | | "w29", |
245 | | "w30", |
246 | | |
247 | | "x0", |
248 | | "x1", |
249 | | "x2", |
250 | | "x3", |
251 | | "x4", |
252 | | "x5", |
253 | | "x6", |
254 | | "x7", |
255 | | "x8", |
256 | | "x9", |
257 | | "x10", |
258 | | "x11", |
259 | | "x12", |
260 | | "x13", |
261 | | "x14", |
262 | | "x15", |
263 | | "x16", |
264 | | "x17", |
265 | | "x18", |
266 | | "x19", |
267 | | "x20", |
268 | | "x21", |
269 | | "x22", |
270 | | "x23", |
271 | | "x24", |
272 | | "x25", |
273 | | "x26", |
274 | | "x27", |
275 | | "x28", |
276 | | |
277 | | "z0", |
278 | | "z1", |
279 | | "z2", |
280 | | "z3", |
281 | | "z4", |
282 | | "z5", |
283 | | "z6", |
284 | | "z7", |
285 | | "z8", |
286 | | "z9", |
287 | | "z10", |
288 | | "z11", |
289 | | "z12", |
290 | | "z13", |
291 | | "z14", |
292 | | "z15", |
293 | | "z16", |
294 | | "z17", |
295 | | "z18", |
296 | | "z19", |
297 | | "z20", |
298 | | "z21", |
299 | | "z22", |
300 | | "z23", |
301 | | "z24", |
302 | | "z25", |
303 | | "z26", |
304 | | "z27", |
305 | | "z28", |
306 | | "z29", |
307 | | "z30", |
308 | | "z31", |
309 | | |
310 | | "zab0", |
311 | | |
312 | | "zad0", |
313 | | "zad1", |
314 | | "zad2", |
315 | | "zad3", |
316 | | "zad4", |
317 | | "zad5", |
318 | | "zad6", |
319 | | "zad7", |
320 | | |
321 | | "zah0", |
322 | | "zah1", |
323 | | |
324 | | "zaq0", |
325 | | "zaq1", |
326 | | "zaq2", |
327 | | "zaq3", |
328 | | "zaq4", |
329 | | "zaq5", |
330 | | "zaq6", |
331 | | "zaq7", |
332 | | "zaq8", |
333 | | "zaq9", |
334 | | "zaq10", |
335 | | "zaq11", |
336 | | "zaq12", |
337 | | "zaq13", |
338 | | "zaq14", |
339 | | "zaq15", |
340 | | |
341 | | "zas0", |
342 | | "zas1", |
343 | | "zas2", |
344 | | "zas3", |
345 | | |
346 | | "v0", |
347 | | "v1", |
348 | | "v2", |
349 | | "v3", |
350 | | "v4", |
351 | | "v5", |
352 | | "v6", |
353 | | "v7", |
354 | | "v8", |
355 | | "v9", |
356 | | "v10", |
357 | | "v11", |
358 | | "v12", |
359 | | "v13", |
360 | | "v14", |
361 | | "v15", |
362 | | "v16", |
363 | | "v17", |
364 | | "v18", |
365 | | "v19", |
366 | | "v20", |
367 | | "v21", |
368 | | "v22", |
369 | | "v23", |
370 | | "v24", |
371 | | "v25", |
372 | | "v26", |
373 | | "v27", |
374 | | "v28", |
375 | | "v29", |
376 | | "v30", |
377 | | "v31", |
378 | | }; |
379 | | #endif |
380 | | |
381 | | const char *AArch64_reg_name(csh handle, unsigned int reg) |
382 | 7.47k | { |
383 | 7.47k | #ifndef CAPSTONE_DIET |
384 | 7.47k | if (reg >= ARR_SIZE(reg_name_maps)) |
385 | 0 | return NULL; |
386 | | |
387 | 7.47k | return reg_name_maps[reg]; |
388 | | #else |
389 | | return NULL; |
390 | | #endif |
391 | 7.47k | } |
392 | | |
393 | | static const insn_map insns[] = { |
394 | | // dummy item |
395 | | { |
396 | | 0, 0, |
397 | | #ifndef CAPSTONE_DIET |
398 | | { 0 }, { 0 }, { 0 }, 0, 0 |
399 | | #endif |
400 | | }, |
401 | | |
402 | | #include "AArch64MappingInsn.inc" |
403 | | }; |
404 | | |
405 | | // given internal insn id, return public instruction info |
406 | | void AArch64_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int id) |
407 | 128k | { |
408 | 128k | int i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache); |
409 | 128k | if (i != 0) { |
410 | 128k | insn->id = insns[i].mapid; |
411 | | |
412 | 128k | if (h->detail) { |
413 | 128k | #ifndef CAPSTONE_DIET |
414 | 128k | cs_struct handle; |
415 | 128k | handle.detail = h->detail; |
416 | | |
417 | 128k | memcpy(insn->detail->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use)); |
418 | 128k | insn->detail->regs_read_count = (uint8_t)count_positive(insns[i].regs_use); |
419 | | |
420 | 128k | memcpy(insn->detail->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod)); |
421 | 128k | insn->detail->regs_write_count = (uint8_t)count_positive(insns[i].regs_mod); |
422 | | |
423 | 128k | memcpy(insn->detail->groups, insns[i].groups, sizeof(insns[i].groups)); |
424 | 128k | insn->detail->groups_count = (uint8_t)count_positive8(insns[i].groups); |
425 | | |
426 | 128k | insn->detail->arm64.update_flags = cs_reg_write((csh)&handle, insn, ARM64_REG_NZCV); |
427 | 128k | #endif |
428 | 128k | } |
429 | 128k | } |
430 | 128k | } |
431 | | |
432 | | static const char * const insn_name_maps[] = { |
433 | | NULL, // ARM64_INS_INVALID |
434 | | #include "AArch64MappingInsnName.inc" |
435 | | "sbfiz", |
436 | | "ubfiz", |
437 | | "sbfx", |
438 | | "ubfx", |
439 | | "bfi", |
440 | | "bfxil", |
441 | | "ic", |
442 | | "dc", |
443 | | "at", |
444 | | "tlbi", |
445 | | "smstart", |
446 | | "smstop", |
447 | | }; |
448 | | |
449 | | const char *AArch64_insn_name(csh handle, unsigned int id) |
450 | 128k | { |
451 | 128k | #ifndef CAPSTONE_DIET |
452 | 128k | if (id >= ARM64_INS_ENDING) |
453 | 0 | return NULL; |
454 | | |
455 | 128k | if (id < ARR_SIZE(insn_name_maps)) |
456 | 128k | return insn_name_maps[id]; |
457 | | |
458 | | // not found |
459 | 0 | return NULL; |
460 | | #else |
461 | | return NULL; |
462 | | #endif |
463 | 128k | } |
464 | | |
465 | | #ifndef CAPSTONE_DIET |
466 | | static const name_map group_name_maps[] = { |
467 | | // generic groups |
468 | | { ARM64_GRP_INVALID, NULL }, |
469 | | { ARM64_GRP_JUMP, "jump" }, |
470 | | { ARM64_GRP_CALL, "call" }, |
471 | | { ARM64_GRP_RET, "return" }, |
472 | | { ARM64_GRP_PRIVILEGE, "privilege" }, |
473 | | { ARM64_GRP_INT, "int" }, |
474 | | { ARM64_GRP_BRANCH_RELATIVE, "branch_relative" }, |
475 | | { ARM64_GRP_PAC, "pointer authentication" }, |
476 | | |
477 | | // architecture-specific groups |
478 | | { ARM64_GRP_CRYPTO, "crypto" }, |
479 | | { ARM64_GRP_FPARMV8, "fparmv8" }, |
480 | | { ARM64_GRP_NEON, "neon" }, |
481 | | { ARM64_GRP_CRC, "crc" }, |
482 | | |
483 | | { ARM64_GRP_AES, "aes" }, |
484 | | { ARM64_GRP_DOTPROD, "dotprod" }, |
485 | | { ARM64_GRP_FULLFP16, "fullfp16" }, |
486 | | { ARM64_GRP_LSE, "lse" }, |
487 | | { ARM64_GRP_RCPC, "rcpc" }, |
488 | | { ARM64_GRP_RDM, "rdm" }, |
489 | | { ARM64_GRP_SHA2, "sha2" }, |
490 | | { ARM64_GRP_SHA3, "sha3" }, |
491 | | { ARM64_GRP_SM4, "sm4" }, |
492 | | { ARM64_GRP_SVE, "sve" }, |
493 | | { ARM64_GRP_SVE2, "sve2" }, |
494 | | { ARM64_GRP_SVE2AES, "sve2-aes" }, |
495 | | { ARM64_GRP_SVE2BitPerm, "sve2-bitperm" }, |
496 | | { ARM64_GRP_SVE2SHA3, "sve2-sha3" }, |
497 | | { ARM64_GRP_SVE2SM4, "sve2-sm4" }, |
498 | | { ARM64_GRP_SME, "sme" }, |
499 | | { ARM64_GRP_SMEF64, "sme-f64" }, |
500 | | { ARM64_GRP_SMEI64, "sme-i64" }, |
501 | | { ARM64_GRP_MatMulFP32, "f32mm" }, |
502 | | { ARM64_GRP_MatMulFP64, "f64mm" }, |
503 | | { ARM64_GRP_MatMulInt8, "i8mm" }, |
504 | | { ARM64_GRP_V8_1A, "v8_1a" }, |
505 | | { ARM64_GRP_V8_3A, "v8_3a" }, |
506 | | { ARM64_GRP_V8_4A, "v8_4a" }, |
507 | | }; |
508 | | #endif |
509 | | |
510 | | const char *AArch64_group_name(csh handle, unsigned int id) |
511 | 313k | { |
512 | 313k | #ifndef CAPSTONE_DIET |
513 | 313k | return id2name(group_name_maps, ARR_SIZE(group_name_maps), id); |
514 | | #else |
515 | | return NULL; |
516 | | #endif |
517 | 313k | } |
518 | | |
519 | | // map instruction name to public instruction ID |
520 | | arm64_insn AArch64_map_insn(const char *name) |
521 | 21.9k | { |
522 | 21.9k | unsigned int i; |
523 | | |
524 | 14.5M | for(i = 1; i < ARR_SIZE(insn_name_maps); i++) { |
525 | 14.5M | if (!strcmp(name, insn_name_maps[i])) |
526 | 21.9k | return i; |
527 | 14.5M | } |
528 | | |
529 | | // not found |
530 | 12 | return ARM64_INS_INVALID; |
531 | 21.9k | } |
532 | | |
533 | | // map internal raw vregister to 'public' register |
534 | | arm64_reg AArch64_map_vregister(unsigned int r) |
535 | 72.6k | { |
536 | 72.6k | static const unsigned short RegAsmOffsetvreg[] = { |
537 | 72.6k | #include "AArch64GenRegisterV.inc" |
538 | 72.6k | }; |
539 | | |
540 | 72.6k | if (r < ARR_SIZE(RegAsmOffsetvreg)) |
541 | 72.6k | return RegAsmOffsetvreg[r - 1]; |
542 | | |
543 | | // cannot find this register |
544 | 0 | return 0; |
545 | 72.6k | } |
546 | | |
547 | | static const name_map sys_op_name_map[] = { |
548 | | { ARM64_TLBI_ALLE1, "alle1"} , |
549 | | { ARM64_TLBI_ALLE1IS, "alle1is"} , |
550 | | { ARM64_TLBI_ALLE1ISNXS, "alle1isnxs"} , |
551 | | { ARM64_TLBI_ALLE1NXS, "alle1nxs"} , |
552 | | { ARM64_TLBI_ALLE1OS, "alle1os"} , |
553 | | { ARM64_TLBI_ALLE1OSNXS, "alle1osnxs"} , |
554 | | { ARM64_TLBI_ALLE2, "alle2"} , |
555 | | { ARM64_TLBI_ALLE2IS, "alle2is"} , |
556 | | { ARM64_TLBI_ALLE2ISNXS, "alle2isnxs"} , |
557 | | { ARM64_TLBI_ALLE2NXS, "alle2nxs"} , |
558 | | { ARM64_TLBI_ALLE2OS, "alle2os"} , |
559 | | { ARM64_TLBI_ALLE2OSNXS, "alle2osnxs"} , |
560 | | { ARM64_TLBI_ALLE3, "alle3"} , |
561 | | { ARM64_TLBI_ALLE3IS, "alle3is"} , |
562 | | { ARM64_TLBI_ALLE3ISNXS, "alle3isnxs"} , |
563 | | { ARM64_TLBI_ALLE3NXS, "alle3nxs"} , |
564 | | { ARM64_TLBI_ALLE3OS, "alle3os"} , |
565 | | { ARM64_TLBI_ALLE3OSNXS, "alle3osnxs"} , |
566 | | { ARM64_TLBI_ASIDE1, "aside1"} , |
567 | | { ARM64_TLBI_ASIDE1IS, "aside1is"} , |
568 | | { ARM64_TLBI_ASIDE1ISNXS, "aside1isnxs"} , |
569 | | { ARM64_TLBI_ASIDE1NXS, "aside1nxs"} , |
570 | | { ARM64_TLBI_ASIDE1OS, "aside1os"} , |
571 | | { ARM64_TLBI_ASIDE1OSNXS, "aside1osnxs"} , |
572 | | { ARM64_TLBI_IPAS2E1, "ipas2e1"} , |
573 | | { ARM64_TLBI_IPAS2E1IS, "ipas2e1is"} , |
574 | | { ARM64_TLBI_IPAS2E1ISNXS, "ipas2e1isnxs"} , |
575 | | { ARM64_TLBI_IPAS2E1NXS, "ipas2e1nxs"} , |
576 | | { ARM64_TLBI_IPAS2E1OS, "ipas2e1os"} , |
577 | | { ARM64_TLBI_IPAS2E1OSNXS, "ipas2e1osnxs"} , |
578 | | { ARM64_TLBI_IPAS2LE1, "ipas2le1"} , |
579 | | { ARM64_TLBI_IPAS2LE1IS, "ipas2le1is"} , |
580 | | { ARM64_TLBI_IPAS2LE1ISNXS, "ipas2le1isnxs"} , |
581 | | { ARM64_TLBI_IPAS2LE1NXS, "ipas2le1nxs"} , |
582 | | { ARM64_TLBI_IPAS2LE1OS, "ipas2le1os"} , |
583 | | { ARM64_TLBI_IPAS2LE1OSNXS, "ipas2le1osnxs"} , |
584 | | { ARM64_TLBI_PAALL, "paall"} , |
585 | | { ARM64_TLBI_PAALLNXS, "paallnxs"} , |
586 | | { ARM64_TLBI_PAALLOS, "paallos"} , |
587 | | { ARM64_TLBI_PAALLOSNXS, "paallosnxs"} , |
588 | | { ARM64_TLBI_RIPAS2E1, "ripas2e1"} , |
589 | | { ARM64_TLBI_RIPAS2E1IS, "ripas2e1is"} , |
590 | | { ARM64_TLBI_RIPAS2E1ISNXS, "ripas2e1isnxs"} , |
591 | | { ARM64_TLBI_RIPAS2E1NXS, "ripas2e1nxs"} , |
592 | | { ARM64_TLBI_RIPAS2E1OS, "ripas2e1os"} , |
593 | | { ARM64_TLBI_RIPAS2E1OSNXS, "ripas2e1osnxs"} , |
594 | | { ARM64_TLBI_RIPAS2LE1, "ripas2le1"} , |
595 | | { ARM64_TLBI_RIPAS2LE1IS, "ripas2le1is"} , |
596 | | { ARM64_TLBI_RIPAS2LE1ISNXS, "ripas2le1isnxs"} , |
597 | | { ARM64_TLBI_RIPAS2LE1NXS, "ripas2le1nxs"} , |
598 | | { ARM64_TLBI_RIPAS2LE1OS, "ripas2le1os"} , |
599 | | { ARM64_TLBI_RIPAS2LE1OSNXS, "ripas2le1osnxs"} , |
600 | | { ARM64_TLBI_RPALOS, "rpalos"} , |
601 | | { ARM64_TLBI_RPALOSNXS, "rpalosnxs"} , |
602 | | { ARM64_TLBI_RPAOS, "rpaos"} , |
603 | | { ARM64_TLBI_RPAOSNXS, "rpaosnxs"} , |
604 | | { ARM64_TLBI_RVAAE1, "rvaae1"} , |
605 | | { ARM64_TLBI_RVAAE1IS, "rvaae1is"} , |
606 | | { ARM64_TLBI_RVAAE1ISNXS, "rvaae1isnxs"} , |
607 | | { ARM64_TLBI_RVAAE1NXS, "rvaae1nxs"} , |
608 | | { ARM64_TLBI_RVAAE1OS, "rvaae1os"} , |
609 | | { ARM64_TLBI_RVAAE1OSNXS, "rvaae1osnxs"} , |
610 | | { ARM64_TLBI_RVAALE1, "rvaale1"} , |
611 | | { ARM64_TLBI_RVAALE1IS, "rvaale1is"} , |
612 | | { ARM64_TLBI_RVAALE1ISNXS, "rvaale1isnxs"} , |
613 | | { ARM64_TLBI_RVAALE1NXS, "rvaale1nxs"} , |
614 | | { ARM64_TLBI_RVAALE1OS, "rvaale1os"} , |
615 | | { ARM64_TLBI_RVAALE1OSNXS, "rvaale1osnxs"} , |
616 | | { ARM64_TLBI_RVAE1, "rvae1"} , |
617 | | { ARM64_TLBI_RVAE1IS, "rvae1is"} , |
618 | | { ARM64_TLBI_RVAE1ISNXS, "rvae1isnxs"} , |
619 | | { ARM64_TLBI_RVAE1NXS, "rvae1nxs"} , |
620 | | { ARM64_TLBI_RVAE1OS, "rvae1os"} , |
621 | | { ARM64_TLBI_RVAE1OSNXS, "rvae1osnxs"} , |
622 | | { ARM64_TLBI_RVAE2, "rvae2"} , |
623 | | { ARM64_TLBI_RVAE2IS, "rvae2is"} , |
624 | | { ARM64_TLBI_RVAE2ISNXS, "rvae2isnxs"} , |
625 | | { ARM64_TLBI_RVAE2NXS, "rvae2nxs"} , |
626 | | { ARM64_TLBI_RVAE2OS, "rvae2os"} , |
627 | | { ARM64_TLBI_RVAE2OSNXS, "rvae2osnxs"} , |
628 | | { ARM64_TLBI_RVAE3, "rvae3"} , |
629 | | { ARM64_TLBI_RVAE3IS, "rvae3is"} , |
630 | | { ARM64_TLBI_RVAE3ISNXS, "rvae3isnxs"} , |
631 | | { ARM64_TLBI_RVAE3NXS, "rvae3nxs"} , |
632 | | { ARM64_TLBI_RVAE3OS, "rvae3os"} , |
633 | | { ARM64_TLBI_RVAE3OSNXS, "rvae3osnxs"} , |
634 | | { ARM64_TLBI_RVALE1, "rvale1"} , |
635 | | { ARM64_TLBI_RVALE1IS, "rvale1is"} , |
636 | | { ARM64_TLBI_RVALE1ISNXS, "rvale1isnxs"} , |
637 | | { ARM64_TLBI_RVALE1NXS, "rvale1nxs"} , |
638 | | { ARM64_TLBI_RVALE1OS, "rvale1os"} , |
639 | | { ARM64_TLBI_RVALE1OSNXS, "rvale1osnxs"} , |
640 | | { ARM64_TLBI_RVALE2, "rvale2"} , |
641 | | { ARM64_TLBI_RVALE2IS, "rvale2is"} , |
642 | | { ARM64_TLBI_RVALE2ISNXS, "rvale2isnxs"} , |
643 | | { ARM64_TLBI_RVALE2NXS, "rvale2nxs"} , |
644 | | { ARM64_TLBI_RVALE2OS, "rvale2os"} , |
645 | | { ARM64_TLBI_RVALE2OSNXS, "rvale2osnxs"} , |
646 | | { ARM64_TLBI_RVALE3, "rvale3"} , |
647 | | { ARM64_TLBI_RVALE3IS, "rvale3is"} , |
648 | | { ARM64_TLBI_RVALE3ISNXS, "rvale3isnxs"} , |
649 | | { ARM64_TLBI_RVALE3NXS, "rvale3nxs"} , |
650 | | { ARM64_TLBI_RVALE3OS, "rvale3os"} , |
651 | | { ARM64_TLBI_RVALE3OSNXS, "rvale3osnxs"} , |
652 | | { ARM64_TLBI_VAAE1, "vaae1"} , |
653 | | { ARM64_TLBI_VAAE1IS, "vaae1is"} , |
654 | | { ARM64_TLBI_VAAE1ISNXS, "vaae1isnxs"} , |
655 | | { ARM64_TLBI_VAAE1NXS, "vaae1nxs"} , |
656 | | { ARM64_TLBI_VAAE1OS, "vaae1os"} , |
657 | | { ARM64_TLBI_VAAE1OSNXS, "vaae1osnxs"} , |
658 | | { ARM64_TLBI_VAALE1, "vaale1"} , |
659 | | { ARM64_TLBI_VAALE1IS, "vaale1is"} , |
660 | | { ARM64_TLBI_VAALE1ISNXS, "vaale1isnxs"} , |
661 | | { ARM64_TLBI_VAALE1NXS, "vaale1nxs"} , |
662 | | { ARM64_TLBI_VAALE1OS, "vaale1os"} , |
663 | | { ARM64_TLBI_VAALE1OSNXS, "vaale1osnxs"} , |
664 | | { ARM64_TLBI_VAE1, "vae1"} , |
665 | | { ARM64_TLBI_VAE1IS, "vae1is"} , |
666 | | { ARM64_TLBI_VAE1ISNXS, "vae1isnxs"} , |
667 | | { ARM64_TLBI_VAE1NXS, "vae1nxs"} , |
668 | | { ARM64_TLBI_VAE1OS, "vae1os"} , |
669 | | { ARM64_TLBI_VAE1OSNXS, "vae1osnxs"} , |
670 | | { ARM64_TLBI_VAE2, "vae2"} , |
671 | | { ARM64_TLBI_VAE2IS, "vae2is"} , |
672 | | { ARM64_TLBI_VAE2ISNXS, "vae2isnxs"} , |
673 | | { ARM64_TLBI_VAE2NXS, "vae2nxs"} , |
674 | | { ARM64_TLBI_VAE2OS, "vae2os"} , |
675 | | { ARM64_TLBI_VAE2OSNXS, "vae2osnxs"} , |
676 | | { ARM64_TLBI_VAE3, "vae3"} , |
677 | | { ARM64_TLBI_VAE3IS, "vae3is"} , |
678 | | { ARM64_TLBI_VAE3ISNXS, "vae3isnxs"} , |
679 | | { ARM64_TLBI_VAE3NXS, "vae3nxs"} , |
680 | | { ARM64_TLBI_VAE3OS, "vae3os"} , |
681 | | { ARM64_TLBI_VAE3OSNXS, "vae3osnxs"} , |
682 | | { ARM64_TLBI_VALE1, "vale1"} , |
683 | | { ARM64_TLBI_VALE1IS, "vale1is"} , |
684 | | { ARM64_TLBI_VALE1ISNXS, "vale1isnxs"} , |
685 | | { ARM64_TLBI_VALE1NXS, "vale1nxs"} , |
686 | | { ARM64_TLBI_VALE1OS, "vale1os"} , |
687 | | { ARM64_TLBI_VALE1OSNXS, "vale1osnxs"} , |
688 | | { ARM64_TLBI_VALE2, "vale2"} , |
689 | | { ARM64_TLBI_VALE2IS, "vale2is"} , |
690 | | { ARM64_TLBI_VALE2ISNXS, "vale2isnxs"} , |
691 | | { ARM64_TLBI_VALE2NXS, "vale2nxs"} , |
692 | | { ARM64_TLBI_VALE2OS, "vale2os"} , |
693 | | { ARM64_TLBI_VALE2OSNXS, "vale2osnxs"} , |
694 | | { ARM64_TLBI_VALE3, "vale3"} , |
695 | | { ARM64_TLBI_VALE3IS, "vale3is"} , |
696 | | { ARM64_TLBI_VALE3ISNXS, "vale3isnxs"} , |
697 | | { ARM64_TLBI_VALE3NXS, "vale3nxs"} , |
698 | | { ARM64_TLBI_VALE3OS, "vale3os"} , |
699 | | { ARM64_TLBI_VALE3OSNXS, "vale3osnxs"} , |
700 | | { ARM64_TLBI_VMALLE1, "vmalle1"} , |
701 | | { ARM64_TLBI_VMALLE1IS, "vmalle1is"} , |
702 | | { ARM64_TLBI_VMALLE1ISNXS, "vmalle1isnxs"} , |
703 | | { ARM64_TLBI_VMALLE1NXS, "vmalle1nxs"} , |
704 | | { ARM64_TLBI_VMALLE1OS, "vmalle1os"} , |
705 | | { ARM64_TLBI_VMALLE1OSNXS, "vmalle1osnxs"} , |
706 | | { ARM64_TLBI_VMALLS12E1, "vmalls12e1"} , |
707 | | { ARM64_TLBI_VMALLS12E1IS, "vmalls12e1is"} , |
708 | | { ARM64_TLBI_VMALLS12E1ISNXS, "vmalls12e1isnxs"} , |
709 | | { ARM64_TLBI_VMALLS12E1NXS, "vmalls12e1nxs"} , |
710 | | { ARM64_TLBI_VMALLS12E1OS, "vmalls12e1os"} , |
711 | | { ARM64_TLBI_VMALLS12E1OSNXS, "vmalls12e1osnxs"} , |
712 | | { ARM64_AT_S1E1R, "s1e1r"} , |
713 | | { ARM64_AT_S1E2R, "s1e2r"} , |
714 | | { ARM64_AT_S1E3R, "s1e3r"} , |
715 | | { ARM64_AT_S1E1W, "s1e1w"} , |
716 | | { ARM64_AT_S1E2W, "s1e2w"} , |
717 | | { ARM64_AT_S1E3W, "s1e3w"} , |
718 | | { ARM64_AT_S1E0R, "s1e0r"} , |
719 | | { ARM64_AT_S1E0W, "s1e0w"} , |
720 | | { ARM64_AT_S12E1R, "s12e1r"} , |
721 | | { ARM64_AT_S12E1W, "s12e1w"} , |
722 | | { ARM64_AT_S12E0R, "s12e0r"} , |
723 | | { ARM64_AT_S12E0W, "s12e0w"} , |
724 | | { ARM64_AT_S1E1RP, "s1e1rp"} , |
725 | | { ARM64_AT_S1E1WP, "s1e1wp"} , |
726 | | { ARM64_DC_CGDSW, "cgdsw"} , |
727 | | { ARM64_DC_CGDVAC, "cgdvac"} , |
728 | | { ARM64_DC_CGDVADP, "cgdvadp"} , |
729 | | { ARM64_DC_CGDVAP, "cgdvap"} , |
730 | | { ARM64_DC_CGSW, "cgsw"} , |
731 | | { ARM64_DC_CGVAC, "cgvac"} , |
732 | | { ARM64_DC_CGVADP, "cgvadp"} , |
733 | | { ARM64_DC_CGVAP, "cgvap"} , |
734 | | { ARM64_DC_CIGDSW, "cigdsw"} , |
735 | | { ARM64_DC_CIGDVAC, "cigdvac"} , |
736 | | { ARM64_DC_CIGSW, "cigsw"} , |
737 | | { ARM64_DC_CIGVAC, "cigvac"} , |
738 | | { ARM64_DC_CISW, "cisw"} , |
739 | | { ARM64_DC_CIVAC, "civac"} , |
740 | | { ARM64_DC_CSW, "csw"} , |
741 | | { ARM64_DC_CVAC, "cvac"} , |
742 | | { ARM64_DC_CVADP, "cvadp"} , |
743 | | { ARM64_DC_CVAP, "cvap"} , |
744 | | { ARM64_DC_CVAU, "cvau"} , |
745 | | { ARM64_DC_GVA, "gva"} , |
746 | | { ARM64_DC_GZVA, "gzva"} , |
747 | | { ARM64_DC_IGDSW, "igdsw"} , |
748 | | { ARM64_DC_IGDVAC, "igdvac"} , |
749 | | { ARM64_DC_IGSW, "igsw"} , |
750 | | { ARM64_DC_IGVAC, "igvac"} , |
751 | | { ARM64_DC_ISW, "isw"} , |
752 | | { ARM64_DC_IVAC, "ivac"} , |
753 | | { ARM64_DC_ZVA, "zva"} , |
754 | | { ARM64_IC_IALLUIS, "ialluis"} , |
755 | | { ARM64_IC_IALLU, "iallu"} , |
756 | | { ARM64_IC_IVAU, "ivau"} , |
757 | | }; |
758 | | |
759 | | arm64_sys_op AArch64_map_sys_op(const char *name) |
760 | 383 | { |
761 | 383 | int result = name2id(sys_op_name_map, ARR_SIZE(sys_op_name_map), name); |
762 | 383 | if (result == -1) { |
763 | 0 | return ARM64_SYS_INVALID; |
764 | 0 | } |
765 | 383 | return result; |
766 | 383 | } |
767 | | |
768 | | void arm64_op_addReg(MCInst *MI, int reg) |
769 | 0 | { |
770 | 0 | if (MI->csh->detail) { |
771 | 0 | MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; |
772 | 0 | MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = reg; |
773 | 0 | MI->flat_insn->detail->arm64.op_count++; |
774 | 0 | } |
775 | 0 | } |
776 | | |
777 | | void arm64_op_addVectorArrSpecifier(MCInst * MI, int sp) |
778 | 16.8k | { |
779 | 16.8k | if (MI->csh->detail) { |
780 | 16.8k | MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].vas = sp; |
781 | 16.8k | } |
782 | 16.8k | } |
783 | | |
784 | | void arm64_op_addFP(MCInst *MI, float fp) |
785 | 262 | { |
786 | 262 | if (MI->csh->detail) { |
787 | 262 | MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_FP; |
788 | 262 | MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].fp = fp; |
789 | 262 | MI->flat_insn->detail->arm64.op_count++; |
790 | 262 | } |
791 | 262 | } |
792 | | |
793 | | void arm64_op_addImm(MCInst *MI, int64_t imm) |
794 | 4.32k | { |
795 | 4.32k | if (MI->csh->detail) { |
796 | 4.32k | MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM; |
797 | 4.32k | MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (int)imm; |
798 | 4.32k | MI->flat_insn->detail->arm64.op_count++; |
799 | 4.32k | } |
800 | 4.32k | } |
801 | | |
802 | | #ifndef CAPSTONE_DIET |
803 | | |
804 | | // map instruction to its characteristics |
805 | | typedef struct insn_op { |
806 | | unsigned int eflags_update; // how this instruction update status flags |
807 | | uint8_t access[5]; |
808 | | } insn_op; |
809 | | |
810 | | static const insn_op insn_ops[] = { |
811 | | { |
812 | | /* NULL item */ |
813 | | 0, { 0 } |
814 | | }, |
815 | | |
816 | | #include "AArch64MappingInsnOp.inc" |
817 | | }; |
818 | | |
819 | | // given internal insn id, return operand access info |
820 | | const uint8_t *AArch64_get_op_access(cs_struct *h, unsigned int id) |
821 | 347k | { |
822 | 347k | int i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache); |
823 | 347k | if (i != 0) { |
824 | 347k | return insn_ops[i].access; |
825 | 347k | } |
826 | | |
827 | 0 | return NULL; |
828 | 347k | } |
829 | | |
830 | | void AArch64_reg_access(const cs_insn *insn, |
831 | | cs_regs regs_read, uint8_t *regs_read_count, |
832 | | cs_regs regs_write, uint8_t *regs_write_count) |
833 | 0 | { |
834 | 0 | uint8_t i; |
835 | 0 | uint8_t read_count, write_count; |
836 | 0 | cs_arm64 *arm64 = &(insn->detail->arm64); |
837 | |
|
838 | 0 | read_count = insn->detail->regs_read_count; |
839 | 0 | write_count = insn->detail->regs_write_count; |
840 | | |
841 | | // implicit registers |
842 | 0 | memcpy(regs_read, insn->detail->regs_read, read_count * sizeof(insn->detail->regs_read[0])); |
843 | 0 | memcpy(regs_write, insn->detail->regs_write, write_count * sizeof(insn->detail->regs_write[0])); |
844 | | |
845 | | // explicit registers |
846 | 0 | for (i = 0; i < arm64->op_count; i++) { |
847 | 0 | cs_arm64_op *op = &(arm64->operands[i]); |
848 | 0 | switch((int)op->type) { |
849 | 0 | case ARM64_OP_REG: |
850 | 0 | if ((op->access & CS_AC_READ) && !arr_exist(regs_read, read_count, op->reg)) { |
851 | 0 | regs_read[read_count] = (uint16_t)op->reg; |
852 | 0 | read_count++; |
853 | 0 | } |
854 | 0 | if ((op->access & CS_AC_WRITE) && !arr_exist(regs_write, write_count, op->reg)) { |
855 | 0 | regs_write[write_count] = (uint16_t)op->reg; |
856 | 0 | write_count++; |
857 | 0 | } |
858 | 0 | break; |
859 | 0 | case ARM_OP_MEM: |
860 | | // registers appeared in memory references always being read |
861 | 0 | if ((op->mem.base != ARM64_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.base)) { |
862 | 0 | regs_read[read_count] = (uint16_t)op->mem.base; |
863 | 0 | read_count++; |
864 | 0 | } |
865 | 0 | if ((op->mem.index != ARM64_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.index)) { |
866 | 0 | regs_read[read_count] = (uint16_t)op->mem.index; |
867 | 0 | read_count++; |
868 | 0 | } |
869 | 0 | if ((arm64->writeback) && (op->mem.base != ARM64_REG_INVALID) && !arr_exist(regs_write, write_count, op->mem.base)) { |
870 | 0 | regs_write[write_count] = (uint16_t)op->mem.base; |
871 | 0 | write_count++; |
872 | 0 | } |
873 | 0 | default: |
874 | 0 | break; |
875 | 0 | } |
876 | 0 | } |
877 | | |
878 | 0 | *regs_read_count = read_count; |
879 | 0 | *regs_write_count = write_count; |
880 | 0 | } |
881 | | #endif |
882 | | |
883 | | #endif |