Coverage Report

Created: 2026-10-17 07:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/capstonev5/arch/AArch64/AArch64InstPrinter.c
Line
Count
Source
1
//==-- AArch64InstPrinter.cpp - Convert AArch64 MCInst to assembly syntax --==//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// This class prints an AArch64 MCInst to a .s file.
11
//
12
//===----------------------------------------------------------------------===//
13
14
/* Capstone Disassembly Engine */
15
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2016 */
16
17
#ifdef CAPSTONE_HAS_ARM64
18
19
#include <capstone/platform.h>
20
#include <stdio.h>
21
#include <stdlib.h>
22
23
#include "AArch64InstPrinter.h"
24
#include "AArch64Disassembler.h"
25
#include "AArch64BaseInfo.h"
26
#include "../../utils.h"
27
#include "../../MCInst.h"
28
#include "../../SStream.h"
29
#include "../../MCRegisterInfo.h"
30
#include "../../MathExtras.h"
31
32
#include "AArch64Mapping.h"
33
#include "AArch64AddressingModes.h"
34
35
#define GET_REGINFO_ENUM
36
#include "AArch64GenRegisterInfo.inc"
37
38
#define GET_INSTRINFO_ENUM
39
#include "AArch64GenInstrInfo.inc"
40
41
#include "AArch64GenSubtargetInfo.inc"
42
43
44
static const char *getRegisterName(unsigned RegNo, unsigned AltIdx);
45
static void printOperand(MCInst *MI, unsigned OpNum, SStream *O);
46
static bool printSysAlias(MCInst *MI, SStream *O);
47
static char *printAliasInstr(MCInst *MI, SStream *OS, MCRegisterInfo *MRI);
48
static void printInstruction(MCInst *MI, SStream *O);
49
static void printShifter(MCInst *MI, unsigned OpNum, SStream *O);
50
static void printCustomAliasOperand(MCInst *MI, uint64_t Address, unsigned OpIdx,
51
    unsigned PrintMethodIdx, SStream *OS);
52
53
54
static cs_ac_type get_op_access(cs_struct *h, unsigned int id, unsigned int index)
55
1.29M
{
56
1.29M
#ifndef CAPSTONE_DIET
57
1.29M
  const uint8_t *arr = AArch64_get_op_access(h, id);
58
59
1.29M
  if (arr[index] == CS_AC_IGNORE)
60
0
    return 0;
61
62
1.29M
  return arr[index];
63
#else
64
  return 0;
65
#endif
66
1.29M
}
67
68
static void op_addImm(MCInst *MI, int v)
69
3.59k
{
70
3.59k
  if (MI->csh->detail) {
71
3.59k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
72
3.59k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = v;
73
3.59k
    MI->flat_insn->detail->arm64.op_count++;
74
3.59k
  }
75
3.59k
}
76
77
static void set_sme_index(MCInst *MI, bool status)
78
14.1k
{
79
  // Doing SME Index operand
80
14.1k
  MI->csh->doing_SME_Index = status;
81
82
14.1k
  if (MI->csh->detail != CS_OPT_ON)
83
0
    return;
84
85
14.1k
  if (status) {
86
9.74k
    unsigned prevOpNum = MI->flat_insn->detail->arm64.op_count - 1; 
87
9.74k
    unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, prevOpNum));
88
    // Replace previous SME register operand with an OP_SME_INDEX operand
89
9.74k
    MI->flat_insn->detail->arm64.operands[prevOpNum].type = ARM64_OP_SME_INDEX;
90
9.74k
    MI->flat_insn->detail->arm64.operands[prevOpNum].sme_index.reg = Reg;
91
9.74k
    MI->flat_insn->detail->arm64.operands[prevOpNum].sme_index.base = ARM64_REG_INVALID;
92
9.74k
    MI->flat_insn->detail->arm64.operands[prevOpNum].sme_index.disp = 0;
93
9.74k
  }
94
14.1k
}
95
96
static void set_mem_access(MCInst *MI, bool status)
97
440k
{
98
  // If status == false, check if this is meant for SME_index
99
440k
  if(!status && MI->csh->doing_SME_Index) {
100
5.30k
    MI->csh->doing_SME_Index = status;
101
5.30k
    return;
102
5.30k
  }
103
104
  // Doing Memory Operation
105
435k
  MI->csh->doing_mem = status;
106
107
108
435k
  if (MI->csh->detail != CS_OPT_ON)
109
0
    return;
110
111
435k
  if (status) {
112
217k
#ifndef CAPSTONE_DIET
113
217k
    uint8_t access;
114
217k
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
115
217k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
116
217k
    MI->ac_idx++;
117
217k
#endif
118
217k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_MEM;
119
217k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.base = ARM64_REG_INVALID;
120
217k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.index = ARM64_REG_INVALID;
121
217k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.disp = 0;
122
217k
  } else {
123
    // done, create the next operand slot
124
217k
    MI->flat_insn->detail->arm64.op_count++;
125
217k
  }
126
435k
}
127
128
void AArch64_printInst(MCInst *MI, SStream *O, void *Info)
129
443k
{
130
  // Check for special encodings and print the canonical alias instead.
131
443k
  unsigned Opcode = MCInst_getOpcode(MI);
132
443k
  int LSB, Width;
133
443k
  char *mnem;
134
135
  // printf(">>> opcode = %u\n", MCInst_getOpcode(MI));
136
137
443k
  if (Opcode == AArch64_SYSxt && printSysAlias(MI, O))
138
2.96k
    return;
139
140
  // SBFM/UBFM should print to a nicer aliased form if possible.
141
440k
  if (Opcode == AArch64_SBFMXri || Opcode == AArch64_SBFMWri ||
142
437k
      Opcode == AArch64_UBFMXri || Opcode == AArch64_UBFMWri) {
143
5.32k
    bool IsSigned = (Opcode == AArch64_SBFMXri || Opcode == AArch64_SBFMWri);
144
5.32k
    bool Is64Bit = (Opcode == AArch64_SBFMXri || Opcode == AArch64_UBFMXri);
145
146
5.32k
    MCOperand *Op0 = MCInst_getOperand(MI, 0);
147
5.32k
    MCOperand *Op1 = MCInst_getOperand(MI, 1);
148
5.32k
    MCOperand *Op2 = MCInst_getOperand(MI, 2);
149
5.32k
    MCOperand *Op3 = MCInst_getOperand(MI, 3);
150
151
5.32k
    if (MCOperand_isImm(Op2) && MCOperand_getImm(Op2) == 0 && MCOperand_isImm(Op3)) {
152
4.09k
      const char *AsmMnemonic = NULL;
153
154
4.09k
      switch (MCOperand_getImm(Op3)) {
155
769
        default:
156
769
          break;
157
158
1.33k
        case 7:
159
1.33k
          if (IsSigned)
160
707
            AsmMnemonic = "sxtb";
161
627
          else if (!Is64Bit)
162
431
            AsmMnemonic = "uxtb";
163
1.33k
          break;
164
165
1.51k
        case 15:
166
1.51k
          if (IsSigned)
167
1.04k
            AsmMnemonic = "sxth";
168
475
          else if (!Is64Bit)
169
129
            AsmMnemonic = "uxth";
170
1.51k
          break;
171
172
478
        case 31:
173
          // *xtw is only valid for signed 64-bit operations.
174
478
          if (Is64Bit && IsSigned)
175
331
            AsmMnemonic = "sxtw";
176
478
          break;
177
4.09k
      }
178
179
4.09k
      if (AsmMnemonic) {
180
2.63k
        SStream_concat(O, "%s\t%s, %s", AsmMnemonic,
181
2.63k
            getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
182
2.63k
            getRegisterName(getWRegFromXReg(MCOperand_getReg(Op1)), AArch64_NoRegAltName));
183
184
2.63k
        if (MI->csh->detail) {
185
2.63k
#ifndef CAPSTONE_DIET
186
2.63k
          uint8_t access;
187
2.63k
          access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
188
2.63k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
189
2.63k
          MI->ac_idx++;
190
2.63k
#endif
191
2.63k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
192
2.63k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
193
2.63k
          MI->flat_insn->detail->arm64.op_count++;
194
2.63k
#ifndef CAPSTONE_DIET
195
2.63k
          access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
196
2.63k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
197
2.63k
          MI->ac_idx++;
198
2.63k
#endif
199
2.63k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
200
2.63k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = getWRegFromXReg(MCOperand_getReg(Op1));
201
2.63k
          MI->flat_insn->detail->arm64.op_count++;
202
2.63k
        }
203
204
2.63k
        MCInst_setOpcodePub(MI, AArch64_map_insn(AsmMnemonic));
205
206
2.63k
        return;
207
2.63k
      }
208
4.09k
    }
209
210
    // All immediate shifts are aliases, implemented using the Bitfield
211
    // instruction. In all cases the immediate shift amount shift must be in
212
    // the range 0 to (reg.size -1).
213
2.68k
    if (MCOperand_isImm(Op2) && MCOperand_isImm(Op3)) {
214
2.68k
      const char *AsmMnemonic = NULL;
215
2.68k
      int shift = 0;
216
2.68k
      int immr = (int)MCOperand_getImm(Op2);
217
2.68k
      int imms = (int)MCOperand_getImm(Op3);
218
219
2.68k
      if (Opcode == AArch64_UBFMWri && imms != 0x1F && ((imms + 1) == immr)) {
220
90
        AsmMnemonic = "lsl";
221
90
        shift = 31 - imms;
222
2.59k
      } else if (Opcode == AArch64_UBFMXri && imms != 0x3f &&
223
843
          ((imms + 1 == immr))) {
224
194
        AsmMnemonic = "lsl";
225
194
        shift = 63 - imms;
226
2.40k
      } else if (Opcode == AArch64_UBFMWri && imms == 0x1f) {
227
57
        AsmMnemonic = "lsr";
228
57
        shift = immr;
229
2.34k
      } else if (Opcode == AArch64_UBFMXri && imms == 0x3f) {
230
259
        AsmMnemonic = "lsr";
231
259
        shift = immr;
232
2.08k
      } else if (Opcode == AArch64_SBFMWri && imms == 0x1f) {
233
85
        AsmMnemonic = "asr";
234
85
        shift = immr;
235
2.00k
      } else if (Opcode == AArch64_SBFMXri && imms == 0x3f) {
236
364
        AsmMnemonic = "asr";
237
364
        shift = immr;
238
364
      }
239
240
2.68k
      if (AsmMnemonic) {
241
1.04k
        SStream_concat(O, "%s\t%s, %s, ", AsmMnemonic,
242
1.04k
            getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
243
1.04k
            getRegisterName(MCOperand_getReg(Op1), AArch64_NoRegAltName));
244
245
1.04k
        printInt32Bang(O, shift);
246
247
1.04k
        MCInst_setOpcodePub(MI, AArch64_map_insn(AsmMnemonic));
248
249
1.04k
        if (MI->csh->detail) {
250
1.04k
#ifndef CAPSTONE_DIET
251
1.04k
          uint8_t access;
252
1.04k
          access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
253
1.04k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
254
1.04k
          MI->ac_idx++;
255
1.04k
#endif
256
1.04k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
257
1.04k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
258
1.04k
          MI->flat_insn->detail->arm64.op_count++;
259
1.04k
#ifndef CAPSTONE_DIET
260
1.04k
          access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
261
1.04k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
262
1.04k
          MI->ac_idx++;
263
1.04k
#endif
264
1.04k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
265
1.04k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op1);
266
1.04k
          MI->flat_insn->detail->arm64.op_count++;
267
1.04k
#ifndef CAPSTONE_DIET
268
1.04k
          access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
269
1.04k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
270
1.04k
          MI->ac_idx++;
271
1.04k
#endif
272
1.04k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
273
1.04k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = shift;
274
1.04k
          MI->flat_insn->detail->arm64.op_count++;
275
1.04k
        }
276
277
1.04k
        return;
278
1.04k
      }
279
2.68k
    }
280
281
    // SBFIZ/UBFIZ aliases
282
1.63k
    if (MCOperand_getImm(Op2) > MCOperand_getImm(Op3)) {
283
570
      SStream_concat(O, "%s\t%s, %s, ", (IsSigned ? "sbfiz" : "ubfiz"),
284
570
          getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
285
570
          getRegisterName(MCOperand_getReg(Op1), AArch64_NoRegAltName));
286
287
570
      printInt32Bang(O, (int)((Is64Bit ? 64 : 32) - MCOperand_getImm(Op2)));
288
289
570
      SStream_concat0(O, ", ");
290
291
570
      printInt32Bang(O, (int)MCOperand_getImm(Op3) + 1);
292
293
570
      MCInst_setOpcodePub(MI, AArch64_map_insn(IsSigned ? "sbfiz" : "ubfiz"));
294
295
570
      if (MI->csh->detail) {
296
570
#ifndef CAPSTONE_DIET
297
570
        uint8_t access;
298
570
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
299
570
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
300
570
        MI->ac_idx++;
301
570
#endif
302
570
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
303
570
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
304
570
        MI->flat_insn->detail->arm64.op_count++;
305
570
#ifndef CAPSTONE_DIET
306
570
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
307
570
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
308
570
        MI->ac_idx++;
309
570
#endif
310
570
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
311
570
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op1);
312
570
        MI->flat_insn->detail->arm64.op_count++;
313
570
#ifndef CAPSTONE_DIET
314
570
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
315
570
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
316
570
        MI->ac_idx++;
317
570
#endif
318
570
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
319
570
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (Is64Bit ? 64 : 32) - (int)MCOperand_getImm(Op2);
320
570
        MI->flat_insn->detail->arm64.op_count++;
321
570
#ifndef CAPSTONE_DIET
322
570
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
323
570
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
324
570
        MI->ac_idx++;
325
570
#endif
326
570
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
327
570
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op3) + 1;
328
570
        MI->flat_insn->detail->arm64.op_count++;
329
570
      }
330
331
570
      return;
332
570
    }
333
334
    // Otherwise SBFX/UBFX is the preferred form
335
1.06k
    SStream_concat(O, "%s\t%s, %s, ", (IsSigned ? "sbfx" : "ubfx"),
336
1.06k
        getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
337
1.06k
        getRegisterName(MCOperand_getReg(Op1), AArch64_NoRegAltName));
338
339
1.06k
    printInt32Bang(O, (int)MCOperand_getImm(Op2));
340
1.06k
    SStream_concat0(O, ", ");
341
1.06k
    printInt32Bang(O, (int)MCOperand_getImm(Op3) - (int)MCOperand_getImm(Op2) + 1);
342
343
1.06k
    MCInst_setOpcodePub(MI, AArch64_map_insn(IsSigned ? "sbfx" : "ubfx"));
344
345
1.06k
    if (MI->csh->detail) {
346
1.06k
#ifndef CAPSTONE_DIET
347
1.06k
      uint8_t access;
348
1.06k
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
349
1.06k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
350
1.06k
      MI->ac_idx++;
351
1.06k
#endif
352
1.06k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
353
1.06k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
354
1.06k
      MI->flat_insn->detail->arm64.op_count++;
355
1.06k
#ifndef CAPSTONE_DIET
356
1.06k
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
357
1.06k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
358
1.06k
      MI->ac_idx++;
359
1.06k
#endif
360
1.06k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
361
1.06k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op1);
362
1.06k
      MI->flat_insn->detail->arm64.op_count++;
363
1.06k
#ifndef CAPSTONE_DIET
364
1.06k
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
365
1.06k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
366
1.06k
      MI->ac_idx++;
367
1.06k
#endif
368
1.06k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
369
1.06k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op2);
370
1.06k
      MI->flat_insn->detail->arm64.op_count++;
371
1.06k
#ifndef CAPSTONE_DIET
372
1.06k
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
373
1.06k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
374
1.06k
      MI->ac_idx++;
375
1.06k
#endif
376
1.06k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
377
1.06k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op3) - MCOperand_getImm(Op2) + 1;
378
1.06k
      MI->flat_insn->detail->arm64.op_count++;
379
1.06k
    }
380
381
1.06k
    return;
382
1.63k
  }
383
384
435k
  if (Opcode == AArch64_BFMXri || Opcode == AArch64_BFMWri) {
385
1.49k
    MCOperand *Op0 = MCInst_getOperand(MI, 0); // Op1 == Op0
386
1.49k
    MCOperand *Op2 = MCInst_getOperand(MI, 2);
387
1.49k
    int ImmR = (int)MCOperand_getImm(MCInst_getOperand(MI, 3));
388
1.49k
    int ImmS = (int)MCOperand_getImm(MCInst_getOperand(MI, 4));
389
390
1.49k
    if ((MCOperand_getReg(Op2) == AArch64_WZR || MCOperand_getReg(Op2) == AArch64_XZR) &&
391
881
        (ImmR == 0 || ImmS < ImmR)) {
392
      // BFC takes precedence over its entire range, sligtly differently to BFI.
393
654
      int BitWidth = Opcode == AArch64_BFMXri ? 64 : 32;
394
654
      int LSB = (BitWidth - ImmR) % BitWidth;
395
654
      int Width = ImmS + 1;
396
397
654
      SStream_concat(O, "bfc\t%s, ",
398
654
          getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName));
399
400
654
      printInt32Bang(O, LSB);
401
654
      SStream_concat0(O, ", ");
402
654
      printInt32Bang(O, Width);
403
654
      MCInst_setOpcodePub(MI, AArch64_map_insn("bfc"));
404
405
654
      if (MI->csh->detail) {
406
654
#ifndef CAPSTONE_DIET
407
654
        uint8_t access;
408
654
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
409
654
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
410
654
        MI->ac_idx++;
411
654
#endif
412
654
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
413
654
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
414
654
        MI->flat_insn->detail->arm64.op_count++;
415
416
654
#ifndef CAPSTONE_DIET
417
654
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
418
654
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
419
654
        MI->ac_idx++;
420
654
#endif
421
654
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
422
654
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = LSB;
423
654
        MI->flat_insn->detail->arm64.op_count++;
424
654
#ifndef CAPSTONE_DIET
425
654
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
426
654
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
427
654
        MI->ac_idx++;
428
654
#endif
429
654
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
430
654
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Width;
431
654
        MI->flat_insn->detail->arm64.op_count++;
432
654
      }
433
434
654
      return;
435
836
    } else if (ImmS < ImmR) {
436
      // BFI alias
437
287
      int BitWidth = Opcode == AArch64_BFMXri ? 64 : 32;
438
287
      LSB = (BitWidth - ImmR) % BitWidth;
439
287
      Width = ImmS + 1;
440
441
287
      SStream_concat(O, "bfi\t%s, %s, ",
442
287
          getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
443
287
          getRegisterName(MCOperand_getReg(Op2), AArch64_NoRegAltName));
444
445
287
      printInt32Bang(O, LSB);
446
287
      SStream_concat0(O, ", ");
447
287
      printInt32Bang(O, Width);
448
449
287
      MCInst_setOpcodePub(MI, AArch64_map_insn("bfi"));
450
451
287
      if (MI->csh->detail) {
452
287
#ifndef CAPSTONE_DIET
453
287
        uint8_t access;
454
287
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
455
287
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
456
287
        MI->ac_idx++;
457
287
#endif
458
287
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
459
287
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
460
287
        MI->flat_insn->detail->arm64.op_count++;
461
287
#ifndef CAPSTONE_DIET
462
287
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
463
287
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
464
287
        MI->ac_idx++;
465
287
#endif
466
287
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
467
287
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op2);
468
287
        MI->flat_insn->detail->arm64.op_count++;
469
287
#ifndef CAPSTONE_DIET
470
287
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
471
287
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
472
287
        MI->ac_idx++;
473
287
#endif
474
287
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
475
287
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = LSB;
476
287
        MI->flat_insn->detail->arm64.op_count++;
477
287
#ifndef CAPSTONE_DIET
478
287
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
479
287
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
480
287
        MI->ac_idx++;
481
287
#endif
482
287
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
483
287
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Width;
484
287
        MI->flat_insn->detail->arm64.op_count++;
485
287
      }
486
487
287
      return;
488
287
    }
489
490
549
    LSB = ImmR;
491
549
    Width = ImmS - ImmR + 1;
492
    // Otherwise BFXIL the preferred form
493
549
    SStream_concat(O, "bfxil\t%s, %s, ",
494
549
        getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
495
549
        getRegisterName(MCOperand_getReg(Op2), AArch64_NoRegAltName));
496
497
549
    printInt32Bang(O, LSB);
498
549
    SStream_concat0(O, ", ");
499
549
    printInt32Bang(O, Width);
500
501
549
    MCInst_setOpcodePub(MI, AArch64_map_insn("bfxil"));
502
503
549
    if (MI->csh->detail) {
504
549
#ifndef CAPSTONE_DIET
505
549
      uint8_t access;
506
549
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
507
549
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
508
549
      MI->ac_idx++;
509
549
#endif
510
549
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
511
549
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
512
549
      MI->flat_insn->detail->arm64.op_count++;
513
549
#ifndef CAPSTONE_DIET
514
549
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
515
549
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
516
549
      MI->ac_idx++;
517
549
#endif
518
549
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
519
549
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op2);
520
549
      MI->flat_insn->detail->arm64.op_count++;
521
549
#ifndef CAPSTONE_DIET
522
549
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
523
549
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
524
549
      MI->ac_idx++;
525
549
#endif
526
549
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
527
549
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = LSB;
528
549
      MI->flat_insn->detail->arm64.op_count++;
529
549
#ifndef CAPSTONE_DIET
530
549
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
531
549
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
532
549
      MI->ac_idx++;
533
549
#endif
534
549
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
535
549
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Width;
536
549
      MI->flat_insn->detail->arm64.op_count++;
537
549
    }
538
539
549
    return;
540
1.49k
  }
541
542
  // MOVZ, MOVN and "ORR wzr, #imm" instructions are aliases for MOV, but their
543
  // domains overlap so they need to be prioritized. The chain is "MOVZ lsl #0 >
544
  // MOVZ lsl #N > MOVN lsl #0 > MOVN lsl #N > ORR". The highest instruction
545
  // that can represent the move is the MOV alias, and the rest get printed
546
  // normally.
547
433k
  if ((Opcode == AArch64_MOVZXi || Opcode == AArch64_MOVZWi) &&
548
1.52k
      MCOperand_isImm(MCInst_getOperand(MI, 1)) && MCOperand_isImm(MCInst_getOperand(MI, 2))) {
549
1.52k
    int RegWidth = Opcode == AArch64_MOVZXi ? 64 : 32;
550
1.52k
    int Shift = MCOperand_getImm(MCInst_getOperand(MI, 2));
551
1.52k
    uint64_t Value = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, 1)) << Shift;
552
553
1.52k
    if (isMOVZMovAlias(Value, Shift,
554
1.52k
          Opcode == AArch64_MOVZXi ? 64 : 32)) {
555
1.24k
      SStream_concat(O, "mov\t%s, ", getRegisterName(MCOperand_getReg(MCInst_getOperand(MI, 0)), AArch64_NoRegAltName));
556
557
1.24k
      printInt64Bang(O, SignExtend64(Value, RegWidth));
558
559
1.24k
      if (MI->csh->detail) {
560
1.24k
#ifndef CAPSTONE_DIET
561
1.24k
        uint8_t access;
562
1.24k
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
563
1.24k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
564
1.24k
        MI->ac_idx++;
565
1.24k
#endif
566
1.24k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
567
1.24k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 0));
568
1.24k
        MI->flat_insn->detail->arm64.op_count++;
569
570
1.24k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
571
1.24k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = SignExtend64(Value, RegWidth);
572
1.24k
        MI->flat_insn->detail->arm64.op_count++;
573
1.24k
      }
574
575
1.24k
      MCInst_setOpcodePub(MI, AArch64_map_insn("mov"));
576
577
1.24k
      return;
578
1.24k
    }
579
1.52k
  }
580
581
432k
  if ((Opcode == AArch64_MOVNXi || Opcode == AArch64_MOVNWi) &&
582
915
      MCOperand_isImm(MCInst_getOperand(MI, 1)) && MCOperand_isImm(MCInst_getOperand(MI, 2))) {
583
915
    int RegWidth = Opcode == AArch64_MOVNXi ? 64 : 32;
584
915
    int Shift = MCOperand_getImm(MCInst_getOperand(MI, 2));
585
915
    uint64_t Value = ~((uint64_t)MCOperand_getImm(MCInst_getOperand(MI, 1)) << Shift);
586
587
915
    if (RegWidth == 32)
588
329
      Value = Value & 0xffffffff;
589
590
915
    if (AArch64_AM_isMOVNMovAlias(Value, Shift, RegWidth)) {
591
654
      SStream_concat(O, "mov\t%s, ", getRegisterName(MCOperand_getReg(MCInst_getOperand(MI, 0)), AArch64_NoRegAltName));
592
593
654
      printInt64Bang(O, SignExtend64(Value, RegWidth));
594
595
654
      if (MI->csh->detail) {
596
654
#ifndef CAPSTONE_DIET
597
654
        uint8_t access;
598
654
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
599
654
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
600
654
        MI->ac_idx++;
601
654
#endif
602
654
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
603
654
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 0));
604
654
        MI->flat_insn->detail->arm64.op_count++;
605
606
654
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
607
654
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = SignExtend64(Value, RegWidth);
608
654
        MI->flat_insn->detail->arm64.op_count++;
609
654
      }
610
611
654
      MCInst_setOpcodePub(MI, AArch64_map_insn("mov"));
612
613
654
      return;
614
654
    }
615
915
  }
616
617
431k
  if ((Opcode == AArch64_ORRXri || Opcode == AArch64_ORRWri) &&
618
2.66k
      (MCOperand_getReg(MCInst_getOperand(MI, 1)) == AArch64_XZR ||
619
2.38k
       MCOperand_getReg(MCInst_getOperand(MI, 1)) == AArch64_WZR) &&
620
1.11k
      MCOperand_isImm(MCInst_getOperand(MI, 2))) {
621
1.11k
    int RegWidth = Opcode == AArch64_ORRXri ? 64 : 32;
622
1.11k
    uint64_t Value = AArch64_AM_decodeLogicalImmediate(
623
1.11k
        MCOperand_getImm(MCInst_getOperand(MI, 2)), RegWidth);
624
1.11k
    SStream_concat(O, "mov\t%s, ", getRegisterName(MCOperand_getReg(MCInst_getOperand(MI, 0)), AArch64_NoRegAltName));
625
626
1.11k
    printInt64Bang(O, SignExtend64(Value, RegWidth));
627
628
1.11k
    if (MI->csh->detail) {
629
1.11k
#ifndef CAPSTONE_DIET
630
1.11k
      uint8_t access;
631
1.11k
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
632
1.11k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
633
1.11k
      MI->ac_idx++;
634
1.11k
#endif
635
1.11k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
636
1.11k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 0));
637
1.11k
      MI->flat_insn->detail->arm64.op_count++;
638
639
1.11k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
640
1.11k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = SignExtend64(Value, RegWidth);
641
1.11k
      MI->flat_insn->detail->arm64.op_count++;
642
1.11k
    }
643
644
1.11k
    MCInst_setOpcodePub(MI, AArch64_map_insn("mov"));
645
646
1.11k
    return;
647
1.11k
  }
648
649
  // Instruction TSB is specified as a one operand instruction, but 'csync' is
650
  // not encoded, so for printing it is treated as a special case here:
651
430k
  if (Opcode == AArch64_TSB) {
652
370
    SStream_concat0(O, "tsb\tcsync");
653
370
    MCInst_setOpcodePub(MI, AArch64_map_insn("tsb"));
654
370
    return;
655
370
  }
656
657
430k
  MI->MRI = Info;
658
659
430k
  mnem = printAliasInstr(MI, O, (MCRegisterInfo *)Info);
660
430k
  if (mnem) {
661
60.5k
    MCInst_setOpcodePub(MI, AArch64_map_insn(mnem));
662
60.5k
    cs_mem_free(mnem);
663
664
60.5k
    switch(MCInst_getOpcode(MI)) {
665
32.9k
      default: break;
666
32.9k
      case AArch64_LD1i8_POST:
667
638
        arm64_op_addImm(MI, 1);
668
638
        break;
669
388
      case AArch64_LD1i16_POST:
670
388
        arm64_op_addImm(MI, 2);
671
388
        break;
672
506
      case AArch64_LD1i32_POST:
673
506
        arm64_op_addImm(MI, 4);
674
506
        break;
675
81
      case AArch64_LD1Onev1d_POST:
676
195
      case AArch64_LD1Onev2s_POST:
677
207
      case AArch64_LD1Onev4h_POST:
678
516
      case AArch64_LD1Onev8b_POST:
679
1.36k
      case AArch64_LD1i64_POST:
680
1.36k
        arm64_op_addImm(MI, 8);
681
1.36k
        break;
682
395
      case AArch64_LD1Onev16b_POST:
683
865
      case AArch64_LD1Onev2d_POST:
684
978
      case AArch64_LD1Onev4s_POST:
685
1.55k
      case AArch64_LD1Onev8h_POST:
686
1.70k
      case AArch64_LD1Twov1d_POST:
687
1.90k
      case AArch64_LD1Twov2s_POST:
688
2.02k
      case AArch64_LD1Twov4h_POST:
689
2.55k
      case AArch64_LD1Twov8b_POST:
690
2.55k
        arm64_op_addImm(MI, 16);
691
2.55k
        break;
692
2.04k
      case AArch64_LD1Threev1d_POST:
693
2.50k
      case AArch64_LD1Threev2s_POST:
694
2.57k
      case AArch64_LD1Threev4h_POST:
695
2.77k
      case AArch64_LD1Threev8b_POST:
696
2.77k
        arm64_op_addImm(MI, 24);
697
2.77k
        break;
698
212
      case AArch64_LD1Fourv1d_POST:
699
454
      case AArch64_LD1Fourv2s_POST:
700
584
      case AArch64_LD1Fourv4h_POST:
701
1.19k
      case AArch64_LD1Fourv8b_POST:
702
1.47k
      case AArch64_LD1Twov16b_POST:
703
1.64k
      case AArch64_LD1Twov2d_POST:
704
1.90k
      case AArch64_LD1Twov4s_POST:
705
2.61k
      case AArch64_LD1Twov8h_POST:
706
2.61k
        arm64_op_addImm(MI, 32);
707
2.61k
        break;
708
449
      case AArch64_LD1Threev16b_POST:
709
537
      case AArch64_LD1Threev2d_POST:
710
1.28k
      case AArch64_LD1Threev4s_POST:
711
1.30k
      case AArch64_LD1Threev8h_POST:
712
1.30k
         arm64_op_addImm(MI, 48);
713
1.30k
         break;
714
74
      case AArch64_LD1Fourv16b_POST:
715
203
      case AArch64_LD1Fourv2d_POST:
716
979
      case AArch64_LD1Fourv4s_POST:
717
1.78k
      case AArch64_LD1Fourv8h_POST:
718
1.78k
        arm64_op_addImm(MI, 64);
719
1.78k
        break;
720
66
      case AArch64_UMOVvi64:
721
66
        arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_1D);
722
66
        break;
723
197
      case AArch64_UMOVvi32:
724
197
        arm64_op_addVectorArrSpecifier(MI, ARM64_VAS_1S);
725
197
        break;
726
71
      case AArch64_INSvi8gpr:
727
325
      case AArch64_DUP_ZI_B:
728
713
      case AArch64_CPY_ZPmI_B:
729
830
      case AArch64_CPY_ZPzI_B:
730
907
      case AArch64_CPY_ZPmV_B:
731
1.11k
      case AArch64_CPY_ZPmR_B:
732
1.25k
      case AArch64_DUP_ZR_B:
733
1.25k
        if (MI->csh->detail) {
734
1.25k
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1B;
735
1.25k
        }
736
1.25k
        break;
737
35
      case AArch64_INSvi16gpr:
738
104
      case AArch64_DUP_ZI_H:
739
257
      case AArch64_CPY_ZPmI_H:
740
1.06k
      case AArch64_CPY_ZPzI_H:
741
1.45k
      case AArch64_CPY_ZPmV_H:
742
1.89k
      case AArch64_CPY_ZPmR_H:
743
2.01k
      case AArch64_DUP_ZR_H:
744
2.21k
      case AArch64_FCPY_ZPmI_H:
745
2.44k
      case AArch64_FDUP_ZI_H:
746
2.44k
        if (MI->csh->detail) {
747
2.44k
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1H;
748
2.44k
        }
749
2.44k
        break;
750
70
      case AArch64_INSvi32gpr:
751
138
      case AArch64_DUP_ZI_S:
752
336
      case AArch64_CPY_ZPmI_S:
753
418
      case AArch64_CPY_ZPzI_S:
754
1.25k
      case AArch64_CPY_ZPmV_S:
755
1.45k
      case AArch64_CPY_ZPmR_S:
756
1.86k
      case AArch64_DUP_ZR_S:
757
1.93k
      case AArch64_FCPY_ZPmI_S:
758
1.99k
      case AArch64_FDUP_ZI_S:
759
1.99k
        if (MI->csh->detail) {
760
1.99k
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1S;
761
1.99k
        }
762
1.99k
        break;
763
344
      case AArch64_INSvi64gpr:
764
379
      case AArch64_DUP_ZI_D:
765
511
      case AArch64_CPY_ZPmI_D:
766
815
      case AArch64_CPY_ZPzI_D:
767
916
      case AArch64_CPY_ZPmV_D:
768
1.07k
      case AArch64_CPY_ZPmR_D:
769
3.07k
      case AArch64_DUP_ZR_D:
770
3.11k
      case AArch64_FCPY_ZPmI_D:
771
3.22k
      case AArch64_FDUP_ZI_D:
772
3.22k
        if (MI->csh->detail) {
773
3.22k
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1D;
774
3.22k
        }
775
3.22k
        break;
776
267
      case AArch64_INSvi8lane:
777
406
      case AArch64_ORR_PPzPP:
778
554
      case AArch64_ORRS_PPzPP:
779
554
        if (MI->csh->detail) {
780
554
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1B;
781
554
          MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1B;
782
554
        }
783
554
        break;
784
393
      case AArch64_INSvi16lane:
785
393
        if (MI->csh->detail) {
786
393
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1H;
787
393
          MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1H;
788
393
        }
789
393
         break;
790
73
      case AArch64_INSvi32lane:
791
73
        if (MI->csh->detail) {
792
73
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1S;
793
73
          MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1S;
794
73
        }
795
73
        break;
796
99
      case AArch64_INSvi64lane:
797
133
      case AArch64_ORR_ZZZ:
798
133
        if (MI->csh->detail) {
799
133
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1D;
800
133
          MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1D;
801
133
        }
802
133
        break;
803
203
      case AArch64_ORRv16i8:
804
297
      case AArch64_NOTv16i8:
805
297
        if (MI->csh->detail) {
806
297
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_16B;
807
297
          MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_16B;
808
297
        }
809
297
        break;
810
196
      case AArch64_ORRv8i8:
811
394
      case AArch64_NOTv8i8:
812
394
        if (MI->csh->detail) {
813
394
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_8B;
814
394
          MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_8B;
815
394
        }
816
394
        break;
817
125
      case AArch64_AND_PPzPP:
818
198
      case AArch64_ANDS_PPzPP:
819
484
      case AArch64_EOR_PPzPP:
820
710
      case AArch64_EORS_PPzPP:
821
879
      case AArch64_SEL_PPPP:
822
1.06k
      case AArch64_SEL_ZPZZ_B:
823
1.06k
        if (MI->csh->detail) {
824
1.06k
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1B;
825
1.06k
          MI->flat_insn->detail->arm64.operands[2].vas = ARM64_VAS_1B;
826
1.06k
        }
827
1.06k
        break;
828
241
      case AArch64_SEL_ZPZZ_D:
829
241
        if (MI->csh->detail) {
830
241
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1D;
831
241
          MI->flat_insn->detail->arm64.operands[2].vas = ARM64_VAS_1D;
832
241
        }
833
241
        break;
834
288
      case AArch64_SEL_ZPZZ_H:
835
288
        if (MI->csh->detail) {
836
288
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1H;
837
288
          MI->flat_insn->detail->arm64.operands[2].vas = ARM64_VAS_1H;
838
288
        }
839
288
        break;
840
77
      case AArch64_SEL_ZPZZ_S:
841
77
        if (MI->csh->detail) {
842
77
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1S;
843
77
          MI->flat_insn->detail->arm64.operands[2].vas = ARM64_VAS_1S;
844
77
        }
845
77
        break;
846
68
      case AArch64_DUP_ZZI_B:
847
68
        if (MI->csh->detail) {
848
68
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1B;
849
68
          if (MI->flat_insn->detail->arm64.op_count == 1) {
850
0
            arm64_op_addReg(MI, ARM64_REG_B0 + MCOperand_getReg(MCInst_getOperand(MI, 1)) - ARM64_REG_Z0);
851
68
          } else {
852
68
            MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1B;
853
68
          }
854
68
        }
855
68
        break;
856
171
      case AArch64_DUP_ZZI_D:
857
171
        if (MI->csh->detail) {
858
171
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1D;
859
171
          if (MI->flat_insn->detail->arm64.op_count == 1) {
860
0
            arm64_op_addReg(MI, ARM64_REG_D0 + MCOperand_getReg(MCInst_getOperand(MI, 1)) - ARM64_REG_Z0);
861
171
          } else {
862
171
            MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1D;
863
171
          }
864
171
        }
865
171
        break;
866
80
      case AArch64_DUP_ZZI_H:
867
80
        if (MI->csh->detail) {
868
80
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1H;
869
80
          if (MI->flat_insn->detail->arm64.op_count == 1) {
870
0
            arm64_op_addReg(MI, ARM64_REG_H0 + MCOperand_getReg(MCInst_getOperand(MI, 1)) - ARM64_REG_Z0);
871
80
          } else {
872
80
            MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1H;
873
80
          }
874
80
        }
875
80
        break;
876
235
      case AArch64_DUP_ZZI_Q:
877
235
        if (MI->csh->detail) {
878
235
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1Q;
879
235
          if (MI->flat_insn->detail->arm64.op_count == 1) {
880
0
            arm64_op_addReg(MI, ARM64_REG_Q0 + MCOperand_getReg(MCInst_getOperand(MI, 1)) - ARM64_REG_Z0);
881
235
          } else {
882
235
            MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1Q;
883
235
          }
884
235
         }
885
235
         break;
886
108
      case AArch64_DUP_ZZI_S:
887
108
        if (MI->csh->detail) {
888
108
          MI->flat_insn->detail->arm64.operands[0].vas = ARM64_VAS_1S;
889
108
          if (MI->flat_insn->detail->arm64.op_count == 1) {
890
0
            arm64_op_addReg(MI, ARM64_REG_S0 + MCOperand_getReg(MCInst_getOperand(MI, 1)) - ARM64_REG_Z0);
891
108
          } else {
892
108
             MI->flat_insn->detail->arm64.operands[1].vas = ARM64_VAS_1S;
893
108
          }
894
108
        }
895
108
        break;
896
      // Hacky detail filling of SMSTART and SMSTOP alias'
897
261
      case AArch64_MSRpstatesvcrImm1:{
898
261
        if(MI->csh->detail){
899
261
          MI->flat_insn->detail->arm64.op_count = 2;
900
261
#ifndef CAPSTONE_DIET
901
261
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
902
261
          MI->ac_idx++;
903
261
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
904
261
          MI->ac_idx++;
905
261
#endif
906
261
          MI->flat_insn->detail->arm64.operands[0].type = ARM64_OP_SVCR;
907
261
          MI->flat_insn->detail->arm64.operands[0].sys = (unsigned)ARM64_SYSREG_SVCR;
908
261
          MI->flat_insn->detail->arm64.operands[0].svcr = lookupSVCRByEncoding(MCOperand_getImm(MCInst_getOperand(MI, 0)))->Encoding;
909
261
          MI->flat_insn->detail->arm64.operands[1].type = ARM64_OP_IMM;
910
261
          MI->flat_insn->detail->arm64.operands[1].imm = MCOperand_getImm(MCInst_getOperand(MI, 1));
911
261
        }
912
261
        break;
913
879
      }
914
60.5k
    }
915
369k
  } else {
916
369k
    printInstruction(MI, O);
917
369k
  }
918
430k
}
919
920
static bool printSysAlias(MCInst *MI, SStream *O)
921
6.55k
{
922
  // unsigned Opcode = MCInst_getOpcode(MI);
923
  //assert(Opcode == AArch64_SYSxt && "Invalid opcode for SYS alias!");
924
925
6.55k
  const char *Ins;
926
6.55k
  uint16_t Encoding;
927
6.55k
  bool NeedsReg;
928
6.55k
  char Name[64];
929
6.55k
  MCOperand *Op1 = MCInst_getOperand(MI, 0);
930
6.55k
  MCOperand *Cn = MCInst_getOperand(MI, 1);
931
6.55k
  MCOperand *Cm = MCInst_getOperand(MI, 2);
932
6.55k
  MCOperand *Op2 = MCInst_getOperand(MI, 3);
933
934
6.55k
  unsigned Op1Val = (unsigned)MCOperand_getImm(Op1);
935
6.55k
  unsigned CnVal = (unsigned)MCOperand_getImm(Cn);
936
6.55k
  unsigned CmVal = (unsigned)MCOperand_getImm(Cm);
937
6.55k
  unsigned Op2Val = (unsigned)MCOperand_getImm(Op2);
938
939
6.55k
  Encoding = Op2Val;
940
6.55k
  Encoding |= CmVal << 3;
941
6.55k
  Encoding |= CnVal << 7;
942
6.55k
  Encoding |= Op1Val << 11;
943
944
6.55k
  if (CnVal == 7) {
945
5.27k
    switch (CmVal) {
946
246
      default:
947
246
        return false;
948
949
      // IC aliases
950
1.26k
      case 1: case 5: {
951
1.26k
        const IC *IC = lookupICByEncoding(Encoding);
952
        // if (!IC || !IC->haveFeatures(STI.getFeatureBits()))
953
1.26k
        if (!IC)
954
377
          return false;
955
956
889
        NeedsReg = IC->NeedsReg;
957
889
        Ins = "ic";
958
889
        strncpy(Name, IC->Name, sizeof(Name) - 1);
959
889
      }
960
0
      break;
961
962
      // DC aliases
963
2.42k
      case 4: case 6: case 10: case 11: case 12: case 14: {
964
2.42k
        const DC *DC = lookupDCByEncoding(Encoding);
965
        // if (!DC || !DC->haveFeatures(STI.getFeatureBits()))
966
2.42k
        if (!DC)
967
1.82k
          return false;
968
969
607
        NeedsReg = true;
970
607
        Ins = "dc";
971
607
        strncpy(Name, DC->Name, sizeof(Name) - 1);
972
607
      }
973
0
      break;
974
975
      // AT aliases
976
1.33k
      case 8: case 9: {
977
1.33k
        const AT *AT = lookupATByEncoding(Encoding);
978
        // if (!AT || !AT->haveFeatures(STI.getFeatureBits()))
979
1.33k
        if (!AT)
980
344
          return false;
981
982
987
        NeedsReg = true;
983
987
        Ins = "at";
984
987
        strncpy(Name, AT->Name, sizeof(Name) - 1);
985
987
      }
986
0
      break;
987
5.27k
    }
988
5.27k
  } else if (CnVal == 8) {
989
    // TLBI aliases
990
876
    const TLBI *TLBI = lookupTLBIByEncoding(Encoding);
991
    // if (!TLBI || !TLBI->haveFeatures(STI.getFeatureBits()))
992
876
    if (!TLBI)
993
399
      return false;
994
995
477
    NeedsReg = TLBI->NeedsReg;
996
477
    Ins = "tlbi";
997
477
    strncpy(Name, TLBI->Name, sizeof(Name) - 1);
998
477
  } else
999
413
    return false;
1000
1001
2.96k
  SStream_concat(O, "%s\t%s", Ins, Name);
1002
1003
2.96k
  if (NeedsReg) {
1004
1.86k
    SStream_concat(O, ", %s", getRegisterName(MCOperand_getReg(MCInst_getOperand(MI, 4)), AArch64_NoRegAltName));
1005
1.86k
  }
1006
1007
2.96k
  MCInst_setOpcodePub(MI, AArch64_map_insn(Ins));
1008
1009
2.96k
  if (MI->csh->detail) {
1010
#if 0
1011
#ifndef CAPSTONE_DIET
1012
    uint8_t access;
1013
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1014
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1015
    MI->ac_idx++;
1016
#endif
1017
#endif
1018
2.96k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SYS;
1019
2.96k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = AArch64_map_sys_op(Name);
1020
2.96k
    MI->flat_insn->detail->arm64.op_count++;
1021
1022
2.96k
    if (NeedsReg) {
1023
1.86k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
1024
1.86k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 4));
1025
1.86k
      MI->flat_insn->detail->arm64.op_count++;
1026
1.86k
    }
1027
2.96k
  }
1028
1029
2.96k
  return true;
1030
6.55k
}
1031
1032
static void printOperand(MCInst *MI, unsigned OpNum, SStream *O)
1033
603k
{
1034
603k
  MCOperand *Op = MCInst_getOperand(MI, OpNum);
1035
1036
603k
  if (MCOperand_isReg(Op)) {
1037
524k
    unsigned Reg = MCOperand_getReg(Op);
1038
1039
524k
    SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));
1040
1041
524k
    if (MI->csh->detail) {
1042
524k
      if (MI->csh->doing_mem) {
1043
241k
        if (MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.base == ARM64_REG_INVALID) {
1044
215k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.base = Reg;
1045
215k
        }
1046
25.7k
        else if (MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.index == ARM64_REG_INVALID) {
1047
25.7k
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.index = Reg;
1048
25.7k
        }
1049
282k
      } else if (MI->csh->doing_SME_Index) {
1050
        // Access op_count-1 as We want to add info to previous operand, not create a new one
1051
9.74k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count-1].sme_index.base = Reg;
1052
273k
      } else {
1053
273k
#ifndef CAPSTONE_DIET
1054
273k
        uint8_t access;
1055
1056
273k
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1057
273k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1058
273k
        MI->ac_idx++;
1059
273k
#endif
1060
273k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
1061
273k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;
1062
273k
        MI->flat_insn->detail->arm64.op_count++;
1063
273k
      }
1064
524k
    }
1065
524k
  } else if (MCOperand_isImm(Op)) {
1066
79.3k
    int64_t imm = MCOperand_getImm(Op);
1067
1068
79.3k
    if (MI->Opcode == AArch64_ADR) {
1069
5.16k
      imm += MI->address;
1070
5.16k
      printUInt64Bang(O, imm);
1071
74.2k
    } else {
1072
74.2k
      if (MI->csh->doing_mem) {
1073
21.1k
        if (MI->csh->imm_unsigned) {
1074
0
          printUInt64Bang(O, imm);
1075
21.1k
        } else {
1076
21.1k
          printInt64Bang(O, imm);
1077
21.1k
        }
1078
21.1k
      } else
1079
53.0k
        printUInt64Bang(O, imm);
1080
74.2k
    }
1081
1082
79.3k
    if (MI->csh->detail) {
1083
79.3k
      if (MI->csh->doing_mem) {
1084
21.1k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.disp = (int32_t)imm;
1085
58.2k
      } else if (MI->csh->doing_SME_Index) {
1086
        // Access op_count-1 as We want to add info to previous operand, not create a new one
1087
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count-1].sme_index.disp = (int32_t)imm; 
1088
58.2k
      } else {
1089
58.2k
#ifndef CAPSTONE_DIET
1090
58.2k
        uint8_t access;
1091
1092
58.2k
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1093
58.2k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1094
58.2k
#endif
1095
58.2k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1096
58.2k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = imm;
1097
58.2k
        MI->flat_insn->detail->arm64.op_count++;
1098
58.2k
      }
1099
79.3k
    }
1100
79.3k
  }
1101
603k
}
1102
1103
static void printImm(MCInst *MI, unsigned OpNum, SStream *O)
1104
7.19k
{
1105
7.19k
  MCOperand *Op = MCInst_getOperand(MI, OpNum);
1106
7.19k
  printUInt64Bang(O, MCOperand_getImm(Op));
1107
1108
7.19k
  if (MI->csh->detail) {
1109
7.19k
#ifndef CAPSTONE_DIET
1110
7.19k
    uint8_t access;
1111
7.19k
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1112
7.19k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1113
7.19k
    MI->ac_idx++;
1114
7.19k
#endif
1115
7.19k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1116
7.19k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op);
1117
7.19k
    MI->flat_insn->detail->arm64.op_count++;
1118
7.19k
  }
1119
7.19k
}
1120
1121
static void printImmHex(MCInst *MI, unsigned OpNum, SStream *O)
1122
71
{
1123
71
  MCOperand *Op = MCInst_getOperand(MI, OpNum);
1124
71
  printUInt64Bang(O, MCOperand_getImm(Op));
1125
1126
71
  if (MI->csh->detail) {
1127
71
#ifndef CAPSTONE_DIET
1128
71
    uint8_t access;
1129
71
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1130
71
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1131
71
    MI->ac_idx++;
1132
71
#endif
1133
71
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1134
71
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op);
1135
71
    MI->flat_insn->detail->arm64.op_count++;
1136
71
  }
1137
71
}
1138
1139
2.81k
static void printSImm(MCInst *MI, unsigned OpNo, SStream *O, int Size) {
1140
2.81k
  MCOperand *Op = MCInst_getOperand(MI, OpNo);
1141
2.81k
  if (Size == 8)
1142
1.75k
  printInt64Bang(O, (signed char) MCOperand_getImm(Op));
1143
1.05k
  else if (Size == 16)
1144
1.05k
  printInt64Bang(O, (signed short) MCOperand_getImm(Op));
1145
0
  else
1146
0
    printInt64Bang(O, MCOperand_getImm(Op));
1147
1148
2.81k
  if (MI->csh->detail) {
1149
2.81k
#ifndef CAPSTONE_DIET
1150
2.81k
    uint8_t access;
1151
2.81k
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1152
2.81k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1153
2.81k
    MI->ac_idx++;
1154
2.81k
#endif
1155
2.81k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1156
2.81k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op);
1157
2.81k
    MI->flat_insn->detail->arm64.op_count++;
1158
2.81k
  }
1159
2.81k
}
1160
1161
static void printPostIncOperand(MCInst *MI, unsigned OpNum, SStream *O,
1162
    unsigned Imm)
1163
53.6k
{
1164
53.6k
  MCOperand *Op = MCInst_getOperand(MI, OpNum);
1165
1166
53.6k
  if (MCOperand_isReg(Op)) {
1167
53.6k
    unsigned Reg = MCOperand_getReg(Op);
1168
53.6k
    if (Reg == AArch64_XZR) {
1169
0
      printInt32Bang(O, Imm);
1170
1171
0
      if (MI->csh->detail) {
1172
0
#ifndef CAPSTONE_DIET
1173
0
        uint8_t access;
1174
1175
0
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1176
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1177
0
        MI->ac_idx++;
1178
0
#endif
1179
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1180
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Imm;
1181
0
        MI->flat_insn->detail->arm64.op_count++;
1182
0
      }
1183
53.6k
    } else {
1184
53.6k
      SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));
1185
1186
53.6k
      if (MI->csh->detail) {
1187
53.6k
#ifndef CAPSTONE_DIET
1188
53.6k
        uint8_t access;
1189
1190
53.6k
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1191
53.6k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1192
53.6k
        MI->ac_idx++;
1193
53.6k
#endif
1194
53.6k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
1195
53.6k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;
1196
53.6k
        MI->flat_insn->detail->arm64.op_count++;
1197
53.6k
      }
1198
53.6k
    }
1199
53.6k
  }
1200
  //llvm_unreachable("unknown operand kind in printPostIncOperand64");
1201
53.6k
}
1202
1203
static void printVRegOperand(MCInst *MI, unsigned OpNum, SStream *O)
1204
85.3k
{
1205
85.3k
  MCOperand *Op = MCInst_getOperand(MI, OpNum);
1206
  //assert(Op.isReg() && "Non-register vreg operand!");
1207
85.3k
  unsigned Reg = MCOperand_getReg(Op);
1208
1209
85.3k
  SStream_concat0(O, getRegisterName(Reg, AArch64_vreg));
1210
1211
85.3k
  if (MI->csh->detail) {
1212
85.3k
#ifndef CAPSTONE_DIET
1213
85.3k
    uint8_t access;
1214
85.3k
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1215
85.3k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1216
85.3k
    MI->ac_idx++;
1217
85.3k
#endif
1218
85.3k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
1219
85.3k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = AArch64_map_vregister(Reg);
1220
85.3k
    MI->flat_insn->detail->arm64.op_count++;
1221
85.3k
  }
1222
85.3k
}
1223
1224
static void printSysCROperand(MCInst *MI, unsigned OpNum, SStream *O)
1225
7.70k
{
1226
7.70k
  MCOperand *Op = MCInst_getOperand(MI, OpNum);
1227
7.70k
  unsigned Val = (unsigned)MCOperand_getImm(Op);
1228
  //assert(Op.isImm() && "System instruction C[nm] operands must be immediates!");
1229
7.70k
  SStream_concat(O, "c%u", Val);
1230
1231
7.70k
  if (MI->csh->detail) {
1232
7.70k
#ifndef CAPSTONE_DIET
1233
7.70k
    uint8_t access;
1234
1235
7.70k
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1236
7.70k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1237
7.70k
    MI->ac_idx++;
1238
7.70k
#endif
1239
7.70k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_CIMM;
1240
7.70k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;
1241
7.70k
    MI->flat_insn->detail->arm64.op_count++;
1242
7.70k
  }
1243
7.70k
}
1244
1245
static void printAddSubImm(MCInst *MI, unsigned OpNum, SStream *O)
1246
2.80k
{
1247
2.80k
  MCOperand *MO = MCInst_getOperand(MI, OpNum);
1248
2.80k
  if (MCOperand_isImm(MO)) {
1249
2.80k
    unsigned Val = (MCOperand_getImm(MO) & 0xfff);
1250
    //assert(Val == MO.getImm() && "Add/sub immediate out of range!");
1251
2.80k
    unsigned Shift = AArch64_AM_getShiftValue((int)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)));
1252
1253
2.80k
    printInt32Bang(O, Val);
1254
1255
2.80k
    if (MI->csh->detail) {
1256
2.80k
#ifndef CAPSTONE_DIET
1257
2.80k
      uint8_t access;
1258
1259
2.80k
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1260
2.80k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1261
2.80k
      MI->ac_idx++;
1262
2.80k
#endif
1263
2.80k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1264
2.80k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;
1265
2.80k
      MI->flat_insn->detail->arm64.op_count++;
1266
2.80k
    }
1267
1268
2.80k
    if (Shift != 0)
1269
1.71k
      printShifter(MI, OpNum + 1, O);
1270
2.80k
  }
1271
2.80k
}
1272
1273
static void printLogicalImm32(MCInst *MI, unsigned OpNum, SStream *O)
1274
4.99k
{
1275
4.99k
  int64_t Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1276
1277
4.99k
  Val = AArch64_AM_decodeLogicalImmediate(Val, 32);
1278
4.99k
  printUInt32Bang(O, (int)Val);
1279
1280
4.99k
  if (MI->csh->detail) {
1281
4.99k
#ifndef CAPSTONE_DIET
1282
4.99k
    uint8_t access;
1283
1284
4.99k
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1285
4.99k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1286
4.99k
    MI->ac_idx++;
1287
4.99k
#endif
1288
4.99k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1289
4.99k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;
1290
4.99k
    MI->flat_insn->detail->arm64.op_count++;
1291
4.99k
  }
1292
4.99k
}
1293
1294
static void printLogicalImm64(MCInst *MI, unsigned OpNum, SStream *O)
1295
4.15k
{
1296
4.15k
  int64_t Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1297
4.15k
  Val = AArch64_AM_decodeLogicalImmediate(Val, 64);
1298
1299
4.15k
  switch(MI->flat_insn->id) {
1300
1.46k
    default:
1301
1.46k
      printInt64Bang(O, Val);
1302
1.46k
      break;
1303
1304
1.50k
    case ARM64_INS_ORR:
1305
2.07k
    case ARM64_INS_AND:
1306
2.69k
    case ARM64_INS_EOR:
1307
2.69k
    case ARM64_INS_TST:
1308
      // do not print number in negative form
1309
2.69k
      if (Val >= 0 && Val <= HEX_THRESHOLD)
1310
359
        SStream_concat(O, "#%u", (int)Val);
1311
2.33k
      else
1312
2.33k
        SStream_concat(O, "#0x%"PRIx64, Val);
1313
2.69k
      break;
1314
4.15k
  }
1315
1316
4.15k
  if (MI->csh->detail) {
1317
4.15k
#ifndef CAPSTONE_DIET
1318
4.15k
    uint8_t access;
1319
1320
4.15k
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1321
4.15k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1322
4.15k
    MI->ac_idx++;
1323
4.15k
#endif
1324
4.15k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1325
4.15k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (int64_t)Val;
1326
4.15k
    MI->flat_insn->detail->arm64.op_count++;
1327
4.15k
  }
1328
4.15k
}
1329
1330
static void printShifter(MCInst *MI, unsigned OpNum, SStream *O)
1331
15.8k
{
1332
15.8k
  unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1333
1334
  // LSL #0 should not be printed.
1335
15.8k
  if (AArch64_AM_getShiftType(Val) == AArch64_AM_LSL &&
1336
8.65k
      AArch64_AM_getShiftValue(Val) == 0)
1337
1.66k
    return;
1338
1339
14.2k
  SStream_concat(O, ", %s ", AArch64_AM_getShiftExtendName(AArch64_AM_getShiftType(Val)));
1340
14.2k
  printInt32BangDec(O, AArch64_AM_getShiftValue(Val));
1341
1342
14.2k
  if (MI->csh->detail) {
1343
14.2k
    arm64_shifter shifter = ARM64_SFT_INVALID;
1344
1345
14.2k
    switch(AArch64_AM_getShiftType(Val)) {
1346
0
      default:  // never reach
1347
6.99k
      case AArch64_AM_LSL:
1348
6.99k
        shifter = ARM64_SFT_LSL;
1349
6.99k
        break;
1350
1351
1.75k
      case AArch64_AM_LSR:
1352
1.75k
        shifter = ARM64_SFT_LSR;
1353
1.75k
        break;
1354
1355
3.04k
      case AArch64_AM_ASR:
1356
3.04k
        shifter = ARM64_SFT_ASR;
1357
3.04k
        break;
1358
1359
1.77k
      case AArch64_AM_ROR:
1360
1.77k
        shifter = ARM64_SFT_ROR;
1361
1.77k
        break;
1362
1363
633
      case AArch64_AM_MSL:
1364
633
        shifter = ARM64_SFT_MSL;
1365
633
        break;
1366
14.2k
    }
1367
1368
14.2k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.type = shifter;
1369
14.2k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.value = AArch64_AM_getShiftValue(Val);
1370
14.2k
  }
1371
14.2k
}
1372
1373
static void printShiftedRegister(MCInst *MI, unsigned OpNum, SStream *O)
1374
8.96k
{
1375
8.96k
  SStream_concat0(O, getRegisterName(MCOperand_getReg(MCInst_getOperand(MI, OpNum)), AArch64_NoRegAltName));
1376
1377
8.96k
  if (MI->csh->detail) {
1378
8.96k
#ifndef CAPSTONE_DIET
1379
8.96k
    uint8_t access;
1380
8.96k
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1381
8.96k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1382
8.96k
    MI->ac_idx++;
1383
8.96k
#endif
1384
8.96k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
1385
8.96k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
1386
8.96k
    MI->flat_insn->detail->arm64.op_count++;
1387
8.96k
  }
1388
1389
8.96k
  printShifter(MI, OpNum + 1, O);
1390
8.96k
}
1391
1392
static void printArithExtend(MCInst *MI, unsigned OpNum, SStream *O)
1393
6.12k
{
1394
6.12k
  unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1395
6.12k
  AArch64_AM_ShiftExtendType ExtType = AArch64_AM_getArithExtendType(Val);
1396
6.12k
  unsigned ShiftVal = AArch64_AM_getArithShiftValue(Val);
1397
1398
  // If the destination or first source register operand is [W]SP, print
1399
  // UXTW/UXTX as LSL, and if the shift amount is also zero, print nothing at
1400
  // all.
1401
6.12k
  if (ExtType == AArch64_AM_UXTW || ExtType == AArch64_AM_UXTX) {
1402
3.39k
    unsigned Dest = MCOperand_getReg(MCInst_getOperand(MI, 0));
1403
3.39k
    unsigned Src1 = MCOperand_getReg(MCInst_getOperand(MI, 1));
1404
1405
3.39k
    if (((Dest == AArch64_SP || Src1 == AArch64_SP) &&
1406
882
          ExtType == AArch64_AM_UXTX) ||
1407
3.03k
        ((Dest == AArch64_WSP || Src1 == AArch64_WSP) &&
1408
1.41k
         ExtType == AArch64_AM_UXTW)) {
1409
602
      if (ShiftVal != 0) {
1410
602
        SStream_concat0(O, ", lsl ");
1411
602
        printInt32Bang(O, ShiftVal);
1412
1413
602
        if (MI->csh->detail) {
1414
602
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.type = ARM64_SFT_LSL;
1415
602
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.value = ShiftVal;
1416
602
        }
1417
602
      }
1418
1419
602
      return;
1420
602
    }
1421
3.39k
  }
1422
1423
5.51k
  SStream_concat(O, ", %s", AArch64_AM_getShiftExtendName(ExtType));
1424
1425
5.51k
  if (MI->csh->detail) {
1426
5.51k
    arm64_extender ext = ARM64_EXT_INVALID;
1427
5.51k
    switch(ExtType) {
1428
0
      default:  // never reach
1429
1430
421
      case AArch64_AM_UXTB:
1431
421
        ext = ARM64_EXT_UXTB;
1432
421
        break;
1433
1434
785
      case AArch64_AM_UXTH:
1435
785
        ext = ARM64_EXT_UXTH;
1436
785
        break;
1437
1438
1.20k
      case AArch64_AM_UXTW:
1439
1.20k
        ext = ARM64_EXT_UXTW;
1440
1.20k
        break;
1441
1442
1.58k
      case AArch64_AM_UXTX:
1443
1.58k
        ext = ARM64_EXT_UXTX;
1444
1.58k
        break;
1445
1446
218
      case AArch64_AM_SXTB:
1447
218
        ext = ARM64_EXT_SXTB;
1448
218
        break;
1449
1450
643
      case AArch64_AM_SXTH:
1451
643
        ext = ARM64_EXT_SXTH;
1452
643
        break;
1453
1454
153
      case AArch64_AM_SXTW:
1455
153
        ext = ARM64_EXT_SXTW;
1456
153
        break;
1457
1458
507
      case AArch64_AM_SXTX:
1459
507
        ext = ARM64_EXT_SXTX;
1460
507
        break;
1461
5.51k
    }
1462
1463
5.51k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].ext = ext;
1464
5.51k
  }
1465
1466
5.51k
  if (ShiftVal != 0) {
1467
4.77k
    SStream_concat0(O, " ");
1468
4.77k
    printInt32Bang(O, ShiftVal);
1469
1470
4.77k
    if (MI->csh->detail) {
1471
4.77k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.type = ARM64_SFT_LSL;
1472
4.77k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.value = ShiftVal;
1473
4.77k
    }
1474
4.77k
  }
1475
5.51k
}
1476
1477
static void printExtendedRegister(MCInst *MI, unsigned OpNum, SStream *O)
1478
4.68k
{
1479
4.68k
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
1480
1481
4.68k
  SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));
1482
1483
4.68k
  if (MI->csh->detail) {
1484
4.68k
#ifndef CAPSTONE_DIET
1485
4.68k
    uint8_t access;
1486
4.68k
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1487
4.68k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1488
4.68k
    MI->ac_idx++;
1489
4.68k
#endif
1490
4.68k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
1491
4.68k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;
1492
4.68k
    MI->flat_insn->detail->arm64.op_count++;
1493
4.68k
  }
1494
1495
4.68k
  printArithExtend(MI, OpNum + 1, O);
1496
4.68k
}
1497
1498
static void printMemExtendImpl(MCInst *MI, bool SignExtend, bool DoShift, unsigned Width,
1499
             char SrcRegKind, SStream *O)
1500
25.6k
{
1501
  // sxtw, sxtx, uxtw or lsl (== uxtx)
1502
25.6k
  bool IsLSL = !SignExtend && SrcRegKind == 'x';
1503
25.6k
  if (IsLSL) {
1504
9.95k
    SStream_concat0(O, "lsl");
1505
1506
9.95k
    if (MI->csh->detail) {
1507
9.95k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].shift.type = ARM64_SFT_LSL;
1508
9.95k
    }
1509
15.7k
  } else {
1510
15.7k
    SStream_concat(O, "%cxt%c", (SignExtend ? 's' : 'u'), SrcRegKind);
1511
1512
15.7k
    if (MI->csh->detail) {
1513
15.7k
      if (!SignExtend) {
1514
7.91k
        switch(SrcRegKind) {
1515
0
          default: break;
1516
0
          case 'b':
1517
0
               MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_UXTB;
1518
0
               break;
1519
0
          case 'h':
1520
0
               MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_UXTH;
1521
0
               break;
1522
7.91k
          case 'w':
1523
7.91k
               MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_UXTW;
1524
7.91k
               break;
1525
7.91k
        }
1526
7.91k
      } else {
1527
7.79k
          switch(SrcRegKind) {
1528
0
            default: break;
1529
0
            case 'b':
1530
0
              MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_SXTB;
1531
0
              break;
1532
0
            case 'h':
1533
0
              MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_SXTH;
1534
0
              break;
1535
6.08k
            case 'w':
1536
6.08k
              MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_SXTW;
1537
6.08k
              break;
1538
1.71k
            case 'x':
1539
1.71k
              MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_SXTX;
1540
1.71k
              break;
1541
7.79k
          }
1542
7.79k
      }
1543
15.7k
    }
1544
15.7k
  }
1545
1546
25.6k
  if (DoShift || IsLSL) {
1547
18.3k
    SStream_concat(O, " #%u", Log2_32(Width / 8));
1548
1549
18.3k
    if (MI->csh->detail) {
1550
18.3k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].shift.type = ARM64_SFT_LSL;
1551
18.3k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].shift.value = Log2_32(Width / 8);
1552
18.3k
    }
1553
18.3k
  }
1554
25.6k
}
1555
1556
static void printMemExtend(MCInst *MI, unsigned OpNum, SStream *O, char SrcRegKind, unsigned Width)
1557
7.47k
{
1558
7.47k
  unsigned SignExtend = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1559
7.47k
  unsigned DoShift = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));
1560
1561
7.47k
  printMemExtendImpl(MI, SignExtend, DoShift, Width, SrcRegKind, O);
1562
7.47k
}
1563
1564
static void printRegWithShiftExtend(MCInst *MI, unsigned OpNum, SStream *O,
1565
            bool SignExtend, int ExtWidth,
1566
            char SrcRegKind, char Suffix)
1567
21.3k
{
1568
21.3k
  bool DoShift;
1569
1570
21.3k
  printOperand(MI, OpNum, O);
1571
1572
21.3k
  if (Suffix == 's' || Suffix == 'd')
1573
13.2k
    SStream_concat(O, ".%c", Suffix);
1574
1575
21.3k
  DoShift = ExtWidth != 8;
1576
21.3k
  if (SignExtend || DoShift || SrcRegKind == 'w') {
1577
18.1k
    SStream_concat0(O, ", ");
1578
18.1k
    printMemExtendImpl(MI, SignExtend, DoShift, ExtWidth, SrcRegKind, O);
1579
18.1k
  }
1580
21.3k
}
1581
1582
static void printCondCode(MCInst *MI, unsigned OpNum, SStream *O)
1583
3.73k
{
1584
3.73k
  AArch64CC_CondCode CC = (AArch64CC_CondCode)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1585
3.73k
  SStream_concat0(O, getCondCodeName(CC));
1586
1587
3.73k
  if (MI->csh->detail)
1588
3.73k
    MI->flat_insn->detail->arm64.cc = (arm64_cc)(CC + 1);
1589
3.73k
}
1590
1591
static void printInverseCondCode(MCInst *MI, unsigned OpNum, SStream *O)
1592
1.35k
{
1593
1.35k
  AArch64CC_CondCode CC = (AArch64CC_CondCode)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1594
1.35k
  SStream_concat0(O, getCondCodeName(getInvertedCondCode(CC)));
1595
1596
1.35k
  if (MI->csh->detail) {
1597
1.35k
    MI->flat_insn->detail->arm64.cc = (arm64_cc)(getInvertedCondCode(CC) + 1);
1598
1.35k
  }
1599
1.35k
}
1600
1601
static void printImmScale(MCInst *MI, unsigned OpNum, SStream *O, int Scale)
1602
28.5k
{
1603
28.5k
  int64_t val = Scale * MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1604
1605
28.5k
  printInt64Bang(O, val);
1606
1607
28.5k
  if (MI->csh->detail) {
1608
28.5k
    if (MI->csh->doing_mem) {
1609
23.6k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.disp = (int32_t)val;
1610
23.6k
    } else {
1611
4.88k
#ifndef CAPSTONE_DIET
1612
4.88k
      uint8_t access;
1613
1614
4.88k
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1615
4.88k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1616
4.88k
      MI->ac_idx++;
1617
4.88k
#endif
1618
4.88k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1619
4.88k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = val;
1620
4.88k
      MI->flat_insn->detail->arm64.op_count++;
1621
4.88k
    }
1622
28.5k
  }
1623
28.5k
}
1624
1625
static void printUImm12Offset(MCInst *MI, unsigned OpNum, SStream *O, unsigned Scale)
1626
10.4k
{
1627
10.4k
  MCOperand *MO = MCInst_getOperand(MI, OpNum);
1628
1629
10.4k
  if (MCOperand_isImm(MO)) {
1630
10.4k
    int64_t val = Scale * MCOperand_getImm(MO);
1631
10.4k
    printInt64Bang(O, val);
1632
1633
10.4k
    if (MI->csh->detail) {
1634
10.4k
      if (MI->csh->doing_mem) {
1635
10.4k
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.disp = (int32_t)val;
1636
10.4k
      } else {
1637
0
#ifndef CAPSTONE_DIET
1638
0
        uint8_t access;
1639
1640
0
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1641
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1642
0
        MI->ac_idx++;
1643
0
#endif
1644
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1645
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (int)val;
1646
0
        MI->flat_insn->detail->arm64.op_count++;
1647
0
      }
1648
10.4k
    }
1649
10.4k
  }
1650
10.4k
}
1651
1652
#if 0
1653
static void printAMIndexedWB(MCInst *MI, unsigned OpNum, SStream *O, unsigned int Scale)
1654
{
1655
  MCOperand *MO = MCInst_getOperand(MI, OpNum + 1);
1656
1657
  SStream_concat(O, "[%s", getRegisterName(MCOperand_getReg(MCInst_getOperand(MI, OpNum)), AArch64_NoRegAltName));
1658
1659
  if (MCOperand_isImm(MO)) {
1660
    int64_t val = Scale * MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1661
    printInt64Bang(O, val);
1662
  // } else {
1663
  //   // assert(MO1.isExpr() && "Unexpected operand type!");
1664
  //   SStream_concat0(O, ", ");
1665
  //   MO1.getExpr()->print(O, &MAI);
1666
  }
1667
1668
  SStream_concat0(O, "]");
1669
}
1670
#endif
1671
1672
// IsSVEPrefetch = false
1673
static void printPrefetchOp(MCInst *MI, unsigned OpNum, SStream *O, bool IsSVEPrefetch)
1674
8.54k
{
1675
8.54k
  unsigned prfop = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1676
1677
8.54k
  if (IsSVEPrefetch) {
1678
6.85k
    const SVEPRFM *PRFM = lookupSVEPRFMByEncoding(prfop);
1679
6.85k
    if (PRFM)
1680
4.89k
      SStream_concat0(O, PRFM->Name);
1681
1682
6.85k
    return;
1683
6.85k
  } else {
1684
1.68k
    const PRFM *PRFM = lookupPRFMByEncoding(prfop);
1685
1.68k
    if (PRFM)
1686
968
      SStream_concat0(O, PRFM->Name);
1687
1688
1.68k
    return;
1689
1.68k
  }
1690
1691
  // FIXME: set OpcodePub?
1692
1693
0
  printInt32Bang(O, prfop);
1694
1695
0
  if (MI->csh->detail) {
1696
0
#ifndef CAPSTONE_DIET
1697
0
    uint8_t access;
1698
0
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1699
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1700
0
    MI->ac_idx++;
1701
0
#endif
1702
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1703
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = prfop;
1704
0
    MI->flat_insn->detail->arm64.op_count++;
1705
0
  }
1706
0
}
1707
1708
static void printPSBHintOp(MCInst *MI, unsigned OpNum, SStream *O)
1709
884
{
1710
884
  MCOperand *Op = MCInst_getOperand(MI, OpNum);
1711
884
  unsigned int psbhintop = MCOperand_getImm(Op);
1712
1713
884
  const PSB *PSB = lookupPSBByEncoding(psbhintop);
1714
884
  if (PSB)
1715
884
    SStream_concat0(O, PSB->Name);
1716
0
  else
1717
0
    printUInt32Bang(O, psbhintop);
1718
884
}
1719
1720
788
static void printBTIHintOp(MCInst *MI, unsigned OpNum, SStream *O) {
1721
788
  unsigned btihintop = MCOperand_getImm(MCInst_getOperand(MI, OpNum)) ^ 32;
1722
1723
788
  const BTI *BTI = lookupBTIByEncoding(btihintop);
1724
788
  if (BTI)
1725
788
  SStream_concat0(O, BTI->Name);
1726
0
  else
1727
0
  printUInt32Bang(O, btihintop);
1728
788
}
1729
1730
static void printFPImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
1731
1.84k
{
1732
1.84k
  MCOperand *MO = MCInst_getOperand(MI, OpNum);
1733
1.84k
  float FPImm = MCOperand_isFPImm(MO) ? MCOperand_getFPImm(MO) : AArch64_AM_getFPImmFloat((int)MCOperand_getImm(MO));
1734
1735
  // 8 decimal places are enough to perfectly represent permitted floats.
1736
#if defined(_KERNEL_MODE)
1737
  // Issue #681: Windows kernel does not support formatting float point
1738
  SStream_concat0(O, "#<float_point_unsupported>");
1739
#else
1740
1.84k
  SStream_concat(O, "#%.8f", FPImm);
1741
1.84k
#endif
1742
1743
1.84k
  if (MI->csh->detail) {
1744
1.84k
#ifndef CAPSTONE_DIET
1745
1.84k
    uint8_t access;
1746
1747
1.84k
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1748
1.84k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1749
1.84k
    MI->ac_idx++;
1750
1.84k
#endif
1751
1.84k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_FP;
1752
1.84k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].fp = FPImm;
1753
1.84k
    MI->flat_insn->detail->arm64.op_count++;
1754
1.84k
  }
1755
1.84k
}
1756
1757
//static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride = 1)
1758
static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride)
1759
307k
{
1760
614k
  while (Stride--) {
1761
307k
    if (Reg >= AArch64_Q0 && Reg <= AArch64_Q30) // AArch64_Q0 .. AArch64_Q30
1762
266k
      Reg += 1;
1763
40.6k
    else if (Reg == AArch64_Q31) // Vector lists can wrap around.
1764
11.9k
      Reg = AArch64_Q0;
1765
28.7k
    else if (Reg >= AArch64_Z0 && Reg <= AArch64_Z30) // AArch64_Z0 .. AArch64_Z30
1766
27.0k
      Reg += 1;
1767
1.66k
    else if (Reg == AArch64_Z31) // Vector lists can wrap around.
1768
1.66k
      Reg = AArch64_Z0;
1769
307k
  }
1770
1771
307k
  return Reg;
1772
307k
}
1773
1774
static void printGPRSeqPairsClassOperand(MCInst *MI, unsigned OpNum, SStream *O, unsigned int size)
1775
2.01k
{
1776
  // static_assert(size == 64 || size == 32,
1777
  //    "Template parameter must be either 32 or 64");
1778
2.01k
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
1779
2.01k
  unsigned Sube = (size == 32) ? AArch64_sube32 : AArch64_sube64;
1780
2.01k
  unsigned Subo = (size == 32) ? AArch64_subo32 : AArch64_subo64;
1781
2.01k
  unsigned Even = MCRegisterInfo_getSubReg(MI->MRI, Reg, Sube);
1782
2.01k
  unsigned Odd = MCRegisterInfo_getSubReg(MI->MRI, Reg, Subo);
1783
1784
2.01k
  SStream_concat(O, "%s, %s", getRegisterName(Even, AArch64_NoRegAltName),
1785
2.01k
      getRegisterName(Odd, AArch64_NoRegAltName));
1786
1787
2.01k
  if (MI->csh->detail) {
1788
2.01k
#ifndef CAPSTONE_DIET
1789
2.01k
    uint8_t access;
1790
1791
2.01k
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1792
2.01k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1793
2.01k
    MI->ac_idx++;
1794
2.01k
#endif
1795
1796
2.01k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
1797
2.01k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Even;
1798
2.01k
    MI->flat_insn->detail->arm64.op_count++;
1799
1800
2.01k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
1801
2.01k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Odd;
1802
2.01k
    MI->flat_insn->detail->arm64.op_count++;
1803
2.01k
  }
1804
2.01k
}
1805
1806
static void printVectorList(MCInst *MI, unsigned OpNum, SStream *O,
1807
    char *LayoutSuffix, MCRegisterInfo *MRI, arm64_vas vas)
1808
124k
{
1809
1.80M
#define GETREGCLASS_CONTAIN0(_class, _reg) MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, _class), _reg)
1810
124k
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
1811
124k
  unsigned NumRegs = 1, FirstReg, i;
1812
1813
124k
  SStream_concat0(O, "{");
1814
1815
  // Work out how many registers there are in the list (if there is an actual
1816
  // list).
1817
124k
  if (GETREGCLASS_CONTAIN0(AArch64_DDRegClassID , Reg) ||
1818
118k
      GETREGCLASS_CONTAIN0(AArch64_ZPR2RegClassID, Reg) ||
1819
116k
      GETREGCLASS_CONTAIN0(AArch64_QQRegClassID, Reg))
1820
29.2k
    NumRegs = 2;
1821
94.8k
  else if (GETREGCLASS_CONTAIN0(AArch64_DDDRegClassID, Reg) ||
1822
87.2k
      GETREGCLASS_CONTAIN0(AArch64_ZPR3RegClassID, Reg) ||
1823
85.3k
      GETREGCLASS_CONTAIN0(AArch64_QQQRegClassID, Reg))
1824
29.5k
    NumRegs = 3;
1825
65.2k
  else if (GETREGCLASS_CONTAIN0(AArch64_DDDDRegClassID, Reg) ||
1826
58.0k
      GETREGCLASS_CONTAIN0(AArch64_ZPR4RegClassID, Reg) ||
1827
56.2k
      GETREGCLASS_CONTAIN0(AArch64_QQQQRegClassID, Reg))
1828
31.6k
    NumRegs = 4;
1829
1830
  // Now forget about the list and find out what the first register is.
1831
124k
  if ((FirstReg = MCRegisterInfo_getSubReg(MRI, Reg, AArch64_dsub0)))
1832
20.7k
    Reg = FirstReg;
1833
103k
  else if ((FirstReg = MCRegisterInfo_getSubReg(MRI, Reg, AArch64_qsub0)))
1834
64.1k
    Reg = FirstReg;
1835
39.2k
  else if ((FirstReg = MCRegisterInfo_getSubReg(MRI, Reg, AArch64_zsub0)))
1836
5.60k
    Reg = FirstReg;
1837
1838
  // If it's a D-reg, we need to promote it to the equivalent Q-reg before
1839
  // printing (otherwise getRegisterName fails).
1840
124k
  if (GETREGCLASS_CONTAIN0(AArch64_FPR64RegClassID, Reg)) {
1841
23.7k
    const MCRegisterClass *FPR128RC = MCRegisterInfo_getRegClass(MRI, AArch64_FPR128RegClassID);
1842
23.7k
    Reg = MCRegisterInfo_getMatchingSuperReg(MRI, Reg, AArch64_dsub, FPR128RC);
1843
23.7k
  }
1844
1845
431k
  for (i = 0; i < NumRegs; ++i, Reg = getNextVectorRegister(Reg, 1)) {
1846
307k
    bool isZReg = GETREGCLASS_CONTAIN0(AArch64_ZPRRegClassID, Reg);
1847
307k
    if (isZReg)
1848
28.7k
      SStream_concat(O, "%s%s", getRegisterName(Reg, AArch64_NoRegAltName), LayoutSuffix);
1849
278k
    else
1850
278k
      SStream_concat(O, "%s%s", getRegisterName(Reg, AArch64_vreg), LayoutSuffix);
1851
1852
307k
    if (MI->csh->detail) {
1853
307k
#ifndef CAPSTONE_DIET
1854
307k
      uint8_t access;
1855
1856
307k
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1857
307k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1858
307k
      MI->ac_idx++;
1859
307k
#endif
1860
307k
      unsigned regForDetail = isZReg ? Reg : AArch64_map_vregister(Reg);
1861
307k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
1862
307k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = regForDetail;
1863
307k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].vas = vas;
1864
307k
      MI->flat_insn->detail->arm64.op_count++;
1865
307k
    }
1866
1867
307k
    if (i + 1 != NumRegs)
1868
183k
      SStream_concat0(O, ", ");
1869
307k
  }
1870
1871
124k
  SStream_concat0(O, "}");
1872
124k
}
1873
1874
static void printTypedVectorList(MCInst *MI, unsigned OpNum, SStream *O, unsigned NumLanes, char LaneKind)
1875
124k
{
1876
124k
  char Suffix[32];
1877
124k
  arm64_vas vas = 0;
1878
1879
124k
  if (NumLanes) {
1880
54.4k
    cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, LaneKind);
1881
1882
54.4k
    switch(LaneKind) {
1883
0
      default: break;
1884
16.5k
      case 'b':
1885
16.5k
        switch(NumLanes) {
1886
0
          default: break;
1887
0
          case 1:
1888
0
               vas = ARM64_VAS_1B;
1889
0
               break;
1890
0
          case 4:
1891
0
               vas = ARM64_VAS_4B;
1892
0
               break;
1893
7.66k
          case 8:
1894
7.66k
               vas = ARM64_VAS_8B;
1895
7.66k
               break;
1896
8.88k
          case 16:
1897
8.88k
               vas = ARM64_VAS_16B;
1898
8.88k
               break;
1899
16.5k
        }
1900
16.5k
        break;
1901
16.5k
      case 'h':
1902
13.2k
        switch(NumLanes) {
1903
0
          default: break;
1904
0
          case 1:
1905
0
               vas = ARM64_VAS_1H;
1906
0
               break;
1907
0
          case 2:
1908
0
               vas = ARM64_VAS_2H;
1909
0
               break;
1910
4.19k
          case 4:
1911
4.19k
               vas = ARM64_VAS_4H;
1912
4.19k
               break;
1913
9.04k
          case 8:
1914
9.04k
               vas = ARM64_VAS_8H;
1915
9.04k
               break;
1916
13.2k
        }
1917
13.2k
        break;
1918
13.2k
      case 's':
1919
12.7k
        switch(NumLanes) {
1920
0
          default: break;
1921
0
          case 1:
1922
0
               vas = ARM64_VAS_1S;
1923
0
               break;
1924
6.67k
          case 2:
1925
6.67k
               vas = ARM64_VAS_2S;
1926
6.67k
               break;
1927
6.05k
          case 4:
1928
6.05k
               vas = ARM64_VAS_4S;
1929
6.05k
               break;
1930
12.7k
        }
1931
12.7k
        break;
1932
12.7k
      case 'd':
1933
11.9k
        switch(NumLanes) {
1934
0
          default: break;
1935
5.17k
          case 1:
1936
5.17k
               vas = ARM64_VAS_1D;
1937
5.17k
               break;
1938
6.77k
          case 2:
1939
6.77k
               vas = ARM64_VAS_2D;
1940
6.77k
               break;
1941
11.9k
        }
1942
11.9k
        break;
1943
11.9k
      case 'q':
1944
0
        switch(NumLanes) {
1945
0
          default: break;
1946
0
          case 1:
1947
0
               vas = ARM64_VAS_1Q;
1948
0
               break;
1949
0
        }
1950
0
        break;
1951
54.4k
    }
1952
69.5k
  } else {
1953
69.5k
    cs_snprintf(Suffix, sizeof(Suffix), ".%c", LaneKind);
1954
1955
69.5k
    switch(LaneKind) {
1956
0
      default: break;
1957
17.5k
      case 'b':
1958
17.5k
           vas = ARM64_VAS_1B;
1959
17.5k
           break;
1960
13.7k
      case 'h':
1961
13.7k
           vas = ARM64_VAS_1H;
1962
13.7k
           break;
1963
20.6k
      case 's':
1964
20.6k
           vas = ARM64_VAS_1S;
1965
20.6k
           break;
1966
17.6k
      case 'd':
1967
17.6k
           vas = ARM64_VAS_1D;
1968
17.6k
           break;
1969
0
      case 'q':
1970
0
           vas = ARM64_VAS_1Q;
1971
0
           break;
1972
69.5k
    }
1973
69.5k
  }
1974
1975
124k
  printVectorList(MI, OpNum, O, Suffix, MI->MRI, vas);
1976
124k
}
1977
1978
static void printVectorIndex(MCInst *MI, unsigned OpNum, SStream *O)
1979
69.6k
{
1980
69.6k
  SStream_concat0(O, "[");
1981
69.6k
  printInt32(O, (int)MCOperand_getImm(MCInst_getOperand(MI, OpNum)));
1982
69.6k
  SStream_concat0(O, "]");
1983
1984
69.6k
  if (MI->csh->detail) {
1985
69.6k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].vector_index = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1986
69.6k
  }
1987
69.6k
}
1988
1989
static void printAlignedLabel(MCInst *MI, unsigned OpNum, SStream *O)
1990
13.2k
{
1991
13.2k
  MCOperand *Op = MCInst_getOperand(MI, OpNum);
1992
1993
  // If the label has already been resolved to an immediate offset (say, when
1994
  // we're running the disassembler), just print the immediate.
1995
13.2k
  if (MCOperand_isImm(Op)) {
1996
13.2k
    uint64_t imm = (MCOperand_getImm(Op) * 4) + MI->address;
1997
13.2k
    printUInt64Bang(O, imm);
1998
1999
13.2k
    if (MI->csh->detail) {
2000
13.2k
#ifndef CAPSTONE_DIET
2001
13.2k
      uint8_t access;
2002
2003
13.2k
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2004
13.2k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2005
13.2k
      MI->ac_idx++;
2006
13.2k
#endif
2007
13.2k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
2008
13.2k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = imm;
2009
13.2k
      MI->flat_insn->detail->arm64.op_count++;
2010
13.2k
    }
2011
13.2k
  }
2012
13.2k
}
2013
2014
static void printAdrpLabel(MCInst *MI, unsigned OpNum, SStream *O)
2015
2.62k
{
2016
2.62k
  MCOperand *Op = MCInst_getOperand(MI, OpNum);
2017
2018
2.62k
  if (MCOperand_isImm(Op)) {
2019
    // ADRP sign extends a 21-bit offset, shifts it left by 12
2020
    // and adds it to the value of the PC with its bottom 12 bits cleared
2021
2.62k
    uint64_t imm = (MCOperand_getImm(Op) * 0x1000) + (MI->address & ~0xfff);
2022
2.62k
    printUInt64Bang(O, imm);
2023
2024
2.62k
    if (MI->csh->detail) {
2025
2.62k
#ifndef CAPSTONE_DIET
2026
2.62k
      uint8_t access;
2027
2028
2.62k
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2029
2.62k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2030
2.62k
      MI->ac_idx++;
2031
2.62k
#endif
2032
2.62k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
2033
2.62k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = imm;
2034
2.62k
      MI->flat_insn->detail->arm64.op_count++;
2035
2.62k
    }
2036
2.62k
  }
2037
2.62k
}
2038
2039
static void printBarrierOption(MCInst *MI, unsigned OpNum, SStream *O)
2040
764
{
2041
764
  unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
2042
764
  unsigned Opcode = MCInst_getOpcode(MI);
2043
764
  const char *Name = NULL;
2044
2045
764
  if (Opcode == AArch64_ISB) {
2046
66
    const ISB *ISB = lookupISBByEncoding(Val);
2047
66
    Name = ISB ? ISB->Name : NULL;
2048
698
  } else if (Opcode == AArch64_TSB) {
2049
0
    const TSB *TSB = lookupTSBByEncoding(Val);
2050
0
    Name = TSB ? TSB->Name : NULL;
2051
698
  } else {
2052
698
    const DB *DB = lookupDBByEncoding(Val);
2053
698
    Name = DB ? DB->Name : NULL;
2054
698
  }
2055
2056
764
  if (Name) {
2057
99
    SStream_concat0(O, Name);
2058
2059
99
    if (MI->csh->detail) {
2060
99
#ifndef CAPSTONE_DIET
2061
99
      uint8_t access;
2062
2063
99
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2064
99
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2065
99
      MI->ac_idx++;
2066
99
#endif
2067
99
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_BARRIER;
2068
99
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].barrier = Val;
2069
99
      MI->flat_insn->detail->arm64.op_count++;
2070
99
    }
2071
665
  } else {
2072
665
    printUInt32Bang(O, Val);
2073
2074
665
    if (MI->csh->detail) {
2075
665
#ifndef CAPSTONE_DIET
2076
665
      uint8_t access;
2077
2078
665
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2079
665
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2080
665
      MI->ac_idx++;
2081
665
#endif
2082
665
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
2083
665
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;
2084
665
      MI->flat_insn->detail->arm64.op_count++;
2085
665
    }
2086
665
  }
2087
764
}
2088
2089
211
static void printBarriernXSOption(MCInst *MI, unsigned OpNo, SStream *O) {
2090
211
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, OpNo));
2091
  // assert(MI->getOpcode() == AArch64::DSBnXS);
2092
2093
211
  const char *Name = NULL;
2094
211
  const DBnXS *DB = lookupDBnXSByEncoding(Val);
2095
211
  Name = DB ? DB->Name : NULL;
2096
2097
211
  if (Name) {
2098
211
    SStream_concat0(O, Name);
2099
2100
211
    if (MI->csh->detail) {
2101
211
#ifndef CAPSTONE_DIET
2102
211
      uint8_t access;
2103
2104
211
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2105
211
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2106
211
      MI->ac_idx++;
2107
211
#endif
2108
211
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_BARRIER;
2109
211
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].barrier = Val;
2110
211
      MI->flat_insn->detail->arm64.op_count++;
2111
211
    }
2112
211
  }
2113
0
  else {
2114
0
    printUInt32Bang(O, Val);
2115
2116
0
    if (MI->csh->detail) {
2117
0
#ifndef CAPSTONE_DIET
2118
0
      uint8_t access;
2119
2120
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2121
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2122
0
      MI->ac_idx++;
2123
0
#endif
2124
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
2125
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;
2126
0
      MI->flat_insn->detail->arm64.op_count++;
2127
0
    }
2128
0
  }
2129
211
}
2130
2131
static void printMRSSystemRegister(MCInst *MI, unsigned OpNum, SStream *O)
2132
2.25k
{
2133
2.25k
  unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
2134
2.25k
  const SysReg *Reg = lookupSysRegByEncoding(Val);
2135
2136
  // Horrible hack for the one register that has identical encodings but
2137
  // different names in MSR and MRS. Because of this, one of MRS and MSR is
2138
  // going to get the wrong entry
2139
2.25k
  if (Val == ARM64_SYSREG_DBGDTRRX_EL0) {
2140
195
    SStream_concat0(O, "dbgdtrrx_el0");
2141
2142
195
    if (MI->csh->detail) {
2143
195
#ifndef CAPSTONE_DIET
2144
195
      uint8_t access;
2145
2146
195
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2147
195
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2148
195
      MI->ac_idx++;
2149
195
#endif
2150
2151
195
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SYS;
2152
195
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = Val;
2153
195
      MI->flat_insn->detail->arm64.op_count++;
2154
195
    }
2155
2156
195
    return;
2157
195
  }
2158
2159
  // Another hack for a register which has an alternative name which is not an alias,
2160
  // and is not in the Armv9-A documentation.
2161
2.06k
  if( Val == ARM64_SYSREG_VSCTLR_EL2){
2162
83
    SStream_concat0(O, "ttbr0_el2");
2163
2164
83
    if (MI->csh->detail) {
2165
83
#ifndef CAPSTONE_DIET
2166
83
      uint8_t access;
2167
2168
83
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2169
83
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2170
83
      MI->ac_idx++;
2171
83
#endif
2172
2173
83
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SYS;
2174
83
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = Val;
2175
83
      MI->flat_insn->detail->arm64.op_count++;
2176
83
    }
2177
2178
83
    return;
2179
83
  }
2180
2181
  // if (Reg && Reg->Readable && Reg->haveFeatures(STI.getFeatureBits()))
2182
1.97k
  if (Reg && Reg->Readable) {
2183
394
    SStream_concat0(O, Reg->Name);
2184
2185
394
    if (MI->csh->detail) {
2186
394
#ifndef CAPSTONE_DIET
2187
394
      uint8_t access;
2188
2189
394
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2190
394
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2191
394
      MI->ac_idx++;
2192
394
#endif
2193
2194
394
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SYS;
2195
394
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = Reg->Encoding;
2196
394
      MI->flat_insn->detail->arm64.op_count++;
2197
394
    }
2198
1.58k
  } else {
2199
1.58k
    char result[128];
2200
2201
1.58k
    AArch64SysReg_genericRegisterString(Val, result);
2202
1.58k
    SStream_concat0(O, result);
2203
2204
1.58k
    if (MI->csh->detail) {
2205
1.58k
#ifndef CAPSTONE_DIET
2206
1.58k
      uint8_t access;
2207
1.58k
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2208
1.58k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2209
1.58k
      MI->ac_idx++;
2210
1.58k
#endif
2211
1.58k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG_MRS;
2212
1.58k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Val;
2213
1.58k
      MI->flat_insn->detail->arm64.op_count++;
2214
1.58k
    }
2215
1.58k
  }
2216
1.97k
}
2217
2218
static void printMSRSystemRegister(MCInst *MI, unsigned OpNum, SStream *O)
2219
6.44k
{
2220
6.44k
  unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
2221
6.44k
  const SysReg *Reg = lookupSysRegByEncoding(Val);
2222
2223
  // Horrible hack for the one register that has identical encodings but
2224
  // different names in MSR and MRS. Because of this, one of MRS and MSR is
2225
  // going to get the wrong entry
2226
6.44k
  if (Val == ARM64_SYSREG_DBGDTRTX_EL0) {
2227
495
    SStream_concat0(O, "dbgdtrtx_el0");
2228
2229
495
    if (MI->csh->detail) {
2230
495
#ifndef CAPSTONE_DIET
2231
495
      uint8_t access;
2232
2233
495
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2234
495
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2235
495
      MI->ac_idx++;
2236
495
#endif
2237
2238
495
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SYS;
2239
495
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = Val;
2240
495
      MI->flat_insn->detail->arm64.op_count++;
2241
495
    }
2242
2243
495
    return;
2244
495
  }
2245
2246
  // Another hack for a register which has an alternative name which is not an alias,
2247
  // and is not in the Armv9-A documentation.
2248
5.95k
  if( Val == ARM64_SYSREG_VSCTLR_EL2){
2249
446
    SStream_concat0(O, "ttbr0_el2");
2250
2251
446
    if (MI->csh->detail) {
2252
446
#ifndef CAPSTONE_DIET
2253
446
      uint8_t access;
2254
2255
446
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2256
446
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2257
446
      MI->ac_idx++;
2258
446
#endif
2259
2260
446
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SYS;
2261
446
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = Val;
2262
446
      MI->flat_insn->detail->arm64.op_count++;
2263
446
    }
2264
2265
446
    return;
2266
446
  }
2267
2268
  // if (Reg && Reg->Writeable && Reg->haveFeatures(STI.getFeatureBits()))
2269
5.50k
  if (Reg && Reg->Writeable) {
2270
480
    SStream_concat0(O, Reg->Name);
2271
2272
480
    if (MI->csh->detail) {
2273
480
#ifndef CAPSTONE_DIET
2274
480
      uint8_t access;
2275
2276
480
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2277
480
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2278
480
      MI->ac_idx++;
2279
480
#endif
2280
2281
480
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SYS;
2282
480
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = Reg->Encoding;
2283
480
      MI->flat_insn->detail->arm64.op_count++;
2284
480
    }
2285
5.02k
  } else {
2286
5.02k
    char result[128];
2287
2288
5.02k
    AArch64SysReg_genericRegisterString(Val, result);
2289
5.02k
    SStream_concat0(O, result);
2290
2291
5.02k
    if (MI->csh->detail) {
2292
5.02k
#ifndef CAPSTONE_DIET
2293
5.02k
      uint8_t access;
2294
5.02k
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2295
5.02k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2296
5.02k
      MI->ac_idx++;
2297
5.02k
#endif
2298
5.02k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG_MRS;
2299
5.02k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Val;
2300
5.02k
      MI->flat_insn->detail->arm64.op_count++;
2301
5.02k
    }
2302
5.02k
  }
2303
5.50k
}
2304
2305
static void printSystemPStateField(MCInst *MI, unsigned OpNum, SStream *O)
2306
704
{
2307
704
  unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
2308
2309
704
  const PState *PState = lookupPStateByEncoding(Val);
2310
2311
704
  if (PState) {
2312
704
    SStream_concat0(O, PState->Name);
2313
2314
704
    if (MI->csh->detail) {
2315
704
#ifndef CAPSTONE_DIET
2316
704
      uint8_t access;
2317
704
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2318
704
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2319
704
      MI->ac_idx++;
2320
704
#endif
2321
704
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_PSTATE;
2322
704
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].pstate = Val;
2323
704
      MI->flat_insn->detail->arm64.op_count++;
2324
704
    }
2325
704
  } else {
2326
0
    printUInt32Bang(O, Val);
2327
2328
0
    if (MI->csh->detail) {
2329
0
#ifndef CAPSTONE_DIET
2330
0
      unsigned char access;
2331
2332
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2333
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2334
0
      MI->ac_idx++;
2335
0
#endif
2336
2337
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
2338
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;
2339
0
      MI->flat_insn->detail->arm64.op_count++;
2340
0
    }
2341
0
  }
2342
704
}
2343
2344
static void printSIMDType10Operand(MCInst *MI, unsigned OpNum, SStream *O)
2345
2.11k
{
2346
2.11k
  uint8_t RawVal = (uint8_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
2347
2.11k
  uint64_t Val = AArch64_AM_decodeAdvSIMDModImmType10(RawVal);
2348
2349
2.11k
  SStream_concat(O, "#%#016llx", Val);
2350
2351
2.11k
  if (MI->csh->detail) {
2352
2.11k
#ifndef CAPSTONE_DIET
2353
2.11k
    unsigned char access;
2354
2355
2.11k
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2356
2.11k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2357
2.11k
    MI->ac_idx++;
2358
2.11k
#endif
2359
2.11k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
2360
2.11k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;
2361
2.11k
    MI->flat_insn->detail->arm64.op_count++;
2362
2.11k
  }
2363
2.11k
}
2364
2365
static void printComplexRotationOp(MCInst *MI, unsigned OpNum, SStream *O, int64_t Angle, int64_t Remainder)
2366
3.53k
{
2367
3.53k
  unsigned int Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
2368
3.53k
  printInt64Bang(O, (Val * Angle) + Remainder);
2369
3.53k
  op_addImm(MI, (Val * Angle) + Remainder);
2370
3.53k
}
2371
2372
static void printSVCROp(MCInst *MI, unsigned OpNum, SStream *O)
2373
0
{
2374
0
  MCOperand *MO = MCInst_getOperand(MI, OpNum);
2375
    // assert(MCOperand_isImm(MO) && "Unexpected operand type!");
2376
0
    unsigned svcrop = MCOperand_getImm(MO);
2377
0
  const SVCR *svcr = lookupSVCRByEncoding(svcrop);
2378
    // assert(svcr && "Unexpected SVCR operand!");
2379
0
  SStream_concat0(O, svcr->Name);
2380
2381
0
  if (MI->csh->detail) {
2382
0
#ifndef CAPSTONE_DIET
2383
0
    uint8_t access;
2384
2385
0
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2386
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2387
0
    MI->ac_idx++;
2388
0
#endif
2389
2390
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SVCR;
2391
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = (unsigned)ARM64_SYSREG_SVCR;
2392
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].svcr = svcr->Encoding;
2393
0
    MI->flat_insn->detail->arm64.op_count++;
2394
0
  }
2395
0
}
2396
2397
static void printMatrix(MCInst *MI, unsigned OpNum, SStream *O, int EltSize)
2398
640
{
2399
640
  MCOperand *RegOp = MCInst_getOperand(MI, OpNum);
2400
    // assert(MCOperand_isReg(RegOp) && "Unexpected operand type!");
2401
640
  unsigned Reg = MCOperand_getReg(RegOp);
2402
2403
640
  SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));
2404
640
  const char *sizeStr = "";
2405
640
    switch (EltSize) {
2406
640
    case 0:
2407
640
    sizeStr = "";
2408
640
      break;
2409
0
    case 8:
2410
0
      sizeStr = ".b";
2411
0
      break;
2412
0
    case 16:
2413
0
      sizeStr = ".h";
2414
0
      break;
2415
0
    case 32:
2416
0
      sizeStr = ".s";
2417
0
      break;
2418
0
    case 64:
2419
0
      sizeStr = ".d";
2420
0
      break;
2421
0
    case 128:
2422
0
      sizeStr = ".q";
2423
0
      break;
2424
0
    default:
2425
0
    break;
2426
    //   llvm_unreachable("Unsupported element size");
2427
640
    }
2428
640
  SStream_concat0(O, sizeStr);
2429
2430
640
  if (MI->csh->detail) {
2431
640
#ifndef CAPSTONE_DIET
2432
640
    uint8_t access;
2433
2434
640
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2435
640
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2436
640
    MI->ac_idx++;
2437
640
#endif
2438
2439
640
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
2440
640
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;
2441
640
    MI->flat_insn->detail->arm64.op_count++;
2442
640
  }
2443
640
}
2444
2445
static void printMatrixIndex(MCInst *MI, unsigned OpNum, SStream *O)
2446
9.74k
{
2447
9.74k
  int64_t imm = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
2448
9.74k
  printInt64(O, imm);
2449
2450
9.74k
  if (MI->csh->detail) {
2451
9.74k
    if (MI->csh->doing_SME_Index) {
2452
      // Access op_count-1 as We want to add info to previous operand, not create a new one
2453
9.74k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count-1].sme_index.disp = imm;
2454
9.74k
    }
2455
9.74k
  }
2456
9.74k
}
2457
2458
static void printMatrixTile(MCInst *MI, unsigned OpNum, SStream *O)
2459
1.87k
{
2460
1.87k
  MCOperand *RegOp = MCInst_getOperand(MI, OpNum);
2461
    // assert(MCOperand_isReg(RegOp) && "Unexpected operand type!");
2462
1.87k
  unsigned Reg = MCOperand_getReg(RegOp);
2463
1.87k
    SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));
2464
2465
1.87k
  if (MI->csh->detail) {
2466
1.87k
#ifndef CAPSTONE_DIET
2467
1.87k
    uint8_t access;
2468
2469
1.87k
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2470
1.87k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2471
1.87k
    MI->ac_idx++;
2472
1.87k
#endif
2473
2474
1.87k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
2475
1.87k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;
2476
1.87k
    MI->flat_insn->detail->arm64.op_count++;
2477
1.87k
  }
2478
1.87k
}
2479
2480
static void printMatrixTileVector(MCInst *MI, unsigned OpNum, SStream *O, bool IsVertical)
2481
8.31k
{
2482
8.31k
  MCOperand *RegOp = MCInst_getOperand(MI, OpNum);
2483
    // assert(MCOperand_isReg(RegOp) && "Unexpected operand type!");
2484
8.31k
  unsigned Reg = MCOperand_getReg(RegOp);
2485
8.31k
#ifndef CAPSTONE_DIET
2486
8.31k
  const char *RegName = getRegisterName(Reg, AArch64_NoRegAltName);
2487
2488
8.31k
  const size_t strLn = strlen(RegName);
2489
  // +2 for extra chars, + 1 for null char \0
2490
8.31k
  char *RegNameNew = cs_mem_malloc(sizeof(char) * (strLn + 2 + 1));
2491
8.31k
  int index = 0, i;
2492
67.0k
  for (i = 0; i < (strLn + 2); i++){
2493
58.7k
    if(RegName[i] != '.'){
2494
50.4k
      RegNameNew[index] = RegName[i];
2495
50.4k
      index++;
2496
50.4k
    }
2497
8.31k
    else{
2498
8.31k
      RegNameNew[index] = IsVertical ? 'v' : 'h';
2499
8.31k
      RegNameNew[index + 1] = '.';
2500
8.31k
      index += 2;
2501
8.31k
    }
2502
58.7k
  }
2503
8.31k
  SStream_concat0(O, RegNameNew);
2504
8.31k
#endif
2505
2506
8.31k
  if (MI->csh->detail) {
2507
8.31k
#ifndef CAPSTONE_DIET
2508
8.31k
    uint8_t access;
2509
2510
8.31k
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2511
8.31k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2512
8.31k
    MI->ac_idx++;
2513
8.31k
#endif
2514
2515
8.31k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
2516
8.31k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;
2517
8.31k
    MI->flat_insn->detail->arm64.op_count++;
2518
8.31k
  }
2519
8.31k
#ifndef CAPSTONE_DIET
2520
8.31k
  cs_mem_free(RegNameNew);
2521
8.31k
#endif
2522
8.31k
}
2523
2524
static const unsigned MatrixZADRegisterTable[] = {
2525
  AArch64_ZAD0, AArch64_ZAD1, AArch64_ZAD2, AArch64_ZAD3,
2526
  AArch64_ZAD4, AArch64_ZAD5, AArch64_ZAD6, AArch64_ZAD7
2527
};
2528
2529
676
static void printMatrixTileList(MCInst *MI, unsigned OpNum, SStream *O){
2530
676
  unsigned MaxRegs = 8;
2531
676
  unsigned RegMask = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
2532
2533
676
  unsigned NumRegs = 0, I;
2534
6.08k
  for (I = 0; I < MaxRegs; ++I)
2535
5.40k
    if ((RegMask & (1 << I)) != 0)
2536
1.84k
      ++NumRegs;
2537
2538
676
  SStream_concat0(O, "{");
2539
676
  unsigned Printed = 0, J;
2540
6.08k
  for (J = 0; J < MaxRegs; ++J) {
2541
5.40k
    unsigned Reg = RegMask & (1 << J);
2542
5.40k
    if (Reg == 0)
2543
3.55k
      continue;
2544
1.84k
    SStream_concat0(O, getRegisterName(MatrixZADRegisterTable[J], AArch64_NoRegAltName));
2545
2546
1.84k
    if (MI->csh->detail) {
2547
1.84k
#ifndef CAPSTONE_DIET
2548
1.84k
      uint8_t access;
2549
2550
1.84k
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2551
1.84k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2552
1.84k
      MI->ac_idx++;
2553
1.84k
#endif
2554
2555
1.84k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
2556
1.84k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MatrixZADRegisterTable[J];
2557
1.84k
      MI->flat_insn->detail->arm64.op_count++;
2558
1.84k
    }
2559
2560
1.84k
    if (Printed + 1 != NumRegs)
2561
1.18k
      SStream_concat0(O, ", ");
2562
1.84k
    ++Printed;
2563
1.84k
  }
2564
676
  SStream_concat0(O, "}");
2565
676
}
2566
2567
static void printSVEPattern(MCInst *MI, unsigned OpNum, SStream *O)
2568
4.52k
{
2569
4.52k
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
2570
2571
4.52k
  const SVEPREDPAT *Pat = lookupSVEPREDPATByEncoding(Val);
2572
4.52k
  if (Pat)
2573
3.72k
    SStream_concat0(O, Pat->Name);
2574
802
  else
2575
802
    printUInt32Bang(O, Val);
2576
4.52k
}
2577
2578
// default suffix = 0
2579
static void printSVERegOp(MCInst *MI, unsigned OpNum, SStream *O, char suffix)
2580
180k
{
2581
180k
  unsigned int Reg;
2582
2583
#if 0
2584
  switch (suffix) {
2585
    case 0:
2586
    case 'b':
2587
    case 'h':
2588
    case 's':
2589
    case 'd':
2590
    case 'q':
2591
      break;
2592
    default:
2593
      // llvm_unreachable("Invalid kind specifier.");
2594
  }
2595
#endif
2596
2597
180k
  Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
2598
2599
180k
  if (MI->csh->detail) {
2600
180k
#ifndef CAPSTONE_DIET
2601
180k
      uint8_t access;
2602
2603
180k
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2604
180k
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2605
180k
      MI->ac_idx++;
2606
180k
#endif
2607
180k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
2608
180k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;
2609
180k
    MI->flat_insn->detail->arm64.op_count++;
2610
180k
  }
2611
2612
180k
  SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));
2613
2614
180k
  if (suffix != '\0')
2615
119k
    SStream_concat(O, ".%c", suffix);
2616
180k
}
2617
2618
static void printImmSVE16(int16_t Val, SStream *O)
2619
1.85k
{
2620
1.85k
  printUInt32Bang(O, Val);
2621
1.85k
}
2622
2623
static void printImmSVE32(int32_t Val, SStream *O)
2624
2.41k
{
2625
2.41k
  printUInt32Bang(O, Val);
2626
2.41k
}
2627
2628
static void printImmSVE64(int64_t Val, SStream *O)
2629
1.70k
{
2630
1.70k
  printUInt64Bang(O, Val);
2631
1.70k
}
2632
2633
static void printImm8OptLsl32(MCInst *MI, unsigned OpNum, SStream *O)
2634
2.49k
{
2635
2.49k
  unsigned UnscaledVal = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
2636
2.49k
  unsigned Shift = MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));
2637
2.49k
  uint32_t Val;
2638
2639
  // assert(AArch64_AM::getShiftType(Shift) == AArch64_AM::LSL &&
2640
  //  "Unexepected shift type!");
2641
2642
  // #0 lsl #8 is never pretty printed
2643
2.49k
  if ((UnscaledVal == 0) && (AArch64_AM_getShiftValue(Shift) != 0)) {
2644
78
    printUInt32Bang(O, UnscaledVal);
2645
78
    printShifter(MI, OpNum + 1, O);
2646
78
    return;
2647
78
  }
2648
2649
2.41k
  Val = UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift));
2650
2.41k
  printImmSVE32(Val, O);
2651
2.41k
}
2652
2653
static void printImm8OptLsl64(MCInst *MI, unsigned OpNum, SStream *O)
2654
588
{
2655
588
  unsigned UnscaledVal = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
2656
588
  unsigned Shift = MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));
2657
588
  uint64_t Val;
2658
2659
  // assert(AArch64_AM::getShiftType(Shift) == AArch64_AM::LSL &&
2660
  //  "Unexepected shift type!");
2661
2662
  // #0 lsl #8 is never pretty printed
2663
588
  if ((UnscaledVal == 0) && (AArch64_AM_getShiftValue(Shift) != 0)) {
2664
87
    printUInt32Bang(O, UnscaledVal);
2665
87
    printShifter(MI, OpNum + 1, O);
2666
87
    return;
2667
87
  }
2668
2669
501
  Val = UnscaledVal * (1 << AArch64_AM_getShiftValue(Shift));
2670
501
  printImmSVE64(Val, O);
2671
501
}
2672
2673
static void printSVELogicalImm16(MCInst *MI, unsigned OpNum, SStream *O)
2674
1.41k
{
2675
1.41k
  uint64_t Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
2676
1.41k
  uint64_t PrintVal = AArch64_AM_decodeLogicalImmediate(Val, 64);
2677
2678
  // Prefer the default format for 16bit values, hex otherwise.
2679
1.41k
  printImmSVE16(PrintVal, O);
2680
1.41k
}
2681
2682
static void printSVELogicalImm32(MCInst *MI, unsigned OpNum, SStream *O)
2683
994
{
2684
994
  uint64_t Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
2685
994
  uint64_t PrintVal = AArch64_AM_decodeLogicalImmediate(Val, 64);
2686
2687
  // Prefer the default format for 16bit values, hex otherwise.
2688
994
  if ((uint16_t)PrintVal == (uint32_t)PrintVal)
2689
438
    printImmSVE16(PrintVal, O);
2690
556
  else
2691
556
    printUInt64Bang(O, PrintVal);
2692
994
}
2693
2694
static void printSVELogicalImm64(MCInst *MI, unsigned OpNum, SStream *O)
2695
1.20k
{
2696
1.20k
  uint64_t Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
2697
1.20k
  uint64_t PrintVal = AArch64_AM_decodeLogicalImmediate(Val, 64);
2698
2699
1.20k
  printImmSVE64(PrintVal, O);
2700
1.20k
}
2701
2702
static void printZPRasFPR(MCInst *MI, unsigned OpNum, SStream *O, int Width)
2703
2.05k
{
2704
2.05k
  unsigned int Base, Reg;
2705
2706
2.05k
  switch (Width) {
2707
0
    default: // llvm_unreachable("Unsupported width");
2708
180
    case 8:   Base = AArch64_B0; break;
2709
548
    case 16:  Base = AArch64_H0; break;
2710
300
    case 32:  Base = AArch64_S0; break;
2711
804
    case 64:  Base = AArch64_D0; break;
2712
227
    case 128: Base = AArch64_Q0; break;
2713
2.05k
  }
2714
2715
2.05k
  Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) - AArch64_Z0 + Base;
2716
2717
2.05k
  SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));
2718
2719
2.05k
  if (MI->csh->detail) {
2720
2.05k
#ifndef CAPSTONE_DIET
2721
2.05k
    uint8_t access;
2722
2723
2.05k
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
2724
2.05k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
2725
2.05k
    MI->ac_idx++;
2726
2.05k
#endif
2727
2.05k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
2728
2.05k
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;
2729
2.05k
    MI->flat_insn->detail->arm64.op_count++;
2730
2.05k
  }
2731
2.05k
}
2732
2733
static void printExactFPImm(MCInst *MI, unsigned OpNum, SStream *O, unsigned ImmIs0, unsigned ImmIs1)
2734
678
{
2735
678
  const ExactFPImm *Imm0Desc = lookupExactFPImmByEnum(ImmIs0);
2736
678
  const ExactFPImm *Imm1Desc = lookupExactFPImmByEnum(ImmIs1);
2737
678
  unsigned Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
2738
2739
678
  SStream_concat0(O, Val ? Imm1Desc->Repr : Imm0Desc->Repr);
2740
678
}
2741
2742
static void printGPR64as32(MCInst *MI, unsigned OpNum, SStream *O)
2743
4.05k
{
2744
4.05k
  unsigned int Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
2745
2746
4.05k
  SStream_concat0(O, getRegisterName(getWRegFromXReg(Reg), AArch64_NoRegAltName));
2747
4.05k
}
2748
2749
static void printGPR64x8(MCInst *MI, unsigned OpNum, SStream *O) 
2750
1.32k
{
2751
1.32k
    unsigned int Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
2752
2753
1.32k
    SStream_concat0(O, getRegisterName(MCRegisterInfo_getSubReg(MI->MRI, Reg, AArch64_x8sub_0), AArch64_NoRegAltName));
2754
1.32k
}
2755
2756
#define PRINT_ALIAS_INSTR
2757
#include "AArch64GenAsmWriter.inc"
2758
#include "AArch64GenRegisterName.inc"
2759
2760
void AArch64_post_printer(csh handle, cs_insn *flat_insn, char *insn_asm, MCInst *mci)
2761
443k
{
2762
443k
  if (((cs_struct *)handle)->detail != CS_OPT_ON)
2763
0
    return;
2764
2765
443k
  if (mci->csh->detail) {
2766
443k
    unsigned opcode = MCInst_getOpcode(mci);
2767
2768
443k
    switch (opcode) {
2769
343k
      default:
2770
343k
        break;
2771
343k
      case AArch64_LD1Fourv16b_POST:
2772
298
      case AArch64_LD1Fourv1d_POST:
2773
431
      case AArch64_LD1Fourv2d_POST:
2774
1.08k
      case AArch64_LD1Fourv2s_POST:
2775
1.22k
      case AArch64_LD1Fourv4h_POST:
2776
2.21k
      case AArch64_LD1Fourv4s_POST:
2777
2.98k
      case AArch64_LD1Fourv8b_POST:
2778
3.79k
      case AArch64_LD1Fourv8h_POST:
2779
4.19k
      case AArch64_LD1Onev16b_POST:
2780
4.29k
      case AArch64_LD1Onev1d_POST:
2781
5.13k
      case AArch64_LD1Onev2d_POST:
2782
5.51k
      case AArch64_LD1Onev2s_POST:
2783
5.72k
      case AArch64_LD1Onev4h_POST:
2784
5.83k
      case AArch64_LD1Onev4s_POST:
2785
6.15k
      case AArch64_LD1Onev8b_POST:
2786
6.82k
      case AArch64_LD1Onev8h_POST:
2787
7.58k
      case AArch64_LD1Rv16b_POST:
2788
7.89k
      case AArch64_LD1Rv1d_POST:
2789
8.43k
      case AArch64_LD1Rv2d_POST:
2790
8.66k
      case AArch64_LD1Rv2s_POST:
2791
8.73k
      case AArch64_LD1Rv4h_POST:
2792
8.94k
      case AArch64_LD1Rv4s_POST:
2793
9.34k
      case AArch64_LD1Rv8b_POST:
2794
9.74k
      case AArch64_LD1Rv8h_POST:
2795
10.1k
      case AArch64_LD1Threev16b_POST:
2796
12.3k
      case AArch64_LD1Threev1d_POST:
2797
12.3k
      case AArch64_LD1Threev2d_POST:
2798
12.8k
      case AArch64_LD1Threev2s_POST:
2799
12.9k
      case AArch64_LD1Threev4h_POST:
2800
13.7k
      case AArch64_LD1Threev4s_POST:
2801
13.9k
      case AArch64_LD1Threev8b_POST:
2802
13.9k
      case AArch64_LD1Threev8h_POST:
2803
14.2k
      case AArch64_LD1Twov16b_POST:
2804
15.0k
      case AArch64_LD1Twov1d_POST:
2805
15.5k
      case AArch64_LD1Twov2d_POST:
2806
15.7k
      case AArch64_LD1Twov2s_POST:
2807
15.8k
      case AArch64_LD1Twov4h_POST:
2808
16.1k
      case AArch64_LD1Twov4s_POST:
2809
16.6k
      case AArch64_LD1Twov8b_POST:
2810
18.1k
      case AArch64_LD1Twov8h_POST:
2811
18.6k
      case AArch64_LD1i16_POST:
2812
20.0k
      case AArch64_LD1i32_POST:
2813
20.9k
      case AArch64_LD1i64_POST:
2814
22.5k
      case AArch64_LD1i8_POST:
2815
23.0k
      case AArch64_LD2Rv16b_POST:
2816
23.2k
      case AArch64_LD2Rv1d_POST:
2817
23.5k
      case AArch64_LD2Rv2d_POST:
2818
23.7k
      case AArch64_LD2Rv2s_POST:
2819
24.2k
      case AArch64_LD2Rv4h_POST:
2820
24.2k
      case AArch64_LD2Rv4s_POST:
2821
24.5k
      case AArch64_LD2Rv8b_POST:
2822
24.7k
      case AArch64_LD2Rv8h_POST:
2823
25.3k
      case AArch64_LD2Twov16b_POST:
2824
25.5k
      case AArch64_LD2Twov2d_POST:
2825
25.6k
      case AArch64_LD2Twov2s_POST:
2826
25.8k
      case AArch64_LD2Twov4h_POST:
2827
25.9k
      case AArch64_LD2Twov4s_POST:
2828
26.3k
      case AArch64_LD2Twov8b_POST:
2829
27.4k
      case AArch64_LD2Twov8h_POST:
2830
28.5k
      case AArch64_LD2i16_POST:
2831
29.2k
      case AArch64_LD2i32_POST:
2832
30.8k
      case AArch64_LD2i64_POST:
2833
31.9k
      case AArch64_LD2i8_POST:
2834
32.3k
      case AArch64_LD3Rv16b_POST:
2835
32.3k
      case AArch64_LD3Rv1d_POST:
2836
33.1k
      case AArch64_LD3Rv2d_POST:
2837
33.3k
      case AArch64_LD3Rv2s_POST:
2838
33.4k
      case AArch64_LD3Rv4h_POST:
2839
33.6k
      case AArch64_LD3Rv4s_POST:
2840
33.9k
      case AArch64_LD3Rv8b_POST:
2841
34.9k
      case AArch64_LD3Rv8h_POST:
2842
35.1k
      case AArch64_LD3Threev16b_POST:
2843
35.4k
      case AArch64_LD3Threev2d_POST:
2844
35.6k
      case AArch64_LD3Threev2s_POST:
2845
35.6k
      case AArch64_LD3Threev4h_POST:
2846
36.0k
      case AArch64_LD3Threev4s_POST:
2847
36.1k
      case AArch64_LD3Threev8b_POST:
2848
36.2k
      case AArch64_LD3Threev8h_POST:
2849
37.7k
      case AArch64_LD3i16_POST:
2850
38.7k
      case AArch64_LD3i32_POST:
2851
40.9k
      case AArch64_LD3i64_POST:
2852
42.2k
      case AArch64_LD3i8_POST:
2853
42.5k
      case AArch64_LD4Fourv16b_POST:
2854
42.7k
      case AArch64_LD4Fourv2d_POST:
2855
42.9k
      case AArch64_LD4Fourv2s_POST:
2856
43.1k
      case AArch64_LD4Fourv4h_POST:
2857
43.8k
      case AArch64_LD4Fourv4s_POST:
2858
44.2k
      case AArch64_LD4Fourv8b_POST:
2859
44.3k
      case AArch64_LD4Fourv8h_POST:
2860
44.4k
      case AArch64_LD4Rv16b_POST:
2861
44.6k
      case AArch64_LD4Rv1d_POST:
2862
44.7k
      case AArch64_LD4Rv2d_POST:
2863
45.8k
      case AArch64_LD4Rv2s_POST:
2864
45.8k
      case AArch64_LD4Rv4h_POST:
2865
46.3k
      case AArch64_LD4Rv4s_POST:
2866
46.4k
      case AArch64_LD4Rv8b_POST:
2867
46.8k
      case AArch64_LD4Rv8h_POST:
2868
47.4k
      case AArch64_LD4i16_POST:
2869
48.1k
      case AArch64_LD4i32_POST:
2870
49.2k
      case AArch64_LD4i64_POST:
2871
50.2k
      case AArch64_LD4i8_POST:
2872
50.3k
      case AArch64_LDRBBpost:
2873
50.6k
      case AArch64_LDRBpost:
2874
50.8k
      case AArch64_LDRDpost:
2875
50.9k
      case AArch64_LDRHHpost:
2876
50.9k
      case AArch64_LDRHpost:
2877
51.1k
      case AArch64_LDRQpost:
2878
51.5k
      case AArch64_LDPDpost:
2879
51.7k
      case AArch64_LDPQpost:
2880
52.0k
      case AArch64_LDPSWpost:
2881
52.2k
      case AArch64_LDPSpost:
2882
52.7k
      case AArch64_LDPWpost:
2883
53.2k
      case AArch64_LDPXpost:
2884
53.2k
      case AArch64_ST1Fourv16b_POST:
2885
53.8k
      case AArch64_ST1Fourv1d_POST:
2886
54.2k
      case AArch64_ST1Fourv2d_POST:
2887
54.5k
      case AArch64_ST1Fourv2s_POST:
2888
54.6k
      case AArch64_ST1Fourv4h_POST:
2889
54.8k
      case AArch64_ST1Fourv4s_POST:
2890
55.2k
      case AArch64_ST1Fourv8b_POST:
2891
55.7k
      case AArch64_ST1Fourv8h_POST:
2892
55.8k
      case AArch64_ST1Onev16b_POST:
2893
56.0k
      case AArch64_ST1Onev1d_POST:
2894
56.1k
      case AArch64_ST1Onev2d_POST:
2895
56.4k
      case AArch64_ST1Onev2s_POST:
2896
56.5k
      case AArch64_ST1Onev4h_POST:
2897
56.7k
      case AArch64_ST1Onev4s_POST:
2898
57.0k
      case AArch64_ST1Onev8b_POST:
2899
57.0k
      case AArch64_ST1Onev8h_POST:
2900
57.1k
      case AArch64_ST1Threev16b_POST:
2901
57.2k
      case AArch64_ST1Threev1d_POST:
2902
57.7k
      case AArch64_ST1Threev2d_POST:
2903
57.9k
      case AArch64_ST1Threev2s_POST:
2904
58.7k
      case AArch64_ST1Threev4h_POST:
2905
58.8k
      case AArch64_ST1Threev4s_POST:
2906
59.6k
      case AArch64_ST1Threev8b_POST:
2907
59.8k
      case AArch64_ST1Threev8h_POST:
2908
60.0k
      case AArch64_ST1Twov16b_POST:
2909
60.2k
      case AArch64_ST1Twov1d_POST:
2910
60.4k
      case AArch64_ST1Twov2d_POST:
2911
60.7k
      case AArch64_ST1Twov2s_POST:
2912
61.0k
      case AArch64_ST1Twov4h_POST:
2913
61.1k
      case AArch64_ST1Twov4s_POST:
2914
61.1k
      case AArch64_ST1Twov8b_POST:
2915
61.5k
      case AArch64_ST1Twov8h_POST:
2916
62.2k
      case AArch64_ST1i16_POST:
2917
62.4k
      case AArch64_ST1i32_POST:
2918
62.7k
      case AArch64_ST1i64_POST:
2919
64.6k
      case AArch64_ST1i8_POST:
2920
64.6k
      case AArch64_ST2GPostIndex:
2921
65.1k
      case AArch64_ST2Twov16b_POST:
2922
65.2k
      case AArch64_ST2Twov2d_POST:
2923
65.4k
      case AArch64_ST2Twov2s_POST:
2924
65.7k
      case AArch64_ST2Twov4h_POST:
2925
65.7k
      case AArch64_ST2Twov4s_POST:
2926
66.1k
      case AArch64_ST2Twov8b_POST:
2927
66.7k
      case AArch64_ST2Twov8h_POST:
2928
67.2k
      case AArch64_ST2i16_POST:
2929
67.6k
      case AArch64_ST2i32_POST:
2930
68.4k
      case AArch64_ST2i64_POST:
2931
69.3k
      case AArch64_ST2i8_POST:
2932
69.4k
      case AArch64_ST3Threev16b_POST:
2933
69.6k
      case AArch64_ST3Threev2d_POST:
2934
70.9k
      case AArch64_ST3Threev2s_POST:
2935
71.0k
      case AArch64_ST3Threev4h_POST:
2936
71.5k
      case AArch64_ST3Threev4s_POST:
2937
71.8k
      case AArch64_ST3Threev8b_POST:
2938
72.0k
      case AArch64_ST3Threev8h_POST:
2939
72.6k
      case AArch64_ST3i16_POST:
2940
73.5k
      case AArch64_ST3i32_POST:
2941
73.7k
      case AArch64_ST3i64_POST:
2942
74.0k
      case AArch64_ST3i8_POST:
2943
74.9k
      case AArch64_ST4Fourv16b_POST:
2944
75.1k
      case AArch64_ST4Fourv2d_POST:
2945
75.2k
      case AArch64_ST4Fourv2s_POST:
2946
75.3k
      case AArch64_ST4Fourv4h_POST:
2947
75.4k
      case AArch64_ST4Fourv4s_POST:
2948
75.9k
      case AArch64_ST4Fourv8b_POST:
2949
76.4k
      case AArch64_ST4Fourv8h_POST:
2950
76.9k
      case AArch64_ST4i16_POST:
2951
78.9k
      case AArch64_ST4i32_POST:
2952
79.3k
      case AArch64_ST4i64_POST:
2953
79.4k
      case AArch64_ST4i8_POST:
2954
79.7k
      case AArch64_STPDpost:
2955
80.3k
      case AArch64_STPQpost:
2956
80.6k
      case AArch64_STPSpost:
2957
81.3k
      case AArch64_STPWpost:
2958
81.5k
      case AArch64_STPXpost:
2959
81.7k
      case AArch64_STRBBpost:
2960
81.8k
      case AArch64_STRBpost:
2961
82.4k
      case AArch64_STRDpost:
2962
82.7k
      case AArch64_STRHHpost:
2963
82.8k
      case AArch64_STRHpost:
2964
83.3k
      case AArch64_STRQpost:
2965
83.4k
      case AArch64_STRSpost:
2966
83.5k
      case AArch64_STRWpost:
2967
83.7k
      case AArch64_STRXpost:
2968
83.8k
      case AArch64_STZ2GPostIndex:
2969
84.0k
      case AArch64_STZGPostIndex:
2970
84.1k
      case AArch64_STGPostIndex:
2971
84.1k
      case AArch64_STGPpost:
2972
84.3k
      case AArch64_LDRSBWpost:
2973
84.5k
      case AArch64_LDRSBXpost:
2974
84.7k
      case AArch64_LDRSHWpost:
2975
85.1k
      case AArch64_LDRSHXpost:
2976
85.2k
      case AArch64_LDRSWpost:
2977
85.4k
      case AArch64_LDRSpost:
2978
85.5k
      case AArch64_LDRWpost:
2979
85.7k
      case AArch64_LDRXpost:
2980
85.7k
        flat_insn->detail->arm64.writeback = true;
2981
85.7k
          flat_insn->detail->arm64.post_index = true;
2982
85.7k
        break;
2983
175
      case AArch64_LDRAAwriteback:
2984
841
      case AArch64_LDRABwriteback:
2985
1.62k
      case AArch64_ST2GPreIndex:
2986
2.10k
      case AArch64_LDPDpre:
2987
2.37k
      case AArch64_LDPQpre:
2988
2.64k
      case AArch64_LDPSWpre:
2989
2.91k
      case AArch64_LDPSpre:
2990
3.06k
      case AArch64_LDPWpre:
2991
3.82k
      case AArch64_LDPXpre:
2992
4.24k
      case AArch64_LDRBBpre:
2993
4.70k
      case AArch64_LDRBpre:
2994
4.93k
      case AArch64_LDRDpre:
2995
5.18k
      case AArch64_LDRHHpre:
2996
5.46k
      case AArch64_LDRHpre:
2997
5.99k
      case AArch64_LDRQpre:
2998
6.26k
      case AArch64_LDRSBWpre:
2999
6.47k
      case AArch64_LDRSBXpre:
3000
6.59k
      case AArch64_LDRSHWpre:
3001
6.66k
      case AArch64_LDRSHXpre:
3002
6.97k
      case AArch64_LDRSWpre:
3003
7.18k
      case AArch64_LDRSpre:
3004
7.38k
      case AArch64_LDRWpre:
3005
7.44k
      case AArch64_LDRXpre:
3006
7.89k
      case AArch64_STGPreIndex:
3007
8.52k
      case AArch64_STPDpre:
3008
9.35k
      case AArch64_STPQpre:
3009
9.69k
      case AArch64_STPSpre:
3010
9.82k
      case AArch64_STPWpre:
3011
10.3k
      case AArch64_STPXpre:
3012
10.6k
      case AArch64_STRBBpre:
3013
10.7k
      case AArch64_STRBpre:
3014
11.1k
      case AArch64_STRDpre:
3015
11.5k
      case AArch64_STRHHpre:
3016
11.8k
      case AArch64_STRHpre:
3017
11.9k
      case AArch64_STRQpre:
3018
12.1k
      case AArch64_STRSpre:
3019
12.2k
      case AArch64_STRWpre:
3020
12.4k
      case AArch64_STRXpre:
3021
13.2k
      case AArch64_STZ2GPreIndex:
3022
13.6k
      case AArch64_STZGPreIndex:
3023
13.6k
      case AArch64_STGPpre:
3024
        flat_insn->detail->arm64.writeback = true;
3025
13.6k
        break;
3026
443k
    }
3027
443k
  }
3028
443k
}
3029
3030
#endif