Coverage Report

Created: 2023-09-25 06:24

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