blob: 7dfd6669064a21f7763387d9df8c9cfc2f40bee3 [file] [log] [blame]
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +08001//===-- 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
Nguyen Anh Quynhbb0744d2014-05-12 13:41:49 +080015/* Capstone Disassembly Engine */
16/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080017
Nguyen Anh Quynh8598a212014-05-14 11:26:41 +080018#ifdef CAPSTONE_HAS_X86
19
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080020#include <ctype.h>
21#include <inttypes.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
26#include "../../utils.h"
27#include "../../MCInst.h"
28#include "../../SStream.h"
Nguyen Anh Quynhe51e2272014-01-12 20:27:54 +080029#include "../../MCRegisterInfo.h"
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080030
Nguyen Anh Quynhf328f302014-01-20 09:47:21 +080031#include "X86Mapping.h"
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080032
Nguyen Anh Quynhe93179b2014-04-25 11:18:40 +080033#define GET_INSTRINFO_ENUM
34#ifdef CAPSTONE_X86_REDUCE
35#include "X86GenInstrInfo_reduce.inc"
36#else
37#include "X86GenInstrInfo.inc"
38#endif
39
Nguyen Anh Quynh0b690382014-08-13 13:01:50 +080040#include "X86BaseInfo.h"
41
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080042static void printMemReference(MCInst *MI, unsigned Op, SStream *O);
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +080043static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080044
Nguyen Anh Quynh10850732014-06-18 12:16:24 +080045
46static void set_mem_access(MCInst *MI, bool status)
47{
48 if (MI->csh->detail != CS_OPT_ON)
49 return;
50
51 MI->csh->doing_mem = status;
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +080052 if (!status)
53 // done, create the next operand slot
54 MI->flat_insn->detail->x86.op_count++;
55
Nguyen Anh Quynh10850732014-06-18 12:16:24 +080056}
57
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080058static void printopaquemem(MCInst *MI, unsigned OpNo, SStream *O)
59{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +080060 SStream_concat0(O, "ptr ");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080061 printMemReference(MI, OpNo, O);
62}
63
64static void printi8mem(MCInst *MI, unsigned OpNo, SStream *O)
65{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +080066 SStream_concat0(O, "byte ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +080067 MI->x86opsize = 1;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080068 printMemReference(MI, OpNo, O);
69}
70
71static void printi16mem(MCInst *MI, unsigned OpNo, SStream *O)
72{
Nguyen Anh Quynh10850732014-06-18 12:16:24 +080073 if (MI->Opcode == X86_BOUNDS16rm) {
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +080074 SStream_concat0(O, "dword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +080075 MI->x86opsize = 4;
76 } else {
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +080077 SStream_concat0(O, "word ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +080078 MI->x86opsize = 2;
79 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080080 printMemReference(MI, OpNo, O);
81}
82
83static void printi32mem(MCInst *MI, unsigned OpNo, SStream *O)
84{
Nguyen Anh Quynh10850732014-06-18 12:16:24 +080085 if (MI->Opcode == X86_BOUNDS32rm) {
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +080086 SStream_concat0(O, "qword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +080087 MI->x86opsize = 8;
88 } else {
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +080089 SStream_concat0(O, "dword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +080090 MI->x86opsize = 4;
91 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080092 printMemReference(MI, OpNo, O);
93}
94
95static void printi64mem(MCInst *MI, unsigned OpNo, SStream *O)
96{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +080097 SStream_concat0(O, "qword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +080098 MI->x86opsize = 8;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +080099 printMemReference(MI, OpNo, O);
100}
101
102static void printi128mem(MCInst *MI, unsigned OpNo, SStream *O)
103{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800104 SStream_concat0(O, "xmmword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800105 MI->x86opsize = 16;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800106 printMemReference(MI, OpNo, O);
107}
108
Nguyen Anh Quynh59b54892014-03-27 10:54:44 +0800109#ifndef CAPSTONE_X86_REDUCE
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800110static void printi256mem(MCInst *MI, unsigned OpNo, SStream *O)
111{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800112 SStream_concat0(O, "ymmword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800113 MI->x86opsize = 32;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800114 printMemReference(MI, OpNo, O);
115}
116
117static void printi512mem(MCInst *MI, unsigned OpNo, SStream *O)
118{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800119 SStream_concat0(O, "zmmword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800120 MI->x86opsize = 64;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800121 printMemReference(MI, OpNo, O);
122}
123
124static void printf32mem(MCInst *MI, unsigned OpNo, SStream *O)
125{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800126 SStream_concat0(O, "dword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800127 MI->x86opsize = 4;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800128 printMemReference(MI, OpNo, O);
129}
130
131static void printf64mem(MCInst *MI, unsigned OpNo, SStream *O)
132{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800133 SStream_concat0(O, "qword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800134 MI->x86opsize = 8;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800135 printMemReference(MI, OpNo, O);
136}
137
138static void printf80mem(MCInst *MI, unsigned OpNo, SStream *O)
139{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800140 SStream_concat0(O, "xword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800141 MI->x86opsize = 10;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800142 printMemReference(MI, OpNo, O);
143}
144
145static void printf128mem(MCInst *MI, unsigned OpNo, SStream *O)
146{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800147 SStream_concat0(O, "xmmword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800148 MI->x86opsize = 16;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800149 printMemReference(MI, OpNo, O);
150}
151
152static void printf256mem(MCInst *MI, unsigned OpNo, SStream *O)
153{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800154 SStream_concat0(O, "ymmword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800155 MI->x86opsize = 32;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800156 printMemReference(MI, OpNo, O);
157}
158
159static void printf512mem(MCInst *MI, unsigned OpNo, SStream *O)
160{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800161 SStream_concat0(O, "zmmword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800162 MI->x86opsize = 64;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800163 printMemReference(MI, OpNo, O);
164}
165
Nguyen Anh Quynh95181482014-03-25 23:20:41 +0800166static void printSSECC(MCInst *MI, unsigned Op, SStream *OS)
167{
168 int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0xf;
169 switch (Imm) {
170 default: break; // never reach
Nguyen Anh Quynh4c5eabc2014-06-24 23:50:41 +0800171 case 0: SStream_concat0(OS, "eq"); op_addSseCC(MI, X86_SSE_CC_EQ); break;
172 case 1: SStream_concat0(OS, "lt"); op_addSseCC(MI, X86_SSE_CC_LT); break;
173 case 2: SStream_concat0(OS, "le"); op_addSseCC(MI, X86_SSE_CC_LE); break;
174 case 3: SStream_concat0(OS, "unord"); op_addSseCC(MI, X86_SSE_CC_UNORD); break;
175 case 4: SStream_concat0(OS, "neq"); op_addSseCC(MI, X86_SSE_CC_NEQ); break;
176 case 5: SStream_concat0(OS, "nlt"); op_addSseCC(MI, X86_SSE_CC_NLT); break;
177 case 6: SStream_concat0(OS, "nle"); op_addSseCC(MI, X86_SSE_CC_NLE); break;
178 case 7: SStream_concat0(OS, "ord"); op_addSseCC(MI, X86_SSE_CC_ORD); break;
179 case 8: SStream_concat0(OS, "eq_uq"); op_addSseCC(MI, X86_SSE_CC_EQ_UQ); break;
180 case 9: SStream_concat0(OS, "nge"); op_addSseCC(MI, X86_SSE_CC_NGE); break;
181 case 0xa: SStream_concat0(OS, "ngt"); op_addSseCC(MI, X86_SSE_CC_NGT); break;
182 case 0xb: SStream_concat0(OS, "false"); op_addSseCC(MI, X86_SSE_CC_FALSE); break;
183 case 0xc: SStream_concat0(OS, "neq_oq"); op_addSseCC(MI, X86_SSE_CC_NEQ_OQ); break;
184 case 0xd: SStream_concat0(OS, "ge"); op_addSseCC(MI, X86_SSE_CC_GE); break;
185 case 0xe: SStream_concat0(OS, "gt"); op_addSseCC(MI, X86_SSE_CC_GT); break;
186 case 0xf: SStream_concat0(OS, "true"); op_addSseCC(MI, X86_SSE_CC_TRUE); break;
Nguyen Anh Quynh95181482014-03-25 23:20:41 +0800187 }
188}
189
190static void printAVXCC(MCInst *MI, unsigned Op, SStream *O)
191{
192 int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x1f;
193 switch (Imm) {
194 default: break;//printf("Invalid avxcc argument!\n"); break;
Nguyen Anh Quynh4c5eabc2014-06-24 23:50:41 +0800195 case 0: SStream_concat0(O, "eq"); op_addAvxCC(MI, X86_AVX_CC_EQ); break;
196 case 1: SStream_concat0(O, "lt"); op_addAvxCC(MI, X86_AVX_CC_LT); break;
197 case 2: SStream_concat0(O, "le"); op_addAvxCC(MI, X86_AVX_CC_LE); break;
198 case 3: SStream_concat0(O, "unord"); op_addAvxCC(MI, X86_AVX_CC_UNORD); break;
199 case 4: SStream_concat0(O, "neq"); op_addAvxCC(MI, X86_AVX_CC_NEQ); break;
200 case 5: SStream_concat0(O, "nlt"); op_addAvxCC(MI, X86_AVX_CC_NLT); break;
201 case 6: SStream_concat0(O, "nle"); op_addAvxCC(MI, X86_AVX_CC_NLE); break;
202 case 7: SStream_concat0(O, "ord"); op_addAvxCC(MI, X86_AVX_CC_ORD); break;
203 case 8: SStream_concat0(O, "eq_uq"); op_addAvxCC(MI, X86_AVX_CC_EQ_UQ); break;
204 case 9: SStream_concat0(O, "nge"); op_addAvxCC(MI, X86_AVX_CC_NGE); break;
205 case 0xa: SStream_concat0(O, "ngt"); op_addAvxCC(MI, X86_AVX_CC_NGT); break;
206 case 0xb: SStream_concat0(O, "false"); op_addAvxCC(MI, X86_AVX_CC_FALSE); break;
207 case 0xc: SStream_concat0(O, "neq_oq"); op_addAvxCC(MI, X86_AVX_CC_NEQ_OQ); break;
208 case 0xd: SStream_concat0(O, "ge"); op_addAvxCC(MI, X86_AVX_CC_GE); break;
209 case 0xe: SStream_concat0(O, "gt"); op_addAvxCC(MI, X86_AVX_CC_GT); break;
210 case 0xf: SStream_concat0(O, "true"); op_addAvxCC(MI, X86_AVX_CC_TRUE); break;
211 case 0x10: SStream_concat0(O, "eq_os"); op_addAvxCC(MI, X86_AVX_CC_EQ_OS); break;
212 case 0x11: SStream_concat0(O, "lt_oq"); op_addAvxCC(MI, X86_AVX_CC_LT_OQ); break;
213 case 0x12: SStream_concat0(O, "le_oq"); op_addAvxCC(MI, X86_AVX_CC_LE_OQ); break;
214 case 0x13: SStream_concat0(O, "unord_s"); op_addAvxCC(MI, X86_AVX_CC_UNORD_S); break;
215 case 0x14: SStream_concat0(O, "neq_us"); op_addAvxCC(MI, X86_AVX_CC_NEQ_US); break;
216 case 0x15: SStream_concat0(O, "nlt_uq"); op_addAvxCC(MI, X86_AVX_CC_NLT_UQ); break;
217 case 0x16: SStream_concat0(O, "nle_uq"); op_addAvxCC(MI, X86_AVX_CC_NLE_UQ); break;
218 case 0x17: SStream_concat0(O, "ord_s"); op_addAvxCC(MI, X86_AVX_CC_ORD_S); break;
219 case 0x18: SStream_concat0(O, "eq_us"); op_addAvxCC(MI, X86_AVX_CC_EQ_US); break;
220 case 0x19: SStream_concat0(O, "nge_uq"); op_addAvxCC(MI, X86_AVX_CC_NGE_UQ); break;
221 case 0x1a: SStream_concat0(O, "ngt_uq"); op_addAvxCC(MI, X86_AVX_CC_NGT_UQ); break;
222 case 0x1b: SStream_concat0(O, "false_os"); op_addAvxCC(MI, X86_AVX_CC_FALSE_OS); break;
223 case 0x1c: SStream_concat0(O, "neq_os"); op_addAvxCC(MI, X86_AVX_CC_NEQ_OS); break;
224 case 0x1d: SStream_concat0(O, "ge_oq"); op_addAvxCC(MI, X86_AVX_CC_GE_OQ); break;
225 case 0x1e: SStream_concat0(O, "gt_oq"); op_addAvxCC(MI, X86_AVX_CC_GT_OQ); break;
226 case 0x1f: SStream_concat0(O, "true_us"); op_addAvxCC(MI, X86_AVX_CC_TRUE_US); break;
Nguyen Anh Quynh95181482014-03-25 23:20:41 +0800227 }
228}
229
230static void printRoundingControl(MCInst *MI, unsigned Op, SStream *O)
231{
232 int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x3;
233 switch (Imm) {
Nguyen Anh Quynh1a66fec2014-06-26 12:09:15 +0800234 case 0: SStream_concat0(O, "{rn-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RN); break;
235 case 1: SStream_concat0(O, "{rd-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RD); break;
236 case 2: SStream_concat0(O, "{ru-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RU); break;
237 case 3: SStream_concat0(O, "{rz-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RZ); break;
Nguyen Anh Quynh95181482014-03-25 23:20:41 +0800238 default: break; // never reach
239 }
240}
241
242#endif
243
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800244static char *getRegisterName(unsigned RegNo);
245static void printRegName(SStream *OS, unsigned RegNo)
246{
247 SStream_concat0(OS, getRegisterName(RegNo));
248}
249
250// local printOperand, without updating public operands
251static void _printOperand(MCInst *MI, unsigned OpNo, SStream *O)
252{
253 MCOperand *Op = MCInst_getOperand(MI, OpNo);
254 if (MCOperand_isReg(Op)) {
255 printRegName(O, MCOperand_getReg(Op));
256 } else if (MCOperand_isImm(Op)) {
257 int64_t imm = MCOperand_getImm(Op);
258 if (imm < 0) {
259 if (imm < -HEX_THRESHOLD)
260 SStream_concat(O, "-0x%"PRIx64, -imm);
261 else
262 SStream_concat(O, "-%"PRIu64, -imm);
263
264 } else {
265 if (imm > HEX_THRESHOLD)
266 SStream_concat(O, "0x%"PRIx64, imm);
267 else
268 SStream_concat(O, "%"PRIu64, imm);
269 }
270 }
271}
272
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800273static void printSrcIdx(MCInst *MI, unsigned Op, SStream *O)
274{
275 MCOperand *SegReg;
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800276 int reg;
277
278 if (MI->csh->detail) {
279 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
280 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
281 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_INVALID;
282 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_REG_INVALID;
283 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = X86_REG_INVALID;
284 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
285 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0;
286 }
Nguyen Anh Quynh42706a32014-05-09 07:33:35 +0800287
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800288 SegReg = MCInst_getOperand(MI, Op+1);
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800289 reg = MCOperand_getReg(SegReg);
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800290
291 // If this has a segment register, print it.
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800292 if (reg) {
293 _printOperand(MI, Op+1, O);
294 if (MI->csh->detail) {
295 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = reg;
296 }
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800297 SStream_concat0(O, ":");
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800298 }
299
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800300 SStream_concat0(O, "[");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800301 set_mem_access(MI, true);
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800302 printOperand(MI, Op, O);
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800303 SStream_concat0(O, "]");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800304 set_mem_access(MI, false);
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800305}
306
307static void printDstIdx(MCInst *MI, unsigned Op, SStream *O)
308{
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800309 if (MI->csh->detail) {
310 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
311 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
312 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_INVALID;
313 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_REG_INVALID;
314 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = X86_REG_INVALID;
315 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
316 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0;
317 }
318
Nguyen Anh Quynh0e534bf2014-06-05 17:05:16 +0700319 // DI accesses are always ES-based on non-64bit mode
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800320 if (MI->csh->mode != CS_MODE_64) {
Nguyen Anh Quynh9417ad62014-06-05 17:03:52 +0700321 SStream_concat(O, "es:[");
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800322 if (MI->csh->detail) {
323 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_ES;
324 }
325 } else
Nguyen Anh Quynh9417ad62014-06-05 17:03:52 +0700326 SStream_concat(O, "[");
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800327
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800328 set_mem_access(MI, true);
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800329 printOperand(MI, Op, O);
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800330 SStream_concat0(O, "]");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800331 set_mem_access(MI, false);
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800332}
333
334void printSrcIdx8(MCInst *MI, unsigned OpNo, SStream *O)
335{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800336 SStream_concat0(O, "byte ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800337 MI->x86opsize = 1;
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800338 printSrcIdx(MI, OpNo, O);
339}
340
341void printSrcIdx16(MCInst *MI, unsigned OpNo, SStream *O)
342{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800343 SStream_concat0(O, "word ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800344 MI->x86opsize = 2;
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800345 printSrcIdx(MI, OpNo, O);
346}
347
348void printSrcIdx32(MCInst *MI, unsigned OpNo, SStream *O)
349{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800350 SStream_concat0(O, "dword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800351 MI->x86opsize = 4;
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800352 printSrcIdx(MI, OpNo, O);
353}
354
355void printSrcIdx64(MCInst *MI, unsigned OpNo, SStream *O)
356{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800357 SStream_concat0(O, "qword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800358 MI->x86opsize = 8;
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800359 printSrcIdx(MI, OpNo, O);
360}
361
362void printDstIdx8(MCInst *MI, unsigned OpNo, SStream *O)
363{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800364 SStream_concat0(O, "byte ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800365 MI->x86opsize = 1;
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800366 printDstIdx(MI, OpNo, O);
367}
368
369void printDstIdx16(MCInst *MI, unsigned OpNo, SStream *O)
370{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800371 SStream_concat0(O, "word ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800372 MI->x86opsize = 2;
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800373 printDstIdx(MI, OpNo, O);
374}
375
376void printDstIdx32(MCInst *MI, unsigned OpNo, SStream *O)
377{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800378 SStream_concat0(O, "dword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800379 MI->x86opsize = 4;
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800380 printDstIdx(MI, OpNo, O);
381}
382
383void printDstIdx64(MCInst *MI, unsigned OpNo, SStream *O)
384{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800385 SStream_concat0(O, "qword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800386 MI->x86opsize = 8;
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800387 printDstIdx(MI, OpNo, O);
388}
389
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800390static void printMemOffset(MCInst *MI, unsigned Op, SStream *O)
391{
392 MCOperand *DispSpec = MCInst_getOperand(MI, Op);
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800393 MCOperand *SegReg = MCInst_getOperand(MI, Op + 1);
394 int reg;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800395
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800396 if (MI->csh->detail) {
Nguyen Anh Quynh5329a6f2014-06-08 23:35:52 +0700397 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800398 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800399 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_INVALID;
Nguyen Anh Quynh5329a6f2014-06-08 23:35:52 +0700400 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_REG_INVALID;
401 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = X86_REG_INVALID;
402 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
403 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800404 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800405
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800406 // If this has a segment register, print it.
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800407 reg = MCOperand_getReg(SegReg);
408 if (reg) {
409 _printOperand(MI, Op + 1, O);
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800410 SStream_concat0(O, ":");
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800411 if (MI->csh->detail) {
412 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = reg;
413 }
Nguyen Anh Quynh13f40d22014-02-07 22:06:33 +0800414 }
415
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800416 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800417
418 if (MCOperand_isImm(DispSpec)) {
419 int64_t imm = MCOperand_getImm(DispSpec);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800420 if (MI->csh->detail)
Nguyen Anh Quynh5329a6f2014-06-08 23:35:52 +0700421 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
Nguyen Anh Quynhbe906392013-12-13 15:37:57 +0800422 if (imm < 0) {
Nguyen Anh Quynh6d3d8002014-03-29 17:26:51 +0800423 SStream_concat(O, "0x%"PRIx64, arch_masks[MI->csh->mode] & imm);
Nguyen Anh Quynhbe906392013-12-13 15:37:57 +0800424 } else {
Nguyen Anh Quynhf22557b2013-12-13 09:37:52 +0800425 if (imm > HEX_THRESHOLD)
426 SStream_concat(O, "0x%"PRIx64, imm);
427 else
428 SStream_concat(O, "%"PRIu64, imm);
429 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800430 }
431
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800432 SStream_concat0(O, "]");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800433
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800434 if (MI->csh->detail)
Nguyen Anh Quynh5329a6f2014-06-08 23:35:52 +0700435 MI->flat_insn->detail->x86.op_count++;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800436}
437
438static void printMemOffs8(MCInst *MI, unsigned OpNo, SStream *O)
439{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800440 SStream_concat0(O, "byte ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800441 MI->x86opsize = 1;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800442 printMemOffset(MI, OpNo, O);
443}
444
445static void printMemOffs16(MCInst *MI, unsigned OpNo, SStream *O)
446{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800447 SStream_concat0(O, "word ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800448 MI->x86opsize = 2;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800449 printMemOffset(MI, OpNo, O);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800450}
451
452static void printMemOffs32(MCInst *MI, unsigned OpNo, SStream *O)
453{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800454 SStream_concat0(O, "dword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800455 MI->x86opsize = 4;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800456 printMemOffset(MI, OpNo, O);
457}
458
459static void printMemOffs64(MCInst *MI, unsigned OpNo, SStream *O)
460{
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800461 SStream_concat0(O, "qword ptr ");
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800462 MI->x86opsize = 8;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800463 printMemOffset(MI, OpNo, O);
464}
465
Nguyen Anh Quynh27b9a962014-02-19 10:13:47 +0800466static char *printAliasInstr(MCInst *MI, SStream *OS, void *info);
Nguyen Anh Quynhe51e2272014-01-12 20:27:54 +0800467static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800468void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info)
469{
Nguyen Anh Quynh27b9a962014-02-19 10:13:47 +0800470 char *mnem;
Nguyen Anh Quynh85cddef2014-02-18 11:59:36 +0800471 x86_reg reg;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800472
Nguyen Anh Quynh005c5142014-02-18 11:11:46 +0800473 // Try to print any aliases first.
Nguyen Anh Quynh0b690382014-08-13 13:01:50 +0800474 mnem = printAliasInstr(MI, O, Info);
Nguyen Anh Quynh27b9a962014-02-19 10:13:47 +0800475 if (mnem)
476 cs_mem_free(mnem);
477 else
Nguyen Anh Quynh0b690382014-08-13 13:01:50 +0800478 printInstruction(MI, O, Info);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800479
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800480 if (MI->csh->detail) {
Nguyen Anh Quynh85cddef2014-02-18 11:59:36 +0800481 // first op can be embedded in the asm by llvm.
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800482 // so we have to add the missing register as the first operand
483 reg = X86_insn_reg_intel(MCInst_getOpcode(MI));
Nguyen Anh Quynh85cddef2014-02-18 11:59:36 +0800484 if (reg) {
485 // shift all the ops right to leave 1st slot for this new register op
Nguyen Anh Quynh5329a6f2014-06-08 23:35:52 +0700486 memmove(&(MI->flat_insn->detail->x86.operands[1]), &(MI->flat_insn->detail->x86.operands[0]),
487 sizeof(MI->flat_insn->detail->x86.operands[0]) * (ARR_SIZE(MI->flat_insn->detail->x86.operands) - 1));
488 MI->flat_insn->detail->x86.operands[0].type = X86_OP_REG;
489 MI->flat_insn->detail->x86.operands[0].reg = reg;
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800490 MI->flat_insn->detail->x86.operands[0].size = MI->csh->regsize_map[reg];
Nguyen Anh Quynh5329a6f2014-06-08 23:35:52 +0700491 MI->flat_insn->detail->x86.op_count++;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800492 }
493 }
494}
495
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800496/// printPCRelImm - This is used to print an immediate value that ends up
497/// being encoded as a pc-relative value.
498static void printPCRelImm(MCInst *MI, unsigned OpNo, SStream *O)
499{
500 MCOperand *Op = MCInst_getOperand(MI, OpNo);
501 if (MCOperand_isImm(Op)) {
Nguyen Anh Quynh5329a6f2014-06-08 23:35:52 +0700502 int64_t imm = MCOperand_getImm(Op) + MI->flat_insn->size + MI->address;
Nguyen Anh Quynhbe906392013-12-13 15:37:57 +0800503 if (imm < 0) {
Nguyen Anh Quynh017df602014-03-20 15:38:51 +0800504 if (imm < -HEX_THRESHOLD)
Nguyen Anh Quynhbe906392013-12-13 15:37:57 +0800505 SStream_concat(O, "-0x%"PRIx64, -imm);
506 else
507 SStream_concat(O, "-%"PRIu64, -imm);
508 } else {
Nguyen Anh Quynh2d342512014-05-11 15:33:11 +0800509 // handle 16bit segment bound
510 if (MI->csh->mode == CS_MODE_16 && imm > 0x100000)
511 imm -= 0x10000;
512
Nguyen Anh Quynhf22557b2013-12-13 09:37:52 +0800513 if (imm > HEX_THRESHOLD)
514 SStream_concat(O, "0x%"PRIx64, imm);
515 else
516 SStream_concat(O, "%"PRIu64, imm);
517 }
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800518 if (MI->csh->detail) {
Nguyen Anh Quynh5329a6f2014-06-08 23:35:52 +0700519 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
Nguyen Anh Quynhf1ec5262014-06-25 22:03:18 +0800520 // if op_count > 0, then this operand's size is taken from the destination op
521 if (MI->flat_insn->detail->x86.op_count > 0)
522 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->flat_insn->detail->x86.operands[0].size;
523 else
524 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->imm_size;
Nguyen Anh Quynh5329a6f2014-06-08 23:35:52 +0700525 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;
526 MI->flat_insn->detail->x86.op_count++;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800527 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800528 }
529}
530
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800531static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
532{
533 MCOperand *Op = MCInst_getOperand(MI, OpNo);
534 if (MCOperand_isReg(Op)) {
535 printRegName(O, MCOperand_getReg(Op));
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800536 if (MI->csh->detail) {
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800537 unsigned int reg = MCOperand_getReg(Op);
538 if (MI->csh->doing_mem) {
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800539 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = reg;
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800540 } else {
541 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_REG;
542 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].reg = reg;
543 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->csh->regsize_map[reg];
544 MI->flat_insn->detail->x86.op_count++;
545 }
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800546 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800547 } else if (MCOperand_isImm(Op)) {
548 int64_t imm = MCOperand_getImm(Op);
Nguyen Anh Quynh94990c92013-12-13 15:56:08 +0800549 if (imm >= 0) {
Nguyen Anh Quynhbe906392013-12-13 15:37:57 +0800550 if (imm > HEX_THRESHOLD)
551 SStream_concat(O, "0x%"PRIx64, imm);
552 else
553 SStream_concat(O, "%"PRIu64, imm);
554 } else {
Nguyen Anh Quynh81a6df42014-04-01 07:23:39 +0800555 if (imm < -HEX_THRESHOLD)
556 SStream_concat(O, "-0x%"PRIx64, -imm);
557 else
558 SStream_concat(O, "-%"PRIu64, -imm);
Nguyen Anh Quynhbe906392013-12-13 15:37:57 +0800559 }
560
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800561 if (MI->csh->detail) {
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800562 if (MI->csh->doing_mem) {
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800563 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800564 } else {
565 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
Nguyen Anh Quynhf1ec5262014-06-25 22:03:18 +0800566 if (MI->flat_insn->detail->x86.op_count > 0)
567 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->flat_insn->detail->x86.operands[0].size;
568 else
569 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->imm_size;
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800570 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;
571 MI->flat_insn->detail->x86.op_count++;
572 }
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800573 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800574 }
575}
576
Nguyen Anh Quynh125f5042014-03-29 12:02:21 +0800577static void printMemReference(MCInst *MI, unsigned Op, SStream *O)
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800578{
Nguyen Anh Quynh42706a32014-05-09 07:33:35 +0800579 bool NeedPlus = false;
Nguyen Anh Quynh0b690382014-08-13 13:01:50 +0800580 MCOperand *BaseReg = MCInst_getOperand(MI, Op + X86_AddrBaseReg);
581 uint64_t ScaleVal = MCOperand_getImm(MCInst_getOperand(MI, Op + X86_AddrScaleAmt));
582 MCOperand *IndexReg = MCInst_getOperand(MI, Op + X86_AddrIndexReg);
583 MCOperand *DispSpec = MCInst_getOperand(MI, Op + X86_AddrDisp);
584 MCOperand *SegReg = MCInst_getOperand(MI, Op + X86_AddrSegmentReg);
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800585 int reg;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800586
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800587 if (MI->csh->detail) {
Nguyen Anh Quynh5329a6f2014-06-08 23:35:52 +0700588 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
Nguyen Anh Quynh10850732014-06-18 12:16:24 +0800589 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800590 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_INVALID;
Nguyen Anh Quynh5329a6f2014-06-08 23:35:52 +0700591 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = MCOperand_getReg(BaseReg);
592 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = MCOperand_getReg(IndexReg);
593 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = (int)ScaleVal;
594 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0;
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800595 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800596
597 // If this has a segment register, print it.
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800598 reg = MCOperand_getReg(SegReg);
599 if (reg) {
Nguyen Anh Quynh0b690382014-08-13 13:01:50 +0800600 _printOperand(MI, Op + X86_AddrSegmentReg, O);
Nguyen Anh Quynh14ba46b2014-06-24 14:32:01 +0800601 if (MI->csh->detail) {
602 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = reg;
603 }
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800604 SStream_concat0(O, ":");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800605 }
606
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800607 SStream_concat0(O, "[");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800608
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800609 if (MCOperand_getReg(BaseReg)) {
Nguyen Anh Quynh0b690382014-08-13 13:01:50 +0800610 _printOperand(MI, Op + X86_AddrBaseReg, O);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800611 NeedPlus = true;
612 }
613
614 if (MCOperand_getReg(IndexReg)) {
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800615 if (NeedPlus) SStream_concat0(O, " + ");
Nguyen Anh Quynh0b690382014-08-13 13:01:50 +0800616 _printOperand(MI, Op + X86_AddrIndexReg, O);
Nguyen Anh Quynhf9e32162013-12-05 21:58:31 +0800617 if (ScaleVal != 1)
618 SStream_concat(O, "*%u", ScaleVal);
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800619 NeedPlus = true;
620 }
621
622 if (!MCOperand_isImm(DispSpec)) {
Nguyen Anh Quynh7a65ad72014-05-21 16:18:56 +0800623 if (NeedPlus)
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800624 SStream_concat0(O, " + ");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800625 } else {
626 int64_t DispVal = MCOperand_getImm(DispSpec);
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800627 if (MI->csh->detail)
Nguyen Anh Quynh5329a6f2014-06-08 23:35:52 +0700628 MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = DispVal;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800629 if (DispVal || (!MCOperand_getReg(IndexReg) && !MCOperand_getReg(BaseReg))) {
630 if (NeedPlus) {
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800631 SStream_concat0(O, " + ");
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800632 }
Nguyen Anh Quynh125f5042014-03-29 12:02:21 +0800633
Nguyen Anh Quynhbe906392013-12-13 15:37:57 +0800634 if (DispVal < 0) {
Nguyen Anh Quynh6d3d8002014-03-29 17:26:51 +0800635 SStream_concat(O, "0x%"PRIx64, arch_masks[MI->csh->mode] & DispVal);
Nguyen Anh Quynhbe906392013-12-13 15:37:57 +0800636 } else {
Nguyen Anh Quynhf22557b2013-12-13 09:37:52 +0800637 if (DispVal > HEX_THRESHOLD)
638 SStream_concat(O, "0x%"PRIx64, DispVal);
639 else
640 SStream_concat(O, "%"PRIu64, DispVal);
641 }
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800642 }
643 }
644
Nguyen Anh Quynhb76233c2014-06-04 18:31:02 +0800645 SStream_concat0(O, "]");
Nguyen Anh Quynha209e672013-12-14 00:23:41 +0800646
Nguyen Anh Quynh42c6b1a2013-12-30 00:15:25 +0800647 if (MI->csh->detail)
Nguyen Anh Quynh5329a6f2014-06-08 23:35:52 +0700648 MI->flat_insn->detail->x86.op_count++;
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800649}
650
Nguyen Anh Quynh0b690382014-08-13 13:01:50 +0800651#define GET_REGINFO_ENUM
652#include "X86GenRegisterInfo.inc"
653
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800654#define PRINT_ALIAS_INSTR
Nguyen Anh Quynh59b54892014-03-27 10:54:44 +0800655#ifdef CAPSTONE_X86_REDUCE
656#include "X86GenAsmWriter1_reduce.inc"
Nguyen Anh Quynh95181482014-03-25 23:20:41 +0800657#else
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800658#include "X86GenAsmWriter1.inc"
Nguyen Anh Quynh95181482014-03-25 23:20:41 +0800659#endif
Nguyen Anh Quynh26ee41a2013-11-27 12:11:31 +0800660
Nguyen Anh Quynh8598a212014-05-14 11:26:41 +0800661#endif