1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
21 /* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
23 modified by John Hassey (hassey@dg-rtp.dg.com)
24 x86-64 support added by Jan Hubicka (jh@suse.cz)
25 VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
27 /* The main tables describing the instructions is essentially a copy
28 of the "Opcode Map" chapter (Appendix A) of the Intel 80386
29 Programmers Manual. Usually, there is a capital letter, followed
30 by a small letter. The capital letter tell the addressing mode,
31 and the small letter tells about the operand size. Refer to
32 the Intel manual for details. */
37 #include "opcode/i386.h"
41 static int fetch_data (struct disassemble_info *, bfd_byte *);
42 static void ckprefix (void);
43 static const char *prefix_name (int, int);
44 static int print_insn (bfd_vma, disassemble_info *);
45 static void dofloat (int);
46 static void OP_ST (int, int);
47 static void OP_STi (int, int);
48 static int putop (const char *, int);
49 static void oappend (const char *);
50 static void append_seg (void);
51 static void OP_indirE (int, int);
52 static void print_operand_value (char *, int, bfd_vma);
53 static void OP_E (int, int);
54 static void OP_G (int, int);
55 static bfd_vma get64 (void);
56 static bfd_signed_vma get32 (void);
57 static bfd_signed_vma get32s (void);
58 static int get16 (void);
59 static void set_op (bfd_vma, int);
60 static void OP_REG (int, int);
61 static void OP_IMREG (int, int);
62 static void OP_I (int, int);
63 static void OP_I64 (int, int);
64 static void OP_sI (int, int);
65 static void OP_J (int, int);
66 static void OP_SEG (int, int);
67 static void OP_DIR (int, int);
68 static void OP_OFF (int, int);
69 static void OP_OFF64 (int, int);
70 static void ptr_reg (int, int);
71 static void OP_ESreg (int, int);
72 static void OP_DSreg (int, int);
73 static void OP_C (int, int);
74 static void OP_D (int, int);
75 static void OP_T (int, int);
76 static void OP_R (int, int);
77 static void OP_MMX (int, int);
78 static void OP_XMM (int, int);
79 static void OP_EM (int, int);
80 static void OP_EX (int, int);
81 static void OP_EMC (int,int);
82 static void OP_MXC (int,int);
83 static void OP_MS (int, int);
84 static void OP_XS (int, int);
85 static void OP_M (int, int);
86 static void OP_VMX (int, int);
87 static void OP_0fae (int, int);
88 static void OP_0f07 (int, int);
89 static void NOP_Fixup1 (int, int);
90 static void NOP_Fixup2 (int, int);
91 static void OP_3DNowSuffix (int, int);
92 static void OP_SIMD_Suffix (int, int);
93 static void SIMD_Fixup (int, int);
94 static void PNI_Fixup (int, int);
95 static void SVME_Fixup (int, int);
96 static void INVLPG_Fixup (int, int);
97 static void BadOp (void);
98 static void VMX_Fixup (int, int);
99 static void REP_Fixup (int, int);
100 static void CMPXCHG8B_Fixup (int, int);
103 /* Points to first byte not fetched. */
104 bfd_byte *max_fetched;
105 bfd_byte the_buffer[MAX_MNEM_SIZE];
118 enum address_mode address_mode;
120 /* Flags for the prefixes for the current instruction. See below. */
123 /* REX prefix the current instruction. See below. */
125 /* Bits of REX we've already used. */
127 /* Mark parts used in the REX prefix. When we are testing for
128 empty prefix (for 8bit register REX extension), just mask it
129 out. Otherwise test for REX bit is excuse for existence of REX
130 only in case value is nonzero. */
131 #define USED_REX(value) \
136 rex_used |= (value) | REX_OPCODE; \
139 rex_used |= REX_OPCODE; \
142 /* Flags for prefixes which we somehow handled when printing the
143 current instruction. */
144 static int used_prefixes;
146 /* Flags stored in PREFIXES. */
147 #define PREFIX_REPZ 1
148 #define PREFIX_REPNZ 2
149 #define PREFIX_LOCK 4
151 #define PREFIX_SS 0x10
152 #define PREFIX_DS 0x20
153 #define PREFIX_ES 0x40
154 #define PREFIX_FS 0x80
155 #define PREFIX_GS 0x100
156 #define PREFIX_DATA 0x200
157 #define PREFIX_ADDR 0x400
158 #define PREFIX_FWAIT 0x800
160 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
161 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
163 #define FETCH_DATA(info, addr) \
164 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
165 ? 1 : fetch_data ((info), (addr)))
168 fetch_data (struct disassemble_info *info, bfd_byte *addr)
171 struct dis_private *priv = (struct dis_private *) info->private_data;
172 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
174 if (addr <= priv->the_buffer + MAX_MNEM_SIZE)
175 status = (*info->read_memory_func) (start,
177 addr - priv->max_fetched,
183 /* If we did manage to read at least one byte, then
184 print_insn_i386 will do something sensible. Otherwise, print
185 an error. We do that here because this is where we know
187 if (priv->max_fetched == priv->the_buffer)
188 (*info->memory_error_func) (status, start, info);
189 longjmp (priv->bailout, 1);
192 priv->max_fetched = addr;
196 #define XX { NULL, 0 }
198 #define Eb { OP_E, b_mode }
199 #define Ev { OP_E, v_mode }
200 #define Ed { OP_E, d_mode }
201 #define Edq { OP_E, dq_mode }
202 #define Edqw { OP_E, dqw_mode }
203 #define indirEv { OP_indirE, stack_v_mode }
204 #define indirEp { OP_indirE, f_mode }
205 #define stackEv { OP_E, stack_v_mode }
206 #define Em { OP_E, m_mode }
207 #define Ew { OP_E, w_mode }
208 #define M { OP_M, 0 } /* lea, lgdt, etc. */
209 #define Ma { OP_M, v_mode }
210 #define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
211 #define Mq { OP_M, q_mode }
212 #define Gb { OP_G, b_mode }
213 #define Gv { OP_G, v_mode }
214 #define Gd { OP_G, d_mode }
215 #define Gdq { OP_G, dq_mode }
216 #define Gm { OP_G, m_mode }
217 #define Gw { OP_G, w_mode }
218 #define Rd { OP_R, d_mode }
219 #define Rm { OP_R, m_mode }
220 #define Ib { OP_I, b_mode }
221 #define sIb { OP_sI, b_mode } /* sign extened byte */
222 #define Iv { OP_I, v_mode }
223 #define Iq { OP_I, q_mode }
224 #define Iv64 { OP_I64, v_mode }
225 #define Iw { OP_I, w_mode }
226 #define I1 { OP_I, const_1_mode }
227 #define Jb { OP_J, b_mode }
228 #define Jv { OP_J, v_mode }
229 #define Cm { OP_C, m_mode }
230 #define Dm { OP_D, m_mode }
231 #define Td { OP_T, d_mode }
233 #define RMeAX { OP_REG, eAX_reg }
234 #define RMeBX { OP_REG, eBX_reg }
235 #define RMeCX { OP_REG, eCX_reg }
236 #define RMeDX { OP_REG, eDX_reg }
237 #define RMeSP { OP_REG, eSP_reg }
238 #define RMeBP { OP_REG, eBP_reg }
239 #define RMeSI { OP_REG, eSI_reg }
240 #define RMeDI { OP_REG, eDI_reg }
241 #define RMrAX { OP_REG, rAX_reg }
242 #define RMrBX { OP_REG, rBX_reg }
243 #define RMrCX { OP_REG, rCX_reg }
244 #define RMrDX { OP_REG, rDX_reg }
245 #define RMrSP { OP_REG, rSP_reg }
246 #define RMrBP { OP_REG, rBP_reg }
247 #define RMrSI { OP_REG, rSI_reg }
248 #define RMrDI { OP_REG, rDI_reg }
249 #define RMAL { OP_REG, al_reg }
250 #define RMAL { OP_REG, al_reg }
251 #define RMCL { OP_REG, cl_reg }
252 #define RMDL { OP_REG, dl_reg }
253 #define RMBL { OP_REG, bl_reg }
254 #define RMAH { OP_REG, ah_reg }
255 #define RMCH { OP_REG, ch_reg }
256 #define RMDH { OP_REG, dh_reg }
257 #define RMBH { OP_REG, bh_reg }
258 #define RMAX { OP_REG, ax_reg }
259 #define RMDX { OP_REG, dx_reg }
261 #define eAX { OP_IMREG, eAX_reg }
262 #define eBX { OP_IMREG, eBX_reg }
263 #define eCX { OP_IMREG, eCX_reg }
264 #define eDX { OP_IMREG, eDX_reg }
265 #define eSP { OP_IMREG, eSP_reg }
266 #define eBP { OP_IMREG, eBP_reg }
267 #define eSI { OP_IMREG, eSI_reg }
268 #define eDI { OP_IMREG, eDI_reg }
269 #define AL { OP_IMREG, al_reg }
270 #define CL { OP_IMREG, cl_reg }
271 #define DL { OP_IMREG, dl_reg }
272 #define BL { OP_IMREG, bl_reg }
273 #define AH { OP_IMREG, ah_reg }
274 #define CH { OP_IMREG, ch_reg }
275 #define DH { OP_IMREG, dh_reg }
276 #define BH { OP_IMREG, bh_reg }
277 #define AX { OP_IMREG, ax_reg }
278 #define DX { OP_IMREG, dx_reg }
279 #define zAX { OP_IMREG, z_mode_ax_reg }
280 #define indirDX { OP_IMREG, indir_dx_reg }
282 #define Sw { OP_SEG, w_mode }
283 #define Sv { OP_SEG, v_mode }
284 #define Ap { OP_DIR, 0 }
285 #define Ob { OP_OFF64, b_mode }
286 #define Ov { OP_OFF64, v_mode }
287 #define Xb { OP_DSreg, eSI_reg }
288 #define Xv { OP_DSreg, eSI_reg }
289 #define Xz { OP_DSreg, eSI_reg }
290 #define Yb { OP_ESreg, eDI_reg }
291 #define Yv { OP_ESreg, eDI_reg }
292 #define DSBX { OP_DSreg, eBX_reg }
294 #define es { OP_REG, es_reg }
295 #define ss { OP_REG, ss_reg }
296 #define cs { OP_REG, cs_reg }
297 #define ds { OP_REG, ds_reg }
298 #define fs { OP_REG, fs_reg }
299 #define gs { OP_REG, gs_reg }
301 #define MX { OP_MMX, 0 }
302 #define XM { OP_XMM, 0 }
303 #define EM { OP_EM, v_mode }
304 #define EX { OP_EX, v_mode }
305 #define MS { OP_MS, v_mode }
306 #define XS { OP_XS, v_mode }
307 #define EMC { OP_EMC, v_mode }
308 #define MXC { OP_MXC, 0 }
309 #define VM { OP_VMX, q_mode }
310 #define OPSUF { OP_3DNowSuffix, 0 }
311 #define OPSIMD { OP_SIMD_Suffix, 0 }
313 /* Used handle "rep" prefix for string instructions. */
314 #define Xbr { REP_Fixup, eSI_reg }
315 #define Xvr { REP_Fixup, eSI_reg }
316 #define Ybr { REP_Fixup, eDI_reg }
317 #define Yvr { REP_Fixup, eDI_reg }
318 #define Yzr { REP_Fixup, eDI_reg }
319 #define indirDXr { REP_Fixup, indir_dx_reg }
320 #define ALr { REP_Fixup, al_reg }
321 #define eAXr { REP_Fixup, eAX_reg }
323 #define cond_jump_flag { NULL, cond_jump_mode }
324 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
326 /* bits in sizeflag */
327 #define SUFFIX_ALWAYS 4
331 #define b_mode 1 /* byte operand */
332 #define v_mode 2 /* operand size depends on prefixes */
333 #define w_mode 3 /* word operand */
334 #define d_mode 4 /* double word operand */
335 #define q_mode 5 /* quad word operand */
336 #define t_mode 6 /* ten-byte operand */
337 #define x_mode 7 /* 16-byte XMM operand */
338 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
339 #define cond_jump_mode 9
340 #define loop_jcxz_mode 10
341 #define dq_mode 11 /* operand size depends on REX prefixes. */
342 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
343 #define f_mode 13 /* 4- or 6-byte pointer operand */
344 #define const_1_mode 14
345 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
346 #define z_mode 16 /* non-quad operand size depends on prefixes */
347 #define o_mode 17 /* 16-byte operand */
392 #define z_mode_ax_reg 149
393 #define indir_dx_reg 150
397 #define USE_PREFIX_USER_TABLE 3
398 #define X86_64_SPECIAL 4
399 #define IS_3BYTE_OPCODE 5
401 #define FLOAT NULL, { { NULL, FLOATCODE } }
403 #define GRP1a NULL, { { NULL, USE_GROUPS }, { NULL, 0 } }
404 #define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 1 } }
405 #define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 2 } }
406 #define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 3 } }
407 #define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 4 } }
408 #define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 5 } }
409 #define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } }
410 #define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 7 } }
411 #define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } }
412 #define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 9 } }
413 #define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
414 #define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
415 #define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
416 #define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
417 #define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
418 #define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
419 #define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
420 #define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
421 #define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
422 #define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
423 #define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
424 #define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
425 #define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
426 #define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
427 #define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
428 #define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
429 #define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
430 #define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 27 } }
432 #define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } }
433 #define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } }
434 #define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } }
435 #define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } }
436 #define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } }
437 #define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } }
438 #define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } }
439 #define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } }
440 #define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } }
441 #define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } }
442 #define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
443 #define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
444 #define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
445 #define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
446 #define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
447 #define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
448 #define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
449 #define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
450 #define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
451 #define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
452 #define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
453 #define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
454 #define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
455 #define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
456 #define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
457 #define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
458 #define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
459 #define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
460 #define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
461 #define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
462 #define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
463 #define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
464 #define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
465 #define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
466 #define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
467 #define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
468 #define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
469 #define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
470 #define PREGRP38 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 38 } }
473 #define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
474 #define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
475 #define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
476 #define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
478 #define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
479 #define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
481 typedef void (*op_rtn) (int bytemode, int sizeflag);
492 /* Upper case letters in the instruction names here are macros.
493 'A' => print 'b' if no register operands or suffix_always is true
494 'B' => print 'b' if suffix_always is true
495 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
497 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
498 . suffix_always is true
499 'E' => print 'e' if 32-bit form of jcxz
500 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
501 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
502 'H' => print ",pt" or ",pn" branch hint
503 'I' => honor following macro letter even in Intel mode (implemented only
504 . for some of the macro letters)
506 'L' => print 'l' if suffix_always is true
507 'N' => print 'n' if instruction has no wait "prefix"
508 'O' => print 'd' or 'o' (or 'q' in Intel mode)
509 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
510 . or suffix_always is true. print 'q' if rex prefix is present.
511 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
513 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
514 'S' => print 'w', 'l' or 'q' if suffix_always is true
515 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
516 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
517 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
518 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
519 'X' => print 's', 'd' depending on data16 prefix (for XMM)
520 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
521 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
523 Many of the above letters print nothing in Intel mode. See "putop"
526 Braces '{' and '}', and vertical bars '|', indicate alternative
527 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
528 modes. In cases where there are only two alternatives, the X86_64
529 instruction is reserved, and "(bad)" is printed.
532 static const struct dis386 dis386[] = {
534 { "addB", { Eb, Gb } },
535 { "addS", { Ev, Gv } },
536 { "addB", { Gb, Eb } },
537 { "addS", { Gv, Ev } },
538 { "addB", { AL, Ib } },
539 { "addS", { eAX, Iv } },
540 { "push{T|}", { es } },
541 { "pop{T|}", { es } },
543 { "orB", { Eb, Gb } },
544 { "orS", { Ev, Gv } },
545 { "orB", { Gb, Eb } },
546 { "orS", { Gv, Ev } },
547 { "orB", { AL, Ib } },
548 { "orS", { eAX, Iv } },
549 { "push{T|}", { cs } },
550 { "(bad)", { XX } }, /* 0x0f extended opcode escape */
552 { "adcB", { Eb, Gb } },
553 { "adcS", { Ev, Gv } },
554 { "adcB", { Gb, Eb } },
555 { "adcS", { Gv, Ev } },
556 { "adcB", { AL, Ib } },
557 { "adcS", { eAX, Iv } },
558 { "push{T|}", { ss } },
559 { "pop{T|}", { ss } },
561 { "sbbB", { Eb, Gb } },
562 { "sbbS", { Ev, Gv } },
563 { "sbbB", { Gb, Eb } },
564 { "sbbS", { Gv, Ev } },
565 { "sbbB", { AL, Ib } },
566 { "sbbS", { eAX, Iv } },
567 { "push{T|}", { ds } },
568 { "pop{T|}", { ds } },
570 { "andB", { Eb, Gb } },
571 { "andS", { Ev, Gv } },
572 { "andB", { Gb, Eb } },
573 { "andS", { Gv, Ev } },
574 { "andB", { AL, Ib } },
575 { "andS", { eAX, Iv } },
576 { "(bad)", { XX } }, /* SEG ES prefix */
577 { "daa{|}", { XX } },
579 { "subB", { Eb, Gb } },
580 { "subS", { Ev, Gv } },
581 { "subB", { Gb, Eb } },
582 { "subS", { Gv, Ev } },
583 { "subB", { AL, Ib } },
584 { "subS", { eAX, Iv } },
585 { "(bad)", { XX } }, /* SEG CS prefix */
586 { "das{|}", { XX } },
588 { "xorB", { Eb, Gb } },
589 { "xorS", { Ev, Gv } },
590 { "xorB", { Gb, Eb } },
591 { "xorS", { Gv, Ev } },
592 { "xorB", { AL, Ib } },
593 { "xorS", { eAX, Iv } },
594 { "(bad)", { XX } }, /* SEG SS prefix */
595 { "aaa{|}", { XX } },
597 { "cmpB", { Eb, Gb } },
598 { "cmpS", { Ev, Gv } },
599 { "cmpB", { Gb, Eb } },
600 { "cmpS", { Gv, Ev } },
601 { "cmpB", { AL, Ib } },
602 { "cmpS", { eAX, Iv } },
603 { "(bad)", { XX } }, /* SEG DS prefix */
604 { "aas{|}", { XX } },
606 { "inc{S|}", { RMeAX } },
607 { "inc{S|}", { RMeCX } },
608 { "inc{S|}", { RMeDX } },
609 { "inc{S|}", { RMeBX } },
610 { "inc{S|}", { RMeSP } },
611 { "inc{S|}", { RMeBP } },
612 { "inc{S|}", { RMeSI } },
613 { "inc{S|}", { RMeDI } },
615 { "dec{S|}", { RMeAX } },
616 { "dec{S|}", { RMeCX } },
617 { "dec{S|}", { RMeDX } },
618 { "dec{S|}", { RMeBX } },
619 { "dec{S|}", { RMeSP } },
620 { "dec{S|}", { RMeBP } },
621 { "dec{S|}", { RMeSI } },
622 { "dec{S|}", { RMeDI } },
624 { "pushV", { RMrAX } },
625 { "pushV", { RMrCX } },
626 { "pushV", { RMrDX } },
627 { "pushV", { RMrBX } },
628 { "pushV", { RMrSP } },
629 { "pushV", { RMrBP } },
630 { "pushV", { RMrSI } },
631 { "pushV", { RMrDI } },
633 { "popV", { RMrAX } },
634 { "popV", { RMrCX } },
635 { "popV", { RMrDX } },
636 { "popV", { RMrBX } },
637 { "popV", { RMrSP } },
638 { "popV", { RMrBP } },
639 { "popV", { RMrSI } },
640 { "popV", { RMrDI } },
646 { "(bad)", { XX } }, /* seg fs */
647 { "(bad)", { XX } }, /* seg gs */
648 { "(bad)", { XX } }, /* op size prefix */
649 { "(bad)", { XX } }, /* adr size prefix */
652 { "imulS", { Gv, Ev, Iv } },
653 { "pushT", { sIb } },
654 { "imulS", { Gv, Ev, sIb } },
655 { "ins{b||b|}", { Ybr, indirDX } },
656 { "ins{R||G|}", { Yzr, indirDX } },
657 { "outs{b||b|}", { indirDXr, Xb } },
658 { "outs{R||G|}", { indirDXr, Xz } },
660 { "joH", { Jb, XX, cond_jump_flag } },
661 { "jnoH", { Jb, XX, cond_jump_flag } },
662 { "jbH", { Jb, XX, cond_jump_flag } },
663 { "jaeH", { Jb, XX, cond_jump_flag } },
664 { "jeH", { Jb, XX, cond_jump_flag } },
665 { "jneH", { Jb, XX, cond_jump_flag } },
666 { "jbeH", { Jb, XX, cond_jump_flag } },
667 { "jaH", { Jb, XX, cond_jump_flag } },
669 { "jsH", { Jb, XX, cond_jump_flag } },
670 { "jnsH", { Jb, XX, cond_jump_flag } },
671 { "jpH", { Jb, XX, cond_jump_flag } },
672 { "jnpH", { Jb, XX, cond_jump_flag } },
673 { "jlH", { Jb, XX, cond_jump_flag } },
674 { "jgeH", { Jb, XX, cond_jump_flag } },
675 { "jleH", { Jb, XX, cond_jump_flag } },
676 { "jgH", { Jb, XX, cond_jump_flag } },
682 { "testB", { Eb, Gb } },
683 { "testS", { Ev, Gv } },
684 { "xchgB", { Eb, Gb } },
685 { "xchgS", { Ev, Gv } },
687 { "movB", { Eb, Gb } },
688 { "movS", { Ev, Gv } },
689 { "movB", { Gb, Eb } },
690 { "movS", { Gv, Ev } },
691 { "movD", { Sv, Sw } },
692 { "leaS", { Gv, M } },
693 { "movD", { Sw, Sv } },
697 { "xchgS", { RMeCX, eAX } },
698 { "xchgS", { RMeDX, eAX } },
699 { "xchgS", { RMeBX, eAX } },
700 { "xchgS", { RMeSP, eAX } },
701 { "xchgS", { RMeBP, eAX } },
702 { "xchgS", { RMeSI, eAX } },
703 { "xchgS", { RMeDI, eAX } },
705 { "cW{t||t|}R", { XX } },
706 { "cR{t||t|}O", { XX } },
707 { "Jcall{T|}", { Ap } },
708 { "(bad)", { XX } }, /* fwait */
709 { "pushfT", { XX } },
711 { "sahf{|}", { XX } },
712 { "lahf{|}", { XX } },
714 { "movB", { AL, Ob } },
715 { "movS", { eAX, Ov } },
716 { "movB", { Ob, AL } },
717 { "movS", { Ov, eAX } },
718 { "movs{b||b|}", { Ybr, Xb } },
719 { "movs{R||R|}", { Yvr, Xv } },
720 { "cmps{b||b|}", { Xb, Yb } },
721 { "cmps{R||R|}", { Xv, Yv } },
723 { "testB", { AL, Ib } },
724 { "testS", { eAX, Iv } },
725 { "stosB", { Ybr, AL } },
726 { "stosS", { Yvr, eAX } },
727 { "lodsB", { ALr, Xb } },
728 { "lodsS", { eAXr, Xv } },
729 { "scasB", { AL, Yb } },
730 { "scasS", { eAX, Yv } },
732 { "movB", { RMAL, Ib } },
733 { "movB", { RMCL, Ib } },
734 { "movB", { RMDL, Ib } },
735 { "movB", { RMBL, Ib } },
736 { "movB", { RMAH, Ib } },
737 { "movB", { RMCH, Ib } },
738 { "movB", { RMDH, Ib } },
739 { "movB", { RMBH, Ib } },
741 { "movS", { RMeAX, Iv64 } },
742 { "movS", { RMeCX, Iv64 } },
743 { "movS", { RMeDX, Iv64 } },
744 { "movS", { RMeBX, Iv64 } },
745 { "movS", { RMeSP, Iv64 } },
746 { "movS", { RMeBP, Iv64 } },
747 { "movS", { RMeSI, Iv64 } },
748 { "movS", { RMeDI, Iv64 } },
754 { "les{S|}", { Gv, Mp } },
755 { "ldsS", { Gv, Mp } },
759 { "enterT", { Iw, Ib } },
760 { "leaveT", { XX } },
765 { "into{|}", { XX } },
772 { "aam{|}", { sIb } },
773 { "aad{|}", { sIb } },
775 { "xlat", { DSBX } },
786 { "loopneFH", { Jb, XX, loop_jcxz_flag } },
787 { "loopeFH", { Jb, XX, loop_jcxz_flag } },
788 { "loopFH", { Jb, XX, loop_jcxz_flag } },
789 { "jEcxzH", { Jb, XX, loop_jcxz_flag } },
790 { "inB", { AL, Ib } },
791 { "inG", { zAX, Ib } },
792 { "outB", { Ib, AL } },
793 { "outG", { Ib, zAX } },
797 { "Jjmp{T|}", { Ap } },
799 { "inB", { AL, indirDX } },
800 { "inG", { zAX, indirDX } },
801 { "outB", { indirDX, AL } },
802 { "outG", { indirDX, zAX } },
804 { "(bad)", { XX } }, /* lock prefix */
806 { "(bad)", { XX } }, /* repne */
807 { "(bad)", { XX } }, /* repz */
823 static const struct dis386 dis386_twobyte[] = {
827 { "larS", { Gv, Ew } },
828 { "lslS", { Gv, Ew } },
830 { "syscall", { XX } },
832 { "sysretP", { XX } },
835 { "wbinvd", { XX } },
841 { "", { MX, EM, OPSUF } }, /* See OP_3DNowSuffix. */
846 { "movlpX", { EX, XM, { SIMD_Fixup, 'h' } } },
847 { "unpcklpX", { XM, EX } },
848 { "unpckhpX", { XM, EX } },
850 { "movhpX", { EX, XM, { SIMD_Fixup, 'l' } } },
861 { "movZ", { Rm, Cm } },
862 { "movZ", { Rm, Dm } },
863 { "movZ", { Cm, Rm } },
864 { "movZ", { Dm, Rm } },
865 { "movL", { Rd, Td } },
867 { "movL", { Td, Rd } },
870 { "movapX", { XM, EX } },
871 { "movapX", { EX, XM } },
876 { "ucomisX", { XM,EX } },
877 { "comisX", { XM,EX } },
883 { "sysenter", { XX } },
884 { "sysexit", { XX } },
897 { "cmovo", { Gv, Ev } },
898 { "cmovno", { Gv, Ev } },
899 { "cmovb", { Gv, Ev } },
900 { "cmovae", { Gv, Ev } },
901 { "cmove", { Gv, Ev } },
902 { "cmovne", { Gv, Ev } },
903 { "cmovbe", { Gv, Ev } },
904 { "cmova", { Gv, Ev } },
906 { "cmovs", { Gv, Ev } },
907 { "cmovns", { Gv, Ev } },
908 { "cmovp", { Gv, Ev } },
909 { "cmovnp", { Gv, Ev } },
910 { "cmovl", { Gv, Ev } },
911 { "cmovge", { Gv, Ev } },
912 { "cmovle", { Gv, Ev } },
913 { "cmovg", { Gv, Ev } },
915 { "movmskpX", { Gdq, XS } },
919 { "andpX", { XM, EX } },
920 { "andnpX", { XM, EX } },
921 { "orpX", { XM, EX } },
922 { "xorpX", { XM, EX } },
933 { "punpcklbw", { MX, EM } },
934 { "punpcklwd", { MX, EM } },
935 { "punpckldq", { MX, EM } },
936 { "packsswb", { MX, EM } },
937 { "pcmpgtb", { MX, EM } },
938 { "pcmpgtw", { MX, EM } },
939 { "pcmpgtd", { MX, EM } },
940 { "packuswb", { MX, EM } },
942 { "punpckhbw", { MX, EM } },
943 { "punpckhwd", { MX, EM } },
944 { "punpckhdq", { MX, EM } },
945 { "packssdw", { MX, EM } },
948 { "movd", { MX, Edq } },
955 { "pcmpeqb", { MX, EM } },
956 { "pcmpeqw", { MX, EM } },
957 { "pcmpeqd", { MX, EM } },
969 { "joH", { Jv, XX, cond_jump_flag } },
970 { "jnoH", { Jv, XX, cond_jump_flag } },
971 { "jbH", { Jv, XX, cond_jump_flag } },
972 { "jaeH", { Jv, XX, cond_jump_flag } },
973 { "jeH", { Jv, XX, cond_jump_flag } },
974 { "jneH", { Jv, XX, cond_jump_flag } },
975 { "jbeH", { Jv, XX, cond_jump_flag } },
976 { "jaH", { Jv, XX, cond_jump_flag } },
978 { "jsH", { Jv, XX, cond_jump_flag } },
979 { "jnsH", { Jv, XX, cond_jump_flag } },
980 { "jpH", { Jv, XX, cond_jump_flag } },
981 { "jnpH", { Jv, XX, cond_jump_flag } },
982 { "jlH", { Jv, XX, cond_jump_flag } },
983 { "jgeH", { Jv, XX, cond_jump_flag } },
984 { "jleH", { Jv, XX, cond_jump_flag } },
985 { "jgH", { Jv, XX, cond_jump_flag } },
1001 { "setge", { Eb } },
1002 { "setle", { Eb } },
1005 { "pushT", { fs } },
1007 { "cpuid", { XX } },
1008 { "btS", { Ev, Gv } },
1009 { "shldS", { Ev, Gv, Ib } },
1010 { "shldS", { Ev, Gv, CL } },
1014 { "pushT", { gs } },
1017 { "btsS", { Ev, Gv } },
1018 { "shrdS", { Ev, Gv, Ib } },
1019 { "shrdS", { Ev, Gv, CL } },
1021 { "imulS", { Gv, Ev } },
1023 { "cmpxchgB", { Eb, Gb } },
1024 { "cmpxchgS", { Ev, Gv } },
1025 { "lssS", { Gv, Mp } },
1026 { "btrS", { Ev, Gv } },
1027 { "lfsS", { Gv, Mp } },
1028 { "lgsS", { Gv, Mp } },
1029 { "movz{bR|x|bR|x}", { Gv, Eb } },
1030 { "movz{wR|x|wR|x}", { Gv, Ew } }, /* yes, there really is movzww ! */
1035 { "btcS", { Ev, Gv } },
1036 { "bsfS", { Gv, Ev } },
1038 { "movs{bR|x|bR|x}", { Gv, Eb } },
1039 { "movs{wR|x|wR|x}", { Gv, Ew } }, /* yes, there really is movsww ! */
1041 { "xaddB", { Eb, Gb } },
1042 { "xaddS", { Ev, Gv } },
1044 { "movntiS", { Ev, Gv } },
1045 { "pinsrw", { MX, Edqw, Ib } },
1046 { "pextrw", { Gdq, MS, Ib } },
1047 { "shufpX", { XM, EX, Ib } },
1050 { "bswap", { RMeAX } },
1051 { "bswap", { RMeCX } },
1052 { "bswap", { RMeDX } },
1053 { "bswap", { RMeBX } },
1054 { "bswap", { RMeSP } },
1055 { "bswap", { RMeBP } },
1056 { "bswap", { RMeSI } },
1057 { "bswap", { RMeDI } },
1060 { "psrlw", { MX, EM } },
1061 { "psrld", { MX, EM } },
1062 { "psrlq", { MX, EM } },
1063 { "paddq", { MX, EM } },
1064 { "pmullw", { MX, EM } },
1066 { "pmovmskb", { Gdq, MS } },
1068 { "psubusb", { MX, EM } },
1069 { "psubusw", { MX, EM } },
1070 { "pminub", { MX, EM } },
1071 { "pand", { MX, EM } },
1072 { "paddusb", { MX, EM } },
1073 { "paddusw", { MX, EM } },
1074 { "pmaxub", { MX, EM } },
1075 { "pandn", { MX, EM } },
1077 { "pavgb", { MX, EM } },
1078 { "psraw", { MX, EM } },
1079 { "psrad", { MX, EM } },
1080 { "pavgw", { MX, EM } },
1081 { "pmulhuw", { MX, EM } },
1082 { "pmulhw", { MX, EM } },
1086 { "psubsb", { MX, EM } },
1087 { "psubsw", { MX, EM } },
1088 { "pminsw", { MX, EM } },
1089 { "por", { MX, EM } },
1090 { "paddsb", { MX, EM } },
1091 { "paddsw", { MX, EM } },
1092 { "pmaxsw", { MX, EM } },
1093 { "pxor", { MX, EM } },
1096 { "psllw", { MX, EM } },
1097 { "pslld", { MX, EM } },
1098 { "psllq", { MX, EM } },
1099 { "pmuludq", { MX, EM } },
1100 { "pmaddwd", { MX, EM } },
1101 { "psadbw", { MX, EM } },
1104 { "psubb", { MX, EM } },
1105 { "psubw", { MX, EM } },
1106 { "psubd", { MX, EM } },
1107 { "psubq", { MX, EM } },
1108 { "paddb", { MX, EM } },
1109 { "paddw", { MX, EM } },
1110 { "paddd", { MX, EM } },
1111 { "(bad)", { XX } },
1114 static const unsigned char onebyte_has_modrm[256] = {
1115 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1116 /* ------------------------------- */
1117 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1118 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1119 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1120 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1121 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1122 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1123 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1124 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1125 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1126 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1127 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1128 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1129 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1130 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1131 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1132 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1133 /* ------------------------------- */
1134 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1137 static const unsigned char twobyte_has_modrm[256] = {
1138 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1139 /* ------------------------------- */
1140 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1141 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1142 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1143 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1144 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1145 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1146 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1147 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1148 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1149 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1150 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1151 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1152 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1153 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1154 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1155 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1156 /* ------------------------------- */
1157 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1160 static const unsigned char twobyte_uses_DATA_prefix[256] = {
1161 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1162 /* ------------------------------- */
1163 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1164 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1165 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1166 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1167 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1168 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1169 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1170 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
1171 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1172 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1173 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1174 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1175 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1176 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1177 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1178 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1179 /* ------------------------------- */
1180 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1183 static const unsigned char twobyte_uses_REPNZ_prefix[256] = {
1184 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1185 /* ------------------------------- */
1186 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1187 /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1188 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1189 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1190 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1191 /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1192 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1193 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1194 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1195 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1196 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1197 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1198 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1199 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1200 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1201 /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1202 /* ------------------------------- */
1203 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1206 static const unsigned char twobyte_uses_REPZ_prefix[256] = {
1207 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1208 /* ------------------------------- */
1209 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1210 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1211 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1212 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1213 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1214 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1215 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1216 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1217 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1218 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1219 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1220 /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1221 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1222 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1223 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1224 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1225 /* ------------------------------- */
1226 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1229 /* This is used to determine if opcode 0f 38 XX uses DATA prefix. */
1230 static const unsigned char threebyte_0x38_uses_DATA_prefix[256] = {
1231 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1232 /* ------------------------------- */
1233 /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1234 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0, /* 1f */
1235 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1236 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1237 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1238 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1239 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1240 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1241 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1242 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1243 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1244 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1245 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1246 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1247 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1248 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1249 /* ------------------------------- */
1250 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1253 /* This is used to determine if opcode 0f 38 XX uses REPNZ prefix. */
1254 static const unsigned char threebyte_0x38_uses_REPNZ_prefix[256] = {
1255 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1256 /* ------------------------------- */
1257 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1258 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1259 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1260 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1261 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1262 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1263 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1264 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1265 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1266 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1267 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1268 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1269 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1270 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1271 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1272 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1273 /* ------------------------------- */
1274 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1277 /* This is used to determine if opcode 0f 38 XX uses REPZ prefix. */
1278 static const unsigned char threebyte_0x38_uses_REPZ_prefix[256] = {
1279 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1280 /* ------------------------------- */
1281 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1282 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1283 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1284 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1285 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1286 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1287 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1288 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1289 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1290 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1291 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1292 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1293 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1294 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1295 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1296 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1297 /* ------------------------------- */
1298 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1301 /* This is used to determine if opcode 0f 3a XX uses DATA prefix. */
1302 static const unsigned char threebyte_0x3a_uses_DATA_prefix[256] = {
1303 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1304 /* ------------------------------- */
1305 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 0f */
1306 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1307 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1308 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1309 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1310 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1311 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1312 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1313 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1314 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1315 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1316 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1317 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1318 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1319 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1320 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1321 /* ------------------------------- */
1322 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1325 /* This is used to determine if opcode 0f 3a XX uses REPNZ prefix. */
1326 static const unsigned char threebyte_0x3a_uses_REPNZ_prefix[256] = {
1327 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1328 /* ------------------------------- */
1329 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1330 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1331 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1332 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1333 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1334 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1335 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1336 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1337 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1338 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1339 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1340 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1341 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1342 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1343 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1344 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1345 /* ------------------------------- */
1346 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1349 /* This is used to determine if opcode 0f 3a XX uses REPZ prefix. */
1350 static const unsigned char threebyte_0x3a_uses_REPZ_prefix[256] = {
1351 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1352 /* ------------------------------- */
1353 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1354 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1355 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1356 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1357 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1358 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1359 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1360 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1361 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1362 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1363 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1364 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1365 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1366 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1367 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1368 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1369 /* ------------------------------- */
1370 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1373 static char obuf[100];
1375 static char scratchbuf[100];
1376 static unsigned char *start_codep;
1377 static unsigned char *insn_codep;
1378 static unsigned char *codep;
1379 static disassemble_info *the_info;
1387 static unsigned char need_modrm;
1389 /* If we are accessing mod/rm/reg without need_modrm set, then the
1390 values are stale. Hitting this abort likely indicates that you
1391 need to update onebyte_has_modrm or twobyte_has_modrm. */
1392 #define MODRM_CHECK if (!need_modrm) abort ()
1394 static const char **names64;
1395 static const char **names32;
1396 static const char **names16;
1397 static const char **names8;
1398 static const char **names8rex;
1399 static const char **names_seg;
1400 static const char **index16;
1402 static const char *intel_names64[] = {
1403 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1404 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1406 static const char *intel_names32[] = {
1407 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1408 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1410 static const char *intel_names16[] = {
1411 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1412 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1414 static const char *intel_names8[] = {
1415 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1417 static const char *intel_names8rex[] = {
1418 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1419 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1421 static const char *intel_names_seg[] = {
1422 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1424 static const char *intel_index16[] = {
1425 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1428 static const char *att_names64[] = {
1429 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1430 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1432 static const char *att_names32[] = {
1433 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1434 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1436 static const char *att_names16[] = {
1437 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1438 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1440 static const char *att_names8[] = {
1441 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1443 static const char *att_names8rex[] = {
1444 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1445 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1447 static const char *att_names_seg[] = {
1448 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1450 static const char *att_index16[] = {
1451 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1454 static const struct dis386 grps[][8] = {
1457 { "popU", { stackEv } },
1458 { "(bad)", { XX } },
1459 { "(bad)", { XX } },
1460 { "(bad)", { XX } },
1461 { "(bad)", { XX } },
1462 { "(bad)", { XX } },
1463 { "(bad)", { XX } },
1464 { "(bad)", { XX } },
1468 { "addA", { Eb, Ib } },
1469 { "orA", { Eb, Ib } },
1470 { "adcA", { Eb, Ib } },
1471 { "sbbA", { Eb, Ib } },
1472 { "andA", { Eb, Ib } },
1473 { "subA", { Eb, Ib } },
1474 { "xorA", { Eb, Ib } },
1475 { "cmpA", { Eb, Ib } },
1479 { "addQ", { Ev, Iv } },
1480 { "orQ", { Ev, Iv } },
1481 { "adcQ", { Ev, Iv } },
1482 { "sbbQ", { Ev, Iv } },
1483 { "andQ", { Ev, Iv } },
1484 { "subQ", { Ev, Iv } },
1485 { "xorQ", { Ev, Iv } },
1486 { "cmpQ", { Ev, Iv } },
1490 { "addQ", { Ev, sIb } },
1491 { "orQ", { Ev, sIb } },
1492 { "adcQ", { Ev, sIb } },
1493 { "sbbQ", { Ev, sIb } },
1494 { "andQ", { Ev, sIb } },
1495 { "subQ", { Ev, sIb } },
1496 { "xorQ", { Ev, sIb } },
1497 { "cmpQ", { Ev, sIb } },
1501 { "rolA", { Eb, Ib } },
1502 { "rorA", { Eb, Ib } },
1503 { "rclA", { Eb, Ib } },
1504 { "rcrA", { Eb, Ib } },
1505 { "shlA", { Eb, Ib } },
1506 { "shrA", { Eb, Ib } },
1507 { "(bad)", { XX } },
1508 { "sarA", { Eb, Ib } },
1512 { "rolQ", { Ev, Ib } },
1513 { "rorQ", { Ev, Ib } },
1514 { "rclQ", { Ev, Ib } },
1515 { "rcrQ", { Ev, Ib } },
1516 { "shlQ", { Ev, Ib } },
1517 { "shrQ", { Ev, Ib } },
1518 { "(bad)", { XX } },
1519 { "sarQ", { Ev, Ib } },
1523 { "rolA", { Eb, I1 } },
1524 { "rorA", { Eb, I1 } },
1525 { "rclA", { Eb, I1 } },
1526 { "rcrA", { Eb, I1 } },
1527 { "shlA", { Eb, I1 } },
1528 { "shrA", { Eb, I1 } },
1529 { "(bad)", { XX } },
1530 { "sarA", { Eb, I1 } },
1534 { "rolQ", { Ev, I1 } },
1535 { "rorQ", { Ev, I1 } },
1536 { "rclQ", { Ev, I1 } },
1537 { "rcrQ", { Ev, I1 } },
1538 { "shlQ", { Ev, I1 } },
1539 { "shrQ", { Ev, I1 } },
1540 { "(bad)", { XX } },
1541 { "sarQ", { Ev, I1 } },
1545 { "rolA", { Eb, CL } },
1546 { "rorA", { Eb, CL } },
1547 { "rclA", { Eb, CL } },
1548 { "rcrA", { Eb, CL } },
1549 { "shlA", { Eb, CL } },
1550 { "shrA", { Eb, CL } },
1551 { "(bad)", { XX } },
1552 { "sarA", { Eb, CL } },
1556 { "rolQ", { Ev, CL } },
1557 { "rorQ", { Ev, CL } },
1558 { "rclQ", { Ev, CL } },
1559 { "rcrQ", { Ev, CL } },
1560 { "shlQ", { Ev, CL } },
1561 { "shrQ", { Ev, CL } },
1562 { "(bad)", { XX } },
1563 { "sarQ", { Ev, CL } },
1567 { "testA", { Eb, Ib } },
1568 { "(bad)", { Eb } },
1571 { "mulA", { Eb } }, /* Don't print the implicit %al register, */
1572 { "imulA", { Eb } }, /* to distinguish these opcodes from other */
1573 { "divA", { Eb } }, /* mul/imul opcodes. Do the same for div */
1574 { "idivA", { Eb } }, /* and idiv for consistency. */
1578 { "testQ", { Ev, Iv } },
1579 { "(bad)", { XX } },
1582 { "mulQ", { Ev } }, /* Don't print the implicit register. */
1583 { "imulQ", { Ev } },
1585 { "idivQ", { Ev } },
1591 { "(bad)", { XX } },
1592 { "(bad)", { XX } },
1593 { "(bad)", { XX } },
1594 { "(bad)", { XX } },
1595 { "(bad)", { XX } },
1596 { "(bad)", { XX } },
1602 { "callT", { indirEv } },
1603 { "JcallT", { indirEp } },
1604 { "jmpT", { indirEv } },
1605 { "JjmpT", { indirEp } },
1606 { "pushU", { stackEv } },
1607 { "(bad)", { XX } },
1611 { "sldtD", { Sv } },
1617 { "(bad)", { XX } },
1618 { "(bad)", { XX } },
1622 { "sgdt{Q|IQ||}", { { VMX_Fixup, 0 } } },
1623 { "sidt{Q|IQ||}", { { PNI_Fixup, 0 } } },
1624 { "lgdt{Q|Q||}", { M } },
1625 { "lidt{Q|Q||}", { { SVME_Fixup, 0 } } },
1626 { "smswD", { Sv } },
1627 { "(bad)", { XX } },
1629 { "invlpg", { { INVLPG_Fixup, w_mode } } },
1633 { "(bad)", { XX } },
1634 { "(bad)", { XX } },
1635 { "(bad)", { XX } },
1636 { "(bad)", { XX } },
1637 { "btQ", { Ev, Ib } },
1638 { "btsQ", { Ev, Ib } },
1639 { "btrQ", { Ev, Ib } },
1640 { "btcQ", { Ev, Ib } },
1644 { "(bad)", { XX } },
1645 { "cmpxchg8b", { { CMPXCHG8B_Fixup, q_mode } } },
1646 { "(bad)", { XX } },
1647 { "(bad)", { XX } },
1648 { "(bad)", { XX } },
1649 { "(bad)", { XX } },
1650 { "", { VM } }, /* See OP_VMX. */
1651 { "vmptrst", { Mq } },
1655 { "movA", { Eb, Ib } },
1656 { "(bad)", { XX } },
1657 { "(bad)", { XX } },
1658 { "(bad)", { XX } },
1659 { "(bad)", { XX } },
1660 { "(bad)", { XX } },
1661 { "(bad)", { XX } },
1662 { "(bad)", { XX } },
1666 { "movQ", { Ev, Iv } },
1667 { "(bad)", { XX } },
1668 { "(bad)", { XX } },
1669 { "(bad)", { XX } },
1670 { "(bad)", { XX } },
1671 { "(bad)", { XX } },
1672 { "(bad)", { XX } },
1673 { "(bad)", { XX } },
1677 { "(bad)", { XX } },
1678 { "(bad)", { XX } },
1679 { "psrlw", { MS, Ib } },
1680 { "(bad)", { XX } },
1681 { "psraw", { MS, Ib } },
1682 { "(bad)", { XX } },
1683 { "psllw", { MS, Ib } },
1684 { "(bad)", { XX } },
1688 { "(bad)", { XX } },
1689 { "(bad)", { XX } },
1690 { "psrld", { MS, Ib } },
1691 { "(bad)", { XX } },
1692 { "psrad", { MS, Ib } },
1693 { "(bad)", { XX } },
1694 { "pslld", { MS, Ib } },
1695 { "(bad)", { XX } },
1699 { "(bad)", { XX } },
1700 { "(bad)", { XX } },
1701 { "psrlq", { MS, Ib } },
1702 { "psrldq", { MS, Ib } },
1703 { "(bad)", { XX } },
1704 { "(bad)", { XX } },
1705 { "psllq", { MS, Ib } },
1706 { "pslldq", { MS, Ib } },
1710 { "fxsave", { Ev } },
1711 { "fxrstor", { Ev } },
1712 { "ldmxcsr", { Ev } },
1713 { "stmxcsr", { Ev } },
1714 { "(bad)", { XX } },
1715 { "lfence", { { OP_0fae, 0 } } },
1716 { "mfence", { { OP_0fae, 0 } } },
1717 { "clflush", { { OP_0fae, 0 } } },
1721 { "prefetchnta", { Ev } },
1722 { "prefetcht0", { Ev } },
1723 { "prefetcht1", { Ev } },
1724 { "prefetcht2", { Ev } },
1725 { "(bad)", { XX } },
1726 { "(bad)", { XX } },
1727 { "(bad)", { XX } },
1728 { "(bad)", { XX } },
1732 { "prefetch", { Eb } },
1733 { "prefetchw", { Eb } },
1734 { "(bad)", { XX } },
1735 { "(bad)", { XX } },
1736 { "(bad)", { XX } },
1737 { "(bad)", { XX } },
1738 { "(bad)", { XX } },
1739 { "(bad)", { XX } },
1743 { "xstore-rng", { { OP_0f07, 0 } } },
1744 { "xcrypt-ecb", { { OP_0f07, 0 } } },
1745 { "xcrypt-cbc", { { OP_0f07, 0 } } },
1746 { "xcrypt-ctr", { { OP_0f07, 0 } } },
1747 { "xcrypt-cfb", { { OP_0f07, 0 } } },
1748 { "xcrypt-ofb", { { OP_0f07, 0 } } },
1749 { "(bad)", { { OP_0f07, 0 } } },
1750 { "(bad)", { { OP_0f07, 0 } } },
1754 { "montmul", { { OP_0f07, 0 } } },
1755 { "xsha1", { { OP_0f07, 0 } } },
1756 { "xsha256", { { OP_0f07, 0 } } },
1757 { "(bad)", { { OP_0f07, 0 } } },
1758 { "(bad)", { { OP_0f07, 0 } } },
1759 { "(bad)", { { OP_0f07, 0 } } },
1760 { "(bad)", { { OP_0f07, 0 } } },
1761 { "(bad)", { { OP_0f07, 0 } } },
1765 static const struct dis386 prefix_user_table[][4] = {
1768 { "addps", { XM, EX } },
1769 { "addss", { XM, EX } },
1770 { "addpd", { XM, EX } },
1771 { "addsd", { XM, EX } },
1775 { "", { XM, EX, OPSIMD } }, /* See OP_SIMD_SUFFIX. */
1776 { "", { XM, EX, OPSIMD } },
1777 { "", { XM, EX, OPSIMD } },
1778 { "", { XM, EX, OPSIMD } },
1782 { "cvtpi2ps", { XM, EMC } },
1783 { "cvtsi2ssY", { XM, Ev } },
1784 { "cvtpi2pd", { XM, EMC } },
1785 { "cvtsi2sdY", { XM, Ev } },
1789 { "cvtps2pi", { MXC, EX } },
1790 { "cvtss2siY", { Gv, EX } },
1791 { "cvtpd2pi", { MXC, EX } },
1792 { "cvtsd2siY", { Gv, EX } },
1796 { "cvttps2pi", { MXC, EX } },
1797 { "cvttss2siY", { Gv, EX } },
1798 { "cvttpd2pi", { MXC, EX } },
1799 { "cvttsd2siY", { Gv, EX } },
1803 { "divps", { XM, EX } },
1804 { "divss", { XM, EX } },
1805 { "divpd", { XM, EX } },
1806 { "divsd", { XM, EX } },
1810 { "maxps", { XM, EX } },
1811 { "maxss", { XM, EX } },
1812 { "maxpd", { XM, EX } },
1813 { "maxsd", { XM, EX } },
1817 { "minps", { XM, EX } },
1818 { "minss", { XM, EX } },
1819 { "minpd", { XM, EX } },
1820 { "minsd", { XM, EX } },
1824 { "movups", { XM, EX } },
1825 { "movss", { XM, EX } },
1826 { "movupd", { XM, EX } },
1827 { "movsd", { XM, EX } },
1831 { "movups", { EX, XM } },
1832 { "movss", { EX, XM } },
1833 { "movupd", { EX, XM } },
1834 { "movsd", { EX, XM } },
1838 { "mulps", { XM, EX } },
1839 { "mulss", { XM, EX } },
1840 { "mulpd", { XM, EX } },
1841 { "mulsd", { XM, EX } },
1845 { "rcpps", { XM, EX } },
1846 { "rcpss", { XM, EX } },
1847 { "(bad)", { XM, EX } },
1848 { "(bad)", { XM, EX } },
1852 { "rsqrtps",{ XM, EX } },
1853 { "rsqrtss",{ XM, EX } },
1854 { "(bad)", { XM, EX } },
1855 { "(bad)", { XM, EX } },
1859 { "sqrtps", { XM, EX } },
1860 { "sqrtss", { XM, EX } },
1861 { "sqrtpd", { XM, EX } },
1862 { "sqrtsd", { XM, EX } },
1866 { "subps", { XM, EX } },
1867 { "subss", { XM, EX } },
1868 { "subpd", { XM, EX } },
1869 { "subsd", { XM, EX } },
1873 { "(bad)", { XM, EX } },
1874 { "cvtdq2pd", { XM, EX } },
1875 { "cvttpd2dq", { XM, EX } },
1876 { "cvtpd2dq", { XM, EX } },
1880 { "cvtdq2ps", { XM, EX } },
1881 { "cvttps2dq", { XM, EX } },
1882 { "cvtps2dq", { XM, EX } },
1883 { "(bad)", { XM, EX } },
1887 { "cvtps2pd", { XM, EX } },
1888 { "cvtss2sd", { XM, EX } },
1889 { "cvtpd2ps", { XM, EX } },
1890 { "cvtsd2ss", { XM, EX } },
1894 { "maskmovq", { MX, MS } },
1895 { "(bad)", { XM, EX } },
1896 { "maskmovdqu", { XM, XS } },
1897 { "(bad)", { XM, EX } },
1901 { "movq", { MX, EM } },
1902 { "movdqu", { XM, EX } },
1903 { "movdqa", { XM, EX } },
1904 { "(bad)", { XM, EX } },
1908 { "movq", { EM, MX } },
1909 { "movdqu", { EX, XM } },
1910 { "movdqa", { EX, XM } },
1911 { "(bad)", { EX, XM } },
1915 { "(bad)", { EX, XM } },
1916 { "movq2dq",{ XM, MS } },
1917 { "movq", { EX, XM } },
1918 { "movdq2q",{ MX, XS } },
1922 { "pshufw", { MX, EM, Ib } },
1923 { "pshufhw",{ XM, EX, Ib } },
1924 { "pshufd", { XM, EX, Ib } },
1925 { "pshuflw",{ XM, EX, Ib } },
1929 { "movd", { Edq, MX } },
1930 { "movq", { XM, EX } },
1931 { "movd", { Edq, XM } },
1932 { "(bad)", { Ed, XM } },
1936 { "(bad)", { MX, EX } },
1937 { "(bad)", { XM, EX } },
1938 { "punpckhqdq", { XM, EX } },
1939 { "(bad)", { XM, EX } },
1943 { "movntq", { EM, MX } },
1944 { "(bad)", { EM, XM } },
1945 { "movntdq",{ EM, XM } },
1946 { "(bad)", { EM, XM } },
1950 { "(bad)", { MX, EX } },
1951 { "(bad)", { XM, EX } },
1952 { "punpcklqdq", { XM, EX } },
1953 { "(bad)", { XM, EX } },
1957 { "(bad)", { MX, EX } },
1958 { "(bad)", { XM, EX } },
1959 { "addsubpd", { XM, EX } },
1960 { "addsubps", { XM, EX } },
1964 { "(bad)", { MX, EX } },
1965 { "(bad)", { XM, EX } },
1966 { "haddpd", { XM, EX } },
1967 { "haddps", { XM, EX } },
1971 { "(bad)", { MX, EX } },
1972 { "(bad)", { XM, EX } },
1973 { "hsubpd", { XM, EX } },
1974 { "hsubps", { XM, EX } },
1978 { "movlpX", { XM, EX, { SIMD_Fixup, 'h' } } }, /* really only 2 operands */
1979 { "movsldup", { XM, EX } },
1980 { "movlpd", { XM, EX } },
1981 { "movddup", { XM, EX } },
1985 { "movhpX", { XM, EX, { SIMD_Fixup, 'l' } } },
1986 { "movshdup", { XM, EX } },
1987 { "movhpd", { XM, EX } },
1988 { "(bad)", { XM, EX } },
1992 { "(bad)", { XM, EX } },
1993 { "(bad)", { XM, EX } },
1994 { "(bad)", { XM, EX } },
1995 { "lddqu", { XM, M } },
1999 {"movntps", { Ev, XM } },
2000 {"movntss", { Ev, XM } },
2001 {"movntpd", { Ev, XM } },
2002 {"movntsd", { Ev, XM } },
2007 {"vmread", { Em, Gm } },
2009 {"extrq", { XS, Ib, Ib } },
2010 {"insertq", { XM, XS, Ib, Ib } },
2015 {"vmwrite", { Gm, Em } },
2017 {"extrq", { XM, XS } },
2018 {"insertq", { XM, XS } },
2023 { "bsrS", { Gv, Ev } },
2024 { "lzcntS", { Gv, Ev } },
2025 { "bsrS", { Gv, Ev } },
2026 { "(bad)", { XX } },
2031 { "(bad)", { XX } },
2032 { "popcntS", { Gv, Ev } },
2033 { "(bad)", { XX } },
2034 { "(bad)", { XX } },
2039 { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
2040 { "pause", { XX } },
2041 { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
2042 { "(bad)", { XX } },
2046 static const struct dis386 x86_64_table[][2] = {
2048 { "pusha{P|}", { XX } },
2049 { "(bad)", { XX } },
2052 { "popa{P|}", { XX } },
2053 { "(bad)", { XX } },
2056 { "bound{S|}", { Gv, Ma } },
2057 { "(bad)", { XX } },
2060 { "arpl", { Ew, Gw } },
2061 { "movs{||lq|xd}", { Gv, Ed } },
2065 static const struct dis386 three_byte_table[][256] = {
2069 { "pshufb", { MX, EM } },
2070 { "phaddw", { MX, EM } },
2071 { "phaddd", { MX, EM } },
2072 { "phaddsw", { MX, EM } },
2073 { "pmaddubsw", { MX, EM } },
2074 { "phsubw", { MX, EM } },
2075 { "phsubd", { MX, EM } },
2076 { "phsubsw", { MX, EM } },
2078 { "psignb", { MX, EM } },
2079 { "psignw", { MX, EM } },
2080 { "psignd", { MX, EM } },
2081 { "pmulhrsw", { MX, EM } },
2082 { "(bad)", { XX } },
2083 { "(bad)", { XX } },
2084 { "(bad)", { XX } },
2085 { "(bad)", { XX } },
2087 { "(bad)", { XX } },
2088 { "(bad)", { XX } },
2089 { "(bad)", { XX } },
2090 { "(bad)", { XX } },
2091 { "(bad)", { XX } },
2092 { "(bad)", { XX } },
2093 { "(bad)", { XX } },
2094 { "(bad)", { XX } },
2096 { "(bad)", { XX } },
2097 { "(bad)", { XX } },
2098 { "(bad)", { XX } },
2099 { "(bad)", { XX } },
2100 { "pabsb", { MX, EM } },
2101 { "pabsw", { MX, EM } },
2102 { "pabsd", { MX, EM } },
2103 { "(bad)", { XX } },
2105 { "(bad)", { XX } },
2106 { "(bad)", { XX } },
2107 { "(bad)", { XX } },
2108 { "(bad)", { XX } },
2109 { "(bad)", { XX } },
2110 { "(bad)", { XX } },
2111 { "(bad)", { XX } },
2112 { "(bad)", { XX } },
2114 { "(bad)", { XX } },
2115 { "(bad)", { XX } },
2116 { "(bad)", { XX } },
2117 { "(bad)", { XX } },
2118 { "(bad)", { XX } },
2119 { "(bad)", { XX } },
2120 { "(bad)", { XX } },
2121 { "(bad)", { XX } },
2123 { "(bad)", { XX } },
2124 { "(bad)", { XX } },
2125 { "(bad)", { XX } },
2126 { "(bad)", { XX } },
2127 { "(bad)", { XX } },
2128 { "(bad)", { XX } },
2129 { "(bad)", { XX } },
2130 { "(bad)", { XX } },
2132 { "(bad)", { XX } },
2133 { "(bad)", { XX } },
2134 { "(bad)", { XX } },
2135 { "(bad)", { XX } },
2136 { "(bad)", { XX } },
2137 { "(bad)", { XX } },
2138 { "(bad)", { XX } },
2139 { "(bad)", { XX } },
2141 { "(bad)", { XX } },
2142 { "(bad)", { XX } },
2143 { "(bad)", { XX } },
2144 { "(bad)", { XX } },
2145 { "(bad)", { XX } },
2146 { "(bad)", { XX } },
2147 { "(bad)", { XX } },
2148 { "(bad)", { XX } },
2150 { "(bad)", { XX } },
2151 { "(bad)", { XX } },
2152 { "(bad)", { XX } },
2153 { "(bad)", { XX } },
2154 { "(bad)", { XX } },
2155 { "(bad)", { XX } },
2156 { "(bad)", { XX } },
2157 { "(bad)", { XX } },
2159 { "(bad)", { XX } },
2160 { "(bad)", { XX } },
2161 { "(bad)", { XX } },
2162 { "(bad)", { XX } },
2163 { "(bad)", { XX } },
2164 { "(bad)", { XX } },
2165 { "(bad)", { XX } },
2166 { "(bad)", { XX } },
2168 { "(bad)", { XX } },
2169 { "(bad)", { XX } },
2170 { "(bad)", { XX } },
2171 { "(bad)", { XX } },
2172 { "(bad)", { XX } },
2173 { "(bad)", { XX } },
2174 { "(bad)", { XX } },
2175 { "(bad)", { XX } },
2177 { "(bad)", { XX } },
2178 { "(bad)", { XX } },
2179 { "(bad)", { XX } },
2180 { "(bad)", { XX } },
2181 { "(bad)", { XX } },
2182 { "(bad)", { XX } },
2183 { "(bad)", { XX } },
2184 { "(bad)", { XX } },
2186 { "(bad)", { XX } },
2187 { "(bad)", { XX } },
2188 { "(bad)", { XX } },
2189 { "(bad)", { XX } },
2190 { "(bad)", { XX } },
2191 { "(bad)", { XX } },
2192 { "(bad)", { XX } },
2193 { "(bad)", { XX } },
2195 { "(bad)", { XX } },
2196 { "(bad)", { XX } },
2197 { "(bad)", { XX } },
2198 { "(bad)", { XX } },
2199 { "(bad)", { XX } },
2200 { "(bad)", { XX } },
2201 { "(bad)", { XX } },
2202 { "(bad)", { XX } },
2204 { "(bad)", { XX } },
2205 { "(bad)", { XX } },
2206 { "(bad)", { XX } },
2207 { "(bad)", { XX } },
2208 { "(bad)", { XX } },
2209 { "(bad)", { XX } },
2210 { "(bad)", { XX } },
2211 { "(bad)", { XX } },
2213 { "(bad)", { XX } },
2214 { "(bad)", { XX } },
2215 { "(bad)", { XX } },
2216 { "(bad)", { XX } },
2217 { "(bad)", { XX } },
2218 { "(bad)", { XX } },
2219 { "(bad)", { XX } },
2220 { "(bad)", { XX } },
2222 { "(bad)", { XX } },
2223 { "(bad)", { XX } },
2224 { "(bad)", { XX } },
2225 { "(bad)", { XX } },
2226 { "(bad)", { XX } },
2227 { "(bad)", { XX } },
2228 { "(bad)", { XX } },
2229 { "(bad)", { XX } },
2231 { "(bad)", { XX } },
2232 { "(bad)", { XX } },
2233 { "(bad)", { XX } },
2234 { "(bad)", { XX } },
2235 { "(bad)", { XX } },
2236 { "(bad)", { XX } },
2237 { "(bad)", { XX } },
2238 { "(bad)", { XX } },
2240 { "(bad)", { XX } },
2241 { "(bad)", { XX } },
2242 { "(bad)", { XX } },
2243 { "(bad)", { XX } },
2244 { "(bad)", { XX } },
2245 { "(bad)", { XX } },
2246 { "(bad)", { XX } },
2247 { "(bad)", { XX } },
2249 { "(bad)", { XX } },
2250 { "(bad)", { XX } },
2251 { "(bad)", { XX } },
2252 { "(bad)", { XX } },
2253 { "(bad)", { XX } },
2254 { "(bad)", { XX } },
2255 { "(bad)", { XX } },
2256 { "(bad)", { XX } },
2258 { "(bad)", { XX } },
2259 { "(bad)", { XX } },
2260 { "(bad)", { XX } },
2261 { "(bad)", { XX } },
2262 { "(bad)", { XX } },
2263 { "(bad)", { XX } },
2264 { "(bad)", { XX } },
2265 { "(bad)", { XX } },
2267 { "(bad)", { XX } },
2268 { "(bad)", { XX } },
2269 { "(bad)", { XX } },
2270 { "(bad)", { XX } },
2271 { "(bad)", { XX } },
2272 { "(bad)", { XX } },
2273 { "(bad)", { XX } },
2274 { "(bad)", { XX } },
2276 { "(bad)", { XX } },
2277 { "(bad)", { XX } },
2278 { "(bad)", { XX } },
2279 { "(bad)", { XX } },
2280 { "(bad)", { XX } },
2281 { "(bad)", { XX } },
2282 { "(bad)", { XX } },
2283 { "(bad)", { XX } },
2285 { "(bad)", { XX } },
2286 { "(bad)", { XX } },
2287 { "(bad)", { XX } },
2288 { "(bad)", { XX } },
2289 { "(bad)", { XX } },
2290 { "(bad)", { XX } },
2291 { "(bad)", { XX } },
2292 { "(bad)", { XX } },
2294 { "(bad)", { XX } },
2295 { "(bad)", { XX } },
2296 { "(bad)", { XX } },
2297 { "(bad)", { XX } },
2298 { "(bad)", { XX } },
2299 { "(bad)", { XX } },
2300 { "(bad)", { XX } },
2301 { "(bad)", { XX } },
2303 { "(bad)", { XX } },
2304 { "(bad)", { XX } },
2305 { "(bad)", { XX } },
2306 { "(bad)", { XX } },
2307 { "(bad)", { XX } },
2308 { "(bad)", { XX } },
2309 { "(bad)", { XX } },
2310 { "(bad)", { XX } },
2312 { "(bad)", { XX } },
2313 { "(bad)", { XX } },
2314 { "(bad)", { XX } },
2315 { "(bad)", { XX } },
2316 { "(bad)", { XX } },
2317 { "(bad)", { XX } },
2318 { "(bad)", { XX } },
2319 { "(bad)", { XX } },
2321 { "(bad)", { XX } },
2322 { "(bad)", { XX } },
2323 { "(bad)", { XX } },
2324 { "(bad)", { XX } },
2325 { "(bad)", { XX } },
2326 { "(bad)", { XX } },
2327 { "(bad)", { XX } },
2328 { "(bad)", { XX } },
2330 { "(bad)", { XX } },
2331 { "(bad)", { XX } },
2332 { "(bad)", { XX } },
2333 { "(bad)", { XX } },
2334 { "(bad)", { XX } },
2335 { "(bad)", { XX } },
2336 { "(bad)", { XX } },
2337 { "(bad)", { XX } },
2339 { "(bad)", { XX } },
2340 { "(bad)", { XX } },
2341 { "(bad)", { XX } },
2342 { "(bad)", { XX } },
2343 { "(bad)", { XX } },
2344 { "(bad)", { XX } },
2345 { "(bad)", { XX } },
2346 { "(bad)", { XX } },
2348 { "(bad)", { XX } },
2349 { "(bad)", { XX } },
2350 { "(bad)", { XX } },
2351 { "(bad)", { XX } },
2352 { "(bad)", { XX } },
2353 { "(bad)", { XX } },
2354 { "(bad)", { XX } },
2355 { "(bad)", { XX } },
2360 { "(bad)", { XX } },
2361 { "(bad)", { XX } },
2362 { "(bad)", { XX } },
2363 { "(bad)", { XX } },
2364 { "(bad)", { XX } },
2365 { "(bad)", { XX } },
2366 { "(bad)", { XX } },
2367 { "(bad)", { XX } },
2369 { "(bad)", { XX } },
2370 { "(bad)", { XX } },
2371 { "(bad)", { XX } },
2372 { "(bad)", { XX } },
2373 { "(bad)", { XX } },
2374 { "(bad)", { XX } },
2375 { "(bad)", { XX } },
2376 { "palignr", { MX, EM, Ib } },
2378 { "(bad)", { XX } },
2379 { "(bad)", { XX } },
2380 { "(bad)", { XX } },
2381 { "(bad)", { XX } },
2382 { "(bad)", { XX } },
2383 { "(bad)", { XX } },
2384 { "(bad)", { XX } },
2385 { "(bad)", { XX } },
2387 { "(bad)", { XX } },
2388 { "(bad)", { XX } },
2389 { "(bad)", { XX } },
2390 { "(bad)", { XX } },
2391 { "(bad)", { XX } },
2392 { "(bad)", { XX } },
2393 { "(bad)", { XX } },
2394 { "(bad)", { XX } },
2396 { "(bad)", { XX } },
2397 { "(bad)", { XX } },
2398 { "(bad)", { XX } },
2399 { "(bad)", { XX } },
2400 { "(bad)", { XX } },
2401 { "(bad)", { XX } },
2402 { "(bad)", { XX } },
2403 { "(bad)", { XX } },
2405 { "(bad)", { XX } },
2406 { "(bad)", { XX } },
2407 { "(bad)", { XX } },
2408 { "(bad)", { XX } },
2409 { "(bad)", { XX } },
2410 { "(bad)", { XX } },
2411 { "(bad)", { XX } },
2412 { "(bad)", { XX } },
2414 { "(bad)", { XX } },
2415 { "(bad)", { XX } },
2416 { "(bad)", { XX } },
2417 { "(bad)", { XX } },
2418 { "(bad)", { XX } },
2419 { "(bad)", { XX } },
2420 { "(bad)", { XX } },
2421 { "(bad)", { XX } },
2423 { "(bad)", { XX } },
2424 { "(bad)", { XX } },
2425 { "(bad)", { XX } },
2426 { "(bad)", { XX } },
2427 { "(bad)", { XX } },
2428 { "(bad)", { XX } },
2429 { "(bad)", { XX } },
2430 { "(bad)", { XX } },
2432 { "(bad)", { XX } },
2433 { "(bad)", { XX } },
2434 { "(bad)", { XX } },
2435 { "(bad)", { XX } },
2436 { "(bad)", { XX } },
2437 { "(bad)", { XX } },
2438 { "(bad)", { XX } },
2439 { "(bad)", { XX } },
2441 { "(bad)", { XX } },
2442 { "(bad)", { XX } },
2443 { "(bad)", { XX } },
2444 { "(bad)", { XX } },
2445 { "(bad)", { XX } },
2446 { "(bad)", { XX } },
2447 { "(bad)", { XX } },
2448 { "(bad)", { XX } },
2450 { "(bad)", { XX } },
2451 { "(bad)", { XX } },
2452 { "(bad)", { XX } },
2453 { "(bad)", { XX } },
2454 { "(bad)", { XX } },
2455 { "(bad)", { XX } },
2456 { "(bad)", { XX } },
2457 { "(bad)", { XX } },
2459 { "(bad)", { XX } },
2460 { "(bad)", { XX } },
2461 { "(bad)", { XX } },
2462 { "(bad)", { XX } },
2463 { "(bad)", { XX } },
2464 { "(bad)", { XX } },
2465 { "(bad)", { XX } },
2466 { "(bad)", { XX } },
2468 { "(bad)", { XX } },
2469 { "(bad)", { XX } },
2470 { "(bad)", { XX } },
2471 { "(bad)", { XX } },
2472 { "(bad)", { XX } },
2473 { "(bad)", { XX } },
2474 { "(bad)", { XX } },
2475 { "(bad)", { XX } },
2477 { "(bad)", { XX } },
2478 { "(bad)", { XX } },
2479 { "(bad)", { XX } },
2480 { "(bad)", { XX } },
2481 { "(bad)", { XX } },
2482 { "(bad)", { XX } },
2483 { "(bad)", { XX } },
2484 { "(bad)", { XX } },
2486 { "(bad)", { XX } },
2487 { "(bad)", { XX } },
2488 { "(bad)", { XX } },
2489 { "(bad)", { XX } },
2490 { "(bad)", { XX } },
2491 { "(bad)", { XX } },
2492 { "(bad)", { XX } },
2493 { "(bad)", { XX } },
2495 { "(bad)", { XX } },
2496 { "(bad)", { XX } },
2497 { "(bad)", { XX } },
2498 { "(bad)", { XX } },
2499 { "(bad)", { XX } },
2500 { "(bad)", { XX } },
2501 { "(bad)", { XX } },
2502 { "(bad)", { XX } },
2504 { "(bad)", { XX } },
2505 { "(bad)", { XX } },
2506 { "(bad)", { XX } },
2507 { "(bad)", { XX } },
2508 { "(bad)", { XX } },
2509 { "(bad)", { XX } },
2510 { "(bad)", { XX } },
2511 { "(bad)", { XX } },
2513 { "(bad)", { XX } },
2514 { "(bad)", { XX } },
2515 { "(bad)", { XX } },
2516 { "(bad)", { XX } },
2517 { "(bad)", { XX } },
2518 { "(bad)", { XX } },
2519 { "(bad)", { XX } },
2520 { "(bad)", { XX } },
2522 { "(bad)", { XX } },
2523 { "(bad)", { XX } },
2524 { "(bad)", { XX } },
2525 { "(bad)", { XX } },
2526 { "(bad)", { XX } },
2527 { "(bad)", { XX } },
2528 { "(bad)", { XX } },
2529 { "(bad)", { XX } },
2531 { "(bad)", { XX } },
2532 { "(bad)", { XX } },
2533 { "(bad)", { XX } },
2534 { "(bad)", { XX } },
2535 { "(bad)", { XX } },
2536 { "(bad)", { XX } },
2537 { "(bad)", { XX } },
2538 { "(bad)", { XX } },
2540 { "(bad)", { XX } },
2541 { "(bad)", { XX } },
2542 { "(bad)", { XX } },
2543 { "(bad)", { XX } },
2544 { "(bad)", { XX } },
2545 { "(bad)", { XX } },
2546 { "(bad)", { XX } },
2547 { "(bad)", { XX } },
2549 { "(bad)", { XX } },
2550 { "(bad)", { XX } },
2551 { "(bad)", { XX } },
2552 { "(bad)", { XX } },
2553 { "(bad)", { XX } },
2554 { "(bad)", { XX } },
2555 { "(bad)", { XX } },
2556 { "(bad)", { XX } },
2558 { "(bad)", { XX } },
2559 { "(bad)", { XX } },
2560 { "(bad)", { XX } },
2561 { "(bad)", { XX } },
2562 { "(bad)", { XX } },
2563 { "(bad)", { XX } },
2564 { "(bad)", { XX } },
2565 { "(bad)", { XX } },
2567 { "(bad)", { XX } },
2568 { "(bad)", { XX } },
2569 { "(bad)", { XX } },
2570 { "(bad)", { XX } },
2571 { "(bad)", { XX } },
2572 { "(bad)", { XX } },
2573 { "(bad)", { XX } },
2574 { "(bad)", { XX } },
2576 { "(bad)", { XX } },
2577 { "(bad)", { XX } },
2578 { "(bad)", { XX } },
2579 { "(bad)", { XX } },
2580 { "(bad)", { XX } },
2581 { "(bad)", { XX } },
2582 { "(bad)", { XX } },
2583 { "(bad)", { XX } },
2585 { "(bad)", { XX } },
2586 { "(bad)", { XX } },
2587 { "(bad)", { XX } },
2588 { "(bad)", { XX } },
2589 { "(bad)", { XX } },
2590 { "(bad)", { XX } },
2591 { "(bad)", { XX } },
2592 { "(bad)", { XX } },
2594 { "(bad)", { XX } },
2595 { "(bad)", { XX } },
2596 { "(bad)", { XX } },
2597 { "(bad)", { XX } },
2598 { "(bad)", { XX } },
2599 { "(bad)", { XX } },
2600 { "(bad)", { XX } },
2601 { "(bad)", { XX } },
2603 { "(bad)", { XX } },
2604 { "(bad)", { XX } },
2605 { "(bad)", { XX } },
2606 { "(bad)", { XX } },
2607 { "(bad)", { XX } },
2608 { "(bad)", { XX } },
2609 { "(bad)", { XX } },
2610 { "(bad)", { XX } },
2612 { "(bad)", { XX } },
2613 { "(bad)", { XX } },
2614 { "(bad)", { XX } },
2615 { "(bad)", { XX } },
2616 { "(bad)", { XX } },
2617 { "(bad)", { XX } },
2618 { "(bad)", { XX } },
2619 { "(bad)", { XX } },
2621 { "(bad)", { XX } },
2622 { "(bad)", { XX } },
2623 { "(bad)", { XX } },
2624 { "(bad)", { XX } },
2625 { "(bad)", { XX } },
2626 { "(bad)", { XX } },
2627 { "(bad)", { XX } },
2628 { "(bad)", { XX } },
2630 { "(bad)", { XX } },
2631 { "(bad)", { XX } },
2632 { "(bad)", { XX } },
2633 { "(bad)", { XX } },
2634 { "(bad)", { XX } },
2635 { "(bad)", { XX } },
2636 { "(bad)", { XX } },
2637 { "(bad)", { XX } },
2639 { "(bad)", { XX } },
2640 { "(bad)", { XX } },
2641 { "(bad)", { XX } },
2642 { "(bad)", { XX } },
2643 { "(bad)", { XX } },
2644 { "(bad)", { XX } },
2645 { "(bad)", { XX } },
2646 { "(bad)", { XX } },
2650 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
2662 FETCH_DATA (the_info, codep + 1);
2666 /* REX prefixes family. */
2683 if (address_mode == mode_64bit)
2689 prefixes |= PREFIX_REPZ;
2692 prefixes |= PREFIX_REPNZ;
2695 prefixes |= PREFIX_LOCK;
2698 prefixes |= PREFIX_CS;
2701 prefixes |= PREFIX_SS;
2704 prefixes |= PREFIX_DS;
2707 prefixes |= PREFIX_ES;
2710 prefixes |= PREFIX_FS;
2713 prefixes |= PREFIX_GS;
2716 prefixes |= PREFIX_DATA;
2719 prefixes |= PREFIX_ADDR;
2722 /* fwait is really an instruction. If there are prefixes
2723 before the fwait, they belong to the fwait, *not* to the
2724 following instruction. */
2725 if (prefixes || rex)
2727 prefixes |= PREFIX_FWAIT;
2731 prefixes = PREFIX_FWAIT;
2736 /* Rex is ignored when followed by another prefix. */
2747 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
2751 prefix_name (int pref, int sizeflag)
2753 static const char *rexes [16] =
2758 "rex.XB", /* 0x43 */
2760 "rex.RB", /* 0x45 */
2761 "rex.RX", /* 0x46 */
2762 "rex.RXB", /* 0x47 */
2764 "rex.WB", /* 0x49 */
2765 "rex.WX", /* 0x4a */
2766 "rex.WXB", /* 0x4b */
2767 "rex.WR", /* 0x4c */
2768 "rex.WRB", /* 0x4d */
2769 "rex.WRX", /* 0x4e */
2770 "rex.WRXB", /* 0x4f */
2775 /* REX prefixes family. */
2792 return rexes [pref - 0x40];
2812 return (sizeflag & DFLAG) ? "data16" : "data32";
2814 if (address_mode == mode_64bit)
2815 return (sizeflag & AFLAG) ? "addr32" : "addr64";
2817 return (sizeflag & AFLAG) ? "addr16" : "addr32";
2825 static char op_out[MAX_OPERANDS][100];
2826 static int op_ad, op_index[MAX_OPERANDS];
2827 static int two_source_ops;
2828 static bfd_vma op_address[MAX_OPERANDS];
2829 static bfd_vma op_riprel[MAX_OPERANDS];
2830 static bfd_vma start_pc;
2833 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
2834 * (see topic "Redundant prefixes" in the "Differences from 8086"
2835 * section of the "Virtual 8086 Mode" chapter.)
2836 * 'pc' should be the address of this instruction, it will
2837 * be used to print the target address if this is a relative jump or call
2838 * The function returns the length of this instruction in bytes.
2841 static char intel_syntax;
2842 static char open_char;
2843 static char close_char;
2844 static char separator_char;
2845 static char scale_char;
2847 /* Here for backwards compatibility. When gdb stops using
2848 print_insn_i386_att and print_insn_i386_intel these functions can
2849 disappear, and print_insn_i386 be merged into print_insn. */
2851 print_insn_i386_att (bfd_vma pc, disassemble_info *info)
2855 return print_insn (pc, info);
2859 print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
2863 return print_insn (pc, info);
2867 print_insn_i386 (bfd_vma pc, disassemble_info *info)
2871 return print_insn (pc, info);
2875 print_i386_disassembler_options (FILE *stream)
2877 fprintf (stream, _("\n\
2878 The following i386/x86-64 specific disassembler options are supported for use\n\
2879 with the -M switch (multiple options should be separated by commas):\n"));
2881 fprintf (stream, _(" x86-64 Disassemble in 64bit mode\n"));
2882 fprintf (stream, _(" i386 Disassemble in 32bit mode\n"));
2883 fprintf (stream, _(" i8086 Disassemble in 16bit mode\n"));
2884 fprintf (stream, _(" att Display instruction in AT&T syntax\n"));
2885 fprintf (stream, _(" intel Display instruction in Intel syntax\n"));
2886 fprintf (stream, _(" addr64 Assume 64bit address size\n"));
2887 fprintf (stream, _(" addr32 Assume 32bit address size\n"));
2888 fprintf (stream, _(" addr16 Assume 16bit address size\n"));
2889 fprintf (stream, _(" data32 Assume 32bit data size\n"));
2890 fprintf (stream, _(" data16 Assume 16bit data size\n"));
2891 fprintf (stream, _(" suffix Always display instruction suffix in AT&T syntax\n"));
2895 print_insn (bfd_vma pc, disassemble_info *info)
2897 const struct dis386 *dp;
2899 char *op_txt[MAX_OPERANDS];
2901 unsigned char uses_DATA_prefix, uses_LOCK_prefix;
2902 unsigned char uses_REPNZ_prefix, uses_REPZ_prefix;
2905 struct dis_private priv;
2908 if (info->mach == bfd_mach_x86_64_intel_syntax
2909 || info->mach == bfd_mach_x86_64)
2910 address_mode = mode_64bit;
2912 address_mode = mode_32bit;
2914 if (intel_syntax == (char) -1)
2915 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
2916 || info->mach == bfd_mach_x86_64_intel_syntax);
2918 if (info->mach == bfd_mach_i386_i386
2919 || info->mach == bfd_mach_x86_64
2920 || info->mach == bfd_mach_i386_i386_intel_syntax
2921 || info->mach == bfd_mach_x86_64_intel_syntax)
2922 priv.orig_sizeflag = AFLAG | DFLAG;
2923 else if (info->mach == bfd_mach_i386_i8086)
2924 priv.orig_sizeflag = 0;
2928 for (p = info->disassembler_options; p != NULL; )
2930 if (CONST_STRNEQ (p, "x86-64"))
2932 address_mode = mode_64bit;
2933 priv.orig_sizeflag = AFLAG | DFLAG;
2935 else if (CONST_STRNEQ (p, "i386"))
2937 address_mode = mode_32bit;
2938 priv.orig_sizeflag = AFLAG | DFLAG;
2940 else if (CONST_STRNEQ (p, "i8086"))
2942 address_mode = mode_16bit;
2943 priv.orig_sizeflag = 0;
2945 else if (CONST_STRNEQ (p, "intel"))
2949 else if (CONST_STRNEQ (p, "att"))
2953 else if (CONST_STRNEQ (p, "addr"))
2955 if (address_mode == mode_64bit)
2957 if (p[4] == '3' && p[5] == '2')
2958 priv.orig_sizeflag &= ~AFLAG;
2959 else if (p[4] == '6' && p[5] == '4')
2960 priv.orig_sizeflag |= AFLAG;
2964 if (p[4] == '1' && p[5] == '6')
2965 priv.orig_sizeflag &= ~AFLAG;
2966 else if (p[4] == '3' && p[5] == '2')
2967 priv.orig_sizeflag |= AFLAG;
2970 else if (CONST_STRNEQ (p, "data"))
2972 if (p[4] == '1' && p[5] == '6')
2973 priv.orig_sizeflag &= ~DFLAG;
2974 else if (p[4] == '3' && p[5] == '2')
2975 priv.orig_sizeflag |= DFLAG;
2977 else if (CONST_STRNEQ (p, "suffix"))
2978 priv.orig_sizeflag |= SUFFIX_ALWAYS;
2980 p = strchr (p, ',');
2987 names64 = intel_names64;
2988 names32 = intel_names32;
2989 names16 = intel_names16;
2990 names8 = intel_names8;
2991 names8rex = intel_names8rex;
2992 names_seg = intel_names_seg;
2993 index16 = intel_index16;
2996 separator_char = '+';
3001 names64 = att_names64;
3002 names32 = att_names32;
3003 names16 = att_names16;
3004 names8 = att_names8;
3005 names8rex = att_names8rex;
3006 names_seg = att_names_seg;
3007 index16 = att_index16;
3010 separator_char = ',';
3014 /* The output looks better if we put 7 bytes on a line, since that
3015 puts most long word instructions on a single line. */
3016 info->bytes_per_line = 7;
3018 info->private_data = &priv;
3019 priv.max_fetched = priv.the_buffer;
3020 priv.insn_start = pc;
3023 for (i = 0; i < MAX_OPERANDS; ++i)
3031 start_codep = priv.the_buffer;
3032 codep = priv.the_buffer;
3034 if (setjmp (priv.bailout) != 0)
3038 /* Getting here means we tried for data but didn't get it. That
3039 means we have an incomplete instruction of some sort. Just
3040 print the first byte as a prefix or a .byte pseudo-op. */
3041 if (codep > priv.the_buffer)
3043 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3045 (*info->fprintf_func) (info->stream, "%s", name);
3048 /* Just print the first byte as a .byte instruction. */
3049 (*info->fprintf_func) (info->stream, ".byte 0x%x",
3050 (unsigned int) priv.the_buffer[0]);
3063 sizeflag = priv.orig_sizeflag;
3065 FETCH_DATA (info, codep + 1);
3066 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
3068 if (((prefixes & PREFIX_FWAIT)
3069 && ((*codep < 0xd8) || (*codep > 0xdf)))
3070 || (rex && rex_used))
3074 /* fwait not followed by floating point instruction, or rex followed
3075 by other prefixes. Print the first prefix. */
3076 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3078 name = INTERNAL_DISASSEMBLER_ERROR;
3079 (*info->fprintf_func) (info->stream, "%s", name);
3086 unsigned char threebyte;
3087 FETCH_DATA (info, codep + 2);
3088 threebyte = *++codep;
3089 dp = &dis386_twobyte[threebyte];
3090 need_modrm = twobyte_has_modrm[*codep];
3091 uses_DATA_prefix = twobyte_uses_DATA_prefix[*codep];
3092 uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[*codep];
3093 uses_REPZ_prefix = twobyte_uses_REPZ_prefix[*codep];
3094 uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
3096 if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
3098 FETCH_DATA (info, codep + 2);
3103 uses_DATA_prefix = threebyte_0x38_uses_DATA_prefix[op];
3104 uses_REPNZ_prefix = threebyte_0x38_uses_REPNZ_prefix[op];
3105 uses_REPZ_prefix = threebyte_0x38_uses_REPZ_prefix[op];
3108 uses_DATA_prefix = threebyte_0x3a_uses_DATA_prefix[op];
3109 uses_REPNZ_prefix = threebyte_0x3a_uses_REPNZ_prefix[op];
3110 uses_REPZ_prefix = threebyte_0x3a_uses_REPZ_prefix[op];
3119 dp = &dis386[*codep];
3120 need_modrm = onebyte_has_modrm[*codep];
3121 uses_DATA_prefix = 0;
3122 uses_REPNZ_prefix = 0;
3123 /* pause is 0xf3 0x90. */
3124 uses_REPZ_prefix = *codep == 0x90;
3125 uses_LOCK_prefix = 0;
3129 if (!uses_REPZ_prefix && (prefixes & PREFIX_REPZ))
3132 used_prefixes |= PREFIX_REPZ;
3134 if (!uses_REPNZ_prefix && (prefixes & PREFIX_REPNZ))
3137 used_prefixes |= PREFIX_REPNZ;
3140 if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
3143 used_prefixes |= PREFIX_LOCK;
3146 if (prefixes & PREFIX_ADDR)
3149 if (dp->op[2].bytemode != loop_jcxz_mode || intel_syntax)
3151 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
3152 oappend ("addr32 ");
3154 oappend ("addr16 ");
3155 used_prefixes |= PREFIX_ADDR;
3159 if (!uses_DATA_prefix && (prefixes & PREFIX_DATA))
3162 if (dp->op[2].bytemode == cond_jump_mode
3163 && dp->op[0].bytemode == v_mode
3166 if (sizeflag & DFLAG)
3167 oappend ("data32 ");
3169 oappend ("data16 ");
3170 used_prefixes |= PREFIX_DATA;
3174 if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
3176 dp = &three_byte_table[dp->op[1].bytemode][op];
3177 modrm.mod = (*codep >> 6) & 3;
3178 modrm.reg = (*codep >> 3) & 7;
3179 modrm.rm = *codep & 7;
3181 else if (need_modrm)
3183 FETCH_DATA (info, codep + 1);
3184 modrm.mod = (*codep >> 6) & 3;
3185 modrm.reg = (*codep >> 3) & 7;
3186 modrm.rm = *codep & 7;
3189 if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE)
3196 if (dp->name == NULL)
3198 switch (dp->op[0].bytemode)
3201 dp = &grps[dp->op[1].bytemode][modrm.reg];
3204 case USE_PREFIX_USER_TABLE:
3206 used_prefixes |= (prefixes & PREFIX_REPZ);
3207 if (prefixes & PREFIX_REPZ)
3211 /* We should check PREFIX_REPNZ and PREFIX_REPZ
3212 before PREFIX_DATA. */
3213 used_prefixes |= (prefixes & PREFIX_REPNZ);
3214 if (prefixes & PREFIX_REPNZ)
3218 used_prefixes |= (prefixes & PREFIX_DATA);
3219 if (prefixes & PREFIX_DATA)
3223 dp = &prefix_user_table[dp->op[1].bytemode][index];
3226 case X86_64_SPECIAL:
3227 index = address_mode == mode_64bit ? 1 : 0;
3228 dp = &x86_64_table[dp->op[1].bytemode][index];
3232 oappend (INTERNAL_DISASSEMBLER_ERROR);
3237 if (putop (dp->name, sizeflag) == 0)
3239 for (i = 0; i < MAX_OPERANDS; ++i)
3242 op_ad = MAX_OPERANDS - 1 - i;
3244 (*dp->op[i].rtn) (dp->op[i].bytemode, sizeflag);
3249 /* See if any prefixes were not used. If so, print the first one
3250 separately. If we don't do this, we'll wind up printing an
3251 instruction stream which does not precisely correspond to the
3252 bytes we are disassembling. */
3253 if ((prefixes & ~used_prefixes) != 0)
3257 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3259 name = INTERNAL_DISASSEMBLER_ERROR;
3260 (*info->fprintf_func) (info->stream, "%s", name);
3263 if (rex & ~rex_used)
3266 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
3268 name = INTERNAL_DISASSEMBLER_ERROR;
3269 (*info->fprintf_func) (info->stream, "%s ", name);
3272 obufp = obuf + strlen (obuf);
3273 for (i = strlen (obuf); i < 6; i++)
3276 (*info->fprintf_func) (info->stream, "%s", obuf);
3278 /* The enter and bound instructions are printed with operands in the same
3279 order as the intel book; everything else is printed in reverse order. */
3280 if (intel_syntax || two_source_ops)
3282 for (i = 0; i < MAX_OPERANDS; ++i)
3283 op_txt[i] = op_out[i];
3285 for (i = 0; i < (MAX_OPERANDS >> 1); ++i)
3287 op_ad = op_index[i];
3288 op_index[i] = op_index[MAX_OPERANDS - 1 - i];
3289 op_index[MAX_OPERANDS - 1 - i] = op_ad;
3294 for (i = 0; i < MAX_OPERANDS; ++i)
3295 op_txt[MAX_OPERANDS - 1 - i] = op_out[i];
3299 for (i = 0; i < MAX_OPERANDS; ++i)
3303 (*info->fprintf_func) (info->stream, ",");
3304 if (op_index[i] != -1 && !op_riprel[i])
3305 (*info->print_address_func) ((bfd_vma) op_address[op_index[i]], info);
3307 (*info->fprintf_func) (info->stream, "%s", op_txt[i]);
3311 for (i = 0; i < MAX_OPERANDS; i++)
3312 if (op_index[i] != -1 && op_riprel[i])
3314 (*info->fprintf_func) (info->stream, " # ");
3315 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
3316 + op_address[op_index[i]]), info);
3318 return codep - priv.the_buffer;
3321 static const char *float_mem[] = {
3396 static const unsigned char float_mem_mode[] = {
3471 #define ST { OP_ST, 0 }
3472 #define STi { OP_STi, 0 }
3474 #define FGRPd9_2 NULL, { { NULL, 0 } }
3475 #define FGRPd9_4 NULL, { { NULL, 1 } }
3476 #define FGRPd9_5 NULL, { { NULL, 2 } }
3477 #define FGRPd9_6 NULL, { { NULL, 3 } }
3478 #define FGRPd9_7 NULL, { { NULL, 4 } }
3479 #define FGRPda_5 NULL, { { NULL, 5 } }
3480 #define FGRPdb_4 NULL, { { NULL, 6 } }
3481 #define FGRPde_3 NULL, { { NULL, 7 } }
3482 #define FGRPdf_4 NULL, { { NULL, 8 } }
3484 static const struct dis386 float_reg[][8] = {
3487 { "fadd", { ST, STi } },
3488 { "fmul", { ST, STi } },
3489 { "fcom", { STi } },
3490 { "fcomp", { STi } },
3491 { "fsub", { ST, STi } },
3492 { "fsubr", { ST, STi } },
3493 { "fdiv", { ST, STi } },
3494 { "fdivr", { ST, STi } },
3499 { "fxch", { STi } },
3501 { "(bad)", { XX } },
3509 { "fcmovb", { ST, STi } },
3510 { "fcmove", { ST, STi } },
3511 { "fcmovbe",{ ST, STi } },
3512 { "fcmovu", { ST, STi } },
3513 { "(bad)", { XX } },
3515 { "(bad)", { XX } },
3516 { "(bad)", { XX } },
3520 { "fcmovnb",{ ST, STi } },
3521 { "fcmovne",{ ST, STi } },
3522 { "fcmovnbe",{ ST, STi } },
3523 { "fcmovnu",{ ST, STi } },
3525 { "fucomi", { ST, STi } },
3526 { "fcomi", { ST, STi } },
3527 { "(bad)", { XX } },
3531 { "fadd", { STi, ST } },
3532 { "fmul", { STi, ST } },
3533 { "(bad)", { XX } },
3534 { "(bad)", { XX } },
3536 { "fsub", { STi, ST } },
3537 { "fsubr", { STi, ST } },
3538 { "fdiv", { STi, ST } },
3539 { "fdivr", { STi, ST } },
3541 { "fsubr", { STi, ST } },
3542 { "fsub", { STi, ST } },
3543 { "fdivr", { STi, ST } },
3544 { "fdiv", { STi, ST } },
3549 { "ffree", { STi } },
3550 { "(bad)", { XX } },
3552 { "fstp", { STi } },
3553 { "fucom", { STi } },
3554 { "fucomp", { STi } },
3555 { "(bad)", { XX } },
3556 { "(bad)", { XX } },
3560 { "faddp", { STi, ST } },
3561 { "fmulp", { STi, ST } },
3562 { "(bad)", { XX } },
3565 { "fsubp", { STi, ST } },
3566 { "fsubrp", { STi, ST } },
3567 { "fdivp", { STi, ST } },
3568 { "fdivrp", { STi, ST } },
3570 { "fsubrp", { STi, ST } },
3571 { "fsubp", { STi, ST } },
3572 { "fdivrp", { STi, ST } },
3573 { "fdivp", { STi, ST } },
3578 { "ffreep", { STi } },
3579 { "(bad)", { XX } },
3580 { "(bad)", { XX } },
3581 { "(bad)", { XX } },
3583 { "fucomip", { ST, STi } },
3584 { "fcomip", { ST, STi } },
3585 { "(bad)", { XX } },
3589 static char *fgrps[][8] = {
3592 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3597 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
3602 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
3607 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
3612 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
3617 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3622 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
3623 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
3628 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3633 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3638 dofloat (int sizeflag)
3640 const struct dis386 *dp;
3641 unsigned char floatop;
3643 floatop = codep[-1];
3647 int fp_indx = (floatop - 0xd8) * 8 + modrm.reg;
3649 putop (float_mem[fp_indx], sizeflag);
3652 OP_E (float_mem_mode[fp_indx], sizeflag);
3655 /* Skip mod/rm byte. */
3659 dp = &float_reg[floatop - 0xd8][modrm.reg];
3660 if (dp->name == NULL)
3662 putop (fgrps[dp->op[0].bytemode][modrm.rm], sizeflag);
3664 /* Instruction fnstsw is only one with strange arg. */
3665 if (floatop == 0xdf && codep[-1] == 0xe0)
3666 strcpy (op_out[0], names16[0]);
3670 putop (dp->name, sizeflag);
3675 (*dp->op[0].rtn) (dp->op[0].bytemode, sizeflag);
3680 (*dp->op[1].rtn) (dp->op[1].bytemode, sizeflag);
3685 OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3687 oappend ("%st" + intel_syntax);
3691 OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3693 sprintf (scratchbuf, "%%st(%d)", modrm.rm);
3694 oappend (scratchbuf + intel_syntax);
3697 /* Capital letters in template are macros. */
3699 putop (const char *template, int sizeflag)
3704 for (p = template; *p; p++)
3715 if (address_mode == mode_64bit)
3723 /* Alternative not valid. */
3724 strcpy (obuf, "(bad)");
3728 else if (*p == '\0')
3749 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
3755 if (sizeflag & SUFFIX_ALWAYS)
3759 if (intel_syntax && !alt)
3761 if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
3763 if (sizeflag & DFLAG)
3764 *obufp++ = intel_syntax ? 'd' : 'l';
3766 *obufp++ = intel_syntax ? 'w' : 's';
3767 used_prefixes |= (prefixes & PREFIX_DATA);
3771 if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
3778 else if (sizeflag & DFLAG)
3779 *obufp++ = intel_syntax ? 'd' : 'l';
3782 used_prefixes |= (prefixes & PREFIX_DATA);
3787 case 'E': /* For jcxz/jecxz */
3788 if (address_mode == mode_64bit)
3790 if (sizeflag & AFLAG)
3796 if (sizeflag & AFLAG)
3798 used_prefixes |= (prefixes & PREFIX_ADDR);
3803 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
3805 if (sizeflag & AFLAG)
3806 *obufp++ = address_mode == mode_64bit ? 'q' : 'l';
3808 *obufp++ = address_mode == mode_64bit ? 'l' : 'w';
3809 used_prefixes |= (prefixes & PREFIX_ADDR);
3813 if (intel_syntax || (obufp[-1] != 's' && !(sizeflag & SUFFIX_ALWAYS)))
3815 if ((rex & REX_W) || (sizeflag & DFLAG))
3820 used_prefixes |= (prefixes & PREFIX_DATA);
3825 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
3826 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
3828 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
3831 if (prefixes & PREFIX_DS)
3845 if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS))
3854 if (sizeflag & SUFFIX_ALWAYS)
3858 if ((prefixes & PREFIX_FWAIT) == 0)
3861 used_prefixes |= PREFIX_FWAIT;
3867 else if (intel_syntax && (sizeflag & DFLAG))
3872 used_prefixes |= (prefixes & PREFIX_DATA);
3877 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3886 if ((prefixes & PREFIX_DATA)
3888 || (sizeflag & SUFFIX_ALWAYS))
3895 if (sizeflag & DFLAG)
3900 used_prefixes |= (prefixes & PREFIX_DATA);
3906 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3908 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
3914 if (intel_syntax && !alt)
3917 if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
3923 if (sizeflag & DFLAG)
3924 *obufp++ = intel_syntax ? 'd' : 'l';
3928 used_prefixes |= (prefixes & PREFIX_DATA);
3935 else if (sizeflag & DFLAG)
3944 if (intel_syntax && !p[1]
3945 && ((rex & REX_W) || (sizeflag & DFLAG)))
3948 used_prefixes |= (prefixes & PREFIX_DATA);
3953 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3955 if (sizeflag & SUFFIX_ALWAYS)
3963 if (sizeflag & SUFFIX_ALWAYS)
3969 if (sizeflag & DFLAG)
3973 used_prefixes |= (prefixes & PREFIX_DATA);
3978 if (prefixes & PREFIX_DATA)
3982 used_prefixes |= (prefixes & PREFIX_DATA);
3993 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
3995 /* operand size flag for cwtl, cbtw */
4004 else if (sizeflag & DFLAG)
4009 used_prefixes |= (prefixes & PREFIX_DATA);
4019 oappend (const char *s)
4022 obufp += strlen (s);
4028 if (prefixes & PREFIX_CS)
4030 used_prefixes |= PREFIX_CS;
4031 oappend ("%cs:" + intel_syntax);
4033 if (prefixes & PREFIX_DS)
4035 used_prefixes |= PREFIX_DS;
4036 oappend ("%ds:" + intel_syntax);
4038 if (prefixes & PREFIX_SS)
4040 used_prefixes |= PREFIX_SS;
4041 oappend ("%ss:" + intel_syntax);
4043 if (prefixes & PREFIX_ES)
4045 used_prefixes |= PREFIX_ES;
4046 oappend ("%es:" + intel_syntax);
4048 if (prefixes & PREFIX_FS)
4050 used_prefixes |= PREFIX_FS;
4051 oappend ("%fs:" + intel_syntax);
4053 if (prefixes & PREFIX_GS)
4055 used_prefixes |= PREFIX_GS;
4056 oappend ("%gs:" + intel_syntax);
4061 OP_indirE (int bytemode, int sizeflag)
4065 OP_E (bytemode, sizeflag);
4069 print_operand_value (char *buf, int hex, bfd_vma disp)
4071 if (address_mode == mode_64bit)
4079 sprintf_vma (tmp, disp);
4080 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
4081 strcpy (buf + 2, tmp + i);
4085 bfd_signed_vma v = disp;
4092 /* Check for possible overflow on 0x8000000000000000. */
4095 strcpy (buf, "9223372036854775808");
4109 tmp[28 - i] = (v % 10) + '0';
4113 strcpy (buf, tmp + 29 - i);
4119 sprintf (buf, "0x%x", (unsigned int) disp);
4121 sprintf (buf, "%d", (int) disp);
4126 intel_operand_size (int bytemode, int sizeflag)
4131 oappend ("BYTE PTR ");
4135 oappend ("WORD PTR ");
4138 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4140 oappend ("QWORD PTR ");
4141 used_prefixes |= (prefixes & PREFIX_DATA);
4149 oappend ("QWORD PTR ");
4150 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
4151 oappend ("DWORD PTR ");
4153 oappend ("WORD PTR ");
4154 used_prefixes |= (prefixes & PREFIX_DATA);
4157 if ((rex & REX_W) || (sizeflag & DFLAG))
4159 oappend ("WORD PTR ");
4161 used_prefixes |= (prefixes & PREFIX_DATA);
4164 oappend ("DWORD PTR ");
4167 oappend ("QWORD PTR ");
4170 if (address_mode == mode_64bit)
4171 oappend ("QWORD PTR ");
4173 oappend ("DWORD PTR ");
4176 if (sizeflag & DFLAG)
4177 oappend ("FWORD PTR ");
4179 oappend ("DWORD PTR ");
4180 used_prefixes |= (prefixes & PREFIX_DATA);
4183 oappend ("TBYTE PTR ");
4186 oappend ("XMMWORD PTR ");
4189 oappend ("OWORD PTR ");
4197 OP_E (int bytemode, int sizeflag)
4206 /* Skip mod/rm byte. */
4217 oappend (names8rex[modrm.rm + add]);
4219 oappend (names8[modrm.rm + add]);
4222 oappend (names16[modrm.rm + add]);
4225 oappend (names32[modrm.rm + add]);
4228 oappend (names64[modrm.rm + add]);
4231 if (address_mode == mode_64bit)
4232 oappend (names64[modrm.rm + add]);
4234 oappend (names32[modrm.rm + add]);
4237 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4239 oappend (names64[modrm.rm + add]);
4240 used_prefixes |= (prefixes & PREFIX_DATA);
4250 oappend (names64[modrm.rm + add]);
4251 else if ((sizeflag & DFLAG) || bytemode != v_mode)
4252 oappend (names32[modrm.rm + add]);
4254 oappend (names16[modrm.rm + add]);
4255 used_prefixes |= (prefixes & PREFIX_DATA);
4260 oappend (INTERNAL_DISASSEMBLER_ERROR);
4268 intel_operand_size (bytemode, sizeflag);
4271 if ((sizeflag & AFLAG) || address_mode == mode_64bit) /* 32 bit address mode */
4286 FETCH_DATA (the_info, codep + 1);
4287 index = (*codep >> 3) & 7;
4288 if (address_mode == mode_64bit || index != 0x4)
4289 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
4290 scale = (*codep >> 6) & 3;
4302 if ((base & 7) == 5)
4305 if (address_mode == mode_64bit && !havesib)
4311 FETCH_DATA (the_info, codep + 1);
4313 if ((disp & 0x80) != 0)
4322 if (modrm.mod != 0 || (base & 7) == 5)
4324 print_operand_value (scratchbuf, !riprel, disp);
4325 oappend (scratchbuf);
4333 if (havebase || (havesib && (index != 4 || scale != 0)))
4335 *obufp++ = open_char;
4336 if (intel_syntax && riprel)
4340 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
4341 ? names64[base] : names32[base]);
4346 if (!intel_syntax || havebase)
4348 *obufp++ = separator_char;
4351 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
4352 ? names64[index] : names32[index]);
4354 if (scale != 0 || (!intel_syntax && index != 4))
4356 *obufp++ = scale_char;
4358 sprintf (scratchbuf, "%d", 1 << scale);
4359 oappend (scratchbuf);
4362 if (intel_syntax && disp)
4364 if ((bfd_signed_vma) disp > 0)
4369 else if (modrm.mod != 1)
4373 disp = - (bfd_signed_vma) disp;
4376 print_operand_value (scratchbuf, modrm.mod != 1, disp);
4377 oappend (scratchbuf);
4380 *obufp++ = close_char;
4383 else if (intel_syntax)
4385 if (modrm.mod != 0 || (base & 7) == 5)
4387 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4388 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
4392 oappend (names_seg[ds_reg - es_reg]);
4395 print_operand_value (scratchbuf, 1, disp);
4396 oappend (scratchbuf);
4401 { /* 16 bit address mode */
4408 if ((disp & 0x8000) != 0)
4413 FETCH_DATA (the_info, codep + 1);
4415 if ((disp & 0x80) != 0)
4420 if ((disp & 0x8000) != 0)
4426 if (modrm.mod != 0 || modrm.rm == 6)
4428 print_operand_value (scratchbuf, 0, disp);
4429 oappend (scratchbuf);
4432 if (modrm.mod != 0 || modrm.rm != 6)
4434 *obufp++ = open_char;
4436 oappend (index16[modrm.rm]);
4437 if (intel_syntax && disp)
4439 if ((bfd_signed_vma) disp > 0)
4444 else if (modrm.mod != 1)
4448 disp = - (bfd_signed_vma) disp;
4451 print_operand_value (scratchbuf, modrm.mod != 1, disp);
4452 oappend (scratchbuf);
4455 *obufp++ = close_char;
4458 else if (intel_syntax)
4460 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4461 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
4465 oappend (names_seg[ds_reg - es_reg]);
4468 print_operand_value (scratchbuf, 1, disp & 0xffff);
4469 oappend (scratchbuf);
4475 OP_G (int bytemode, int sizeflag)
4486 oappend (names8rex[modrm.reg + add]);
4488 oappend (names8[modrm.reg + add]);
4491 oappend (names16[modrm.reg + add]);
4494 oappend (names32[modrm.reg + add]);
4497 oappend (names64[modrm.reg + add]);
4504 oappend (names64[modrm.reg + add]);
4505 else if ((sizeflag & DFLAG) || bytemode != v_mode)
4506 oappend (names32[modrm.reg + add]);
4508 oappend (names16[modrm.reg + add]);
4509 used_prefixes |= (prefixes & PREFIX_DATA);
4512 if (address_mode == mode_64bit)
4513 oappend (names64[modrm.reg + add]);
4515 oappend (names32[modrm.reg + add]);
4518 oappend (INTERNAL_DISASSEMBLER_ERROR);
4531 FETCH_DATA (the_info, codep + 8);
4532 a = *codep++ & 0xff;
4533 a |= (*codep++ & 0xff) << 8;
4534 a |= (*codep++ & 0xff) << 16;
4535 a |= (*codep++ & 0xff) << 24;
4536 b = *codep++ & 0xff;
4537 b |= (*codep++ & 0xff) << 8;
4538 b |= (*codep++ & 0xff) << 16;
4539 b |= (*codep++ & 0xff) << 24;
4540 x = a + ((bfd_vma) b << 32);
4548 static bfd_signed_vma
4551 bfd_signed_vma x = 0;
4553 FETCH_DATA (the_info, codep + 4);
4554 x = *codep++ & (bfd_signed_vma) 0xff;
4555 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
4556 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
4557 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
4561 static bfd_signed_vma
4564 bfd_signed_vma x = 0;
4566 FETCH_DATA (the_info, codep + 4);
4567 x = *codep++ & (bfd_signed_vma) 0xff;
4568 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
4569 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
4570 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
4572 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
4582 FETCH_DATA (the_info, codep + 2);
4583 x = *codep++ & 0xff;
4584 x |= (*codep++ & 0xff) << 8;
4589 set_op (bfd_vma op, int riprel)
4591 op_index[op_ad] = op_ad;
4592 if (address_mode == mode_64bit)
4594 op_address[op_ad] = op;
4595 op_riprel[op_ad] = riprel;
4599 /* Mask to get a 32-bit address. */
4600 op_address[op_ad] = op & 0xffffffff;
4601 op_riprel[op_ad] = riprel & 0xffffffff;
4606 OP_REG (int code, int sizeflag)
4616 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
4617 case sp_reg: case bp_reg: case si_reg: case di_reg:
4618 s = names16[code - ax_reg + add];
4620 case es_reg: case ss_reg: case cs_reg:
4621 case ds_reg: case fs_reg: case gs_reg:
4622 s = names_seg[code - es_reg + add];
4624 case al_reg: case ah_reg: case cl_reg: case ch_reg:
4625 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
4628 s = names8rex[code - al_reg + add];
4630 s = names8[code - al_reg];
4632 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
4633 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
4634 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4636 s = names64[code - rAX_reg + add];
4639 code += eAX_reg - rAX_reg;
4641 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
4642 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
4645 s = names64[code - eAX_reg + add];
4646 else if (sizeflag & DFLAG)
4647 s = names32[code - eAX_reg + add];
4649 s = names16[code - eAX_reg + add];
4650 used_prefixes |= (prefixes & PREFIX_DATA);
4653 s = INTERNAL_DISASSEMBLER_ERROR;
4660 OP_IMREG (int code, int sizeflag)
4672 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
4673 case sp_reg: case bp_reg: case si_reg: case di_reg:
4674 s = names16[code - ax_reg];
4676 case es_reg: case ss_reg: case cs_reg:
4677 case ds_reg: case fs_reg: case gs_reg:
4678 s = names_seg[code - es_reg];
4680 case al_reg: case ah_reg: case cl_reg: case ch_reg:
4681 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
4684 s = names8rex[code - al_reg];
4686 s = names8[code - al_reg];
4688 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
4689 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
4692 s = names64[code - eAX_reg];
4693 else if (sizeflag & DFLAG)
4694 s = names32[code - eAX_reg];
4696 s = names16[code - eAX_reg];
4697 used_prefixes |= (prefixes & PREFIX_DATA);
4700 if ((rex & REX_W) || (sizeflag & DFLAG))
4705 used_prefixes |= (prefixes & PREFIX_DATA);
4708 s = INTERNAL_DISASSEMBLER_ERROR;
4715 OP_I (int bytemode, int sizeflag)
4718 bfd_signed_vma mask = -1;
4723 FETCH_DATA (the_info, codep + 1);
4728 if (address_mode == mode_64bit)
4738 else if (sizeflag & DFLAG)
4748 used_prefixes |= (prefixes & PREFIX_DATA);
4759 oappend (INTERNAL_DISASSEMBLER_ERROR);
4764 scratchbuf[0] = '$';
4765 print_operand_value (scratchbuf + 1, 1, op);
4766 oappend (scratchbuf + intel_syntax);
4767 scratchbuf[0] = '\0';
4771 OP_I64 (int bytemode, int sizeflag)
4774 bfd_signed_vma mask = -1;
4776 if (address_mode != mode_64bit)
4778 OP_I (bytemode, sizeflag);
4785 FETCH_DATA (the_info, codep + 1);
4793 else if (sizeflag & DFLAG)
4803 used_prefixes |= (prefixes & PREFIX_DATA);
4810 oappend (INTERNAL_DISASSEMBLER_ERROR);
4815 scratchbuf[0] = '$';
4816 print_operand_value (scratchbuf + 1, 1, op);
4817 oappend (scratchbuf + intel_syntax);
4818 scratchbuf[0] = '\0';
4822 OP_sI (int bytemode, int sizeflag)
4825 bfd_signed_vma mask = -1;
4830 FETCH_DATA (the_info, codep + 1);
4832 if ((op & 0x80) != 0)
4840 else if (sizeflag & DFLAG)
4849 if ((op & 0x8000) != 0)
4852 used_prefixes |= (prefixes & PREFIX_DATA);
4857 if ((op & 0x8000) != 0)
4861 oappend (INTERNAL_DISASSEMBLER_ERROR);
4865 scratchbuf[0] = '$';
4866 print_operand_value (scratchbuf + 1, 1, op);
4867 oappend (scratchbuf + intel_syntax);
4871 OP_J (int bytemode, int sizeflag)
4875 bfd_vma segment = 0;
4880 FETCH_DATA (the_info, codep + 1);
4882 if ((disp & 0x80) != 0)
4886 if ((sizeflag & DFLAG) || (rex & REX_W))
4891 if ((disp & 0x8000) != 0)
4893 /* In 16bit mode, address is wrapped around at 64k within
4894 the same segment. Otherwise, a data16 prefix on a jump
4895 instruction means that the pc is masked to 16 bits after
4896 the displacement is added! */
4898 if ((prefixes & PREFIX_DATA) == 0)
4899 segment = ((start_pc + codep - start_codep)
4900 & ~((bfd_vma) 0xffff));
4902 used_prefixes |= (prefixes & PREFIX_DATA);
4905 oappend (INTERNAL_DISASSEMBLER_ERROR);
4908 disp = ((start_pc + codep - start_codep + disp) & mask) | segment;
4910 print_operand_value (scratchbuf, 1, disp);
4911 oappend (scratchbuf);
4915 OP_SEG (int bytemode, int sizeflag)
4917 if (bytemode == w_mode)
4918 oappend (names_seg[modrm.reg]);
4920 OP_E (modrm.mod == 3 ? bytemode : w_mode, sizeflag);
4924 OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
4928 if (sizeflag & DFLAG)
4938 used_prefixes |= (prefixes & PREFIX_DATA);
4940 sprintf (scratchbuf, "0x%x:0x%x", seg, offset);
4942 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
4943 oappend (scratchbuf);
4947 OP_OFF (int bytemode, int sizeflag)
4951 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
4952 intel_operand_size (bytemode, sizeflag);
4955 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
4962 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4963 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
4965 oappend (names_seg[ds_reg - es_reg]);
4969 print_operand_value (scratchbuf, 1, off);
4970 oappend (scratchbuf);
4974 OP_OFF64 (int bytemode, int sizeflag)
4978 if (address_mode != mode_64bit
4979 || (prefixes & PREFIX_ADDR))
4981 OP_OFF (bytemode, sizeflag);
4985 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
4986 intel_operand_size (bytemode, sizeflag);
4993 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4994 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
4996 oappend (names_seg[ds_reg - es_reg]);
5000 print_operand_value (scratchbuf, 1, off);
5001 oappend (scratchbuf);
5005 ptr_reg (int code, int sizeflag)
5009 *obufp++ = open_char;
5010 used_prefixes |= (prefixes & PREFIX_ADDR);
5011 if (address_mode == mode_64bit)
5013 if (!(sizeflag & AFLAG))
5014 s = names32[code - eAX_reg];
5016 s = names64[code - eAX_reg];
5018 else if (sizeflag & AFLAG)
5019 s = names32[code - eAX_reg];
5021 s = names16[code - eAX_reg];
5023 *obufp++ = close_char;
5028 OP_ESreg (int code, int sizeflag)
5034 case 0x6d: /* insw/insl */
5035 intel_operand_size (z_mode, sizeflag);
5037 case 0xa5: /* movsw/movsl/movsq */
5038 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5039 case 0xab: /* stosw/stosl */
5040 case 0xaf: /* scasw/scasl */
5041 intel_operand_size (v_mode, sizeflag);
5044 intel_operand_size (b_mode, sizeflag);
5047 oappend ("%es:" + intel_syntax);
5048 ptr_reg (code, sizeflag);
5052 OP_DSreg (int code, int sizeflag)
5058 case 0x6f: /* outsw/outsl */
5059 intel_operand_size (z_mode, sizeflag);
5061 case 0xa5: /* movsw/movsl/movsq */
5062 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5063 case 0xad: /* lodsw/lodsl/lodsq */
5064 intel_operand_size (v_mode, sizeflag);
5067 intel_operand_size (b_mode, sizeflag);
5077 prefixes |= PREFIX_DS;
5079 ptr_reg (code, sizeflag);
5083 OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5091 else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
5093 used_prefixes |= PREFIX_LOCK;
5096 sprintf (scratchbuf, "%%cr%d", modrm.reg + add);
5097 oappend (scratchbuf + intel_syntax);
5101 OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5108 sprintf (scratchbuf, "db%d", modrm.reg + add);
5110 sprintf (scratchbuf, "%%db%d", modrm.reg + add);
5111 oappend (scratchbuf);
5115 OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5117 sprintf (scratchbuf, "%%tr%d", modrm.reg);
5118 oappend (scratchbuf + intel_syntax);
5122 OP_R (int bytemode, int sizeflag)
5125 OP_E (bytemode, sizeflag);
5131 OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5133 used_prefixes |= (prefixes & PREFIX_DATA);
5134 if (prefixes & PREFIX_DATA)
5140 sprintf (scratchbuf, "%%xmm%d", modrm.reg + add);
5143 sprintf (scratchbuf, "%%mm%d", modrm.reg);
5144 oappend (scratchbuf + intel_syntax);
5148 OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5154 sprintf (scratchbuf, "%%xmm%d", modrm.reg + add);
5155 oappend (scratchbuf + intel_syntax);
5159 OP_EM (int bytemode, int sizeflag)
5163 if (intel_syntax && bytemode == v_mode)
5165 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
5166 used_prefixes |= (prefixes & PREFIX_DATA);
5168 OP_E (bytemode, sizeflag);
5172 /* Skip mod/rm byte. */
5175 used_prefixes |= (prefixes & PREFIX_DATA);
5176 if (prefixes & PREFIX_DATA)
5183 sprintf (scratchbuf, "%%xmm%d", modrm.rm + add);
5186 sprintf (scratchbuf, "%%mm%d", modrm.rm);
5187 oappend (scratchbuf + intel_syntax);
5190 /* cvt* are the only instructions in sse2 which have
5191 both SSE and MMX operands and also have 0x66 prefix
5192 in their opcode. 0x66 was originally used to differentiate
5193 between SSE and MMX instruction(operands). So we have to handle the
5194 cvt* separately using OP_EMC and OP_MXC */
5196 OP_EMC (int bytemode, int sizeflag)
5200 if (intel_syntax && bytemode == v_mode)
5202 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
5203 used_prefixes |= (prefixes & PREFIX_DATA);
5205 OP_E (bytemode, sizeflag);
5209 /* Skip mod/rm byte. */
5212 used_prefixes |= (prefixes & PREFIX_DATA);
5213 sprintf (scratchbuf, "%%mm%d", modrm.rm);
5214 oappend (scratchbuf + intel_syntax);
5218 OP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5220 used_prefixes |= (prefixes & PREFIX_DATA);
5221 sprintf (scratchbuf, "%%mm%d", modrm.reg);
5222 oappend (scratchbuf + intel_syntax);
5226 OP_EX (int bytemode, int sizeflag)
5231 if (intel_syntax && bytemode == v_mode)
5233 switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ))
5235 case 0: bytemode = x_mode; break;
5236 case PREFIX_REPZ: bytemode = d_mode; used_prefixes |= PREFIX_REPZ; break;
5237 case PREFIX_DATA: bytemode = x_mode; used_prefixes |= PREFIX_DATA; break;
5238 case PREFIX_REPNZ: bytemode = q_mode; used_prefixes |= PREFIX_REPNZ; break;
5239 default: bytemode = 0; break;
5242 OP_E (bytemode, sizeflag);
5249 /* Skip mod/rm byte. */
5252 sprintf (scratchbuf, "%%xmm%d", modrm.rm + add);
5253 oappend (scratchbuf + intel_syntax);
5257 OP_MS (int bytemode, int sizeflag)
5260 OP_EM (bytemode, sizeflag);
5266 OP_XS (int bytemode, int sizeflag)
5269 OP_EX (bytemode, sizeflag);
5275 OP_M (int bytemode, int sizeflag)
5278 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
5281 OP_E (bytemode, sizeflag);
5285 OP_0f07 (int bytemode, int sizeflag)
5287 if (modrm.mod != 3 || modrm.rm != 0)
5290 OP_E (bytemode, sizeflag);
5294 OP_0fae (int bytemode, int sizeflag)
5299 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
5301 if (modrm.reg < 5 || modrm.rm != 0)
5303 BadOp (); /* bad sfence, mfence, or lfence */
5307 else if (modrm.reg != 7)
5309 BadOp (); /* bad clflush */
5313 OP_E (bytemode, sizeflag);
5316 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
5317 32bit mode and "xchg %rax,%rax" in 64bit mode. */
5320 NOP_Fixup1 (int bytemode, int sizeflag)
5322 if ((prefixes & PREFIX_DATA) != 0
5325 && address_mode == mode_64bit))
5326 OP_REG (bytemode, sizeflag);
5328 strcpy (obuf, "nop");
5332 NOP_Fixup2 (int bytemode, int sizeflag)
5334 if ((prefixes & PREFIX_DATA) != 0
5337 && address_mode == mode_64bit))
5338 OP_IMREG (bytemode, sizeflag);
5341 static const char *const Suffix3DNow[] = {
5342 /* 00 */ NULL, NULL, NULL, NULL,
5343 /* 04 */ NULL, NULL, NULL, NULL,
5344 /* 08 */ NULL, NULL, NULL, NULL,
5345 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
5346 /* 10 */ NULL, NULL, NULL, NULL,
5347 /* 14 */ NULL, NULL, NULL, NULL,
5348 /* 18 */ NULL, NULL, NULL, NULL,
5349 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
5350 /* 20 */ NULL, NULL, NULL, NULL,
5351 /* 24 */ NULL, NULL, NULL, NULL,
5352 /* 28 */ NULL, NULL, NULL, NULL,
5353 /* 2C */ NULL, NULL, NULL, NULL,
5354 /* 30 */ NULL, NULL, NULL, NULL,
5355 /* 34 */ NULL, NULL, NULL, NULL,
5356 /* 38 */ NULL, NULL, NULL, NULL,
5357 /* 3C */ NULL, NULL, NULL, NULL,
5358 /* 40 */ NULL, NULL, NULL, NULL,
5359 /* 44 */ NULL, NULL, NULL, NULL,
5360 /* 48 */ NULL, NULL, NULL, NULL,
5361 /* 4C */ NULL, NULL, NULL, NULL,
5362 /* 50 */ NULL, NULL, NULL, NULL,
5363 /* 54 */ NULL, NULL, NULL, NULL,
5364 /* 58 */ NULL, NULL, NULL, NULL,
5365 /* 5C */ NULL, NULL, NULL, NULL,
5366 /* 60 */ NULL, NULL, NULL, NULL,
5367 /* 64 */ NULL, NULL, NULL, NULL,
5368 /* 68 */ NULL, NULL, NULL, NULL,
5369 /* 6C */ NULL, NULL, NULL, NULL,
5370 /* 70 */ NULL, NULL, NULL, NULL,
5371 /* 74 */ NULL, NULL, NULL, NULL,
5372 /* 78 */ NULL, NULL, NULL, NULL,
5373 /* 7C */ NULL, NULL, NULL, NULL,
5374 /* 80 */ NULL, NULL, NULL, NULL,
5375 /* 84 */ NULL, NULL, NULL, NULL,
5376 /* 88 */ NULL, NULL, "pfnacc", NULL,
5377 /* 8C */ NULL, NULL, "pfpnacc", NULL,
5378 /* 90 */ "pfcmpge", NULL, NULL, NULL,
5379 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
5380 /* 98 */ NULL, NULL, "pfsub", NULL,
5381 /* 9C */ NULL, NULL, "pfadd", NULL,
5382 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
5383 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
5384 /* A8 */ NULL, NULL, "pfsubr", NULL,
5385 /* AC */ NULL, NULL, "pfacc", NULL,
5386 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
5387 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
5388 /* B8 */ NULL, NULL, NULL, "pswapd",
5389 /* BC */ NULL, NULL, NULL, "pavgusb",
5390 /* C0 */ NULL, NULL, NULL, NULL,
5391 /* C4 */ NULL, NULL, NULL, NULL,
5392 /* C8 */ NULL, NULL, NULL, NULL,
5393 /* CC */ NULL, NULL, NULL, NULL,
5394 /* D0 */ NULL, NULL, NULL, NULL,
5395 /* D4 */ NULL, NULL, NULL, NULL,
5396 /* D8 */ NULL, NULL, NULL, NULL,
5397 /* DC */ NULL, NULL, NULL, NULL,
5398 /* E0 */ NULL, NULL, NULL, NULL,
5399 /* E4 */ NULL, NULL, NULL, NULL,
5400 /* E8 */ NULL, NULL, NULL, NULL,
5401 /* EC */ NULL, NULL, NULL, NULL,
5402 /* F0 */ NULL, NULL, NULL, NULL,
5403 /* F4 */ NULL, NULL, NULL, NULL,
5404 /* F8 */ NULL, NULL, NULL, NULL,
5405 /* FC */ NULL, NULL, NULL, NULL,
5409 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5411 const char *mnemonic;
5413 FETCH_DATA (the_info, codep + 1);
5414 /* AMD 3DNow! instructions are specified by an opcode suffix in the
5415 place where an 8-bit immediate would normally go. ie. the last
5416 byte of the instruction. */
5417 obufp = obuf + strlen (obuf);
5418 mnemonic = Suffix3DNow[*codep++ & 0xff];
5423 /* Since a variable sized modrm/sib chunk is between the start
5424 of the opcode (0x0f0f) and the opcode suffix, we need to do
5425 all the modrm processing first, and don't know until now that
5426 we have a bad opcode. This necessitates some cleaning up. */
5427 op_out[0][0] = '\0';
5428 op_out[1][0] = '\0';
5433 static const char *simd_cmp_op[] = {
5445 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5447 unsigned int cmp_type;
5449 FETCH_DATA (the_info, codep + 1);
5450 obufp = obuf + strlen (obuf);
5451 cmp_type = *codep++ & 0xff;
5454 char suffix1 = 'p', suffix2 = 's';
5455 used_prefixes |= (prefixes & PREFIX_REPZ);
5456 if (prefixes & PREFIX_REPZ)
5460 used_prefixes |= (prefixes & PREFIX_DATA);
5461 if (prefixes & PREFIX_DATA)
5465 used_prefixes |= (prefixes & PREFIX_REPNZ);
5466 if (prefixes & PREFIX_REPNZ)
5467 suffix1 = 's', suffix2 = 'd';
5470 sprintf (scratchbuf, "cmp%s%c%c",
5471 simd_cmp_op[cmp_type], suffix1, suffix2);
5472 used_prefixes |= (prefixes & PREFIX_REPZ);
5473 oappend (scratchbuf);
5477 /* We have a bad extension byte. Clean up. */
5478 op_out[0][0] = '\0';
5479 op_out[1][0] = '\0';
5485 SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
5487 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
5488 forms of these instructions. */
5491 char *p = obuf + strlen (obuf);
5494 *(p - 1) = *(p - 2);
5495 *(p - 2) = *(p - 3);
5496 *(p - 3) = extrachar;
5501 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
5503 if (modrm.mod == 3 && modrm.reg == 1 && modrm.rm <= 1)
5505 /* Override "sidt". */
5506 size_t olen = strlen (obuf);
5507 char *p = obuf + olen - 4;
5508 const char **names = (address_mode == mode_64bit
5509 ? names64 : names32);
5511 /* We might have a suffix when disassembling with -Msuffix. */
5515 /* Remove "addr16/addr32" if we aren't in Intel mode. */
5517 && (prefixes & PREFIX_ADDR)
5520 && CONST_STRNEQ (p - 7, "addr")
5521 && (CONST_STRNEQ (p - 3, "16")
5522 || CONST_STRNEQ (p - 3, "32")))
5527 /* mwait %eax,%ecx */
5528 strcpy (p, "mwait");
5530 strcpy (op_out[0], names[0]);
5534 /* monitor %eax,%ecx,%edx" */
5535 strcpy (p, "monitor");
5538 const char **op1_names;
5539 if (!(prefixes & PREFIX_ADDR))
5540 op1_names = (address_mode == mode_16bit
5544 op1_names = (address_mode != mode_32bit
5545 ? names32 : names16);
5546 used_prefixes |= PREFIX_ADDR;
5548 strcpy (op_out[0], op1_names[0]);
5549 strcpy (op_out[2], names[2]);
5554 strcpy (op_out[1], names[1]);
5565 SVME_Fixup (int bytemode, int sizeflag)
5597 OP_M (bytemode, sizeflag);
5600 /* Override "lidt". */
5601 p = obuf + strlen (obuf) - 4;
5602 /* We might have a suffix. */
5606 if (!(prefixes & PREFIX_ADDR))
5611 used_prefixes |= PREFIX_ADDR;
5615 strcpy (op_out[1], names32[1]);
5621 *obufp++ = open_char;
5622 if (address_mode == mode_64bit || (sizeflag & AFLAG))
5626 strcpy (obufp, alt);
5627 obufp += strlen (alt);
5628 *obufp++ = close_char;
5635 INVLPG_Fixup (int bytemode, int sizeflag)
5648 OP_M (bytemode, sizeflag);
5651 /* Override "invlpg". */
5652 strcpy (obuf + strlen (obuf) - 6, alt);
5659 /* Throw away prefixes and 1st. opcode byte. */
5660 codep = insn_codep + 1;
5665 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
5672 /* Override "sgdt". */
5673 char *p = obuf + strlen (obuf) - 4;
5675 /* We might have a suffix when disassembling with -Msuffix. */
5682 strcpy (p, "vmcall");
5685 strcpy (p, "vmlaunch");
5688 strcpy (p, "vmresume");
5691 strcpy (p, "vmxoff");
5702 OP_VMX (int bytemode, int sizeflag)
5704 used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
5705 if (prefixes & PREFIX_DATA)
5706 strcpy (obuf, "vmclear");
5707 else if (prefixes & PREFIX_REPZ)
5708 strcpy (obuf, "vmxon");
5710 strcpy (obuf, "vmptrld");
5711 OP_E (bytemode, sizeflag);
5715 REP_Fixup (int bytemode, int sizeflag)
5717 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
5721 if (prefixes & PREFIX_REPZ)
5722 switch (*insn_codep)
5724 case 0x6e: /* outsb */
5725 case 0x6f: /* outsw/outsl */
5726 case 0xa4: /* movsb */
5727 case 0xa5: /* movsw/movsl/movsq */
5733 case 0xaa: /* stosb */
5734 case 0xab: /* stosw/stosl/stosq */
5735 case 0xac: /* lodsb */
5736 case 0xad: /* lodsw/lodsl/lodsq */
5737 if (!intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5742 case 0x6c: /* insb */
5743 case 0x6d: /* insl/insw */
5759 olen = strlen (obuf);
5760 p = obuf + olen - ilen - 1 - 4;
5761 /* Handle "repz [addr16|addr32]". */
5762 if ((prefixes & PREFIX_ADDR))
5765 memmove (p + 3, p + 4, olen - (p + 3 - obuf));
5773 OP_IMREG (bytemode, sizeflag);
5776 OP_ESreg (bytemode, sizeflag);
5779 OP_DSreg (bytemode, sizeflag);
5788 CMPXCHG8B_Fixup (int bytemode, int sizeflag)
5793 /* Change cmpxchg8b to cmpxchg16b. */
5794 char *p = obuf + strlen (obuf) - 2;
5798 OP_M (bytemode, sizeflag);