Coverage Report

Created: 2025-11-09 07:00

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