Coverage Report

Created: 2026-03-03 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/capstonenext/arch/AArch64/AArch64InstPrinter.c
Line
Count
Source
1
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
2
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
3
/*    Rot127 <unisono@quyllur.org> 2022-2023 */
4
/* Automatically translated source file from LLVM. */
5
6
/* LLVM-commit: <commit> */
7
/* LLVM-tag: <tag> */
8
9
/* Only small edits allowed. */
10
/* For multiple similar edits, please create a Patch for the translator. */
11
12
/* Capstone's C++ file translator: */
13
/* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */
14
15
//==-- AArch64InstPrinter.cpp - Convert AArch64 MCInst to assembly syntax --==//
16
//
17
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
18
// See https://llvm.org/LICENSE.txt for license information.
19
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
20
//
21
//===----------------------------------------------------------------------===//
22
//
23
// This class prints an AArch64 MCInst to a .s file.
24
//
25
//===----------------------------------------------------------------------===//
26
27
#include <stdio.h>
28
#include <string.h>
29
#include <stdlib.h>
30
#include <capstone/platform.h>
31
32
#include "../../Mapping.h"
33
#include "../../MCInst.h"
34
#include "../../MCInstPrinter.h"
35
#include "../../MCRegisterInfo.h"
36
#include "../../SStream.h"
37
#include "../../utils.h"
38
#include "AArch64AddressingModes.h"
39
#include "AArch64BaseInfo.h"
40
#include "AArch64DisassemblerExtension.h"
41
#include "AArch64InstPrinter.h"
42
#include "AArch64Linkage.h"
43
#include "AArch64Mapping.h"
44
45
#define GET_BANKEDREG_IMPL
46
#include "AArch64GenSystemOperands.inc"
47
48
185k
#define CONCAT(a, b) CONCAT_(a, b)
49
185k
#define CONCAT_(a, b) a##_##b
50
51
#define CONCATs(a, b) CONCATS(a, b)
52
#define CONCATS(a, b) a##b
53
54
#define DEBUG_TYPE "asm-printer"
55
56
// BEGIN Static declarations.
57
// These functions must be declared statically here, because they
58
// are also defined in the ARM module.
59
// If they are not static, we fail during linking.
60
61
static void printCustomAliasOperand(MCInst *MI, uint64_t Address,
62
            unsigned OpIdx, unsigned PrintMethodIdx,
63
            SStream *OS);
64
65
static void printFPImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
66
67
#define DECLARE_printComplexRotationOp(Angle, Remainder) \
68
  static void CONCAT(printComplexRotationOp, CONCAT(Angle, Remainder))( \
69
    MCInst * MI, unsigned OpNo, SStream *O);
70
DECLARE_printComplexRotationOp(180, 90);
71
DECLARE_printComplexRotationOp(90, 0);
72
73
// END Static declarations.
74
75
#define GET_INSTRUCTION_NAME
76
#define PRINT_ALIAS_INSTR
77
#include "AArch64GenAsmWriter.inc"
78
79
void printRegName(SStream *OS, unsigned Reg)
80
318k
{
81
318k
  SStream_concat(OS, "%s%s", markup("<reg:"),
82
318k
           getRegisterName(Reg, AArch64_NoRegAltName));
83
318k
  SStream_concat0(OS, markup(">"));
84
318k
}
85
86
void printRegNameAlt(SStream *OS, unsigned Reg, unsigned AltIdx)
87
79.5k
{
88
79.5k
  SStream_concat(OS, "%s%s", markup("<reg:"),
89
79.5k
           getRegisterName(Reg, AltIdx));
90
79.5k
  SStream_concat0(OS, markup(">"));
91
79.5k
}
92
93
const char *getRegName(unsigned Reg)
94
0
{
95
0
  return getRegisterName(Reg, AArch64_NoRegAltName);
96
0
}
97
98
void printInst(MCInst *MI, uint64_t Address, const char *Annot, SStream *O)
99
158k
{
100
158k
  bool isAlias = false;
101
158k
  bool useAliasDetails = map_use_alias_details(MI);
102
158k
  map_set_fill_detail_ops(MI, useAliasDetails);
103
104
158k
  unsigned Opcode = MCInst_getOpcode(MI);
105
106
158k
  if (Opcode == AArch64_SYSxt) {
107
1.51k
    if (printSysAlias(MI, O)) {
108
398
      isAlias = true;
109
398
      MCInst_setIsAlias(MI, isAlias);
110
398
      if (useAliasDetails)
111
398
        return;
112
398
    }
113
1.51k
  }
114
115
158k
  if (Opcode == AArch64_SYSPxt || Opcode == AArch64_SYSPxt_XZR) {
116
2.55k
    if (printSyspAlias(MI, O)) {
117
1.24k
      isAlias = true;
118
1.24k
      MCInst_setIsAlias(MI, isAlias);
119
1.24k
      if (useAliasDetails)
120
1.24k
        return;
121
1.24k
    }
122
2.55k
  }
123
124
  // RPRFM overlaps PRFM (reg), so try to print it as RPRFM here.
125
156k
  if ((Opcode == AArch64_PRFMroX) || (Opcode == AArch64_PRFMroW)) {
126
130
    if (printRangePrefetchAlias(MI, O, Annot)) {
127
0
      isAlias = true;
128
0
      MCInst_setIsAlias(MI, isAlias);
129
0
      if (useAliasDetails)
130
0
        return;
131
0
    }
132
130
  }
133
134
  // SBFM/UBFM should print to a nicer aliased form if possible.
135
156k
  if (Opcode == AArch64_SBFMXri || Opcode == AArch64_SBFMWri ||
136
155k
      Opcode == AArch64_UBFMXri || Opcode == AArch64_UBFMWri) {
137
1.60k
    MCOperand *Op0 = MCInst_getOperand(MI, (0));
138
1.60k
    MCOperand *Op1 = MCInst_getOperand(MI, (1));
139
1.60k
    MCOperand *Op2 = MCInst_getOperand(MI, (2));
140
1.60k
    MCOperand *Op3 = MCInst_getOperand(MI, (3));
141
142
1.60k
    bool IsSigned = (Opcode == AArch64_SBFMXri ||
143
582
         Opcode == AArch64_SBFMWri);
144
1.60k
    bool Is64Bit = (Opcode == AArch64_SBFMXri ||
145
582
        Opcode == AArch64_UBFMXri);
146
1.60k
    if (MCOperand_isImm(Op2) && MCOperand_getImm(Op2) == 0 &&
147
909
        MCOperand_isImm(Op3)) {
148
909
      const char *AsmMnemonic = NULL;
149
150
909
      switch (MCOperand_getImm(Op3)) {
151
133
      default:
152
133
        break;
153
473
      case 7:
154
473
        if (IsSigned)
155
420
          AsmMnemonic = "sxtb";
156
53
        else if (!Is64Bit)
157
2
          AsmMnemonic = "uxtb";
158
473
        break;
159
219
      case 15:
160
219
        if (IsSigned)
161
153
          AsmMnemonic = "sxth";
162
66
        else if (!Is64Bit)
163
39
          AsmMnemonic = "uxth";
164
219
        break;
165
84
      case 31:
166
        // *xtw is only valid for signed 64-bit operations.
167
84
        if (Is64Bit && IsSigned)
168
58
          AsmMnemonic = "sxtw";
169
84
        break;
170
909
      }
171
172
909
      if (AsmMnemonic) {
173
672
        SStream_concat(O, "%s", AsmMnemonic);
174
672
        SStream_concat0(O, " ");
175
176
672
        printRegName(O, MCOperand_getReg(Op0));
177
672
        SStream_concat0(O, ", ");
178
672
        printRegName(O, getWRegFromXReg(
179
672
              MCOperand_getReg(Op1)));
180
672
        if (detail_is_set(MI) && useAliasDetails) {
181
672
          AArch64_set_detail_op_reg(
182
672
            MI, 0, MCOperand_getReg(Op0));
183
672
          AArch64_set_detail_op_reg(
184
672
            MI, 1,
185
672
            getWRegFromXReg(
186
672
              MCOperand_getReg(Op1)));
187
672
          if (strings_match(AsmMnemonic, "uxtb"))
188
2
            AArch64_get_detail_op(MI, -1)
189
2
              ->ext =
190
2
              AARCH64_EXT_UXTB;
191
670
          else if (strings_match(AsmMnemonic,
192
670
                     "sxtb"))
193
420
            AArch64_get_detail_op(MI, -1)
194
420
              ->ext =
195
420
              AARCH64_EXT_SXTB;
196
250
          else if (strings_match(AsmMnemonic,
197
250
                     "uxth"))
198
39
            AArch64_get_detail_op(MI, -1)
199
39
              ->ext =
200
39
              AARCH64_EXT_UXTH;
201
211
          else if (strings_match(AsmMnemonic,
202
211
                     "sxth"))
203
153
            AArch64_get_detail_op(MI, -1)
204
153
              ->ext =
205
153
              AARCH64_EXT_SXTH;
206
58
          else if (strings_match(AsmMnemonic,
207
58
                     "sxtw"))
208
58
            AArch64_get_detail_op(MI, -1)
209
58
              ->ext =
210
58
              AARCH64_EXT_SXTW;
211
0
          else
212
0
            AArch64_get_detail_op(MI, -1)
213
0
              ->ext =
214
0
              AARCH64_EXT_INVALID;
215
672
        }
216
672
        isAlias = true;
217
672
        MCInst_setIsAlias(MI, isAlias);
218
672
        if (useAliasDetails)
219
672
          return;
220
0
        else
221
0
          goto add_real_detail;
222
672
      }
223
909
    }
224
225
    // All immediate shifts are aliases, implemented using the Bitfield
226
    // instruction. In all cases the immediate shift amount shift must be in
227
    // the range 0 to (reg.size -1).
228
935
    if (MCOperand_isImm(Op2) && MCOperand_isImm(Op3)) {
229
935
      const char *AsmMnemonic = NULL;
230
935
      int shift = 0;
231
935
      int64_t immr = MCOperand_getImm(Op2);
232
935
      int64_t imms = MCOperand_getImm(Op3);
233
935
      if (Opcode == AArch64_UBFMWri && imms != 0x1F &&
234
19
          ((imms + 1) == immr)) {
235
1
        AsmMnemonic = "lsl";
236
1
        shift = 31 - imms;
237
934
      } else if (Opcode == AArch64_UBFMXri && imms != 0x3f &&
238
223
           ((imms + 1 == immr))) {
239
33
        AsmMnemonic = "lsl";
240
33
        shift = 63 - imms;
241
901
      } else if (Opcode == AArch64_UBFMWri && imms == 0x1f) {
242
7
        AsmMnemonic = "lsr";
243
7
        shift = immr;
244
894
      } else if (Opcode == AArch64_UBFMXri && imms == 0x3f) {
245
18
        AsmMnemonic = "lsr";
246
18
        shift = immr;
247
876
      } else if (Opcode == AArch64_SBFMWri && imms == 0x1f) {
248
24
        AsmMnemonic = "asr";
249
24
        shift = immr;
250
852
      } else if (Opcode == AArch64_SBFMXri && imms == 0x3f) {
251
146
        AsmMnemonic = "asr";
252
146
        shift = immr;
253
146
      }
254
935
      if (AsmMnemonic) {
255
229
        SStream_concat(O, "%s", AsmMnemonic);
256
229
        SStream_concat0(O, " ");
257
258
229
        printRegName(O, MCOperand_getReg(Op0));
259
229
        SStream_concat0(O, ", ");
260
229
        printRegName(O, MCOperand_getReg(Op1));
261
229
        SStream_concat(O, "%s%s#%d", ", ",
262
229
                 markup("<imm:"), shift);
263
229
        SStream_concat0(O, markup(">"));
264
229
        if (detail_is_set(MI) && useAliasDetails) {
265
229
          AArch64_set_detail_op_reg(
266
229
            MI, 0, MCOperand_getReg(Op0));
267
229
          AArch64_set_detail_op_reg(
268
229
            MI, 1, MCOperand_getReg(Op1));
269
229
          if (strings_match(AsmMnemonic, "lsl"))
270
34
            AArch64_get_detail_op(MI, -1)
271
34
              ->shift.type =
272
34
              AARCH64_SFT_LSL;
273
195
          else if (strings_match(AsmMnemonic,
274
195
                     "lsr"))
275
25
            AArch64_get_detail_op(MI, -1)
276
25
              ->shift.type =
277
25
              AARCH64_SFT_LSR;
278
170
          else if (strings_match(AsmMnemonic,
279
170
                     "asr"))
280
170
            AArch64_get_detail_op(MI, -1)
281
170
              ->shift.type =
282
170
              AARCH64_SFT_ASR;
283
0
          else
284
0
            AArch64_get_detail_op(MI, -1)
285
0
              ->shift.type =
286
0
              AARCH64_SFT_INVALID;
287
229
          AArch64_get_detail_op(MI, -1)
288
229
            ->shift.value = shift;
289
229
        }
290
229
        isAlias = true;
291
229
        MCInst_setIsAlias(MI, isAlias);
292
229
        if (useAliasDetails)
293
229
          return;
294
0
        else
295
0
          goto add_real_detail;
296
229
      }
297
935
    }
298
299
    // SBFIZ/UBFIZ aliases
300
706
    if (MCOperand_getImm(Op2) > MCOperand_getImm(Op3)) {
301
458
      SStream_concat(O, "%s", (IsSigned ? "sbfiz" : "ubfiz"));
302
458
      SStream_concat0(O, " ");
303
304
458
      printRegName(O, MCOperand_getReg(Op0));
305
458
      SStream_concat0(O, ", ");
306
458
      printRegName(O, MCOperand_getReg(Op1));
307
458
      SStream_concat(O, "%s%s", ", ", markup("<imm:"));
308
458
      printUInt32Bang(O, (Is64Bit ? 64 : 32) -
309
458
               MCOperand_getImm(Op2));
310
458
      SStream_concat(O, "%s%s%s", markup(">"), ", ",
311
458
               markup("<imm:"));
312
458
      printInt64Bang(O, MCOperand_getImm(Op3) + 1);
313
458
      SStream_concat0(O, markup(">"));
314
458
      if (detail_is_set(MI) && useAliasDetails) {
315
458
        AArch64_set_detail_op_reg(
316
458
          MI, 0, MCOperand_getReg(Op0));
317
458
        AArch64_set_detail_op_reg(
318
458
          MI, 1, MCOperand_getReg(Op1));
319
458
        AArch64_set_detail_op_imm(
320
458
          MI, 2, AARCH64_OP_IMM,
321
458
          (Is64Bit ? 64 : 32) -
322
458
            MCOperand_getImm(Op2));
323
458
        AArch64_set_detail_op_imm(
324
458
          MI, 3, AARCH64_OP_IMM,
325
458
          MCOperand_getImm(Op3) + 1);
326
458
      }
327
458
      isAlias = true;
328
458
      MCInst_setIsAlias(MI, isAlias);
329
458
      if (useAliasDetails)
330
458
        return;
331
0
      else
332
0
        goto add_real_detail;
333
458
    }
334
335
    // Otherwise SBFX/UBFX is the preferred form
336
248
    SStream_concat(O, "%s", (IsSigned ? "sbfx" : "ubfx"));
337
248
    SStream_concat0(O, " ");
338
339
248
    printRegName(O, MCOperand_getReg(Op0));
340
248
    SStream_concat0(O, ", ");
341
248
    printRegName(O, MCOperand_getReg(Op1));
342
248
    SStream_concat(O, "%s%s", ", ", markup("<imm:"));
343
248
    printInt64Bang(O, MCOperand_getImm(Op2));
344
248
    SStream_concat(O, "%s%s%s", markup(">"), ", ", markup("<imm:"));
345
248
    printInt64Bang(O, MCOperand_getImm(Op3) -
346
248
            MCOperand_getImm(Op2) + 1);
347
248
    SStream_concat0(O, markup(">"));
348
248
    if (detail_is_set(MI) && useAliasDetails) {
349
248
      AArch64_set_detail_op_reg(MI, 0, MCOperand_getReg(Op0));
350
248
      AArch64_set_detail_op_reg(MI, 1, MCOperand_getReg(Op1));
351
248
      AArch64_set_detail_op_imm(MI, 2, AARCH64_OP_IMM,
352
248
              MCOperand_getImm(Op2));
353
248
      AArch64_set_detail_op_imm(
354
248
        MI, 3, AARCH64_OP_IMM,
355
248
        MCOperand_getImm(Op3) - MCOperand_getImm(Op2) +
356
248
          1);
357
248
    }
358
248
    isAlias = true;
359
248
    MCInst_setIsAlias(MI, isAlias);
360
248
    if (useAliasDetails)
361
248
      return;
362
0
    else
363
0
      goto add_real_detail;
364
248
  }
365
366
155k
  if (Opcode == AArch64_BFMXri || Opcode == AArch64_BFMWri) {
367
547
    isAlias = true;
368
547
    MCInst_setIsAlias(MI, isAlias);
369
547
    MCOperand *Op0 = MCInst_getOperand(MI, (0)); // Op1 == Op0
370
547
    MCOperand *Op2 = MCInst_getOperand(MI, (2));
371
547
    int ImmR = MCOperand_getImm(MCInst_getOperand(MI, (3)));
372
547
    int ImmS = MCOperand_getImm(MCInst_getOperand(MI, (4)));
373
374
547
    if ((MCOperand_getReg(Op2) == AArch64_WZR ||
375
533
         MCOperand_getReg(Op2) == AArch64_XZR) &&
376
238
        (ImmR == 0 || ImmS < ImmR) &&
377
142
        (AArch64_getFeatureBits(MI->csh->mode,
378
142
              AArch64_FeatureAll) ||
379
0
         AArch64_getFeatureBits(MI->csh->mode,
380
142
              AArch64_HasV8_2aOps))) {
381
      // BFC takes precedence over its entire range, sligtly differently
382
      // to BFI.
383
142
      int BitWidth = Opcode == AArch64_BFMXri ? 64 : 32;
384
142
      int LSB = (BitWidth - ImmR) % BitWidth;
385
142
      int Width = ImmS + 1;
386
387
142
      SStream_concat0(O, "bfc ");
388
142
      printRegName(O, MCOperand_getReg(Op0));
389
142
      SStream_concat(O, "%s%s#%d", ", ", markup("<imm:"),
390
142
               LSB);
391
142
      SStream_concat(O, "%s%s%s#%d", markup(">"), ", ",
392
142
               markup("<imm:"), Width);
393
142
      SStream_concat0(O, markup(">"));
394
142
      if (detail_is_set(MI) && useAliasDetails) {
395
142
        AArch64_set_detail_op_reg(
396
142
          MI, 0, MCOperand_getReg(Op0));
397
142
        AArch64_set_detail_op_imm(MI, 3, AARCH64_OP_IMM,
398
142
                LSB);
399
142
        AArch64_set_detail_op_imm(MI, 4, AARCH64_OP_IMM,
400
142
                Width);
401
142
      }
402
403
142
      if (useAliasDetails)
404
142
        return;
405
0
      else
406
0
        goto add_real_detail;
407
405
    } else if (ImmS < ImmR) {
408
      // BFI alias
409
175
      int BitWidth = Opcode == AArch64_BFMXri ? 64 : 32;
410
175
      int LSB = (BitWidth - ImmR) % BitWidth;
411
175
      int Width = ImmS + 1;
412
413
175
      SStream_concat0(O, "bfi ");
414
175
      printRegName(O, MCOperand_getReg(Op0));
415
175
      SStream_concat0(O, ", ");
416
175
      printRegName(O, MCOperand_getReg(Op2));
417
175
      SStream_concat(O, "%s%s#%d", ", ", markup("<imm:"),
418
175
               LSB);
419
175
      SStream_concat(O, "%s%s%s#%d", markup(">"), ", ",
420
175
               markup("<imm:"), Width);
421
175
      SStream_concat0(O, markup(">"));
422
175
      if (detail_is_set(MI) && useAliasDetails) {
423
175
        AArch64_set_detail_op_reg(
424
175
          MI, 0, MCOperand_getReg(Op0));
425
175
        AArch64_set_detail_op_reg(
426
175
          MI, 2, MCOperand_getReg(Op2));
427
175
        AArch64_set_detail_op_imm(MI, 3, AARCH64_OP_IMM,
428
175
                LSB);
429
175
        AArch64_set_detail_op_imm(MI, 4, AARCH64_OP_IMM,
430
175
                Width);
431
175
      }
432
175
      if (useAliasDetails)
433
175
        return;
434
0
      else
435
0
        goto add_real_detail;
436
175
    }
437
438
230
    int LSB = ImmR;
439
230
    int Width = ImmS - ImmR + 1;
440
    // Otherwise BFXIL the preferred form
441
230
    SStream_concat0(O, "bfxil ");
442
230
    printRegName(O, MCOperand_getReg(Op0));
443
230
    SStream_concat0(O, ", ");
444
230
    printRegName(O, MCOperand_getReg(Op2));
445
230
    SStream_concat(O, "%s%s#%d", ", ", markup("<imm:"), LSB);
446
230
    SStream_concat(O, "%s%s%s#%d", markup(">"), ", ",
447
230
             markup("<imm:"), Width);
448
230
    SStream_concat0(O, markup(">"));
449
230
    if (detail_is_set(MI) && useAliasDetails) {
450
230
      AArch64_set_detail_op_reg(MI, 0, MCOperand_getReg(Op0));
451
230
      AArch64_set_detail_op_reg(MI, 2, MCOperand_getReg(Op2));
452
230
      AArch64_set_detail_op_imm(MI, 3, AARCH64_OP_IMM, LSB);
453
230
      AArch64_set_detail_op_imm(MI, 4, AARCH64_OP_IMM, Width);
454
230
    }
455
230
    if (useAliasDetails)
456
230
      return;
457
230
  }
458
459
  // Symbolic operands for MOVZ, MOVN and MOVK already imply a shift
460
  // (e.g. :gottprel_g1: is always going to be "lsl #16") so it should not be
461
  // printed.
462
154k
  if ((Opcode == AArch64_MOVZXi || Opcode == AArch64_MOVZWi ||
463
154k
       Opcode == AArch64_MOVNXi || Opcode == AArch64_MOVNWi) &&
464
1.07k
      MCOperand_isExpr(MCInst_getOperand(MI, (1)))) {
465
0
    printUInt64Bang(O, MCInst_getOpVal(MI, 1));
466
0
    if (detail_is_set(MI) && useAliasDetails) {
467
0
      AArch64_set_detail_op_imm(MI, 1, AARCH64_OP_IMM,
468
0
              MCInst_getOpVal(MI, 1));
469
0
    }
470
0
  }
471
472
154k
  if ((Opcode == AArch64_MOVKXi || Opcode == AArch64_MOVKWi) &&
473
823
      MCOperand_isExpr(MCInst_getOperand(MI, (2)))) {
474
0
    printUInt64Bang(O, MCInst_getOpVal(MI, 2));
475
0
    if (detail_is_set(MI) && useAliasDetails) {
476
0
      AArch64_set_detail_op_imm(MI, 2, AARCH64_OP_IMM,
477
0
              MCInst_getOpVal(MI, 2));
478
0
    }
479
0
  }
480
481
  // MOVZ, MOVN and "ORR wzr, #imm" instructions are aliases for MOV, but
482
  // their domains overlap so they need to be prioritized. The chain is "MOVZ
483
  // lsl #0 > MOVZ lsl #N > MOVN lsl #0 > MOVN lsl #N > ORR". The highest
484
  // instruction that can represent the move is the MOV alias, and the rest
485
  // get printed normally.
486
154k
  if ((Opcode == AArch64_MOVZXi || Opcode == AArch64_MOVZWi) &&
487
586
      MCOperand_isImm(MCInst_getOperand(MI, (1))) &&
488
586
      MCOperand_isImm(MCInst_getOperand(MI, (2)))) {
489
586
    int RegWidth = Opcode == AArch64_MOVZXi ? 64 : 32;
490
586
    int Shift = MCOperand_getImm(MCInst_getOperand(MI, (2)));
491
586
    uint64_t Value =
492
586
      (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, (1)))
493
586
      << Shift;
494
495
586
    if (AArch64_AM_isMOVZMovAlias(
496
586
          Value, Shift, Opcode == AArch64_MOVZXi ? 64 : 32)) {
497
486
      isAlias = true;
498
486
      MCInst_setIsAlias(MI, isAlias);
499
486
      SStream_concat0(O, "mov ");
500
486
      printRegName(O, MCOperand_getReg(
501
486
            MCInst_getOperand(MI, (0))));
502
486
      SStream_concat(O, "%s%s", ", ", markup("<imm:"));
503
486
      printInt64Bang(O, SignExtend64(Value, RegWidth));
504
486
      SStream_concat0(O, markup(">"));
505
486
      if (detail_is_set(MI) && useAliasDetails) {
506
486
        AArch64_set_detail_op_reg(
507
486
          MI, 0, MCInst_getOpVal(MI, 0));
508
486
        AArch64_set_detail_op_imm(
509
486
          MI, 1, AARCH64_OP_IMM,
510
486
          SignExtend64(Value, RegWidth));
511
486
      }
512
486
      if (useAliasDetails)
513
486
        return;
514
486
    }
515
586
  }
516
517
154k
  if ((Opcode == AArch64_MOVNXi || Opcode == AArch64_MOVNWi) &&
518
485
      MCOperand_isImm(MCInst_getOperand(MI, (1))) &&
519
485
      MCOperand_isImm(MCInst_getOperand(MI, (2)))) {
520
485
    int RegWidth = Opcode == AArch64_MOVNXi ? 64 : 32;
521
485
    int Shift = MCOperand_getImm(MCInst_getOperand(MI, (2)));
522
485
    uint64_t Value =
523
485
      ~((uint64_t)MCOperand_getImm(MCInst_getOperand(MI, (1)))
524
485
        << Shift);
525
485
    if (RegWidth == 32)
526
321
      Value = Value & 0xffffffff;
527
528
485
    if (AArch64_AM_isMOVNMovAlias(Value, Shift, RegWidth)) {
529
180
      isAlias = true;
530
180
      MCInst_setIsAlias(MI, isAlias);
531
180
      SStream_concat0(O, "mov ");
532
180
      printRegName(O, MCOperand_getReg(
533
180
            MCInst_getOperand(MI, (0))));
534
180
      SStream_concat(O, "%s%s", ", ", markup("<imm:"));
535
180
      printInt64Bang(O, SignExtend64(Value, RegWidth));
536
180
      SStream_concat0(O, markup(">"));
537
180
      if (detail_is_set(MI) && useAliasDetails) {
538
180
        AArch64_set_detail_op_reg(
539
180
          MI, 0, MCInst_getOpVal(MI, 0));
540
180
        AArch64_set_detail_op_imm(
541
180
          MI, 1, AARCH64_OP_IMM,
542
180
          SignExtend64(Value, RegWidth));
543
180
      }
544
180
      if (useAliasDetails)
545
180
        return;
546
180
    }
547
485
  }
548
549
154k
  if ((Opcode == AArch64_ORRXri || Opcode == AArch64_ORRWri) &&
550
1.39k
      (MCOperand_getReg(MCInst_getOperand(MI, (1))) == AArch64_XZR ||
551
618
       MCOperand_getReg(MCInst_getOperand(MI, (1))) == AArch64_WZR) &&
552
956
      MCOperand_isImm(MCInst_getOperand(MI, (2)))) {
553
956
    int RegWidth = Opcode == AArch64_ORRXri ? 64 : 32;
554
956
    uint64_t Value = AArch64_AM_decodeLogicalImmediate(
555
956
      MCOperand_getImm(MCInst_getOperand(MI, (2))), RegWidth);
556
956
    if (!AArch64_AM_isAnyMOVWMovAlias(Value, RegWidth)) {
557
535
      isAlias = true;
558
535
      MCInst_setIsAlias(MI, isAlias);
559
535
      SStream_concat0(O, "mov ");
560
535
      printRegName(O, MCOperand_getReg(
561
535
            MCInst_getOperand(MI, (0))));
562
535
      SStream_concat(O, "%s%s", ", ", markup("<imm:"));
563
535
      printInt64Bang(O, SignExtend64(Value, RegWidth));
564
535
      SStream_concat0(O, markup(">"));
565
535
      if (detail_is_set(MI) && useAliasDetails) {
566
535
        AArch64_set_detail_op_reg(
567
535
          MI, 0, MCInst_getOpVal(MI, 0));
568
535
        AArch64_set_detail_op_imm(
569
535
          MI, 2, AARCH64_OP_IMM,
570
535
          SignExtend64(Value, RegWidth));
571
535
      }
572
535
      if (useAliasDetails)
573
535
        return;
574
535
    }
575
956
  }
576
577
153k
  if (Opcode == AArch64_SPACE) {
578
0
    isAlias = true;
579
0
    MCInst_setIsAlias(MI, isAlias);
580
0
    SStream_concat1(O, ' ');
581
0
    SStream_concat(O, "%s", " SPACE ");
582
0
    printInt64(O, MCOperand_getImm(MCInst_getOperand(MI, (1))));
583
0
    if (detail_is_set(MI) && useAliasDetails) {
584
0
      AArch64_set_detail_op_imm(MI, 1, AARCH64_OP_IMM,
585
0
              MCInst_getOpVal(MI, 1));
586
0
    }
587
0
    if (useAliasDetails)
588
0
      return;
589
0
  }
590
591
153k
  if (!isAlias)
592
153k
    isAlias |= printAliasInstr(MI, Address, O);
593
594
153k
add_real_detail:
595
153k
  MCInst_setIsAlias(MI, isAlias);
596
597
153k
  if (!isAlias || !useAliasDetails) {
598
139k
    map_set_fill_detail_ops(MI, !(isAlias && useAliasDetails));
599
139k
    if (isAlias)
600
0
      SStream_Close(O);
601
139k
    printInstruction(MI, Address, O);
602
139k
    if (isAlias)
603
0
      SStream_Open(O);
604
139k
  }
605
153k
}
606
607
bool printRangePrefetchAlias(MCInst *MI, SStream *O, const char *Annot)
608
130
{
609
130
  unsigned Opcode = MCInst_getOpcode(MI);
610
611
130
#ifndef NDEBUG
612
613
130
#endif
614
615
130
  unsigned PRFOp = MCOperand_getImm(MCInst_getOperand(MI, (0)));
616
130
  unsigned Mask = 0x18; // 0b11000
617
130
  if ((PRFOp & Mask) != Mask)
618
130
    return false; // Rt != '11xxx', it's a PRFM instruction.
619
620
0
  unsigned Rm = MCOperand_getReg(MCInst_getOperand(MI, (2)));
621
622
  // "Rm" must be a 64-bit GPR for RPRFM.
623
0
  if (MCRegisterInfo_getRegClass(MI->MRI, Rm))
624
0
    Rm = MCRegisterInfo_getMatchingSuperReg(
625
0
      MI->MRI, Rm, AArch64_sub_32,
626
0
      MCRegisterInfo_getRegClass(MI->MRI, Rm));
627
628
0
  unsigned SignExtend = MCOperand_getImm(
629
0
    MCInst_getOperand(MI, (3))); // encoded in "option<2>".
630
0
  unsigned Shift =
631
0
    MCOperand_getImm(MCInst_getOperand(MI, (4))); // encoded in "S".
632
633
0
  unsigned Option0 = (Opcode == AArch64_PRFMroX) ? 1 : 0;
634
635
  // encoded in "option<2>:option<0>:S:Rt<2:0>".
636
0
  unsigned RPRFOp = (SignExtend << 5) | (Option0 << 4) | (Shift << 3) |
637
0
        (PRFOp & 0x7);
638
639
0
  SStream_concat0(O, "rprfm ");
640
0
  const AArch64RPRFM_RPRFM *RPRFM =
641
0
    AArch64RPRFM_lookupRPRFMByEncoding(RPRFOp);
642
0
  if (RPRFM) {
643
0
    SStream_concat0(O, RPRFM->Name);
644
0
  } else {
645
0
    printUInt32Bang(O, RPRFOp);
646
0
    SStream_concat(O, ", ");
647
0
  }
648
0
  SStream_concat0(O, getRegisterName(Rm, AArch64_NoRegAltName));
649
0
  SStream_concat0(O, ", [");
650
0
  printOperand(MI, 1, O); // "Rn".
651
0
  SStream_concat0(O, "]");
652
653
0
  return true;
654
130
}
655
656
bool printSysAlias(MCInst *MI, SStream *O)
657
1.51k
{
658
1.51k
  MCOperand *Op1 = MCInst_getOperand(MI, (0));
659
1.51k
  MCOperand *Cn = MCInst_getOperand(MI, (1));
660
1.51k
  MCOperand *Cm = MCInst_getOperand(MI, (2));
661
1.51k
  MCOperand *Op2 = MCInst_getOperand(MI, (3));
662
663
1.51k
  unsigned Op1Val = MCOperand_getImm(Op1);
664
1.51k
  unsigned CnVal = MCOperand_getImm(Cn);
665
1.51k
  unsigned CmVal = MCOperand_getImm(Cm);
666
1.51k
  unsigned Op2Val = MCOperand_getImm(Op2);
667
668
1.51k
  uint16_t Encoding = Op2Val;
669
1.51k
  Encoding |= CmVal << 3;
670
1.51k
  Encoding |= CnVal << 7;
671
1.51k
  Encoding |= Op1Val << 11;
672
673
1.51k
  bool NeedsReg;
674
1.51k
  const char *Ins;
675
1.51k
  const char *Name;
676
677
1.51k
  if (CnVal == 7) {
678
615
    switch (CmVal) {
679
5
    default:
680
5
      return false;
681
    // Maybe IC, maybe Prediction Restriction
682
218
    case 1:
683
218
      switch (Op1Val) {
684
31
      default:
685
31
        return false;
686
172
      case 0:
687
172
        goto Search_IC;
688
15
      case 3:
689
15
        goto Search_PRCTX;
690
218
      }
691
    // Prediction Restriction aliases
692
49
    case 3: {
693
64
Search_PRCTX:
694
64
      if (Op1Val != 3 || CnVal != 7 || CmVal != 3)
695
38
        return false;
696
697
26
      unsigned int Requires =
698
26
        Op2Val == 6 ? AArch64_FeatureSPECRES2 :
699
26
                AArch64_FeaturePredRes;
700
26
      if (!(AArch64_getFeatureBits(MI->csh->mode,
701
26
                 AArch64_FeatureAll) ||
702
0
            AArch64_getFeatureBits(MI->csh->mode, Requires)))
703
0
        return false;
704
705
26
      NeedsReg = true;
706
26
      switch (Op2Val) {
707
1
      default:
708
1
        return false;
709
0
      case 4:
710
0
        Ins = "cfp ";
711
0
        break;
712
0
      case 5:
713
0
        Ins = "dvp ";
714
0
        break;
715
1
      case 6:
716
1
        Ins = "cosp ";
717
1
        break;
718
24
      case 7:
719
24
        Ins = "cpp ";
720
24
        break;
721
26
      }
722
25
      Name = "RCTX";
723
25
    } break;
724
    // IC aliases
725
19
    case 5: {
726
191
Search_IC: {
727
191
  const AArch64IC_IC *IC = AArch64IC_lookupICByEncoding(Encoding);
728
191
  if (!IC ||
729
18
      !AArch64_testFeatureList(MI->csh->mode, IC->FeaturesRequired))
730
173
    return false;
731
18
  if (detail_is_set(MI)) {
732
18
    aarch64_sysop sysop = { 0 };
733
18
    sysop.reg = IC->SysReg;
734
18
    sysop.sub_type = AARCH64_OP_IC;
735
18
    AArch64_get_detail_op(MI, 0)->type = AARCH64_OP_SYSREG;
736
18
    AArch64_get_detail_op(MI, 0)->sysop = sysop;
737
18
    AArch64_inc_op_count(MI);
738
18
  }
739
740
18
  NeedsReg = IC->NeedsReg;
741
18
  Ins = "ic ";
742
18
  Name = IC->Name;
743
18
}
744
18
    } break;
745
    // DC aliases
746
13
    case 4:
747
39
    case 6:
748
82
    case 10:
749
88
    case 11:
750
88
    case 12:
751
97
    case 13:
752
162
    case 14: {
753
162
      const AArch64DC_DC *DC =
754
162
        AArch64DC_lookupDCByEncoding(Encoding);
755
162
      if (!DC || !AArch64_testFeatureList(
756
51
             MI->csh->mode, DC->FeaturesRequired))
757
111
        return false;
758
51
      if (detail_is_set(MI)) {
759
51
        aarch64_sysop sysop = { 0 };
760
51
        sysop.alias = DC->SysAlias;
761
51
        sysop.sub_type = AARCH64_OP_DC;
762
51
        AArch64_get_detail_op(MI, 0)->type =
763
51
          AARCH64_OP_SYSALIAS;
764
51
        AArch64_get_detail_op(MI, 0)->sysop = sysop;
765
51
        AArch64_inc_op_count(MI);
766
51
      }
767
768
51
      NeedsReg = true;
769
51
      Ins = "dc ";
770
51
      Name = DC->Name;
771
51
    } break;
772
    // AT aliases
773
111
    case 8:
774
162
    case 9: {
775
162
      const AArch64AT_AT *AT =
776
162
        AArch64AT_lookupATByEncoding(Encoding);
777
162
      if (!AT || !AArch64_testFeatureList(
778
116
             MI->csh->mode, AT->FeaturesRequired))
779
46
        return false;
780
781
116
      if (detail_is_set(MI)) {
782
116
        aarch64_sysop sysop = { 0 };
783
116
        sysop.alias = AT->SysAlias;
784
116
        sysop.sub_type = AARCH64_OP_AT;
785
116
        AArch64_get_detail_op(MI, 0)->type =
786
116
          AARCH64_OP_SYSALIAS;
787
116
        AArch64_get_detail_op(MI, 0)->sysop = sysop;
788
116
        AArch64_inc_op_count(MI);
789
116
      }
790
116
      NeedsReg = true;
791
116
      Ins = "at ";
792
116
      Name = AT->Name;
793
116
    } break;
794
615
    }
795
900
  } else if (CnVal == 8 || CnVal == 9) {
796
    // TLBI aliases
797
621
    const AArch64TLBI_TLBI *TLBI =
798
621
      AArch64TLBI_lookupTLBIByEncoding(Encoding);
799
621
    if (!TLBI || !AArch64_testFeatureList(MI->csh->mode,
800
188
                  TLBI->FeaturesRequired))
801
433
      return false;
802
803
188
    if (detail_is_set(MI)) {
804
188
      aarch64_sysop sysop = { 0 };
805
188
      sysop.reg = TLBI->SysReg;
806
188
      sysop.sub_type = AARCH64_OP_TLBI;
807
188
      AArch64_get_detail_op(MI, 0)->type = AARCH64_OP_SYSREG;
808
188
      AArch64_get_detail_op(MI, 0)->sysop = sysop;
809
188
      AArch64_inc_op_count(MI);
810
188
    }
811
188
    NeedsReg = TLBI->NeedsReg;
812
188
    Ins = "tlbi ";
813
188
    Name = TLBI->Name;
814
188
  } else
815
279
    return false;
816
817
796
#define TMP_STR_LEN 32
818
398
  char Str[TMP_STR_LEN] = { 0 };
819
398
  append_to_str_lower(Str, TMP_STR_LEN, Ins);
820
398
  append_to_str_lower(Str, TMP_STR_LEN, Name);
821
398
#undef TMP_STR_LEN
822
823
398
  SStream_concat1(O, ' ');
824
398
  SStream_concat0(O, Str);
825
398
  if (NeedsReg) {
826
377
    SStream_concat0(O, ", ");
827
377
    printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (4))));
828
377
    AArch64_set_detail_op_reg(MI, 4, MCInst_getOpVal(MI, 4));
829
377
  }
830
831
398
  return true;
832
1.51k
}
833
834
bool printSyspAlias(MCInst *MI, SStream *O)
835
2.55k
{
836
2.55k
  MCOperand *Op1 = MCInst_getOperand(MI, (0));
837
2.55k
  MCOperand *Cn = MCInst_getOperand(MI, (1));
838
2.55k
  MCOperand *Cm = MCInst_getOperand(MI, (2));
839
2.55k
  MCOperand *Op2 = MCInst_getOperand(MI, (3));
840
841
2.55k
  unsigned Op1Val = MCOperand_getImm(Op1);
842
2.55k
  unsigned CnVal = MCOperand_getImm(Cn);
843
2.55k
  unsigned CmVal = MCOperand_getImm(Cm);
844
2.55k
  unsigned Op2Val = MCOperand_getImm(Op2);
845
846
2.55k
  uint16_t Encoding = Op2Val;
847
2.55k
  Encoding |= CmVal << 3;
848
2.55k
  Encoding |= CnVal << 7;
849
2.55k
  Encoding |= Op1Val << 11;
850
851
2.55k
  const char *Ins;
852
2.55k
  const char *Name;
853
854
2.55k
  if (CnVal == 8 || CnVal == 9) {
855
    // TLBIP aliases
856
857
1.71k
    if (CnVal == 9) {
858
261
      if (!AArch64_getFeatureBits(MI->csh->mode,
859
261
                AArch64_FeatureAll) ||
860
261
          !AArch64_getFeatureBits(MI->csh->mode,
861
261
                AArch64_FeatureXS))
862
0
        return false;
863
261
      Encoding &= ~(1 << 7);
864
261
    }
865
866
1.71k
    const AArch64TLBI_TLBI *TLBI =
867
1.71k
      AArch64TLBI_lookupTLBIByEncoding(Encoding);
868
1.71k
    if (!TLBI || !AArch64_testFeatureList(MI->csh->mode,
869
1.24k
                  TLBI->FeaturesRequired))
870
469
      return false;
871
872
1.24k
    if (detail_is_set(MI)) {
873
1.24k
      aarch64_sysop sysop = { 0 };
874
1.24k
      sysop.reg = TLBI->SysReg;
875
1.24k
      sysop.sub_type = AARCH64_OP_TLBI;
876
1.24k
      AArch64_get_detail_op(MI, 0)->type = AARCH64_OP_SYSREG;
877
1.24k
      AArch64_get_detail_op(MI, 0)->sysop = sysop;
878
1.24k
      AArch64_inc_op_count(MI);
879
1.24k
    }
880
1.24k
    Ins = "tlbip ";
881
1.24k
    Name = TLBI->Name;
882
1.24k
  } else
883
848
    return false;
884
885
2.68k
#define TMP_STR_LEN 32
886
1.24k
  char Str[TMP_STR_LEN] = { 0 };
887
1.24k
  append_to_str_lower(Str, TMP_STR_LEN, Ins);
888
1.24k
  append_to_str_lower(Str, TMP_STR_LEN, Name);
889
890
1.24k
  if (CnVal == 9) {
891
202
    append_to_str_lower(Str, TMP_STR_LEN, "nxs");
892
202
  }
893
1.24k
#undef TMP_STR_LEN
894
895
1.24k
  SStream_concat1(O, ' ');
896
1.24k
  SStream_concat0(O, Str);
897
1.24k
  SStream_concat0(O, ", ");
898
1.24k
  if (MCOperand_getReg(MCInst_getOperand(MI, (4))) == AArch64_XZR)
899
967
    printSyspXzrPair(MI, 4, O);
900
275
  else
901
275
    CONCAT(printGPRSeqPairsClassOperand, 64)(MI, 4, O);
902
903
1.24k
  return true;
904
2.55k
}
905
906
#define DEFINE_printMatrix(EltSize) \
907
  void CONCAT(printMatrix, EltSize)(MCInst * MI, unsigned OpNum, \
908
            SStream *O) \
909
3.61k
  { \
910
3.61k
    AArch64_add_cs_detail_1( \
911
3.61k
      MI, CONCAT(AArch64_OP_GROUP_Matrix, EltSize), OpNum, \
912
3.61k
      EltSize); \
913
3.61k
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
914
3.61k
\
915
3.61k
    printRegName(O, MCOperand_getReg(RegOp)); \
916
3.61k
    switch (EltSize) { \
917
282
    case 0: \
918
282
      break; \
919
0
    case 8: \
920
0
      SStream_concat0(O, ".b"); \
921
0
      break; \
922
840
    case 16: \
923
840
      SStream_concat0(O, ".h"); \
924
840
      break; \
925
2.00k
    case 32: \
926
2.00k
      SStream_concat0(O, ".s"); \
927
2.00k
      break; \
928
496
    case 64: \
929
496
      SStream_concat0(O, ".d"); \
930
496
      break; \
931
0
    case 128: \
932
0
      SStream_concat0(O, ".q"); \
933
0
      break; \
934
0
    default: \
935
0
      CS_ASSERT_RET(0 && "Unsupported element size"); \
936
3.61k
    } \
937
3.61k
  }
printMatrix_64
Line
Count
Source
909
496
  { \
910
496
    AArch64_add_cs_detail_1( \
911
496
      MI, CONCAT(AArch64_OP_GROUP_Matrix, EltSize), OpNum, \
912
496
      EltSize); \
913
496
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
914
496
\
915
496
    printRegName(O, MCOperand_getReg(RegOp)); \
916
496
    switch (EltSize) { \
917
0
    case 0: \
918
0
      break; \
919
0
    case 8: \
920
0
      SStream_concat0(O, ".b"); \
921
0
      break; \
922
0
    case 16: \
923
0
      SStream_concat0(O, ".h"); \
924
0
      break; \
925
0
    case 32: \
926
0
      SStream_concat0(O, ".s"); \
927
0
      break; \
928
496
    case 64: \
929
496
      SStream_concat0(O, ".d"); \
930
496
      break; \
931
0
    case 128: \
932
0
      SStream_concat0(O, ".q"); \
933
0
      break; \
934
0
    default: \
935
0
      CS_ASSERT_RET(0 && "Unsupported element size"); \
936
496
    } \
937
496
  }
printMatrix_32
Line
Count
Source
909
2.00k
  { \
910
2.00k
    AArch64_add_cs_detail_1( \
911
2.00k
      MI, CONCAT(AArch64_OP_GROUP_Matrix, EltSize), OpNum, \
912
2.00k
      EltSize); \
913
2.00k
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
914
2.00k
\
915
2.00k
    printRegName(O, MCOperand_getReg(RegOp)); \
916
2.00k
    switch (EltSize) { \
917
0
    case 0: \
918
0
      break; \
919
0
    case 8: \
920
0
      SStream_concat0(O, ".b"); \
921
0
      break; \
922
0
    case 16: \
923
0
      SStream_concat0(O, ".h"); \
924
0
      break; \
925
2.00k
    case 32: \
926
2.00k
      SStream_concat0(O, ".s"); \
927
2.00k
      break; \
928
0
    case 64: \
929
0
      SStream_concat0(O, ".d"); \
930
0
      break; \
931
0
    case 128: \
932
0
      SStream_concat0(O, ".q"); \
933
0
      break; \
934
0
    default: \
935
0
      CS_ASSERT_RET(0 && "Unsupported element size"); \
936
2.00k
    } \
937
2.00k
  }
printMatrix_16
Line
Count
Source
909
840
  { \
910
840
    AArch64_add_cs_detail_1( \
911
840
      MI, CONCAT(AArch64_OP_GROUP_Matrix, EltSize), OpNum, \
912
840
      EltSize); \
913
840
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
914
840
\
915
840
    printRegName(O, MCOperand_getReg(RegOp)); \
916
840
    switch (EltSize) { \
917
0
    case 0: \
918
0
      break; \
919
0
    case 8: \
920
0
      SStream_concat0(O, ".b"); \
921
0
      break; \
922
840
    case 16: \
923
840
      SStream_concat0(O, ".h"); \
924
840
      break; \
925
0
    case 32: \
926
0
      SStream_concat0(O, ".s"); \
927
0
      break; \
928
0
    case 64: \
929
0
      SStream_concat0(O, ".d"); \
930
0
      break; \
931
0
    case 128: \
932
0
      SStream_concat0(O, ".q"); \
933
0
      break; \
934
0
    default: \
935
0
      CS_ASSERT_RET(0 && "Unsupported element size"); \
936
840
    } \
937
840
  }
printMatrix_0
Line
Count
Source
909
282
  { \
910
282
    AArch64_add_cs_detail_1( \
911
282
      MI, CONCAT(AArch64_OP_GROUP_Matrix, EltSize), OpNum, \
912
282
      EltSize); \
913
282
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
914
282
\
915
282
    printRegName(O, MCOperand_getReg(RegOp)); \
916
282
    switch (EltSize) { \
917
282
    case 0: \
918
282
      break; \
919
0
    case 8: \
920
0
      SStream_concat0(O, ".b"); \
921
0
      break; \
922
0
    case 16: \
923
0
      SStream_concat0(O, ".h"); \
924
0
      break; \
925
0
    case 32: \
926
0
      SStream_concat0(O, ".s"); \
927
0
      break; \
928
0
    case 64: \
929
0
      SStream_concat0(O, ".d"); \
930
0
      break; \
931
0
    case 128: \
932
0
      SStream_concat0(O, ".q"); \
933
0
      break; \
934
0
    default: \
935
0
      CS_ASSERT_RET(0 && "Unsupported element size"); \
936
282
    } \
937
282
  }
938
DEFINE_printMatrix(64);
939
DEFINE_printMatrix(32);
940
DEFINE_printMatrix(16);
941
DEFINE_printMatrix(0);
942
943
#define DEFINE_printMatrixTileVector(IsVertical) \
944
  void CONCAT(printMatrixTileVector, \
945
        IsVertical)(MCInst * MI, unsigned OpNum, SStream *O) \
946
3.70k
  { \
947
3.70k
    AArch64_add_cs_detail_1( \
948
3.70k
      MI, \
949
3.70k
      CONCAT(AArch64_OP_GROUP_MatrixTileVector, IsVertical), \
950
3.70k
      OpNum, IsVertical); \
951
3.70k
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
952
3.70k
\
953
3.70k
    const char *RegName = getRegisterName(MCOperand_getReg(RegOp), \
954
3.70k
                  AArch64_NoRegAltName); \
955
3.70k
\
956
3.70k
    unsigned buf_len = strlen(RegName) + 1; \
957
3.70k
    char *Base = cs_mem_calloc(1, buf_len); \
958
3.70k
    memcpy(Base, RegName, buf_len); \
959
3.70k
    char *Dot = strchr(Base, '.'); \
960
3.70k
    if (!Dot) { \
961
0
      SStream_concat0(O, RegName); \
962
0
      return; \
963
0
    } \
964
3.70k
    *Dot = '\0'; /* Split string */ \
965
3.70k
    char *Suffix = Dot + 1; \
966
3.70k
    SStream_concat(O, "%s%s", Base, (IsVertical ? "v" : "h")); \
967
3.70k
    SStream_concat1(O, '.'); \
968
3.70k
    SStream_concat0(O, Suffix); \
969
3.70k
    cs_mem_free(Base); \
970
3.70k
  }
printMatrixTileVector_0
Line
Count
Source
946
1.90k
  { \
947
1.90k
    AArch64_add_cs_detail_1( \
948
1.90k
      MI, \
949
1.90k
      CONCAT(AArch64_OP_GROUP_MatrixTileVector, IsVertical), \
950
1.90k
      OpNum, IsVertical); \
951
1.90k
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
952
1.90k
\
953
1.90k
    const char *RegName = getRegisterName(MCOperand_getReg(RegOp), \
954
1.90k
                  AArch64_NoRegAltName); \
955
1.90k
\
956
1.90k
    unsigned buf_len = strlen(RegName) + 1; \
957
1.90k
    char *Base = cs_mem_calloc(1, buf_len); \
958
1.90k
    memcpy(Base, RegName, buf_len); \
959
1.90k
    char *Dot = strchr(Base, '.'); \
960
1.90k
    if (!Dot) { \
961
0
      SStream_concat0(O, RegName); \
962
0
      return; \
963
0
    } \
964
1.90k
    *Dot = '\0'; /* Split string */ \
965
1.90k
    char *Suffix = Dot + 1; \
966
1.90k
    SStream_concat(O, "%s%s", Base, (IsVertical ? "v" : "h")); \
967
1.90k
    SStream_concat1(O, '.'); \
968
1.90k
    SStream_concat0(O, Suffix); \
969
1.90k
    cs_mem_free(Base); \
970
1.90k
  }
printMatrixTileVector_1
Line
Count
Source
946
1.80k
  { \
947
1.80k
    AArch64_add_cs_detail_1( \
948
1.80k
      MI, \
949
1.80k
      CONCAT(AArch64_OP_GROUP_MatrixTileVector, IsVertical), \
950
1.80k
      OpNum, IsVertical); \
951
1.80k
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
952
1.80k
\
953
1.80k
    const char *RegName = getRegisterName(MCOperand_getReg(RegOp), \
954
1.80k
                  AArch64_NoRegAltName); \
955
1.80k
\
956
1.80k
    unsigned buf_len = strlen(RegName) + 1; \
957
1.80k
    char *Base = cs_mem_calloc(1, buf_len); \
958
1.80k
    memcpy(Base, RegName, buf_len); \
959
1.80k
    char *Dot = strchr(Base, '.'); \
960
1.80k
    if (!Dot) { \
961
0
      SStream_concat0(O, RegName); \
962
0
      return; \
963
0
    } \
964
1.80k
    *Dot = '\0'; /* Split string */ \
965
1.80k
    char *Suffix = Dot + 1; \
966
1.80k
    SStream_concat(O, "%s%s", Base, (IsVertical ? "v" : "h")); \
967
1.80k
    SStream_concat1(O, '.'); \
968
1.80k
    SStream_concat0(O, Suffix); \
969
1.80k
    cs_mem_free(Base); \
970
1.80k
  }
971
DEFINE_printMatrixTileVector(0);
972
DEFINE_printMatrixTileVector(1);
973
974
void printMatrixTile(MCInst *MI, unsigned OpNum, SStream *O)
975
791
{
976
791
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_MatrixTile, OpNum);
977
791
  MCOperand *RegOp = MCInst_getOperand(MI, (OpNum));
978
979
791
  printRegName(O, MCOperand_getReg(RegOp));
980
791
}
981
982
void printSVCROp(MCInst *MI, unsigned OpNum, SStream *O)
983
0
{
984
0
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_SVCROp, OpNum);
985
0
  MCOperand *MO = MCInst_getOperand(MI, (OpNum));
986
987
0
  unsigned svcrop = MCOperand_getImm(MO);
988
0
  const AArch64SVCR_SVCR *SVCR = AArch64SVCR_lookupSVCRByEncoding(svcrop);
989
990
0
  SStream_concat0(O, SVCR->Name);
991
0
}
992
993
void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
994
212k
{
995
212k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_Operand, OpNo);
996
212k
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
997
212k
  if (MCOperand_isReg(Op)) {
998
179k
    unsigned Reg = MCOperand_getReg(Op);
999
179k
    printRegName(O, Reg);
1000
179k
  } else if (MCOperand_isImm(Op)) {
1001
32.5k
    Op = MCInst_getOperand(MI, (OpNo));
1002
32.5k
    SStream_concat(O, "%s", markup("<imm:"));
1003
32.5k
    printInt64Bang(O, MCOperand_getImm(Op));
1004
32.5k
    SStream_concat0(O, markup(">"));
1005
32.5k
  } else {
1006
0
    printUInt64Bang(O, MCInst_getOpVal(MI, OpNo));
1007
0
  }
1008
212k
}
1009
1010
void printImm(MCInst *MI, unsigned OpNo, SStream *O)
1011
2.66k
{
1012
2.66k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_Imm, OpNo);
1013
2.66k
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1014
2.66k
  SStream_concat(O, "%s", markup("<imm:"));
1015
2.66k
  printInt64Bang(O, MCOperand_getImm(Op));
1016
2.66k
  SStream_concat0(O, markup(">"));
1017
2.66k
}
1018
1019
void printImmHex(MCInst *MI, unsigned OpNo, SStream *O)
1020
142
{
1021
142
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_ImmHex, OpNo);
1022
142
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1023
142
  SStream_concat(O, "%s", markup("<imm:"));
1024
142
  printInt64Bang(O, MCOperand_getImm(Op));
1025
142
  SStream_concat0(O, markup(">"));
1026
142
}
1027
1028
#define DEFINE_printSImm(Size) \
1029
  void CONCAT(printSImm, Size)(MCInst * MI, unsigned OpNo, SStream *O) \
1030
760
  { \
1031
760
    AArch64_add_cs_detail_1( \
1032
760
      MI, CONCAT(AArch64_OP_GROUP_SImm, Size), OpNo, Size); \
1033
760
    MCOperand *Op = MCInst_getOperand(MI, (OpNo)); \
1034
760
    if (Size == 8) { \
1035
183
      SStream_concat(O, "%s", markup("<imm:")); \
1036
183
      printInt32Bang(O, MCOperand_getImm(Op)); \
1037
183
      SStream_concat0(O, markup(">")); \
1038
577
    } else if (Size == 16) { \
1039
577
      SStream_concat(O, "%s", markup("<imm:")); \
1040
577
      printInt32Bang(O, MCOperand_getImm(Op)); \
1041
577
      SStream_concat0(O, markup(">")); \
1042
577
    } else { \
1043
0
      SStream_concat(O, "%s", markup("<imm:")); \
1044
0
      printInt64Bang(O, MCOperand_getImm(Op)); \
1045
0
      SStream_concat0(O, markup(">")); \
1046
0
    } \
1047
760
  }
printSImm_16
Line
Count
Source
1030
577
  { \
1031
577
    AArch64_add_cs_detail_1( \
1032
577
      MI, CONCAT(AArch64_OP_GROUP_SImm, Size), OpNo, Size); \
1033
577
    MCOperand *Op = MCInst_getOperand(MI, (OpNo)); \
1034
577
    if (Size == 8) { \
1035
0
      SStream_concat(O, "%s", markup("<imm:")); \
1036
0
      printInt32Bang(O, MCOperand_getImm(Op)); \
1037
0
      SStream_concat0(O, markup(">")); \
1038
577
    } else if (Size == 16) { \
1039
577
      SStream_concat(O, "%s", markup("<imm:")); \
1040
577
      printInt32Bang(O, MCOperand_getImm(Op)); \
1041
577
      SStream_concat0(O, markup(">")); \
1042
577
    } else { \
1043
0
      SStream_concat(O, "%s", markup("<imm:")); \
1044
0
      printInt64Bang(O, MCOperand_getImm(Op)); \
1045
0
      SStream_concat0(O, markup(">")); \
1046
0
    } \
1047
577
  }
printSImm_8
Line
Count
Source
1030
183
  { \
1031
183
    AArch64_add_cs_detail_1( \
1032
183
      MI, CONCAT(AArch64_OP_GROUP_SImm, Size), OpNo, Size); \
1033
183
    MCOperand *Op = MCInst_getOperand(MI, (OpNo)); \
1034
183
    if (Size == 8) { \
1035
183
      SStream_concat(O, "%s", markup("<imm:")); \
1036
183
      printInt32Bang(O, MCOperand_getImm(Op)); \
1037
183
      SStream_concat0(O, markup(">")); \
1038
183
    } else if (Size == 16) { \
1039
0
      SStream_concat(O, "%s", markup("<imm:")); \
1040
0
      printInt32Bang(O, MCOperand_getImm(Op)); \
1041
0
      SStream_concat0(O, markup(">")); \
1042
0
    } else { \
1043
0
      SStream_concat(O, "%s", markup("<imm:")); \
1044
0
      printInt64Bang(O, MCOperand_getImm(Op)); \
1045
0
      SStream_concat0(O, markup(">")); \
1046
0
    } \
1047
183
  }
1048
DEFINE_printSImm(16);
1049
DEFINE_printSImm(8);
1050
1051
void printPostIncOperand(MCInst *MI, unsigned OpNo, unsigned Imm, SStream *O)
1052
6.48k
{
1053
6.48k
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1054
6.48k
  if (MCOperand_isReg(Op)) {
1055
6.48k
    unsigned Reg = MCOperand_getReg(Op);
1056
6.48k
    if (Reg == AArch64_XZR) {
1057
0
      SStream_concat(O, "%s", markup("<imm:"));
1058
0
      printUInt64Bang(O, Imm);
1059
0
      SStream_concat0(O, markup(">"));
1060
0
    } else
1061
6.48k
      printRegName(O, Reg);
1062
6.48k
  } else
1063
0
    CS_ASSERT_RET(0 &&
1064
6.48k
            "unknown operand kind in printPostIncOperand64");
1065
6.48k
}
1066
1067
void printVRegOperand(MCInst *MI, unsigned OpNo, SStream *O)
1068
37.7k
{
1069
37.7k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_VRegOperand, OpNo);
1070
37.7k
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1071
1072
37.7k
  unsigned Reg = MCOperand_getReg(Op);
1073
37.7k
  printRegNameAlt(O, Reg, AArch64_vreg);
1074
37.7k
}
1075
1076
void printSysCROperand(MCInst *MI, unsigned OpNo, SStream *O)
1077
5.01k
{
1078
5.01k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_SysCROperand, OpNo);
1079
5.01k
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1080
1081
5.01k
  SStream_concat(O, "%s", "c");
1082
5.01k
  printUInt32(O, MCOperand_getImm(Op));
1083
5.01k
  SStream_concat1(O, '\0');
1084
5.01k
}
1085
1086
void printAddSubImm(MCInst *MI, unsigned OpNum, SStream *O)
1087
1.37k
{
1088
1.37k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_AddSubImm, OpNum);
1089
1.37k
  MCOperand *MO = MCInst_getOperand(MI, (OpNum));
1090
1.37k
  if (MCOperand_isImm(MO)) {
1091
1.37k
    unsigned Val = (MCOperand_getImm(MO) & 0xfff);
1092
1093
1.37k
    unsigned Shift = AArch64_AM_getShiftValue(
1094
1.37k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))));
1095
1.37k
    SStream_concat(O, "%s", markup("<imm:"));
1096
1.37k
    printUInt32Bang(O, (Val));
1097
1.37k
    SStream_concat0(O, markup(">"));
1098
1.37k
    if (Shift != 0) {
1099
510
      printShifter(MI, OpNum + 1, O);
1100
510
    }
1101
1.37k
  } else {
1102
0
    printShifter(MI, OpNum + 1, O);
1103
0
  }
1104
1.37k
}
1105
1106
#define DEFINE_printLogicalImm(T) \
1107
  void CONCAT(printLogicalImm, T)(MCInst * MI, unsigned OpNum, \
1108
          SStream *O) \
1109
2.44k
  { \
1110
2.44k
    AArch64_add_cs_detail_1( \
1111
2.44k
      MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, \
1112
2.44k
      sizeof(T)); \
1113
2.44k
    uint64_t Val = \
1114
2.44k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1115
2.44k
    SStream_concat(O, "%s", markup("<imm:")); \
1116
2.44k
    printUInt64Bang(O, (AArch64_AM_decodeLogicalImmediate( \
1117
2.44k
             Val, 8 * sizeof(T)))); \
1118
2.44k
    SStream_concat0(O, markup(">")); \
1119
2.44k
  }
printLogicalImm_int64_t
Line
Count
Source
1109
1.17k
  { \
1110
1.17k
    AArch64_add_cs_detail_1( \
1111
1.17k
      MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, \
1112
1.17k
      sizeof(T)); \
1113
1.17k
    uint64_t Val = \
1114
1.17k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1115
1.17k
    SStream_concat(O, "%s", markup("<imm:")); \
1116
1.17k
    printUInt64Bang(O, (AArch64_AM_decodeLogicalImmediate( \
1117
1.17k
             Val, 8 * sizeof(T)))); \
1118
1.17k
    SStream_concat0(O, markup(">")); \
1119
1.17k
  }
printLogicalImm_int32_t
Line
Count
Source
1109
796
  { \
1110
796
    AArch64_add_cs_detail_1( \
1111
796
      MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, \
1112
796
      sizeof(T)); \
1113
796
    uint64_t Val = \
1114
796
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1115
796
    SStream_concat(O, "%s", markup("<imm:")); \
1116
796
    printUInt64Bang(O, (AArch64_AM_decodeLogicalImmediate( \
1117
796
             Val, 8 * sizeof(T)))); \
1118
796
    SStream_concat0(O, markup(">")); \
1119
796
  }
printLogicalImm_int8_t
Line
Count
Source
1109
256
  { \
1110
256
    AArch64_add_cs_detail_1( \
1111
256
      MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, \
1112
256
      sizeof(T)); \
1113
256
    uint64_t Val = \
1114
256
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1115
256
    SStream_concat(O, "%s", markup("<imm:")); \
1116
256
    printUInt64Bang(O, (AArch64_AM_decodeLogicalImmediate( \
1117
256
             Val, 8 * sizeof(T)))); \
1118
256
    SStream_concat0(O, markup(">")); \
1119
256
  }
printLogicalImm_int16_t
Line
Count
Source
1109
214
  { \
1110
214
    AArch64_add_cs_detail_1( \
1111
214
      MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, \
1112
214
      sizeof(T)); \
1113
214
    uint64_t Val = \
1114
214
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1115
214
    SStream_concat(O, "%s", markup("<imm:")); \
1116
214
    printUInt64Bang(O, (AArch64_AM_decodeLogicalImmediate( \
1117
214
             Val, 8 * sizeof(T)))); \
1118
214
    SStream_concat0(O, markup(">")); \
1119
214
  }
1120
DEFINE_printLogicalImm(int64_t);
1121
DEFINE_printLogicalImm(int32_t);
1122
DEFINE_printLogicalImm(int8_t);
1123
DEFINE_printLogicalImm(int16_t);
1124
1125
void printShifter(MCInst *MI, unsigned OpNum, SStream *O)
1126
7.00k
{
1127
7.00k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_Shifter, OpNum);
1128
7.00k
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1129
  // LSL #0 should not be printed.
1130
7.00k
  if (AArch64_AM_getShiftType(Val) == AArch64_AM_LSL &&
1131
4.23k
      AArch64_AM_getShiftValue(Val) == 0)
1132
726
    return;
1133
6.27k
  SStream_concat(
1134
6.27k
    O, "%s%s%s%s#%u", ", ",
1135
6.27k
    AArch64_AM_getShiftExtendName(AArch64_AM_getShiftType(Val)),
1136
6.27k
    " ", markup("<imm:"), AArch64_AM_getShiftValue(Val));
1137
6.27k
  SStream_concat0(O, markup(">"));
1138
6.27k
}
1139
1140
void printShiftedRegister(MCInst *MI, unsigned OpNum, SStream *O)
1141
3.82k
{
1142
3.82k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_ShiftedRegister, OpNum);
1143
3.82k
  printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))));
1144
3.82k
  printShifter(MI, OpNum + 1, O);
1145
3.82k
}
1146
1147
void printExtendedRegister(MCInst *MI, unsigned OpNum, SStream *O)
1148
539
{
1149
539
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_ExtendedRegister, OpNum);
1150
539
  printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))));
1151
539
  printArithExtend(MI, OpNum + 1, O);
1152
539
}
1153
1154
void printArithExtend(MCInst *MI, unsigned OpNum, SStream *O)
1155
737
{
1156
737
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_ArithExtend, OpNum);
1157
737
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1158
737
  AArch64_AM_ShiftExtendType ExtType = AArch64_AM_getArithExtendType(Val);
1159
737
  unsigned ShiftVal = AArch64_AM_getArithShiftValue(Val);
1160
1161
  // If the destination or first source register operand is [W]SP, print
1162
  // UXTW/UXTX as LSL, and if the shift amount is also zero, print nothing at
1163
  // all.
1164
737
  if (ExtType == AArch64_AM_UXTW || ExtType == AArch64_AM_UXTX) {
1165
180
    unsigned Dest = MCOperand_getReg(MCInst_getOperand(MI, (0)));
1166
180
    unsigned Src1 = MCOperand_getReg(MCInst_getOperand(MI, (1)));
1167
180
    if (((Dest == AArch64_SP || Src1 == AArch64_SP) &&
1168
66
         ExtType == AArch64_AM_UXTX) ||
1169
114
        ((Dest == AArch64_WSP || Src1 == AArch64_WSP) &&
1170
68
         ExtType == AArch64_AM_UXTW)) {
1171
68
      if (ShiftVal != 0) {
1172
68
        SStream_concat(O, "%s%s", ", lsl ",
1173
68
                 markup("<imm:"));
1174
68
        printUInt32Bang(O, ShiftVal);
1175
68
        SStream_concat0(O, markup(">"));
1176
68
      }
1177
68
      return;
1178
68
    }
1179
180
  }
1180
669
  SStream_concat(O, "%s", ", ");
1181
669
  SStream_concat0(O, AArch64_AM_getShiftExtendName(ExtType));
1182
669
  if (ShiftVal != 0) {
1183
635
    SStream_concat(O, "%s%s#%d", " ", markup("<imm:"), ShiftVal);
1184
635
    SStream_concat0(O, markup(">"));
1185
635
  }
1186
669
}
1187
1188
static void printMemExtendImpl(bool SignExtend, bool DoShift, unsigned Width,
1189
             char SrcRegKind, SStream *O, bool getUseMarkup)
1190
8.85k
{
1191
  // sxtw, sxtx, uxtw or lsl (== uxtx)
1192
8.85k
  bool IsLSL = !SignExtend && SrcRegKind == 'x';
1193
8.85k
  if (IsLSL)
1194
4.34k
    SStream_concat0(O, "lsl");
1195
4.51k
  else {
1196
4.51k
    SStream_concat(O, "%c%s", (SignExtend ? 's' : 'u'), "xt");
1197
4.51k
    SStream_concat1(O, SrcRegKind);
1198
4.51k
  }
1199
1200
8.85k
  if (DoShift || IsLSL) {
1201
7.14k
    SStream_concat0(O, " ");
1202
7.14k
    if (getUseMarkup)
1203
0
      SStream_concat0(O, "<imm:");
1204
7.14k
    unsigned ShiftAmount = DoShift ? Log2_32(Width / 8) : 0;
1205
7.14k
    SStream_concat(O, "%s%u", "#", ShiftAmount);
1206
7.14k
    if (getUseMarkup)
1207
0
      SStream_concat0(O, ">");
1208
7.14k
  }
1209
8.85k
}
1210
1211
void printMemExtend(MCInst *MI, unsigned OpNum, SStream *O, char SrcRegKind,
1212
        unsigned Width)
1213
1.12k
{
1214
1.12k
  bool SignExtend = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1215
1.12k
  bool DoShift = MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1)));
1216
1.12k
  printMemExtendImpl(SignExtend, DoShift, Width, SrcRegKind, O,
1217
1.12k
         getUseMarkup());
1218
1.12k
}
1219
1220
#define DEFINE_printRegWithShiftExtend(SignExtend, ExtWidth, SrcRegKind, \
1221
               Suffix) \
1222
  void CONCAT(printRegWithShiftExtend, \
1223
        CONCAT(SignExtend, \
1224
         CONCAT(ExtWidth, CONCAT(SrcRegKind, Suffix))))( \
1225
    MCInst * MI, unsigned OpNum, SStream *O) \
1226
10.1k
  { \
1227
10.1k
    AArch64_add_cs_detail_4( \
1228
10.1k
      MI, \
1229
10.1k
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1230
10.1k
                SignExtend), \
1231
10.1k
               ExtWidth), \
1232
10.1k
              SrcRegKind), \
1233
10.1k
             Suffix), \
1234
10.1k
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), \
1235
10.1k
      CHAR(Suffix)); \
1236
10.1k
    printOperand(MI, OpNum, O); \
1237
10.1k
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1238
5.46k
      SStream_concat1(O, '.'); \
1239
5.46k
      SStream_concat1(O, CHAR(Suffix)); \
1240
5.46k
      SStream_concat1(O, '\0'); \
1241
5.46k
    } else \
1242
10.1k
      CS_ASSERT_RET((CHAR(Suffix) == '0') && \
1243
10.1k
              "Unsupported suffix size"); \
1244
10.1k
    bool DoShift = ExtWidth != 8; \
1245
10.1k
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1246
7.73k
      SStream_concat0(O, ", "); \
1247
7.73k
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, \
1248
7.73k
             CHAR(SrcRegKind), O, \
1249
7.73k
             getUseMarkup()); \
1250
7.73k
    } \
1251
10.1k
  }
1252
443
DEFINE_printRegWithShiftExtend(false, 8, x, d);
1253
279
DEFINE_printRegWithShiftExtend(true, 8, w, d);
1254
843
DEFINE_printRegWithShiftExtend(false, 8, w, d);
1255
1.82k
DEFINE_printRegWithShiftExtend(false, 8, x, 0);
1256
169
DEFINE_printRegWithShiftExtend(true, 8, w, s);
1257
181
DEFINE_printRegWithShiftExtend(false, 8, w, s);
1258
412
DEFINE_printRegWithShiftExtend(false, 64, x, d);
1259
156
DEFINE_printRegWithShiftExtend(true, 64, w, d);
1260
257
DEFINE_printRegWithShiftExtend(false, 64, w, d);
1261
406
DEFINE_printRegWithShiftExtend(false, 64, x, 0);
1262
78
DEFINE_printRegWithShiftExtend(true, 64, w, s);
1263
7
DEFINE_printRegWithShiftExtend(false, 64, w, s);
1264
178
DEFINE_printRegWithShiftExtend(false, 16, x, d);
1265
551
DEFINE_printRegWithShiftExtend(true, 16, w, d);
1266
188
DEFINE_printRegWithShiftExtend(false, 16, w, d);
1267
1.19k
DEFINE_printRegWithShiftExtend(false, 16, x, 0);
1268
47
DEFINE_printRegWithShiftExtend(true, 16, w, s);
1269
304
DEFINE_printRegWithShiftExtend(false, 16, w, s);
1270
195
DEFINE_printRegWithShiftExtend(false, 32, x, d);
1271
175
DEFINE_printRegWithShiftExtend(true, 32, w, d);
1272
329
DEFINE_printRegWithShiftExtend(false, 32, w, d);
1273
855
DEFINE_printRegWithShiftExtend(false, 32, x, 0);
1274
216
DEFINE_printRegWithShiftExtend(true, 32, w, s);
1275
110
DEFINE_printRegWithShiftExtend(false, 32, w, s);
1276
105
DEFINE_printRegWithShiftExtend(false, 8, x, s);
1277
7
DEFINE_printRegWithShiftExtend(false, 16, x, s);
1278
31
DEFINE_printRegWithShiftExtend(false, 32, x, s);
1279
208
DEFINE_printRegWithShiftExtend(false, 64, x, s);
1280
357
DEFINE_printRegWithShiftExtend(false, 128, x, 0);
1281
1282
#define DEFINE_printPredicateAsCounter(EltSize) \
1283
  void CONCAT(printPredicateAsCounter, \
1284
        EltSize)(MCInst * MI, unsigned OpNum, SStream *O) \
1285
4.63k
  { \
1286
4.63k
    AArch64_add_cs_detail_1( \
1287
4.63k
      MI, \
1288
4.63k
      CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1289
4.63k
      OpNum, EltSize); \
1290
4.63k
    unsigned Reg = \
1291
4.63k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1292
4.63k
    if (Reg < AArch64_PN0 || Reg > AArch64_PN15) \
1293
4.63k
      CS_ASSERT_RET( \
1294
4.63k
        0 && \
1295
4.63k
        "Unsupported predicate-as-counter register"); \
1296
4.63k
    SStream_concat(O, "%s", "pn"); \
1297
4.63k
    printUInt32(O, (Reg - AArch64_PN0)); \
1298
4.63k
    switch (EltSize) { \
1299
3.95k
    case 0: \
1300
3.95k
      break; \
1301
257
    case 8: \
1302
257
      SStream_concat0(O, ".b"); \
1303
257
      break; \
1304
17
    case 16: \
1305
17
      SStream_concat0(O, ".h"); \
1306
17
      break; \
1307
148
    case 32: \
1308
148
      SStream_concat0(O, ".s"); \
1309
148
      break; \
1310
254
    case 64: \
1311
254
      SStream_concat0(O, ".d"); \
1312
254
      break; \
1313
0
    default: \
1314
0
      CS_ASSERT_RET(0 && "Unsupported element size"); \
1315
4.63k
    } \
1316
4.63k
  }
printPredicateAsCounter_8
Line
Count
Source
1285
257
  { \
1286
257
    AArch64_add_cs_detail_1( \
1287
257
      MI, \
1288
257
      CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1289
257
      OpNum, EltSize); \
1290
257
    unsigned Reg = \
1291
257
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1292
257
    if (Reg < AArch64_PN0 || Reg > AArch64_PN15) \
1293
257
      CS_ASSERT_RET( \
1294
257
        0 && \
1295
257
        "Unsupported predicate-as-counter register"); \
1296
257
    SStream_concat(O, "%s", "pn"); \
1297
257
    printUInt32(O, (Reg - AArch64_PN0)); \
1298
257
    switch (EltSize) { \
1299
0
    case 0: \
1300
0
      break; \
1301
257
    case 8: \
1302
257
      SStream_concat0(O, ".b"); \
1303
257
      break; \
1304
0
    case 16: \
1305
0
      SStream_concat0(O, ".h"); \
1306
0
      break; \
1307
0
    case 32: \
1308
0
      SStream_concat0(O, ".s"); \
1309
0
      break; \
1310
0
    case 64: \
1311
0
      SStream_concat0(O, ".d"); \
1312
0
      break; \
1313
0
    default: \
1314
0
      CS_ASSERT_RET(0 && "Unsupported element size"); \
1315
257
    } \
1316
257
  }
printPredicateAsCounter_64
Line
Count
Source
1285
254
  { \
1286
254
    AArch64_add_cs_detail_1( \
1287
254
      MI, \
1288
254
      CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1289
254
      OpNum, EltSize); \
1290
254
    unsigned Reg = \
1291
254
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1292
254
    if (Reg < AArch64_PN0 || Reg > AArch64_PN15) \
1293
254
      CS_ASSERT_RET( \
1294
254
        0 && \
1295
254
        "Unsupported predicate-as-counter register"); \
1296
254
    SStream_concat(O, "%s", "pn"); \
1297
254
    printUInt32(O, (Reg - AArch64_PN0)); \
1298
254
    switch (EltSize) { \
1299
0
    case 0: \
1300
0
      break; \
1301
0
    case 8: \
1302
0
      SStream_concat0(O, ".b"); \
1303
0
      break; \
1304
0
    case 16: \
1305
0
      SStream_concat0(O, ".h"); \
1306
0
      break; \
1307
0
    case 32: \
1308
0
      SStream_concat0(O, ".s"); \
1309
0
      break; \
1310
254
    case 64: \
1311
254
      SStream_concat0(O, ".d"); \
1312
254
      break; \
1313
0
    default: \
1314
0
      CS_ASSERT_RET(0 && "Unsupported element size"); \
1315
254
    } \
1316
254
  }
printPredicateAsCounter_16
Line
Count
Source
1285
17
  { \
1286
17
    AArch64_add_cs_detail_1( \
1287
17
      MI, \
1288
17
      CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1289
17
      OpNum, EltSize); \
1290
17
    unsigned Reg = \
1291
17
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1292
17
    if (Reg < AArch64_PN0 || Reg > AArch64_PN15) \
1293
17
      CS_ASSERT_RET( \
1294
17
        0 && \
1295
17
        "Unsupported predicate-as-counter register"); \
1296
17
    SStream_concat(O, "%s", "pn"); \
1297
17
    printUInt32(O, (Reg - AArch64_PN0)); \
1298
17
    switch (EltSize) { \
1299
0
    case 0: \
1300
0
      break; \
1301
0
    case 8: \
1302
0
      SStream_concat0(O, ".b"); \
1303
0
      break; \
1304
17
    case 16: \
1305
17
      SStream_concat0(O, ".h"); \
1306
17
      break; \
1307
0
    case 32: \
1308
0
      SStream_concat0(O, ".s"); \
1309
0
      break; \
1310
0
    case 64: \
1311
0
      SStream_concat0(O, ".d"); \
1312
0
      break; \
1313
0
    default: \
1314
0
      CS_ASSERT_RET(0 && "Unsupported element size"); \
1315
17
    } \
1316
17
  }
printPredicateAsCounter_32
Line
Count
Source
1285
148
  { \
1286
148
    AArch64_add_cs_detail_1( \
1287
148
      MI, \
1288
148
      CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1289
148
      OpNum, EltSize); \
1290
148
    unsigned Reg = \
1291
148
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1292
148
    if (Reg < AArch64_PN0 || Reg > AArch64_PN15) \
1293
148
      CS_ASSERT_RET( \
1294
148
        0 && \
1295
148
        "Unsupported predicate-as-counter register"); \
1296
148
    SStream_concat(O, "%s", "pn"); \
1297
148
    printUInt32(O, (Reg - AArch64_PN0)); \
1298
148
    switch (EltSize) { \
1299
0
    case 0: \
1300
0
      break; \
1301
0
    case 8: \
1302
0
      SStream_concat0(O, ".b"); \
1303
0
      break; \
1304
0
    case 16: \
1305
0
      SStream_concat0(O, ".h"); \
1306
0
      break; \
1307
148
    case 32: \
1308
148
      SStream_concat0(O, ".s"); \
1309
148
      break; \
1310
0
    case 64: \
1311
0
      SStream_concat0(O, ".d"); \
1312
0
      break; \
1313
0
    default: \
1314
0
      CS_ASSERT_RET(0 && "Unsupported element size"); \
1315
148
    } \
1316
148
  }
printPredicateAsCounter_0
Line
Count
Source
1285
3.95k
  { \
1286
3.95k
    AArch64_add_cs_detail_1( \
1287
3.95k
      MI, \
1288
3.95k
      CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1289
3.95k
      OpNum, EltSize); \
1290
3.95k
    unsigned Reg = \
1291
3.95k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1292
3.95k
    if (Reg < AArch64_PN0 || Reg > AArch64_PN15) \
1293
3.95k
      CS_ASSERT_RET( \
1294
3.95k
        0 && \
1295
3.95k
        "Unsupported predicate-as-counter register"); \
1296
3.95k
    SStream_concat(O, "%s", "pn"); \
1297
3.95k
    printUInt32(O, (Reg - AArch64_PN0)); \
1298
3.95k
    switch (EltSize) { \
1299
3.95k
    case 0: \
1300
3.95k
      break; \
1301
0
    case 8: \
1302
0
      SStream_concat0(O, ".b"); \
1303
0
      break; \
1304
0
    case 16: \
1305
0
      SStream_concat0(O, ".h"); \
1306
0
      break; \
1307
0
    case 32: \
1308
0
      SStream_concat0(O, ".s"); \
1309
0
      break; \
1310
0
    case 64: \
1311
0
      SStream_concat0(O, ".d"); \
1312
0
      break; \
1313
0
    default: \
1314
0
      CS_ASSERT_RET(0 && "Unsupported element size"); \
1315
3.95k
    } \
1316
3.95k
  }
1317
DEFINE_printPredicateAsCounter(8);
1318
DEFINE_printPredicateAsCounter(64);
1319
DEFINE_printPredicateAsCounter(16);
1320
DEFINE_printPredicateAsCounter(32);
1321
DEFINE_printPredicateAsCounter(0);
1322
1323
void printCondCode(MCInst *MI, unsigned OpNum, SStream *O)
1324
1.34k
{
1325
1.34k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_CondCode, OpNum);
1326
1.34k
  AArch64CC_CondCode CC = (AArch64CC_CondCode)MCOperand_getImm(
1327
1.34k
    MCInst_getOperand(MI, (OpNum)));
1328
1.34k
  SStream_concat0(O, AArch64CC_getCondCodeName(CC));
1329
1.34k
}
1330
1331
void printInverseCondCode(MCInst *MI, unsigned OpNum, SStream *O)
1332
145
{
1333
145
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_InverseCondCode, OpNum);
1334
145
  AArch64CC_CondCode CC = (AArch64CC_CondCode)MCOperand_getImm(
1335
145
    MCInst_getOperand(MI, (OpNum)));
1336
145
  SStream_concat0(O, AArch64CC_getCondCodeName(
1337
145
           AArch64CC_getInvertedCondCode(CC)));
1338
145
}
1339
1340
void printAMNoIndex(MCInst *MI, unsigned OpNum, SStream *O)
1341
0
{
1342
0
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_AMNoIndex, OpNum);
1343
0
  SStream_concat0(O, "[");
1344
1345
0
  printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))));
1346
0
  SStream_concat0(O, "]");
1347
0
}
1348
1349
#define DEFINE_printImmScale(Scale) \
1350
  void CONCAT(printImmScale, Scale)(MCInst * MI, unsigned OpNum, \
1351
            SStream *O) \
1352
9.63k
  { \
1353
9.63k
    AArch64_add_cs_detail_1( \
1354
9.63k
      MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1355
9.63k
      Scale); \
1356
9.63k
    SStream_concat(O, "%s", markup("<imm:")); \
1357
9.63k
    printInt32Bang(O, Scale *MCOperand_getImm( \
1358
9.63k
            MCInst_getOperand(MI, (OpNum)))); \
1359
9.63k
    SStream_concat0(O, markup(">")); \
1360
9.63k
  }
printImmScale_8
Line
Count
Source
1352
2.06k
  { \
1353
2.06k
    AArch64_add_cs_detail_1( \
1354
2.06k
      MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1355
2.06k
      Scale); \
1356
2.06k
    SStream_concat(O, "%s", markup("<imm:")); \
1357
2.06k
    printInt32Bang(O, Scale *MCOperand_getImm( \
1358
2.06k
            MCInst_getOperand(MI, (OpNum)))); \
1359
2.06k
    SStream_concat0(O, markup(">")); \
1360
2.06k
  }
printImmScale_2
Line
Count
Source
1352
367
  { \
1353
367
    AArch64_add_cs_detail_1( \
1354
367
      MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1355
367
      Scale); \
1356
367
    SStream_concat(O, "%s", markup("<imm:")); \
1357
367
    printInt32Bang(O, Scale *MCOperand_getImm( \
1358
367
            MCInst_getOperand(MI, (OpNum)))); \
1359
367
    SStream_concat0(O, markup(">")); \
1360
367
  }
printImmScale_4
Line
Count
Source
1352
5.14k
  { \
1353
5.14k
    AArch64_add_cs_detail_1( \
1354
5.14k
      MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1355
5.14k
      Scale); \
1356
5.14k
    SStream_concat(O, "%s", markup("<imm:")); \
1357
5.14k
    printInt32Bang(O, Scale *MCOperand_getImm( \
1358
5.14k
            MCInst_getOperand(MI, (OpNum)))); \
1359
5.14k
    SStream_concat0(O, markup(">")); \
1360
5.14k
  }
printImmScale_16
Line
Count
Source
1352
1.92k
  { \
1353
1.92k
    AArch64_add_cs_detail_1( \
1354
1.92k
      MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1355
1.92k
      Scale); \
1356
1.92k
    SStream_concat(O, "%s", markup("<imm:")); \
1357
1.92k
    printInt32Bang(O, Scale *MCOperand_getImm( \
1358
1.92k
            MCInst_getOperand(MI, (OpNum)))); \
1359
1.92k
    SStream_concat0(O, markup(">")); \
1360
1.92k
  }
printImmScale_32
Line
Count
Source
1352
35
  { \
1353
35
    AArch64_add_cs_detail_1( \
1354
35
      MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1355
35
      Scale); \
1356
35
    SStream_concat(O, "%s", markup("<imm:")); \
1357
35
    printInt32Bang(O, Scale *MCOperand_getImm( \
1358
35
            MCInst_getOperand(MI, (OpNum)))); \
1359
35
    SStream_concat0(O, markup(">")); \
1360
35
  }
printImmScale_3
Line
Count
Source
1352
104
  { \
1353
104
    AArch64_add_cs_detail_1( \
1354
104
      MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1355
104
      Scale); \
1356
104
    SStream_concat(O, "%s", markup("<imm:")); \
1357
104
    printInt32Bang(O, Scale *MCOperand_getImm( \
1358
104
            MCInst_getOperand(MI, (OpNum)))); \
1359
104
    SStream_concat0(O, markup(">")); \
1360
104
  }
1361
DEFINE_printImmScale(8);
1362
DEFINE_printImmScale(2);
1363
DEFINE_printImmScale(4);
1364
DEFINE_printImmScale(16);
1365
DEFINE_printImmScale(32);
1366
DEFINE_printImmScale(3);
1367
1368
#define DEFINE_printImmRangeScale(Scale, Offset) \
1369
  void CONCAT(printImmRangeScale, CONCAT(Scale, Offset))( \
1370
    MCInst * MI, unsigned OpNum, SStream *O) \
1371
2.82k
  { \
1372
2.82k
    AArch64_add_cs_detail_2( \
1373
2.82k
      MI, \
1374
2.82k
      CONCAT(CONCAT(AArch64_OP_GROUP_ImmRangeScale, Scale), \
1375
2.82k
             Offset), \
1376
2.82k
      OpNum, Scale, Offset); \
1377
2.82k
    unsigned FirstImm = \
1378
2.82k
      Scale * \
1379
2.82k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1380
2.82k
    printUInt32(O, (FirstImm)); \
1381
2.82k
    SStream_concat(O, "%s", ":"); \
1382
2.82k
    printUInt32(O, (FirstImm + Offset)); \
1383
2.82k
    SStream_concat1(O, '\0'); \
1384
2.82k
  }
printImmRangeScale_2_1
Line
Count
Source
1371
1.23k
  { \
1372
1.23k
    AArch64_add_cs_detail_2( \
1373
1.23k
      MI, \
1374
1.23k
      CONCAT(CONCAT(AArch64_OP_GROUP_ImmRangeScale, Scale), \
1375
1.23k
             Offset), \
1376
1.23k
      OpNum, Scale, Offset); \
1377
1.23k
    unsigned FirstImm = \
1378
1.23k
      Scale * \
1379
1.23k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1380
1.23k
    printUInt32(O, (FirstImm)); \
1381
1.23k
    SStream_concat(O, "%s", ":"); \
1382
1.23k
    printUInt32(O, (FirstImm + Offset)); \
1383
1.23k
    SStream_concat1(O, '\0'); \
1384
1.23k
  }
printImmRangeScale_4_3
Line
Count
Source
1371
1.59k
  { \
1372
1.59k
    AArch64_add_cs_detail_2( \
1373
1.59k
      MI, \
1374
1.59k
      CONCAT(CONCAT(AArch64_OP_GROUP_ImmRangeScale, Scale), \
1375
1.59k
             Offset), \
1376
1.59k
      OpNum, Scale, Offset); \
1377
1.59k
    unsigned FirstImm = \
1378
1.59k
      Scale * \
1379
1.59k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1380
1.59k
    printUInt32(O, (FirstImm)); \
1381
1.59k
    SStream_concat(O, "%s", ":"); \
1382
1.59k
    printUInt32(O, (FirstImm + Offset)); \
1383
1.59k
    SStream_concat1(O, '\0'); \
1384
1.59k
  }
1385
DEFINE_printImmRangeScale(2, 1);
1386
DEFINE_printImmRangeScale(4, 3);
1387
1388
void printUImm12Offset(MCInst *MI, unsigned OpNum, unsigned Scale, SStream *O)
1389
3.78k
{
1390
3.78k
  MCOperand *MO = MCInst_getOperand(MI, (OpNum));
1391
3.78k
  if (MCOperand_isImm(MO)) {
1392
3.78k
    SStream_concat(O, "%s", markup("<imm:"));
1393
3.78k
    printUInt32Bang(O, (MCOperand_getImm(MO) * Scale));
1394
3.78k
    SStream_concat0(O, markup(">"));
1395
3.78k
  } else {
1396
0
    printUInt64Bang(O, MCOperand_getImm(MO));
1397
0
  }
1398
3.78k
}
1399
1400
void printAMIndexedWB(MCInst *MI, unsigned OpNum, unsigned Scale, SStream *O)
1401
0
{
1402
0
  MCOperand *MO1 = MCInst_getOperand(MI, (OpNum + 1));
1403
0
  SStream_concat0(O, "[");
1404
1405
0
  printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))));
1406
0
  if (MCOperand_isImm(MO1)) {
1407
0
    SStream_concat(O, "%s%s", ", ", markup("<imm:"));
1408
0
    printUInt32Bang(O, MCOperand_getImm(MO1) * Scale);
1409
0
    SStream_concat0(O, markup(">"));
1410
0
  } else {
1411
0
    printUInt64Bang(O, MCOperand_getImm(MO1));
1412
0
  }
1413
0
  SStream_concat0(O, "]");
1414
0
}
1415
1416
void printRPRFMOperand(MCInst *MI, unsigned OpNum, SStream *O)
1417
226
{
1418
226
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_RPRFMOperand, OpNum);
1419
226
  unsigned prfop = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1420
226
  const AArch64PRFM_PRFM *PRFM =
1421
226
    AArch64RPRFM_lookupRPRFMByEncoding(prfop);
1422
226
  if (PRFM) {
1423
169
    SStream_concat0(O, PRFM->Name);
1424
169
    return;
1425
169
  }
1426
1427
57
  printUInt32Bang(O, (prfop));
1428
57
  SStream_concat1(O, '\0');
1429
57
}
1430
1431
#define DEFINE_printPrefetchOp(IsSVEPrefetch) \
1432
  void CONCAT(printPrefetchOp, \
1433
        IsSVEPrefetch)(MCInst * MI, unsigned OpNum, SStream *O) \
1434
3.20k
  { \
1435
3.20k
    AArch64_add_cs_detail_1(MI, \
1436
3.20k
          CONCAT(AArch64_OP_GROUP_PrefetchOp, \
1437
3.20k
                 IsSVEPrefetch), \
1438
3.20k
          OpNum, IsSVEPrefetch); \
1439
3.20k
    unsigned prfop = \
1440
3.20k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1441
3.20k
    if (IsSVEPrefetch) { \
1442
2.20k
      const AArch64SVEPRFM_SVEPRFM *PRFM = \
1443
2.20k
        AArch64SVEPRFM_lookupSVEPRFMByEncoding(prfop); \
1444
2.20k
      if (PRFM) { \
1445
1.58k
        SStream_concat0(O, PRFM->Name); \
1446
1.58k
        return; \
1447
1.58k
      } \
1448
2.20k
    } else { \
1449
1.00k
      const AArch64PRFM_PRFM *PRFM = \
1450
1.00k
        AArch64PRFM_lookupPRFMByEncoding(prfop); \
1451
1.00k
      if (PRFM && \
1452
1.00k
          AArch64_testFeatureList(MI->csh->mode, \
1453
500
                PRFM->FeaturesRequired)) { \
1454
500
        SStream_concat0(O, PRFM->Name); \
1455
500
        return; \
1456
500
      } \
1457
1.00k
    } \
1458
3.20k
\
1459
3.20k
    SStream_concat(O, "%s", markup("<imm:")); \
1460
1.12k
    printUInt32Bang(O, (prfop)); \
1461
1.12k
    SStream_concat0(O, markup(">")); \
1462
1.12k
  }
printPrefetchOp_0
Line
Count
Source
1434
1.00k
  { \
1435
1.00k
    AArch64_add_cs_detail_1(MI, \
1436
1.00k
          CONCAT(AArch64_OP_GROUP_PrefetchOp, \
1437
1.00k
                 IsSVEPrefetch), \
1438
1.00k
          OpNum, IsSVEPrefetch); \
1439
1.00k
    unsigned prfop = \
1440
1.00k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1441
1.00k
    if (IsSVEPrefetch) { \
1442
0
      const AArch64SVEPRFM_SVEPRFM *PRFM = \
1443
0
        AArch64SVEPRFM_lookupSVEPRFMByEncoding(prfop); \
1444
0
      if (PRFM) { \
1445
0
        SStream_concat0(O, PRFM->Name); \
1446
0
        return; \
1447
0
      } \
1448
1.00k
    } else { \
1449
1.00k
      const AArch64PRFM_PRFM *PRFM = \
1450
1.00k
        AArch64PRFM_lookupPRFMByEncoding(prfop); \
1451
1.00k
      if (PRFM && \
1452
1.00k
          AArch64_testFeatureList(MI->csh->mode, \
1453
500
                PRFM->FeaturesRequired)) { \
1454
500
        SStream_concat0(O, PRFM->Name); \
1455
500
        return; \
1456
500
      } \
1457
1.00k
    } \
1458
1.00k
\
1459
1.00k
    SStream_concat(O, "%s", markup("<imm:")); \
1460
501
    printUInt32Bang(O, (prfop)); \
1461
501
    SStream_concat0(O, markup(">")); \
1462
501
  }
printPrefetchOp_1
Line
Count
Source
1434
2.20k
  { \
1435
2.20k
    AArch64_add_cs_detail_1(MI, \
1436
2.20k
          CONCAT(AArch64_OP_GROUP_PrefetchOp, \
1437
2.20k
                 IsSVEPrefetch), \
1438
2.20k
          OpNum, IsSVEPrefetch); \
1439
2.20k
    unsigned prfop = \
1440
2.20k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1441
2.20k
    if (IsSVEPrefetch) { \
1442
2.20k
      const AArch64SVEPRFM_SVEPRFM *PRFM = \
1443
2.20k
        AArch64SVEPRFM_lookupSVEPRFMByEncoding(prfop); \
1444
2.20k
      if (PRFM) { \
1445
1.58k
        SStream_concat0(O, PRFM->Name); \
1446
1.58k
        return; \
1447
1.58k
      } \
1448
2.20k
    } else { \
1449
0
      const AArch64PRFM_PRFM *PRFM = \
1450
0
        AArch64PRFM_lookupPRFMByEncoding(prfop); \
1451
0
      if (PRFM && \
1452
0
          AArch64_testFeatureList(MI->csh->mode, \
1453
0
                PRFM->FeaturesRequired)) { \
1454
0
        SStream_concat0(O, PRFM->Name); \
1455
0
        return; \
1456
0
      } \
1457
0
    } \
1458
2.20k
\
1459
2.20k
    SStream_concat(O, "%s", markup("<imm:")); \
1460
628
    printUInt32Bang(O, (prfop)); \
1461
628
    SStream_concat0(O, markup(">")); \
1462
628
  }
1463
DEFINE_printPrefetchOp(false);
1464
DEFINE_printPrefetchOp(true);
1465
1466
void printPSBHintOp(MCInst *MI, unsigned OpNum, SStream *O)
1467
176
{
1468
176
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_PSBHintOp, OpNum);
1469
176
  unsigned psbhintop = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1470
176
  const AArch64PSBHint_PSB *PSB =
1471
176
    AArch64PSBHint_lookupPSBByEncoding(psbhintop);
1472
176
  if (PSB)
1473
176
    SStream_concat0(O, PSB->Name);
1474
0
  else {
1475
0
    SStream_concat(O, "%s", markup("<imm:"));
1476
0
    SStream_concat1(O, '#');
1477
0
    printUInt32Bang(O, (psbhintop));
1478
0
    SStream_concat0(O, markup(">"));
1479
0
  }
1480
176
}
1481
1482
void printBTIHintOp(MCInst *MI, unsigned OpNum, SStream *O)
1483
214
{
1484
214
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_BTIHintOp, OpNum);
1485
214
  unsigned btihintop = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))) ^
1486
214
           32;
1487
214
  const AArch64BTIHint_BTI *BTI =
1488
214
    AArch64BTIHint_lookupBTIByEncoding(btihintop);
1489
214
  if (BTI)
1490
214
    SStream_concat0(O, BTI->Name);
1491
0
  else {
1492
0
    SStream_concat(O, "%s", markup("<imm:"));
1493
0
    printUInt32Bang(O, (btihintop));
1494
0
    SStream_concat0(O, markup(">"));
1495
0
  }
1496
214
}
1497
1498
static void printFPImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
1499
229
{
1500
229
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_FPImmOperand, OpNum);
1501
229
  MCOperand *MO = MCInst_getOperand(MI, (OpNum));
1502
229
  float FPImm = MCOperand_isDFPImm(MO) ?
1503
0
            BitsToDouble(MCOperand_getImm(MO)) :
1504
229
            AArch64_AM_getFPImmFloat(MCOperand_getImm(MO));
1505
1506
  // 8 decimal places are enough to perfectly represent permitted floats.
1507
229
  SStream_concat(O, "%s", markup("<imm:"));
1508
229
  SStream_concat(O, "#%.8f", FPImm);
1509
229
  SStream_concat0(O, markup(">"));
1510
229
}
1511
1512
static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride /* = 1 */)
1513
73.4k
{
1514
196k
  while (Stride--) {
1515
122k
    switch (Reg) {
1516
0
    default:
1517
0
      CS_ASSERT_RET_VAL(0 && "Vector register expected!", 0);
1518
4.31k
    case AArch64_Q0:
1519
4.31k
      Reg = AArch64_Q1;
1520
4.31k
      break;
1521
3.70k
    case AArch64_Q1:
1522
3.70k
      Reg = AArch64_Q2;
1523
3.70k
      break;
1524
1.81k
    case AArch64_Q2:
1525
1.81k
      Reg = AArch64_Q3;
1526
1.81k
      break;
1527
1.14k
    case AArch64_Q3:
1528
1.14k
      Reg = AArch64_Q4;
1529
1.14k
      break;
1530
581
    case AArch64_Q4:
1531
581
      Reg = AArch64_Q5;
1532
581
      break;
1533
604
    case AArch64_Q5:
1534
604
      Reg = AArch64_Q6;
1535
604
      break;
1536
375
    case AArch64_Q6:
1537
375
      Reg = AArch64_Q7;
1538
375
      break;
1539
646
    case AArch64_Q7:
1540
646
      Reg = AArch64_Q8;
1541
646
      break;
1542
550
    case AArch64_Q8:
1543
550
      Reg = AArch64_Q9;
1544
550
      break;
1545
831
    case AArch64_Q9:
1546
831
      Reg = AArch64_Q10;
1547
831
      break;
1548
1.63k
    case AArch64_Q10:
1549
1.63k
      Reg = AArch64_Q11;
1550
1.63k
      break;
1551
1.89k
    case AArch64_Q11:
1552
1.89k
      Reg = AArch64_Q12;
1553
1.89k
      break;
1554
2.05k
    case AArch64_Q12:
1555
2.05k
      Reg = AArch64_Q13;
1556
2.05k
      break;
1557
1.50k
    case AArch64_Q13:
1558
1.50k
      Reg = AArch64_Q14;
1559
1.50k
      break;
1560
1.09k
    case AArch64_Q14:
1561
1.09k
      Reg = AArch64_Q15;
1562
1.09k
      break;
1563
809
    case AArch64_Q15:
1564
809
      Reg = AArch64_Q16;
1565
809
      break;
1566
826
    case AArch64_Q16:
1567
826
      Reg = AArch64_Q17;
1568
826
      break;
1569
808
    case AArch64_Q17:
1570
808
      Reg = AArch64_Q18;
1571
808
      break;
1572
1.34k
    case AArch64_Q18:
1573
1.34k
      Reg = AArch64_Q19;
1574
1.34k
      break;
1575
1.03k
    case AArch64_Q19:
1576
1.03k
      Reg = AArch64_Q20;
1577
1.03k
      break;
1578
1.99k
    case AArch64_Q20:
1579
1.99k
      Reg = AArch64_Q21;
1580
1.99k
      break;
1581
1.23k
    case AArch64_Q21:
1582
1.23k
      Reg = AArch64_Q22;
1583
1.23k
      break;
1584
1.22k
    case AArch64_Q22:
1585
1.22k
      Reg = AArch64_Q23;
1586
1.22k
      break;
1587
1.36k
    case AArch64_Q23:
1588
1.36k
      Reg = AArch64_Q24;
1589
1.36k
      break;
1590
2.01k
    case AArch64_Q24:
1591
2.01k
      Reg = AArch64_Q25;
1592
2.01k
      break;
1593
1.36k
    case AArch64_Q25:
1594
1.36k
      Reg = AArch64_Q26;
1595
1.36k
      break;
1596
1.04k
    case AArch64_Q26:
1597
1.04k
      Reg = AArch64_Q27;
1598
1.04k
      break;
1599
500
    case AArch64_Q27:
1600
500
      Reg = AArch64_Q28;
1601
500
      break;
1602
475
    case AArch64_Q28:
1603
475
      Reg = AArch64_Q29;
1604
475
      break;
1605
595
    case AArch64_Q29:
1606
595
      Reg = AArch64_Q30;
1607
595
      break;
1608
585
    case AArch64_Q30:
1609
585
      Reg = AArch64_Q31;
1610
585
      break;
1611
    // Vector lists can wrap around.
1612
1.88k
    case AArch64_Q31:
1613
1.88k
      Reg = AArch64_Q0;
1614
1.88k
      break;
1615
7.71k
    case AArch64_Z0:
1616
7.71k
      Reg = AArch64_Z1;
1617
7.71k
      break;
1618
5.78k
    case AArch64_Z1:
1619
5.78k
      Reg = AArch64_Z2;
1620
5.78k
      break;
1621
6.60k
    case AArch64_Z2:
1622
6.60k
      Reg = AArch64_Z3;
1623
6.60k
      break;
1624
1.81k
    case AArch64_Z3:
1625
1.81k
      Reg = AArch64_Z4;
1626
1.81k
      break;
1627
5.09k
    case AArch64_Z4:
1628
5.09k
      Reg = AArch64_Z5;
1629
5.09k
      break;
1630
3.50k
    case AArch64_Z5:
1631
3.50k
      Reg = AArch64_Z6;
1632
3.50k
      break;
1633
3.23k
    case AArch64_Z6:
1634
3.23k
      Reg = AArch64_Z7;
1635
3.23k
      break;
1636
1.58k
    case AArch64_Z7:
1637
1.58k
      Reg = AArch64_Z8;
1638
1.58k
      break;
1639
3.99k
    case AArch64_Z8:
1640
3.99k
      Reg = AArch64_Z9;
1641
3.99k
      break;
1642
3.56k
    case AArch64_Z9:
1643
3.56k
      Reg = AArch64_Z10;
1644
3.56k
      break;
1645
3.76k
    case AArch64_Z10:
1646
3.76k
      Reg = AArch64_Z11;
1647
3.76k
      break;
1648
1.52k
    case AArch64_Z11:
1649
1.52k
      Reg = AArch64_Z12;
1650
1.52k
      break;
1651
1.72k
    case AArch64_Z12:
1652
1.72k
      Reg = AArch64_Z13;
1653
1.72k
      break;
1654
1.72k
    case AArch64_Z13:
1655
1.72k
      Reg = AArch64_Z14;
1656
1.72k
      break;
1657
2.01k
    case AArch64_Z14:
1658
2.01k
      Reg = AArch64_Z15;
1659
2.01k
      break;
1660
1.63k
    case AArch64_Z15:
1661
1.63k
      Reg = AArch64_Z16;
1662
1.63k
      break;
1663
1.53k
    case AArch64_Z16:
1664
1.53k
      Reg = AArch64_Z17;
1665
1.53k
      break;
1666
809
    case AArch64_Z17:
1667
809
      Reg = AArch64_Z18;
1668
809
      break;
1669
663
    case AArch64_Z18:
1670
663
      Reg = AArch64_Z19;
1671
663
      break;
1672
1.01k
    case AArch64_Z19:
1673
1.01k
      Reg = AArch64_Z20;
1674
1.01k
      break;
1675
2.01k
    case AArch64_Z20:
1676
2.01k
      Reg = AArch64_Z21;
1677
2.01k
      break;
1678
1.68k
    case AArch64_Z21:
1679
1.68k
      Reg = AArch64_Z22;
1680
1.68k
      break;
1681
1.96k
    case AArch64_Z22:
1682
1.96k
      Reg = AArch64_Z23;
1683
1.96k
      break;
1684
1.16k
    case AArch64_Z23:
1685
1.16k
      Reg = AArch64_Z24;
1686
1.16k
      break;
1687
2.03k
    case AArch64_Z24:
1688
2.03k
      Reg = AArch64_Z25;
1689
2.03k
      break;
1690
1.63k
    case AArch64_Z25:
1691
1.63k
      Reg = AArch64_Z26;
1692
1.63k
      break;
1693
1.88k
    case AArch64_Z26:
1694
1.88k
      Reg = AArch64_Z27;
1695
1.88k
      break;
1696
1.29k
    case AArch64_Z27:
1697
1.29k
      Reg = AArch64_Z28;
1698
1.29k
      break;
1699
1.78k
    case AArch64_Z28:
1700
1.78k
      Reg = AArch64_Z29;
1701
1.78k
      break;
1702
1.41k
    case AArch64_Z29:
1703
1.41k
      Reg = AArch64_Z30;
1704
1.41k
      break;
1705
1.93k
    case AArch64_Z30:
1706
1.93k
      Reg = AArch64_Z31;
1707
1.93k
      break;
1708
    // Vector lists can wrap around.
1709
1.50k
    case AArch64_Z31:
1710
1.50k
      Reg = AArch64_Z0;
1711
1.50k
      break;
1712
20
    case AArch64_P0:
1713
20
      Reg = AArch64_P1;
1714
20
      break;
1715
16
    case AArch64_P1:
1716
16
      Reg = AArch64_P2;
1717
16
      break;
1718
220
    case AArch64_P2:
1719
220
      Reg = AArch64_P3;
1720
220
      break;
1721
40
    case AArch64_P3:
1722
40
      Reg = AArch64_P4;
1723
40
      break;
1724
8
    case AArch64_P4:
1725
8
      Reg = AArch64_P5;
1726
8
      break;
1727
248
    case AArch64_P5:
1728
248
      Reg = AArch64_P6;
1729
248
      break;
1730
70
    case AArch64_P6:
1731
70
      Reg = AArch64_P7;
1732
70
      break;
1733
6
    case AArch64_P7:
1734
6
      Reg = AArch64_P8;
1735
6
      break;
1736
12
    case AArch64_P8:
1737
12
      Reg = AArch64_P9;
1738
12
      break;
1739
14
    case AArch64_P9:
1740
14
      Reg = AArch64_P10;
1741
14
      break;
1742
14
    case AArch64_P10:
1743
14
      Reg = AArch64_P11;
1744
14
      break;
1745
2
    case AArch64_P11:
1746
2
      Reg = AArch64_P12;
1747
2
      break;
1748
72
    case AArch64_P12:
1749
72
      Reg = AArch64_P13;
1750
72
      break;
1751
654
    case AArch64_P13:
1752
654
      Reg = AArch64_P14;
1753
654
      break;
1754
32
    case AArch64_P14:
1755
32
      Reg = AArch64_P15;
1756
32
      break;
1757
    // Vector lists can wrap around.
1758
20
    case AArch64_P15:
1759
20
      Reg = AArch64_P0;
1760
20
      break;
1761
122k
    }
1762
122k
  }
1763
73.4k
  return Reg;
1764
73.4k
}
1765
1766
#define DEFINE_printGPRSeqPairsClassOperand(size) \
1767
  void CONCAT(printGPRSeqPairsClassOperand, \
1768
        size)(MCInst * MI, unsigned OpNum, SStream *O) \
1769
1.27k
  { \
1770
1.27k
    AArch64_add_cs_detail_1( \
1771
1.27k
      MI, \
1772
1.27k
      CONCAT(AArch64_OP_GROUP_GPRSeqPairsClassOperand, \
1773
1.27k
             size), \
1774
1.27k
      OpNum, size); \
1775
1.27k
    CS_ASSERT_RET((size == 64 || size == 32) && \
1776
1.27k
            "Template parameter must be either 32 or 64"); \
1777
1.27k
    unsigned Reg = \
1778
1.27k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1779
1.27k
\
1780
1.27k
    unsigned Sube = (size == 32) ? AArch64_sube32 : \
1781
1.27k
                 AArch64_sube64; \
1782
1.27k
    unsigned Subo = (size == 32) ? AArch64_subo32 : \
1783
1.27k
                 AArch64_subo64; \
1784
1.27k
\
1785
1.27k
    unsigned Even = MCRegisterInfo_getSubReg(MI->MRI, Reg, Sube); \
1786
1.27k
    unsigned Odd = MCRegisterInfo_getSubReg(MI->MRI, Reg, Subo); \
1787
1.27k
    printRegName(O, Even); \
1788
1.27k
    SStream_concat0(O, ", "); \
1789
1.27k
    printRegName(O, Odd); \
1790
1.27k
  }
printGPRSeqPairsClassOperand_32
Line
Count
Source
1769
88
  { \
1770
88
    AArch64_add_cs_detail_1( \
1771
88
      MI, \
1772
88
      CONCAT(AArch64_OP_GROUP_GPRSeqPairsClassOperand, \
1773
88
             size), \
1774
88
      OpNum, size); \
1775
88
    CS_ASSERT_RET((size == 64 || size == 32) && \
1776
88
            "Template parameter must be either 32 or 64"); \
1777
88
    unsigned Reg = \
1778
88
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1779
88
\
1780
88
    unsigned Sube = (size == 32) ? AArch64_sube32 : \
1781
88
                 AArch64_sube64; \
1782
88
    unsigned Subo = (size == 32) ? AArch64_subo32 : \
1783
88
                 AArch64_subo64; \
1784
88
\
1785
88
    unsigned Even = MCRegisterInfo_getSubReg(MI->MRI, Reg, Sube); \
1786
88
    unsigned Odd = MCRegisterInfo_getSubReg(MI->MRI, Reg, Subo); \
1787
88
    printRegName(O, Even); \
1788
88
    SStream_concat0(O, ", "); \
1789
88
    printRegName(O, Odd); \
1790
88
  }
printGPRSeqPairsClassOperand_64
Line
Count
Source
1769
1.19k
  { \
1770
1.19k
    AArch64_add_cs_detail_1( \
1771
1.19k
      MI, \
1772
1.19k
      CONCAT(AArch64_OP_GROUP_GPRSeqPairsClassOperand, \
1773
1.19k
             size), \
1774
1.19k
      OpNum, size); \
1775
1.19k
    CS_ASSERT_RET((size == 64 || size == 32) && \
1776
1.19k
            "Template parameter must be either 32 or 64"); \
1777
1.19k
    unsigned Reg = \
1778
1.19k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1779
1.19k
\
1780
1.19k
    unsigned Sube = (size == 32) ? AArch64_sube32 : \
1781
1.19k
                 AArch64_sube64; \
1782
1.19k
    unsigned Subo = (size == 32) ? AArch64_subo32 : \
1783
1.19k
                 AArch64_subo64; \
1784
1.19k
\
1785
1.19k
    unsigned Even = MCRegisterInfo_getSubReg(MI->MRI, Reg, Sube); \
1786
1.19k
    unsigned Odd = MCRegisterInfo_getSubReg(MI->MRI, Reg, Subo); \
1787
1.19k
    printRegName(O, Even); \
1788
1.19k
    SStream_concat0(O, ", "); \
1789
1.19k
    printRegName(O, Odd); \
1790
1.19k
  }
1791
DEFINE_printGPRSeqPairsClassOperand(32);
1792
DEFINE_printGPRSeqPairsClassOperand(64);
1793
1794
#define DEFINE_printMatrixIndex(Scale) \
1795
  void CONCAT(printMatrixIndex, Scale)(MCInst * MI, unsigned OpNum, \
1796
               SStream *O) \
1797
4.87k
  { \
1798
4.87k
    AArch64_add_cs_detail_1( \
1799
4.87k
      MI, CONCAT(AArch64_OP_GROUP_MatrixIndex, Scale), \
1800
4.87k
      OpNum, Scale); \
1801
4.87k
    printInt64(O, Scale *MCOperand_getImm( \
1802
4.87k
              MCInst_getOperand(MI, (OpNum)))); \
1803
4.87k
  }
printMatrixIndex_8
Line
Count
Source
1797
137
  { \
1798
137
    AArch64_add_cs_detail_1( \
1799
137
      MI, CONCAT(AArch64_OP_GROUP_MatrixIndex, Scale), \
1800
137
      OpNum, Scale); \
1801
137
    printInt64(O, Scale *MCOperand_getImm( \
1802
137
              MCInst_getOperand(MI, (OpNum)))); \
1803
137
  }
Unexecuted instantiation: printMatrixIndex_0
printMatrixIndex_1
Line
Count
Source
1797
4.73k
  { \
1798
4.73k
    AArch64_add_cs_detail_1( \
1799
4.73k
      MI, CONCAT(AArch64_OP_GROUP_MatrixIndex, Scale), \
1800
4.73k
      OpNum, Scale); \
1801
4.73k
    printInt64(O, Scale *MCOperand_getImm( \
1802
4.73k
              MCInst_getOperand(MI, (OpNum)))); \
1803
4.73k
  }
1804
DEFINE_printMatrixIndex(8);
1805
DEFINE_printMatrixIndex(0);
1806
DEFINE_printMatrixIndex(1);
1807
1808
void printMatrixTileList(MCInst *MI, unsigned OpNum, SStream *O)
1809
362
{
1810
362
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_MatrixTileList, OpNum);
1811
362
  unsigned MaxRegs = 8;
1812
362
  unsigned RegMask = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1813
1814
362
  unsigned NumRegs = 0;
1815
3.25k
  for (unsigned I = 0; I < MaxRegs; ++I)
1816
2.89k
    if ((RegMask & (1 << I)) != 0)
1817
1.13k
      ++NumRegs;
1818
1819
362
  SStream_concat0(O, "{");
1820
362
  unsigned Printed = 0;
1821
3.25k
  for (unsigned I = 0; I < MaxRegs; ++I) {
1822
2.89k
    unsigned Reg = RegMask & (1 << I);
1823
2.89k
    if (Reg == 0)
1824
1.76k
      continue;
1825
1.13k
    printRegName(O, AArch64_ZAD0 + I);
1826
1.13k
    if (Printed + 1 != NumRegs)
1827
776
      SStream_concat0(O, ", ");
1828
1.13k
    ++Printed;
1829
1.13k
  }
1830
362
  SStream_concat0(O, "}");
1831
362
}
1832
1833
void printVectorList(MCInst *MI, unsigned OpNum, SStream *O,
1834
         const char *LayoutSuffix)
1835
33.8k
{
1836
33.8k
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum)));
1837
1838
33.8k
  SStream_concat0(O, "{ ");
1839
1840
  // Work out how many registers there are in the list (if there is an actual
1841
  // list).
1842
33.8k
  unsigned NumRegs = 1;
1843
33.8k
  if (MCRegisterClass_contains(
1844
33.8k
        MCRegisterInfo_getRegClass(MI->MRI, AArch64_DDRegClassID),
1845
33.8k
        Reg) ||
1846
32.6k
      MCRegisterClass_contains(
1847
32.6k
        MCRegisterInfo_getRegClass(MI->MRI, AArch64_ZPR2RegClassID),
1848
32.6k
        Reg) ||
1849
28.1k
      MCRegisterClass_contains(
1850
28.1k
        MCRegisterInfo_getRegClass(MI->MRI, AArch64_QQRegClassID),
1851
28.1k
        Reg) ||
1852
24.9k
      MCRegisterClass_contains(
1853
24.9k
        MCRegisterInfo_getRegClass(MI->MRI, AArch64_PPR2RegClassID),
1854
24.9k
        Reg) ||
1855
24.2k
      MCRegisterClass_contains(
1856
24.2k
        MCRegisterInfo_getRegClass(MI->MRI,
1857
24.2k
                 AArch64_ZPR2StridedRegClassID),
1858
24.2k
        Reg))
1859
11.1k
    NumRegs = 2;
1860
22.7k
  else if (MCRegisterClass_contains(
1861
22.7k
       MCRegisterInfo_getRegClass(MI->MRI,
1862
22.7k
                AArch64_DDDRegClassID),
1863
22.7k
       Reg) ||
1864
21.8k
     MCRegisterClass_contains(
1865
21.8k
       MCRegisterInfo_getRegClass(MI->MRI,
1866
21.8k
                AArch64_ZPR3RegClassID),
1867
21.8k
       Reg) ||
1868
21.6k
     MCRegisterClass_contains(
1869
21.6k
       MCRegisterInfo_getRegClass(MI->MRI,
1870
21.6k
                AArch64_QQQRegClassID),
1871
21.6k
       Reg))
1872
5.58k
    NumRegs = 3;
1873
17.1k
  else if (MCRegisterClass_contains(
1874
17.1k
       MCRegisterInfo_getRegClass(MI->MRI,
1875
17.1k
                AArch64_DDDDRegClassID),
1876
17.1k
       Reg) ||
1877
16.5k
     MCRegisterClass_contains(
1878
16.5k
       MCRegisterInfo_getRegClass(MI->MRI,
1879
16.5k
                AArch64_ZPR4RegClassID),
1880
16.5k
       Reg) ||
1881
12.6k
     MCRegisterClass_contains(
1882
12.6k
       MCRegisterInfo_getRegClass(MI->MRI,
1883
12.6k
                AArch64_QQQQRegClassID),
1884
12.6k
       Reg) ||
1885
10.0k
     MCRegisterClass_contains(
1886
10.0k
       MCRegisterInfo_getRegClass(
1887
10.0k
         MI->MRI, AArch64_ZPR4StridedRegClassID),
1888
10.0k
       Reg))
1889
8.29k
    NumRegs = 4;
1890
1891
33.8k
  unsigned Stride = 1;
1892
33.8k
  if (MCRegisterClass_contains(
1893
33.8k
        MCRegisterInfo_getRegClass(MI->MRI,
1894
33.8k
                 AArch64_ZPR2StridedRegClassID),
1895
33.8k
        Reg))
1896
1.43k
    Stride = 8;
1897
32.4k
  else if (MCRegisterClass_contains(
1898
32.4k
       MCRegisterInfo_getRegClass(
1899
32.4k
         MI->MRI, AArch64_ZPR4StridedRegClassID),
1900
32.4k
       Reg))
1901
1.13k
    Stride = 4;
1902
1903
  // Now forget about the list and find out what the first register is.
1904
33.8k
  if (MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_dsub0))
1905
2.85k
    Reg = MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_dsub0);
1906
31.0k
  else if (MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_qsub0))
1907
10.2k
    Reg = MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_qsub0);
1908
20.7k
  else if (MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_zsub0))
1909
11.1k
    Reg = MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_zsub0);
1910
9.62k
  else if (MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_psub0))
1911
719
    Reg = MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_psub0);
1912
1913
  // If it's a D-reg, we need to promote it to the equivalent Q-reg before
1914
  // printing (otherwise getRegisterName fails).
1915
33.8k
  if (MCRegisterClass_contains(MCRegisterInfo_getRegClass(
1916
33.8k
               MI->MRI, AArch64_FPR64RegClassID),
1917
33.8k
             Reg)) {
1918
3.07k
    const MCRegisterClass *FPR128RC = MCRegisterInfo_getRegClass(
1919
3.07k
      MI->MRI, AArch64_FPR128RegClassID);
1920
3.07k
    Reg = MCRegisterInfo_getMatchingSuperReg(
1921
3.07k
      MI->MRI, Reg, AArch64_dsub, FPR128RC);
1922
3.07k
  }
1923
1924
33.8k
  if ((MCRegisterClass_contains(
1925
33.8k
         MCRegisterInfo_getRegClass(MI->MRI, AArch64_ZPRRegClassID),
1926
33.8k
         Reg) ||
1927
17.5k
       MCRegisterClass_contains(
1928
17.5k
         MCRegisterInfo_getRegClass(MI->MRI, AArch64_PPRRegClassID),
1929
17.5k
         Reg)) &&
1930
17.0k
      NumRegs > 1 && Stride == 1 &&
1931
      // Do not print the range when the last register is lower than the
1932
      // first. Because it is a wrap-around register.
1933
9.28k
      Reg < getNextVectorRegister(Reg, NumRegs - 1)) {
1934
9.13k
    printRegName(O, Reg);
1935
9.13k
    SStream_concat0(O, LayoutSuffix);
1936
9.13k
    if (NumRegs > 1) {
1937
      // Set of two sve registers should be separated by ','
1938
9.13k
      const char *split_char = NumRegs == 2 ? ", " : " - ";
1939
9.13k
      SStream_concat0(O, split_char);
1940
9.13k
      printRegName(O,
1941
9.13k
             (getNextVectorRegister(Reg, NumRegs - 1)));
1942
9.13k
      SStream_concat0(O, LayoutSuffix);
1943
9.13k
    }
1944
24.7k
  } else {
1945
79.7k
    for (unsigned i = 0; i < NumRegs;
1946
54.9k
         ++i, Reg = getNextVectorRegister(Reg, Stride)) {
1947
      // wrap-around sve register
1948
54.9k
      if (MCRegisterClass_contains(
1949
54.9k
            MCRegisterInfo_getRegClass(
1950
54.9k
              MI->MRI, AArch64_ZPRRegClassID),
1951
54.9k
            Reg) ||
1952
41.8k
          MCRegisterClass_contains(
1953
41.8k
            MCRegisterInfo_getRegClass(
1954
41.8k
              MI->MRI, AArch64_PPRRegClassID),
1955
41.8k
            Reg))
1956
13.1k
        printRegName(O, Reg);
1957
41.8k
      else
1958
41.8k
        printRegNameAlt(O, Reg, AArch64_vreg);
1959
54.9k
      SStream_concat0(O, LayoutSuffix);
1960
54.9k
      if (i + 1 != NumRegs)
1961
30.2k
        SStream_concat0(O, ", ");
1962
54.9k
    }
1963
24.7k
  }
1964
33.8k
  SStream_concat0(O, " }");
1965
33.8k
}
1966
1967
void printImplicitlyTypedVectorList(MCInst *MI, unsigned OpNum, SStream *O)
1968
0
{
1969
0
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_ImplicitlyTypedVectorList,
1970
0
        OpNum);
1971
0
  printVectorList(MI, OpNum, O, "");
1972
0
}
1973
1974
#define DEFINE_printTypedVectorList(NumLanes, LaneKind) \
1975
  void CONCAT(printTypedVectorList, CONCAT(NumLanes, LaneKind))( \
1976
    MCInst * MI, unsigned OpNum, SStream *O) \
1977
33.8k
  { \
1978
33.8k
    AArch64_add_cs_detail_2( \
1979
33.8k
      MI, \
1980
33.8k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
33.8k
              NumLanes), \
1982
33.8k
             LaneKind), \
1983
33.8k
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
33.8k
    if (CHAR(LaneKind) == '0') { \
1985
81
      printVectorList(MI, OpNum, O, ""); \
1986
81
      return; \
1987
81
    } \
1988
33.8k
    char Suffix[32]; \
1989
33.8k
    if (NumLanes) \
1990
33.8k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
7.23k
            CHAR(LaneKind)); \
1992
33.8k
    else \
1993
33.8k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
26.5k
            CHAR(LaneKind)); \
1995
33.8k
\
1996
33.8k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
33.8k
  }
printTypedVectorList_0_b
Line
Count
Source
1977
7.81k
  { \
1978
7.81k
    AArch64_add_cs_detail_2( \
1979
7.81k
      MI, \
1980
7.81k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
7.81k
              NumLanes), \
1982
7.81k
             LaneKind), \
1983
7.81k
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
7.81k
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
7.81k
    char Suffix[32]; \
1989
7.81k
    if (NumLanes) \
1990
7.81k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
0
            CHAR(LaneKind)); \
1992
7.81k
    else \
1993
7.81k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
7.81k
            CHAR(LaneKind)); \
1995
7.81k
\
1996
7.81k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
7.81k
  }
printTypedVectorList_0_d
Line
Count
Source
1977
5.59k
  { \
1978
5.59k
    AArch64_add_cs_detail_2( \
1979
5.59k
      MI, \
1980
5.59k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
5.59k
              NumLanes), \
1982
5.59k
             LaneKind), \
1983
5.59k
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
5.59k
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
5.59k
    char Suffix[32]; \
1989
5.59k
    if (NumLanes) \
1990
5.59k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
0
            CHAR(LaneKind)); \
1992
5.59k
    else \
1993
5.59k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
5.59k
            CHAR(LaneKind)); \
1995
5.59k
\
1996
5.59k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
5.59k
  }
printTypedVectorList_0_h
Line
Count
Source
1977
6.77k
  { \
1978
6.77k
    AArch64_add_cs_detail_2( \
1979
6.77k
      MI, \
1980
6.77k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
6.77k
              NumLanes), \
1982
6.77k
             LaneKind), \
1983
6.77k
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
6.77k
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
6.77k
    char Suffix[32]; \
1989
6.77k
    if (NumLanes) \
1990
6.77k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
0
            CHAR(LaneKind)); \
1992
6.77k
    else \
1993
6.77k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
6.77k
            CHAR(LaneKind)); \
1995
6.77k
\
1996
6.77k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
6.77k
  }
printTypedVectorList_0_s
Line
Count
Source
1977
6.13k
  { \
1978
6.13k
    AArch64_add_cs_detail_2( \
1979
6.13k
      MI, \
1980
6.13k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
6.13k
              NumLanes), \
1982
6.13k
             LaneKind), \
1983
6.13k
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
6.13k
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
6.13k
    char Suffix[32]; \
1989
6.13k
    if (NumLanes) \
1990
6.13k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
0
            CHAR(LaneKind)); \
1992
6.13k
    else \
1993
6.13k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
6.13k
            CHAR(LaneKind)); \
1995
6.13k
\
1996
6.13k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
6.13k
  }
printTypedVectorList_0_q
Line
Count
Source
1977
260
  { \
1978
260
    AArch64_add_cs_detail_2( \
1979
260
      MI, \
1980
260
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
260
              NumLanes), \
1982
260
             LaneKind), \
1983
260
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
260
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
260
    char Suffix[32]; \
1989
260
    if (NumLanes) \
1990
260
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
0
            CHAR(LaneKind)); \
1992
260
    else \
1993
260
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
260
            CHAR(LaneKind)); \
1995
260
\
1996
260
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
260
  }
printTypedVectorList_16_b
Line
Count
Source
1977
1.10k
  { \
1978
1.10k
    AArch64_add_cs_detail_2( \
1979
1.10k
      MI, \
1980
1.10k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
1.10k
              NumLanes), \
1982
1.10k
             LaneKind), \
1983
1.10k
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
1.10k
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
1.10k
    char Suffix[32]; \
1989
1.10k
    if (NumLanes) \
1990
1.10k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
1.10k
            CHAR(LaneKind)); \
1992
1.10k
    else \
1993
1.10k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
1.10k
\
1996
1.10k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
1.10k
  }
printTypedVectorList_1_d
Line
Count
Source
1977
147
  { \
1978
147
    AArch64_add_cs_detail_2( \
1979
147
      MI, \
1980
147
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
147
              NumLanes), \
1982
147
             LaneKind), \
1983
147
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
147
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
147
    char Suffix[32]; \
1989
147
    if (NumLanes) \
1990
147
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
147
            CHAR(LaneKind)); \
1992
147
    else \
1993
147
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
147
\
1996
147
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
147
  }
printTypedVectorList_2_d
Line
Count
Source
1977
929
  { \
1978
929
    AArch64_add_cs_detail_2( \
1979
929
      MI, \
1980
929
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
929
              NumLanes), \
1982
929
             LaneKind), \
1983
929
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
929
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
929
    char Suffix[32]; \
1989
929
    if (NumLanes) \
1990
929
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
929
            CHAR(LaneKind)); \
1992
929
    else \
1993
929
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
929
\
1996
929
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
929
  }
printTypedVectorList_2_s
Line
Count
Source
1977
291
  { \
1978
291
    AArch64_add_cs_detail_2( \
1979
291
      MI, \
1980
291
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
291
              NumLanes), \
1982
291
             LaneKind), \
1983
291
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
291
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
291
    char Suffix[32]; \
1989
291
    if (NumLanes) \
1990
291
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
291
            CHAR(LaneKind)); \
1992
291
    else \
1993
291
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
291
\
1996
291
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
291
  }
printTypedVectorList_4_h
Line
Count
Source
1977
1.18k
  { \
1978
1.18k
    AArch64_add_cs_detail_2( \
1979
1.18k
      MI, \
1980
1.18k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
1.18k
              NumLanes), \
1982
1.18k
             LaneKind), \
1983
1.18k
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
1.18k
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
1.18k
    char Suffix[32]; \
1989
1.18k
    if (NumLanes) \
1990
1.18k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
1.18k
            CHAR(LaneKind)); \
1992
1.18k
    else \
1993
1.18k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
1.18k
\
1996
1.18k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
1.18k
  }
printTypedVectorList_4_s
Line
Count
Source
1977
622
  { \
1978
622
    AArch64_add_cs_detail_2( \
1979
622
      MI, \
1980
622
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
622
              NumLanes), \
1982
622
             LaneKind), \
1983
622
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
622
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
622
    char Suffix[32]; \
1989
622
    if (NumLanes) \
1990
622
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
622
            CHAR(LaneKind)); \
1992
622
    else \
1993
622
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
622
\
1996
622
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
622
  }
printTypedVectorList_8_b
Line
Count
Source
1977
1.45k
  { \
1978
1.45k
    AArch64_add_cs_detail_2( \
1979
1.45k
      MI, \
1980
1.45k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
1.45k
              NumLanes), \
1982
1.45k
             LaneKind), \
1983
1.45k
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
1.45k
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
1.45k
    char Suffix[32]; \
1989
1.45k
    if (NumLanes) \
1990
1.45k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
1.45k
            CHAR(LaneKind)); \
1992
1.45k
    else \
1993
1.45k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
1.45k
\
1996
1.45k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
1.45k
  }
printTypedVectorList_8_h
Line
Count
Source
1977
1.49k
  { \
1978
1.49k
    AArch64_add_cs_detail_2( \
1979
1.49k
      MI, \
1980
1.49k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
1.49k
              NumLanes), \
1982
1.49k
             LaneKind), \
1983
1.49k
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
1.49k
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
1.49k
    char Suffix[32]; \
1989
1.49k
    if (NumLanes) \
1990
1.49k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
1.49k
            CHAR(LaneKind)); \
1992
1.49k
    else \
1993
1.49k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
1.49k
\
1996
1.49k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
1.49k
  }
printTypedVectorList_0_0
Line
Count
Source
1977
81
  { \
1978
81
    AArch64_add_cs_detail_2( \
1979
81
      MI, \
1980
81
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
81
              NumLanes), \
1982
81
             LaneKind), \
1983
81
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
81
    if (CHAR(LaneKind) == '0') { \
1985
81
      printVectorList(MI, OpNum, O, ""); \
1986
81
      return; \
1987
81
    } \
1988
81
    char Suffix[32]; \
1989
0
    if (NumLanes) \
1990
0
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
0
            CHAR(LaneKind)); \
1992
0
    else \
1993
0
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
0
\
1996
0
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
0
  }
1998
DEFINE_printTypedVectorList(0, b);
1999
DEFINE_printTypedVectorList(0, d);
2000
DEFINE_printTypedVectorList(0, h);
2001
DEFINE_printTypedVectorList(0, s);
2002
DEFINE_printTypedVectorList(0, q);
2003
DEFINE_printTypedVectorList(16, b);
2004
DEFINE_printTypedVectorList(1, d);
2005
DEFINE_printTypedVectorList(2, d);
2006
DEFINE_printTypedVectorList(2, s);
2007
DEFINE_printTypedVectorList(4, h);
2008
DEFINE_printTypedVectorList(4, s);
2009
DEFINE_printTypedVectorList(8, b);
2010
DEFINE_printTypedVectorList(8, h);
2011
DEFINE_printTypedVectorList(0, 0);
2012
2013
#define DEFINE_printVectorIndex(Scale) \
2014
  void CONCAT(printVectorIndex, Scale)(MCInst * MI, unsigned OpNum, \
2015
               SStream *O) \
2016
19.7k
  { \
2017
19.7k
    AArch64_add_cs_detail_1( \
2018
19.7k
      MI, CONCAT(AArch64_OP_GROUP_VectorIndex, Scale), \
2019
19.7k
      OpNum, Scale); \
2020
19.7k
    SStream_concat(O, "%s", "["); \
2021
19.7k
    printUInt64(O, Scale *MCOperand_getImm( \
2022
19.7k
               MCInst_getOperand(MI, (OpNum)))); \
2023
19.7k
    SStream_concat0(O, "]"); \
2024
19.7k
  }
printVectorIndex_1
Line
Count
Source
2016
19.7k
  { \
2017
19.7k
    AArch64_add_cs_detail_1( \
2018
19.7k
      MI, CONCAT(AArch64_OP_GROUP_VectorIndex, Scale), \
2019
19.7k
      OpNum, Scale); \
2020
19.7k
    SStream_concat(O, "%s", "["); \
2021
19.7k
    printUInt64(O, Scale *MCOperand_getImm( \
2022
19.7k
               MCInst_getOperand(MI, (OpNum)))); \
2023
19.7k
    SStream_concat0(O, "]"); \
2024
19.7k
  }
Unexecuted instantiation: printVectorIndex_8
2025
DEFINE_printVectorIndex(1);
2026
DEFINE_printVectorIndex(8);
2027
2028
void printAlignedLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
2029
5.52k
{
2030
5.52k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_AlignedLabel, OpNum);
2031
5.52k
  MCOperand *Op = MCInst_getOperand(MI, (OpNum));
2032
2033
  // If the label has already been resolved to an immediate offset (say, when
2034
  // we're running the disassembler), just print the immediate.
2035
5.52k
  if (MCOperand_isImm(Op)) {
2036
5.43k
    SStream_concat0(O, markup("<imm:"));
2037
5.43k
    int64_t Offset = MCOperand_getImm(Op) * 4;
2038
5.43k
    if (MI->csh->PrintBranchImmAsAddress)
2039
5.43k
      printUInt64(O, (Address + Offset));
2040
0
    else {
2041
0
      printUInt64Bang(O, (Offset));
2042
0
    }
2043
5.43k
    SStream_concat0(O, markup(">"));
2044
5.43k
    return;
2045
5.43k
  }
2046
2047
91
  printUInt64Bang(O, MCOperand_getImm(Op));
2048
91
}
2049
2050
void printAdrLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
2051
0
{
2052
0
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_AdrLabel, OpNum);
2053
0
  MCOperand *Op = MCInst_getOperand(MI, (OpNum));
2054
2055
  // If the label has already been resolved to an immediate offset (say, when
2056
  // we're running the disassembler), just print the immediate.
2057
0
  if (MCOperand_isImm(Op)) {
2058
0
    const int64_t Offset = MCOperand_getImm(Op);
2059
0
    SStream_concat0(O, markup("<imm:"));
2060
0
    if (MI->csh->PrintBranchImmAsAddress)
2061
0
      printUInt64(O, ((Address & -4) + Offset));
2062
0
    else {
2063
0
      printUInt64Bang(O, Offset);
2064
0
    }
2065
0
    SStream_concat0(O, markup(">"));
2066
0
    return;
2067
0
  }
2068
2069
0
  printUInt64Bang(O, MCOperand_getImm(Op));
2070
0
}
2071
2072
void printAdrpLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
2073
0
{
2074
0
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_AdrpLabel, OpNum);
2075
0
  MCOperand *Op = MCInst_getOperand(MI, (OpNum));
2076
2077
  // If the label has already been resolved to an immediate offset (say, when
2078
  // we're running the disassembler), just print the immediate.
2079
0
  if (MCOperand_isImm(Op)) {
2080
0
    const int64_t Offset = MCOperand_getImm(Op) * 4096;
2081
0
    SStream_concat0(O, markup("<imm:"));
2082
0
    if (MI->csh->PrintBranchImmAsAddress)
2083
0
      printUInt64(O, ((Address & -4096) + Offset));
2084
0
    else {
2085
0
      printUInt64Bang(O, Offset);
2086
0
    }
2087
0
    SStream_concat0(O, markup(">"));
2088
0
    return;
2089
0
  }
2090
2091
0
  printUInt64Bang(O, MCOperand_getImm(Op));
2092
0
}
2093
2094
void printAdrAdrpLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
2095
2.53k
{
2096
2.53k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_AdrAdrpLabel, OpNum);
2097
2.53k
  MCOperand *Op = MCInst_getOperand(MI, (OpNum));
2098
2099
  // If the label has already been resolved to an immediate offset (say, when
2100
  // we're running the disassembler), just print the immediate.
2101
2.53k
  if (MCOperand_isImm(Op)) {
2102
2.53k
    int64_t Offset = MCOperand_getImm(Op);
2103
2.53k
    if (MCInst_getOpcode(MI) == AArch64_ADRP) {
2104
526
      Offset = Offset * 4096;
2105
526
      Address = Address & -4096;
2106
526
    }
2107
2.53k
    SStream_concat0(O, markup(">"));
2108
2.53k
    if (MI->csh->PrintBranchImmAsAddress)
2109
2.53k
      printUInt64(O, (Address + Offset));
2110
0
    else {
2111
0
      printUInt64Bang(O, Offset);
2112
0
    }
2113
2.53k
    SStream_concat0(O, markup(">"));
2114
2.53k
    return;
2115
2.53k
  }
2116
2117
0
  printUInt64Bang(O, MCOperand_getImm(Op));
2118
0
}
2119
2120
/// Not part of upstream LLVM.
2121
/// Just prints the barrier options as documented in
2122
/// https://github.com/AsahiLinux/docs/blob/main/docs/hw/cpu/apple-instructions.md
2123
void printAppleSysBarrierOption(MCInst *MI, unsigned OpNo, SStream *O)
2124
25
{
2125
25
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_AppleSysBarrierOption,
2126
25
        OpNo);
2127
25
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2128
25
  switch (Val) {
2129
14
  default:
2130
14
    SStream_concat0(O, "<undefined>");
2131
14
    break;
2132
0
  case 0:
2133
0
    SStream_concat0(O, "osh");
2134
0
    break;
2135
4
  case 1:
2136
4
    SStream_concat0(O, "nsh");
2137
4
    break;
2138
6
  case 2:
2139
6
    SStream_concat0(O, "ish");
2140
6
    break;
2141
1
  case 3:
2142
1
    SStream_concat0(O, "sy");
2143
1
    break;
2144
25
  }
2145
25
}
2146
2147
void printBarrierOption(MCInst *MI, unsigned OpNo, SStream *O)
2148
362
{
2149
362
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_BarrierOption, OpNo);
2150
362
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2151
362
  unsigned Opcode = MCInst_getOpcode(MI);
2152
2153
362
  const char *Name;
2154
362
  if (Opcode == AArch64_ISB) {
2155
21
    const AArch64ISB_ISB *ISB = AArch64ISB_lookupISBByEncoding(Val);
2156
21
    Name = ISB ? ISB->Name : "";
2157
341
  } else if (Opcode == AArch64_TSB) {
2158
157
    const AArch64TSB_TSB *TSB = AArch64TSB_lookupTSBByEncoding(Val);
2159
157
    Name = TSB ? TSB->Name : "";
2160
184
  } else {
2161
184
    const AArch64DB_DB *DB = AArch64DB_lookupDBByEncoding(Val);
2162
184
    Name = DB ? DB->Name : "";
2163
184
  }
2164
362
  if (Name[0] != '\0')
2165
285
    SStream_concat0(O, Name);
2166
77
  else {
2167
77
    SStream_concat(O, "%s", markup("<imm:"));
2168
77
    printUInt32Bang(O, Val);
2169
77
    SStream_concat0(O, markup(">"));
2170
77
  }
2171
362
}
2172
2173
void printBarriernXSOption(MCInst *MI, unsigned OpNo, SStream *O)
2174
363
{
2175
363
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_BarriernXSOption, OpNo);
2176
363
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2177
2178
363
  const char *Name;
2179
363
  const AArch64DBnXS_DBnXS *DB = AArch64DBnXS_lookupDBnXSByEncoding(Val);
2180
363
  Name = DB ? DB->Name : "";
2181
2182
363
  if (Name[0] != '\0')
2183
363
    SStream_concat0(O, Name);
2184
0
  else {
2185
0
    SStream_concat(O, "%s%s%s", markup("<imm:"), "#", Val);
2186
0
    SStream_concat0(O, markup(">"));
2187
0
  }
2188
363
}
2189
2190
static bool isValidSysReg(const AArch64SysReg_SysReg *Reg, bool Read,
2191
        unsigned mode)
2192
2.41k
{
2193
2.41k
  return (Reg && (Read ? Reg->Readable : Reg->Writeable) &&
2194
140
    AArch64_testFeatureList(mode, Reg->FeaturesRequired));
2195
2.41k
}
2196
2197
// Looks up a system register either by encoding or by name. Some system
2198
// registers share the same encoding between different architectures,
2199
// therefore a tablegen lookup by encoding will return an entry regardless
2200
// of the register's predication on a specific subtarget feature. To work
2201
// around this problem we keep an alternative name for such registers and
2202
// look them up by that name if the first lookup was unsuccessful.
2203
static const AArch64SysReg_SysReg *lookupSysReg(unsigned Val, bool Read,
2204
            unsigned mode)
2205
1.90k
{
2206
1.90k
  const AArch64SysReg_SysReg *Reg =
2207
1.90k
    AArch64SysReg_lookupSysRegByEncoding(Val);
2208
2209
1.90k
  if (Reg && !isValidSysReg(Reg, Read, mode))
2210
441
    Reg = AArch64SysReg_lookupSysRegByName(Reg->AltName);
2211
2212
1.90k
  return Reg;
2213
1.90k
}
2214
2215
void printMRSSystemRegister(MCInst *MI, unsigned OpNo, SStream *O)
2216
499
{
2217
499
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_MRSSystemRegister, OpNo);
2218
499
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2219
2220
  // Horrible hack for the one register that has identical encodings but
2221
  // different names in MSR and MRS. Because of this, one of MRS and MSR is
2222
  // going to get the wrong entry
2223
499
  if (Val == AARCH64_SYSREG_DBGDTRRX_EL0) {
2224
3
    SStream_concat0(O, "DBGDTRRX_EL0");
2225
3
    return;
2226
3
  }
2227
2228
  // Horrible hack for two different registers having the same encoding.
2229
496
  if (Val == AARCH64_SYSREG_TRCEXTINSELR) {
2230
125
    SStream_concat0(O, "TRCEXTINSELR");
2231
125
    return;
2232
125
  }
2233
2234
371
  const AArch64SysReg_SysReg *Reg =
2235
371
    lookupSysReg(Val, true /*Read*/, MI->csh->mode);
2236
2237
371
  if (isValidSysReg(Reg, true /*Read*/, MI->csh->mode))
2238
46
    SStream_concat0(O, Reg->Name);
2239
325
  else {
2240
325
    char result[AARCH64_GRS_LEN + 1] = { 0 };
2241
325
    AArch64SysReg_genericRegisterString(Val, result);
2242
325
    SStream_concat0(O, result);
2243
325
  }
2244
371
}
2245
2246
void printMSRSystemRegister(MCInst *MI, unsigned OpNo, SStream *O)
2247
1.64k
{
2248
1.64k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_MSRSystemRegister, OpNo);
2249
1.64k
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2250
2251
  // Horrible hack for the one register that has identical encodings but
2252
  // different names in MSR and MRS. Because of this, one of MRS and MSR is
2253
  // going to get the wrong entry
2254
1.64k
  if (Val == AARCH64_SYSREG_DBGDTRTX_EL0) {
2255
97
    SStream_concat0(O, "DBGDTRTX_EL0");
2256
97
    return;
2257
97
  }
2258
2259
  // Horrible hack for two different registers having the same encoding.
2260
1.54k
  if (Val == AARCH64_SYSREG_TRCEXTINSELR) {
2261
11
    SStream_concat0(O, "TRCEXTINSELR");
2262
11
    return;
2263
11
  }
2264
2265
1.53k
  const AArch64SysReg_SysReg *Reg =
2266
1.53k
    lookupSysReg(Val, false /*Read*/, MI->csh->mode);
2267
2268
1.53k
  if (isValidSysReg(Reg, false /*Read*/, MI->csh->mode))
2269
24
    SStream_concat0(O, Reg->Name);
2270
1.51k
  else {
2271
1.51k
    char result[AARCH64_GRS_LEN + 1] = { 0 };
2272
1.51k
    AArch64SysReg_genericRegisterString(Val, result);
2273
1.51k
    SStream_concat0(O, result);
2274
1.51k
  }
2275
1.53k
}
2276
2277
void printSystemPStateField(MCInst *MI, unsigned OpNo, SStream *O)
2278
267
{
2279
267
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_SystemPStateField, OpNo);
2280
267
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2281
2282
267
  const AArch64PState_PStateImm0_15 *PStateImm15 =
2283
267
    AArch64PState_lookupPStateImm0_15ByEncoding(Val);
2284
267
  const AArch64PState_PStateImm0_1 *PStateImm1 =
2285
267
    AArch64PState_lookupPStateImm0_1ByEncoding(Val);
2286
267
  if (PStateImm15 &&
2287
183
      AArch64_testFeatureList(MI->csh->mode,
2288
183
            PStateImm15->FeaturesRequired))
2289
183
    SStream_concat0(O, PStateImm15->Name);
2290
84
  else if (PStateImm1 &&
2291
84
     AArch64_testFeatureList(MI->csh->mode,
2292
84
           PStateImm1->FeaturesRequired))
2293
84
    SStream_concat0(O, PStateImm1->Name);
2294
0
  else {
2295
0
    printUInt32Bang(O, (Val));
2296
0
    SStream_concat1(O, '\0');
2297
0
  }
2298
267
}
2299
2300
void printSIMDType10Operand(MCInst *MI, unsigned OpNo, SStream *O)
2301
1.52k
{
2302
1.52k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_SIMDType10Operand, OpNo);
2303
1.52k
  unsigned RawVal = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2304
1.52k
  uint64_t Val = AArch64_AM_decodeAdvSIMDModImmType10(RawVal);
2305
1.52k
  SStream_concat(O, "%s#%#016llx", markup("<imm:"), Val);
2306
1.52k
  SStream_concat0(O, markup(">"));
2307
1.52k
}
2308
2309
#define DEFINE_printComplexRotationOp(Angle, Remainder) \
2310
  static void CONCAT(printComplexRotationOp, CONCAT(Angle, Remainder))( \
2311
    MCInst * MI, unsigned OpNo, SStream *O) \
2312
1.77k
  { \
2313
1.77k
    AArch64_add_cs_detail_2( \
2314
1.77k
      MI, \
2315
1.77k
      CONCAT(CONCAT(AArch64_OP_GROUP_ComplexRotationOp, \
2316
1.77k
              Angle), \
2317
1.77k
             Remainder), \
2318
1.77k
      OpNo, Angle, Remainder); \
2319
1.77k
    unsigned Val = \
2320
1.77k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); \
2321
1.77k
    SStream_concat(O, "%s", markup("<imm:")); \
2322
1.77k
    SStream_concat(O, "#%" PRId32, \
2323
1.77k
             (int32_t)((Val * Angle) + Remainder)); \
2324
1.77k
    SStream_concat0(O, markup(">")); \
2325
1.77k
  }
2326
421
DEFINE_printComplexRotationOp(180, 90);
2327
1.35k
DEFINE_printComplexRotationOp(90, 0);
2328
2329
void printSVEPattern(MCInst *MI, unsigned OpNum, SStream *O)
2330
5.19k
{
2331
5.19k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_SVEPattern, OpNum);
2332
5.19k
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
2333
5.19k
  const AArch64SVEPredPattern_SVEPREDPAT *Pat =
2334
5.19k
    AArch64SVEPredPattern_lookupSVEPREDPATByEncoding(Val);
2335
5.19k
  if (Pat)
2336
2.41k
    SStream_concat0(O, Pat->Name);
2337
2.77k
  else
2338
2.77k
    printUInt32Bang(O, Val);
2339
5.19k
}
2340
2341
void printSVEVecLenSpecifier(MCInst *MI, unsigned OpNum, SStream *O)
2342
674
{
2343
674
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_SVEVecLenSpecifier, OpNum);
2344
674
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
2345
  // Pattern has only 1 bit
2346
674
  if (Val > 1)
2347
0
    CS_ASSERT_RET(0 && "Invalid vector length specifier");
2348
674
  const AArch64SVEVecLenSpecifier_SVEVECLENSPECIFIER *Pat =
2349
674
    AArch64SVEVecLenSpecifier_lookupSVEVECLENSPECIFIERByEncoding(
2350
674
      Val);
2351
674
  if (Pat)
2352
674
    SStream_concat0(O, Pat->Name);
2353
674
}
2354
2355
#define DEFINE_printSVERegOp(suffix) \
2356
  void CONCAT(printSVERegOp, suffix)(MCInst * MI, unsigned OpNum, \
2357
             SStream *O) \
2358
77.9k
  { \
2359
77.9k
    AArch64_add_cs_detail_1( \
2360
77.9k
      MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2361
77.9k
      CHAR(suffix)); \
2362
77.9k
    switch (CHAR(suffix)) { \
2363
22.6k
    case '0': \
2364
35.4k
    case 'b': \
2365
52.4k
    case 'h': \
2366
65.1k
    case 's': \
2367
77.3k
    case 'd': \
2368
77.9k
    case 'q': \
2369
77.9k
      break; \
2370
77.3k
    default: \
2371
0
      CS_ASSERT_RET(0 && "Invalid kind specifier."); \
2372
77.9k
    } \
2373
77.9k
\
2374
77.9k
    unsigned Reg = \
2375
77.9k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2376
77.9k
    printRegName(O, Reg); \
2377
77.9k
    if (CHAR(suffix) != '0') { \
2378
55.2k
      SStream_concat1(O, '.'); \
2379
55.2k
      SStream_concat1(O, CHAR(suffix)); \
2380
55.2k
    } \
2381
77.9k
  }
printSVERegOp_b
Line
Count
Source
2358
12.7k
  { \
2359
12.7k
    AArch64_add_cs_detail_1( \
2360
12.7k
      MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2361
12.7k
      CHAR(suffix)); \
2362
12.7k
    switch (CHAR(suffix)) { \
2363
0
    case '0': \
2364
12.7k
    case 'b': \
2365
12.7k
    case 'h': \
2366
12.7k
    case 's': \
2367
12.7k
    case 'd': \
2368
12.7k
    case 'q': \
2369
12.7k
      break; \
2370
12.7k
    default: \
2371
0
      CS_ASSERT_RET(0 && "Invalid kind specifier."); \
2372
12.7k
    } \
2373
12.7k
\
2374
12.7k
    unsigned Reg = \
2375
12.7k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2376
12.7k
    printRegName(O, Reg); \
2377
12.7k
    if (CHAR(suffix) != '0') { \
2378
12.7k
      SStream_concat1(O, '.'); \
2379
12.7k
      SStream_concat1(O, CHAR(suffix)); \
2380
12.7k
    } \
2381
12.7k
  }
printSVERegOp_d
Line
Count
Source
2358
12.2k
  { \
2359
12.2k
    AArch64_add_cs_detail_1( \
2360
12.2k
      MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2361
12.2k
      CHAR(suffix)); \
2362
12.2k
    switch (CHAR(suffix)) { \
2363
0
    case '0': \
2364
0
    case 'b': \
2365
0
    case 'h': \
2366
0
    case 's': \
2367
12.2k
    case 'd': \
2368
12.2k
    case 'q': \
2369
12.2k
      break; \
2370
12.2k
    default: \
2371
0
      CS_ASSERT_RET(0 && "Invalid kind specifier."); \
2372
12.2k
    } \
2373
12.2k
\
2374
12.2k
    unsigned Reg = \
2375
12.2k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2376
12.2k
    printRegName(O, Reg); \
2377
12.2k
    if (CHAR(suffix) != '0') { \
2378
12.2k
      SStream_concat1(O, '.'); \
2379
12.2k
      SStream_concat1(O, CHAR(suffix)); \
2380
12.2k
    } \
2381
12.2k
  }
printSVERegOp_h
Line
Count
Source
2358
16.9k
  { \
2359
16.9k
    AArch64_add_cs_detail_1( \
2360
16.9k
      MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2361
16.9k
      CHAR(suffix)); \
2362
16.9k
    switch (CHAR(suffix)) { \
2363
0
    case '0': \
2364
0
    case 'b': \
2365
16.9k
    case 'h': \
2366
16.9k
    case 's': \
2367
16.9k
    case 'd': \
2368
16.9k
    case 'q': \
2369
16.9k
      break; \
2370
16.9k
    default: \
2371
0
      CS_ASSERT_RET(0 && "Invalid kind specifier."); \
2372
16.9k
    } \
2373
16.9k
\
2374
16.9k
    unsigned Reg = \
2375
16.9k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2376
16.9k
    printRegName(O, Reg); \
2377
16.9k
    if (CHAR(suffix) != '0') { \
2378
16.9k
      SStream_concat1(O, '.'); \
2379
16.9k
      SStream_concat1(O, CHAR(suffix)); \
2380
16.9k
    } \
2381
16.9k
  }
printSVERegOp_s
Line
Count
Source
2358
12.6k
  { \
2359
12.6k
    AArch64_add_cs_detail_1( \
2360
12.6k
      MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2361
12.6k
      CHAR(suffix)); \
2362
12.6k
    switch (CHAR(suffix)) { \
2363
0
    case '0': \
2364
0
    case 'b': \
2365
0
    case 'h': \
2366
12.6k
    case 's': \
2367
12.6k
    case 'd': \
2368
12.6k
    case 'q': \
2369
12.6k
      break; \
2370
12.6k
    default: \
2371
0
      CS_ASSERT_RET(0 && "Invalid kind specifier."); \
2372
12.6k
    } \
2373
12.6k
\
2374
12.6k
    unsigned Reg = \
2375
12.6k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2376
12.6k
    printRegName(O, Reg); \
2377
12.6k
    if (CHAR(suffix) != '0') { \
2378
12.6k
      SStream_concat1(O, '.'); \
2379
12.6k
      SStream_concat1(O, CHAR(suffix)); \
2380
12.6k
    } \
2381
12.6k
  }
printSVERegOp_0
Line
Count
Source
2358
22.6k
  { \
2359
22.6k
    AArch64_add_cs_detail_1( \
2360
22.6k
      MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2361
22.6k
      CHAR(suffix)); \
2362
22.6k
    switch (CHAR(suffix)) { \
2363
22.6k
    case '0': \
2364
22.6k
    case 'b': \
2365
22.6k
    case 'h': \
2366
22.6k
    case 's': \
2367
22.6k
    case 'd': \
2368
22.6k
    case 'q': \
2369
22.6k
      break; \
2370
22.6k
    default: \
2371
0
      CS_ASSERT_RET(0 && "Invalid kind specifier."); \
2372
22.6k
    } \
2373
22.6k
\
2374
22.6k
    unsigned Reg = \
2375
22.6k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2376
22.6k
    printRegName(O, Reg); \
2377
22.6k
    if (CHAR(suffix) != '0') { \
2378
0
      SStream_concat1(O, '.'); \
2379
0
      SStream_concat1(O, CHAR(suffix)); \
2380
0
    } \
2381
22.6k
  }
printSVERegOp_q
Line
Count
Source
2358
527
  { \
2359
527
    AArch64_add_cs_detail_1( \
2360
527
      MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2361
527
      CHAR(suffix)); \
2362
527
    switch (CHAR(suffix)) { \
2363
0
    case '0': \
2364
0
    case 'b': \
2365
0
    case 'h': \
2366
0
    case 's': \
2367
0
    case 'd': \
2368
527
    case 'q': \
2369
527
      break; \
2370
0
    default: \
2371
0
      CS_ASSERT_RET(0 && "Invalid kind specifier."); \
2372
527
    } \
2373
527
\
2374
527
    unsigned Reg = \
2375
527
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2376
527
    printRegName(O, Reg); \
2377
527
    if (CHAR(suffix) != '0') { \
2378
527
      SStream_concat1(O, '.'); \
2379
527
      SStream_concat1(O, CHAR(suffix)); \
2380
527
    } \
2381
527
  }
2382
DEFINE_printSVERegOp(b);
2383
DEFINE_printSVERegOp(d);
2384
DEFINE_printSVERegOp(h);
2385
DEFINE_printSVERegOp(s);
2386
DEFINE_printSVERegOp(0);
2387
DEFINE_printSVERegOp(q);
2388
2389
#define DECLARE_printImmSVE_S32(T) \
2390
  void CONCAT(printImmSVE, T)(T Val, SStream * O) \
2391
726
  { \
2392
726
    printInt32Bang(O, Val); \
2393
726
  }
printImmSVE_int16_t
Line
Count
Source
2391
161
  { \
2392
161
    printInt32Bang(O, Val); \
2393
161
  }
printImmSVE_int8_t
Line
Count
Source
2391
218
  { \
2392
218
    printInt32Bang(O, Val); \
2393
218
  }
printImmSVE_int32_t
Line
Count
Source
2391
347
  { \
2392
347
    printInt32Bang(O, Val); \
2393
347
  }
2394
DECLARE_printImmSVE_S32(int16_t);
2395
DECLARE_printImmSVE_S32(int8_t);
2396
DECLARE_printImmSVE_S32(int32_t);
2397
2398
#define DECLARE_printImmSVE_U32(T) \
2399
  void CONCAT(printImmSVE, T)(T Val, SStream * O) \
2400
185
  { \
2401
185
    printUInt32Bang(O, Val); \
2402
185
  }
printImmSVE_uint16_t
Line
Count
Source
2400
29
  { \
2401
29
    printUInt32Bang(O, Val); \
2402
29
  }
printImmSVE_uint8_t
Line
Count
Source
2400
66
  { \
2401
66
    printUInt32Bang(O, Val); \
2402
66
  }
printImmSVE_uint32_t
Line
Count
Source
2400
90
  { \
2401
90
    printUInt32Bang(O, Val); \
2402
90
  }
2403
DECLARE_printImmSVE_U32(uint16_t);
2404
DECLARE_printImmSVE_U32(uint8_t);
2405
DECLARE_printImmSVE_U32(uint32_t);
2406
2407
#define DECLARE_printImmSVE_S64(T) \
2408
  void CONCAT(printImmSVE, T)(T Val, SStream * O) \
2409
194
  { \
2410
194
    printInt64Bang(O, Val); \
2411
194
  }
2412
DECLARE_printImmSVE_S64(int64_t);
2413
2414
#define DECLARE_printImmSVE_U64(T) \
2415
  void CONCAT(printImmSVE, T)(T Val, SStream * O) \
2416
69
  { \
2417
69
    printUInt64Bang(O, Val); \
2418
69
  }
2419
DECLARE_printImmSVE_U64(uint64_t);
2420
2421
#define DEFINE_isSignedType(T) \
2422
  static inline bool CONCAT(isSignedType, T)() \
2423
864
  { \
2424
864
    return CHAR(T) == 'i'; \
2425
864
  }
AArch64InstPrinter.c:isSignedType_int16_t
Line
Count
Source
2423
113
  { \
2424
113
    return CHAR(T) == 'i'; \
2425
113
  }
AArch64InstPrinter.c:isSignedType_int8_t
Line
Count
Source
2423
218
  { \
2424
218
    return CHAR(T) == 'i'; \
2425
218
  }
AArch64InstPrinter.c:isSignedType_int64_t
Line
Count
Source
2423
160
  { \
2424
160
    return CHAR(T) == 'i'; \
2425
160
  }
AArch64InstPrinter.c:isSignedType_int32_t
Line
Count
Source
2423
119
  { \
2424
119
    return CHAR(T) == 'i'; \
2425
119
  }
AArch64InstPrinter.c:isSignedType_uint16_t
Line
Count
Source
2423
29
  { \
2424
29
    return CHAR(T) == 'i'; \
2425
29
  }
AArch64InstPrinter.c:isSignedType_uint8_t
Line
Count
Source
2423
66
  { \
2424
66
    return CHAR(T) == 'i'; \
2425
66
  }
AArch64InstPrinter.c:isSignedType_uint64_t
Line
Count
Source
2423
69
  { \
2424
69
    return CHAR(T) == 'i'; \
2425
69
  }
AArch64InstPrinter.c:isSignedType_uint32_t
Line
Count
Source
2423
90
  { \
2424
90
    return CHAR(T) == 'i'; \
2425
90
  }
2426
DEFINE_isSignedType(int8_t);
2427
DEFINE_isSignedType(int16_t);
2428
DEFINE_isSignedType(int32_t);
2429
DEFINE_isSignedType(int64_t);
2430
DEFINE_isSignedType(uint8_t);
2431
DEFINE_isSignedType(uint16_t);
2432
DEFINE_isSignedType(uint32_t);
2433
DEFINE_isSignedType(uint64_t);
2434
2435
#define DEFINE_printImm8OptLsl(T) \
2436
  void CONCAT(printImm8OptLsl, T)(MCInst * MI, unsigned OpNum, \
2437
          SStream *O) \
2438
1.14k
  { \
2439
1.14k
    AArch64_add_cs_detail_1( \
2440
1.14k
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2441
1.14k
      sizeof(T)); \
2442
1.14k
    unsigned UnscaledVal = \
2443
1.14k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2444
1.14k
    unsigned Shift = \
2445
1.14k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2446
1.14k
\
2447
1.14k
    if ((UnscaledVal == 0) && \
2448
1.14k
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2449
284
      SStream_concat(O, "%s", markup("<imm:")); \
2450
284
      SStream_concat1(O, '#'); \
2451
284
      printUInt64(O, (UnscaledVal)); \
2452
284
      SStream_concat0(O, markup(">")); \
2453
284
      printShifter(MI, OpNum + 1, O); \
2454
284
      return; \
2455
284
    } \
2456
1.14k
\
2457
1.14k
    T Val; \
2458
864
    if (CONCAT(isSignedType, T)()) \
2459
864
      Val = (int8_t)UnscaledVal * \
2460
610
            (1 << AArch64_AM_getShiftValue(Shift)); \
2461
864
    else \
2462
864
      Val = (uint8_t)UnscaledVal * \
2463
254
            (1 << AArch64_AM_getShiftValue(Shift)); \
2464
864
\
2465
864
    CONCAT(printImmSVE, T)(Val, O); \
2466
864
  }
printImm8OptLsl_int16_t
Line
Count
Source
2438
146
  { \
2439
146
    AArch64_add_cs_detail_1( \
2440
146
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2441
146
      sizeof(T)); \
2442
146
    unsigned UnscaledVal = \
2443
146
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2444
146
    unsigned Shift = \
2445
146
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2446
146
\
2447
146
    if ((UnscaledVal == 0) && \
2448
146
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2449
33
      SStream_concat(O, "%s", markup("<imm:")); \
2450
33
      SStream_concat1(O, '#'); \
2451
33
      printUInt64(O, (UnscaledVal)); \
2452
33
      SStream_concat0(O, markup(">")); \
2453
33
      printShifter(MI, OpNum + 1, O); \
2454
33
      return; \
2455
33
    } \
2456
146
\
2457
146
    T Val; \
2458
113
    if (CONCAT(isSignedType, T)()) \
2459
113
      Val = (int8_t)UnscaledVal * \
2460
113
            (1 << AArch64_AM_getShiftValue(Shift)); \
2461
113
    else \
2462
113
      Val = (uint8_t)UnscaledVal * \
2463
0
            (1 << AArch64_AM_getShiftValue(Shift)); \
2464
113
\
2465
113
    CONCAT(printImmSVE, T)(Val, O); \
2466
113
  }
printImm8OptLsl_int8_t
Line
Count
Source
2438
218
  { \
2439
218
    AArch64_add_cs_detail_1( \
2440
218
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2441
218
      sizeof(T)); \
2442
218
    unsigned UnscaledVal = \
2443
218
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2444
218
    unsigned Shift = \
2445
218
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2446
218
\
2447
218
    if ((UnscaledVal == 0) && \
2448
218
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2449
0
      SStream_concat(O, "%s", markup("<imm:")); \
2450
0
      SStream_concat1(O, '#'); \
2451
0
      printUInt64(O, (UnscaledVal)); \
2452
0
      SStream_concat0(O, markup(">")); \
2453
0
      printShifter(MI, OpNum + 1, O); \
2454
0
      return; \
2455
0
    } \
2456
218
\
2457
218
    T Val; \
2458
218
    if (CONCAT(isSignedType, T)()) \
2459
218
      Val = (int8_t)UnscaledVal * \
2460
218
            (1 << AArch64_AM_getShiftValue(Shift)); \
2461
218
    else \
2462
218
      Val = (uint8_t)UnscaledVal * \
2463
0
            (1 << AArch64_AM_getShiftValue(Shift)); \
2464
218
\
2465
218
    CONCAT(printImmSVE, T)(Val, O); \
2466
218
  }
printImm8OptLsl_int64_t
Line
Count
Source
2438
215
  { \
2439
215
    AArch64_add_cs_detail_1( \
2440
215
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2441
215
      sizeof(T)); \
2442
215
    unsigned UnscaledVal = \
2443
215
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2444
215
    unsigned Shift = \
2445
215
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2446
215
\
2447
215
    if ((UnscaledVal == 0) && \
2448
215
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2449
55
      SStream_concat(O, "%s", markup("<imm:")); \
2450
55
      SStream_concat1(O, '#'); \
2451
55
      printUInt64(O, (UnscaledVal)); \
2452
55
      SStream_concat0(O, markup(">")); \
2453
55
      printShifter(MI, OpNum + 1, O); \
2454
55
      return; \
2455
55
    } \
2456
215
\
2457
215
    T Val; \
2458
160
    if (CONCAT(isSignedType, T)()) \
2459
160
      Val = (int8_t)UnscaledVal * \
2460
160
            (1 << AArch64_AM_getShiftValue(Shift)); \
2461
160
    else \
2462
160
      Val = (uint8_t)UnscaledVal * \
2463
0
            (1 << AArch64_AM_getShiftValue(Shift)); \
2464
160
\
2465
160
    CONCAT(printImmSVE, T)(Val, O); \
2466
160
  }
printImm8OptLsl_int32_t
Line
Count
Source
2438
137
  { \
2439
137
    AArch64_add_cs_detail_1( \
2440
137
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2441
137
      sizeof(T)); \
2442
137
    unsigned UnscaledVal = \
2443
137
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2444
137
    unsigned Shift = \
2445
137
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2446
137
\
2447
137
    if ((UnscaledVal == 0) && \
2448
137
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2449
18
      SStream_concat(O, "%s", markup("<imm:")); \
2450
18
      SStream_concat1(O, '#'); \
2451
18
      printUInt64(O, (UnscaledVal)); \
2452
18
      SStream_concat0(O, markup(">")); \
2453
18
      printShifter(MI, OpNum + 1, O); \
2454
18
      return; \
2455
18
    } \
2456
137
\
2457
137
    T Val; \
2458
119
    if (CONCAT(isSignedType, T)()) \
2459
119
      Val = (int8_t)UnscaledVal * \
2460
119
            (1 << AArch64_AM_getShiftValue(Shift)); \
2461
119
    else \
2462
119
      Val = (uint8_t)UnscaledVal * \
2463
0
            (1 << AArch64_AM_getShiftValue(Shift)); \
2464
119
\
2465
119
    CONCAT(printImmSVE, T)(Val, O); \
2466
119
  }
printImm8OptLsl_uint16_t
Line
Count
Source
2438
83
  { \
2439
83
    AArch64_add_cs_detail_1( \
2440
83
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2441
83
      sizeof(T)); \
2442
83
    unsigned UnscaledVal = \
2443
83
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2444
83
    unsigned Shift = \
2445
83
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2446
83
\
2447
83
    if ((UnscaledVal == 0) && \
2448
83
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2449
54
      SStream_concat(O, "%s", markup("<imm:")); \
2450
54
      SStream_concat1(O, '#'); \
2451
54
      printUInt64(O, (UnscaledVal)); \
2452
54
      SStream_concat0(O, markup(">")); \
2453
54
      printShifter(MI, OpNum + 1, O); \
2454
54
      return; \
2455
54
    } \
2456
83
\
2457
83
    T Val; \
2458
29
    if (CONCAT(isSignedType, T)()) \
2459
29
      Val = (int8_t)UnscaledVal * \
2460
0
            (1 << AArch64_AM_getShiftValue(Shift)); \
2461
29
    else \
2462
29
      Val = (uint8_t)UnscaledVal * \
2463
29
            (1 << AArch64_AM_getShiftValue(Shift)); \
2464
29
\
2465
29
    CONCAT(printImmSVE, T)(Val, O); \
2466
29
  }
printImm8OptLsl_uint8_t
Line
Count
Source
2438
66
  { \
2439
66
    AArch64_add_cs_detail_1( \
2440
66
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2441
66
      sizeof(T)); \
2442
66
    unsigned UnscaledVal = \
2443
66
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2444
66
    unsigned Shift = \
2445
66
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2446
66
\
2447
66
    if ((UnscaledVal == 0) && \
2448
66
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2449
0
      SStream_concat(O, "%s", markup("<imm:")); \
2450
0
      SStream_concat1(O, '#'); \
2451
0
      printUInt64(O, (UnscaledVal)); \
2452
0
      SStream_concat0(O, markup(">")); \
2453
0
      printShifter(MI, OpNum + 1, O); \
2454
0
      return; \
2455
0
    } \
2456
66
\
2457
66
    T Val; \
2458
66
    if (CONCAT(isSignedType, T)()) \
2459
66
      Val = (int8_t)UnscaledVal * \
2460
0
            (1 << AArch64_AM_getShiftValue(Shift)); \
2461
66
    else \
2462
66
      Val = (uint8_t)UnscaledVal * \
2463
66
            (1 << AArch64_AM_getShiftValue(Shift)); \
2464
66
\
2465
66
    CONCAT(printImmSVE, T)(Val, O); \
2466
66
  }
printImm8OptLsl_uint64_t
Line
Count
Source
2438
144
  { \
2439
144
    AArch64_add_cs_detail_1( \
2440
144
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2441
144
      sizeof(T)); \
2442
144
    unsigned UnscaledVal = \
2443
144
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2444
144
    unsigned Shift = \
2445
144
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2446
144
\
2447
144
    if ((UnscaledVal == 0) && \
2448
144
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2449
75
      SStream_concat(O, "%s", markup("<imm:")); \
2450
75
      SStream_concat1(O, '#'); \
2451
75
      printUInt64(O, (UnscaledVal)); \
2452
75
      SStream_concat0(O, markup(">")); \
2453
75
      printShifter(MI, OpNum + 1, O); \
2454
75
      return; \
2455
75
    } \
2456
144
\
2457
144
    T Val; \
2458
69
    if (CONCAT(isSignedType, T)()) \
2459
69
      Val = (int8_t)UnscaledVal * \
2460
0
            (1 << AArch64_AM_getShiftValue(Shift)); \
2461
69
    else \
2462
69
      Val = (uint8_t)UnscaledVal * \
2463
69
            (1 << AArch64_AM_getShiftValue(Shift)); \
2464
69
\
2465
69
    CONCAT(printImmSVE, T)(Val, O); \
2466
69
  }
printImm8OptLsl_uint32_t
Line
Count
Source
2438
139
  { \
2439
139
    AArch64_add_cs_detail_1( \
2440
139
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2441
139
      sizeof(T)); \
2442
139
    unsigned UnscaledVal = \
2443
139
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2444
139
    unsigned Shift = \
2445
139
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2446
139
\
2447
139
    if ((UnscaledVal == 0) && \
2448
139
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2449
49
      SStream_concat(O, "%s", markup("<imm:")); \
2450
49
      SStream_concat1(O, '#'); \
2451
49
      printUInt64(O, (UnscaledVal)); \
2452
49
      SStream_concat0(O, markup(">")); \
2453
49
      printShifter(MI, OpNum + 1, O); \
2454
49
      return; \
2455
49
    } \
2456
139
\
2457
139
    T Val; \
2458
90
    if (CONCAT(isSignedType, T)()) \
2459
90
      Val = (int8_t)UnscaledVal * \
2460
0
            (1 << AArch64_AM_getShiftValue(Shift)); \
2461
90
    else \
2462
90
      Val = (uint8_t)UnscaledVal * \
2463
90
            (1 << AArch64_AM_getShiftValue(Shift)); \
2464
90
\
2465
90
    CONCAT(printImmSVE, T)(Val, O); \
2466
90
  }
2467
DEFINE_printImm8OptLsl(int16_t);
2468
DEFINE_printImm8OptLsl(int8_t);
2469
DEFINE_printImm8OptLsl(int64_t);
2470
DEFINE_printImm8OptLsl(int32_t);
2471
DEFINE_printImm8OptLsl(uint16_t);
2472
DEFINE_printImm8OptLsl(uint8_t);
2473
DEFINE_printImm8OptLsl(uint64_t);
2474
DEFINE_printImm8OptLsl(uint32_t);
2475
2476
#define DEFINE_printSVELogicalImm(T) \
2477
  void CONCAT(printSVELogicalImm, T)(MCInst * MI, unsigned OpNum, \
2478
             SStream *O) \
2479
458
  { \
2480
458
    AArch64_add_cs_detail_1( \
2481
458
      MI, CONCAT(AArch64_OP_GROUP_SVELogicalImm, T), OpNum, \
2482
458
      sizeof(T)); \
2483
458
    typedef T SignedT; \
2484
458
    typedef CONCATS(u, T) UnsignedT; \
2485
458
\
2486
458
    uint64_t Val = \
2487
458
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2488
458
    UnsignedT PrintVal = \
2489
458
      AArch64_AM_decodeLogicalImmediate(Val, 64); \
2490
458
\
2491
458
    if ((int16_t)PrintVal == (SignedT)PrintVal) \
2492
458
      CONCAT(printImmSVE, T)((T)PrintVal, O); \
2493
458
    else if ((uint16_t)PrintVal == PrintVal) \
2494
190
      CONCAT(printImmSVE, T)(PrintVal, O); \
2495
190
    else { \
2496
148
      SStream_concat(O, "%s", markup("<imm:")); \
2497
148
      printUInt64Bang(O, ((uint64_t)PrintVal)); \
2498
148
      SStream_concat0(O, markup(">")); \
2499
148
    } \
2500
458
  }
printSVELogicalImm_int16_t
Line
Count
Source
2479
48
  { \
2480
48
    AArch64_add_cs_detail_1( \
2481
48
      MI, CONCAT(AArch64_OP_GROUP_SVELogicalImm, T), OpNum, \
2482
48
      sizeof(T)); \
2483
48
    typedef T SignedT; \
2484
48
    typedef CONCATS(u, T) UnsignedT; \
2485
48
\
2486
48
    uint64_t Val = \
2487
48
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2488
48
    UnsignedT PrintVal = \
2489
48
      AArch64_AM_decodeLogicalImmediate(Val, 64); \
2490
48
\
2491
48
    if ((int16_t)PrintVal == (SignedT)PrintVal) \
2492
48
      CONCAT(printImmSVE, T)((T)PrintVal, O); \
2493
48
    else if ((uint16_t)PrintVal == PrintVal) \
2494
0
      CONCAT(printImmSVE, T)(PrintVal, O); \
2495
0
    else { \
2496
0
      SStream_concat(O, "%s", markup("<imm:")); \
2497
0
      printUInt64Bang(O, ((uint64_t)PrintVal)); \
2498
0
      SStream_concat0(O, markup(">")); \
2499
0
    } \
2500
48
  }
printSVELogicalImm_int32_t
Line
Count
Source
2479
313
  { \
2480
313
    AArch64_add_cs_detail_1( \
2481
313
      MI, CONCAT(AArch64_OP_GROUP_SVELogicalImm, T), OpNum, \
2482
313
      sizeof(T)); \
2483
313
    typedef T SignedT; \
2484
313
    typedef CONCATS(u, T) UnsignedT; \
2485
313
\
2486
313
    uint64_t Val = \
2487
313
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2488
313
    UnsignedT PrintVal = \
2489
313
      AArch64_AM_decodeLogicalImmediate(Val, 64); \
2490
313
\
2491
313
    if ((int16_t)PrintVal == (SignedT)PrintVal) \
2492
313
      CONCAT(printImmSVE, T)((T)PrintVal, O); \
2493
313
    else if ((uint16_t)PrintVal == PrintVal) \
2494
109
      CONCAT(printImmSVE, T)(PrintVal, O); \
2495
109
    else { \
2496
85
      SStream_concat(O, "%s", markup("<imm:")); \
2497
85
      printUInt64Bang(O, ((uint64_t)PrintVal)); \
2498
85
      SStream_concat0(O, markup(">")); \
2499
85
    } \
2500
313
  }
printSVELogicalImm_int64_t
Line
Count
Source
2479
97
  { \
2480
97
    AArch64_add_cs_detail_1( \
2481
97
      MI, CONCAT(AArch64_OP_GROUP_SVELogicalImm, T), OpNum, \
2482
97
      sizeof(T)); \
2483
97
    typedef T SignedT; \
2484
97
    typedef CONCATS(u, T) UnsignedT; \
2485
97
\
2486
97
    uint64_t Val = \
2487
97
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2488
97
    UnsignedT PrintVal = \
2489
97
      AArch64_AM_decodeLogicalImmediate(Val, 64); \
2490
97
\
2491
97
    if ((int16_t)PrintVal == (SignedT)PrintVal) \
2492
97
      CONCAT(printImmSVE, T)((T)PrintVal, O); \
2493
97
    else if ((uint16_t)PrintVal == PrintVal) \
2494
81
      CONCAT(printImmSVE, T)(PrintVal, O); \
2495
81
    else { \
2496
63
      SStream_concat(O, "%s", markup("<imm:")); \
2497
63
      printUInt64Bang(O, ((uint64_t)PrintVal)); \
2498
63
      SStream_concat0(O, markup(">")); \
2499
63
    } \
2500
97
  }
2501
DEFINE_printSVELogicalImm(int16_t);
2502
DEFINE_printSVELogicalImm(int32_t);
2503
DEFINE_printSVELogicalImm(int64_t);
2504
2505
#define DEFINE_printZPRasFPR(Width) \
2506
  void CONCAT(printZPRasFPR, Width)(MCInst * MI, unsigned OpNum, \
2507
            SStream *O) \
2508
934
  { \
2509
934
    AArch64_add_cs_detail_1( \
2510
934
      MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2511
934
      Width); \
2512
934
    unsigned Base; \
2513
934
    switch (Width) { \
2514
126
    case 8: \
2515
126
      Base = AArch64_B0; \
2516
126
      break; \
2517
447
    case 16: \
2518
447
      Base = AArch64_H0; \
2519
447
      break; \
2520
253
    case 32: \
2521
253
      Base = AArch64_S0; \
2522
253
      break; \
2523
107
    case 64: \
2524
107
      Base = AArch64_D0; \
2525
107
      break; \
2526
1
    case 128: \
2527
1
      Base = AArch64_Q0; \
2528
1
      break; \
2529
0
    default: \
2530
0
      CS_ASSERT_RET(0 && "Unsupported width"); \
2531
934
    } \
2532
934
    unsigned Reg = \
2533
934
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2534
934
    printRegName(O, Reg - AArch64_Z0 + Base); \
2535
934
  }
printZPRasFPR_8
Line
Count
Source
2508
126
  { \
2509
126
    AArch64_add_cs_detail_1( \
2510
126
      MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2511
126
      Width); \
2512
126
    unsigned Base; \
2513
126
    switch (Width) { \
2514
126
    case 8: \
2515
126
      Base = AArch64_B0; \
2516
126
      break; \
2517
0
    case 16: \
2518
0
      Base = AArch64_H0; \
2519
0
      break; \
2520
0
    case 32: \
2521
0
      Base = AArch64_S0; \
2522
0
      break; \
2523
0
    case 64: \
2524
0
      Base = AArch64_D0; \
2525
0
      break; \
2526
0
    case 128: \
2527
0
      Base = AArch64_Q0; \
2528
0
      break; \
2529
0
    default: \
2530
0
      CS_ASSERT_RET(0 && "Unsupported width"); \
2531
126
    } \
2532
126
    unsigned Reg = \
2533
126
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2534
126
    printRegName(O, Reg - AArch64_Z0 + Base); \
2535
126
  }
printZPRasFPR_64
Line
Count
Source
2508
107
  { \
2509
107
    AArch64_add_cs_detail_1( \
2510
107
      MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2511
107
      Width); \
2512
107
    unsigned Base; \
2513
107
    switch (Width) { \
2514
0
    case 8: \
2515
0
      Base = AArch64_B0; \
2516
0
      break; \
2517
0
    case 16: \
2518
0
      Base = AArch64_H0; \
2519
0
      break; \
2520
0
    case 32: \
2521
0
      Base = AArch64_S0; \
2522
0
      break; \
2523
107
    case 64: \
2524
107
      Base = AArch64_D0; \
2525
107
      break; \
2526
0
    case 128: \
2527
0
      Base = AArch64_Q0; \
2528
0
      break; \
2529
0
    default: \
2530
0
      CS_ASSERT_RET(0 && "Unsupported width"); \
2531
107
    } \
2532
107
    unsigned Reg = \
2533
107
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2534
107
    printRegName(O, Reg - AArch64_Z0 + Base); \
2535
107
  }
printZPRasFPR_16
Line
Count
Source
2508
447
  { \
2509
447
    AArch64_add_cs_detail_1( \
2510
447
      MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2511
447
      Width); \
2512
447
    unsigned Base; \
2513
447
    switch (Width) { \
2514
0
    case 8: \
2515
0
      Base = AArch64_B0; \
2516
0
      break; \
2517
447
    case 16: \
2518
447
      Base = AArch64_H0; \
2519
447
      break; \
2520
0
    case 32: \
2521
0
      Base = AArch64_S0; \
2522
0
      break; \
2523
0
    case 64: \
2524
0
      Base = AArch64_D0; \
2525
0
      break; \
2526
0
    case 128: \
2527
0
      Base = AArch64_Q0; \
2528
0
      break; \
2529
0
    default: \
2530
0
      CS_ASSERT_RET(0 && "Unsupported width"); \
2531
447
    } \
2532
447
    unsigned Reg = \
2533
447
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2534
447
    printRegName(O, Reg - AArch64_Z0 + Base); \
2535
447
  }
printZPRasFPR_32
Line
Count
Source
2508
253
  { \
2509
253
    AArch64_add_cs_detail_1( \
2510
253
      MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2511
253
      Width); \
2512
253
    unsigned Base; \
2513
253
    switch (Width) { \
2514
0
    case 8: \
2515
0
      Base = AArch64_B0; \
2516
0
      break; \
2517
0
    case 16: \
2518
0
      Base = AArch64_H0; \
2519
0
      break; \
2520
253
    case 32: \
2521
253
      Base = AArch64_S0; \
2522
253
      break; \
2523
0
    case 64: \
2524
0
      Base = AArch64_D0; \
2525
0
      break; \
2526
0
    case 128: \
2527
0
      Base = AArch64_Q0; \
2528
0
      break; \
2529
0
    default: \
2530
0
      CS_ASSERT_RET(0 && "Unsupported width"); \
2531
253
    } \
2532
253
    unsigned Reg = \
2533
253
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2534
253
    printRegName(O, Reg - AArch64_Z0 + Base); \
2535
253
  }
printZPRasFPR_128
Line
Count
Source
2508
1
  { \
2509
1
    AArch64_add_cs_detail_1( \
2510
1
      MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2511
1
      Width); \
2512
1
    unsigned Base; \
2513
1
    switch (Width) { \
2514
0
    case 8: \
2515
0
      Base = AArch64_B0; \
2516
0
      break; \
2517
0
    case 16: \
2518
0
      Base = AArch64_H0; \
2519
0
      break; \
2520
0
    case 32: \
2521
0
      Base = AArch64_S0; \
2522
0
      break; \
2523
0
    case 64: \
2524
0
      Base = AArch64_D0; \
2525
0
      break; \
2526
1
    case 128: \
2527
1
      Base = AArch64_Q0; \
2528
1
      break; \
2529
0
    default: \
2530
0
      CS_ASSERT_RET(0 && "Unsupported width"); \
2531
1
    } \
2532
1
    unsigned Reg = \
2533
1
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2534
1
    printRegName(O, Reg - AArch64_Z0 + Base); \
2535
1
  }
2536
DEFINE_printZPRasFPR(8);
2537
DEFINE_printZPRasFPR(64);
2538
DEFINE_printZPRasFPR(16);
2539
DEFINE_printZPRasFPR(32);
2540
DEFINE_printZPRasFPR(128);
2541
2542
#define DEFINE_printExactFPImm(ImmIs0, ImmIs1) \
2543
  void CONCAT(printExactFPImm, CONCAT(ImmIs0, ImmIs1))( \
2544
    MCInst * MI, unsigned OpNum, SStream *O) \
2545
447
  { \
2546
447
    AArch64_add_cs_detail_2( \
2547
447
      MI, \
2548
447
      CONCAT(CONCAT(AArch64_OP_GROUP_ExactFPImm, ImmIs0), \
2549
447
             ImmIs1), \
2550
447
      OpNum, ImmIs0, ImmIs1); \
2551
447
    const AArch64ExactFPImm_ExactFPImm *Imm0Desc = \
2552
447
      AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs0); \
2553
447
    const AArch64ExactFPImm_ExactFPImm *Imm1Desc = \
2554
447
      AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs1); \
2555
447
    unsigned Val = \
2556
447
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2557
447
    SStream_concat(O, "%s%s%s", markup("<imm:"), "#", \
2558
447
             (Val ? Imm1Desc->Repr : Imm0Desc->Repr)); \
2559
447
    SStream_concat0(O, markup(">")); \
2560
447
  }
printExactFPImm_AArch64ExactFPImm_half_AArch64ExactFPImm_one
Line
Count
Source
2545
28
  { \
2546
28
    AArch64_add_cs_detail_2( \
2547
28
      MI, \
2548
28
      CONCAT(CONCAT(AArch64_OP_GROUP_ExactFPImm, ImmIs0), \
2549
28
             ImmIs1), \
2550
28
      OpNum, ImmIs0, ImmIs1); \
2551
28
    const AArch64ExactFPImm_ExactFPImm *Imm0Desc = \
2552
28
      AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs0); \
2553
28
    const AArch64ExactFPImm_ExactFPImm *Imm1Desc = \
2554
28
      AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs1); \
2555
28
    unsigned Val = \
2556
28
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2557
28
    SStream_concat(O, "%s%s%s", markup("<imm:"), "#", \
2558
28
             (Val ? Imm1Desc->Repr : Imm0Desc->Repr)); \
2559
28
    SStream_concat0(O, markup(">")); \
2560
28
  }
printExactFPImm_AArch64ExactFPImm_zero_AArch64ExactFPImm_one
Line
Count
Source
2545
312
  { \
2546
312
    AArch64_add_cs_detail_2( \
2547
312
      MI, \
2548
312
      CONCAT(CONCAT(AArch64_OP_GROUP_ExactFPImm, ImmIs0), \
2549
312
             ImmIs1), \
2550
312
      OpNum, ImmIs0, ImmIs1); \
2551
312
    const AArch64ExactFPImm_ExactFPImm *Imm0Desc = \
2552
312
      AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs0); \
2553
312
    const AArch64ExactFPImm_ExactFPImm *Imm1Desc = \
2554
312
      AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs1); \
2555
312
    unsigned Val = \
2556
312
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2557
312
    SStream_concat(O, "%s%s%s", markup("<imm:"), "#", \
2558
312
             (Val ? Imm1Desc->Repr : Imm0Desc->Repr)); \
2559
312
    SStream_concat0(O, markup(">")); \
2560
312
  }
printExactFPImm_AArch64ExactFPImm_half_AArch64ExactFPImm_two
Line
Count
Source
2545
107
  { \
2546
107
    AArch64_add_cs_detail_2( \
2547
107
      MI, \
2548
107
      CONCAT(CONCAT(AArch64_OP_GROUP_ExactFPImm, ImmIs0), \
2549
107
             ImmIs1), \
2550
107
      OpNum, ImmIs0, ImmIs1); \
2551
107
    const AArch64ExactFPImm_ExactFPImm *Imm0Desc = \
2552
107
      AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs0); \
2553
107
    const AArch64ExactFPImm_ExactFPImm *Imm1Desc = \
2554
107
      AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs1); \
2555
107
    unsigned Val = \
2556
107
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2557
107
    SStream_concat(O, "%s%s%s", markup("<imm:"), "#", \
2558
107
             (Val ? Imm1Desc->Repr : Imm0Desc->Repr)); \
2559
107
    SStream_concat0(O, markup(">")); \
2560
107
  }
2561
DEFINE_printExactFPImm(AArch64ExactFPImm_half, AArch64ExactFPImm_one);
2562
DEFINE_printExactFPImm(AArch64ExactFPImm_zero, AArch64ExactFPImm_one);
2563
DEFINE_printExactFPImm(AArch64ExactFPImm_half, AArch64ExactFPImm_two);
2564
2565
void printGPR64as32(MCInst *MI, unsigned OpNum, SStream *O)
2566
3.81k
{
2567
3.81k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_GPR64as32, OpNum);
2568
3.81k
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum)));
2569
3.81k
  printRegName(O, getWRegFromXReg(Reg));
2570
3.81k
}
2571
2572
void printGPR64x8(MCInst *MI, unsigned OpNum, SStream *O)
2573
18
{
2574
18
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_GPR64x8, OpNum);
2575
18
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum)));
2576
18
  printRegName(O,
2577
18
         MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_x8sub_0));
2578
18
}
2579
2580
void printSyspXzrPair(MCInst *MI, unsigned OpNum, SStream *O)
2581
967
{
2582
967
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_SyspXzrPair, OpNum);
2583
967
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum)));
2584
2585
967
  SStream_concat(O, "%s%s", getRegisterName(Reg, AArch64_NoRegAltName),
2586
967
           ", ");
2587
967
  SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));
2588
967
}
2589
2590
const char *AArch64_LLVM_getRegisterName(unsigned RegNo, unsigned AltIdx)
2591
96.6k
{
2592
96.6k
  return getRegisterName(RegNo, AltIdx);
2593
96.6k
}
2594
2595
void AArch64_LLVM_printInstruction(MCInst *MI, SStream *O,
2596
           void * /* MCRegisterInfo* */ info)
2597
158k
{
2598
158k
  printInst(MI, MI->address, "", O);
2599
158k
}