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