Coverage Report

Created: 2026-08-31 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/capstonev5/arch/AArch64/AArch64Mapping.c
Line
Count
Source
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
17.4k
{
383
17.4k
#ifndef CAPSTONE_DIET
384
17.4k
  if (reg >= ARR_SIZE(reg_name_maps))
385
0
    return NULL;
386
387
17.4k
  return reg_name_maps[reg];
388
#else
389
  return NULL;
390
#endif
391
17.4k
}
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
361k
{
408
361k
  int i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache);
409
361k
  if (i != 0) {
410
361k
    insn->id = insns[i].mapid;
411
412
361k
    if (h->detail) {
413
361k
#ifndef CAPSTONE_DIET
414
361k
      cs_struct handle;
415
361k
      handle.detail = h->detail;
416
417
361k
      memcpy(insn->detail->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use));
418
361k
      insn->detail->regs_read_count = (uint8_t)count_positive(insns[i].regs_use);
419
420
361k
      memcpy(insn->detail->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod));
421
361k
      insn->detail->regs_write_count = (uint8_t)count_positive(insns[i].regs_mod);
422
423
361k
      memcpy(insn->detail->groups, insns[i].groups, sizeof(insns[i].groups));
424
361k
      insn->detail->groups_count = (uint8_t)count_positive8(insns[i].groups);
425
426
361k
      insn->detail->arm64.update_flags = cs_reg_write((csh)&handle, insn, ARM64_REG_NZCV);
427
361k
#endif
428
361k
    }
429
361k
  }
430
361k
}
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
361k
{
451
361k
#ifndef CAPSTONE_DIET
452
361k
  if (id >= ARM64_INS_ENDING)
453
0
    return NULL;
454
455
361k
  if (id < ARR_SIZE(insn_name_maps))
456
361k
    return insn_name_maps[id];
457
458
  // not found
459
0
  return NULL;
460
#else
461
  return NULL;
462
#endif
463
361k
}
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
132k
{
512
132k
#ifndef CAPSTONE_DIET
513
132k
  return id2name(group_name_maps, ARR_SIZE(group_name_maps), id);
514
#else
515
  return NULL;
516
#endif
517
132k
}
518
519
// map instruction name to public instruction ID
520
arm64_insn AArch64_map_insn(const char *name)
521
51.0k
{
522
51.0k
  unsigned int i;
523
524
34.0M
  for(i = 1; i < ARR_SIZE(insn_name_maps); i++) {
525
34.0M
    if (!strcmp(name, insn_name_maps[i]))
526
50.8k
      return i;
527
34.0M
  }
528
529
  // not found
530
250
  return ARM64_INS_INVALID;
531
51.0k
}
532
533
// map internal raw vregister to 'public' register
534
arm64_reg AArch64_map_vregister(unsigned int r)
535
253k
{
536
253k
  static const unsigned short RegAsmOffsetvreg[] = {
537
253k
#include "AArch64GenRegisterV.inc"
538
253k
  };
539
540
253k
  if (r < ARR_SIZE(RegAsmOffsetvreg))
541
253k
    return RegAsmOffsetvreg[r - 1];
542
543
  // cannot find this register
544
0
  return 0;
545
253k
}
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
1.65k
{
761
1.65k
  int result = name2id(sys_op_name_map, ARR_SIZE(sys_op_name_map), name);
762
1.65k
  if (result == -1) {
763
0
    return ARM64_SYS_INVALID;
764
0
  }
765
1.65k
  return result;
766
1.65k
}
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
68.1k
{
779
68.1k
  if (MI->csh->detail) {
780
68.1k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].vas = sp;
781
68.1k
  }
782
68.1k
}
783
784
void arm64_op_addFP(MCInst *MI, float fp)
785
1.40k
{
786
1.40k
  if (MI->csh->detail) {
787
1.40k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_FP;
788
1.40k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].fp = fp;
789
1.40k
    MI->flat_insn->detail->arm64.op_count++;
790
1.40k
  }
791
1.40k
}
792
793
void arm64_op_addImm(MCInst *MI, int64_t imm)
794
6.96k
{
795
6.96k
  if (MI->csh->detail) {
796
6.96k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
797
6.96k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (int)imm;
798
6.96k
    MI->flat_insn->detail->arm64.op_count++;
799
6.96k
  }
800
6.96k
}
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
1.04M
{
822
1.04M
  int i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache);
823
1.04M
  if (i != 0) {
824
1.04M
    return insn_ops[i].access;
825
1.04M
  }
826
827
0
  return NULL;
828
1.04M
}
829
830
static bool is_casp(unsigned int id);
831
static void add_casp_register_pair_access(const cs_arm64 *arm64,
832
    cs_regs regs_read, uint8_t *read_count,
833
    cs_regs regs_write, uint8_t *write_count);
834
835
void AArch64_reg_access(const cs_insn *insn,
836
    cs_regs regs_read, uint8_t *regs_read_count,
837
    cs_regs regs_write, uint8_t *regs_write_count)
838
0
{
839
0
  uint8_t i;
840
0
  uint8_t read_count, write_count;
841
0
  cs_arm64 *arm64 = &(insn->detail->arm64);
842
843
0
  read_count = insn->detail->regs_read_count;
844
0
  write_count = insn->detail->regs_write_count;
845
846
  // implicit registers
847
0
  memcpy(regs_read, insn->detail->regs_read, read_count * sizeof(insn->detail->regs_read[0]));
848
0
  memcpy(regs_write, insn->detail->regs_write, write_count * sizeof(insn->detail->regs_write[0]));
849
850
  // explicit registers
851
0
  for (i = 0; i < arm64->op_count; i++) {
852
0
    cs_arm64_op *op = &(arm64->operands[i]);
853
0
    switch((int)op->type) {
854
0
      case ARM64_OP_REG:
855
0
        if ((op->access & CS_AC_READ) && !arr_exist(regs_read, read_count, op->reg)) {
856
0
          regs_read[read_count] = (uint16_t)op->reg;
857
0
          read_count++;
858
0
        }
859
0
        if ((op->access & CS_AC_WRITE) && !arr_exist(regs_write, write_count, op->reg)) {
860
0
          regs_write[write_count] = (uint16_t)op->reg;
861
0
          write_count++;
862
0
        }
863
0
        break;
864
0
      case ARM_OP_MEM:
865
        // registers appeared in memory references always being read
866
0
        if ((op->mem.base != ARM64_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.base)) {
867
0
          regs_read[read_count] = (uint16_t)op->mem.base;
868
0
          read_count++;
869
0
        }
870
0
        if ((op->mem.index != ARM64_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.index)) {
871
0
          regs_read[read_count] = (uint16_t)op->mem.index;
872
0
          read_count++;
873
0
        }
874
0
        if ((arm64->writeback) && (op->mem.base != ARM64_REG_INVALID) && !arr_exist(regs_write, write_count, op->mem.base)) {
875
0
          regs_write[write_count] = (uint16_t)op->mem.base;
876
0
          write_count++;
877
0
        }
878
0
      default:
879
0
        break;
880
0
    }
881
0
  }
882
883
0
  if (is_casp(insn->id))
884
0
    add_casp_register_pair_access(arm64, regs_read, &read_count, regs_write, &write_count);
885
886
0
  *regs_read_count = read_count;
887
0
  *regs_write_count = write_count;
888
0
}
889
890
static bool is_casp(unsigned int id)
891
0
{
892
0
  return id == ARM64_INS_CASP || id == ARM64_INS_CASPA ||
893
0
    id == ARM64_INS_CASPAL || id == ARM64_INS_CASPL;
894
0
}
895
896
// The CASP register-pair operands have their second element printed without any
897
// operand-access info, so populate it here: operands 0..1 are read and written,
898
// 2..3 are read.
899
static void add_casp_register_pair_access(const cs_arm64 *arm64,
900
    cs_regs regs_read, uint8_t *read_count,
901
    cs_regs regs_write, uint8_t *write_count)
902
0
{
903
0
  uint8_t i;
904
905
0
  for (i = 0; i < 4 && i < arm64->op_count; i++) {
906
0
    arm64_reg reg = arm64->operands[i].reg;
907
0
    if (!arr_exist(regs_read, *read_count, reg)) {
908
0
      regs_read[*read_count] = (uint16_t)reg;
909
0
      (*read_count)++;
910
0
    }
911
0
    if (i < 2 && !arr_exist(regs_write, *write_count, reg)) {
912
0
      regs_write[*write_count] = (uint16_t)reg;
913
0
      (*write_count)++;
914
0
    }
915
0
  }
916
0
}
917
#endif
918
919
#endif