Coverage Report

Created: 2025-07-01 07:03

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