Coverage Report

Created: 2023-12-08 06:05

/src/capstonenext/arch/AArch64/AArch64InstPrinter.c
Line
Count
Source (jump to first uncovered line)
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 <capstone/platform.h>
28
#include <ctype.h>
29
#include <stdio.h>
30
#include <stdlib.h>
31
#include <string.h>
32
33
#include "../../Mapping.h"
34
#include "../../MCInst.h"
35
#include "../../MCInstPrinter.h"
36
#include "../../MCRegisterInfo.h"
37
#include "../../SStream.h"
38
#include "../../utils.h"
39
#include "AArch64AddressingModes.h"
40
#include "AArch64BaseInfo.h"
41
#include "AArch64DisassemblerExtension.h"
42
#include "AArch64InstPrinter.h"
43
#include "AArch64Linkage.h"
44
#include "AArch64Mapping.h"
45
46
#define GET_BANKEDREG_IMPL
47
#include "AArch64GenSystemOperands.inc"
48
49
230k
#define CONCAT(a, b) CONCAT_(a, b)
50
230k
#define CONCAT_(a, b) a##_##b
51
52
#define CONCATs(a, b) CONCATS(a, b)
53
#define CONCATS(a, b) a##b
54
55
#define DEBUG_TYPE "asm-printer"
56
57
static void printCustomAliasOperand(
58
         MCInst *MI, uint64_t Address, unsigned OpIdx,
59
         unsigned PrintMethodIdx,
60
         SStream *OS);
61
62
#define DECLARE_printComplexRotationOp(Angle, Remainder) \
63
  static void CONCAT(printComplexRotationOp, CONCAT(Angle, Remainder))( \
64
    MCInst * MI, unsigned OpNo, SStream *O);
65
DECLARE_printComplexRotationOp(180, 90);
66
DECLARE_printComplexRotationOp(90, 0);
67
68
static void printFPImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
69
70
#define GET_INSTRUCTION_NAME
71
#define PRINT_ALIAS_INSTR
72
#include "AArch64GenAsmWriter.inc"
73
74
void printRegName(SStream *OS, unsigned Reg)
75
401k
{
76
401k
  SStream_concat(OS, "%s%s", markup("<reg:"), getRegisterName(Reg, AArch64_NoRegAltName));
77
401k
  SStream_concat0(OS, markup(">"));
78
401k
}
79
80
void printRegNameAlt(SStream *OS, unsigned Reg, unsigned AltIdx)
81
80.8k
{
82
80.8k
  SStream_concat(OS, "%s%s", markup("<reg:"), getRegisterName(Reg, AltIdx));
83
80.8k
  SStream_concat0(OS, markup(">"));
84
80.8k
}
85
86
0
const char *getRegName(unsigned Reg) { return getRegisterName(Reg, AArch64_NoRegAltName); }
87
88
void printInst(MCInst *MI, uint64_t Address, const char *Annot, SStream *O)
89
204k
{
90
204k
  bool isAlias = false;
91
204k
  bool useAliasDetails = map_use_alias_details(MI);
92
204k
  map_set_fill_detail_ops(MI, useAliasDetails);
93
94
204k
  unsigned Opcode = MCInst_getOpcode(MI);
95
96
204k
  if (Opcode == AArch64_SYSxt) {
97
2.15k
    if (printSysAlias(MI, O)) {
98
486
      isAlias = true;
99
486
      MCInst_setIsAlias(MI, isAlias);
100
486
      if (useAliasDetails)
101
486
        return;
102
486
    }
103
2.15k
  }
104
105
203k
  if (Opcode == AArch64_SYSPxt || Opcode == AArch64_SYSPxt_XZR) {
106
1.30k
    if (printSyspAlias(MI, O)) {
107
488
      isAlias = true;
108
488
      MCInst_setIsAlias(MI, isAlias);
109
488
      if (useAliasDetails)
110
488
        return;
111
488
    }
112
1.30k
  }
113
114
  // RPRFM overlaps PRFM (reg), so try to print it as RPRFM here.
115
203k
  if ((Opcode == AArch64_PRFMroX) || (Opcode == AArch64_PRFMroW)) {
116
120
    if (printRangePrefetchAlias(MI, O, Annot)) {
117
0
      isAlias = true;
118
0
      MCInst_setIsAlias(MI, isAlias);
119
0
      if (useAliasDetails)
120
0
        return;
121
0
    }
122
120
  }
123
124
  // SBFM/UBFM should print to a nicer aliased form if possible.
125
203k
  if (Opcode == AArch64_SBFMXri || Opcode == AArch64_SBFMWri ||
126
203k
    Opcode == AArch64_UBFMXri || Opcode == AArch64_UBFMWri) {
127
4.08k
    MCOperand *Op0 = MCInst_getOperand(MI, (0));
128
4.08k
    MCOperand *Op1 = MCInst_getOperand(MI, (1));
129
4.08k
    MCOperand *Op2 = MCInst_getOperand(MI, (2));
130
4.08k
    MCOperand *Op3 = MCInst_getOperand(MI, (3));
131
132
4.08k
    bool IsSigned =
133
4.08k
      (Opcode == AArch64_SBFMXri || Opcode == AArch64_SBFMWri);
134
4.08k
    bool Is64Bit = (Opcode == AArch64_SBFMXri || Opcode == AArch64_UBFMXri);
135
4.08k
    if (MCOperand_isImm(Op2) && MCOperand_getImm(Op2) == 0 &&
136
4.08k
      MCOperand_isImm(Op3)) {
137
3.43k
      const char *AsmMnemonic = NULL;
138
139
3.43k
      switch (MCOperand_getImm(Op3)) {
140
968
      default:
141
968
        break;
142
968
      case 7:
143
389
        if (IsSigned)
144
367
          AsmMnemonic = "sxtb";
145
22
        else if (!Is64Bit)
146
10
          AsmMnemonic = "uxtb";
147
389
        break;
148
1.56k
      case 15:
149
1.56k
        if (IsSigned)
150
1.51k
          AsmMnemonic = "sxth";
151
45
        else if (!Is64Bit)
152
11
          AsmMnemonic = "uxth";
153
1.56k
        break;
154
513
      case 31:
155
        // *xtw is only valid for signed 64-bit operations.
156
513
        if (Is64Bit && IsSigned)
157
449
          AsmMnemonic = "sxtw";
158
513
        break;
159
3.43k
      }
160
161
3.43k
      if (AsmMnemonic) {
162
2.35k
        SStream_concat(O, "%s", AsmMnemonic);
163
2.35k
        SStream_concat0(O, " ");
164
165
2.35k
        printRegName(O, MCOperand_getReg(Op0));
166
2.35k
        SStream_concat0(O, ", ");
167
2.35k
        printRegName(O, getWRegFromXReg(MCOperand_getReg(Op1)));
168
2.35k
        if (detail_is_set(MI) && useAliasDetails) {
169
2.35k
          AArch64_set_detail_op_reg(MI, 0, MCOperand_getReg(Op0));
170
2.35k
          AArch64_set_detail_op_reg(MI, 1, getWRegFromXReg(MCOperand_getReg(Op1)));
171
2.35k
          if (strings_match(AsmMnemonic, "uxtb"))
172
10
            AArch64_get_detail_op(MI, -1)->ext = AArch64_EXT_UXTB;
173
2.34k
          else if (strings_match(AsmMnemonic, "sxtb"))
174
367
            AArch64_get_detail_op(MI, -1)->ext = AArch64_EXT_SXTB;
175
1.97k
          else if (strings_match(AsmMnemonic, "uxth"))
176
11
            AArch64_get_detail_op(MI, -1)->ext = AArch64_EXT_UXTH;
177
1.96k
          else if (strings_match(AsmMnemonic, "sxth"))
178
1.51k
            AArch64_get_detail_op(MI, -1)->ext = AArch64_EXT_SXTH;
179
449
          else if (strings_match(AsmMnemonic, "sxtw"))
180
449
            AArch64_get_detail_op(MI, -1)->ext = AArch64_EXT_SXTW;
181
0
          else
182
0
            AArch64_get_detail_op(MI, -1)->ext = AArch64_EXT_INVALID;
183
2.35k
        }
184
2.35k
        isAlias = true;
185
2.35k
        MCInst_setIsAlias(MI, isAlias);
186
2.35k
        if (useAliasDetails)
187
2.35k
          return;
188
0
        else
189
0
          goto add_real_detail;
190
2.35k
      }
191
3.43k
    }
192
193
    // All immediate shifts are aliases, implemented using the Bitfield
194
    // instruction. In all cases the immediate shift amount shift must be in
195
    // the range 0 to (reg.size -1).
196
1.72k
    if (MCOperand_isImm(Op2) && MCOperand_isImm(Op3)) {
197
1.72k
      const char *AsmMnemonic = NULL;
198
1.72k
      int shift = 0;
199
1.72k
      int64_t immr = MCOperand_getImm(Op2);
200
1.72k
      int64_t imms = MCOperand_getImm(Op3);
201
1.72k
      if (Opcode == AArch64_UBFMWri && imms != 0x1F &&
202
1.72k
        ((imms + 1) == immr)) {
203
10
        AsmMnemonic = "lsl";
204
10
        shift = 31 - imms;
205
1.71k
      } else if (Opcode == AArch64_UBFMXri && imms != 0x3f &&
206
1.71k
             ((imms + 1 == immr))) {
207
12
        AsmMnemonic = "lsl";
208
12
        shift = 63 - imms;
209
1.70k
      } else if (Opcode == AArch64_UBFMWri && imms == 0x1f) {
210
21
        AsmMnemonic = "lsr";
211
21
        shift = immr;
212
1.68k
      } else if (Opcode == AArch64_UBFMXri && imms == 0x3f) {
213
41
        AsmMnemonic = "lsr";
214
41
        shift = immr;
215
1.64k
      } else if (Opcode == AArch64_SBFMWri && imms == 0x1f) {
216
45
        AsmMnemonic = "asr";
217
45
        shift = immr;
218
1.59k
      } else if (Opcode == AArch64_SBFMXri && imms == 0x3f) {
219
302
        AsmMnemonic = "asr";
220
302
        shift = immr;
221
302
      }
222
1.72k
      if (AsmMnemonic) {
223
431
        SStream_concat(O, "%s", AsmMnemonic);
224
431
        SStream_concat0(O, " ");
225
226
431
        printRegName(O, MCOperand_getReg(Op0));
227
431
        SStream_concat0(O, ", ");
228
431
        printRegName(O, MCOperand_getReg(Op1));
229
431
        SStream_concat(O, "%s%s#%d", ", ", markup("<imm:"), shift);
230
431
        SStream_concat0(O, markup(">"));
231
431
        if (detail_is_set(MI) && useAliasDetails) {
232
431
          AArch64_set_detail_op_reg(MI, 0, MCOperand_getReg(Op0));
233
431
          AArch64_set_detail_op_reg(MI, 1, MCOperand_getReg(Op1));
234
431
          if (strings_match(AsmMnemonic, "lsl"))
235
22
            AArch64_get_detail_op(MI, -1)->shift.type = AArch64_SFT_LSL;
236
409
          else if (strings_match(AsmMnemonic, "lsr"))
237
62
            AArch64_get_detail_op(MI, -1)->shift.type = AArch64_SFT_LSR;
238
347
          else if (strings_match(AsmMnemonic, "asr"))
239
347
            AArch64_get_detail_op(MI, -1)->shift.type = AArch64_SFT_ASR;
240
0
          else
241
0
            AArch64_get_detail_op(MI, -1)->shift.type = AArch64_SFT_INVALID;
242
431
          AArch64_get_detail_op(MI, -1)->shift.value = shift;
243
431
        }
244
431
        isAlias = true;
245
431
        MCInst_setIsAlias(MI, isAlias);
246
431
        if (useAliasDetails)
247
431
          return;
248
0
        else
249
0
          goto add_real_detail;
250
431
      }
251
1.72k
    }
252
253
    // SBFIZ/UBFIZ aliases
254
1.29k
    if (MCOperand_getImm(Op2) > MCOperand_getImm(Op3)) {
255
504
      SStream_concat(O, "%s", (IsSigned ? "sbfiz" : "ubfiz"));
256
504
      SStream_concat0(O, " ");
257
258
504
      printRegName(O, MCOperand_getReg(Op0));
259
504
      SStream_concat0(O, ", ");
260
504
      printRegName(O, MCOperand_getReg(Op1));
261
504
      SStream_concat(O, "%s%s", ", ", markup("<imm:"));
262
504
      printUInt32Bang(O, (Is64Bit ? 64 : 32) - MCOperand_getImm(Op2));
263
504
      SStream_concat(O, "%s%s%s", markup(">"), ", ", markup("<imm:"));
264
504
      printInt64Bang(O, MCOperand_getImm(Op3) + 1);
265
504
      SStream_concat0(O, markup(">"));
266
504
      if (detail_is_set(MI) && useAliasDetails) {
267
504
        AArch64_set_detail_op_reg(MI, 0, MCOperand_getReg(Op0));
268
504
        AArch64_set_detail_op_reg(MI, 1, MCOperand_getReg(Op1));
269
504
        AArch64_set_detail_op_imm(MI, 2, AArch64_OP_IMM, (Is64Bit ? 64 : 32) - MCOperand_getImm(Op2));
270
504
        AArch64_set_detail_op_imm(MI, 3, AArch64_OP_IMM, MCOperand_getImm(Op3) + 1);
271
504
      }
272
504
      isAlias = true;
273
504
      MCInst_setIsAlias(MI, isAlias);
274
504
      if (useAliasDetails)
275
504
        return;
276
0
      else
277
0
        goto add_real_detail;
278
504
    }
279
280
    // Otherwise SBFX/UBFX is the preferred form
281
790
    SStream_concat(O, "%s", (IsSigned ? "sbfx" : "ubfx"));
282
790
    SStream_concat0(O, " ");
283
284
790
    printRegName(O, MCOperand_getReg(Op0));
285
790
    SStream_concat0(O, ", ");
286
790
    printRegName(O, MCOperand_getReg(Op1));
287
790
    SStream_concat(O, "%s%s", ", ", markup("<imm:"));
288
790
    printInt64Bang(O, MCOperand_getImm(Op2));
289
790
    SStream_concat(O, "%s%s%s", markup(">"), ", ", markup("<imm:"));
290
790
    printInt64Bang(O, MCOperand_getImm(Op3) - MCOperand_getImm(Op2) + 1);
291
790
    SStream_concat0(O, markup(">"));
292
790
    if (detail_is_set(MI) && useAliasDetails) {
293
790
      AArch64_set_detail_op_reg(MI, 0, MCOperand_getReg(Op0));
294
790
      AArch64_set_detail_op_reg(MI, 1, MCOperand_getReg(Op1));
295
790
      AArch64_set_detail_op_imm(MI, 2, AArch64_OP_IMM, MCOperand_getImm(Op2));
296
790
      AArch64_set_detail_op_imm(MI, 3, AArch64_OP_IMM, MCOperand_getImm(Op3) - MCOperand_getImm(Op2) + 1);
297
790
    }
298
790
    isAlias = true;
299
790
    MCInst_setIsAlias(MI, isAlias);
300
790
    if (useAliasDetails)
301
790
      return;
302
0
    else
303
0
      goto add_real_detail;
304
790
  }
305
306
199k
  if (Opcode == AArch64_BFMXri || Opcode == AArch64_BFMWri) {
307
1.39k
    isAlias = true;
308
1.39k
    MCInst_setIsAlias(MI, isAlias);
309
1.39k
    MCOperand *Op0 = MCInst_getOperand(MI, (0)); // Op1 == Op0
310
1.39k
    MCOperand *Op2 = MCInst_getOperand(MI, (2));
311
1.39k
    int ImmR = MCOperand_getImm(MCInst_getOperand(MI, (3)));
312
1.39k
    int ImmS = MCOperand_getImm(MCInst_getOperand(MI, (4)));
313
314
1.39k
    if ((MCOperand_getReg(Op2) == AArch64_WZR ||
315
1.39k
       MCOperand_getReg(Op2) == AArch64_XZR) &&
316
1.39k
      (ImmR == 0 || ImmS < ImmR) &&
317
1.39k
      (AArch64_getFeatureBits(MI->csh->mode, AArch64_FeatureAll) ||
318
843
       AArch64_getFeatureBits(MI->csh->mode, AArch64_HasV8_2aOps))) {
319
      // BFC takes precedence over its entire range, sligtly differently
320
      // to BFI.
321
843
      int BitWidth = Opcode == AArch64_BFMXri ? 64 : 32;
322
843
      int LSB = (BitWidth - ImmR) % BitWidth;
323
843
      int Width = ImmS + 1;
324
325
843
      SStream_concat0(O, "bfc ");
326
843
      printRegName(O, MCOperand_getReg(Op0));
327
843
      SStream_concat(O, "%s%s#%d", ", ", markup("<imm:"), LSB);
328
843
      SStream_concat(O, "%s%s%s#%d", markup(">"), ", ", markup("<imm:"), Width);
329
843
      SStream_concat0(O, markup(">"));
330
843
      if (detail_is_set(MI) && useAliasDetails) {
331
843
        AArch64_set_detail_op_reg(MI, 0, MCOperand_getReg(Op0));
332
843
        AArch64_set_detail_op_imm(MI, 3, AArch64_OP_IMM, LSB);
333
843
        AArch64_set_detail_op_imm(MI, 4, AArch64_OP_IMM, Width);
334
843
      }
335
336
843
      if (useAliasDetails)
337
843
        return;
338
0
      else
339
0
        goto add_real_detail;
340
843
    } else if (ImmS < ImmR) {
341
      // BFI alias
342
143
      int BitWidth = Opcode == AArch64_BFMXri ? 64 : 32;
343
143
      int LSB = (BitWidth - ImmR) % BitWidth;
344
143
      int Width = ImmS + 1;
345
346
143
      SStream_concat0(O, "bfi ");
347
143
      printRegName(O, MCOperand_getReg(Op0));
348
143
      SStream_concat0(O, ", ");
349
143
      printRegName(O, MCOperand_getReg(Op2));
350
143
      SStream_concat(O, "%s%s#%d", ", ", markup("<imm:"), LSB);
351
143
      SStream_concat(O, "%s%s%s#%d", markup(">"), ", ", markup("<imm:"), Width);
352
143
      SStream_concat0(O, markup(">"));
353
143
      if (detail_is_set(MI) && useAliasDetails) {
354
143
        AArch64_set_detail_op_reg(MI, 0, MCOperand_getReg(Op0));
355
143
        AArch64_set_detail_op_reg(MI, 2, MCOperand_getReg(Op2));
356
143
        AArch64_set_detail_op_imm(MI, 3, AArch64_OP_IMM, LSB);
357
143
        AArch64_set_detail_op_imm(MI, 4, AArch64_OP_IMM, Width);
358
143
      }
359
143
      if (useAliasDetails)
360
143
        return;
361
0
      else
362
0
        goto add_real_detail;
363
143
    }
364
365
410
    int LSB = ImmR;
366
410
    int Width = ImmS - ImmR + 1;
367
    // Otherwise BFXIL the preferred form
368
410
    SStream_concat0(O, "bfxil ");
369
410
    printRegName(O, MCOperand_getReg(Op0));
370
410
    SStream_concat0(O, ", ");
371
410
    printRegName(O, MCOperand_getReg(Op2));
372
410
    SStream_concat(O, "%s%s#%d", ", ", markup("<imm:"), LSB);
373
410
    SStream_concat(O, "%s%s%s#%d", markup(">"), ", ", markup("<imm:"), Width);
374
410
    SStream_concat0(O, markup(">"));
375
410
    if (detail_is_set(MI) && useAliasDetails) {
376
410
      AArch64_set_detail_op_reg(MI, 0, MCOperand_getReg(Op0));
377
410
      AArch64_set_detail_op_reg(MI, 2, MCOperand_getReg(Op2));
378
410
      AArch64_set_detail_op_imm(MI, 3, AArch64_OP_IMM, LSB);
379
410
      AArch64_set_detail_op_imm(MI, 4, AArch64_OP_IMM, Width);
380
410
    }
381
410
    if (useAliasDetails)
382
410
      return;
383
410
  }
384
385
  // Symbolic operands for MOVZ, MOVN and MOVK already imply a shift
386
  // (e.g. :gottprel_g1: is always going to be "lsl #16") so it should not be
387
  // printed.
388
197k
  if ((Opcode == AArch64_MOVZXi || Opcode == AArch64_MOVZWi ||
389
197k
     Opcode == AArch64_MOVNXi || Opcode == AArch64_MOVNWi) &&
390
197k
    MCOperand_isExpr(MCInst_getOperand(MI, (1)))) {
391
0
    assert(0 && "Expressions are not supported.");
392
0
  }
393
394
197k
  if ((Opcode == AArch64_MOVKXi || Opcode == AArch64_MOVKWi) &&
395
197k
    MCOperand_isExpr(MCInst_getOperand(MI, (2)))) {
396
0
    assert(0 && "Expressions are not supported.");
397
0
  }
398
399
  // MOVZ, MOVN and "ORR wzr, #imm" instructions are aliases for MOV, but
400
  // their domains overlap so they need to be prioritized. The chain is "MOVZ
401
  // lsl #0 > MOVZ lsl #N > MOVN lsl #0 > MOVN lsl #N > ORR". The highest
402
  // instruction that can represent the move is the MOV alias, and the rest
403
  // get printed normally.
404
197k
  if ((Opcode == AArch64_MOVZXi || Opcode == AArch64_MOVZWi) &&
405
197k
    MCOperand_isImm(MCInst_getOperand(MI, (1))) &&
406
197k
    MCOperand_isImm(MCInst_getOperand(MI, (2)))) {
407
783
    int RegWidth = Opcode == AArch64_MOVZXi ? 64 : 32;
408
783
    int Shift = MCOperand_getImm(MCInst_getOperand(MI, (2)));
409
783
    uint64_t Value = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, (1)))
410
783
             << Shift;
411
412
783
    if (AArch64_AM_isMOVZMovAlias(Value, Shift,
413
783
                    Opcode == AArch64_MOVZXi ? 64 : 32)) {
414
773
      isAlias = true;
415
773
      MCInst_setIsAlias(MI, isAlias);
416
773
      SStream_concat0(O, "mov ");
417
773
      printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (0))));
418
773
      SStream_concat(O, "%s%s", ", ", markup("<imm:"));
419
773
      printInt64Bang(O, SignExtend64(Value, RegWidth));
420
773
      SStream_concat0(O, markup(">"));
421
773
      if (detail_is_set(MI) && useAliasDetails) {
422
773
        AArch64_set_detail_op_reg(MI, 0, MCInst_getOpVal(MI, 0));
423
773
        AArch64_set_detail_op_imm(MI, 1, AArch64_OP_IMM, SignExtend64(Value, RegWidth));
424
773
      }
425
773
      if (useAliasDetails)
426
773
        return;
427
773
    }
428
783
  }
429
430
196k
  if ((Opcode == AArch64_MOVNXi || Opcode == AArch64_MOVNWi) &&
431
196k
    MCOperand_isImm(MCInst_getOperand(MI, (1))) &&
432
196k
    MCOperand_isImm(MCInst_getOperand(MI, (2)))) {
433
1.19k
    int RegWidth = Opcode == AArch64_MOVNXi ? 64 : 32;
434
1.19k
    int Shift = MCOperand_getImm(MCInst_getOperand(MI, (2)));
435
1.19k
    uint64_t Value =
436
1.19k
      ~((uint64_t)MCOperand_getImm(MCInst_getOperand(MI, (1))) << Shift);
437
1.19k
    if (RegWidth == 32)
438
632
      Value = Value & 0xffffffff;
439
440
1.19k
    if (AArch64_AM_isMOVNMovAlias(Value, Shift, RegWidth)) {
441
826
      isAlias = true;
442
826
      MCInst_setIsAlias(MI, isAlias);
443
826
      SStream_concat0(O, "mov ");
444
826
      printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (0))));
445
826
      SStream_concat(O, "%s%s", ", ", markup("<imm:"));
446
826
      printInt64Bang(O, SignExtend64(Value, RegWidth));
447
826
      SStream_concat0(O, markup(">"));
448
826
      if (detail_is_set(MI) && useAliasDetails) {
449
826
        AArch64_set_detail_op_reg(MI, 0, MCInst_getOpVal(MI, 0));
450
826
        AArch64_set_detail_op_imm(MI, 1, AArch64_OP_IMM, SignExtend64(Value, RegWidth));
451
826
      }
452
826
      if (useAliasDetails)
453
826
        return;
454
826
    }
455
1.19k
  }
456
457
196k
  if ((Opcode == AArch64_ORRXri || Opcode == AArch64_ORRWri) &&
458
196k
    (MCOperand_getReg(MCInst_getOperand(MI, (1))) == AArch64_XZR ||
459
2.04k
     MCOperand_getReg(MCInst_getOperand(MI, (1))) == AArch64_WZR) &&
460
196k
    MCOperand_isImm(MCInst_getOperand(MI, (2)))) {
461
1.07k
    int RegWidth = Opcode == AArch64_ORRXri ? 64 : 32;
462
1.07k
    uint64_t Value = AArch64_AM_decodeLogicalImmediate(
463
1.07k
      MCOperand_getImm(MCInst_getOperand(MI, (2))), RegWidth);
464
1.07k
    if (!AArch64_AM_isAnyMOVWMovAlias(Value, RegWidth)) {
465
404
      isAlias = true;
466
404
      MCInst_setIsAlias(MI, isAlias);
467
404
      SStream_concat0(O, "mov ");
468
404
      printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (0))));
469
404
      SStream_concat(O, "%s%s", ", ", markup("<imm:"));
470
404
      printInt64Bang(O, SignExtend64(Value, RegWidth));
471
404
      SStream_concat0(O, markup(">"));
472
404
      if (detail_is_set(MI) && useAliasDetails) {
473
404
        AArch64_set_detail_op_reg(MI, 0, MCInst_getOpVal(MI, 0));
474
404
        AArch64_set_detail_op_imm(MI, 2, AArch64_OP_IMM, SignExtend64(Value, RegWidth));
475
404
      }
476
404
      if (useAliasDetails)
477
404
        return;
478
404
    }
479
1.07k
  }
480
481
195k
  if (Opcode == AArch64_SPACE) {
482
0
    isAlias = true;
483
0
    MCInst_setIsAlias(MI, isAlias);
484
0
    SStream_concat1(O, ' ');
485
0
    SStream_concat(O, "%s", " SPACE ");
486
0
    printInt64(O, MCOperand_getImm(MCInst_getOperand(MI, (1))));
487
0
    if (detail_is_set(MI) && useAliasDetails) {
488
0
      AArch64_set_detail_op_imm(MI, 1, AArch64_OP_IMM, MCInst_getOpVal(MI, 1));
489
0
    }
490
0
    if (useAliasDetails)
491
0
      return;
492
0
  }
493
494
195k
  if (!isAlias)
495
195k
    isAlias |= printAliasInstr(MI, Address, O);
496
497
195k
add_real_detail:
498
195k
  MCInst_setIsAlias(MI, isAlias);
499
500
195k
  if (!isAlias || !useAliasDetails) {
501
178k
    map_set_fill_detail_ops(MI, !(isAlias && useAliasDetails));
502
178k
    if (isAlias)
503
0
      SStream_Close(O);
504
178k
    printInstruction(MI, Address, O);
505
178k
    if (isAlias)
506
0
      SStream_Open(O);
507
178k
  }
508
195k
}
509
510
static bool isTblTbxInstruction(unsigned Opcode, const char **Layout, bool *IsTbx)
511
0
{
512
0
  switch (Opcode) {
513
0
  case AArch64_TBXv8i8One:
514
0
  case AArch64_TBXv8i8Two:
515
0
  case AArch64_TBXv8i8Three:
516
0
  case AArch64_TBXv8i8Four:
517
0
    *IsTbx = true;
518
0
    *Layout = ".8b";
519
0
    return true;
520
0
  case AArch64_TBLv8i8One:
521
0
  case AArch64_TBLv8i8Two:
522
0
  case AArch64_TBLv8i8Three:
523
0
  case AArch64_TBLv8i8Four:
524
0
    *IsTbx = false;
525
0
    *Layout = ".8b";
526
0
    return true;
527
0
  case AArch64_TBXv16i8One:
528
0
  case AArch64_TBXv16i8Two:
529
0
  case AArch64_TBXv16i8Three:
530
0
  case AArch64_TBXv16i8Four:
531
0
    *IsTbx = true;
532
0
    *Layout = ".16b";
533
0
    return true;
534
0
  case AArch64_TBLv16i8One:
535
0
  case AArch64_TBLv16i8Two:
536
0
  case AArch64_TBLv16i8Three:
537
0
  case AArch64_TBLv16i8Four:
538
0
    *IsTbx = false;
539
0
    *Layout = ".16b";
540
0
    return true;
541
0
  default:
542
0
    return false;
543
0
  }
544
0
}
545
546
typedef struct LdStNInstrDesc {
547
  unsigned Opcode;
548
  const char *Mnemonic;
549
  const char *Layout;
550
  int ListOperand;
551
  bool HasLane;
552
  int NaturalOffset;
553
} LdStNInstrDesc;
554
555
static const LdStNInstrDesc LdStNInstInfo[] = {
556
  {AArch64_LD1i8, "ld1", ".b", 1, true, 0},
557
  {AArch64_LD1i16, "ld1", ".h", 1, true, 0},
558
  {AArch64_LD1i32, "ld1", ".s", 1, true, 0},
559
  {AArch64_LD1i64, "ld1", ".d", 1, true, 0},
560
  {AArch64_LD1i8_POST, "ld1", ".b", 2, true, 1},
561
  {AArch64_LD1i16_POST, "ld1", ".h", 2, true, 2},
562
  {AArch64_LD1i32_POST, "ld1", ".s", 2, true, 4},
563
  {AArch64_LD1i64_POST, "ld1", ".d", 2, true, 8},
564
  {AArch64_LD1Rv16b, "ld1r", ".16b", 0, false, 0},
565
  {AArch64_LD1Rv8h, "ld1r", ".8h", 0, false, 0},
566
  {AArch64_LD1Rv4s, "ld1r", ".4s", 0, false, 0},
567
  {AArch64_LD1Rv2d, "ld1r", ".2d", 0, false, 0},
568
  {AArch64_LD1Rv8b, "ld1r", ".8b", 0, false, 0},
569
  {AArch64_LD1Rv4h, "ld1r", ".4h", 0, false, 0},
570
  {AArch64_LD1Rv2s, "ld1r", ".2s", 0, false, 0},
571
  {AArch64_LD1Rv1d, "ld1r", ".1d", 0, false, 0},
572
  {AArch64_LD1Rv16b_POST, "ld1r", ".16b", 1, false, 1},
573
  {AArch64_LD1Rv8h_POST, "ld1r", ".8h", 1, false, 2},
574
  {AArch64_LD1Rv4s_POST, "ld1r", ".4s", 1, false, 4},
575
  {AArch64_LD1Rv2d_POST, "ld1r", ".2d", 1, false, 8},
576
  {AArch64_LD1Rv8b_POST, "ld1r", ".8b", 1, false, 1},
577
  {AArch64_LD1Rv4h_POST, "ld1r", ".4h", 1, false, 2},
578
  {AArch64_LD1Rv2s_POST, "ld1r", ".2s", 1, false, 4},
579
  {AArch64_LD1Rv1d_POST, "ld1r", ".1d", 1, false, 8},
580
  {AArch64_LD1Onev16b, "ld1", ".16b", 0, false, 0},
581
  {AArch64_LD1Onev8h, "ld1", ".8h", 0, false, 0},
582
  {AArch64_LD1Onev4s, "ld1", ".4s", 0, false, 0},
583
  {AArch64_LD1Onev2d, "ld1", ".2d", 0, false, 0},
584
  {AArch64_LD1Onev8b, "ld1", ".8b", 0, false, 0},
585
  {AArch64_LD1Onev4h, "ld1", ".4h", 0, false, 0},
586
  {AArch64_LD1Onev2s, "ld1", ".2s", 0, false, 0},
587
  {AArch64_LD1Onev1d, "ld1", ".1d", 0, false, 0},
588
  {AArch64_LD1Onev16b_POST, "ld1", ".16b", 1, false, 16},
589
  {AArch64_LD1Onev8h_POST, "ld1", ".8h", 1, false, 16},
590
  {AArch64_LD1Onev4s_POST, "ld1", ".4s", 1, false, 16},
591
  {AArch64_LD1Onev2d_POST, "ld1", ".2d", 1, false, 16},
592
  {AArch64_LD1Onev8b_POST, "ld1", ".8b", 1, false, 8},
593
  {AArch64_LD1Onev4h_POST, "ld1", ".4h", 1, false, 8},
594
  {AArch64_LD1Onev2s_POST, "ld1", ".2s", 1, false, 8},
595
  {AArch64_LD1Onev1d_POST, "ld1", ".1d", 1, false, 8},
596
  {AArch64_LD1Twov16b, "ld1", ".16b", 0, false, 0},
597
  {AArch64_LD1Twov8h, "ld1", ".8h", 0, false, 0},
598
  {AArch64_LD1Twov4s, "ld1", ".4s", 0, false, 0},
599
  {AArch64_LD1Twov2d, "ld1", ".2d", 0, false, 0},
600
  {AArch64_LD1Twov8b, "ld1", ".8b", 0, false, 0},
601
  {AArch64_LD1Twov4h, "ld1", ".4h", 0, false, 0},
602
  {AArch64_LD1Twov2s, "ld1", ".2s", 0, false, 0},
603
  {AArch64_LD1Twov1d, "ld1", ".1d", 0, false, 0},
604
  {AArch64_LD1Twov16b_POST, "ld1", ".16b", 1, false, 32},
605
  {AArch64_LD1Twov8h_POST, "ld1", ".8h", 1, false, 32},
606
  {AArch64_LD1Twov4s_POST, "ld1", ".4s", 1, false, 32},
607
  {AArch64_LD1Twov2d_POST, "ld1", ".2d", 1, false, 32},
608
  {AArch64_LD1Twov8b_POST, "ld1", ".8b", 1, false, 16},
609
  {AArch64_LD1Twov4h_POST, "ld1", ".4h", 1, false, 16},
610
  {AArch64_LD1Twov2s_POST, "ld1", ".2s", 1, false, 16},
611
  {AArch64_LD1Twov1d_POST, "ld1", ".1d", 1, false, 16},
612
  {AArch64_LD1Threev16b, "ld1", ".16b", 0, false, 0},
613
  {AArch64_LD1Threev8h, "ld1", ".8h", 0, false, 0},
614
  {AArch64_LD1Threev4s, "ld1", ".4s", 0, false, 0},
615
  {AArch64_LD1Threev2d, "ld1", ".2d", 0, false, 0},
616
  {AArch64_LD1Threev8b, "ld1", ".8b", 0, false, 0},
617
  {AArch64_LD1Threev4h, "ld1", ".4h", 0, false, 0},
618
  {AArch64_LD1Threev2s, "ld1", ".2s", 0, false, 0},
619
  {AArch64_LD1Threev1d, "ld1", ".1d", 0, false, 0},
620
  {AArch64_LD1Threev16b_POST, "ld1", ".16b", 1, false, 48},
621
  {AArch64_LD1Threev8h_POST, "ld1", ".8h", 1, false, 48},
622
  {AArch64_LD1Threev4s_POST, "ld1", ".4s", 1, false, 48},
623
  {AArch64_LD1Threev2d_POST, "ld1", ".2d", 1, false, 48},
624
  {AArch64_LD1Threev8b_POST, "ld1", ".8b", 1, false, 24},
625
  {AArch64_LD1Threev4h_POST, "ld1", ".4h", 1, false, 24},
626
  {AArch64_LD1Threev2s_POST, "ld1", ".2s", 1, false, 24},
627
  {AArch64_LD1Threev1d_POST, "ld1", ".1d", 1, false, 24},
628
  {AArch64_LD1Fourv16b, "ld1", ".16b", 0, false, 0},
629
  {AArch64_LD1Fourv8h, "ld1", ".8h", 0, false, 0},
630
  {AArch64_LD1Fourv4s, "ld1", ".4s", 0, false, 0},
631
  {AArch64_LD1Fourv2d, "ld1", ".2d", 0, false, 0},
632
  {AArch64_LD1Fourv8b, "ld1", ".8b", 0, false, 0},
633
  {AArch64_LD1Fourv4h, "ld1", ".4h", 0, false, 0},
634
  {AArch64_LD1Fourv2s, "ld1", ".2s", 0, false, 0},
635
  {AArch64_LD1Fourv1d, "ld1", ".1d", 0, false, 0},
636
  {AArch64_LD1Fourv16b_POST, "ld1", ".16b", 1, false, 64},
637
  {AArch64_LD1Fourv8h_POST, "ld1", ".8h", 1, false, 64},
638
  {AArch64_LD1Fourv4s_POST, "ld1", ".4s", 1, false, 64},
639
  {AArch64_LD1Fourv2d_POST, "ld1", ".2d", 1, false, 64},
640
  {AArch64_LD1Fourv8b_POST, "ld1", ".8b", 1, false, 32},
641
  {AArch64_LD1Fourv4h_POST, "ld1", ".4h", 1, false, 32},
642
  {AArch64_LD1Fourv2s_POST, "ld1", ".2s", 1, false, 32},
643
  {AArch64_LD1Fourv1d_POST, "ld1", ".1d", 1, false, 32},
644
  {AArch64_LD2i8, "ld2", ".b", 1, true, 0},
645
  {AArch64_LD2i16, "ld2", ".h", 1, true, 0},
646
  {AArch64_LD2i32, "ld2", ".s", 1, true, 0},
647
  {AArch64_LD2i64, "ld2", ".d", 1, true, 0},
648
  {AArch64_LD2i8_POST, "ld2", ".b", 2, true, 2},
649
  {AArch64_LD2i16_POST, "ld2", ".h", 2, true, 4},
650
  {AArch64_LD2i32_POST, "ld2", ".s", 2, true, 8},
651
  {AArch64_LD2i64_POST, "ld2", ".d", 2, true, 16},
652
  {AArch64_LD2Rv16b, "ld2r", ".16b", 0, false, 0},
653
  {AArch64_LD2Rv8h, "ld2r", ".8h", 0, false, 0},
654
  {AArch64_LD2Rv4s, "ld2r", ".4s", 0, false, 0},
655
  {AArch64_LD2Rv2d, "ld2r", ".2d", 0, false, 0},
656
  {AArch64_LD2Rv8b, "ld2r", ".8b", 0, false, 0},
657
  {AArch64_LD2Rv4h, "ld2r", ".4h", 0, false, 0},
658
  {AArch64_LD2Rv2s, "ld2r", ".2s", 0, false, 0},
659
  {AArch64_LD2Rv1d, "ld2r", ".1d", 0, false, 0},
660
  {AArch64_LD2Rv16b_POST, "ld2r", ".16b", 1, false, 2},
661
  {AArch64_LD2Rv8h_POST, "ld2r", ".8h", 1, false, 4},
662
  {AArch64_LD2Rv4s_POST, "ld2r", ".4s", 1, false, 8},
663
  {AArch64_LD2Rv2d_POST, "ld2r", ".2d", 1, false, 16},
664
  {AArch64_LD2Rv8b_POST, "ld2r", ".8b", 1, false, 2},
665
  {AArch64_LD2Rv4h_POST, "ld2r", ".4h", 1, false, 4},
666
  {AArch64_LD2Rv2s_POST, "ld2r", ".2s", 1, false, 8},
667
  {AArch64_LD2Rv1d_POST, "ld2r", ".1d", 1, false, 16},
668
  {AArch64_LD2Twov16b, "ld2", ".16b", 0, false, 0},
669
  {AArch64_LD2Twov8h, "ld2", ".8h", 0, false, 0},
670
  {AArch64_LD2Twov4s, "ld2", ".4s", 0, false, 0},
671
  {AArch64_LD2Twov2d, "ld2", ".2d", 0, false, 0},
672
  {AArch64_LD2Twov8b, "ld2", ".8b", 0, false, 0},
673
  {AArch64_LD2Twov4h, "ld2", ".4h", 0, false, 0},
674
  {AArch64_LD2Twov2s, "ld2", ".2s", 0, false, 0},
675
  {AArch64_LD2Twov16b_POST, "ld2", ".16b", 1, false, 32},
676
  {AArch64_LD2Twov8h_POST, "ld2", ".8h", 1, false, 32},
677
  {AArch64_LD2Twov4s_POST, "ld2", ".4s", 1, false, 32},
678
  {AArch64_LD2Twov2d_POST, "ld2", ".2d", 1, false, 32},
679
  {AArch64_LD2Twov8b_POST, "ld2", ".8b", 1, false, 16},
680
  {AArch64_LD2Twov4h_POST, "ld2", ".4h", 1, false, 16},
681
  {AArch64_LD2Twov2s_POST, "ld2", ".2s", 1, false, 16},
682
  {AArch64_LD3i8, "ld3", ".b", 1, true, 0},
683
  {AArch64_LD3i16, "ld3", ".h", 1, true, 0},
684
  {AArch64_LD3i32, "ld3", ".s", 1, true, 0},
685
  {AArch64_LD3i64, "ld3", ".d", 1, true, 0},
686
  {AArch64_LD3i8_POST, "ld3", ".b", 2, true, 3},
687
  {AArch64_LD3i16_POST, "ld3", ".h", 2, true, 6},
688
  {AArch64_LD3i32_POST, "ld3", ".s", 2, true, 12},
689
  {AArch64_LD3i64_POST, "ld3", ".d", 2, true, 24},
690
  {AArch64_LD3Rv16b, "ld3r", ".16b", 0, false, 0},
691
  {AArch64_LD3Rv8h, "ld3r", ".8h", 0, false, 0},
692
  {AArch64_LD3Rv4s, "ld3r", ".4s", 0, false, 0},
693
  {AArch64_LD3Rv2d, "ld3r", ".2d", 0, false, 0},
694
  {AArch64_LD3Rv8b, "ld3r", ".8b", 0, false, 0},
695
  {AArch64_LD3Rv4h, "ld3r", ".4h", 0, false, 0},
696
  {AArch64_LD3Rv2s, "ld3r", ".2s", 0, false, 0},
697
  {AArch64_LD3Rv1d, "ld3r", ".1d", 0, false, 0},
698
  {AArch64_LD3Rv16b_POST, "ld3r", ".16b", 1, false, 3},
699
  {AArch64_LD3Rv8h_POST, "ld3r", ".8h", 1, false, 6},
700
  {AArch64_LD3Rv4s_POST, "ld3r", ".4s", 1, false, 12},
701
  {AArch64_LD3Rv2d_POST, "ld3r", ".2d", 1, false, 24},
702
  {AArch64_LD3Rv8b_POST, "ld3r", ".8b", 1, false, 3},
703
  {AArch64_LD3Rv4h_POST, "ld3r", ".4h", 1, false, 6},
704
  {AArch64_LD3Rv2s_POST, "ld3r", ".2s", 1, false, 12},
705
  {AArch64_LD3Rv1d_POST, "ld3r", ".1d", 1, false, 24},
706
  {AArch64_LD3Threev16b, "ld3", ".16b", 0, false, 0},
707
  {AArch64_LD3Threev8h, "ld3", ".8h", 0, false, 0},
708
  {AArch64_LD3Threev4s, "ld3", ".4s", 0, false, 0},
709
  {AArch64_LD3Threev2d, "ld3", ".2d", 0, false, 0},
710
  {AArch64_LD3Threev8b, "ld3", ".8b", 0, false, 0},
711
  {AArch64_LD3Threev4h, "ld3", ".4h", 0, false, 0},
712
  {AArch64_LD3Threev2s, "ld3", ".2s", 0, false, 0},
713
  {AArch64_LD3Threev16b_POST, "ld3", ".16b", 1, false, 48},
714
  {AArch64_LD3Threev8h_POST, "ld3", ".8h", 1, false, 48},
715
  {AArch64_LD3Threev4s_POST, "ld3", ".4s", 1, false, 48},
716
  {AArch64_LD3Threev2d_POST, "ld3", ".2d", 1, false, 48},
717
  {AArch64_LD3Threev8b_POST, "ld3", ".8b", 1, false, 24},
718
  {AArch64_LD3Threev4h_POST, "ld3", ".4h", 1, false, 24},
719
  {AArch64_LD3Threev2s_POST, "ld3", ".2s", 1, false, 24},
720
  {AArch64_LD4i8, "ld4", ".b", 1, true, 0},
721
  {AArch64_LD4i16, "ld4", ".h", 1, true, 0},
722
  {AArch64_LD4i32, "ld4", ".s", 1, true, 0},
723
  {AArch64_LD4i64, "ld4", ".d", 1, true, 0},
724
  {AArch64_LD4i8_POST, "ld4", ".b", 2, true, 4},
725
  {AArch64_LD4i16_POST, "ld4", ".h", 2, true, 8},
726
  {AArch64_LD4i32_POST, "ld4", ".s", 2, true, 16},
727
  {AArch64_LD4i64_POST, "ld4", ".d", 2, true, 32},
728
  {AArch64_LD4Rv16b, "ld4r", ".16b", 0, false, 0},
729
  {AArch64_LD4Rv8h, "ld4r", ".8h", 0, false, 0},
730
  {AArch64_LD4Rv4s, "ld4r", ".4s", 0, false, 0},
731
  {AArch64_LD4Rv2d, "ld4r", ".2d", 0, false, 0},
732
  {AArch64_LD4Rv8b, "ld4r", ".8b", 0, false, 0},
733
  {AArch64_LD4Rv4h, "ld4r", ".4h", 0, false, 0},
734
  {AArch64_LD4Rv2s, "ld4r", ".2s", 0, false, 0},
735
  {AArch64_LD4Rv1d, "ld4r", ".1d", 0, false, 0},
736
  {AArch64_LD4Rv16b_POST, "ld4r", ".16b", 1, false, 4},
737
  {AArch64_LD4Rv8h_POST, "ld4r", ".8h", 1, false, 8},
738
  {AArch64_LD4Rv4s_POST, "ld4r", ".4s", 1, false, 16},
739
  {AArch64_LD4Rv2d_POST, "ld4r", ".2d", 1, false, 32},
740
  {AArch64_LD4Rv8b_POST, "ld4r", ".8b", 1, false, 4},
741
  {AArch64_LD4Rv4h_POST, "ld4r", ".4h", 1, false, 8},
742
  {AArch64_LD4Rv2s_POST, "ld4r", ".2s", 1, false, 16},
743
  {AArch64_LD4Rv1d_POST, "ld4r", ".1d", 1, false, 32},
744
  {AArch64_LD4Fourv16b, "ld4", ".16b", 0, false, 0},
745
  {AArch64_LD4Fourv8h, "ld4", ".8h", 0, false, 0},
746
  {AArch64_LD4Fourv4s, "ld4", ".4s", 0, false, 0},
747
  {AArch64_LD4Fourv2d, "ld4", ".2d", 0, false, 0},
748
  {AArch64_LD4Fourv8b, "ld4", ".8b", 0, false, 0},
749
  {AArch64_LD4Fourv4h, "ld4", ".4h", 0, false, 0},
750
  {AArch64_LD4Fourv2s, "ld4", ".2s", 0, false, 0},
751
  {AArch64_LD4Fourv16b_POST, "ld4", ".16b", 1, false, 64},
752
  {AArch64_LD4Fourv8h_POST, "ld4", ".8h", 1, false, 64},
753
  {AArch64_LD4Fourv4s_POST, "ld4", ".4s", 1, false, 64},
754
  {AArch64_LD4Fourv2d_POST, "ld4", ".2d", 1, false, 64},
755
  {AArch64_LD4Fourv8b_POST, "ld4", ".8b", 1, false, 32},
756
  {AArch64_LD4Fourv4h_POST, "ld4", ".4h", 1, false, 32},
757
  {AArch64_LD4Fourv2s_POST, "ld4", ".2s", 1, false, 32},
758
  {AArch64_ST1i8, "st1", ".b", 0, true, 0},
759
  {AArch64_ST1i16, "st1", ".h", 0, true, 0},
760
  {AArch64_ST1i32, "st1", ".s", 0, true, 0},
761
  {AArch64_ST1i64, "st1", ".d", 0, true, 0},
762
  {AArch64_ST1i8_POST, "st1", ".b", 1, true, 1},
763
  {AArch64_ST1i16_POST, "st1", ".h", 1, true, 2},
764
  {AArch64_ST1i32_POST, "st1", ".s", 1, true, 4},
765
  {AArch64_ST1i64_POST, "st1", ".d", 1, true, 8},
766
  {AArch64_ST1Onev16b, "st1", ".16b", 0, false, 0},
767
  {AArch64_ST1Onev8h, "st1", ".8h", 0, false, 0},
768
  {AArch64_ST1Onev4s, "st1", ".4s", 0, false, 0},
769
  {AArch64_ST1Onev2d, "st1", ".2d", 0, false, 0},
770
  {AArch64_ST1Onev8b, "st1", ".8b", 0, false, 0},
771
  {AArch64_ST1Onev4h, "st1", ".4h", 0, false, 0},
772
  {AArch64_ST1Onev2s, "st1", ".2s", 0, false, 0},
773
  {AArch64_ST1Onev1d, "st1", ".1d", 0, false, 0},
774
  {AArch64_ST1Onev16b_POST, "st1", ".16b", 1, false, 16},
775
  {AArch64_ST1Onev8h_POST, "st1", ".8h", 1, false, 16},
776
  {AArch64_ST1Onev4s_POST, "st1", ".4s", 1, false, 16},
777
  {AArch64_ST1Onev2d_POST, "st1", ".2d", 1, false, 16},
778
  {AArch64_ST1Onev8b_POST, "st1", ".8b", 1, false, 8},
779
  {AArch64_ST1Onev4h_POST, "st1", ".4h", 1, false, 8},
780
  {AArch64_ST1Onev2s_POST, "st1", ".2s", 1, false, 8},
781
  {AArch64_ST1Onev1d_POST, "st1", ".1d", 1, false, 8},
782
  {AArch64_ST1Twov16b, "st1", ".16b", 0, false, 0},
783
  {AArch64_ST1Twov8h, "st1", ".8h", 0, false, 0},
784
  {AArch64_ST1Twov4s, "st1", ".4s", 0, false, 0},
785
  {AArch64_ST1Twov2d, "st1", ".2d", 0, false, 0},
786
  {AArch64_ST1Twov8b, "st1", ".8b", 0, false, 0},
787
  {AArch64_ST1Twov4h, "st1", ".4h", 0, false, 0},
788
  {AArch64_ST1Twov2s, "st1", ".2s", 0, false, 0},
789
  {AArch64_ST1Twov1d, "st1", ".1d", 0, false, 0},
790
  {AArch64_ST1Twov16b_POST, "st1", ".16b", 1, false, 32},
791
  {AArch64_ST1Twov8h_POST, "st1", ".8h", 1, false, 32},
792
  {AArch64_ST1Twov4s_POST, "st1", ".4s", 1, false, 32},
793
  {AArch64_ST1Twov2d_POST, "st1", ".2d", 1, false, 32},
794
  {AArch64_ST1Twov8b_POST, "st1", ".8b", 1, false, 16},
795
  {AArch64_ST1Twov4h_POST, "st1", ".4h", 1, false, 16},
796
  {AArch64_ST1Twov2s_POST, "st1", ".2s", 1, false, 16},
797
  {AArch64_ST1Twov1d_POST, "st1", ".1d", 1, false, 16},
798
  {AArch64_ST1Threev16b, "st1", ".16b", 0, false, 0},
799
  {AArch64_ST1Threev8h, "st1", ".8h", 0, false, 0},
800
  {AArch64_ST1Threev4s, "st1", ".4s", 0, false, 0},
801
  {AArch64_ST1Threev2d, "st1", ".2d", 0, false, 0},
802
  {AArch64_ST1Threev8b, "st1", ".8b", 0, false, 0},
803
  {AArch64_ST1Threev4h, "st1", ".4h", 0, false, 0},
804
  {AArch64_ST1Threev2s, "st1", ".2s", 0, false, 0},
805
  {AArch64_ST1Threev1d, "st1", ".1d", 0, false, 0},
806
  {AArch64_ST1Threev16b_POST, "st1", ".16b", 1, false, 48},
807
  {AArch64_ST1Threev8h_POST, "st1", ".8h", 1, false, 48},
808
  {AArch64_ST1Threev4s_POST, "st1", ".4s", 1, false, 48},
809
  {AArch64_ST1Threev2d_POST, "st1", ".2d", 1, false, 48},
810
  {AArch64_ST1Threev8b_POST, "st1", ".8b", 1, false, 24},
811
  {AArch64_ST1Threev4h_POST, "st1", ".4h", 1, false, 24},
812
  {AArch64_ST1Threev2s_POST, "st1", ".2s", 1, false, 24},
813
  {AArch64_ST1Threev1d_POST, "st1", ".1d", 1, false, 24},
814
  {AArch64_ST1Fourv16b, "st1", ".16b", 0, false, 0},
815
  {AArch64_ST1Fourv8h, "st1", ".8h", 0, false, 0},
816
  {AArch64_ST1Fourv4s, "st1", ".4s", 0, false, 0},
817
  {AArch64_ST1Fourv2d, "st1", ".2d", 0, false, 0},
818
  {AArch64_ST1Fourv8b, "st1", ".8b", 0, false, 0},
819
  {AArch64_ST1Fourv4h, "st1", ".4h", 0, false, 0},
820
  {AArch64_ST1Fourv2s, "st1", ".2s", 0, false, 0},
821
  {AArch64_ST1Fourv1d, "st1", ".1d", 0, false, 0},
822
  {AArch64_ST1Fourv16b_POST, "st1", ".16b", 1, false, 64},
823
  {AArch64_ST1Fourv8h_POST, "st1", ".8h", 1, false, 64},
824
  {AArch64_ST1Fourv4s_POST, "st1", ".4s", 1, false, 64},
825
  {AArch64_ST1Fourv2d_POST, "st1", ".2d", 1, false, 64},
826
  {AArch64_ST1Fourv8b_POST, "st1", ".8b", 1, false, 32},
827
  {AArch64_ST1Fourv4h_POST, "st1", ".4h", 1, false, 32},
828
  {AArch64_ST1Fourv2s_POST, "st1", ".2s", 1, false, 32},
829
  {AArch64_ST1Fourv1d_POST, "st1", ".1d", 1, false, 32},
830
  {AArch64_ST2i8, "st2", ".b", 0, true, 0},
831
  {AArch64_ST2i16, "st2", ".h", 0, true, 0},
832
  {AArch64_ST2i32, "st2", ".s", 0, true, 0},
833
  {AArch64_ST2i64, "st2", ".d", 0, true, 0},
834
  {AArch64_ST2i8_POST, "st2", ".b", 1, true, 2},
835
  {AArch64_ST2i16_POST, "st2", ".h", 1, true, 4},
836
  {AArch64_ST2i32_POST, "st2", ".s", 1, true, 8},
837
  {AArch64_ST2i64_POST, "st2", ".d", 1, true, 16},
838
  {AArch64_ST2Twov16b, "st2", ".16b", 0, false, 0},
839
  {AArch64_ST2Twov8h, "st2", ".8h", 0, false, 0},
840
  {AArch64_ST2Twov4s, "st2", ".4s", 0, false, 0},
841
  {AArch64_ST2Twov2d, "st2", ".2d", 0, false, 0},
842
  {AArch64_ST2Twov8b, "st2", ".8b", 0, false, 0},
843
  {AArch64_ST2Twov4h, "st2", ".4h", 0, false, 0},
844
  {AArch64_ST2Twov2s, "st2", ".2s", 0, false, 0},
845
  {AArch64_ST2Twov16b_POST, "st2", ".16b", 1, false, 32},
846
  {AArch64_ST2Twov8h_POST, "st2", ".8h", 1, false, 32},
847
  {AArch64_ST2Twov4s_POST, "st2", ".4s", 1, false, 32},
848
  {AArch64_ST2Twov2d_POST, "st2", ".2d", 1, false, 32},
849
  {AArch64_ST2Twov8b_POST, "st2", ".8b", 1, false, 16},
850
  {AArch64_ST2Twov4h_POST, "st2", ".4h", 1, false, 16},
851
  {AArch64_ST2Twov2s_POST, "st2", ".2s", 1, false, 16},
852
  {AArch64_ST3i8, "st3", ".b", 0, true, 0},
853
  {AArch64_ST3i16, "st3", ".h", 0, true, 0},
854
  {AArch64_ST3i32, "st3", ".s", 0, true, 0},
855
  {AArch64_ST3i64, "st3", ".d", 0, true, 0},
856
  {AArch64_ST3i8_POST, "st3", ".b", 1, true, 3},
857
  {AArch64_ST3i16_POST, "st3", ".h", 1, true, 6},
858
  {AArch64_ST3i32_POST, "st3", ".s", 1, true, 12},
859
  {AArch64_ST3i64_POST, "st3", ".d", 1, true, 24},
860
  {AArch64_ST3Threev16b, "st3", ".16b", 0, false, 0},
861
  {AArch64_ST3Threev8h, "st3", ".8h", 0, false, 0},
862
  {AArch64_ST3Threev4s, "st3", ".4s", 0, false, 0},
863
  {AArch64_ST3Threev2d, "st3", ".2d", 0, false, 0},
864
  {AArch64_ST3Threev8b, "st3", ".8b", 0, false, 0},
865
  {AArch64_ST3Threev4h, "st3", ".4h", 0, false, 0},
866
  {AArch64_ST3Threev2s, "st3", ".2s", 0, false, 0},
867
  {AArch64_ST3Threev16b_POST, "st3", ".16b", 1, false, 48},
868
  {AArch64_ST3Threev8h_POST, "st3", ".8h", 1, false, 48},
869
  {AArch64_ST3Threev4s_POST, "st3", ".4s", 1, false, 48},
870
  {AArch64_ST3Threev2d_POST, "st3", ".2d", 1, false, 48},
871
  {AArch64_ST3Threev8b_POST, "st3", ".8b", 1, false, 24},
872
  {AArch64_ST3Threev4h_POST, "st3", ".4h", 1, false, 24},
873
  {AArch64_ST3Threev2s_POST, "st3", ".2s", 1, false, 24},
874
  {AArch64_ST4i8, "st4", ".b", 0, true, 0},
875
  {AArch64_ST4i16, "st4", ".h", 0, true, 0},
876
  {AArch64_ST4i32, "st4", ".s", 0, true, 0},
877
  {AArch64_ST4i64, "st4", ".d", 0, true, 0},
878
  {AArch64_ST4i8_POST, "st4", ".b", 1, true, 4},
879
  {AArch64_ST4i16_POST, "st4", ".h", 1, true, 8},
880
  {AArch64_ST4i32_POST, "st4", ".s", 1, true, 16},
881
  {AArch64_ST4i64_POST, "st4", ".d", 1, true, 32},
882
  {AArch64_ST4Fourv16b, "st4", ".16b", 0, false, 0},
883
  {AArch64_ST4Fourv8h, "st4", ".8h", 0, false, 0},
884
  {AArch64_ST4Fourv4s, "st4", ".4s", 0, false, 0},
885
  {AArch64_ST4Fourv2d, "st4", ".2d", 0, false, 0},
886
  {AArch64_ST4Fourv8b, "st4", ".8b", 0, false, 0},
887
  {AArch64_ST4Fourv4h, "st4", ".4h", 0, false, 0},
888
  {AArch64_ST4Fourv2s, "st4", ".2s", 0, false, 0},
889
  {AArch64_ST4Fourv16b_POST, "st4", ".16b", 1, false, 64},
890
  {AArch64_ST4Fourv8h_POST, "st4", ".8h", 1, false, 64},
891
  {AArch64_ST4Fourv4s_POST, "st4", ".4s", 1, false, 64},
892
  {AArch64_ST4Fourv2d_POST, "st4", ".2d", 1, false, 64},
893
  {AArch64_ST4Fourv8b_POST, "st4", ".8b", 1, false, 32},
894
  {AArch64_ST4Fourv4h_POST, "st4", ".4h", 1, false, 32},
895
  {AArch64_ST4Fourv2s_POST, "st4", ".2s", 1, false, 32},
896
};
897
898
static const LdStNInstrDesc *getLdStNInstrDesc(unsigned Opcode)
899
0
{
900
0
  for (int i = 0; i < (sizeof(LdStNInstInfo)/sizeof(LdStNInstInfo[0])); ++i) {
901
0
    const LdStNInstrDesc *Info = &LdStNInstInfo[i];
902
0
    if (Info->Opcode == Opcode)
903
0
      return Info;
904
0
  }
905
906
0
  return NULL;
907
0
}
908
909
void AArch64AppleInstPrinter_printInst(MCInst *MI, uint64_t Address, const char *Annot, SStream *O)
910
0
{
911
0
  unsigned Opcode = MCInst_getOpcode(MI);
912
0
  const char *Layout;
913
914
0
  bool IsTbx;
915
0
  if (isTblTbxInstruction(MCInst_getOpcode(MI), &Layout, &IsTbx)) {
916
0
    SStream_concat(O, "%s%s", (IsTbx ? "tbx" : "tbl"), Layout);
917
0
    SStream_concat0(O, " ");
918
919
0
    printRegNameAlt(O, MCOperand_getReg(MCInst_getOperand(MI, (0))),
920
0
           AArch64_vreg);
921
0
    SStream_concat0(O, ", ");
922
923
0
    unsigned ListOpNum = IsTbx ? 2 : 1;
924
0
    printVectorList(MI, ListOpNum, O, "");
925
926
0
    SStream_concat0(O, ", ");
927
0
    printRegNameAlt(O,
928
0
           MCOperand_getReg(MCInst_getOperand(MI, (ListOpNum + 1))),
929
0
           AArch64_vreg);
930
0
    ;
931
0
    return;
932
0
  }
933
934
0
  const LdStNInstrDesc *LdStDesc = getLdStNInstrDesc(Opcode);
935
0
  if (LdStDesc) {
936
0
    SStream_concat(O, "%s%s", LdStDesc->Mnemonic, LdStDesc->Layout);
937
0
    SStream_concat0(O, " ");
938
939
    // Now onto the operands: first a vector list with possible lane
940
    // specifier. E.g. { v0 }[2]
941
0
    int OpNum = LdStDesc->ListOperand;
942
0
    printVectorList(MI, OpNum++, O, "");
943
944
0
    if (LdStDesc->HasLane) {
945
0
      SStream_concat1(O, '[');
946
0
      SStream_concat(O, "%s",
947
0
               MCOperand_getImm(MCInst_getOperand(MI, (OpNum++))));
948
0
      SStream_concat0(O, "]");
949
0
    }
950
951
    // Next the address: [xN]
952
0
    unsigned AddrReg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum++)));
953
0
    SStream_concat0(O, ", [");
954
0
    printRegName(O, AddrReg);
955
0
    SStream_concat0(O, "]");
956
957
    // Finally, there might be a post-indexed offset.
958
0
    if (LdStDesc->NaturalOffset != 0) {
959
0
      unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum++)));
960
0
      if (Reg != AArch64_XZR) {
961
0
        SStream_concat0(O, ", ");
962
0
        printRegName(O, Reg);
963
0
      } else {
964
965
0
        SStream_concat(O, "%s%s%s%s", ", ", markup("<imm:"), "#",
966
0
                 LdStDesc->NaturalOffset);
967
0
        SStream_concat0(O, markup(">"));
968
0
      }
969
0
    }
970
971
0
    ;
972
0
    return;
973
0
  }
974
975
0
  printInst(MI, Address, Annot, O);
976
0
}
977
978
bool printRangePrefetchAlias(MCInst *MI, SStream *O, const char *Annot)
979
120
{
980
120
  unsigned Opcode = MCInst_getOpcode(MI);
981
982
120
#ifndef NDEBUG
983
984
120
#endif
985
986
120
  unsigned PRFOp = MCOperand_getImm(MCInst_getOperand(MI, (0)));
987
120
  unsigned Mask = 0x18; // 0b11000
988
120
  if ((PRFOp & Mask) != Mask)
989
120
    return false;    // Rt != '11xxx', it's a PRFM instruction.
990
991
0
  unsigned Rm = MCOperand_getReg(MCInst_getOperand(MI, (2)));
992
993
  // "Rm" must be a 64-bit GPR for RPRFM.
994
0
  if (MCRegisterInfo_getRegClass(MI->MRI, Rm))
995
0
    Rm = MCRegisterInfo_getMatchingSuperReg(MI->MRI, Rm, AArch64_sub_32,
996
0
                   MCRegisterInfo_getRegClass(MI->MRI, Rm));
997
998
0
  unsigned SignExtend =
999
0
    MCOperand_getImm(MCInst_getOperand(MI, (3))); // encoded in "option<2>".
1000
0
  unsigned Shift =
1001
0
    MCOperand_getImm(MCInst_getOperand(MI, (4))); // encoded in "S".
1002
1003
0
  unsigned Option0 = (Opcode == AArch64_PRFMroX) ? 1 : 0;
1004
1005
  // encoded in "option<2>:option<0>:S:Rt<2:0>".
1006
0
  unsigned RPRFOp =
1007
0
    (SignExtend << 5) | (Option0 << 4) | (Shift << 3) | (PRFOp & 0x7);
1008
1009
0
  SStream_concat0(O, "rprfm ");
1010
0
  const AArch64RPRFM_RPRFM *RPRFM = AArch64RPRFM_lookupRPRFMByEncoding(RPRFOp);
1011
0
  if (RPRFM) {
1012
0
    SStream_concat0(O, RPRFM->Name);
1013
0
    if (detail_is_set(MI)) {
1014
0
      aarch64_sysop sysop;
1015
0
      sysop.alias = RPRFM->SysAlias;
1016
0
      sysop.sub_type = AArch64_OP_RPRFM;
1017
0
      AArch64_get_detail_op(MI, 0)->type = AArch64_OP_SYSALIAS;
1018
0
      AArch64_get_detail_op(MI, 0)->sysop = sysop;
1019
0
      AArch64_inc_op_count(MI);
1020
0
    }
1021
0
  }
1022
0
  SStream_concat0(O, ", [");
1023
0
  printOperand(MI, 1, O); // "Rn".
1024
0
  SStream_concat0(O, "]");
1025
1026
0
  ;
1027
1028
0
  return true;
1029
120
}
1030
1031
bool printSysAlias(MCInst *MI, SStream *O)
1032
2.15k
{
1033
2.15k
  MCOperand *Op1 = MCInst_getOperand(MI, (0));
1034
2.15k
  MCOperand *Cn = MCInst_getOperand(MI, (1));
1035
2.15k
  MCOperand *Cm = MCInst_getOperand(MI, (2));
1036
2.15k
  MCOperand *Op2 = MCInst_getOperand(MI, (3));
1037
1038
2.15k
  unsigned Op1Val = MCOperand_getImm(Op1);
1039
2.15k
  unsigned CnVal = MCOperand_getImm(Cn);
1040
2.15k
  unsigned CmVal = MCOperand_getImm(Cm);
1041
2.15k
  unsigned Op2Val = MCOperand_getImm(Op2);
1042
1043
2.15k
  uint16_t Encoding = Op2Val;
1044
2.15k
  Encoding |= CmVal << 3;
1045
2.15k
  Encoding |= CnVal << 7;
1046
2.15k
  Encoding |= Op1Val << 11;
1047
1048
2.15k
  bool NeedsReg;
1049
2.15k
  const char *Ins;
1050
2.15k
  const char *Name;
1051
1052
2.15k
  if (CnVal == 7) {
1053
1.71k
    switch (CmVal) {
1054
47
    default:
1055
47
      return false;
1056
    // Maybe IC, maybe Prediction Restriction
1057
297
    case 1:
1058
297
      switch (Op1Val) {
1059
169
      default:
1060
169
        return false;
1061
118
      case 0:
1062
118
        goto Search_IC;
1063
10
      case 3:
1064
10
        goto Search_PRCTX;
1065
297
      }
1066
    // Prediction Restriction aliases
1067
120
    case 3: {
1068
130
    Search_PRCTX:
1069
130
      if (Op1Val != 3 || CnVal != 7 || CmVal != 3)
1070
20
        return false;
1071
1072
110
      aarch64_insn_group Requires =
1073
110
        Op2Val == 6 ? AArch64_FeatureSPECRES2 : AArch64_FeaturePredRes;
1074
110
      if (!(AArch64_getFeatureBits(MI->csh->mode, AArch64_FeatureAll) ||
1075
110
          AArch64_getFeatureBits(MI->csh->mode, Requires)))
1076
0
        return false;
1077
1078
110
      NeedsReg = true;
1079
110
      switch (Op2Val) {
1080
43
      default:
1081
43
        return false;
1082
3
      case 4:
1083
3
        Ins = "cfp ";
1084
3
        break;
1085
10
      case 5:
1086
10
        Ins = "dvp ";
1087
10
        break;
1088
6
      case 6:
1089
6
        Ins = "cosp ";
1090
6
        break;
1091
48
      case 7:
1092
48
        Ins = "cpp ";
1093
48
        break;
1094
110
      }
1095
67
      Name = "RCTX";
1096
67
    } break;
1097
    // IC aliases
1098
119
    case 5: {
1099
237
    Search_IC: {
1100
237
      const AArch64IC_IC *IC = AArch64IC_lookupICByEncoding(Encoding);
1101
237
      if (!IC || !AArch64_testFeatureList(MI->csh->mode, IC->FeaturesRequired))
1102
119
        return false;
1103
118
      if (detail_is_set(MI)) {
1104
118
        aarch64_sysop sysop;
1105
118
        sysop.reg = IC->SysReg;
1106
118
            sysop.sub_type = AArch64_OP_IC;
1107
118
        AArch64_get_detail_op(MI, 0)->type = AArch64_OP_SYSREG;
1108
118
        AArch64_get_detail_op(MI, 0)->sysop = sysop;
1109
118
        AArch64_inc_op_count(MI);
1110
118
      }
1111
1112
118
      NeedsReg = IC->NeedsReg;
1113
118
      Ins = "ic ";
1114
118
      Name = IC->Name;
1115
118
    }
1116
118
    } break;
1117
    // DC aliases
1118
161
    case 4:
1119
164
    case 6:
1120
379
    case 10:
1121
511
    case 11:
1122
768
    case 12:
1123
1.03k
    case 13:
1124
1.04k
    case 14: {
1125
1.04k
      const AArch64DC_DC *DC = AArch64DC_lookupDCByEncoding(Encoding);
1126
1.04k
      if (!DC || !AArch64_testFeatureList(MI->csh->mode, DC->FeaturesRequired))
1127
889
        return false;
1128
155
      if (detail_is_set(MI)) {
1129
155
        aarch64_sysop sysop;
1130
155
        sysop.alias = DC->SysAlias;
1131
155
          sysop.sub_type = AArch64_OP_DC;
1132
155
        AArch64_get_detail_op(MI, 0)->type = AArch64_OP_SYSALIAS;
1133
155
        AArch64_get_detail_op(MI, 0)->sysop = sysop;
1134
155
        AArch64_inc_op_count(MI);
1135
155
      }
1136
1137
155
      NeedsReg = true;
1138
155
      Ins = "dc ";
1139
155
      Name = DC->Name;
1140
155
    } break;
1141
    // AT aliases
1142
56
    case 8:
1143
86
    case 9: {
1144
86
      const AArch64AT_AT *AT = AArch64AT_lookupATByEncoding(Encoding);
1145
86
      if (!AT || !AArch64_testFeatureList(MI->csh->mode, AT->FeaturesRequired))
1146
64
        return false;
1147
1148
22
      if (detail_is_set(MI)) {
1149
22
        aarch64_sysop sysop;
1150
22
        sysop.alias = AT->SysAlias;
1151
22
          sysop.sub_type = AArch64_OP_AT;
1152
22
        AArch64_get_detail_op(MI, 0)->type = AArch64_OP_SYSALIAS;
1153
22
        AArch64_get_detail_op(MI, 0)->sysop = sysop;
1154
22
        AArch64_inc_op_count(MI);
1155
22
      }
1156
22
      NeedsReg = true;
1157
22
      Ins = "at ";
1158
22
      Name = AT->Name;
1159
22
    } break;
1160
1.71k
    }
1161
1.71k
  } else if (CnVal == 8 || CnVal == 9) {
1162
    // TLBI aliases
1163
213
    const AArch64TLBI_TLBI *TLBI =
1164
213
      AArch64TLBI_lookupTLBIByEncoding(Encoding);
1165
213
    if (!TLBI || !AArch64_testFeatureList(MI->csh->mode, TLBI->FeaturesRequired))
1166
89
      return false;
1167
1168
124
    if (detail_is_set(MI)) {
1169
124
      aarch64_sysop sysop;
1170
124
      sysop.reg = TLBI->SysReg;
1171
124
      sysop.sub_type = AArch64_OP_TLBI;
1172
124
      AArch64_get_detail_op(MI, 0)->type = AArch64_OP_SYSREG;
1173
124
      AArch64_get_detail_op(MI, 0)->sysop = sysop;
1174
124
      AArch64_inc_op_count(MI);
1175
124
    }
1176
124
    NeedsReg = TLBI->NeedsReg;
1177
124
    Ins = "tlbi ";
1178
124
    Name = TLBI->Name;
1179
124
  } else
1180
224
    return false;
1181
1182
972
  #define TMP_STR_LEN 32
1183
486
  char Str[TMP_STR_LEN] = {0};
1184
486
  append_to_str_lower(Str, TMP_STR_LEN, Ins);
1185
486
  append_to_str_lower(Str, TMP_STR_LEN, Name);
1186
486
  #undef TMP_STR_LEN
1187
1188
486
  SStream_concat1(O, ' ');
1189
486
  SStream_concat0(O, Str);
1190
486
  if (NeedsReg) {
1191
282
    SStream_concat0(O, ", ");
1192
282
    printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (4))));
1193
282
    AArch64_set_detail_op_reg(MI, 4, MCInst_getOpVal(MI, 4));
1194
282
  }
1195
1196
486
  return true;
1197
2.15k
}
1198
1199
bool printSyspAlias(MCInst *MI, SStream *O)
1200
1.30k
{
1201
1.30k
  MCOperand *Op1 = MCInst_getOperand(MI, (0));
1202
1.30k
  MCOperand *Cn = MCInst_getOperand(MI, (1));
1203
1.30k
  MCOperand *Cm = MCInst_getOperand(MI, (2));
1204
1.30k
  MCOperand *Op2 = MCInst_getOperand(MI, (3));
1205
1206
1.30k
  unsigned Op1Val = MCOperand_getImm(Op1);
1207
1.30k
  unsigned CnVal = MCOperand_getImm(Cn);
1208
1.30k
  unsigned CmVal = MCOperand_getImm(Cm);
1209
1.30k
  unsigned Op2Val = MCOperand_getImm(Op2);
1210
1211
1.30k
  uint16_t Encoding = Op2Val;
1212
1.30k
  Encoding |= CmVal << 3;
1213
1.30k
  Encoding |= CnVal << 7;
1214
1.30k
  Encoding |= Op1Val << 11;
1215
1216
1.30k
  const char *Ins;
1217
1.30k
  const char *Name;
1218
1219
1.30k
  if (CnVal == 8 || CnVal == 9) {
1220
    // TLBIP aliases
1221
1222
775
    if (CnVal == 9) {
1223
682
      if (!AArch64_getFeatureBits(MI->csh->mode, AArch64_FeatureAll) ||
1224
682
        !AArch64_getFeatureBits(MI->csh->mode, AArch64_FeatureXS))
1225
0
        return false;
1226
682
      Encoding &= ~(1 << 7);
1227
682
    }
1228
1229
775
    const AArch64TLBI_TLBI *TLBI =
1230
775
      AArch64TLBI_lookupTLBIByEncoding(Encoding);
1231
775
    if (!TLBI || !AArch64_testFeatureList(MI->csh->mode, TLBI->FeaturesRequired))
1232
287
      return false;
1233
1234
488
    if (detail_is_set(MI)) {
1235
488
      aarch64_sysop sysop;
1236
488
      sysop.reg = TLBI->SysReg;
1237
488
      sysop.sub_type = AArch64_OP_TLBI;
1238
488
      AArch64_get_detail_op(MI, 0)->type = AArch64_OP_SYSREG;
1239
488
      AArch64_get_detail_op(MI, 0)->sysop = sysop;
1240
488
      AArch64_inc_op_count(MI);
1241
488
    }
1242
488
    Ins = "tlbip ";
1243
488
    Name = TLBI->Name;
1244
488
  } else
1245
534
    return false;
1246
1247
1.38k
  #define TMP_STR_LEN 32
1248
488
  char Str[TMP_STR_LEN] = {0};
1249
488
  append_to_str_lower(Str, TMP_STR_LEN, Ins);
1250
488
  append_to_str_lower(Str, TMP_STR_LEN, Name);
1251
1252
488
  if (CnVal == 9) {
1253
407
    append_to_str_lower(Str, TMP_STR_LEN, "nxs");
1254
407
  }
1255
488
  #undef TMP_STR_LEN
1256
1257
488
  SStream_concat1(O, ' ');
1258
488
  SStream_concat0(O, Str);
1259
488
  SStream_concat0(O, ", ");
1260
488
  if (MCOperand_getReg(MCInst_getOperand(MI, (4))) == AArch64_XZR)
1261
52
    printSyspXzrPair(MI, 4, O);
1262
436
  else
1263
436
    CONCAT(printGPRSeqPairsClassOperand, 64)(MI, 4, O);
1264
1265
488
  return true;
1266
1.30k
}
1267
1268
#define DEFINE_printMatrix(EltSize) \
1269
  void CONCAT(printMatrix, EltSize)(MCInst * MI, unsigned OpNum, SStream *O) \
1270
1.78k
  { \
1271
1.78k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_Matrix, EltSize), OpNum, \
1272
1.78k
            EltSize); \
1273
1.78k
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
1274
1.78k
\
1275
1.78k
    printRegName(O, MCOperand_getReg(RegOp)); \
1276
1.78k
    switch (EltSize) { \
1277
45
    case 0: \
1278
45
      break; \
1279
0
    case 8: \
1280
0
      SStream_concat0(O, ".b"); \
1281
0
      break; \
1282
59
    case 16: \
1283
59
      SStream_concat0(O, ".h"); \
1284
59
      break; \
1285
1.21k
    case 32: \
1286
1.21k
      SStream_concat0(O, ".s"); \
1287
1.21k
      break; \
1288
475
    case 64: \
1289
475
      SStream_concat0(O, ".d"); \
1290
475
      break; \
1291
0
    case 128: \
1292
0
      SStream_concat0(O, ".q"); \
1293
0
      break; \
1294
0
    default: \
1295
0
      assert(0 && "Unsupported element size"); \
1296
1.78k
    } \
1297
1.78k
  }
printMatrix_64
Line
Count
Source
1270
475
  { \
1271
475
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_Matrix, EltSize), OpNum, \
1272
475
            EltSize); \
1273
475
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
1274
475
\
1275
475
    printRegName(O, MCOperand_getReg(RegOp)); \
1276
475
    switch (EltSize) { \
1277
0
    case 0: \
1278
0
      break; \
1279
0
    case 8: \
1280
0
      SStream_concat0(O, ".b"); \
1281
0
      break; \
1282
0
    case 16: \
1283
0
      SStream_concat0(O, ".h"); \
1284
0
      break; \
1285
0
    case 32: \
1286
0
      SStream_concat0(O, ".s"); \
1287
0
      break; \
1288
475
    case 64: \
1289
475
      SStream_concat0(O, ".d"); \
1290
475
      break; \
1291
0
    case 128: \
1292
0
      SStream_concat0(O, ".q"); \
1293
0
      break; \
1294
0
    default: \
1295
0
      assert(0 && "Unsupported element size"); \
1296
475
    } \
1297
475
  }
printMatrix_32
Line
Count
Source
1270
1.21k
  { \
1271
1.21k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_Matrix, EltSize), OpNum, \
1272
1.21k
            EltSize); \
1273
1.21k
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
1274
1.21k
\
1275
1.21k
    printRegName(O, MCOperand_getReg(RegOp)); \
1276
1.21k
    switch (EltSize) { \
1277
0
    case 0: \
1278
0
      break; \
1279
0
    case 8: \
1280
0
      SStream_concat0(O, ".b"); \
1281
0
      break; \
1282
0
    case 16: \
1283
0
      SStream_concat0(O, ".h"); \
1284
0
      break; \
1285
1.21k
    case 32: \
1286
1.21k
      SStream_concat0(O, ".s"); \
1287
1.21k
      break; \
1288
0
    case 64: \
1289
0
      SStream_concat0(O, ".d"); \
1290
0
      break; \
1291
0
    case 128: \
1292
0
      SStream_concat0(O, ".q"); \
1293
0
      break; \
1294
0
    default: \
1295
0
      assert(0 && "Unsupported element size"); \
1296
1.21k
    } \
1297
1.21k
  }
printMatrix_16
Line
Count
Source
1270
59
  { \
1271
59
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_Matrix, EltSize), OpNum, \
1272
59
            EltSize); \
1273
59
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
1274
59
\
1275
59
    printRegName(O, MCOperand_getReg(RegOp)); \
1276
59
    switch (EltSize) { \
1277
0
    case 0: \
1278
0
      break; \
1279
0
    case 8: \
1280
0
      SStream_concat0(O, ".b"); \
1281
0
      break; \
1282
59
    case 16: \
1283
59
      SStream_concat0(O, ".h"); \
1284
59
      break; \
1285
0
    case 32: \
1286
0
      SStream_concat0(O, ".s"); \
1287
0
      break; \
1288
0
    case 64: \
1289
0
      SStream_concat0(O, ".d"); \
1290
0
      break; \
1291
0
    case 128: \
1292
0
      SStream_concat0(O, ".q"); \
1293
0
      break; \
1294
0
    default: \
1295
0
      assert(0 && "Unsupported element size"); \
1296
59
    } \
1297
59
  }
printMatrix_0
Line
Count
Source
1270
45
  { \
1271
45
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_Matrix, EltSize), OpNum, \
1272
45
            EltSize); \
1273
45
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
1274
45
\
1275
45
    printRegName(O, MCOperand_getReg(RegOp)); \
1276
45
    switch (EltSize) { \
1277
45
    case 0: \
1278
45
      break; \
1279
0
    case 8: \
1280
0
      SStream_concat0(O, ".b"); \
1281
0
      break; \
1282
0
    case 16: \
1283
0
      SStream_concat0(O, ".h"); \
1284
0
      break; \
1285
0
    case 32: \
1286
0
      SStream_concat0(O, ".s"); \
1287
0
      break; \
1288
0
    case 64: \
1289
0
      SStream_concat0(O, ".d"); \
1290
0
      break; \
1291
0
    case 128: \
1292
0
      SStream_concat0(O, ".q"); \
1293
0
      break; \
1294
0
    default: \
1295
0
      assert(0 && "Unsupported element size"); \
1296
45
    } \
1297
45
  }
1298
DEFINE_printMatrix(64);
1299
DEFINE_printMatrix(32);
1300
DEFINE_printMatrix(16);
1301
DEFINE_printMatrix(0);
1302
1303
#define DEFINE_printMatrixTileVector(IsVertical) \
1304
  void CONCAT(printMatrixTileVector, IsVertical)(MCInst * MI, \
1305
                           unsigned OpNum, SStream *O) \
1306
2.73k
  { \
1307
2.73k
    add_cs_detail(MI, \
1308
2.73k
            CONCAT(AArch64_OP_GROUP_MatrixTileVector, IsVertical), \
1309
2.73k
            OpNum, IsVertical); \
1310
2.73k
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
1311
2.73k
\
1312
2.73k
    const char *RegName = getRegisterName(MCOperand_getReg(RegOp), AArch64_NoRegAltName); \
1313
2.73k
\
1314
2.73k
    unsigned buf_len = strlen(RegName) + 1; \
1315
2.73k
    char *Base = calloc(1, buf_len); \
1316
2.73k
    memcpy(Base, RegName, buf_len); \
1317
2.73k
    char *Dot = strchr(Base, '.'); \
1318
2.73k
    if (!Dot) { \
1319
0
      SStream_concat0(O, RegName); \
1320
0
      return; \
1321
0
    } \
1322
2.73k
    *Dot = '\0'; /* Split string */ \
1323
2.73k
    char *Suffix = Dot + 1; \
1324
2.73k
    SStream_concat(O, "%s%s", Base, (IsVertical ? "v" : "h")); \
1325
2.73k
    SStream_concat1(O, '.'); \
1326
2.73k
    SStream_concat0(O, Suffix); \
1327
2.73k
    free(Base); \
1328
2.73k
  }
printMatrixTileVector_0
Line
Count
Source
1306
793
  { \
1307
793
    add_cs_detail(MI, \
1308
793
            CONCAT(AArch64_OP_GROUP_MatrixTileVector, IsVertical), \
1309
793
            OpNum, IsVertical); \
1310
793
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
1311
793
\
1312
793
    const char *RegName = getRegisterName(MCOperand_getReg(RegOp), AArch64_NoRegAltName); \
1313
793
\
1314
793
    unsigned buf_len = strlen(RegName) + 1; \
1315
793
    char *Base = calloc(1, buf_len); \
1316
793
    memcpy(Base, RegName, buf_len); \
1317
793
    char *Dot = strchr(Base, '.'); \
1318
793
    if (!Dot) { \
1319
0
      SStream_concat0(O, RegName); \
1320
0
      return; \
1321
0
    } \
1322
793
    *Dot = '\0'; /* Split string */ \
1323
793
    char *Suffix = Dot + 1; \
1324
793
    SStream_concat(O, "%s%s", Base, (IsVertical ? "v" : "h")); \
1325
793
    SStream_concat1(O, '.'); \
1326
793
    SStream_concat0(O, Suffix); \
1327
793
    free(Base); \
1328
793
  }
printMatrixTileVector_1
Line
Count
Source
1306
1.93k
  { \
1307
1.93k
    add_cs_detail(MI, \
1308
1.93k
            CONCAT(AArch64_OP_GROUP_MatrixTileVector, IsVertical), \
1309
1.93k
            OpNum, IsVertical); \
1310
1.93k
    MCOperand *RegOp = MCInst_getOperand(MI, (OpNum)); \
1311
1.93k
\
1312
1.93k
    const char *RegName = getRegisterName(MCOperand_getReg(RegOp), AArch64_NoRegAltName); \
1313
1.93k
\
1314
1.93k
    unsigned buf_len = strlen(RegName) + 1; \
1315
1.93k
    char *Base = calloc(1, buf_len); \
1316
1.93k
    memcpy(Base, RegName, buf_len); \
1317
1.93k
    char *Dot = strchr(Base, '.'); \
1318
1.93k
    if (!Dot) { \
1319
0
      SStream_concat0(O, RegName); \
1320
0
      return; \
1321
0
    } \
1322
1.93k
    *Dot = '\0'; /* Split string */ \
1323
1.93k
    char *Suffix = Dot + 1; \
1324
1.93k
    SStream_concat(O, "%s%s", Base, (IsVertical ? "v" : "h")); \
1325
1.93k
    SStream_concat1(O, '.'); \
1326
1.93k
    SStream_concat0(O, Suffix); \
1327
1.93k
    free(Base); \
1328
1.93k
  }
1329
DEFINE_printMatrixTileVector(0);
1330
DEFINE_printMatrixTileVector(1);
1331
1332
void printMatrixTile(MCInst *MI, unsigned OpNum, SStream *O)
1333
1.22k
{
1334
1.22k
  add_cs_detail(MI, AArch64_OP_GROUP_MatrixTile, OpNum);
1335
1.22k
  MCOperand *RegOp = MCInst_getOperand(MI, (OpNum));
1336
1337
1.22k
  printRegName(O, MCOperand_getReg(RegOp));
1338
1.22k
}
1339
1340
void printSVCROp(MCInst *MI, unsigned OpNum, SStream *O)
1341
0
{
1342
0
  add_cs_detail(MI, AArch64_OP_GROUP_SVCROp, OpNum);
1343
0
  MCOperand *MO = MCInst_getOperand(MI, (OpNum));
1344
1345
0
  unsigned svcrop = MCOperand_getImm(MO);
1346
0
  const AArch64SVCR_SVCR *SVCR = AArch64SVCR_lookupSVCRByEncoding(svcrop);
1347
1348
0
  SStream_concat0(O, SVCR->Name);
1349
0
}
1350
1351
void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
1352
258k
{
1353
258k
  add_cs_detail(MI, AArch64_OP_GROUP_Operand, OpNo);
1354
258k
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1355
258k
  if (MCOperand_isReg(Op)) {
1356
216k
    unsigned Reg = MCOperand_getReg(Op);
1357
216k
    printRegName(O, Reg);
1358
216k
  } else if (MCOperand_isImm(Op)) {
1359
42.0k
    MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1360
42.0k
    SStream_concat(O, "%s", markup("<imm:"));
1361
42.0k
    printInt64Bang(O, MCOperand_getImm(Op));
1362
42.0k
    SStream_concat0(O, markup(">"));
1363
42.0k
  } else {
1364
0
    assert(0 && "Expressions are not supported.");
1365
0
  }
1366
258k
}
1367
1368
void printImm(MCInst *MI, unsigned OpNo, SStream *O)
1369
3.14k
{
1370
3.14k
  add_cs_detail(MI, AArch64_OP_GROUP_Imm, OpNo);
1371
3.14k
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1372
3.14k
  SStream_concat(O, "%s", markup("<imm:"));
1373
3.14k
  printInt64Bang(O, MCOperand_getImm(Op));
1374
3.14k
  SStream_concat0(O, markup(">"));
1375
3.14k
}
1376
1377
void printImmHex(MCInst *MI, unsigned OpNo, SStream *O)
1378
88
{
1379
88
  add_cs_detail(MI, AArch64_OP_GROUP_ImmHex, OpNo);
1380
88
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1381
88
  SStream_concat(O, "%s", markup("<imm:"));
1382
88
  printInt64Bang(O, MCOperand_getImm(Op));
1383
88
  SStream_concat0(O, markup(">"));
1384
88
}
1385
1386
#define DEFINE_printSImm(Size) \
1387
  void CONCAT(printSImm, Size)(MCInst * MI, unsigned OpNo, SStream *O) \
1388
517
  { \
1389
517
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_SImm, Size), OpNo, Size); \
1390
517
    MCOperand *Op = MCInst_getOperand(MI, (OpNo)); \
1391
517
    if (Size == 8) { \
1392
283
      SStream_concat(O, "%s", markup("<imm:")); \
1393
283
      printInt32Bang(O, MCOperand_getImm(Op)); \
1394
283
      SStream_concat0(O, markup(">")); \
1395
283
    } else if (Size == 16) { \
1396
234
      SStream_concat(O, "%s", markup("<imm:")); \
1397
234
      printInt32Bang(O, MCOperand_getImm(Op)); \
1398
234
      SStream_concat0(O, markup(">")); \
1399
234
    } else { \
1400
0
      SStream_concat(O, "%s", markup("<imm:")); \
1401
0
      printInt64Bang(O, MCOperand_getImm(Op)); \
1402
0
      SStream_concat0(O, markup(">")); \
1403
0
    } \
1404
517
  }
printSImm_16
Line
Count
Source
1388
234
  { \
1389
234
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_SImm, Size), OpNo, Size); \
1390
234
    MCOperand *Op = MCInst_getOperand(MI, (OpNo)); \
1391
234
    if (Size == 8) { \
1392
0
      SStream_concat(O, "%s", markup("<imm:")); \
1393
0
      printInt32Bang(O, MCOperand_getImm(Op)); \
1394
0
      SStream_concat0(O, markup(">")); \
1395
234
    } else if (Size == 16) { \
1396
234
      SStream_concat(O, "%s", markup("<imm:")); \
1397
234
      printInt32Bang(O, MCOperand_getImm(Op)); \
1398
234
      SStream_concat0(O, markup(">")); \
1399
234
    } else { \
1400
0
      SStream_concat(O, "%s", markup("<imm:")); \
1401
0
      printInt64Bang(O, MCOperand_getImm(Op)); \
1402
0
      SStream_concat0(O, markup(">")); \
1403
0
    } \
1404
234
  }
printSImm_8
Line
Count
Source
1388
283
  { \
1389
283
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_SImm, Size), OpNo, Size); \
1390
283
    MCOperand *Op = MCInst_getOperand(MI, (OpNo)); \
1391
283
    if (Size == 8) { \
1392
283
      SStream_concat(O, "%s", markup("<imm:")); \
1393
283
      printInt32Bang(O, MCOperand_getImm(Op)); \
1394
283
      SStream_concat0(O, markup(">")); \
1395
283
    } else if (Size == 16) { \
1396
0
      SStream_concat(O, "%s", markup("<imm:")); \
1397
0
      printInt32Bang(O, MCOperand_getImm(Op)); \
1398
0
      SStream_concat0(O, markup(">")); \
1399
0
    } else { \
1400
0
      SStream_concat(O, "%s", markup("<imm:")); \
1401
0
      printInt64Bang(O, MCOperand_getImm(Op)); \
1402
0
      SStream_concat0(O, markup(">")); \
1403
0
    } \
1404
283
  }
1405
DEFINE_printSImm(16);
1406
DEFINE_printSImm(8);
1407
1408
void printPostIncOperand(MCInst *MI, unsigned OpNo, unsigned Imm, SStream *O)
1409
5.61k
{
1410
5.61k
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1411
5.61k
  if (MCOperand_isReg(Op)) {
1412
5.61k
    unsigned Reg = MCOperand_getReg(Op);
1413
5.61k
    if (Reg == AArch64_XZR) {
1414
0
      SStream_concat(O, "%s", markup("<imm:"));
1415
0
      printUInt64Bang(O, Imm);
1416
0
      SStream_concat0(O, markup(">"));
1417
0
    } else
1418
5.61k
      printRegName(O, Reg);
1419
5.61k
  } else
1420
0
    assert(0 && "unknown operand kind in printPostIncOperand64");
1421
5.61k
}
1422
1423
void printVRegOperand(MCInst *MI, unsigned OpNo, SStream *O)
1424
39.7k
{
1425
39.7k
  add_cs_detail(MI, AArch64_OP_GROUP_VRegOperand, OpNo);
1426
39.7k
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1427
1428
39.7k
  unsigned Reg = MCOperand_getReg(Op);
1429
39.7k
  printRegNameAlt(O, Reg, AArch64_vreg);
1430
39.7k
}
1431
1432
void printSysCROperand(MCInst *MI, unsigned OpNo, SStream *O)
1433
5.16k
{
1434
5.16k
  add_cs_detail(MI, AArch64_OP_GROUP_SysCROperand, OpNo);
1435
5.16k
  MCOperand *Op = MCInst_getOperand(MI, (OpNo));
1436
1437
5.16k
  SStream_concat(O, "%s", "c");
1438
5.16k
  printUInt32(O, MCOperand_getImm(Op));
1439
5.16k
  SStream_concat1(O, '\0');
1440
5.16k
}
1441
1442
void printAddSubImm(MCInst *MI, unsigned OpNum, SStream *O)
1443
1.95k
{
1444
1.95k
  add_cs_detail(MI, AArch64_OP_GROUP_AddSubImm, OpNum);
1445
1.95k
  MCOperand *MO = MCInst_getOperand(MI, (OpNum));
1446
1.95k
  if (MCOperand_isImm(MO)) {
1447
1.95k
    unsigned Val = (MCOperand_getImm(MO) & 0xfff);
1448
1449
1.95k
    unsigned Shift = AArch64_AM_getShiftValue(
1450
1.95k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))));
1451
1.95k
    SStream_concat(O, "%s", markup("<imm:"));
1452
1.95k
    printUInt32Bang(O, (Val));
1453
1.95k
    SStream_concat0(O, markup(">"));
1454
1.95k
    if (Shift != 0) {
1455
766
      printShifter(MI, OpNum + 1, O);
1456
766
    }
1457
1.95k
  } else {
1458
0
    printShifter(MI, OpNum + 1, O);
1459
0
  }
1460
1.95k
}
1461
1462
#define DEFINE_printLogicalImm(T) \
1463
  void CONCAT(printLogicalImm, T)(MCInst * MI, unsigned OpNum, SStream *O) \
1464
4.43k
  { \
1465
4.43k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, sizeof(T)); \
1466
4.43k
    uint64_t Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1467
4.43k
    SStream_concat(O, "%s", markup("<imm:")); \
1468
4.43k
    printUInt64Bang(O, (AArch64_AM_decodeLogicalImmediate(Val, 8 * sizeof(T)))); \
1469
4.43k
    SStream_concat0(O, markup(">")); \
1470
4.43k
  }
printLogicalImm_int64_t
Line
Count
Source
1464
1.09k
  { \
1465
1.09k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, sizeof(T)); \
1466
1.09k
    uint64_t Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1467
1.09k
    SStream_concat(O, "%s", markup("<imm:")); \
1468
1.09k
    printUInt64Bang(O, (AArch64_AM_decodeLogicalImmediate(Val, 8 * sizeof(T)))); \
1469
1.09k
    SStream_concat0(O, markup(">")); \
1470
1.09k
  }
printLogicalImm_int32_t
Line
Count
Source
1464
2.33k
  { \
1465
2.33k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, sizeof(T)); \
1466
2.33k
    uint64_t Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1467
2.33k
    SStream_concat(O, "%s", markup("<imm:")); \
1468
2.33k
    printUInt64Bang(O, (AArch64_AM_decodeLogicalImmediate(Val, 8 * sizeof(T)))); \
1469
2.33k
    SStream_concat0(O, markup(">")); \
1470
2.33k
  }
printLogicalImm_int8_t
Line
Count
Source
1464
326
  { \
1465
326
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, sizeof(T)); \
1466
326
    uint64_t Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1467
326
    SStream_concat(O, "%s", markup("<imm:")); \
1468
326
    printUInt64Bang(O, (AArch64_AM_decodeLogicalImmediate(Val, 8 * sizeof(T)))); \
1469
326
    SStream_concat0(O, markup(">")); \
1470
326
  }
printLogicalImm_int16_t
Line
Count
Source
1464
672
  { \
1465
672
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_LogicalImm, T), OpNum, sizeof(T)); \
1466
672
    uint64_t Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1467
672
    SStream_concat(O, "%s", markup("<imm:")); \
1468
672
    printUInt64Bang(O, (AArch64_AM_decodeLogicalImmediate(Val, 8 * sizeof(T)))); \
1469
672
    SStream_concat0(O, markup(">")); \
1470
672
  }
1471
DEFINE_printLogicalImm(int64_t);
1472
DEFINE_printLogicalImm(int32_t);
1473
DEFINE_printLogicalImm(int8_t);
1474
DEFINE_printLogicalImm(int16_t);
1475
1476
void printShifter(MCInst *MI, unsigned OpNum, SStream *O)
1477
8.53k
{
1478
8.53k
  add_cs_detail(MI, AArch64_OP_GROUP_Shifter, OpNum);
1479
8.53k
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1480
  // LSL #0 should not be printed.
1481
8.53k
  if (AArch64_AM_getShiftType(Val) == AArch64_AM_LSL &&
1482
8.53k
    AArch64_AM_getShiftValue(Val) == 0)
1483
430
    return;
1484
8.10k
  SStream_concat(O, "%s%s%s%s#%d", ", ",
1485
8.10k
           AArch64_AM_getShiftExtendName(AArch64_AM_getShiftType(Val)),
1486
8.10k
           " ", markup("<imm:"), AArch64_AM_getShiftValue(Val));
1487
8.10k
  SStream_concat0(O, markup(">"));
1488
8.10k
}
1489
1490
void printShiftedRegister(MCInst *MI, unsigned OpNum, SStream *O)
1491
5.67k
{
1492
5.67k
  add_cs_detail(MI, AArch64_OP_GROUP_ShiftedRegister, OpNum);
1493
5.67k
  printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))));
1494
5.67k
  printShifter(MI, OpNum + 1, O);
1495
5.67k
}
1496
1497
void printExtendedRegister(MCInst *MI, unsigned OpNum, SStream *O)
1498
1.39k
{
1499
1.39k
  add_cs_detail(MI, AArch64_OP_GROUP_ExtendedRegister, OpNum);
1500
1.39k
  printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))));
1501
1.39k
  printArithExtend(MI, OpNum + 1, O);
1502
1.39k
}
1503
1504
void printArithExtend(MCInst *MI, unsigned OpNum, SStream *O)
1505
1.98k
{
1506
1.98k
  add_cs_detail(MI, AArch64_OP_GROUP_ArithExtend, OpNum);
1507
1.98k
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1508
1.98k
  AArch64_AM_ShiftExtendType ExtType = AArch64_AM_getArithExtendType(Val);
1509
1.98k
  unsigned ShiftVal = AArch64_AM_getArithShiftValue(Val);
1510
1511
  // If the destination or first source register operand is [W]SP, print
1512
  // UXTW/UXTX as LSL, and if the shift amount is also zero, print nothing at
1513
  // all.
1514
1.98k
  if (ExtType == AArch64_AM_UXTW || ExtType == AArch64_AM_UXTX) {
1515
843
    unsigned Dest = MCOperand_getReg(MCInst_getOperand(MI, (0)));
1516
843
    unsigned Src1 = MCOperand_getReg(MCInst_getOperand(MI, (1)));
1517
843
    if (((Dest == AArch64_SP || Src1 == AArch64_SP) &&
1518
843
       ExtType == AArch64_AM_UXTX) ||
1519
843
      ((Dest == AArch64_WSP || Src1 == AArch64_WSP) &&
1520
708
       ExtType == AArch64_AM_UXTW)) {
1521
273
      if (ShiftVal != 0) {
1522
273
        SStream_concat(O, "%s%s", ", lsl ", markup("<imm:"));
1523
273
        printUInt32Bang(O, ShiftVal);
1524
273
        SStream_concat0(O, markup(">"));
1525
273
      }
1526
273
      return;
1527
273
    }
1528
843
  }
1529
1.71k
  SStream_concat(O, "%s", ", ");
1530
1.71k
  SStream_concat0(O, AArch64_AM_getShiftExtendName(ExtType));
1531
1.71k
  if (ShiftVal != 0) {
1532
1.39k
    SStream_concat(O, "%s%s#%d", " ", markup("<imm:"), ShiftVal);
1533
1.39k
    SStream_concat0(O, markup(">"));
1534
1.39k
  }
1535
1.71k
}
1536
1537
static void printMemExtendImpl(bool SignExtend, bool DoShift, unsigned Width,
1538
                 char SrcRegKind, SStream *O, bool getUseMarkup)
1539
8.39k
{
1540
  // sxtw, sxtx, uxtw or lsl (== uxtx)
1541
8.39k
  bool IsLSL = !SignExtend && SrcRegKind == 'x';
1542
8.39k
  if (IsLSL)
1543
4.42k
    SStream_concat0(O, "lsl");
1544
3.96k
  else {
1545
3.96k
    SStream_concat(O, "%c%s", (SignExtend ? 's' : 'u'), "xt");
1546
3.96k
    SStream_concat1(O, SrcRegKind);
1547
3.96k
  }
1548
1549
8.39k
  if (DoShift || IsLSL) {
1550
7.02k
    SStream_concat0(O, " ");
1551
7.02k
    if (getUseMarkup)
1552
0
      SStream_concat0(O, "<imm:");
1553
7.02k
    unsigned ShiftAmount = DoShift ? Log2_32(Width / 8) : 0;
1554
7.02k
    SStream_concat(O, "%s%d", "#", ShiftAmount);
1555
7.02k
    if (getUseMarkup)
1556
0
      SStream_concat0(O, ">");
1557
7.02k
  }
1558
8.39k
}
1559
1560
void printMemExtend(MCInst *MI, unsigned OpNum, SStream *O, char SrcRegKind,
1561
          unsigned Width)
1562
1.52k
{
1563
1.52k
  bool SignExtend = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1564
1.52k
  bool DoShift = MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1)));
1565
1.52k
  printMemExtendImpl(SignExtend, DoShift, Width, SrcRegKind, O,
1566
1.52k
             getUseMarkup());
1567
1.52k
}
1568
1569
#define DEFINE_printRegWithShiftExtend(SignExtend, ExtWidth, SrcRegKind, \
1570
                     Suffix) \
1571
  void CONCAT( \
1572
    printRegWithShiftExtend, \
1573
    CONCAT(SignExtend, CONCAT(ExtWidth, CONCAT(SrcRegKind, Suffix))))( \
1574
    MCInst * MI, unsigned OpNum, SStream *O) \
1575
9.12k
  { \
1576
9.12k
    add_cs_detail( \
1577
9.12k
      MI, \
1578
9.12k
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
9.12k
                    SignExtend), \
1580
9.12k
                 ExtWidth), \
1581
9.12k
              SrcRegKind), \
1582
9.12k
           Suffix), \
1583
9.12k
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
9.12k
    printOperand(MI, OpNum, O); \
1585
9.12k
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
5.78k
      SStream_concat1(O, '.'); \
1587
5.78k
      SStream_concat1(O, CHAR(Suffix)); \
1588
5.78k
      SStream_concat1(O, '\0'); \
1589
5.78k
    } else \
1590
9.12k
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
9.12k
    bool DoShift = ExtWidth != 8; \
1592
9.12k
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
6.86k
      SStream_concat0(O, ", "); \
1594
6.86k
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
6.86k
                 getUseMarkup()); \
1596
6.86k
    } \
1597
9.12k
  }
printRegWithShiftExtend_0_8_x_d
Line
Count
Source
1575
1.21k
  { \
1576
1.21k
    add_cs_detail( \
1577
1.21k
      MI, \
1578
1.21k
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
1.21k
                    SignExtend), \
1580
1.21k
                 ExtWidth), \
1581
1.21k
              SrcRegKind), \
1582
1.21k
           Suffix), \
1583
1.21k
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
1.21k
    printOperand(MI, OpNum, O); \
1585
1.21k
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
1.21k
      SStream_concat1(O, '.'); \
1587
1.21k
      SStream_concat1(O, CHAR(Suffix)); \
1588
1.21k
      SStream_concat1(O, '\0'); \
1589
1.21k
    } else \
1590
1.21k
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
1.21k
    bool DoShift = ExtWidth != 8; \
1592
1.21k
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
0
      SStream_concat0(O, ", "); \
1594
0
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
0
                 getUseMarkup()); \
1596
0
    } \
1597
1.21k
  }
printRegWithShiftExtend_1_8_w_d
Line
Count
Source
1575
262
  { \
1576
262
    add_cs_detail( \
1577
262
      MI, \
1578
262
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
262
                    SignExtend), \
1580
262
                 ExtWidth), \
1581
262
              SrcRegKind), \
1582
262
           Suffix), \
1583
262
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
262
    printOperand(MI, OpNum, O); \
1585
262
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
262
      SStream_concat1(O, '.'); \
1587
262
      SStream_concat1(O, CHAR(Suffix)); \
1588
262
      SStream_concat1(O, '\0'); \
1589
262
    } else \
1590
262
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
262
    bool DoShift = ExtWidth != 8; \
1592
262
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
262
      SStream_concat0(O, ", "); \
1594
262
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
262
                 getUseMarkup()); \
1596
262
    } \
1597
262
  }
printRegWithShiftExtend_0_8_w_d
Line
Count
Source
1575
485
  { \
1576
485
    add_cs_detail( \
1577
485
      MI, \
1578
485
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
485
                    SignExtend), \
1580
485
                 ExtWidth), \
1581
485
              SrcRegKind), \
1582
485
           Suffix), \
1583
485
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
485
    printOperand(MI, OpNum, O); \
1585
485
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
485
      SStream_concat1(O, '.'); \
1587
485
      SStream_concat1(O, CHAR(Suffix)); \
1588
485
      SStream_concat1(O, '\0'); \
1589
485
    } else \
1590
485
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
485
    bool DoShift = ExtWidth != 8; \
1592
485
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
485
      SStream_concat0(O, ", "); \
1594
485
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
485
                 getUseMarkup()); \
1596
485
    } \
1597
485
  }
printRegWithShiftExtend_0_8_x_0
Line
Count
Source
1575
849
  { \
1576
849
    add_cs_detail( \
1577
849
      MI, \
1578
849
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
849
                    SignExtend), \
1580
849
                 ExtWidth), \
1581
849
              SrcRegKind), \
1582
849
           Suffix), \
1583
849
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
849
    printOperand(MI, OpNum, O); \
1585
849
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
0
      SStream_concat1(O, '.'); \
1587
0
      SStream_concat1(O, CHAR(Suffix)); \
1588
0
      SStream_concat1(O, '\0'); \
1589
0
    } else \
1590
849
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
849
    bool DoShift = ExtWidth != 8; \
1592
849
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
0
      SStream_concat0(O, ", "); \
1594
0
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
0
                 getUseMarkup()); \
1596
0
    } \
1597
849
  }
printRegWithShiftExtend_1_8_w_s
Line
Count
Source
1575
166
  { \
1576
166
    add_cs_detail( \
1577
166
      MI, \
1578
166
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
166
                    SignExtend), \
1580
166
                 ExtWidth), \
1581
166
              SrcRegKind), \
1582
166
           Suffix), \
1583
166
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
166
    printOperand(MI, OpNum, O); \
1585
166
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
166
      SStream_concat1(O, '.'); \
1587
166
      SStream_concat1(O, CHAR(Suffix)); \
1588
166
      SStream_concat1(O, '\0'); \
1589
166
    } else \
1590
166
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
166
    bool DoShift = ExtWidth != 8; \
1592
166
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
166
      SStream_concat0(O, ", "); \
1594
166
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
166
                 getUseMarkup()); \
1596
166
    } \
1597
166
  }
printRegWithShiftExtend_0_8_w_s
Line
Count
Source
1575
314
  { \
1576
314
    add_cs_detail( \
1577
314
      MI, \
1578
314
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
314
                    SignExtend), \
1580
314
                 ExtWidth), \
1581
314
              SrcRegKind), \
1582
314
           Suffix), \
1583
314
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
314
    printOperand(MI, OpNum, O); \
1585
314
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
314
      SStream_concat1(O, '.'); \
1587
314
      SStream_concat1(O, CHAR(Suffix)); \
1588
314
      SStream_concat1(O, '\0'); \
1589
314
    } else \
1590
314
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
314
    bool DoShift = ExtWidth != 8; \
1592
314
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
314
      SStream_concat0(O, ", "); \
1594
314
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
314
                 getUseMarkup()); \
1596
314
    } \
1597
314
  }
printRegWithShiftExtend_0_64_x_d
Line
Count
Source
1575
145
  { \
1576
145
    add_cs_detail( \
1577
145
      MI, \
1578
145
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
145
                    SignExtend), \
1580
145
                 ExtWidth), \
1581
145
              SrcRegKind), \
1582
145
           Suffix), \
1583
145
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
145
    printOperand(MI, OpNum, O); \
1585
145
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
145
      SStream_concat1(O, '.'); \
1587
145
      SStream_concat1(O, CHAR(Suffix)); \
1588
145
      SStream_concat1(O, '\0'); \
1589
145
    } else \
1590
145
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
145
    bool DoShift = ExtWidth != 8; \
1592
145
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
145
      SStream_concat0(O, ", "); \
1594
145
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
145
                 getUseMarkup()); \
1596
145
    } \
1597
145
  }
printRegWithShiftExtend_1_64_w_d
Line
Count
Source
1575
87
  { \
1576
87
    add_cs_detail( \
1577
87
      MI, \
1578
87
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
87
                    SignExtend), \
1580
87
                 ExtWidth), \
1581
87
              SrcRegKind), \
1582
87
           Suffix), \
1583
87
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
87
    printOperand(MI, OpNum, O); \
1585
87
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
87
      SStream_concat1(O, '.'); \
1587
87
      SStream_concat1(O, CHAR(Suffix)); \
1588
87
      SStream_concat1(O, '\0'); \
1589
87
    } else \
1590
87
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
87
    bool DoShift = ExtWidth != 8; \
1592
87
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
87
      SStream_concat0(O, ", "); \
1594
87
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
87
                 getUseMarkup()); \
1596
87
    } \
1597
87
  }
printRegWithShiftExtend_0_64_w_d
Line
Count
Source
1575
61
  { \
1576
61
    add_cs_detail( \
1577
61
      MI, \
1578
61
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
61
                    SignExtend), \
1580
61
                 ExtWidth), \
1581
61
              SrcRegKind), \
1582
61
           Suffix), \
1583
61
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
61
    printOperand(MI, OpNum, O); \
1585
61
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
61
      SStream_concat1(O, '.'); \
1587
61
      SStream_concat1(O, CHAR(Suffix)); \
1588
61
      SStream_concat1(O, '\0'); \
1589
61
    } else \
1590
61
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
61
    bool DoShift = ExtWidth != 8; \
1592
61
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
61
      SStream_concat0(O, ", "); \
1594
61
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
61
                 getUseMarkup()); \
1596
61
    } \
1597
61
  }
printRegWithShiftExtend_0_64_x_0
Line
Count
Source
1575
714
  { \
1576
714
    add_cs_detail( \
1577
714
      MI, \
1578
714
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
714
                    SignExtend), \
1580
714
                 ExtWidth), \
1581
714
              SrcRegKind), \
1582
714
           Suffix), \
1583
714
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
714
    printOperand(MI, OpNum, O); \
1585
714
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
0
      SStream_concat1(O, '.'); \
1587
0
      SStream_concat1(O, CHAR(Suffix)); \
1588
0
      SStream_concat1(O, '\0'); \
1589
0
    } else \
1590
714
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
714
    bool DoShift = ExtWidth != 8; \
1592
714
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
714
      SStream_concat0(O, ", "); \
1594
714
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
714
                 getUseMarkup()); \
1596
714
    } \
1597
714
  }
printRegWithShiftExtend_1_64_w_s
Line
Count
Source
1575
188
  { \
1576
188
    add_cs_detail( \
1577
188
      MI, \
1578
188
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
188
                    SignExtend), \
1580
188
                 ExtWidth), \
1581
188
              SrcRegKind), \
1582
188
           Suffix), \
1583
188
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
188
    printOperand(MI, OpNum, O); \
1585
188
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
188
      SStream_concat1(O, '.'); \
1587
188
      SStream_concat1(O, CHAR(Suffix)); \
1588
188
      SStream_concat1(O, '\0'); \
1589
188
    } else \
1590
188
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
188
    bool DoShift = ExtWidth != 8; \
1592
188
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
188
      SStream_concat0(O, ", "); \
1594
188
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
188
                 getUseMarkup()); \
1596
188
    } \
1597
188
  }
printRegWithShiftExtend_0_64_w_s
Line
Count
Source
1575
19
  { \
1576
19
    add_cs_detail( \
1577
19
      MI, \
1578
19
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
19
                    SignExtend), \
1580
19
                 ExtWidth), \
1581
19
              SrcRegKind), \
1582
19
           Suffix), \
1583
19
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
19
    printOperand(MI, OpNum, O); \
1585
19
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
19
      SStream_concat1(O, '.'); \
1587
19
      SStream_concat1(O, CHAR(Suffix)); \
1588
19
      SStream_concat1(O, '\0'); \
1589
19
    } else \
1590
19
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
19
    bool DoShift = ExtWidth != 8; \
1592
19
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
19
      SStream_concat0(O, ", "); \
1594
19
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
19
                 getUseMarkup()); \
1596
19
    } \
1597
19
  }
printRegWithShiftExtend_0_16_x_d
Line
Count
Source
1575
364
  { \
1576
364
    add_cs_detail( \
1577
364
      MI, \
1578
364
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
364
                    SignExtend), \
1580
364
                 ExtWidth), \
1581
364
              SrcRegKind), \
1582
364
           Suffix), \
1583
364
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
364
    printOperand(MI, OpNum, O); \
1585
364
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
364
      SStream_concat1(O, '.'); \
1587
364
      SStream_concat1(O, CHAR(Suffix)); \
1588
364
      SStream_concat1(O, '\0'); \
1589
364
    } else \
1590
364
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
364
    bool DoShift = ExtWidth != 8; \
1592
364
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
364
      SStream_concat0(O, ", "); \
1594
364
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
364
                 getUseMarkup()); \
1596
364
    } \
1597
364
  }
printRegWithShiftExtend_1_16_w_d
Line
Count
Source
1575
237
  { \
1576
237
    add_cs_detail( \
1577
237
      MI, \
1578
237
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
237
                    SignExtend), \
1580
237
                 ExtWidth), \
1581
237
              SrcRegKind), \
1582
237
           Suffix), \
1583
237
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
237
    printOperand(MI, OpNum, O); \
1585
237
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
237
      SStream_concat1(O, '.'); \
1587
237
      SStream_concat1(O, CHAR(Suffix)); \
1588
237
      SStream_concat1(O, '\0'); \
1589
237
    } else \
1590
237
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
237
    bool DoShift = ExtWidth != 8; \
1592
237
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
237
      SStream_concat0(O, ", "); \
1594
237
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
237
                 getUseMarkup()); \
1596
237
    } \
1597
237
  }
printRegWithShiftExtend_0_16_w_d
Line
Count
Source
1575
261
  { \
1576
261
    add_cs_detail( \
1577
261
      MI, \
1578
261
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
261
                    SignExtend), \
1580
261
                 ExtWidth), \
1581
261
              SrcRegKind), \
1582
261
           Suffix), \
1583
261
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
261
    printOperand(MI, OpNum, O); \
1585
261
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
261
      SStream_concat1(O, '.'); \
1587
261
      SStream_concat1(O, CHAR(Suffix)); \
1588
261
      SStream_concat1(O, '\0'); \
1589
261
    } else \
1590
261
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
261
    bool DoShift = ExtWidth != 8; \
1592
261
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
261
      SStream_concat0(O, ", "); \
1594
261
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
261
                 getUseMarkup()); \
1596
261
    } \
1597
261
  }
printRegWithShiftExtend_0_16_x_0
Line
Count
Source
1575
1.06k
  { \
1576
1.06k
    add_cs_detail( \
1577
1.06k
      MI, \
1578
1.06k
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
1.06k
                    SignExtend), \
1580
1.06k
                 ExtWidth), \
1581
1.06k
              SrcRegKind), \
1582
1.06k
           Suffix), \
1583
1.06k
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
1.06k
    printOperand(MI, OpNum, O); \
1585
1.06k
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
0
      SStream_concat1(O, '.'); \
1587
0
      SStream_concat1(O, CHAR(Suffix)); \
1588
0
      SStream_concat1(O, '\0'); \
1589
0
    } else \
1590
1.06k
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
1.06k
    bool DoShift = ExtWidth != 8; \
1592
1.06k
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
1.06k
      SStream_concat0(O, ", "); \
1594
1.06k
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
1.06k
                 getUseMarkup()); \
1596
1.06k
    } \
1597
1.06k
  }
printRegWithShiftExtend_1_16_w_s
Line
Count
Source
1575
174
  { \
1576
174
    add_cs_detail( \
1577
174
      MI, \
1578
174
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
174
                    SignExtend), \
1580
174
                 ExtWidth), \
1581
174
              SrcRegKind), \
1582
174
           Suffix), \
1583
174
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
174
    printOperand(MI, OpNum, O); \
1585
174
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
174
      SStream_concat1(O, '.'); \
1587
174
      SStream_concat1(O, CHAR(Suffix)); \
1588
174
      SStream_concat1(O, '\0'); \
1589
174
    } else \
1590
174
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
174
    bool DoShift = ExtWidth != 8; \
1592
174
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
174
      SStream_concat0(O, ", "); \
1594
174
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
174
                 getUseMarkup()); \
1596
174
    } \
1597
174
  }
printRegWithShiftExtend_0_16_w_s
Line
Count
Source
1575
128
  { \
1576
128
    add_cs_detail( \
1577
128
      MI, \
1578
128
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
128
                    SignExtend), \
1580
128
                 ExtWidth), \
1581
128
              SrcRegKind), \
1582
128
           Suffix), \
1583
128
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
128
    printOperand(MI, OpNum, O); \
1585
128
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
128
      SStream_concat1(O, '.'); \
1587
128
      SStream_concat1(O, CHAR(Suffix)); \
1588
128
      SStream_concat1(O, '\0'); \
1589
128
    } else \
1590
128
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
128
    bool DoShift = ExtWidth != 8; \
1592
128
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
128
      SStream_concat0(O, ", "); \
1594
128
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
128
                 getUseMarkup()); \
1596
128
    } \
1597
128
  }
printRegWithShiftExtend_0_32_x_d
Line
Count
Source
1575
395
  { \
1576
395
    add_cs_detail( \
1577
395
      MI, \
1578
395
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
395
                    SignExtend), \
1580
395
                 ExtWidth), \
1581
395
              SrcRegKind), \
1582
395
           Suffix), \
1583
395
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
395
    printOperand(MI, OpNum, O); \
1585
395
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
395
      SStream_concat1(O, '.'); \
1587
395
      SStream_concat1(O, CHAR(Suffix)); \
1588
395
      SStream_concat1(O, '\0'); \
1589
395
    } else \
1590
395
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
395
    bool DoShift = ExtWidth != 8; \
1592
395
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
395
      SStream_concat0(O, ", "); \
1594
395
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
395
                 getUseMarkup()); \
1596
395
    } \
1597
395
  }
printRegWithShiftExtend_1_32_w_d
Line
Count
Source
1575
174
  { \
1576
174
    add_cs_detail( \
1577
174
      MI, \
1578
174
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
174
                    SignExtend), \
1580
174
                 ExtWidth), \
1581
174
              SrcRegKind), \
1582
174
           Suffix), \
1583
174
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
174
    printOperand(MI, OpNum, O); \
1585
174
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
174
      SStream_concat1(O, '.'); \
1587
174
      SStream_concat1(O, CHAR(Suffix)); \
1588
174
      SStream_concat1(O, '\0'); \
1589
174
    } else \
1590
174
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
174
    bool DoShift = ExtWidth != 8; \
1592
174
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
174
      SStream_concat0(O, ", "); \
1594
174
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
174
                 getUseMarkup()); \
1596
174
    } \
1597
174
  }
printRegWithShiftExtend_0_32_w_d
Line
Count
Source
1575
339
  { \
1576
339
    add_cs_detail( \
1577
339
      MI, \
1578
339
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
339
                    SignExtend), \
1580
339
                 ExtWidth), \
1581
339
              SrcRegKind), \
1582
339
           Suffix), \
1583
339
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
339
    printOperand(MI, OpNum, O); \
1585
339
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
339
      SStream_concat1(O, '.'); \
1587
339
      SStream_concat1(O, CHAR(Suffix)); \
1588
339
      SStream_concat1(O, '\0'); \
1589
339
    } else \
1590
339
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
339
    bool DoShift = ExtWidth != 8; \
1592
339
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
339
      SStream_concat0(O, ", "); \
1594
339
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
339
                 getUseMarkup()); \
1596
339
    } \
1597
339
  }
printRegWithShiftExtend_0_32_x_0
Line
Count
Source
1575
443
  { \
1576
443
    add_cs_detail( \
1577
443
      MI, \
1578
443
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
443
                    SignExtend), \
1580
443
                 ExtWidth), \
1581
443
              SrcRegKind), \
1582
443
           Suffix), \
1583
443
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
443
    printOperand(MI, OpNum, O); \
1585
443
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
0
      SStream_concat1(O, '.'); \
1587
0
      SStream_concat1(O, CHAR(Suffix)); \
1588
0
      SStream_concat1(O, '\0'); \
1589
0
    } else \
1590
443
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
443
    bool DoShift = ExtWidth != 8; \
1592
443
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
443
      SStream_concat0(O, ", "); \
1594
443
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
443
                 getUseMarkup()); \
1596
443
    } \
1597
443
  }
printRegWithShiftExtend_1_32_w_s
Line
Count
Source
1575
238
  { \
1576
238
    add_cs_detail( \
1577
238
      MI, \
1578
238
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
238
                    SignExtend), \
1580
238
                 ExtWidth), \
1581
238
              SrcRegKind), \
1582
238
           Suffix), \
1583
238
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
238
    printOperand(MI, OpNum, O); \
1585
238
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
238
      SStream_concat1(O, '.'); \
1587
238
      SStream_concat1(O, CHAR(Suffix)); \
1588
238
      SStream_concat1(O, '\0'); \
1589
238
    } else \
1590
238
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
238
    bool DoShift = ExtWidth != 8; \
1592
238
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
238
      SStream_concat0(O, ", "); \
1594
238
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
238
                 getUseMarkup()); \
1596
238
    } \
1597
238
  }
printRegWithShiftExtend_0_32_w_s
Line
Count
Source
1575
103
  { \
1576
103
    add_cs_detail( \
1577
103
      MI, \
1578
103
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
103
                    SignExtend), \
1580
103
                 ExtWidth), \
1581
103
              SrcRegKind), \
1582
103
           Suffix), \
1583
103
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
103
    printOperand(MI, OpNum, O); \
1585
103
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
103
      SStream_concat1(O, '.'); \
1587
103
      SStream_concat1(O, CHAR(Suffix)); \
1588
103
      SStream_concat1(O, '\0'); \
1589
103
    } else \
1590
103
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
103
    bool DoShift = ExtWidth != 8; \
1592
103
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
103
      SStream_concat0(O, ", "); \
1594
103
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
103
                 getUseMarkup()); \
1596
103
    } \
1597
103
  }
printRegWithShiftExtend_0_8_x_s
Line
Count
Source
1575
190
  { \
1576
190
    add_cs_detail( \
1577
190
      MI, \
1578
190
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
190
                    SignExtend), \
1580
190
                 ExtWidth), \
1581
190
              SrcRegKind), \
1582
190
           Suffix), \
1583
190
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
190
    printOperand(MI, OpNum, O); \
1585
190
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
190
      SStream_concat1(O, '.'); \
1587
190
      SStream_concat1(O, CHAR(Suffix)); \
1588
190
      SStream_concat1(O, '\0'); \
1589
190
    } else \
1590
190
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
190
    bool DoShift = ExtWidth != 8; \
1592
190
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
0
      SStream_concat0(O, ", "); \
1594
0
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
0
                 getUseMarkup()); \
1596
0
    } \
1597
190
  }
printRegWithShiftExtend_0_16_x_s
Line
Count
Source
1575
185
  { \
1576
185
    add_cs_detail( \
1577
185
      MI, \
1578
185
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
185
                    SignExtend), \
1580
185
                 ExtWidth), \
1581
185
              SrcRegKind), \
1582
185
           Suffix), \
1583
185
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
185
    printOperand(MI, OpNum, O); \
1585
185
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
185
      SStream_concat1(O, '.'); \
1587
185
      SStream_concat1(O, CHAR(Suffix)); \
1588
185
      SStream_concat1(O, '\0'); \
1589
185
    } else \
1590
185
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
185
    bool DoShift = ExtWidth != 8; \
1592
185
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
185
      SStream_concat0(O, ", "); \
1594
185
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
185
                 getUseMarkup()); \
1596
185
    } \
1597
185
  }
printRegWithShiftExtend_0_32_x_s
Line
Count
Source
1575
22
  { \
1576
22
    add_cs_detail( \
1577
22
      MI, \
1578
22
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
22
                    SignExtend), \
1580
22
                 ExtWidth), \
1581
22
              SrcRegKind), \
1582
22
           Suffix), \
1583
22
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
22
    printOperand(MI, OpNum, O); \
1585
22
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
22
      SStream_concat1(O, '.'); \
1587
22
      SStream_concat1(O, CHAR(Suffix)); \
1588
22
      SStream_concat1(O, '\0'); \
1589
22
    } else \
1590
22
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
22
    bool DoShift = ExtWidth != 8; \
1592
22
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
22
      SStream_concat0(O, ", "); \
1594
22
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
22
                 getUseMarkup()); \
1596
22
    } \
1597
22
  }
printRegWithShiftExtend_0_64_x_s
Line
Count
Source
1575
34
  { \
1576
34
    add_cs_detail( \
1577
34
      MI, \
1578
34
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
34
                    SignExtend), \
1580
34
                 ExtWidth), \
1581
34
              SrcRegKind), \
1582
34
           Suffix), \
1583
34
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
34
    printOperand(MI, OpNum, O); \
1585
34
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
34
      SStream_concat1(O, '.'); \
1587
34
      SStream_concat1(O, CHAR(Suffix)); \
1588
34
      SStream_concat1(O, '\0'); \
1589
34
    } else \
1590
34
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
34
    bool DoShift = ExtWidth != 8; \
1592
34
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
34
      SStream_concat0(O, ", "); \
1594
34
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
34
                 getUseMarkup()); \
1596
34
    } \
1597
34
  }
printRegWithShiftExtend_0_128_x_0
Line
Count
Source
1575
262
  { \
1576
262
    add_cs_detail( \
1577
262
      MI, \
1578
262
      CONCAT(CONCAT(CONCAT(CONCAT(AArch64_OP_GROUP_RegWithShiftExtend, \
1579
262
                    SignExtend), \
1580
262
                 ExtWidth), \
1581
262
              SrcRegKind), \
1582
262
           Suffix), \
1583
262
      OpNum, SignExtend, ExtWidth, CHAR(SrcRegKind), CHAR(Suffix)); \
1584
262
    printOperand(MI, OpNum, O); \
1585
262
    if (CHAR(Suffix) == 's' || CHAR(Suffix) == 'd') { \
1586
0
      SStream_concat1(O, '.'); \
1587
0
      SStream_concat1(O, CHAR(Suffix)); \
1588
0
      SStream_concat1(O, '\0'); \
1589
0
    } else \
1590
262
      assert((CHAR(Suffix) == '0') && "Unsupported suffix size"); \
1591
262
    bool DoShift = ExtWidth != 8; \
1592
262
    if (SignExtend || DoShift || CHAR(SrcRegKind) == 'w') { \
1593
262
      SStream_concat0(O, ", "); \
1594
262
      printMemExtendImpl(SignExtend, DoShift, ExtWidth, CHAR(SrcRegKind), O, \
1595
262
                 getUseMarkup()); \
1596
262
    } \
1597
262
  }
1598
DEFINE_printRegWithShiftExtend(false, 8, x, d);
1599
DEFINE_printRegWithShiftExtend(true, 8, w, d);
1600
DEFINE_printRegWithShiftExtend(false, 8, w, d);
1601
DEFINE_printRegWithShiftExtend(false, 8, x, 0);
1602
DEFINE_printRegWithShiftExtend(true, 8, w, s);
1603
DEFINE_printRegWithShiftExtend(false, 8, w, s);
1604
DEFINE_printRegWithShiftExtend(false, 64, x, d);
1605
DEFINE_printRegWithShiftExtend(true, 64, w, d);
1606
DEFINE_printRegWithShiftExtend(false, 64, w, d);
1607
DEFINE_printRegWithShiftExtend(false, 64, x, 0);
1608
DEFINE_printRegWithShiftExtend(true, 64, w, s);
1609
DEFINE_printRegWithShiftExtend(false, 64, w, s);
1610
DEFINE_printRegWithShiftExtend(false, 16, x, d);
1611
DEFINE_printRegWithShiftExtend(true, 16, w, d);
1612
DEFINE_printRegWithShiftExtend(false, 16, w, d);
1613
DEFINE_printRegWithShiftExtend(false, 16, x, 0);
1614
DEFINE_printRegWithShiftExtend(true, 16, w, s);
1615
DEFINE_printRegWithShiftExtend(false, 16, w, s);
1616
DEFINE_printRegWithShiftExtend(false, 32, x, d);
1617
DEFINE_printRegWithShiftExtend(true, 32, w, d);
1618
DEFINE_printRegWithShiftExtend(false, 32, w, d);
1619
DEFINE_printRegWithShiftExtend(false, 32, x, 0);
1620
DEFINE_printRegWithShiftExtend(true, 32, w, s);
1621
DEFINE_printRegWithShiftExtend(false, 32, w, s);
1622
DEFINE_printRegWithShiftExtend(false, 8, x, s);
1623
DEFINE_printRegWithShiftExtend(false, 16, x, s);
1624
DEFINE_printRegWithShiftExtend(false, 32, x, s);
1625
DEFINE_printRegWithShiftExtend(false, 64, x, s);
1626
DEFINE_printRegWithShiftExtend(false, 128, x, 0);
1627
1628
#define DEFINE_printPredicateAsCounter(EltSize) \
1629
  void CONCAT(printPredicateAsCounter, EltSize)(MCInst * MI, unsigned OpNum, \
1630
                          SStream *O) \
1631
2.09k
  { \
1632
2.09k
    add_cs_detail(MI, \
1633
2.09k
            CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1634
2.09k
            OpNum, EltSize); \
1635
2.09k
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1636
2.09k
\
1637
2.09k
    SStream_concat(O, "%s", "pn"); \
1638
2.09k
    printUInt32(O, (Reg - AArch64_P0)); \
1639
2.09k
    switch (EltSize) { \
1640
1.94k
    case 0: \
1641
1.94k
      break; \
1642
21
    case 8: \
1643
21
      SStream_concat0(O, ".b"); \
1644
21
      break; \
1645
62
    case 16: \
1646
62
      SStream_concat0(O, ".h"); \
1647
62
      break; \
1648
25
    case 32: \
1649
25
      SStream_concat0(O, ".s"); \
1650
25
      break; \
1651
42
    case 64: \
1652
42
      SStream_concat0(O, ".d"); \
1653
42
      break; \
1654
0
    default: \
1655
0
      assert(0 && "Unsupported element size"); \
1656
2.09k
    } \
1657
2.09k
  }
printPredicateAsCounter_8
Line
Count
Source
1631
21
  { \
1632
21
    add_cs_detail(MI, \
1633
21
            CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1634
21
            OpNum, EltSize); \
1635
21
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1636
21
\
1637
21
    SStream_concat(O, "%s", "pn"); \
1638
21
    printUInt32(O, (Reg - AArch64_P0)); \
1639
21
    switch (EltSize) { \
1640
0
    case 0: \
1641
0
      break; \
1642
21
    case 8: \
1643
21
      SStream_concat0(O, ".b"); \
1644
21
      break; \
1645
0
    case 16: \
1646
0
      SStream_concat0(O, ".h"); \
1647
0
      break; \
1648
0
    case 32: \
1649
0
      SStream_concat0(O, ".s"); \
1650
0
      break; \
1651
0
    case 64: \
1652
0
      SStream_concat0(O, ".d"); \
1653
0
      break; \
1654
0
    default: \
1655
0
      assert(0 && "Unsupported element size"); \
1656
21
    } \
1657
21
  }
printPredicateAsCounter_64
Line
Count
Source
1631
42
  { \
1632
42
    add_cs_detail(MI, \
1633
42
            CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1634
42
            OpNum, EltSize); \
1635
42
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1636
42
\
1637
42
    SStream_concat(O, "%s", "pn"); \
1638
42
    printUInt32(O, (Reg - AArch64_P0)); \
1639
42
    switch (EltSize) { \
1640
0
    case 0: \
1641
0
      break; \
1642
0
    case 8: \
1643
0
      SStream_concat0(O, ".b"); \
1644
0
      break; \
1645
0
    case 16: \
1646
0
      SStream_concat0(O, ".h"); \
1647
0
      break; \
1648
0
    case 32: \
1649
0
      SStream_concat0(O, ".s"); \
1650
0
      break; \
1651
42
    case 64: \
1652
42
      SStream_concat0(O, ".d"); \
1653
42
      break; \
1654
0
    default: \
1655
0
      assert(0 && "Unsupported element size"); \
1656
42
    } \
1657
42
  }
printPredicateAsCounter_16
Line
Count
Source
1631
62
  { \
1632
62
    add_cs_detail(MI, \
1633
62
            CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1634
62
            OpNum, EltSize); \
1635
62
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1636
62
\
1637
62
    SStream_concat(O, "%s", "pn"); \
1638
62
    printUInt32(O, (Reg - AArch64_P0)); \
1639
62
    switch (EltSize) { \
1640
0
    case 0: \
1641
0
      break; \
1642
0
    case 8: \
1643
0
      SStream_concat0(O, ".b"); \
1644
0
      break; \
1645
62
    case 16: \
1646
62
      SStream_concat0(O, ".h"); \
1647
62
      break; \
1648
0
    case 32: \
1649
0
      SStream_concat0(O, ".s"); \
1650
0
      break; \
1651
0
    case 64: \
1652
0
      SStream_concat0(O, ".d"); \
1653
0
      break; \
1654
0
    default: \
1655
0
      assert(0 && "Unsupported element size"); \
1656
62
    } \
1657
62
  }
printPredicateAsCounter_32
Line
Count
Source
1631
25
  { \
1632
25
    add_cs_detail(MI, \
1633
25
            CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1634
25
            OpNum, EltSize); \
1635
25
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1636
25
\
1637
25
    SStream_concat(O, "%s", "pn"); \
1638
25
    printUInt32(O, (Reg - AArch64_P0)); \
1639
25
    switch (EltSize) { \
1640
0
    case 0: \
1641
0
      break; \
1642
0
    case 8: \
1643
0
      SStream_concat0(O, ".b"); \
1644
0
      break; \
1645
0
    case 16: \
1646
0
      SStream_concat0(O, ".h"); \
1647
0
      break; \
1648
25
    case 32: \
1649
25
      SStream_concat0(O, ".s"); \
1650
25
      break; \
1651
0
    case 64: \
1652
0
      SStream_concat0(O, ".d"); \
1653
0
      break; \
1654
0
    default: \
1655
0
      assert(0 && "Unsupported element size"); \
1656
25
    } \
1657
25
  }
printPredicateAsCounter_0
Line
Count
Source
1631
1.94k
  { \
1632
1.94k
    add_cs_detail(MI, \
1633
1.94k
            CONCAT(AArch64_OP_GROUP_PredicateAsCounter, EltSize), \
1634
1.94k
            OpNum, EltSize); \
1635
1.94k
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
1636
1.94k
\
1637
1.94k
    SStream_concat(O, "%s", "pn"); \
1638
1.94k
    printUInt32(O, (Reg - AArch64_P0)); \
1639
1.94k
    switch (EltSize) { \
1640
1.94k
    case 0: \
1641
1.94k
      break; \
1642
0
    case 8: \
1643
0
      SStream_concat0(O, ".b"); \
1644
0
      break; \
1645
0
    case 16: \
1646
0
      SStream_concat0(O, ".h"); \
1647
0
      break; \
1648
0
    case 32: \
1649
0
      SStream_concat0(O, ".s"); \
1650
0
      break; \
1651
0
    case 64: \
1652
0
      SStream_concat0(O, ".d"); \
1653
0
      break; \
1654
0
    default: \
1655
0
      assert(0 && "Unsupported element size"); \
1656
1.94k
    } \
1657
1.94k
  }
1658
DEFINE_printPredicateAsCounter(8);
1659
DEFINE_printPredicateAsCounter(64);
1660
DEFINE_printPredicateAsCounter(16);
1661
DEFINE_printPredicateAsCounter(32);
1662
DEFINE_printPredicateAsCounter(0);
1663
1664
void printCondCode(MCInst *MI, unsigned OpNum, SStream *O)
1665
1.87k
{
1666
1.87k
  add_cs_detail(MI, AArch64_OP_GROUP_CondCode, OpNum);
1667
1.87k
  AArch64CC_CondCode CC =
1668
1.87k
    (AArch64CC_CondCode)MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1669
1.87k
  SStream_concat0(O, AArch64CC_getCondCodeName(CC));
1670
1.87k
}
1671
1672
void printInverseCondCode(MCInst *MI, unsigned OpNum, SStream *O)
1673
17
{
1674
17
  add_cs_detail(MI, AArch64_OP_GROUP_InverseCondCode, OpNum);
1675
17
  AArch64CC_CondCode CC =
1676
17
    (AArch64CC_CondCode)MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1677
17
  SStream_concat0(
1678
17
    O, AArch64CC_getCondCodeName(AArch64CC_getInvertedCondCode(CC)));
1679
17
}
1680
1681
void printAMNoIndex(MCInst *MI, unsigned OpNum, SStream *O)
1682
0
{
1683
0
  add_cs_detail(MI, AArch64_OP_GROUP_AMNoIndex, OpNum);
1684
0
  SStream_concat0(O, "[");
1685
1686
0
  printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))));
1687
0
  SStream_concat0(O, "]");
1688
0
}
1689
1690
#define DEFINE_printImmScale(Scale) \
1691
  void CONCAT(printImmScale, Scale)(MCInst * MI, unsigned OpNum, SStream *O) \
1692
16.5k
  { \
1693
16.5k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1694
16.5k
            Scale); \
1695
16.5k
    SStream_concat(O, "%s", markup("<imm:")); \
1696
16.5k
    printInt32Bang(O, \
1697
16.5k
             Scale * MCOperand_getImm( \
1698
16.5k
               MCInst_getOperand(MI, (OpNum)))); \
1699
16.5k
    SStream_concat0(O, markup(">")); \
1700
16.5k
  }
printImmScale_8
Line
Count
Source
1692
4.60k
  { \
1693
4.60k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1694
4.60k
            Scale); \
1695
4.60k
    SStream_concat(O, "%s", markup("<imm:")); \
1696
4.60k
    printInt32Bang(O, \
1697
4.60k
             Scale * MCOperand_getImm( \
1698
4.60k
               MCInst_getOperand(MI, (OpNum)))); \
1699
4.60k
    SStream_concat0(O, markup(">")); \
1700
4.60k
  }
printImmScale_2
Line
Count
Source
1692
1.19k
  { \
1693
1.19k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1694
1.19k
            Scale); \
1695
1.19k
    SStream_concat(O, "%s", markup("<imm:")); \
1696
1.19k
    printInt32Bang(O, \
1697
1.19k
             Scale * MCOperand_getImm( \
1698
1.19k
               MCInst_getOperand(MI, (OpNum)))); \
1699
1.19k
    SStream_concat0(O, markup(">")); \
1700
1.19k
  }
printImmScale_4
Line
Count
Source
1692
4.93k
  { \
1693
4.93k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1694
4.93k
            Scale); \
1695
4.93k
    SStream_concat(O, "%s", markup("<imm:")); \
1696
4.93k
    printInt32Bang(O, \
1697
4.93k
             Scale * MCOperand_getImm( \
1698
4.93k
               MCInst_getOperand(MI, (OpNum)))); \
1699
4.93k
    SStream_concat0(O, markup(">")); \
1700
4.93k
  }
printImmScale_16
Line
Count
Source
1692
5.52k
  { \
1693
5.52k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1694
5.52k
            Scale); \
1695
5.52k
    SStream_concat(O, "%s", markup("<imm:")); \
1696
5.52k
    printInt32Bang(O, \
1697
5.52k
             Scale * MCOperand_getImm( \
1698
5.52k
               MCInst_getOperand(MI, (OpNum)))); \
1699
5.52k
    SStream_concat0(O, markup(">")); \
1700
5.52k
  }
printImmScale_32
Line
Count
Source
1692
141
  { \
1693
141
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1694
141
            Scale); \
1695
141
    SStream_concat(O, "%s", markup("<imm:")); \
1696
141
    printInt32Bang(O, \
1697
141
             Scale * MCOperand_getImm( \
1698
141
               MCInst_getOperand(MI, (OpNum)))); \
1699
141
    SStream_concat0(O, markup(">")); \
1700
141
  }
printImmScale_3
Line
Count
Source
1692
119
  { \
1693
119
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_ImmScale, Scale), OpNum, \
1694
119
            Scale); \
1695
119
    SStream_concat(O, "%s", markup("<imm:")); \
1696
119
    printInt32Bang(O, \
1697
119
             Scale * MCOperand_getImm( \
1698
119
               MCInst_getOperand(MI, (OpNum)))); \
1699
119
    SStream_concat0(O, markup(">")); \
1700
119
  }
1701
DEFINE_printImmScale(8);
1702
DEFINE_printImmScale(2);
1703
DEFINE_printImmScale(4);
1704
DEFINE_printImmScale(16);
1705
DEFINE_printImmScale(32);
1706
DEFINE_printImmScale(3);
1707
1708
#define DEFINE_printImmRangeScale(Scale, Offset) \
1709
  void CONCAT(printImmRangeScale, CONCAT(Scale, Offset))( \
1710
    MCInst * MI, unsigned OpNum, SStream *O) \
1711
1.83k
  { \
1712
1.83k
    add_cs_detail( \
1713
1.83k
      MI, CONCAT(CONCAT(AArch64_OP_GROUP_ImmRangeScale, Scale), Offset), \
1714
1.83k
      OpNum, Scale, Offset); \
1715
1.83k
    unsigned FirstImm = \
1716
1.83k
      Scale * MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1717
1.83k
    printUInt32(O, (FirstImm)); \
1718
1.83k
    SStream_concat(O, "%s", ":"); \
1719
1.83k
    printUInt32(O, (FirstImm + Offset)); \
1720
1.83k
    SStream_concat1(O, '\0'); \
1721
1.83k
  }
printImmRangeScale_2_1
Line
Count
Source
1711
477
  { \
1712
477
    add_cs_detail( \
1713
477
      MI, CONCAT(CONCAT(AArch64_OP_GROUP_ImmRangeScale, Scale), Offset), \
1714
477
      OpNum, Scale, Offset); \
1715
477
    unsigned FirstImm = \
1716
477
      Scale * MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1717
477
    printUInt32(O, (FirstImm)); \
1718
477
    SStream_concat(O, "%s", ":"); \
1719
477
    printUInt32(O, (FirstImm + Offset)); \
1720
477
    SStream_concat1(O, '\0'); \
1721
477
  }
printImmRangeScale_4_3
Line
Count
Source
1711
1.35k
  { \
1712
1.35k
    add_cs_detail( \
1713
1.35k
      MI, CONCAT(CONCAT(AArch64_OP_GROUP_ImmRangeScale, Scale), Offset), \
1714
1.35k
      OpNum, Scale, Offset); \
1715
1.35k
    unsigned FirstImm = \
1716
1.35k
      Scale * MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1717
1.35k
    printUInt32(O, (FirstImm)); \
1718
1.35k
    SStream_concat(O, "%s", ":"); \
1719
1.35k
    printUInt32(O, (FirstImm + Offset)); \
1720
1.35k
    SStream_concat1(O, '\0'); \
1721
1.35k
  }
1722
DEFINE_printImmRangeScale(2, 1);
1723
DEFINE_printImmRangeScale(4, 3);
1724
1725
void printUImm12Offset(MCInst *MI, unsigned OpNum, unsigned Scale, SStream *O)
1726
6.34k
{
1727
6.34k
  MCOperand *MO = MCInst_getOperand(MI, (OpNum));
1728
6.34k
  if (MCOperand_isImm(MO)) {
1729
6.34k
    SStream_concat(O, "%s", markup("<imm:"));
1730
6.34k
    printUInt32Bang(O, (MCOperand_getImm(MO) * Scale));
1731
6.34k
    SStream_concat0(O, markup(">"));
1732
6.34k
  } else {
1733
0
    assert(0 && "Expressions not supported.");
1734
0
  }
1735
6.34k
}
1736
1737
void printAMIndexedWB(MCInst *MI, unsigned OpNum, unsigned Scale, SStream *O)
1738
0
{
1739
0
  MCOperand *MO1 = MCInst_getOperand(MI, (OpNum + 1));
1740
0
  SStream_concat0(O, "[");
1741
1742
0
  printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, (OpNum))));
1743
0
  if (MCOperand_isImm(MO1)) {
1744
0
    SStream_concat(O, "%s%s", ", ", markup("<imm:"));
1745
0
    printUInt32Bang(O, MCOperand_getImm(MO1) * Scale);
1746
0
    SStream_concat0(O, markup(">"));
1747
0
  } else {
1748
0
    assert(0 && "Expressions not supported.");
1749
0
  }
1750
0
  SStream_concat0(O, "]");
1751
0
}
1752
1753
void printRPRFMOperand(MCInst *MI, unsigned OpNum, SStream *O)
1754
41
{
1755
41
  add_cs_detail(MI, AArch64_OP_GROUP_RPRFMOperand, OpNum);
1756
41
  unsigned prfop = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1757
41
  const AArch64PRFM_PRFM *PRFM = AArch64RPRFM_lookupRPRFMByEncoding(prfop);
1758
41
  if (PRFM) {
1759
17
    SStream_concat0(O, PRFM->Name);
1760
17
    return;
1761
17
  }
1762
1763
24
  printUInt32Bang(O, (prfop));
1764
24
  SStream_concat1(O, '\0');
1765
24
}
1766
1767
#define DEFINE_printPrefetchOp(IsSVEPrefetch) \
1768
  void CONCAT(printPrefetchOp, IsSVEPrefetch)(MCInst * MI, unsigned OpNum, \
1769
                        SStream *O) \
1770
4.27k
  { \
1771
4.27k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_PrefetchOp, IsSVEPrefetch), \
1772
4.27k
            OpNum, IsSVEPrefetch); \
1773
4.27k
    unsigned prfop = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1774
4.27k
    if (IsSVEPrefetch) { \
1775
2.38k
      const AArch64SVEPRFM_SVEPRFM *PRFM = AArch64SVEPRFM_lookupSVEPRFMByEncoding(prfop); \
1776
2.38k
      if (PRFM) { \
1777
2.06k
        SStream_concat0(O, PRFM->Name); \
1778
2.06k
        return; \
1779
2.06k
      } \
1780
2.38k
    } else { \
1781
1.88k
      const AArch64PRFM_PRFM *PRFM = AArch64PRFM_lookupPRFMByEncoding(prfop); \
1782
1.88k
      if (PRFM && AArch64_testFeatureList(MI->csh->mode, PRFM->FeaturesRequired)) { \
1783
1.10k
        SStream_concat0(O, PRFM->Name); \
1784
1.10k
        return; \
1785
1.10k
      } \
1786
1.88k
    } \
1787
4.27k
\
1788
4.27k
    SStream_concat(O, "%s", markup("<imm:")); \
1789
1.10k
    printUInt32Bang(O, (prfop)); \
1790
1.10k
    SStream_concat0(O, markup(">")); \
1791
1.10k
  }
printPrefetchOp_0
Line
Count
Source
1770
1.88k
  { \
1771
1.88k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_PrefetchOp, IsSVEPrefetch), \
1772
1.88k
            OpNum, IsSVEPrefetch); \
1773
1.88k
    unsigned prfop = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1774
1.88k
    if (IsSVEPrefetch) { \
1775
0
      const AArch64SVEPRFM_SVEPRFM *PRFM = AArch64SVEPRFM_lookupSVEPRFMByEncoding(prfop); \
1776
0
      if (PRFM) { \
1777
0
        SStream_concat0(O, PRFM->Name); \
1778
0
        return; \
1779
0
      } \
1780
1.88k
    } else { \
1781
1.88k
      const AArch64PRFM_PRFM *PRFM = AArch64PRFM_lookupPRFMByEncoding(prfop); \
1782
1.88k
      if (PRFM && AArch64_testFeatureList(MI->csh->mode, PRFM->FeaturesRequired)) { \
1783
1.10k
        SStream_concat0(O, PRFM->Name); \
1784
1.10k
        return; \
1785
1.10k
      } \
1786
1.88k
    } \
1787
1.88k
\
1788
1.88k
    SStream_concat(O, "%s", markup("<imm:")); \
1789
780
    printUInt32Bang(O, (prfop)); \
1790
780
    SStream_concat0(O, markup(">")); \
1791
780
  }
printPrefetchOp_1
Line
Count
Source
1770
2.38k
  { \
1771
2.38k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_PrefetchOp, IsSVEPrefetch), \
1772
2.38k
            OpNum, IsSVEPrefetch); \
1773
2.38k
    unsigned prfop = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
1774
2.38k
    if (IsSVEPrefetch) { \
1775
2.38k
      const AArch64SVEPRFM_SVEPRFM *PRFM = AArch64SVEPRFM_lookupSVEPRFMByEncoding(prfop); \
1776
2.38k
      if (PRFM) { \
1777
2.06k
        SStream_concat0(O, PRFM->Name); \
1778
2.06k
        return; \
1779
2.06k
      } \
1780
2.38k
    } else { \
1781
0
      const AArch64PRFM_PRFM *PRFM = AArch64PRFM_lookupPRFMByEncoding(prfop); \
1782
0
      if (PRFM && AArch64_testFeatureList(MI->csh->mode, PRFM->FeaturesRequired)) { \
1783
0
        SStream_concat0(O, PRFM->Name); \
1784
0
        return; \
1785
0
      } \
1786
0
    } \
1787
2.38k
\
1788
2.38k
    SStream_concat(O, "%s", markup("<imm:")); \
1789
321
    printUInt32Bang(O, (prfop)); \
1790
321
    SStream_concat0(O, markup(">")); \
1791
321
  }
1792
DEFINE_printPrefetchOp(false);
1793
DEFINE_printPrefetchOp(true);
1794
1795
void printPSBHintOp(MCInst *MI, unsigned OpNum, SStream *O)
1796
3
{
1797
3
  add_cs_detail(MI, AArch64_OP_GROUP_PSBHintOp, OpNum);
1798
3
  unsigned psbhintop = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
1799
3
  const AArch64PSBHint_PSB *PSB = AArch64PSBHint_lookupPSBByEncoding(psbhintop);
1800
3
  if (PSB)
1801
3
    SStream_concat0(O, PSB->Name);
1802
0
  else {
1803
0
    SStream_concat(O, "%s", markup("<imm:"));
1804
0
    SStream_concat1(O, '#');
1805
0
    printUInt32Bang(O, (psbhintop));
1806
0
    SStream_concat0(O, markup(">"));
1807
0
  }
1808
3
}
1809
1810
void printBTIHintOp(MCInst *MI, unsigned OpNum, SStream *O)
1811
37
{
1812
37
  add_cs_detail(MI, AArch64_OP_GROUP_BTIHintOp, OpNum);
1813
37
  unsigned btihintop = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))) ^ 32;
1814
37
  const AArch64BTIHint_BTI *BTI = AArch64BTIHint_lookupBTIByEncoding(btihintop);
1815
37
  if (BTI)
1816
37
    SStream_concat0(O, BTI->Name);
1817
0
  else {
1818
0
    SStream_concat(O, "%s", markup("<imm:"));
1819
0
    printUInt32Bang(O, (btihintop));
1820
0
    SStream_concat0(O, markup(">"));
1821
0
  }
1822
37
}
1823
1824
static void printFPImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
1825
1.38k
{
1826
1.38k
  add_cs_detail(MI, AArch64_OP_GROUP_FPImmOperand, OpNum);
1827
1.38k
  MCOperand *MO = MCInst_getOperand(MI, (OpNum));
1828
1.38k
  float FPImm = MCOperand_isDFPImm(MO)
1829
1.38k
            ? BitsToDouble(MCOperand_getImm(MO))
1830
1.38k
            : AArch64_AM_getFPImmFloat(MCOperand_getImm(MO));
1831
1832
  // 8 decimal places are enough to perfectly represent permitted floats.
1833
1.38k
  SStream_concat(O, "%s", markup("<imm:"));
1834
1.38k
  SStream_concat(O, "#%.8f", FPImm);
1835
1.38k
  SStream_concat0(O, markup(">"));
1836
1.38k
}
1837
1838
static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride /* = 1 */)
1839
65.8k
{
1840
162k
  while (Stride--) {
1841
96.4k
    switch (Reg) {
1842
0
    default:
1843
0
      assert(0 && "Vector register expected!");
1844
2.61k
    case AArch64_Q0:
1845
2.61k
      Reg = AArch64_Q1;
1846
2.61k
      break;
1847
2.86k
    case AArch64_Q1:
1848
2.86k
      Reg = AArch64_Q2;
1849
2.86k
      break;
1850
2.36k
    case AArch64_Q2:
1851
2.36k
      Reg = AArch64_Q3;
1852
2.36k
      break;
1853
2.35k
    case AArch64_Q3:
1854
2.35k
      Reg = AArch64_Q4;
1855
2.35k
      break;
1856
1.82k
    case AArch64_Q4:
1857
1.82k
      Reg = AArch64_Q5;
1858
1.82k
      break;
1859
1.06k
    case AArch64_Q5:
1860
1.06k
      Reg = AArch64_Q6;
1861
1.06k
      break;
1862
490
    case AArch64_Q6:
1863
490
      Reg = AArch64_Q7;
1864
490
      break;
1865
1.83k
    case AArch64_Q7:
1866
1.83k
      Reg = AArch64_Q8;
1867
1.83k
      break;
1868
3.28k
    case AArch64_Q8:
1869
3.28k
      Reg = AArch64_Q9;
1870
3.28k
      break;
1871
2.08k
    case AArch64_Q9:
1872
2.08k
      Reg = AArch64_Q10;
1873
2.08k
      break;
1874
1.76k
    case AArch64_Q10:
1875
1.76k
      Reg = AArch64_Q11;
1876
1.76k
      break;
1877
921
    case AArch64_Q11:
1878
921
      Reg = AArch64_Q12;
1879
921
      break;
1880
944
    case AArch64_Q12:
1881
944
      Reg = AArch64_Q13;
1882
944
      break;
1883
849
    case AArch64_Q13:
1884
849
      Reg = AArch64_Q14;
1885
849
      break;
1886
588
    case AArch64_Q14:
1887
588
      Reg = AArch64_Q15;
1888
588
      break;
1889
539
    case AArch64_Q15:
1890
539
      Reg = AArch64_Q16;
1891
539
      break;
1892
505
    case AArch64_Q16:
1893
505
      Reg = AArch64_Q17;
1894
505
      break;
1895
231
    case AArch64_Q17:
1896
231
      Reg = AArch64_Q18;
1897
231
      break;
1898
529
    case AArch64_Q18:
1899
529
      Reg = AArch64_Q19;
1900
529
      break;
1901
390
    case AArch64_Q19:
1902
390
      Reg = AArch64_Q20;
1903
390
      break;
1904
1.01k
    case AArch64_Q20:
1905
1.01k
      Reg = AArch64_Q21;
1906
1.01k
      break;
1907
968
    case AArch64_Q21:
1908
968
      Reg = AArch64_Q22;
1909
968
      break;
1910
492
    case AArch64_Q22:
1911
492
      Reg = AArch64_Q23;
1912
492
      break;
1913
217
    case AArch64_Q23:
1914
217
      Reg = AArch64_Q24;
1915
217
      break;
1916
1.68k
    case AArch64_Q24:
1917
1.68k
      Reg = AArch64_Q25;
1918
1.68k
      break;
1919
1.48k
    case AArch64_Q25:
1920
1.48k
      Reg = AArch64_Q26;
1921
1.48k
      break;
1922
1.06k
    case AArch64_Q26:
1923
1.06k
      Reg = AArch64_Q27;
1924
1.06k
      break;
1925
1.25k
    case AArch64_Q27:
1926
1.25k
      Reg = AArch64_Q28;
1927
1.25k
      break;
1928
791
    case AArch64_Q28:
1929
791
      Reg = AArch64_Q29;
1930
791
      break;
1931
1.41k
    case AArch64_Q29:
1932
1.41k
      Reg = AArch64_Q30;
1933
1.41k
      break;
1934
1.26k
    case AArch64_Q30:
1935
1.26k
      Reg = AArch64_Q31;
1936
1.26k
      break;
1937
    // Vector lists can wrap around.
1938
1.39k
    case AArch64_Q31:
1939
1.39k
      Reg = AArch64_Q0;
1940
1.39k
      break;
1941
4.53k
    case AArch64_Z0:
1942
4.53k
      Reg = AArch64_Z1;
1943
4.53k
      break;
1944
2.91k
    case AArch64_Z1:
1945
2.91k
      Reg = AArch64_Z2;
1946
2.91k
      break;
1947
2.54k
    case AArch64_Z2:
1948
2.54k
      Reg = AArch64_Z3;
1949
2.54k
      break;
1950
892
    case AArch64_Z3:
1951
892
      Reg = AArch64_Z4;
1952
892
      break;
1953
4.52k
    case AArch64_Z4:
1954
4.52k
      Reg = AArch64_Z5;
1955
4.52k
      break;
1956
2.83k
    case AArch64_Z5:
1957
2.83k
      Reg = AArch64_Z6;
1958
2.83k
      break;
1959
2.26k
    case AArch64_Z6:
1960
2.26k
      Reg = AArch64_Z7;
1961
2.26k
      break;
1962
652
    case AArch64_Z7:
1963
652
      Reg = AArch64_Z8;
1964
652
      break;
1965
1.41k
    case AArch64_Z8:
1966
1.41k
      Reg = AArch64_Z9;
1967
1.41k
      break;
1968
1.18k
    case AArch64_Z9:
1969
1.18k
      Reg = AArch64_Z10;
1970
1.18k
      break;
1971
1.07k
    case AArch64_Z10:
1972
1.07k
      Reg = AArch64_Z11;
1973
1.07k
      break;
1974
653
    case AArch64_Z11:
1975
653
      Reg = AArch64_Z12;
1976
653
      break;
1977
1.30k
    case AArch64_Z12:
1978
1.30k
      Reg = AArch64_Z13;
1979
1.30k
      break;
1980
1.18k
    case AArch64_Z13:
1981
1.18k
      Reg = AArch64_Z14;
1982
1.18k
      break;
1983
1.40k
    case AArch64_Z14:
1984
1.40k
      Reg = AArch64_Z15;
1985
1.40k
      break;
1986
714
    case AArch64_Z15:
1987
714
      Reg = AArch64_Z16;
1988
714
      break;
1989
1.23k
    case AArch64_Z16:
1990
1.23k
      Reg = AArch64_Z17;
1991
1.23k
      break;
1992
1.05k
    case AArch64_Z17:
1993
1.05k
      Reg = AArch64_Z18;
1994
1.05k
      break;
1995
1.42k
    case AArch64_Z18:
1996
1.42k
      Reg = AArch64_Z19;
1997
1.42k
      break;
1998
814
    case AArch64_Z19:
1999
814
      Reg = AArch64_Z20;
2000
814
      break;
2001
1.08k
    case AArch64_Z20:
2002
1.08k
      Reg = AArch64_Z21;
2003
1.08k
      break;
2004
1.07k
    case AArch64_Z21:
2005
1.07k
      Reg = AArch64_Z22;
2006
1.07k
      break;
2007
1.24k
    case AArch64_Z22:
2008
1.24k
      Reg = AArch64_Z23;
2009
1.24k
      break;
2010
1.04k
    case AArch64_Z23:
2011
1.04k
      Reg = AArch64_Z24;
2012
1.04k
      break;
2013
2.85k
    case AArch64_Z24:
2014
2.85k
      Reg = AArch64_Z25;
2015
2.85k
      break;
2016
3.29k
    case AArch64_Z25:
2017
3.29k
      Reg = AArch64_Z26;
2018
3.29k
      break;
2019
2.56k
    case AArch64_Z26:
2020
2.56k
      Reg = AArch64_Z27;
2021
2.56k
      break;
2022
959
    case AArch64_Z27:
2023
959
      Reg = AArch64_Z28;
2024
959
      break;
2025
1.67k
    case AArch64_Z28:
2026
1.67k
      Reg = AArch64_Z29;
2027
1.67k
      break;
2028
1.36k
    case AArch64_Z29:
2029
1.36k
      Reg = AArch64_Z30;
2030
1.36k
      break;
2031
1.51k
    case AArch64_Z30:
2032
1.51k
      Reg = AArch64_Z31;
2033
1.51k
      break;
2034
    // Vector lists can wrap around.
2035
1.22k
    case AArch64_Z31:
2036
1.22k
      Reg = AArch64_Z0;
2037
1.22k
      break;
2038
73
    case AArch64_P0:
2039
73
      Reg = AArch64_P1;
2040
73
      break;
2041
10
    case AArch64_P1:
2042
10
      Reg = AArch64_P2;
2043
10
      break;
2044
6
    case AArch64_P2:
2045
6
      Reg = AArch64_P3;
2046
6
      break;
2047
24
    case AArch64_P3:
2048
24
      Reg = AArch64_P4;
2049
24
      break;
2050
8
    case AArch64_P4:
2051
8
      Reg = AArch64_P5;
2052
8
      break;
2053
176
    case AArch64_P5:
2054
176
      Reg = AArch64_P6;
2055
176
      break;
2056
40
    case AArch64_P6:
2057
40
      Reg = AArch64_P7;
2058
40
      break;
2059
22
    case AArch64_P7:
2060
22
      Reg = AArch64_P8;
2061
22
      break;
2062
44
    case AArch64_P8:
2063
44
      Reg = AArch64_P9;
2064
44
      break;
2065
6
    case AArch64_P9:
2066
6
      Reg = AArch64_P10;
2067
6
      break;
2068
22
    case AArch64_P10:
2069
22
      Reg = AArch64_P11;
2070
22
      break;
2071
96
    case AArch64_P11:
2072
96
      Reg = AArch64_P12;
2073
96
      break;
2074
142
    case AArch64_P12:
2075
142
      Reg = AArch64_P13;
2076
142
      break;
2077
6
    case AArch64_P13:
2078
6
      Reg = AArch64_P14;
2079
6
      break;
2080
82
    case AArch64_P14:
2081
82
      Reg = AArch64_P15;
2082
82
      break;
2083
    // Vector lists can wrap around.
2084
46
    case AArch64_P15:
2085
46
      Reg = AArch64_P0;
2086
46
      break;
2087
96.4k
    }
2088
96.4k
  }
2089
65.8k
  return Reg;
2090
65.8k
}
2091
2092
#define DEFINE_printGPRSeqPairsClassOperand(size) \
2093
  void CONCAT(printGPRSeqPairsClassOperand, \
2094
        size)(MCInst * MI, unsigned OpNum, SStream *O) \
2095
1.53k
  { \
2096
1.53k
    add_cs_detail(MI, \
2097
1.53k
            CONCAT(AArch64_OP_GROUP_GPRSeqPairsClassOperand, size), \
2098
1.53k
            OpNum, size); \
2099
1.53k
    assert((size == 64 || size == 32) && \
2100
1.53k
            "Template parameter must be either 32 or 64"); \
2101
1.53k
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2102
1.53k
\
2103
1.53k
    unsigned Sube = (size == 32) ? AArch64_sube32 : AArch64_sube64; \
2104
1.53k
    unsigned Subo = (size == 32) ? AArch64_subo32 : AArch64_subo64; \
2105
1.53k
\
2106
1.53k
    unsigned Even = MCRegisterInfo_getSubReg(MI->MRI, Reg, Sube); \
2107
1.53k
    unsigned Odd = MCRegisterInfo_getSubReg(MI->MRI, Reg, Subo); \
2108
1.53k
    printRegName(O, Even); \
2109
1.53k
    SStream_concat0(O, ", "); \
2110
1.53k
    printRegName(O, Odd); \
2111
1.53k
  }
printGPRSeqPairsClassOperand_32
Line
Count
Source
2095
68
  { \
2096
68
    add_cs_detail(MI, \
2097
68
            CONCAT(AArch64_OP_GROUP_GPRSeqPairsClassOperand, size), \
2098
68
            OpNum, size); \
2099
68
    assert((size == 64 || size == 32) && \
2100
68
            "Template parameter must be either 32 or 64"); \
2101
68
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2102
68
\
2103
68
    unsigned Sube = (size == 32) ? AArch64_sube32 : AArch64_sube64; \
2104
68
    unsigned Subo = (size == 32) ? AArch64_subo32 : AArch64_subo64; \
2105
68
\
2106
68
    unsigned Even = MCRegisterInfo_getSubReg(MI->MRI, Reg, Sube); \
2107
68
    unsigned Odd = MCRegisterInfo_getSubReg(MI->MRI, Reg, Subo); \
2108
68
    printRegName(O, Even); \
2109
68
    SStream_concat0(O, ", "); \
2110
68
    printRegName(O, Odd); \
2111
68
  }
printGPRSeqPairsClassOperand_64
Line
Count
Source
2095
1.46k
  { \
2096
1.46k
    add_cs_detail(MI, \
2097
1.46k
            CONCAT(AArch64_OP_GROUP_GPRSeqPairsClassOperand, size), \
2098
1.46k
            OpNum, size); \
2099
1.46k
    assert((size == 64 || size == 32) && \
2100
1.46k
            "Template parameter must be either 32 or 64"); \
2101
1.46k
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2102
1.46k
\
2103
1.46k
    unsigned Sube = (size == 32) ? AArch64_sube32 : AArch64_sube64; \
2104
1.46k
    unsigned Subo = (size == 32) ? AArch64_subo32 : AArch64_subo64; \
2105
1.46k
\
2106
1.46k
    unsigned Even = MCRegisterInfo_getSubReg(MI->MRI, Reg, Sube); \
2107
1.46k
    unsigned Odd = MCRegisterInfo_getSubReg(MI->MRI, Reg, Subo); \
2108
1.46k
    printRegName(O, Even); \
2109
1.46k
    SStream_concat0(O, ", "); \
2110
1.46k
    printRegName(O, Odd); \
2111
1.46k
  }
2112
DEFINE_printGPRSeqPairsClassOperand(32);
2113
DEFINE_printGPRSeqPairsClassOperand(64);
2114
2115
void printMatrixTileList(MCInst *MI, unsigned OpNum, SStream *O)
2116
47
{
2117
47
  add_cs_detail(MI, AArch64_OP_GROUP_MatrixTileList, OpNum);
2118
47
  unsigned MaxRegs = 8;
2119
47
  unsigned RegMask = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
2120
2121
47
  unsigned NumRegs = 0;
2122
423
  for (unsigned I = 0; I < MaxRegs; ++I)
2123
376
    if ((RegMask & (1 << I)) != 0)
2124
190
      ++NumRegs;
2125
2126
47
  SStream_concat0(O, "{");
2127
47
  unsigned Printed = 0;
2128
423
  for (unsigned I = 0; I < MaxRegs; ++I) {
2129
376
    unsigned Reg = RegMask & (1 << I);
2130
376
    if (Reg == 0)
2131
186
      continue;
2132
190
    printRegName(O, AArch64_ZAD0 + I);
2133
190
    if (Printed + 1 != NumRegs)
2134
144
      SStream_concat0(O, ", ");
2135
190
    ++Printed;
2136
190
  }
2137
47
  SStream_concat0(O, "}");
2138
47
}
2139
2140
void printVectorList(MCInst *MI, unsigned OpNum, SStream *O,
2141
           const char *LayoutSuffix)
2142
30.8k
{
2143
30.8k
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum)));
2144
2145
30.8k
  SStream_concat0(O, "{ ");
2146
2147
  // Work out how many registers there are in the list (if there is an actual
2148
  // list).
2149
30.8k
  unsigned NumRegs = 1;
2150
30.8k
  if (MCRegisterClass_contains(
2151
30.8k
      MCRegisterInfo_getRegClass(MI->MRI, AArch64_DDRegClassID), Reg) ||
2152
30.8k
    MCRegisterClass_contains(
2153
30.0k
      MCRegisterInfo_getRegClass(MI->MRI, AArch64_ZPR2RegClassID),
2154
30.0k
      Reg) ||
2155
30.8k
    MCRegisterClass_contains(
2156
26.9k
      MCRegisterInfo_getRegClass(MI->MRI, AArch64_QQRegClassID), Reg) ||
2157
30.8k
    MCRegisterClass_contains(
2158
24.9k
      MCRegisterInfo_getRegClass(MI->MRI, AArch64_PPR2RegClassID),
2159
24.9k
      Reg) ||
2160
30.8k
    MCRegisterClass_contains(
2161
24.6k
      MCRegisterInfo_getRegClass(MI->MRI, AArch64_ZPR2StridedRegClassID),
2162
24.6k
      Reg))
2163
7.15k
    NumRegs = 2;
2164
23.7k
  else if (MCRegisterClass_contains(
2165
23.7k
         MCRegisterInfo_getRegClass(MI->MRI, AArch64_DDDRegClassID),
2166
23.7k
         Reg) ||
2167
23.7k
       MCRegisterClass_contains(
2168
22.6k
         MCRegisterInfo_getRegClass(MI->MRI, AArch64_ZPR3RegClassID),
2169
22.6k
         Reg) ||
2170
23.7k
       MCRegisterClass_contains(
2171
22.3k
         MCRegisterInfo_getRegClass(MI->MRI, AArch64_QQQRegClassID),
2172
22.3k
         Reg))
2173
4.72k
    NumRegs = 3;
2174
19.0k
  else if (MCRegisterClass_contains(
2175
19.0k
         MCRegisterInfo_getRegClass(MI->MRI, AArch64_DDDDRegClassID),
2176
19.0k
         Reg) ||
2177
19.0k
       MCRegisterClass_contains(
2178
17.9k
         MCRegisterInfo_getRegClass(MI->MRI, AArch64_ZPR4RegClassID),
2179
17.9k
         Reg) ||
2180
19.0k
       MCRegisterClass_contains(
2181
14.8k
         MCRegisterInfo_getRegClass(MI->MRI, AArch64_QQQQRegClassID),
2182
14.8k
         Reg) ||
2183
19.0k
       MCRegisterClass_contains(
2184
11.3k
         MCRegisterInfo_getRegClass(MI->MRI,
2185
11.3k
                       AArch64_ZPR4StridedRegClassID),
2186
11.3k
         Reg))
2187
8.15k
    NumRegs = 4;
2188
2189
30.8k
  unsigned Stride = 1;
2190
30.8k
  if (MCRegisterClass_contains(
2191
30.8k
      MCRegisterInfo_getRegClass(MI->MRI, AArch64_ZPR2StridedRegClassID),
2192
30.8k
      Reg))
2193
871
    Stride = 8;
2194
30.0k
  else if (MCRegisterClass_contains(
2195
30.0k
         MCRegisterInfo_getRegClass(MI->MRI,
2196
30.0k
                       AArch64_ZPR4StridedRegClassID),
2197
30.0k
         Reg))
2198
477
    Stride = 4;
2199
2200
  // Now forget about the list and find out what the first register is.
2201
30.8k
  if (MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_dsub0))
2202
3.03k
    Reg = MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_dsub0);
2203
27.8k
  else if (MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_qsub0))
2204
8.73k
    Reg = MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_qsub0);
2205
19.1k
  else if (MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_zsub0))
2206
7.87k
    Reg = MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_zsub0);
2207
11.2k
  else if (MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_psub0))
2208
390
    Reg = MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_psub0);
2209
2210
  // If it's a D-reg, we need to promote it to the equivalent Q-reg before
2211
  // printing (otherwise getRegisterName fails).
2212
30.8k
  if (MCRegisterClass_contains(
2213
30.8k
      MCRegisterInfo_getRegClass(MI->MRI, AArch64_FPR64RegClassID),
2214
30.8k
      Reg)) {
2215
4.47k
    const MCRegisterClass *FPR128RC =
2216
4.47k
      MCRegisterInfo_getRegClass(MI->MRI, AArch64_FPR128RegClassID);
2217
4.47k
    Reg = MCRegisterInfo_getMatchingSuperReg(MI->MRI, Reg, AArch64_dsub,
2218
4.47k
                   FPR128RC);
2219
4.47k
  }
2220
2221
30.8k
  if ((MCRegisterClass_contains(
2222
30.8k
       MCRegisterInfo_getRegClass(MI->MRI, AArch64_ZPRRegClassID),
2223
30.8k
       Reg) ||
2224
30.8k
     MCRegisterClass_contains(
2225
16.0k
       MCRegisterInfo_getRegClass(MI->MRI, AArch64_PPRRegClassID),
2226
16.0k
       Reg)) &&
2227
30.8k
    NumRegs > 1 && Stride == 1 &&
2228
    // Do not print the range when the last register is lower than the
2229
    // first. Because it is a wrap-around register.
2230
30.8k
    Reg < getNextVectorRegister(Reg, NumRegs - 1)) {
2231
6.75k
    printRegName(O, Reg);
2232
6.75k
    SStream_concat0(O, LayoutSuffix);
2233
6.75k
    if (NumRegs > 1) {
2234
      // Set of two sve registers should be separated by ','
2235
6.75k
      const char *split_char = NumRegs == 2 ? ", " : " - ";
2236
6.75k
      SStream_concat0(O, split_char);
2237
6.75k
      printRegName(O, (getNextVectorRegister(Reg, NumRegs - 1)));
2238
6.75k
      SStream_concat0(O, LayoutSuffix);
2239
6.75k
    }
2240
24.1k
  } else {
2241
76.3k
    for (unsigned i = 0; i < NumRegs;
2242
52.2k
       ++i, Reg = getNextVectorRegister(Reg, Stride)) {
2243
      // wrap-around sve register
2244
52.2k
      if (MCRegisterClass_contains(
2245
52.2k
          MCRegisterInfo_getRegClass(MI->MRI, AArch64_ZPRRegClassID),
2246
52.2k
          Reg) ||
2247
52.2k
        MCRegisterClass_contains(
2248
41.1k
          MCRegisterInfo_getRegClass(MI->MRI, AArch64_PPRRegClassID),
2249
41.1k
          Reg))
2250
11.1k
        printRegName(O, Reg);
2251
41.0k
      else
2252
41.0k
        printRegNameAlt(O, Reg, AArch64_vreg);
2253
52.2k
      SStream_concat0(O, LayoutSuffix);
2254
52.2k
      if (i + 1 != NumRegs)
2255
28.0k
        SStream_concat0(O, ", ");
2256
52.2k
    }
2257
24.1k
  }
2258
30.8k
  SStream_concat0(O, " }");
2259
30.8k
}
2260
2261
void printImplicitlyTypedVectorList(MCInst *MI, unsigned OpNum, SStream *O)
2262
0
{
2263
0
  add_cs_detail(MI, AArch64_OP_GROUP_ImplicitlyTypedVectorList, OpNum);
2264
0
  printVectorList(MI, OpNum, O, "");
2265
0
}
2266
2267
#define DEFINE_printTypedVectorList(NumLanes, LaneKind) \
2268
  void CONCAT(printTypedVectorList, CONCAT(NumLanes, LaneKind))( \
2269
    MCInst * MI, unsigned OpNum, SStream *O) \
2270
30.8k
  { \
2271
30.8k
    add_cs_detail( \
2272
30.8k
      MI, \
2273
30.8k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, NumLanes), \
2274
30.8k
           LaneKind), \
2275
30.8k
      OpNum, NumLanes, CHAR(LaneKind)); \
2276
30.8k
    char Suffix[32]; \
2277
30.8k
    if (NumLanes) \
2278
30.8k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, CHAR(LaneKind)); \
2279
30.8k
    else \
2280
30.8k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", CHAR(LaneKind)); \
2281
30.8k
\
2282
30.8k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
2283
30.8k
  }
printTypedVectorList_0_b
Line
Count
Source
2270
3.77k
  { \
2271
3.77k
    add_cs_detail( \
2272
3.77k
      MI, \
2273
3.77k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, NumLanes), \
2274
3.77k
           LaneKind), \
2275
3.77k
      OpNum, NumLanes, CHAR(LaneKind)); \
2276
3.77k
    char Suffix[32]; \
2277
3.77k
    if (NumLanes) \
2278
3.77k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, CHAR(LaneKind)); \
2279
3.77k
    else \
2280
3.77k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", CHAR(LaneKind)); \
2281
3.77k
\
2282
3.77k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
2283
3.77k
  }
printTypedVectorList_0_d
Line
Count
Source
2270
7.90k
  { \
2271
7.90k
    add_cs_detail( \
2272
7.90k
      MI, \
2273
7.90k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, NumLanes), \
2274
7.90k
           LaneKind), \
2275
7.90k
      OpNum, NumLanes, CHAR(LaneKind)); \
2276
7.90k
    char Suffix[32]; \
2277
7.90k
    if (NumLanes) \
2278
7.90k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, CHAR(LaneKind)); \
2279
7.90k
    else \
2280
7.90k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", CHAR(LaneKind)); \
2281
7.90k
\
2282
7.90k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
2283
7.90k
  }
printTypedVectorList_0_h
Line
Count
Source
2270
5.26k
  { \
2271
5.26k
    add_cs_detail( \
2272
5.26k
      MI, \
2273
5.26k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, NumLanes), \
2274
5.26k
           LaneKind), \
2275
5.26k
      OpNum, NumLanes, CHAR(LaneKind)); \
2276
5.26k
    char Suffix[32]; \
2277
5.26k
    if (NumLanes) \
2278
5.26k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, CHAR(LaneKind)); \
2279
5.26k
    else \
2280
5.26k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", CHAR(LaneKind)); \
2281
5.26k
\
2282
5.26k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
2283
5.26k
  }
printTypedVectorList_0_s
Line
Count
Source
2270
5.82k
  { \
2271
5.82k
    add_cs_detail( \
2272
5.82k
      MI, \
2273
5.82k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, NumLanes), \
2274
5.82k
           LaneKind), \
2275
5.82k
      OpNum, NumLanes, CHAR(LaneKind)); \
2276
5.82k
    char Suffix[32]; \
2277
5.82k
    if (NumLanes) \
2278
5.82k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, CHAR(LaneKind)); \
2279
5.82k
    else \
2280
5.82k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", CHAR(LaneKind)); \
2281
5.82k
\
2282
5.82k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
2283
5.82k
  }
printTypedVectorList_0_q
Line
Count
Source
2270
329
  { \
2271
329
    add_cs_detail( \
2272
329
      MI, \
2273
329
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, NumLanes), \
2274
329
           LaneKind), \
2275
329
      OpNum, NumLanes, CHAR(LaneKind)); \
2276
329
    char Suffix[32]; \
2277
329
    if (NumLanes) \
2278
329
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, CHAR(LaneKind)); \
2279
329
    else \
2280
329
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", CHAR(LaneKind)); \
2281
329
\
2282
329
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
2283
329
  }
printTypedVectorList_16_b
Line
Count
Source
2270
2.31k
  { \
2271
2.31k
    add_cs_detail( \
2272
2.31k
      MI, \
2273
2.31k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, NumLanes), \
2274
2.31k
           LaneKind), \
2275
2.31k
      OpNum, NumLanes, CHAR(LaneKind)); \
2276
2.31k
    char Suffix[32]; \
2277
2.31k
    if (NumLanes) \
2278
2.31k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, CHAR(LaneKind)); \
2279
2.31k
    else \
2280
2.31k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", CHAR(LaneKind)); \
2281
2.31k
\
2282
2.31k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
2283
2.31k
  }
printTypedVectorList_1_d
Line
Count
Source
2270
440
  { \
2271
440
    add_cs_detail( \
2272
440
      MI, \
2273
440
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, NumLanes), \
2274
440
           LaneKind), \
2275
440
      OpNum, NumLanes, CHAR(LaneKind)); \
2276
440
    char Suffix[32]; \
2277
440
    if (NumLanes) \
2278
440
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, CHAR(LaneKind)); \
2279
440
    else \
2280
440
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", CHAR(LaneKind)); \
2281
440
\
2282
440
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
2283
440
  }
printTypedVectorList_2_d
Line
Count
Source
2270
238
  { \
2271
238
    add_cs_detail( \
2272
238
      MI, \
2273
238
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, NumLanes), \
2274
238
           LaneKind), \
2275
238
      OpNum, NumLanes, CHAR(LaneKind)); \
2276
238
    char Suffix[32]; \
2277
238
    if (NumLanes) \
2278
238
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, CHAR(LaneKind)); \
2279
238
    else \
2280
238
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", CHAR(LaneKind)); \
2281
238
\
2282
238
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
2283
238
  }
printTypedVectorList_2_s
Line
Count
Source
2270
1.78k
  { \
2271
1.78k
    add_cs_detail( \
2272
1.78k
      MI, \
2273
1.78k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, NumLanes), \
2274
1.78k
           LaneKind), \
2275
1.78k
      OpNum, NumLanes, CHAR(LaneKind)); \
2276
1.78k
    char Suffix[32]; \
2277
1.78k
    if (NumLanes) \
2278
1.78k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, CHAR(LaneKind)); \
2279
1.78k
    else \
2280
1.78k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", CHAR(LaneKind)); \
2281
1.78k
\
2282
1.78k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
2283
1.78k
  }
printTypedVectorList_4_h
Line
Count
Source
2270
413
  { \
2271
413
    add_cs_detail( \
2272
413
      MI, \
2273
413
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, NumLanes), \
2274
413
           LaneKind), \
2275
413
      OpNum, NumLanes, CHAR(LaneKind)); \
2276
413
    char Suffix[32]; \
2277
413
    if (NumLanes) \
2278
413
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, CHAR(LaneKind)); \
2279
413
    else \
2280
413
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", CHAR(LaneKind)); \
2281
413
\
2282
413
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
2283
413
  }
printTypedVectorList_4_s
Line
Count
Source
2270
403
  { \
2271
403
    add_cs_detail( \
2272
403
      MI, \
2273
403
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, NumLanes), \
2274
403
           LaneKind), \
2275
403
      OpNum, NumLanes, CHAR(LaneKind)); \
2276
403
    char Suffix[32]; \
2277
403
    if (NumLanes) \
2278
403
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, CHAR(LaneKind)); \
2279
403
    else \
2280
403
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", CHAR(LaneKind)); \
2281
403
\
2282
403
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
2283
403
  }
printTypedVectorList_8_b
Line
Count
Source
2270
1.84k
  { \
2271
1.84k
    add_cs_detail( \
2272
1.84k
      MI, \
2273
1.84k
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, NumLanes), \
2274
1.84k
           LaneKind), \
2275
1.84k
      OpNum, NumLanes, CHAR(LaneKind)); \
2276
1.84k
    char Suffix[32]; \
2277
1.84k
    if (NumLanes) \
2278
1.84k
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, CHAR(LaneKind)); \
2279
1.84k
    else \
2280
1.84k
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", CHAR(LaneKind)); \
2281
1.84k
\
2282
1.84k
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
2283
1.84k
  }
printTypedVectorList_8_h
Line
Count
Source
2270
364
  { \
2271
364
    add_cs_detail( \
2272
364
      MI, \
2273
364
      CONCAT(CONCAT(AArch64_OP_GROUP_TypedVectorList, NumLanes), \
2274
364
           LaneKind), \
2275
364
      OpNum, NumLanes, CHAR(LaneKind)); \
2276
364
    char Suffix[32]; \
2277
364
    if (NumLanes) \
2278
364
      cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, CHAR(LaneKind)); \
2279
364
    else \
2280
364
      cs_snprintf(Suffix, sizeof(Suffix), ".%c", CHAR(LaneKind)); \
2281
364
\
2282
364
    printVectorList(MI, OpNum, O, ((const char *)&Suffix)); \
2283
364
  }
2284
DEFINE_printTypedVectorList(0, b);
2285
DEFINE_printTypedVectorList(0, d);
2286
DEFINE_printTypedVectorList(0, h);
2287
DEFINE_printTypedVectorList(0, s);
2288
DEFINE_printTypedVectorList(0, q);
2289
DEFINE_printTypedVectorList(16, b);
2290
DEFINE_printTypedVectorList(1, d);
2291
DEFINE_printTypedVectorList(2, d);
2292
DEFINE_printTypedVectorList(2, s);
2293
DEFINE_printTypedVectorList(4, h);
2294
DEFINE_printTypedVectorList(4, s);
2295
DEFINE_printTypedVectorList(8, b);
2296
DEFINE_printTypedVectorList(8, h);
2297
2298
#define DEFINE_printVectorIndex(Scale) \
2299
  void CONCAT(printVectorIndex, Scale)(MCInst * MI, unsigned OpNum, \
2300
                     SStream *O) \
2301
17.4k
  { \
2302
17.4k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_VectorIndex, Scale), OpNum, \
2303
17.4k
            Scale); \
2304
17.4k
    SStream_concat(O, "%s", "["); \
2305
17.4k
    printUInt64(O, Scale * MCOperand_getImm(MCInst_getOperand(MI, (OpNum)))); \
2306
17.4k
    SStream_concat0(O, "]"); \
2307
17.4k
  }
printVectorIndex_1
Line
Count
Source
2301
17.4k
  { \
2302
17.4k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_VectorIndex, Scale), OpNum, \
2303
17.4k
            Scale); \
2304
17.4k
    SStream_concat(O, "%s", "["); \
2305
17.4k
    printUInt64(O, Scale * MCOperand_getImm(MCInst_getOperand(MI, (OpNum)))); \
2306
17.4k
    SStream_concat0(O, "]"); \
2307
17.4k
  }
printVectorIndex_8
Line
Count
Source
2301
24
  { \
2302
24
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_VectorIndex, Scale), OpNum, \
2303
24
            Scale); \
2304
24
    SStream_concat(O, "%s", "["); \
2305
24
    printUInt64(O, Scale * MCOperand_getImm(MCInst_getOperand(MI, (OpNum)))); \
2306
24
    SStream_concat0(O, "]"); \
2307
24
  }
2308
DEFINE_printVectorIndex(1);
2309
DEFINE_printVectorIndex(8);
2310
2311
void printMatrixIndex(MCInst *MI, unsigned OpNum, SStream *O)
2312
3.31k
{
2313
3.31k
  add_cs_detail(MI, AArch64_OP_GROUP_MatrixIndex, OpNum);
2314
3.31k
  printUInt32(O, MCOperand_getImm(MCInst_getOperand(MI, (OpNum))));
2315
3.31k
}
2316
2317
void printAlignedLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
2318
13.8k
{
2319
13.8k
  add_cs_detail(MI, AArch64_OP_GROUP_AlignedLabel, OpNum);
2320
13.8k
  MCOperand *Op = MCInst_getOperand(MI, (OpNum));
2321
2322
  // If the label has already been resolved to an immediate offset (say, when
2323
  // we're running the disassembler), just print the immediate.
2324
13.8k
  if (MCOperand_isImm(Op)) {
2325
13.8k
    SStream_concat0(O, markup("<imm:"));
2326
13.8k
    int64_t Offset = MCOperand_getImm(Op) * 4;
2327
13.8k
    if (!MI->csh->PrintBranchImmNotAsAddress)
2328
13.8k
      printUInt64(O, (Address + Offset));
2329
0
    else {
2330
0
      printUInt64Bang(O, (Offset));
2331
0
    }
2332
13.8k
    SStream_concat0(O, markup(">"));
2333
13.8k
    return;
2334
13.8k
  }
2335
2336
  // If the branch target is simply an address then print it in hex.
2337
0
  assert(0 && "Expressions are not supported.");
2338
0
}
2339
2340
void printAdrLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
2341
2.69k
{
2342
2.69k
  add_cs_detail(MI, AArch64_OP_GROUP_AdrLabel, OpNum);
2343
2.69k
  MCOperand *Op = MCInst_getOperand(MI, (OpNum));
2344
2345
  // If the label has already been resolved to an immediate offset (say, when
2346
  // we're running the disassembler), just print the immediate.
2347
2.69k
  if (MCOperand_isImm(Op)) {
2348
2.69k
    const int64_t Offset = MCOperand_getImm(Op);
2349
2.69k
    SStream_concat0(O, markup("<imm:"));
2350
2.69k
    if (!MI->csh->PrintBranchImmNotAsAddress)
2351
2.69k
      printUInt64(O, ((Address & -4096) + Offset));
2352
0
    else {
2353
0
      printUInt64Bang(O, Offset);
2354
0
    }
2355
2.69k
    SStream_concat0(O, markup(">"));
2356
2.69k
    return;
2357
2.69k
  }
2358
2359
  // Otherwise, just print the expression.
2360
0
  assert(0 && "Expressions are not supported.");
2361
0
}
2362
2363
void printAdrpLabel(MCInst *MI, uint64_t Address, unsigned OpNum, SStream *O)
2364
1.86k
{
2365
1.86k
  add_cs_detail(MI, AArch64_OP_GROUP_AdrpLabel, OpNum);
2366
1.86k
  MCOperand *Op = MCInst_getOperand(MI, (OpNum));
2367
2368
  // If the label has already been resolved to an immediate offset (say, when
2369
  // we're running the disassembler), just print the immediate.
2370
1.86k
  if (MCOperand_isImm(Op)) {
2371
1.86k
    const int64_t Offset = MCOperand_getImm(Op) * 4096;
2372
1.86k
    SStream_concat0(O, markup("<imm:"));
2373
1.86k
    if (!MI->csh->PrintBranchImmNotAsAddress)
2374
1.86k
      printUInt64(O, ((Address & -4096) + Offset));
2375
0
    else {
2376
0
      printUInt64Bang(O, Offset);
2377
0
    }
2378
1.86k
    SStream_concat0(O, markup(">"));
2379
1.86k
    return;
2380
1.86k
  }
2381
2382
  // Otherwise, just print the expression.
2383
0
  assert(0 && "Expressions are not supported.");
2384
0
}
2385
2386
void printBarrierOption(MCInst *MI, unsigned OpNo, SStream *O)
2387
628
{
2388
628
  add_cs_detail(MI, AArch64_OP_GROUP_BarrierOption, OpNo);
2389
628
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2390
628
  unsigned Opcode = MCInst_getOpcode(MI);
2391
2392
628
  const char *Name;
2393
628
  if (Opcode == AArch64_ISB) {
2394
29
    const AArch64ISB_ISB *ISB = AArch64ISB_lookupISBByEncoding(Val);
2395
29
    Name = ISB ? ISB->Name : "";
2396
599
  } else if (Opcode == AArch64_TSB) {
2397
10
    const AArch64TSB_TSB *TSB = AArch64TSB_lookupTSBByEncoding(Val);
2398
10
    Name = TSB ? TSB->Name : "";
2399
589
  } else {
2400
589
    const AArch64DB_DB *DB = AArch64DB_lookupDBByEncoding(Val);
2401
589
    Name = DB ? DB->Name : "";
2402
589
  }
2403
628
  if (Name[0] != '\0')
2404
444
    SStream_concat0(O, Name);
2405
184
  else {
2406
184
    SStream_concat(O, "%s", markup("<imm:"));
2407
184
    printUInt32Bang(O, Val);
2408
184
    SStream_concat0(O, markup(">"));
2409
184
  }
2410
628
}
2411
2412
void printBarriernXSOption(MCInst *MI, unsigned OpNo, SStream *O)
2413
6
{
2414
6
  add_cs_detail(MI, AArch64_OP_GROUP_BarriernXSOption, OpNo);
2415
6
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2416
2417
6
  const char *Name;
2418
6
  const AArch64DBnXS_DBnXS *DB = AArch64DBnXS_lookupDBnXSByEncoding(Val);
2419
6
  Name = DB ? DB->Name : "";
2420
2421
6
  if (Name[0] != '\0')
2422
6
    SStream_concat0(O, Name);
2423
0
  else {
2424
0
    SStream_concat(O, "%s%s%s", markup("<imm:"), "#", Val);
2425
0
    SStream_concat0(O, markup(">"));
2426
0
  }
2427
6
}
2428
2429
static bool isValidSysReg(const AArch64SysReg_SysReg *Reg, bool Read, unsigned mode)
2430
2.83k
{
2431
2.83k
  return (Reg && (Read ? Reg->Readable : Reg->Writeable) &&
2432
2.83k
      AArch64_testFeatureList(mode, Reg->FeaturesRequired));
2433
2.83k
}
2434
2435
// Looks up a system register either by encoding or by name. Some system
2436
// registers share the same encoding between different architectures,
2437
// therefore a tablegen lookup by encoding will return an entry regardless
2438
// of the register's predication on a specific subtarget feature. To work
2439
// around this problem we keep an alternative name for such registers and
2440
// look them up by that name if the first lookup was unsuccessful.
2441
static const AArch64SysReg_SysReg *lookupSysReg(unsigned Val, bool Read, unsigned mode)
2442
2.42k
{
2443
2.42k
  const AArch64SysReg_SysReg *Reg = AArch64SysReg_lookupSysRegByEncoding(Val);
2444
2445
2.42k
  if (Reg && !isValidSysReg(Reg, Read, mode))
2446
193
    Reg = AArch64SysReg_lookupSysRegByName(Reg->AltName);
2447
2448
2.42k
  return Reg;
2449
2.42k
}
2450
2451
void printMRSSystemRegister(MCInst *MI, unsigned OpNo, SStream *O)
2452
585
{
2453
585
  add_cs_detail(MI, AArch64_OP_GROUP_MRSSystemRegister, OpNo);
2454
585
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2455
2456
  // Horrible hack for the one register that has identical encodings but
2457
  // different names in MSR and MRS. Because of this, one of MRS and MSR is
2458
  // going to get the wrong entry
2459
585
  if (Val == AArch64_SYSREG_DBGDTRRX_EL0) {
2460
19
    SStream_concat0(O, "DBGDTRRX_EL0");
2461
19
    return;
2462
19
  }
2463
2464
  // Horrible hack for two different registers having the same encoding.
2465
566
  if (Val == AArch64_SYSREG_TRCEXTINSELR) {
2466
21
    SStream_concat0(O, "TRCEXTINSELR");
2467
21
    return;
2468
21
  }
2469
2470
545
  const AArch64SysReg_SysReg *Reg = lookupSysReg(Val, true /*Read*/, MI->csh->mode);
2471
2472
545
  if (isValidSysReg(Reg, true /*Read*/, MI->csh->mode))
2473
29
    SStream_concat0(O, Reg->Name);
2474
516
  else {
2475
516
    char result[AARCH64_GRS_LEN + 1] = {0};
2476
516
    AArch64SysReg_genericRegisterString(Val, result);
2477
516
    SStream_concat0(O, result);
2478
516
  }
2479
545
}
2480
2481
void printMSRSystemRegister(MCInst *MI, unsigned OpNo, SStream *O)
2482
1.90k
{
2483
1.90k
  add_cs_detail(MI, AArch64_OP_GROUP_MSRSystemRegister, OpNo);
2484
1.90k
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2485
2486
  // Horrible hack for the one register that has identical encodings but
2487
  // different names in MSR and MRS. Because of this, one of MRS and MSR is
2488
  // going to get the wrong entry
2489
1.90k
  if (Val == AArch64_SYSREG_DBGDTRTX_EL0) {
2490
20
    SStream_concat0(O, "DBGDTRTX_EL0");
2491
20
    return;
2492
20
  }
2493
2494
  // Horrible hack for two different registers having the same encoding.
2495
1.88k
  if (Val == AArch64_SYSREG_TRCEXTINSELR) {
2496
10
    SStream_concat0(O, "TRCEXTINSELR");
2497
10
    return;
2498
10
  }
2499
2500
1.87k
  const AArch64SysReg_SysReg *Reg = lookupSysReg(Val, false /*Read*/, MI->csh->mode);
2501
2502
1.87k
  if (isValidSysReg(Reg, false /*Read*/, MI->csh->mode))
2503
188
    SStream_concat0(O, Reg->Name);
2504
1.68k
  else {
2505
1.68k
    char result[AARCH64_GRS_LEN + 1] = {0};
2506
1.68k
    AArch64SysReg_genericRegisterString(Val, result);
2507
1.68k
    SStream_concat0(O, result);
2508
1.68k
  }
2509
1.87k
}
2510
2511
void printSystemPStateField(MCInst *MI, unsigned OpNo, SStream *O)
2512
224
{
2513
224
  add_cs_detail(MI, AArch64_OP_GROUP_SystemPStateField, OpNo);
2514
224
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2515
2516
224
  const AArch64PState_PStateImm0_15 *PStateImm15 = AArch64PState_lookupPStateImm0_15ByEncoding(Val);
2517
224
  const AArch64PState_PStateImm0_1 *PStateImm1 = AArch64PState_lookupPStateImm0_1ByEncoding(Val);
2518
224
  if (PStateImm15 && AArch64_testFeatureList(MI->csh->mode, PStateImm15->FeaturesRequired))
2519
195
    SStream_concat0(O, PStateImm15->Name);
2520
29
  else if (PStateImm1 && AArch64_testFeatureList(MI->csh->mode, PStateImm1->FeaturesRequired))
2521
29
    SStream_concat0(O, PStateImm1->Name);
2522
0
  else {
2523
0
    printUInt32Bang(O, (Val));
2524
0
    SStream_concat1(O, '\0');
2525
0
  }
2526
224
}
2527
2528
void printSIMDType10Operand(MCInst *MI, unsigned OpNo, SStream *O)
2529
143
{
2530
143
  add_cs_detail(MI, AArch64_OP_GROUP_SIMDType10Operand, OpNo);
2531
143
  unsigned RawVal = MCOperand_getImm(MCInst_getOperand(MI, (OpNo)));
2532
143
  uint64_t Val = AArch64_AM_decodeAdvSIMDModImmType10(RawVal);
2533
143
  SStream_concat(O, "%s#%#016llx", markup("<imm:"),  Val);
2534
143
  SStream_concat0(O, markup(">"));
2535
143
}
2536
2537
#define DEFINE_printComplexRotationOp(Angle, Remainder) \
2538
  static void CONCAT(printComplexRotationOp, CONCAT(Angle, Remainder))( \
2539
    MCInst * MI, unsigned OpNo, SStream *O) \
2540
1.36k
  { \
2541
1.36k
    add_cs_detail( \
2542
1.36k
      MI, \
2543
1.36k
      CONCAT(CONCAT(AArch64_OP_GROUP_ComplexRotationOp, Angle), \
2544
1.36k
           Remainder), \
2545
1.36k
      OpNo, Angle, Remainder); \
2546
1.36k
    unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); \
2547
1.36k
    SStream_concat(O, "%s", markup("<imm:")); \
2548
1.36k
    SStream_concat(O, "#%d", (Val * Angle) + Remainder); \
2549
1.36k
    SStream_concat0(O, markup(">")); \
2550
1.36k
  }
AArch64InstPrinter.c:printComplexRotationOp_180_90
Line
Count
Source
2540
339
  { \
2541
339
    add_cs_detail( \
2542
339
      MI, \
2543
339
      CONCAT(CONCAT(AArch64_OP_GROUP_ComplexRotationOp, Angle), \
2544
339
           Remainder), \
2545
339
      OpNo, Angle, Remainder); \
2546
339
    unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); \
2547
339
    SStream_concat(O, "%s", markup("<imm:")); \
2548
339
    SStream_concat(O, "#%d", (Val * Angle) + Remainder); \
2549
339
    SStream_concat0(O, markup(">")); \
2550
339
  }
AArch64InstPrinter.c:printComplexRotationOp_90_0
Line
Count
Source
2540
1.02k
  { \
2541
1.02k
    add_cs_detail( \
2542
1.02k
      MI, \
2543
1.02k
      CONCAT(CONCAT(AArch64_OP_GROUP_ComplexRotationOp, Angle), \
2544
1.02k
           Remainder), \
2545
1.02k
      OpNo, Angle, Remainder); \
2546
1.02k
    unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNo))); \
2547
1.02k
    SStream_concat(O, "%s", markup("<imm:")); \
2548
1.02k
    SStream_concat(O, "#%d", (Val * Angle) + Remainder); \
2549
1.02k
    SStream_concat0(O, markup(">")); \
2550
1.02k
  }
2551
DEFINE_printComplexRotationOp(180, 90);
2552
DEFINE_printComplexRotationOp(90, 0);
2553
2554
void printSVEPattern(MCInst *MI, unsigned OpNum, SStream *O)
2555
2.39k
{
2556
2.39k
  add_cs_detail(MI, AArch64_OP_GROUP_SVEPattern, OpNum);
2557
2.39k
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
2558
2.39k
  const AArch64SVEPredPattern_SVEPREDPAT *Pat = AArch64SVEPredPattern_lookupSVEPREDPATByEncoding(Val);
2559
2.39k
  if (Pat)
2560
2.09k
    SStream_concat0(O, Pat->Name);
2561
2.39k
}
2562
2563
void printSVEVecLenSpecifier(MCInst *MI, unsigned OpNum, SStream *O)
2564
140
{
2565
140
  add_cs_detail(MI, AArch64_OP_GROUP_SVEVecLenSpecifier, OpNum);
2566
140
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum)));
2567
  // Pattern has only 1 bit
2568
140
  if (Val > 1)
2569
0
    assert(0 && "Invalid vector length specifier");
2570
140
  const AArch64SVEVecLenSpecifier_SVEVECLENSPECIFIER *Pat =
2571
140
    AArch64SVEVecLenSpecifier_lookupSVEVECLENSPECIFIERByEncoding(Val);
2572
140
  if (Pat)
2573
140
    SStream_concat0(O, Pat->Name);
2574
140
}
2575
2576
#define DEFINE_printSVERegOp(suffix) \
2577
  void CONCAT(printSVERegOp, suffix)(MCInst * MI, unsigned OpNum, \
2578
                     SStream *O) \
2579
123k
  { \
2580
123k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2581
123k
            CHAR(suffix)); \
2582
123k
    switch (CHAR(suffix)) { \
2583
37.5k
    case '0': \
2584
50.9k
    case 'b': \
2585
75.1k
    case 'h': \
2586
101k
    case 's': \
2587
123k
    case 'd': \
2588
123k
    case 'q': \
2589
123k
      break; \
2590
123k
    default: \
2591
0
      assert(0 && "Invalid kind specifier."); \
2592
123k
    } \
2593
123k
\
2594
123k
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2595
123k
    printRegName(O, Reg); \
2596
123k
    if (CHAR(suffix) != '0') { \
2597
86.3k
      SStream_concat1(O, '.'); \
2598
86.3k
      SStream_concat1(O, CHAR(suffix)); \
2599
86.3k
    } \
2600
123k
  }
printSVERegOp_b
Line
Count
Source
2579
13.4k
  { \
2580
13.4k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2581
13.4k
            CHAR(suffix)); \
2582
13.4k
    switch (CHAR(suffix)) { \
2583
0
    case '0': \
2584
13.4k
    case 'b': \
2585
13.4k
    case 'h': \
2586
13.4k
    case 's': \
2587
13.4k
    case 'd': \
2588
13.4k
    case 'q': \
2589
13.4k
      break; \
2590
13.4k
    default: \
2591
0
      assert(0 && "Invalid kind specifier."); \
2592
13.4k
    } \
2593
13.4k
\
2594
13.4k
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2595
13.4k
    printRegName(O, Reg); \
2596
13.4k
    if (CHAR(suffix) != '0') { \
2597
13.4k
      SStream_concat1(O, '.'); \
2598
13.4k
      SStream_concat1(O, CHAR(suffix)); \
2599
13.4k
    } \
2600
13.4k
  }
printSVERegOp_d
Line
Count
Source
2579
22.2k
  { \
2580
22.2k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2581
22.2k
            CHAR(suffix)); \
2582
22.2k
    switch (CHAR(suffix)) { \
2583
0
    case '0': \
2584
0
    case 'b': \
2585
0
    case 'h': \
2586
0
    case 's': \
2587
22.2k
    case 'd': \
2588
22.2k
    case 'q': \
2589
22.2k
      break; \
2590
22.2k
    default: \
2591
0
      assert(0 && "Invalid kind specifier."); \
2592
22.2k
    } \
2593
22.2k
\
2594
22.2k
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2595
22.2k
    printRegName(O, Reg); \
2596
22.2k
    if (CHAR(suffix) != '0') { \
2597
22.2k
      SStream_concat1(O, '.'); \
2598
22.2k
      SStream_concat1(O, CHAR(suffix)); \
2599
22.2k
    } \
2600
22.2k
  }
printSVERegOp_h
Line
Count
Source
2579
24.1k
  { \
2580
24.1k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2581
24.1k
            CHAR(suffix)); \
2582
24.1k
    switch (CHAR(suffix)) { \
2583
0
    case '0': \
2584
0
    case 'b': \
2585
24.1k
    case 'h': \
2586
24.1k
    case 's': \
2587
24.1k
    case 'd': \
2588
24.1k
    case 'q': \
2589
24.1k
      break; \
2590
24.1k
    default: \
2591
0
      assert(0 && "Invalid kind specifier."); \
2592
24.1k
    } \
2593
24.1k
\
2594
24.1k
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2595
24.1k
    printRegName(O, Reg); \
2596
24.1k
    if (CHAR(suffix) != '0') { \
2597
24.1k
      SStream_concat1(O, '.'); \
2598
24.1k
      SStream_concat1(O, CHAR(suffix)); \
2599
24.1k
    } \
2600
24.1k
  }
printSVERegOp_s
Line
Count
Source
2579
25.9k
  { \
2580
25.9k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2581
25.9k
            CHAR(suffix)); \
2582
25.9k
    switch (CHAR(suffix)) { \
2583
0
    case '0': \
2584
0
    case 'b': \
2585
0
    case 'h': \
2586
25.9k
    case 's': \
2587
25.9k
    case 'd': \
2588
25.9k
    case 'q': \
2589
25.9k
      break; \
2590
25.9k
    default: \
2591
0
      assert(0 && "Invalid kind specifier."); \
2592
25.9k
    } \
2593
25.9k
\
2594
25.9k
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2595
25.9k
    printRegName(O, Reg); \
2596
25.9k
    if (CHAR(suffix) != '0') { \
2597
25.9k
      SStream_concat1(O, '.'); \
2598
25.9k
      SStream_concat1(O, CHAR(suffix)); \
2599
25.9k
    } \
2600
25.9k
  }
printSVERegOp_0
Line
Count
Source
2579
37.5k
  { \
2580
37.5k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2581
37.5k
            CHAR(suffix)); \
2582
37.5k
    switch (CHAR(suffix)) { \
2583
37.5k
    case '0': \
2584
37.5k
    case 'b': \
2585
37.5k
    case 'h': \
2586
37.5k
    case 's': \
2587
37.5k
    case 'd': \
2588
37.5k
    case 'q': \
2589
37.5k
      break; \
2590
37.5k
    default: \
2591
0
      assert(0 && "Invalid kind specifier."); \
2592
37.5k
    } \
2593
37.5k
\
2594
37.5k
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2595
37.5k
    printRegName(O, Reg); \
2596
37.5k
    if (CHAR(suffix) != '0') { \
2597
0
      SStream_concat1(O, '.'); \
2598
0
      SStream_concat1(O, CHAR(suffix)); \
2599
0
    } \
2600
37.5k
  }
printSVERegOp_q
Line
Count
Source
2579
585
  { \
2580
585
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_SVERegOp, suffix), OpNum, \
2581
585
            CHAR(suffix)); \
2582
585
    switch (CHAR(suffix)) { \
2583
0
    case '0': \
2584
0
    case 'b': \
2585
0
    case 'h': \
2586
0
    case 's': \
2587
0
    case 'd': \
2588
585
    case 'q': \
2589
585
      break; \
2590
0
    default: \
2591
0
      assert(0 && "Invalid kind specifier."); \
2592
585
    } \
2593
585
\
2594
585
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2595
585
    printRegName(O, Reg); \
2596
585
    if (CHAR(suffix) != '0') { \
2597
585
      SStream_concat1(O, '.'); \
2598
585
      SStream_concat1(O, CHAR(suffix)); \
2599
585
    } \
2600
585
  }
2601
DEFINE_printSVERegOp(b);
2602
DEFINE_printSVERegOp(d);
2603
DEFINE_printSVERegOp(h);
2604
DEFINE_printSVERegOp(s);
2605
DEFINE_printSVERegOp(0);
2606
DEFINE_printSVERegOp(q);
2607
2608
#define DECLARE_printImmSVE_S32(T) \
2609
2.79k
  void CONCAT(printImmSVE, T)(T Val, SStream *O) { \
2610
2.79k
  printInt32Bang(O, Val); \
2611
2.79k
}
printImmSVE_int16_t
Line
Count
Source
2609
2.32k
  void CONCAT(printImmSVE, T)(T Val, SStream *O) { \
2610
2.32k
  printInt32Bang(O, Val); \
2611
2.32k
}
printImmSVE_int8_t
Line
Count
Source
2609
127
  void CONCAT(printImmSVE, T)(T Val, SStream *O) { \
2610
127
  printInt32Bang(O, Val); \
2611
127
}
printImmSVE_int32_t
Line
Count
Source
2609
341
  void CONCAT(printImmSVE, T)(T Val, SStream *O) { \
2610
341
  printInt32Bang(O, Val); \
2611
341
}
2612
DECLARE_printImmSVE_S32(int16_t);
2613
DECLARE_printImmSVE_S32(int8_t);
2614
DECLARE_printImmSVE_S32(int32_t);
2615
2616
#define DECLARE_printImmSVE_U32(T) \
2617
499
  void CONCAT(printImmSVE, T)(T Val, SStream *O) { \
2618
499
  printUInt32Bang(O, Val); \
2619
499
}
printImmSVE_uint16_t
Line
Count
Source
2617
348
  void CONCAT(printImmSVE, T)(T Val, SStream *O) { \
2618
348
  printUInt32Bang(O, Val); \
2619
348
}
printImmSVE_uint8_t
Line
Count
Source
2617
67
  void CONCAT(printImmSVE, T)(T Val, SStream *O) { \
2618
67
  printUInt32Bang(O, Val); \
2619
67
}
printImmSVE_uint32_t
Line
Count
Source
2617
84
  void CONCAT(printImmSVE, T)(T Val, SStream *O) { \
2618
84
  printUInt32Bang(O, Val); \
2619
84
}
2620
DECLARE_printImmSVE_U32(uint16_t);
2621
DECLARE_printImmSVE_U32(uint8_t);
2622
DECLARE_printImmSVE_U32(uint32_t);
2623
2624
#define DECLARE_printImmSVE_S64(T) \
2625
40
  void CONCAT(printImmSVE, T)(T Val, SStream *O) { \
2626
40
  printInt64Bang(O, Val); \
2627
40
}
2628
DECLARE_printImmSVE_S64(uint64_t);
2629
2630
#define DECLARE_printImmSVE_U64(T) \
2631
470
  void CONCAT(printImmSVE, T)(T Val, SStream *O) { \
2632
470
  printUInt64Bang(O, Val); \
2633
470
}
2634
DECLARE_printImmSVE_U64(int64_t);
2635
2636
#define DEFINE_isSignedType(T) \
2637
1.84k
static inline bool CONCAT(isSignedType, T)() {\
2638
1.84k
  return CHAR(t) == 'i'; \
2639
1.84k
}
AArch64InstPrinter.c:isSignedType_int16_t
Line
Count
Source
2637
567
static inline bool CONCAT(isSignedType, T)() {\
2638
567
  return CHAR(t) == 'i'; \
2639
567
}
AArch64InstPrinter.c:isSignedType_int8_t
Line
Count
Source
2637
127
static inline bool CONCAT(isSignedType, T)() {\
2638
127
  return CHAR(t) == 'i'; \
2639
127
}
AArch64InstPrinter.c:isSignedType_int64_t
Line
Count
Source
2637
397
static inline bool CONCAT(isSignedType, T)() {\
2638
397
  return CHAR(t) == 'i'; \
2639
397
}
AArch64InstPrinter.c:isSignedType_int32_t
Line
Count
Source
2637
214
static inline bool CONCAT(isSignedType, T)() {\
2638
214
  return CHAR(t) == 'i'; \
2639
214
}
AArch64InstPrinter.c:isSignedType_uint16_t
Line
Count
Source
2637
348
static inline bool CONCAT(isSignedType, T)() {\
2638
348
  return CHAR(t) == 'i'; \
2639
348
}
AArch64InstPrinter.c:isSignedType_uint8_t
Line
Count
Source
2637
67
static inline bool CONCAT(isSignedType, T)() {\
2638
67
  return CHAR(t) == 'i'; \
2639
67
}
AArch64InstPrinter.c:isSignedType_uint64_t
Line
Count
Source
2637
40
static inline bool CONCAT(isSignedType, T)() {\
2638
40
  return CHAR(t) == 'i'; \
2639
40
}
AArch64InstPrinter.c:isSignedType_uint32_t
Line
Count
Source
2637
84
static inline bool CONCAT(isSignedType, T)() {\
2638
84
  return CHAR(t) == 'i'; \
2639
84
}
2640
DEFINE_isSignedType(int8_t);
2641
DEFINE_isSignedType(int16_t);
2642
DEFINE_isSignedType(int32_t);
2643
DEFINE_isSignedType(int64_t);
2644
DEFINE_isSignedType(uint8_t);
2645
DEFINE_isSignedType(uint16_t);
2646
DEFINE_isSignedType(uint32_t);
2647
DEFINE_isSignedType(uint64_t);
2648
2649
#define DEFINE_printImm8OptLsl(T) \
2650
  void CONCAT(printImm8OptLsl, T)(MCInst * MI, unsigned OpNum, SStream *O) \
2651
1.94k
  { \
2652
1.94k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, sizeof(T)); \
2653
1.94k
    unsigned UnscaledVal = \
2654
1.94k
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2655
1.94k
    unsigned Shift = MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2656
1.94k
\
2657
1.94k
    if ((UnscaledVal == 0) && (AArch64_AM_getShiftValue(Shift) != 0)) { \
2658
101
      SStream_concat(O, "%s", markup("<imm:")); \
2659
101
      SStream_concat1(O, '#'); \
2660
101
      printUInt64(O, (UnscaledVal)); \
2661
101
      SStream_concat0(O, markup(">")); \
2662
101
      printShifter(MI, OpNum + 1, O); \
2663
101
      return; \
2664
101
    } \
2665
1.94k
\
2666
1.94k
    T Val; \
2667
1.84k
    if (CONCAT(isSignedType, T)()) \
2668
1.84k
      Val = \
2669
0
        (int8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2670
1.84k
    else \
2671
1.84k
      Val = \
2672
1.84k
        (uint8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2673
1.84k
\
2674
1.84k
    CONCAT(printImmSVE, T)(Val, O); \
2675
1.84k
  }
printImm8OptLsl_int16_t
Line
Count
Source
2651
573
  { \
2652
573
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, sizeof(T)); \
2653
573
    unsigned UnscaledVal = \
2654
573
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2655
573
    unsigned Shift = MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2656
573
\
2657
573
    if ((UnscaledVal == 0) && (AArch64_AM_getShiftValue(Shift) != 0)) { \
2658
6
      SStream_concat(O, "%s", markup("<imm:")); \
2659
6
      SStream_concat1(O, '#'); \
2660
6
      printUInt64(O, (UnscaledVal)); \
2661
6
      SStream_concat0(O, markup(">")); \
2662
6
      printShifter(MI, OpNum + 1, O); \
2663
6
      return; \
2664
6
    } \
2665
573
\
2666
573
    T Val; \
2667
567
    if (CONCAT(isSignedType, T)()) \
2668
567
      Val = \
2669
0
        (int8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2670
567
    else \
2671
567
      Val = \
2672
567
        (uint8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2673
567
\
2674
567
    CONCAT(printImmSVE, T)(Val, O); \
2675
567
  }
printImm8OptLsl_int8_t
Line
Count
Source
2651
127
  { \
2652
127
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, sizeof(T)); \
2653
127
    unsigned UnscaledVal = \
2654
127
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2655
127
    unsigned Shift = MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2656
127
\
2657
127
    if ((UnscaledVal == 0) && (AArch64_AM_getShiftValue(Shift) != 0)) { \
2658
0
      SStream_concat(O, "%s", markup("<imm:")); \
2659
0
      SStream_concat1(O, '#'); \
2660
0
      printUInt64(O, (UnscaledVal)); \
2661
0
      SStream_concat0(O, markup(">")); \
2662
0
      printShifter(MI, OpNum + 1, O); \
2663
0
      return; \
2664
0
    } \
2665
127
\
2666
127
    T Val; \
2667
127
    if (CONCAT(isSignedType, T)()) \
2668
127
      Val = \
2669
0
        (int8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2670
127
    else \
2671
127
      Val = \
2672
127
        (uint8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2673
127
\
2674
127
    CONCAT(printImmSVE, T)(Val, O); \
2675
127
  }
printImm8OptLsl_int64_t
Line
Count
Source
2651
428
  { \
2652
428
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, sizeof(T)); \
2653
428
    unsigned UnscaledVal = \
2654
428
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2655
428
    unsigned Shift = MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2656
428
\
2657
428
    if ((UnscaledVal == 0) && (AArch64_AM_getShiftValue(Shift) != 0)) { \
2658
31
      SStream_concat(O, "%s", markup("<imm:")); \
2659
31
      SStream_concat1(O, '#'); \
2660
31
      printUInt64(O, (UnscaledVal)); \
2661
31
      SStream_concat0(O, markup(">")); \
2662
31
      printShifter(MI, OpNum + 1, O); \
2663
31
      return; \
2664
31
    } \
2665
428
\
2666
428
    T Val; \
2667
397
    if (CONCAT(isSignedType, T)()) \
2668
397
      Val = \
2669
0
        (int8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2670
397
    else \
2671
397
      Val = \
2672
397
        (uint8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2673
397
\
2674
397
    CONCAT(printImmSVE, T)(Val, O); \
2675
397
  }
printImm8OptLsl_int32_t
Line
Count
Source
2651
242
  { \
2652
242
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, sizeof(T)); \
2653
242
    unsigned UnscaledVal = \
2654
242
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2655
242
    unsigned Shift = MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2656
242
\
2657
242
    if ((UnscaledVal == 0) && (AArch64_AM_getShiftValue(Shift) != 0)) { \
2658
28
      SStream_concat(O, "%s", markup("<imm:")); \
2659
28
      SStream_concat1(O, '#'); \
2660
28
      printUInt64(O, (UnscaledVal)); \
2661
28
      SStream_concat0(O, markup(">")); \
2662
28
      printShifter(MI, OpNum + 1, O); \
2663
28
      return; \
2664
28
    } \
2665
242
\
2666
242
    T Val; \
2667
214
    if (CONCAT(isSignedType, T)()) \
2668
214
      Val = \
2669
0
        (int8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2670
214
    else \
2671
214
      Val = \
2672
214
        (uint8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2673
214
\
2674
214
    CONCAT(printImmSVE, T)(Val, O); \
2675
214
  }
printImm8OptLsl_uint16_t
Line
Count
Source
2651
351
  { \
2652
351
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, sizeof(T)); \
2653
351
    unsigned UnscaledVal = \
2654
351
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2655
351
    unsigned Shift = MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2656
351
\
2657
351
    if ((UnscaledVal == 0) && (AArch64_AM_getShiftValue(Shift) != 0)) { \
2658
3
      SStream_concat(O, "%s", markup("<imm:")); \
2659
3
      SStream_concat1(O, '#'); \
2660
3
      printUInt64(O, (UnscaledVal)); \
2661
3
      SStream_concat0(O, markup(">")); \
2662
3
      printShifter(MI, OpNum + 1, O); \
2663
3
      return; \
2664
3
    } \
2665
351
\
2666
351
    T Val; \
2667
348
    if (CONCAT(isSignedType, T)()) \
2668
348
      Val = \
2669
0
        (int8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2670
348
    else \
2671
348
      Val = \
2672
348
        (uint8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2673
348
\
2674
348
    CONCAT(printImmSVE, T)(Val, O); \
2675
348
  }
printImm8OptLsl_uint8_t
Line
Count
Source
2651
67
  { \
2652
67
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, sizeof(T)); \
2653
67
    unsigned UnscaledVal = \
2654
67
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2655
67
    unsigned Shift = MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2656
67
\
2657
67
    if ((UnscaledVal == 0) && (AArch64_AM_getShiftValue(Shift) != 0)) { \
2658
0
      SStream_concat(O, "%s", markup("<imm:")); \
2659
0
      SStream_concat1(O, '#'); \
2660
0
      printUInt64(O, (UnscaledVal)); \
2661
0
      SStream_concat0(O, markup(">")); \
2662
0
      printShifter(MI, OpNum + 1, O); \
2663
0
      return; \
2664
0
    } \
2665
67
\
2666
67
    T Val; \
2667
67
    if (CONCAT(isSignedType, T)()) \
2668
67
      Val = \
2669
0
        (int8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2670
67
    else \
2671
67
      Val = \
2672
67
        (uint8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2673
67
\
2674
67
    CONCAT(printImmSVE, T)(Val, O); \
2675
67
  }
printImm8OptLsl_uint64_t
Line
Count
Source
2651
63
  { \
2652
63
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, sizeof(T)); \
2653
63
    unsigned UnscaledVal = \
2654
63
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2655
63
    unsigned Shift = MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2656
63
\
2657
63
    if ((UnscaledVal == 0) && (AArch64_AM_getShiftValue(Shift) != 0)) { \
2658
23
      SStream_concat(O, "%s", markup("<imm:")); \
2659
23
      SStream_concat1(O, '#'); \
2660
23
      printUInt64(O, (UnscaledVal)); \
2661
23
      SStream_concat0(O, markup(">")); \
2662
23
      printShifter(MI, OpNum + 1, O); \
2663
23
      return; \
2664
23
    } \
2665
63
\
2666
63
    T Val; \
2667
40
    if (CONCAT(isSignedType, T)()) \
2668
40
      Val = \
2669
0
        (int8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2670
40
    else \
2671
40
      Val = \
2672
40
        (uint8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2673
40
\
2674
40
    CONCAT(printImmSVE, T)(Val, O); \
2675
40
  }
printImm8OptLsl_uint32_t
Line
Count
Source
2651
94
  { \
2652
94
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_Imm8OptLsl, T), OpNum, sizeof(T)); \
2653
94
    unsigned UnscaledVal = \
2654
94
      MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2655
94
    unsigned Shift = MCOperand_getImm(MCInst_getOperand(MI, (OpNum + 1))); \
2656
94
\
2657
94
    if ((UnscaledVal == 0) && (AArch64_AM_getShiftValue(Shift) != 0)) { \
2658
10
      SStream_concat(O, "%s", markup("<imm:")); \
2659
10
      SStream_concat1(O, '#'); \
2660
10
      printUInt64(O, (UnscaledVal)); \
2661
10
      SStream_concat0(O, markup(">")); \
2662
10
      printShifter(MI, OpNum + 1, O); \
2663
10
      return; \
2664
10
    } \
2665
94
\
2666
94
    T Val; \
2667
84
    if (CONCAT(isSignedType, T)()) \
2668
84
      Val = \
2669
0
        (int8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2670
84
    else \
2671
84
      Val = \
2672
84
        (uint8_t)UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift)); \
2673
84
\
2674
84
    CONCAT(printImmSVE, T)(Val, O); \
2675
84
  }
2676
DEFINE_printImm8OptLsl(int16_t);
2677
DEFINE_printImm8OptLsl(int8_t);
2678
DEFINE_printImm8OptLsl(int64_t);
2679
DEFINE_printImm8OptLsl(int32_t);
2680
DEFINE_printImm8OptLsl(uint16_t);
2681
DEFINE_printImm8OptLsl(uint8_t);
2682
DEFINE_printImm8OptLsl(uint64_t);
2683
DEFINE_printImm8OptLsl(uint32_t);
2684
2685
#define DEFINE_printSVELogicalImm(T) \
2686
  void CONCAT(printSVELogicalImm, T)(MCInst * MI, unsigned OpNum, \
2687
                     SStream *O) \
2688
3.02k
  { \
2689
3.02k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_SVELogicalImm, T), OpNum, \
2690
3.02k
            sizeof(T)); \
2691
3.02k
    typedef T SignedT; \
2692
3.02k
    typedef CONCATS(u, T) UnsignedT; \
2693
3.02k
\
2694
3.02k
    uint64_t Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2695
3.02k
    UnsignedT PrintVal = AArch64_AM_decodeLogicalImmediate(Val, 64); \
2696
3.02k
\
2697
3.02k
    if ((int16_t)PrintVal == (SignedT)PrintVal) \
2698
3.02k
      CONCAT(printImmSVE, T)((T)PrintVal, O); \
2699
3.02k
    else if ((uint16_t)PrintVal == PrintVal) \
2700
1.15k
      CONCAT(printImmSVE, T)(PrintVal, O); \
2701
1.15k
    else { \
2702
1.06k
      SStream_concat(O, "%s", markup("<imm:")); \
2703
1.06k
      printUInt64Bang(O, ((uint64_t)PrintVal)); \
2704
1.06k
      SStream_concat0(O, markup(">")); \
2705
1.06k
    } \
2706
3.02k
  }
printSVELogicalImm_int16_t
Line
Count
Source
2688
1.76k
  { \
2689
1.76k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_SVELogicalImm, T), OpNum, \
2690
1.76k
            sizeof(T)); \
2691
1.76k
    typedef T SignedT; \
2692
1.76k
    typedef CONCATS(u, T) UnsignedT; \
2693
1.76k
\
2694
1.76k
    uint64_t Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2695
1.76k
    UnsignedT PrintVal = AArch64_AM_decodeLogicalImmediate(Val, 64); \
2696
1.76k
\
2697
1.76k
    if ((int16_t)PrintVal == (SignedT)PrintVal) \
2698
1.76k
      CONCAT(printImmSVE, T)((T)PrintVal, O); \
2699
1.76k
    else if ((uint16_t)PrintVal == PrintVal) \
2700
0
      CONCAT(printImmSVE, T)(PrintVal, O); \
2701
0
    else { \
2702
0
      SStream_concat(O, "%s", markup("<imm:")); \
2703
0
      printUInt64Bang(O, ((uint64_t)PrintVal)); \
2704
0
      SStream_concat0(O, markup(">")); \
2705
0
    } \
2706
1.76k
  }
printSVELogicalImm_int32_t
Line
Count
Source
2688
1.02k
  { \
2689
1.02k
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_SVELogicalImm, T), OpNum, \
2690
1.02k
            sizeof(T)); \
2691
1.02k
    typedef T SignedT; \
2692
1.02k
    typedef CONCATS(u, T) UnsignedT; \
2693
1.02k
\
2694
1.02k
    uint64_t Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2695
1.02k
    UnsignedT PrintVal = AArch64_AM_decodeLogicalImmediate(Val, 64); \
2696
1.02k
\
2697
1.02k
    if ((int16_t)PrintVal == (SignedT)PrintVal) \
2698
1.02k
      CONCAT(printImmSVE, T)((T)PrintVal, O); \
2699
1.02k
    else if ((uint16_t)PrintVal == PrintVal) \
2700
969
      CONCAT(printImmSVE, T)(PrintVal, O); \
2701
969
    else { \
2702
902
      SStream_concat(O, "%s", markup("<imm:")); \
2703
902
      printUInt64Bang(O, ((uint64_t)PrintVal)); \
2704
902
      SStream_concat0(O, markup(">")); \
2705
902
    } \
2706
1.02k
  }
printSVELogicalImm_int64_t
Line
Count
Source
2688
235
  { \
2689
235
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_SVELogicalImm, T), OpNum, \
2690
235
            sizeof(T)); \
2691
235
    typedef T SignedT; \
2692
235
    typedef CONCATS(u, T) UnsignedT; \
2693
235
\
2694
235
    uint64_t Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2695
235
    UnsignedT PrintVal = AArch64_AM_decodeLogicalImmediate(Val, 64); \
2696
235
\
2697
235
    if ((int16_t)PrintVal == (SignedT)PrintVal) \
2698
235
      CONCAT(printImmSVE, T)((T)PrintVal, O); \
2699
235
    else if ((uint16_t)PrintVal == PrintVal) \
2700
185
      CONCAT(printImmSVE, T)(PrintVal, O); \
2701
185
    else { \
2702
162
      SStream_concat(O, "%s", markup("<imm:")); \
2703
162
      printUInt64Bang(O, ((uint64_t)PrintVal)); \
2704
162
      SStream_concat0(O, markup(">")); \
2705
162
    } \
2706
235
  }
2707
DEFINE_printSVELogicalImm(int16_t);
2708
DEFINE_printSVELogicalImm(int32_t);
2709
DEFINE_printSVELogicalImm(int64_t);
2710
2711
#define DEFINE_printZPRasFPR(Width) \
2712
  void CONCAT(printZPRasFPR, Width)(MCInst * MI, unsigned OpNum, SStream *O) \
2713
493
  { \
2714
493
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2715
493
            Width); \
2716
493
    unsigned Base; \
2717
493
    switch (Width) { \
2718
63
    case 8: \
2719
63
      Base = AArch64_B0; \
2720
63
      break; \
2721
129
    case 16: \
2722
129
      Base = AArch64_H0; \
2723
129
      break; \
2724
168
    case 32: \
2725
168
      Base = AArch64_S0; \
2726
168
      break; \
2727
122
    case 64: \
2728
122
      Base = AArch64_D0; \
2729
122
      break; \
2730
11
    case 128: \
2731
11
      Base = AArch64_Q0; \
2732
11
      break; \
2733
0
    default: \
2734
0
      assert(0 && "Unsupported width"); \
2735
493
    } \
2736
493
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2737
493
    printRegName(O, Reg - AArch64_Z0 + Base); \
2738
493
  }
printZPRasFPR_8
Line
Count
Source
2713
63
  { \
2714
63
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2715
63
            Width); \
2716
63
    unsigned Base; \
2717
63
    switch (Width) { \
2718
63
    case 8: \
2719
63
      Base = AArch64_B0; \
2720
63
      break; \
2721
0
    case 16: \
2722
0
      Base = AArch64_H0; \
2723
0
      break; \
2724
0
    case 32: \
2725
0
      Base = AArch64_S0; \
2726
0
      break; \
2727
0
    case 64: \
2728
0
      Base = AArch64_D0; \
2729
0
      break; \
2730
0
    case 128: \
2731
0
      Base = AArch64_Q0; \
2732
0
      break; \
2733
0
    default: \
2734
0
      assert(0 && "Unsupported width"); \
2735
63
    } \
2736
63
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2737
63
    printRegName(O, Reg - AArch64_Z0 + Base); \
2738
63
  }
printZPRasFPR_64
Line
Count
Source
2713
122
  { \
2714
122
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2715
122
            Width); \
2716
122
    unsigned Base; \
2717
122
    switch (Width) { \
2718
0
    case 8: \
2719
0
      Base = AArch64_B0; \
2720
0
      break; \
2721
0
    case 16: \
2722
0
      Base = AArch64_H0; \
2723
0
      break; \
2724
0
    case 32: \
2725
0
      Base = AArch64_S0; \
2726
0
      break; \
2727
122
    case 64: \
2728
122
      Base = AArch64_D0; \
2729
122
      break; \
2730
0
    case 128: \
2731
0
      Base = AArch64_Q0; \
2732
0
      break; \
2733
0
    default: \
2734
0
      assert(0 && "Unsupported width"); \
2735
122
    } \
2736
122
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2737
122
    printRegName(O, Reg - AArch64_Z0 + Base); \
2738
122
  }
printZPRasFPR_16
Line
Count
Source
2713
129
  { \
2714
129
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2715
129
            Width); \
2716
129
    unsigned Base; \
2717
129
    switch (Width) { \
2718
0
    case 8: \
2719
0
      Base = AArch64_B0; \
2720
0
      break; \
2721
129
    case 16: \
2722
129
      Base = AArch64_H0; \
2723
129
      break; \
2724
0
    case 32: \
2725
0
      Base = AArch64_S0; \
2726
0
      break; \
2727
0
    case 64: \
2728
0
      Base = AArch64_D0; \
2729
0
      break; \
2730
0
    case 128: \
2731
0
      Base = AArch64_Q0; \
2732
0
      break; \
2733
0
    default: \
2734
0
      assert(0 && "Unsupported width"); \
2735
129
    } \
2736
129
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2737
129
    printRegName(O, Reg - AArch64_Z0 + Base); \
2738
129
  }
printZPRasFPR_32
Line
Count
Source
2713
168
  { \
2714
168
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2715
168
            Width); \
2716
168
    unsigned Base; \
2717
168
    switch (Width) { \
2718
0
    case 8: \
2719
0
      Base = AArch64_B0; \
2720
0
      break; \
2721
0
    case 16: \
2722
0
      Base = AArch64_H0; \
2723
0
      break; \
2724
168
    case 32: \
2725
168
      Base = AArch64_S0; \
2726
168
      break; \
2727
0
    case 64: \
2728
0
      Base = AArch64_D0; \
2729
0
      break; \
2730
0
    case 128: \
2731
0
      Base = AArch64_Q0; \
2732
0
      break; \
2733
0
    default: \
2734
0
      assert(0 && "Unsupported width"); \
2735
168
    } \
2736
168
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2737
168
    printRegName(O, Reg - AArch64_Z0 + Base); \
2738
168
  }
printZPRasFPR_128
Line
Count
Source
2713
11
  { \
2714
11
    add_cs_detail(MI, CONCAT(AArch64_OP_GROUP_ZPRasFPR, Width), OpNum, \
2715
11
            Width); \
2716
11
    unsigned Base; \
2717
11
    switch (Width) { \
2718
0
    case 8: \
2719
0
      Base = AArch64_B0; \
2720
0
      break; \
2721
0
    case 16: \
2722
0
      Base = AArch64_H0; \
2723
0
      break; \
2724
0
    case 32: \
2725
0
      Base = AArch64_S0; \
2726
0
      break; \
2727
0
    case 64: \
2728
0
      Base = AArch64_D0; \
2729
0
      break; \
2730
11
    case 128: \
2731
11
      Base = AArch64_Q0; \
2732
11
      break; \
2733
0
    default: \
2734
0
      assert(0 && "Unsupported width"); \
2735
11
    } \
2736
11
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum))); \
2737
11
    printRegName(O, Reg - AArch64_Z0 + Base); \
2738
11
  }
2739
DEFINE_printZPRasFPR(8);
2740
DEFINE_printZPRasFPR(64);
2741
DEFINE_printZPRasFPR(16);
2742
DEFINE_printZPRasFPR(32);
2743
DEFINE_printZPRasFPR(128);
2744
2745
#define DEFINE_printExactFPImm(ImmIs0, ImmIs1) \
2746
  void CONCAT(printExactFPImm, CONCAT(ImmIs0, ImmIs1))( \
2747
    MCInst * MI, unsigned OpNum, SStream *O) \
2748
728
  { \
2749
728
    add_cs_detail( \
2750
728
      MI, CONCAT(CONCAT(AArch64_OP_GROUP_ExactFPImm, ImmIs0), ImmIs1), \
2751
728
      OpNum, ImmIs0, ImmIs1); \
2752
728
    const AArch64ExactFPImm_ExactFPImm *Imm0Desc = AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs0); \
2753
728
    const AArch64ExactFPImm_ExactFPImm  *Imm1Desc = AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs1); \
2754
728
    unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2755
728
    SStream_concat(O, "%s%s%s", markup("<imm:"), "#", \
2756
728
             (Val ? Imm1Desc->Repr : Imm0Desc->Repr)); \
2757
728
    SStream_concat0(O, markup(">")); \
2758
728
  }
printExactFPImm_AArch64ExactFPImm_half_AArch64ExactFPImm_one
Line
Count
Source
2748
41
  { \
2749
41
    add_cs_detail( \
2750
41
      MI, CONCAT(CONCAT(AArch64_OP_GROUP_ExactFPImm, ImmIs0), ImmIs1), \
2751
41
      OpNum, ImmIs0, ImmIs1); \
2752
41
    const AArch64ExactFPImm_ExactFPImm *Imm0Desc = AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs0); \
2753
41
    const AArch64ExactFPImm_ExactFPImm  *Imm1Desc = AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs1); \
2754
41
    unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2755
41
    SStream_concat(O, "%s%s%s", markup("<imm:"), "#", \
2756
41
             (Val ? Imm1Desc->Repr : Imm0Desc->Repr)); \
2757
41
    SStream_concat0(O, markup(">")); \
2758
41
  }
printExactFPImm_AArch64ExactFPImm_zero_AArch64ExactFPImm_one
Line
Count
Source
2748
621
  { \
2749
621
    add_cs_detail( \
2750
621
      MI, CONCAT(CONCAT(AArch64_OP_GROUP_ExactFPImm, ImmIs0), ImmIs1), \
2751
621
      OpNum, ImmIs0, ImmIs1); \
2752
621
    const AArch64ExactFPImm_ExactFPImm *Imm0Desc = AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs0); \
2753
621
    const AArch64ExactFPImm_ExactFPImm  *Imm1Desc = AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs1); \
2754
621
    unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2755
621
    SStream_concat(O, "%s%s%s", markup("<imm:"), "#", \
2756
621
             (Val ? Imm1Desc->Repr : Imm0Desc->Repr)); \
2757
621
    SStream_concat0(O, markup(">")); \
2758
621
  }
printExactFPImm_AArch64ExactFPImm_half_AArch64ExactFPImm_two
Line
Count
Source
2748
66
  { \
2749
66
    add_cs_detail( \
2750
66
      MI, CONCAT(CONCAT(AArch64_OP_GROUP_ExactFPImm, ImmIs0), ImmIs1), \
2751
66
      OpNum, ImmIs0, ImmIs1); \
2752
66
    const AArch64ExactFPImm_ExactFPImm *Imm0Desc = AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs0); \
2753
66
    const AArch64ExactFPImm_ExactFPImm  *Imm1Desc = AArch64ExactFPImm_lookupExactFPImmByEnum(ImmIs1); \
2754
66
    unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, (OpNum))); \
2755
66
    SStream_concat(O, "%s%s%s", markup("<imm:"), "#", \
2756
66
             (Val ? Imm1Desc->Repr : Imm0Desc->Repr)); \
2757
66
    SStream_concat0(O, markup(">")); \
2758
66
  }
2759
DEFINE_printExactFPImm(AArch64ExactFPImm_half, AArch64ExactFPImm_one);
2760
DEFINE_printExactFPImm(AArch64ExactFPImm_zero, AArch64ExactFPImm_one);
2761
DEFINE_printExactFPImm(AArch64ExactFPImm_half, AArch64ExactFPImm_two);
2762
2763
void printGPR64as32(MCInst *MI, unsigned OpNum, SStream *O)
2764
4.40k
{
2765
4.40k
  add_cs_detail(MI, AArch64_OP_GROUP_GPR64as32, OpNum);
2766
4.40k
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum)));
2767
4.40k
  printRegName(O, getWRegFromXReg(Reg));
2768
4.40k
}
2769
2770
void printGPR64x8(MCInst *MI, unsigned OpNum, SStream *O)
2771
64
{
2772
64
  add_cs_detail(MI, AArch64_OP_GROUP_GPR64x8, OpNum);
2773
64
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum)));
2774
64
  printRegName(O, MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_x8sub_0));
2775
64
}
2776
2777
void printSyspXzrPair(MCInst *MI, unsigned OpNum, SStream *O)
2778
52
{
2779
52
  add_cs_detail(MI, AArch64_OP_GROUP_SyspXzrPair, OpNum);
2780
52
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, (OpNum)));
2781
2782
52
  SStream_concat(O, "%s%s", getRegisterName(Reg, AArch64_NoRegAltName), ", ");
2783
52
  SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));
2784
52
}
2785
2786
114k
const char *AArch64_LLVM_getRegisterName(unsigned RegNo, unsigned AltIdx) {
2787
114k
  return getRegisterName(RegNo, AltIdx);
2788
114k
}
2789
2790
204k
void AArch64_LLVM_printInstruction(MCInst *MI, SStream *O, void * /* MCRegisterInfo* */ info) {
2791
204k
  printInst(MI, MI->address, "", O);
2792
204k
}