Coverage Report

Created: 2025-06-13 06:15

/src/bloaty/third_party/capstone/arch/AArch64/AArch64InstPrinter.c
Line
Count
Source (jump to first uncovered line)
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 "AArch64BaseInfo.h"
25
#include "../../utils.h"
26
#include "../../MCInst.h"
27
#include "../../SStream.h"
28
#include "../../MCRegisterInfo.h"
29
#include "../../MathExtras.h"
30
31
#include "AArch64Mapping.h"
32
#include "AArch64AddressingModes.h"
33
34
#define GET_REGINFO_ENUM
35
#include "AArch64GenRegisterInfo.inc"
36
37
#define GET_INSTRINFO_ENUM
38
#include "AArch64GenInstrInfo.inc"
39
40
41
static const char *getRegisterName(unsigned RegNo, int AltIdx);
42
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
43
static bool printSysAlias(MCInst *MI, SStream *O);
44
static char *printAliasInstr(MCInst *MI, SStream *OS, void *info);
45
static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI);
46
static void printShifter(MCInst *MI, unsigned OpNum, SStream *O);
47
48
static cs_ac_type get_op_access(cs_struct *h, unsigned int id, unsigned int index)
49
0
{
50
0
#ifndef CAPSTONE_DIET
51
0
  uint8_t *arr = AArch64_get_op_access(h, id);
52
53
0
  if (arr[index] == CS_AC_IGNORE)
54
0
    return 0;
55
56
0
  return arr[index];
57
#else
58
  return 0;
59
#endif
60
0
}
61
62
static void set_mem_access(MCInst *MI, bool status)
63
0
{
64
0
  MI->csh->doing_mem = status;
65
66
0
  if (MI->csh->detail != CS_OPT_ON)
67
0
    return;
68
69
0
  if (status) {
70
0
#ifndef CAPSTONE_DIET
71
0
    uint8_t access;
72
0
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
73
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
74
0
    MI->ac_idx++;
75
0
#endif
76
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_MEM;
77
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.base = ARM64_REG_INVALID;
78
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.index = ARM64_REG_INVALID;
79
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.disp = 0;
80
0
  } else {
81
    // done, create the next operand slot
82
0
    MI->flat_insn->detail->arm64.op_count++;
83
0
  }
84
0
}
85
86
void AArch64_printInst(MCInst *MI, SStream *O, void *Info)
87
0
{
88
  // Check for special encodings and print the canonical alias instead.
89
0
  unsigned Opcode = MCInst_getOpcode(MI);
90
0
  int LSB;
91
0
  int Width;
92
0
  char *mnem;
93
94
0
  if (Opcode == AArch64_SYSxt && printSysAlias(MI, O))
95
0
    return;
96
97
  // SBFM/UBFM should print to a nicer aliased form if possible.
98
0
  if (Opcode == AArch64_SBFMXri || Opcode == AArch64_SBFMWri ||
99
0
      Opcode == AArch64_UBFMXri || Opcode == AArch64_UBFMWri) {
100
0
    MCOperand *Op0 = MCInst_getOperand(MI, 0);
101
0
    MCOperand *Op1 = MCInst_getOperand(MI, 1);
102
0
    MCOperand *Op2 = MCInst_getOperand(MI, 2);
103
0
    MCOperand *Op3 = MCInst_getOperand(MI, 3);
104
105
0
    bool IsSigned = (Opcode == AArch64_SBFMXri || Opcode == AArch64_SBFMWri);
106
0
    bool Is64Bit = (Opcode == AArch64_SBFMXri || Opcode == AArch64_UBFMXri);
107
108
0
    if (MCOperand_isImm(Op2) && MCOperand_getImm(Op2) == 0 && MCOperand_isImm(Op3)) {
109
0
      const char *AsmMnemonic = NULL;
110
111
0
      switch (MCOperand_getImm(Op3)) {
112
0
        default:
113
0
          break;
114
0
        case 7:
115
0
          if (IsSigned)
116
0
            AsmMnemonic = "sxtb";
117
0
          else if (!Is64Bit)
118
0
            AsmMnemonic = "uxtb";
119
0
          break;
120
0
        case 15:
121
0
          if (IsSigned)
122
0
            AsmMnemonic = "sxth";
123
0
          else if (!Is64Bit)
124
0
            AsmMnemonic = "uxth";
125
0
          break;
126
0
        case 31:
127
          // *xtw is only valid for signed 64-bit operations.
128
0
          if (Is64Bit && IsSigned)
129
0
            AsmMnemonic = "sxtw";
130
0
          break;
131
0
      }
132
133
0
      if (AsmMnemonic) {
134
0
        SStream_concat(O, "%s\t%s, %s", AsmMnemonic,
135
0
            getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
136
0
            getRegisterName(getWRegFromXReg(MCOperand_getReg(Op1)), AArch64_NoRegAltName));
137
138
0
        if (MI->csh->detail) {
139
0
#ifndef CAPSTONE_DIET
140
0
          uint8_t access;
141
0
          access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
142
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
143
0
          MI->ac_idx++;
144
0
#endif
145
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
146
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
147
0
          MI->flat_insn->detail->arm64.op_count++;
148
0
#ifndef CAPSTONE_DIET
149
0
          access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
150
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
151
0
          MI->ac_idx++;
152
0
#endif
153
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
154
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = getWRegFromXReg(MCOperand_getReg(Op1));
155
0
          MI->flat_insn->detail->arm64.op_count++;
156
0
        }
157
158
0
        MCInst_setOpcodePub(MI, AArch64_map_insn(AsmMnemonic));
159
160
0
        return;
161
0
      }
162
0
    }
163
164
    // All immediate shifts are aliases, implemented using the Bitfield
165
    // instruction. In all cases the immediate shift amount shift must be in
166
    // the range 0 to (reg.size -1).
167
0
    if (MCOperand_isImm(Op2) && MCOperand_isImm(Op3)) {
168
0
      const char *AsmMnemonic = NULL;
169
0
      int shift = 0;
170
0
      int immr = (int)MCOperand_getImm(Op2);
171
0
      int imms = (int)MCOperand_getImm(Op3);
172
173
0
      if (Opcode == AArch64_UBFMWri && imms != 0x1F && ((imms + 1) == immr)) {
174
0
        AsmMnemonic = "lsl";
175
0
        shift = 31 - imms;
176
0
      } else if (Opcode == AArch64_UBFMXri && imms != 0x3f &&
177
0
          ((imms + 1 == immr))) {
178
0
        AsmMnemonic = "lsl";
179
0
        shift = 63 - imms;
180
0
      } else if (Opcode == AArch64_UBFMWri && imms == 0x1f) {
181
0
        AsmMnemonic = "lsr";
182
0
        shift = immr;
183
0
      } else if (Opcode == AArch64_UBFMXri && imms == 0x3f) {
184
0
        AsmMnemonic = "lsr";
185
0
        shift = immr;
186
0
      } else if (Opcode == AArch64_SBFMWri && imms == 0x1f) {
187
0
        AsmMnemonic = "asr";
188
0
        shift = immr;
189
0
      } else if (Opcode == AArch64_SBFMXri && imms == 0x3f) {
190
0
        AsmMnemonic = "asr";
191
0
        shift = immr;
192
0
      }
193
194
0
      if (AsmMnemonic) {
195
0
        SStream_concat(O, "%s\t%s, %s, ", AsmMnemonic,
196
0
            getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
197
0
            getRegisterName(MCOperand_getReg(Op1), AArch64_NoRegAltName));
198
199
0
        printInt32Bang(O, shift);
200
201
0
        MCInst_setOpcodePub(MI, AArch64_map_insn(AsmMnemonic));
202
203
0
        if (MI->csh->detail) {
204
0
#ifndef CAPSTONE_DIET
205
0
          uint8_t access;
206
0
          access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
207
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
208
0
          MI->ac_idx++;
209
0
#endif
210
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
211
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
212
0
          MI->flat_insn->detail->arm64.op_count++;
213
0
#ifndef CAPSTONE_DIET
214
0
          access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
215
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
216
0
          MI->ac_idx++;
217
0
#endif
218
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
219
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op1);
220
0
          MI->flat_insn->detail->arm64.op_count++;
221
0
#ifndef CAPSTONE_DIET
222
0
          access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
223
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
224
0
          MI->ac_idx++;
225
0
#endif
226
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
227
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = shift;
228
0
          MI->flat_insn->detail->arm64.op_count++;
229
0
        }
230
231
0
        return;
232
0
      }
233
0
    }
234
235
    // SBFIZ/UBFIZ aliases
236
0
    if (MCOperand_getImm(Op2) > MCOperand_getImm(Op3)) {
237
0
      SStream_concat(O, "%s\t%s, %s, ", (IsSigned ? "sbfiz" : "ubfiz"),
238
0
          getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
239
0
          getRegisterName(MCOperand_getReg(Op1), AArch64_NoRegAltName));
240
0
      printInt32Bang(O, (int)((Is64Bit ? 64 : 32) - MCOperand_getImm(Op2)));
241
0
      SStream_concat0(O, ", ");
242
0
      printInt32Bang(O, (int)MCOperand_getImm(Op3) + 1);
243
244
0
      MCInst_setOpcodePub(MI, AArch64_map_insn(IsSigned ? "sbfiz" : "ubfiz"));
245
246
0
      if (MI->csh->detail) {
247
0
#ifndef CAPSTONE_DIET
248
0
        uint8_t access;
249
0
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
250
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
251
0
        MI->ac_idx++;
252
0
#endif
253
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
254
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
255
0
        MI->flat_insn->detail->arm64.op_count++;
256
0
#ifndef CAPSTONE_DIET
257
0
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
258
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
259
0
        MI->ac_idx++;
260
0
#endif
261
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
262
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op1);
263
0
        MI->flat_insn->detail->arm64.op_count++;
264
0
#ifndef CAPSTONE_DIET
265
0
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
266
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
267
0
        MI->ac_idx++;
268
0
#endif
269
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
270
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (Is64Bit ? 64 : 32) - (int)MCOperand_getImm(Op2);
271
0
        MI->flat_insn->detail->arm64.op_count++;
272
0
#ifndef CAPSTONE_DIET
273
0
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
274
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
275
0
        MI->ac_idx++;
276
0
#endif
277
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
278
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op3) + 1;
279
0
        MI->flat_insn->detail->arm64.op_count++;
280
0
      }
281
282
0
      return;
283
0
    }
284
285
    // Otherwise SBFX/UBFX is the preferred form
286
0
    SStream_concat(O, "%s\t%s, %s, ", (IsSigned ? "sbfx" : "ubfx"),
287
0
        getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
288
0
        getRegisterName(MCOperand_getReg(Op1), AArch64_NoRegAltName));
289
0
    printInt32Bang(O, (int)MCOperand_getImm(Op2));
290
0
    SStream_concat0(O, ", ");
291
0
    printInt32Bang(O, (int)MCOperand_getImm(Op3) - (int)MCOperand_getImm(Op2) + 1);
292
293
0
    MCInst_setOpcodePub(MI, AArch64_map_insn(IsSigned ? "sbfx" : "ubfx"));
294
295
0
    if (MI->csh->detail) {
296
0
#ifndef CAPSTONE_DIET
297
0
      uint8_t access;
298
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
299
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
300
0
      MI->ac_idx++;
301
0
#endif
302
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
303
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
304
0
      MI->flat_insn->detail->arm64.op_count++;
305
0
#ifndef CAPSTONE_DIET
306
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
307
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
308
0
      MI->ac_idx++;
309
0
#endif
310
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
311
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op1);
312
0
      MI->flat_insn->detail->arm64.op_count++;
313
0
#ifndef CAPSTONE_DIET
314
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
315
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
316
0
      MI->ac_idx++;
317
0
#endif
318
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
319
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op2);
320
0
      MI->flat_insn->detail->arm64.op_count++;
321
0
#ifndef CAPSTONE_DIET
322
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
323
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
324
0
      MI->ac_idx++;
325
0
#endif
326
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
327
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op3) - MCOperand_getImm(Op2) + 1;
328
0
      MI->flat_insn->detail->arm64.op_count++;
329
0
    }
330
331
0
    return;
332
0
  }
333
334
0
  if (Opcode == AArch64_BFMXri || Opcode == AArch64_BFMWri) {
335
0
    MCOperand *Op0 = MCInst_getOperand(MI, 0); // Op1 == Op0
336
0
    MCOperand *Op2 = MCInst_getOperand(MI, 2);
337
0
    int ImmR = (int)MCOperand_getImm(MCInst_getOperand(MI, 3));
338
0
    int ImmS = (int)MCOperand_getImm(MCInst_getOperand(MI, 4));
339
340
    // BFI alias
341
0
    if (ImmS < ImmR) {
342
0
      int BitWidth = Opcode == AArch64_BFMXri ? 64 : 32;
343
0
      LSB = (BitWidth - ImmR) % BitWidth;
344
0
      Width = ImmS + 1;
345
346
0
      SStream_concat(O, "bfi\t%s, %s, ",
347
0
          getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
348
0
          getRegisterName(MCOperand_getReg(Op2), AArch64_NoRegAltName));
349
0
      printInt32Bang(O, LSB);
350
0
      SStream_concat0(O, ", ");
351
0
      printInt32Bang(O, Width);
352
0
      MCInst_setOpcodePub(MI, AArch64_map_insn("bfi"));
353
354
0
      if (MI->csh->detail) {
355
0
#ifndef CAPSTONE_DIET
356
0
        uint8_t access;
357
0
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
358
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
359
0
        MI->ac_idx++;
360
0
#endif
361
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
362
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
363
0
        MI->flat_insn->detail->arm64.op_count++;
364
0
#ifndef CAPSTONE_DIET
365
0
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
366
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
367
0
        MI->ac_idx++;
368
0
#endif
369
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
370
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op2);
371
0
        MI->flat_insn->detail->arm64.op_count++;
372
0
#ifndef CAPSTONE_DIET
373
0
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
374
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
375
0
        MI->ac_idx++;
376
0
#endif
377
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
378
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = LSB;
379
0
        MI->flat_insn->detail->arm64.op_count++;
380
0
#ifndef CAPSTONE_DIET
381
0
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
382
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
383
0
        MI->ac_idx++;
384
0
#endif
385
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
386
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Width;
387
0
        MI->flat_insn->detail->arm64.op_count++;
388
0
      }
389
390
0
      return;
391
0
    }
392
393
0
    LSB = ImmR;
394
0
    Width = ImmS - ImmR + 1;
395
    // Otherwise BFXIL the preferred form
396
0
    SStream_concat(O, "bfxil\t%s, %s, ",
397
0
        getRegisterName(MCOperand_getReg(Op0), AArch64_NoRegAltName),
398
0
        getRegisterName(MCOperand_getReg(Op2), AArch64_NoRegAltName));
399
0
    printInt32Bang(O, LSB);
400
0
    SStream_concat0(O, ", ");
401
0
    printInt32Bang(O, Width);
402
0
    MCInst_setOpcodePub(MI, AArch64_map_insn("bfxil"));
403
404
0
    if (MI->csh->detail) {
405
0
#ifndef CAPSTONE_DIET
406
0
      uint8_t access;
407
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
408
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
409
0
      MI->ac_idx++;
410
0
#endif
411
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
412
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op0);
413
0
      MI->flat_insn->detail->arm64.op_count++;
414
0
#ifndef CAPSTONE_DIET
415
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
416
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
417
0
      MI->ac_idx++;
418
0
#endif
419
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
420
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(Op2);
421
0
      MI->flat_insn->detail->arm64.op_count++;
422
0
#ifndef CAPSTONE_DIET
423
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
424
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
425
0
      MI->ac_idx++;
426
0
#endif
427
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
428
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = LSB;
429
0
      MI->flat_insn->detail->arm64.op_count++;
430
0
#ifndef CAPSTONE_DIET
431
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
432
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
433
0
      MI->ac_idx++;
434
0
#endif
435
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
436
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Width;
437
0
      MI->flat_insn->detail->arm64.op_count++;
438
0
    }
439
440
0
    return;
441
0
  }
442
443
0
  mnem = printAliasInstr(MI, O, Info);
444
0
  if (mnem) {
445
0
    MCInst_setOpcodePub(MI, AArch64_map_insn(mnem));
446
0
    cs_mem_free(mnem);
447
0
  } else {
448
0
    printInstruction(MI, O, Info);
449
0
  }
450
0
}
451
452
static bool printSysAlias(MCInst *MI, SStream *O)
453
0
{
454
  // unsigned Opcode = MCInst_getOpcode(MI);
455
  //assert(Opcode == AArch64_SYSxt && "Invalid opcode for SYS alias!");
456
457
0
  const char *Asm = NULL;
458
0
  MCOperand *Op1 = MCInst_getOperand(MI, 0);
459
0
  MCOperand *Cn = MCInst_getOperand(MI, 1);
460
0
  MCOperand *Cm = MCInst_getOperand(MI, 2);
461
0
  MCOperand *Op2 = MCInst_getOperand(MI, 3);
462
463
0
  unsigned Op1Val = (unsigned)MCOperand_getImm(Op1);
464
0
  unsigned CnVal = (unsigned)MCOperand_getImm(Cn);
465
0
  unsigned CmVal = (unsigned)MCOperand_getImm(Cm);
466
0
  unsigned Op2Val = (unsigned)MCOperand_getImm(Op2);
467
0
  unsigned insn_id = ARM64_INS_INVALID;
468
0
  unsigned op_ic = 0, op_dc = 0, op_at = 0, op_tlbi = 0;
469
470
0
  if (CnVal == 7) {
471
0
    switch (CmVal) {
472
0
      default:
473
0
        break;
474
475
        // IC aliases
476
0
      case 1:
477
0
        if (Op1Val == 0 && Op2Val == 0) {
478
0
          Asm = "ic\tialluis";
479
0
          insn_id = ARM64_INS_IC;
480
0
          op_ic = ARM64_IC_IALLUIS;
481
0
        }
482
0
        break;
483
0
      case 5:
484
0
        if (Op1Val == 0 && Op2Val == 0) {
485
0
          Asm = "ic\tiallu";
486
0
          insn_id = ARM64_INS_IC;
487
0
          op_ic = ARM64_IC_IALLU;
488
0
        } else if (Op1Val == 3 && Op2Val == 1) {
489
0
          Asm = "ic\tivau";
490
0
          insn_id = ARM64_INS_IC;
491
0
          op_ic = ARM64_IC_IVAU;
492
0
        }
493
0
        break;
494
495
        // DC aliases
496
0
      case 4:
497
0
        if (Op1Val == 3 && Op2Val == 1) {
498
0
          Asm = "dc\tzva";
499
0
          insn_id = ARM64_INS_DC;
500
0
          op_dc = ARM64_DC_ZVA;
501
0
        }
502
0
        break;
503
0
      case 6:
504
0
        if (Op1Val == 0 && Op2Val == 1) {
505
0
          Asm = "dc\tivac";
506
0
          insn_id = ARM64_INS_DC;
507
0
          op_dc = ARM64_DC_IVAC;
508
0
        }
509
0
        if (Op1Val == 0 && Op2Val == 2) {
510
0
          Asm = "dc\tisw";
511
0
          insn_id = ARM64_INS_DC;
512
0
          op_dc = ARM64_DC_ISW;
513
0
        }
514
0
        break;
515
0
      case 10:
516
0
        if (Op1Val == 3 && Op2Val == 1) {
517
0
          Asm = "dc\tcvac";
518
0
          insn_id = ARM64_INS_DC;
519
0
          op_dc = ARM64_DC_CVAC;
520
0
        } else if (Op1Val == 0 && Op2Val == 2) {
521
0
          Asm = "dc\tcsw";
522
0
          insn_id = ARM64_INS_DC;
523
0
          op_dc = ARM64_DC_CSW;
524
0
        }
525
0
        break;
526
0
      case 11:
527
0
        if (Op1Val == 3 && Op2Val == 1) {
528
0
          Asm = "dc\tcvau";
529
0
          insn_id = ARM64_INS_DC;
530
0
          op_dc = ARM64_DC_CVAU;
531
0
        }
532
0
        break;
533
0
      case 14:
534
0
        if (Op1Val == 3 && Op2Val == 1) {
535
0
          Asm = "dc\tcivac";
536
0
          insn_id = ARM64_INS_DC;
537
0
          op_dc = ARM64_DC_CIVAC;
538
0
        } else if (Op1Val == 0 && Op2Val == 2) {
539
0
          Asm = "dc\tcisw";
540
0
          insn_id = ARM64_INS_DC;
541
0
          op_dc = ARM64_DC_CISW;
542
0
        }
543
0
        break;
544
545
        // AT aliases
546
0
      case 8:
547
0
        switch (Op1Val) {
548
0
          default:
549
0
            break;
550
0
          case 0:
551
0
            switch (Op2Val) {
552
0
              default:
553
0
                break;
554
0
              case 0: Asm = "at\ts1e1r"; insn_id = ARM64_INS_AT; op_at = ARM64_AT_S1E1R; break;
555
0
              case 1: Asm = "at\ts1e1w"; insn_id = ARM64_INS_AT; op_at = ARM64_AT_S1E1W; break;
556
0
              case 2: Asm = "at\ts1e0r"; insn_id = ARM64_INS_AT; op_at = ARM64_AT_S1E0R; break;
557
0
              case 3: Asm = "at\ts1e0w"; insn_id = ARM64_INS_AT; op_at = ARM64_AT_S1E0W; break;
558
0
            }
559
0
            break;
560
0
          case 4:
561
0
            switch (Op2Val) {
562
0
              default:
563
0
                break;
564
0
              case 0: Asm = "at\ts1e2r"; insn_id = ARM64_INS_AT; op_at = ARM64_AT_S1E2R; break;
565
0
              case 1: Asm = "at\ts1e2w"; insn_id = ARM64_INS_AT; op_at = ARM64_AT_S1E2W; break;
566
0
              case 4: Asm = "at\ts12e1r"; insn_id = ARM64_INS_AT; op_at = ARM64_AT_S1E1R; break;
567
0
              case 5: Asm = "at\ts12e1w"; insn_id = ARM64_INS_AT; op_at = ARM64_AT_S1E1W; break;
568
0
              case 6: Asm = "at\ts12e0r"; insn_id = ARM64_INS_AT; op_at = ARM64_AT_S1E0R; break;
569
0
              case 7: Asm = "at\ts12e0w"; insn_id = ARM64_INS_AT; op_at = ARM64_AT_S1E0W; break;
570
0
            }
571
0
            break;
572
0
          case 6:
573
0
            switch (Op2Val) {
574
0
              default:
575
0
                break;
576
0
              case 0: Asm = "at\ts1e3r"; insn_id = ARM64_INS_AT; op_at = ARM64_AT_S1E3R; break;
577
0
              case 1: Asm = "at\ts1e3w"; insn_id = ARM64_INS_AT; op_at = ARM64_AT_S1E3W; break;
578
0
            }
579
0
            break;
580
0
        }
581
0
        break;
582
0
    }
583
0
  } else if (CnVal == 8) {
584
    // TLBI aliases
585
0
    switch (CmVal) {
586
0
      default:
587
0
        break;
588
0
      case 3:
589
0
        switch (Op1Val) {
590
0
          default:
591
0
            break;
592
0
          case 0:
593
0
            switch (Op2Val) {
594
0
              default:
595
0
                break;
596
0
              case 0: Asm = "tlbi\tvmalle1is"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VMALLE1IS; break;
597
0
              case 1: Asm = "tlbi\tvae1is"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VAE1IS; break;
598
0
              case 2: Asm = "tlbi\taside1is"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_ASIDE1IS; break;
599
0
              case 3: Asm = "tlbi\tvaae1is"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VAAE1IS; break;
600
0
              case 5: Asm = "tlbi\tvale1is"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VALE1IS; break;
601
0
              case 7: Asm = "tlbi\tvaale1is"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VAALE1IS; break;
602
0
            }
603
0
            break;
604
0
          case 4:
605
0
            switch (Op2Val) {
606
0
              default:
607
0
                break;
608
0
              case 0: Asm = "tlbi\talle2is"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_ALLE2IS; break;
609
0
              case 1: Asm = "tlbi\tvae2is"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VAE2IS; break;
610
0
              case 4: Asm = "tlbi\talle1is"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_ALLE1IS; break;
611
0
              case 5: Asm = "tlbi\tvale2is"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VALE2IS; break;
612
0
              case 6: Asm = "tlbi\tvmalls12e1is"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VMALLS12E1IS; break;
613
0
            }
614
0
            break;
615
0
          case 6:
616
0
            switch (Op2Val) {
617
0
              default:
618
0
                break;
619
0
              case 0: Asm = "tlbi\talle3is"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_ALLE3IS; break;
620
0
              case 1: Asm = "tlbi\tvae3is"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VAE3IS; break;
621
0
              case 5: Asm = "tlbi\tvale3is"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VALE3IS; break;
622
0
            }
623
0
            break;
624
0
        }
625
0
        break;
626
0
      case 0:
627
0
        switch (Op1Val) {
628
0
          default:
629
0
            break;
630
0
          case 4:
631
0
            switch (Op2Val) {
632
0
              default:
633
0
                break;
634
0
              case 1: Asm = "tlbi\tipas2e1is"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_IPAS2E1IS; break;
635
0
              case 5: Asm = "tlbi\tipas2le1is"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_IPAS2LE1IS; break;
636
0
            }
637
0
            break;
638
0
        }
639
0
        break;
640
0
      case 4:
641
0
        switch (Op1Val) {
642
0
          default:
643
0
            break;
644
0
          case 4:
645
0
            switch (Op2Val) {
646
0
              default:
647
0
                break;
648
0
              case 1: Asm = "tlbi\tipas2e1"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_IPAS2E1; break;
649
0
              case 5: Asm = "tlbi\tipas2le1"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_IPAS2LE1; break;
650
0
            }
651
0
            break;
652
0
        }
653
0
        break;
654
0
      case 7:
655
0
        switch (Op1Val) {
656
0
          default:
657
0
            break;
658
0
          case 0:
659
0
            switch (Op2Val) {
660
0
              default:
661
0
                break;
662
0
              case 0: Asm = "tlbi\tvmalle1"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VMALLE1; break;
663
0
              case 1: Asm = "tlbi\tvae1"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VAE1; break;
664
0
              case 2: Asm = "tlbi\taside1"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_ASIDE1; break;
665
0
              case 3: Asm = "tlbi\tvaae1"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VAAE1; break;
666
0
              case 5: Asm = "tlbi\tvale1"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VALE1; break;
667
0
              case 7: Asm = "tlbi\tvaale1"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VAALE1; break;
668
0
            }
669
0
            break;
670
0
          case 4:
671
0
            switch (Op2Val) {
672
0
              default:
673
0
                break;
674
0
              case 0: Asm = "tlbi\talle2"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_ALLE2; break;
675
0
              case 1: Asm = "tlbi\tvae2"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VAE2; break;
676
0
              case 4: Asm = "tlbi\talle1"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_ALLE1; break;
677
0
              case 5: Asm = "tlbi\tvale2"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VALE2; break;
678
0
              case 6: Asm = "tlbi\tvmalls12e1"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VMALLS12E1; break;
679
0
            }
680
0
            break;
681
0
          case 6:
682
0
            switch (Op2Val) {
683
0
              default:
684
0
                break;
685
0
              case 0: Asm = "tlbi\talle3"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_ALLE3; break;
686
0
              case 1: Asm = "tlbi\tvae3"; insn_id = ARM64_INS_TLBI;  op_tlbi = ARM64_TLBI_VAE3; break;
687
0
              case 5: Asm = "tlbi\tvale3"; insn_id = ARM64_INS_TLBI; op_tlbi = ARM64_TLBI_VALE3; break;
688
0
            }
689
0
            break;
690
0
        }
691
0
        break;
692
0
    }
693
0
  }
694
695
0
  if (Asm) {
696
0
    MCInst_setOpcodePub(MI, insn_id);
697
0
    SStream_concat0(O, Asm);
698
0
    if (MI->csh->detail) {
699
0
#ifndef CAPSTONE_DIET
700
0
      uint8_t access;
701
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
702
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
703
0
      MI->ac_idx++;
704
0
#endif
705
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_SYS;
706
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].sys = op_ic + op_dc + op_at + op_tlbi;
707
0
      MI->flat_insn->detail->arm64.op_count++;
708
0
    }
709
710
0
    if (!strstr(Asm, "all")) {
711
0
      unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, 4));
712
0
      SStream_concat(O, ", %s", getRegisterName(Reg, AArch64_NoRegAltName));
713
0
      if (MI->csh->detail) {
714
0
#ifndef CAPSTONE_DIET
715
0
        uint8_t access;
716
0
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
717
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
718
0
        MI->ac_idx++;
719
0
#endif
720
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
721
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;
722
0
        MI->flat_insn->detail->arm64.op_count++;
723
0
      }
724
0
    }
725
0
  }
726
727
0
  return Asm != NULL;
728
0
}
729
730
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
731
0
{
732
0
  MCOperand *Op = MCInst_getOperand(MI, OpNo);
733
734
0
  if (MCOperand_isReg(Op)) {
735
0
    unsigned Reg = MCOperand_getReg(Op);
736
0
    SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));
737
0
    if (MI->csh->detail) {
738
0
      if (MI->csh->doing_mem) {
739
0
        if (MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.base == ARM64_REG_INVALID) {
740
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.base = Reg;
741
0
        }
742
0
        else if (MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.index == ARM64_REG_INVALID) {
743
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.index = Reg;
744
0
        }
745
0
      } else {
746
0
#ifndef CAPSTONE_DIET
747
0
        uint8_t access;
748
0
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
749
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
750
0
        MI->ac_idx++;
751
0
#endif
752
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
753
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;
754
0
        MI->flat_insn->detail->arm64.op_count++;
755
0
      }
756
0
    }
757
0
  } else if (MCOperand_isImm(Op)) {
758
0
    int64_t imm = MCOperand_getImm(Op);
759
760
0
    if (MI->Opcode == AArch64_ADR) {
761
0
      imm += MI->address;
762
0
      printUInt64Bang(O, imm);
763
0
    } else {
764
0
      if (MI->csh->doing_mem) {
765
0
        if (MI->csh->imm_unsigned) {
766
0
          printUInt64Bang(O, imm);
767
0
        } else {
768
0
          printInt64Bang(O, imm);
769
0
        }
770
0
      } else
771
0
        printUInt64Bang(O, imm);
772
0
    }
773
774
0
    if (MI->csh->detail) {
775
0
      if (MI->csh->doing_mem) {
776
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.disp = (int32_t)imm;
777
0
      } else {
778
0
#ifndef CAPSTONE_DIET
779
0
        uint8_t access;
780
0
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
781
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
782
0
        MI->ac_idx++;
783
0
#endif
784
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
785
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = imm;
786
0
        MI->flat_insn->detail->arm64.op_count++;
787
0
      }
788
0
    }
789
0
  }
790
0
}
791
792
static void printHexImm(MCInst *MI, unsigned OpNo, SStream *O)
793
0
{
794
0
  MCOperand *Op = MCInst_getOperand(MI, OpNo);
795
0
  SStream_concat(O, "#%#llx", MCOperand_getImm(Op));
796
0
  if (MI->csh->detail) {
797
0
#ifndef CAPSTONE_DIET
798
0
    uint8_t access;
799
0
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
800
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
801
0
    MI->ac_idx++;
802
0
#endif
803
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
804
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op);
805
0
    MI->flat_insn->detail->arm64.op_count++;
806
0
  }
807
0
}
808
809
static void printPostIncOperand(MCInst *MI, unsigned OpNo,
810
    unsigned Imm, SStream *O)
811
0
{
812
0
  MCOperand *Op = MCInst_getOperand(MI, OpNo);
813
814
0
  if (MCOperand_isReg(Op)) {
815
0
    unsigned Reg = MCOperand_getReg(Op);
816
0
    if (Reg == AArch64_XZR) {
817
0
      printInt32Bang(O, Imm);
818
0
      if (MI->csh->detail) {
819
0
#ifndef CAPSTONE_DIET
820
0
        uint8_t access;
821
0
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
822
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
823
0
        MI->ac_idx++;
824
0
#endif
825
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
826
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Imm;
827
0
        MI->flat_insn->detail->arm64.op_count++;
828
0
      }
829
0
    } else {
830
0
      SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));
831
0
      if (MI->csh->detail) {
832
0
#ifndef CAPSTONE_DIET
833
0
        uint8_t access;
834
0
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
835
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
836
0
        MI->ac_idx++;
837
0
#endif
838
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
839
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;
840
0
        MI->flat_insn->detail->arm64.op_count++;
841
0
      }
842
0
    }
843
0
  }
844
  //llvm_unreachable("unknown operand kind in printPostIncOperand64");
845
0
}
846
847
static void printPostIncOperand2(MCInst *MI, unsigned OpNo, SStream *O, int Amount)
848
0
{
849
0
  printPostIncOperand(MI, OpNo, Amount, O);
850
0
}
851
852
static void printVRegOperand(MCInst *MI, unsigned OpNo, SStream *O)
853
0
{
854
0
  MCOperand *Op = MCInst_getOperand(MI, OpNo);
855
  //assert(Op.isReg() && "Non-register vreg operand!");
856
0
  unsigned Reg = MCOperand_getReg(Op);
857
0
  SStream_concat0(O, getRegisterName(Reg, AArch64_vreg));
858
0
  if (MI->csh->detail) {
859
0
#ifndef CAPSTONE_DIET
860
0
    uint8_t access;
861
0
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
862
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
863
0
    MI->ac_idx++;
864
0
#endif
865
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
866
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = AArch64_map_vregister(Reg);
867
0
    MI->flat_insn->detail->arm64.op_count++;
868
0
  }
869
0
}
870
871
static void printSysCROperand(MCInst *MI, unsigned OpNo, SStream *O)
872
0
{
873
0
  MCOperand *Op = MCInst_getOperand(MI, OpNo);
874
  //assert(Op.isImm() && "System instruction C[nm] operands must be immediates!");
875
0
  SStream_concat(O, "c%u", MCOperand_getImm(Op));
876
0
  if (MI->csh->detail) {
877
0
#ifndef CAPSTONE_DIET
878
0
    uint8_t access;
879
0
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
880
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
881
0
    MI->ac_idx++;
882
0
#endif
883
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_CIMM;
884
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = MCOperand_getImm(Op);
885
0
    MI->flat_insn->detail->arm64.op_count++;
886
0
  }
887
0
}
888
889
static void printAddSubImm(MCInst *MI, unsigned OpNum, SStream *O)
890
0
{
891
0
  MCOperand *MO = MCInst_getOperand(MI, OpNum);
892
0
  if (MCOperand_isImm(MO)) {
893
0
    unsigned Val = (MCOperand_getImm(MO) & 0xfff);
894
    //assert(Val == MO.getImm() && "Add/sub immediate out of range!");
895
0
    unsigned Shift = AArch64_AM_getShiftValue((int)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)));
896
897
0
    printInt32Bang(O, Val);
898
899
0
    if (MI->csh->detail) {
900
0
#ifndef CAPSTONE_DIET
901
0
      uint8_t access;
902
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
903
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
904
0
      MI->ac_idx++;
905
0
#endif
906
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
907
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;
908
0
      MI->flat_insn->detail->arm64.op_count++;
909
0
    }
910
911
0
    if (Shift != 0)
912
0
      printShifter(MI, OpNum + 1, O);
913
0
  }
914
0
}
915
916
static void printLogicalImm32(MCInst *MI, unsigned OpNum, SStream *O)
917
0
{
918
0
  int64_t Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
919
920
0
  Val = AArch64_AM_decodeLogicalImmediate(Val, 32);
921
0
  printUInt32Bang(O, (int)Val);
922
923
0
  if (MI->csh->detail) {
924
0
#ifndef CAPSTONE_DIET
925
0
    uint8_t access;
926
0
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
927
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
928
0
    MI->ac_idx++;
929
0
#endif
930
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
931
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;
932
0
    MI->flat_insn->detail->arm64.op_count++;
933
0
  }
934
0
}
935
936
static void printLogicalImm64(MCInst *MI, unsigned OpNum, SStream *O)
937
0
{
938
0
  int64_t Val = MCOperand_getImm(MCInst_getOperand(MI, OpNum));
939
0
  Val = AArch64_AM_decodeLogicalImmediate(Val, 64);
940
941
0
  switch(MI->flat_insn->id) {
942
0
    default:
943
0
      printInt64Bang(O, Val);
944
0
      break;
945
0
    case ARM64_INS_ORR:
946
0
    case ARM64_INS_AND:
947
0
    case ARM64_INS_EOR:
948
0
    case ARM64_INS_TST:
949
      // do not print number in negative form
950
0
      if (Val >= 0 && Val <= HEX_THRESHOLD)
951
0
        SStream_concat(O, "#%u", (int)Val);
952
0
      else
953
0
        SStream_concat(O, "#0x%"PRIx64, Val);
954
0
      break;
955
0
  }
956
957
0
  if (MI->csh->detail) {
958
0
#ifndef CAPSTONE_DIET
959
0
    uint8_t access;
960
0
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
961
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
962
0
    MI->ac_idx++;
963
0
#endif
964
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
965
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (int64_t)Val;
966
0
    MI->flat_insn->detail->arm64.op_count++;
967
0
  }
968
0
}
969
970
static void printShifter(MCInst *MI, unsigned OpNum, SStream *O)
971
0
{
972
0
  unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
973
974
  // LSL #0 should not be printed.
975
0
  if (AArch64_AM_getShiftType(Val) == AArch64_AM_LSL &&
976
0
      AArch64_AM_getShiftValue(Val) == 0)
977
0
    return;
978
979
0
  SStream_concat(O, ", %s ", AArch64_AM_getShiftExtendName(AArch64_AM_getShiftType(Val)));
980
0
  printInt32BangDec(O, AArch64_AM_getShiftValue(Val));
981
0
  if (MI->csh->detail) {
982
0
    arm64_shifter shifter = ARM64_SFT_INVALID;
983
0
    switch(AArch64_AM_getShiftType(Val)) {
984
0
      default:  // never reach
985
0
      case AArch64_AM_LSL:
986
0
        shifter = ARM64_SFT_LSL;
987
0
        break;
988
0
      case AArch64_AM_LSR:
989
0
        shifter = ARM64_SFT_LSR;
990
0
        break;
991
0
      case AArch64_AM_ASR:
992
0
        shifter = ARM64_SFT_ASR;
993
0
        break;
994
0
      case AArch64_AM_ROR:
995
0
        shifter = ARM64_SFT_ROR;
996
0
        break;
997
0
      case AArch64_AM_MSL:
998
0
        shifter = ARM64_SFT_MSL;
999
0
        break;
1000
0
    }
1001
1002
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.type = shifter;
1003
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.value = AArch64_AM_getShiftValue(Val);
1004
0
  }
1005
0
}
1006
1007
static void printShiftedRegister(MCInst *MI, unsigned OpNum, SStream *O)
1008
0
{
1009
0
  SStream_concat0(O, getRegisterName(MCOperand_getReg(MCInst_getOperand(MI, OpNum)), AArch64_NoRegAltName));
1010
0
  if (MI->csh->detail) {
1011
0
#ifndef CAPSTONE_DIET
1012
0
    uint8_t access;
1013
0
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1014
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1015
0
    MI->ac_idx++;
1016
0
#endif
1017
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
1018
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
1019
0
    MI->flat_insn->detail->arm64.op_count++;
1020
0
  }
1021
0
  printShifter(MI, OpNum + 1, O);
1022
0
}
1023
1024
static void printArithExtend(MCInst *MI, unsigned OpNum, SStream *O)
1025
0
{
1026
0
  unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1027
0
  AArch64_AM_ShiftExtendType ExtType = AArch64_AM_getArithExtendType(Val);
1028
0
  unsigned ShiftVal = AArch64_AM_getArithShiftValue(Val);
1029
1030
  // If the destination or first source register operand is [W]SP, print
1031
  // UXTW/UXTX as LSL, and if the shift amount is also zero, print nothing at
1032
  // all.
1033
0
  if (ExtType == AArch64_AM_UXTW || ExtType == AArch64_AM_UXTX) {
1034
0
    unsigned Dest = MCOperand_getReg(MCInst_getOperand(MI, 0));
1035
0
    unsigned Src1 = MCOperand_getReg(MCInst_getOperand(MI, 1));
1036
0
    if ( ((Dest == AArch64_SP || Src1 == AArch64_SP) &&
1037
0
          ExtType == AArch64_AM_UXTX) ||
1038
0
        ((Dest == AArch64_WSP || Src1 == AArch64_WSP) &&
1039
0
         ExtType == AArch64_AM_UXTW) ) {
1040
0
      if (ShiftVal != 0) {
1041
0
        SStream_concat0(O, ", lsl ");
1042
0
        printInt32Bang(O, ShiftVal);
1043
0
        if (MI->csh->detail) {
1044
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.type = ARM64_SFT_LSL;
1045
0
          MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.value = ShiftVal;
1046
0
        }
1047
0
      }
1048
1049
0
      return;
1050
0
    }
1051
0
  }
1052
1053
0
  SStream_concat(O, ", %s", AArch64_AM_getShiftExtendName(ExtType));
1054
0
  if (MI->csh->detail) {
1055
0
    arm64_extender ext = ARM64_EXT_INVALID;
1056
0
    switch(ExtType) {
1057
0
      default:  // never reach
1058
0
      case AArch64_AM_UXTB:
1059
0
        ext = ARM64_EXT_UXTB;
1060
0
        break;
1061
0
      case AArch64_AM_UXTH:
1062
0
        ext = ARM64_EXT_UXTH;
1063
0
        break;
1064
0
      case AArch64_AM_UXTW:
1065
0
        ext = ARM64_EXT_UXTW;
1066
0
        break;
1067
0
      case AArch64_AM_UXTX:
1068
0
        ext = ARM64_EXT_UXTX;
1069
0
        break;
1070
0
      case AArch64_AM_SXTB:
1071
0
        ext = ARM64_EXT_SXTB;
1072
0
        break;
1073
0
      case AArch64_AM_SXTH:
1074
0
        ext = ARM64_EXT_SXTH;
1075
0
        break;
1076
0
      case AArch64_AM_SXTW:
1077
0
        ext = ARM64_EXT_SXTW;
1078
0
        break;
1079
0
      case AArch64_AM_SXTX:
1080
0
        ext = ARM64_EXT_SXTX;
1081
0
        break;
1082
0
    }
1083
1084
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].ext = ext;
1085
0
  }
1086
1087
0
  if (ShiftVal != 0) {
1088
0
    SStream_concat0(O, " ");
1089
0
    printInt32Bang(O, ShiftVal);
1090
0
    if (MI->csh->detail) {
1091
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.type = ARM64_SFT_LSL;
1092
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].shift.value = ShiftVal;
1093
0
    }
1094
0
  }
1095
0
}
1096
1097
static void printExtendedRegister(MCInst *MI, unsigned OpNum, SStream *O)
1098
0
{
1099
0
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
1100
1101
0
  SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName));
1102
0
  if (MI->csh->detail) {
1103
0
#ifndef CAPSTONE_DIET
1104
0
    uint8_t access;
1105
0
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1106
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1107
0
    MI->ac_idx++;
1108
0
#endif
1109
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
1110
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg;
1111
0
    MI->flat_insn->detail->arm64.op_count++;
1112
0
  }
1113
1114
0
  printArithExtend(MI, OpNum + 1, O);
1115
0
}
1116
1117
static void printMemExtend(MCInst *MI, unsigned OpNum, SStream *O, char SrcRegKind, unsigned Width)
1118
0
{
1119
0
  unsigned SignExtend = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1120
0
  unsigned DoShift = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));
1121
1122
  // sxtw, sxtx, uxtw or lsl (== uxtx)
1123
0
  bool IsLSL = !SignExtend && SrcRegKind == 'x';
1124
0
  if (IsLSL) {
1125
0
    SStream_concat0(O, "lsl");
1126
0
    if (MI->csh->detail) {
1127
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].shift.type = ARM64_SFT_LSL;
1128
0
    }
1129
0
  } else {
1130
0
    SStream_concat(O, "%cxt%c", (SignExtend ? 's' : 'u'), SrcRegKind);
1131
0
    if (MI->csh->detail) {
1132
0
      if (!SignExtend) {
1133
0
        switch(SrcRegKind) {
1134
0
          default: break;
1135
0
          case 'b':
1136
0
               MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_UXTB;
1137
0
               break;
1138
0
          case 'h':
1139
0
               MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_UXTH;
1140
0
               break;
1141
0
          case 'w':
1142
0
               MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_UXTW;
1143
0
               break;
1144
0
        }
1145
0
      } else {
1146
0
          switch(SrcRegKind) {
1147
0
            default: break;
1148
0
            case 'b':
1149
0
              MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_SXTB;
1150
0
              break;
1151
0
            case 'h':
1152
0
              MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_SXTH;
1153
0
              break;
1154
0
            case 'w':
1155
0
              MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_SXTW;
1156
0
              break;
1157
0
            case 'x':
1158
0
              MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_SXTX;
1159
0
              break;
1160
0
          }
1161
0
      }
1162
0
    }
1163
0
  }
1164
1165
0
  if (DoShift || IsLSL) {
1166
0
    SStream_concat(O, " #%u", Log2_32(Width / 8));
1167
0
    if (MI->csh->detail) {
1168
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].shift.type = ARM64_SFT_LSL;
1169
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].shift.value = Log2_32(Width / 8);
1170
0
    }
1171
0
  }
1172
0
}
1173
1174
static void printCondCode(MCInst *MI, unsigned OpNum, SStream *O)
1175
0
{
1176
0
  A64CC_CondCode CC = (A64CC_CondCode)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1177
0
  SStream_concat0(O, getCondCodeName(CC));
1178
1179
0
  if (MI->csh->detail)
1180
0
    MI->flat_insn->detail->arm64.cc = (arm64_cc)(CC + 1);
1181
0
}
1182
1183
static void printInverseCondCode(MCInst *MI, unsigned OpNum, SStream *O)
1184
0
{
1185
0
  A64CC_CondCode CC = (A64CC_CondCode)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1186
0
  SStream_concat0(O, getCondCodeName(getInvertedCondCode(CC)));
1187
1188
0
  if (MI->csh->detail) {
1189
0
    MI->flat_insn->detail->arm64.cc = (arm64_cc)(getInvertedCondCode(CC) + 1);
1190
0
  }
1191
0
}
1192
1193
static void printImmScale(MCInst *MI, unsigned OpNum, SStream *O, int Scale)
1194
0
{
1195
0
  int64_t val = Scale * MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1196
1197
0
  printInt64Bang(O, val);
1198
1199
0
  if (MI->csh->detail) {
1200
0
    if (MI->csh->doing_mem) {
1201
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.disp = (int32_t)val;
1202
0
    } else {
1203
0
#ifndef CAPSTONE_DIET
1204
0
      uint8_t access;
1205
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1206
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1207
0
      MI->ac_idx++;
1208
0
#endif
1209
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1210
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = val;
1211
0
      MI->flat_insn->detail->arm64.op_count++;
1212
0
    }
1213
0
  }
1214
0
}
1215
1216
static void printUImm12Offset(MCInst *MI, unsigned OpNum, unsigned Scale, SStream *O)
1217
0
{
1218
0
  MCOperand *MO = MCInst_getOperand(MI, OpNum);
1219
1220
0
  if (MCOperand_isImm(MO)) {
1221
0
    int64_t val = Scale * MCOperand_getImm(MO);
1222
0
    printInt64Bang(O, val);
1223
0
    if (MI->csh->detail) {
1224
0
      if (MI->csh->doing_mem) {
1225
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].mem.disp = (int32_t)val;
1226
0
      } else {
1227
0
#ifndef CAPSTONE_DIET
1228
0
        uint8_t access;
1229
0
        access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1230
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1231
0
        MI->ac_idx++;
1232
0
#endif
1233
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1234
0
        MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = (int)val;
1235
0
        MI->flat_insn->detail->arm64.op_count++;
1236
0
      }
1237
0
    }
1238
0
  }
1239
0
}
1240
1241
static void printUImm12Offset2(MCInst *MI, unsigned OpNum, SStream *O, int Scale)
1242
0
{
1243
0
  printUImm12Offset(MI, OpNum, Scale, O);
1244
0
}
1245
1246
static void printPrefetchOp(MCInst *MI, unsigned OpNum, SStream *O)
1247
0
{
1248
0
  unsigned prfop = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1249
0
  bool Valid;
1250
0
  const char *Name = A64NamedImmMapper_toString(&A64PRFM_PRFMMapper, prfop, &Valid);
1251
1252
0
  if (Valid) {
1253
0
    SStream_concat0(O, Name);
1254
0
    if (MI->csh->detail) {
1255
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_PREFETCH;
1256
      // we have to plus 1 to prfop because 0 is a valid value of prfop
1257
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].prefetch = prfop + 1;
1258
0
      MI->flat_insn->detail->arm64.op_count++;
1259
0
    }
1260
0
  } else {
1261
0
    printInt32Bang(O, prfop);
1262
0
    if (MI->csh->detail) {
1263
0
#ifndef CAPSTONE_DIET
1264
0
      uint8_t access;
1265
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1266
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1267
0
      MI->ac_idx++;
1268
0
#endif
1269
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1270
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = prfop;
1271
0
      MI->flat_insn->detail->arm64.op_count++;
1272
0
    }
1273
0
  }
1274
0
}
1275
1276
static void printFPImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
1277
0
{
1278
0
  MCOperand *MO = MCInst_getOperand(MI, OpNum);
1279
0
  double FPImm = MCOperand_isFPImm(MO) ? MCOperand_getFPImm(MO) : AArch64_AM_getFPImmFloat((int)MCOperand_getImm(MO));
1280
1281
  // 8 decimal places are enough to perfectly represent permitted floats.
1282
#if defined(_KERNEL_MODE)
1283
  // Issue #681: Windows kernel does not support formatting float point
1284
  SStream_concat(O, "#<float_point_unsupported>");
1285
#else
1286
0
  SStream_concat(O, "#%.8f", FPImm);
1287
0
#endif
1288
0
  if (MI->csh->detail) {
1289
0
#ifndef CAPSTONE_DIET
1290
0
    uint8_t access;
1291
0
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1292
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1293
0
    MI->ac_idx++;
1294
0
#endif
1295
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_FP;
1296
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].fp = FPImm;
1297
0
    MI->flat_insn->detail->arm64.op_count++;
1298
0
  }
1299
0
}
1300
1301
//static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride = 1)
1302
static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride)
1303
0
{
1304
0
  while (Stride--) {
1305
0
    switch (Reg) {
1306
0
      default:
1307
        // llvm_unreachable("Vector register expected!");
1308
0
      case AArch64_Q0:  Reg = AArch64_Q1;  break;
1309
0
      case AArch64_Q1:  Reg = AArch64_Q2;  break;
1310
0
      case AArch64_Q2:  Reg = AArch64_Q3;  break;
1311
0
      case AArch64_Q3:  Reg = AArch64_Q4;  break;
1312
0
      case AArch64_Q4:  Reg = AArch64_Q5;  break;
1313
0
      case AArch64_Q5:  Reg = AArch64_Q6;  break;
1314
0
      case AArch64_Q6:  Reg = AArch64_Q7;  break;
1315
0
      case AArch64_Q7:  Reg = AArch64_Q8;  break;
1316
0
      case AArch64_Q8:  Reg = AArch64_Q9;  break;
1317
0
      case AArch64_Q9:  Reg = AArch64_Q10; break;
1318
0
      case AArch64_Q10: Reg = AArch64_Q11; break;
1319
0
      case AArch64_Q11: Reg = AArch64_Q12; break;
1320
0
      case AArch64_Q12: Reg = AArch64_Q13; break;
1321
0
      case AArch64_Q13: Reg = AArch64_Q14; break;
1322
0
      case AArch64_Q14: Reg = AArch64_Q15; break;
1323
0
      case AArch64_Q15: Reg = AArch64_Q16; break;
1324
0
      case AArch64_Q16: Reg = AArch64_Q17; break;
1325
0
      case AArch64_Q17: Reg = AArch64_Q18; break;
1326
0
      case AArch64_Q18: Reg = AArch64_Q19; break;
1327
0
      case AArch64_Q19: Reg = AArch64_Q20; break;
1328
0
      case AArch64_Q20: Reg = AArch64_Q21; break;
1329
0
      case AArch64_Q21: Reg = AArch64_Q22; break;
1330
0
      case AArch64_Q22: Reg = AArch64_Q23; break;
1331
0
      case AArch64_Q23: Reg = AArch64_Q24; break;
1332
0
      case AArch64_Q24: Reg = AArch64_Q25; break;
1333
0
      case AArch64_Q25: Reg = AArch64_Q26; break;
1334
0
      case AArch64_Q26: Reg = AArch64_Q27; break;
1335
0
      case AArch64_Q27: Reg = AArch64_Q28; break;
1336
0
      case AArch64_Q28: Reg = AArch64_Q29; break;
1337
0
      case AArch64_Q29: Reg = AArch64_Q30; break;
1338
0
      case AArch64_Q30: Reg = AArch64_Q31; break;
1339
                 // Vector lists can wrap around.
1340
0
      case AArch64_Q31: Reg = AArch64_Q0; break;
1341
0
    }
1342
0
  }
1343
1344
0
  return Reg;
1345
0
}
1346
1347
static void printVectorList(MCInst *MI, unsigned OpNum, SStream *O, char *LayoutSuffix, MCRegisterInfo *MRI, arm64_vas vas, arm64_vess vess)
1348
0
{
1349
0
#define GETREGCLASS_CONTAIN0(_class, _reg) MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, _class), _reg)
1350
1351
0
  unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
1352
0
  unsigned NumRegs = 1, FirstReg, i;
1353
1354
0
  SStream_concat0(O, "{");
1355
1356
  // Work out how many registers there are in the list (if there is an actual
1357
  // list).
1358
0
  if (GETREGCLASS_CONTAIN0(AArch64_DDRegClassID , Reg) ||
1359
0
      GETREGCLASS_CONTAIN0(AArch64_QQRegClassID, Reg))
1360
0
    NumRegs = 2;
1361
0
  else if (GETREGCLASS_CONTAIN0(AArch64_DDDRegClassID, Reg) ||
1362
0
      GETREGCLASS_CONTAIN0(AArch64_QQQRegClassID, Reg))
1363
0
    NumRegs = 3;
1364
0
  else if (GETREGCLASS_CONTAIN0(AArch64_DDDDRegClassID, Reg) ||
1365
0
      GETREGCLASS_CONTAIN0(AArch64_QQQQRegClassID, Reg))
1366
0
    NumRegs = 4;
1367
1368
  // Now forget about the list and find out what the first register is.
1369
0
  if ((FirstReg = MCRegisterInfo_getSubReg(MRI, Reg, AArch64_dsub0)))
1370
0
    Reg = FirstReg;
1371
0
  else if ((FirstReg = MCRegisterInfo_getSubReg(MRI, Reg, AArch64_qsub0)))
1372
0
    Reg = FirstReg;
1373
1374
  // If it's a D-reg, we need to promote it to the equivalent Q-reg before
1375
  // printing (otherwise getRegisterName fails).
1376
0
  if (GETREGCLASS_CONTAIN0(AArch64_FPR64RegClassID, Reg)) {
1377
0
    const MCRegisterClass *FPR128RC = MCRegisterInfo_getRegClass(MRI, AArch64_FPR128RegClassID);
1378
0
    Reg = MCRegisterInfo_getMatchingSuperReg(MRI, Reg, AArch64_dsub, FPR128RC);
1379
0
  }
1380
1381
0
  for (i = 0; i < NumRegs; ++i, Reg = getNextVectorRegister(Reg, 1)) {
1382
0
    SStream_concat(O, "%s%s", getRegisterName(Reg, AArch64_vreg), LayoutSuffix);
1383
0
    if (i + 1 != NumRegs)
1384
0
      SStream_concat0(O, ", ");
1385
0
    if (MI->csh->detail) {
1386
0
#ifndef CAPSTONE_DIET
1387
0
      uint8_t access;
1388
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1389
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1390
0
      MI->ac_idx++;
1391
0
#endif
1392
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG;
1393
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = AArch64_map_vregister(Reg);
1394
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].vas = vas;
1395
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].vess = vess;
1396
0
      MI->flat_insn->detail->arm64.op_count++;
1397
0
    }
1398
0
  }
1399
1400
0
  SStream_concat0(O, "}");
1401
0
}
1402
1403
static void printTypedVectorList(MCInst *MI, unsigned OpNum, SStream *O, unsigned NumLanes, char LaneKind, MCRegisterInfo *MRI)
1404
0
{
1405
0
  char Suffix[32];
1406
0
  arm64_vas vas = 0;
1407
0
  arm64_vess vess = 0;
1408
1409
0
  if (NumLanes) {
1410
0
    cs_snprintf(Suffix, sizeof(Suffix), ".%u%c", NumLanes, LaneKind);
1411
0
    switch(LaneKind) {
1412
0
      default: break;
1413
0
      case 'b':
1414
0
        switch(NumLanes) {
1415
0
          default: break;
1416
0
          case 8:
1417
0
               vas = ARM64_VAS_8B;
1418
0
               break;
1419
0
          case 16:
1420
0
               vas = ARM64_VAS_16B;
1421
0
               break;
1422
0
        }
1423
0
        break;
1424
0
      case 'h':
1425
0
        switch(NumLanes) {
1426
0
          default: break;
1427
0
          case 4:
1428
0
               vas = ARM64_VAS_4H;
1429
0
               break;
1430
0
          case 8:
1431
0
               vas = ARM64_VAS_8H;
1432
0
               break;
1433
0
        }
1434
0
        break;
1435
0
      case 's':
1436
0
        switch(NumLanes) {
1437
0
          default: break;
1438
0
          case 2:
1439
0
               vas = ARM64_VAS_2S;
1440
0
               break;
1441
0
          case 4:
1442
0
               vas = ARM64_VAS_4S;
1443
0
               break;
1444
0
        }
1445
0
        break;
1446
0
      case 'd':
1447
0
        switch(NumLanes) {
1448
0
          default: break;
1449
0
          case 1:
1450
0
               vas = ARM64_VAS_1D;
1451
0
               break;
1452
0
          case 2:
1453
0
               vas = ARM64_VAS_2D;
1454
0
               break;
1455
0
        }
1456
0
        break;
1457
0
      case 'q':
1458
0
        switch(NumLanes) {
1459
0
          default: break;
1460
0
          case 1:
1461
0
               vas = ARM64_VAS_1Q;
1462
0
               break;
1463
0
        }
1464
0
        break;
1465
0
    }
1466
0
  } else {
1467
0
    cs_snprintf(Suffix, sizeof(Suffix), ".%c", LaneKind);
1468
0
    switch(LaneKind) {
1469
0
      default: break;
1470
0
      case 'b':
1471
0
           vess = ARM64_VESS_B;
1472
0
           break;
1473
0
      case 'h':
1474
0
           vess = ARM64_VESS_H;
1475
0
           break;
1476
0
      case 's':
1477
0
           vess = ARM64_VESS_S;
1478
0
           break;
1479
0
      case 'd':
1480
0
           vess = ARM64_VESS_D;
1481
0
           break;
1482
0
    }
1483
0
  }
1484
1485
0
  printVectorList(MI, OpNum, O, Suffix, MRI, vas, vess);
1486
0
}
1487
1488
static void printVectorIndex(MCInst *MI, unsigned OpNum, SStream *O)
1489
0
{
1490
0
  SStream_concat0(O, "[");
1491
0
  printInt32(O, (int)MCOperand_getImm(MCInst_getOperand(MI, OpNum)));
1492
0
  SStream_concat0(O, "]");
1493
0
  if (MI->csh->detail) {
1494
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].vector_index = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
1495
0
  }
1496
0
}
1497
1498
static void printAlignedLabel(MCInst *MI, unsigned OpNum, SStream *O)
1499
0
{
1500
0
  MCOperand *Op = MCInst_getOperand(MI, OpNum);
1501
1502
  // If the label has already been resolved to an immediate offset (say, when
1503
  // we're running the disassembler), just print the immediate.
1504
0
  if (MCOperand_isImm(Op)) {
1505
0
    uint64_t imm = (MCOperand_getImm(Op) * 4) + MI->address;
1506
0
    printUInt64Bang(O, imm);
1507
0
    if (MI->csh->detail) {
1508
0
#ifndef CAPSTONE_DIET
1509
0
      uint8_t access;
1510
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1511
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1512
0
      MI->ac_idx++;
1513
0
#endif
1514
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1515
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = imm;
1516
0
      MI->flat_insn->detail->arm64.op_count++;
1517
0
    }
1518
0
    return;
1519
0
  }
1520
0
}
1521
1522
static void printAdrpLabel(MCInst *MI, unsigned OpNum, SStream *O)
1523
0
{
1524
0
  MCOperand *Op = MCInst_getOperand(MI, OpNum);
1525
1526
0
  if (MCOperand_isImm(Op)) {
1527
    // ADRP sign extends a 21-bit offset, shifts it left by 12
1528
    // and adds it to the value of the PC with its bottom 12 bits cleared
1529
0
    uint64_t imm = (MCOperand_getImm(Op) * 0x1000) + (MI->address & ~0xfff);
1530
0
    printUInt64Bang(O, imm);
1531
1532
0
    if (MI->csh->detail) {
1533
0
#ifndef CAPSTONE_DIET
1534
0
      uint8_t access;
1535
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1536
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1537
0
      MI->ac_idx++;
1538
0
#endif
1539
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1540
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = imm;
1541
0
      MI->flat_insn->detail->arm64.op_count++;
1542
0
    }
1543
0
    return;
1544
0
  }
1545
0
}
1546
1547
static void printBarrierOption(MCInst *MI, unsigned OpNo, SStream *O)
1548
0
{
1549
0
  unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
1550
0
  unsigned Opcode = MCInst_getOpcode(MI);
1551
0
  bool Valid;
1552
0
  const char *Name;
1553
1554
0
  if (Opcode == AArch64_ISB)
1555
0
    Name = A64NamedImmMapper_toString(&A64ISB_ISBMapper, Val, &Valid);
1556
0
  else
1557
0
    Name = A64NamedImmMapper_toString(&A64DB_DBarrierMapper, Val, &Valid);
1558
1559
0
  if (Valid) {
1560
0
    SStream_concat0(O, Name);
1561
0
    if (MI->csh->detail) {
1562
0
#ifndef CAPSTONE_DIET
1563
0
      uint8_t access;
1564
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1565
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1566
0
      MI->ac_idx++;
1567
0
#endif
1568
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_BARRIER;
1569
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].barrier = Val;
1570
0
      MI->flat_insn->detail->arm64.op_count++;
1571
0
    }
1572
0
  } else {
1573
0
    printUInt32Bang(O, Val);
1574
0
    if (MI->csh->detail) {
1575
0
#ifndef CAPSTONE_DIET
1576
0
      uint8_t access;
1577
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1578
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1579
0
      MI->ac_idx++;
1580
0
#endif
1581
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1582
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;
1583
0
      MI->flat_insn->detail->arm64.op_count++;
1584
0
    }
1585
0
  }
1586
0
}
1587
1588
static void printMRSSystemRegister(MCInst *MI, unsigned OpNo, SStream *O)
1589
0
{
1590
0
  unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
1591
0
  char Name[128];
1592
1593
0
  A64SysRegMapper_toString(&AArch64_MRSMapper, Val, Name);
1594
1595
0
  SStream_concat0(O, Name);
1596
0
  if (MI->csh->detail) {
1597
0
#ifndef CAPSTONE_DIET
1598
0
    uint8_t access;
1599
0
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1600
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1601
0
    MI->ac_idx++;
1602
0
#endif
1603
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG_MRS;
1604
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Val;
1605
0
    MI->flat_insn->detail->arm64.op_count++;
1606
0
  }
1607
0
}
1608
1609
static void printMSRSystemRegister(MCInst *MI, unsigned OpNo, SStream *O)
1610
0
{
1611
0
  unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
1612
0
  char Name[128];
1613
1614
0
  A64SysRegMapper_toString(&AArch64_MSRMapper, Val, Name);
1615
1616
0
  SStream_concat0(O, Name);
1617
0
  if (MI->csh->detail) {
1618
0
#ifndef CAPSTONE_DIET
1619
0
    uint8_t access;
1620
0
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1621
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1622
0
    MI->ac_idx++;
1623
0
#endif
1624
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG_MSR;
1625
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Val;
1626
0
    MI->flat_insn->detail->arm64.op_count++;
1627
0
  }
1628
0
}
1629
1630
static void printSystemPStateField(MCInst *MI, unsigned OpNo, SStream *O)
1631
0
{
1632
0
  unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
1633
0
  bool Valid;
1634
0
  const char *Name;
1635
1636
0
  Name = A64NamedImmMapper_toString(&A64PState_PStateMapper, Val, &Valid);
1637
0
  if (Valid) {
1638
0
    SStream_concat0(O, Name);
1639
0
    if (MI->csh->detail) {
1640
0
#ifndef CAPSTONE_DIET
1641
0
      uint8_t access;
1642
0
      access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1643
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1644
0
      MI->ac_idx++;
1645
0
#endif
1646
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_PSTATE;
1647
0
      MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].pstate = Val;
1648
0
      MI->flat_insn->detail->arm64.op_count++;
1649
0
    }
1650
0
  } else {
1651
0
#ifndef CAPSTONE_DIET
1652
0
    unsigned char access;
1653
0
#endif
1654
0
    printInt32Bang(O, Val);
1655
0
#ifndef CAPSTONE_DIET
1656
0
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1657
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1658
0
    MI->ac_idx++;
1659
0
#endif
1660
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1661
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;
1662
0
    MI->flat_insn->detail->arm64.op_count++;
1663
0
  }
1664
0
}
1665
1666
static void printSIMDType10Operand(MCInst *MI, unsigned OpNo, SStream *O)
1667
0
{
1668
0
  uint8_t RawVal = (uint8_t)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
1669
0
  uint64_t Val = AArch64_AM_decodeAdvSIMDModImmType10(RawVal);
1670
0
  SStream_concat(O, "#%#016llx", Val);
1671
0
  if (MI->csh->detail) {
1672
0
#ifndef CAPSTONE_DIET
1673
0
    unsigned char access;
1674
0
    access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
1675
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].access = access;
1676
0
    MI->ac_idx++;
1677
0
#endif
1678
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM;
1679
0
    MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val;
1680
0
    MI->flat_insn->detail->arm64.op_count++;
1681
0
  }
1682
0
}
1683
1684
1685
#define PRINT_ALIAS_INSTR
1686
#include "AArch64GenAsmWriter.inc"
1687
1688
void AArch64_post_printer(csh handle, cs_insn *flat_insn, char *insn_asm, MCInst *mci)
1689
0
{
1690
0
  if (((cs_struct *)handle)->detail != CS_OPT_ON)
1691
0
    return;
1692
1693
0
  if (mci->csh->detail) {
1694
0
    unsigned opcode = MCInst_getOpcode(mci);
1695
0
    switch (opcode) {
1696
0
      default:
1697
0
        break;
1698
0
      case AArch64_LD1Fourv16b_POST:
1699
0
      case AArch64_LD1Fourv1d_POST:
1700
0
      case AArch64_LD1Fourv2d_POST:
1701
0
      case AArch64_LD1Fourv2s_POST:
1702
0
      case AArch64_LD1Fourv4h_POST:
1703
0
      case AArch64_LD1Fourv4s_POST:
1704
0
      case AArch64_LD1Fourv8b_POST:
1705
0
      case AArch64_LD1Fourv8h_POST:
1706
0
      case AArch64_LD1Onev16b_POST:
1707
0
      case AArch64_LD1Onev1d_POST:
1708
0
      case AArch64_LD1Onev2d_POST:
1709
0
      case AArch64_LD1Onev2s_POST:
1710
0
      case AArch64_LD1Onev4h_POST:
1711
0
      case AArch64_LD1Onev4s_POST:
1712
0
      case AArch64_LD1Onev8b_POST:
1713
0
      case AArch64_LD1Onev8h_POST:
1714
0
      case AArch64_LD1Rv16b_POST:
1715
0
      case AArch64_LD1Rv1d_POST:
1716
0
      case AArch64_LD1Rv2d_POST:
1717
0
      case AArch64_LD1Rv2s_POST:
1718
0
      case AArch64_LD1Rv4h_POST:
1719
0
      case AArch64_LD1Rv4s_POST:
1720
0
      case AArch64_LD1Rv8b_POST:
1721
0
      case AArch64_LD1Rv8h_POST:
1722
0
      case AArch64_LD1Threev16b_POST:
1723
0
      case AArch64_LD1Threev1d_POST:
1724
0
      case AArch64_LD1Threev2d_POST:
1725
0
      case AArch64_LD1Threev2s_POST:
1726
0
      case AArch64_LD1Threev4h_POST:
1727
0
      case AArch64_LD1Threev4s_POST:
1728
0
      case AArch64_LD1Threev8b_POST:
1729
0
      case AArch64_LD1Threev8h_POST:
1730
0
      case AArch64_LD1Twov16b_POST:
1731
0
      case AArch64_LD1Twov1d_POST:
1732
0
      case AArch64_LD1Twov2d_POST:
1733
0
      case AArch64_LD1Twov2s_POST:
1734
0
      case AArch64_LD1Twov4h_POST:
1735
0
      case AArch64_LD1Twov4s_POST:
1736
0
      case AArch64_LD1Twov8b_POST:
1737
0
      case AArch64_LD1Twov8h_POST:
1738
0
      case AArch64_LD1i16_POST:
1739
0
      case AArch64_LD1i32_POST:
1740
0
      case AArch64_LD1i64_POST:
1741
0
      case AArch64_LD1i8_POST:
1742
0
      case AArch64_LD2Rv16b_POST:
1743
0
      case AArch64_LD2Rv1d_POST:
1744
0
      case AArch64_LD2Rv2d_POST:
1745
0
      case AArch64_LD2Rv2s_POST:
1746
0
      case AArch64_LD2Rv4h_POST:
1747
0
      case AArch64_LD2Rv4s_POST:
1748
0
      case AArch64_LD2Rv8b_POST:
1749
0
      case AArch64_LD2Rv8h_POST:
1750
0
      case AArch64_LD2Twov16b_POST:
1751
0
      case AArch64_LD2Twov2d_POST:
1752
0
      case AArch64_LD2Twov2s_POST:
1753
0
      case AArch64_LD2Twov4h_POST:
1754
0
      case AArch64_LD2Twov4s_POST:
1755
0
      case AArch64_LD2Twov8b_POST:
1756
0
      case AArch64_LD2Twov8h_POST:
1757
0
      case AArch64_LD2i16_POST:
1758
0
      case AArch64_LD2i32_POST:
1759
0
      case AArch64_LD2i64_POST:
1760
0
      case AArch64_LD2i8_POST:
1761
0
      case AArch64_LD3Rv16b_POST:
1762
0
      case AArch64_LD3Rv1d_POST:
1763
0
      case AArch64_LD3Rv2d_POST:
1764
0
      case AArch64_LD3Rv2s_POST:
1765
0
      case AArch64_LD3Rv4h_POST:
1766
0
      case AArch64_LD3Rv4s_POST:
1767
0
      case AArch64_LD3Rv8b_POST:
1768
0
      case AArch64_LD3Rv8h_POST:
1769
0
      case AArch64_LD3Threev16b_POST:
1770
0
      case AArch64_LD3Threev2d_POST:
1771
0
      case AArch64_LD3Threev2s_POST:
1772
0
      case AArch64_LD3Threev4h_POST:
1773
0
      case AArch64_LD3Threev4s_POST:
1774
0
      case AArch64_LD3Threev8b_POST:
1775
0
      case AArch64_LD3Threev8h_POST:
1776
0
      case AArch64_LD3i16_POST:
1777
0
      case AArch64_LD3i32_POST:
1778
0
      case AArch64_LD3i64_POST:
1779
0
      case AArch64_LD3i8_POST:
1780
0
      case AArch64_LD4Fourv16b_POST:
1781
0
      case AArch64_LD4Fourv2d_POST:
1782
0
      case AArch64_LD4Fourv2s_POST:
1783
0
      case AArch64_LD4Fourv4h_POST:
1784
0
      case AArch64_LD4Fourv4s_POST:
1785
0
      case AArch64_LD4Fourv8b_POST:
1786
0
      case AArch64_LD4Fourv8h_POST:
1787
0
      case AArch64_LD4Rv16b_POST:
1788
0
      case AArch64_LD4Rv1d_POST:
1789
0
      case AArch64_LD4Rv2d_POST:
1790
0
      case AArch64_LD4Rv2s_POST:
1791
0
      case AArch64_LD4Rv4h_POST:
1792
0
      case AArch64_LD4Rv4s_POST:
1793
0
      case AArch64_LD4Rv8b_POST:
1794
0
      case AArch64_LD4Rv8h_POST:
1795
0
      case AArch64_LD4i16_POST:
1796
0
      case AArch64_LD4i32_POST:
1797
0
      case AArch64_LD4i64_POST:
1798
0
      case AArch64_LD4i8_POST:
1799
0
      case AArch64_LDPDpost:
1800
0
      case AArch64_LDPDpre:
1801
0
      case AArch64_LDPQpost:
1802
0
      case AArch64_LDPQpre:
1803
0
      case AArch64_LDPSWpost:
1804
0
      case AArch64_LDPSWpre:
1805
0
      case AArch64_LDPSpost:
1806
0
      case AArch64_LDPSpre:
1807
0
      case AArch64_LDPWpost:
1808
0
      case AArch64_LDPWpre:
1809
0
      case AArch64_LDPXpost:
1810
0
      case AArch64_LDPXpre:
1811
0
      case AArch64_LDRBBpost:
1812
0
      case AArch64_LDRBBpre:
1813
0
      case AArch64_LDRBpost:
1814
0
      case AArch64_LDRBpre:
1815
0
      case AArch64_LDRDpost:
1816
0
      case AArch64_LDRDpre:
1817
0
      case AArch64_LDRHHpost:
1818
0
      case AArch64_LDRHHpre:
1819
0
      case AArch64_LDRHpost:
1820
0
      case AArch64_LDRHpre:
1821
0
      case AArch64_LDRQpost:
1822
0
      case AArch64_LDRQpre:
1823
0
      case AArch64_LDRSBWpost:
1824
0
      case AArch64_LDRSBWpre:
1825
0
      case AArch64_LDRSBXpost:
1826
0
      case AArch64_LDRSBXpre:
1827
0
      case AArch64_LDRSHWpost:
1828
0
      case AArch64_LDRSHWpre:
1829
0
      case AArch64_LDRSHXpost:
1830
0
      case AArch64_LDRSHXpre:
1831
0
      case AArch64_LDRSWpost:
1832
0
      case AArch64_LDRSWpre:
1833
0
      case AArch64_LDRSpost:
1834
0
      case AArch64_LDRSpre:
1835
0
      case AArch64_LDRWpost:
1836
0
      case AArch64_LDRWpre:
1837
0
      case AArch64_LDRXpost:
1838
0
      case AArch64_LDRXpre:
1839
0
      case AArch64_ST1Fourv16b_POST:
1840
0
      case AArch64_ST1Fourv1d_POST:
1841
0
      case AArch64_ST1Fourv2d_POST:
1842
0
      case AArch64_ST1Fourv2s_POST:
1843
0
      case AArch64_ST1Fourv4h_POST:
1844
0
      case AArch64_ST1Fourv4s_POST:
1845
0
      case AArch64_ST1Fourv8b_POST:
1846
0
      case AArch64_ST1Fourv8h_POST:
1847
0
      case AArch64_ST1Onev16b_POST:
1848
0
      case AArch64_ST1Onev1d_POST:
1849
0
      case AArch64_ST1Onev2d_POST:
1850
0
      case AArch64_ST1Onev2s_POST:
1851
0
      case AArch64_ST1Onev4h_POST:
1852
0
      case AArch64_ST1Onev4s_POST:
1853
0
      case AArch64_ST1Onev8b_POST:
1854
0
      case AArch64_ST1Onev8h_POST:
1855
0
      case AArch64_ST1Threev16b_POST:
1856
0
      case AArch64_ST1Threev1d_POST:
1857
0
      case AArch64_ST1Threev2d_POST:
1858
0
      case AArch64_ST1Threev2s_POST:
1859
0
      case AArch64_ST1Threev4h_POST:
1860
0
      case AArch64_ST1Threev4s_POST:
1861
0
      case AArch64_ST1Threev8b_POST:
1862
0
      case AArch64_ST1Threev8h_POST:
1863
0
      case AArch64_ST1Twov16b_POST:
1864
0
      case AArch64_ST1Twov1d_POST:
1865
0
      case AArch64_ST1Twov2d_POST:
1866
0
      case AArch64_ST1Twov2s_POST:
1867
0
      case AArch64_ST1Twov4h_POST:
1868
0
      case AArch64_ST1Twov4s_POST:
1869
0
      case AArch64_ST1Twov8b_POST:
1870
0
      case AArch64_ST1Twov8h_POST:
1871
0
      case AArch64_ST1i16_POST:
1872
0
      case AArch64_ST1i32_POST:
1873
0
      case AArch64_ST1i64_POST:
1874
0
      case AArch64_ST1i8_POST:
1875
0
      case AArch64_ST2Twov16b_POST:
1876
0
      case AArch64_ST2Twov2d_POST:
1877
0
      case AArch64_ST2Twov2s_POST:
1878
0
      case AArch64_ST2Twov4h_POST:
1879
0
      case AArch64_ST2Twov4s_POST:
1880
0
      case AArch64_ST2Twov8b_POST:
1881
0
      case AArch64_ST2Twov8h_POST:
1882
0
      case AArch64_ST2i16_POST:
1883
0
      case AArch64_ST2i32_POST:
1884
0
      case AArch64_ST2i64_POST:
1885
0
      case AArch64_ST2i8_POST:
1886
0
      case AArch64_ST3Threev16b_POST:
1887
0
      case AArch64_ST3Threev2d_POST:
1888
0
      case AArch64_ST3Threev2s_POST:
1889
0
      case AArch64_ST3Threev4h_POST:
1890
0
      case AArch64_ST3Threev4s_POST:
1891
0
      case AArch64_ST3Threev8b_POST:
1892
0
      case AArch64_ST3Threev8h_POST:
1893
0
      case AArch64_ST3i16_POST:
1894
0
      case AArch64_ST3i32_POST:
1895
0
      case AArch64_ST3i64_POST:
1896
0
      case AArch64_ST3i8_POST:
1897
0
      case AArch64_ST4Fourv16b_POST:
1898
0
      case AArch64_ST4Fourv2d_POST:
1899
0
      case AArch64_ST4Fourv2s_POST:
1900
0
      case AArch64_ST4Fourv4h_POST:
1901
0
      case AArch64_ST4Fourv4s_POST:
1902
0
      case AArch64_ST4Fourv8b_POST:
1903
0
      case AArch64_ST4Fourv8h_POST:
1904
0
      case AArch64_ST4i16_POST:
1905
0
      case AArch64_ST4i32_POST:
1906
0
      case AArch64_ST4i64_POST:
1907
0
      case AArch64_ST4i8_POST:
1908
0
      case AArch64_STPDpost:
1909
0
      case AArch64_STPDpre:
1910
0
      case AArch64_STPQpost:
1911
0
      case AArch64_STPQpre:
1912
0
      case AArch64_STPSpost:
1913
0
      case AArch64_STPSpre:
1914
0
      case AArch64_STPWpost:
1915
0
      case AArch64_STPWpre:
1916
0
      case AArch64_STPXpost:
1917
0
      case AArch64_STPXpre:
1918
0
      case AArch64_STRBBpost:
1919
0
      case AArch64_STRBBpre:
1920
0
      case AArch64_STRBpost:
1921
0
      case AArch64_STRBpre:
1922
0
      case AArch64_STRDpost:
1923
0
      case AArch64_STRDpre:
1924
0
      case AArch64_STRHHpost:
1925
0
      case AArch64_STRHHpre:
1926
0
      case AArch64_STRHpost:
1927
0
      case AArch64_STRHpre:
1928
0
      case AArch64_STRQpost:
1929
0
      case AArch64_STRQpre:
1930
0
      case AArch64_STRSpost:
1931
0
      case AArch64_STRSpre:
1932
0
      case AArch64_STRWpost:
1933
0
      case AArch64_STRWpre:
1934
0
      case AArch64_STRXpost:
1935
0
      case AArch64_STRXpre:
1936
0
        flat_insn->detail->arm64.writeback = true;
1937
0
        break;
1938
0
    }
1939
0
  }
1940
0
}
1941
1942
#endif