Rizin
unix-like reverse engineering framework and cli tools
X86IntelInstPrinter.c
Go to the documentation of this file.
1 //===-- X86IntelInstPrinter.cpp - Intel assembly instruction printing -----===//
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 file includes code for rendering MCInst instances as Intel-style
11 // assembly.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 /* Capstone Disassembly Engine */
16 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
17 
18 #ifdef CAPSTONE_HAS_X86
19 
20 #if defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)
21 #pragma warning(disable:4996) // disable MSVC's warning on strncpy()
22 #pragma warning(disable:28719) // disable MSVC's warning on strncpy()
23 #endif
24 
25 #if !defined(CAPSTONE_HAS_OSXKERNEL)
26 #include <ctype.h>
27 #endif
28 #include <capstone/platform.h>
29 
30 #if defined(CAPSTONE_HAS_OSXKERNEL)
31 #include <Availability.h>
32 #include <libkern/libkern.h>
33 #else
34 #include <stdio.h>
35 #include <stdlib.h>
36 #endif
37 #include <string.h>
38 
39 #include "../../utils.h"
40 #include "../../MCInst.h"
41 #include "../../SStream.h"
42 #include "../../MCRegisterInfo.h"
43 
44 #include "X86InstPrinter.h"
45 #include "X86Mapping.h"
46 
47 #define GET_INSTRINFO_ENUM
48 #ifdef CAPSTONE_X86_REDUCE
50 #else
51 #include "X86GenInstrInfo.inc"
52 #endif
53 
54 #include "X86BaseInfo.h"
55 
56 static void printMemReference(MCInst *MI, unsigned Op, SStream *O);
57 static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
58 
59 
60 static void set_mem_access(MCInst *MI, bool status)
61 {
62  if (MI->csh->detail != CS_OPT_ON)
63  return;
64 
65  MI->csh->doing_mem = status;
66  if (!status)
67  // done, create the next operand slot
68  MI->flat_insn->detail->x86.op_count++;
69 
70 }
71 
72 static void printopaquemem(MCInst *MI, unsigned OpNo, SStream *O)
73 {
74  // FIXME: do this with autogen
75  // printf(">>> ID = %u\n", MI->flat_insn->id);
76  switch(MI->flat_insn->id) {
77  default:
78  SStream_concat0(O, "ptr ");
79  break;
80  case X86_INS_SGDT:
81  case X86_INS_SIDT:
82  case X86_INS_LGDT:
83  case X86_INS_LIDT:
84  case X86_INS_FXRSTOR:
85  case X86_INS_FXSAVE:
86  case X86_INS_LJMP:
87  case X86_INS_LCALL:
88  // do not print "ptr"
89  break;
90  }
91 
92  switch(MI->csh->mode) {
93  case CS_MODE_16:
94  switch(MI->flat_insn->id) {
95  default:
96  MI->x86opsize = 2;
97  break;
98  case X86_INS_LJMP:
99  case X86_INS_LCALL:
100  MI->x86opsize = 4;
101  break;
102  case X86_INS_SGDT:
103  case X86_INS_SIDT:
104  case X86_INS_LGDT:
105  case X86_INS_LIDT:
106  MI->x86opsize = 6;
107  break;
108  }
109  break;
110  case CS_MODE_32:
111  switch(MI->flat_insn->id) {
112  default:
113  MI->x86opsize = 4;
114  break;
115  case X86_INS_LJMP:
116  case X86_INS_LCALL:
117  case X86_INS_SGDT:
118  case X86_INS_SIDT:
119  case X86_INS_LGDT:
120  case X86_INS_LIDT:
121  MI->x86opsize = 6;
122  break;
123  }
124  break;
125  case CS_MODE_64:
126  switch(MI->flat_insn->id) {
127  default:
128  MI->x86opsize = 8;
129  break;
130  case X86_INS_LJMP:
131  case X86_INS_LCALL:
132  case X86_INS_SGDT:
133  case X86_INS_SIDT:
134  case X86_INS_LGDT:
135  case X86_INS_LIDT:
136  MI->x86opsize = 10;
137  break;
138  }
139  break;
140  default: // never reach
141  break;
142  }
143 
144  printMemReference(MI, OpNo, O);
145 }
146 
147 static void printi8mem(MCInst *MI, unsigned OpNo, SStream *O)
148 {
149  SStream_concat0(O, "byte ptr ");
150  MI->x86opsize = 1;
151  printMemReference(MI, OpNo, O);
152 }
153 
154 static void printi16mem(MCInst *MI, unsigned OpNo, SStream *O)
155 {
156  MI->x86opsize = 2;
157  SStream_concat0(O, "word ptr ");
158  printMemReference(MI, OpNo, O);
159 }
160 
161 static void printi32mem(MCInst *MI, unsigned OpNo, SStream *O)
162 {
163  MI->x86opsize = 4;
164  SStream_concat0(O, "dword ptr ");
165  printMemReference(MI, OpNo, O);
166 }
167 
168 static void printi64mem(MCInst *MI, unsigned OpNo, SStream *O)
169 {
170  SStream_concat0(O, "qword ptr ");
171  MI->x86opsize = 8;
172  printMemReference(MI, OpNo, O);
173 }
174 
175 static void printi128mem(MCInst *MI, unsigned OpNo, SStream *O)
176 {
177  SStream_concat0(O, "xmmword ptr ");
178  MI->x86opsize = 16;
179  printMemReference(MI, OpNo, O);
180 }
181 
182 #ifndef CAPSTONE_X86_REDUCE
183 static void printi256mem(MCInst *MI, unsigned OpNo, SStream *O)
184 {
185  SStream_concat0(O, "ymmword ptr ");
186  MI->x86opsize = 32;
187  printMemReference(MI, OpNo, O);
188 }
189 
190 static void printi512mem(MCInst *MI, unsigned OpNo, SStream *O)
191 {
192  SStream_concat0(O, "zmmword ptr ");
193  MI->x86opsize = 64;
194  printMemReference(MI, OpNo, O);
195 }
196 
197 static void printf32mem(MCInst *MI, unsigned OpNo, SStream *O)
198 {
199  switch(MCInst_getOpcode(MI)) {
200  default:
201  SStream_concat0(O, "dword ptr ");
202  MI->x86opsize = 4;
203  break;
204  case X86_FBSTPm:
205  case X86_FBLDm:
206  // TODO: fix this in tablegen instead
207  SStream_concat0(O, "tbyte ptr ");
208  MI->x86opsize = 10;
209  break;
210  case X86_FSTENVm:
211  case X86_FLDENVm:
212  // TODO: fix this in tablegen instead
213  switch(MI->csh->mode) {
214  default: // never reach
215  break;
216  case CS_MODE_16:
217  MI->x86opsize = 14;
218  break;
219  case CS_MODE_32:
220  case CS_MODE_64:
221  MI->x86opsize = 28;
222  break;
223  }
224  break;
225  }
226 
227  printMemReference(MI, OpNo, O);
228 }
229 
230 static void printf64mem(MCInst *MI, unsigned OpNo, SStream *O)
231 {
232  SStream_concat0(O, "qword ptr ");
233  MI->x86opsize = 8;
234  printMemReference(MI, OpNo, O);
235 }
236 
237 static void printf80mem(MCInst *MI, unsigned OpNo, SStream *O)
238 {
239  SStream_concat0(O, "xword ptr ");
240  MI->x86opsize = 10;
241  printMemReference(MI, OpNo, O);
242 }
243 
244 static void printf128mem(MCInst *MI, unsigned OpNo, SStream *O)
245 {
246  SStream_concat0(O, "xmmword ptr ");
247  MI->x86opsize = 16;
248  printMemReference(MI, OpNo, O);
249 }
250 
251 static void printf256mem(MCInst *MI, unsigned OpNo, SStream *O)
252 {
253  SStream_concat0(O, "ymmword ptr ");
254  MI->x86opsize = 32;
255  printMemReference(MI, OpNo, O);
256 }
257 
258 static void printf512mem(MCInst *MI, unsigned OpNo, SStream *O)
259 {
260  SStream_concat0(O, "zmmword ptr ");
261  MI->x86opsize = 64;
262  printMemReference(MI, OpNo, O);
263 }
264 
265 static void printSSECC(MCInst *MI, unsigned Op, SStream *OS)
266 {
267  uint8_t Imm = (uint8_t)(MCOperand_getImm(MCInst_getOperand(MI, Op)) & 7);
268  switch (Imm) {
269  default: break; // never reach
270  case 0: SStream_concat0(OS, "eq"); op_addSseCC(MI, X86_SSE_CC_EQ); break;
271  case 1: SStream_concat0(OS, "lt"); op_addSseCC(MI, X86_SSE_CC_LT); break;
272  case 2: SStream_concat0(OS, "le"); op_addSseCC(MI, X86_SSE_CC_LE); break;
273  case 3: SStream_concat0(OS, "unord"); op_addSseCC(MI, X86_SSE_CC_UNORD); break;
274  case 4: SStream_concat0(OS, "neq"); op_addSseCC(MI, X86_SSE_CC_NEQ); break;
275  case 5: SStream_concat0(OS, "nlt"); op_addSseCC(MI, X86_SSE_CC_NLT); break;
276  case 6: SStream_concat0(OS, "nle"); op_addSseCC(MI, X86_SSE_CC_NLE); break;
277  case 7: SStream_concat0(OS, "ord"); op_addSseCC(MI, X86_SSE_CC_ORD); break;
278  }
279 
280  MI->popcode_adjust = Imm + 1;
281 }
282 
283 static void printAVXCC(MCInst *MI, unsigned Op, SStream *O)
284 {
285  uint8_t Imm = (uint8_t)(MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x1f);
286  switch (Imm) {
287  default: break;//printf("Invalid avxcc argument!\n"); break;
288  case 0: SStream_concat0(O, "eq"); op_addAvxCC(MI, X86_AVX_CC_EQ); break;
289  case 1: SStream_concat0(O, "lt"); op_addAvxCC(MI, X86_AVX_CC_LT); break;
290  case 2: SStream_concat0(O, "le"); op_addAvxCC(MI, X86_AVX_CC_LE); break;
291  case 3: SStream_concat0(O, "unord"); op_addAvxCC(MI, X86_AVX_CC_UNORD); break;
292  case 4: SStream_concat0(O, "neq"); op_addAvxCC(MI, X86_AVX_CC_NEQ); break;
293  case 5: SStream_concat0(O, "nlt"); op_addAvxCC(MI, X86_AVX_CC_NLT); break;
294  case 6: SStream_concat0(O, "nle"); op_addAvxCC(MI, X86_AVX_CC_NLE); break;
295  case 7: SStream_concat0(O, "ord"); op_addAvxCC(MI, X86_AVX_CC_ORD); break;
296  case 8: SStream_concat0(O, "eq_uq"); op_addAvxCC(MI, X86_AVX_CC_EQ_UQ); break;
297  case 9: SStream_concat0(O, "nge"); op_addAvxCC(MI, X86_AVX_CC_NGE); break;
298  case 0xa: SStream_concat0(O, "ngt"); op_addAvxCC(MI, X86_AVX_CC_NGT); break;
299  case 0xb: SStream_concat0(O, "false"); op_addAvxCC(MI, X86_AVX_CC_FALSE); break;
300  case 0xc: SStream_concat0(O, "neq_oq"); op_addAvxCC(MI, X86_AVX_CC_NEQ_OQ); break;
301  case 0xd: SStream_concat0(O, "ge"); op_addAvxCC(MI, X86_AVX_CC_GE); break;
302  case 0xe: SStream_concat0(O, "gt"); op_addAvxCC(MI, X86_AVX_CC_GT); break;
303  case 0xf: SStream_concat0(O, "true"); op_addAvxCC(MI, X86_AVX_CC_TRUE); break;
304  case 0x10: SStream_concat0(O, "eq_os"); op_addAvxCC(MI, X86_AVX_CC_EQ_OS); break;
305  case 0x11: SStream_concat0(O, "lt_oq"); op_addAvxCC(MI, X86_AVX_CC_LT_OQ); break;
306  case 0x12: SStream_concat0(O, "le_oq"); op_addAvxCC(MI, X86_AVX_CC_LE_OQ); break;
307  case 0x13: SStream_concat0(O, "unord_s"); op_addAvxCC(MI, X86_AVX_CC_UNORD_S); break;
308  case 0x14: SStream_concat0(O, "neq_us"); op_addAvxCC(MI, X86_AVX_CC_NEQ_US); break;
309  case 0x15: SStream_concat0(O, "nlt_uq"); op_addAvxCC(MI, X86_AVX_CC_NLT_UQ); break;
310  case 0x16: SStream_concat0(O, "nle_uq"); op_addAvxCC(MI, X86_AVX_CC_NLE_UQ); break;
311  case 0x17: SStream_concat0(O, "ord_s"); op_addAvxCC(MI, X86_AVX_CC_ORD_S); break;
312  case 0x18: SStream_concat0(O, "eq_us"); op_addAvxCC(MI, X86_AVX_CC_EQ_US); break;
313  case 0x19: SStream_concat0(O, "nge_uq"); op_addAvxCC(MI, X86_AVX_CC_NGE_UQ); break;
314  case 0x1a: SStream_concat0(O, "ngt_uq"); op_addAvxCC(MI, X86_AVX_CC_NGT_UQ); break;
315  case 0x1b: SStream_concat0(O, "false_os"); op_addAvxCC(MI, X86_AVX_CC_FALSE_OS); break;
316  case 0x1c: SStream_concat0(O, "neq_os"); op_addAvxCC(MI, X86_AVX_CC_NEQ_OS); break;
317  case 0x1d: SStream_concat0(O, "ge_oq"); op_addAvxCC(MI, X86_AVX_CC_GE_OQ); break;
318  case 0x1e: SStream_concat0(O, "gt_oq"); op_addAvxCC(MI, X86_AVX_CC_GT_OQ); break;
319  case 0x1f: SStream_concat0(O, "true_us"); op_addAvxCC(MI, X86_AVX_CC_TRUE_US); break;
320  }
321 
322  MI->popcode_adjust = Imm + 1;
323 }
324 
325 static void printXOPCC(MCInst *MI, unsigned Op, SStream *O)
326 {
328 
329  switch (Imm) {
330  default: // llvm_unreachable("Invalid xopcc argument!");
331  case 0: SStream_concat0(O, "lt"); op_addXopCC(MI, X86_XOP_CC_LT); break;
332  case 1: SStream_concat0(O, "le"); op_addXopCC(MI, X86_XOP_CC_LE); break;
333  case 2: SStream_concat0(O, "gt"); op_addXopCC(MI, X86_XOP_CC_GT); break;
334  case 3: SStream_concat0(O, "ge"); op_addXopCC(MI, X86_XOP_CC_GE); break;
335  case 4: SStream_concat0(O, "eq"); op_addXopCC(MI, X86_XOP_CC_EQ); break;
336  case 5: SStream_concat0(O, "neq"); op_addXopCC(MI, X86_XOP_CC_NEQ); break;
337  case 6: SStream_concat0(O, "false"); op_addXopCC(MI, X86_XOP_CC_FALSE); break;
338  case 7: SStream_concat0(O, "true"); op_addXopCC(MI, X86_XOP_CC_TRUE); break;
339  }
340 }
341 
342 static void printRoundingControl(MCInst *MI, unsigned Op, SStream *O)
343 {
344  int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x3;
345  switch (Imm) {
346  case 0: SStream_concat0(O, "{rn-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RN); break;
347  case 1: SStream_concat0(O, "{rd-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RD); break;
348  case 2: SStream_concat0(O, "{ru-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RU); break;
349  case 3: SStream_concat0(O, "{rz-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RZ); break;
350  default: break; // never reach
351  }
352 }
353 
354 #endif
355 
356 static const char *getRegisterName(unsigned RegNo);
357 static void printRegName(SStream *OS, unsigned RegNo)
358 {
359  SStream_concat0(OS, getRegisterName(RegNo));
360 }
361 
362 // for MASM syntax, 0x123 = 123h, 0xA123 = 0A123h
363 // this function tell us if we need to have prefix 0 in front of a number
364 static bool need_zero_prefix(uint64_t imm)
365 {
366  // find the first hex letter representing imm
367  while(imm >= 0x10)
368  imm >>= 4;
369 
370  if (imm < 0xa)
371  return false;
372  else // this need 0 prefix
373  return true;
374 }
375 
376 static void printImm(MCInst *MI, SStream *O, int64_t imm, bool positive)
377 {
378  if (positive) {
379  // always print this number in positive form
380  if (MI->csh->syntax == CS_OPT_SYNTAX_MASM) {
381  if (imm < 0) {
382  if (MI->op1_size) {
383  switch(MI->op1_size) {
384  default:
385  break;
386  case 1:
387  imm &= 0xff;
388  break;
389  case 2:
390  imm &= 0xffff;
391  break;
392  case 4:
393  imm &= 0xffffffff;
394  break;
395  }
396  }
397 
398  if (imm == 0x8000000000000000LL) // imm == -imm
399  SStream_concat0(O, "8000000000000000h");
400  else if (need_zero_prefix(imm))
401  SStream_concat(O, "0%"PRIx64"h", imm);
402  else
403  SStream_concat(O, "%"PRIx64"h", imm);
404  } else {
405  if (imm > HEX_THRESHOLD) {
406  if (need_zero_prefix(imm))
407  SStream_concat(O, "0%"PRIx64"h", imm);
408  else
409  SStream_concat(O, "%"PRIx64"h", imm);
410  } else
411  SStream_concat(O, "%"PRIu64, imm);
412  }
413  } else { // Intel syntax
414  if (imm < 0) {
415  if (MI->op1_size) {
416  switch(MI->op1_size) {
417  default:
418  break;
419  case 1:
420  imm &= 0xff;
421  break;
422  case 2:
423  imm &= 0xffff;
424  break;
425  case 4:
426  imm &= 0xffffffff;
427  break;
428  }
429  }
430 
431  SStream_concat(O, "0x%"PRIx64, imm);
432  } else {
433  if (imm > HEX_THRESHOLD)
434  SStream_concat(O, "0x%"PRIx64, imm);
435  else
436  SStream_concat(O, "%"PRIu64, imm);
437  }
438  }
439  } else {
440  if (MI->csh->syntax == CS_OPT_SYNTAX_MASM) {
441  if (imm < 0) {
442  if (imm == 0x8000000000000000LL) // imm == -imm
443  SStream_concat0(O, "8000000000000000h");
444  else if (imm < -HEX_THRESHOLD) {
445  if (need_zero_prefix(imm))
446  SStream_concat(O, "-0%"PRIx64"h", -imm);
447  else
448  SStream_concat(O, "-%"PRIx64"h", -imm);
449  } else
450  SStream_concat(O, "-%"PRIu64, -imm);
451  } else {
452  if (imm > HEX_THRESHOLD) {
453  if (need_zero_prefix(imm))
454  SStream_concat(O, "0%"PRIx64"h", imm);
455  else
456  SStream_concat(O, "%"PRIx64"h", imm);
457  } else
458  SStream_concat(O, "%"PRIu64, imm);
459  }
460  } else { // Intel syntax
461  if (imm < 0) {
462  if (imm == 0x8000000000000000LL) // imm == -imm
463  SStream_concat0(O, "0x8000000000000000");
464  else if (imm < -HEX_THRESHOLD)
465  SStream_concat(O, "-0x%"PRIx64, -imm);
466  else
467  SStream_concat(O, "-%"PRIu64, -imm);
468 
469  } else {
470  if (imm > HEX_THRESHOLD)
471  SStream_concat(O, "0x%"PRIx64, imm);
472  else
473  SStream_concat(O, "%"PRIu64, imm);
474  }
475  }
476  }
477 }
478 
479 // local printOperand, without updating public operands
480 static void _printOperand(MCInst *MI, unsigned OpNo, SStream *O)
481 {
482  MCOperand *Op = MCInst_getOperand(MI, OpNo);
483  if (MCOperand_isReg(Op)) {
484  printRegName(O, MCOperand_getReg(Op));
485  } else if (MCOperand_isImm(Op)) {
487  printImm(MI, O, imm, MI->csh->imm_unsigned);
488  }
489 }
490 
491 #ifndef CAPSTONE_DIET
492 // copy & normalize access info
493 static void get_op_access(cs_struct *h, unsigned int id, uint8_t *access, uint64_t *eflags)
494 {
495 #ifndef CAPSTONE_DIET
496  uint8_t i;
497  uint8_t *arr = X86_get_op_access(h, id, eflags);
498 
499  if (!arr) {
500  access[0] = 0;
501  return;
502  }
503 
504  // copy to access but zero out CS_AC_IGNORE
505  for(i = 0; arr[i]; i++) {
506  if (arr[i] != CS_AC_IGNORE)
507  access[i] = arr[i];
508  else
509  access[i] = 0;
510  }
511 
512  // mark the end of array
513  access[i] = 0;
514 #endif
515 }
516 #endif
517 
518 static void printSrcIdx(MCInst *MI, unsigned Op, SStream *O)
519 {
520  MCOperand *SegReg;
521  int reg;
522 
523  if (MI->csh->detail) {
524 #ifndef CAPSTONE_DIET
525  uint8_t access[6];
526 #endif
527 
528  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
529  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
530  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_INVALID;
531  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_REG_INVALID;
532  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = X86_REG_INVALID;
533  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
534  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0;
535 
536 #ifndef CAPSTONE_DIET
537  get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
538  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
539 #endif
540  }
541 
542  SegReg = MCInst_getOperand(MI, Op+1);
543  reg = MCOperand_getReg(SegReg);
544 
545  // If this has a segment register, print it.
546  if (reg) {
547  _printOperand(MI, Op+1, O);
548  if (MI->csh->detail) {
549  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = reg;
550  }
551  SStream_concat0(O, ":");
552  }
553 
554  SStream_concat0(O, "[");
555  set_mem_access(MI, true);
556  printOperand(MI, Op, O);
557  SStream_concat0(O, "]");
558  set_mem_access(MI, false);
559 }
560 
561 static void printDstIdx(MCInst *MI, unsigned Op, SStream *O)
562 {
563  if (MI->csh->detail) {
564 #ifndef CAPSTONE_DIET
565  uint8_t access[6];
566 #endif
567 
568  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
569  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
570  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_INVALID;
571  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_REG_INVALID;
572  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = X86_REG_INVALID;
573  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
574  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0;
575 
576 #ifndef CAPSTONE_DIET
577  get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
578  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
579 #endif
580  }
581 
582  // DI accesses are always ES-based on non-64bit mode
583  if (MI->csh->mode != CS_MODE_64) {
584  SStream_concat(O, "es:[");
585  if (MI->csh->detail) {
586  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_ES;
587  }
588  } else
589  SStream_concat(O, "[");
590 
591  set_mem_access(MI, true);
592  printOperand(MI, Op, O);
593  SStream_concat0(O, "]");
594  set_mem_access(MI, false);
595 }
596 
597 static void printSrcIdx8(MCInst *MI, unsigned OpNo, SStream *O)
598 {
599  SStream_concat0(O, "byte ptr ");
600  MI->x86opsize = 1;
601  printSrcIdx(MI, OpNo, O);
602 }
603 
604 static void printSrcIdx16(MCInst *MI, unsigned OpNo, SStream *O)
605 {
606  SStream_concat0(O, "word ptr ");
607  MI->x86opsize = 2;
608  printSrcIdx(MI, OpNo, O);
609 }
610 
611 static void printSrcIdx32(MCInst *MI, unsigned OpNo, SStream *O)
612 {
613  SStream_concat0(O, "dword ptr ");
614  MI->x86opsize = 4;
615  printSrcIdx(MI, OpNo, O);
616 }
617 
618 static void printSrcIdx64(MCInst *MI, unsigned OpNo, SStream *O)
619 {
620  SStream_concat0(O, "qword ptr ");
621  MI->x86opsize = 8;
622  printSrcIdx(MI, OpNo, O);
623 }
624 
625 static void printDstIdx8(MCInst *MI, unsigned OpNo, SStream *O)
626 {
627  SStream_concat0(O, "byte ptr ");
628  MI->x86opsize = 1;
629  printDstIdx(MI, OpNo, O);
630 }
631 
632 static void printDstIdx16(MCInst *MI, unsigned OpNo, SStream *O)
633 {
634  SStream_concat0(O, "word ptr ");
635  MI->x86opsize = 2;
636  printDstIdx(MI, OpNo, O);
637 }
638 
639 static void printDstIdx32(MCInst *MI, unsigned OpNo, SStream *O)
640 {
641  SStream_concat0(O, "dword ptr ");
642  MI->x86opsize = 4;
643  printDstIdx(MI, OpNo, O);
644 }
645 
646 static void printDstIdx64(MCInst *MI, unsigned OpNo, SStream *O)
647 {
648  SStream_concat0(O, "qword ptr ");
649  MI->x86opsize = 8;
650  printDstIdx(MI, OpNo, O);
651 }
652 
653 static void printMemOffset(MCInst *MI, unsigned Op, SStream *O)
654 {
655  MCOperand *DispSpec = MCInst_getOperand(MI, Op);
656  MCOperand *SegReg = MCInst_getOperand(MI, Op + 1);
657  int reg;
658 
659  if (MI->csh->detail) {
660 #ifndef CAPSTONE_DIET
661  uint8_t access[6];
662 #endif
663 
664  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
665  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
666  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_INVALID;
667  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_REG_INVALID;
668  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = X86_REG_INVALID;
669  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
670  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0;
671 
672 #ifndef CAPSTONE_DIET
673  get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
674  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
675 #endif
676  }
677 
678  // If this has a segment register, print it.
679  reg = MCOperand_getReg(SegReg);
680  if (reg) {
681  _printOperand(MI, Op + 1, O);
682  SStream_concat0(O, ":");
683  if (MI->csh->detail) {
684  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = reg;
685  }
686  }
687 
688  SStream_concat0(O, "[");
689 
690  if (MCOperand_isImm(DispSpec)) {
691  int64_t imm = MCOperand_getImm(DispSpec);
692  if (MI->csh->detail)
693  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
694 
695  if (imm < 0)
696  printImm(MI, O, arch_masks[MI->csh->mode] & imm, true);
697  else
698  printImm(MI, O, imm, true);
699  }
700 
701  SStream_concat0(O, "]");
702 
703  if (MI->csh->detail)
704  MI->flat_insn->detail->x86.op_count++;
705 
706  if (MI->op1_size == 0)
707  MI->op1_size = MI->x86opsize;
708 }
709 
710 #ifndef CAPSTONE_X86_REDUCE
711 static void printU8Imm(MCInst *MI, unsigned Op, SStream *O)
712 {
713  uint8_t val = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0xff;
714 
715  printImm(MI, O, val, true);
716 
717  if (MI->csh->detail) {
718 #ifndef CAPSTONE_DIET
719  uint8_t access[6];
720 #endif
721 
722  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
723  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = val;
724  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = 1;
725 
726 #ifndef CAPSTONE_DIET
727  get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
728  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
729 #endif
730 
731  MI->flat_insn->detail->x86.op_count++;
732  }
733 }
734 #endif
735 
736 static void printMemOffs8(MCInst *MI, unsigned OpNo, SStream *O)
737 {
738  SStream_concat0(O, "byte ptr ");
739  MI->x86opsize = 1;
740  printMemOffset(MI, OpNo, O);
741 }
742 
743 static void printMemOffs16(MCInst *MI, unsigned OpNo, SStream *O)
744 {
745  SStream_concat0(O, "word ptr ");
746  MI->x86opsize = 2;
747  printMemOffset(MI, OpNo, O);
748 }
749 
750 static void printMemOffs32(MCInst *MI, unsigned OpNo, SStream *O)
751 {
752  SStream_concat0(O, "dword ptr ");
753  MI->x86opsize = 4;
754  printMemOffset(MI, OpNo, O);
755 }
756 
757 static void printMemOffs64(MCInst *MI, unsigned OpNo, SStream *O)
758 {
759  SStream_concat0(O, "qword ptr ");
760  MI->x86opsize = 8;
761  printMemOffset(MI, OpNo, O);
762 }
763 
764 #ifndef CAPSTONE_DIET
765 static char *printAliasInstr(MCInst *MI, SStream *OS, void *info);
766 #endif
767 static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI);
768 
769 void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info)
770 {
771 #ifndef CAPSTONE_DIET
772  char *mnem;
773 #endif
774  x86_reg reg, reg2;
775  enum cs_ac_type access1, access2;
776 
777  // perhaps this instruction does not need printer
778  if (MI->assembly[0]) {
779  strncpy(O->buffer, MI->assembly, sizeof(O->buffer));
780  return;
781  }
782 
783 #ifndef CAPSTONE_DIET
784  // Try to print any aliases first.
785  mnem = printAliasInstr(MI, O, Info);
786  if (mnem)
787  cs_mem_free(mnem);
788  else
789 #endif
790  printInstruction(MI, O, Info);
791 
792  reg = X86_insn_reg_intel(MCInst_getOpcode(MI), &access1);
793  if (MI->csh->detail) {
794 #ifndef CAPSTONE_DIET
795  uint8_t access[6] = {0};
796 #endif
797 
798  // first op can be embedded in the asm by llvm.
799  // so we have to add the missing register as the first operand
800  if (reg) {
801  // shift all the ops right to leave 1st slot for this new register op
802  memmove(&(MI->flat_insn->detail->x86.operands[1]), &(MI->flat_insn->detail->x86.operands[0]),
803  sizeof(MI->flat_insn->detail->x86.operands[0]) * (ARR_SIZE(MI->flat_insn->detail->x86.operands) - 1));
804  MI->flat_insn->detail->x86.operands[0].type = X86_OP_REG;
805  MI->flat_insn->detail->x86.operands[0].reg = reg;
806  MI->flat_insn->detail->x86.operands[0].size = MI->csh->regsize_map[reg];
807  MI->flat_insn->detail->x86.operands[0].access = access1;
808  MI->flat_insn->detail->x86.op_count++;
809  } else {
810  if (X86_insn_reg_intel2(MCInst_getOpcode(MI), &reg, &access1, &reg2, &access2)) {
811  MI->flat_insn->detail->x86.operands[0].type = X86_OP_REG;
812  MI->flat_insn->detail->x86.operands[0].reg = reg;
813  MI->flat_insn->detail->x86.operands[0].size = MI->csh->regsize_map[reg];
814  MI->flat_insn->detail->x86.operands[0].access = access1;
815  MI->flat_insn->detail->x86.operands[1].type = X86_OP_REG;
816  MI->flat_insn->detail->x86.operands[1].reg = reg2;
817  MI->flat_insn->detail->x86.operands[1].size = MI->csh->regsize_map[reg2];
818  MI->flat_insn->detail->x86.operands[1].access = access2;
819  MI->flat_insn->detail->x86.op_count = 2;
820  }
821  }
822 
823 #ifndef CAPSTONE_DIET
824  get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
825  MI->flat_insn->detail->x86.operands[0].access = access[0];
826  MI->flat_insn->detail->x86.operands[1].access = access[1];
827 #endif
828  }
829 
830  if (MI->op1_size == 0 && reg)
831  MI->op1_size = MI->csh->regsize_map[reg];
832 }
833 
836 static void printPCRelImm(MCInst *MI, unsigned OpNo, SStream *O)
837 {
838  MCOperand *Op = MCInst_getOperand(MI, OpNo);
839  if (MCOperand_isImm(Op)) {
840  int64_t imm = MCOperand_getImm(Op) + MI->flat_insn->size + MI->address;
841  uint8_t opsize = X86_immediate_size(MI->Opcode, NULL);
842 
843  // truncat imm for non-64bit
844  if (MI->csh->mode != CS_MODE_64) {
845  imm = imm & 0xffffffff;
846  }
847 
848  if (MI->csh->mode == CS_MODE_16 &&
849  (MI->Opcode != X86_JMP_4 && MI->Opcode != X86_CALLpcrel32))
850  imm = imm & 0xffff;
851 
852  // Hack: X86 16bit with opcode X86_JMP_4
853  if (MI->csh->mode == CS_MODE_16 &&
854  (MI->Opcode == X86_JMP_4 && MI->x86_prefix[2] != 0x66))
855  imm = imm & 0xffff;
856 
857  // CALL/JMP rel16 is special
858  if (MI->Opcode == X86_CALLpcrel16 || MI->Opcode == X86_JMP_2)
859  imm = imm & 0xffff;
860 
861  if (MI->csh->mode == CS_MODE_16)
862  imm |= (MI->address >> 16) << 16;
863 
864  printImm(MI, O, imm, true);
865 
866  if (MI->csh->detail) {
867 #ifndef CAPSTONE_DIET
868  uint8_t access[6];
869 #endif
870 
871  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
872  // if op_count > 0, then this operand's size is taken from the destination op
873  if (MI->flat_insn->detail->x86.op_count > 0)
874  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->flat_insn->detail->x86.operands[0].size;
875  else if (opsize > 0)
876  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = opsize;
877  else
878  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->imm_size;
879  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;
880 
881 #ifndef CAPSTONE_DIET
882  get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
883  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
884 #endif
885 
886  MI->flat_insn->detail->x86.op_count++;
887  }
888 
889  if (MI->op1_size == 0)
890  MI->op1_size = MI->imm_size;
891  }
892 }
893 
894 static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
895 {
896  MCOperand *Op = MCInst_getOperand(MI, OpNo);
897 
898  if (MCOperand_isReg(Op)) {
899  unsigned int reg = MCOperand_getReg(Op);
900 
901  printRegName(O, reg);
902  if (MI->csh->detail) {
903  if (MI->csh->doing_mem) {
904  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = reg;
905  } else {
906 #ifndef CAPSTONE_DIET
907  uint8_t access[6];
908 #endif
909 
910  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_REG;
911  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].reg = reg;
912  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->csh->regsize_map[reg];
913 
914 #ifndef CAPSTONE_DIET
915  get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
916  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
917 #endif
918 
919  MI->flat_insn->detail->x86.op_count++;
920  }
921  }
922 
923  if (MI->op1_size == 0)
924  MI->op1_size = MI->csh->regsize_map[reg];
925  } else if (MCOperand_isImm(Op)) {
926  uint8_t encsize;
928  uint8_t opsize = X86_immediate_size(MCInst_getOpcode(MI), &encsize);
929 
930  if (opsize == 1) // print 1 byte immediate in positive form
931  imm = imm & 0xff;
932 
933  // printf(">>> id = %u\n", MI->flat_insn->id);
934  switch(MI->flat_insn->id) {
935  default:
936  printImm(MI, O, imm, MI->csh->imm_unsigned);
937  break;
938 
939  case X86_INS_MOVABS:
940  // do not print number in negative form
941  printImm(MI, O, imm, true);
942  break;
943 
944  case X86_INS_IN:
945  case X86_INS_OUT:
946  case X86_INS_INT:
947  // do not print number in negative form
948  imm = imm & 0xff;
949  printImm(MI, O, imm, true);
950  break;
951 
952  case X86_INS_LCALL:
953  case X86_INS_LJMP:
954  // always print address in positive form
955  if (OpNo == 1) { // ptr16 part
956  imm = imm & 0xffff;
957  opsize = 2;
958  }
959  printImm(MI, O, imm, true);
960  break;
961 
962  case X86_INS_AND:
963  case X86_INS_OR:
964  case X86_INS_XOR:
965  // do not print number in negative form
966  if (imm >= 0 && imm <= HEX_THRESHOLD)
967  printImm(MI, O, imm, true);
968  else {
969  imm = arch_masks[opsize? opsize : MI->imm_size] & imm;
970  printImm(MI, O, imm, true);
971  }
972  break;
973 
974  case X86_INS_RET:
975  case X86_INS_RETF:
976  // RET imm16
977  if (imm >= 0 && imm <= HEX_THRESHOLD)
978  printImm(MI, O, imm, true);
979  else {
980  imm = 0xffff & imm;
981  printImm(MI, O, imm, true);
982  }
983  break;
984  }
985 
986  if (MI->csh->detail) {
987  if (MI->csh->doing_mem) {
988  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
989  } else {
990 #ifndef CAPSTONE_DIET
991  uint8_t access[6];
992 #endif
993 
994  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
995  if (opsize > 0) {
996  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = opsize;
997  MI->flat_insn->detail->x86.encoding.imm_size = encsize;
998  } else if (MI->flat_insn->detail->x86.op_count > 0) {
999  if (MI->flat_insn->id != X86_INS_LCALL && MI->flat_insn->id != X86_INS_LJMP) {
1000  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size =
1001  MI->flat_insn->detail->x86.operands[0].size;
1002  } else
1003  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->imm_size;
1004  } else
1005  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->imm_size;
1006  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;
1007 
1008 #ifndef CAPSTONE_DIET
1009  get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
1010  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
1011 #endif
1012 
1013  MI->flat_insn->detail->x86.op_count++;
1014  }
1015  }
1016  }
1017 }
1018 
1019 static void printMemReference(MCInst *MI, unsigned Op, SStream *O)
1020 {
1021  bool NeedPlus = false;
1022  MCOperand *BaseReg = MCInst_getOperand(MI, Op + X86_AddrBaseReg);
1024  MCOperand *IndexReg = MCInst_getOperand(MI, Op + X86_AddrIndexReg);
1025  MCOperand *DispSpec = MCInst_getOperand(MI, Op + X86_AddrDisp);
1026  MCOperand *SegReg = MCInst_getOperand(MI, Op + X86_AddrSegmentReg);
1027  int reg;
1028 
1029  if (MI->csh->detail) {
1030 #ifndef CAPSTONE_DIET
1031  uint8_t access[6];
1032 #endif
1033 
1034  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
1035  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
1036  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_INVALID;
1037  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = MCOperand_getReg(BaseReg);
1038  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = MCOperand_getReg(IndexReg);
1039  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = (int)ScaleVal;
1040  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0;
1041 
1042 #ifndef CAPSTONE_DIET
1043  get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
1044  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
1045 #endif
1046  }
1047 
1048  // If this has a segment register, print it.
1049  reg = MCOperand_getReg(SegReg);
1050  if (reg) {
1051  _printOperand(MI, Op + X86_AddrSegmentReg, O);
1052  if (MI->csh->detail) {
1053  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = reg;
1054  }
1055  SStream_concat0(O, ":");
1056  }
1057 
1058  SStream_concat0(O, "[");
1059 
1060  if (MCOperand_getReg(BaseReg)) {
1061  _printOperand(MI, Op + X86_AddrBaseReg, O);
1062  NeedPlus = true;
1063  }
1064 
1065  if (MCOperand_getReg(IndexReg)) {
1066  if (NeedPlus) SStream_concat0(O, " + ");
1067  _printOperand(MI, Op + X86_AddrIndexReg, O);
1068  if (ScaleVal != 1)
1069  SStream_concat(O, "*%u", ScaleVal);
1070  NeedPlus = true;
1071  }
1072 
1073  if (MCOperand_isImm(DispSpec)) {
1074  int64_t DispVal = MCOperand_getImm(DispSpec);
1075  if (MI->csh->detail)
1076  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = DispVal;
1077  if (DispVal) {
1078  if (NeedPlus) {
1079  if (DispVal < 0) {
1080  SStream_concat0(O, " - ");
1081  printImm(MI, O, -DispVal, true);
1082  } else {
1083  SStream_concat0(O, " + ");
1084  printImm(MI, O, DispVal, true);
1085  }
1086  } else {
1087  // memory reference to an immediate address
1088  if (DispVal < 0) {
1089  printImm(MI, O, arch_masks[MI->csh->mode] & DispVal, true);
1090  } else {
1091  printImm(MI, O, DispVal, true);
1092  }
1093  }
1094 
1095  } else {
1096  // DispVal = 0
1097  if (!NeedPlus) // [0]
1098  SStream_concat0(O, "0");
1099  }
1100  }
1101 
1102  SStream_concat0(O, "]");
1103 
1104  if (MI->csh->detail)
1105  MI->flat_insn->detail->x86.op_count++;
1106 
1107  if (MI->op1_size == 0)
1108  MI->op1_size = MI->x86opsize;
1109 }
1110 
1111 static void printanymem(MCInst *MI, unsigned OpNo, SStream *O)
1112 {
1113  switch(MI->Opcode) {
1114  default: break;
1115  case X86_LEA16r:
1116  MI->x86opsize = 2;
1117  break;
1118  case X86_LEA32r:
1119  case X86_LEA64_32r:
1120  MI->x86opsize = 4;
1121  break;
1122  case X86_LEA64r:
1123  MI->x86opsize = 8;
1124  break;
1125  }
1126  printMemReference(MI, OpNo, O);
1127 }
1128 
1129 #define GET_REGINFO_ENUM
1130 #include "X86GenRegisterInfo.inc"
1131 
1132 #define PRINT_ALIAS_INSTR
1133 #ifdef CAPSTONE_X86_REDUCE
1134 #include "X86GenAsmWriter1_reduce.inc"
1135 #else
1136 #include "X86GenAsmWriter1.inc"
1137 #endif
1138 
1139 #endif
#define mnem(n, mn)
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
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_isImm(const MCOperand *op)
Definition: MCInst.c:106
void SStream_concat(SStream *ss, const char *fmt,...)
Definition: SStream.c:45
void SStream_concat0(SStream *ss, const char *s)
Definition: SStream.c:31
@ X86_AddrIndexReg
Definition: X86BaseInfo.h:30
@ X86_AddrBaseReg
Definition: X86BaseInfo.h:28
@ X86_AddrSegmentReg
AddrSegmentReg - The operand # of the segment in the memory operand.
Definition: X86BaseInfo.h:34
@ X86_AddrScaleAmt
Definition: X86BaseInfo.h:29
@ X86_AddrDisp
Definition: X86BaseInfo.h:31
void X86_Intel_printInst(MCInst *MI, SStream *OS, void *Info)
uint8_t X86_immediate_size(unsigned int id, uint8_t *enc_size)
const uint64_t arch_masks[9]
void op_addSseCC(MCInst *MI, int v)
void op_addAvxRoundingMode(MCInst *MI, int v)
uint8_t * X86_get_op_access(cs_struct *h, unsigned int id, uint64_t *eflags)
void op_addAvxSae(MCInst *MI)
void op_addXopCC(MCInst *MI, int v)
bool X86_insn_reg_intel2(unsigned int id, x86_reg *reg1, enum cs_ac_type *access1, x86_reg *reg2, enum cs_ac_type *access2)
x86_reg X86_insn_reg_intel(unsigned int id, enum cs_ac_type *access)
void op_addAvxCC(MCInst *MI, int v)
#define imm
lzma_index ** i
Definition: index.h:629
ut16 val
Definition: armass64_const.h:6
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
@ CS_MODE_64
64-bit mode (X86, PPC)
Definition: capstone.h:107
@ CS_MODE_32
32-bit mode (X86)
Definition: capstone.h:106
@ CS_MODE_16
16-bit mode (X86)
Definition: capstone.h:105
@ CS_OPT_ON
Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
Definition: capstone.h:183
@ CS_OPT_SYNTAX_MASM
X86 Intel Masm syntax (CS_OPT_SYNTAX).
Definition: capstone.h:188
cs_ac_type
Definition: capstone.h:202
@ X86_AVX_RM_RD
Round down.
Definition: x86.h:241
@ X86_AVX_RM_RN
Round to nearest.
Definition: x86.h:240
@ X86_AVX_RM_RU
Round up.
Definition: x86.h:242
@ X86_AVX_RM_RZ
Round toward zero.
Definition: x86.h:243
@ X86_INS_FXRSTOR
Definition: x86.h:576
@ X86_INS_INT
Definition: x86.h:607
@ X86_INS_LCALL
Definition: x86.h:540
@ X86_INS_RET
Definition: x86.h:533
@ X86_INS_LGDT
Definition: x86.h:713
@ X86_INS_AND
Definition: x86.h:411
@ X86_INS_SGDT
Definition: x86.h:1029
@ X86_INS_XOR
Definition: x86.h:720
@ X86_INS_OUT
Definition: x86.h:882
@ X86_INS_SIDT
Definition: x86.h:1045
@ X86_INS_MOVABS
Definition: x86.h:836
@ X86_INS_FXSAVE
Definition: x86.h:578
@ X86_INS_OR
Definition: x86.h:718
@ X86_INS_IN
Definition: x86.h:600
@ X86_INS_RETF
Definition: x86.h:728
@ X86_INS_LIDT
Definition: x86.h:715
@ X86_INS_LJMP
Definition: x86.h:541
@ X86_OP_IMM
= CS_OP_IMM (Immediate operand).
Definition: x86.h:161
@ X86_OP_REG
= CS_OP_REG (Register operand).
Definition: x86.h:160
@ X86_OP_MEM
= CS_OP_MEM (Memory operand).
Definition: x86.h:162
x86_reg
X86 registers.
Definition: x86.h:19
@ X86_REG_ES
Definition: x86.h:26
@ X86_REG_INVALID
Definition: x86.h:20
@ X86_XOP_CC_GE
Definition: x86.h:171
@ X86_XOP_CC_GT
Definition: x86.h:170
@ X86_XOP_CC_LT
Definition: x86.h:168
@ X86_XOP_CC_LE
Definition: x86.h:169
@ X86_XOP_CC_FALSE
Definition: x86.h:174
@ X86_XOP_CC_NEQ
Definition: x86.h:173
@ X86_XOP_CC_EQ
Definition: x86.h:172
@ X86_XOP_CC_TRUE
Definition: x86.h:175
@ X86_AVX_CC_UNORD_S
Definition: x86.h:222
@ X86_AVX_CC_EQ_US
Definition: x86.h:227
@ X86_AVX_CC_LE
Definition: x86.h:205
@ X86_AVX_CC_GT
Definition: x86.h:217
@ X86_AVX_CC_NLT_UQ
Definition: x86.h:224
@ X86_AVX_CC_ORD
Definition: x86.h:210
@ X86_AVX_CC_NLE
Definition: x86.h:209
@ X86_AVX_CC_NEQ_OS
Definition: x86.h:231
@ X86_AVX_CC_NGE_UQ
Definition: x86.h:228
@ X86_AVX_CC_NGT_UQ
Definition: x86.h:229
@ X86_AVX_CC_NEQ_OQ
Definition: x86.h:215
@ X86_AVX_CC_ORD_S
Definition: x86.h:226
@ X86_AVX_CC_GE_OQ
Definition: x86.h:232
@ X86_AVX_CC_NEQ
Definition: x86.h:207
@ X86_AVX_CC_TRUE_US
Definition: x86.h:234
@ X86_AVX_CC_LT
Definition: x86.h:204
@ X86_AVX_CC_FALSE
Definition: x86.h:214
@ X86_AVX_CC_EQ_OS
Definition: x86.h:219
@ X86_AVX_CC_LT_OQ
Definition: x86.h:220
@ X86_AVX_CC_EQ
Definition: x86.h:203
@ X86_AVX_CC_UNORD
Definition: x86.h:206
@ X86_AVX_CC_GE
Definition: x86.h:216
@ X86_AVX_CC_EQ_UQ
Definition: x86.h:211
@ X86_AVX_CC_NGE
Definition: x86.h:212
@ X86_AVX_CC_LE_OQ
Definition: x86.h:221
@ X86_AVX_CC_GT_OQ
Definition: x86.h:233
@ X86_AVX_CC_NLT
Definition: x86.h:208
@ X86_AVX_CC_NGT
Definition: x86.h:213
@ X86_AVX_CC_FALSE_OS
Definition: x86.h:230
@ X86_AVX_CC_NEQ_US
Definition: x86.h:223
@ X86_AVX_CC_NLE_UQ
Definition: x86.h:225
@ X86_AVX_CC_TRUE
Definition: x86.h:218
@ X86_SSE_CC_ORD
Definition: x86.h:197
@ X86_SSE_CC_LE
Definition: x86.h:192
@ X86_SSE_CC_NEQ
Definition: x86.h:194
@ X86_SSE_CC_LT
Definition: x86.h:191
@ X86_SSE_CC_EQ
Definition: x86.h:190
@ X86_SSE_CC_NLE
Definition: x86.h:196
@ X86_SSE_CC_NLT
Definition: x86.h:195
@ X86_SSE_CC_UNORD
Definition: x86.h:193
#define NULL
Definition: cris-opc.c:27
cs_free_t cs_mem_free
Definition: cs.c:351
@ OS
Definition: inflate.h:24
#define reg(n)
#define PRIu64
Definition: macros.h:18
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
#define ARR_SIZE(a)
Definition: ocaml.c:13
#define O
Definition: rcond.c:14
static int
Definition: sfsocketcall.h:114
long int64_t
Definition: sftypes.h:32
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 op1_size
Definition: MCInst.h:92
uint8_t imm_size
Definition: MCInst.h:104
char assembly[8]
Definition: MCInst.h:109
uint8_t x86_prefix[4]
Definition: MCInst.h:103
unsigned Opcode
Definition: MCInst.h:93
uint8_t popcode_adjust
Definition: MCInst.h:108
uint8_t x86opsize
Definition: MCInst.h:98
uint64_t address
Definition: MCInst.h:96
Definition: SStream.h:9
bool doing_mem
Definition: cs_priv.h:70
int syntax
Definition: cs_priv.h:69
cs_mode mode
Definition: cs_priv.h:56
cs_opt_value imm_unsigned
Definition: cs_priv.h:68
cs_opt_value detail
Definition: cs_priv.h:68
const uint8_t * regsize_map
Definition: cs_priv.h:76
#define HEX_THRESHOLD
Definition: utils.h:16
#define CS_AC_IGNORE
Definition: utils.h:64
#define PRIx64
Definition: sysdefs.h:94