1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4 Free Software Foundation, Inc.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
25 * modified by John Hassey (hassey@dg-rtp.dg.com)
26 * x86-64 support added by Jan Hubicka (jh@suse.cz)
30 * The main tables describing the instructions is essentially a copy
31 * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
32 * Programmers Manual. Usually, there is a capital letter, followed
33 * by a small letter. The capital letter tell the addressing mode,
34 * and the small letter tells about the operand size. Refer to
35 * the Intel manual for details.
46 #ifndef UNIXWARE_COMPAT
47 /* Set non-zero for broken, compatible instructions. Set to zero for
48 non-broken opcodes. */
49 #define UNIXWARE_COMPAT 1
52 static int fetch_data
PARAMS ((struct disassemble_info
*, bfd_byte
*));
56 /* Points to first byte not fetched. */
57 bfd_byte
*max_fetched
;
58 bfd_byte the_buffer
[MAXLEN
];
63 /* The opcode for the fwait instruction, which we treat as a prefix
65 #define FWAIT_OPCODE (0x9b)
67 /* Set to 1 for 64bit mode disassembly. */
68 static int mode_64bit
;
70 /* Flags for the prefixes for the current instruction. See below. */
73 /* REX prefix the current instruction. See below. */
75 /* Bits of REX we've already used. */
81 /* Mark parts used in the REX prefix. When we are testing for
82 empty prefix (for 8bit register REX extension), just mask it
83 out. Otherwise test for REX bit is excuse for existence of REX
84 only in case value is nonzero. */
85 #define USED_REX(value) \
88 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
93 /* Flags for prefixes which we somehow handled when printing the
94 current instruction. */
95 static int used_prefixes
;
97 /* Flags stored in PREFIXES. */
99 #define PREFIX_REPNZ 2
100 #define PREFIX_LOCK 4
102 #define PREFIX_SS 0x10
103 #define PREFIX_DS 0x20
104 #define PREFIX_ES 0x40
105 #define PREFIX_FS 0x80
106 #define PREFIX_GS 0x100
107 #define PREFIX_DATA 0x200
108 #define PREFIX_ADDR 0x400
109 #define PREFIX_FWAIT 0x800
111 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
112 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
114 #define FETCH_DATA(info, addr) \
115 ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
116 ? 1 : fetch_data ((info), (addr)))
119 fetch_data (info
, addr
)
120 struct disassemble_info
*info
;
124 struct dis_private
*priv
= (struct dis_private
*)info
->private_data
;
125 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
127 status
= (*info
->read_memory_func
) (start
,
129 addr
- priv
->max_fetched
,
133 /* If we did manage to read at least one byte, then
134 print_insn_i386 will do something sensible. Otherwise, print
135 an error. We do that here because this is where we know
137 if (priv
->max_fetched
== priv
->the_buffer
)
138 (*info
->memory_error_func
) (status
, start
, info
);
139 longjmp (priv
->bailout
, 1);
142 priv
->max_fetched
= addr
;
148 #define Eb OP_E, b_mode
149 #define Ev OP_E, v_mode
150 #define Ed OP_E, d_mode
151 #define indirEb OP_indirE, b_mode
152 #define Gb OP_G, b_mode
153 #define Ev OP_E, v_mode
154 #define Ed OP_E, d_mode
155 #define indirEv OP_indirE, v_mode
156 #define Ew OP_E, w_mode
157 #define Ma OP_E, v_mode
158 #define M OP_E, 0 /* lea */
159 #define Mp OP_E, 0 /* 32 or 48 bit memory operand for LDS, LES etc */
160 #define Gv OP_G, v_mode
161 #define Gw OP_G, w_mode
162 #define Rd OP_Rd, d_mode
163 #define Rm OP_Rd, m_mode
164 #define Ib OP_I, b_mode
165 #define sIb OP_sI, b_mode /* sign extened byte */
166 #define Iv OP_I, v_mode
167 #define Iq OP_I, q_mode
168 #define Iv64 OP_I64, v_mode
169 #define Iw OP_I, w_mode
170 #define Jb OP_J, b_mode
171 #define Jv OP_J, v_mode
172 #define Cm OP_C, m_mode
173 #define Dm OP_D, m_mode
174 #define Td OP_T, d_mode
176 #define RMeAX OP_REG, eAX_reg
177 #define RMeBX OP_REG, eBX_reg
178 #define RMeCX OP_REG, eCX_reg
179 #define RMeDX OP_REG, eDX_reg
180 #define RMeSP OP_REG, eSP_reg
181 #define RMeBP OP_REG, eBP_reg
182 #define RMeSI OP_REG, eSI_reg
183 #define RMeDI OP_REG, eDI_reg
184 #define RMrAX OP_REG, rAX_reg
185 #define RMrBX OP_REG, rBX_reg
186 #define RMrCX OP_REG, rCX_reg
187 #define RMrDX OP_REG, rDX_reg
188 #define RMrSP OP_REG, rSP_reg
189 #define RMrBP OP_REG, rBP_reg
190 #define RMrSI OP_REG, rSI_reg
191 #define RMrDI OP_REG, rDI_reg
192 #define RMAL OP_REG, al_reg
193 #define RMAL OP_REG, al_reg
194 #define RMCL OP_REG, cl_reg
195 #define RMDL OP_REG, dl_reg
196 #define RMBL OP_REG, bl_reg
197 #define RMAH OP_REG, ah_reg
198 #define RMCH OP_REG, ch_reg
199 #define RMDH OP_REG, dh_reg
200 #define RMBH OP_REG, bh_reg
201 #define RMAX OP_REG, ax_reg
202 #define RMDX OP_REG, dx_reg
204 #define eAX OP_IMREG, eAX_reg
205 #define eBX OP_IMREG, eBX_reg
206 #define eCX OP_IMREG, eCX_reg
207 #define eDX OP_IMREG, eDX_reg
208 #define eSP OP_IMREG, eSP_reg
209 #define eBP OP_IMREG, eBP_reg
210 #define eSI OP_IMREG, eSI_reg
211 #define eDI OP_IMREG, eDI_reg
212 #define AL OP_IMREG, al_reg
213 #define AL OP_IMREG, al_reg
214 #define CL OP_IMREG, cl_reg
215 #define DL OP_IMREG, dl_reg
216 #define BL OP_IMREG, bl_reg
217 #define AH OP_IMREG, ah_reg
218 #define CH OP_IMREG, ch_reg
219 #define DH OP_IMREG, dh_reg
220 #define BH OP_IMREG, bh_reg
221 #define AX OP_IMREG, ax_reg
222 #define DX OP_IMREG, dx_reg
223 #define indirDX OP_IMREG, indir_dx_reg
225 #define Sw OP_SEG, w_mode
227 #define Ob OP_OFF, b_mode
228 #define Ob64 OP_OFF64, b_mode
229 #define Ov OP_OFF, v_mode
230 #define Ov64 OP_OFF64, v_mode
231 #define Xb OP_DSreg, eSI_reg
232 #define Xv OP_DSreg, eSI_reg
233 #define Yb OP_ESreg, eDI_reg
234 #define Yv OP_ESreg, eDI_reg
235 #define DSBX OP_DSreg, eBX_reg
237 #define es OP_REG, es_reg
238 #define ss OP_REG, ss_reg
239 #define cs OP_REG, cs_reg
240 #define ds OP_REG, ds_reg
241 #define fs OP_REG, fs_reg
242 #define gs OP_REG, gs_reg
246 #define EM OP_EM, v_mode
247 #define EX OP_EX, v_mode
248 #define MS OP_MS, v_mode
250 #define OPSUF OP_3DNowSuffix, 0
251 #define OPSIMD OP_SIMD_Suffix, 0
253 /* bits in sizeflag */
254 #if 0 /* leave undefined until someone adds the extra flag to objdump */
255 #define SUFFIX_ALWAYS 4
260 typedef void (*op_rtn
) PARAMS ((int bytemode
, int sizeflag
));
262 static void OP_E
PARAMS ((int, int));
263 static void OP_G
PARAMS ((int, int));
264 static void OP_I
PARAMS ((int, int));
265 static void OP_I64
PARAMS ((int, int));
266 static void OP_OFF
PARAMS ((int, int));
267 static void OP_REG
PARAMS ((int, int));
268 static void OP_IMREG
PARAMS ((int, int));
269 static void OP_OFF64
PARAMS ((int, int));
270 static void OP_indirE
PARAMS ((int, int));
271 static void OP_sI
PARAMS ((int, int));
272 static void OP_REG
PARAMS ((int, int));
273 static void OP_J
PARAMS ((int, int));
274 static void OP_DIR
PARAMS ((int, int));
275 static void OP_OFF
PARAMS ((int, int));
276 static void OP_ESreg
PARAMS ((int, int));
277 static void OP_DSreg
PARAMS ((int, int));
278 static void OP_SEG
PARAMS ((int, int));
279 static void OP_C
PARAMS ((int, int));
280 static void OP_D
PARAMS ((int, int));
281 static void OP_T
PARAMS ((int, int));
282 static void OP_Rd
PARAMS ((int, int));
283 static void OP_ST
PARAMS ((int, int));
284 static void OP_STi
PARAMS ((int, int));
285 static void OP_MMX
PARAMS ((int, int));
286 static void OP_XMM
PARAMS ((int, int));
287 static void OP_EM
PARAMS ((int, int));
288 static void OP_EX
PARAMS ((int, int));
289 static void OP_MS
PARAMS ((int, int));
290 static void OP_3DNowSuffix
PARAMS ((int, int));
291 static void OP_SIMD_Suffix
PARAMS ((int, int));
292 static void SIMD_Fixup
PARAMS ((int, int));
294 static void append_seg
PARAMS ((void));
295 static void set_op
PARAMS ((unsigned int op
, int));
296 static void putop
PARAMS ((const char *template, int sizeflag
));
297 static void dofloat
PARAMS ((int sizeflag
));
298 static int get16
PARAMS ((void));
299 static bfd_vma get64
PARAMS ((void));
300 static bfd_signed_vma get32
PARAMS ((void));
301 static bfd_signed_vma get32s
PARAMS ((void));
302 static void ckprefix
PARAMS ((void));
303 static const char *prefix_name
PARAMS ((int, int));
304 static void ptr_reg
PARAMS ((int, int));
305 static void BadOp
PARAMS ((void));
307 #define b_mode 1 /* byte operand */
308 #define v_mode 2 /* operand size depends on prefixes */
309 #define w_mode 3 /* word operand */
310 #define d_mode 4 /* double word operand */
311 #define q_mode 5 /* quad word operand */
313 #define m_mode 7 /* d_mode in 32bit, q_mode in 64bit mode. */
358 #define indir_dx_reg 150
361 #define USE_PREFIX_USER_TABLE 2
363 #define GRP1b NULL, NULL, 0, NULL, USE_GROUPS, NULL, 0
364 #define GRP1S NULL, NULL, 1, NULL, USE_GROUPS, NULL, 0
365 #define GRP1Ss NULL, NULL, 2, NULL, USE_GROUPS, NULL, 0
366 #define GRP2b NULL, NULL, 3, NULL, USE_GROUPS, NULL, 0
367 #define GRP2S NULL, NULL, 4, NULL, USE_GROUPS, NULL, 0
368 #define GRP2b_one NULL, NULL, 5, NULL, USE_GROUPS, NULL, 0
369 #define GRP2S_one NULL, NULL, 6, NULL, USE_GROUPS, NULL, 0
370 #define GRP2b_cl NULL, NULL, 7, NULL, USE_GROUPS, NULL, 0
371 #define GRP2S_cl NULL, NULL, 8, NULL, USE_GROUPS, NULL, 0
372 #define GRP3b NULL, NULL, 9, NULL, USE_GROUPS, NULL, 0
373 #define GRP3S NULL, NULL, 10, NULL, USE_GROUPS, NULL, 0
374 #define GRP4 NULL, NULL, 11, NULL, USE_GROUPS, NULL, 0
375 #define GRP5 NULL, NULL, 12, NULL, USE_GROUPS, NULL, 0
376 #define GRP6 NULL, NULL, 13, NULL, USE_GROUPS, NULL, 0
377 #define GRP7 NULL, NULL, 14, NULL, USE_GROUPS, NULL, 0
378 #define GRP8 NULL, NULL, 15, NULL, USE_GROUPS, NULL, 0
379 #define GRP9 NULL, NULL, 16, NULL, USE_GROUPS, NULL, 0
380 #define GRP10 NULL, NULL, 17, NULL, USE_GROUPS, NULL, 0
381 #define GRP11 NULL, NULL, 18, NULL, USE_GROUPS, NULL, 0
382 #define GRP12 NULL, NULL, 19, NULL, USE_GROUPS, NULL, 0
383 #define GRP13 NULL, NULL, 20, NULL, USE_GROUPS, NULL, 0
384 #define GRP14 NULL, NULL, 21, NULL, USE_GROUPS, NULL, 0
385 #define GRPAMD NULL, NULL, 22, NULL, USE_GROUPS, NULL, 0
387 #define PREGRP0 NULL, NULL, 0, NULL, USE_PREFIX_USER_TABLE, NULL, 0
388 #define PREGRP1 NULL, NULL, 1, NULL, USE_PREFIX_USER_TABLE, NULL, 0
389 #define PREGRP2 NULL, NULL, 2, NULL, USE_PREFIX_USER_TABLE, NULL, 0
390 #define PREGRP3 NULL, NULL, 3, NULL, USE_PREFIX_USER_TABLE, NULL, 0
391 #define PREGRP4 NULL, NULL, 4, NULL, USE_PREFIX_USER_TABLE, NULL, 0
392 #define PREGRP5 NULL, NULL, 5, NULL, USE_PREFIX_USER_TABLE, NULL, 0
393 #define PREGRP6 NULL, NULL, 6, NULL, USE_PREFIX_USER_TABLE, NULL, 0
394 #define PREGRP7 NULL, NULL, 7, NULL, USE_PREFIX_USER_TABLE, NULL, 0
395 #define PREGRP8 NULL, NULL, 8, NULL, USE_PREFIX_USER_TABLE, NULL, 0
396 #define PREGRP9 NULL, NULL, 9, NULL, USE_PREFIX_USER_TABLE, NULL, 0
397 #define PREGRP10 NULL, NULL, 10, NULL, USE_PREFIX_USER_TABLE, NULL, 0
398 #define PREGRP11 NULL, NULL, 11, NULL, USE_PREFIX_USER_TABLE, NULL, 0
399 #define PREGRP12 NULL, NULL, 12, NULL, USE_PREFIX_USER_TABLE, NULL, 0
400 #define PREGRP13 NULL, NULL, 13, NULL, USE_PREFIX_USER_TABLE, NULL, 0
401 #define PREGRP14 NULL, NULL, 14, NULL, USE_PREFIX_USER_TABLE, NULL, 0
402 #define PREGRP15 NULL, NULL, 15, NULL, USE_PREFIX_USER_TABLE, NULL, 0
403 #define PREGRP16 NULL, NULL, 16, NULL, USE_PREFIX_USER_TABLE, NULL, 0
404 #define PREGRP17 NULL, NULL, 17, NULL, USE_PREFIX_USER_TABLE, NULL, 0
405 #define PREGRP18 NULL, NULL, 18, NULL, USE_PREFIX_USER_TABLE, NULL, 0
406 #define PREGRP19 NULL, NULL, 19, NULL, USE_PREFIX_USER_TABLE, NULL, 0
407 #define PREGRP20 NULL, NULL, 20, NULL, USE_PREFIX_USER_TABLE, NULL, 0
408 #define PREGRP21 NULL, NULL, 21, NULL, USE_PREFIX_USER_TABLE, NULL, 0
409 #define PREGRP22 NULL, NULL, 22, NULL, USE_PREFIX_USER_TABLE, NULL, 0
410 #define PREGRP23 NULL, NULL, 23, NULL, USE_PREFIX_USER_TABLE, NULL, 0
411 #define PREGRP24 NULL, NULL, 24, NULL, USE_PREFIX_USER_TABLE, NULL, 0
412 #define PREGRP25 NULL, NULL, 25, NULL, USE_PREFIX_USER_TABLE, NULL, 0
413 #define PREGRP26 NULL, NULL, 26, NULL, USE_PREFIX_USER_TABLE, NULL, 0
416 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
428 /* Upper case letters in the instruction names here are macros.
429 'A' => print 'b' if no register operands or suffix_always is true
430 'B' => print 'b' if suffix_always is true
431 'E' => print 'e' if 32-bit form of jcxz
432 'L' => print 'l' if suffix_always is true
433 'N' => print 'n' if instruction has no wait "prefix"
434 'O' => print 'd', or 'o'
435 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
436 or suffix_always is true
437 print 'q' if rex prefix is present.
438 'I' => print 'q' in 64bit mode and behave as 'P' otherwise
439 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always is true
440 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
441 'S' => print 'w', 'l' or 'q' if suffix_always is true
442 'T' => print 'q' in 64bit mode and behave as 'I' otherwise
443 'X' => print 's', 'd' depending on data16 prefix (for XMM)
444 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
445 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
448 static const struct dis386 dis386_att
[] = {
450 { "addB", Eb
, Gb
, XX
},
451 { "addS", Ev
, Gv
, XX
},
452 { "addB", Gb
, Eb
, XX
},
453 { "addS", Gv
, Ev
, XX
},
454 { "addB", AL
, Ib
, XX
},
455 { "addS", eAX
, Iv
, XX
},
456 { "pushI", es
, XX
, XX
},
457 { "popI", es
, XX
, XX
},
459 { "orB", Eb
, Gb
, XX
},
460 { "orS", Ev
, Gv
, XX
},
461 { "orB", Gb
, Eb
, XX
},
462 { "orS", Gv
, Ev
, XX
},
463 { "orB", AL
, Ib
, XX
},
464 { "orS", eAX
, Iv
, XX
},
465 { "pushI", cs
, XX
, XX
},
466 { "(bad)", XX
, XX
, XX
}, /* 0x0f extended opcode escape */
468 { "adcB", Eb
, Gb
, XX
},
469 { "adcS", Ev
, Gv
, XX
},
470 { "adcB", Gb
, Eb
, XX
},
471 { "adcS", Gv
, Ev
, XX
},
472 { "adcB", AL
, Ib
, XX
},
473 { "adcS", eAX
, Iv
, XX
},
474 { "pushI", ss
, XX
, XX
},
475 { "popI", ss
, XX
, XX
},
477 { "sbbB", Eb
, Gb
, XX
},
478 { "sbbS", Ev
, Gv
, XX
},
479 { "sbbB", Gb
, Eb
, XX
},
480 { "sbbS", Gv
, Ev
, XX
},
481 { "sbbB", AL
, Ib
, XX
},
482 { "sbbS", eAX
, Iv
, XX
},
483 { "pushI", ds
, XX
, XX
},
484 { "popI", ds
, XX
, XX
},
486 { "andB", Eb
, Gb
, XX
},
487 { "andS", Ev
, Gv
, XX
},
488 { "andB", Gb
, Eb
, XX
},
489 { "andS", Gv
, Ev
, XX
},
490 { "andB", AL
, Ib
, XX
},
491 { "andS", eAX
, Iv
, XX
},
492 { "(bad)", XX
, XX
, XX
}, /* SEG ES prefix */
493 { "daa", XX
, XX
, XX
},
495 { "subB", Eb
, Gb
, XX
},
496 { "subS", Ev
, Gv
, XX
},
497 { "subB", Gb
, Eb
, XX
},
498 { "subS", Gv
, Ev
, XX
},
499 { "subB", AL
, Ib
, XX
},
500 { "subS", eAX
, Iv
, XX
},
501 { "(bad)", XX
, XX
, XX
}, /* SEG CS prefix */
502 { "das", XX
, XX
, XX
},
504 { "xorB", Eb
, Gb
, XX
},
505 { "xorS", Ev
, Gv
, XX
},
506 { "xorB", Gb
, Eb
, XX
},
507 { "xorS", Gv
, Ev
, XX
},
508 { "xorB", AL
, Ib
, XX
},
509 { "xorS", eAX
, Iv
, XX
},
510 { "(bad)", XX
, XX
, XX
}, /* SEG SS prefix */
511 { "aaa", XX
, XX
, XX
},
513 { "cmpB", Eb
, Gb
, XX
},
514 { "cmpS", Ev
, Gv
, XX
},
515 { "cmpB", Gb
, Eb
, XX
},
516 { "cmpS", Gv
, Ev
, XX
},
517 { "cmpB", AL
, Ib
, XX
},
518 { "cmpS", eAX
, Iv
, XX
},
519 { "(bad)", XX
, XX
, XX
}, /* SEG DS prefix */
520 { "aas", XX
, XX
, XX
},
522 { "incS", RMeAX
, XX
, XX
},
523 { "incS", RMeCX
, XX
, XX
},
524 { "incS", RMeDX
, XX
, XX
},
525 { "incS", RMeBX
, XX
, XX
},
526 { "incS", RMeSP
, XX
, XX
},
527 { "incS", RMeBP
, XX
, XX
},
528 { "incS", RMeSI
, XX
, XX
},
529 { "incS", RMeDI
, XX
, XX
},
531 { "decS", RMeAX
, XX
, XX
},
532 { "decS", RMeCX
, XX
, XX
},
533 { "decS", RMeDX
, XX
, XX
},
534 { "decS", RMeBX
, XX
, XX
},
535 { "decS", RMeSP
, XX
, XX
},
536 { "decS", RMeBP
, XX
, XX
},
537 { "decS", RMeSI
, XX
, XX
},
538 { "decS", RMeDI
, XX
, XX
},
540 { "pushS", RMeAX
, XX
, XX
},
541 { "pushS", RMeCX
, XX
, XX
},
542 { "pushS", RMeDX
, XX
, XX
},
543 { "pushS", RMeBX
, XX
, XX
},
544 { "pushS", RMeSP
, XX
, XX
},
545 { "pushS", RMeBP
, XX
, XX
},
546 { "pushS", RMeSI
, XX
, XX
},
547 { "pushS", RMeDI
, XX
, XX
},
549 { "popS", RMeAX
, XX
, XX
},
550 { "popS", RMeCX
, XX
, XX
},
551 { "popS", RMeDX
, XX
, XX
},
552 { "popS", RMeBX
, XX
, XX
},
553 { "popS", RMeSP
, XX
, XX
},
554 { "popS", RMeBP
, XX
, XX
},
555 { "popS", RMeSI
, XX
, XX
},
556 { "popS", RMeDI
, XX
, XX
},
558 { "pushaP", XX
, XX
, XX
},
559 { "popaP", XX
, XX
, XX
},
560 { "boundS", Gv
, Ma
, XX
},
561 { "arpl", Ew
, Gw
, XX
},
562 { "(bad)", XX
, XX
, XX
}, /* seg fs */
563 { "(bad)", XX
, XX
, XX
}, /* seg gs */
564 { "(bad)", XX
, XX
, XX
}, /* op size prefix */
565 { "(bad)", XX
, XX
, XX
}, /* adr size prefix */
567 { "pushI", Iv
, XX
, XX
}, /* 386 book wrong */
568 { "imulS", Gv
, Ev
, Iv
},
569 { "pushI", sIb
, XX
, XX
}, /* push of byte really pushes 2 or 4 bytes */
570 { "imulS", Gv
, Ev
, sIb
},
571 { "insb", Yb
, indirDX
, XX
},
572 { "insR", Yv
, indirDX
, XX
},
573 { "outsb", indirDX
, Xb
, XX
},
574 { "outsR", indirDX
, Xv
, XX
},
576 { "jo", Jb
, XX
, XX
},
577 { "jno", Jb
, XX
, XX
},
578 { "jb", Jb
, XX
, XX
},
579 { "jae", Jb
, XX
, XX
},
580 { "je", Jb
, XX
, XX
},
581 { "jne", Jb
, XX
, XX
},
582 { "jbe", Jb
, XX
, XX
},
583 { "ja", Jb
, XX
, XX
},
585 { "js", Jb
, XX
, XX
},
586 { "jns", Jb
, XX
, XX
},
587 { "jp", Jb
, XX
, XX
},
588 { "jnp", Jb
, XX
, XX
},
589 { "jl", Jb
, XX
, XX
},
590 { "jge", Jb
, XX
, XX
},
591 { "jle", Jb
, XX
, XX
},
592 { "jg", Jb
, XX
, XX
},
596 { "(bad)", XX
, XX
, XX
},
598 { "testB", Eb
, Gb
, XX
},
599 { "testS", Ev
, Gv
, XX
},
600 { "xchgB", Eb
, Gb
, XX
},
601 { "xchgS", Ev
, Gv
, XX
},
603 { "movB", Eb
, Gb
, XX
},
604 { "movS", Ev
, Gv
, XX
},
605 { "movB", Gb
, Eb
, XX
},
606 { "movS", Gv
, Ev
, XX
},
607 { "movQ", Ev
, Sw
, XX
},
608 { "leaS", Gv
, M
, XX
},
609 { "movQ", Sw
, Ev
, XX
},
610 { "popT", Ev
, XX
, XX
},
612 { "nop", XX
, XX
, XX
},
613 /* FIXME: NOP with REPz prefix is called PAUSE. */
614 { "xchgS", RMeCX
, eAX
, XX
},
615 { "xchgS", RMeDX
, eAX
, XX
},
616 { "xchgS", RMeBX
, eAX
, XX
},
617 { "xchgS", RMeSP
, eAX
, XX
},
618 { "xchgS", RMeBP
, eAX
, XX
},
619 { "xchgS", RMeSI
, eAX
, XX
},
620 { "xchgS", RMeDI
, eAX
, XX
},
622 { "cWtR", XX
, XX
, XX
},
623 { "cRtO", XX
, XX
, XX
},
624 { "lcallI", Ap
, XX
, XX
},
625 { "(bad)", XX
, XX
, XX
}, /* fwait */
626 { "pushfI", XX
, XX
, XX
},
627 { "popfI", XX
, XX
, XX
},
628 { "sahf", XX
, XX
, XX
},
629 { "lahf", XX
, XX
, XX
},
631 { "movB", AL
, Ob
, XX
},
632 { "movS", eAX
, Ov
, XX
},
633 { "movB", Ob
, AL
, XX
},
634 { "movS", Ov
, eAX
, XX
},
635 { "movsb", Yb
, Xb
, XX
},
636 { "movsR", Yv
, Xv
, XX
},
637 { "cmpsb", Xb
, Yb
, XX
},
638 { "cmpsR", Xv
, Yv
, XX
},
640 { "testB", AL
, Ib
, XX
},
641 { "testS", eAX
, Iv
, XX
},
642 { "stosB", Yb
, AL
, XX
},
643 { "stosS", Yv
, eAX
, XX
},
644 { "lodsB", AL
, Xb
, XX
},
645 { "lodsS", eAX
, Xv
, XX
},
646 { "scasB", AL
, Yb
, XX
},
647 { "scasS", eAX
, Yv
, XX
},
649 { "movB", RMAL
, Ib
, XX
},
650 { "movB", RMCL
, Ib
, XX
},
651 { "movB", RMDL
, Ib
, XX
},
652 { "movB", RMBL
, Ib
, XX
},
653 { "movB", RMAH
, Ib
, XX
},
654 { "movB", RMCH
, Ib
, XX
},
655 { "movB", RMDH
, Ib
, XX
},
656 { "movB", RMBH
, Ib
, XX
},
658 { "movS", RMeAX
, Iv
, XX
},
659 { "movS", RMeCX
, Iv
, XX
},
660 { "movS", RMeDX
, Iv
, XX
},
661 { "movS", RMeBX
, Iv
, XX
},
662 { "movS", RMeSP
, Iv
, XX
},
663 { "movS", RMeBP
, Iv
, XX
},
664 { "movS", RMeSI
, Iv
, XX
},
665 { "movS", RMeDI
, Iv
, XX
},
669 { "retI", Iw
, XX
, XX
},
670 { "retI", XX
, XX
, XX
},
671 { "lesS", Gv
, Mp
, XX
},
672 { "ldsS", Gv
, Mp
, XX
},
673 { "movA", Eb
, Ib
, XX
},
674 { "movQ", Ev
, Iv
, XX
},
676 { "enterI", Iw
, Ib
, XX
},
677 { "leaveI", XX
, XX
, XX
},
678 { "lretP", Iw
, XX
, XX
},
679 { "lretP", XX
, XX
, XX
},
680 { "int3", XX
, XX
, XX
},
681 { "int", Ib
, XX
, XX
},
682 { "into", XX
, XX
, XX
},
683 { "iretP", XX
, XX
, XX
},
689 { "aam", sIb
, XX
, XX
},
690 { "aad", sIb
, XX
, XX
},
691 { "(bad)", XX
, XX
, XX
},
692 { "xlat", DSBX
, XX
, XX
},
703 { "loopne", Jb
, XX
, XX
},
704 { "loope", Jb
, XX
, XX
},
705 { "loop", Jb
, XX
, XX
},
706 { "jEcxz", Jb
, XX
, XX
},
707 { "inB", AL
, Ib
, XX
},
708 { "inS", eAX
, Ib
, XX
},
709 { "outB", Ib
, AL
, XX
},
710 { "outS", Ib
, eAX
, XX
},
712 { "callI", Jv
, XX
, XX
},
713 { "jmpI", Jv
, XX
, XX
},
714 { "ljmpI", Ap
, XX
, XX
},
715 { "jmp", Jb
, XX
, XX
},
716 { "inB", AL
, indirDX
, XX
},
717 { "inS", eAX
, indirDX
, XX
},
718 { "outB", indirDX
, AL
, XX
},
719 { "outS", indirDX
, eAX
, XX
},
721 { "(bad)", XX
, XX
, XX
}, /* lock prefix */
722 { "(bad)", XX
, XX
, XX
},
723 { "(bad)", XX
, XX
, XX
}, /* repne */
724 { "(bad)", XX
, XX
, XX
}, /* repz */
725 { "hlt", XX
, XX
, XX
},
726 { "cmc", XX
, XX
, XX
},
730 { "clc", XX
, XX
, XX
},
731 { "stc", XX
, XX
, XX
},
732 { "cli", XX
, XX
, XX
},
733 { "sti", XX
, XX
, XX
},
734 { "cld", XX
, XX
, XX
},
735 { "std", XX
, XX
, XX
},
740 static const struct dis386 dis386_intel
[] = {
742 { "add", Eb
, Gb
, XX
},
743 { "add", Ev
, Gv
, XX
},
744 { "add", Gb
, Eb
, XX
},
745 { "add", Gv
, Ev
, XX
},
746 { "add", AL
, Ib
, XX
},
747 { "add", eAX
, Iv
, XX
},
748 { "push", es
, XX
, XX
},
749 { "pop", es
, XX
, XX
},
751 { "or", Eb
, Gb
, XX
},
752 { "or", Ev
, Gv
, XX
},
753 { "or", Gb
, Eb
, XX
},
754 { "or", Gv
, Ev
, XX
},
755 { "or", AL
, Ib
, XX
},
756 { "or", eAX
, Iv
, XX
},
757 { "push", cs
, XX
, XX
},
758 { "(bad)", XX
, XX
, XX
}, /* 0x0f extended opcode escape */
760 { "adc", Eb
, Gb
, XX
},
761 { "adc", Ev
, Gv
, XX
},
762 { "adc", Gb
, Eb
, XX
},
763 { "adc", Gv
, Ev
, XX
},
764 { "adc", AL
, Ib
, XX
},
765 { "adc", eAX
, Iv
, XX
},
766 { "push", ss
, XX
, XX
},
767 { "pop", ss
, XX
, XX
},
769 { "sbb", Eb
, Gb
, XX
},
770 { "sbb", Ev
, Gv
, XX
},
771 { "sbb", Gb
, Eb
, XX
},
772 { "sbb", Gv
, Ev
, XX
},
773 { "sbb", AL
, Ib
, XX
},
774 { "sbb", eAX
, Iv
, XX
},
775 { "push", ds
, XX
, XX
},
776 { "pop", ds
, XX
, XX
},
778 { "and", Eb
, Gb
, XX
},
779 { "and", Ev
, Gv
, XX
},
780 { "and", Gb
, Eb
, XX
},
781 { "and", Gv
, Ev
, XX
},
782 { "and", AL
, Ib
, XX
},
783 { "and", eAX
, Iv
, XX
},
784 { "(bad)", XX
, XX
, XX
}, /* SEG ES prefix */
785 { "daa", XX
, XX
, XX
},
787 { "sub", Eb
, Gb
, XX
},
788 { "sub", Ev
, Gv
, XX
},
789 { "sub", Gb
, Eb
, XX
},
790 { "sub", Gv
, Ev
, XX
},
791 { "sub", AL
, Ib
, XX
},
792 { "sub", eAX
, Iv
, XX
},
793 { "(bad)", XX
, XX
, XX
}, /* SEG CS prefix */
794 { "das", XX
, XX
, XX
},
796 { "xor", Eb
, Gb
, XX
},
797 { "xor", Ev
, Gv
, XX
},
798 { "xor", Gb
, Eb
, XX
},
799 { "xor", Gv
, Ev
, XX
},
800 { "xor", AL
, Ib
, XX
},
801 { "xor", eAX
, Iv
, XX
},
802 { "(bad)", XX
, XX
, XX
}, /* SEG SS prefix */
803 { "aaa", XX
, XX
, XX
},
805 { "cmp", Eb
, Gb
, XX
},
806 { "cmp", Ev
, Gv
, XX
},
807 { "cmp", Gb
, Eb
, XX
},
808 { "cmp", Gv
, Ev
, XX
},
809 { "cmp", AL
, Ib
, XX
},
810 { "cmp", eAX
, Iv
, XX
},
811 { "(bad)", XX
, XX
, XX
}, /* SEG DS prefix */
812 { "aas", XX
, XX
, XX
},
814 { "inc", RMeAX
, XX
, XX
},
815 { "inc", RMeCX
, XX
, XX
},
816 { "inc", RMeDX
, XX
, XX
},
817 { "inc", RMeBX
, XX
, XX
},
818 { "inc", RMeSP
, XX
, XX
},
819 { "inc", RMeBP
, XX
, XX
},
820 { "inc", RMeSI
, XX
, XX
},
821 { "inc", RMeDI
, XX
, XX
},
823 { "dec", RMeAX
, XX
, XX
},
824 { "dec", RMeCX
, XX
, XX
},
825 { "dec", RMeDX
, XX
, XX
},
826 { "dec", RMeBX
, XX
, XX
},
827 { "dec", RMeSP
, XX
, XX
},
828 { "dec", RMeBP
, XX
, XX
},
829 { "dec", RMeSI
, XX
, XX
},
830 { "dec", RMeDI
, XX
, XX
},
832 { "push", RMeAX
, XX
, XX
},
833 { "push", RMeCX
, XX
, XX
},
834 { "push", RMeDX
, XX
, XX
},
835 { "push", RMeBX
, XX
, XX
},
836 { "push", RMeSP
, XX
, XX
},
837 { "push", RMeBP
, XX
, XX
},
838 { "push", RMeSI
, XX
, XX
},
839 { "push", RMeDI
, XX
, XX
},
841 { "pop", RMeAX
, XX
, XX
},
842 { "pop", RMeCX
, XX
, XX
},
843 { "pop", RMeDX
, XX
, XX
},
844 { "pop", RMeBX
, XX
, XX
},
845 { "pop", RMeSP
, XX
, XX
},
846 { "pop", RMeBP
, XX
, XX
},
847 { "pop", RMeSI
, XX
, XX
},
848 { "pop", RMeDI
, XX
, XX
},
850 { "pusha", XX
, XX
, XX
},
851 { "popa", XX
, XX
, XX
},
852 { "bound", Gv
, Ma
, XX
},
853 { "arpl", Ew
, Gw
, XX
},
854 { "(bad)", XX
, XX
, XX
}, /* seg fs */
855 { "(bad)", XX
, XX
, XX
}, /* seg gs */
856 { "(bad)", XX
, XX
, XX
}, /* op size prefix */
857 { "(bad)", XX
, XX
, XX
}, /* adr size prefix */
859 { "push", Iv
, XX
, XX
}, /* 386 book wrong */
860 { "imul", Gv
, Ev
, Iv
},
861 { "push", sIb
, XX
, XX
}, /* push of byte really pushes 2 or 4 bytes */
862 { "imul", Gv
, Ev
, sIb
},
863 { "ins", Yb
, indirDX
, XX
},
864 { "ins", Yv
, indirDX
, XX
},
865 { "outs", indirDX
, Xb
, XX
},
866 { "outs", indirDX
, Xv
, XX
},
868 { "jo", Jb
, XX
, XX
},
869 { "jno", Jb
, XX
, XX
},
870 { "jb", Jb
, XX
, XX
},
871 { "jae", Jb
, XX
, XX
},
872 { "je", Jb
, XX
, XX
},
873 { "jne", Jb
, XX
, XX
},
874 { "jbe", Jb
, XX
, XX
},
875 { "ja", Jb
, XX
, XX
},
877 { "js", Jb
, XX
, XX
},
878 { "jns", Jb
, XX
, XX
},
879 { "jp", Jb
, XX
, XX
},
880 { "jnp", Jb
, XX
, XX
},
881 { "jl", Jb
, XX
, XX
},
882 { "jge", Jb
, XX
, XX
},
883 { "jle", Jb
, XX
, XX
},
884 { "jg", Jb
, XX
, XX
},
888 { "(bad)", XX
, XX
, XX
},
890 { "test", Eb
, Gb
, XX
},
891 { "test", Ev
, Gv
, XX
},
892 { "xchg", Eb
, Gb
, XX
},
893 { "xchg", Ev
, Gv
, XX
},
895 { "mov", Eb
, Gb
, XX
},
896 { "mov", Ev
, Gv
, XX
},
897 { "mov", Gb
, Eb
, XX
},
898 { "mov", Gv
, Ev
, XX
},
899 { "mov", Ev
, Sw
, XX
},
900 { "lea", Gv
, M
, XX
},
901 { "mov", Sw
, Ev
, XX
},
902 { "pop", Ev
, XX
, XX
},
904 { "nop", XX
, XX
, XX
},
905 /* FIXME: NOP with REPz prefix is called PAUSE. */
906 { "xchg", RMeCX
, eAX
, XX
},
907 { "xchg", RMeDX
, eAX
, XX
},
908 { "xchg", RMeBX
, eAX
, XX
},
909 { "xchg", RMeSP
, eAX
, XX
},
910 { "xchg", RMeBP
, eAX
, XX
},
911 { "xchg", RMeSI
, eAX
, XX
},
912 { "xchg", RMeDI
, eAX
, XX
},
914 { "cW", XX
, XX
, XX
}, /* cwde and cbw */
915 { "cR", XX
, XX
, XX
}, /* cdq and cwd */
916 { "lcall", Ap
, XX
, XX
},
917 { "(bad)", XX
, XX
, XX
}, /* fwait */
918 { "pushf", XX
, XX
, XX
},
919 { "popf", XX
, XX
, XX
},
920 { "sahf", XX
, XX
, XX
},
921 { "lahf", XX
, XX
, XX
},
923 { "mov", AL
, Ob
, XX
},
924 { "mov", eAX
, Ov
, XX
},
925 { "mov", Ob
, AL
, XX
},
926 { "mov", Ov
, eAX
, XX
},
927 { "movs", Yb
, Xb
, XX
},
928 { "movs", Yv
, Xv
, XX
},
929 { "cmps", Xb
, Yb
, XX
},
930 { "cmps", Xv
, Yv
, XX
},
932 { "test", AL
, Ib
, XX
},
933 { "test", eAX
, Iv
, XX
},
934 { "stos", Yb
, AL
, XX
},
935 { "stos", Yv
, eAX
, XX
},
936 { "lods", AL
, Xb
, XX
},
937 { "lods", eAX
, Xv
, XX
},
938 { "scas", AL
, Yb
, XX
},
939 { "scas", eAX
, Yv
, XX
},
941 { "mov", RMAL
, Ib
, XX
},
942 { "mov", RMCL
, Ib
, XX
},
943 { "mov", RMDL
, Ib
, XX
},
944 { "mov", RMBL
, Ib
, XX
},
945 { "mov", RMAH
, Ib
, XX
},
946 { "mov", RMCH
, Ib
, XX
},
947 { "mov", RMDH
, Ib
, XX
},
948 { "mov", RMBH
, Ib
, XX
},
950 { "mov", RMeAX
, Iv
, XX
},
951 { "mov", RMeCX
, Iv
, XX
},
952 { "mov", RMeDX
, Iv
, XX
},
953 { "mov", RMeBX
, Iv
, XX
},
954 { "mov", RMeSP
, Iv
, XX
},
955 { "mov", RMeBP
, Iv
, XX
},
956 { "mov", RMeSI
, Iv
, XX
},
957 { "mov", RMeDI
, Iv
, XX
},
961 { "ret", Iw
, XX
, XX
},
962 { "ret", XX
, XX
, XX
},
963 { "les", Gv
, Mp
, XX
},
964 { "lds", Gv
, Mp
, XX
},
965 { "mov", Eb
, Ib
, XX
},
966 { "mov", Ev
, Iv
, XX
},
968 { "enter", Iw
, Ib
, XX
},
969 { "leave", XX
, XX
, XX
},
970 { "lret", Iw
, XX
, XX
},
971 { "lret", XX
, XX
, XX
},
972 { "int3", XX
, XX
, XX
},
973 { "int", Ib
, XX
, XX
},
974 { "into", XX
, XX
, XX
},
975 { "iret", XX
, XX
, XX
},
981 { "aam", sIb
, XX
, XX
},
982 { "aad", sIb
, XX
, XX
},
983 { "(bad)", XX
, XX
, XX
},
984 { "xlat", DSBX
, XX
, XX
},
995 { "loopne", Jb
, XX
, XX
},
996 { "loope", Jb
, XX
, XX
},
997 { "loop", Jb
, XX
, XX
},
998 { "jEcxz", Jb
, XX
, XX
},
999 { "in", AL
, Ib
, XX
},
1000 { "in", eAX
, Ib
, XX
},
1001 { "out", Ib
, AL
, XX
},
1002 { "out", Ib
, eAX
, XX
},
1004 { "call", Jv
, XX
, XX
},
1005 { "jmp", Jv
, XX
, XX
},
1006 { "ljmp", Ap
, XX
, XX
},
1007 { "jmp", Jb
, XX
, XX
},
1008 { "in", AL
, indirDX
, XX
},
1009 { "in", eAX
, indirDX
, XX
},
1010 { "out", indirDX
, AL
, XX
},
1011 { "out", indirDX
, eAX
, XX
},
1013 { "(bad)", XX
, XX
, XX
}, /* lock prefix */
1014 { "(bad)", XX
, XX
, XX
},
1015 { "(bad)", XX
, XX
, XX
}, /* repne */
1016 { "(bad)", XX
, XX
, XX
}, /* repz */
1017 { "hlt", XX
, XX
, XX
},
1018 { "cmc", XX
, XX
, XX
},
1022 { "clc", XX
, XX
, XX
},
1023 { "stc", XX
, XX
, XX
},
1024 { "cli", XX
, XX
, XX
},
1025 { "sti", XX
, XX
, XX
},
1026 { "cld", XX
, XX
, XX
},
1027 { "std", XX
, XX
, XX
},
1032 /* 64bit mode is having some instruction set differences, so separate table is
1034 static const struct dis386 disx86_64_att
[] = {
1036 { "addB", Eb
, Gb
, XX
},
1037 { "addS", Ev
, Gv
, XX
},
1038 { "addB", Gb
, Eb
, XX
},
1039 { "addS", Gv
, Ev
, XX
},
1040 { "addB", AL
, Ib
, XX
},
1041 { "addS", eAX
, Iv
, XX
},
1042 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1043 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1045 { "orB", Eb
, Gb
, XX
},
1046 { "orS", Ev
, Gv
, XX
},
1047 { "orB", Gb
, Eb
, XX
},
1048 { "orS", Gv
, Ev
, XX
},
1049 { "orB", AL
, Ib
, XX
},
1050 { "orS", eAX
, Iv
, XX
},
1051 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1052 { "(bad)", XX
, XX
, XX
}, /* 0x0f extended opcode escape */
1054 { "adcB", Eb
, Gb
, XX
},
1055 { "adcS", Ev
, Gv
, XX
},
1056 { "adcB", Gb
, Eb
, XX
},
1057 { "adcS", Gv
, Ev
, XX
},
1058 { "adcB", AL
, Ib
, XX
},
1059 { "adcS", eAX
, Iv
, XX
},
1060 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1061 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1063 { "sbbB", Eb
, Gb
, XX
},
1064 { "sbbS", Ev
, Gv
, XX
},
1065 { "sbbB", Gb
, Eb
, XX
},
1066 { "sbbS", Gv
, Ev
, XX
},
1067 { "sbbB", AL
, Ib
, XX
},
1068 { "sbbS", eAX
, Iv
, XX
},
1069 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1070 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1072 { "andB", Eb
, Gb
, XX
},
1073 { "andS", Ev
, Gv
, XX
},
1074 { "andB", Gb
, Eb
, XX
},
1075 { "andS", Gv
, Ev
, XX
},
1076 { "andB", AL
, Ib
, XX
},
1077 { "andS", eAX
, Iv
, XX
},
1078 { "(bad)", XX
, XX
, XX
}, /* SEG ES prefix */
1079 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1081 { "subB", Eb
, Gb
, XX
},
1082 { "subS", Ev
, Gv
, XX
},
1083 { "subB", Gb
, Eb
, XX
},
1084 { "subS", Gv
, Ev
, XX
},
1085 { "subB", AL
, Ib
, XX
},
1086 { "subS", eAX
, Iv
, XX
},
1087 { "(bad)", XX
, XX
, XX
}, /* SEG CS prefix */
1088 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1090 { "xorB", Eb
, Gb
, XX
},
1091 { "xorS", Ev
, Gv
, XX
},
1092 { "xorB", Gb
, Eb
, XX
},
1093 { "xorS", Gv
, Ev
, XX
},
1094 { "xorB", AL
, Ib
, XX
},
1095 { "xorS", eAX
, Iv
, XX
},
1096 { "(bad)", XX
, XX
, XX
}, /* SEG SS prefix */
1097 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1099 { "cmpB", Eb
, Gb
, XX
},
1100 { "cmpS", Ev
, Gv
, XX
},
1101 { "cmpB", Gb
, Eb
, XX
},
1102 { "cmpS", Gv
, Ev
, XX
},
1103 { "cmpB", AL
, Ib
, XX
},
1104 { "cmpS", eAX
, Iv
, XX
},
1105 { "(bad)", XX
, XX
, XX
}, /* SEG DS prefix */
1106 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1108 { "(bad)", XX
, XX
, XX
}, /* REX prefix area. */
1109 { "(bad)", XX
, XX
, XX
},
1110 { "(bad)", XX
, XX
, XX
},
1111 { "(bad)", XX
, XX
, XX
},
1112 { "(bad)", XX
, XX
, XX
},
1113 { "(bad)", XX
, XX
, XX
},
1114 { "(bad)", XX
, XX
, XX
},
1115 { "(bad)", XX
, XX
, XX
},
1117 { "(bad)", XX
, XX
, XX
},
1118 { "(bad)", XX
, XX
, XX
},
1119 { "(bad)", XX
, XX
, XX
},
1120 { "(bad)", XX
, XX
, XX
},
1121 { "(bad)", XX
, XX
, XX
},
1122 { "(bad)", XX
, XX
, XX
},
1123 { "(bad)", XX
, XX
, XX
},
1124 { "(bad)", XX
, XX
, XX
},
1126 { "pushI", RMrAX
, XX
, XX
},
1127 { "pushI", RMrCX
, XX
, XX
},
1128 { "pushI", RMrDX
, XX
, XX
},
1129 { "pushI", RMrBX
, XX
, XX
},
1130 { "pushI", RMrSP
, XX
, XX
},
1131 { "pushI", RMrBP
, XX
, XX
},
1132 { "pushI", RMrSI
, XX
, XX
},
1133 { "pushI", RMrDI
, XX
, XX
},
1135 { "popI", RMrAX
, XX
, XX
},
1136 { "popI", RMrCX
, XX
, XX
},
1137 { "popI", RMrDX
, XX
, XX
},
1138 { "popI", RMrBX
, XX
, XX
},
1139 { "popI", RMrSP
, XX
, XX
},
1140 { "popI", RMrBP
, XX
, XX
},
1141 { "popI", RMrSI
, XX
, XX
},
1142 { "popI", RMrDI
, XX
, XX
},
1144 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1145 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1146 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1147 { "movslR", Gv
, Ed
, XX
},
1148 { "(bad)", XX
, XX
, XX
}, /* seg fs */
1149 { "(bad)", XX
, XX
, XX
}, /* seg gs */
1150 { "(bad)", XX
, XX
, XX
}, /* op size prefix */
1151 { "(bad)", XX
, XX
, XX
}, /* adr size prefix */
1153 { "pushI", Iq
, XX
, XX
}, /* 386 book wrong */
1154 { "imulS", Gv
, Ev
, Iv
},
1155 { "pushI", sIb
, XX
, XX
}, /* push of byte really pushes 2 or 4 bytes */
1156 { "imulS", Gv
, Ev
, sIb
},
1157 { "insb", Yb
, indirDX
, XX
},
1158 { "insR", Yv
, indirDX
, XX
},
1159 { "outsb", indirDX
, Xb
, XX
},
1160 { "outsR", indirDX
, Xv
, XX
},
1162 { "jo", Jb
, XX
, XX
},
1163 { "jno", Jb
, XX
, XX
},
1164 { "jb", Jb
, XX
, XX
},
1165 { "jae", Jb
, XX
, XX
},
1166 { "je", Jb
, XX
, XX
},
1167 { "jne", Jb
, XX
, XX
},
1168 { "jbe", Jb
, XX
, XX
},
1169 { "ja", Jb
, XX
, XX
},
1171 { "js", Jb
, XX
, XX
},
1172 { "jns", Jb
, XX
, XX
},
1173 { "jp", Jb
, XX
, XX
},
1174 { "jnp", Jb
, XX
, XX
},
1175 { "jl", Jb
, XX
, XX
},
1176 { "jge", Jb
, XX
, XX
},
1177 { "jle", Jb
, XX
, XX
},
1178 { "jg", Jb
, XX
, XX
},
1182 { "(bad)", XX
, XX
, XX
},
1184 { "testB", Eb
, Gb
, XX
},
1185 { "testS", Ev
, Gv
, XX
},
1186 { "xchgB", Eb
, Gb
, XX
},
1187 { "xchgS", Ev
, Gv
, XX
},
1189 { "movB", Eb
, Gb
, XX
},
1190 { "movS", Ev
, Gv
, XX
},
1191 { "movB", Gb
, Eb
, XX
},
1192 { "movS", Gv
, Ev
, XX
},
1193 { "movQ", Ev
, Sw
, XX
},
1194 { "leaS", Gv
, M
, XX
},
1195 { "movQ", Sw
, Ev
, XX
},
1196 { "popI", Ev
, XX
, XX
},
1198 { "nop", XX
, XX
, XX
},
1199 /* FIXME: NOP with REPz prefix is called PAUSE. */
1200 { "xchgS", RMeCX
, eAX
, XX
},
1201 { "xchgS", RMeDX
, eAX
, XX
},
1202 { "xchgS", RMeBX
, eAX
, XX
},
1203 { "xchgS", RMeSP
, eAX
, XX
},
1204 { "xchgS", RMeBP
, eAX
, XX
},
1205 { "xchgS", RMeSI
, eAX
, XX
},
1206 { "xchgS", RMeDI
, eAX
, XX
},
1208 { "cWtR", XX
, XX
, XX
},
1209 { "cRtO", XX
, XX
, XX
},
1210 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1211 { "(bad)", XX
, XX
, XX
}, /* fwait */
1212 { "pushfI", XX
, XX
, XX
},
1213 { "popfI", XX
, XX
, XX
},
1214 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1215 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1217 { "movB", AL
, Ob64
, XX
},
1218 { "movS", eAX
, Ov64
, XX
},
1219 { "movB", Ob64
, AL
, XX
},
1220 { "movS", Ov64
, eAX
, XX
},
1221 { "movsb", Yb
, Xb
, XX
},
1222 { "movsR", Yv
, Xv
, XX
},
1223 { "cmpsb", Xb
, Yb
, XX
},
1224 { "cmpsR", Xv
, Yv
, XX
},
1226 { "testB", AL
, Ib
, XX
},
1227 { "testS", eAX
, Iv
, XX
},
1228 { "stosB", Yb
, AL
, XX
},
1229 { "stosS", Yv
, eAX
, XX
},
1230 { "lodsB", AL
, Xb
, XX
},
1231 { "lodsS", eAX
, Xv
, XX
},
1232 { "scasB", AL
, Yb
, XX
},
1233 { "scasS", eAX
, Yv
, XX
},
1235 { "movB", RMAL
, Ib
, XX
},
1236 { "movB", RMCL
, Ib
, XX
},
1237 { "movB", RMDL
, Ib
, XX
},
1238 { "movB", RMBL
, Ib
, XX
},
1239 { "movB", RMAH
, Ib
, XX
},
1240 { "movB", RMCH
, Ib
, XX
},
1241 { "movB", RMDH
, Ib
, XX
},
1242 { "movB", RMBH
, Ib
, XX
},
1244 { "movS", RMeAX
, Iv64
, XX
},
1245 { "movS", RMeCX
, Iv64
, XX
},
1246 { "movS", RMeDX
, Iv64
, XX
},
1247 { "movS", RMeBX
, Iv64
, XX
},
1248 { "movS", RMeSP
, Iv64
, XX
},
1249 { "movS", RMeBP
, Iv64
, XX
},
1250 { "movS", RMeSI
, Iv64
, XX
},
1251 { "movS", RMeDI
, Iv64
, XX
},
1255 { "retI", Iw
, XX
, XX
},
1256 { "retI", XX
, XX
, XX
},
1257 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1258 { "ldsS", Gv
, Mp
, XX
},
1259 { "movA", Eb
, Ib
, XX
},
1260 { "movQ", Ev
, Iv
, XX
},
1262 { "enterI", Iw
, Ib
, XX
},
1263 { "leaveI", XX
, XX
, XX
},
1264 { "lretP", Iw
, XX
, XX
},
1265 { "lretP", XX
, XX
, XX
},
1266 { "int3", XX
, XX
, XX
},
1267 { "int", Ib
, XX
, XX
},
1268 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1269 { "iretP", XX
, XX
, XX
},
1275 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1276 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1277 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1278 { "xlat", DSBX
, XX
, XX
},
1289 { "loopne", Jb
, XX
, XX
},
1290 { "loope", Jb
, XX
, XX
},
1291 { "loop", Jb
, XX
, XX
},
1292 { "jEcxz", Jb
, XX
, XX
},
1293 { "inB", AL
, Ib
, XX
},
1294 { "inS", eAX
, Ib
, XX
},
1295 { "outB", Ib
, AL
, XX
},
1296 { "outS", Ib
, eAX
, XX
},
1298 { "callI", Jv
, XX
, XX
},
1299 { "jmpI", Jv
, XX
, XX
},
1300 { "(bad)", XX
, XX
, XX
}, /* reserved. */
1301 { "jmp", Jb
, XX
, XX
},
1302 { "inB", AL
, indirDX
, XX
},
1303 { "inS", eAX
, indirDX
, XX
},
1304 { "outB", indirDX
, AL
, XX
},
1305 { "outS", indirDX
, eAX
, XX
},
1307 { "(bad)", XX
, XX
, XX
}, /* lock prefix */
1308 { "(bad)", XX
, XX
, XX
},
1309 { "(bad)", XX
, XX
, XX
}, /* repne */
1310 { "(bad)", XX
, XX
, XX
}, /* repz */
1311 { "hlt", XX
, XX
, XX
},
1312 { "cmc", XX
, XX
, XX
},
1316 { "clc", XX
, XX
, XX
},
1317 { "stc", XX
, XX
, XX
},
1318 { "cli", XX
, XX
, XX
},
1319 { "sti", XX
, XX
, XX
},
1320 { "cld", XX
, XX
, XX
},
1321 { "std", XX
, XX
, XX
},
1326 static const struct dis386 dis386_64_intel
[] = {
1328 { "add", Eb
, Gb
, XX
},
1329 { "add", Ev
, Gv
, XX
},
1330 { "add", Gb
, Eb
, XX
},
1331 { "add", Gv
, Ev
, XX
},
1332 { "add", AL
, Ib
, XX
},
1333 { "add", eAX
, Iv
, XX
},
1334 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1335 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1337 { "or", Eb
, Gb
, XX
},
1338 { "or", Ev
, Gv
, XX
},
1339 { "or", Gb
, Eb
, XX
},
1340 { "or", Gv
, Ev
, XX
},
1341 { "or", AL
, Ib
, XX
},
1342 { "or", eAX
, Iv
, XX
},
1343 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1344 { "(bad)", XX
, XX
, XX
}, /* 0x0f extended opcode escape */
1346 { "adc", Eb
, Gb
, XX
},
1347 { "adc", Ev
, Gv
, XX
},
1348 { "adc", Gb
, Eb
, XX
},
1349 { "adc", Gv
, Ev
, XX
},
1350 { "adc", AL
, Ib
, XX
},
1351 { "adc", eAX
, Iv
, XX
},
1352 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1353 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1355 { "sbb", Eb
, Gb
, XX
},
1356 { "sbb", Ev
, Gv
, XX
},
1357 { "sbb", Gb
, Eb
, XX
},
1358 { "sbb", Gv
, Ev
, XX
},
1359 { "sbb", AL
, Ib
, XX
},
1360 { "sbb", eAX
, Iv
, XX
},
1361 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1362 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1364 { "and", Eb
, Gb
, XX
},
1365 { "and", Ev
, Gv
, XX
},
1366 { "and", Gb
, Eb
, XX
},
1367 { "and", Gv
, Ev
, XX
},
1368 { "and", AL
, Ib
, XX
},
1369 { "and", eAX
, Iv
, XX
},
1370 { "(bad)", XX
, XX
, XX
}, /* SEG ES prefix */
1371 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1373 { "sub", Eb
, Gb
, XX
},
1374 { "sub", Ev
, Gv
, XX
},
1375 { "sub", Gb
, Eb
, XX
},
1376 { "sub", Gv
, Ev
, XX
},
1377 { "sub", AL
, Ib
, XX
},
1378 { "sub", eAX
, Iv
, XX
},
1379 { "(bad)", XX
, XX
, XX
}, /* SEG CS prefix */
1380 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1382 { "xor", Eb
, Gb
, XX
},
1383 { "xor", Ev
, Gv
, XX
},
1384 { "xor", Gb
, Eb
, XX
},
1385 { "xor", Gv
, Ev
, XX
},
1386 { "xor", AL
, Ib
, XX
},
1387 { "xor", eAX
, Iv
, XX
},
1388 { "(bad)", XX
, XX
, XX
}, /* SEG SS prefix */
1389 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1391 { "cmp", Eb
, Gb
, XX
},
1392 { "cmp", Ev
, Gv
, XX
},
1393 { "cmp", Gb
, Eb
, XX
},
1394 { "cmp", Gv
, Ev
, XX
},
1395 { "cmp", AL
, Ib
, XX
},
1396 { "cmp", eAX
, Iv
, XX
},
1397 { "(bad)", XX
, XX
, XX
}, /* SEG DS prefix */
1398 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1400 { "(bad)", XX
, XX
, XX
}, /* REX prefix area. */
1401 { "(bad)", XX
, XX
, XX
},
1402 { "(bad)", XX
, XX
, XX
},
1403 { "(bad)", XX
, XX
, XX
},
1404 { "(bad)", XX
, XX
, XX
},
1405 { "(bad)", XX
, XX
, XX
},
1406 { "(bad)", XX
, XX
, XX
},
1407 { "(bad)", XX
, XX
, XX
},
1409 { "(bad)", XX
, XX
, XX
},
1410 { "(bad)", XX
, XX
, XX
},
1411 { "(bad)", XX
, XX
, XX
},
1412 { "(bad)", XX
, XX
, XX
},
1413 { "(bad)", XX
, XX
, XX
},
1414 { "(bad)", XX
, XX
, XX
},
1415 { "(bad)", XX
, XX
, XX
},
1416 { "(bad)", XX
, XX
, XX
},
1418 { "push", RMrAX
, XX
, XX
},
1419 { "push", RMrCX
, XX
, XX
},
1420 { "push", RMrDX
, XX
, XX
},
1421 { "push", RMrBX
, XX
, XX
},
1422 { "push", RMrSP
, XX
, XX
},
1423 { "push", RMrBP
, XX
, XX
},
1424 { "push", RMrSI
, XX
, XX
},
1425 { "push", RMrDI
, XX
, XX
},
1427 { "pop", RMrAX
, XX
, XX
},
1428 { "pop", RMrCX
, XX
, XX
},
1429 { "pop", RMrDX
, XX
, XX
},
1430 { "pop", RMrBX
, XX
, XX
},
1431 { "pop", RMrSP
, XX
, XX
},
1432 { "pop", RMrBP
, XX
, XX
},
1433 { "pop", RMrSI
, XX
, XX
},
1434 { "pop", RMrDI
, XX
, XX
},
1436 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1437 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1438 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1439 { "movsx", Gv
, Ed
, XX
},
1440 { "(bad)", XX
, XX
, XX
}, /* seg fs */
1441 { "(bad)", XX
, XX
, XX
}, /* seg gs */
1442 { "(bad)", XX
, XX
, XX
}, /* op size prefix */
1443 { "(bad)", XX
, XX
, XX
}, /* adr size prefix */
1445 { "push", Iq
, XX
, XX
}, /* 386 book wrong */
1446 { "imul", Gv
, Ev
, Iv
},
1447 { "push", sIb
, XX
, XX
}, /* push of byte really pushes 2 or 4 bytes */
1448 { "imul", Gv
, Ev
, sIb
},
1449 { "ins", Yb
, indirDX
, XX
},
1450 { "ins", Yv
, indirDX
, XX
},
1451 { "outs", indirDX
, Xb
, XX
},
1452 { "outs", indirDX
, Xv
, XX
},
1454 { "jo", Jb
, XX
, XX
},
1455 { "jno", Jb
, XX
, XX
},
1456 { "jb", Jb
, XX
, XX
},
1457 { "jae", Jb
, XX
, XX
},
1458 { "je", Jb
, XX
, XX
},
1459 { "jne", Jb
, XX
, XX
},
1460 { "jbe", Jb
, XX
, XX
},
1461 { "ja", Jb
, XX
, XX
},
1463 { "js", Jb
, XX
, XX
},
1464 { "jns", Jb
, XX
, XX
},
1465 { "jp", Jb
, XX
, XX
},
1466 { "jnp", Jb
, XX
, XX
},
1467 { "jl", Jb
, XX
, XX
},
1468 { "jge", Jb
, XX
, XX
},
1469 { "jle", Jb
, XX
, XX
},
1470 { "jg", Jb
, XX
, XX
},
1474 { "(bad)", XX
, XX
, XX
},
1476 { "test", Eb
, Gb
, XX
},
1477 { "test", Ev
, Gv
, XX
},
1478 { "xchg", Eb
, Gb
, XX
},
1479 { "xchg", Ev
, Gv
, XX
},
1481 { "mov", Eb
, Gb
, XX
},
1482 { "mov", Ev
, Gv
, XX
},
1483 { "mov", Gb
, Eb
, XX
},
1484 { "mov", Gv
, Ev
, XX
},
1485 { "mov", Ev
, Sw
, XX
},
1486 { "lea", Gv
, M
, XX
},
1487 { "mov", Sw
, Ev
, XX
},
1488 { "pop", Ev
, XX
, XX
},
1490 { "nop", XX
, XX
, XX
},
1491 /* FIXME: NOP with REPz prefix is called PAUSE. */
1492 { "xchg", RMeCX
, eAX
, XX
},
1493 { "xchg", RMeDX
, eAX
, XX
},
1494 { "xchg", RMeBX
, eAX
, XX
},
1495 { "xchg", RMeSP
, eAX
, XX
},
1496 { "xchg", RMeBP
, eAX
, XX
},
1497 { "xchg", RMeSI
, eAX
, XX
},
1498 { "xchg", RMeDI
, eAX
, XX
},
1500 { "cW", XX
, XX
, XX
}, /* cwde and cbw */
1501 { "cR", XX
, XX
, XX
}, /* cdq and cwd */
1502 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1503 { "(bad)", XX
, XX
, XX
}, /* fwait */
1504 { "pushf", XX
, XX
, XX
},
1505 { "popf", XX
, XX
, XX
},
1506 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1507 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1509 { "mov", AL
, Ob
, XX
},
1510 { "mov", eAX
, Ov
, XX
},
1511 { "mov", Ob
, AL
, XX
},
1512 { "mov", Ov
, eAX
, XX
},
1513 { "movs", Yb
, Xb
, XX
},
1514 { "movs", Yv
, Xv
, XX
},
1515 { "cmps", Xb
, Yb
, XX
},
1516 { "cmps", Xv
, Yv
, XX
},
1518 { "test", AL
, Ib
, XX
},
1519 { "test", eAX
, Iv
, XX
},
1520 { "stos", Yb
, AL
, XX
},
1521 { "stos", Yv
, eAX
, XX
},
1522 { "lods", AL
, Xb
, XX
},
1523 { "lods", eAX
, Xv
, XX
},
1524 { "scas", AL
, Yb
, XX
},
1525 { "scas", eAX
, Yv
, XX
},
1527 { "mov", RMAL
, Ib
, XX
},
1528 { "mov", RMCL
, Ib
, XX
},
1529 { "mov", RMDL
, Ib
, XX
},
1530 { "mov", RMBL
, Ib
, XX
},
1531 { "mov", RMAH
, Ib
, XX
},
1532 { "mov", RMCH
, Ib
, XX
},
1533 { "mov", RMDH
, Ib
, XX
},
1534 { "mov", RMBH
, Ib
, XX
},
1536 { "mov", RMeAX
, Iv
, XX
},
1537 { "mov", RMeCX
, Iv
, XX
},
1538 { "mov", RMeDX
, Iv
, XX
},
1539 { "mov", RMeBX
, Iv
, XX
},
1540 { "mov", RMeSP
, Iv
, XX
},
1541 { "mov", RMeBP
, Iv
, XX
},
1542 { "mov", RMeSI
, Iv
, XX
},
1543 { "mov", RMeDI
, Iv
, XX
},
1547 { "ret", Iw
, XX
, XX
},
1548 { "ret", XX
, XX
, XX
},
1549 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1550 { "lds", Gv
, Mp
, XX
},
1551 { "mov", Eb
, Ib
, XX
},
1552 { "mov", Ev
, Iv
, XX
},
1554 { "enter", Iw
, Ib
, XX
},
1555 { "leave", XX
, XX
, XX
},
1556 { "lret", Iw
, XX
, XX
},
1557 { "lret", XX
, XX
, XX
},
1558 { "int3", XX
, XX
, XX
},
1559 { "int", Ib
, XX
, XX
},
1560 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1561 { "iret", XX
, XX
, XX
},
1567 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1568 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1569 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1570 { "xlat", DSBX
, XX
, XX
},
1581 { "loopne", Jb
, XX
, XX
},
1582 { "loope", Jb
, XX
, XX
},
1583 { "loop", Jb
, XX
, XX
},
1584 { "jEcxz", Jb
, XX
, XX
},
1585 { "in", AL
, Ib
, XX
},
1586 { "in", eAX
, Ib
, XX
},
1587 { "out", Ib
, AL
, XX
},
1588 { "out", Ib
, eAX
, XX
},
1590 { "call", Jv
, XX
, XX
},
1591 { "jmp", Jv
, XX
, XX
},
1592 { "(bad)", XX
, XX
, XX
}, /* Reserved. */
1593 { "jmp", Jb
, XX
, XX
},
1594 { "in", AL
, indirDX
, XX
},
1595 { "in", eAX
, indirDX
, XX
},
1596 { "out", indirDX
, AL
, XX
},
1597 { "out", indirDX
, eAX
, XX
},
1599 { "(bad)", XX
, XX
, XX
}, /* lock prefix */
1600 { "(bad)", XX
, XX
, XX
},
1601 { "(bad)", XX
, XX
, XX
}, /* repne */
1602 { "(bad)", XX
, XX
, XX
}, /* repz */
1603 { "hlt", XX
, XX
, XX
},
1604 { "cmc", XX
, XX
, XX
},
1608 { "clc", XX
, XX
, XX
},
1609 { "stc", XX
, XX
, XX
},
1610 { "cli", XX
, XX
, XX
},
1611 { "sti", XX
, XX
, XX
},
1612 { "cld", XX
, XX
, XX
},
1613 { "std", XX
, XX
, XX
},
1618 static const struct dis386 dis386_twobyte_att
[] = {
1622 { "larS", Gv
, Ew
, XX
},
1623 { "lslS", Gv
, Ew
, XX
},
1624 { "(bad)", XX
, XX
, XX
},
1625 { "syscall", XX
, XX
, XX
},
1626 { "clts", XX
, XX
, XX
},
1627 { "sysretP", XX
, XX
, XX
},
1629 { "invd", XX
, XX
, XX
},
1630 { "wbinvd", XX
, XX
, XX
},
1631 { "(bad)", XX
, XX
, XX
},
1632 { "ud2a", XX
, XX
, XX
},
1633 { "(bad)", XX
, XX
, XX
},
1635 { "femms", XX
, XX
, XX
},
1636 { "", MX
, EM
, OPSUF
}, /* See OP_3DNowSuffix */
1640 { "movlpX", XM
, EX
, SIMD_Fixup
, 'h' }, /* really only 2 operands */
1641 { "movlpX", EX
, XM
, SIMD_Fixup
, 'h' },
1642 { "unpcklpX", XM
, EX
, XX
},
1643 { "unpckhpX", XM
, EX
, XX
},
1644 { "movhpX", XM
, EX
, SIMD_Fixup
, 'l' },
1645 { "movhpX", EX
, XM
, SIMD_Fixup
, 'l' },
1648 { "(bad)", XX
, XX
, XX
},
1649 { "(bad)", XX
, XX
, XX
},
1650 { "(bad)", XX
, XX
, XX
},
1651 { "(bad)", XX
, XX
, XX
},
1652 { "(bad)", XX
, XX
, XX
},
1653 { "(bad)", XX
, XX
, XX
},
1654 { "(bad)", XX
, XX
, XX
},
1656 /* these are all backward in appendix A of the intel book */
1657 { "movL", Rm
, Cm
, XX
},
1658 { "movL", Rm
, Dm
, XX
},
1659 { "movL", Cm
, Rm
, XX
},
1660 { "movL", Dm
, Rm
, XX
},
1661 { "movL", Rd
, Td
, XX
},
1662 { "(bad)", XX
, XX
, XX
},
1663 { "movL", Td
, Rd
, XX
},
1664 { "(bad)", XX
, XX
, XX
},
1666 { "movapX", XM
, EX
, XX
},
1667 { "movapX", EX
, XM
, XX
},
1669 { "movntpX", Ev
, XM
, XX
},
1672 { "ucomisX", XM
,EX
, XX
},
1673 { "comisX", XM
,EX
, XX
},
1675 { "wrmsr", XX
, XX
, XX
},
1676 { "rdtsc", XX
, XX
, XX
},
1677 { "rdmsr", XX
, XX
, XX
},
1678 { "rdpmc", XX
, XX
, XX
},
1679 { "sysenter", XX
, XX
, XX
},
1680 { "sysexit", XX
, XX
, XX
},
1681 { "(bad)", XX
, XX
, XX
},
1682 { "(bad)", XX
, XX
, XX
},
1684 { "(bad)", XX
, XX
, XX
},
1685 { "(bad)", XX
, XX
, XX
},
1686 { "(bad)", XX
, XX
, XX
},
1687 { "(bad)", XX
, XX
, XX
},
1688 { "(bad)", XX
, XX
, XX
},
1689 { "(bad)", XX
, XX
, XX
},
1690 { "(bad)", XX
, XX
, XX
},
1691 { "(bad)", XX
, XX
, XX
},
1693 { "cmovo", Gv
, Ev
, XX
},
1694 { "cmovno", Gv
, Ev
, XX
},
1695 { "cmovb", Gv
, Ev
, XX
},
1696 { "cmovae", Gv
, Ev
, XX
},
1697 { "cmove", Gv
, Ev
, XX
},
1698 { "cmovne", Gv
, Ev
, XX
},
1699 { "cmovbe", Gv
, Ev
, XX
},
1700 { "cmova", Gv
, Ev
, XX
},
1702 { "cmovs", Gv
, Ev
, XX
},
1703 { "cmovns", Gv
, Ev
, XX
},
1704 { "cmovp", Gv
, Ev
, XX
},
1705 { "cmovnp", Gv
, Ev
, XX
},
1706 { "cmovl", Gv
, Ev
, XX
},
1707 { "cmovge", Gv
, Ev
, XX
},
1708 { "cmovle", Gv
, Ev
, XX
},
1709 { "cmovg", Gv
, Ev
, XX
},
1711 { "movmskpX", Gv
, EX
, XX
},
1715 { "andpX", XM
, EX
, XX
},
1716 { "andnpX", XM
, EX
, XX
},
1717 { "orpX", XM
, EX
, XX
},
1718 { "xorpX", XM
, EX
, XX
},
1729 { "punpcklbw", MX
, EM
, XX
},
1730 { "punpcklwd", MX
, EM
, XX
},
1731 { "punpckldq", MX
, EM
, XX
},
1732 { "packsswb", MX
, EM
, XX
},
1733 { "pcmpgtb", MX
, EM
, XX
},
1734 { "pcmpgtw", MX
, EM
, XX
},
1735 { "pcmpgtd", MX
, EM
, XX
},
1736 { "packuswb", MX
, EM
, XX
},
1738 { "punpckhbw", MX
, EM
, XX
},
1739 { "punpckhwd", MX
, EM
, XX
},
1740 { "punpckhdq", MX
, EM
, XX
},
1741 { "packssdw", MX
, EM
, XX
},
1744 { "movd", MX
, Ed
, XX
},
1751 { "pcmpeqb", MX
, EM
, XX
},
1752 { "pcmpeqw", MX
, EM
, XX
},
1753 { "pcmpeqd", MX
, EM
, XX
},
1754 { "emms", XX
, XX
, XX
},
1756 { "(bad)", XX
, XX
, XX
},
1757 { "(bad)", XX
, XX
, XX
},
1758 { "(bad)", XX
, XX
, XX
},
1759 { "(bad)", XX
, XX
, XX
},
1760 { "(bad)", XX
, XX
, XX
},
1761 { "(bad)", XX
, XX
, XX
},
1765 { "jo", Jv
, XX
, XX
},
1766 { "jno", Jv
, XX
, XX
},
1767 { "jb", Jv
, XX
, XX
},
1768 { "jae", Jv
, XX
, XX
},
1769 { "je", Jv
, XX
, XX
},
1770 { "jne", Jv
, XX
, XX
},
1771 { "jbe", Jv
, XX
, XX
},
1772 { "ja", Jv
, XX
, XX
},
1774 { "js", Jv
, XX
, XX
},
1775 { "jns", Jv
, XX
, XX
},
1776 { "jp", Jv
, XX
, XX
},
1777 { "jnp", Jv
, XX
, XX
},
1778 { "jl", Jv
, XX
, XX
},
1779 { "jge", Jv
, XX
, XX
},
1780 { "jle", Jv
, XX
, XX
},
1781 { "jg", Jv
, XX
, XX
},
1783 { "seto", Eb
, XX
, XX
},
1784 { "setno", Eb
, XX
, XX
},
1785 { "setb", Eb
, XX
, XX
},
1786 { "setae", Eb
, XX
, XX
},
1787 { "sete", Eb
, XX
, XX
},
1788 { "setne", Eb
, XX
, XX
},
1789 { "setbe", Eb
, XX
, XX
},
1790 { "seta", Eb
, XX
, XX
},
1792 { "sets", Eb
, XX
, XX
},
1793 { "setns", Eb
, XX
, XX
},
1794 { "setp", Eb
, XX
, XX
},
1795 { "setnp", Eb
, XX
, XX
},
1796 { "setl", Eb
, XX
, XX
},
1797 { "setge", Eb
, XX
, XX
},
1798 { "setle", Eb
, XX
, XX
},
1799 { "setg", Eb
, XX
, XX
},
1801 { "pushI", fs
, XX
, XX
},
1802 { "popI", fs
, XX
, XX
},
1803 { "cpuid", XX
, XX
, XX
},
1804 { "btS", Ev
, Gv
, XX
},
1805 { "shldS", Ev
, Gv
, Ib
},
1806 { "shldS", Ev
, Gv
, CL
},
1807 { "(bad)", XX
, XX
, XX
},
1808 { "(bad)", XX
, XX
, XX
},
1810 { "pushI", gs
, XX
, XX
},
1811 { "popI", gs
, XX
, XX
},
1812 { "rsm", XX
, XX
, XX
},
1813 { "btsS", Ev
, Gv
, XX
},
1814 { "shrdS", Ev
, Gv
, Ib
},
1815 { "shrdS", Ev
, Gv
, CL
},
1817 { "imulS", Gv
, Ev
, XX
},
1819 { "cmpxchgB", Eb
, Gb
, XX
},
1820 { "cmpxchgS", Ev
, Gv
, XX
},
1821 { "lssS", Gv
, Mp
, XX
},
1822 { "btrS", Ev
, Gv
, XX
},
1823 { "lfsS", Gv
, Mp
, XX
},
1824 { "lgsS", Gv
, Mp
, XX
},
1825 { "movzbR", Gv
, Eb
, XX
},
1826 { "movzwR", Gv
, Ew
, XX
}, /* yes, there really is movzww ! */
1828 { "(bad)", XX
, XX
, XX
},
1829 { "ud2b", XX
, XX
, XX
},
1831 { "btcS", Ev
, Gv
, XX
},
1832 { "bsfS", Gv
, Ev
, XX
},
1833 { "bsrS", Gv
, Ev
, XX
},
1834 { "movsbR", Gv
, Eb
, XX
},
1835 { "movswR", Gv
, Ew
, XX
}, /* yes, there really is movsww ! */
1837 { "xaddB", Eb
, Gb
, XX
},
1838 { "xaddS", Ev
, Gv
, XX
},
1840 { "movntiS", Ev
, Gv
, XX
},
1841 { "pinsrw", MX
, Ev
, Ib
},
1842 { "pextrw", Ev
, MX
, Ib
},
1843 { "shufpX", XM
, EX
, Ib
},
1846 { "bswap", RMeAX
, XX
, XX
}, /* bswap doesn't support 16 bit regs */
1847 { "bswap", RMeCX
, XX
, XX
},
1848 { "bswap", RMeDX
, XX
, XX
},
1849 { "bswap", RMeBX
, XX
, XX
},
1850 { "bswap", RMeSP
, XX
, XX
},
1851 { "bswap", RMeBP
, XX
, XX
},
1852 { "bswap", RMeSI
, XX
, XX
},
1853 { "bswap", RMeDI
, XX
, XX
},
1855 { "(bad)", XX
, XX
, XX
},
1856 { "psrlw", MX
, EM
, XX
},
1857 { "psrld", MX
, EM
, XX
},
1858 { "psrlq", MX
, EM
, XX
},
1859 { "paddq", MX
, EM
, XX
},
1860 { "pmullw", MX
, EM
, XX
},
1862 { "pmovmskb", Ev
, MX
, XX
},
1864 { "psubusb", MX
, EM
, XX
},
1865 { "psubusw", MX
, EM
, XX
},
1866 { "pminub", MX
, EM
, XX
},
1867 { "pand", MX
, EM
, XX
},
1868 { "paddusb", MX
, EM
, XX
},
1869 { "paddusw", MX
, EM
, XX
},
1870 { "pmaxub", MX
, EM
, XX
},
1871 { "pandn", MX
, EM
, XX
},
1873 { "pavgb", MX
, EM
, XX
},
1874 { "psraw", MX
, EM
, XX
},
1875 { "psrad", MX
, EM
, XX
},
1876 { "pavgw", MX
, EM
, XX
},
1877 { "pmulhuw", MX
, EM
, XX
},
1878 { "pmulhw", MX
, EM
, XX
},
1882 { "psubsb", MX
, EM
, XX
},
1883 { "psubsw", MX
, EM
, XX
},
1884 { "pminsw", MX
, EM
, XX
},
1885 { "por", MX
, EM
, XX
},
1886 { "paddsb", MX
, EM
, XX
},
1887 { "paddsw", MX
, EM
, XX
},
1888 { "pmaxsw", MX
, EM
, XX
},
1889 { "pxor", MX
, EM
, XX
},
1891 { "(bad)", XX
, XX
, XX
},
1892 { "psllw", MX
, EM
, XX
},
1893 { "pslld", MX
, EM
, XX
},
1894 { "psllq", MX
, EM
, XX
},
1895 { "pmuludq", MX
, EM
, XX
},
1896 { "pmaddwd", MX
, EM
, XX
},
1897 { "psadbw", MX
, EM
, XX
},
1900 { "psubb", MX
, EM
, XX
},
1901 { "psubw", MX
, EM
, XX
},
1902 { "psubd", MX
, EM
, XX
},
1903 { "psubq", MX
, EM
, XX
},
1904 { "paddb", MX
, EM
, XX
},
1905 { "paddw", MX
, EM
, XX
},
1906 { "paddd", MX
, EM
, XX
},
1907 { "(bad)", XX
, XX
, XX
}
1910 static const struct dis386 dis386_twobyte_intel
[] = {
1914 { "lar", Gv
, Ew
, XX
},
1915 { "lsl", Gv
, Ew
, XX
},
1916 { "(bad)", XX
, XX
, XX
},
1917 { "syscall", XX
, XX
, XX
},
1918 { "clts", XX
, XX
, XX
},
1919 { "sysretP", XX
, XX
, XX
},
1921 { "invd", XX
, XX
, XX
},
1922 { "wbinvd", XX
, XX
, XX
},
1923 { "(bad)", XX
, XX
, XX
},
1924 { "ud2a", XX
, XX
, XX
},
1925 { "(bad)", XX
, XX
, XX
},
1927 { "femms" , XX
, XX
, XX
},
1928 { "", MX
, EM
, OPSUF
}, /* See OP_3DNowSuffix */
1932 { "movlpX", XM
, EX
, SIMD_Fixup
, 'h' }, /* really only 2 operands */
1933 { "movlpX", EX
, XM
, SIMD_Fixup
, 'h' },
1934 { "unpcklpX", XM
, EX
, XX
},
1935 { "unpckhpX", XM
, EX
, XX
},
1936 { "movhpX", XM
, EX
, SIMD_Fixup
, 'l' },
1937 { "movhpX", EX
, XM
, SIMD_Fixup
, 'l' },
1940 { "(bad)", XX
, XX
, XX
},
1941 { "(bad)", XX
, XX
, XX
},
1942 { "(bad)", XX
, XX
, XX
},
1943 { "(bad)", XX
, XX
, XX
},
1944 { "(bad)", XX
, XX
, XX
},
1945 { "(bad)", XX
, XX
, XX
},
1946 { "(bad)", XX
, XX
, XX
},
1948 /* these are all backward in appendix A of the intel book */
1949 { "mov", Rm
, Cm
, XX
},
1950 { "mov", Rm
, Dm
, XX
},
1951 { "mov", Cm
, Rm
, XX
},
1952 { "mov", Dm
, Rm
, XX
},
1953 { "mov", Rd
, Td
, XX
},
1954 { "(bad)", XX
, XX
, XX
},
1955 { "mov", Td
, Rd
, XX
},
1956 { "(bad)", XX
, XX
, XX
},
1958 { "movapX", XM
, EX
, XX
},
1959 { "movapX", EX
, XM
, XX
},
1961 { "movntpX", Ev
, XM
, XX
},
1964 { "ucomisX", XM
,EX
, XX
},
1965 { "comisX", XM
,EX
, XX
},
1967 { "wrmsr", XX
, XX
, XX
},
1968 { "rdtsc", XX
, XX
, XX
},
1969 { "rdmsr", XX
, XX
, XX
},
1970 { "rdpmc", XX
, XX
, XX
},
1971 { "sysenter", XX
, XX
, XX
},
1972 { "sysexit", XX
, XX
, XX
},
1973 { "(bad)", XX
, XX
, XX
},
1974 { "(bad)", XX
, XX
, XX
},
1976 { "(bad)", XX
, XX
, XX
},
1977 { "(bad)", XX
, XX
, XX
},
1978 { "(bad)", XX
, XX
, XX
},
1979 { "(bad)", XX
, XX
, XX
},
1980 { "(bad)", XX
, XX
, XX
},
1981 { "(bad)", XX
, XX
, XX
},
1982 { "(bad)", XX
, XX
, XX
},
1983 { "(bad)", XX
, XX
, XX
},
1985 { "cmovo", Gv
, Ev
, XX
},
1986 { "cmovno", Gv
, Ev
, XX
},
1987 { "cmovb", Gv
, Ev
, XX
},
1988 { "cmovae", Gv
, Ev
, XX
},
1989 { "cmove", Gv
, Ev
, XX
},
1990 { "cmovne", Gv
, Ev
, XX
},
1991 { "cmovbe", Gv
, Ev
, XX
},
1992 { "cmova", Gv
, Ev
, XX
},
1994 { "cmovs", Gv
, Ev
, XX
},
1995 { "cmovns", Gv
, Ev
, XX
},
1996 { "cmovp", Gv
, Ev
, XX
},
1997 { "cmovnp", Gv
, Ev
, XX
},
1998 { "cmovl", Gv
, Ev
, XX
},
1999 { "cmovge", Gv
, Ev
, XX
},
2000 { "cmovle", Gv
, Ev
, XX
},
2001 { "cmovg", Gv
, Ev
, XX
},
2003 { "movmskpX", Gv
, EX
, XX
},
2007 { "andpX", XM
, EX
, XX
},
2008 { "andnpX", XM
, EX
, XX
},
2009 { "orpX", XM
, EX
, XX
},
2010 { "xorpX", XM
, EX
, XX
},
2021 { "punpcklbw", MX
, EM
, XX
},
2022 { "punpcklwd", MX
, EM
, XX
},
2023 { "punpckldq", MX
, EM
, XX
},
2024 { "packsswb", MX
, EM
, XX
},
2025 { "pcmpgtb", MX
, EM
, XX
},
2026 { "pcmpgtw", MX
, EM
, XX
},
2027 { "pcmpgtd", MX
, EM
, XX
},
2028 { "packuswb", MX
, EM
, XX
},
2030 { "punpckhbw", MX
, EM
, XX
},
2031 { "punpckhwd", MX
, EM
, XX
},
2032 { "punpckhdq", MX
, EM
, XX
},
2033 { "packssdw", MX
, EM
, XX
},
2036 { "movd", MX
, Ed
, XX
},
2043 { "pcmpeqb", MX
, EM
, XX
},
2044 { "pcmpeqw", MX
, EM
, XX
},
2045 { "pcmpeqd", MX
, EM
, XX
},
2046 { "emms", XX
, XX
, XX
},
2048 { "(bad)", XX
, XX
, XX
},
2049 { "(bad)", XX
, XX
, XX
},
2050 { "(bad)", XX
, XX
, XX
},
2051 { "(bad)", XX
, XX
, XX
},
2052 { "(bad)", XX
, XX
, XX
},
2053 { "(bad)", XX
, XX
, XX
},
2057 { "jo", Jv
, XX
, XX
},
2058 { "jno", Jv
, XX
, XX
},
2059 { "jb", Jv
, XX
, XX
},
2060 { "jae", Jv
, XX
, XX
},
2061 { "je", Jv
, XX
, XX
},
2062 { "jne", Jv
, XX
, XX
},
2063 { "jbe", Jv
, XX
, XX
},
2064 { "ja", Jv
, XX
, XX
},
2066 { "js", Jv
, XX
, XX
},
2067 { "jns", Jv
, XX
, XX
},
2068 { "jp", Jv
, XX
, XX
},
2069 { "jnp", Jv
, XX
, XX
},
2070 { "jl", Jv
, XX
, XX
},
2071 { "jge", Jv
, XX
, XX
},
2072 { "jle", Jv
, XX
, XX
},
2073 { "jg", Jv
, XX
, XX
},
2075 { "seto", Eb
, XX
, XX
},
2076 { "setno", Eb
, XX
, XX
},
2077 { "setb", Eb
, XX
, XX
},
2078 { "setae", Eb
, XX
, XX
},
2079 { "sete", Eb
, XX
, XX
},
2080 { "setne", Eb
, XX
, XX
},
2081 { "setbe", Eb
, XX
, XX
},
2082 { "seta", Eb
, XX
, XX
},
2084 { "sets", Eb
, XX
, XX
},
2085 { "setns", Eb
, XX
, XX
},
2086 { "setp", Eb
, XX
, XX
},
2087 { "setnp", Eb
, XX
, XX
},
2088 { "setl", Eb
, XX
, XX
},
2089 { "setge", Eb
, XX
, XX
},
2090 { "setle", Eb
, XX
, XX
},
2091 { "setg", Eb
, XX
, XX
},
2093 { "push", fs
, XX
, XX
},
2094 { "pop", fs
, XX
, XX
},
2095 { "cpuid", XX
, XX
, XX
},
2096 { "bt", Ev
, Gv
, XX
},
2097 { "shld", Ev
, Gv
, Ib
},
2098 { "shld", Ev
, Gv
, CL
},
2099 { "(bad)", XX
, XX
, XX
},
2100 { "(bad)", XX
, XX
, XX
},
2102 { "push", gs
, XX
, XX
},
2103 { "pop", gs
, XX
, XX
},
2104 { "rsm" , XX
, XX
, XX
},
2105 { "bts", Ev
, Gv
, XX
},
2106 { "shrd", Ev
, Gv
, Ib
},
2107 { "shrd", Ev
, Gv
, CL
},
2109 { "imul", Gv
, Ev
, XX
},
2111 { "cmpxchg", Eb
, Gb
, XX
},
2112 { "cmpxchg", Ev
, Gv
, XX
},
2113 { "lss", Gv
, Mp
, XX
},
2114 { "btr", Ev
, Gv
, XX
},
2115 { "lfs", Gv
, Mp
, XX
},
2116 { "lgs", Gv
, Mp
, XX
},
2117 { "movzx", Gv
, Eb
, XX
},
2118 { "movzx", Gv
, Ew
, XX
},
2120 { "(bad)", XX
, XX
, XX
},
2121 { "ud2b", XX
, XX
, XX
},
2123 { "btc", Ev
, Gv
, XX
},
2124 { "bsf", Gv
, Ev
, XX
},
2125 { "bsr", Gv
, Ev
, XX
},
2126 { "movsx", Gv
, Eb
, XX
},
2127 { "movsx", Gv
, Ew
, XX
},
2129 { "xadd", Eb
, Gb
, XX
},
2130 { "xadd", Ev
, Gv
, XX
},
2132 { "movnti", Ev
, Gv
, XX
},
2133 { "pinsrw", MX
, Ev
, Ib
},
2134 { "pextrw", Ev
, MX
, Ib
},
2135 { "shufpX", XM
, EX
, Ib
},
2138 { "bswap", RMeAX
, XX
, XX
}, /* bswap doesn't support 16 bit regs */
2139 { "bswap", RMeCX
, XX
, XX
},
2140 { "bswap", RMeDX
, XX
, XX
},
2141 { "bswap", RMeBX
, XX
, XX
},
2142 { "bswap", RMeSP
, XX
, XX
},
2143 { "bswap", RMeBP
, XX
, XX
},
2144 { "bswap", RMeSI
, XX
, XX
},
2145 { "bswap", RMeDI
, XX
, XX
},
2147 { "(bad)", XX
, XX
, XX
},
2148 { "psrlw", MX
, EM
, XX
},
2149 { "psrld", MX
, EM
, XX
},
2150 { "psrlq", MX
, EM
, XX
},
2151 { "paddq", MX
, EM
, XX
},
2152 { "pmullw", MX
, EM
, XX
},
2154 { "pmovmskb", Ev
, MX
, XX
},
2156 { "psubusb", MX
, EM
, XX
},
2157 { "psubusw", MX
, EM
, XX
},
2158 { "pminub", MX
, EM
, XX
},
2159 { "pand", MX
, EM
, XX
},
2160 { "paddusb", MX
, EM
, XX
},
2161 { "paddusw", MX
, EM
, XX
},
2162 { "pmaxub", MX
, EM
, XX
},
2163 { "pandn", MX
, EM
, XX
},
2165 { "pavgb", MX
, EM
, XX
},
2166 { "psraw", MX
, EM
, XX
},
2167 { "psrad", MX
, EM
, XX
},
2168 { "pavgw", MX
, EM
, XX
},
2169 { "pmulhuw", MX
, EM
, XX
},
2170 { "pmulhw", MX
, EM
, XX
},
2174 { "psubsb", MX
, EM
, XX
},
2175 { "psubsw", MX
, EM
, XX
},
2176 { "pminsw", MX
, EM
, XX
},
2177 { "por", MX
, EM
, XX
},
2178 { "paddsb", MX
, EM
, XX
},
2179 { "paddsw", MX
, EM
, XX
},
2180 { "pmaxsw", MX
, EM
, XX
},
2181 { "pxor", MX
, EM
, XX
},
2183 { "(bad)", XX
, XX
, XX
},
2184 { "psllw", MX
, EM
, XX
},
2185 { "pslld", MX
, EM
, XX
},
2186 { "psllq", MX
, EM
, XX
},
2187 { "pmuludq", MX
, EM
, XX
},
2188 { "pmaddwd", MX
, EM
, XX
},
2189 { "psadbw", MX
, EM
, XX
},
2192 { "psubb", MX
, EM
, XX
},
2193 { "psubw", MX
, EM
, XX
},
2194 { "psubd", MX
, EM
, XX
},
2195 { "psubq", MX
, EM
, XX
},
2196 { "paddb", MX
, EM
, XX
},
2197 { "paddw", MX
, EM
, XX
},
2198 { "paddd", MX
, EM
, XX
},
2199 { "(bad)", XX
, XX
, XX
}
2202 static const unsigned char onebyte_has_modrm
[256] = {
2203 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2204 /* ------------------------------- */
2205 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
2206 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
2207 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
2208 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
2209 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
2210 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
2211 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
2212 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
2213 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
2214 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
2215 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
2216 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
2217 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
2218 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
2219 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
2220 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
2221 /* ------------------------------- */
2222 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2225 static const unsigned char twobyte_has_modrm
[256] = {
2226 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2227 /* ------------------------------- */
2228 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
2229 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
2230 /* 20 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 2f */
2231 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
2232 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
2233 /* 50 */ 1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1, /* 5f */
2234 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
2235 /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
2236 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
2237 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
2238 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
2239 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
2240 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
2241 /* d0 */ 0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* df */
2242 /* e0 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* ef */
2243 /* f0 */ 0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,0 /* ff */
2244 /* ------------------------------- */
2245 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2248 static const unsigned char twobyte_uses_SSE_prefix
[256] = {
2249 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2250 /* ------------------------------- */
2251 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
2252 /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
2253 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
2254 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
2255 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
2256 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
2257 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
2258 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
2259 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
2260 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
2261 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
2262 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
2263 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
2264 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
2265 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
2266 /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
2267 /* ------------------------------- */
2268 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2271 static char obuf
[100];
2273 static char scratchbuf
[100];
2274 static unsigned char *start_codep
;
2275 static unsigned char *insn_codep
;
2276 static unsigned char *codep
;
2277 static disassemble_info
*the_info
;
2281 static void oappend
PARAMS ((const char *s
));
2283 static const char *names64
[] = {
2284 "%rax","%rcx","%rdx","%rbx", "%rsp","%rbp","%rsi","%rdi",
2285 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
2287 static const char *names32
[] = {
2288 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
2289 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
2291 static const char *names16
[] = {
2292 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
2293 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
2295 static const char *names8
[] = {
2296 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
2298 static const char *names8rex
[] = {
2299 "%al","%cl","%dl","%bl","%spl", "%bpl", "%sil", "%dil",
2300 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
2302 static const char *names_seg
[] = {
2303 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
2305 static const char *index16
[] = {
2306 "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx"
2309 static const struct dis386 grps
[][8] = {
2312 { "addA", Eb
, Ib
, XX
},
2313 { "orA", Eb
, Ib
, XX
},
2314 { "adcA", Eb
, Ib
, XX
},
2315 { "sbbA", Eb
, Ib
, XX
},
2316 { "andA", Eb
, Ib
, XX
},
2317 { "subA", Eb
, Ib
, XX
},
2318 { "xorA", Eb
, Ib
, XX
},
2319 { "cmpA", Eb
, Ib
, XX
}
2323 { "addQ", Ev
, Iv
, XX
},
2324 { "orQ", Ev
, Iv
, XX
},
2325 { "adcQ", Ev
, Iv
, XX
},
2326 { "sbbQ", Ev
, Iv
, XX
},
2327 { "andQ", Ev
, Iv
, XX
},
2328 { "subQ", Ev
, Iv
, XX
},
2329 { "xorQ", Ev
, Iv
, XX
},
2330 { "cmpQ", Ev
, Iv
, XX
}
2334 { "addQ", Ev
, sIb
, XX
},
2335 { "orQ", Ev
, sIb
, XX
},
2336 { "adcQ", Ev
, sIb
, XX
},
2337 { "sbbQ", Ev
, sIb
, XX
},
2338 { "andQ", Ev
, sIb
, XX
},
2339 { "subQ", Ev
, sIb
, XX
},
2340 { "xorQ", Ev
, sIb
, XX
},
2341 { "cmpQ", Ev
, sIb
, XX
}
2345 { "rolA", Eb
, Ib
, XX
},
2346 { "rorA", Eb
, Ib
, XX
},
2347 { "rclA", Eb
, Ib
, XX
},
2348 { "rcrA", Eb
, Ib
, XX
},
2349 { "shlA", Eb
, Ib
, XX
},
2350 { "shrA", Eb
, Ib
, XX
},
2351 { "(bad)", XX
, XX
, XX
},
2352 { "sarA", Eb
, Ib
, XX
},
2356 { "rolQ", Ev
, Ib
, XX
},
2357 { "rorQ", Ev
, Ib
, XX
},
2358 { "rclQ", Ev
, Ib
, XX
},
2359 { "rcrQ", Ev
, Ib
, XX
},
2360 { "shlQ", Ev
, Ib
, XX
},
2361 { "shrQ", Ev
, Ib
, XX
},
2362 { "(bad)", XX
, XX
, XX
},
2363 { "sarQ", Ev
, Ib
, XX
},
2367 { "rolA", Eb
, XX
, XX
},
2368 { "rorA", Eb
, XX
, XX
},
2369 { "rclA", Eb
, XX
, XX
},
2370 { "rcrA", Eb
, XX
, XX
},
2371 { "shlA", Eb
, XX
, XX
},
2372 { "shrA", Eb
, XX
, XX
},
2373 { "(bad)", XX
, XX
, XX
},
2374 { "sarA", Eb
, XX
, XX
},
2378 { "rolQ", Ev
, XX
, XX
},
2379 { "rorQ", Ev
, XX
, XX
},
2380 { "rclQ", Ev
, XX
, XX
},
2381 { "rcrQ", Ev
, XX
, XX
},
2382 { "shlQ", Ev
, XX
, XX
},
2383 { "shrQ", Ev
, XX
, XX
},
2384 { "(bad)", XX
, XX
, XX
},
2385 { "sarQ", Ev
, XX
, XX
},
2389 { "rolA", Eb
, CL
, XX
},
2390 { "rorA", Eb
, CL
, XX
},
2391 { "rclA", Eb
, CL
, XX
},
2392 { "rcrA", Eb
, CL
, XX
},
2393 { "shlA", Eb
, CL
, XX
},
2394 { "shrA", Eb
, CL
, XX
},
2395 { "(bad)", XX
, XX
, XX
},
2396 { "sarA", Eb
, CL
, XX
},
2400 { "rolQ", Ev
, CL
, XX
},
2401 { "rorQ", Ev
, CL
, XX
},
2402 { "rclQ", Ev
, CL
, XX
},
2403 { "rcrQ", Ev
, CL
, XX
},
2404 { "shlQ", Ev
, CL
, XX
},
2405 { "shrQ", Ev
, CL
, XX
},
2406 { "(bad)", XX
, XX
, XX
},
2407 { "sarQ", Ev
, CL
, XX
}
2411 { "testA", Eb
, Ib
, XX
},
2412 { "(bad)", Eb
, XX
, XX
},
2413 { "notA", Eb
, XX
, XX
},
2414 { "negA", Eb
, XX
, XX
},
2415 { "mulB", AL
, Eb
, XX
},
2416 { "imulB", AL
, Eb
, XX
},
2417 { "divB", AL
, Eb
, XX
},
2418 { "idivB", AL
, Eb
, XX
}
2422 { "testQ", Ev
, Iv
, XX
},
2423 { "(bad)", XX
, XX
, XX
},
2424 { "notQ", Ev
, XX
, XX
},
2425 { "negQ", Ev
, XX
, XX
},
2426 { "mulS", eAX
, Ev
, XX
},
2427 { "imulS", eAX
, Ev
, XX
},
2428 { "divS", eAX
, Ev
, XX
},
2429 { "idivS", eAX
, Ev
, XX
},
2433 { "incA", Eb
, XX
, XX
},
2434 { "decA", Eb
, XX
, XX
},
2435 { "(bad)", XX
, XX
, XX
},
2436 { "(bad)", XX
, XX
, XX
},
2437 { "(bad)", XX
, XX
, XX
},
2438 { "(bad)", XX
, XX
, XX
},
2439 { "(bad)", XX
, XX
, XX
},
2440 { "(bad)", XX
, XX
, XX
},
2444 { "incQ", Ev
, XX
, XX
},
2445 { "decQ", Ev
, XX
, XX
},
2446 { "callI", indirEv
, XX
, XX
},
2447 { "lcallI", indirEv
, XX
, XX
},
2448 { "jmpI", indirEv
, XX
, XX
},
2449 { "ljmpI", indirEv
, XX
, XX
},
2450 { "pushT", Ev
, XX
, XX
},
2451 { "(bad)", XX
, XX
, XX
},
2455 { "sldt", Ew
, XX
, XX
},
2456 { "str", Ew
, XX
, XX
},
2457 { "lldt", Ew
, XX
, XX
},
2458 { "ltr", Ew
, XX
, XX
},
2459 { "verr", Ew
, XX
, XX
},
2460 { "verw", Ew
, XX
, XX
},
2461 { "(bad)", XX
, XX
, XX
},
2462 { "(bad)", XX
, XX
, XX
}
2466 { "sgdt", Ew
, XX
, XX
},
2467 { "sidt", Ew
, XX
, XX
},
2468 { "lgdt", Ew
, XX
, XX
},
2469 { "lidt", Ew
, XX
, XX
},
2470 { "smsw", Ew
, XX
, XX
},
2471 { "(bad)", XX
, XX
, XX
},
2472 { "lmsw", Ew
, XX
, XX
},
2473 { "invlpg", Ew
, XX
, XX
},
2477 { "(bad)", XX
, XX
, XX
},
2478 { "(bad)", XX
, XX
, XX
},
2479 { "(bad)", XX
, XX
, XX
},
2480 { "(bad)", XX
, XX
, XX
},
2481 { "btQ", Ev
, Ib
, XX
},
2482 { "btsQ", Ev
, Ib
, XX
},
2483 { "btrQ", Ev
, Ib
, XX
},
2484 { "btcQ", Ev
, Ib
, XX
},
2488 { "(bad)", XX
, XX
, XX
},
2489 { "cmpxchg8b", Ev
, XX
, XX
},
2490 { "(bad)", XX
, XX
, XX
},
2491 { "(bad)", XX
, XX
, XX
},
2492 { "(bad)", XX
, XX
, XX
},
2493 { "(bad)", XX
, XX
, XX
},
2494 { "(bad)", XX
, XX
, XX
},
2495 { "(bad)", XX
, XX
, XX
},
2499 { "(bad)", XX
, XX
, XX
},
2500 { "(bad)", XX
, XX
, XX
},
2501 { "psrlw", MS
, Ib
, XX
},
2502 { "(bad)", XX
, XX
, XX
},
2503 { "psraw", MS
, Ib
, XX
},
2504 { "(bad)", XX
, XX
, XX
},
2505 { "psllw", MS
, Ib
, XX
},
2506 { "(bad)", XX
, XX
, XX
},
2510 { "(bad)", XX
, XX
, XX
},
2511 { "(bad)", XX
, XX
, XX
},
2512 { "psrld", MS
, Ib
, XX
},
2513 { "(bad)", XX
, XX
, XX
},
2514 { "psrad", MS
, Ib
, XX
},
2515 { "(bad)", XX
, XX
, XX
},
2516 { "pslld", MS
, Ib
, XX
},
2517 { "(bad)", XX
, XX
, XX
},
2521 { "(bad)", XX
, XX
, XX
},
2522 { "(bad)", XX
, XX
, XX
},
2523 { "psrlq", MS
, Ib
, XX
},
2524 { "psrldq", MS
, Ib
, XX
},
2525 { "(bad)", XX
, XX
, XX
},
2526 { "(bad)", XX
, XX
, XX
},
2527 { "psllq", MS
, Ib
, XX
},
2528 { "pslldq", MS
, Ib
, XX
},
2532 { "fxsave", Ev
, XX
, XX
},
2533 { "fxrstor", Ev
, XX
, XX
},
2534 { "ldmxcsr", Ev
, XX
, XX
},
2535 { "stmxcsr", Ev
, XX
, XX
},
2536 { "(bad)", XX
, XX
, XX
},
2537 { "lfence", None
, XX
, XX
},
2538 { "mfence", None
, XX
, XX
},
2539 { "sfence", None
, XX
, XX
},
2540 /* FIXME: the sfence with memory operand is clflush! */
2544 { "prefetchnta", Ev
, XX
, XX
},
2545 { "prefetcht0", Ev
, XX
, XX
},
2546 { "prefetcht1", Ev
, XX
, XX
},
2547 { "prefetcht2", Ev
, XX
, XX
},
2548 { "(bad)", XX
, XX
, XX
},
2549 { "(bad)", XX
, XX
, XX
},
2550 { "(bad)", XX
, XX
, XX
},
2551 { "(bad)", XX
, XX
, XX
},
2555 { "prefetch", Eb
, XX
, XX
},
2556 { "prefetchw", Eb
, XX
, XX
},
2557 { "(bad)", XX
, XX
, XX
},
2558 { "(bad)", XX
, XX
, XX
},
2559 { "(bad)", XX
, XX
, XX
},
2560 { "(bad)", XX
, XX
, XX
},
2561 { "(bad)", XX
, XX
, XX
},
2562 { "(bad)", XX
, XX
, XX
},
2567 static const struct dis386 prefix_user_table
[][4] = {
2570 { "addps", XM
, EX
, XX
},
2571 { "addss", XM
, EX
, XX
},
2572 { "addpd", XM
, EX
, XX
},
2573 { "addsd", XM
, EX
, XX
},
2577 { "", XM
, EX
, OPSIMD
}, /* See OP_SIMD_SUFFIX */
2578 { "", XM
, EX
, OPSIMD
},
2579 { "", XM
, EX
, OPSIMD
},
2580 { "", XM
, EX
, OPSIMD
},
2584 { "cvtpi2ps", XM
, EM
, XX
},
2585 { "cvtsi2ssY", XM
, Ev
, XX
},
2586 { "cvtpi2pd", XM
, EM
, XX
},
2587 { "cvtsi2sdY", XM
, Ev
, XX
},
2591 { "cvtps2pi", MX
, EX
, XX
},
2592 { "cvtss2siY", Gv
, EX
, XX
},
2593 { "cvtpd2pi", MX
, EX
, XX
},
2594 { "cvtsd2siY", Gv
, EX
, XX
},
2598 { "cvttps2pi", MX
, EX
, XX
},
2599 { "cvttss2siY", Gv
, EX
, XX
},
2600 { "cvttpd2pi", MX
, EX
, XX
},
2601 { "cvttsd2siY", Gv
, EX
, XX
},
2605 { "divps", XM
, EX
, XX
},
2606 { "divss", XM
, EX
, XX
},
2607 { "divpd", XM
, EX
, XX
},
2608 { "divsd", XM
, EX
, XX
},
2612 { "maxps", XM
, EX
, XX
},
2613 { "maxss", XM
, EX
, XX
},
2614 { "maxpd", XM
, EX
, XX
},
2615 { "maxsd", XM
, EX
, XX
},
2619 { "minps", XM
, EX
, XX
},
2620 { "minss", XM
, EX
, XX
},
2621 { "minpd", XM
, EX
, XX
},
2622 { "minsd", XM
, EX
, XX
},
2626 { "movups", XM
, EX
, XX
},
2627 { "movss", XM
, EX
, XX
},
2628 { "movupd", XM
, EX
, XX
},
2629 { "movsd", XM
, EX
, XX
},
2633 { "movups", EX
, XM
, XX
},
2634 { "movss", EX
, XM
, XX
},
2635 { "movupd", EX
, XM
, XX
},
2636 { "movsd", EX
, XM
, XX
},
2640 { "mulps", XM
, EX
, XX
},
2641 { "mulss", XM
, EX
, XX
},
2642 { "mulpd", XM
, EX
, XX
},
2643 { "mulsd", XM
, EX
, XX
},
2647 { "rcpps", XM
, EX
, XX
},
2648 { "rcpss", XM
, EX
, XX
},
2649 { "(bad)", XM
, EX
, XX
},
2650 { "(bad)", XM
, EX
, XX
},
2654 { "rsqrtps", XM
, EX
, XX
},
2655 { "rsqrtss", XM
, EX
, XX
},
2656 { "(bad)", XM
, EX
, XX
},
2657 { "(bad)", XM
, EX
, XX
},
2661 { "sqrtps", XM
, EX
, XX
},
2662 { "sqrtss", XM
, EX
, XX
},
2663 { "sqrtpd", XM
, EX
, XX
},
2664 { "sqrtsd", XM
, EX
, XX
},
2668 { "subps", XM
, EX
, XX
},
2669 { "subss", XM
, EX
, XX
},
2670 { "subpd", XM
, EX
, XX
},
2671 { "subsd", XM
, EX
, XX
},
2675 { "(bad)", XM
, EX
, XX
},
2676 { "cvtdq2pd", XM
, EX
, XX
},
2677 { "cvttpd2dq", XM
, EX
, XX
},
2678 { "cvtpd2dq", XM
, EX
, XX
},
2682 { "cvtdq2ps", XM
, EX
, XX
},
2683 { "cvttps2dq",XM
, EX
, XX
},
2684 { "cvtps2dq",XM
, EX
, XX
},
2685 { "(bad)", XM
, EX
, XX
},
2689 { "cvtps2pd", XM
, EX
, XX
},
2690 { "cvtss2sd", XM
, EX
, XX
},
2691 { "cvtpd2ps", XM
, EX
, XX
},
2692 { "cvtsd2ss", XM
, EX
, XX
},
2696 { "maskmovq", MX
, EM
, XX
},
2697 { "(bad)", XM
, EX
, XX
},
2698 { "maskmovdqu", XM
, EX
, XX
},
2699 { "(bad)", XM
, EX
, XX
},
2703 { "movq", MX
, EM
, XX
},
2704 { "movdqu", XM
, EX
, XX
},
2705 { "movdqa", XM
, EX
, XX
},
2706 { "(bad)", XM
, EX
, XX
},
2710 { "movq", EM
, MX
, XX
},
2711 { "movdqu", EX
, XM
, XX
},
2712 { "movdqa", EX
, XM
, XX
},
2713 { "(bad)", EX
, XM
, XX
},
2717 { "(bad)", EX
, XM
, XX
},
2718 { "movq2dq", EX
, EM
, XX
},
2719 { "movq", EX
, XM
, XX
},
2720 { "movdq2q", EM
, MX
, XX
},
2724 { "pshufw", MX
, EM
, Ib
},
2725 { "pshufhw", XM
, EX
, Ib
},
2726 { "pshufd", XM
, EX
, Ib
},
2727 { "pshuflw", XM
, EX
, Ib
},
2731 { "movd", Ed
, MX
, XX
},
2732 { "movq", Ed
, XM
, XX
},
2733 { "movd", Ed
, XM
, XX
},
2734 { "(bad)", Ed
, XM
, XX
},
2738 { "(bad)", MX
, EX
, XX
},
2739 { "(bad)", XM
, EX
, XX
},
2740 { "punpckhqdq", XM
, EX
, XX
},
2741 { "(bad)", XM
, EX
, XX
},
2745 { "movntq", Ev
, MX
, XX
},
2746 { "(bad)", Ev
, XM
, XX
},
2747 { "movntdq", Ev
, XM
, XX
},
2748 { "(bad)", Ev
, XM
, XX
},
2752 { "(bad)", MX
, EX
, XX
},
2753 { "(bad)", XM
, EX
, XX
},
2754 { "punpcklqdq", XM
, EX
, XX
},
2755 { "(bad)", XM
, EX
, XX
},
2759 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
2771 FETCH_DATA (the_info
, codep
+ 1);
2775 /* REX prefixes family. */
2798 prefixes
|= PREFIX_REPZ
;
2801 prefixes
|= PREFIX_REPNZ
;
2804 prefixes
|= PREFIX_LOCK
;
2807 prefixes
|= PREFIX_CS
;
2810 prefixes
|= PREFIX_SS
;
2813 prefixes
|= PREFIX_DS
;
2816 prefixes
|= PREFIX_ES
;
2819 prefixes
|= PREFIX_FS
;
2822 prefixes
|= PREFIX_GS
;
2825 prefixes
|= PREFIX_DATA
;
2828 prefixes
|= PREFIX_ADDR
;
2831 /* fwait is really an instruction. If there are prefixes
2832 before the fwait, they belong to the fwait, *not* to the
2833 following instruction. */
2836 prefixes
|= PREFIX_FWAIT
;
2840 prefixes
= PREFIX_FWAIT
;
2845 /* Rex is ignored when followed by another prefix. */
2848 oappend (prefix_name (rex
, 0));
2856 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
2860 prefix_name (pref
, sizeflag
)
2866 /* REX prefixes family. */
2918 return (sizeflag
& DFLAG
) ? "data16" : "data32";
2920 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
2928 static char op1out
[100], op2out
[100], op3out
[100];
2929 static int op_ad
, op_index
[3];
2930 static unsigned int op_address
[3];
2931 static unsigned int op_riprel
[3];
2932 static bfd_vma start_pc
;
2936 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
2937 * (see topic "Redundant prefixes" in the "Differences from 8086"
2938 * section of the "Virtual 8086 Mode" chapter.)
2939 * 'pc' should be the address of this instruction, it will
2940 * be used to print the target address if this is a relative jump or call
2941 * The function returns the length of this instruction in bytes.
2944 static int print_insn_i386
2945 PARAMS ((bfd_vma pc
, disassemble_info
*info
));
2947 static char intel_syntax
;
2948 static char open_char
;
2949 static char close_char
;
2950 static char separator_char
;
2951 static char scale_char
;
2954 print_insn_i386_att (pc
, info
)
2956 disassemble_info
*info
;
2961 separator_char
= ',';
2964 return print_insn_i386 (pc
, info
);
2968 print_insn_i386_intel (pc
, info
)
2970 disassemble_info
*info
;
2975 separator_char
= '+';
2978 return print_insn_i386 (pc
, info
);
2982 print_insn_i386 (pc
, info
)
2984 disassemble_info
*info
;
2986 const struct dis386
*dp
;
2989 char *first
, *second
, *third
;
2991 unsigned char need_modrm
;
2992 unsigned char uses_SSE_prefix
;
2993 VOLATILE
int sizeflag
;
2994 VOLATILE
int orig_sizeflag
;
2996 struct dis_private priv
;
2997 bfd_byte
*inbuf
= priv
.the_buffer
;
2999 mode_64bit
= (info
->mach
== bfd_mach_x86_64_intel_syntax
3000 || info
->mach
== bfd_mach_x86_64
);
3002 if (info
->mach
== bfd_mach_i386_i386
3003 || info
->mach
== bfd_mach_x86_64
3004 || info
->mach
== bfd_mach_i386_i386_intel_syntax
3005 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
3006 sizeflag
= AFLAG
|DFLAG
;
3007 else if (info
->mach
== bfd_mach_i386_i8086
)
3011 orig_sizeflag
= sizeflag
;
3013 /* The output looks better if we put 7 bytes on a line, since that
3014 puts most long word instructions on a single line. */
3015 info
->bytes_per_line
= 7;
3017 info
->private_data
= (PTR
) &priv
;
3018 priv
.max_fetched
= priv
.the_buffer
;
3019 priv
.insn_start
= pc
;
3026 op_index
[0] = op_index
[1] = op_index
[2] = -1;
3030 start_codep
= inbuf
;
3033 if (setjmp (priv
.bailout
) != 0)
3037 /* Getting here means we tried for data but didn't get it. That
3038 means we have an incomplete instruction of some sort. Just
3039 print the first byte as a prefix or a .byte pseudo-op. */
3042 name
= prefix_name (inbuf
[0], orig_sizeflag
);
3044 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3047 /* Just print the first byte as a .byte instruction. */
3048 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
3049 (unsigned int) inbuf
[0]);
3063 FETCH_DATA (info
, codep
+ 1);
3064 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
3066 if ((prefixes
& PREFIX_FWAIT
)
3067 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
3071 /* fwait not followed by floating point instruction. Print the
3072 first prefix, which is probably fwait itself. */
3073 name
= prefix_name (inbuf
[0], orig_sizeflag
);
3075 name
= INTERNAL_DISASSEMBLER_ERROR
;
3076 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3082 FETCH_DATA (info
, codep
+ 2);
3084 dp
= &dis386_twobyte_intel
[*++codep
];
3086 dp
= &dis386_twobyte_att
[*++codep
];
3087 need_modrm
= twobyte_has_modrm
[*codep
];
3088 uses_SSE_prefix
= twobyte_uses_SSE_prefix
[*codep
];
3094 dp
= &dis386_64_intel
[*codep
];
3096 dp
= &dis386_intel
[*codep
];
3099 dp
= &disx86_64_att
[*codep
];
3101 dp
= &dis386_att
[*codep
];
3102 need_modrm
= onebyte_has_modrm
[*codep
];
3103 uses_SSE_prefix
= 0;
3107 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_REPZ
))
3110 used_prefixes
|= PREFIX_REPZ
;
3112 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_REPNZ
))
3115 used_prefixes
|= PREFIX_REPNZ
;
3117 if (prefixes
& PREFIX_LOCK
)
3120 used_prefixes
|= PREFIX_LOCK
;
3123 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_DATA
))
3126 if (prefixes
& PREFIX_ADDR
)
3129 if (sizeflag
& AFLAG
)
3130 oappend ("addr32 ");
3132 oappend ("addr16 ");
3133 used_prefixes
|= PREFIX_ADDR
;
3138 FETCH_DATA (info
, codep
+ 1);
3139 mod
= (*codep
>> 6) & 3;
3140 reg
= (*codep
>> 3) & 7;
3144 if (dp
->name
== NULL
&& dp
->bytemode1
== FLOATCODE
)
3151 if (dp
->name
== NULL
)
3153 switch(dp
->bytemode2
)
3156 dp
= &grps
[dp
->bytemode1
][reg
];
3158 case USE_PREFIX_USER_TABLE
:
3160 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
3161 if (prefixes
& PREFIX_REPZ
)
3165 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3166 if (prefixes
& PREFIX_DATA
)
3170 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
3171 if (prefixes
& PREFIX_REPNZ
)
3176 dp
= &prefix_user_table
[dp
->bytemode1
][index
];
3179 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3184 putop (dp
->name
, sizeflag
);
3189 (*dp
->op1
)(dp
->bytemode1
, sizeflag
);
3194 (*dp
->op2
)(dp
->bytemode2
, sizeflag
);
3199 (*dp
->op3
)(dp
->bytemode3
, sizeflag
);
3202 /* See if any prefixes were not used. If so, print the first one
3203 separately. If we don't do this, we'll wind up printing an
3204 instruction stream which does not precisely correspond to the
3205 bytes we are disassembling. */
3206 if ((prefixes
& ~used_prefixes
) != 0)
3210 name
= prefix_name (inbuf
[0], orig_sizeflag
);
3212 name
= INTERNAL_DISASSEMBLER_ERROR
;
3213 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
3216 if (rex
& ~rex_used
)
3219 name
= prefix_name (rex
| 0x40, orig_sizeflag
);
3221 name
= INTERNAL_DISASSEMBLER_ERROR
;
3222 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
3225 obufp
= obuf
+ strlen (obuf
);
3226 for (i
= strlen (obuf
); i
< 6; i
++)
3229 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
3231 /* The enter and bound instructions are printed with operands in the same
3232 order as the intel book; everything else is printed in reverse order. */
3233 if (intel_syntax
|| two_source_ops
)
3238 op_ad
= op_index
[0];
3239 op_index
[0] = op_index
[2];
3240 op_index
[2] = op_ad
;
3251 if (op_index
[0] != -1 && !op_riprel
[0])
3252 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[0]], info
);
3254 (*info
->fprintf_func
) (info
->stream
, "%s", first
);
3260 (*info
->fprintf_func
) (info
->stream
, ",");
3261 if (op_index
[1] != -1 && !op_riprel
[1])
3262 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[1]], info
);
3264 (*info
->fprintf_func
) (info
->stream
, "%s", second
);
3270 (*info
->fprintf_func
) (info
->stream
, ",");
3271 if (op_index
[2] != -1 && !op_riprel
[2])
3272 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[2]], info
);
3274 (*info
->fprintf_func
) (info
->stream
, "%s", third
);
3276 for (i
= 0; i
< 3; i
++)
3277 if (op_index
[i
] != -1 && op_riprel
[i
])
3279 (*info
->fprintf_func
) (info
->stream
, " # ");
3280 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
3281 + op_address
[op_index
[i
]]), info
);
3283 return codep
- inbuf
;
3286 static const char *float_mem_att
[] = {
3361 static const char *float_mem_intel
[] = {
3437 #define STi OP_STi, 0
3439 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
3440 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
3441 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
3442 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
3443 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
3444 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
3445 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
3446 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
3447 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
3449 static const struct dis386 float_reg
[][8] = {
3452 { "fadd", ST
, STi
, XX
},
3453 { "fmul", ST
, STi
, XX
},
3454 { "fcom", STi
, XX
, XX
},
3455 { "fcomp", STi
, XX
, XX
},
3456 { "fsub", ST
, STi
, XX
},
3457 { "fsubr", ST
, STi
, XX
},
3458 { "fdiv", ST
, STi
, XX
},
3459 { "fdivr", ST
, STi
, XX
},
3463 { "fld", STi
, XX
, XX
},
3464 { "fxch", STi
, XX
, XX
},
3466 { "(bad)", XX
, XX
, XX
},
3474 { "fcmovb", ST
, STi
, XX
},
3475 { "fcmove", ST
, STi
, XX
},
3476 { "fcmovbe",ST
, STi
, XX
},
3477 { "fcmovu", ST
, STi
, XX
},
3478 { "(bad)", XX
, XX
, XX
},
3480 { "(bad)", XX
, XX
, XX
},
3481 { "(bad)", XX
, XX
, XX
},
3485 { "fcmovnb",ST
, STi
, XX
},
3486 { "fcmovne",ST
, STi
, XX
},
3487 { "fcmovnbe",ST
, STi
, XX
},
3488 { "fcmovnu",ST
, STi
, XX
},
3490 { "fucomi", ST
, STi
, XX
},
3491 { "fcomi", ST
, STi
, XX
},
3492 { "(bad)", XX
, XX
, XX
},
3496 { "fadd", STi
, ST
, XX
},
3497 { "fmul", STi
, ST
, XX
},
3498 { "(bad)", XX
, XX
, XX
},
3499 { "(bad)", XX
, XX
, XX
},
3501 { "fsub", STi
, ST
, XX
},
3502 { "fsubr", STi
, ST
, XX
},
3503 { "fdiv", STi
, ST
, XX
},
3504 { "fdivr", STi
, ST
, XX
},
3506 { "fsubr", STi
, ST
, XX
},
3507 { "fsub", STi
, ST
, XX
},
3508 { "fdivr", STi
, ST
, XX
},
3509 { "fdiv", STi
, ST
, XX
},
3514 { "ffree", STi
, XX
, XX
},
3515 { "(bad)", XX
, XX
, XX
},
3516 { "fst", STi
, XX
, XX
},
3517 { "fstp", STi
, XX
, XX
},
3518 { "fucom", STi
, XX
, XX
},
3519 { "fucomp", STi
, XX
, XX
},
3520 { "(bad)", XX
, XX
, XX
},
3521 { "(bad)", XX
, XX
, XX
},
3525 { "faddp", STi
, ST
, XX
},
3526 { "fmulp", STi
, ST
, XX
},
3527 { "(bad)", XX
, XX
, XX
},
3530 { "fsubp", STi
, ST
, XX
},
3531 { "fsubrp", STi
, ST
, XX
},
3532 { "fdivp", STi
, ST
, XX
},
3533 { "fdivrp", STi
, ST
, XX
},
3535 { "fsubrp", STi
, ST
, XX
},
3536 { "fsubp", STi
, ST
, XX
},
3537 { "fdivrp", STi
, ST
, XX
},
3538 { "fdivp", STi
, ST
, XX
},
3543 { "ffreep", STi
, XX
, XX
},
3544 { "(bad)", XX
, XX
, XX
},
3545 { "(bad)", XX
, XX
, XX
},
3546 { "(bad)", XX
, XX
, XX
},
3548 { "fucomip",ST
, STi
, XX
},
3549 { "fcomip", ST
, STi
, XX
},
3550 { "(bad)", XX
, XX
, XX
},
3555 static char *fgrps
[][8] = {
3558 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3563 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
3568 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
3573 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
3578 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
3583 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3588 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
3589 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
3594 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3599 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3607 const struct dis386
*dp
;
3608 unsigned char floatop
;
3610 floatop
= codep
[-1];
3615 putop (float_mem_intel
[(floatop
- 0xd8 ) * 8 + reg
], sizeflag
);
3617 putop (float_mem_att
[(floatop
- 0xd8 ) * 8 + reg
], sizeflag
);
3619 if (floatop
== 0xdb)
3620 OP_E (x_mode
, sizeflag
);
3621 else if (floatop
== 0xdd)
3622 OP_E (d_mode
, sizeflag
);
3624 OP_E (v_mode
, sizeflag
);
3629 dp
= &float_reg
[floatop
- 0xd8][reg
];
3630 if (dp
->name
== NULL
)
3632 putop (fgrps
[dp
->bytemode1
][rm
], sizeflag
);
3634 /* instruction fnstsw is only one with strange arg */
3635 if (floatop
== 0xdf && codep
[-1] == 0xe0)
3636 strcpy (op1out
, names16
[0]);
3640 putop (dp
->name
, sizeflag
);
3644 (*dp
->op1
)(dp
->bytemode1
, sizeflag
);
3647 (*dp
->op2
)(dp
->bytemode2
, sizeflag
);
3653 OP_ST (ignore
, sizeflag
)
3654 int ignore ATTRIBUTE_UNUSED
;
3655 int sizeflag ATTRIBUTE_UNUSED
;
3662 OP_STi (ignore
, sizeflag
)
3663 int ignore ATTRIBUTE_UNUSED
;
3664 int sizeflag ATTRIBUTE_UNUSED
;
3666 sprintf (scratchbuf
, "%%st(%d)", rm
);
3667 oappend (scratchbuf
);
3671 /* capital letters in template are macros */
3673 putop (template, sizeflag
)
3674 const char *template;
3679 for (p
= template; *p
; p
++)
3690 #ifdef SUFFIX_ALWAYS
3691 || (sizeflag
& SUFFIX_ALWAYS
)
3699 #ifdef SUFFIX_ALWAYS
3700 if (sizeflag
& SUFFIX_ALWAYS
)
3704 case 'E': /* For jcxz/jecxz */
3705 if (sizeflag
& AFLAG
)
3715 if ((prefixes
& PREFIX_DATA
)
3716 #ifdef SUFFIX_ALWAYS
3717 || (sizeflag
& SUFFIX_ALWAYS
)
3721 if (sizeflag
& DFLAG
)
3725 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3732 #ifdef SUFFIX_ALWAYS
3733 if (sizeflag
& SUFFIX_ALWAYS
)
3738 if ((prefixes
& PREFIX_FWAIT
) == 0)
3741 used_prefixes
|= PREFIX_FWAIT
;
3744 USED_REX (REX_MODE64
);
3745 if (rex
& REX_MODE64
)
3753 if ((prefixes
& PREFIX_DATA
)
3754 || (rex
& REX_MODE64
)
3755 #ifdef SUFFIX_ALWAYS
3756 || (sizeflag
& SUFFIX_ALWAYS
)
3760 USED_REX (REX_MODE64
);
3761 if (rex
& REX_MODE64
)
3765 if (sizeflag
& DFLAG
)
3769 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3776 USED_REX (REX_MODE64
);
3778 #ifdef SUFFIX_ALWAYS
3779 || (sizeflag
& SUFFIX_ALWAYS
)
3783 if (rex
& REX_MODE64
)
3787 if (sizeflag
& DFLAG
)
3791 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3796 USED_REX (REX_MODE64
);
3799 if (rex
& REX_MODE64
)
3804 else if (sizeflag
& DFLAG
)
3817 if (rex
& REX_MODE64
)
3819 else if (sizeflag
& DFLAG
)
3824 if (!(rex
& REX_MODE64
))
3825 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3830 #ifdef SUFFIX_ALWAYS
3831 if (sizeflag
& SUFFIX_ALWAYS
)
3833 if (rex
& REX_MODE64
)
3837 if (sizeflag
& DFLAG
)
3841 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3852 #ifdef SUFFIX_ALWAYS
3853 || (sizeflag
& SUFFIX_ALWAYS
)
3857 if (sizeflag
& DFLAG
)
3861 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3865 if (prefixes
& PREFIX_DATA
)
3869 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3874 if (rex
& REX_MODE64
)
3876 USED_REX (REX_MODE64
);
3880 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
3882 /* operand size flag for cwtl, cbtw */
3886 else if (sizeflag
& DFLAG
)
3897 if (sizeflag
& DFLAG
)
3908 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3920 obufp
+= strlen (s
);
3926 if (prefixes
& PREFIX_CS
)
3929 used_prefixes
|= PREFIX_CS
;
3931 if (prefixes
& PREFIX_DS
)
3934 used_prefixes
|= PREFIX_DS
;
3936 if (prefixes
& PREFIX_SS
)
3939 used_prefixes
|= PREFIX_SS
;
3941 if (prefixes
& PREFIX_ES
)
3944 used_prefixes
|= PREFIX_ES
;
3946 if (prefixes
& PREFIX_FS
)
3949 used_prefixes
|= PREFIX_FS
;
3951 if (prefixes
& PREFIX_GS
)
3954 used_prefixes
|= PREFIX_GS
;
3959 OP_indirE (bytemode
, sizeflag
)
3965 OP_E (bytemode
, sizeflag
);
3969 print_operand_value (buf
, hex
, disp
)
3982 sprintf_vma (tmp
, disp
);
3983 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+1]; i
++);
3984 strcpy (buf
+ 2, tmp
+ i
);
3988 bfd_signed_vma v
= disp
;
3995 /* Check for possible overflow on 0x8000000000000000 */
3998 strcpy (buf
, "9223372036854775808");
4012 tmp
[28-i
] = (v
% 10) + '0';
4016 strcpy (buf
, tmp
+ 29 - i
);
4022 sprintf (buf
, "0x%x", (unsigned int) disp
);
4024 sprintf (buf
, "%d", (int) disp
);
4029 OP_E (bytemode
, sizeflag
)
4036 USED_REX (REX_EXTZ
);
4040 /* skip mod/rm byte */
4050 oappend (names8rex
[rm
+ add
]);
4052 oappend (names8
[rm
+ add
]);
4055 oappend (names16
[rm
+ add
]);
4058 oappend (names32
[rm
+ add
]);
4061 oappend (names64
[rm
+ add
]);
4065 oappend (names64
[rm
+ add
]);
4067 oappend (names32
[rm
+ add
]);
4070 USED_REX (REX_MODE64
);
4071 if (rex
& REX_MODE64
)
4072 oappend (names64
[rm
+ add
]);
4073 else if (sizeflag
& DFLAG
)
4074 oappend (names32
[rm
+ add
]);
4076 oappend (names16
[rm
+ add
]);
4077 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4080 if ( !(codep
[-2] == 0xAE && codep
[-1] == 0xF8 /* sfence */)
4081 && !(codep
[-2] == 0xAE && codep
[-1] == 0xF0 /* mfence */)
4082 && !(codep
[-2] == 0xAE && codep
[-1] == 0xe8 /* lfence */))
4083 BadOp(); /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */
4086 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4095 if (sizeflag
& AFLAG
) /* 32 bit address mode */
4110 FETCH_DATA (the_info
, codep
+ 1);
4111 scale
= (*codep
>> 6) & 3;
4112 index
= (*codep
>> 3) & 7;
4114 USED_REX (REX_EXTY
);
4115 USED_REX (REX_EXTZ
);
4126 if ((base
& 7) == 5)
4129 if (mode_64bit
&& !havesib
)
4135 FETCH_DATA (the_info
, codep
+ 1);
4137 if ((disp
& 0x80) != 0)
4146 if (mod
!= 0 || (base
& 7) == 5)
4148 print_operand_value (scratchbuf
, !riprel
, disp
);
4149 oappend (scratchbuf
);
4157 if (havebase
|| (havesib
&& (index
!= 4 || scale
!= 0)))
4164 oappend ("BYTE PTR ");
4167 oappend ("WORD PTR ");
4170 oappend ("DWORD PTR ");
4173 oappend ("QWORD PTR ");
4177 oappend ("DWORD PTR ");
4179 oappend ("QWORD PTR ");
4182 oappend ("XWORD PTR ");
4188 *obufp
++ = open_char
;
4189 if (intel_syntax
&& riprel
)
4192 USED_REX (REX_EXTZ
);
4193 if (!havesib
&& (rex
& REX_EXTZ
))
4196 oappend (mode_64bit
? names64
[base
] : names32
[base
]);
4205 *obufp
++ = separator_char
;
4208 sprintf (scratchbuf
, "%s", mode_64bit
? names64
[index
] : names32
[index
]);
4211 sprintf (scratchbuf
, ",%s", mode_64bit
? names64
[index
] : names32
[index
]);
4212 oappend (scratchbuf
);
4216 && bytemode
!= b_mode
4217 && bytemode
!= w_mode
4218 && bytemode
!= v_mode
))
4220 *obufp
++ = scale_char
;
4222 sprintf (scratchbuf
, "%d", 1 << scale
);
4223 oappend (scratchbuf
);
4227 if (mod
!= 0 || (base
& 7) == 5)
4229 /* Don't print zero displacements */
4232 print_operand_value (scratchbuf
, 0, disp
);
4233 oappend (scratchbuf
);
4237 *obufp
++ = close_char
;
4240 else if (intel_syntax
)
4242 if (mod
!= 0 || (base
& 7) == 5)
4244 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4245 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
4249 oappend (names_seg
[3]);
4252 print_operand_value (scratchbuf
, 1, disp
);
4253 oappend (scratchbuf
);
4258 { /* 16 bit address mode */
4265 if ((disp
& 0x8000) != 0)
4270 FETCH_DATA (the_info
, codep
+ 1);
4272 if ((disp
& 0x80) != 0)
4277 if ((disp
& 0x8000) != 0)
4283 if (mod
!= 0 || (rm
& 7) == 6)
4285 print_operand_value (scratchbuf
, 0, disp
);
4286 oappend (scratchbuf
);
4289 if (mod
!= 0 || (rm
& 7) != 6)
4291 *obufp
++ = open_char
;
4293 oappend (index16
[rm
+ add
]);
4294 *obufp
++ = close_char
;
4301 OP_G (bytemode
, sizeflag
)
4306 USED_REX (REX_EXTX
);
4314 oappend (names8rex
[reg
+ add
]);
4316 oappend (names8
[reg
+ add
]);
4319 oappend (names16
[reg
+ add
]);
4322 oappend (names32
[reg
+ add
]);
4325 oappend (names64
[reg
+ add
]);
4328 USED_REX (REX_MODE64
);
4329 if (rex
& REX_MODE64
)
4330 oappend (names64
[reg
+ add
]);
4331 else if (sizeflag
& DFLAG
)
4332 oappend (names32
[reg
+ add
]);
4334 oappend (names16
[reg
+ add
]);
4335 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4338 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4351 FETCH_DATA (the_info
, codep
+ 8);
4352 a
= *codep
++ & 0xff;
4353 a
|= (*codep
++ & 0xff) << 8;
4354 a
|= (*codep
++ & 0xff) << 16;
4355 a
|= (*codep
++ & 0xff) << 24;
4356 b
|= (*codep
++ & 0xff);
4357 b
|= (*codep
++ & 0xff) << 8;
4358 b
|= (*codep
++ & 0xff) << 16;
4359 b
|= (*codep
++ & 0xff) << 24;
4360 x
= a
+ ((bfd_vma
) b
<< 32);
4367 static bfd_signed_vma
4370 bfd_signed_vma x
= 0;
4372 FETCH_DATA (the_info
, codep
+ 4);
4373 x
= *codep
++ & (bfd_signed_vma
) 0xff;
4374 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
4375 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
4376 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
4380 static bfd_signed_vma
4383 bfd_signed_vma x
= 0;
4385 FETCH_DATA (the_info
, codep
+ 4);
4386 x
= *codep
++ & (bfd_signed_vma
) 0xff;
4387 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
4388 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
4389 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
4391 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
4401 FETCH_DATA (the_info
, codep
+ 2);
4402 x
= *codep
++ & 0xff;
4403 x
|= (*codep
++ & 0xff) << 8;
4412 op_index
[op_ad
] = op_ad
;
4413 op_address
[op_ad
] = op
;
4414 op_riprel
[op_ad
] = riprel
;
4418 OP_REG (code
, sizeflag
)
4424 USED_REX (REX_EXTZ
);
4433 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
4434 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
4435 s
= names16
[code
- ax_reg
+ add
];
4437 case es_reg
: case ss_reg
: case cs_reg
:
4438 case ds_reg
: case fs_reg
: case gs_reg
:
4439 s
= names_seg
[code
- es_reg
+ add
];
4441 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
4442 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
4445 s
= names8rex
[code
- al_reg
+ add
];
4447 s
= names8
[code
- al_reg
];
4449 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
4450 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
4451 USED_REX (REX_MODE64
);
4452 if (rex
& REX_MODE64
)
4453 s
= names64
[code
- eAX_reg
+ add
];
4454 else if (sizeflag
& DFLAG
)
4455 s
= names32
[code
- eAX_reg
+ add
];
4457 s
= names16
[code
- eAX_reg
+ add
];
4458 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4460 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
4461 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
4462 s
= names64
[code
- rAX_reg
+ add
];
4465 s
= INTERNAL_DISASSEMBLER_ERROR
;
4472 OP_IMREG (code
, sizeflag
)
4483 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
4484 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
4485 s
= names16
[code
- ax_reg
];
4487 case es_reg
: case ss_reg
: case cs_reg
:
4488 case ds_reg
: case fs_reg
: case gs_reg
:
4489 s
= names_seg
[code
- es_reg
];
4491 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
4492 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
4495 s
= names8rex
[code
- al_reg
];
4497 s
= names8
[code
- al_reg
];
4499 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
4500 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
4501 USED_REX (REX_MODE64
);
4502 if (rex
& REX_MODE64
)
4503 s
= names64
[code
- eAX_reg
];
4504 else if (sizeflag
& DFLAG
)
4505 s
= names32
[code
- eAX_reg
];
4507 s
= names16
[code
- eAX_reg
];
4508 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4511 s
= INTERNAL_DISASSEMBLER_ERROR
;
4518 OP_I (bytemode
, sizeflag
)
4523 bfd_signed_vma mask
= -1;
4528 FETCH_DATA (the_info
, codep
+ 1);
4536 USED_REX (REX_MODE64
);
4537 if (rex
& REX_MODE64
)
4539 else if (sizeflag
& DFLAG
)
4549 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4556 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4561 scratchbuf
[0] = '$';
4562 print_operand_value (scratchbuf
+ !intel_syntax
, 1, op
);
4563 oappend (scratchbuf
);
4564 scratchbuf
[0] = '\0';
4568 OP_I64 (bytemode
, sizeflag
)
4573 bfd_signed_vma mask
= -1;
4578 FETCH_DATA (the_info
, codep
+ 1);
4583 USED_REX (REX_MODE64
);
4584 if (rex
& REX_MODE64
)
4586 else if (sizeflag
& DFLAG
)
4596 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4603 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4608 scratchbuf
[0] = '$';
4609 print_operand_value (scratchbuf
+ !intel_syntax
, 1, op
);
4610 oappend (scratchbuf
);
4611 scratchbuf
[0] = '\0';
4615 OP_sI (bytemode
, sizeflag
)
4620 bfd_signed_vma mask
= -1;
4625 FETCH_DATA (the_info
, codep
+ 1);
4627 if ((op
& 0x80) != 0)
4632 USED_REX (REX_MODE64
);
4633 if (rex
& REX_MODE64
)
4635 else if (sizeflag
& DFLAG
)
4644 if ((op
& 0x8000) != 0)
4647 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4652 if ((op
& 0x8000) != 0)
4656 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4660 scratchbuf
[0] = '$';
4661 print_operand_value (scratchbuf
+ 1, 1, op
);
4662 oappend (scratchbuf
);
4666 OP_J (bytemode
, sizeflag
)
4676 FETCH_DATA (the_info
, codep
+ 1);
4678 if ((disp
& 0x80) != 0)
4682 if (sizeflag
& DFLAG
)
4687 /* for some reason, a data16 prefix on a jump instruction
4688 means that the pc is masked to 16 bits after the
4689 displacement is added! */
4692 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4695 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4698 disp
= (start_pc
+ codep
- start_codep
+ disp
) & mask
;
4700 print_operand_value (scratchbuf
, 1, disp
);
4701 oappend (scratchbuf
);
4706 OP_SEG (dummy
, sizeflag
)
4707 int dummy ATTRIBUTE_UNUSED
;
4708 int sizeflag ATTRIBUTE_UNUSED
;
4710 static char *sreg
[] = {
4711 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
4714 oappend (sreg
[reg
]);
4719 OP_DIR (dummy
, sizeflag
)
4720 int dummy ATTRIBUTE_UNUSED
;
4725 if (sizeflag
& DFLAG
)
4735 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4736 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
4737 oappend (scratchbuf
);
4742 OP_OFF (ignored
, sizeflag
)
4743 int ignored ATTRIBUTE_UNUSED
;
4750 if (sizeflag
& AFLAG
)
4757 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4758 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4760 oappend (names_seg
[3]);
4764 print_operand_value (scratchbuf
, 1, off
);
4765 oappend (scratchbuf
);
4769 OP_OFF64 (ignored
, sizeflag
)
4770 int ignored ATTRIBUTE_UNUSED
;
4771 int sizeflag ATTRIBUTE_UNUSED
;
4781 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4782 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4784 oappend (names_seg
[3]);
4788 print_operand_value (scratchbuf
, 1, off
);
4789 oappend (scratchbuf
);
4793 ptr_reg (code
, sizeflag
)
4799 USED_REX (REX_MODE64
);
4800 if (rex
& REX_MODE64
)
4801 s
= names64
[code
- eAX_reg
];
4802 else if (sizeflag
& AFLAG
)
4803 s
= names32
[code
- eAX_reg
];
4805 s
= names16
[code
- eAX_reg
];
4811 OP_ESreg (code
, sizeflag
)
4816 ptr_reg (code
, sizeflag
);
4820 OP_DSreg (code
, sizeflag
)
4831 prefixes
|= PREFIX_DS
;
4833 ptr_reg (code
, sizeflag
);
4838 OP_C (dummy
, sizeflag
)
4839 int dummy ATTRIBUTE_UNUSED
;
4840 int sizeflag ATTRIBUTE_UNUSED
;
4843 USED_REX (REX_EXTX
);
4846 sprintf (scratchbuf
, "%%cr%d", reg
+add
);
4847 oappend (scratchbuf
);
4852 OP_D (dummy
, sizeflag
)
4853 int dummy ATTRIBUTE_UNUSED
;
4854 int sizeflag ATTRIBUTE_UNUSED
;
4857 USED_REX (REX_EXTX
);
4860 sprintf (scratchbuf
, "%%db%d", reg
+add
);
4861 oappend (scratchbuf
);
4866 OP_T (dummy
, sizeflag
)
4867 int dummy ATTRIBUTE_UNUSED
;
4868 int sizeflag ATTRIBUTE_UNUSED
;
4870 sprintf (scratchbuf
, "%%tr%d", reg
);
4871 oappend (scratchbuf
);
4875 OP_Rd (bytemode
, sizeflag
)
4880 OP_E (bytemode
, sizeflag
);
4886 OP_MMX (ignore
, sizeflag
)
4887 int ignore ATTRIBUTE_UNUSED
;
4888 int sizeflag ATTRIBUTE_UNUSED
;
4891 USED_REX (REX_EXTX
);
4894 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4895 if (prefixes
& PREFIX_DATA
)
4896 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
4898 sprintf (scratchbuf
, "%%mm%d", reg
+ add
);
4899 oappend (scratchbuf
);
4903 OP_XMM (bytemode
, sizeflag
)
4904 int bytemode ATTRIBUTE_UNUSED
;
4905 int sizeflag ATTRIBUTE_UNUSED
;
4908 USED_REX (REX_EXTX
);
4911 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
4912 oappend (scratchbuf
);
4916 OP_EM (bytemode
, sizeflag
)
4923 OP_E (bytemode
, sizeflag
);
4926 USED_REX (REX_EXTZ
);
4931 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4932 if (prefixes
& PREFIX_DATA
)
4933 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
4935 sprintf (scratchbuf
, "%%mm%d", rm
+ add
);
4936 oappend (scratchbuf
);
4940 OP_EX (bytemode
, sizeflag
)
4947 OP_E (bytemode
, sizeflag
);
4950 USED_REX (REX_EXTZ
);
4955 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
4956 oappend (scratchbuf
);
4960 OP_MS (bytemode
, sizeflag
)
4965 OP_EM (bytemode
, sizeflag
);
4970 static const char *Suffix3DNow
[] = {
4971 /* 00 */ NULL
, NULL
, NULL
, NULL
,
4972 /* 04 */ NULL
, NULL
, NULL
, NULL
,
4973 /* 08 */ NULL
, NULL
, NULL
, NULL
,
4974 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
4975 /* 10 */ NULL
, NULL
, NULL
, NULL
,
4976 /* 14 */ NULL
, NULL
, NULL
, NULL
,
4977 /* 18 */ NULL
, NULL
, NULL
, NULL
,
4978 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
4979 /* 20 */ NULL
, NULL
, NULL
, NULL
,
4980 /* 24 */ NULL
, NULL
, NULL
, NULL
,
4981 /* 28 */ NULL
, NULL
, NULL
, NULL
,
4982 /* 2C */ NULL
, NULL
, NULL
, NULL
,
4983 /* 30 */ NULL
, NULL
, NULL
, NULL
,
4984 /* 34 */ NULL
, NULL
, NULL
, NULL
,
4985 /* 38 */ NULL
, NULL
, NULL
, NULL
,
4986 /* 3C */ NULL
, NULL
, NULL
, NULL
,
4987 /* 40 */ NULL
, NULL
, NULL
, NULL
,
4988 /* 44 */ NULL
, NULL
, NULL
, NULL
,
4989 /* 48 */ NULL
, NULL
, NULL
, NULL
,
4990 /* 4C */ NULL
, NULL
, NULL
, NULL
,
4991 /* 50 */ NULL
, NULL
, NULL
, NULL
,
4992 /* 54 */ NULL
, NULL
, NULL
, NULL
,
4993 /* 58 */ NULL
, NULL
, NULL
, NULL
,
4994 /* 5C */ NULL
, NULL
, NULL
, NULL
,
4995 /* 60 */ NULL
, NULL
, NULL
, NULL
,
4996 /* 64 */ NULL
, NULL
, NULL
, NULL
,
4997 /* 68 */ NULL
, NULL
, NULL
, NULL
,
4998 /* 6C */ NULL
, NULL
, NULL
, NULL
,
4999 /* 70 */ NULL
, NULL
, NULL
, NULL
,
5000 /* 74 */ NULL
, NULL
, NULL
, NULL
,
5001 /* 78 */ NULL
, NULL
, NULL
, NULL
,
5002 /* 7C */ NULL
, NULL
, NULL
, NULL
,
5003 /* 80 */ NULL
, NULL
, NULL
, NULL
,
5004 /* 84 */ NULL
, NULL
, NULL
, NULL
,
5005 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
5006 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
5007 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
5008 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
5009 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
5010 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
5011 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
5012 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
5013 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
5014 /* AC */ NULL
, NULL
, "pfacc", NULL
,
5015 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
5016 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pfmulhrw",
5017 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
5018 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
5019 /* C0 */ NULL
, NULL
, NULL
, NULL
,
5020 /* C4 */ NULL
, NULL
, NULL
, NULL
,
5021 /* C8 */ NULL
, NULL
, NULL
, NULL
,
5022 /* CC */ NULL
, NULL
, NULL
, NULL
,
5023 /* D0 */ NULL
, NULL
, NULL
, NULL
,
5024 /* D4 */ NULL
, NULL
, NULL
, NULL
,
5025 /* D8 */ NULL
, NULL
, NULL
, NULL
,
5026 /* DC */ NULL
, NULL
, NULL
, NULL
,
5027 /* E0 */ NULL
, NULL
, NULL
, NULL
,
5028 /* E4 */ NULL
, NULL
, NULL
, NULL
,
5029 /* E8 */ NULL
, NULL
, NULL
, NULL
,
5030 /* EC */ NULL
, NULL
, NULL
, NULL
,
5031 /* F0 */ NULL
, NULL
, NULL
, NULL
,
5032 /* F4 */ NULL
, NULL
, NULL
, NULL
,
5033 /* F8 */ NULL
, NULL
, NULL
, NULL
,
5034 /* FC */ NULL
, NULL
, NULL
, NULL
,
5038 OP_3DNowSuffix (bytemode
, sizeflag
)
5039 int bytemode ATTRIBUTE_UNUSED
;
5040 int sizeflag ATTRIBUTE_UNUSED
;
5042 const char *mnemonic
;
5044 FETCH_DATA (the_info
, codep
+ 1);
5045 /* AMD 3DNow! instructions are specified by an opcode suffix in the
5046 place where an 8-bit immediate would normally go. ie. the last
5047 byte of the instruction. */
5048 obufp
= obuf
+ strlen(obuf
);
5049 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
5054 /* Since a variable sized modrm/sib chunk is between the start
5055 of the opcode (0x0f0f) and the opcode suffix, we need to do
5056 all the modrm processing first, and don't know until now that
5057 we have a bad opcode. This necessitates some cleaning up. */
5065 static const char *simd_cmp_op
[] = {
5077 OP_SIMD_Suffix (bytemode
, sizeflag
)
5078 int bytemode ATTRIBUTE_UNUSED
;
5079 int sizeflag ATTRIBUTE_UNUSED
;
5081 unsigned int cmp_type
;
5083 FETCH_DATA (the_info
, codep
+ 1);
5084 obufp
= obuf
+ strlen(obuf
);
5085 cmp_type
= *codep
++ & 0xff;
5088 char suffix1
= 'p', suffix2
= 's';
5089 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
5090 if (prefixes
& PREFIX_REPZ
)
5094 used_prefixes
|= (prefixes
& PREFIX_DATA
);
5095 if (prefixes
& PREFIX_DATA
)
5099 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
5100 if (prefixes
& PREFIX_REPNZ
)
5101 suffix1
= 's', suffix2
= 'd';
5104 sprintf (scratchbuf
, "cmp%s%c%c",
5105 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
5106 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
5107 oappend (scratchbuf
);
5111 /* We have a bad extension byte. Clean up. */
5119 SIMD_Fixup (extrachar
, sizeflag
)
5121 int sizeflag ATTRIBUTE_UNUSED
;
5123 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
5124 forms of these instructions. */
5127 char *p
= obuf
+ strlen(obuf
);
5136 static void BadOp (void)
5138 codep
= insn_codep
+ 1; /* throw away prefixes and 1st. opcode byte */