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