Coverage Report

Created: 2025-10-10 06:20

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
151k
#define CONCAT(a, b) CONCAT_(a, b)
49
151k
#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
247k
{
81
247k
  SStream_concat(OS, "%s%s", markup("<reg:"),
82
247k
           getRegisterName(Reg, AArch64_NoRegAltName));
83
247k
  SStream_concat0(OS, markup(">"));
84
247k
}
85
86
void printRegNameAlt(SStream *OS, unsigned Reg, unsigned AltIdx)
87
56.6k
{
88
56.6k
  SStream_concat(OS, "%s%s", markup("<reg:"),
89
56.6k
           getRegisterName(Reg, AltIdx));
90
56.6k
  SStream_concat0(OS, markup(">"));
91
56.6k
}
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
123k
{
100
123k
  bool isAlias = false;
101
123k
  bool useAliasDetails = map_use_alias_details(MI);
102
123k
  map_set_fill_detail_ops(MI, useAliasDetails);
103
104
123k
  unsigned Opcode = MCInst_getOpcode(MI);
105
106
123k
  if (Opcode == AArch64_SYSxt) {
107
1.72k
    if (printSysAlias(MI, O)) {
108
924
      isAlias = true;
109
924
      MCInst_setIsAlias(MI, isAlias);
110
924
      if (useAliasDetails)
111
924
        return;
112
924
    }
113
1.72k
  }
114
115
122k
  if (Opcode == AArch64_SYSPxt || Opcode == AArch64_SYSPxt_XZR) {
116
956
    if (printSyspAlias(MI, O)) {
117
588
      isAlias = true;
118
588
      MCInst_setIsAlias(MI, isAlias);
119
588
      if (useAliasDetails)
120
588
        return;
121
588
    }
122
956
  }
123
124
  // RPRFM overlaps PRFM (reg), so try to print it as RPRFM here.
125
122k
  if ((Opcode == AArch64_PRFMroX) || (Opcode == AArch64_PRFMroW)) {
126
189
    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
189
  }
133
134
  // SBFM/UBFM should print to a nicer aliased form if possible.
135
122k
  if (Opcode == AArch64_SBFMXri || Opcode == AArch64_SBFMWri ||
136
121k
      Opcode == AArch64_UBFMXri || Opcode == AArch64_UBFMWri) {
137
1.40k
    MCOperand *Op0 = MCInst_getOperand(MI, (0));
138
1.40k
    MCOperand *Op1 = MCInst_getOperand(MI, (1));
139
1.40k
    MCOperand *Op2 = MCInst_getOperand(MI, (2));
140
1.40k
    MCOperand *Op3 = MCInst_getOperand(MI, (3));
141
142
1.40k
    bool IsSigned = (Opcode == AArch64_SBFMXri ||
143
813
         Opcode == AArch64_SBFMWri);
144
1.40k
    bool Is64Bit = (Opcode == AArch64_SBFMXri ||
145
813
        Opcode == AArch64_UBFMXri);
146
1.40k
    if (MCOperand_isImm(Op2) && MCOperand_getImm(Op2) == 0 &&
147
1.01k
        MCOperand_isImm(Op3)) {
148
1.01k
      const char *AsmMnemonic = NULL;
149
150
1.01k
      switch (MCOperand_getImm(Op3)) {
151
250
      default:
152
250
        break;
153
293
      case 7:
154
293
        if (IsSigned)
155
110
          AsmMnemonic = "sxtb";
156
183
        else if (!Is64Bit)
157
16
          AsmMnemonic = "uxtb";
158
293
        break;
159
337
      case 15:
160
337
        if (IsSigned)
161
102
          AsmMnemonic = "sxth";
162
235
        else if (!Is64Bit)
163
28
          AsmMnemonic = "uxth";
164
337
        break;
165
134
      case 31:
166
        // *xtw is only valid for signed 64-bit operations.
167
134
        if (Is64Bit && IsSigned)
168
99
          AsmMnemonic = "sxtw";
169
134
        break;
170
1.01k
      }
171
172
1.01k
      if (AsmMnemonic) {
173
355
        SStream_concat(O, "%s", AsmMnemonic);
174
355
        SStream_concat0(O, " ");
175
176
355
        printRegName(O, MCOperand_getReg(Op0));
177
355
        SStream_concat0(O, ", ");
178
355
        printRegName(O, getWRegFromXReg(
179
355
              MCOperand_getReg(Op1)));
180
355
        if (detail_is_set(MI) && useAliasDetails) {
181
355
          AArch64_set_detail_op_reg(
182
355
            MI, 0, MCOperand_getReg(Op0));
183
355
          AArch64_set_detail_op_reg(
184
355
            MI, 1,
185
355
            getWRegFromXReg(
186
355
              MCOperand_getReg(Op1)));
187
355
          if (strings_match(AsmMnemonic, "uxtb"))
188
16
            AArch64_get_detail_op(MI, -1)
189
16
              ->ext =
190
16
              AARCH64_EXT_UXTB;
191
339
          else if (strings_match(AsmMnemonic,
192
339
                     "sxtb"))
193
110
            AArch64_get_detail_op(MI, -1)
194
110
              ->ext =
195
110
              AARCH64_EXT_SXTB;
196
229
          else if (strings_match(AsmMnemonic,
197
229
                     "uxth"))
198
28
            AArch64_get_detail_op(MI, -1)
199
28
              ->ext =
200
28
              AARCH64_EXT_UXTH;
201
201
          else if (strings_match(AsmMnemonic,
202
201
                     "sxth"))
203
102
            AArch64_get_detail_op(MI, -1)
204
102
              ->ext =
205
102
              AARCH64_EXT_SXTH;
206
99
          else if (strings_match(AsmMnemonic,
207
99
                     "sxtw"))
208
99
            AArch64_get_detail_op(MI, -1)
209
99
              ->ext =
210
99
              AARCH64_EXT_SXTW;
211
0
          else
212
0
            AArch64_get_detail_op(MI, -1)
213
0
              ->ext =
214
0
              AARCH64_EXT_INVALID;
215
355
        }
216
355
        isAlias = true;
217
355
        MCInst_setIsAlias(MI, isAlias);
218
355
        if (useAliasDetails)
219
355
          return;
220
0
        else
221
0
          goto add_real_detail;
222
355
      }
223
1.01k
    }
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
1.04k
    if (MCOperand_isImm(Op2) && MCOperand_isImm(Op3)) {
229
1.04k
      const char *AsmMnemonic = NULL;
230
1.04k
      int shift = 0;
231
1.04k
      int64_t immr = MCOperand_getImm(Op2);
232
1.04k
      int64_t imms = MCOperand_getImm(Op3);
233
1.04k
      if (Opcode == AArch64_UBFMWri && imms != 0x1F &&
234
67
          ((imms + 1) == immr)) {
235
42
        AsmMnemonic = "lsl";
236
42
        shift = 31 - imms;
237
1.00k
      } else if (Opcode == AArch64_UBFMXri && imms != 0x3f &&
238
543
           ((imms + 1 == immr))) {
239
14
        AsmMnemonic = "lsl";
240
14
        shift = 63 - imms;
241
993
      } else if (Opcode == AArch64_UBFMWri && imms == 0x1f) {
242
21
        AsmMnemonic = "lsr";
243
21
        shift = immr;
244
972
      } else if (Opcode == AArch64_UBFMXri && imms == 0x3f) {
245
16
        AsmMnemonic = "lsr";
246
16
        shift = immr;
247
956
      } else if (Opcode == AArch64_SBFMWri && imms == 0x1f) {
248
18
        AsmMnemonic = "asr";
249
18
        shift = immr;
250
938
      } else if (Opcode == AArch64_SBFMXri && imms == 0x3f) {
251
231
        AsmMnemonic = "asr";
252
231
        shift = immr;
253
231
      }
254
1.04k
      if (AsmMnemonic) {
255
342
        SStream_concat(O, "%s", AsmMnemonic);
256
342
        SStream_concat0(O, " ");
257
258
342
        printRegName(O, MCOperand_getReg(Op0));
259
342
        SStream_concat0(O, ", ");
260
342
        printRegName(O, MCOperand_getReg(Op1));
261
342
        SStream_concat(O, "%s%s#%d", ", ",
262
342
                 markup("<imm:"), shift);
263
342
        SStream_concat0(O, markup(">"));
264
342
        if (detail_is_set(MI) && useAliasDetails) {
265
342
          AArch64_set_detail_op_reg(
266
342
            MI, 0, MCOperand_getReg(Op0));
267
342
          AArch64_set_detail_op_reg(
268
342
            MI, 1, MCOperand_getReg(Op1));
269
342
          if (strings_match(AsmMnemonic, "lsl"))
270
56
            AArch64_get_detail_op(MI, -1)
271
56
              ->shift.type =
272
56
              AARCH64_SFT_LSL;
273
286
          else if (strings_match(AsmMnemonic,
274
286
                     "lsr"))
275
37
            AArch64_get_detail_op(MI, -1)
276
37
              ->shift.type =
277
37
              AARCH64_SFT_LSR;
278
249
          else if (strings_match(AsmMnemonic,
279
249
                     "asr"))
280
249
            AArch64_get_detail_op(MI, -1)
281
249
              ->shift.type =
282
249
              AARCH64_SFT_ASR;
283
0
          else
284
0
            AArch64_get_detail_op(MI, -1)
285
0
              ->shift.type =
286
0
              AARCH64_SFT_INVALID;
287
342
          AArch64_get_detail_op(MI, -1)
288
342
            ->shift.value = shift;
289
342
        }
290
342
        isAlias = true;
291
342
        MCInst_setIsAlias(MI, isAlias);
292
342
        if (useAliasDetails)
293
342
          return;
294
0
        else
295
0
          goto add_real_detail;
296
342
      }
297
1.04k
    }
298
299
    // SBFIZ/UBFIZ aliases
300
707
    if (MCOperand_getImm(Op2) > MCOperand_getImm(Op3)) {
301
265
      SStream_concat(O, "%s", (IsSigned ? "sbfiz" : "ubfiz"));
302
265
      SStream_concat0(O, " ");
303
304
265
      printRegName(O, MCOperand_getReg(Op0));
305
265
      SStream_concat0(O, ", ");
306
265
      printRegName(O, MCOperand_getReg(Op1));
307
265
      SStream_concat(O, "%s%s", ", ", markup("<imm:"));
308
265
      printUInt32Bang(O, (Is64Bit ? 64 : 32) -
309
265
               MCOperand_getImm(Op2));
310
265
      SStream_concat(O, "%s%s%s", markup(">"), ", ",
311
265
               markup("<imm:"));
312
265
      printInt64Bang(O, MCOperand_getImm(Op3) + 1);
313
265
      SStream_concat0(O, markup(">"));
314
265
      if (detail_is_set(MI) && useAliasDetails) {
315
265
        AArch64_set_detail_op_reg(
316
265
          MI, 0, MCOperand_getReg(Op0));
317
265
        AArch64_set_detail_op_reg(
318
265
          MI, 1, MCOperand_getReg(Op1));
319
265
        AArch64_set_detail_op_imm(
320
265
          MI, 2, AARCH64_OP_IMM,
321
265
          (Is64Bit ? 64 : 32) -
322
265
            MCOperand_getImm(Op2));
323
265
        AArch64_set_detail_op_imm(
324
265
          MI, 3, AARCH64_OP_IMM,
325
265
          MCOperand_getImm(Op3) + 1);
326
265
      }
327
265
      isAlias = true;
328
265
      MCInst_setIsAlias(MI, isAlias);
329
265
      if (useAliasDetails)
330
265
        return;
331
0
      else
332
0
        goto add_real_detail;
333
265
    }
334
335
    // Otherwise SBFX/UBFX is the preferred form
336
442
    SStream_concat(O, "%s", (IsSigned ? "sbfx" : "ubfx"));
337
442
    SStream_concat0(O, " ");
338
339
442
    printRegName(O, MCOperand_getReg(Op0));
340
442
    SStream_concat0(O, ", ");
341
442
    printRegName(O, MCOperand_getReg(Op1));
342
442
    SStream_concat(O, "%s%s", ", ", markup("<imm:"));
343
442
    printInt64Bang(O, MCOperand_getImm(Op2));
344
442
    SStream_concat(O, "%s%s%s", markup(">"), ", ", markup("<imm:"));
345
442
    printInt64Bang(O, MCOperand_getImm(Op3) -
346
442
            MCOperand_getImm(Op2) + 1);
347
442
    SStream_concat0(O, markup(">"));
348
442
    if (detail_is_set(MI) && useAliasDetails) {
349
442
      AArch64_set_detail_op_reg(MI, 0, MCOperand_getReg(Op0));
350
442
      AArch64_set_detail_op_reg(MI, 1, MCOperand_getReg(Op1));
351
442
      AArch64_set_detail_op_imm(MI, 2, AARCH64_OP_IMM,
352
442
              MCOperand_getImm(Op2));
353
442
      AArch64_set_detail_op_imm(
354
442
        MI, 3, AARCH64_OP_IMM,
355
442
        MCOperand_getImm(Op3) - MCOperand_getImm(Op2) +
356
442
          1);
357
442
    }
358
442
    isAlias = true;
359
442
    MCInst_setIsAlias(MI, isAlias);
360
442
    if (useAliasDetails)
361
442
      return;
362
0
    else
363
0
      goto add_real_detail;
364
442
  }
365
366
120k
  if (Opcode == AArch64_BFMXri || Opcode == AArch64_BFMWri) {
367
440
    isAlias = true;
368
440
    MCInst_setIsAlias(MI, isAlias);
369
440
    MCOperand *Op0 = MCInst_getOperand(MI, (0)); // Op1 == Op0
370
440
    MCOperand *Op2 = MCInst_getOperand(MI, (2));
371
440
    int ImmR = MCOperand_getImm(MCInst_getOperand(MI, (3)));
372
440
    int ImmS = MCOperand_getImm(MCInst_getOperand(MI, (4)));
373
374
440
    if ((MCOperand_getReg(Op2) == AArch64_WZR ||
375
391
         MCOperand_getReg(Op2) == AArch64_XZR) &&
376
143
        (ImmR == 0 || ImmS < ImmR) &&
377
107
        (AArch64_getFeatureBits(MI->csh->mode,
378
107
              AArch64_FeatureAll) ||
379
0
         AArch64_getFeatureBits(MI->csh->mode,
380
107
              AArch64_HasV8_2aOps))) {
381
      // BFC takes precedence over its entire range, sligtly differently
382
      // to BFI.
383
107
      int BitWidth = Opcode == AArch64_BFMXri ? 64 : 32;
384
107
      int LSB = (BitWidth - ImmR) % BitWidth;
385
107
      int Width = ImmS + 1;
386
387
107
      SStream_concat0(O, "bfc ");
388
107
      printRegName(O, MCOperand_getReg(Op0));
389
107
      SStream_concat(O, "%s%s#%d", ", ", markup("<imm:"),
390
107
               LSB);
391
107
      SStream_concat(O, "%s%s%s#%d", markup(">"), ", ",
392
107
               markup("<imm:"), Width);
393
107
      SStream_concat0(O, markup(">"));
394
107
      if (detail_is_set(MI) && useAliasDetails) {
395
107
        AArch64_set_detail_op_reg(
396
107
          MI, 0, MCOperand_getReg(Op0));
397
107
        AArch64_set_detail_op_imm(MI, 3, AARCH64_OP_IMM,
398
107
                LSB);
399
107
        AArch64_set_detail_op_imm(MI, 4, AARCH64_OP_IMM,
400
107
                Width);
401
107
      }
402
403
107
      if (useAliasDetails)
404
107
        return;
405
0
      else
406
0
        goto add_real_detail;
407
333
    } else if (ImmS < ImmR) {
408
      // BFI alias
409
213
      int BitWidth = Opcode == AArch64_BFMXri ? 64 : 32;
410
213
      int LSB = (BitWidth - ImmR) % BitWidth;
411
213
      int Width = ImmS + 1;
412
413
213
      SStream_concat0(O, "bfi ");
414
213
      printRegName(O, MCOperand_getReg(Op0));
415
213
      SStream_concat0(O, ", ");
416
213
      printRegName(O, MCOperand_getReg(Op2));
417
213
      SStream_concat(O, "%s%s#%d", ", ", markup("<imm:"),
418
213
               LSB);
419
213
      SStream_concat(O, "%s%s%s#%d", markup(">"), ", ",
420
213
               markup("<imm:"), Width);
421
213
      SStream_concat0(O, markup(">"));
422
213
      if (detail_is_set(MI) && useAliasDetails) {
423
213
        AArch64_set_detail_op_reg(
424
213
          MI, 0, MCOperand_getReg(Op0));
425
213
        AArch64_set_detail_op_reg(
426
213
          MI, 2, MCOperand_getReg(Op2));
427
213
        AArch64_set_detail_op_imm(MI, 3, AARCH64_OP_IMM,
428
213
                LSB);
429
213
        AArch64_set_detail_op_imm(MI, 4, AARCH64_OP_IMM,
430
213
                Width);
431
213
      }
432
213
      if (useAliasDetails)
433
213
        return;
434
0
      else
435
0
        goto add_real_detail;
436
213
    }
437
438
120
    int LSB = ImmR;
439
120
    int Width = ImmS - ImmR + 1;
440
    // Otherwise BFXIL the preferred form
441
120
    SStream_concat0(O, "bfxil ");
442
120
    printRegName(O, MCOperand_getReg(Op0));
443
120
    SStream_concat0(O, ", ");
444
120
    printRegName(O, MCOperand_getReg(Op2));
445
120
    SStream_concat(O, "%s%s#%d", ", ", markup("<imm:"), LSB);
446
120
    SStream_concat(O, "%s%s%s#%d", markup(">"), ", ",
447
120
             markup("<imm:"), Width);
448
120
    SStream_concat0(O, markup(">"));
449
120
    if (detail_is_set(MI) && useAliasDetails) {
450
120
      AArch64_set_detail_op_reg(MI, 0, MCOperand_getReg(Op0));
451
120
      AArch64_set_detail_op_reg(MI, 2, MCOperand_getReg(Op2));
452
120
      AArch64_set_detail_op_imm(MI, 3, AARCH64_OP_IMM, LSB);
453
120
      AArch64_set_detail_op_imm(MI, 4, AARCH64_OP_IMM, Width);
454
120
    }
455
120
    if (useAliasDetails)
456
120
      return;
457
120
  }
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
120k
  if ((Opcode == AArch64_MOVZXi || Opcode == AArch64_MOVZWi ||
463
120k
       Opcode == AArch64_MOVNXi || Opcode == AArch64_MOVNWi) &&
464
562
      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
120k
  if ((Opcode == AArch64_MOVKXi || Opcode == AArch64_MOVKWi) &&
473
229
      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
120k
  if ((Opcode == AArch64_MOVZXi || Opcode == AArch64_MOVZWi) &&
487
292
      MCOperand_isImm(MCInst_getOperand(MI, (1))) &&
488
292
      MCOperand_isImm(MCInst_getOperand(MI, (2)))) {
489
292
    int RegWidth = Opcode == AArch64_MOVZXi ? 64 : 32;
490
292
    int Shift = MCOperand_getImm(MCInst_getOperand(MI, (2)));
491
292
    uint64_t Value =
492
292
      (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, (1)))
493
292
      << Shift;
494
495
292
    if (AArch64_AM_isMOVZMovAlias(
496
292
          Value, Shift, Opcode == AArch64_MOVZXi ? 64 : 32)) {
497
275
      isAlias = true;
498
275
      MCInst_setIsAlias(MI, isAlias);
499
275
      SStream_concat0(O, "mov ");
500
275
      printRegName(O, MCOperand_getReg(
501
275
            MCInst_getOperand(MI, (0))));
502
275
      SStream_concat(O, "%s%s", ", ", markup("<imm:"));
503
275
      printInt64Bang(O, SignExtend64(Value, RegWidth));
504
275
      SStream_concat0(O, markup(">"));
505
275
      if (detail_is_set(MI) && useAliasDetails) {
506
275
        AArch64_set_detail_op_reg(
507
275
          MI, 0, MCInst_getOpVal(MI, 0));
508
275
        AArch64_set_detail_op_imm(
509
275
          MI, 1, AARCH64_OP_IMM,
510
275
          SignExtend64(Value, RegWidth));
511
275
      }
512
275
      if (useAliasDetails)
513
275
        return;
514
275
    }
515
292
  }
516
517
120k
  if ((Opcode == AArch64_MOVNXi || Opcode == AArch64_MOVNWi) &&
518
270
      MCOperand_isImm(MCInst_getOperand(MI, (1))) &&
519
270
      MCOperand_isImm(MCInst_getOperand(MI, (2)))) {
520
270
    int RegWidth = Opcode == AArch64_MOVNXi ? 64 : 32;
521
270
    int Shift = MCOperand_getImm(MCInst_getOperand(MI, (2)));
522
270
    uint64_t Value =
523
270
      ~((uint64_t)MCOperand_getImm(MCInst_getOperand(MI, (1)))
524
270
        << Shift);
525
270
    if (RegWidth == 32)
526
62
      Value = Value & 0xffffffff;
527
528
270
    if (AArch64_AM_isMOVNMovAlias(Value, Shift, RegWidth)) {
529
160
      isAlias = true;
530
160
      MCInst_setIsAlias(MI, isAlias);
531
160
      SStream_concat0(O, "mov ");
532
160
      printRegName(O, MCOperand_getReg(
533
160
            MCInst_getOperand(MI, (0))));
534
160
      SStream_concat(O, "%s%s", ", ", markup("<imm:"));
535
160
      printInt64Bang(O, SignExtend64(Value, RegWidth));
536
160
      SStream_concat0(O, markup(">"));
537
160
      if (detail_is_set(MI) && useAliasDetails) {
538
160
        AArch64_set_detail_op_reg(
539
160
          MI, 0, MCInst_getOpVal(MI, 0));
540
160
        AArch64_set_detail_op_imm(
541
160
          MI, 1, AARCH64_OP_IMM,
542
160
          SignExtend64(Value, RegWidth));
543
160
      }
544
160
      if (useAliasDetails)
545
160
        return;
546
160
    }
547
270
  }
548
549
119k
  if ((Opcode == AArch64_ORRXri || Opcode == AArch64_ORRWri) &&
550
1.00k
      (MCOperand_getReg(MCInst_getOperand(MI, (1))) == AArch64_XZR ||
551
433
       MCOperand_getReg(MCInst_getOperand(MI, (1))) == AArch64_WZR) &&
552
693
      MCOperand_isImm(MCInst_getOperand(MI, (2)))) {
553
693
    int RegWidth = Opcode == AArch64_ORRXri ? 64 : 32;
554
693
    uint64_t Value = AArch64_AM_decodeLogicalImmediate(
555
693
      MCOperand_getImm(MCInst_getOperand(MI, (2))), RegWidth);
556
693
    if (!AArch64_AM_isAnyMOVWMovAlias(Value, RegWidth)) {
557
395
      isAlias = true;
558
395
      MCInst_setIsAlias(MI, isAlias);
559
395
      SStream_concat0(O, "mov ");
560
395
      printRegName(O, MCOperand_getReg(
561
395
            MCInst_getOperand(MI, (0))));
562
395
      SStream_concat(O, "%s%s", ", ", markup("<imm:"));
563
395
      printInt64Bang(O, SignExtend64(Value, RegWidth));
564
395
      SStream_concat0(O, markup(">"));
565
395
      if (detail_is_set(MI) && useAliasDetails) {
566
395
        AArch64_set_detail_op_reg(
567
395
          MI, 0, MCInst_getOpVal(MI, 0));
568
395
        AArch64_set_detail_op_imm(
569
395
          MI, 2, AARCH64_OP_IMM,
570
395
          SignExtend64(Value, RegWidth));
571
395
      }
572
395
      if (useAliasDetails)
573
395
        return;
574
395
    }
575
693
  }
576
577
119k
  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
119k
  if (!isAlias)
592
119k
    isAlias |= printAliasInstr(MI, Address, O);
593
594
119k
add_real_detail:
595
119k
  MCInst_setIsAlias(MI, isAlias);
596
597
119k
  if (!isAlias || !useAliasDetails) {
598
106k
    map_set_fill_detail_ops(MI, !(isAlias && useAliasDetails));
599
106k
    if (isAlias)
600
0
      SStream_Close(O);
601
106k
    printInstruction(MI, Address, O);
602
106k
    if (isAlias)
603
0
      SStream_Open(O);
604
106k
  }
605
119k
}
606
607
bool printRangePrefetchAlias(MCInst *MI, SStream *O, const char *Annot)
608
189
{
609
189
  unsigned Opcode = MCInst_getOpcode(MI);
610
611
189
#ifndef NDEBUG
612
613
189
#endif
614
615
189
  unsigned PRFOp = MCOperand_getImm(MCInst_getOperand(MI, (0)));
616
189
  unsigned Mask = 0x18; // 0b11000
617
189
  if ((PRFOp & Mask) != Mask)
618
189
    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
189
}
655
656
bool printSysAlias(MCInst *MI, SStream *O)
657
1.72k
{
658
1.72k
  MCOperand *Op1 = MCInst_getOperand(MI, (0));
659
1.72k
  MCOperand *Cn = MCInst_getOperand(MI, (1));
660
1.72k
  MCOperand *Cm = MCInst_getOperand(MI, (2));
661
1.72k
  MCOperand *Op2 = MCInst_getOperand(MI, (3));
662
663
1.72k
  unsigned Op1Val = MCOperand_getImm(Op1);
664
1.72k
  unsigned CnVal = MCOperand_getImm(Cn);
665
1.72k
  unsigned CmVal = MCOperand_getImm(Cm);
666
1.72k
  unsigned Op2Val = MCOperand_getImm(Op2);
667
668
1.72k
  uint16_t Encoding = Op2Val;
669
1.72k
  Encoding |= CmVal << 3;
670
1.72k
  Encoding |= CnVal << 7;
671
1.72k
  Encoding |= Op1Val << 11;
672
673
1.72k
  bool NeedsReg;
674
1.72k
  const char *Ins;
675
1.72k
  const char *Name;
676
677
1.72k
  if (CnVal == 7) {
678
1.39k
    switch (CmVal) {
679
65
    default:
680
65
      return false;
681
    // Maybe IC, maybe Prediction Restriction
682
267
    case 1:
683
267
      switch (Op1Val) {
684
43
      default:
685
43
        return false;
686
208
      case 0:
687
208
        goto Search_IC;
688
16
      case 3:
689
16
        goto Search_PRCTX;
690
267
      }
691
    // Prediction Restriction aliases
692
752
    case 3: {
693
768
Search_PRCTX:
694
768
      if (Op1Val != 3 || CnVal != 7 || CmVal != 3)
695
51
        return false;
696
697
717
      unsigned int Requires =
698
717
        Op2Val == 6 ? AArch64_FeatureSPECRES2 :
699
717
                AArch64_FeaturePredRes;
700
717
      if (!(AArch64_getFeatureBits(MI->csh->mode,
701
717
                 AArch64_FeatureAll) ||
702
0
            AArch64_getFeatureBits(MI->csh->mode, Requires)))
703
0
        return false;
704
705
717
      NeedsReg = true;
706
717
      switch (Op2Val) {
707
14
      default:
708
14
        return false;
709
242
      case 4:
710
242
        Ins = "cfp ";
711
242
        break;
712
330
      case 5:
713
330
        Ins = "dvp ";
714
330
        break;
715
32
      case 6:
716
32
        Ins = "cosp ";
717
32
        break;
718
99
      case 7:
719
99
        Ins = "cpp ";
720
99
        break;
721
717
      }
722
703
      Name = "RCTX";
723
703
    } break;
724
    // IC aliases
725
37
    case 5: {
726
245
Search_IC: {
727
245
  const AArch64IC_IC *IC = AArch64IC_lookupICByEncoding(Encoding);
728
245
  if (!IC ||
729
74
      !AArch64_testFeatureList(MI->csh->mode, IC->FeaturesRequired))
730
171
    return false;
731
74
  if (detail_is_set(MI)) {
732
74
    aarch64_sysop sysop = { 0 };
733
74
    sysop.reg = IC->SysReg;
734
74
    sysop.sub_type = AARCH64_OP_IC;
735
74
    AArch64_get_detail_op(MI, 0)->type = AARCH64_OP_SYSREG;
736
74
    AArch64_get_detail_op(MI, 0)->sysop = sysop;
737
74
    AArch64_inc_op_count(MI);
738
74
  }
739
740
74
  NeedsReg = IC->NeedsReg;
741
74
  Ins = "ic ";
742
74
  Name = IC->Name;
743
74
}
744
74
    } break;
745
    // DC aliases
746
2
    case 4:
747
80
    case 6:
748
99
    case 10:
749
132
    case 11:
750
148
    case 12:
751
191
    case 13:
752
208
    case 14: {
753
208
      const AArch64DC_DC *DC =
754
208
        AArch64DC_lookupDCByEncoding(Encoding);
755
208
      if (!DC || !AArch64_testFeatureList(
756
40
             MI->csh->mode, DC->FeaturesRequired))
757
168
        return false;
758
40
      if (detail_is_set(MI)) {
759
40
        aarch64_sysop sysop = { 0 };
760
40
        sysop.alias = DC->SysAlias;
761
40
        sysop.sub_type = AARCH64_OP_DC;
762
40
        AArch64_get_detail_op(MI, 0)->type =
763
40
          AARCH64_OP_SYSALIAS;
764
40
        AArch64_get_detail_op(MI, 0)->sysop = sysop;
765
40
        AArch64_inc_op_count(MI);
766
40
      }
767
768
40
      NeedsReg = true;
769
40
      Ins = "dc ";
770
40
      Name = DC->Name;
771
40
    } break;
772
    // AT aliases
773
52
    case 8:
774
62
    case 9: {
775
62
      const AArch64AT_AT *AT =
776
62
        AArch64AT_lookupATByEncoding(Encoding);
777
62
      if (!AT || !AArch64_testFeatureList(
778
49
             MI->csh->mode, AT->FeaturesRequired))
779
13
        return false;
780
781
49
      if (detail_is_set(MI)) {
782
49
        aarch64_sysop sysop = { 0 };
783
49
        sysop.alias = AT->SysAlias;
784
49
        sysop.sub_type = AARCH64_OP_AT;
785
49
        AArch64_get_detail_op(MI, 0)->type =
786
49
          AARCH64_OP_SYSALIAS;
787
49
        AArch64_get_detail_op(MI, 0)->sysop = sysop;
788
49
        AArch64_inc_op_count(MI);
789
49
      }
790
49
      NeedsReg = true;
791
49
      Ins = "at ";
792
49
      Name = AT->Name;
793
49
    } break;
794
1.39k
    }
795
1.39k
  } else if (CnVal == 8 || CnVal == 9) {
796
    // TLBI aliases
797
124
    const AArch64TLBI_TLBI *TLBI =
798
124
      AArch64TLBI_lookupTLBIByEncoding(Encoding);
799
124
    if (!TLBI || !AArch64_testFeatureList(MI->csh->mode,
800
58
                  TLBI->FeaturesRequired))
801
66
      return false;
802
803
58
    if (detail_is_set(MI)) {
804
58
      aarch64_sysop sysop = { 0 };
805
58
      sysop.reg = TLBI->SysReg;
806
58
      sysop.sub_type = AARCH64_OP_TLBI;
807
58
      AArch64_get_detail_op(MI, 0)->type = AARCH64_OP_SYSREG;
808
58
      AArch64_get_detail_op(MI, 0)->sysop = sysop;
809
58
      AArch64_inc_op_count(MI);
810
58
    }
811
58
    NeedsReg = TLBI->NeedsReg;
812
58
    Ins = "tlbi ";
813
58
    Name = TLBI->Name;
814
58
  } else
815
206
    return false;
816
817
1.84k
#define TMP_STR_LEN 32
818
924
  char Str[TMP_STR_LEN] = { 0 };
819
924
  append_to_str_lower(Str, TMP_STR_LEN, Ins);
820
924
  append_to_str_lower(Str, TMP_STR_LEN, Name);
821
924
#undef TMP_STR_LEN
822
823
924
  SStream_concat1(O, ' ');
824
924
  SStream_concat0(O, Str);
825
924
  if (NeedsReg) {
826
799
    SStream_concat0(O, ", ");
827
799
    printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (4))));
828
799
    AArch64_set_detail_op_reg(MI, 4, MCInst_getOpVal(MI, 4));
829
799
  }
830
831
924
  return true;
832
1.72k
}
833
834
bool printSyspAlias(MCInst *MI, SStream *O)
835
956
{
836
956
  MCOperand *Op1 = MCInst_getOperand(MI, (0));
837
956
  MCOperand *Cn = MCInst_getOperand(MI, (1));
838
956
  MCOperand *Cm = MCInst_getOperand(MI, (2));
839
956
  MCOperand *Op2 = MCInst_getOperand(MI, (3));
840
841
956
  unsigned Op1Val = MCOperand_getImm(Op1);
842
956
  unsigned CnVal = MCOperand_getImm(Cn);
843
956
  unsigned CmVal = MCOperand_getImm(Cm);
844
956
  unsigned Op2Val = MCOperand_getImm(Op2);
845
846
956
  uint16_t Encoding = Op2Val;
847
956
  Encoding |= CmVal << 3;
848
956
  Encoding |= CnVal << 7;
849
956
  Encoding |= Op1Val << 11;
850
851
956
  const char *Ins;
852
956
  const char *Name;
853
854
956
  if (CnVal == 8 || CnVal == 9) {
855
    // TLBIP aliases
856
857
697
    if (CnVal == 9) {
858
352
      if (!AArch64_getFeatureBits(MI->csh->mode,
859
352
                AArch64_FeatureAll) ||
860
352
          !AArch64_getFeatureBits(MI->csh->mode,
861
352
                AArch64_FeatureXS))
862
0
        return false;
863
352
      Encoding &= ~(1 << 7);
864
352
    }
865
866
697
    const AArch64TLBI_TLBI *TLBI =
867
697
      AArch64TLBI_lookupTLBIByEncoding(Encoding);
868
697
    if (!TLBI || !AArch64_testFeatureList(MI->csh->mode,
869
588
                  TLBI->FeaturesRequired))
870
109
      return false;
871
872
588
    if (detail_is_set(MI)) {
873
588
      aarch64_sysop sysop = { 0 };
874
588
      sysop.reg = TLBI->SysReg;
875
588
      sysop.sub_type = AARCH64_OP_TLBI;
876
588
      AArch64_get_detail_op(MI, 0)->type = AARCH64_OP_SYSREG;
877
588
      AArch64_get_detail_op(MI, 0)->sysop = sysop;
878
588
      AArch64_inc_op_count(MI);
879
588
    }
880
588
    Ins = "tlbip ";
881
588
    Name = TLBI->Name;
882
588
  } else
883
259
    return false;
884
885
1.51k
#define TMP_STR_LEN 32
886
588
  char Str[TMP_STR_LEN] = { 0 };
887
588
  append_to_str_lower(Str, TMP_STR_LEN, Ins);
888
588
  append_to_str_lower(Str, TMP_STR_LEN, Name);
889
890
588
  if (CnVal == 9) {
891
343
    append_to_str_lower(Str, TMP_STR_LEN, "nxs");
892
343
  }
893
588
#undef TMP_STR_LEN
894
895
588
  SStream_concat1(O, ' ');
896
588
  SStream_concat0(O, Str);
897
588
  SStream_concat0(O, ", ");
898
588
  if (MCOperand_getReg(MCInst_getOperand(MI, (4))) == AArch64_XZR)
899
230
    printSyspXzrPair(MI, 4, O);
900
358
  else
901
358
    CONCAT(printGPRSeqPairsClassOperand, 64)(MI, 4, O);
902
903
588
  return true;
904
956
}
905
906
#define DEFINE_printMatrix(EltSize) \
907
  void CONCAT(printMatrix, EltSize)(MCInst * MI, unsigned OpNum, \
908
            SStream *O) \
909
2.58k
  { \
910
2.58k
    AArch64_add_cs_detail_1( \
911
2.58k
      MI, CONCAT(AArch64_OP_GROUP_Matrix, EltSize), OpNum, \
912
2.58k
      EltSize); \
913
2.58k
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
914
2.58k
\
915
2.58k
    printRegName(O, MCOperand_getReg(RegOp)); \
916
2.58k
    switch (EltSize) { \
917
16
    case 0: \
918
16
      break; \
919
0
    case 8: \
920
0
      SStream_concat0(O, ".b"); \
921
0
      break; \
922
418
    case 16: \
923
418
      SStream_concat0(O, ".h"); \
924
418
      break; \
925
1.64k
    case 32: \
926
1.64k
      SStream_concat0(O, ".s"); \
927
1.64k
      break; \
928
512
    case 64: \
929
512
      SStream_concat0(O, ".d"); \
930
512
      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.58k
    } \
937
2.58k
  }
printMatrix_64
Line
Count
Source
909
512
  { \
910
512
    AArch64_add_cs_detail_1( \
911
512
      MI, CONCAT(AArch64_OP_GROUP_Matrix, EltSize), OpNum, \
912
512
      EltSize); \
913
512
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
914
512
\
915
512
    printRegName(O, MCOperand_getReg(RegOp)); \
916
512
    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
512
    case 64: \
929
512
      SStream_concat0(O, ".d"); \
930
512
      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
512
    } \
937
512
  }
printMatrix_32
Line
Count
Source
909
1.64k
  { \
910
1.64k
    AArch64_add_cs_detail_1( \
911
1.64k
      MI, CONCAT(AArch64_OP_GROUP_Matrix, EltSize), OpNum, \
912
1.64k
      EltSize); \
913
1.64k
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
914
1.64k
\
915
1.64k
    printRegName(O, MCOperand_getReg(RegOp)); \
916
1.64k
    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
1.64k
    case 32: \
926
1.64k
      SStream_concat0(O, ".s"); \
927
1.64k
      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
1.64k
    } \
937
1.64k
  }
printMatrix_16
Line
Count
Source
909
418
  { \
910
418
    AArch64_add_cs_detail_1( \
911
418
      MI, CONCAT(AArch64_OP_GROUP_Matrix, EltSize), OpNum, \
912
418
      EltSize); \
913
418
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
914
418
\
915
418
    printRegName(O, MCOperand_getReg(RegOp)); \
916
418
    switch (EltSize) { \
917
0
    case 0: \
918
0
      break; \
919
0
    case 8: \
920
0
      SStream_concat0(O, ".b"); \
921
0
      break; \
922
418
    case 16: \
923
418
      SStream_concat0(O, ".h"); \
924
418
      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
418
    } \
937
418
  }
printMatrix_0
Line
Count
Source
909
16
  { \
910
16
    AArch64_add_cs_detail_1( \
911
16
      MI, CONCAT(AArch64_OP_GROUP_Matrix, EltSize), OpNum, \
912
16
      EltSize); \
913
16
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
914
16
\
915
16
    printRegName(O, MCOperand_getReg(RegOp)); \
916
16
    switch (EltSize) { \
917
16
    case 0: \
918
16
      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
16
    } \
937
16
  }
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.63k
  { \
947
3.63k
    AArch64_add_cs_detail_1( \
948
3.63k
      MI, \
949
3.63k
      CONCAT(AArch64_OP_GROUP_MatrixTileVector, IsVertical), \
950
3.63k
      OpNum, IsVertical); \
951
3.63k
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
952
3.63k
\
953
3.63k
    const char *RegName = getRegisterName(MCOperand_getReg(RegOp), \
954
3.63k
                  AArch64_NoRegAltName); \
955
3.63k
\
956
3.63k
    unsigned buf_len = strlen(RegName) + 1; \
957
3.63k
    char *Base = cs_mem_calloc(1, buf_len); \
958
3.63k
    memcpy(Base, RegName, buf_len); \
959
3.63k
    char *Dot = strchr(Base, '.'); \
960
3.63k
    if (!Dot) { \
961
0
      SStream_concat0(O, RegName); \
962
0
      return; \
963
0
    } \
964
3.63k
    *Dot = '\0'; /* Split string */ \
965
3.63k
    char *Suffix = Dot + 1; \
966
3.63k
    SStream_concat(O, "%s%s", Base, (IsVertical ? "v" : "h")); \
967
3.63k
    SStream_concat1(O, '.'); \
968
3.63k
    SStream_concat0(O, Suffix); \
969
3.63k
    cs_mem_free(Base); \
970
3.63k
  }
printMatrixTileVector_0
Line
Count
Source
946
2.43k
  { \
947
2.43k
    AArch64_add_cs_detail_1( \
948
2.43k
      MI, \
949
2.43k
      CONCAT(AArch64_OP_GROUP_MatrixTileVector, IsVertical), \
950
2.43k
      OpNum, IsVertical); \
951
2.43k
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
952
2.43k
\
953
2.43k
    const char *RegName = getRegisterName(MCOperand_getReg(RegOp), \
954
2.43k
                  AArch64_NoRegAltName); \
955
2.43k
\
956
2.43k
    unsigned buf_len = strlen(RegName) + 1; \
957
2.43k
    char *Base = cs_mem_calloc(1, buf_len); \
958
2.43k
    memcpy(Base, RegName, buf_len); \
959
2.43k
    char *Dot = strchr(Base, '.'); \
960
2.43k
    if (!Dot) { \
961
0
      SStream_concat0(O, RegName); \
962
0
      return; \
963
0
    } \
964
2.43k
    *Dot = '\0'; /* Split string */ \
965
2.43k
    char *Suffix = Dot + 1; \
966
2.43k
    SStream_concat(O, "%s%s", Base, (IsVertical ? "v" : "h")); \
967
2.43k
    SStream_concat1(O, '.'); \
968
2.43k
    SStream_concat0(O, Suffix); \
969
2.43k
    cs_mem_free(Base); \
970
2.43k
  }
printMatrixTileVector_1
Line
Count
Source
946
1.19k
  { \
947
1.19k
    AArch64_add_cs_detail_1( \
948
1.19k
      MI, \
949
1.19k
      CONCAT(AArch64_OP_GROUP_MatrixTileVector, IsVertical), \
950
1.19k
      OpNum, IsVertical); \
951
1.19k
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
952
1.19k
\
953
1.19k
    const char *RegName = getRegisterName(MCOperand_getReg(RegOp), \
954
1.19k
                  AArch64_NoRegAltName); \
955
1.19k
\
956
1.19k
    unsigned buf_len = strlen(RegName) + 1; \
957
1.19k
    char *Base = cs_mem_calloc(1, buf_len); \
958
1.19k
    memcpy(Base, RegName, buf_len); \
959
1.19k
    char *Dot = strchr(Base, '.'); \
960
1.19k
    if (!Dot) { \
961
0
      SStream_concat0(O, RegName); \
962
0
      return; \
963
0
    } \
964
1.19k
    *Dot = '\0'; /* Split string */ \
965
1.19k
    char *Suffix = Dot + 1; \
966
1.19k
    SStream_concat(O, "%s%s", Base, (IsVertical ? "v" : "h")); \
967
1.19k
    SStream_concat1(O, '.'); \
968
1.19k
    SStream_concat0(O, Suffix); \
969
1.19k
    cs_mem_free(Base); \
970
1.19k
  }
971
DEFINE_printMatrixTileVector(0);
972
DEFINE_printMatrixTileVector(1);
973
974
void printMatrixTile(MCInst *MI, unsigned OpNum, SStream *O)
975
1.24k
{
976
1.24k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_MatrixTile, OpNum);
977
1.24k
  MCOperand *RegOp = MCInst_getOperand(MI, (OpNum));
978
979
1.24k
  printRegName(O, MCOperand_getReg(RegOp));
980
1.24k
}
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
155k
{
995
155k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_Operand, OpNo);
996
155k
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
997
155k
  if (MCOperand_isReg(Op)) {
998
131k
    unsigned Reg = MCOperand_getReg(Op);
999
131k
    printRegName(O, Reg);
1000
131k
  } else if (MCOperand_isImm(Op)) {
1001
23.9k
    Op = MCInst_getOperand(MI, (OpNo));
1002
23.9k
    SStream_concat(O, "%s", markup("<imm:"));
1003
23.9k
    printInt64Bang(O, MCOperand_getImm(Op));
1004
23.9k
    SStream_concat0(O, markup(">"));
1005
23.9k
  } else {
1006
0
    printUInt64Bang(O, MCInst_getOpVal(MI, OpNo));
1007
0
  }
1008
155k
}
1009
1010
void printImm(MCInst *MI, unsigned OpNo, SStream *O)
1011
1.73k
{
1012
1.73k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_Imm, OpNo);
1013
1.73k
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1014
1.73k
  SStream_concat(O, "%s", markup("<imm:"));
1015
1.73k
  printInt64Bang(O, MCOperand_getImm(Op));
1016
1.73k
  SStream_concat0(O, markup(">"));
1017
1.73k
}
1018
1019
void printImmHex(MCInst *MI, unsigned OpNo, SStream *O)
1020
52
{
1021
52
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_ImmHex, OpNo);
1022
52
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1023
52
  SStream_concat(O, "%s", markup("<imm:"));
1024
52
  printInt64Bang(O, MCOperand_getImm(Op));
1025
52
  SStream_concat0(O, markup(">"));
1026
52
}
1027
1028
#define DEFINE_printSImm(Size) \
1029
  void CONCAT(printSImm, Size)(MCInst * MI, unsigned OpNo, SStream *O) \
1030
146
  { \
1031
146
    AArch64_add_cs_detail_1( \
1032
146
      MI, CONCAT(AArch64_OP_GROUP_SImm, Size), OpNo, Size); \
1033
146
    MCOperand *Op = MCInst_getOperand(MI, (OpNo)); \
1034
146
    if (Size == 8) { \
1035
77
      SStream_concat(O, "%s", markup("<imm:")); \
1036
77
      printInt32Bang(O, MCOperand_getImm(Op)); \
1037
77
      SStream_concat0(O, markup(">")); \
1038
77
    } else if (Size == 16) { \
1039
69
      SStream_concat(O, "%s", markup("<imm:")); \
1040
69
      printInt32Bang(O, MCOperand_getImm(Op)); \
1041
69
      SStream_concat0(O, markup(">")); \
1042
69
    } 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
146
  }
printSImm_16
Line
Count
Source
1030
69
  { \
1031
69
    AArch64_add_cs_detail_1( \
1032
69
      MI, CONCAT(AArch64_OP_GROUP_SImm, Size), OpNo, Size); \
1033
69
    MCOperand *Op = MCInst_getOperand(MI, (OpNo)); \
1034
69
    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
69
    } else if (Size == 16) { \
1039
69
      SStream_concat(O, "%s", markup("<imm:")); \
1040
69
      printInt32Bang(O, MCOperand_getImm(Op)); \
1041
69
      SStream_concat0(O, markup(">")); \
1042
69
    } 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
69
  }
printSImm_8
Line
Count
Source
1030
77
  { \
1031
77
    AArch64_add_cs_detail_1( \
1032
77
      MI, CONCAT(AArch64_OP_GROUP_SImm, Size), OpNo, Size); \
1033
77
    MCOperand *Op = MCInst_getOperand(MI, (OpNo)); \
1034
77
    if (Size == 8) { \
1035
77
      SStream_concat(O, "%s", markup("<imm:")); \
1036
77
      printInt32Bang(O, MCOperand_getImm(Op)); \
1037
77
      SStream_concat0(O, markup(">")); \
1038
77
    } 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
77
  }
1048
DEFINE_printSImm(16);
1049
DEFINE_printSImm(8);
1050
1051
void printPostIncOperand(MCInst *MI, unsigned OpNo, unsigned Imm, SStream *O)
1052
3.31k
{
1053
3.31k
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1054
3.31k
  if (MCOperand_isReg(Op)) {
1055
3.31k
    unsigned Reg = MCOperand_getReg(Op);
1056
3.31k
    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
3.31k
      printRegName(O, Reg);
1062
3.31k
  } else
1063
0
    CS_ASSERT_RET(0 &&
1064
0
            "unknown operand kind in printPostIncOperand64");
1065
3.31k
}
1066
1067
void printVRegOperand(MCInst *MI, unsigned OpNo, SStream *O)
1068
33.4k
{
1069
33.4k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_VRegOperand, OpNo);
1070
33.4k
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1071
1072
33.4k
  unsigned Reg = MCOperand_getReg(Op);
1073
33.4k
  printRegNameAlt(O, Reg, AArch64_vreg);
1074
33.4k
}
1075
1076
void printSysCROperand(MCInst *MI, unsigned OpNo, SStream *O)
1077
2.49k
{
1078
2.49k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_SysCROperand, OpNo);
1079
2.49k
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1080
1081
2.49k
  SStream_concat(O, "%s", "c");
1082
2.49k
  printUInt32(O, MCOperand_getImm(Op));
1083
2.49k
  SStream_concat1(O, '\0');
1084
2.49k
}
1085
1086
void printAddSubImm(MCInst *MI, unsigned OpNum, SStream *O)
1087
873
{
1088
873
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_AddSubImm, OpNum);
1089
873
  MCOperand *MO = MCInst_getOperand(MI, (OpNum));
1090
873
  if (MCOperand_isImm(MO)) {
1091
873
    unsigned Val = (MCOperand_getImm(MO) & 0xfff);
1092
1093
873
    unsigned Shift = AArch64_AM_getShiftValue(
1094
873
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))));
1095
873
    SStream_concat(O, "%s", markup("<imm:"));
1096
873
    printUInt32Bang(O, (Val));
1097
873
    SStream_concat0(O, markup(">"));
1098
873
    if (Shift != 0) {
1099
505
      printShifter(MI, OpNum + 1, O);
1100
505
    }
1101
873
  } else {
1102
0
    printShifter(MI, OpNum + 1, O);
1103
0
  }
1104
873
}
1105
1106
#define DEFINE_printLogicalImm(T) \
1107
  void CONCAT(printLogicalImm, T)(MCInst * MI, unsigned OpNum, \
1108
          SStream *O) \
1109
2.41k
  { \
1110
2.41k
    AArch64_add_cs_detail_1( \
1111
2.41k
      MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, \
1112
2.41k
      sizeof(T)); \
1113
2.41k
    uint64_t Val = \
1114
2.41k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1115
2.41k
    SStream_concat(O, "%s", markup("<imm:")); \
1116
2.41k
    printUInt64Bang(O, (AArch64_AM_decodeLogicalImmediate( \
1117
2.41k
             Val, 8 * sizeof(T)))); \
1118
2.41k
    SStream_concat0(O, markup(">")); \
1119
2.41k
  }
printLogicalImm_int64_t
Line
Count
Source
1109
1.23k
  { \
1110
1.23k
    AArch64_add_cs_detail_1( \
1111
1.23k
      MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, \
1112
1.23k
      sizeof(T)); \
1113
1.23k
    uint64_t Val = \
1114
1.23k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1115
1.23k
    SStream_concat(O, "%s", markup("<imm:")); \
1116
1.23k
    printUInt64Bang(O, (AArch64_AM_decodeLogicalImmediate( \
1117
1.23k
             Val, 8 * sizeof(T)))); \
1118
1.23k
    SStream_concat0(O, markup(">")); \
1119
1.23k
  }
printLogicalImm_int32_t
Line
Count
Source
1109
654
  { \
1110
654
    AArch64_add_cs_detail_1( \
1111
654
      MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, \
1112
654
      sizeof(T)); \
1113
654
    uint64_t Val = \
1114
654
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1115
654
    SStream_concat(O, "%s", markup("<imm:")); \
1116
654
    printUInt64Bang(O, (AArch64_AM_decodeLogicalImmediate( \
1117
654
             Val, 8 * sizeof(T)))); \
1118
654
    SStream_concat0(O, markup(">")); \
1119
654
  }
printLogicalImm_int8_t
Line
Count
Source
1109
433
  { \
1110
433
    AArch64_add_cs_detail_1( \
1111
433
      MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, \
1112
433
      sizeof(T)); \
1113
433
    uint64_t Val = \
1114
433
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1115
433
    SStream_concat(O, "%s", markup("<imm:")); \
1116
433
    printUInt64Bang(O, (AArch64_AM_decodeLogicalImmediate( \
1117
433
             Val, 8 * sizeof(T)))); \
1118
433
    SStream_concat0(O, markup(">")); \
1119
433
  }
printLogicalImm_int16_t
Line
Count
Source
1109
98
  { \
1110
98
    AArch64_add_cs_detail_1( \
1111
98
      MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, \
1112
98
      sizeof(T)); \
1113
98
    uint64_t Val = \
1114
98
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1115
98
    SStream_concat(O, "%s", markup("<imm:")); \
1116
98
    printUInt64Bang(O, (AArch64_AM_decodeLogicalImmediate( \
1117
98
             Val, 8 * sizeof(T)))); \
1118
98
    SStream_concat0(O, markup(">")); \
1119
98
  }
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
3.69k
{
1127
3.69k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_Shifter, OpNum);
1128
3.69k
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1129
  // LSL #0 should not be printed.
1130
3.69k
  if (AArch64_AM_getShiftType(Val) == AArch64_AM_LSL &&
1131
2.24k
      AArch64_AM_getShiftValue(Val) == 0)
1132
269
    return;
1133
3.42k
  SStream_concat(
1134
3.42k
    O, "%s%s%s%s#%d", ", ",
1135
3.42k
    AArch64_AM_getShiftExtendName(AArch64_AM_getShiftType(Val)),
1136
3.42k
    " ", markup("<imm:"), AArch64_AM_getShiftValue(Val));
1137
3.42k
  SStream_concat0(O, markup(">"));
1138
3.42k
}
1139
1140
void printShiftedRegister(MCInst *MI, unsigned OpNum, SStream *O)
1141
1.41k
{
1142
1.41k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_ShiftedRegister, OpNum);
1143
1.41k
  printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))));
1144
1.41k
  printShifter(MI, OpNum + 1, O);
1145
1.41k
}
1146
1147
void printExtendedRegister(MCInst *MI, unsigned OpNum, SStream *O)
1148
1.08k
{
1149
1.08k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_ExtendedRegister, OpNum);
1150
1.08k
  printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))));
1151
1.08k
  printArithExtend(MI, OpNum + 1, O);
1152
1.08k
}
1153
1154
void printArithExtend(MCInst *MI, unsigned OpNum, SStream *O)
1155
2.51k
{
1156
2.51k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_ArithExtend, OpNum);
1157
2.51k
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1158
2.51k
  AArch64_AM_ShiftExtendType ExtType = AArch64_AM_getArithExtendType(Val);
1159
2.51k
  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
2.51k
  if (ExtType == AArch64_AM_UXTW || ExtType == AArch64_AM_UXTX) {
1165
803
    unsigned Dest = MCOperand_getReg(MCInst_getOperand(MI, (0)));
1166
803
    unsigned Src1 = MCOperand_getReg(MCInst_getOperand(MI, (1)));
1167
803
    if (((Dest == AArch64_SP || Src1 == AArch64_SP) &&
1168
9
         ExtType == AArch64_AM_UXTX) ||
1169
801
        ((Dest == AArch64_WSP || Src1 == AArch64_WSP) &&
1170
341
         ExtType == AArch64_AM_UXTW)) {
1171
173
      if (ShiftVal != 0) {
1172
173
        SStream_concat(O, "%s%s", ", lsl ",
1173
173
                 markup("<imm:"));
1174
173
        printUInt32Bang(O, ShiftVal);
1175
173
        SStream_concat0(O, markup(">"));
1176
173
      }
1177
173
      return;
1178
173
    }
1179
803
  }
1180
2.34k
  SStream_concat(O, "%s", ", ");
1181
2.34k
  SStream_concat0(O, AArch64_AM_getShiftExtendName(ExtType));
1182
2.34k
  if (ShiftVal != 0) {
1183
1.81k
    SStream_concat(O, "%s%s#%d", " ", markup("<imm:"), ShiftVal);
1184
1.81k
    SStream_concat0(O, markup(">"));
1185
1.81k
  }
1186
2.34k
}
1187
1188
static void printMemExtendImpl(bool SignExtend, bool DoShift, unsigned Width,
1189
             char SrcRegKind, SStream *O, bool getUseMarkup)
1190
6.86k
{
1191
  // sxtw, sxtx, uxtw or lsl (== uxtx)
1192
6.86k
  bool IsLSL = !SignExtend && SrcRegKind == 'x';
1193
6.86k
  if (IsLSL)
1194
3.51k
    SStream_concat0(O, "lsl");
1195
3.35k
  else {
1196
3.35k
    SStream_concat(O, "%c%s", (SignExtend ? 's' : 'u'), "xt");
1197
3.35k
    SStream_concat1(O, SrcRegKind);
1198
3.35k
  }
1199
1200
6.86k
  if (DoShift || IsLSL) {
1201
5.17k
    SStream_concat0(O, " ");
1202
5.17k
    if (getUseMarkup)
1203
0
      SStream_concat0(O, "<imm:");
1204
5.17k
    unsigned ShiftAmount = DoShift ? Log2_32(Width / 8) : 0;
1205
5.17k
    SStream_concat(O, "%s%d", "#", ShiftAmount);
1206
5.17k
    if (getUseMarkup)
1207
0
      SStream_concat0(O, ">");
1208
5.17k
  }
1209
6.86k
}
1210
1211
void printMemExtend(MCInst *MI, unsigned OpNum, SStream *O, char SrcRegKind,
1212
        unsigned Width)
1213
1.08k
{
1214
1.08k
  bool SignExtend = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1215
1.08k
  bool DoShift = MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1)));
1216
1.08k
  printMemExtendImpl(SignExtend, DoShift, Width, SrcRegKind, O,
1217
1.08k
         getUseMarkup());
1218
1.08k
}
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
7.09k
  { \
1227
7.09k
    AArch64_add_cs_detail_4( \
1228
7.09k
      MI, \
1229
7.09k
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1230
7.09k
                SignExtend), \
1231
7.09k
               ExtWidth), \
1232
7.09k
              SrcRegKind), \
1233
7.09k
             Suffix), \
1234
7.09k
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), \
1235
7.09k
      CHAR(Suffix)); \
1236
7.09k
    printOperand(MI, OpNum, O); \
1237
7.09k
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1238
4.06k
      SStream_concat1(O, '.'); \
1239
4.06k
      SStream_concat1(O, CHAR(Suffix)); \
1240
4.06k
      SStream_concat1(O, '\0'); \
1241
4.06k
    } else \
1242
7.09k
      CS_ASSERT_RET((CHAR(Suffix) == '0') && \
1243
7.09k
              "Unsupported suffix size"); \
1244
7.09k
    bool DoShift = ExtWidth != 8; \
1245
7.09k
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1246
5.77k
      SStream_concat0(O, ", "); \
1247
5.77k
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, \
1248
5.77k
             CHAR(SrcRegKind), O, \
1249
5.77k
             getUseMarkup()); \
1250
5.77k
    } \
1251
7.09k
  }
1252
243
DEFINE_printRegWithShiftExtend(false, 8, x, d);
1253
276
DEFINE_printRegWithShiftExtend(true, 8, w, d);
1254
808
DEFINE_printRegWithShiftExtend(false, 8, w, d);
1255
1.02k
DEFINE_printRegWithShiftExtend(false, 8, x, 0);
1256
53
DEFINE_printRegWithShiftExtend(true, 8, w, s);
1257
289
DEFINE_printRegWithShiftExtend(false, 8, w, s);
1258
292
DEFINE_printRegWithShiftExtend(false, 64, x, d);
1259
70
DEFINE_printRegWithShiftExtend(true, 64, w, d);
1260
123
DEFINE_printRegWithShiftExtend(false, 64, w, d);
1261
454
DEFINE_printRegWithShiftExtend(false, 64, x, 0);
1262
16
DEFINE_printRegWithShiftExtend(true, 64, w, s);
1263
38
DEFINE_printRegWithShiftExtend(false, 64, w, s);
1264
226
DEFINE_printRegWithShiftExtend(false, 16, x, d);
1265
242
DEFINE_printRegWithShiftExtend(true, 16, w, d);
1266
157
DEFINE_printRegWithShiftExtend(false, 16, w, d);
1267
590
DEFINE_printRegWithShiftExtend(false, 16, x, 0);
1268
46
DEFINE_printRegWithShiftExtend(true, 16, w, s);
1269
172
DEFINE_printRegWithShiftExtend(false, 16, w, s);
1270
379
DEFINE_printRegWithShiftExtend(false, 32, x, d);
1271
175
DEFINE_printRegWithShiftExtend(true, 32, w, d);
1272
162
DEFINE_printRegWithShiftExtend(false, 32, w, d);
1273
493
DEFINE_printRegWithShiftExtend(false, 32, x, 0);
1274
40
DEFINE_printRegWithShiftExtend(true, 32, w, s);
1275
16
DEFINE_printRegWithShiftExtend(false, 32, w, s);
1276
44
DEFINE_printRegWithShiftExtend(false, 8, x, s);
1277
41
DEFINE_printRegWithShiftExtend(false, 16, x, s);
1278
157
DEFINE_printRegWithShiftExtend(false, 32, x, s);
1279
4
DEFINE_printRegWithShiftExtend(false, 64, x, s);
1280
458
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
3.90k
  { \
1286
3.90k
    AArch64_add_cs_detail_1( \
1287
3.90k
      MI, \
1288
3.90k
      CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1289
3.90k
      OpNum, EltSize); \
1290
3.90k
    unsigned Reg = \
1291
3.90k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1292
3.90k
    if (Reg < AArch64_PN0 || Reg > AArch64_PN15) \
1293
3.90k
      CS_ASSERT_RET( \
1294
3.90k
        0 && \
1295
3.90k
        "Unsupported predicate-as-counter register"); \
1296
3.90k
    SStream_concat(O, "%s", "pn"); \
1297
3.90k
    printUInt32(O, (Reg - AArch64_PN0)); \
1298
3.90k
    switch (EltSize) { \
1299
3.51k
    case 0: \
1300
3.51k
      break; \
1301
110
    case 8: \
1302
110
      SStream_concat0(O, ".b"); \
1303
110
      break; \
1304
110
    case 16: \
1305
110
      SStream_concat0(O, ".h"); \
1306
110
      break; \
1307
44
    case 32: \
1308
44
      SStream_concat0(O, ".s"); \
1309
44
      break; \
1310
124
    case 64: \
1311
124
      SStream_concat0(O, ".d"); \
1312
124
      break; \
1313
0
    default: \
1314
0
      CS_ASSERT_RET(0 && "Unsupported element size"); \
1315
3.90k
    } \
1316
3.90k
  }
printPredicateAsCounter_8
Line
Count
Source
1285
110
  { \
1286
110
    AArch64_add_cs_detail_1( \
1287
110
      MI, \
1288
110
      CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1289
110
      OpNum, EltSize); \
1290
110
    unsigned Reg = \
1291
110
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1292
110
    if (Reg < AArch64_PN0 || Reg > AArch64_PN15) \
1293
110
      CS_ASSERT_RET( \
1294
110
        0 && \
1295
110
        "Unsupported predicate-as-counter register"); \
1296
110
    SStream_concat(O, "%s", "pn"); \
1297
110
    printUInt32(O, (Reg - AArch64_PN0)); \
1298
110
    switch (EltSize) { \
1299
0
    case 0: \
1300
0
      break; \
1301
110
    case 8: \
1302
110
      SStream_concat0(O, ".b"); \
1303
110
      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
110
    } \
1316
110
  }
printPredicateAsCounter_64
Line
Count
Source
1285
124
  { \
1286
124
    AArch64_add_cs_detail_1( \
1287
124
      MI, \
1288
124
      CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1289
124
      OpNum, EltSize); \
1290
124
    unsigned Reg = \
1291
124
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1292
124
    if (Reg < AArch64_PN0 || Reg > AArch64_PN15) \
1293
124
      CS_ASSERT_RET( \
1294
124
        0 && \
1295
124
        "Unsupported predicate-as-counter register"); \
1296
124
    SStream_concat(O, "%s", "pn"); \
1297
124
    printUInt32(O, (Reg - AArch64_PN0)); \
1298
124
    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
124
    case 64: \
1311
124
      SStream_concat0(O, ".d"); \
1312
124
      break; \
1313
0
    default: \
1314
0
      CS_ASSERT_RET(0 && "Unsupported element size"); \
1315
124
    } \
1316
124
  }
printPredicateAsCounter_16
Line
Count
Source
1285
110
  { \
1286
110
    AArch64_add_cs_detail_1( \
1287
110
      MI, \
1288
110
      CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1289
110
      OpNum, EltSize); \
1290
110
    unsigned Reg = \
1291
110
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1292
110
    if (Reg < AArch64_PN0 || Reg > AArch64_PN15) \
1293
110
      CS_ASSERT_RET( \
1294
110
        0 && \
1295
110
        "Unsupported predicate-as-counter register"); \
1296
110
    SStream_concat(O, "%s", "pn"); \
1297
110
    printUInt32(O, (Reg - AArch64_PN0)); \
1298
110
    switch (EltSize) { \
1299
0
    case 0: \
1300
0
      break; \
1301
0
    case 8: \
1302
0
      SStream_concat0(O, ".b"); \
1303
0
      break; \
1304
110
    case 16: \
1305
110
      SStream_concat0(O, ".h"); \
1306
110
      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
110
    } \
1316
110
  }
printPredicateAsCounter_32
Line
Count
Source
1285
44
  { \
1286
44
    AArch64_add_cs_detail_1( \
1287
44
      MI, \
1288
44
      CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1289
44
      OpNum, EltSize); \
1290
44
    unsigned Reg = \
1291
44
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1292
44
    if (Reg < AArch64_PN0 || Reg > AArch64_PN15) \
1293
44
      CS_ASSERT_RET( \
1294
44
        0 && \
1295
44
        "Unsupported predicate-as-counter register"); \
1296
44
    SStream_concat(O, "%s", "pn"); \
1297
44
    printUInt32(O, (Reg - AArch64_PN0)); \
1298
44
    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
44
    case 32: \
1308
44
      SStream_concat0(O, ".s"); \
1309
44
      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
44
    } \
1316
44
  }
printPredicateAsCounter_0
Line
Count
Source
1285
3.51k
  { \
1286
3.51k
    AArch64_add_cs_detail_1( \
1287
3.51k
      MI, \
1288
3.51k
      CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1289
3.51k
      OpNum, EltSize); \
1290
3.51k
    unsigned Reg = \
1291
3.51k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1292
3.51k
    if (Reg < AArch64_PN0 || Reg > AArch64_PN15) \
1293
3.51k
      CS_ASSERT_RET( \
1294
3.51k
        0 && \
1295
3.51k
        "Unsupported predicate-as-counter register"); \
1296
3.51k
    SStream_concat(O, "%s", "pn"); \
1297
3.51k
    printUInt32(O, (Reg - AArch64_PN0)); \
1298
3.51k
    switch (EltSize) { \
1299
3.51k
    case 0: \
1300
3.51k
      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.51k
    } \
1316
3.51k
  }
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
655
{
1325
655
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_CondCode, OpNum);
1326
655
  AArch64CC_CondCode CC = (AArch64CC_CondCode)MCOperand_getImm(
1327
655
    MCInst_getOperand(MI, (OpNum)));
1328
655
  SStream_concat0(O, AArch64CC_getCondCodeName(CC));
1329
655
}
1330
1331
void printInverseCondCode(MCInst *MI, unsigned OpNum, SStream *O)
1332
24
{
1333
24
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_InverseCondCode, OpNum);
1334
24
  AArch64CC_CondCode CC = (AArch64CC_CondCode)MCOperand_getImm(
1335
24
    MCInst_getOperand(MI, (OpNum)));
1336
24
  SStream_concat0(O, AArch64CC_getCondCodeName(
1337
24
           AArch64CC_getInvertedCondCode(CC)));
1338
24
}
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
8.23k
  { \
1353
8.23k
    AArch64_add_cs_detail_1( \
1354
8.23k
      MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1355
8.23k
      Scale); \
1356
8.23k
    SStream_concat(O, "%s", markup("<imm:")); \
1357
8.23k
    printInt32Bang(O, Scale *MCOperand_getImm( \
1358
8.23k
            MCInst_getOperand(MI, (OpNum)))); \
1359
8.23k
    SStream_concat0(O, markup(">")); \
1360
8.23k
  }
printImmScale_8
Line
Count
Source
1352
2.26k
  { \
1353
2.26k
    AArch64_add_cs_detail_1( \
1354
2.26k
      MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1355
2.26k
      Scale); \
1356
2.26k
    SStream_concat(O, "%s", markup("<imm:")); \
1357
2.26k
    printInt32Bang(O, Scale *MCOperand_getImm( \
1358
2.26k
            MCInst_getOperand(MI, (OpNum)))); \
1359
2.26k
    SStream_concat0(O, markup(">")); \
1360
2.26k
  }
printImmScale_2
Line
Count
Source
1352
595
  { \
1353
595
    AArch64_add_cs_detail_1( \
1354
595
      MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1355
595
      Scale); \
1356
595
    SStream_concat(O, "%s", markup("<imm:")); \
1357
595
    printInt32Bang(O, Scale *MCOperand_getImm( \
1358
595
            MCInst_getOperand(MI, (OpNum)))); \
1359
595
    SStream_concat0(O, markup(">")); \
1360
595
  }
printImmScale_4
Line
Count
Source
1352
3.58k
  { \
1353
3.58k
    AArch64_add_cs_detail_1( \
1354
3.58k
      MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1355
3.58k
      Scale); \
1356
3.58k
    SStream_concat(O, "%s", markup("<imm:")); \
1357
3.58k
    printInt32Bang(O, Scale *MCOperand_getImm( \
1358
3.58k
            MCInst_getOperand(MI, (OpNum)))); \
1359
3.58k
    SStream_concat0(O, markup(">")); \
1360
3.58k
  }
printImmScale_16
Line
Count
Source
1352
1.74k
  { \
1353
1.74k
    AArch64_add_cs_detail_1( \
1354
1.74k
      MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1355
1.74k
      Scale); \
1356
1.74k
    SStream_concat(O, "%s", markup("<imm:")); \
1357
1.74k
    printInt32Bang(O, Scale *MCOperand_getImm( \
1358
1.74k
            MCInst_getOperand(MI, (OpNum)))); \
1359
1.74k
    SStream_concat0(O, markup(">")); \
1360
1.74k
  }
printImmScale_32
Line
Count
Source
1352
28
  { \
1353
28
    AArch64_add_cs_detail_1( \
1354
28
      MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1355
28
      Scale); \
1356
28
    SStream_concat(O, "%s", markup("<imm:")); \
1357
28
    printInt32Bang(O, Scale *MCOperand_getImm( \
1358
28
            MCInst_getOperand(MI, (OpNum)))); \
1359
28
    SStream_concat0(O, markup(">")); \
1360
28
  }
printImmScale_3
Line
Count
Source
1352
19
  { \
1353
19
    AArch64_add_cs_detail_1( \
1354
19
      MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1355
19
      Scale); \
1356
19
    SStream_concat(O, "%s", markup("<imm:")); \
1357
19
    printInt32Bang(O, Scale *MCOperand_getImm( \
1358
19
            MCInst_getOperand(MI, (OpNum)))); \
1359
19
    SStream_concat0(O, markup(">")); \
1360
19
  }
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.68k
  { \
1372
2.68k
    AArch64_add_cs_detail_2( \
1373
2.68k
      MI, \
1374
2.68k
      CONCAT(CONCAT(AArch64_OP_GROUP_ImmRangeScale, Scale), \
1375
2.68k
             Offset), \
1376
2.68k
      OpNum, Scale, Offset); \
1377
2.68k
    unsigned FirstImm = \
1378
2.68k
      Scale * \
1379
2.68k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1380
2.68k
    printUInt32(O, (FirstImm)); \
1381
2.68k
    SStream_concat(O, "%s", ":"); \
1382
2.68k
    printUInt32(O, (FirstImm + Offset)); \
1383
2.68k
    SStream_concat1(O, '\0'); \
1384
2.68k
  }
printImmRangeScale_2_1
Line
Count
Source
1371
987
  { \
1372
987
    AArch64_add_cs_detail_2( \
1373
987
      MI, \
1374
987
      CONCAT(CONCAT(AArch64_OP_GROUP_ImmRangeScale, Scale), \
1375
987
             Offset), \
1376
987
      OpNum, Scale, Offset); \
1377
987
    unsigned FirstImm = \
1378
987
      Scale * \
1379
987
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1380
987
    printUInt32(O, (FirstImm)); \
1381
987
    SStream_concat(O, "%s", ":"); \
1382
987
    printUInt32(O, (FirstImm + Offset)); \
1383
987
    SStream_concat1(O, '\0'); \
1384
987
  }
printImmRangeScale_4_3
Line
Count
Source
1371
1.70k
  { \
1372
1.70k
    AArch64_add_cs_detail_2( \
1373
1.70k
      MI, \
1374
1.70k
      CONCAT(CONCAT(AArch64_OP_GROUP_ImmRangeScale, Scale), \
1375
1.70k
             Offset), \
1376
1.70k
      OpNum, Scale, Offset); \
1377
1.70k
    unsigned FirstImm = \
1378
1.70k
      Scale * \
1379
1.70k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1380
1.70k
    printUInt32(O, (FirstImm)); \
1381
1.70k
    SStream_concat(O, "%s", ":"); \
1382
1.70k
    printUInt32(O, (FirstImm + Offset)); \
1383
1.70k
    SStream_concat1(O, '\0'); \
1384
1.70k
  }
1385
DEFINE_printImmRangeScale(2, 1);
1386
DEFINE_printImmRangeScale(4, 3);
1387
1388
void printUImm12Offset(MCInst *MI, unsigned OpNum, unsigned Scale, SStream *O)
1389
2.54k
{
1390
2.54k
  MCOperand *MO = MCInst_getOperand(MI, (OpNum));
1391
2.54k
  if (MCOperand_isImm(MO)) {
1392
2.54k
    SStream_concat(O, "%s", markup("<imm:"));
1393
2.54k
    printUInt32Bang(O, (MCOperand_getImm(MO) * Scale));
1394
2.54k
    SStream_concat0(O, markup(">"));
1395
2.54k
  } else {
1396
0
    printUInt64Bang(O, MCOperand_getImm(MO));
1397
0
  }
1398
2.54k
}
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
1.09k
{
1418
1.09k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_RPRFMOperand, OpNum);
1419
1.09k
  unsigned prfop = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1420
1.09k
  const AArch64PRFM_PRFM *PRFM =
1421
1.09k
    AArch64RPRFM_lookupRPRFMByEncoding(prfop);
1422
1.09k
  if (PRFM) {
1423
873
    SStream_concat0(O, PRFM->Name);
1424
873
    return;
1425
873
  }
1426
1427
223
  printUInt32Bang(O, (prfop));
1428
223
  SStream_concat1(O, '\0');
1429
223
}
1430
1431
#define DEFINE_printPrefetchOp(IsSVEPrefetch) \
1432
  void CONCAT(printPrefetchOp, \
1433
        IsSVEPrefetch)(MCInst * MI, unsigned OpNum, SStream *O) \
1434
2.94k
  { \
1435
2.94k
    AArch64_add_cs_detail_1(MI, \
1436
2.94k
          CONCAT(AArch64_OP_GROUP_PrefetchOp, \
1437
2.94k
                 IsSVEPrefetch), \
1438
2.94k
          OpNum, IsSVEPrefetch); \
1439
2.94k
    unsigned prfop = \
1440
2.94k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1441
2.94k
    if (IsSVEPrefetch) { \
1442
2.41k
      const AArch64SVEPRFM_SVEPRFM *PRFM = \
1443
2.41k
        AArch64SVEPRFM_lookupSVEPRFMByEncoding(prfop); \
1444
2.41k
      if (PRFM) { \
1445
2.17k
        SStream_concat0(O, PRFM->Name); \
1446
2.17k
        return; \
1447
2.17k
      } \
1448
2.41k
    } else { \
1449
534
      const AArch64PRFM_PRFM *PRFM = \
1450
534
        AArch64PRFM_lookupPRFMByEncoding(prfop); \
1451
534
      if (PRFM && \
1452
534
          AArch64_testFeatureList(MI->csh->mode, \
1453
285
                PRFM->FeaturesRequired)) { \
1454
285
        SStream_concat0(O, PRFM->Name); \
1455
285
        return; \
1456
285
      } \
1457
534
    } \
1458
2.94k
\
1459
2.94k
    SStream_concat(O, "%s", markup("<imm:")); \
1460
487
    printUInt32Bang(O, (prfop)); \
1461
487
    SStream_concat0(O, markup(">")); \
1462
487
  }
printPrefetchOp_0
Line
Count
Source
1434
534
  { \
1435
534
    AArch64_add_cs_detail_1(MI, \
1436
534
          CONCAT(AArch64_OP_GROUP_PrefetchOp, \
1437
534
                 IsSVEPrefetch), \
1438
534
          OpNum, IsSVEPrefetch); \
1439
534
    unsigned prfop = \
1440
534
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1441
534
    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
534
    } else { \
1449
534
      const AArch64PRFM_PRFM *PRFM = \
1450
534
        AArch64PRFM_lookupPRFMByEncoding(prfop); \
1451
534
      if (PRFM && \
1452
534
          AArch64_testFeatureList(MI->csh->mode, \
1453
285
                PRFM->FeaturesRequired)) { \
1454
285
        SStream_concat0(O, PRFM->Name); \
1455
285
        return; \
1456
285
      } \
1457
534
    } \
1458
534
\
1459
534
    SStream_concat(O, "%s", markup("<imm:")); \
1460
249
    printUInt32Bang(O, (prfop)); \
1461
249
    SStream_concat0(O, markup(">")); \
1462
249
  }
printPrefetchOp_1
Line
Count
Source
1434
2.41k
  { \
1435
2.41k
    AArch64_add_cs_detail_1(MI, \
1436
2.41k
          CONCAT(AArch64_OP_GROUP_PrefetchOp, \
1437
2.41k
                 IsSVEPrefetch), \
1438
2.41k
          OpNum, IsSVEPrefetch); \
1439
2.41k
    unsigned prfop = \
1440
2.41k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1441
2.41k
    if (IsSVEPrefetch) { \
1442
2.41k
      const AArch64SVEPRFM_SVEPRFM *PRFM = \
1443
2.41k
        AArch64SVEPRFM_lookupSVEPRFMByEncoding(prfop); \
1444
2.41k
      if (PRFM) { \
1445
2.17k
        SStream_concat0(O, PRFM->Name); \
1446
2.17k
        return; \
1447
2.17k
      } \
1448
2.41k
    } 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.41k
\
1459
2.41k
    SStream_concat(O, "%s", markup("<imm:")); \
1460
238
    printUInt32Bang(O, (prfop)); \
1461
238
    SStream_concat0(O, markup(">")); \
1462
238
  }
1463
DEFINE_printPrefetchOp(false);
1464
DEFINE_printPrefetchOp(true);
1465
1466
void printPSBHintOp(MCInst *MI, unsigned OpNum, SStream *O)
1467
38
{
1468
38
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_PSBHintOp, OpNum);
1469
38
  unsigned psbhintop = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1470
38
  const AArch64PSBHint_PSB *PSB =
1471
38
    AArch64PSBHint_lookupPSBByEncoding(psbhintop);
1472
38
  if (PSB)
1473
38
    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
38
}
1481
1482
void printBTIHintOp(MCInst *MI, unsigned OpNum, SStream *O)
1483
281
{
1484
281
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_BTIHintOp, OpNum);
1485
281
  unsigned btihintop = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))) ^
1486
281
           32;
1487
281
  const AArch64BTIHint_BTI *BTI =
1488
281
    AArch64BTIHint_lookupBTIByEncoding(btihintop);
1489
281
  if (BTI)
1490
281
    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
281
}
1497
1498
static void printFPImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
1499
97
{
1500
97
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_FPImmOperand, OpNum);
1501
97
  MCOperand *MO = MCInst_getOperand(MI, (OpNum));
1502
97
  float FPImm = MCOperand_isDFPImm(MO) ?
1503
0
            BitsToDouble(MCOperand_getImm(MO)) :
1504
97
            AArch64_AM_getFPImmFloat(MCOperand_getImm(MO));
1505
1506
  // 8 decimal places are enough to perfectly represent permitted floats.
1507
97
  SStream_concat(O, "%s", markup("<imm:"));
1508
97
  SStream_concat(O, "#%.8f", FPImm);
1509
97
  SStream_concat0(O, markup(">"));
1510
97
}
1511
1512
static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride /* = 1 */)
1513
49.7k
{
1514
141k
  while (Stride--) {
1515
91.6k
    switch (Reg) {
1516
0
    default:
1517
0
      CS_ASSERT_RET_VAL(0 && "Vector register expected!", 0);
1518
2.41k
    case AArch64_Q0:
1519
2.41k
      Reg = AArch64_Q1;
1520
2.41k
      break;
1521
2.07k
    case AArch64_Q1:
1522
2.07k
      Reg = AArch64_Q2;
1523
2.07k
      break;
1524
1.31k
    case AArch64_Q2:
1525
1.31k
      Reg = AArch64_Q3;
1526
1.31k
      break;
1527
668
    case AArch64_Q3:
1528
668
      Reg = AArch64_Q4;
1529
668
      break;
1530
346
    case AArch64_Q4:
1531
346
      Reg = AArch64_Q5;
1532
346
      break;
1533
753
    case AArch64_Q5:
1534
753
      Reg = AArch64_Q6;
1535
753
      break;
1536
689
    case AArch64_Q6:
1537
689
      Reg = AArch64_Q7;
1538
689
      break;
1539
850
    case AArch64_Q7:
1540
850
      Reg = AArch64_Q8;
1541
850
      break;
1542
818
    case AArch64_Q8:
1543
818
      Reg = AArch64_Q9;
1544
818
      break;
1545
440
    case AArch64_Q9:
1546
440
      Reg = AArch64_Q10;
1547
440
      break;
1548
264
    case AArch64_Q10:
1549
264
      Reg = AArch64_Q11;
1550
264
      break;
1551
593
    case AArch64_Q11:
1552
593
      Reg = AArch64_Q12;
1553
593
      break;
1554
619
    case AArch64_Q12:
1555
619
      Reg = AArch64_Q13;
1556
619
      break;
1557
515
    case AArch64_Q13:
1558
515
      Reg = AArch64_Q14;
1559
515
      break;
1560
208
    case AArch64_Q14:
1561
208
      Reg = AArch64_Q15;
1562
208
      break;
1563
269
    case AArch64_Q15:
1564
269
      Reg = AArch64_Q16;
1565
269
      break;
1566
320
    case AArch64_Q16:
1567
320
      Reg = AArch64_Q17;
1568
320
      break;
1569
382
    case AArch64_Q17:
1570
382
      Reg = AArch64_Q18;
1571
382
      break;
1572
428
    case AArch64_Q18:
1573
428
      Reg = AArch64_Q19;
1574
428
      break;
1575
528
    case AArch64_Q19:
1576
528
      Reg = AArch64_Q20;
1577
528
      break;
1578
1.55k
    case AArch64_Q20:
1579
1.55k
      Reg = AArch64_Q21;
1580
1.55k
      break;
1581
749
    case AArch64_Q21:
1582
749
      Reg = AArch64_Q22;
1583
749
      break;
1584
1.09k
    case AArch64_Q22:
1585
1.09k
      Reg = AArch64_Q23;
1586
1.09k
      break;
1587
893
    case AArch64_Q23:
1588
893
      Reg = AArch64_Q24;
1589
893
      break;
1590
755
    case AArch64_Q24:
1591
755
      Reg = AArch64_Q25;
1592
755
      break;
1593
780
    case AArch64_Q25:
1594
780
      Reg = AArch64_Q26;
1595
780
      break;
1596
460
    case AArch64_Q26:
1597
460
      Reg = AArch64_Q27;
1598
460
      break;
1599
507
    case AArch64_Q27:
1600
507
      Reg = AArch64_Q28;
1601
507
      break;
1602
315
    case AArch64_Q28:
1603
315
      Reg = AArch64_Q29;
1604
315
      break;
1605
436
    case AArch64_Q29:
1606
436
      Reg = AArch64_Q30;
1607
436
      break;
1608
418
    case AArch64_Q30:
1609
418
      Reg = AArch64_Q31;
1610
418
      break;
1611
    // Vector lists can wrap around.
1612
806
    case AArch64_Q31:
1613
806
      Reg = AArch64_Q0;
1614
806
      break;
1615
8.00k
    case AArch64_Z0:
1616
8.00k
      Reg = AArch64_Z1;
1617
8.00k
      break;
1618
6.13k
    case AArch64_Z1:
1619
6.13k
      Reg = AArch64_Z2;
1620
6.13k
      break;
1621
6.52k
    case AArch64_Z2:
1622
6.52k
      Reg = AArch64_Z3;
1623
6.52k
      break;
1624
1.39k
    case AArch64_Z3:
1625
1.39k
      Reg = AArch64_Z4;
1626
1.39k
      break;
1627
4.33k
    case AArch64_Z4:
1628
4.33k
      Reg = AArch64_Z5;
1629
4.33k
      break;
1630
3.08k
    case AArch64_Z5:
1631
3.08k
      Reg = AArch64_Z6;
1632
3.08k
      break;
1633
2.77k
    case AArch64_Z6:
1634
2.77k
      Reg = AArch64_Z7;
1635
2.77k
      break;
1636
1.39k
    case AArch64_Z7:
1637
1.39k
      Reg = AArch64_Z8;
1638
1.39k
      break;
1639
2.63k
    case AArch64_Z8:
1640
2.63k
      Reg = AArch64_Z9;
1641
2.63k
      break;
1642
2.50k
    case AArch64_Z9:
1643
2.50k
      Reg = AArch64_Z10;
1644
2.50k
      break;
1645
2.33k
    case AArch64_Z10:
1646
2.33k
      Reg = AArch64_Z11;
1647
2.33k
      break;
1648
1.69k
    case AArch64_Z11:
1649
1.69k
      Reg = AArch64_Z12;
1650
1.69k
      break;
1651
1.47k
    case AArch64_Z12:
1652
1.47k
      Reg = AArch64_Z13;
1653
1.47k
      break;
1654
1.48k
    case AArch64_Z13:
1655
1.48k
      Reg = AArch64_Z14;
1656
1.48k
      break;
1657
1.83k
    case AArch64_Z14:
1658
1.83k
      Reg = AArch64_Z15;
1659
1.83k
      break;
1660
1.45k
    case AArch64_Z15:
1661
1.45k
      Reg = AArch64_Z16;
1662
1.45k
      break;
1663
936
    case AArch64_Z16:
1664
936
      Reg = AArch64_Z17;
1665
936
      break;
1666
594
    case AArch64_Z17:
1667
594
      Reg = AArch64_Z18;
1668
594
      break;
1669
841
    case AArch64_Z18:
1670
841
      Reg = AArch64_Z19;
1671
841
      break;
1672
872
    case AArch64_Z19:
1673
872
      Reg = AArch64_Z20;
1674
872
      break;
1675
1.84k
    case AArch64_Z20:
1676
1.84k
      Reg = AArch64_Z21;
1677
1.84k
      break;
1678
1.41k
    case AArch64_Z21:
1679
1.41k
      Reg = AArch64_Z22;
1680
1.41k
      break;
1681
1.33k
    case AArch64_Z22:
1682
1.33k
      Reg = AArch64_Z23;
1683
1.33k
      break;
1684
821
    case AArch64_Z23:
1685
821
      Reg = AArch64_Z24;
1686
821
      break;
1687
1.27k
    case AArch64_Z24:
1688
1.27k
      Reg = AArch64_Z25;
1689
1.27k
      break;
1690
1.21k
    case AArch64_Z25:
1691
1.21k
      Reg = AArch64_Z26;
1692
1.21k
      break;
1693
1.83k
    case AArch64_Z26:
1694
1.83k
      Reg = AArch64_Z27;
1695
1.83k
      break;
1696
865
    case AArch64_Z27:
1697
865
      Reg = AArch64_Z28;
1698
865
      break;
1699
1.02k
    case AArch64_Z28:
1700
1.02k
      Reg = AArch64_Z29;
1701
1.02k
      break;
1702
970
    case AArch64_Z29:
1703
970
      Reg = AArch64_Z30;
1704
970
      break;
1705
965
    case AArch64_Z30:
1706
965
      Reg = AArch64_Z31;
1707
965
      break;
1708
    // Vector lists can wrap around.
1709
862
    case AArch64_Z31:
1710
862
      Reg = AArch64_Z0;
1711
862
      break;
1712
99
    case AArch64_P0:
1713
99
      Reg = AArch64_P1;
1714
99
      break;
1715
182
    case AArch64_P1:
1716
182
      Reg = AArch64_P2;
1717
182
      break;
1718
192
    case AArch64_P2:
1719
192
      Reg = AArch64_P3;
1720
192
      break;
1721
68
    case AArch64_P3:
1722
68
      Reg = AArch64_P4;
1723
68
      break;
1724
2
    case AArch64_P4:
1725
2
      Reg = AArch64_P5;
1726
2
      break;
1727
208
    case AArch64_P5:
1728
208
      Reg = AArch64_P6;
1729
208
      break;
1730
212
    case AArch64_P6:
1731
212
      Reg = AArch64_P7;
1732
212
      break;
1733
62
    case AArch64_P7:
1734
62
      Reg = AArch64_P8;
1735
62
      break;
1736
22
    case AArch64_P8:
1737
22
      Reg = AArch64_P9;
1738
22
      break;
1739
8
    case AArch64_P9:
1740
8
      Reg = AArch64_P10;
1741
8
      break;
1742
76
    case AArch64_P10:
1743
76
      Reg = AArch64_P11;
1744
76
      break;
1745
0
    case AArch64_P11:
1746
0
      Reg = AArch64_P12;
1747
0
      break;
1748
40
    case AArch64_P12:
1749
40
      Reg = AArch64_P13;
1750
40
      break;
1751
406
    case AArch64_P13:
1752
406
      Reg = AArch64_P14;
1753
406
      break;
1754
24
    case AArch64_P14:
1755
24
      Reg = AArch64_P15;
1756
24
      break;
1757
    // Vector lists can wrap around.
1758
70
    case AArch64_P15:
1759
70
      Reg = AArch64_P0;
1760
70
      break;
1761
91.6k
    }
1762
91.6k
  }
1763
49.7k
  return Reg;
1764
49.7k
}
1765
1766
#define DEFINE_printGPRSeqPairsClassOperand(size) \
1767
  void CONCAT(printGPRSeqPairsClassOperand, \
1768
        size)(MCInst * MI, unsigned OpNum, SStream *O) \
1769
723
  { \
1770
723
    AArch64_add_cs_detail_1( \
1771
723
      MI, \
1772
723
      CONCAT(AArch64_OP_GROUP_GPRSeqPairsClassOperand, \
1773
723
             size), \
1774
723
      OpNum, size); \
1775
723
    CS_ASSERT_RET((size == 64 || size == 32) && \
1776
723
            "Template parameter must be either 32 or 64"); \
1777
723
    unsigned Reg = \
1778
723
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1779
723
\
1780
723
    unsigned Sube = (size == 32) ? AArch64_sube32 : \
1781
723
                 AArch64_sube64; \
1782
723
    unsigned Subo = (size == 32) ? AArch64_subo32 : \
1783
723
                 AArch64_subo64; \
1784
723
\
1785
723
    unsigned Even = MCRegisterInfo_getSubReg(MI->MRI, Reg, Sube); \
1786
723
    unsigned Odd = MCRegisterInfo_getSubReg(MI->MRI, Reg, Subo); \
1787
723
    printRegName(O, Even); \
1788
723
    SStream_concat0(O, ", "); \
1789
723
    printRegName(O, Odd); \
1790
723
  }
printGPRSeqPairsClassOperand_32
Line
Count
Source
1769
96
  { \
1770
96
    AArch64_add_cs_detail_1( \
1771
96
      MI, \
1772
96
      CONCAT(AArch64_OP_GROUP_GPRSeqPairsClassOperand, \
1773
96
             size), \
1774
96
      OpNum, size); \
1775
96
    CS_ASSERT_RET((size == 64 || size == 32) && \
1776
96
            "Template parameter must be either 32 or 64"); \
1777
96
    unsigned Reg = \
1778
96
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1779
96
\
1780
96
    unsigned Sube = (size == 32) ? AArch64_sube32 : \
1781
96
                 AArch64_sube64; \
1782
96
    unsigned Subo = (size == 32) ? AArch64_subo32 : \
1783
96
                 AArch64_subo64; \
1784
96
\
1785
96
    unsigned Even = MCRegisterInfo_getSubReg(MI->MRI, Reg, Sube); \
1786
96
    unsigned Odd = MCRegisterInfo_getSubReg(MI->MRI, Reg, Subo); \
1787
96
    printRegName(O, Even); \
1788
96
    SStream_concat0(O, ", "); \
1789
96
    printRegName(O, Odd); \
1790
96
  }
printGPRSeqPairsClassOperand_64
Line
Count
Source
1769
627
  { \
1770
627
    AArch64_add_cs_detail_1( \
1771
627
      MI, \
1772
627
      CONCAT(AArch64_OP_GROUP_GPRSeqPairsClassOperand, \
1773
627
             size), \
1774
627
      OpNum, size); \
1775
627
    CS_ASSERT_RET((size == 64 || size == 32) && \
1776
627
            "Template parameter must be either 32 or 64"); \
1777
627
    unsigned Reg = \
1778
627
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1779
627
\
1780
627
    unsigned Sube = (size == 32) ? AArch64_sube32 : \
1781
627
                 AArch64_sube64; \
1782
627
    unsigned Subo = (size == 32) ? AArch64_subo32 : \
1783
627
                 AArch64_subo64; \
1784
627
\
1785
627
    unsigned Even = MCRegisterInfo_getSubReg(MI->MRI, Reg, Sube); \
1786
627
    unsigned Odd = MCRegisterInfo_getSubReg(MI->MRI, Reg, Subo); \
1787
627
    printRegName(O, Even); \
1788
627
    SStream_concat0(O, ", "); \
1789
627
    printRegName(O, Odd); \
1790
627
  }
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
5.06k
  { \
1798
5.06k
    AArch64_add_cs_detail_1( \
1799
5.06k
      MI, CONCAT(AArch64_OP_GROUP_MatrixIndex, Scale), \
1800
5.06k
      OpNum, Scale); \
1801
5.06k
    printInt64(O, Scale *MCOperand_getImm( \
1802
5.06k
              MCInst_getOperand(MI, (OpNum)))); \
1803
5.06k
  }
printMatrixIndex_8
Line
Count
Source
1797
737
  { \
1798
737
    AArch64_add_cs_detail_1( \
1799
737
      MI, CONCAT(AArch64_OP_GROUP_MatrixIndex, Scale), \
1800
737
      OpNum, Scale); \
1801
737
    printInt64(O, Scale *MCOperand_getImm( \
1802
737
              MCInst_getOperand(MI, (OpNum)))); \
1803
737
  }
Unexecuted instantiation: printMatrixIndex_0
printMatrixIndex_1
Line
Count
Source
1797
4.32k
  { \
1798
4.32k
    AArch64_add_cs_detail_1( \
1799
4.32k
      MI, CONCAT(AArch64_OP_GROUP_MatrixIndex, Scale), \
1800
4.32k
      OpNum, Scale); \
1801
4.32k
    printInt64(O, Scale *MCOperand_getImm( \
1802
4.32k
              MCInst_getOperand(MI, (OpNum)))); \
1803
4.32k
  }
1804
DEFINE_printMatrixIndex(8);
1805
DEFINE_printMatrixIndex(0);
1806
DEFINE_printMatrixIndex(1);
1807
1808
void printMatrixTileList(MCInst *MI, unsigned OpNum, SStream *O)
1809
441
{
1810
441
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_MatrixTileList, OpNum);
1811
441
  unsigned MaxRegs = 8;
1812
441
  unsigned RegMask = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1813
1814
441
  unsigned NumRegs = 0;
1815
3.96k
  for (unsigned I = 0; I < MaxRegs; ++I)
1816
3.52k
    if ((RegMask & (1 << I)) != 0)
1817
2.15k
      ++NumRegs;
1818
1819
441
  SStream_concat0(O, "{");
1820
441
  unsigned Printed = 0;
1821
3.96k
  for (unsigned I = 0; I < MaxRegs; ++I) {
1822
3.52k
    unsigned Reg = RegMask & (1 << I);
1823
3.52k
    if (Reg == 0)
1824
1.37k
      continue;
1825
2.15k
    printRegName(O, AArch64_ZAD0 + I);
1826
2.15k
    if (Printed + 1 != NumRegs)
1827
1.72k
      SStream_concat0(O, ", ");
1828
2.15k
    ++Printed;
1829
2.15k
  }
1830
441
  SStream_concat0(O, "}");
1831
441
}
1832
1833
void printVectorList(MCInst *MI, unsigned OpNum, SStream *O,
1834
         const char *LayoutSuffix)
1835
23.6k
{
1836
23.6k
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum)));
1837
1838
23.6k
  SStream_concat0(O, "{ ");
1839
1840
  // Work out how many registers there are in the list (if there is an actual
1841
  // list).
1842
23.6k
  unsigned NumRegs = 1;
1843
23.6k
  if (MCRegisterClass_contains(
1844
23.6k
        MCRegisterInfo_getRegClass(MI->MRI, AArch64_DDRegClassID),
1845
23.6k
        Reg) ||
1846
23.3k
      MCRegisterClass_contains(
1847
23.3k
        MCRegisterInfo_getRegClass(MI->MRI, AArch64_ZPR2RegClassID),
1848
23.3k
        Reg) ||
1849
19.5k
      MCRegisterClass_contains(
1850
19.5k
        MCRegisterInfo_getRegClass(MI->MRI, AArch64_QQRegClassID),
1851
19.5k
        Reg) ||
1852
17.1k
      MCRegisterClass_contains(
1853
17.1k
        MCRegisterInfo_getRegClass(MI->MRI, AArch64_PPR2RegClassID),
1854
17.1k
        Reg) ||
1855
16.3k
      MCRegisterClass_contains(
1856
16.3k
        MCRegisterInfo_getRegClass(MI->MRI,
1857
16.3k
                 AArch64_ZPR2StridedRegClassID),
1858
16.3k
        Reg))
1859
8.57k
    NumRegs = 2;
1860
15.0k
  else if (MCRegisterClass_contains(
1861
15.0k
       MCRegisterInfo_getRegClass(MI->MRI,
1862
15.0k
                AArch64_DDDRegClassID),
1863
15.0k
       Reg) ||
1864
14.8k
     MCRegisterClass_contains(
1865
14.8k
       MCRegisterInfo_getRegClass(MI->MRI,
1866
14.8k
                AArch64_ZPR3RegClassID),
1867
14.8k
       Reg) ||
1868
14.7k
     MCRegisterClass_contains(
1869
14.7k
       MCRegisterInfo_getRegClass(MI->MRI,
1870
14.7k
                AArch64_QQQRegClassID),
1871
14.7k
       Reg))
1872
2.08k
    NumRegs = 3;
1873
12.9k
  else if (MCRegisterClass_contains(
1874
12.9k
       MCRegisterInfo_getRegClass(MI->MRI,
1875
12.9k
                AArch64_DDDDRegClassID),
1876
12.9k
       Reg) ||
1877
12.7k
     MCRegisterClass_contains(
1878
12.7k
       MCRegisterInfo_getRegClass(MI->MRI,
1879
12.7k
                AArch64_ZPR4RegClassID),
1880
12.7k
       Reg) ||
1881
9.19k
     MCRegisterClass_contains(
1882
9.19k
       MCRegisterInfo_getRegClass(MI->MRI,
1883
9.19k
                AArch64_QQQQRegClassID),
1884
9.19k
       Reg) ||
1885
6.84k
     MCRegisterClass_contains(
1886
6.84k
       MCRegisterInfo_getRegClass(
1887
6.84k
         MI->MRI, AArch64_ZPR4StridedRegClassID),
1888
6.84k
       Reg))
1889
6.85k
    NumRegs = 4;
1890
1891
23.6k
  unsigned Stride = 1;
1892
23.6k
  if (MCRegisterClass_contains(
1893
23.6k
        MCRegisterInfo_getRegClass(MI->MRI,
1894
23.6k
                 AArch64_ZPR2StridedRegClassID),
1895
23.6k
        Reg))
1896
1.33k
    Stride = 8;
1897
22.2k
  else if (MCRegisterClass_contains(
1898
22.2k
       MCRegisterInfo_getRegClass(
1899
22.2k
         MI->MRI, AArch64_ZPR4StridedRegClassID),
1900
22.2k
       Reg))
1901
737
    Stride = 4;
1902
1903
  // Now forget about the list and find out what the first register is.
1904
23.6k
  if (MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_dsub0))
1905
693
    Reg = MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_dsub0);
1906
22.9k
  else if (MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_qsub0))
1907
6.48k
    Reg = MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_qsub0);
1908
16.4k
  else if (MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_zsub0))
1909
9.52k
    Reg = MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_zsub0);
1910
6.92k
  else if (MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_psub0))
1911
818
    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
23.6k
  if (MCRegisterClass_contains(MCRegisterInfo_getRegClass(
1916
23.6k
               MI->MRI, AArch64_FPR64RegClassID),
1917
23.6k
             Reg)) {
1918
953
    const MCRegisterClass *FPR128RC = MCRegisterInfo_getRegClass(
1919
953
      MI->MRI, AArch64_FPR128RegClassID);
1920
953
    Reg = MCRegisterInfo_getMatchingSuperReg(
1921
953
      MI->MRI, Reg, AArch64_dsub, FPR128RC);
1922
953
  }
1923
1924
23.6k
  if ((MCRegisterClass_contains(
1925
23.6k
         MCRegisterInfo_getRegClass(MI->MRI, AArch64_ZPRRegClassID),
1926
23.6k
         Reg) ||
1927
9.80k
       MCRegisterClass_contains(
1928
9.80k
         MCRegisterInfo_getRegClass(MI->MRI, AArch64_PPRRegClassID),
1929
9.80k
         Reg)) &&
1930
14.6k
      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
8.27k
      Reg < getNextVectorRegister(Reg, NumRegs - 1)) {
1934
8.21k
    printRegName(O, Reg);
1935
8.21k
    SStream_concat0(O, LayoutSuffix);
1936
8.21k
    if (NumRegs > 1) {
1937
      // Set of two sve registers should be separated by ','
1938
8.21k
      const char *split_char = NumRegs == 2 ? ", " : " - ";
1939
8.21k
      SStream_concat0(O, split_char);
1940
8.21k
      printRegName(O,
1941
8.21k
             (getNextVectorRegister(Reg, NumRegs - 1)));
1942
8.21k
      SStream_concat0(O, LayoutSuffix);
1943
8.21k
    }
1944
15.4k
  } else {
1945
48.7k
    for (unsigned i = 0; i < NumRegs;
1946
33.3k
         ++i, Reg = getNextVectorRegister(Reg, Stride)) {
1947
      // wrap-around sve register
1948
33.3k
      if (MCRegisterClass_contains(
1949
33.3k
            MCRegisterInfo_getRegClass(
1950
33.3k
              MI->MRI, AArch64_ZPRRegClassID),
1951
33.3k
            Reg) ||
1952
23.3k
          MCRegisterClass_contains(
1953
23.3k
            MCRegisterInfo_getRegClass(
1954
23.3k
              MI->MRI, AArch64_PPRRegClassID),
1955
23.3k
            Reg))
1956
10.0k
        printRegName(O, Reg);
1957
23.2k
      else
1958
23.2k
        printRegNameAlt(O, Reg, AArch64_vreg);
1959
33.3k
      SStream_concat0(O, LayoutSuffix);
1960
33.3k
      if (i + 1 != NumRegs)
1961
17.9k
        SStream_concat0(O, ", ");
1962
33.3k
    }
1963
15.4k
  }
1964
23.6k
  SStream_concat0(O, " }");
1965
23.6k
}
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
23.6k
  { \
1978
23.6k
    AArch64_add_cs_detail_2( \
1979
23.6k
      MI, \
1980
23.6k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
23.6k
              NumLanes), \
1982
23.6k
             LaneKind), \
1983
23.6k
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
23.6k
    if (CHAR(LaneKind) == '0') { \
1985
13
      printVectorList(MI, OpNum, O, ""); \
1986
13
      return; \
1987
13
    } \
1988
23.6k
    char Suffix[32]; \
1989
23.6k
    if (NumLanes) \
1990
23.6k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
2.95k
            CHAR(LaneKind)); \
1992
23.6k
    else \
1993
23.6k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
20.6k
            CHAR(LaneKind)); \
1995
23.6k
\
1996
23.6k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
23.6k
  }
printTypedVectorList_0_b
Line
Count
Source
1977
6.03k
  { \
1978
6.03k
    AArch64_add_cs_detail_2( \
1979
6.03k
      MI, \
1980
6.03k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
6.03k
              NumLanes), \
1982
6.03k
             LaneKind), \
1983
6.03k
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
6.03k
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
6.03k
    char Suffix[32]; \
1989
6.03k
    if (NumLanes) \
1990
6.03k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
0
            CHAR(LaneKind)); \
1992
6.03k
    else \
1993
6.03k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
6.03k
            CHAR(LaneKind)); \
1995
6.03k
\
1996
6.03k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
6.03k
  }
printTypedVectorList_0_d
Line
Count
Source
1977
5.05k
  { \
1978
5.05k
    AArch64_add_cs_detail_2( \
1979
5.05k
      MI, \
1980
5.05k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
5.05k
              NumLanes), \
1982
5.05k
             LaneKind), \
1983
5.05k
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
5.05k
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
5.05k
    char Suffix[32]; \
1989
5.05k
    if (NumLanes) \
1990
5.05k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
0
            CHAR(LaneKind)); \
1992
5.05k
    else \
1993
5.05k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
5.05k
            CHAR(LaneKind)); \
1995
5.05k
\
1996
5.05k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
5.05k
  }
printTypedVectorList_0_h
Line
Count
Source
1977
4.49k
  { \
1978
4.49k
    AArch64_add_cs_detail_2( \
1979
4.49k
      MI, \
1980
4.49k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
4.49k
              NumLanes), \
1982
4.49k
             LaneKind), \
1983
4.49k
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
4.49k
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
4.49k
    char Suffix[32]; \
1989
4.49k
    if (NumLanes) \
1990
4.49k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
0
            CHAR(LaneKind)); \
1992
4.49k
    else \
1993
4.49k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
4.49k
            CHAR(LaneKind)); \
1995
4.49k
\
1996
4.49k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
4.49k
  }
printTypedVectorList_0_s
Line
Count
Source
1977
4.46k
  { \
1978
4.46k
    AArch64_add_cs_detail_2( \
1979
4.46k
      MI, \
1980
4.46k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
4.46k
              NumLanes), \
1982
4.46k
             LaneKind), \
1983
4.46k
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
4.46k
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
4.46k
    char Suffix[32]; \
1989
4.46k
    if (NumLanes) \
1990
4.46k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
0
            CHAR(LaneKind)); \
1992
4.46k
    else \
1993
4.46k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
4.46k
            CHAR(LaneKind)); \
1995
4.46k
\
1996
4.46k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
4.46k
  }
printTypedVectorList_0_q
Line
Count
Source
1977
604
  { \
1978
604
    AArch64_add_cs_detail_2( \
1979
604
      MI, \
1980
604
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
604
              NumLanes), \
1982
604
             LaneKind), \
1983
604
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
604
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
604
    char Suffix[32]; \
1989
604
    if (NumLanes) \
1990
604
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
0
            CHAR(LaneKind)); \
1992
604
    else \
1993
604
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
604
            CHAR(LaneKind)); \
1995
604
\
1996
604
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
604
  }
printTypedVectorList_16_b
Line
Count
Source
1977
1.19k
  { \
1978
1.19k
    AArch64_add_cs_detail_2( \
1979
1.19k
      MI, \
1980
1.19k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
1.19k
              NumLanes), \
1982
1.19k
             LaneKind), \
1983
1.19k
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
1.19k
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
1.19k
    char Suffix[32]; \
1989
1.19k
    if (NumLanes) \
1990
1.19k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
1.19k
            CHAR(LaneKind)); \
1992
1.19k
    else \
1993
1.19k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
1.19k
\
1996
1.19k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
1.19k
  }
printTypedVectorList_1_d
Line
Count
Source
1977
145
  { \
1978
145
    AArch64_add_cs_detail_2( \
1979
145
      MI, \
1980
145
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
145
              NumLanes), \
1982
145
             LaneKind), \
1983
145
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
145
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
145
    char Suffix[32]; \
1989
145
    if (NumLanes) \
1990
145
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
145
            CHAR(LaneKind)); \
1992
145
    else \
1993
145
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
145
\
1996
145
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
145
  }
printTypedVectorList_2_d
Line
Count
Source
1977
282
  { \
1978
282
    AArch64_add_cs_detail_2( \
1979
282
      MI, \
1980
282
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
282
              NumLanes), \
1982
282
             LaneKind), \
1983
282
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
282
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
282
    char Suffix[32]; \
1989
282
    if (NumLanes) \
1990
282
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
282
            CHAR(LaneKind)); \
1992
282
    else \
1993
282
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
282
\
1996
282
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
282
  }
printTypedVectorList_2_s
Line
Count
Source
1977
444
  { \
1978
444
    AArch64_add_cs_detail_2( \
1979
444
      MI, \
1980
444
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
444
              NumLanes), \
1982
444
             LaneKind), \
1983
444
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
444
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
444
    char Suffix[32]; \
1989
444
    if (NumLanes) \
1990
444
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
444
            CHAR(LaneKind)); \
1992
444
    else \
1993
444
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
444
\
1996
444
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
444
  }
printTypedVectorList_4_h
Line
Count
Source
1977
122
  { \
1978
122
    AArch64_add_cs_detail_2( \
1979
122
      MI, \
1980
122
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
122
              NumLanes), \
1982
122
             LaneKind), \
1983
122
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
122
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
122
    char Suffix[32]; \
1989
122
    if (NumLanes) \
1990
122
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
122
            CHAR(LaneKind)); \
1992
122
    else \
1993
122
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
122
\
1996
122
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
122
  }
printTypedVectorList_4_s
Line
Count
Source
1977
193
  { \
1978
193
    AArch64_add_cs_detail_2( \
1979
193
      MI, \
1980
193
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
193
              NumLanes), \
1982
193
             LaneKind), \
1983
193
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
193
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
193
    char Suffix[32]; \
1989
193
    if (NumLanes) \
1990
193
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
193
            CHAR(LaneKind)); \
1992
193
    else \
1993
193
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
193
\
1996
193
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
193
  }
printTypedVectorList_8_b
Line
Count
Source
1977
242
  { \
1978
242
    AArch64_add_cs_detail_2( \
1979
242
      MI, \
1980
242
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
242
              NumLanes), \
1982
242
             LaneKind), \
1983
242
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
242
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
242
    char Suffix[32]; \
1989
242
    if (NumLanes) \
1990
242
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
242
            CHAR(LaneKind)); \
1992
242
    else \
1993
242
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
242
\
1996
242
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
242
  }
printTypedVectorList_8_h
Line
Count
Source
1977
325
  { \
1978
325
    AArch64_add_cs_detail_2( \
1979
325
      MI, \
1980
325
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
325
              NumLanes), \
1982
325
             LaneKind), \
1983
325
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
325
    if (CHAR(LaneKind) == '0') { \
1985
0
      printVectorList(MI, OpNum, O, ""); \
1986
0
      return; \
1987
0
    } \
1988
325
    char Suffix[32]; \
1989
325
    if (NumLanes) \
1990
325
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, \
1991
325
            CHAR(LaneKind)); \
1992
325
    else \
1993
325
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", \
1994
0
            CHAR(LaneKind)); \
1995
325
\
1996
325
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
1997
325
  }
printTypedVectorList_0_0
Line
Count
Source
1977
13
  { \
1978
13
    AArch64_add_cs_detail_2( \
1979
13
      MI, \
1980
13
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, \
1981
13
              NumLanes), \
1982
13
             LaneKind), \
1983
13
      OpNum, NumLanes, CHAR(LaneKind)); \
1984
13
    if (CHAR(LaneKind) == '0') { \
1985
13
      printVectorList(MI, OpNum, O, ""); \
1986
13
      return; \
1987
13
    } \
1988
13
    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
14.3k
  { \
2017
14.3k
    AArch64_add_cs_detail_1( \
2018
14.3k
      MI, CONCAT(AArch64_OP_GROUP_VectorIndex, Scale), \
2019
14.3k
      OpNum, Scale); \
2020
14.3k
    SStream_concat(O, "%s", "["); \
2021
14.3k
    printUInt64(O, Scale *MCOperand_getImm( \
2022
14.3k
               MCInst_getOperand(MI, (OpNum)))); \
2023
14.3k
    SStream_concat0(O, "]"); \
2024
14.3k
  }
printVectorIndex_1
Line
Count
Source
2016
14.3k
  { \
2017
14.3k
    AArch64_add_cs_detail_1( \
2018
14.3k
      MI, CONCAT(AArch64_OP_GROUP_VectorIndex, Scale), \
2019
14.3k
      OpNum, Scale); \
2020
14.3k
    SStream_concat(O, "%s", "["); \
2021
14.3k
    printUInt64(O, Scale *MCOperand_getImm( \
2022
14.3k
               MCInst_getOperand(MI, (OpNum)))); \
2023
14.3k
    SStream_concat0(O, "]"); \
2024
14.3k
  }
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
3.98k
{
2030
3.98k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_AlignedLabel, OpNum);
2031
3.98k
  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
3.98k
  if (MCOperand_isImm(Op)) {
2036
3.84k
    SStream_concat0(O, markup("<imm:"));
2037
3.84k
    int64_t Offset = MCOperand_getImm(Op) * 4;
2038
3.84k
    if (MI->csh->PrintBranchImmAsAddress)
2039
3.84k
      printUInt64(O, (Address + Offset));
2040
0
    else {
2041
0
      printUInt64Bang(O, (Offset));
2042
0
    }
2043
3.84k
    SStream_concat0(O, markup(">"));
2044
3.84k
    return;
2045
3.84k
  }
2046
2047
143
  printUInt64Bang(O, MCOperand_getImm(Op));
2048
143
}
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.03k
{
2096
2.03k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_AdrAdrpLabel, OpNum);
2097
2.03k
  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.03k
  if (MCOperand_isImm(Op)) {
2102
2.03k
    int64_t Offset = MCOperand_getImm(Op);
2103
2.03k
    if (MCInst_getOpcode(MI) == AArch64_ADRP) {
2104
1.20k
      Offset = Offset * 4096;
2105
1.20k
      Address = Address & -4096;
2106
1.20k
    }
2107
2.03k
    SStream_concat0(O, markup(">"));
2108
2.03k
    if (MI->csh->PrintBranchImmAsAddress)
2109
2.03k
      printUInt64(O, (Address + Offset));
2110
0
    else {
2111
0
      printUInt64Bang(O, Offset);
2112
0
    }
2113
2.03k
    SStream_concat0(O, markup(">"));
2114
2.03k
    return;
2115
2.03k
  }
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
64
{
2125
64
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_AppleSysBarrierOption,
2126
64
        OpNo);
2127
64
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2128
64
  switch (Val) {
2129
32
  default:
2130
32
    SStream_concat0(O, "<undefined>");
2131
32
    break;
2132
10
  case 0:
2133
10
    SStream_concat0(O, "osh");
2134
10
    break;
2135
15
  case 1:
2136
15
    SStream_concat0(O, "nsh");
2137
15
    break;
2138
0
  case 2:
2139
0
    SStream_concat0(O, "ish");
2140
0
    break;
2141
7
  case 3:
2142
7
    SStream_concat0(O, "sy");
2143
7
    break;
2144
64
  }
2145
64
}
2146
2147
void printBarrierOption(MCInst *MI, unsigned OpNo, SStream *O)
2148
331
{
2149
331
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_BarrierOption, OpNo);
2150
331
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2151
331
  unsigned Opcode = MCInst_getOpcode(MI);
2152
2153
331
  const char *Name;
2154
331
  if (Opcode == AArch64_ISB) {
2155
17
    const AArch64ISB_ISB *ISB = AArch64ISB_lookupISBByEncoding(Val);
2156
17
    Name = ISB ? ISB->Name : "";
2157
314
  } else if (Opcode == AArch64_TSB) {
2158
30
    const AArch64TSB_TSB *TSB = AArch64TSB_lookupTSBByEncoding(Val);
2159
30
    Name = TSB ? TSB->Name : "";
2160
284
  } else {
2161
284
    const AArch64DB_DB *DB = AArch64DB_lookupDBByEncoding(Val);
2162
284
    Name = DB ? DB->Name : "";
2163
284
  }
2164
331
  if (Name[0] != '\0')
2165
76
    SStream_concat0(O, Name);
2166
255
  else {
2167
255
    SStream_concat(O, "%s", markup("<imm:"));
2168
255
    printUInt32Bang(O, Val);
2169
255
    SStream_concat0(O, markup(">"));
2170
255
  }
2171
331
}
2172
2173
void printBarriernXSOption(MCInst *MI, unsigned OpNo, SStream *O)
2174
105
{
2175
105
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_BarriernXSOption, OpNo);
2176
105
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2177
2178
105
  const char *Name;
2179
105
  const AArch64DBnXS_DBnXS *DB = AArch64DBnXS_lookupDBnXSByEncoding(Val);
2180
105
  Name = DB ? DB->Name : "";
2181
2182
105
  if (Name[0] != '\0')
2183
105
    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
105
}
2189
2190
static bool isValidSysReg(const AArch64SysReg_SysReg *Reg, bool Read,
2191
        unsigned mode)
2192
3.26k
{
2193
3.26k
  return (Reg && (Read ? Reg->Readable : Reg->Writeable) &&
2194
70
    AArch64_testFeatureList(mode, Reg->FeaturesRequired));
2195
3.26k
}
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
2.69k
{
2206
2.69k
  const AArch64SysReg_SysReg *Reg =
2207
2.69k
    AArch64SysReg_lookupSysRegByEncoding(Val);
2208
2209
2.69k
  if (Reg && !isValidSysReg(Reg, Read, mode))
2210
540
    Reg = AArch64SysReg_lookupSysRegByName(Reg->AltName);
2211
2212
2.69k
  return Reg;
2213
2.69k
}
2214
2215
void printMRSSystemRegister(MCInst *MI, unsigned OpNo, SStream *O)
2216
542
{
2217
542
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_MRSSystemRegister, OpNo);
2218
542
  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
542
  if (Val == AARCH64_SYSREG_DBGDTRRX_EL0) {
2224
14
    SStream_concat0(O, "DBGDTRRX_EL0");
2225
14
    return;
2226
14
  }
2227
2228
  // Horrible hack for two different registers having the same encoding.
2229
528
  if (Val == AARCH64_SYSREG_TRCEXTINSELR) {
2230
21
    SStream_concat0(O, "TRCEXTINSELR");
2231
21
    return;
2232
21
  }
2233
2234
507
  const AArch64SysReg_SysReg *Reg =
2235
507
    lookupSysReg(Val, true /*Read*/, MI->csh->mode);
2236
2237
507
  if (isValidSysReg(Reg, true /*Read*/, MI->csh->mode))
2238
14
    SStream_concat0(O, Reg->Name);
2239
493
  else {
2240
493
    char result[AARCH64_GRS_LEN + 1] = { 0 };
2241
493
    AArch64SysReg_genericRegisterString(Val, result);
2242
493
    SStream_concat0(O, result);
2243
493
  }
2244
507
}
2245
2246
void printMSRSystemRegister(MCInst *MI, unsigned OpNo, SStream *O)
2247
2.31k
{
2248
2.31k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_MSRSystemRegister, OpNo);
2249
2.31k
  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
2.31k
  if (Val == AARCH64_SYSREG_DBGDTRTX_EL0) {
2255
85
    SStream_concat0(O, "DBGDTRTX_EL0");
2256
85
    return;
2257
85
  }
2258
2259
  // Horrible hack for two different registers having the same encoding.
2260
2.22k
  if (Val == AARCH64_SYSREG_TRCEXTINSELR) {
2261
38
    SStream_concat0(O, "TRCEXTINSELR");
2262
38
    return;
2263
38
  }
2264
2265
2.18k
  const AArch64SysReg_SysReg *Reg =
2266
2.18k
    lookupSysReg(Val, false /*Read*/, MI->csh->mode);
2267
2268
2.18k
  if (isValidSysReg(Reg, false /*Read*/, MI->csh->mode))
2269
21
    SStream_concat0(O, Reg->Name);
2270
2.16k
  else {
2271
2.16k
    char result[AARCH64_GRS_LEN + 1] = { 0 };
2272
2.16k
    AArch64SysReg_genericRegisterString(Val, result);
2273
2.16k
    SStream_concat0(O, result);
2274
2.16k
  }
2275
2.18k
}
2276
2277
void printSystemPStateField(MCInst *MI, unsigned OpNo, SStream *O)
2278
471
{
2279
471
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_SystemPStateField, OpNo);
2280
471
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2281
2282
471
  const AArch64PState_PStateImm0_15 *PStateImm15 =
2283
471
    AArch64PState_lookupPStateImm0_15ByEncoding(Val);
2284
471
  const AArch64PState_PStateImm0_1 *PStateImm1 =
2285
471
    AArch64PState_lookupPStateImm0_1ByEncoding(Val);
2286
471
  if (PStateImm15 &&
2287
416
      AArch64_testFeatureList(MI->csh->mode,
2288
416
            PStateImm15->FeaturesRequired))
2289
416
    SStream_concat0(O, PStateImm15->Name);
2290
55
  else if (PStateImm1 &&
2291
55
     AArch64_testFeatureList(MI->csh->mode,
2292
55
           PStateImm1->FeaturesRequired))
2293
55
    SStream_concat0(O, PStateImm1->Name);
2294
0
  else {
2295
0
    printUInt32Bang(O, (Val));
2296
0
    SStream_concat1(O, '\0');
2297
0
  }
2298
471
}
2299
2300
void printSIMDType10Operand(MCInst *MI, unsigned OpNo, SStream *O)
2301
744
{
2302
744
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_SIMDType10Operand, OpNo);
2303
744
  unsigned RawVal = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2304
744
  uint64_t Val = AArch64_AM_decodeAdvSIMDModImmType10(RawVal);
2305
744
  SStream_concat(O, "%s#%#016llx", markup("<imm:"), Val);
2306
744
  SStream_concat0(O, markup(">"));
2307
744
}
2308
2309
#define DEFINE_printComplexRotationOp(Angle, Remainder) \
2310
  static void CONCAT(printComplexRotationOp, CONCAT(Angle, Remainder))( \
2311
    MCInst * MI, unsigned OpNo, SStream *O) \
2312
1.32k
  { \
2313
1.32k
    AArch64_add_cs_detail_2( \
2314
1.32k
      MI, \
2315
1.32k
      CONCAT(CONCAT(AArch64_OP_GROUP_ComplexRotationOp, \
2316
1.32k
              Angle), \
2317
1.32k
             Remainder), \
2318
1.32k
      OpNo, Angle, Remainder); \
2319
1.32k
    unsigned Val = \
2320
1.32k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); \
2321
1.32k
    SStream_concat(O, "%s", markup("<imm:")); \
2322
1.32k
    SStream_concat(O, "#%d", (Val * Angle) + Remainder); \
2323
1.32k
    SStream_concat0(O, markup(">")); \
2324
1.32k
  }
AArch64InstPrinter.c:printComplexRotationOp_180_90
Line
Count
Source
2312
271
  { \
2313
271
    AArch64_add_cs_detail_2( \
2314
271
      MI, \
2315
271
      CONCAT(CONCAT(AArch64_OP_GROUP_ComplexRotationOp, \
2316
271
              Angle), \
2317
271
             Remainder), \
2318
271
      OpNo, Angle, Remainder); \
2319
271
    unsigned Val = \
2320
271
      MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); \
2321
271
    SStream_concat(O, "%s", markup("<imm:")); \
2322
271
    SStream_concat(O, "#%d", (Val * Angle) + Remainder); \
2323
271
    SStream_concat0(O, markup(">")); \
2324
271
  }
AArch64InstPrinter.c:printComplexRotationOp_90_0
Line
Count
Source
2312
1.04k
  { \
2313
1.04k
    AArch64_add_cs_detail_2( \
2314
1.04k
      MI, \
2315
1.04k
      CONCAT(CONCAT(AArch64_OP_GROUP_ComplexRotationOp, \
2316
1.04k
              Angle), \
2317
1.04k
             Remainder), \
2318
1.04k
      OpNo, Angle, Remainder); \
2319
1.04k
    unsigned Val = \
2320
1.04k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); \
2321
1.04k
    SStream_concat(O, "%s", markup("<imm:")); \
2322
1.04k
    SStream_concat(O, "#%d", (Val * Angle) + Remainder); \
2323
1.04k
    SStream_concat0(O, markup(">")); \
2324
1.04k
  }
2325
DEFINE_printComplexRotationOp(180, 90);
2326
DEFINE_printComplexRotationOp(90, 0);
2327
2328
void printSVEPattern(MCInst *MI, unsigned OpNum, SStream *O)
2329
3.51k
{
2330
3.51k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_SVEPattern, OpNum);
2331
3.51k
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
2332
3.51k
  const AArch64SVEPredPattern_SVEPREDPAT *Pat =
2333
3.51k
    AArch64SVEPredPattern_lookupSVEPREDPATByEncoding(Val);
2334
3.51k
  if (Pat)
2335
2.22k
    SStream_concat0(O, Pat->Name);
2336
1.28k
  else
2337
1.28k
    printUInt32Bang(O, Val);
2338
3.51k
}
2339
2340
void printSVEVecLenSpecifier(MCInst *MI, unsigned OpNum, SStream *O)
2341
376
{
2342
376
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_SVEVecLenSpecifier, OpNum);
2343
376
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
2344
  // Pattern has only 1 bit
2345
376
  if (Val > 1)
2346
0
    CS_ASSERT_RET(0 && "Invalid vector length specifier");
2347
376
  const AArch64SVEVecLenSpecifier_SVEVECLENSPECIFIER *Pat =
2348
376
    AArch64SVEVecLenSpecifier_lookupSVEVECLENSPECIFIERByEncoding(
2349
376
      Val);
2350
376
  if (Pat)
2351
376
    SStream_concat0(O, Pat->Name);
2352
376
}
2353
2354
#define DEFINE_printSVERegOp(suffix) \
2355
  void CONCAT(printSVERegOp, suffix)(MCInst * MI, unsigned OpNum, \
2356
             SStream *O) \
2357
66.8k
  { \
2358
66.8k
    AArch64_add_cs_detail_1( \
2359
66.8k
      MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2360
66.8k
      CHAR(suffix)); \
2361
66.8k
    switch (CHAR(suffix)) { \
2362
21.8k
    case '0': \
2363
34.5k
    case 'b': \
2364
46.9k
    case 'h': \
2365
56.3k
    case 's': \
2366
66.4k
    case 'd': \
2367
66.8k
    case 'q': \
2368
66.8k
      break; \
2369
66.4k
    default: \
2370
0
      CS_ASSERT_RET(0 && "Invalid kind specifier."); \
2371
66.8k
    } \
2372
66.8k
\
2373
66.8k
    unsigned Reg = \
2374
66.8k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2375
66.8k
    printRegName(O, Reg); \
2376
66.8k
    if (CHAR(suffix) != '0') { \
2377
44.9k
      SStream_concat1(O, '.'); \
2378
44.9k
      SStream_concat1(O, CHAR(suffix)); \
2379
44.9k
    } \
2380
66.8k
  }
printSVERegOp_b
Line
Count
Source
2357
12.6k
  { \
2358
12.6k
    AArch64_add_cs_detail_1( \
2359
12.6k
      MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2360
12.6k
      CHAR(suffix)); \
2361
12.6k
    switch (CHAR(suffix)) { \
2362
0
    case '0': \
2363
12.6k
    case 'b': \
2364
12.6k
    case 'h': \
2365
12.6k
    case 's': \
2366
12.6k
    case 'd': \
2367
12.6k
    case 'q': \
2368
12.6k
      break; \
2369
12.6k
    default: \
2370
0
      CS_ASSERT_RET(0 && "Invalid kind specifier."); \
2371
12.6k
    } \
2372
12.6k
\
2373
12.6k
    unsigned Reg = \
2374
12.6k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2375
12.6k
    printRegName(O, Reg); \
2376
12.6k
    if (CHAR(suffix) != '0') { \
2377
12.6k
      SStream_concat1(O, '.'); \
2378
12.6k
      SStream_concat1(O, CHAR(suffix)); \
2379
12.6k
    } \
2380
12.6k
  }
printSVERegOp_d
Line
Count
Source
2357
10.0k
  { \
2358
10.0k
    AArch64_add_cs_detail_1( \
2359
10.0k
      MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2360
10.0k
      CHAR(suffix)); \
2361
10.0k
    switch (CHAR(suffix)) { \
2362
0
    case '0': \
2363
0
    case 'b': \
2364
0
    case 'h': \
2365
0
    case 's': \
2366
10.0k
    case 'd': \
2367
10.0k
    case 'q': \
2368
10.0k
      break; \
2369
10.0k
    default: \
2370
0
      CS_ASSERT_RET(0 && "Invalid kind specifier."); \
2371
10.0k
    } \
2372
10.0k
\
2373
10.0k
    unsigned Reg = \
2374
10.0k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2375
10.0k
    printRegName(O, Reg); \
2376
10.0k
    if (CHAR(suffix) != '0') { \
2377
10.0k
      SStream_concat1(O, '.'); \
2378
10.0k
      SStream_concat1(O, CHAR(suffix)); \
2379
10.0k
    } \
2380
10.0k
  }
printSVERegOp_h
Line
Count
Source
2357
12.3k
  { \
2358
12.3k
    AArch64_add_cs_detail_1( \
2359
12.3k
      MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2360
12.3k
      CHAR(suffix)); \
2361
12.3k
    switch (CHAR(suffix)) { \
2362
0
    case '0': \
2363
0
    case 'b': \
2364
12.3k
    case 'h': \
2365
12.3k
    case 's': \
2366
12.3k
    case 'd': \
2367
12.3k
    case 'q': \
2368
12.3k
      break; \
2369
12.3k
    default: \
2370
0
      CS_ASSERT_RET(0 && "Invalid kind specifier."); \
2371
12.3k
    } \
2372
12.3k
\
2373
12.3k
    unsigned Reg = \
2374
12.3k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2375
12.3k
    printRegName(O, Reg); \
2376
12.3k
    if (CHAR(suffix) != '0') { \
2377
12.3k
      SStream_concat1(O, '.'); \
2378
12.3k
      SStream_concat1(O, CHAR(suffix)); \
2379
12.3k
    } \
2380
12.3k
  }
printSVERegOp_s
Line
Count
Source
2357
9.49k
  { \
2358
9.49k
    AArch64_add_cs_detail_1( \
2359
9.49k
      MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2360
9.49k
      CHAR(suffix)); \
2361
9.49k
    switch (CHAR(suffix)) { \
2362
0
    case '0': \
2363
0
    case 'b': \
2364
0
    case 'h': \
2365
9.49k
    case 's': \
2366
9.49k
    case 'd': \
2367
9.49k
    case 'q': \
2368
9.49k
      break; \
2369
9.49k
    default: \
2370
0
      CS_ASSERT_RET(0 && "Invalid kind specifier."); \
2371
9.49k
    } \
2372
9.49k
\
2373
9.49k
    unsigned Reg = \
2374
9.49k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2375
9.49k
    printRegName(O, Reg); \
2376
9.49k
    if (CHAR(suffix) != '0') { \
2377
9.49k
      SStream_concat1(O, '.'); \
2378
9.49k
      SStream_concat1(O, CHAR(suffix)); \
2379
9.49k
    } \
2380
9.49k
  }
printSVERegOp_0
Line
Count
Source
2357
21.8k
  { \
2358
21.8k
    AArch64_add_cs_detail_1( \
2359
21.8k
      MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2360
21.8k
      CHAR(suffix)); \
2361
21.8k
    switch (CHAR(suffix)) { \
2362
21.8k
    case '0': \
2363
21.8k
    case 'b': \
2364
21.8k
    case 'h': \
2365
21.8k
    case 's': \
2366
21.8k
    case 'd': \
2367
21.8k
    case 'q': \
2368
21.8k
      break; \
2369
21.8k
    default: \
2370
0
      CS_ASSERT_RET(0 && "Invalid kind specifier."); \
2371
21.8k
    } \
2372
21.8k
\
2373
21.8k
    unsigned Reg = \
2374
21.8k
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2375
21.8k
    printRegName(O, Reg); \
2376
21.8k
    if (CHAR(suffix) != '0') { \
2377
0
      SStream_concat1(O, '.'); \
2378
0
      SStream_concat1(O, CHAR(suffix)); \
2379
0
    } \
2380
21.8k
  }
printSVERegOp_q
Line
Count
Source
2357
356
  { \
2358
356
    AArch64_add_cs_detail_1( \
2359
356
      MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2360
356
      CHAR(suffix)); \
2361
356
    switch (CHAR(suffix)) { \
2362
0
    case '0': \
2363
0
    case 'b': \
2364
0
    case 'h': \
2365
0
    case 's': \
2366
0
    case 'd': \
2367
356
    case 'q': \
2368
356
      break; \
2369
0
    default: \
2370
0
      CS_ASSERT_RET(0 && "Invalid kind specifier."); \
2371
356
    } \
2372
356
\
2373
356
    unsigned Reg = \
2374
356
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2375
356
    printRegName(O, Reg); \
2376
356
    if (CHAR(suffix) != '0') { \
2377
356
      SStream_concat1(O, '.'); \
2378
356
      SStream_concat1(O, CHAR(suffix)); \
2379
356
    } \
2380
356
  }
2381
DEFINE_printSVERegOp(b);
2382
DEFINE_printSVERegOp(d);
2383
DEFINE_printSVERegOp(h);
2384
DEFINE_printSVERegOp(s);
2385
DEFINE_printSVERegOp(0);
2386
DEFINE_printSVERegOp(q);
2387
2388
#define DECLARE_printImmSVE_S32(T) \
2389
  void CONCAT(printImmSVE, T)(T Val, SStream * O) \
2390
1.00k
  { \
2391
1.00k
    printInt32Bang(O, Val); \
2392
1.00k
  }
printImmSVE_int16_t
Line
Count
Source
2390
558
  { \
2391
558
    printInt32Bang(O, Val); \
2392
558
  }
printImmSVE_int8_t
Line
Count
Source
2390
340
  { \
2391
340
    printInt32Bang(O, Val); \
2392
340
  }
printImmSVE_int32_t
Line
Count
Source
2390
111
  { \
2391
111
    printInt32Bang(O, Val); \
2392
111
  }
2393
DECLARE_printImmSVE_S32(int16_t);
2394
DECLARE_printImmSVE_S32(int8_t);
2395
DECLARE_printImmSVE_S32(int32_t);
2396
2397
#define DECLARE_printImmSVE_U32(T) \
2398
  void CONCAT(printImmSVE, T)(T Val, SStream * O) \
2399
155
  { \
2400
155
    printUInt32Bang(O, Val); \
2401
155
  }
printImmSVE_uint16_t
Line
Count
Source
2399
36
  { \
2400
36
    printUInt32Bang(O, Val); \
2401
36
  }
printImmSVE_uint8_t
Line
Count
Source
2399
65
  { \
2400
65
    printUInt32Bang(O, Val); \
2401
65
  }
printImmSVE_uint32_t
Line
Count
Source
2399
54
  { \
2400
54
    printUInt32Bang(O, Val); \
2401
54
  }
2402
DECLARE_printImmSVE_U32(uint16_t);
2403
DECLARE_printImmSVE_U32(uint8_t);
2404
DECLARE_printImmSVE_U32(uint32_t);
2405
2406
#define DECLARE_printImmSVE_S64(T) \
2407
  void CONCAT(printImmSVE, T)(T Val, SStream * O) \
2408
161
  { \
2409
161
    printInt64Bang(O, Val); \
2410
161
  }
2411
DECLARE_printImmSVE_S64(int64_t);
2412
2413
#define DECLARE_printImmSVE_U64(T) \
2414
  void CONCAT(printImmSVE, T)(T Val, SStream * O) \
2415
54
  { \
2416
54
    printUInt64Bang(O, Val); \
2417
54
  }
2418
DECLARE_printImmSVE_U64(uint64_t);
2419
2420
#define DEFINE_isSignedType(T) \
2421
  static inline bool CONCAT(isSignedType, T)() \
2422
793
  { \
2423
793
    return CHAR(T) == 'i'; \
2424
793
  }
AArch64InstPrinter.c:isSignedType_int16_t
Line
Count
Source
2422
109
  { \
2423
109
    return CHAR(T) == 'i'; \
2424
109
  }
AArch64InstPrinter.c:isSignedType_int8_t
Line
Count
Source
2422
340
  { \
2423
340
    return CHAR(T) == 'i'; \
2424
340
  }
AArch64InstPrinter.c:isSignedType_int64_t
Line
Count
Source
2422
91
  { \
2423
91
    return CHAR(T) == 'i'; \
2424
91
  }
AArch64InstPrinter.c:isSignedType_int32_t
Line
Count
Source
2422
44
  { \
2423
44
    return CHAR(T) == 'i'; \
2424
44
  }
AArch64InstPrinter.c:isSignedType_uint16_t
Line
Count
Source
2422
36
  { \
2423
36
    return CHAR(T) == 'i'; \
2424
36
  }
AArch64InstPrinter.c:isSignedType_uint8_t
Line
Count
Source
2422
65
  { \
2423
65
    return CHAR(T) == 'i'; \
2424
65
  }
AArch64InstPrinter.c:isSignedType_uint64_t
Line
Count
Source
2422
54
  { \
2423
54
    return CHAR(T) == 'i'; \
2424
54
  }
AArch64InstPrinter.c:isSignedType_uint32_t
Line
Count
Source
2422
54
  { \
2423
54
    return CHAR(T) == 'i'; \
2424
54
  }
2425
DEFINE_isSignedType(int8_t);
2426
DEFINE_isSignedType(int16_t);
2427
DEFINE_isSignedType(int32_t);
2428
DEFINE_isSignedType(int64_t);
2429
DEFINE_isSignedType(uint8_t);
2430
DEFINE_isSignedType(uint16_t);
2431
DEFINE_isSignedType(uint32_t);
2432
DEFINE_isSignedType(uint64_t);
2433
2434
#define DEFINE_printImm8OptLsl(T) \
2435
  void CONCAT(printImm8OptLsl, T)(MCInst * MI, unsigned OpNum, \
2436
          SStream *O) \
2437
1.16k
  { \
2438
1.16k
    AArch64_add_cs_detail_1( \
2439
1.16k
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2440
1.16k
      sizeof(T)); \
2441
1.16k
    unsigned UnscaledVal = \
2442
1.16k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2443
1.16k
    unsigned Shift = \
2444
1.16k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2445
1.16k
\
2446
1.16k
    if ((UnscaledVal == 0) && \
2447
1.16k
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2448
367
      SStream_concat(O, "%s", markup("<imm:")); \
2449
367
      SStream_concat1(O, '#'); \
2450
367
      printUInt64(O, (UnscaledVal)); \
2451
367
      SStream_concat0(O, markup(">")); \
2452
367
      printShifter(MI, OpNum + 1, O); \
2453
367
      return; \
2454
367
    } \
2455
1.16k
\
2456
1.16k
    T Val; \
2457
793
    if (CONCAT(isSignedType, T)()) \
2458
793
      Val = (int8_t)UnscaledVal * \
2459
584
            (1 << AArch64_AM_getShiftValue(Shift)); \
2460
793
    else \
2461
793
      Val = (uint8_t)UnscaledVal * \
2462
209
            (1 << AArch64_AM_getShiftValue(Shift)); \
2463
793
\
2464
793
    CONCAT(printImmSVE, T)(Val, O); \
2465
793
  }
printImm8OptLsl_int16_t
Line
Count
Source
2437
144
  { \
2438
144
    AArch64_add_cs_detail_1( \
2439
144
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2440
144
      sizeof(T)); \
2441
144
    unsigned UnscaledVal = \
2442
144
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2443
144
    unsigned Shift = \
2444
144
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2445
144
\
2446
144
    if ((UnscaledVal == 0) && \
2447
144
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2448
35
      SStream_concat(O, "%s", markup("<imm:")); \
2449
35
      SStream_concat1(O, '#'); \
2450
35
      printUInt64(O, (UnscaledVal)); \
2451
35
      SStream_concat0(O, markup(">")); \
2452
35
      printShifter(MI, OpNum + 1, O); \
2453
35
      return; \
2454
35
    } \
2455
144
\
2456
144
    T Val; \
2457
109
    if (CONCAT(isSignedType, T)()) \
2458
109
      Val = (int8_t)UnscaledVal * \
2459
109
            (1 << AArch64_AM_getShiftValue(Shift)); \
2460
109
    else \
2461
109
      Val = (uint8_t)UnscaledVal * \
2462
0
            (1 << AArch64_AM_getShiftValue(Shift)); \
2463
109
\
2464
109
    CONCAT(printImmSVE, T)(Val, O); \
2465
109
  }
printImm8OptLsl_int8_t
Line
Count
Source
2437
340
  { \
2438
340
    AArch64_add_cs_detail_1( \
2439
340
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2440
340
      sizeof(T)); \
2441
340
    unsigned UnscaledVal = \
2442
340
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2443
340
    unsigned Shift = \
2444
340
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2445
340
\
2446
340
    if ((UnscaledVal == 0) && \
2447
340
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2448
0
      SStream_concat(O, "%s", markup("<imm:")); \
2449
0
      SStream_concat1(O, '#'); \
2450
0
      printUInt64(O, (UnscaledVal)); \
2451
0
      SStream_concat0(O, markup(">")); \
2452
0
      printShifter(MI, OpNum + 1, O); \
2453
0
      return; \
2454
0
    } \
2455
340
\
2456
340
    T Val; \
2457
340
    if (CONCAT(isSignedType, T)()) \
2458
340
      Val = (int8_t)UnscaledVal * \
2459
340
            (1 << AArch64_AM_getShiftValue(Shift)); \
2460
340
    else \
2461
340
      Val = (uint8_t)UnscaledVal * \
2462
0
            (1 << AArch64_AM_getShiftValue(Shift)); \
2463
340
\
2464
340
    CONCAT(printImmSVE, T)(Val, O); \
2465
340
  }
printImm8OptLsl_int64_t
Line
Count
Source
2437
91
  { \
2438
91
    AArch64_add_cs_detail_1( \
2439
91
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2440
91
      sizeof(T)); \
2441
91
    unsigned UnscaledVal = \
2442
91
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2443
91
    unsigned Shift = \
2444
91
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2445
91
\
2446
91
    if ((UnscaledVal == 0) && \
2447
91
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2448
0
      SStream_concat(O, "%s", markup("<imm:")); \
2449
0
      SStream_concat1(O, '#'); \
2450
0
      printUInt64(O, (UnscaledVal)); \
2451
0
      SStream_concat0(O, markup(">")); \
2452
0
      printShifter(MI, OpNum + 1, O); \
2453
0
      return; \
2454
0
    } \
2455
91
\
2456
91
    T Val; \
2457
91
    if (CONCAT(isSignedType, T)()) \
2458
91
      Val = (int8_t)UnscaledVal * \
2459
91
            (1 << AArch64_AM_getShiftValue(Shift)); \
2460
91
    else \
2461
91
      Val = (uint8_t)UnscaledVal * \
2462
0
            (1 << AArch64_AM_getShiftValue(Shift)); \
2463
91
\
2464
91
    CONCAT(printImmSVE, T)(Val, O); \
2465
91
  }
printImm8OptLsl_int32_t
Line
Count
Source
2437
83
  { \
2438
83
    AArch64_add_cs_detail_1( \
2439
83
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2440
83
      sizeof(T)); \
2441
83
    unsigned UnscaledVal = \
2442
83
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2443
83
    unsigned Shift = \
2444
83
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2445
83
\
2446
83
    if ((UnscaledVal == 0) && \
2447
83
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2448
39
      SStream_concat(O, "%s", markup("<imm:")); \
2449
39
      SStream_concat1(O, '#'); \
2450
39
      printUInt64(O, (UnscaledVal)); \
2451
39
      SStream_concat0(O, markup(">")); \
2452
39
      printShifter(MI, OpNum + 1, O); \
2453
39
      return; \
2454
39
    } \
2455
83
\
2456
83
    T Val; \
2457
44
    if (CONCAT(isSignedType, T)()) \
2458
44
      Val = (int8_t)UnscaledVal * \
2459
44
            (1 << AArch64_AM_getShiftValue(Shift)); \
2460
44
    else \
2461
44
      Val = (uint8_t)UnscaledVal * \
2462
0
            (1 << AArch64_AM_getShiftValue(Shift)); \
2463
44
\
2464
44
    CONCAT(printImmSVE, T)(Val, O); \
2465
44
  }
printImm8OptLsl_uint16_t
Line
Count
Source
2437
44
  { \
2438
44
    AArch64_add_cs_detail_1( \
2439
44
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2440
44
      sizeof(T)); \
2441
44
    unsigned UnscaledVal = \
2442
44
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2443
44
    unsigned Shift = \
2444
44
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2445
44
\
2446
44
    if ((UnscaledVal == 0) && \
2447
44
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2448
8
      SStream_concat(O, "%s", markup("<imm:")); \
2449
8
      SStream_concat1(O, '#'); \
2450
8
      printUInt64(O, (UnscaledVal)); \
2451
8
      SStream_concat0(O, markup(">")); \
2452
8
      printShifter(MI, OpNum + 1, O); \
2453
8
      return; \
2454
8
    } \
2455
44
\
2456
44
    T Val; \
2457
36
    if (CONCAT(isSignedType, T)()) \
2458
36
      Val = (int8_t)UnscaledVal * \
2459
0
            (1 << AArch64_AM_getShiftValue(Shift)); \
2460
36
    else \
2461
36
      Val = (uint8_t)UnscaledVal * \
2462
36
            (1 << AArch64_AM_getShiftValue(Shift)); \
2463
36
\
2464
36
    CONCAT(printImmSVE, T)(Val, O); \
2465
36
  }
printImm8OptLsl_uint8_t
Line
Count
Source
2437
65
  { \
2438
65
    AArch64_add_cs_detail_1( \
2439
65
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2440
65
      sizeof(T)); \
2441
65
    unsigned UnscaledVal = \
2442
65
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2443
65
    unsigned Shift = \
2444
65
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2445
65
\
2446
65
    if ((UnscaledVal == 0) && \
2447
65
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2448
0
      SStream_concat(O, "%s", markup("<imm:")); \
2449
0
      SStream_concat1(O, '#'); \
2450
0
      printUInt64(O, (UnscaledVal)); \
2451
0
      SStream_concat0(O, markup(">")); \
2452
0
      printShifter(MI, OpNum + 1, O); \
2453
0
      return; \
2454
0
    } \
2455
65
\
2456
65
    T Val; \
2457
65
    if (CONCAT(isSignedType, T)()) \
2458
65
      Val = (int8_t)UnscaledVal * \
2459
0
            (1 << AArch64_AM_getShiftValue(Shift)); \
2460
65
    else \
2461
65
      Val = (uint8_t)UnscaledVal * \
2462
65
            (1 << AArch64_AM_getShiftValue(Shift)); \
2463
65
\
2464
65
    CONCAT(printImmSVE, T)(Val, O); \
2465
65
  }
printImm8OptLsl_uint64_t
Line
Count
Source
2437
157
  { \
2438
157
    AArch64_add_cs_detail_1( \
2439
157
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2440
157
      sizeof(T)); \
2441
157
    unsigned UnscaledVal = \
2442
157
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2443
157
    unsigned Shift = \
2444
157
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2445
157
\
2446
157
    if ((UnscaledVal == 0) && \
2447
157
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2448
103
      SStream_concat(O, "%s", markup("<imm:")); \
2449
103
      SStream_concat1(O, '#'); \
2450
103
      printUInt64(O, (UnscaledVal)); \
2451
103
      SStream_concat0(O, markup(">")); \
2452
103
      printShifter(MI, OpNum + 1, O); \
2453
103
      return; \
2454
103
    } \
2455
157
\
2456
157
    T Val; \
2457
54
    if (CONCAT(isSignedType, T)()) \
2458
54
      Val = (int8_t)UnscaledVal * \
2459
0
            (1 << AArch64_AM_getShiftValue(Shift)); \
2460
54
    else \
2461
54
      Val = (uint8_t)UnscaledVal * \
2462
54
            (1 << AArch64_AM_getShiftValue(Shift)); \
2463
54
\
2464
54
    CONCAT(printImmSVE, T)(Val, O); \
2465
54
  }
printImm8OptLsl_uint32_t
Line
Count
Source
2437
236
  { \
2438
236
    AArch64_add_cs_detail_1( \
2439
236
      MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, \
2440
236
      sizeof(T)); \
2441
236
    unsigned UnscaledVal = \
2442
236
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2443
236
    unsigned Shift = \
2444
236
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2445
236
\
2446
236
    if ((UnscaledVal == 0) && \
2447
236
        (AArch64_AM_getShiftValue(Shift) != 0)) { \
2448
182
      SStream_concat(O, "%s", markup("<imm:")); \
2449
182
      SStream_concat1(O, '#'); \
2450
182
      printUInt64(O, (UnscaledVal)); \
2451
182
      SStream_concat0(O, markup(">")); \
2452
182
      printShifter(MI, OpNum + 1, O); \
2453
182
      return; \
2454
182
    } \
2455
236
\
2456
236
    T Val; \
2457
54
    if (CONCAT(isSignedType, T)()) \
2458
54
      Val = (int8_t)UnscaledVal * \
2459
0
            (1 << AArch64_AM_getShiftValue(Shift)); \
2460
54
    else \
2461
54
      Val = (uint8_t)UnscaledVal * \
2462
54
            (1 << AArch64_AM_getShiftValue(Shift)); \
2463
54
\
2464
54
    CONCAT(printImmSVE, T)(Val, O); \
2465
54
  }
2466
DEFINE_printImm8OptLsl(int16_t);
2467
DEFINE_printImm8OptLsl(int8_t);
2468
DEFINE_printImm8OptLsl(int64_t);
2469
DEFINE_printImm8OptLsl(int32_t);
2470
DEFINE_printImm8OptLsl(uint16_t);
2471
DEFINE_printImm8OptLsl(uint8_t);
2472
DEFINE_printImm8OptLsl(uint64_t);
2473
DEFINE_printImm8OptLsl(uint32_t);
2474
2475
#define DEFINE_printSVELogicalImm(T) \
2476
  void CONCAT(printSVELogicalImm, T)(MCInst * MI, unsigned OpNum, \
2477
             SStream *O) \
2478
1.03k
  { \
2479
1.03k
    AArch64_add_cs_detail_1( \
2480
1.03k
      MI, CONCAT(AArch64_OP_GROUP_SVELogicalImm, T), OpNum, \
2481
1.03k
      sizeof(T)); \
2482
1.03k
    typedef T SignedT; \
2483
1.03k
    typedef CONCATS(u, T) UnsignedT; \
2484
1.03k
\
2485
1.03k
    uint64_t Val = \
2486
1.03k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2487
1.03k
    UnsignedT PrintVal = \
2488
1.03k
      AArch64_AM_decodeLogicalImmediate(Val, 64); \
2489
1.03k
\
2490
1.03k
    if ((int16_t)PrintVal == (SignedT)PrintVal) \
2491
1.03k
      CONCAT(printImmSVE, T)((T)PrintVal, O); \
2492
1.03k
    else if ((uint16_t)PrintVal == PrintVal) \
2493
505
      CONCAT(printImmSVE, T)(PrintVal, O); \
2494
505
    else { \
2495
451
      SStream_concat(O, "%s", markup("<imm:")); \
2496
451
      printUInt64Bang(O, ((uint64_t)PrintVal)); \
2497
451
      SStream_concat0(O, markup(">")); \
2498
451
    } \
2499
1.03k
  }
printSVELogicalImm_int16_t
Line
Count
Source
2478
449
  { \
2479
449
    AArch64_add_cs_detail_1( \
2480
449
      MI, CONCAT(AArch64_OP_GROUP_SVELogicalImm, T), OpNum, \
2481
449
      sizeof(T)); \
2482
449
    typedef T SignedT; \
2483
449
    typedef CONCATS(u, T) UnsignedT; \
2484
449
\
2485
449
    uint64_t Val = \
2486
449
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2487
449
    UnsignedT PrintVal = \
2488
449
      AArch64_AM_decodeLogicalImmediate(Val, 64); \
2489
449
\
2490
449
    if ((int16_t)PrintVal == (SignedT)PrintVal) \
2491
449
      CONCAT(printImmSVE, T)((T)PrintVal, O); \
2492
449
    else if ((uint16_t)PrintVal == PrintVal) \
2493
0
      CONCAT(printImmSVE, T)(PrintVal, O); \
2494
0
    else { \
2495
0
      SStream_concat(O, "%s", markup("<imm:")); \
2496
0
      printUInt64Bang(O, ((uint64_t)PrintVal)); \
2497
0
      SStream_concat0(O, markup(">")); \
2498
0
    } \
2499
449
  }
printSVELogicalImm_int32_t
Line
Count
Source
2478
444
  { \
2479
444
    AArch64_add_cs_detail_1( \
2480
444
      MI, CONCAT(AArch64_OP_GROUP_SVELogicalImm, T), OpNum, \
2481
444
      sizeof(T)); \
2482
444
    typedef T SignedT; \
2483
444
    typedef CONCATS(u, T) UnsignedT; \
2484
444
\
2485
444
    uint64_t Val = \
2486
444
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2487
444
    UnsignedT PrintVal = \
2488
444
      AArch64_AM_decodeLogicalImmediate(Val, 64); \
2489
444
\
2490
444
    if ((int16_t)PrintVal == (SignedT)PrintVal) \
2491
444
      CONCAT(printImmSVE, T)((T)PrintVal, O); \
2492
444
    else if ((uint16_t)PrintVal == PrintVal) \
2493
424
      CONCAT(printImmSVE, T)(PrintVal, O); \
2494
424
    else { \
2495
377
      SStream_concat(O, "%s", markup("<imm:")); \
2496
377
      printUInt64Bang(O, ((uint64_t)PrintVal)); \
2497
377
      SStream_concat0(O, markup(">")); \
2498
377
    } \
2499
444
  }
printSVELogicalImm_int64_t
Line
Count
Source
2478
144
  { \
2479
144
    AArch64_add_cs_detail_1( \
2480
144
      MI, CONCAT(AArch64_OP_GROUP_SVELogicalImm, T), OpNum, \
2481
144
      sizeof(T)); \
2482
144
    typedef T SignedT; \
2483
144
    typedef CONCATS(u, T) UnsignedT; \
2484
144
\
2485
144
    uint64_t Val = \
2486
144
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2487
144
    UnsignedT PrintVal = \
2488
144
      AArch64_AM_decodeLogicalImmediate(Val, 64); \
2489
144
\
2490
144
    if ((int16_t)PrintVal == (SignedT)PrintVal) \
2491
144
      CONCAT(printImmSVE, T)((T)PrintVal, O); \
2492
144
    else if ((uint16_t)PrintVal == PrintVal) \
2493
81
      CONCAT(printImmSVE, T)(PrintVal, O); \
2494
81
    else { \
2495
74
      SStream_concat(O, "%s", markup("<imm:")); \
2496
74
      printUInt64Bang(O, ((uint64_t)PrintVal)); \
2497
74
      SStream_concat0(O, markup(">")); \
2498
74
    } \
2499
144
  }
2500
DEFINE_printSVELogicalImm(int16_t);
2501
DEFINE_printSVELogicalImm(int32_t);
2502
DEFINE_printSVELogicalImm(int64_t);
2503
2504
#define DEFINE_printZPRasFPR(Width) \
2505
  void CONCAT(printZPRasFPR, Width)(MCInst * MI, unsigned OpNum, \
2506
            SStream *O) \
2507
644
  { \
2508
644
    AArch64_add_cs_detail_1( \
2509
644
      MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2510
644
      Width); \
2511
644
    unsigned Base; \
2512
644
    switch (Width) { \
2513
50
    case 8: \
2514
50
      Base = AArch64_B0; \
2515
50
      break; \
2516
38
    case 16: \
2517
38
      Base = AArch64_H0; \
2518
38
      break; \
2519
235
    case 32: \
2520
235
      Base = AArch64_S0; \
2521
235
      break; \
2522
321
    case 64: \
2523
321
      Base = AArch64_D0; \
2524
321
      break; \
2525
0
    case 128: \
2526
0
      Base = AArch64_Q0; \
2527
0
      break; \
2528
0
    default: \
2529
0
      CS_ASSERT_RET(0 && "Unsupported width"); \
2530
644
    } \
2531
644
    unsigned Reg = \
2532
644
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2533
644
    printRegName(O, Reg - AArch64_Z0 + Base); \
2534
644
  }
printZPRasFPR_8
Line
Count
Source
2507
50
  { \
2508
50
    AArch64_add_cs_detail_1( \
2509
50
      MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2510
50
      Width); \
2511
50
    unsigned Base; \
2512
50
    switch (Width) { \
2513
50
    case 8: \
2514
50
      Base = AArch64_B0; \
2515
50
      break; \
2516
0
    case 16: \
2517
0
      Base = AArch64_H0; \
2518
0
      break; \
2519
0
    case 32: \
2520
0
      Base = AArch64_S0; \
2521
0
      break; \
2522
0
    case 64: \
2523
0
      Base = AArch64_D0; \
2524
0
      break; \
2525
0
    case 128: \
2526
0
      Base = AArch64_Q0; \
2527
0
      break; \
2528
0
    default: \
2529
0
      CS_ASSERT_RET(0 && "Unsupported width"); \
2530
50
    } \
2531
50
    unsigned Reg = \
2532
50
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2533
50
    printRegName(O, Reg - AArch64_Z0 + Base); \
2534
50
  }
printZPRasFPR_64
Line
Count
Source
2507
321
  { \
2508
321
    AArch64_add_cs_detail_1( \
2509
321
      MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2510
321
      Width); \
2511
321
    unsigned Base; \
2512
321
    switch (Width) { \
2513
0
    case 8: \
2514
0
      Base = AArch64_B0; \
2515
0
      break; \
2516
0
    case 16: \
2517
0
      Base = AArch64_H0; \
2518
0
      break; \
2519
0
    case 32: \
2520
0
      Base = AArch64_S0; \
2521
0
      break; \
2522
321
    case 64: \
2523
321
      Base = AArch64_D0; \
2524
321
      break; \
2525
0
    case 128: \
2526
0
      Base = AArch64_Q0; \
2527
0
      break; \
2528
0
    default: \
2529
0
      CS_ASSERT_RET(0 && "Unsupported width"); \
2530
321
    } \
2531
321
    unsigned Reg = \
2532
321
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2533
321
    printRegName(O, Reg - AArch64_Z0 + Base); \
2534
321
  }
printZPRasFPR_16
Line
Count
Source
2507
38
  { \
2508
38
    AArch64_add_cs_detail_1( \
2509
38
      MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2510
38
      Width); \
2511
38
    unsigned Base; \
2512
38
    switch (Width) { \
2513
0
    case 8: \
2514
0
      Base = AArch64_B0; \
2515
0
      break; \
2516
38
    case 16: \
2517
38
      Base = AArch64_H0; \
2518
38
      break; \
2519
0
    case 32: \
2520
0
      Base = AArch64_S0; \
2521
0
      break; \
2522
0
    case 64: \
2523
0
      Base = AArch64_D0; \
2524
0
      break; \
2525
0
    case 128: \
2526
0
      Base = AArch64_Q0; \
2527
0
      break; \
2528
0
    default: \
2529
0
      CS_ASSERT_RET(0 && "Unsupported width"); \
2530
38
    } \
2531
38
    unsigned Reg = \
2532
38
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2533
38
    printRegName(O, Reg - AArch64_Z0 + Base); \
2534
38
  }
printZPRasFPR_32
Line
Count
Source
2507
235
  { \
2508
235
    AArch64_add_cs_detail_1( \
2509
235
      MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2510
235
      Width); \
2511
235
    unsigned Base; \
2512
235
    switch (Width) { \
2513
0
    case 8: \
2514
0
      Base = AArch64_B0; \
2515
0
      break; \
2516
0
    case 16: \
2517
0
      Base = AArch64_H0; \
2518
0
      break; \
2519
235
    case 32: \
2520
235
      Base = AArch64_S0; \
2521
235
      break; \
2522
0
    case 64: \
2523
0
      Base = AArch64_D0; \
2524
0
      break; \
2525
0
    case 128: \
2526
0
      Base = AArch64_Q0; \
2527
0
      break; \
2528
0
    default: \
2529
0
      CS_ASSERT_RET(0 && "Unsupported width"); \
2530
235
    } \
2531
235
    unsigned Reg = \
2532
235
      MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2533
235
    printRegName(O, Reg - AArch64_Z0 + Base); \
2534
235
  }
Unexecuted instantiation: printZPRasFPR_128
2535
DEFINE_printZPRasFPR(8);
2536
DEFINE_printZPRasFPR(64);
2537
DEFINE_printZPRasFPR(16);
2538
DEFINE_printZPRasFPR(32);
2539
DEFINE_printZPRasFPR(128);
2540
2541
#define DEFINE_printExactFPImm(ImmIs0, ImmIs1) \
2542
  void CONCAT(printExactFPImm, CONCAT(ImmIs0, ImmIs1))( \
2543
    MCInst * MI, unsigned OpNum, SStream *O) \
2544
934
  { \
2545
934
    AArch64_add_cs_detail_2( \
2546
934
      MI, \
2547
934
      CONCAT(CONCAT(AArch64_OP_GROUP_ExactFPImm, ImmIs0), \
2548
934
             ImmIs1), \
2549
934
      OpNum, ImmIs0, ImmIs1); \
2550
934
    const AArch64ExactFPImm_ExactFPImm *Imm0Desc = \
2551
934
      AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs0); \
2552
934
    const AArch64ExactFPImm_ExactFPImm *Imm1Desc = \
2553
934
      AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs1); \
2554
934
    unsigned Val = \
2555
934
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2556
934
    SStream_concat(O, "%s%s%s", markup("<imm:"), "#", \
2557
934
             (Val ? Imm1Desc->Repr : Imm0Desc->Repr)); \
2558
934
    SStream_concat0(O, markup(">")); \
2559
934
  }
printExactFPImm_AArch64ExactFPImm_half_AArch64ExactFPImm_one
Line
Count
Source
2544
75
  { \
2545
75
    AArch64_add_cs_detail_2( \
2546
75
      MI, \
2547
75
      CONCAT(CONCAT(AArch64_OP_GROUP_ExactFPImm, ImmIs0), \
2548
75
             ImmIs1), \
2549
75
      OpNum, ImmIs0, ImmIs1); \
2550
75
    const AArch64ExactFPImm_ExactFPImm *Imm0Desc = \
2551
75
      AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs0); \
2552
75
    const AArch64ExactFPImm_ExactFPImm *Imm1Desc = \
2553
75
      AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs1); \
2554
75
    unsigned Val = \
2555
75
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2556
75
    SStream_concat(O, "%s%s%s", markup("<imm:"), "#", \
2557
75
             (Val ? Imm1Desc->Repr : Imm0Desc->Repr)); \
2558
75
    SStream_concat0(O, markup(">")); \
2559
75
  }
printExactFPImm_AArch64ExactFPImm_zero_AArch64ExactFPImm_one
Line
Count
Source
2544
74
  { \
2545
74
    AArch64_add_cs_detail_2( \
2546
74
      MI, \
2547
74
      CONCAT(CONCAT(AArch64_OP_GROUP_ExactFPImm, ImmIs0), \
2548
74
             ImmIs1), \
2549
74
      OpNum, ImmIs0, ImmIs1); \
2550
74
    const AArch64ExactFPImm_ExactFPImm *Imm0Desc = \
2551
74
      AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs0); \
2552
74
    const AArch64ExactFPImm_ExactFPImm *Imm1Desc = \
2553
74
      AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs1); \
2554
74
    unsigned Val = \
2555
74
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2556
74
    SStream_concat(O, "%s%s%s", markup("<imm:"), "#", \
2557
74
             (Val ? Imm1Desc->Repr : Imm0Desc->Repr)); \
2558
74
    SStream_concat0(O, markup(">")); \
2559
74
  }
printExactFPImm_AArch64ExactFPImm_half_AArch64ExactFPImm_two
Line
Count
Source
2544
785
  { \
2545
785
    AArch64_add_cs_detail_2( \
2546
785
      MI, \
2547
785
      CONCAT(CONCAT(AArch64_OP_GROUP_ExactFPImm, ImmIs0), \
2548
785
             ImmIs1), \
2549
785
      OpNum, ImmIs0, ImmIs1); \
2550
785
    const AArch64ExactFPImm_ExactFPImm *Imm0Desc = \
2551
785
      AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs0); \
2552
785
    const AArch64ExactFPImm_ExactFPImm *Imm1Desc = \
2553
785
      AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs1); \
2554
785
    unsigned Val = \
2555
785
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2556
785
    SStream_concat(O, "%s%s%s", markup("<imm:"), "#", \
2557
785
             (Val ? Imm1Desc->Repr : Imm0Desc->Repr)); \
2558
785
    SStream_concat0(O, markup(">")); \
2559
785
  }
2560
DEFINE_printExactFPImm(AArch64ExactFPImm_half, AArch64ExactFPImm_one);
2561
DEFINE_printExactFPImm(AArch64ExactFPImm_zero, AArch64ExactFPImm_one);
2562
DEFINE_printExactFPImm(AArch64ExactFPImm_half, AArch64ExactFPImm_two);
2563
2564
void printGPR64as32(MCInst *MI, unsigned OpNum, SStream *O)
2565
3.27k
{
2566
3.27k
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_GPR64as32, OpNum);
2567
3.27k
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum)));
2568
3.27k
  printRegName(O, getWRegFromXReg(Reg));
2569
3.27k
}
2570
2571
void printGPR64x8(MCInst *MI, unsigned OpNum, SStream *O)
2572
202
{
2573
202
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_GPR64x8, OpNum);
2574
202
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum)));
2575
202
  printRegName(O,
2576
202
         MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_x8sub_0));
2577
202
}
2578
2579
void printSyspXzrPair(MCInst *MI, unsigned OpNum, SStream *O)
2580
230
{
2581
230
  AArch64_add_cs_detail_0(MI, AArch64_OP_GROUP_SyspXzrPair, OpNum);
2582
230
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum)));
2583
2584
230
  SStream_concat(O, "%s%s", getRegisterName(Reg, AArch64_NoRegAltName),
2585
230
           ", ");
2586
230
  SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));
2587
230
}
2588
2589
const char *AArch64_LLVM_getRegisterName(unsigned RegNo, unsigned AltIdx)
2590
72.6k
{
2591
72.6k
  return getRegisterName(RegNo, AltIdx);
2592
72.6k
}
2593
2594
void AArch64_LLVM_printInstruction(MCInst *MI, SStream *O,
2595
           void * /* MCRegisterInfo* */ info)
2596
123k
{
2597
123k
  printInst(MI, MI->address, "", O);
2598
123k
}