Coverage Report

Created: 2025-11-24 06:12

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
4.18k
{
383
4.18k
#ifndef CAPSTONE_DIET
384
4.18k
  if (reg >= ARR_SIZE(reg_name_maps))
385
0
    return NULL;
386
387
4.18k
  return reg_name_maps[reg];
388
#else
389
  return NULL;
390
#endif
391
4.18k
}
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
56.4k
{
408
56.4k
  int i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache);
409
56.4k
  if (i != 0) {
410
56.4k
    insn->id = insns[i].mapid;
411
412
56.4k
    if (h->detail) {
413
56.4k
#ifndef CAPSTONE_DIET
414
56.4k
      cs_struct handle;
415
56.4k
      handle.detail = h->detail;
416
417
56.4k
      memcpy(insn->detail->regs_read, insns[i].regs_use, sizeof(insns[i].regs_use));
418
56.4k
      insn->detail->regs_read_count = (uint8_t)count_positive(insns[i].regs_use);
419
420
56.4k
      memcpy(insn->detail->regs_write, insns[i].regs_mod, sizeof(insns[i].regs_mod));
421
56.4k
      insn->detail->regs_write_count = (uint8_t)count_positive(insns[i].regs_mod);
422
423
56.4k
      memcpy(insn->detail->groups, insns[i].groups, sizeof(insns[i].groups));
424
56.4k
      insn->detail->groups_count = (uint8_t)count_positive8(insns[i].groups);
425
426
56.4k
      insn->detail->arm64.update_flags = cs_reg_write((csh)&handle, insn, ARM64_REG_NZCV);
427
56.4k
#endif
428
56.4k
    }
429
56.4k
  }
430
56.4k
}
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
56.4k
{
451
56.4k
#ifndef CAPSTONE_DIET
452
56.4k
  if (id >= ARM64_INS_ENDING)
453
0
    return NULL;
454
455
56.4k
  if (id < ARR_SIZE(insn_name_maps))
456
56.4k
    return insn_name_maps[id];
457
458
  // not found
459
0
  return NULL;
460
#else
461
  return NULL;
462
#endif
463
56.4k
}
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
391k
{
512
391k
#ifndef CAPSTONE_DIET
513
391k
  return id2name(group_name_maps, ARR_SIZE(group_name_maps), id);
514
#else
515
  return NULL;
516
#endif
517
391k
}
518
519
// map instruction name to public instruction ID
520
arm64_insn AArch64_map_insn(const char *name)
521
9.15k
{
522
9.15k
  unsigned int i;
523
524
5.64M
  for(i = 1; i < ARR_SIZE(insn_name_maps); i++) {
525
5.64M
    if (!strcmp(name, insn_name_maps[i]))
526
9.14k
      return i;
527
5.64M
  }
528
529
  // not found
530
7
  return ARM64_INS_INVALID;
531
9.15k
}
532
533
// map internal raw vregister to 'public' register
534
arm64_reg AArch64_map_vregister(unsigned int r)
535
46.4k
{
536
46.4k
  static const unsigned short RegAsmOffsetvreg[] = {
537
46.4k
#include "AArch64GenRegisterV.inc"
538
46.4k
  };
539
540
46.4k
  if (r < ARR_SIZE(RegAsmOffsetvreg))
541
46.4k
    return RegAsmOffsetvreg[r - 1];
542
543
  // cannot find this register
544
0
  return 0;
545
46.4k
}
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
121
{
761
121
  int result = name2id(sys_op_name_map, ARR_SIZE(sys_op_name_map), name);
762
121
  if (result == -1) {
763
0
    return ARM64_SYS_INVALID;
764
0
  }
765
121
  return result;
766
121
}
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
9.68k
{
779
9.68k
  if (MI->csh->detail) {
780
9.68k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].vas = sp;
781
9.68k
  }
782
9.68k
}
783
784
void arm64_op_addFP(MCInst *MI, float fp)
785
58
{
786
58
  if (MI->csh->detail) {
787
58
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_FP;
788
58
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].fp = fp;
789
58
    MI->flat_insn->detail->arm64.op_count++;
790
58
  }
791
58
}
792
793
void arm64_op_addImm(MCInst *MI, int64_t imm)
794
1.26k
{
795
1.26k
  if (MI->csh->detail) {
796
1.26k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
797
1.26k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (int)imm;
798
1.26k
    MI->flat_insn->detail->arm64.op_count++;
799
1.26k
  }
800
1.26k
}
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
161k
{
822
161k
  int i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache);
823
161k
  if (i != 0) {
824
161k
    return insn_ops[i].access;
825
161k
  }
826
827
0
  return NULL;
828
161k
}
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