Coverage Report

Created: 2023-09-25 06:24

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