1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 98, 1999
3 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
24 * modified by John Hassey (hassey@dg-rtp.dg.com)
25 * x86-64 support added by Jan Hubicka (jh@suse.cz)
29 * The main tables describing the instructions is essentially a copy
30 * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
31 * Programmers Manual. Usually, there is a capital letter, followed
32 * by a small letter. The capital letter tell the addressing mode,
33 * and the small letter tells about the operand size. Refer to
34 * the Intel manual for details.
45 #ifndef UNIXWARE_COMPAT
46 /* Set non-zero for broken, compatible instructions. Set to zero for
47 non-broken opcodes. */
48 #define UNIXWARE_COMPAT 1
51 static int fetch_data
PARAMS ((struct disassemble_info
*, bfd_byte
*));
55 /* Points to first byte not fetched. */
56 bfd_byte
*max_fetched
;
57 bfd_byte the_buffer
[MAXLEN
];
62 /* The opcode for the fwait instruction, which we treat as a prefix
64 #define FWAIT_OPCODE (0x9b)
66 /* Set to 1 for 64bit mode disassembly. */
67 static int mode_64bit
;
69 /* Flags for the prefixes for the current instruction. See below. */
72 /* REX prefix the current instruction. See below. */
74 /* Bits of REX we've already used. */
80 /* Mark parts used in the REX prefix. When we are testing for
81 empty prefix (for 8bit register REX extension), just mask it
82 out. Otherwise test for REX bit is excuse for existence of REX
83 only in case value is nonzero. */
84 #define USED_REX(value) \
87 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
92 /* Flags for prefixes which we somehow handled when printing the
93 current instruction. */
94 static int used_prefixes
;
96 /* Flags stored in PREFIXES. */
98 #define PREFIX_REPNZ 2
101 #define PREFIX_SS 0x10
102 #define PREFIX_DS 0x20
103 #define PREFIX_ES 0x40
104 #define PREFIX_FS 0x80
105 #define PREFIX_GS 0x100
106 #define PREFIX_DATA 0x200
107 #define PREFIX_ADDR 0x400
108 #define PREFIX_FWAIT 0x800
110 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
111 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
113 #define FETCH_DATA(info, addr) \
114 ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
115 ? 1 : fetch_data ((info), (addr)))
118 fetch_data (info
, addr
)
119 struct disassemble_info
*info
;
123 struct dis_private
*priv
= (struct dis_private
*)info
->private_data
;
124 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
126 status
= (*info
->read_memory_func
) (start
,
128 addr
- priv
->max_fetched
,
132 /* If we did manage to read at least one byte, then
133 print_insn_i386 will do something sensible. Otherwise, print
134 an error. We do that here because this is where we know
136 if (priv
->max_fetched
== priv
->the_buffer
)
137 (*info
->memory_error_func
) (status
, start
, info
);
138 longjmp (priv
->bailout
, 1);
141 priv
->max_fetched
= addr
;
147 #define Eb OP_E, b_mode
148 #define Ev OP_E, v_mode
149 #define Ed OP_E, d_mode
150 #define indirEb OP_indirE, b_mode
151 #define Gb OP_G, b_mode
152 #define Ev OP_E, v_mode
153 #define Ed OP_E, d_mode
154 #define indirEv OP_indirE, v_mode
155 #define Ew OP_E, w_mode
156 #define Ma OP_E, v_mode
157 #define M OP_E, 0 /* lea */
158 #define Mp OP_E, 0 /* 32 or 48 bit memory operand for LDS, LES etc */
159 #define Gv OP_G, v_mode
160 #define Gw OP_G, w_mode
161 #define Rd OP_Rd, d_mode
162 #define Rm OP_Rd, m_mode
163 #define Ib OP_I, b_mode
164 #define sIb OP_sI, b_mode /* sign extened byte */
165 #define Iv OP_I, v_mode
166 #define Iq OP_I, q_mode
167 #define Iv64 OP_I64, v_mode
168 #define Iw OP_I, w_mode
169 #define Jb OP_J, b_mode
170 #define Jv OP_J, v_mode
171 #define Cm OP_C, m_mode
172 #define Dm OP_D, m_mode
173 #define Td OP_T, d_mode
175 #define RMeAX OP_REG, eAX_reg
176 #define RMeBX OP_REG, eBX_reg
177 #define RMeCX OP_REG, eCX_reg
178 #define RMeDX OP_REG, eDX_reg
179 #define RMeSP OP_REG, eSP_reg
180 #define RMeBP OP_REG, eBP_reg
181 #define RMeSI OP_REG, eSI_reg
182 #define RMeDI OP_REG, eDI_reg
183 #define RMrAX OP_REG, rAX_reg
184 #define RMrBX OP_REG, rBX_reg
185 #define RMrCX OP_REG, rCX_reg
186 #define RMrDX OP_REG, rDX_reg
187 #define RMrSP OP_REG, rSP_reg
188 #define RMrBP OP_REG, rBP_reg
189 #define RMrSI OP_REG, rSI_reg
190 #define RMrDI OP_REG, rDI_reg
191 #define RMAL OP_REG, al_reg
192 #define RMAL OP_REG, al_reg
193 #define RMCL OP_REG, cl_reg
194 #define RMDL OP_REG, dl_reg
195 #define RMBL OP_REG, bl_reg
196 #define RMAH OP_REG, ah_reg
197 #define RMCH OP_REG, ch_reg
198 #define RMDH OP_REG, dh_reg
199 #define RMBH OP_REG, bh_reg
200 #define RMAX OP_REG, ax_reg
201 #define RMDX OP_REG, dx_reg
203 #define eAX OP_IMREG, eAX_reg
204 #define eBX OP_IMREG, eBX_reg
205 #define eCX OP_IMREG, eCX_reg
206 #define eDX OP_IMREG, eDX_reg
207 #define eSP OP_IMREG, eSP_reg
208 #define eBP OP_IMREG, eBP_reg
209 #define eSI OP_IMREG, eSI_reg
210 #define eDI OP_IMREG, eDI_reg
211 #define AL OP_IMREG, al_reg
212 #define AL OP_IMREG, al_reg
213 #define CL OP_IMREG, cl_reg
214 #define DL OP_IMREG, dl_reg
215 #define BL OP_IMREG, bl_reg
216 #define AH OP_IMREG, ah_reg
217 #define CH OP_IMREG, ch_reg
218 #define DH OP_IMREG, dh_reg
219 #define BH OP_IMREG, bh_reg
220 #define AX OP_IMREG, ax_reg
221 #define DX OP_IMREG, dx_reg
222 #define indirDX OP_IMREG, indir_dx_reg
224 #define Sw OP_SEG, w_mode
226 #define Ob OP_OFF, b_mode
227 #define Ob64 OP_OFF64, b_mode
228 #define Ov OP_OFF, v_mode
229 #define Ov64 OP_OFF64, v_mode
230 #define Xb OP_DSreg, eSI_reg
231 #define Xv OP_DSreg, eSI_reg
232 #define Yb OP_ESreg, eDI_reg
233 #define Yv OP_ESreg, eDI_reg
234 #define DSBX OP_DSreg, eBX_reg
236 #define es OP_REG, es_reg
237 #define ss OP_REG, ss_reg
238 #define cs OP_REG, cs_reg
239 #define ds OP_REG, ds_reg
240 #define fs OP_REG, fs_reg
241 #define gs OP_REG, gs_reg
245 #define EM OP_EM, v_mode
246 #define EX OP_EX, v_mode
247 #define MS OP_MS, v_mode
249 #define OPSUF OP_3DNowSuffix, 0
250 #define OPSIMD OP_SIMD_Suffix, 0
252 /* bits in sizeflag */
253 #if 0 /* leave undefined until someone adds the extra flag to objdump */
254 #define SUFFIX_ALWAYS 4
259 typedef void (*op_rtn
) PARAMS ((int bytemode
, int sizeflag
));
261 static void OP_E
PARAMS ((int, int));
262 static void OP_G
PARAMS ((int, int));
263 static void OP_I
PARAMS ((int, int));
264 static void OP_I64
PARAMS ((int, int));
265 static void OP_OFF
PARAMS ((int, int));
266 static void OP_REG
PARAMS ((int, int));
267 static void OP_IMREG
PARAMS ((int, int));
268 static void OP_OFF64
PARAMS ((int, int));
269 static void OP_indirE
PARAMS ((int, int));
270 static void OP_sI
PARAMS ((int, int));
271 static void OP_REG
PARAMS ((int, int));
272 static void OP_J
PARAMS ((int, int));
273 static void OP_DIR
PARAMS ((int, int));
274 static void OP_OFF
PARAMS ((int, int));
275 static void OP_ESreg
PARAMS ((int, int));
276 static void OP_DSreg
PARAMS ((int, int));
277 static void OP_SEG
PARAMS ((int, int));
278 static void OP_C
PARAMS ((int, int));
279 static void OP_D
PARAMS ((int, int));
280 static void OP_T
PARAMS ((int, int));
281 static void OP_Rd
PARAMS ((int, int));
282 static void OP_ST
PARAMS ((int, int));
283 static void OP_STi
PARAMS ((int, int));
284 static void OP_MMX
PARAMS ((int, int));
285 static void OP_XMM
PARAMS ((int, int));
286 static void OP_EM
PARAMS ((int, int));
287 static void OP_EX
PARAMS ((int, int));
288 static void OP_MS
PARAMS ((int, int));
289 static void OP_3DNowSuffix
PARAMS ((int, int));
290 static void OP_SIMD_Suffix
PARAMS ((int, int));
291 static void SIMD_Fixup
PARAMS ((int, int));
293 static void append_seg
PARAMS ((void));
294 static void set_op
PARAMS ((unsigned int op
, int));
295 static void putop
PARAMS ((const char *template, int sizeflag
));
296 static void dofloat
PARAMS ((int sizeflag
));
297 static int get16
PARAMS ((void));
298 static bfd_vma get64
PARAMS ((void));
299 static bfd_signed_vma get32
PARAMS ((void));
300 static bfd_signed_vma get32s
PARAMS ((void));
301 static void ckprefix
PARAMS ((void));
302 static const char *prefix_name
PARAMS ((int, int));
303 static void ptr_reg
PARAMS ((int, int));
304 static void BadOp
PARAMS ((void));
306 #define b_mode 1 /* byte operand */
307 #define v_mode 2 /* operand size depends on prefixes */
308 #define w_mode 3 /* word operand */
309 #define d_mode 4 /* double word operand */
310 #define q_mode 5 /* quad word operand */
312 #define m_mode 7 /* d_mode in 32bit, q_mode in 64bit mode. */
357 #define indir_dx_reg 150
360 #define USE_PREFIX_USER_TABLE 2
362 #define GRP1b NULL, NULL, 0, NULL, USE_GROUPS, NULL, 0
363 #define GRP1S NULL, NULL, 1, NULL, USE_GROUPS, NULL, 0
364 #define GRP1Ss NULL, NULL, 2, NULL, USE_GROUPS, NULL, 0
365 #define GRP2b NULL, NULL, 3, NULL, USE_GROUPS, NULL, 0
366 #define GRP2S NULL, NULL, 4, NULL, USE_GROUPS, NULL, 0
367 #define GRP2b_one NULL, NULL, 5, NULL, USE_GROUPS, NULL, 0
368 #define GRP2S_one NULL, NULL, 6, NULL, USE_GROUPS, NULL, 0
369 #define GRP2b_cl NULL, NULL, 7, NULL, USE_GROUPS, NULL, 0
370 #define GRP2S_cl NULL, NULL, 8, NULL, USE_GROUPS, NULL, 0
371 #define GRP3b NULL, NULL, 9, NULL, USE_GROUPS, NULL, 0
372 #define GRP3S NULL, NULL, 10, NULL, USE_GROUPS, NULL, 0
373 #define GRP4 NULL, NULL, 11, NULL, USE_GROUPS, NULL, 0
374 #define GRP5 NULL, NULL, 12, NULL, USE_GROUPS, NULL, 0
375 #define GRP6 NULL, NULL, 13, NULL, USE_GROUPS, NULL, 0
376 #define GRP7 NULL, NULL, 14, NULL, USE_GROUPS, NULL, 0
377 #define GRP8 NULL, NULL, 15, NULL, USE_GROUPS, NULL, 0
378 #define GRP9 NULL, NULL, 16, NULL, USE_GROUPS, NULL, 0
379 #define GRP10 NULL, NULL, 17, NULL, USE_GROUPS, NULL, 0
380 #define GRP11 NULL, NULL, 18, NULL, USE_GROUPS, NULL, 0
381 #define GRP12 NULL, NULL, 19, NULL, USE_GROUPS, NULL, 0
382 #define GRP13 NULL, NULL, 20, NULL, USE_GROUPS, NULL, 0
383 #define GRP14 NULL, NULL, 21, NULL, USE_GROUPS, NULL, 0
384 #define GRPAMD NULL, NULL, 22, NULL, USE_GROUPS, NULL, 0
386 #define PREGRP0 NULL, NULL, 0, NULL, USE_PREFIX_USER_TABLE, NULL, 0
387 #define PREGRP1 NULL, NULL, 1, NULL, USE_PREFIX_USER_TABLE, NULL, 0
388 #define PREGRP2 NULL, NULL, 2, NULL, USE_PREFIX_USER_TABLE, NULL, 0
389 #define PREGRP3 NULL, NULL, 3, NULL, USE_PREFIX_USER_TABLE, NULL, 0
390 #define PREGRP4 NULL, NULL, 4, NULL, USE_PREFIX_USER_TABLE, NULL, 0
391 #define PREGRP5 NULL, NULL, 5, NULL, USE_PREFIX_USER_TABLE, NULL, 0
392 #define PREGRP6 NULL, NULL, 6, NULL, USE_PREFIX_USER_TABLE, NULL, 0
393 #define PREGRP7 NULL, NULL, 7, NULL, USE_PREFIX_USER_TABLE, NULL, 0
394 #define PREGRP8 NULL, NULL, 8, NULL, USE_PREFIX_USER_TABLE, NULL, 0
395 #define PREGRP9 NULL, NULL, 9, NULL, USE_PREFIX_USER_TABLE, NULL, 0
396 #define PREGRP10 NULL, NULL, 10, NULL, USE_PREFIX_USER_TABLE, NULL, 0
397 #define PREGRP11 NULL, NULL, 11, NULL, USE_PREFIX_USER_TABLE, NULL, 0
398 #define PREGRP12 NULL, NULL, 12, NULL, USE_PREFIX_USER_TABLE, NULL, 0
399 #define PREGRP13 NULL, NULL, 13, NULL, USE_PREFIX_USER_TABLE, NULL, 0
400 #define PREGRP14 NULL, NULL, 14, NULL, USE_PREFIX_USER_TABLE, NULL, 0
401 #define PREGRP15 NULL, NULL, 15, NULL, USE_PREFIX_USER_TABLE, NULL, 0
402 #define PREGRP16 NULL, NULL, 16, NULL, USE_PREFIX_USER_TABLE, NULL, 0
403 #define PREGRP17 NULL, NULL, 17, NULL, USE_PREFIX_USER_TABLE, NULL, 0
404 #define PREGRP18 NULL, NULL, 18, NULL, USE_PREFIX_USER_TABLE, NULL, 0
405 #define PREGRP19 NULL, NULL, 19, NULL, USE_PREFIX_USER_TABLE, NULL, 0
406 #define PREGRP20 NULL, NULL, 20, NULL, USE_PREFIX_USER_TABLE, NULL, 0
407 #define PREGRP21 NULL, NULL, 21, NULL, USE_PREFIX_USER_TABLE, NULL, 0
408 #define PREGRP22 NULL, NULL, 22, NULL, USE_PREFIX_USER_TABLE, NULL, 0
409 #define PREGRP23 NULL, NULL, 23, NULL, USE_PREFIX_USER_TABLE, NULL, 0
410 #define PREGRP24 NULL, NULL, 24, NULL, USE_PREFIX_USER_TABLE, NULL, 0
413 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
425 /* Upper case letters in the instruction names here are macros.
426 'A' => print 'b' if no register operands or suffix_always is true
427 'B' => print 'b' if suffix_always is true
428 'E' => print 'e' if 32-bit form of jcxz
429 'L' => print 'l' if suffix_always is true
430 'N' => print 'n' if instruction has no wait "prefix"
431 'O' => print 'd', or 'o'
432 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
433 or suffix_always is true
434 print 'q' if rex prefix is present.
435 'I' => print 'q' in 64bit mode and behave as 'P' otherwise
436 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always is true
437 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
438 'S' => print 'w', 'l' or 'q' if suffix_always is true
439 'X' => print 's', 'd' depending on data16 prefix (for XMM)
440 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
443 static const struct dis386 dis386_att
[] = {
445 { "addB", Eb
, Gb
, XX
},
446 { "addS", Ev
, Gv
, XX
},
447 { "addB", Gb
, Eb
, XX
},
448 { "addS", Gv
, Ev
, XX
},
449 { "addB", AL
, Ib
, XX
},
450 { "addS", eAX
, Iv
, XX
},
451 { "pushI", es
, XX
, XX
},
452 { "popI", es
, XX
, XX
},
454 { "orB", Eb
, Gb
, XX
},
455 { "orS", Ev
, Gv
, XX
},
456 { "orB", Gb
, Eb
, XX
},
457 { "orS", Gv
, Ev
, XX
},
458 { "orB", AL
, Ib
, XX
},
459 { "orS", eAX
, Iv
, XX
},
460 { "pushI", cs
, XX
, XX
},
461 { "(bad)", XX
, XX
, XX
}, /* 0x0f extended opcode escape */
463 { "adcB", Eb
, Gb
, XX
},
464 { "adcS", Ev
, Gv
, XX
},
465 { "adcB", Gb
, Eb
, XX
},
466 { "adcS", Gv
, Ev
, XX
},
467 { "adcB", AL
, Ib
, XX
},
468 { "adcS", eAX
, Iv
, XX
},
469 { "pushI", ss
, XX
, XX
},
470 { "popI", ss
, XX
, XX
},
472 { "sbbB", Eb
, Gb
, XX
},
473 { "sbbS", Ev
, Gv
, XX
},
474 { "sbbB", Gb
, Eb
, XX
},
475 { "sbbS", Gv
, Ev
, XX
},
476 { "sbbB", AL
, Ib
, XX
},
477 { "sbbS", eAX
, Iv
, XX
},
478 { "pushI", ds
, XX
, XX
},
479 { "popI", ds
, XX
, XX
},
481 { "andB", Eb
, Gb
, XX
},
482 { "andS", Ev
, Gv
, XX
},
483 { "andB", Gb
, Eb
, XX
},
484 { "andS", Gv
, Ev
, XX
},
485 { "andB", AL
, Ib
, XX
},
486 { "andS", eAX
, Iv
, XX
},
487 { "(bad)", XX
, XX
, XX
}, /* SEG ES prefix */
488 { "daa", XX
, XX
, XX
},
490 { "subB", Eb
, Gb
, XX
},
491 { "subS", Ev
, Gv
, XX
},
492 { "subB", Gb
, Eb
, XX
},
493 { "subS", Gv
, Ev
, XX
},
494 { "subB", AL
, Ib
, XX
},
495 { "subS", eAX
, Iv
, XX
},
496 { "(bad)", XX
, XX
, XX
}, /* SEG CS prefix */
497 { "das", XX
, XX
, XX
},
499 { "xorB", Eb
, Gb
, XX
},
500 { "xorS", Ev
, Gv
, XX
},
501 { "xorB", Gb
, Eb
, XX
},
502 { "xorS", Gv
, Ev
, XX
},
503 { "xorB", AL
, Ib
, XX
},
504 { "xorS", eAX
, Iv
, XX
},
505 { "(bad)", XX
, XX
, XX
}, /* SEG SS prefix */
506 { "aaa", XX
, XX
, XX
},
508 { "cmpB", Eb
, Gb
, XX
},
509 { "cmpS", Ev
, Gv
, XX
},
510 { "cmpB", Gb
, Eb
, XX
},
511 { "cmpS", Gv
, Ev
, XX
},
512 { "cmpB", AL
, Ib
, XX
},
513 { "cmpS", eAX
, Iv
, XX
},
514 { "(bad)", XX
, XX
, XX
}, /* SEG DS prefix */
515 { "aas", XX
, XX
, XX
},
517 { "incS", RMeAX
, XX
, XX
},
518 { "incS", RMeCX
, XX
, XX
},
519 { "incS", RMeDX
, XX
, XX
},
520 { "incS", RMeBX
, XX
, XX
},
521 { "incS", RMeSP
, XX
, XX
},
522 { "incS", RMeBP
, XX
, XX
},
523 { "incS", RMeSI
, XX
, XX
},
524 { "incS", RMeDI
, XX
, XX
},
526 { "decS", RMeAX
, XX
, XX
},
527 { "decS", RMeCX
, XX
, XX
},
528 { "decS", RMeDX
, XX
, XX
},
529 { "decS", RMeBX
, XX
, XX
},
530 { "decS", RMeSP
, XX
, XX
},
531 { "decS", RMeBP
, XX
, XX
},
532 { "decS", RMeSI
, XX
, XX
},
533 { "decS", RMeDI
, XX
, XX
},
535 { "pushS", RMeAX
, XX
, XX
},
536 { "pushS", RMeCX
, XX
, XX
},
537 { "pushS", RMeDX
, XX
, XX
},
538 { "pushS", RMeBX
, XX
, XX
},
539 { "pushS", RMeSP
, XX
, XX
},
540 { "pushS", RMeBP
, XX
, XX
},
541 { "pushS", RMeSI
, XX
, XX
},
542 { "pushS", RMeDI
, XX
, XX
},
544 { "popS", RMeAX
, XX
, XX
},
545 { "popS", RMeCX
, XX
, XX
},
546 { "popS", RMeDX
, XX
, XX
},
547 { "popS", RMeBX
, XX
, XX
},
548 { "popS", RMeSP
, XX
, XX
},
549 { "popS", RMeBP
, XX
, XX
},
550 { "popS", RMeSI
, XX
, XX
},
551 { "popS", RMeDI
, XX
, XX
},
553 { "pushaP", XX
, XX
, XX
},
554 { "popaP", XX
, XX
, XX
},
555 { "boundS", Gv
, Ma
, XX
},
556 { "arpl", Ew
, Gw
, XX
},
557 { "(bad)", XX
, XX
, XX
}, /* seg fs */
558 { "(bad)", XX
, XX
, XX
}, /* seg gs */
559 { "(bad)", XX
, XX
, XX
}, /* op size prefix */
560 { "(bad)", XX
, XX
, XX
}, /* adr size prefix */
562 { "pushI", Iv
, XX
, XX
}, /* 386 book wrong */
563 { "imulS", Gv
, Ev
, Iv
},
564 { "pushI", sIb
, XX
, XX
}, /* push of byte really pushes 2 or 4 bytes */
565 { "imulS", Gv
, Ev
, sIb
},
566 { "insb", Yb
, indirDX
, XX
},
567 { "insR", Yv
, indirDX
, XX
},
568 { "outsb", indirDX
, Xb
, XX
},
569 { "outsR", indirDX
, Xv
, XX
},
571 { "jo", Jb
, XX
, XX
},
572 { "jno", Jb
, XX
, XX
},
573 { "jb", Jb
, XX
, XX
},
574 { "jae", Jb
, XX
, XX
},
575 { "je", Jb
, XX
, XX
},
576 { "jne", Jb
, XX
, XX
},
577 { "jbe", Jb
, XX
, XX
},
578 { "ja", Jb
, XX
, XX
},
580 { "js", Jb
, XX
, XX
},
581 { "jns", Jb
, XX
, XX
},
582 { "jp", Jb
, XX
, XX
},
583 { "jnp", Jb
, XX
, XX
},
584 { "jl", Jb
, XX
, XX
},
585 { "jge", Jb
, XX
, XX
},
586 { "jle", Jb
, XX
, XX
},
587 { "jg", Jb
, XX
, XX
},
591 { "(bad)", XX
, XX
, XX
},
593 { "testB", Eb
, Gb
, XX
},
594 { "testS", Ev
, Gv
, XX
},
595 { "xchgB", Eb
, Gb
, XX
},
596 { "xchgS", Ev
, Gv
, XX
},
598 { "movB", Eb
, Gb
, XX
},
599 { "movS", Ev
, Gv
, XX
},
600 { "movB", Gb
, Eb
, XX
},
601 { "movS", Gv
, Ev
, XX
},
602 { "movQ", Ev
, Sw
, XX
},
603 { "leaS", Gv
, M
, XX
},
604 { "movQ", Sw
, Ev
, XX
},
605 { "popQ", Ev
, XX
, XX
},
607 { "nop", XX
, XX
, XX
},
608 /* FIXME: NOP with REPz prefix is called PAUSE. */
609 { "xchgS", RMeCX
, eAX
, XX
},
610 { "xchgS", RMeDX
, eAX
, XX
},
611 { "xchgS", RMeBX
, eAX
, XX
},
612 { "xchgS", RMeSP
, eAX
, XX
},
613 { "xchgS", RMeBP
, eAX
, XX
},
614 { "xchgS", RMeSI
, eAX
, XX
},
615 { "xchgS", RMeDI
, eAX
, XX
},
617 { "cWtR", XX
, XX
, XX
},
618 { "cRtO", XX
, XX
, XX
},
619 { "lcallI", Ap
, XX
, XX
},
620 { "(bad)", XX
, XX
, XX
}, /* fwait */
621 { "pushfI", XX
, XX
, XX
},
622 { "popfI", XX
, XX
, XX
},
623 { "sahf", XX
, XX
, XX
},
624 { "lahf", XX
, XX
, XX
},
626 { "movB", AL
, Ob
, XX
},
627 { "movS", eAX
, Ov
, XX
},
628 { "movB", Ob
, AL
, XX
},
629 { "movS", Ov
, eAX
, XX
},
630 { "movsb", Yb
, Xb
, XX
},
631 { "movsR", Yv
, Xv
, XX
},
632 { "cmpsb", Xb
, Yb
, XX
},
633 { "cmpsR", Xv
, Yv
, XX
},
635 { "testB", AL
, Ib
, XX
},
636 { "testS", eAX
, Iv
, XX
},
637 { "stosB", Yb
, AL
, XX
},
638 { "stosS", Yv
, eAX
, XX
},
639 { "lodsB", AL
, Xb
, XX
},
640 { "lodsS", eAX
, Xv
, XX
},
641 { "scasB", AL
, Yb
, XX
},
642 { "scasS", eAX
, Yv
, XX
},
644 { "movB", RMAL
, Ib
, XX
},
645 { "movB", RMCL
, Ib
, XX
},
646 { "movB", RMDL
, Ib
, XX
},
647 { "movB", RMBL
, Ib
, XX
},
648 { "movB", RMAH
, Ib
, XX
},
649 { "movB", RMCH
, Ib
, XX
},
650 { "movB", RMDH
, Ib
, XX
},
651 { "movB", RMBH
, Ib
, XX
},
653 { "movS", RMeAX
, Iv
, XX
},
654 { "movS", RMeCX
, Iv
, XX
},
655 { "movS", RMeDX
, Iv
, XX
},
656 { "movS", RMeBX
, Iv
, XX
},
657 { "movS", RMeSP
, Iv
, XX
},
658 { "movS", RMeBP
, Iv
, XX
},
659 { "movS", RMeSI
, Iv
, XX
},
660 { "movS", RMeDI
, Iv
, XX
},
664 { "retI", Iw
, XX
, XX
},
665 { "retI", XX
, XX
, XX
},
666 { "lesS", Gv
, Mp
, XX
},
667 { "ldsS", Gv
, Mp
, XX
},
668 { "movA", Eb
, Ib
, XX
},
669 { "movQ", Ev
, Iv
, XX
},
671 { "enterI", Iw
, Ib
, XX
},
672 { "leaveI", XX
, XX
, XX
},
673 { "lretP", Iw
, XX
, XX
},
674 { "lretP", XX
, XX
, XX
},
675 { "int3", XX
, XX
, XX
},
676 { "int", Ib
, XX
, XX
},
677 { "into", XX
, XX
, XX
},
678 { "iretP", XX
, XX
, XX
},
684 { "aam", sIb
, XX
, XX
},
685 { "aad", sIb
, XX
, XX
},
686 { "(bad)", XX
, XX
, XX
},
687 { "xlat", DSBX
, XX
, XX
},
698 { "loopne", Jb
, XX
, XX
},
699 { "loope", Jb
, XX
, XX
},
700 { "loop", Jb
, XX
, XX
},
701 { "jEcxz", Jb
, XX
, XX
},
702 { "inB", AL
, Ib
, XX
},
703 { "inS", eAX
, Ib
, XX
},
704 { "outB", Ib
, AL
, XX
},
705 { "outS", Ib
, eAX
, XX
},
707 { "callI", Jv
, XX
, XX
},
708 { "jmpI", Jv
, XX
, XX
},
709 { "ljmpI", Ap
, XX
, XX
},
710 { "jmp", Jb
, XX
, XX
},
711 { "inB", AL
, indirDX
, XX
},
712 { "inS", eAX
, indirDX
, XX
},
713 { "outB", indirDX
, AL
, XX
},
714 { "outS", indirDX
, eAX
, XX
},
716 { "(bad)", XX
, XX
, XX
}, /* lock prefix */
717 { "(bad)", XX
, XX
, XX
},
718 { "(bad)", XX
, XX
, XX
}, /* repne */
719 { "(bad)", XX
, XX
, XX
}, /* repz */
720 { "hlt", XX
, XX
, XX
},
721 { "cmc", XX
, XX
, XX
},
725 { "clc", XX
, XX
, XX
},
726 { "stc", XX
, XX
, XX
},
727 { "cli", XX
, XX
, XX
},
728 { "sti", XX
, XX
, XX
},
729 { "cld", XX
, XX
, XX
},
730 { "std", XX
, XX
, XX
},
735 static const struct dis386 dis386_intel
[] = {
737 { "add", Eb
, Gb
, XX
},
738 { "add", Ev
, Gv
, XX
},
739 { "add", Gb
, Eb
, XX
},
740 { "add", Gv
, Ev
, XX
},
741 { "add", AL
, Ib
, XX
},
742 { "add", eAX
, Iv
, XX
},
743 { "push", es
, XX
, XX
},
744 { "pop", es
, XX
, XX
},
746 { "or", Eb
, Gb
, XX
},
747 { "or", Ev
, Gv
, XX
},
748 { "or", Gb
, Eb
, XX
},
749 { "or", Gv
, Ev
, XX
},
750 { "or", AL
, Ib
, XX
},
751 { "or", eAX
, Iv
, XX
},
752 { "push", cs
, XX
, XX
},
753 { "(bad)", XX
, XX
, XX
}, /* 0x0f extended opcode escape */
755 { "adc", Eb
, Gb
, XX
},
756 { "adc", Ev
, Gv
, XX
},
757 { "adc", Gb
, Eb
, XX
},
758 { "adc", Gv
, Ev
, XX
},
759 { "adc", AL
, Ib
, XX
},
760 { "adc", eAX
, Iv
, XX
},
761 { "push", ss
, XX
, XX
},
762 { "pop", ss
, XX
, XX
},
764 { "sbb", Eb
, Gb
, XX
},
765 { "sbb", Ev
, Gv
, XX
},
766 { "sbb", Gb
, Eb
, XX
},
767 { "sbb", Gv
, Ev
, XX
},
768 { "sbb", AL
, Ib
, XX
},
769 { "sbb", eAX
, Iv
, XX
},
770 { "push", ds
, XX
, XX
},
771 { "pop", ds
, XX
, XX
},
773 { "and", Eb
, Gb
, XX
},
774 { "and", Ev
, Gv
, XX
},
775 { "and", Gb
, Eb
, XX
},
776 { "and", Gv
, Ev
, XX
},
777 { "and", AL
, Ib
, XX
},
778 { "and", eAX
, Iv
, XX
},
779 { "(bad)", XX
, XX
, XX
}, /* SEG ES prefix */
780 { "daa", XX
, XX
, XX
},
782 { "sub", Eb
, Gb
, XX
},
783 { "sub", Ev
, Gv
, XX
},
784 { "sub", Gb
, Eb
, XX
},
785 { "sub", Gv
, Ev
, XX
},
786 { "sub", AL
, Ib
, XX
},
787 { "sub", eAX
, Iv
, XX
},
788 { "(bad)", XX
, XX
, XX
}, /* SEG CS prefix */
789 { "das", XX
, XX
, XX
},
791 { "xor", Eb
, Gb
, XX
},
792 { "xor", Ev
, Gv
, XX
},
793 { "xor", Gb
, Eb
, XX
},
794 { "xor", Gv
, Ev
, XX
},
795 { "xor", AL
, Ib
, XX
},
796 { "xor", eAX
, Iv
, XX
},
797 { "(bad)", XX
, XX
, XX
}, /* SEG SS prefix */
798 { "aaa", XX
, XX
, XX
},
800 { "cmp", Eb
, Gb
, XX
},
801 { "cmp", Ev
, Gv
, XX
},
802 { "cmp", Gb
, Eb
, XX
},
803 { "cmp", Gv
, Ev
, XX
},
804 { "cmp", AL
, Ib
, XX
},
805 { "cmp", eAX
, Iv
, XX
},
806 { "(bad)", XX
, XX
, XX
}, /* SEG DS prefix */
807 { "aas", XX
, XX
, XX
},
809 { "inc", RMeAX
, XX
, XX
},
810 { "inc", RMeCX
, XX
, XX
},
811 { "inc", RMeDX
, XX
, XX
},
812 { "inc", RMeBX
, XX
, XX
},
813 { "inc", RMeSP
, XX
, XX
},
814 { "inc", RMeBP
, XX
, XX
},
815 { "inc", RMeSI
, XX
, XX
},
816 { "inc", RMeDI
, XX
, XX
},
818 { "dec", RMeAX
, XX
, XX
},
819 { "dec", RMeCX
, XX
, XX
},
820 { "dec", RMeDX
, XX
, XX
},
821 { "dec", RMeBX
, XX
, XX
},
822 { "dec", RMeSP
, XX
, XX
},
823 { "dec", RMeBP
, XX
, XX
},
824 { "dec", RMeSI
, XX
, XX
},
825 { "dec", RMeDI
, XX
, XX
},
827 { "push", RMeAX
, XX
, XX
},
828 { "push", RMeCX
, XX
, XX
},
829 { "push", RMeDX
, XX
, XX
},
830 { "push", RMeBX
, XX
, XX
},
831 { "push", RMeSP
, XX
, XX
},
832 { "push", RMeBP
, XX
, XX
},
833 { "push", RMeSI
, XX
, XX
},
834 { "push", RMeDI
, XX
, XX
},
836 { "pop", RMeAX
, XX
, XX
},
837 { "pop", RMeCX
, XX
, XX
},
838 { "pop", RMeDX
, XX
, XX
},
839 { "pop", RMeBX
, XX
, XX
},
840 { "pop", RMeSP
, XX
, XX
},
841 { "pop", RMeBP
, XX
, XX
},
842 { "pop", RMeSI
, XX
, XX
},
843 { "pop", RMeDI
, XX
, XX
},
845 { "pusha", XX
, XX
, XX
},
846 { "popa", XX
, XX
, XX
},
847 { "bound", Gv
, Ma
, XX
},
848 { "arpl", Ew
, Gw
, XX
},
849 { "(bad)", XX
, XX
, XX
}, /* seg fs */
850 { "(bad)", XX
, XX
, XX
}, /* seg gs */
851 { "(bad)", XX
, XX
, XX
}, /* op size prefix */
852 { "(bad)", XX
, XX
, XX
}, /* adr size prefix */
854 { "push", Iv
, XX
, XX
}, /* 386 book wrong */
855 { "imul", Gv
, Ev
, Iv
},
856 { "push", sIb
, XX
, XX
}, /* push of byte really pushes 2 or 4 bytes */
857 { "imul", Gv
, Ev
, sIb
},
858 { "ins", Yb
, indirDX
, XX
},
859 { "ins", Yv
, indirDX
, XX
},
860 { "outs", indirDX
, Xb
, XX
},
861 { "outs", indirDX
, Xv
, XX
},
863 { "jo", Jb
, XX
, XX
},
864 { "jno", Jb
, XX
, XX
},
865 { "jb", Jb
, XX
, XX
},
866 { "jae", Jb
, XX
, XX
},
867 { "je", Jb
, XX
, XX
},
868 { "jne", Jb
, XX
, XX
},
869 { "jbe", Jb
, XX
, XX
},
870 { "ja", Jb
, XX
, XX
},
872 { "js", Jb
, XX
, XX
},
873 { "jns", Jb
, XX
, XX
},
874 { "jp", Jb
, XX
, XX
},
875 { "jnp", Jb
, XX
, XX
},
876 { "jl", Jb
, XX
, XX
},
877 { "jge", Jb
, XX
, XX
},
878 { "jle", Jb
, XX
, XX
},
879 { "jg", Jb
, XX
, XX
},
883 { "(bad)", XX
, XX
, XX
},
885 { "test", Eb
, Gb
, XX
},
886 { "test", Ev
, Gv
, XX
},
887 { "xchg", Eb
, Gb
, XX
},
888 { "xchg", Ev
, Gv
, XX
},
890 { "mov", Eb
, Gb
, XX
},
891 { "mov", Ev
, Gv
, XX
},
892 { "mov", Gb
, Eb
, XX
},
893 { "mov", Gv
, Ev
, XX
},
894 { "mov", Ev
, Sw
, XX
},
895 { "lea", Gv
, M
, XX
},
896 { "mov", Sw
, Ev
, XX
},
897 { "pop", Ev
, XX
, XX
},
899 { "nop", XX
, XX
, XX
},
900 /* FIXME: NOP with REPz prefix is called PAUSE. */
901 { "xchg", RMeCX
, eAX
, XX
},
902 { "xchg", RMeDX
, eAX
, XX
},
903 { "xchg", RMeBX
, eAX
, XX
},
904 { "xchg", RMeSP
, eAX
, XX
},
905 { "xchg", RMeBP
, eAX
, XX
},
906 { "xchg", RMeSI
, eAX
, XX
},
907 { "xchg", RMeDI
, eAX
, XX
},
909 { "cW", XX
, XX
, XX
}, /* cwde and cbw */
910 { "cR", XX
, XX
, XX
}, /* cdq and cwd */
911 { "lcall", Ap
, XX
, XX
},
912 { "(bad)", XX
, XX
, XX
}, /* fwait */
913 { "pushf", XX
, XX
, XX
},
914 { "popf", XX
, XX
, XX
},
915 { "sahf", XX
, XX
, XX
},
916 { "lahf", XX
, XX
, XX
},
918 { "mov", AL
, Ob
, XX
},
919 { "mov", eAX
, Ov
, XX
},
920 { "mov", Ob
, AL
, XX
},
921 { "mov", Ov
, eAX
, XX
},
922 { "movs", Yb
, Xb
, XX
},
923 { "movs", Yv
, Xv
, XX
},
924 { "cmps", Xb
, Yb
, XX
},
925 { "cmps", Xv
, Yv
, XX
},
927 { "test", AL
, Ib
, XX
},
928 { "test", eAX
, Iv
, XX
},
929 { "stos", Yb
, AL
, XX
},
930 { "stos", Yv
, eAX
, XX
},
931 { "lods", AL
, Xb
, XX
},
932 { "lods", eAX
, Xv
, XX
},
933 { "scas", AL
, Yb
, XX
},
934 { "scas", eAX
, Yv
, XX
},
936 { "mov", RMAL
, Ib
, XX
},
937 { "mov", RMCL
, Ib
, XX
},
938 { "mov", RMDL
, Ib
, XX
},
939 { "mov", RMBL
, Ib
, XX
},
940 { "mov", RMAH
, Ib
, XX
},
941 { "mov", RMCH
, Ib
, XX
},
942 { "mov", RMDH
, Ib
, XX
},
943 { "mov", RMBH
, Ib
, XX
},
945 { "mov", RMeAX
, Iv
, XX
},
946 { "mov", RMeCX
, Iv
, XX
},
947 { "mov", RMeDX
, Iv
, XX
},
948 { "mov", RMeBX
, Iv
, XX
},
949 { "mov", RMeSP
, Iv
, XX
},
950 { "mov", RMeBP
, Iv
, XX
},
951 { "mov", RMeSI
, Iv
, XX
},
952 { "mov", RMeDI
, Iv
, XX
},
956 { "ret", Iw
, XX
, XX
},
957 { "ret", XX
, XX
, XX
},
958 { "les", Gv
, Mp
, XX
},
959 { "lds", Gv
, Mp
, XX
},
960 { "mov", Eb
, Ib
, XX
},
961 { "mov", Ev
, Iv
, XX
},
963 { "enter", Iw
, Ib
, XX
},
964 { "leave", XX
, XX
, XX
},
965 { "lret", Iw
, XX
, XX
},
966 { "lret", XX
, XX
, XX
},
967 { "int3", XX
, XX
, XX
},
968 { "int", Ib
, XX
, XX
},
969 { "into", XX
, XX
, XX
},
970 { "iret", XX
, XX
, XX
},
976 { "aam", sIb
, XX
, XX
},
977 { "aad", sIb
, XX
, XX
},
978 { "(bad)", XX
, XX
, XX
},
979 { "xlat", DSBX
, XX
, XX
},
990 { "loopne", Jb
, XX
, XX
},
991 { "loope", Jb
, XX
, XX
},
992 { "loop", Jb
, XX
, XX
},
993 { "jEcxz", Jb
, XX
, XX
},
994 { "in", AL
, Ib
, XX
},
995 { "in", eAX
, Ib
, XX
},
996 { "out", Ib
, AL
, XX
},
997 { "out", Ib
, eAX
, XX
},
999 { "call", Jv
, XX
, XX
},
1000 { "jmp", Jv
, XX
, XX
},
1001 { "ljmp", Ap
, XX
, XX
},
1002 { "jmp", Jb
, XX
, XX
},
1003 { "in", AL
, indirDX
, XX
},
1004 { "in", eAX
, indirDX
, XX
},
1005 { "out", indirDX
, AL
, XX
},
1006 { "out", indirDX
, eAX
, XX
},
1008 { "(bad)", XX
, XX
, XX
}, /* lock prefix */
1009 { "(bad)", XX
, XX
, XX
},
1010 { "(bad)", XX
, XX
, XX
}, /* repne */
1011 { "(bad)", XX
, XX
, XX
}, /* repz */
1012 { "hlt", XX
, XX
, XX
},
1013 { "cmc", XX
, XX
, XX
},
1017 { "clc", XX
, XX
, XX
},
1018 { "stc", XX
, XX
, XX
},
1019 { "cli", XX
, XX
, XX
},
1020 { "sti", XX
, XX
, XX
},
1021 { "cld", XX
, XX
, XX
},
1022 { "std", XX
, XX
, XX
},
1027 /* 64bit mode is having some instruction set differences, so separate table is
1029 static const struct dis386 disx86_64_att
[] = {
1031 { "addB", Eb
, Gb
, XX
},
1032 { "addS", Ev
, Gv
, XX
},
1033 { "addB", Gb
, Eb
, XX
},
1034 { "addS", Gv
, Ev
, XX
},
1035 { "addB", AL
, Ib
, XX
},
1036 { "addS", eAX
, Iv
, XX
},
1037 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1038 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1040 { "orB", Eb
, Gb
, XX
},
1041 { "orS", Ev
, Gv
, XX
},
1042 { "orB", Gb
, Eb
, XX
},
1043 { "orS", Gv
, Ev
, XX
},
1044 { "orB", AL
, Ib
, XX
},
1045 { "orS", eAX
, Iv
, XX
},
1046 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1047 { "(bad)", XX
, XX
, XX
}, /* 0x0f extended opcode escape */
1049 { "adcB", Eb
, Gb
, XX
},
1050 { "adcS", Ev
, Gv
, XX
},
1051 { "adcB", Gb
, Eb
, XX
},
1052 { "adcS", Gv
, Ev
, XX
},
1053 { "adcB", AL
, Ib
, XX
},
1054 { "adcS", eAX
, Iv
, XX
},
1055 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1056 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1058 { "sbbB", Eb
, Gb
, XX
},
1059 { "sbbS", Ev
, Gv
, XX
},
1060 { "sbbB", Gb
, Eb
, XX
},
1061 { "sbbS", Gv
, Ev
, XX
},
1062 { "sbbB", AL
, Ib
, XX
},
1063 { "sbbS", eAX
, Iv
, XX
},
1064 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1065 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1067 { "andB", Eb
, Gb
, XX
},
1068 { "andS", Ev
, Gv
, XX
},
1069 { "andB", Gb
, Eb
, XX
},
1070 { "andS", Gv
, Ev
, XX
},
1071 { "andB", AL
, Ib
, XX
},
1072 { "andS", eAX
, Iv
, XX
},
1073 { "(bad)", XX
, XX
, XX
}, /* SEG ES prefix */
1074 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1076 { "subB", Eb
, Gb
, XX
},
1077 { "subS", Ev
, Gv
, XX
},
1078 { "subB", Gb
, Eb
, XX
},
1079 { "subS", Gv
, Ev
, XX
},
1080 { "subB", AL
, Ib
, XX
},
1081 { "subS", eAX
, Iv
, XX
},
1082 { "(bad)", XX
, XX
, XX
}, /* SEG CS prefix */
1083 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1085 { "xorB", Eb
, Gb
, XX
},
1086 { "xorS", Ev
, Gv
, XX
},
1087 { "xorB", Gb
, Eb
, XX
},
1088 { "xorS", Gv
, Ev
, XX
},
1089 { "xorB", AL
, Ib
, XX
},
1090 { "xorS", eAX
, Iv
, XX
},
1091 { "(bad)", XX
, XX
, XX
}, /* SEG SS prefix */
1092 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1094 { "cmpB", Eb
, Gb
, XX
},
1095 { "cmpS", Ev
, Gv
, XX
},
1096 { "cmpB", Gb
, Eb
, XX
},
1097 { "cmpS", Gv
, Ev
, XX
},
1098 { "cmpB", AL
, Ib
, XX
},
1099 { "cmpS", eAX
, Iv
, XX
},
1100 { "(bad)", XX
, XX
, XX
}, /* SEG DS prefix */
1101 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1103 { "(bad)", XX
, XX
, XX
}, /* REX prefix area. */
1104 { "(bad)", XX
, XX
, XX
},
1105 { "(bad)", XX
, XX
, XX
},
1106 { "(bad)", XX
, XX
, XX
},
1107 { "(bad)", XX
, XX
, XX
},
1108 { "(bad)", XX
, XX
, XX
},
1109 { "(bad)", XX
, XX
, XX
},
1110 { "(bad)", XX
, XX
, XX
},
1112 { "(bad)", XX
, XX
, XX
},
1113 { "(bad)", XX
, XX
, XX
},
1114 { "(bad)", XX
, XX
, XX
},
1115 { "(bad)", XX
, XX
, XX
},
1116 { "(bad)", XX
, XX
, XX
},
1117 { "(bad)", XX
, XX
, XX
},
1118 { "(bad)", XX
, XX
, XX
},
1119 { "(bad)", XX
, XX
, XX
},
1121 { "pushI", RMrAX
, XX
, XX
},
1122 { "pushI", RMrCX
, XX
, XX
},
1123 { "pushI", RMrDX
, XX
, XX
},
1124 { "pushI", RMrBX
, XX
, XX
},
1125 { "pushI", RMrSP
, XX
, XX
},
1126 { "pushI", RMrBP
, XX
, XX
},
1127 { "pushI", RMrSI
, XX
, XX
},
1128 { "pushI", RMrDI
, XX
, XX
},
1130 { "popI", RMrAX
, XX
, XX
},
1131 { "popI", RMrCX
, XX
, XX
},
1132 { "popI", RMrDX
, XX
, XX
},
1133 { "popI", RMrBX
, XX
, XX
},
1134 { "popI", RMrSP
, XX
, XX
},
1135 { "popI", RMrBP
, XX
, XX
},
1136 { "popI", RMrSI
, XX
, XX
},
1137 { "popI", RMrDI
, XX
, XX
},
1139 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1140 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1141 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1142 { "movslR", Gv
, Ed
, XX
},
1143 { "(bad)", XX
, XX
, XX
}, /* seg fs */
1144 { "(bad)", XX
, XX
, XX
}, /* seg gs */
1145 { "(bad)", XX
, XX
, XX
}, /* op size prefix */
1146 { "(bad)", XX
, XX
, XX
}, /* adr size prefix */
1148 { "pushI", Iq
, XX
, XX
}, /* 386 book wrong */
1149 { "imulS", Gv
, Ev
, Iv
},
1150 { "pushI", sIb
, XX
, XX
}, /* push of byte really pushes 2 or 4 bytes */
1151 { "imulS", Gv
, Ev
, sIb
},
1152 { "insb", Yb
, indirDX
, XX
},
1153 { "insR", Yv
, indirDX
, XX
},
1154 { "outsb", indirDX
, Xb
, XX
},
1155 { "outsR", indirDX
, Xv
, XX
},
1157 { "jo", Jb
, XX
, XX
},
1158 { "jno", Jb
, XX
, XX
},
1159 { "jb", Jb
, XX
, XX
},
1160 { "jae", Jb
, XX
, XX
},
1161 { "je", Jb
, XX
, XX
},
1162 { "jne", Jb
, XX
, XX
},
1163 { "jbe", Jb
, XX
, XX
},
1164 { "ja", Jb
, XX
, XX
},
1166 { "js", Jb
, XX
, XX
},
1167 { "jns", Jb
, XX
, XX
},
1168 { "jp", Jb
, XX
, XX
},
1169 { "jnp", Jb
, XX
, XX
},
1170 { "jl", Jb
, XX
, XX
},
1171 { "jge", Jb
, XX
, XX
},
1172 { "jle", Jb
, XX
, XX
},
1173 { "jg", Jb
, XX
, XX
},
1177 { "(bad)", XX
, XX
, XX
},
1179 { "testB", Eb
, Gb
, XX
},
1180 { "testS", Ev
, Gv
, XX
},
1181 { "xchgB", Eb
, Gb
, XX
},
1182 { "xchgS", Ev
, Gv
, XX
},
1184 { "movB", Eb
, Gb
, XX
},
1185 { "movS", Ev
, Gv
, XX
},
1186 { "movB", Gb
, Eb
, XX
},
1187 { "movS", Gv
, Ev
, XX
},
1188 { "movQ", Ev
, Sw
, XX
},
1189 { "leaS", Gv
, M
, XX
},
1190 { "movQ", Sw
, Ev
, XX
},
1191 { "popI", Ev
, XX
, XX
},
1193 { "nop", XX
, XX
, XX
},
1194 /* FIXME: NOP with REPz prefix is called PAUSE. */
1195 { "xchgS", RMeCX
, eAX
, XX
},
1196 { "xchgS", RMeDX
, eAX
, XX
},
1197 { "xchgS", RMeBX
, eAX
, XX
},
1198 { "xchgS", RMeSP
, eAX
, XX
},
1199 { "xchgS", RMeBP
, eAX
, XX
},
1200 { "xchgS", RMeSI
, eAX
, XX
},
1201 { "xchgS", RMeDI
, eAX
, XX
},
1203 { "cWtR", XX
, XX
, XX
},
1204 { "cRtO", XX
, XX
, XX
},
1205 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1206 { "(bad)", XX
, XX
, XX
}, /* fwait */
1207 { "pushfI", XX
, XX
, XX
},
1208 { "popfI", XX
, XX
, XX
},
1209 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1210 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1212 { "movB", AL
, Ob64
, XX
},
1213 { "movS", eAX
, Ov64
, XX
},
1214 { "movB", Ob64
, AL
, XX
},
1215 { "movS", Ov64
, eAX
, XX
},
1216 { "movsb", Yb
, Xb
, XX
},
1217 { "movsR", Yv
, Xv
, XX
},
1218 { "cmpsb", Xb
, Yb
, XX
},
1219 { "cmpsR", Xv
, Yv
, XX
},
1221 { "testB", AL
, Ib
, XX
},
1222 { "testS", eAX
, Iv
, XX
},
1223 { "stosB", Yb
, AL
, XX
},
1224 { "stosS", Yv
, eAX
, XX
},
1225 { "lodsB", AL
, Xb
, XX
},
1226 { "lodsS", eAX
, Xv
, XX
},
1227 { "scasB", AL
, Yb
, XX
},
1228 { "scasS", eAX
, Yv
, XX
},
1230 { "movB", RMAL
, Ib
, XX
},
1231 { "movB", RMCL
, Ib
, XX
},
1232 { "movB", RMDL
, Ib
, XX
},
1233 { "movB", RMBL
, Ib
, XX
},
1234 { "movB", RMAH
, Ib
, XX
},
1235 { "movB", RMCH
, Ib
, XX
},
1236 { "movB", RMDH
, Ib
, XX
},
1237 { "movB", RMBH
, Ib
, XX
},
1239 { "movS", RMeAX
, Iv64
, XX
},
1240 { "movS", RMeCX
, Iv64
, XX
},
1241 { "movS", RMeDX
, Iv64
, XX
},
1242 { "movS", RMeBX
, Iv64
, XX
},
1243 { "movS", RMeSP
, Iv64
, XX
},
1244 { "movS", RMeBP
, Iv64
, XX
},
1245 { "movS", RMeSI
, Iv64
, XX
},
1246 { "movS", RMeDI
, Iv64
, XX
},
1250 { "retI", Iw
, XX
, XX
},
1251 { "retI", XX
, XX
, XX
},
1252 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1253 { "ldsS", Gv
, Mp
, XX
},
1254 { "movA", Eb
, Ib
, XX
},
1255 { "movQ", Ev
, Iv
, XX
},
1257 { "enterI", Iw
, Ib
, XX
},
1258 { "leaveI", XX
, XX
, XX
},
1259 { "lretP", Iw
, XX
, XX
},
1260 { "lretP", XX
, XX
, XX
},
1261 { "int3", XX
, XX
, XX
},
1262 { "int", Ib
, XX
, XX
},
1263 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1264 { "iretP", XX
, XX
, XX
},
1270 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1271 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1272 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1273 { "xlat", DSBX
, XX
, XX
},
1284 { "loopne", Jb
, XX
, XX
},
1285 { "loope", Jb
, XX
, XX
},
1286 { "loop", Jb
, XX
, XX
},
1287 { "jEcxz", Jb
, XX
, XX
},
1288 { "inB", AL
, Ib
, XX
},
1289 { "inS", eAX
, Ib
, XX
},
1290 { "outB", Ib
, AL
, XX
},
1291 { "outS", Ib
, eAX
, XX
},
1293 { "callI", Jv
, XX
, XX
},
1294 { "jmpI", Jv
, XX
, XX
},
1295 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1296 { "jmp", Jb
, XX
, XX
},
1297 { "inB", AL
, indirDX
, XX
},
1298 { "inS", eAX
, indirDX
, XX
},
1299 { "outB", indirDX
, AL
, XX
},
1300 { "outS", indirDX
, eAX
, XX
},
1302 { "(bad)", XX
, XX
, XX
}, /* lock prefix */
1303 { "(bad)", XX
, XX
, XX
},
1304 { "(bad)", XX
, XX
, XX
}, /* repne */
1305 { "(bad)", XX
, XX
, XX
}, /* repz */
1306 { "hlt", XX
, XX
, XX
},
1307 { "cmc", XX
, XX
, XX
},
1311 { "clc", XX
, XX
, XX
},
1312 { "stc", XX
, XX
, XX
},
1313 { "cli", XX
, XX
, XX
},
1314 { "sti", XX
, XX
, XX
},
1315 { "cld", XX
, XX
, XX
},
1316 { "std", XX
, XX
, XX
},
1321 static const struct dis386 dis386_64_intel
[] = {
1323 { "add", Eb
, Gb
, XX
},
1324 { "add", Ev
, Gv
, XX
},
1325 { "add", Gb
, Eb
, XX
},
1326 { "add", Gv
, Ev
, XX
},
1327 { "add", AL
, Ib
, XX
},
1328 { "add", eAX
, Iv
, XX
},
1329 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1330 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1332 { "or", Eb
, Gb
, XX
},
1333 { "or", Ev
, Gv
, XX
},
1334 { "or", Gb
, Eb
, XX
},
1335 { "or", Gv
, Ev
, XX
},
1336 { "or", AL
, Ib
, XX
},
1337 { "or", eAX
, Iv
, XX
},
1338 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1339 { "(bad)", XX
, XX
, XX
}, /* 0x0f extended opcode escape */
1341 { "adc", Eb
, Gb
, XX
},
1342 { "adc", Ev
, Gv
, XX
},
1343 { "adc", Gb
, Eb
, XX
},
1344 { "adc", Gv
, Ev
, XX
},
1345 { "adc", AL
, Ib
, XX
},
1346 { "adc", eAX
, Iv
, XX
},
1347 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1348 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1350 { "sbb", Eb
, Gb
, XX
},
1351 { "sbb", Ev
, Gv
, XX
},
1352 { "sbb", Gb
, Eb
, XX
},
1353 { "sbb", Gv
, Ev
, XX
},
1354 { "sbb", AL
, Ib
, XX
},
1355 { "sbb", eAX
, Iv
, XX
},
1356 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1357 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1359 { "and", Eb
, Gb
, XX
},
1360 { "and", Ev
, Gv
, XX
},
1361 { "and", Gb
, Eb
, XX
},
1362 { "and", Gv
, Ev
, XX
},
1363 { "and", AL
, Ib
, XX
},
1364 { "and", eAX
, Iv
, XX
},
1365 { "(bad)", XX
, XX
, XX
}, /* SEG ES prefix */
1366 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1368 { "sub", Eb
, Gb
, XX
},
1369 { "sub", Ev
, Gv
, XX
},
1370 { "sub", Gb
, Eb
, XX
},
1371 { "sub", Gv
, Ev
, XX
},
1372 { "sub", AL
, Ib
, XX
},
1373 { "sub", eAX
, Iv
, XX
},
1374 { "(bad)", XX
, XX
, XX
}, /* SEG CS prefix */
1375 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1377 { "xor", Eb
, Gb
, XX
},
1378 { "xor", Ev
, Gv
, XX
},
1379 { "xor", Gb
, Eb
, XX
},
1380 { "xor", Gv
, Ev
, XX
},
1381 { "xor", AL
, Ib
, XX
},
1382 { "xor", eAX
, Iv
, XX
},
1383 { "(bad)", XX
, XX
, XX
}, /* SEG SS prefix */
1384 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1386 { "cmp", Eb
, Gb
, XX
},
1387 { "cmp", Ev
, Gv
, XX
},
1388 { "cmp", Gb
, Eb
, XX
},
1389 { "cmp", Gv
, Ev
, XX
},
1390 { "cmp", AL
, Ib
, XX
},
1391 { "cmp", eAX
, Iv
, XX
},
1392 { "(bad)", XX
, XX
, XX
}, /* SEG DS prefix */
1393 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1395 { "(bad)", XX
, XX
, XX
}, /* REX prefix area. */
1396 { "(bad)", XX
, XX
, XX
},
1397 { "(bad)", XX
, XX
, XX
},
1398 { "(bad)", XX
, XX
, XX
},
1399 { "(bad)", XX
, XX
, XX
},
1400 { "(bad)", XX
, XX
, XX
},
1401 { "(bad)", XX
, XX
, XX
},
1402 { "(bad)", XX
, XX
, XX
},
1404 { "(bad)", XX
, XX
, XX
},
1405 { "(bad)", XX
, XX
, XX
},
1406 { "(bad)", XX
, XX
, XX
},
1407 { "(bad)", XX
, XX
, XX
},
1408 { "(bad)", XX
, XX
, XX
},
1409 { "(bad)", XX
, XX
, XX
},
1410 { "(bad)", XX
, XX
, XX
},
1411 { "(bad)", XX
, XX
, XX
},
1413 { "push", RMrAX
, XX
, XX
},
1414 { "push", RMrCX
, XX
, XX
},
1415 { "push", RMrDX
, XX
, XX
},
1416 { "push", RMrBX
, XX
, XX
},
1417 { "push", RMrSP
, XX
, XX
},
1418 { "push", RMrBP
, XX
, XX
},
1419 { "push", RMrSI
, XX
, XX
},
1420 { "push", RMrDI
, XX
, XX
},
1422 { "pop", RMrAX
, XX
, XX
},
1423 { "pop", RMrCX
, XX
, XX
},
1424 { "pop", RMrDX
, XX
, XX
},
1425 { "pop", RMrBX
, XX
, XX
},
1426 { "pop", RMrSP
, XX
, XX
},
1427 { "pop", RMrBP
, XX
, XX
},
1428 { "pop", RMrSI
, XX
, XX
},
1429 { "pop", RMrDI
, XX
, XX
},
1431 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1432 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1433 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1434 { "movsx", Gv
, Ed
, XX
},
1435 { "(bad)", XX
, XX
, XX
}, /* seg fs */
1436 { "(bad)", XX
, XX
, XX
}, /* seg gs */
1437 { "(bad)", XX
, XX
, XX
}, /* op size prefix */
1438 { "(bad)", XX
, XX
, XX
}, /* adr size prefix */
1440 { "push", Iq
, XX
, XX
}, /* 386 book wrong */
1441 { "imul", Gv
, Ev
, Iv
},
1442 { "push", sIb
, XX
, XX
}, /* push of byte really pushes 2 or 4 bytes */
1443 { "imul", Gv
, Ev
, sIb
},
1444 { "ins", Yb
, indirDX
, XX
},
1445 { "ins", Yv
, indirDX
, XX
},
1446 { "outs", indirDX
, Xb
, XX
},
1447 { "outs", indirDX
, Xv
, XX
},
1449 { "jo", Jb
, XX
, XX
},
1450 { "jno", Jb
, XX
, XX
},
1451 { "jb", Jb
, XX
, XX
},
1452 { "jae", Jb
, XX
, XX
},
1453 { "je", Jb
, XX
, XX
},
1454 { "jne", Jb
, XX
, XX
},
1455 { "jbe", Jb
, XX
, XX
},
1456 { "ja", Jb
, XX
, XX
},
1458 { "js", Jb
, XX
, XX
},
1459 { "jns", Jb
, XX
, XX
},
1460 { "jp", Jb
, XX
, XX
},
1461 { "jnp", Jb
, XX
, XX
},
1462 { "jl", Jb
, XX
, XX
},
1463 { "jge", Jb
, XX
, XX
},
1464 { "jle", Jb
, XX
, XX
},
1465 { "jg", Jb
, XX
, XX
},
1469 { "(bad)", XX
, XX
, XX
},
1471 { "test", Eb
, Gb
, XX
},
1472 { "test", Ev
, Gv
, XX
},
1473 { "xchg", Eb
, Gb
, XX
},
1474 { "xchg", Ev
, Gv
, XX
},
1476 { "mov", Eb
, Gb
, XX
},
1477 { "mov", Ev
, Gv
, XX
},
1478 { "mov", Gb
, Eb
, XX
},
1479 { "mov", Gv
, Ev
, XX
},
1480 { "mov", Ev
, Sw
, XX
},
1481 { "lea", Gv
, M
, XX
},
1482 { "mov", Sw
, Ev
, XX
},
1483 { "pop", Ev
, XX
, XX
},
1485 { "nop", XX
, XX
, XX
},
1486 /* FIXME: NOP with REPz prefix is called PAUSE. */
1487 { "xchg", RMeCX
, eAX
, XX
},
1488 { "xchg", RMeDX
, eAX
, XX
},
1489 { "xchg", RMeBX
, eAX
, XX
},
1490 { "xchg", RMeSP
, eAX
, XX
},
1491 { "xchg", RMeBP
, eAX
, XX
},
1492 { "xchg", RMeSI
, eAX
, XX
},
1493 { "xchg", RMeDI
, eAX
, XX
},
1495 { "cW", XX
, XX
, XX
}, /* cwde and cbw */
1496 { "cR", XX
, XX
, XX
}, /* cdq and cwd */
1497 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1498 { "(bad)", XX
, XX
, XX
}, /* fwait */
1499 { "pushf", XX
, XX
, XX
},
1500 { "popf", XX
, XX
, XX
},
1501 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1502 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1504 { "mov", AL
, Ob
, XX
},
1505 { "mov", eAX
, Ov
, XX
},
1506 { "mov", Ob
, AL
, XX
},
1507 { "mov", Ov
, eAX
, XX
},
1508 { "movs", Yb
, Xb
, XX
},
1509 { "movs", Yv
, Xv
, XX
},
1510 { "cmps", Xb
, Yb
, XX
},
1511 { "cmps", Xv
, Yv
, XX
},
1513 { "test", AL
, Ib
, XX
},
1514 { "test", eAX
, Iv
, XX
},
1515 { "stos", Yb
, AL
, XX
},
1516 { "stos", Yv
, eAX
, XX
},
1517 { "lods", AL
, Xb
, XX
},
1518 { "lods", eAX
, Xv
, XX
},
1519 { "scas", AL
, Yb
, XX
},
1520 { "scas", eAX
, Yv
, XX
},
1522 { "mov", RMAL
, Ib
, XX
},
1523 { "mov", RMCL
, Ib
, XX
},
1524 { "mov", RMDL
, Ib
, XX
},
1525 { "mov", RMBL
, Ib
, XX
},
1526 { "mov", RMAH
, Ib
, XX
},
1527 { "mov", RMCH
, Ib
, XX
},
1528 { "mov", RMDH
, Ib
, XX
},
1529 { "mov", RMBH
, Ib
, XX
},
1531 { "mov", RMeAX
, Iv
, XX
},
1532 { "mov", RMeCX
, Iv
, XX
},
1533 { "mov", RMeDX
, Iv
, XX
},
1534 { "mov", RMeBX
, Iv
, XX
},
1535 { "mov", RMeSP
, Iv
, XX
},
1536 { "mov", RMeBP
, Iv
, XX
},
1537 { "mov", RMeSI
, Iv
, XX
},
1538 { "mov", RMeDI
, Iv
, XX
},
1542 { "ret", Iw
, XX
, XX
},
1543 { "ret", XX
, XX
, XX
},
1544 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1545 { "lds", Gv
, Mp
, XX
},
1546 { "mov", Eb
, Ib
, XX
},
1547 { "mov", Ev
, Iv
, XX
},
1549 { "enter", Iw
, Ib
, XX
},
1550 { "leave", XX
, XX
, XX
},
1551 { "lret", Iw
, XX
, XX
},
1552 { "lret", XX
, XX
, XX
},
1553 { "int3", XX
, XX
, XX
},
1554 { "int", Ib
, XX
, XX
},
1555 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1556 { "iret", XX
, XX
, XX
},
1562 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1563 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1564 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1565 { "xlat", DSBX
, XX
, XX
},
1576 { "loopne", Jb
, XX
, XX
},
1577 { "loope", Jb
, XX
, XX
},
1578 { "loop", Jb
, XX
, XX
},
1579 { "jEcxz", Jb
, XX
, XX
},
1580 { "in", AL
, Ib
, XX
},
1581 { "in", eAX
, Ib
, XX
},
1582 { "out", Ib
, AL
, XX
},
1583 { "out", Ib
, eAX
, XX
},
1585 { "call", Jv
, XX
, XX
},
1586 { "jmp", Jv
, XX
, XX
},
1587 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1588 { "jmp", Jb
, XX
, XX
},
1589 { "in", AL
, indirDX
, XX
},
1590 { "in", eAX
, indirDX
, XX
},
1591 { "out", indirDX
, AL
, XX
},
1592 { "out", indirDX
, eAX
, XX
},
1594 { "(bad)", XX
, XX
, XX
}, /* lock prefix */
1595 { "(bad)", XX
, XX
, XX
},
1596 { "(bad)", XX
, XX
, XX
}, /* repne */
1597 { "(bad)", XX
, XX
, XX
}, /* repz */
1598 { "hlt", XX
, XX
, XX
},
1599 { "cmc", XX
, XX
, XX
},
1603 { "clc", XX
, XX
, XX
},
1604 { "stc", XX
, XX
, XX
},
1605 { "cli", XX
, XX
, XX
},
1606 { "sti", XX
, XX
, XX
},
1607 { "cld", XX
, XX
, XX
},
1608 { "std", XX
, XX
, XX
},
1613 static const struct dis386 dis386_twobyte_att
[] = {
1617 { "larS", Gv
, Ew
, XX
},
1618 { "lslS", Gv
, Ew
, XX
},
1619 { "(bad)", XX
, XX
, XX
},
1620 { "syscall", XX
, XX
, XX
},
1621 { "clts", XX
, XX
, XX
},
1622 { "sysretP", XX
, XX
, XX
},
1624 { "invd", XX
, XX
, XX
},
1625 { "wbinvd", XX
, XX
, XX
},
1626 { "(bad)", XX
, XX
, XX
},
1627 { "ud2a", XX
, XX
, XX
},
1628 { "(bad)", XX
, XX
, XX
},
1630 { "femms", XX
, XX
, XX
},
1631 { "", MX
, EM
, OPSUF
}, /* See OP_3DNowSuffix */
1635 { "movlpX", XM
, EX
, SIMD_Fixup
, 'h' }, /* really only 2 operands */
1636 { "movlpX", EX
, XM
, SIMD_Fixup
, 'h' },
1637 { "unpcklpX", XM
, EX
, XX
},
1638 { "unpckhpX", XM
, EX
, XX
},
1639 { "movhpX", XM
, EX
, SIMD_Fixup
, 'l' },
1640 { "movhpX", EX
, XM
, SIMD_Fixup
, 'l' },
1643 { "(bad)", XX
, XX
, XX
},
1644 { "(bad)", XX
, XX
, XX
},
1645 { "(bad)", XX
, XX
, XX
},
1646 { "(bad)", XX
, XX
, XX
},
1647 { "(bad)", XX
, XX
, XX
},
1648 { "(bad)", XX
, XX
, XX
},
1649 { "(bad)", XX
, XX
, XX
},
1651 /* these are all backward in appendix A of the intel book */
1652 { "movL", Rm
, Cm
, XX
},
1653 { "movL", Rm
, Dm
, XX
},
1654 { "movL", Cm
, Rm
, XX
},
1655 { "movL", Dm
, Rm
, XX
},
1656 { "movL", Rd
, Td
, XX
},
1657 { "(bad)", XX
, XX
, XX
},
1658 { "movL", Td
, Rd
, XX
},
1659 { "(bad)", XX
, XX
, XX
},
1661 { "movapX", XM
, EX
, XX
},
1662 { "movapX", EX
, XM
, XX
},
1664 { "movntpX", Ev
, XM
, XX
},
1667 { "ucomisX", XM
,EX
, XX
},
1668 { "comisX", XM
,EX
, XX
},
1670 { "wrmsr", XX
, XX
, XX
},
1671 { "rdtsc", XX
, XX
, XX
},
1672 { "rdmsr", XX
, XX
, XX
},
1673 { "rdpmc", XX
, XX
, XX
},
1674 { "sysenter", XX
, XX
, XX
},
1675 { "sysexit", XX
, XX
, XX
},
1676 { "(bad)", XX
, XX
, XX
},
1677 { "(bad)", XX
, XX
, XX
},
1679 { "(bad)", XX
, XX
, XX
},
1680 { "(bad)", XX
, XX
, XX
},
1681 { "(bad)", XX
, XX
, XX
},
1682 { "(bad)", XX
, XX
, XX
},
1683 { "(bad)", XX
, XX
, XX
},
1684 { "(bad)", XX
, XX
, XX
},
1685 { "(bad)", XX
, XX
, XX
},
1686 { "(bad)", XX
, XX
, XX
},
1688 { "cmovo", Gv
, Ev
, XX
},
1689 { "cmovno", Gv
, Ev
, XX
},
1690 { "cmovb", Gv
, Ev
, XX
},
1691 { "cmovae", Gv
, Ev
, XX
},
1692 { "cmove", Gv
, Ev
, XX
},
1693 { "cmovne", Gv
, Ev
, XX
},
1694 { "cmovbe", Gv
, Ev
, XX
},
1695 { "cmova", Gv
, Ev
, XX
},
1697 { "cmovs", Gv
, Ev
, XX
},
1698 { "cmovns", Gv
, Ev
, XX
},
1699 { "cmovp", Gv
, Ev
, XX
},
1700 { "cmovnp", Gv
, Ev
, XX
},
1701 { "cmovl", Gv
, Ev
, XX
},
1702 { "cmovge", Gv
, Ev
, XX
},
1703 { "cmovle", Gv
, Ev
, XX
},
1704 { "cmovg", Gv
, Ev
, XX
},
1706 { "movmskpX", Gv
, EX
, XX
},
1710 { "andpX", XM
, EX
, XX
},
1711 { "andnpX", XM
, EX
, XX
},
1712 { "orpX", XM
, EX
, XX
},
1713 { "xorpX", XM
, EX
, XX
},
1724 { "punpcklbw", MX
, EM
, XX
},
1725 { "punpcklwd", MX
, EM
, XX
},
1726 { "punpckldq", MX
, EM
, XX
},
1727 { "packsswb", MX
, EM
, XX
},
1728 { "pcmpgtb", MX
, EM
, XX
},
1729 { "pcmpgtw", MX
, EM
, XX
},
1730 { "pcmpgtd", MX
, EM
, XX
},
1731 { "packuswb", MX
, EM
, XX
},
1733 { "punpckhbw", MX
, EM
, XX
},
1734 { "punpckhwd", MX
, EM
, XX
},
1735 { "punpckhdq", MX
, EM
, XX
},
1736 { "packssdw", MX
, EM
, XX
},
1737 { "(bad)", XX
, XX
, XX
},
1739 { "movd", MX
, Ed
, XX
},
1746 { "pcmpeqb", MX
, EM
, XX
},
1747 { "pcmpeqw", MX
, EM
, XX
},
1748 { "pcmpeqd", MX
, EM
, XX
},
1749 { "emms", XX
, XX
, XX
},
1751 { "(bad)", XX
, XX
, XX
},
1752 { "(bad)", XX
, XX
, XX
},
1753 { "(bad)", XX
, XX
, XX
},
1754 { "(bad)", XX
, XX
, XX
},
1755 { "(bad)", XX
, XX
, XX
},
1756 { "(bad)", XX
, XX
, XX
},
1760 { "jo", Jv
, XX
, XX
},
1761 { "jno", Jv
, XX
, XX
},
1762 { "jb", Jv
, XX
, XX
},
1763 { "jae", Jv
, XX
, XX
},
1764 { "je", Jv
, XX
, XX
},
1765 { "jne", Jv
, XX
, XX
},
1766 { "jbe", Jv
, XX
, XX
},
1767 { "ja", Jv
, XX
, XX
},
1769 { "js", Jv
, XX
, XX
},
1770 { "jns", Jv
, XX
, XX
},
1771 { "jp", Jv
, XX
, XX
},
1772 { "jnp", Jv
, XX
, XX
},
1773 { "jl", Jv
, XX
, XX
},
1774 { "jge", Jv
, XX
, XX
},
1775 { "jle", Jv
, XX
, XX
},
1776 { "jg", Jv
, XX
, XX
},
1778 { "seto", Eb
, XX
, XX
},
1779 { "setno", Eb
, XX
, XX
},
1780 { "setb", Eb
, XX
, XX
},
1781 { "setae", Eb
, XX
, XX
},
1782 { "sete", Eb
, XX
, XX
},
1783 { "setne", Eb
, XX
, XX
},
1784 { "setbe", Eb
, XX
, XX
},
1785 { "seta", Eb
, XX
, XX
},
1787 { "sets", Eb
, XX
, XX
},
1788 { "setns", Eb
, XX
, XX
},
1789 { "setp", Eb
, XX
, XX
},
1790 { "setnp", Eb
, XX
, XX
},
1791 { "setl", Eb
, XX
, XX
},
1792 { "setge", Eb
, XX
, XX
},
1793 { "setle", Eb
, XX
, XX
},
1794 { "setg", Eb
, XX
, XX
},
1796 { "pushI", fs
, XX
, XX
},
1797 { "popI", fs
, XX
, XX
},
1798 { "cpuid", XX
, XX
, XX
},
1799 { "btS", Ev
, Gv
, XX
},
1800 { "shldS", Ev
, Gv
, Ib
},
1801 { "shldS", Ev
, Gv
, CL
},
1802 { "(bad)", XX
, XX
, XX
},
1803 { "(bad)", XX
, XX
, XX
},
1805 { "pushI", gs
, XX
, XX
},
1806 { "popI", gs
, XX
, XX
},
1807 { "rsm", XX
, XX
, XX
},
1808 { "btsS", Ev
, Gv
, XX
},
1809 { "shrdS", Ev
, Gv
, Ib
},
1810 { "shrdS", Ev
, Gv
, CL
},
1812 { "imulS", Gv
, Ev
, XX
},
1814 { "cmpxchgB", Eb
, Gb
, XX
},
1815 { "cmpxchgS", Ev
, Gv
, XX
},
1816 { "lssS", Gv
, Mp
, XX
},
1817 { "btrS", Ev
, Gv
, XX
},
1818 { "lfsS", Gv
, Mp
, XX
},
1819 { "lgsS", Gv
, Mp
, XX
},
1820 { "movzbR", Gv
, Eb
, XX
},
1821 { "movzwR", Gv
, Ew
, XX
}, /* yes, there really is movzww ! */
1823 { "(bad)", XX
, XX
, XX
},
1824 { "ud2b", XX
, XX
, XX
},
1826 { "btcS", Ev
, Gv
, XX
},
1827 { "bsfS", Gv
, Ev
, XX
},
1828 { "bsrS", Gv
, Ev
, XX
},
1829 { "movsbR", Gv
, Eb
, XX
},
1830 { "movswR", Gv
, Ew
, XX
}, /* yes, there really is movsww ! */
1832 { "xaddB", Eb
, Gb
, XX
},
1833 { "xaddS", Ev
, Gv
, XX
},
1835 { "movntiS", Ev
, Gv
, XX
},
1836 { "pinsrw", MX
, Ev
, Ib
},
1837 { "pextrw", Ev
, MX
, Ib
},
1838 { "shufpX", XM
, EX
, Ib
},
1841 { "bswap", RMeAX
, XX
, XX
}, /* bswap doesn't support 16 bit regs */
1842 { "bswap", RMeCX
, XX
, XX
},
1843 { "bswap", RMeDX
, XX
, XX
},
1844 { "bswap", RMeBX
, XX
, XX
},
1845 { "bswap", RMeSP
, XX
, XX
},
1846 { "bswap", RMeBP
, XX
, XX
},
1847 { "bswap", RMeSI
, XX
, XX
},
1848 { "bswap", RMeDI
, XX
, XX
},
1850 { "(bad)", XX
, XX
, XX
},
1851 { "psrlw", MX
, EM
, XX
},
1852 { "psrld", MX
, EM
, XX
},
1853 { "psrlq", MX
, EM
, XX
},
1854 { "(bad)", XX
, XX
, XX
},
1855 { "pmullw", MX
, EM
, XX
},
1857 { "pmovmskb", Ev
, MX
, XX
},
1859 { "psubusb", MX
, EM
, XX
},
1860 { "psubusw", MX
, EM
, XX
},
1861 { "pminub", MX
, EM
, XX
},
1862 { "pand", MX
, EM
, XX
},
1863 { "paddusb", MX
, EM
, XX
},
1864 { "paddusw", MX
, EM
, XX
},
1865 { "pmaxub", MX
, EM
, XX
},
1866 { "pandn", MX
, EM
, XX
},
1868 { "pavgb", MX
, EM
, XX
},
1869 { "psraw", MX
, EM
, XX
},
1870 { "psrad", MX
, EM
, XX
},
1871 { "pavgw", MX
, EM
, XX
},
1872 { "pmulhuw", MX
, EM
, XX
},
1873 { "pmulhw", MX
, EM
, XX
},
1875 { "movntq", Ev
, MX
, XX
},
1877 { "psubsb", MX
, EM
, XX
},
1878 { "psubsw", MX
, EM
, XX
},
1879 { "pminsw", MX
, EM
, XX
},
1880 { "por", MX
, EM
, XX
},
1881 { "paddsb", MX
, EM
, XX
},
1882 { "paddsw", MX
, EM
, XX
},
1883 { "pmaxsw", MX
, EM
, XX
},
1884 { "pxor", MX
, EM
, XX
},
1886 { "(bad)", XX
, XX
, XX
},
1887 { "psllw", MX
, EM
, XX
},
1888 { "pslld", MX
, EM
, XX
},
1889 { "psllq", MX
, EM
, XX
},
1890 { "pmuludq", MX
, EM
, XX
},
1891 { "pmaddwd", MX
, EM
, XX
},
1892 { "psadbw", MX
, EM
, XX
},
1895 { "psubb", MX
, EM
, XX
},
1896 { "psubw", MX
, EM
, XX
},
1897 { "psubd", MX
, EM
, XX
},
1898 { "(bad)", XX
, XX
, XX
},
1899 { "paddb", MX
, EM
, XX
},
1900 { "paddw", MX
, EM
, XX
},
1901 { "paddd", MX
, EM
, XX
},
1902 { "(bad)", XX
, XX
, XX
}
1905 static const struct dis386 dis386_twobyte_intel
[] = {
1909 { "lar", Gv
, Ew
, XX
},
1910 { "lsl", Gv
, Ew
, XX
},
1911 { "(bad)", XX
, XX
, XX
},
1912 { "syscall", XX
, XX
, XX
},
1913 { "clts", XX
, XX
, XX
},
1914 { "sysretP", XX
, XX
, XX
},
1916 { "invd", XX
, XX
, XX
},
1917 { "wbinvd", XX
, XX
, XX
},
1918 { "(bad)", XX
, XX
, XX
},
1919 { "ud2a", XX
, XX
, XX
},
1920 { "(bad)", XX
, XX
, XX
},
1922 { "femms" , XX
, XX
, XX
},
1923 { "", MX
, EM
, OPSUF
}, /* See OP_3DNowSuffix */
1927 { "movlpX", XM
, EX
, SIMD_Fixup
, 'h' }, /* really only 2 operands */
1928 { "movlpX", EX
, XM
, SIMD_Fixup
, 'h' },
1929 { "unpcklpX", XM
, EX
, XX
},
1930 { "unpckhpX", XM
, EX
, XX
},
1931 { "movhpX", XM
, EX
, SIMD_Fixup
, 'l' },
1932 { "movhpX", EX
, XM
, SIMD_Fixup
, 'l' },
1935 { "(bad)", XX
, XX
, XX
},
1936 { "(bad)", XX
, XX
, XX
},
1937 { "(bad)", XX
, XX
, XX
},
1938 { "(bad)", XX
, XX
, XX
},
1939 { "(bad)", XX
, XX
, XX
},
1940 { "(bad)", XX
, XX
, XX
},
1941 { "(bad)", XX
, XX
, XX
},
1943 /* these are all backward in appendix A of the intel book */
1944 { "mov", Rm
, Cm
, XX
},
1945 { "mov", Rm
, Dm
, XX
},
1946 { "mov", Cm
, Rm
, XX
},
1947 { "mov", Dm
, Rm
, XX
},
1948 { "mov", Rd
, Td
, XX
},
1949 { "(bad)", XX
, XX
, XX
},
1950 { "mov", Td
, Rd
, XX
},
1951 { "(bad)", XX
, XX
, XX
},
1953 { "movapX", XM
, EX
, XX
},
1954 { "movapX", EX
, XM
, XX
},
1956 { "movntpX", Ev
, XM
, XX
},
1959 { "ucomisX", XM
,EX
, XX
},
1960 { "comisX", XM
,EX
, XX
},
1962 { "wrmsr", XX
, XX
, XX
},
1963 { "rdtsc", XX
, XX
, XX
},
1964 { "rdmsr", XX
, XX
, XX
},
1965 { "rdpmc", XX
, XX
, XX
},
1966 { "sysenter", XX
, XX
, XX
},
1967 { "sysexit", XX
, XX
, XX
},
1968 { "(bad)", XX
, XX
, XX
},
1969 { "(bad)", XX
, XX
, XX
},
1971 { "(bad)", XX
, XX
, XX
},
1972 { "(bad)", XX
, XX
, XX
},
1973 { "(bad)", XX
, XX
, XX
},
1974 { "(bad)", XX
, XX
, XX
},
1975 { "(bad)", XX
, XX
, XX
},
1976 { "(bad)", XX
, XX
, XX
},
1977 { "(bad)", XX
, XX
, XX
},
1978 { "(bad)", XX
, XX
, XX
},
1980 { "cmovo", Gv
, Ev
, XX
},
1981 { "cmovno", Gv
, Ev
, XX
},
1982 { "cmovb", Gv
, Ev
, XX
},
1983 { "cmovae", Gv
, Ev
, XX
},
1984 { "cmove", Gv
, Ev
, XX
},
1985 { "cmovne", Gv
, Ev
, XX
},
1986 { "cmovbe", Gv
, Ev
, XX
},
1987 { "cmova", Gv
, Ev
, XX
},
1989 { "cmovs", Gv
, Ev
, XX
},
1990 { "cmovns", Gv
, Ev
, XX
},
1991 { "cmovp", Gv
, Ev
, XX
},
1992 { "cmovnp", Gv
, Ev
, XX
},
1993 { "cmovl", Gv
, Ev
, XX
},
1994 { "cmovge", Gv
, Ev
, XX
},
1995 { "cmovle", Gv
, Ev
, XX
},
1996 { "cmovg", Gv
, Ev
, XX
},
1998 { "movmskpX", Gv
, EX
, XX
},
2002 { "andpX", XM
, EX
, XX
},
2003 { "andnpX", XM
, EX
, XX
},
2004 { "orpX", XM
, EX
, XX
},
2005 { "xorpX", XM
, EX
, XX
},
2016 { "punpcklbw", MX
, EM
, XX
},
2017 { "punpcklwd", MX
, EM
, XX
},
2018 { "punpckldq", MX
, EM
, XX
},
2019 { "packsswb", MX
, EM
, XX
},
2020 { "pcmpgtb", MX
, EM
, XX
},
2021 { "pcmpgtw", MX
, EM
, XX
},
2022 { "pcmpgtd", MX
, EM
, XX
},
2023 { "packuswb", MX
, EM
, XX
},
2025 { "punpckhbw", MX
, EM
, XX
},
2026 { "punpckhwd", MX
, EM
, XX
},
2027 { "punpckhdq", MX
, EM
, XX
},
2028 { "packssdw", MX
, EM
, XX
},
2029 { "(bad)", XX
, XX
, XX
},
2031 { "movd", MX
, Ed
, XX
},
2038 { "pcmpeqb", MX
, EM
, XX
},
2039 { "pcmpeqw", MX
, EM
, XX
},
2040 { "pcmpeqd", MX
, EM
, XX
},
2041 { "emms", XX
, XX
, XX
},
2043 { "(bad)", XX
, XX
, XX
},
2044 { "(bad)", XX
, XX
, XX
},
2045 { "(bad)", XX
, XX
, XX
},
2046 { "(bad)", XX
, XX
, XX
},
2047 { "(bad)", XX
, XX
, XX
},
2048 { "(bad)", XX
, XX
, XX
},
2052 { "jo", Jv
, XX
, XX
},
2053 { "jno", Jv
, XX
, XX
},
2054 { "jb", Jv
, XX
, XX
},
2055 { "jae", Jv
, XX
, XX
},
2056 { "je", Jv
, XX
, XX
},
2057 { "jne", Jv
, XX
, XX
},
2058 { "jbe", Jv
, XX
, XX
},
2059 { "ja", Jv
, XX
, XX
},
2061 { "js", Jv
, XX
, XX
},
2062 { "jns", Jv
, XX
, XX
},
2063 { "jp", Jv
, XX
, XX
},
2064 { "jnp", Jv
, XX
, XX
},
2065 { "jl", Jv
, XX
, XX
},
2066 { "jge", Jv
, XX
, XX
},
2067 { "jle", Jv
, XX
, XX
},
2068 { "jg", Jv
, XX
, XX
},
2070 { "seto", Eb
, XX
, XX
},
2071 { "setno", Eb
, XX
, XX
},
2072 { "setb", Eb
, XX
, XX
},
2073 { "setae", Eb
, XX
, XX
},
2074 { "sete", Eb
, XX
, XX
},
2075 { "setne", Eb
, XX
, XX
},
2076 { "setbe", Eb
, XX
, XX
},
2077 { "seta", Eb
, XX
, XX
},
2079 { "sets", Eb
, XX
, XX
},
2080 { "setns", Eb
, XX
, XX
},
2081 { "setp", Eb
, XX
, XX
},
2082 { "setnp", Eb
, XX
, XX
},
2083 { "setl", Eb
, XX
, XX
},
2084 { "setge", Eb
, XX
, XX
},
2085 { "setle", Eb
, XX
, XX
},
2086 { "setg", Eb
, XX
, XX
},
2088 { "push", fs
, XX
, XX
},
2089 { "pop", fs
, XX
, XX
},
2090 { "cpuid", XX
, XX
, XX
},
2091 { "bt", Ev
, Gv
, XX
},
2092 { "shld", Ev
, Gv
, Ib
},
2093 { "shld", Ev
, Gv
, CL
},
2094 { "(bad)", XX
, XX
, XX
},
2095 { "(bad)", XX
, XX
, XX
},
2097 { "push", gs
, XX
, XX
},
2098 { "pop", gs
, XX
, XX
},
2099 { "rsm" , XX
, XX
, XX
},
2100 { "bts", Ev
, Gv
, XX
},
2101 { "shrd", Ev
, Gv
, Ib
},
2102 { "shrd", Ev
, Gv
, CL
},
2104 { "imul", Gv
, Ev
, XX
},
2106 { "cmpxchg", Eb
, Gb
, XX
},
2107 { "cmpxchg", Ev
, Gv
, XX
},
2108 { "lss", Gv
, Mp
, XX
},
2109 { "btr", Ev
, Gv
, XX
},
2110 { "lfs", Gv
, Mp
, XX
},
2111 { "lgs", Gv
, Mp
, XX
},
2112 { "movzx", Gv
, Eb
, XX
},
2113 { "movzx", Gv
, Ew
, XX
},
2115 { "(bad)", XX
, XX
, XX
},
2116 { "ud2b", XX
, XX
, XX
},
2118 { "btc", Ev
, Gv
, XX
},
2119 { "bsf", Gv
, Ev
, XX
},
2120 { "bsr", Gv
, Ev
, XX
},
2121 { "movsx", Gv
, Eb
, XX
},
2122 { "movsx", Gv
, Ew
, XX
},
2124 { "xadd", Eb
, Gb
, XX
},
2125 { "xadd", Ev
, Gv
, XX
},
2127 { "movnti", Ev
, Gv
, XX
},
2128 { "pinsrw", MX
, Ev
, Ib
},
2129 { "pextrw", Ev
, MX
, Ib
},
2130 { "shufpX", XM
, EX
, Ib
},
2133 { "bswap", RMeAX
, XX
, XX
}, /* bswap doesn't support 16 bit regs */
2134 { "bswap", RMeCX
, XX
, XX
},
2135 { "bswap", RMeDX
, XX
, XX
},
2136 { "bswap", RMeBX
, XX
, XX
},
2137 { "bswap", RMeSP
, XX
, XX
},
2138 { "bswap", RMeBP
, XX
, XX
},
2139 { "bswap", RMeSI
, XX
, XX
},
2140 { "bswap", RMeDI
, XX
, XX
},
2142 { "(bad)", XX
, XX
, XX
},
2143 { "psrlw", MX
, EM
, XX
},
2144 { "psrld", MX
, EM
, XX
},
2145 { "psrlq", MX
, EM
, XX
},
2146 { "(bad)", XX
, XX
, XX
},
2147 { "pmullw", MX
, EM
, XX
},
2149 { "pmovmskb", Ev
, MX
, XX
},
2151 { "psubusb", MX
, EM
, XX
},
2152 { "psubusw", MX
, EM
, XX
},
2153 { "pminub", MX
, EM
, XX
},
2154 { "pand", MX
, EM
, XX
},
2155 { "paddusb", MX
, EM
, XX
},
2156 { "paddusw", MX
, EM
, XX
},
2157 { "pmaxub", MX
, EM
, XX
},
2158 { "pandn", MX
, EM
, XX
},
2160 { "pavgb", MX
, EM
, XX
},
2161 { "psraw", MX
, EM
, XX
},
2162 { "psrad", MX
, EM
, XX
},
2163 { "pavgw", MX
, EM
, XX
},
2164 { "pmulhuw", MX
, EM
, XX
},
2165 { "pmulhw", MX
, EM
, XX
},
2167 { "movntq", Ev
, MX
, XX
},
2169 { "psubsb", MX
, EM
, XX
},
2170 { "psubsw", MX
, EM
, XX
},
2171 { "pminsw", MX
, EM
, XX
},
2172 { "por", MX
, EM
, XX
},
2173 { "paddsb", MX
, EM
, XX
},
2174 { "paddsw", MX
, EM
, XX
},
2175 { "pmaxsw", MX
, EM
, XX
},
2176 { "pxor", MX
, EM
, XX
},
2178 { "(bad)", XX
, XX
, XX
},
2179 { "psllw", MX
, EM
, XX
},
2180 { "pslld", MX
, EM
, XX
},
2181 { "psllq", MX
, EM
, XX
},
2182 { "pmuludq", MX
, EM
, XX
},
2183 { "pmaddwd", MX
, EM
, XX
},
2184 { "psadbw", MX
, EM
, XX
},
2187 { "psubb", MX
, EM
, XX
},
2188 { "psubw", MX
, EM
, XX
},
2189 { "psubd", MX
, EM
, XX
},
2190 { "(bad)", XX
, XX
, XX
},
2191 { "paddb", MX
, EM
, XX
},
2192 { "paddw", MX
, EM
, XX
},
2193 { "paddd", MX
, EM
, XX
},
2194 { "(bad)", XX
, XX
, XX
}
2197 static const unsigned char onebyte_has_modrm
[256] = {
2198 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2199 /* ------------------------------- */
2200 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
2201 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
2202 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
2203 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
2204 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
2205 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
2206 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
2207 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
2208 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
2209 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
2210 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
2211 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
2212 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
2213 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
2214 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
2215 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
2216 /* ------------------------------- */
2217 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2220 static const unsigned char twobyte_has_modrm
[256] = {
2221 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2222 /* ------------------------------- */
2223 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
2224 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
2225 /* 20 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 2f */
2226 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
2227 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
2228 /* 50 */ 1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1, /* 5f */
2229 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
2230 /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
2231 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
2232 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
2233 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
2234 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
2235 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
2236 /* d0 */ 0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, /* df */
2237 /* e0 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* ef */
2238 /* f0 */ 0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0 /* ff */
2239 /* ------------------------------- */
2240 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2243 static const unsigned char twobyte_uses_SSE_prefix
[256] = {
2244 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2245 /* ------------------------------- */
2246 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
2247 /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
2248 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
2249 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
2250 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
2251 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
2252 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
2253 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
2254 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
2255 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
2256 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
2257 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
2258 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
2259 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
2260 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
2261 /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
2262 /* ------------------------------- */
2263 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2266 static char obuf
[100];
2268 static char scratchbuf
[100];
2269 static unsigned char *start_codep
;
2270 static unsigned char *insn_codep
;
2271 static unsigned char *codep
;
2272 static disassemble_info
*the_info
;
2276 static void oappend
PARAMS ((const char *s
));
2278 static const char *names64
[] = {
2279 "%rax","%rcx","%rdx","%rbx", "%rsp","%rbp","%rsi","%rdi",
2280 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
2282 static const char *names32
[] = {
2283 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
2284 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
2286 static const char *names16
[] = {
2287 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
2288 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
2290 static const char *names8
[] = {
2291 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
2293 static const char *names8rex
[] = {
2294 "%al","%cl","%dl","%bl","%spl", "%bpl", "%sil", "%dil",
2295 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
2297 static const char *names_seg
[] = {
2298 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
2300 static const char *index16
[] = {
2301 "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx"
2304 static const struct dis386 grps
[][8] = {
2307 { "addA", Eb
, Ib
, XX
},
2308 { "orA", Eb
, Ib
, XX
},
2309 { "adcA", Eb
, Ib
, XX
},
2310 { "sbbA", Eb
, Ib
, XX
},
2311 { "andA", Eb
, Ib
, XX
},
2312 { "subA", Eb
, Ib
, XX
},
2313 { "xorA", Eb
, Ib
, XX
},
2314 { "cmpA", Eb
, Ib
, XX
}
2318 { "addQ", Ev
, Iv
, XX
},
2319 { "orQ", Ev
, Iv
, XX
},
2320 { "adcQ", Ev
, Iv
, XX
},
2321 { "sbbQ", Ev
, Iv
, XX
},
2322 { "andQ", Ev
, Iv
, XX
},
2323 { "subQ", Ev
, Iv
, XX
},
2324 { "xorQ", Ev
, Iv
, XX
},
2325 { "cmpQ", Ev
, Iv
, XX
}
2329 { "addQ", Ev
, sIb
, XX
},
2330 { "orQ", Ev
, sIb
, XX
},
2331 { "adcQ", Ev
, sIb
, XX
},
2332 { "sbbQ", Ev
, sIb
, XX
},
2333 { "andQ", Ev
, sIb
, XX
},
2334 { "subQ", Ev
, sIb
, XX
},
2335 { "xorQ", Ev
, sIb
, XX
},
2336 { "cmpQ", Ev
, sIb
, XX
}
2340 { "rolA", Eb
, Ib
, XX
},
2341 { "rorA", Eb
, Ib
, XX
},
2342 { "rclA", Eb
, Ib
, XX
},
2343 { "rcrA", Eb
, Ib
, XX
},
2344 { "shlA", Eb
, Ib
, XX
},
2345 { "shrA", Eb
, Ib
, XX
},
2346 { "(bad)", XX
, XX
, XX
},
2347 { "sarA", Eb
, Ib
, XX
},
2351 { "rolQ", Ev
, Ib
, XX
},
2352 { "rorQ", Ev
, Ib
, XX
},
2353 { "rclQ", Ev
, Ib
, XX
},
2354 { "rcrQ", Ev
, Ib
, XX
},
2355 { "shlQ", Ev
, Ib
, XX
},
2356 { "shrQ", Ev
, Ib
, XX
},
2357 { "(bad)", XX
, XX
, XX
},
2358 { "sarQ", Ev
, Ib
, XX
},
2362 { "rolA", Eb
, XX
, XX
},
2363 { "rorA", Eb
, XX
, XX
},
2364 { "rclA", Eb
, XX
, XX
},
2365 { "rcrA", Eb
, XX
, XX
},
2366 { "shlA", Eb
, XX
, XX
},
2367 { "shrA", Eb
, XX
, XX
},
2368 { "(bad)", XX
, XX
, XX
},
2369 { "sarA", Eb
, XX
, XX
},
2373 { "rolQ", Ev
, XX
, XX
},
2374 { "rorQ", Ev
, XX
, XX
},
2375 { "rclQ", Ev
, XX
, XX
},
2376 { "rcrQ", Ev
, XX
, XX
},
2377 { "shlQ", Ev
, XX
, XX
},
2378 { "shrQ", Ev
, XX
, XX
},
2379 { "(bad)", XX
, XX
, XX
},
2380 { "sarQ", Ev
, XX
, XX
},
2384 { "rolA", Eb
, CL
, XX
},
2385 { "rorA", Eb
, CL
, XX
},
2386 { "rclA", Eb
, CL
, XX
},
2387 { "rcrA", Eb
, CL
, XX
},
2388 { "shlA", Eb
, CL
, XX
},
2389 { "shrA", Eb
, CL
, XX
},
2390 { "(bad)", XX
, XX
, XX
},
2391 { "sarA", Eb
, CL
, XX
},
2395 { "rolQ", Ev
, CL
, XX
},
2396 { "rorQ", Ev
, CL
, XX
},
2397 { "rclQ", Ev
, CL
, XX
},
2398 { "rcrQ", Ev
, CL
, XX
},
2399 { "shlQ", Ev
, CL
, XX
},
2400 { "shrQ", Ev
, CL
, XX
},
2401 { "(bad)", XX
, XX
, XX
},
2402 { "sarQ", Ev
, CL
, XX
}
2406 { "testA", Eb
, Ib
, XX
},
2407 { "(bad)", Eb
, XX
, XX
},
2408 { "notA", Eb
, XX
, XX
},
2409 { "negA", Eb
, XX
, XX
},
2410 { "mulB", AL
, Eb
, XX
},
2411 { "imulB", AL
, Eb
, XX
},
2412 { "divB", AL
, Eb
, XX
},
2413 { "idivB", AL
, Eb
, XX
}
2417 { "testQ", Ev
, Iv
, XX
},
2418 { "(bad)", XX
, XX
, XX
},
2419 { "notQ", Ev
, XX
, XX
},
2420 { "negQ", Ev
, XX
, XX
},
2421 { "mulS", eAX
, Ev
, XX
},
2422 { "imulS", eAX
, Ev
, XX
},
2423 { "divS", eAX
, Ev
, XX
},
2424 { "idivS", eAX
, Ev
, XX
},
2428 { "incA", Eb
, XX
, XX
},
2429 { "decA", Eb
, XX
, XX
},
2430 { "(bad)", XX
, XX
, XX
},
2431 { "(bad)", XX
, XX
, XX
},
2432 { "(bad)", XX
, XX
, XX
},
2433 { "(bad)", XX
, XX
, XX
},
2434 { "(bad)", XX
, XX
, XX
},
2435 { "(bad)", XX
, XX
, XX
},
2439 { "incQ", Ev
, XX
, XX
},
2440 { "decQ", Ev
, XX
, XX
},
2441 { "callI", indirEv
, XX
, XX
},
2442 { "lcallI", indirEv
, XX
, XX
},
2443 { "jmpI", indirEv
, XX
, XX
},
2444 { "ljmpI", indirEv
, XX
, XX
},
2445 { "pushQ", Ev
, XX
, XX
},
2446 { "(bad)", XX
, XX
, XX
},
2450 { "sldt", Ew
, XX
, XX
},
2451 { "str", Ew
, XX
, XX
},
2452 { "lldt", Ew
, XX
, XX
},
2453 { "ltr", Ew
, XX
, XX
},
2454 { "verr", Ew
, XX
, XX
},
2455 { "verw", Ew
, XX
, XX
},
2456 { "(bad)", XX
, XX
, XX
},
2457 { "(bad)", XX
, XX
, XX
}
2461 { "sgdt", Ew
, XX
, XX
},
2462 { "sidt", Ew
, XX
, XX
},
2463 { "lgdt", Ew
, XX
, XX
},
2464 { "lidt", Ew
, XX
, XX
},
2465 { "smsw", Ew
, XX
, XX
},
2466 { "(bad)", XX
, XX
, XX
},
2467 { "lmsw", Ew
, XX
, XX
},
2468 { "invlpg", Ew
, XX
, XX
},
2472 { "(bad)", XX
, XX
, XX
},
2473 { "(bad)", XX
, XX
, XX
},
2474 { "(bad)", XX
, XX
, XX
},
2475 { "(bad)", XX
, XX
, XX
},
2476 { "btQ", Ev
, Ib
, XX
},
2477 { "btsQ", Ev
, Ib
, XX
},
2478 { "btrQ", Ev
, Ib
, XX
},
2479 { "btcQ", Ev
, Ib
, XX
},
2483 { "(bad)", XX
, XX
, XX
},
2484 { "cmpxchg8b", Ev
, XX
, XX
},
2485 { "(bad)", XX
, XX
, XX
},
2486 { "(bad)", XX
, XX
, XX
},
2487 { "(bad)", XX
, XX
, XX
},
2488 { "(bad)", XX
, XX
, XX
},
2489 { "(bad)", XX
, XX
, XX
},
2490 { "(bad)", XX
, XX
, XX
},
2494 { "(bad)", XX
, XX
, XX
},
2495 { "(bad)", XX
, XX
, XX
},
2496 { "psrlw", MS
, Ib
, XX
},
2497 { "(bad)", XX
, XX
, XX
},
2498 { "psraw", MS
, Ib
, XX
},
2499 { "(bad)", XX
, XX
, XX
},
2500 { "psllw", MS
, Ib
, XX
},
2501 { "(bad)", XX
, XX
, XX
},
2505 { "(bad)", XX
, XX
, XX
},
2506 { "(bad)", XX
, XX
, XX
},
2507 { "psrld", MS
, Ib
, XX
},
2508 { "(bad)", XX
, XX
, XX
},
2509 { "psrad", MS
, Ib
, XX
},
2510 { "(bad)", XX
, XX
, XX
},
2511 { "pslld", MS
, Ib
, XX
},
2512 { "(bad)", XX
, XX
, XX
},
2516 { "(bad)", XX
, XX
, XX
},
2517 { "(bad)", XX
, XX
, XX
},
2518 { "psrlq", MS
, Ib
, XX
},
2519 { "psrldq", MS
, Ib
, XX
},
2520 { "(bad)", XX
, XX
, XX
},
2521 { "(bad)", XX
, XX
, XX
},
2522 { "psllq", MS
, Ib
, XX
},
2523 { "pslldq", MS
, Ib
, XX
},
2527 { "fxsave", Ev
, XX
, XX
},
2528 { "fxrstor", Ev
, XX
, XX
},
2529 { "ldmxcsr", Ev
, XX
, XX
},
2530 { "stmxcsr", Ev
, XX
, XX
},
2531 { "(bad)", XX
, XX
, XX
},
2532 { "lfence", None
, XX
, XX
},
2533 { "mfence", None
, XX
, XX
},
2534 { "sfence", None
, XX
, XX
},
2535 /* FIXME: the sfence with memory operand is clflush! */
2539 { "prefetchnta", Ev
, XX
, XX
},
2540 { "prefetcht0", Ev
, XX
, XX
},
2541 { "prefetcht1", Ev
, XX
, XX
},
2542 { "prefetcht2", Ev
, XX
, XX
},
2543 { "(bad)", XX
, XX
, XX
},
2544 { "(bad)", XX
, XX
, XX
},
2545 { "(bad)", XX
, XX
, XX
},
2546 { "(bad)", XX
, XX
, XX
},
2550 { "prefetch", Eb
, XX
, XX
},
2551 { "prefetchw", Eb
, XX
, XX
},
2552 { "(bad)", XX
, XX
, XX
},
2553 { "(bad)", XX
, XX
, XX
},
2554 { "(bad)", XX
, XX
, XX
},
2555 { "(bad)", XX
, XX
, XX
},
2556 { "(bad)", XX
, XX
, XX
},
2557 { "(bad)", XX
, XX
, XX
},
2562 static const struct dis386 prefix_user_table
[][4] = {
2565 { "addps", XM
, EX
, XX
},
2566 { "addss", XM
, EX
, XX
},
2567 { "addpd", XM
, EX
, XX
},
2568 { "addsd", XM
, EX
, XX
},
2572 { "", XM
, EX
, OPSIMD
}, /* See OP_SIMD_SUFFIX */
2573 { "", XM
, EX
, OPSIMD
},
2574 { "", XM
, EX
, OPSIMD
},
2575 { "", XM
, EX
, OPSIMD
},
2579 { "cvtpi2ps", XM
, EM
, XX
},
2580 { "cvtsi2ss", XM
, Ev
, XX
},
2581 { "cvtpi2pd", XM
, EM
, XX
},
2582 { "cvtsi2sd", XM
, Ev
, XX
},
2586 { "cvtps2pi", MX
, EX
, XX
},
2587 { "cvtss2si", Gv
, EX
, XX
},
2588 { "cvtpd2pi", MX
, EX
, XX
},
2589 { "cvtsd2si", Gv
, EX
, XX
},
2593 { "cvttps2pi", MX
, EX
, XX
},
2594 { "cvttss2si", Gv
, EX
, XX
},
2595 { "cvttpd2pi", MX
, EX
, XX
},
2596 { "cvttsd2si", Gv
, EX
, XX
},
2600 { "divps", XM
, EX
, XX
},
2601 { "divss", XM
, EX
, XX
},
2602 { "divpd", XM
, EX
, XX
},
2603 { "divsd", XM
, EX
, XX
},
2607 { "maxps", XM
, EX
, XX
},
2608 { "maxss", XM
, EX
, XX
},
2609 { "maxpd", XM
, EX
, XX
},
2610 { "maxsd", XM
, EX
, XX
},
2614 { "minps", XM
, EX
, XX
},
2615 { "minss", XM
, EX
, XX
},
2616 { "minpd", XM
, EX
, XX
},
2617 { "minsd", XM
, EX
, XX
},
2621 { "movups", XM
, EX
, XX
},
2622 { "movss", XM
, EX
, XX
},
2623 { "movupd", XM
, EX
, XX
},
2624 { "movsd", XM
, EX
, XX
},
2628 { "movups", EX
, XM
, XX
},
2629 { "movss", EX
, XM
, XX
},
2630 { "movupd", EX
, XM
, XX
},
2631 { "movsd", EX
, XM
, XX
},
2635 { "mulps", XM
, EX
, XX
},
2636 { "mulss", XM
, EX
, XX
},
2637 { "mulpd", XM
, EX
, XX
},
2638 { "mulsd", XM
, EX
, XX
},
2642 { "rcpps", XM
, EX
, XX
},
2643 { "rcpss", XM
, EX
, XX
},
2644 { "(bad)", XM
, EX
, XX
},
2645 { "(bad)", XM
, EX
, XX
},
2649 { "rsqrtps", XM
, EX
, XX
},
2650 { "rsqrtss", XM
, EX
, XX
},
2651 { "(bad)", XM
, EX
, XX
},
2652 { "(bad)", XM
, EX
, XX
},
2656 { "sqrtps", XM
, EX
, XX
},
2657 { "sqrtss", XM
, EX
, XX
},
2658 { "sqrtpd", XM
, EX
, XX
},
2659 { "sqrtsd", XM
, EX
, XX
},
2663 { "subps", XM
, EX
, XX
},
2664 { "subss", XM
, EX
, XX
},
2665 { "subpd", XM
, EX
, XX
},
2666 { "subsd", XM
, EX
, XX
},
2670 { "(bad)", XM
, EX
, XX
},
2671 { "cvtdq2pd", XM
, EX
, XX
},
2672 { "cvttpd2dq", XM
, EX
, XX
},
2673 { "cvtpd2dq", XM
, EX
, XX
},
2677 { "cvtdq2ps", XM
, EX
, XX
},
2678 { "cvttps2dq",XM
, EX
, XX
},
2679 { "cvtps2dq",XM
, EX
, XX
},
2680 { "(bad)", XM
, EX
, XX
},
2684 { "cvtps2pd", XM
, EX
, XX
},
2685 { "cvtss2sd", XM
, EX
, XX
},
2686 { "cvtpd2ps", XM
, EX
, XX
},
2687 { "cvtsd2ss", XM
, EX
, XX
},
2691 { "maskmovq", MX
, EM
, XX
},
2692 { "(bad)", XM
, EX
, XX
},
2693 { "maskmovdqu", MX
, EX
, XX
},
2694 { "(bad)", XM
, EX
, XX
},
2698 { "movq", MX
, EM
, XX
},
2699 { "movdqu", XM
, EX
, XX
},
2700 { "movdqa", XM
, EX
, XX
},
2701 { "(bad)", XM
, EX
, XX
},
2705 { "movq", EM
, MX
, XX
},
2706 { "movdqu", EX
, XM
, XX
},
2707 { "movdqa", EX
, XM
, XX
},
2708 { "(bad)", EX
, XM
, XX
},
2712 { "(bad)", EX
, XM
, XX
},
2713 { "movq2dq", EX
, EM
, XX
},
2714 { "movq", EX
, XM
, XX
},
2715 { "movdq2q", EM
, MX
, XX
},
2719 { "pshufw", MX
, EM
, Ib
},
2720 { "pshufhw", XM
, EX
, Ib
},
2721 { "pshufd", XM
, EX
, Ib
},
2722 { "pshuflw", XM
, EX
, Ib
},
2726 { "movd", Ed
, MX
, XX
},
2727 { "movq", Ed
, XM
, XX
},
2728 { "movd", Ed
, XM
, XX
},
2729 { "(bad)", EX
, XM
, XX
},
2733 { "(bad)", EX
, XM
, XX
},
2734 { "(bad)", EX
, XM
, XX
},
2735 { "punpckhqdq", XM
, EX
, XX
},
2736 { "(bad)", EX
, XM
, XX
},
2740 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
2752 FETCH_DATA (the_info
, codep
+ 1);
2756 /* REX prefixes family. */
2779 prefixes
|= PREFIX_REPZ
;
2782 prefixes
|= PREFIX_REPNZ
;
2785 prefixes
|= PREFIX_LOCK
;
2788 prefixes
|= PREFIX_CS
;
2791 prefixes
|= PREFIX_SS
;
2794 prefixes
|= PREFIX_DS
;
2797 prefixes
|= PREFIX_ES
;
2800 prefixes
|= PREFIX_FS
;
2803 prefixes
|= PREFIX_GS
;
2806 prefixes
|= PREFIX_DATA
;
2809 prefixes
|= PREFIX_ADDR
;
2812 /* fwait is really an instruction. If there are prefixes
2813 before the fwait, they belong to the fwait, *not* to the
2814 following instruction. */
2817 prefixes
|= PREFIX_FWAIT
;
2821 prefixes
= PREFIX_FWAIT
;
2826 /* Rex is ignored when followed by another prefix. */
2829 oappend (prefix_name (rex
, 0));
2837 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
2841 prefix_name (pref
, sizeflag
)
2847 /* REX prefixes family. */
2899 return (sizeflag
& DFLAG
) ? "data16" : "data32";
2901 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
2909 static char op1out
[100], op2out
[100], op3out
[100];
2910 static int op_ad
, op_index
[3];
2911 static unsigned int op_address
[3];
2912 static unsigned int op_riprel
[3];
2913 static bfd_vma start_pc
;
2917 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
2918 * (see topic "Redundant prefixes" in the "Differences from 8086"
2919 * section of the "Virtual 8086 Mode" chapter.)
2920 * 'pc' should be the address of this instruction, it will
2921 * be used to print the target address if this is a relative jump or call
2922 * The function returns the length of this instruction in bytes.
2925 static int print_insn_i386
2926 PARAMS ((bfd_vma pc
, disassemble_info
*info
));
2928 static char intel_syntax
;
2929 static char open_char
;
2930 static char close_char
;
2931 static char separator_char
;
2932 static char scale_char
;
2935 print_insn_i386_att (pc
, info
)
2937 disassemble_info
*info
;
2942 separator_char
= ',';
2945 return print_insn_i386 (pc
, info
);
2949 print_insn_i386_intel (pc
, info
)
2951 disassemble_info
*info
;
2956 separator_char
= '+';
2959 return print_insn_i386 (pc
, info
);
2963 print_insn_i386 (pc
, info
)
2965 disassemble_info
*info
;
2967 const struct dis386
*dp
;
2970 char *first
, *second
, *third
;
2972 unsigned char need_modrm
;
2973 unsigned char uses_SSE_prefix
;
2974 VOLATILE
int sizeflag
;
2975 VOLATILE
int orig_sizeflag
;
2977 struct dis_private priv
;
2978 bfd_byte
*inbuf
= priv
.the_buffer
;
2980 mode_64bit
= (info
->mach
== bfd_mach_x86_64_intel_syntax
2981 || info
->mach
== bfd_mach_x86_64
);
2983 if (info
->mach
== bfd_mach_i386_i386
2984 || info
->mach
== bfd_mach_x86_64
2985 || info
->mach
== bfd_mach_i386_i386_intel_syntax
2986 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
2987 sizeflag
= AFLAG
|DFLAG
;
2988 else if (info
->mach
== bfd_mach_i386_i8086
)
2992 orig_sizeflag
= sizeflag
;
2994 /* The output looks better if we put 7 bytes on a line, since that
2995 puts most long word instructions on a single line. */
2996 info
->bytes_per_line
= 7;
2998 info
->private_data
= (PTR
) &priv
;
2999 priv
.max_fetched
= priv
.the_buffer
;
3000 priv
.insn_start
= pc
;
3007 op_index
[0] = op_index
[1] = op_index
[2] = -1;
3011 start_codep
= inbuf
;
3014 if (setjmp (priv
.bailout
) != 0)
3018 /* Getting here means we tried for data but didn't get it. That
3019 means we have an incomplete instruction of some sort. Just
3020 print the first byte as a prefix or a .byte pseudo-op. */
3023 name
= prefix_name (inbuf
[0], orig_sizeflag
);
3025 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3028 /* Just print the first byte as a .byte instruction. */
3029 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
3030 (unsigned int) inbuf
[0]);
3044 FETCH_DATA (info
, codep
+ 1);
3045 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
3047 if ((prefixes
& PREFIX_FWAIT
)
3048 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
3052 /* fwait not followed by floating point instruction. Print the
3053 first prefix, which is probably fwait itself. */
3054 name
= prefix_name (inbuf
[0], orig_sizeflag
);
3056 name
= INTERNAL_DISASSEMBLER_ERROR
;
3057 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3063 FETCH_DATA (info
, codep
+ 2);
3065 dp
= &dis386_twobyte_intel
[*++codep
];
3067 dp
= &dis386_twobyte_att
[*++codep
];
3068 need_modrm
= twobyte_has_modrm
[*codep
];
3069 uses_SSE_prefix
= twobyte_uses_SSE_prefix
[*codep
];
3075 dp
= &dis386_64_intel
[*codep
];
3077 dp
= &dis386_intel
[*codep
];
3080 dp
= &disx86_64_att
[*codep
];
3082 dp
= &dis386_att
[*codep
];
3083 need_modrm
= onebyte_has_modrm
[*codep
];
3084 uses_SSE_prefix
= 0;
3088 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_REPZ
))
3091 used_prefixes
|= PREFIX_REPZ
;
3093 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_REPNZ
))
3096 used_prefixes
|= PREFIX_REPNZ
;
3098 if (prefixes
& PREFIX_LOCK
)
3101 used_prefixes
|= PREFIX_LOCK
;
3104 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_DATA
))
3107 if (prefixes
& PREFIX_ADDR
)
3110 if (sizeflag
& AFLAG
)
3111 oappend ("addr32 ");
3113 oappend ("addr16 ");
3114 used_prefixes
|= PREFIX_ADDR
;
3119 FETCH_DATA (info
, codep
+ 1);
3120 mod
= (*codep
>> 6) & 3;
3121 reg
= (*codep
>> 3) & 7;
3125 if (dp
->name
== NULL
&& dp
->bytemode1
== FLOATCODE
)
3132 if (dp
->name
== NULL
)
3134 switch(dp
->bytemode2
)
3137 dp
= &grps
[dp
->bytemode1
][reg
];
3139 case USE_PREFIX_USER_TABLE
:
3141 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
3142 if (prefixes
& PREFIX_REPZ
)
3146 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3147 if (prefixes
& PREFIX_DATA
)
3151 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
3152 if (prefixes
& PREFIX_REPNZ
)
3157 dp
= &prefix_user_table
[dp
->bytemode1
][index
];
3160 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3165 putop (dp
->name
, sizeflag
);
3170 (*dp
->op1
)(dp
->bytemode1
, sizeflag
);
3175 (*dp
->op2
)(dp
->bytemode2
, sizeflag
);
3180 (*dp
->op3
)(dp
->bytemode3
, sizeflag
);
3183 /* See if any prefixes were not used. If so, print the first one
3184 separately. If we don't do this, we'll wind up printing an
3185 instruction stream which does not precisely correspond to the
3186 bytes we are disassembling. */
3187 if ((prefixes
& ~used_prefixes
) != 0)
3191 name
= prefix_name (inbuf
[0], orig_sizeflag
);
3193 name
= INTERNAL_DISASSEMBLER_ERROR
;
3194 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3197 if (rex
& ~rex_used
)
3200 name
= prefix_name (rex
| 0x40, orig_sizeflag
);
3202 name
= INTERNAL_DISASSEMBLER_ERROR
;
3203 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
3206 obufp
= obuf
+ strlen (obuf
);
3207 for (i
= strlen (obuf
); i
< 6; i
++)
3210 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
3212 /* The enter and bound instructions are printed with operands in the same
3213 order as the intel book; everything else is printed in reverse order. */
3214 if (intel_syntax
|| two_source_ops
)
3219 op_ad
= op_index
[0];
3220 op_index
[0] = op_index
[2];
3221 op_index
[2] = op_ad
;
3232 if (op_index
[0] != -1 && !op_riprel
[0])
3233 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[0]], info
);
3235 (*info
->fprintf_func
) (info
->stream
, "%s", first
);
3241 (*info
->fprintf_func
) (info
->stream
, ",");
3242 if (op_index
[1] != -1 && !op_riprel
[1])
3243 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[1]], info
);
3245 (*info
->fprintf_func
) (info
->stream
, "%s", second
);
3251 (*info
->fprintf_func
) (info
->stream
, ",");
3252 if (op_index
[2] != -1 && !op_riprel
[2])
3253 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[2]], info
);
3255 (*info
->fprintf_func
) (info
->stream
, "%s", third
);
3257 for (i
= 0; i
< 3; i
++)
3258 if (op_index
[i
] != -1 && op_riprel
[i
])
3260 (*info
->fprintf_func
) (info
->stream
, " # ");
3261 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
3262 + op_address
[op_index
[i
]]), info
);
3264 return codep
- inbuf
;
3267 static const char *float_mem_att
[] = {
3342 static const char *float_mem_intel
[] = {
3418 #define STi OP_STi, 0
3420 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
3421 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
3422 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
3423 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
3424 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
3425 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
3426 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
3427 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
3428 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
3430 static const struct dis386 float_reg
[][8] = {
3433 { "fadd", ST
, STi
, XX
},
3434 { "fmul", ST
, STi
, XX
},
3435 { "fcom", STi
, XX
, XX
},
3436 { "fcomp", STi
, XX
, XX
},
3437 { "fsub", ST
, STi
, XX
},
3438 { "fsubr", ST
, STi
, XX
},
3439 { "fdiv", ST
, STi
, XX
},
3440 { "fdivr", ST
, STi
, XX
},
3444 { "fld", STi
, XX
, XX
},
3445 { "fxch", STi
, XX
, XX
},
3447 { "(bad)", XX
, XX
, XX
},
3455 { "fcmovb", ST
, STi
, XX
},
3456 { "fcmove", ST
, STi
, XX
},
3457 { "fcmovbe",ST
, STi
, XX
},
3458 { "fcmovu", ST
, STi
, XX
},
3459 { "(bad)", XX
, XX
, XX
},
3461 { "(bad)", XX
, XX
, XX
},
3462 { "(bad)", XX
, XX
, XX
},
3466 { "fcmovnb",ST
, STi
, XX
},
3467 { "fcmovne",ST
, STi
, XX
},
3468 { "fcmovnbe",ST
, STi
, XX
},
3469 { "fcmovnu",ST
, STi
, XX
},
3471 { "fucomi", ST
, STi
, XX
},
3472 { "fcomi", ST
, STi
, XX
},
3473 { "(bad)", XX
, XX
, XX
},
3477 { "fadd", STi
, ST
, XX
},
3478 { "fmul", STi
, ST
, XX
},
3479 { "(bad)", XX
, XX
, XX
},
3480 { "(bad)", XX
, XX
, XX
},
3482 { "fsub", STi
, ST
, XX
},
3483 { "fsubr", STi
, ST
, XX
},
3484 { "fdiv", STi
, ST
, XX
},
3485 { "fdivr", STi
, ST
, XX
},
3487 { "fsubr", STi
, ST
, XX
},
3488 { "fsub", STi
, ST
, XX
},
3489 { "fdivr", STi
, ST
, XX
},
3490 { "fdiv", STi
, ST
, XX
},
3495 { "ffree", STi
, XX
, XX
},
3496 { "(bad)", XX
, XX
, XX
},
3497 { "fst", STi
, XX
, XX
},
3498 { "fstp", STi
, XX
, XX
},
3499 { "fucom", STi
, XX
, XX
},
3500 { "fucomp", STi
, XX
, XX
},
3501 { "(bad)", XX
, XX
, XX
},
3502 { "(bad)", XX
, XX
, XX
},
3506 { "faddp", STi
, ST
, XX
},
3507 { "fmulp", STi
, ST
, XX
},
3508 { "(bad)", XX
, XX
, XX
},
3511 { "fsubp", STi
, ST
, XX
},
3512 { "fsubrp", STi
, ST
, XX
},
3513 { "fdivp", STi
, ST
, XX
},
3514 { "fdivrp", STi
, ST
, XX
},
3516 { "fsubrp", STi
, ST
, XX
},
3517 { "fsubp", STi
, ST
, XX
},
3518 { "fdivrp", STi
, ST
, XX
},
3519 { "fdivp", STi
, ST
, XX
},
3524 { "(bad)", XX
, XX
, XX
},
3525 { "(bad)", XX
, XX
, XX
},
3526 { "(bad)", XX
, XX
, XX
},
3527 { "(bad)", XX
, XX
, XX
},
3529 { "fucomip",ST
, STi
, XX
},
3530 { "fcomip", ST
, STi
, XX
},
3531 { "(bad)", XX
, XX
, XX
},
3536 static char *fgrps
[][8] = {
3539 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3544 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
3549 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
3554 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
3559 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
3564 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3569 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
3570 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
3575 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3580 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3588 const struct dis386
*dp
;
3589 unsigned char floatop
;
3591 floatop
= codep
[-1];
3596 putop (float_mem_intel
[(floatop
- 0xd8 ) * 8 + reg
], sizeflag
);
3598 putop (float_mem_att
[(floatop
- 0xd8 ) * 8 + reg
], sizeflag
);
3600 if (floatop
== 0xdb)
3601 OP_E (x_mode
, sizeflag
);
3602 else if (floatop
== 0xdd)
3603 OP_E (d_mode
, sizeflag
);
3605 OP_E (v_mode
, sizeflag
);
3610 dp
= &float_reg
[floatop
- 0xd8][reg
];
3611 if (dp
->name
== NULL
)
3613 putop (fgrps
[dp
->bytemode1
][rm
], sizeflag
);
3615 /* instruction fnstsw is only one with strange arg */
3616 if (floatop
== 0xdf && codep
[-1] == 0xe0)
3617 strcpy (op1out
, names16
[0]);
3621 putop (dp
->name
, sizeflag
);
3625 (*dp
->op1
)(dp
->bytemode1
, sizeflag
);
3628 (*dp
->op2
)(dp
->bytemode2
, sizeflag
);
3634 OP_ST (ignore
, sizeflag
)
3635 int ignore ATTRIBUTE_UNUSED
;
3636 int sizeflag ATTRIBUTE_UNUSED
;
3643 OP_STi (ignore
, sizeflag
)
3644 int ignore ATTRIBUTE_UNUSED
;
3645 int sizeflag ATTRIBUTE_UNUSED
;
3647 sprintf (scratchbuf
, "%%st(%d)", rm
);
3648 oappend (scratchbuf
);
3652 /* capital letters in template are macros */
3654 putop (template, sizeflag
)
3655 const char *template;
3660 for (p
= template; *p
; p
++)
3671 #ifdef SUFFIX_ALWAYS
3672 || (sizeflag
& SUFFIX_ALWAYS
)
3680 #ifdef SUFFIX_ALWAYS
3681 if (sizeflag
& SUFFIX_ALWAYS
)
3685 case 'E': /* For jcxz/jecxz */
3686 if (sizeflag
& AFLAG
)
3692 #ifdef SUFFIX_ALWAYS
3693 if (sizeflag
& SUFFIX_ALWAYS
)
3698 if ((prefixes
& PREFIX_FWAIT
) == 0)
3701 used_prefixes
|= PREFIX_FWAIT
;
3704 USED_REX (REX_MODE64
);
3705 if (rex
& REX_MODE64
)
3713 if ((prefixes
& PREFIX_DATA
)
3714 || (rex
& REX_MODE64
)
3715 #ifdef SUFFIX_ALWAYS
3716 || (sizeflag
& SUFFIX_ALWAYS
)
3720 USED_REX (REX_MODE64
);
3721 if (rex
& REX_MODE64
)
3725 if (sizeflag
& DFLAG
)
3729 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3734 USED_REX (REX_MODE64
);
3738 #ifdef SUFFIX_ALWAYS
3739 || (sizeflag
& SUFFIX_ALWAYS
)
3743 if (rex
& REX_MODE64
)
3747 if (sizeflag
& DFLAG
)
3751 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3756 USED_REX (REX_MODE64
);
3759 if (rex
& REX_MODE64
)
3764 else if (sizeflag
& DFLAG
)
3777 if (rex
& REX_MODE64
)
3779 else if (sizeflag
& DFLAG
)
3784 if (!(rex
& REX_MODE64
))
3785 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3790 #ifdef SUFFIX_ALWAYS
3791 if (sizeflag
& SUFFIX_ALWAYS
)
3793 if (rex
& REX_MODE64
)
3797 if (sizeflag
& DFLAG
)
3801 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3807 if (prefixes
& PREFIX_DATA
)
3811 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3813 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
3819 if ((prefixes
& PREFIX_DATA
)
3820 #ifdef SUFFIX_ALWAYS
3821 || (sizeflag
& SUFFIX_ALWAYS
)
3825 if (sizeflag
& DFLAG
)
3829 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3834 /* operand size flag for cwtl, cbtw */
3838 else if (sizeflag
& DFLAG
)
3849 if (sizeflag
& DFLAG
)
3860 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3872 obufp
+= strlen (s
);
3878 if (prefixes
& PREFIX_CS
)
3881 used_prefixes
|= PREFIX_CS
;
3883 if (prefixes
& PREFIX_DS
)
3886 used_prefixes
|= PREFIX_DS
;
3888 if (prefixes
& PREFIX_SS
)
3891 used_prefixes
|= PREFIX_SS
;
3893 if (prefixes
& PREFIX_ES
)
3896 used_prefixes
|= PREFIX_ES
;
3898 if (prefixes
& PREFIX_FS
)
3901 used_prefixes
|= PREFIX_FS
;
3903 if (prefixes
& PREFIX_GS
)
3906 used_prefixes
|= PREFIX_GS
;
3911 OP_indirE (bytemode
, sizeflag
)
3917 OP_E (bytemode
, sizeflag
);
3921 print_operand_value (buf
, hex
, disp
)
3934 sprintf_vma (tmp
, disp
);
3935 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+1]; i
++);
3936 strcpy (buf
+ 2, tmp
+ i
);
3940 bfd_signed_vma v
= disp
;
3947 /* Check for possible overflow on 0x8000000000000000 */
3950 strcpy (buf
, "9223372036854775808");
3964 tmp
[28-i
] = (v
% 10) + '0';
3968 strcpy (buf
, tmp
+ 29 - i
);
3974 sprintf (buf
, "0x%x", (unsigned int) disp
);
3976 sprintf (buf
, "%d", (int) disp
);
3981 OP_E (bytemode
, sizeflag
)
3988 USED_REX (REX_EXTZ
);
3992 /* skip mod/rm byte */
4002 oappend (names8rex
[rm
+ add
]);
4004 oappend (names8
[rm
+ add
]);
4007 oappend (names16
[rm
+ add
]);
4010 oappend (names32
[rm
+ add
]);
4013 oappend (names64
[rm
+ add
]);
4017 oappend (names64
[rm
+ add
]);
4019 oappend (names32
[rm
+ add
]);
4022 USED_REX (REX_MODE64
);
4023 if (rex
& REX_MODE64
)
4024 oappend (names64
[rm
+ add
]);
4025 else if (sizeflag
& DFLAG
)
4026 oappend (names32
[rm
+ add
]);
4028 oappend (names16
[rm
+ add
]);
4029 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4032 if ( !(codep
[-2] == 0xAE && codep
[-1] == 0xF8 /* sfence */)
4033 && !(codep
[-2] == 0xAE && codep
[-1] == 0xF0 /* mfence */)
4034 && !(codep
[-2] == 0xAE && codep
[-1] == 0xe8 /* lfence */))
4035 BadOp(); /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */
4038 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4047 if (sizeflag
& AFLAG
) /* 32 bit address mode */
4062 FETCH_DATA (the_info
, codep
+ 1);
4063 scale
= (*codep
>> 6) & 3;
4064 index
= (*codep
>> 3) & 7;
4066 USED_REX (REX_EXTY
);
4067 USED_REX (REX_EXTZ
);
4078 if ((base
& 7) == 5)
4081 if (mode_64bit
&& !havesib
)
4087 FETCH_DATA (the_info
, codep
+ 1);
4089 if ((disp
& 0x80) != 0)
4098 if (mod
!= 0 || (base
& 7) == 5)
4100 print_operand_value (scratchbuf
, !riprel
, disp
);
4101 oappend (scratchbuf
);
4109 if (havebase
|| (havesib
&& (index
!= 4 || scale
!= 0)))
4116 oappend ("BYTE PTR ");
4119 oappend ("WORD PTR ");
4122 oappend ("DWORD PTR ");
4125 oappend ("QWORD PTR ");
4129 oappend ("DWORD PTR ");
4131 oappend ("QWORD PTR ");
4134 oappend ("XWORD PTR ");
4140 *obufp
++ = open_char
;
4141 if (intel_syntax
&& riprel
)
4144 USED_REX (REX_EXTZ
);
4145 if (!havesib
&& (rex
& REX_EXTZ
))
4148 oappend (mode_64bit
? names64
[base
] : names32
[base
]);
4157 *obufp
++ = separator_char
;
4160 sprintf (scratchbuf
, "%s", mode_64bit
? names64
[index
] : names32
[index
]);
4163 sprintf (scratchbuf
, ",%s", mode_64bit
? names64
[index
] : names32
[index
]);
4164 oappend (scratchbuf
);
4168 && bytemode
!= b_mode
4169 && bytemode
!= w_mode
4170 && bytemode
!= v_mode
))
4172 *obufp
++ = scale_char
;
4174 sprintf (scratchbuf
, "%d", 1 << scale
);
4175 oappend (scratchbuf
);
4179 if (mod
!= 0 || (base
& 7) == 5)
4181 /* Don't print zero displacements */
4184 print_operand_value (scratchbuf
, 0, disp
);
4185 oappend (scratchbuf
);
4189 *obufp
++ = close_char
;
4192 else if (intel_syntax
)
4194 if (mod
!= 0 || (base
& 7) == 5)
4196 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4197 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
4201 oappend (names_seg
[3]);
4204 print_operand_value (scratchbuf
, 1, disp
);
4205 oappend (scratchbuf
);
4210 { /* 16 bit address mode */
4217 if ((disp
& 0x8000) != 0)
4222 FETCH_DATA (the_info
, codep
+ 1);
4224 if ((disp
& 0x80) != 0)
4229 if ((disp
& 0x8000) != 0)
4235 if (mod
!= 0 || (rm
& 7) == 6)
4237 print_operand_value (scratchbuf
, 0, disp
);
4238 oappend (scratchbuf
);
4241 if (mod
!= 0 || (rm
& 7) != 6)
4243 *obufp
++ = open_char
;
4245 oappend (index16
[rm
+ add
]);
4246 *obufp
++ = close_char
;
4253 OP_G (bytemode
, sizeflag
)
4258 USED_REX (REX_EXTX
);
4266 oappend (names8rex
[reg
+ add
]);
4268 oappend (names8
[reg
+ add
]);
4271 oappend (names16
[reg
+ add
]);
4274 oappend (names32
[reg
+ add
]);
4277 oappend (names64
[reg
+ add
]);
4280 USED_REX (REX_MODE64
);
4281 if (rex
& REX_MODE64
)
4282 oappend (names64
[reg
+ add
]);
4283 else if (sizeflag
& DFLAG
)
4284 oappend (names32
[reg
+ add
]);
4286 oappend (names16
[reg
+ add
]);
4287 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4290 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4303 FETCH_DATA (the_info
, codep
+ 8);
4304 a
= *codep
++ & 0xff;
4305 a
|= (*codep
++ & 0xff) << 8;
4306 a
|= (*codep
++ & 0xff) << 16;
4307 a
|= (*codep
++ & 0xff) << 24;
4308 b
|= (*codep
++ & 0xff);
4309 b
|= (*codep
++ & 0xff) << 8;
4310 b
|= (*codep
++ & 0xff) << 16;
4311 b
|= (*codep
++ & 0xff) << 24;
4312 x
= a
+ ((bfd_vma
) b
<< 32);
4319 static bfd_signed_vma
4322 bfd_signed_vma x
= 0;
4324 FETCH_DATA (the_info
, codep
+ 4);
4325 x
= *codep
++ & (bfd_signed_vma
) 0xff;
4326 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
4327 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
4328 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
4332 static bfd_signed_vma
4335 bfd_signed_vma x
= 0;
4337 FETCH_DATA (the_info
, codep
+ 4);
4338 x
= *codep
++ & (bfd_signed_vma
) 0xff;
4339 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
4340 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
4341 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
4343 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
4353 FETCH_DATA (the_info
, codep
+ 2);
4354 x
= *codep
++ & 0xff;
4355 x
|= (*codep
++ & 0xff) << 8;
4364 op_index
[op_ad
] = op_ad
;
4365 op_address
[op_ad
] = op
;
4366 op_riprel
[op_ad
] = riprel
;
4370 OP_REG (code
, sizeflag
)
4376 USED_REX (REX_EXTZ
);
4385 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
4386 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
4387 s
= names16
[code
- ax_reg
+ add
];
4389 case es_reg
: case ss_reg
: case cs_reg
:
4390 case ds_reg
: case fs_reg
: case gs_reg
:
4391 s
= names_seg
[code
- es_reg
+ add
];
4393 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
4394 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
4397 s
= names8rex
[code
- al_reg
+ add
];
4399 s
= names8
[code
- al_reg
];
4401 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
4402 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
4403 USED_REX (REX_MODE64
);
4404 if (rex
& REX_MODE64
)
4405 s
= names64
[code
- eAX_reg
+ add
];
4406 else if (sizeflag
& DFLAG
)
4407 s
= names32
[code
- eAX_reg
+ add
];
4409 s
= names16
[code
- eAX_reg
+ add
];
4410 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4412 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
4413 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
4414 s
= names64
[code
- rAX_reg
+ add
];
4417 s
= INTERNAL_DISASSEMBLER_ERROR
;
4424 OP_IMREG (code
, sizeflag
)
4435 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
4436 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
4437 s
= names16
[code
- ax_reg
];
4439 case es_reg
: case ss_reg
: case cs_reg
:
4440 case ds_reg
: case fs_reg
: case gs_reg
:
4441 s
= names_seg
[code
- es_reg
];
4443 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
4444 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
4447 s
= names8rex
[code
- al_reg
];
4449 s
= names8
[code
- al_reg
];
4451 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
4452 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
4453 USED_REX (REX_MODE64
);
4454 if (rex
& REX_MODE64
)
4455 s
= names64
[code
- eAX_reg
];
4456 else if (sizeflag
& DFLAG
)
4457 s
= names32
[code
- eAX_reg
];
4459 s
= names16
[code
- eAX_reg
];
4460 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4463 s
= INTERNAL_DISASSEMBLER_ERROR
;
4470 OP_I (bytemode
, sizeflag
)
4475 bfd_signed_vma mask
= -1;
4480 FETCH_DATA (the_info
, codep
+ 1);
4488 USED_REX (REX_MODE64
);
4489 if (rex
& REX_MODE64
)
4491 else if (sizeflag
& DFLAG
)
4501 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4508 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4513 scratchbuf
[0] = '$';
4514 print_operand_value (scratchbuf
+ !intel_syntax
, 1, op
);
4515 oappend (scratchbuf
);
4516 scratchbuf
[0] = '\0';
4520 OP_I64 (bytemode
, sizeflag
)
4525 bfd_signed_vma mask
= -1;
4530 FETCH_DATA (the_info
, codep
+ 1);
4535 USED_REX (REX_MODE64
);
4536 if (rex
& REX_MODE64
)
4538 else if (sizeflag
& DFLAG
)
4548 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4555 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4560 scratchbuf
[0] = '$';
4561 print_operand_value (scratchbuf
+ !intel_syntax
, 1, op
);
4562 oappend (scratchbuf
);
4563 scratchbuf
[0] = '\0';
4567 OP_sI (bytemode
, sizeflag
)
4572 bfd_signed_vma mask
= -1;
4577 FETCH_DATA (the_info
, codep
+ 1);
4579 if ((op
& 0x80) != 0)
4584 USED_REX (REX_MODE64
);
4585 if (rex
& REX_MODE64
)
4587 else if (sizeflag
& DFLAG
)
4596 if ((op
& 0x8000) != 0)
4599 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4604 if ((op
& 0x8000) != 0)
4608 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4612 scratchbuf
[0] = '$';
4613 print_operand_value (scratchbuf
+ 1, 1, op
);
4614 oappend (scratchbuf
);
4618 OP_J (bytemode
, sizeflag
)
4628 FETCH_DATA (the_info
, codep
+ 1);
4630 if ((disp
& 0x80) != 0)
4634 if (sizeflag
& DFLAG
)
4639 /* for some reason, a data16 prefix on a jump instruction
4640 means that the pc is masked to 16 bits after the
4641 displacement is added! */
4644 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4647 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4650 disp
= (start_pc
+ codep
- start_codep
+ disp
) & mask
;
4652 print_operand_value (scratchbuf
, 1, disp
);
4653 oappend (scratchbuf
);
4658 OP_SEG (dummy
, sizeflag
)
4659 int dummy ATTRIBUTE_UNUSED
;
4660 int sizeflag ATTRIBUTE_UNUSED
;
4662 static char *sreg
[] = {
4663 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
4666 oappend (sreg
[reg
]);
4671 OP_DIR (dummy
, sizeflag
)
4672 int dummy ATTRIBUTE_UNUSED
;
4677 if (sizeflag
& DFLAG
)
4687 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4688 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
4689 oappend (scratchbuf
);
4694 OP_OFF (ignored
, sizeflag
)
4695 int ignored ATTRIBUTE_UNUSED
;
4702 if (sizeflag
& AFLAG
)
4709 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4710 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4712 oappend (names_seg
[3]);
4716 print_operand_value (scratchbuf
, 1, off
);
4717 oappend (scratchbuf
);
4721 OP_OFF64 (ignored
, sizeflag
)
4722 int ignored ATTRIBUTE_UNUSED
;
4723 int sizeflag ATTRIBUTE_UNUSED
;
4733 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4734 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4736 oappend (names_seg
[3]);
4740 print_operand_value (scratchbuf
, 1, off
);
4741 oappend (scratchbuf
);
4745 ptr_reg (code
, sizeflag
)
4751 USED_REX (REX_MODE64
);
4752 if (rex
& REX_MODE64
)
4753 s
= names64
[code
- eAX_reg
];
4754 else if (sizeflag
& AFLAG
)
4755 s
= names32
[code
- eAX_reg
];
4757 s
= names16
[code
- eAX_reg
];
4763 OP_ESreg (code
, sizeflag
)
4768 ptr_reg (code
, sizeflag
);
4772 OP_DSreg (code
, sizeflag
)
4783 prefixes
|= PREFIX_DS
;
4785 ptr_reg (code
, sizeflag
);
4790 OP_C (dummy
, sizeflag
)
4791 int dummy ATTRIBUTE_UNUSED
;
4792 int sizeflag ATTRIBUTE_UNUSED
;
4795 USED_REX (REX_EXTX
);
4798 sprintf (scratchbuf
, "%%cr%d", reg
+add
);
4799 oappend (scratchbuf
);
4804 OP_D (dummy
, sizeflag
)
4805 int dummy ATTRIBUTE_UNUSED
;
4806 int sizeflag ATTRIBUTE_UNUSED
;
4809 USED_REX (REX_EXTX
);
4812 sprintf (scratchbuf
, "%%db%d", reg
+add
);
4813 oappend (scratchbuf
);
4818 OP_T (dummy
, sizeflag
)
4819 int dummy ATTRIBUTE_UNUSED
;
4820 int sizeflag ATTRIBUTE_UNUSED
;
4822 sprintf (scratchbuf
, "%%tr%d", reg
);
4823 oappend (scratchbuf
);
4827 OP_Rd (bytemode
, sizeflag
)
4832 OP_E (bytemode
, sizeflag
);
4838 OP_MMX (ignore
, sizeflag
)
4839 int ignore ATTRIBUTE_UNUSED
;
4840 int sizeflag ATTRIBUTE_UNUSED
;
4843 USED_REX (REX_EXTX
);
4846 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4847 if (prefixes
& PREFIX_DATA
)
4848 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
4850 sprintf (scratchbuf
, "%%mm%d", reg
+ add
);
4851 oappend (scratchbuf
);
4855 OP_XMM (bytemode
, sizeflag
)
4856 int bytemode ATTRIBUTE_UNUSED
;
4857 int sizeflag ATTRIBUTE_UNUSED
;
4860 USED_REX (REX_EXTX
);
4863 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
4864 oappend (scratchbuf
);
4868 OP_EM (bytemode
, sizeflag
)
4875 OP_E (bytemode
, sizeflag
);
4878 USED_REX (REX_EXTZ
);
4883 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4884 if (prefixes
& PREFIX_DATA
)
4885 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
4887 sprintf (scratchbuf
, "%%mm%d", rm
+ add
);
4888 oappend (scratchbuf
);
4892 OP_EX (bytemode
, sizeflag
)
4899 OP_E (bytemode
, sizeflag
);
4902 USED_REX (REX_EXTZ
);
4907 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
4908 oappend (scratchbuf
);
4912 OP_MS (bytemode
, sizeflag
)
4917 OP_EM (bytemode
, sizeflag
);
4922 static const char *Suffix3DNow
[] = {
4923 /* 00 */ NULL
, NULL
, NULL
, NULL
,
4924 /* 04 */ NULL
, NULL
, NULL
, NULL
,
4925 /* 08 */ NULL
, NULL
, NULL
, NULL
,
4926 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
4927 /* 10 */ NULL
, NULL
, NULL
, NULL
,
4928 /* 14 */ NULL
, NULL
, NULL
, NULL
,
4929 /* 18 */ NULL
, NULL
, NULL
, NULL
,
4930 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
4931 /* 20 */ NULL
, NULL
, NULL
, NULL
,
4932 /* 24 */ NULL
, NULL
, NULL
, NULL
,
4933 /* 28 */ NULL
, NULL
, NULL
, NULL
,
4934 /* 2C */ NULL
, NULL
, NULL
, NULL
,
4935 /* 30 */ NULL
, NULL
, NULL
, NULL
,
4936 /* 34 */ NULL
, NULL
, NULL
, NULL
,
4937 /* 38 */ NULL
, NULL
, NULL
, NULL
,
4938 /* 3C */ NULL
, NULL
, NULL
, NULL
,
4939 /* 40 */ NULL
, NULL
, NULL
, NULL
,
4940 /* 44 */ NULL
, NULL
, NULL
, NULL
,
4941 /* 48 */ NULL
, NULL
, NULL
, NULL
,
4942 /* 4C */ NULL
, NULL
, NULL
, NULL
,
4943 /* 50 */ NULL
, NULL
, NULL
, NULL
,
4944 /* 54 */ NULL
, NULL
, NULL
, NULL
,
4945 /* 58 */ NULL
, NULL
, NULL
, NULL
,
4946 /* 5C */ NULL
, NULL
, NULL
, NULL
,
4947 /* 60 */ NULL
, NULL
, NULL
, NULL
,
4948 /* 64 */ NULL
, NULL
, NULL
, NULL
,
4949 /* 68 */ NULL
, NULL
, NULL
, NULL
,
4950 /* 6C */ NULL
, NULL
, NULL
, NULL
,
4951 /* 70 */ NULL
, NULL
, NULL
, NULL
,
4952 /* 74 */ NULL
, NULL
, NULL
, NULL
,
4953 /* 78 */ NULL
, NULL
, NULL
, NULL
,
4954 /* 7C */ NULL
, NULL
, NULL
, NULL
,
4955 /* 80 */ NULL
, NULL
, NULL
, NULL
,
4956 /* 84 */ NULL
, NULL
, NULL
, NULL
,
4957 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
4958 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
4959 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
4960 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
4961 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
4962 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
4963 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
4964 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
4965 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
4966 /* AC */ NULL
, NULL
, "pfacc", NULL
,
4967 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
4968 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pfmulhrw",
4969 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
4970 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
4971 /* C0 */ NULL
, NULL
, NULL
, NULL
,
4972 /* C4 */ NULL
, NULL
, NULL
, NULL
,
4973 /* C8 */ NULL
, NULL
, NULL
, NULL
,
4974 /* CC */ NULL
, NULL
, NULL
, NULL
,
4975 /* D0 */ NULL
, NULL
, NULL
, NULL
,
4976 /* D4 */ NULL
, NULL
, NULL
, NULL
,
4977 /* D8 */ NULL
, NULL
, NULL
, NULL
,
4978 /* DC */ NULL
, NULL
, NULL
, NULL
,
4979 /* E0 */ NULL
, NULL
, NULL
, NULL
,
4980 /* E4 */ NULL
, NULL
, NULL
, NULL
,
4981 /* E8 */ NULL
, NULL
, NULL
, NULL
,
4982 /* EC */ NULL
, NULL
, NULL
, NULL
,
4983 /* F0 */ NULL
, NULL
, NULL
, NULL
,
4984 /* F4 */ NULL
, NULL
, NULL
, NULL
,
4985 /* F8 */ NULL
, NULL
, NULL
, NULL
,
4986 /* FC */ NULL
, NULL
, NULL
, NULL
,
4990 OP_3DNowSuffix (bytemode
, sizeflag
)
4991 int bytemode ATTRIBUTE_UNUSED
;
4992 int sizeflag ATTRIBUTE_UNUSED
;
4994 const char *mnemonic
;
4996 FETCH_DATA (the_info
, codep
+ 1);
4997 /* AMD 3DNow! instructions are specified by an opcode suffix in the
4998 place where an 8-bit immediate would normally go. ie. the last
4999 byte of the instruction. */
5000 obufp
= obuf
+ strlen(obuf
);
5001 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
5006 /* Since a variable sized modrm/sib chunk is between the start
5007 of the opcode (0x0f0f) and the opcode suffix, we need to do
5008 all the modrm processing first, and don't know until now that
5009 we have a bad opcode. This necessitates some cleaning up. */
5017 static const char *simd_cmp_op
[] = {
5029 OP_SIMD_Suffix (bytemode
, sizeflag
)
5030 int bytemode ATTRIBUTE_UNUSED
;
5031 int sizeflag ATTRIBUTE_UNUSED
;
5033 unsigned int cmp_type
;
5035 FETCH_DATA (the_info
, codep
+ 1);
5036 obufp
= obuf
+ strlen(obuf
);
5037 cmp_type
= *codep
++ & 0xff;
5040 char suffix1
= 'p', suffix2
= 's';
5041 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
5042 if (prefixes
& PREFIX_REPZ
)
5046 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5047 if (prefixes
& PREFIX_DATA
)
5051 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
5052 if (prefixes
& PREFIX_REPNZ
)
5053 suffix1
= 's', suffix2
= 'd';
5056 sprintf (scratchbuf
, "cmp%s%c%c",
5057 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
5058 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
5059 oappend (scratchbuf
);
5063 /* We have a bad extension byte. Clean up. */
5071 SIMD_Fixup (extrachar
, sizeflag
)
5073 int sizeflag ATTRIBUTE_UNUSED
;
5075 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
5076 forms of these instructions. */
5079 char *p
= obuf
+ strlen(obuf
);
5088 static void BadOp (void)
5090 codep
= insn_codep
+ 1; /* throw away prefixes and 1st. opcode byte */