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