Coverage Report

Created: 2025-12-05 06:11

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