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


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:39