Coverage Report

Created: 2026-11-12 06:22

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