1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
21 /* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
23 modified by John Hassey (hassey@dg-rtp.dg.com)
24 x86-64 support added by Jan Hubicka (jh@suse.cz)
25 VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
27 /* The main tables describing the instructions is essentially a copy
28 of the "Opcode Map" chapter (Appendix A) of the Intel 80386
29 Programmers Manual. Usually, there is a capital letter, followed
30 by a small letter. The capital letter tell the addressing mode,
31 and the small letter tells about the operand size. Refer to
32 the Intel manual for details. */
42 #ifndef UNIXWARE_COMPAT
43 /* Set non-zero for broken, compatible instructions. Set to zero for
44 non-broken opcodes. */
45 #define UNIXWARE_COMPAT 1
48 static int fetch_data (struct disassemble_info
*, bfd_byte
*);
49 static void ckprefix (void);
50 static const char *prefix_name (int, int);
51 static int print_insn (bfd_vma
, disassemble_info
*);
52 static void dofloat (int);
53 static void OP_ST (int, int);
54 static void OP_STi (int, int);
55 static int putop (const char *, int);
56 static void oappend (const char *);
57 static void append_seg (void);
58 static void OP_indirE (int, int);
59 static void print_operand_value (char *, int, bfd_vma
);
60 static void OP_E (int, int);
61 static void OP_G (int, int);
62 static bfd_vma
get64 (void);
63 static bfd_signed_vma
get32 (void);
64 static bfd_signed_vma
get32s (void);
65 static int get16 (void);
66 static void set_op (bfd_vma
, int);
67 static void OP_REG (int, int);
68 static void OP_IMREG (int, int);
69 static void OP_I (int, int);
70 static void OP_I64 (int, int);
71 static void OP_sI (int, int);
72 static void OP_J (int, int);
73 static void OP_SEG (int, int);
74 static void OP_DIR (int, int);
75 static void OP_OFF (int, int);
76 static void OP_OFF64 (int, int);
77 static void ptr_reg (int, int);
78 static void OP_ESreg (int, int);
79 static void OP_DSreg (int, int);
80 static void OP_C (int, int);
81 static void OP_D (int, int);
82 static void OP_T (int, int);
83 static void OP_Rd (int, int);
84 static void OP_MMX (int, int);
85 static void OP_XMM (int, int);
86 static void OP_EM (int, int);
87 static void OP_EX (int, int);
88 static void OP_MS (int, int);
89 static void OP_XS (int, int);
90 static void OP_M (int, int);
91 static void OP_VMX (int, int);
92 static void OP_0fae (int, int);
93 static void OP_0f07 (int, int);
94 static void NOP_Fixup (int, int);
95 static void OP_3DNowSuffix (int, int);
96 static void OP_SIMD_Suffix (int, int);
97 static void SIMD_Fixup (int, int);
98 static void PNI_Fixup (int, int);
99 static void SVME_Fixup (int, int);
100 static void INVLPG_Fixup (int, int);
101 static void BadOp (void);
102 static void SEG_Fixup (int, int);
103 static void VMX_Fixup (int, int);
104 static void REP_Fixup (int, int);
107 /* Points to first byte not fetched. */
108 bfd_byte
*max_fetched
;
109 bfd_byte the_buffer
[MAXLEN
];
115 /* The opcode for the fwait instruction, which we treat as a prefix
117 #define FWAIT_OPCODE (0x9b)
126 enum address_mode address_mode
;
128 /* Flags for the prefixes for the current instruction. See below. */
131 /* REX prefix the current instruction. See below. */
133 /* Bits of REX we've already used. */
139 /* Mark parts used in the REX prefix. When we are testing for
140 empty prefix (for 8bit register REX extension), just mask it
141 out. Otherwise test for REX bit is excuse for existence of REX
142 only in case value is nonzero. */
143 #define USED_REX(value) \
146 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
151 /* Flags for prefixes which we somehow handled when printing the
152 current instruction. */
153 static int used_prefixes
;
155 /* Flags stored in PREFIXES. */
156 #define PREFIX_REPZ 1
157 #define PREFIX_REPNZ 2
158 #define PREFIX_LOCK 4
160 #define PREFIX_SS 0x10
161 #define PREFIX_DS 0x20
162 #define PREFIX_ES 0x40
163 #define PREFIX_FS 0x80
164 #define PREFIX_GS 0x100
165 #define PREFIX_DATA 0x200
166 #define PREFIX_ADDR 0x400
167 #define PREFIX_FWAIT 0x800
169 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
170 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
172 #define FETCH_DATA(info, addr) \
173 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
174 ? 1 : fetch_data ((info), (addr)))
177 fetch_data (struct disassemble_info
*info
, bfd_byte
*addr
)
180 struct dis_private
*priv
= (struct dis_private
*) info
->private_data
;
181 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
183 if (addr
<= priv
->the_buffer
+ MAXLEN
)
184 status
= (*info
->read_memory_func
) (start
,
186 addr
- priv
->max_fetched
,
192 /* If we did manage to read at least one byte, then
193 print_insn_i386 will do something sensible. Otherwise, print
194 an error. We do that here because this is where we know
196 if (priv
->max_fetched
== priv
->the_buffer
)
197 (*info
->memory_error_func
) (status
, start
, info
);
198 longjmp (priv
->bailout
, 1);
201 priv
->max_fetched
= addr
;
207 #define Eb OP_E, b_mode
208 #define Ev OP_E, v_mode
209 #define Ed OP_E, d_mode
210 #define Eq OP_E, q_mode
211 #define Edq OP_E, dq_mode
212 #define Edqw OP_E, dqw_mode
213 #define indirEv OP_indirE, stack_v_mode
214 #define indirEp OP_indirE, f_mode
215 #define stackEv OP_E, stack_v_mode
216 #define Em OP_E, m_mode
217 #define Ew OP_E, w_mode
218 #define Ma OP_E, v_mode
219 #define M OP_M, 0 /* lea, lgdt, etc. */
220 #define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */
221 #define Gb OP_G, b_mode
222 #define Gv OP_G, v_mode
223 #define Gd OP_G, d_mode
224 #define Gdq OP_G, dq_mode
225 #define Gm OP_G, m_mode
226 #define Gw OP_G, w_mode
227 #define Rd OP_Rd, d_mode
228 #define Rm OP_Rd, m_mode
229 #define Ib OP_I, b_mode
230 #define sIb OP_sI, b_mode /* sign extened byte */
231 #define Iv OP_I, v_mode
232 #define Iq OP_I, q_mode
233 #define Iv64 OP_I64, v_mode
234 #define Iw OP_I, w_mode
235 #define I1 OP_I, const_1_mode
236 #define Jb OP_J, b_mode
237 #define Jv OP_J, v_mode
238 #define Cm OP_C, m_mode
239 #define Dm OP_D, m_mode
240 #define Td OP_T, d_mode
241 #define Sv SEG_Fixup, v_mode
243 #define RMeAX OP_REG, eAX_reg
244 #define RMeBX OP_REG, eBX_reg
245 #define RMeCX OP_REG, eCX_reg
246 #define RMeDX OP_REG, eDX_reg
247 #define RMeSP OP_REG, eSP_reg
248 #define RMeBP OP_REG, eBP_reg
249 #define RMeSI OP_REG, eSI_reg
250 #define RMeDI OP_REG, eDI_reg
251 #define RMrAX OP_REG, rAX_reg
252 #define RMrBX OP_REG, rBX_reg
253 #define RMrCX OP_REG, rCX_reg
254 #define RMrDX OP_REG, rDX_reg
255 #define RMrSP OP_REG, rSP_reg
256 #define RMrBP OP_REG, rBP_reg
257 #define RMrSI OP_REG, rSI_reg
258 #define RMrDI OP_REG, rDI_reg
259 #define RMAL OP_REG, al_reg
260 #define RMAL OP_REG, al_reg
261 #define RMCL OP_REG, cl_reg
262 #define RMDL OP_REG, dl_reg
263 #define RMBL OP_REG, bl_reg
264 #define RMAH OP_REG, ah_reg
265 #define RMCH OP_REG, ch_reg
266 #define RMDH OP_REG, dh_reg
267 #define RMBH OP_REG, bh_reg
268 #define RMAX OP_REG, ax_reg
269 #define RMDX OP_REG, dx_reg
271 #define eAX OP_IMREG, eAX_reg
272 #define eBX OP_IMREG, eBX_reg
273 #define eCX OP_IMREG, eCX_reg
274 #define eDX OP_IMREG, eDX_reg
275 #define eSP OP_IMREG, eSP_reg
276 #define eBP OP_IMREG, eBP_reg
277 #define eSI OP_IMREG, eSI_reg
278 #define eDI OP_IMREG, eDI_reg
279 #define AL OP_IMREG, al_reg
280 #define CL OP_IMREG, cl_reg
281 #define DL OP_IMREG, dl_reg
282 #define BL OP_IMREG, bl_reg
283 #define AH OP_IMREG, ah_reg
284 #define CH OP_IMREG, ch_reg
285 #define DH OP_IMREG, dh_reg
286 #define BH OP_IMREG, bh_reg
287 #define AX OP_IMREG, ax_reg
288 #define DX OP_IMREG, dx_reg
289 #define indirDX OP_IMREG, indir_dx_reg
291 #define Sw OP_SEG, w_mode
293 #define Ob OP_OFF64, b_mode
294 #define Ov OP_OFF64, v_mode
295 #define Xb OP_DSreg, eSI_reg
296 #define Xv OP_DSreg, eSI_reg
297 #define Yb OP_ESreg, eDI_reg
298 #define Yv OP_ESreg, eDI_reg
299 #define DSBX OP_DSreg, eBX_reg
301 #define es OP_REG, es_reg
302 #define ss OP_REG, ss_reg
303 #define cs OP_REG, cs_reg
304 #define ds OP_REG, ds_reg
305 #define fs OP_REG, fs_reg
306 #define gs OP_REG, gs_reg
310 #define EM OP_EM, v_mode
311 #define EX OP_EX, v_mode
312 #define MS OP_MS, v_mode
313 #define XS OP_XS, v_mode
314 #define VM OP_VMX, q_mode
315 #define OPSUF OP_3DNowSuffix, 0
316 #define OPSIMD OP_SIMD_Suffix, 0
318 /* Used handle "rep" prefix for string instructions. */
319 #define Xbr REP_Fixup, eSI_reg
320 #define Xvr REP_Fixup, eSI_reg
321 #define Ybr REP_Fixup, eDI_reg
322 #define Yvr REP_Fixup, eDI_reg
323 #define indirDXr REP_Fixup, indir_dx_reg
324 #define ALr REP_Fixup, al_reg
325 #define eAXr REP_Fixup, eAX_reg
327 #define cond_jump_flag NULL, cond_jump_mode
328 #define loop_jcxz_flag NULL, loop_jcxz_mode
330 /* bits in sizeflag */
331 #define SUFFIX_ALWAYS 4
335 #define b_mode 1 /* byte operand */
336 #define v_mode 2 /* operand size depends on prefixes */
337 #define w_mode 3 /* word operand */
338 #define d_mode 4 /* double word operand */
339 #define q_mode 5 /* quad word operand */
340 #define t_mode 6 /* ten-byte operand */
341 #define x_mode 7 /* 16-byte XMM operand */
342 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
343 #define cond_jump_mode 9
344 #define loop_jcxz_mode 10
345 #define dq_mode 11 /* operand size depends on REX prefixes. */
346 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
347 #define f_mode 13 /* 4- or 6-byte pointer operand */
348 #define const_1_mode 14
349 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
394 #define indir_dx_reg 150
398 #define USE_PREFIX_USER_TABLE 3
399 #define X86_64_SPECIAL 4
400 #define IS_3BYTE_OPCODE 5
402 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
404 #define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
405 #define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
406 #define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
407 #define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
408 #define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
409 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
410 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
411 #define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
412 #define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
413 #define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
414 #define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
415 #define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
416 #define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
417 #define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
418 #define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
419 #define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
420 #define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
421 #define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
422 #define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
423 #define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
424 #define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
425 #define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
426 #define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
427 #define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0
428 #define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0
430 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
431 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
432 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
433 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
434 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
435 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
436 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
437 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
438 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
439 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
440 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
441 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
442 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
443 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
444 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
445 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
446 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
447 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
448 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
449 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
450 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
451 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
452 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
453 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
454 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
455 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
456 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
457 #define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0
458 #define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0
459 #define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0
460 #define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0
461 #define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0
462 #define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0
464 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
466 #define THREE_BYTE_0 NULL, NULL, IS_3BYTE_OPCODE, NULL, 0, NULL, 0
467 #define THREE_BYTE_1 NULL, NULL, IS_3BYTE_OPCODE, NULL, 1, NULL, 0
469 typedef void (*op_rtn
) (int bytemode
, int sizeflag
);
481 /* Upper case letters in the instruction names here are macros.
482 'A' => print 'b' if no register operands or suffix_always is true
483 'B' => print 'b' if suffix_always is true
484 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
486 'E' => print 'e' if 32-bit form of jcxz
487 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
488 'H' => print ",pt" or ",pn" branch hint
489 'I' => honor following macro letter even in Intel mode (implemented only
490 . for some of the macro letters)
492 'L' => print 'l' if suffix_always is true
493 'N' => print 'n' if instruction has no wait "prefix"
494 'O' => print 'd', or 'o'
495 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
496 . or suffix_always is true. print 'q' if rex prefix is present.
497 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
499 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
500 'S' => print 'w', 'l' or 'q' if suffix_always is true
501 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
502 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
503 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
504 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
505 'X' => print 's', 'd' depending on data16 prefix (for XMM)
506 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
507 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
509 Many of the above letters print nothing in Intel mode. See "putop"
512 Braces '{' and '}', and vertical bars '|', indicate alternative
513 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
514 modes. In cases where there are only two alternatives, the X86_64
515 instruction is reserved, and "(bad)" is printed.
518 static const struct dis386 dis386
[] = {
520 { "addB", Eb
, Gb
, XX
},
521 { "addS", Ev
, Gv
, XX
},
522 { "addB", Gb
, Eb
, XX
},
523 { "addS", Gv
, Ev
, XX
},
524 { "addB", AL
, Ib
, XX
},
525 { "addS", eAX
, Iv
, XX
},
526 { "push{T|}", es
, XX
, XX
},
527 { "pop{T|}", es
, XX
, XX
},
529 { "orB", Eb
, Gb
, XX
},
530 { "orS", Ev
, Gv
, XX
},
531 { "orB", Gb
, Eb
, XX
},
532 { "orS", Gv
, Ev
, XX
},
533 { "orB", AL
, Ib
, XX
},
534 { "orS", eAX
, Iv
, XX
},
535 { "push{T|}", cs
, XX
, XX
},
536 { "(bad)", XX
, XX
, XX
}, /* 0x0f extended opcode escape */
538 { "adcB", Eb
, Gb
, XX
},
539 { "adcS", Ev
, Gv
, XX
},
540 { "adcB", Gb
, Eb
, XX
},
541 { "adcS", Gv
, Ev
, XX
},
542 { "adcB", AL
, Ib
, XX
},
543 { "adcS", eAX
, Iv
, XX
},
544 { "push{T|}", ss
, XX
, XX
},
545 { "pop{T|}", ss
, XX
, XX
},
547 { "sbbB", Eb
, Gb
, XX
},
548 { "sbbS", Ev
, Gv
, XX
},
549 { "sbbB", Gb
, Eb
, XX
},
550 { "sbbS", Gv
, Ev
, XX
},
551 { "sbbB", AL
, Ib
, XX
},
552 { "sbbS", eAX
, Iv
, XX
},
553 { "push{T|}", ds
, XX
, XX
},
554 { "pop{T|}", ds
, XX
, XX
},
556 { "andB", Eb
, Gb
, XX
},
557 { "andS", Ev
, Gv
, XX
},
558 { "andB", Gb
, Eb
, XX
},
559 { "andS", Gv
, Ev
, XX
},
560 { "andB", AL
, Ib
, XX
},
561 { "andS", eAX
, Iv
, XX
},
562 { "(bad)", XX
, XX
, XX
}, /* SEG ES prefix */
563 { "daa{|}", XX
, XX
, XX
},
565 { "subB", Eb
, Gb
, XX
},
566 { "subS", Ev
, Gv
, XX
},
567 { "subB", Gb
, Eb
, XX
},
568 { "subS", Gv
, Ev
, XX
},
569 { "subB", AL
, Ib
, XX
},
570 { "subS", eAX
, Iv
, XX
},
571 { "(bad)", XX
, XX
, XX
}, /* SEG CS prefix */
572 { "das{|}", XX
, XX
, XX
},
574 { "xorB", Eb
, Gb
, XX
},
575 { "xorS", Ev
, Gv
, XX
},
576 { "xorB", Gb
, Eb
, XX
},
577 { "xorS", Gv
, Ev
, XX
},
578 { "xorB", AL
, Ib
, XX
},
579 { "xorS", eAX
, Iv
, XX
},
580 { "(bad)", XX
, XX
, XX
}, /* SEG SS prefix */
581 { "aaa{|}", XX
, XX
, XX
},
583 { "cmpB", Eb
, Gb
, XX
},
584 { "cmpS", Ev
, Gv
, XX
},
585 { "cmpB", Gb
, Eb
, XX
},
586 { "cmpS", Gv
, Ev
, XX
},
587 { "cmpB", AL
, Ib
, XX
},
588 { "cmpS", eAX
, Iv
, XX
},
589 { "(bad)", XX
, XX
, XX
}, /* SEG DS prefix */
590 { "aas{|}", XX
, XX
, XX
},
592 { "inc{S|}", RMeAX
, XX
, XX
},
593 { "inc{S|}", RMeCX
, XX
, XX
},
594 { "inc{S|}", RMeDX
, XX
, XX
},
595 { "inc{S|}", RMeBX
, XX
, XX
},
596 { "inc{S|}", RMeSP
, XX
, XX
},
597 { "inc{S|}", RMeBP
, XX
, XX
},
598 { "inc{S|}", RMeSI
, XX
, XX
},
599 { "inc{S|}", RMeDI
, XX
, XX
},
601 { "dec{S|}", RMeAX
, XX
, XX
},
602 { "dec{S|}", RMeCX
, XX
, XX
},
603 { "dec{S|}", RMeDX
, XX
, XX
},
604 { "dec{S|}", RMeBX
, XX
, XX
},
605 { "dec{S|}", RMeSP
, XX
, XX
},
606 { "dec{S|}", RMeBP
, XX
, XX
},
607 { "dec{S|}", RMeSI
, XX
, XX
},
608 { "dec{S|}", RMeDI
, XX
, XX
},
610 { "pushV", RMrAX
, XX
, XX
},
611 { "pushV", RMrCX
, XX
, XX
},
612 { "pushV", RMrDX
, XX
, XX
},
613 { "pushV", RMrBX
, XX
, XX
},
614 { "pushV", RMrSP
, XX
, XX
},
615 { "pushV", RMrBP
, XX
, XX
},
616 { "pushV", RMrSI
, XX
, XX
},
617 { "pushV", RMrDI
, XX
, XX
},
619 { "popV", RMrAX
, XX
, XX
},
620 { "popV", RMrCX
, XX
, XX
},
621 { "popV", RMrDX
, XX
, XX
},
622 { "popV", RMrBX
, XX
, XX
},
623 { "popV", RMrSP
, XX
, XX
},
624 { "popV", RMrBP
, XX
, XX
},
625 { "popV", RMrSI
, XX
, XX
},
626 { "popV", RMrDI
, XX
, XX
},
628 { "pusha{P|}", XX
, XX
, XX
},
629 { "popa{P|}", XX
, XX
, XX
},
630 { "bound{S|}", Gv
, Ma
, XX
},
632 { "(bad)", XX
, XX
, XX
}, /* seg fs */
633 { "(bad)", XX
, XX
, XX
}, /* seg gs */
634 { "(bad)", XX
, XX
, XX
}, /* op size prefix */
635 { "(bad)", XX
, XX
, XX
}, /* adr size prefix */
637 { "pushT", Iq
, XX
, XX
},
638 { "imulS", Gv
, Ev
, Iv
},
639 { "pushT", sIb
, XX
, XX
},
640 { "imulS", Gv
, Ev
, sIb
},
641 { "ins{b||b|}", Ybr
, indirDX
, XX
},
642 { "ins{R||R|}", Yvr
, indirDX
, XX
},
643 { "outs{b||b|}", indirDXr
, Xb
, XX
},
644 { "outs{R||R|}", indirDXr
, Xv
, XX
},
646 { "joH", Jb
, XX
, cond_jump_flag
},
647 { "jnoH", Jb
, XX
, cond_jump_flag
},
648 { "jbH", Jb
, XX
, cond_jump_flag
},
649 { "jaeH", Jb
, XX
, cond_jump_flag
},
650 { "jeH", Jb
, XX
, cond_jump_flag
},
651 { "jneH", Jb
, XX
, cond_jump_flag
},
652 { "jbeH", Jb
, XX
, cond_jump_flag
},
653 { "jaH", Jb
, XX
, cond_jump_flag
},
655 { "jsH", Jb
, XX
, cond_jump_flag
},
656 { "jnsH", Jb
, XX
, cond_jump_flag
},
657 { "jpH", Jb
, XX
, cond_jump_flag
},
658 { "jnpH", Jb
, XX
, cond_jump_flag
},
659 { "jlH", Jb
, XX
, cond_jump_flag
},
660 { "jgeH", Jb
, XX
, cond_jump_flag
},
661 { "jleH", Jb
, XX
, cond_jump_flag
},
662 { "jgH", Jb
, XX
, cond_jump_flag
},
666 { "(bad)", XX
, XX
, XX
},
668 { "testB", Eb
, Gb
, XX
},
669 { "testS", Ev
, Gv
, XX
},
670 { "xchgB", Eb
, Gb
, XX
},
671 { "xchgS", Ev
, Gv
, XX
},
673 { "movB", Eb
, Gb
, XX
},
674 { "movS", Ev
, Gv
, XX
},
675 { "movB", Gb
, Eb
, XX
},
676 { "movS", Gv
, Ev
, XX
},
677 { "movQ", Sv
, Sw
, XX
},
678 { "leaS", Gv
, M
, XX
},
679 { "movQ", Sw
, Sv
, XX
},
680 { "popU", stackEv
, XX
, XX
},
682 { "nop", NOP_Fixup
, 0, XX
, XX
},
683 { "xchgS", RMeCX
, eAX
, XX
},
684 { "xchgS", RMeDX
, eAX
, XX
},
685 { "xchgS", RMeBX
, eAX
, XX
},
686 { "xchgS", RMeSP
, eAX
, XX
},
687 { "xchgS", RMeBP
, eAX
, XX
},
688 { "xchgS", RMeSI
, eAX
, XX
},
689 { "xchgS", RMeDI
, eAX
, XX
},
691 { "cW{tR||tR|}", XX
, XX
, XX
},
692 { "cR{tO||tO|}", XX
, XX
, XX
},
693 { "Jcall{T|}", Ap
, XX
, XX
},
694 { "(bad)", XX
, XX
, XX
}, /* fwait */
695 { "pushfT", XX
, XX
, XX
},
696 { "popfT", XX
, XX
, XX
},
697 { "sahf{|}", XX
, XX
, XX
},
698 { "lahf{|}", XX
, XX
, XX
},
700 { "movB", AL
, Ob
, XX
},
701 { "movS", eAX
, Ov
, XX
},
702 { "movB", Ob
, AL
, XX
},
703 { "movS", Ov
, eAX
, XX
},
704 { "movs{b||b|}", Ybr
, Xb
, XX
},
705 { "movs{R||R|}", Yvr
, Xv
, XX
},
706 { "cmps{b||b|}", Xb
, Yb
, XX
},
707 { "cmps{R||R|}", Xv
, Yv
, XX
},
709 { "testB", AL
, Ib
, XX
},
710 { "testS", eAX
, Iv
, XX
},
711 { "stosB", Ybr
, AL
, XX
},
712 { "stosS", Yvr
, eAX
, XX
},
713 { "lodsB", ALr
, Xb
, XX
},
714 { "lodsS", eAXr
, Xv
, XX
},
715 { "scasB", AL
, Yb
, XX
},
716 { "scasS", eAX
, Yv
, XX
},
718 { "movB", RMAL
, Ib
, XX
},
719 { "movB", RMCL
, Ib
, XX
},
720 { "movB", RMDL
, Ib
, XX
},
721 { "movB", RMBL
, Ib
, XX
},
722 { "movB", RMAH
, Ib
, XX
},
723 { "movB", RMCH
, Ib
, XX
},
724 { "movB", RMDH
, Ib
, XX
},
725 { "movB", RMBH
, Ib
, XX
},
727 { "movS", RMeAX
, Iv64
, XX
},
728 { "movS", RMeCX
, Iv64
, XX
},
729 { "movS", RMeDX
, Iv64
, XX
},
730 { "movS", RMeBX
, Iv64
, XX
},
731 { "movS", RMeSP
, Iv64
, XX
},
732 { "movS", RMeBP
, Iv64
, XX
},
733 { "movS", RMeSI
, Iv64
, XX
},
734 { "movS", RMeDI
, Iv64
, XX
},
738 { "retT", Iw
, XX
, XX
},
739 { "retT", XX
, XX
, XX
},
740 { "les{S|}", Gv
, Mp
, XX
},
741 { "ldsS", Gv
, Mp
, XX
},
742 { "movA", Eb
, Ib
, XX
},
743 { "movQ", Ev
, Iv
, XX
},
745 { "enterT", Iw
, Ib
, XX
},
746 { "leaveT", XX
, XX
, XX
},
747 { "lretP", Iw
, XX
, XX
},
748 { "lretP", XX
, XX
, XX
},
749 { "int3", XX
, XX
, XX
},
750 { "int", Ib
, XX
, XX
},
751 { "into{|}", XX
, XX
, XX
},
752 { "iretP", XX
, XX
, XX
},
758 { "aam{|}", sIb
, XX
, XX
},
759 { "aad{|}", sIb
, XX
, XX
},
760 { "(bad)", XX
, XX
, XX
},
761 { "xlat", DSBX
, XX
, XX
},
772 { "loopneFH", Jb
, XX
, loop_jcxz_flag
},
773 { "loopeFH", Jb
, XX
, loop_jcxz_flag
},
774 { "loopFH", Jb
, XX
, loop_jcxz_flag
},
775 { "jEcxzH", Jb
, XX
, loop_jcxz_flag
},
776 { "inB", AL
, Ib
, XX
},
777 { "inS", eAX
, Ib
, XX
},
778 { "outB", Ib
, AL
, XX
},
779 { "outS", Ib
, eAX
, XX
},
781 { "callT", Jv
, XX
, XX
},
782 { "jmpT", Jv
, XX
, XX
},
783 { "Jjmp{T|}", Ap
, XX
, XX
},
784 { "jmp", Jb
, XX
, XX
},
785 { "inB", AL
, indirDX
, XX
},
786 { "inS", eAX
, indirDX
, XX
},
787 { "outB", indirDX
, AL
, XX
},
788 { "outS", indirDX
, eAX
, XX
},
790 { "(bad)", XX
, XX
, XX
}, /* lock prefix */
791 { "icebp", XX
, XX
, XX
},
792 { "(bad)", XX
, XX
, XX
}, /* repne */
793 { "(bad)", XX
, XX
, XX
}, /* repz */
794 { "hlt", XX
, XX
, XX
},
795 { "cmc", XX
, XX
, XX
},
799 { "clc", XX
, XX
, XX
},
800 { "stc", XX
, XX
, XX
},
801 { "cli", XX
, XX
, XX
},
802 { "sti", XX
, XX
, XX
},
803 { "cld", XX
, XX
, XX
},
804 { "std", XX
, XX
, XX
},
809 static const struct dis386 dis386_twobyte
[] = {
813 { "larS", Gv
, Ew
, XX
},
814 { "lslS", Gv
, Ew
, XX
},
815 { "(bad)", XX
, XX
, XX
},
816 { "syscall", XX
, XX
, XX
},
817 { "clts", XX
, XX
, XX
},
818 { "sysretP", XX
, XX
, XX
},
820 { "invd", XX
, XX
, XX
},
821 { "wbinvd", XX
, XX
, XX
},
822 { "(bad)", XX
, XX
, XX
},
823 { "ud2a", XX
, XX
, XX
},
824 { "(bad)", XX
, XX
, XX
},
826 { "femms", XX
, XX
, XX
},
827 { "", MX
, EM
, OPSUF
}, /* See OP_3DNowSuffix. */
832 { "movlpX", EX
, XM
, SIMD_Fixup
, 'h' },
833 { "unpcklpX", XM
, EX
, XX
},
834 { "unpckhpX", XM
, EX
, XX
},
836 { "movhpX", EX
, XM
, SIMD_Fixup
, 'l' },
839 { "(bad)", XX
, XX
, XX
},
840 { "(bad)", XX
, XX
, XX
},
841 { "(bad)", XX
, XX
, XX
},
842 { "(bad)", XX
, XX
, XX
},
843 { "(bad)", XX
, XX
, XX
},
844 { "(bad)", XX
, XX
, XX
},
845 { "(bad)", XX
, XX
, XX
},
847 { "movZ", Rm
, Cm
, XX
},
848 { "movZ", Rm
, Dm
, XX
},
849 { "movZ", Cm
, Rm
, XX
},
850 { "movZ", Dm
, Rm
, XX
},
851 { "movL", Rd
, Td
, XX
},
852 { "(bad)", XX
, XX
, XX
},
853 { "movL", Td
, Rd
, XX
},
854 { "(bad)", XX
, XX
, XX
},
856 { "movapX", XM
, EX
, XX
},
857 { "movapX", EX
, XM
, XX
},
859 { "movntpX", Ev
, XM
, XX
},
862 { "ucomisX", XM
,EX
, XX
},
863 { "comisX", XM
,EX
, XX
},
865 { "wrmsr", XX
, XX
, XX
},
866 { "rdtsc", XX
, XX
, XX
},
867 { "rdmsr", XX
, XX
, XX
},
868 { "rdpmc", XX
, XX
, XX
},
869 { "sysenter", XX
, XX
, XX
},
870 { "sysexit", XX
, XX
, XX
},
871 { "(bad)", XX
, XX
, XX
},
872 { "(bad)", XX
, XX
, XX
},
875 { "(bad)", XX
, XX
, XX
},
877 { "(bad)", XX
, XX
, XX
},
878 { "(bad)", XX
, XX
, XX
},
879 { "(bad)", XX
, XX
, XX
},
880 { "(bad)", XX
, XX
, XX
},
881 { "(bad)", XX
, XX
, XX
},
883 { "cmovo", Gv
, Ev
, XX
},
884 { "cmovno", Gv
, Ev
, XX
},
885 { "cmovb", Gv
, Ev
, XX
},
886 { "cmovae", Gv
, Ev
, XX
},
887 { "cmove", Gv
, Ev
, XX
},
888 { "cmovne", Gv
, Ev
, XX
},
889 { "cmovbe", Gv
, Ev
, XX
},
890 { "cmova", Gv
, Ev
, XX
},
892 { "cmovs", Gv
, Ev
, XX
},
893 { "cmovns", Gv
, Ev
, XX
},
894 { "cmovp", Gv
, Ev
, XX
},
895 { "cmovnp", Gv
, Ev
, XX
},
896 { "cmovl", Gv
, Ev
, XX
},
897 { "cmovge", Gv
, Ev
, XX
},
898 { "cmovle", Gv
, Ev
, XX
},
899 { "cmovg", Gv
, Ev
, XX
},
901 { "movmskpX", Gdq
, XS
, XX
},
905 { "andpX", XM
, EX
, XX
},
906 { "andnpX", XM
, EX
, XX
},
907 { "orpX", XM
, EX
, XX
},
908 { "xorpX", XM
, EX
, XX
},
919 { "punpcklbw", MX
, EM
, XX
},
920 { "punpcklwd", MX
, EM
, XX
},
921 { "punpckldq", MX
, EM
, XX
},
922 { "packsswb", MX
, EM
, XX
},
923 { "pcmpgtb", MX
, EM
, XX
},
924 { "pcmpgtw", MX
, EM
, XX
},
925 { "pcmpgtd", MX
, EM
, XX
},
926 { "packuswb", MX
, EM
, XX
},
928 { "punpckhbw", MX
, EM
, XX
},
929 { "punpckhwd", MX
, EM
, XX
},
930 { "punpckhdq", MX
, EM
, XX
},
931 { "packssdw", MX
, EM
, XX
},
934 { "movd", MX
, Edq
, XX
},
941 { "pcmpeqb", MX
, EM
, XX
},
942 { "pcmpeqw", MX
, EM
, XX
},
943 { "pcmpeqd", MX
, EM
, XX
},
944 { "emms", XX
, XX
, XX
},
946 { "vmread", Em
, Gm
, XX
},
947 { "vmwrite", Gm
, Em
, XX
},
948 { "(bad)", XX
, XX
, XX
},
949 { "(bad)", XX
, XX
, XX
},
955 { "joH", Jv
, XX
, cond_jump_flag
},
956 { "jnoH", Jv
, XX
, cond_jump_flag
},
957 { "jbH", Jv
, XX
, cond_jump_flag
},
958 { "jaeH", Jv
, XX
, cond_jump_flag
},
959 { "jeH", Jv
, XX
, cond_jump_flag
},
960 { "jneH", Jv
, XX
, cond_jump_flag
},
961 { "jbeH", Jv
, XX
, cond_jump_flag
},
962 { "jaH", Jv
, XX
, cond_jump_flag
},
964 { "jsH", Jv
, XX
, cond_jump_flag
},
965 { "jnsH", Jv
, XX
, cond_jump_flag
},
966 { "jpH", Jv
, XX
, cond_jump_flag
},
967 { "jnpH", Jv
, XX
, cond_jump_flag
},
968 { "jlH", Jv
, XX
, cond_jump_flag
},
969 { "jgeH", Jv
, XX
, cond_jump_flag
},
970 { "jleH", Jv
, XX
, cond_jump_flag
},
971 { "jgH", Jv
, XX
, cond_jump_flag
},
973 { "seto", Eb
, XX
, XX
},
974 { "setno", Eb
, XX
, XX
},
975 { "setb", Eb
, XX
, XX
},
976 { "setae", Eb
, XX
, XX
},
977 { "sete", Eb
, XX
, XX
},
978 { "setne", Eb
, XX
, XX
},
979 { "setbe", Eb
, XX
, XX
},
980 { "seta", Eb
, XX
, XX
},
982 { "sets", Eb
, XX
, XX
},
983 { "setns", Eb
, XX
, XX
},
984 { "setp", Eb
, XX
, XX
},
985 { "setnp", Eb
, XX
, XX
},
986 { "setl", Eb
, XX
, XX
},
987 { "setge", Eb
, XX
, XX
},
988 { "setle", Eb
, XX
, XX
},
989 { "setg", Eb
, XX
, XX
},
991 { "pushT", fs
, XX
, XX
},
992 { "popT", fs
, XX
, XX
},
993 { "cpuid", XX
, XX
, XX
},
994 { "btS", Ev
, Gv
, XX
},
995 { "shldS", Ev
, Gv
, Ib
},
996 { "shldS", Ev
, Gv
, CL
},
1000 { "pushT", gs
, XX
, XX
},
1001 { "popT", gs
, XX
, XX
},
1002 { "rsm", XX
, XX
, XX
},
1003 { "btsS", Ev
, Gv
, XX
},
1004 { "shrdS", Ev
, Gv
, Ib
},
1005 { "shrdS", Ev
, Gv
, CL
},
1007 { "imulS", Gv
, Ev
, XX
},
1009 { "cmpxchgB", Eb
, Gb
, XX
},
1010 { "cmpxchgS", Ev
, Gv
, XX
},
1011 { "lssS", Gv
, Mp
, XX
},
1012 { "btrS", Ev
, Gv
, XX
},
1013 { "lfsS", Gv
, Mp
, XX
},
1014 { "lgsS", Gv
, Mp
, XX
},
1015 { "movz{bR|x|bR|x}", Gv
, Eb
, XX
},
1016 { "movz{wR|x|wR|x}", Gv
, Ew
, XX
}, /* yes, there really is movzww ! */
1018 { "(bad)", XX
, XX
, XX
},
1019 { "ud2b", XX
, XX
, XX
},
1021 { "btcS", Ev
, Gv
, XX
},
1022 { "bsfS", Gv
, Ev
, XX
},
1023 { "bsrS", Gv
, Ev
, XX
},
1024 { "movs{bR|x|bR|x}", Gv
, Eb
, XX
},
1025 { "movs{wR|x|wR|x}", Gv
, Ew
, XX
}, /* yes, there really is movsww ! */
1027 { "xaddB", Eb
, Gb
, XX
},
1028 { "xaddS", Ev
, Gv
, XX
},
1030 { "movntiS", Ev
, Gv
, XX
},
1031 { "pinsrw", MX
, Edqw
, Ib
},
1032 { "pextrw", Gdq
, MS
, Ib
},
1033 { "shufpX", XM
, EX
, Ib
},
1036 { "bswap", RMeAX
, XX
, XX
},
1037 { "bswap", RMeCX
, XX
, XX
},
1038 { "bswap", RMeDX
, XX
, XX
},
1039 { "bswap", RMeBX
, XX
, XX
},
1040 { "bswap", RMeSP
, XX
, XX
},
1041 { "bswap", RMeBP
, XX
, XX
},
1042 { "bswap", RMeSI
, XX
, XX
},
1043 { "bswap", RMeDI
, XX
, XX
},
1046 { "psrlw", MX
, EM
, XX
},
1047 { "psrld", MX
, EM
, XX
},
1048 { "psrlq", MX
, EM
, XX
},
1049 { "paddq", MX
, EM
, XX
},
1050 { "pmullw", MX
, EM
, XX
},
1052 { "pmovmskb", Gdq
, MS
, XX
},
1054 { "psubusb", MX
, EM
, XX
},
1055 { "psubusw", MX
, EM
, XX
},
1056 { "pminub", MX
, EM
, XX
},
1057 { "pand", MX
, EM
, XX
},
1058 { "paddusb", MX
, EM
, XX
},
1059 { "paddusw", MX
, EM
, XX
},
1060 { "pmaxub", MX
, EM
, XX
},
1061 { "pandn", MX
, EM
, XX
},
1063 { "pavgb", MX
, EM
, XX
},
1064 { "psraw", MX
, EM
, XX
},
1065 { "psrad", MX
, EM
, XX
},
1066 { "pavgw", MX
, EM
, XX
},
1067 { "pmulhuw", MX
, EM
, XX
},
1068 { "pmulhw", MX
, EM
, XX
},
1072 { "psubsb", MX
, EM
, XX
},
1073 { "psubsw", MX
, EM
, XX
},
1074 { "pminsw", MX
, EM
, XX
},
1075 { "por", MX
, EM
, XX
},
1076 { "paddsb", MX
, EM
, XX
},
1077 { "paddsw", MX
, EM
, XX
},
1078 { "pmaxsw", MX
, EM
, XX
},
1079 { "pxor", MX
, EM
, XX
},
1082 { "psllw", MX
, EM
, XX
},
1083 { "pslld", MX
, EM
, XX
},
1084 { "psllq", MX
, EM
, XX
},
1085 { "pmuludq", MX
, EM
, XX
},
1086 { "pmaddwd", MX
, EM
, XX
},
1087 { "psadbw", MX
, EM
, XX
},
1090 { "psubb", MX
, EM
, XX
},
1091 { "psubw", MX
, EM
, XX
},
1092 { "psubd", MX
, EM
, XX
},
1093 { "psubq", MX
, EM
, XX
},
1094 { "paddb", MX
, EM
, XX
},
1095 { "paddw", MX
, EM
, XX
},
1096 { "paddd", MX
, EM
, XX
},
1097 { "(bad)", XX
, XX
, XX
}
1100 static const unsigned char onebyte_has_modrm
[256] = {
1101 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1102 /* ------------------------------- */
1103 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1104 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1105 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1106 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1107 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1108 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1109 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1110 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1111 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1112 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1113 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1114 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1115 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1116 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1117 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1118 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1119 /* ------------------------------- */
1120 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1123 static const unsigned char twobyte_has_modrm
[256] = {
1124 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1125 /* ------------------------------- */
1126 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1127 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1128 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1129 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1130 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1131 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1132 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1133 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1134 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1135 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1136 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1137 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1138 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1139 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1140 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1141 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1142 /* ------------------------------- */
1143 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1146 static const unsigned char twobyte_uses_SSE_prefix
[256] = {
1147 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1148 /* ------------------------------- */
1149 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1150 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1151 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1152 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1153 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1154 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1155 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1156 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */
1157 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1158 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1159 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1160 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1161 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1162 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1163 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1164 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1165 /* ------------------------------- */
1166 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1169 static char obuf
[100];
1171 static char scratchbuf
[100];
1172 static unsigned char *start_codep
;
1173 static unsigned char *insn_codep
;
1174 static unsigned char *codep
;
1175 static disassemble_info
*the_info
;
1179 static unsigned char need_modrm
;
1181 /* If we are accessing mod/rm/reg without need_modrm set, then the
1182 values are stale. Hitting this abort likely indicates that you
1183 need to update onebyte_has_modrm or twobyte_has_modrm. */
1184 #define MODRM_CHECK if (!need_modrm) abort ()
1186 static const char **names64
;
1187 static const char **names32
;
1188 static const char **names16
;
1189 static const char **names8
;
1190 static const char **names8rex
;
1191 static const char **names_seg
;
1192 static const char **index16
;
1194 static const char *intel_names64
[] = {
1195 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1196 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1198 static const char *intel_names32
[] = {
1199 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1200 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1202 static const char *intel_names16
[] = {
1203 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1204 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1206 static const char *intel_names8
[] = {
1207 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1209 static const char *intel_names8rex
[] = {
1210 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1211 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1213 static const char *intel_names_seg
[] = {
1214 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1216 static const char *intel_index16
[] = {
1217 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1220 static const char *att_names64
[] = {
1221 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1222 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1224 static const char *att_names32
[] = {
1225 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1226 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1228 static const char *att_names16
[] = {
1229 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1230 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1232 static const char *att_names8
[] = {
1233 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1235 static const char *att_names8rex
[] = {
1236 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1237 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1239 static const char *att_names_seg
[] = {
1240 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1242 static const char *att_index16
[] = {
1243 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1246 static const struct dis386 grps
[][8] = {
1249 { "addA", Eb
, Ib
, XX
},
1250 { "orA", Eb
, Ib
, XX
},
1251 { "adcA", Eb
, Ib
, XX
},
1252 { "sbbA", Eb
, Ib
, XX
},
1253 { "andA", Eb
, Ib
, XX
},
1254 { "subA", Eb
, Ib
, XX
},
1255 { "xorA", Eb
, Ib
, XX
},
1256 { "cmpA", Eb
, Ib
, XX
}
1260 { "addQ", Ev
, Iv
, XX
},
1261 { "orQ", Ev
, Iv
, XX
},
1262 { "adcQ", Ev
, Iv
, XX
},
1263 { "sbbQ", Ev
, Iv
, XX
},
1264 { "andQ", Ev
, Iv
, XX
},
1265 { "subQ", Ev
, Iv
, XX
},
1266 { "xorQ", Ev
, Iv
, XX
},
1267 { "cmpQ", Ev
, Iv
, XX
}
1271 { "addQ", Ev
, sIb
, XX
},
1272 { "orQ", Ev
, sIb
, XX
},
1273 { "adcQ", Ev
, sIb
, XX
},
1274 { "sbbQ", Ev
, sIb
, XX
},
1275 { "andQ", Ev
, sIb
, XX
},
1276 { "subQ", Ev
, sIb
, XX
},
1277 { "xorQ", Ev
, sIb
, XX
},
1278 { "cmpQ", Ev
, sIb
, XX
}
1282 { "rolA", Eb
, Ib
, XX
},
1283 { "rorA", Eb
, Ib
, XX
},
1284 { "rclA", Eb
, Ib
, XX
},
1285 { "rcrA", Eb
, Ib
, XX
},
1286 { "shlA", Eb
, Ib
, XX
},
1287 { "shrA", Eb
, Ib
, XX
},
1288 { "(bad)", XX
, XX
, XX
},
1289 { "sarA", Eb
, Ib
, XX
},
1293 { "rolQ", Ev
, Ib
, XX
},
1294 { "rorQ", Ev
, Ib
, XX
},
1295 { "rclQ", Ev
, Ib
, XX
},
1296 { "rcrQ", Ev
, Ib
, XX
},
1297 { "shlQ", Ev
, Ib
, XX
},
1298 { "shrQ", Ev
, Ib
, XX
},
1299 { "(bad)", XX
, XX
, XX
},
1300 { "sarQ", Ev
, Ib
, XX
},
1304 { "rolA", Eb
, I1
, XX
},
1305 { "rorA", Eb
, I1
, XX
},
1306 { "rclA", Eb
, I1
, XX
},
1307 { "rcrA", Eb
, I1
, XX
},
1308 { "shlA", Eb
, I1
, XX
},
1309 { "shrA", Eb
, I1
, XX
},
1310 { "(bad)", XX
, XX
, XX
},
1311 { "sarA", Eb
, I1
, XX
},
1315 { "rolQ", Ev
, I1
, XX
},
1316 { "rorQ", Ev
, I1
, XX
},
1317 { "rclQ", Ev
, I1
, XX
},
1318 { "rcrQ", Ev
, I1
, XX
},
1319 { "shlQ", Ev
, I1
, XX
},
1320 { "shrQ", Ev
, I1
, XX
},
1321 { "(bad)", XX
, XX
, XX
},
1322 { "sarQ", Ev
, I1
, XX
},
1326 { "rolA", Eb
, CL
, XX
},
1327 { "rorA", Eb
, CL
, XX
},
1328 { "rclA", Eb
, CL
, XX
},
1329 { "rcrA", Eb
, CL
, XX
},
1330 { "shlA", Eb
, CL
, XX
},
1331 { "shrA", Eb
, CL
, XX
},
1332 { "(bad)", XX
, XX
, XX
},
1333 { "sarA", Eb
, CL
, XX
},
1337 { "rolQ", Ev
, CL
, XX
},
1338 { "rorQ", Ev
, CL
, XX
},
1339 { "rclQ", Ev
, CL
, XX
},
1340 { "rcrQ", Ev
, CL
, XX
},
1341 { "shlQ", Ev
, CL
, XX
},
1342 { "shrQ", Ev
, CL
, XX
},
1343 { "(bad)", XX
, XX
, XX
},
1344 { "sarQ", Ev
, CL
, XX
}
1348 { "testA", Eb
, Ib
, XX
},
1349 { "(bad)", Eb
, XX
, XX
},
1350 { "notA", Eb
, XX
, XX
},
1351 { "negA", Eb
, XX
, XX
},
1352 { "mulA", Eb
, XX
, XX
}, /* Don't print the implicit %al register, */
1353 { "imulA", Eb
, XX
, XX
}, /* to distinguish these opcodes from other */
1354 { "divA", Eb
, XX
, XX
}, /* mul/imul opcodes. Do the same for div */
1355 { "idivA", Eb
, XX
, XX
} /* and idiv for consistency. */
1359 { "testQ", Ev
, Iv
, XX
},
1360 { "(bad)", XX
, XX
, XX
},
1361 { "notQ", Ev
, XX
, XX
},
1362 { "negQ", Ev
, XX
, XX
},
1363 { "mulQ", Ev
, XX
, XX
}, /* Don't print the implicit register. */
1364 { "imulQ", Ev
, XX
, XX
},
1365 { "divQ", Ev
, XX
, XX
},
1366 { "idivQ", Ev
, XX
, XX
},
1370 { "incA", Eb
, XX
, XX
},
1371 { "decA", Eb
, XX
, XX
},
1372 { "(bad)", XX
, XX
, XX
},
1373 { "(bad)", XX
, XX
, XX
},
1374 { "(bad)", XX
, XX
, XX
},
1375 { "(bad)", XX
, XX
, XX
},
1376 { "(bad)", XX
, XX
, XX
},
1377 { "(bad)", XX
, XX
, XX
},
1381 { "incQ", Ev
, XX
, XX
},
1382 { "decQ", Ev
, XX
, XX
},
1383 { "callT", indirEv
, XX
, XX
},
1384 { "JcallT", indirEp
, XX
, XX
},
1385 { "jmpT", indirEv
, XX
, XX
},
1386 { "JjmpT", indirEp
, XX
, XX
},
1387 { "pushU", stackEv
, XX
, XX
},
1388 { "(bad)", XX
, XX
, XX
},
1392 { "sldtQ", Ev
, XX
, XX
},
1393 { "strQ", Ev
, XX
, XX
},
1394 { "lldt", Ew
, XX
, XX
},
1395 { "ltr", Ew
, XX
, XX
},
1396 { "verr", Ew
, XX
, XX
},
1397 { "verw", Ew
, XX
, XX
},
1398 { "(bad)", XX
, XX
, XX
},
1399 { "(bad)", XX
, XX
, XX
}
1403 { "sgdtIQ", VMX_Fixup
, 0, XX
, XX
},
1404 { "sidtIQ", PNI_Fixup
, 0, XX
, XX
},
1405 { "lgdt{Q|Q||}", M
, XX
, XX
},
1406 { "lidt{Q|Q||}", SVME_Fixup
, 0, XX
, XX
},
1407 { "smswQ", Ev
, XX
, XX
},
1408 { "(bad)", XX
, XX
, XX
},
1409 { "lmsw", Ew
, XX
, XX
},
1410 { "invlpg", INVLPG_Fixup
, w_mode
, XX
, XX
},
1414 { "(bad)", XX
, XX
, XX
},
1415 { "(bad)", XX
, XX
, XX
},
1416 { "(bad)", XX
, XX
, XX
},
1417 { "(bad)", XX
, XX
, XX
},
1418 { "btQ", Ev
, Ib
, XX
},
1419 { "btsQ", Ev
, Ib
, XX
},
1420 { "btrQ", Ev
, Ib
, XX
},
1421 { "btcQ", Ev
, Ib
, XX
},
1425 { "(bad)", XX
, XX
, XX
},
1426 { "cmpxchg8b", Eq
, XX
, XX
},
1427 { "(bad)", XX
, XX
, XX
},
1428 { "(bad)", XX
, XX
, XX
},
1429 { "(bad)", XX
, XX
, XX
},
1430 { "(bad)", XX
, XX
, XX
},
1431 { "", VM
, XX
, XX
}, /* See OP_VMX. */
1432 { "vmptrst", Eq
, XX
, XX
},
1436 { "(bad)", XX
, XX
, XX
},
1437 { "(bad)", XX
, XX
, XX
},
1438 { "psrlw", MS
, Ib
, XX
},
1439 { "(bad)", XX
, XX
, XX
},
1440 { "psraw", MS
, Ib
, XX
},
1441 { "(bad)", XX
, XX
, XX
},
1442 { "psllw", MS
, Ib
, XX
},
1443 { "(bad)", XX
, XX
, XX
},
1447 { "(bad)", XX
, XX
, XX
},
1448 { "(bad)", XX
, XX
, XX
},
1449 { "psrld", MS
, Ib
, XX
},
1450 { "(bad)", XX
, XX
, XX
},
1451 { "psrad", MS
, Ib
, XX
},
1452 { "(bad)", XX
, XX
, XX
},
1453 { "pslld", MS
, Ib
, XX
},
1454 { "(bad)", XX
, XX
, XX
},
1458 { "(bad)", XX
, XX
, XX
},
1459 { "(bad)", XX
, XX
, XX
},
1460 { "psrlq", MS
, Ib
, XX
},
1461 { "psrldq", MS
, Ib
, XX
},
1462 { "(bad)", XX
, XX
, XX
},
1463 { "(bad)", XX
, XX
, XX
},
1464 { "psllq", MS
, Ib
, XX
},
1465 { "pslldq", MS
, Ib
, XX
},
1469 { "fxsave", Ev
, XX
, XX
},
1470 { "fxrstor", Ev
, XX
, XX
},
1471 { "ldmxcsr", Ev
, XX
, XX
},
1472 { "stmxcsr", Ev
, XX
, XX
},
1473 { "(bad)", XX
, XX
, XX
},
1474 { "lfence", OP_0fae
, 0, XX
, XX
},
1475 { "mfence", OP_0fae
, 0, XX
, XX
},
1476 { "clflush", OP_0fae
, 0, XX
, XX
},
1480 { "prefetchnta", Ev
, XX
, XX
},
1481 { "prefetcht0", Ev
, XX
, XX
},
1482 { "prefetcht1", Ev
, XX
, XX
},
1483 { "prefetcht2", Ev
, XX
, XX
},
1484 { "(bad)", XX
, XX
, XX
},
1485 { "(bad)", XX
, XX
, XX
},
1486 { "(bad)", XX
, XX
, XX
},
1487 { "(bad)", XX
, XX
, XX
},
1491 { "prefetch", Eb
, XX
, XX
},
1492 { "prefetchw", Eb
, XX
, XX
},
1493 { "(bad)", XX
, XX
, XX
},
1494 { "(bad)", XX
, XX
, XX
},
1495 { "(bad)", XX
, XX
, XX
},
1496 { "(bad)", XX
, XX
, XX
},
1497 { "(bad)", XX
, XX
, XX
},
1498 { "(bad)", XX
, XX
, XX
},
1502 { "xstore-rng", OP_0f07
, 0, XX
, XX
},
1503 { "xcrypt-ecb", OP_0f07
, 0, XX
, XX
},
1504 { "xcrypt-cbc", OP_0f07
, 0, XX
, XX
},
1505 { "xcrypt-ctr", OP_0f07
, 0, XX
, XX
},
1506 { "xcrypt-cfb", OP_0f07
, 0, XX
, XX
},
1507 { "xcrypt-ofb", OP_0f07
, 0, XX
, XX
},
1508 { "(bad)", OP_0f07
, 0, XX
, XX
},
1509 { "(bad)", OP_0f07
, 0, XX
, XX
},
1513 { "montmul", OP_0f07
, 0, XX
, XX
},
1514 { "xsha1", OP_0f07
, 0, XX
, XX
},
1515 { "xsha256", OP_0f07
, 0, XX
, XX
},
1516 { "(bad)", OP_0f07
, 0, XX
, XX
},
1517 { "(bad)", OP_0f07
, 0, XX
, XX
},
1518 { "(bad)", OP_0f07
, 0, XX
, XX
},
1519 { "(bad)", OP_0f07
, 0, XX
, XX
},
1520 { "(bad)", OP_0f07
, 0, XX
, XX
},
1524 static const struct dis386 prefix_user_table
[][4] = {
1527 { "addps", XM
, EX
, XX
},
1528 { "addss", XM
, EX
, XX
},
1529 { "addpd", XM
, EX
, XX
},
1530 { "addsd", XM
, EX
, XX
},
1534 { "", XM
, EX
, OPSIMD
}, /* See OP_SIMD_SUFFIX. */
1535 { "", XM
, EX
, OPSIMD
},
1536 { "", XM
, EX
, OPSIMD
},
1537 { "", XM
, EX
, OPSIMD
},
1541 { "cvtpi2ps", XM
, EM
, XX
},
1542 { "cvtsi2ssY", XM
, Ev
, XX
},
1543 { "cvtpi2pd", XM
, EM
, XX
},
1544 { "cvtsi2sdY", XM
, Ev
, XX
},
1548 { "cvtps2pi", MX
, EX
, XX
},
1549 { "cvtss2siY", Gv
, EX
, XX
},
1550 { "cvtpd2pi", MX
, EX
, XX
},
1551 { "cvtsd2siY", Gv
, EX
, XX
},
1555 { "cvttps2pi", MX
, EX
, XX
},
1556 { "cvttss2siY", Gv
, EX
, XX
},
1557 { "cvttpd2pi", MX
, EX
, XX
},
1558 { "cvttsd2siY", Gv
, EX
, XX
},
1562 { "divps", XM
, EX
, XX
},
1563 { "divss", XM
, EX
, XX
},
1564 { "divpd", XM
, EX
, XX
},
1565 { "divsd", XM
, EX
, XX
},
1569 { "maxps", XM
, EX
, XX
},
1570 { "maxss", XM
, EX
, XX
},
1571 { "maxpd", XM
, EX
, XX
},
1572 { "maxsd", XM
, EX
, XX
},
1576 { "minps", XM
, EX
, XX
},
1577 { "minss", XM
, EX
, XX
},
1578 { "minpd", XM
, EX
, XX
},
1579 { "minsd", XM
, EX
, XX
},
1583 { "movups", XM
, EX
, XX
},
1584 { "movss", XM
, EX
, XX
},
1585 { "movupd", XM
, EX
, XX
},
1586 { "movsd", XM
, EX
, XX
},
1590 { "movups", EX
, XM
, XX
},
1591 { "movss", EX
, XM
, XX
},
1592 { "movupd", EX
, XM
, XX
},
1593 { "movsd", EX
, XM
, XX
},
1597 { "mulps", XM
, EX
, XX
},
1598 { "mulss", XM
, EX
, XX
},
1599 { "mulpd", XM
, EX
, XX
},
1600 { "mulsd", XM
, EX
, XX
},
1604 { "rcpps", XM
, EX
, XX
},
1605 { "rcpss", XM
, EX
, XX
},
1606 { "(bad)", XM
, EX
, XX
},
1607 { "(bad)", XM
, EX
, XX
},
1611 { "rsqrtps", XM
, EX
, XX
},
1612 { "rsqrtss", XM
, EX
, XX
},
1613 { "(bad)", XM
, EX
, XX
},
1614 { "(bad)", XM
, EX
, XX
},
1618 { "sqrtps", XM
, EX
, XX
},
1619 { "sqrtss", XM
, EX
, XX
},
1620 { "sqrtpd", XM
, EX
, XX
},
1621 { "sqrtsd", XM
, EX
, XX
},
1625 { "subps", XM
, EX
, XX
},
1626 { "subss", XM
, EX
, XX
},
1627 { "subpd", XM
, EX
, XX
},
1628 { "subsd", XM
, EX
, XX
},
1632 { "(bad)", XM
, EX
, XX
},
1633 { "cvtdq2pd", XM
, EX
, XX
},
1634 { "cvttpd2dq", XM
, EX
, XX
},
1635 { "cvtpd2dq", XM
, EX
, XX
},
1639 { "cvtdq2ps", XM
, EX
, XX
},
1640 { "cvttps2dq",XM
, EX
, XX
},
1641 { "cvtps2dq",XM
, EX
, XX
},
1642 { "(bad)", XM
, EX
, XX
},
1646 { "cvtps2pd", XM
, EX
, XX
},
1647 { "cvtss2sd", XM
, EX
, XX
},
1648 { "cvtpd2ps", XM
, EX
, XX
},
1649 { "cvtsd2ss", XM
, EX
, XX
},
1653 { "maskmovq", MX
, MS
, XX
},
1654 { "(bad)", XM
, EX
, XX
},
1655 { "maskmovdqu", XM
, EX
, XX
},
1656 { "(bad)", XM
, EX
, XX
},
1660 { "movq", MX
, EM
, XX
},
1661 { "movdqu", XM
, EX
, XX
},
1662 { "movdqa", XM
, EX
, XX
},
1663 { "(bad)", XM
, EX
, XX
},
1667 { "movq", EM
, MX
, XX
},
1668 { "movdqu", EX
, XM
, XX
},
1669 { "movdqa", EX
, XM
, XX
},
1670 { "(bad)", EX
, XM
, XX
},
1674 { "(bad)", EX
, XM
, XX
},
1675 { "movq2dq", XM
, MS
, XX
},
1676 { "movq", EX
, XM
, XX
},
1677 { "movdq2q", MX
, XS
, XX
},
1681 { "pshufw", MX
, EM
, Ib
},
1682 { "pshufhw", XM
, EX
, Ib
},
1683 { "pshufd", XM
, EX
, Ib
},
1684 { "pshuflw", XM
, EX
, Ib
},
1688 { "movd", Edq
, MX
, XX
},
1689 { "movq", XM
, EX
, XX
},
1690 { "movd", Edq
, XM
, XX
},
1691 { "(bad)", Ed
, XM
, XX
},
1695 { "(bad)", MX
, EX
, XX
},
1696 { "(bad)", XM
, EX
, XX
},
1697 { "punpckhqdq", XM
, EX
, XX
},
1698 { "(bad)", XM
, EX
, XX
},
1702 { "movntq", EM
, MX
, XX
},
1703 { "(bad)", EM
, XM
, XX
},
1704 { "movntdq", EM
, XM
, XX
},
1705 { "(bad)", EM
, XM
, XX
},
1709 { "(bad)", MX
, EX
, XX
},
1710 { "(bad)", XM
, EX
, XX
},
1711 { "punpcklqdq", XM
, EX
, XX
},
1712 { "(bad)", XM
, EX
, XX
},
1716 { "(bad)", MX
, EX
, XX
},
1717 { "(bad)", XM
, EX
, XX
},
1718 { "addsubpd", XM
, EX
, XX
},
1719 { "addsubps", XM
, EX
, XX
},
1723 { "(bad)", MX
, EX
, XX
},
1724 { "(bad)", XM
, EX
, XX
},
1725 { "haddpd", XM
, EX
, XX
},
1726 { "haddps", XM
, EX
, XX
},
1730 { "(bad)", MX
, EX
, XX
},
1731 { "(bad)", XM
, EX
, XX
},
1732 { "hsubpd", XM
, EX
, XX
},
1733 { "hsubps", XM
, EX
, XX
},
1737 { "movlpX", XM
, EX
, SIMD_Fixup
, 'h' }, /* really only 2 operands */
1738 { "movsldup", XM
, EX
, XX
},
1739 { "movlpd", XM
, EX
, XX
},
1740 { "movddup", XM
, EX
, XX
},
1744 { "movhpX", XM
, EX
, SIMD_Fixup
, 'l' },
1745 { "movshdup", XM
, EX
, XX
},
1746 { "movhpd", XM
, EX
, XX
},
1747 { "(bad)", XM
, EX
, XX
},
1751 { "(bad)", XM
, EX
, XX
},
1752 { "(bad)", XM
, EX
, XX
},
1753 { "(bad)", XM
, EX
, XX
},
1754 { "lddqu", XM
, M
, XX
},
1758 static const struct dis386 x86_64_table
[][2] = {
1760 { "arpl", Ew
, Gw
, XX
},
1761 { "movs{||lq|xd}", Gv
, Ed
, XX
},
1765 static const struct dis386 three_byte_table
[][32] = {
1768 { "pshufb", MX
, EM
, XX
},
1769 { "phaddw", MX
, EM
, XX
},
1770 { "phaddd", MX
, EM
, XX
},
1771 { "phaddsw", MX
, EM
, XX
},
1772 { "pmaddubsw", MX
, EM
, XX
},
1773 { "phsubw", MX
, EM
, XX
},
1774 { "phsubd", MX
, EM
, XX
},
1775 { "phsubsw", MX
, EM
, XX
},
1776 { "psignb", MX
, EM
, XX
},
1777 { "psignw", MX
, EM
, XX
},
1778 { "psignd", MX
, EM
, XX
},
1779 { "pmulhrsw", MX
, EM
, XX
},
1780 { "(bad)", XX
, XX
, XX
},
1781 { "(bad)", XX
, XX
, XX
},
1782 { "(bad)", XX
, XX
, XX
},
1783 { "(bad)", XX
, XX
, XX
},
1784 { "(bad)", XX
, XX
, XX
},
1785 { "(bad)", XX
, XX
, XX
},
1786 { "(bad)", XX
, XX
, XX
},
1787 { "(bad)", XX
, XX
, XX
},
1788 { "(bad)", XX
, XX
, XX
},
1789 { "(bad)", XX
, XX
, XX
},
1790 { "(bad)", XX
, XX
, XX
},
1791 { "(bad)", XX
, XX
, XX
},
1792 { "(bad)", XX
, XX
, XX
},
1793 { "(bad)", XX
, XX
, XX
},
1794 { "(bad)", XX
, XX
, XX
},
1795 { "(bad)", XX
, XX
, XX
},
1796 { "pabsb", MX
, EM
, XX
},
1797 { "pabsw", MX
, EM
, XX
},
1798 { "pabsd", MX
, EM
, XX
},
1799 { "(bad)", XX
, XX
, XX
}
1803 { "(bad)", XX
, XX
, XX
},
1804 { "(bad)", XX
, XX
, XX
},
1805 { "(bad)", XX
, XX
, XX
},
1806 { "(bad)", XX
, XX
, XX
},
1807 { "(bad)", XX
, XX
, XX
},
1808 { "(bad)", XX
, XX
, XX
},
1809 { "(bad)", XX
, XX
, XX
},
1810 { "(bad)", XX
, XX
, XX
},
1811 { "(bad)", XX
, XX
, XX
},
1812 { "(bad)", XX
, XX
, XX
},
1813 { "(bad)", XX
, XX
, XX
},
1814 { "(bad)", XX
, XX
, XX
},
1815 { "(bad)", XX
, XX
, XX
},
1816 { "(bad)", XX
, XX
, XX
},
1817 { "(bad)", XX
, XX
, XX
},
1818 { "palignr", MX
, EM
, Ib
},
1819 { "(bad)", XX
, XX
, XX
},
1820 { "(bad)", XX
, XX
, XX
},
1821 { "(bad)", XX
, XX
, XX
},
1822 { "(bad)", XX
, XX
, XX
},
1823 { "(bad)", XX
, XX
, XX
},
1824 { "(bad)", XX
, XX
, XX
},
1825 { "(bad)", XX
, XX
, XX
},
1826 { "(bad)", XX
, XX
, XX
},
1827 { "(bad)", XX
, XX
, XX
},
1828 { "(bad)", XX
, XX
, XX
},
1829 { "(bad)", XX
, XX
, XX
},
1830 { "(bad)", XX
, XX
, XX
},
1831 { "(bad)", XX
, XX
, XX
},
1832 { "(bad)", XX
, XX
, XX
},
1833 { "(bad)", XX
, XX
, XX
},
1834 { "(bad)", XX
, XX
, XX
}
1838 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1850 FETCH_DATA (the_info
, codep
+ 1);
1854 /* REX prefixes family. */
1871 if (address_mode
== mode_64bit
)
1877 prefixes
|= PREFIX_REPZ
;
1880 prefixes
|= PREFIX_REPNZ
;
1883 prefixes
|= PREFIX_LOCK
;
1886 prefixes
|= PREFIX_CS
;
1889 prefixes
|= PREFIX_SS
;
1892 prefixes
|= PREFIX_DS
;
1895 prefixes
|= PREFIX_ES
;
1898 prefixes
|= PREFIX_FS
;
1901 prefixes
|= PREFIX_GS
;
1904 prefixes
|= PREFIX_DATA
;
1907 prefixes
|= PREFIX_ADDR
;
1910 /* fwait is really an instruction. If there are prefixes
1911 before the fwait, they belong to the fwait, *not* to the
1912 following instruction. */
1913 if (prefixes
|| rex
)
1915 prefixes
|= PREFIX_FWAIT
;
1919 prefixes
= PREFIX_FWAIT
;
1924 /* Rex is ignored when followed by another prefix. */
1935 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
1939 prefix_name (int pref
, int sizeflag
)
1943 /* REX prefixes family. */
1995 return (sizeflag
& DFLAG
) ? "data16" : "data32";
1997 if (address_mode
== mode_64bit
)
1998 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
2000 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
2008 static char op1out
[100], op2out
[100], op3out
[100];
2009 static int op_ad
, op_index
[3];
2010 static int two_source_ops
;
2011 static bfd_vma op_address
[3];
2012 static bfd_vma op_riprel
[3];
2013 static bfd_vma start_pc
;
2016 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
2017 * (see topic "Redundant prefixes" in the "Differences from 8086"
2018 * section of the "Virtual 8086 Mode" chapter.)
2019 * 'pc' should be the address of this instruction, it will
2020 * be used to print the target address if this is a relative jump or call
2021 * The function returns the length of this instruction in bytes.
2024 static char intel_syntax
;
2025 static char open_char
;
2026 static char close_char
;
2027 static char separator_char
;
2028 static char scale_char
;
2030 /* Here for backwards compatibility. When gdb stops using
2031 print_insn_i386_att and print_insn_i386_intel these functions can
2032 disappear, and print_insn_i386 be merged into print_insn. */
2034 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
2038 return print_insn (pc
, info
);
2042 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
2046 return print_insn (pc
, info
);
2050 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
2054 return print_insn (pc
, info
);
2058 print_insn (bfd_vma pc
, disassemble_info
*info
)
2060 const struct dis386
*dp
;
2062 char *first
, *second
, *third
;
2064 unsigned char uses_SSE_prefix
, uses_LOCK_prefix
;
2067 struct dis_private priv
;
2069 if (info
->mach
== bfd_mach_x86_64_intel_syntax
2070 || info
->mach
== bfd_mach_x86_64
)
2071 address_mode
= mode_64bit
;
2073 address_mode
= mode_32bit
;
2075 if (intel_syntax
== (char) -1)
2076 intel_syntax
= (info
->mach
== bfd_mach_i386_i386_intel_syntax
2077 || info
->mach
== bfd_mach_x86_64_intel_syntax
);
2079 if (info
->mach
== bfd_mach_i386_i386
2080 || info
->mach
== bfd_mach_x86_64
2081 || info
->mach
== bfd_mach_i386_i386_intel_syntax
2082 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
2083 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2084 else if (info
->mach
== bfd_mach_i386_i8086
)
2085 priv
.orig_sizeflag
= 0;
2089 for (p
= info
->disassembler_options
; p
!= NULL
; )
2091 if (strncmp (p
, "x86-64", 6) == 0)
2093 address_mode
= mode_64bit
;
2094 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2096 else if (strncmp (p
, "i386", 4) == 0)
2098 address_mode
= mode_32bit
;
2099 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2101 else if (strncmp (p
, "i8086", 5) == 0)
2103 address_mode
= mode_16bit
;
2104 priv
.orig_sizeflag
= 0;
2106 else if (strncmp (p
, "intel", 5) == 0)
2110 else if (strncmp (p
, "att", 3) == 0)
2114 else if (strncmp (p
, "addr", 4) == 0)
2116 if (p
[4] == '1' && p
[5] == '6')
2117 priv
.orig_sizeflag
&= ~AFLAG
;
2118 else if (p
[4] == '3' && p
[5] == '2')
2119 priv
.orig_sizeflag
|= AFLAG
;
2121 else if (strncmp (p
, "data", 4) == 0)
2123 if (p
[4] == '1' && p
[5] == '6')
2124 priv
.orig_sizeflag
&= ~DFLAG
;
2125 else if (p
[4] == '3' && p
[5] == '2')
2126 priv
.orig_sizeflag
|= DFLAG
;
2128 else if (strncmp (p
, "suffix", 6) == 0)
2129 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
2131 p
= strchr (p
, ',');
2138 names64
= intel_names64
;
2139 names32
= intel_names32
;
2140 names16
= intel_names16
;
2141 names8
= intel_names8
;
2142 names8rex
= intel_names8rex
;
2143 names_seg
= intel_names_seg
;
2144 index16
= intel_index16
;
2147 separator_char
= '+';
2152 names64
= att_names64
;
2153 names32
= att_names32
;
2154 names16
= att_names16
;
2155 names8
= att_names8
;
2156 names8rex
= att_names8rex
;
2157 names_seg
= att_names_seg
;
2158 index16
= att_index16
;
2161 separator_char
= ',';
2165 /* The output looks better if we put 7 bytes on a line, since that
2166 puts most long word instructions on a single line. */
2167 info
->bytes_per_line
= 7;
2169 info
->private_data
= &priv
;
2170 priv
.max_fetched
= priv
.the_buffer
;
2171 priv
.insn_start
= pc
;
2178 op_index
[0] = op_index
[1] = op_index
[2] = -1;
2182 start_codep
= priv
.the_buffer
;
2183 codep
= priv
.the_buffer
;
2185 if (setjmp (priv
.bailout
) != 0)
2189 /* Getting here means we tried for data but didn't get it. That
2190 means we have an incomplete instruction of some sort. Just
2191 print the first byte as a prefix or a .byte pseudo-op. */
2192 if (codep
> priv
.the_buffer
)
2194 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2196 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
2199 /* Just print the first byte as a .byte instruction. */
2200 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
2201 (unsigned int) priv
.the_buffer
[0]);
2214 sizeflag
= priv
.orig_sizeflag
;
2216 FETCH_DATA (info
, codep
+ 1);
2217 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
2219 if (((prefixes
& PREFIX_FWAIT
)
2220 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
2221 || (rex
&& rex_used
))
2225 /* fwait not followed by floating point instruction, or rex followed
2226 by other prefixes. Print the first prefix. */
2227 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2229 name
= INTERNAL_DISASSEMBLER_ERROR
;
2230 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
2236 FETCH_DATA (info
, codep
+ 2);
2237 dp
= &dis386_twobyte
[*++codep
];
2238 need_modrm
= twobyte_has_modrm
[*codep
];
2239 uses_SSE_prefix
= twobyte_uses_SSE_prefix
[*codep
];
2240 uses_LOCK_prefix
= (*codep
& ~0x02) == 0x20;
2244 dp
= &dis386
[*codep
];
2245 need_modrm
= onebyte_has_modrm
[*codep
];
2246 uses_SSE_prefix
= 0;
2247 uses_LOCK_prefix
= 0;
2251 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_REPZ
))
2254 used_prefixes
|= PREFIX_REPZ
;
2256 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_REPNZ
))
2259 used_prefixes
|= PREFIX_REPNZ
;
2261 if (!uses_LOCK_prefix
&& (prefixes
& PREFIX_LOCK
))
2264 used_prefixes
|= PREFIX_LOCK
;
2267 if (prefixes
& PREFIX_ADDR
)
2270 if (dp
->bytemode3
!= loop_jcxz_mode
|| intel_syntax
)
2272 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
2273 oappend ("addr32 ");
2275 oappend ("addr16 ");
2276 used_prefixes
|= PREFIX_ADDR
;
2280 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_DATA
))
2283 if (dp
->bytemode3
== cond_jump_mode
2284 && dp
->bytemode1
== v_mode
2287 if (sizeflag
& DFLAG
)
2288 oappend ("data32 ");
2290 oappend ("data16 ");
2291 used_prefixes
|= PREFIX_DATA
;
2295 if (dp
->name
== NULL
&& dp
->bytemode1
== IS_3BYTE_OPCODE
)
2297 FETCH_DATA (info
, codep
+ 2);
2298 dp
= &three_byte_table
[dp
->bytemode2
][*codep
++];
2299 mod
= (*codep
>> 6) & 3;
2300 reg
= (*codep
>> 3) & 7;
2303 else if (need_modrm
)
2305 FETCH_DATA (info
, codep
+ 1);
2306 mod
= (*codep
>> 6) & 3;
2307 reg
= (*codep
>> 3) & 7;
2311 if (dp
->name
== NULL
&& dp
->bytemode1
== FLOATCODE
)
2318 if (dp
->name
== NULL
)
2320 switch (dp
->bytemode1
)
2323 dp
= &grps
[dp
->bytemode2
][reg
];
2326 case USE_PREFIX_USER_TABLE
:
2328 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
2329 if (prefixes
& PREFIX_REPZ
)
2333 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2334 if (prefixes
& PREFIX_DATA
)
2338 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
2339 if (prefixes
& PREFIX_REPNZ
)
2343 dp
= &prefix_user_table
[dp
->bytemode2
][index
];
2346 case X86_64_SPECIAL
:
2347 index
= address_mode
== mode_64bit
? 1 : 0;
2348 dp
= &x86_64_table
[dp
->bytemode2
][index
];
2352 oappend (INTERNAL_DISASSEMBLER_ERROR
);
2357 if (putop (dp
->name
, sizeflag
) == 0)
2362 (*dp
->op1
) (dp
->bytemode1
, sizeflag
);
2367 (*dp
->op2
) (dp
->bytemode2
, sizeflag
);
2372 (*dp
->op3
) (dp
->bytemode3
, sizeflag
);
2376 /* See if any prefixes were not used. If so, print the first one
2377 separately. If we don't do this, we'll wind up printing an
2378 instruction stream which does not precisely correspond to the
2379 bytes we are disassembling. */
2380 if ((prefixes
& ~used_prefixes
) != 0)
2384 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2386 name
= INTERNAL_DISASSEMBLER_ERROR
;
2387 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
2390 if (rex
& ~rex_used
)
2393 name
= prefix_name (rex
| 0x40, priv
.orig_sizeflag
);
2395 name
= INTERNAL_DISASSEMBLER_ERROR
;
2396 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
2399 obufp
= obuf
+ strlen (obuf
);
2400 for (i
= strlen (obuf
); i
< 6; i
++)
2403 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
2405 /* The enter and bound instructions are printed with operands in the same
2406 order as the intel book; everything else is printed in reverse order. */
2407 if (intel_syntax
|| two_source_ops
)
2412 op_ad
= op_index
[0];
2413 op_index
[0] = op_index
[2];
2414 op_index
[2] = op_ad
;
2425 if (op_index
[0] != -1 && !op_riprel
[0])
2426 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[0]], info
);
2428 (*info
->fprintf_func
) (info
->stream
, "%s", first
);
2434 (*info
->fprintf_func
) (info
->stream
, ",");
2435 if (op_index
[1] != -1 && !op_riprel
[1])
2436 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[1]], info
);
2438 (*info
->fprintf_func
) (info
->stream
, "%s", second
);
2444 (*info
->fprintf_func
) (info
->stream
, ",");
2445 if (op_index
[2] != -1 && !op_riprel
[2])
2446 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[2]], info
);
2448 (*info
->fprintf_func
) (info
->stream
, "%s", third
);
2450 for (i
= 0; i
< 3; i
++)
2451 if (op_index
[i
] != -1 && op_riprel
[i
])
2453 (*info
->fprintf_func
) (info
->stream
, " # ");
2454 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
2455 + op_address
[op_index
[i
]]), info
);
2457 return codep
- priv
.the_buffer
;
2460 static const char *float_mem
[] = {
2535 static const unsigned char float_mem_mode
[] = {
2611 #define STi OP_STi, 0
2613 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
2614 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
2615 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
2616 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
2617 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
2618 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
2619 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
2620 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
2621 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
2623 static const struct dis386 float_reg
[][8] = {
2626 { "fadd", ST
, STi
, XX
},
2627 { "fmul", ST
, STi
, XX
},
2628 { "fcom", STi
, XX
, XX
},
2629 { "fcomp", STi
, XX
, XX
},
2630 { "fsub", ST
, STi
, XX
},
2631 { "fsubr", ST
, STi
, XX
},
2632 { "fdiv", ST
, STi
, XX
},
2633 { "fdivr", ST
, STi
, XX
},
2637 { "fld", STi
, XX
, XX
},
2638 { "fxch", STi
, XX
, XX
},
2640 { "(bad)", XX
, XX
, XX
},
2648 { "fcmovb", ST
, STi
, XX
},
2649 { "fcmove", ST
, STi
, XX
},
2650 { "fcmovbe",ST
, STi
, XX
},
2651 { "fcmovu", ST
, STi
, XX
},
2652 { "(bad)", XX
, XX
, XX
},
2654 { "(bad)", XX
, XX
, XX
},
2655 { "(bad)", XX
, XX
, XX
},
2659 { "fcmovnb",ST
, STi
, XX
},
2660 { "fcmovne",ST
, STi
, XX
},
2661 { "fcmovnbe",ST
, STi
, XX
},
2662 { "fcmovnu",ST
, STi
, XX
},
2664 { "fucomi", ST
, STi
, XX
},
2665 { "fcomi", ST
, STi
, XX
},
2666 { "(bad)", XX
, XX
, XX
},
2670 { "fadd", STi
, ST
, XX
},
2671 { "fmul", STi
, ST
, XX
},
2672 { "(bad)", XX
, XX
, XX
},
2673 { "(bad)", XX
, XX
, XX
},
2675 { "fsub", STi
, ST
, XX
},
2676 { "fsubr", STi
, ST
, XX
},
2677 { "fdiv", STi
, ST
, XX
},
2678 { "fdivr", STi
, ST
, XX
},
2680 { "fsubr", STi
, ST
, XX
},
2681 { "fsub", STi
, ST
, XX
},
2682 { "fdivr", STi
, ST
, XX
},
2683 { "fdiv", STi
, ST
, XX
},
2688 { "ffree", STi
, XX
, XX
},
2689 { "(bad)", XX
, XX
, XX
},
2690 { "fst", STi
, XX
, XX
},
2691 { "fstp", STi
, XX
, XX
},
2692 { "fucom", STi
, XX
, XX
},
2693 { "fucomp", STi
, XX
, XX
},
2694 { "(bad)", XX
, XX
, XX
},
2695 { "(bad)", XX
, XX
, XX
},
2699 { "faddp", STi
, ST
, XX
},
2700 { "fmulp", STi
, ST
, XX
},
2701 { "(bad)", XX
, XX
, XX
},
2704 { "fsubp", STi
, ST
, XX
},
2705 { "fsubrp", STi
, ST
, XX
},
2706 { "fdivp", STi
, ST
, XX
},
2707 { "fdivrp", STi
, ST
, XX
},
2709 { "fsubrp", STi
, ST
, XX
},
2710 { "fsubp", STi
, ST
, XX
},
2711 { "fdivrp", STi
, ST
, XX
},
2712 { "fdivp", STi
, ST
, XX
},
2717 { "ffreep", STi
, XX
, XX
},
2718 { "(bad)", XX
, XX
, XX
},
2719 { "(bad)", XX
, XX
, XX
},
2720 { "(bad)", XX
, XX
, XX
},
2722 { "fucomip",ST
, STi
, XX
},
2723 { "fcomip", ST
, STi
, XX
},
2724 { "(bad)", XX
, XX
, XX
},
2728 static char *fgrps
[][8] = {
2731 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2736 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2741 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2746 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2751 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2756 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2761 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2762 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2767 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2772 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2777 dofloat (int sizeflag
)
2779 const struct dis386
*dp
;
2780 unsigned char floatop
;
2782 floatop
= codep
[-1];
2786 int fp_indx
= (floatop
- 0xd8) * 8 + reg
;
2788 putop (float_mem
[fp_indx
], sizeflag
);
2791 OP_E (float_mem_mode
[fp_indx
], sizeflag
);
2794 /* Skip mod/rm byte. */
2798 dp
= &float_reg
[floatop
- 0xd8][reg
];
2799 if (dp
->name
== NULL
)
2801 putop (fgrps
[dp
->bytemode1
][rm
], sizeflag
);
2803 /* Instruction fnstsw is only one with strange arg. */
2804 if (floatop
== 0xdf && codep
[-1] == 0xe0)
2805 strcpy (op1out
, names16
[0]);
2809 putop (dp
->name
, sizeflag
);
2814 (*dp
->op1
) (dp
->bytemode1
, sizeflag
);
2819 (*dp
->op2
) (dp
->bytemode2
, sizeflag
);
2824 OP_ST (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
2826 oappend ("%st" + intel_syntax
);
2830 OP_STi (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
2832 sprintf (scratchbuf
, "%%st(%d)", rm
);
2833 oappend (scratchbuf
+ intel_syntax
);
2836 /* Capital letters in template are macros. */
2838 putop (const char *template, int sizeflag
)
2843 for (p
= template; *p
; p
++)
2854 if (address_mode
== mode_64bit
)
2862 /* Alternative not valid. */
2863 strcpy (obuf
, "(bad)");
2867 else if (*p
== '\0')
2888 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
2894 if (sizeflag
& SUFFIX_ALWAYS
)
2898 if (intel_syntax
&& !alt
)
2900 if ((prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
2902 if (sizeflag
& DFLAG
)
2903 *obufp
++ = intel_syntax
? 'd' : 'l';
2905 *obufp
++ = intel_syntax
? 'w' : 's';
2906 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2909 case 'E': /* For jcxz/jecxz */
2910 if (address_mode
== mode_64bit
)
2912 if (sizeflag
& AFLAG
)
2918 if (sizeflag
& AFLAG
)
2920 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
2925 if ((prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
2927 if (sizeflag
& AFLAG
)
2928 *obufp
++ = address_mode
== mode_64bit
? 'q' : 'l';
2930 *obufp
++ = address_mode
== mode_64bit
? 'l' : 'w';
2931 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
2937 if ((prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
2938 || (prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
2940 used_prefixes
|= prefixes
& (PREFIX_CS
| PREFIX_DS
);
2943 if (prefixes
& PREFIX_DS
)
2957 if (address_mode
== mode_64bit
&& (sizeflag
& SUFFIX_ALWAYS
))
2966 if (sizeflag
& SUFFIX_ALWAYS
)
2970 if ((prefixes
& PREFIX_FWAIT
) == 0)
2973 used_prefixes
|= PREFIX_FWAIT
;
2976 USED_REX (REX_MODE64
);
2977 if (rex
& REX_MODE64
)
2985 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
2994 if ((prefixes
& PREFIX_DATA
)
2995 || (rex
& REX_MODE64
)
2996 || (sizeflag
& SUFFIX_ALWAYS
))
2998 USED_REX (REX_MODE64
);
2999 if (rex
& REX_MODE64
)
3003 if (sizeflag
& DFLAG
)
3008 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3014 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3016 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3022 if (intel_syntax
&& !alt
)
3024 USED_REX (REX_MODE64
);
3025 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3027 if (rex
& REX_MODE64
)
3031 if (sizeflag
& DFLAG
)
3032 *obufp
++ = intel_syntax
? 'd' : 'l';
3036 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3040 USED_REX (REX_MODE64
);
3043 if (rex
& REX_MODE64
)
3048 else if (sizeflag
& DFLAG
)
3061 if (rex
& REX_MODE64
)
3063 else if (sizeflag
& DFLAG
)
3068 if (!(rex
& REX_MODE64
))
3069 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3074 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3076 if (sizeflag
& SUFFIX_ALWAYS
)
3084 if (sizeflag
& SUFFIX_ALWAYS
)
3086 if (rex
& REX_MODE64
)
3090 if (sizeflag
& DFLAG
)
3094 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3099 if (prefixes
& PREFIX_DATA
)
3103 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3108 if (rex
& REX_MODE64
)
3110 USED_REX (REX_MODE64
);
3114 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
3116 /* operand size flag for cwtl, cbtw */
3120 else if (sizeflag
& DFLAG
)
3131 if (sizeflag
& DFLAG
)
3142 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3152 oappend (const char *s
)
3155 obufp
+= strlen (s
);
3161 if (prefixes
& PREFIX_CS
)
3163 used_prefixes
|= PREFIX_CS
;
3164 oappend ("%cs:" + intel_syntax
);
3166 if (prefixes
& PREFIX_DS
)
3168 used_prefixes
|= PREFIX_DS
;
3169 oappend ("%ds:" + intel_syntax
);
3171 if (prefixes
& PREFIX_SS
)
3173 used_prefixes
|= PREFIX_SS
;
3174 oappend ("%ss:" + intel_syntax
);
3176 if (prefixes
& PREFIX_ES
)
3178 used_prefixes
|= PREFIX_ES
;
3179 oappend ("%es:" + intel_syntax
);
3181 if (prefixes
& PREFIX_FS
)
3183 used_prefixes
|= PREFIX_FS
;
3184 oappend ("%fs:" + intel_syntax
);
3186 if (prefixes
& PREFIX_GS
)
3188 used_prefixes
|= PREFIX_GS
;
3189 oappend ("%gs:" + intel_syntax
);
3194 OP_indirE (int bytemode
, int sizeflag
)
3198 OP_E (bytemode
, sizeflag
);
3202 print_operand_value (char *buf
, int hex
, bfd_vma disp
)
3204 if (address_mode
== mode_64bit
)
3212 sprintf_vma (tmp
, disp
);
3213 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+ 1]; i
++);
3214 strcpy (buf
+ 2, tmp
+ i
);
3218 bfd_signed_vma v
= disp
;
3225 /* Check for possible overflow on 0x8000000000000000. */
3228 strcpy (buf
, "9223372036854775808");
3242 tmp
[28 - i
] = (v
% 10) + '0';
3246 strcpy (buf
, tmp
+ 29 - i
);
3252 sprintf (buf
, "0x%x", (unsigned int) disp
);
3254 sprintf (buf
, "%d", (int) disp
);
3259 intel_operand_size (int bytemode
, int sizeflag
)
3264 oappend ("BYTE PTR ");
3268 oappend ("WORD PTR ");
3271 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3273 oappend ("QWORD PTR ");
3274 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3280 USED_REX (REX_MODE64
);
3281 if (rex
& REX_MODE64
)
3282 oappend ("QWORD PTR ");
3283 else if ((sizeflag
& DFLAG
) || bytemode
== dq_mode
)
3284 oappend ("DWORD PTR ");
3286 oappend ("WORD PTR ");
3287 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3290 oappend ("DWORD PTR ");
3293 oappend ("QWORD PTR ");
3296 if (address_mode
== mode_64bit
)
3297 oappend ("QWORD PTR ");
3299 oappend ("DWORD PTR ");
3302 if (sizeflag
& DFLAG
)
3303 oappend ("FWORD PTR ");
3305 oappend ("DWORD PTR ");
3306 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3309 oappend ("TBYTE PTR ");
3312 oappend ("XMMWORD PTR ");
3320 OP_E (int bytemode
, int sizeflag
)
3325 USED_REX (REX_EXTZ
);
3329 /* Skip mod/rm byte. */
3340 oappend (names8rex
[rm
+ add
]);
3342 oappend (names8
[rm
+ add
]);
3345 oappend (names16
[rm
+ add
]);
3348 oappend (names32
[rm
+ add
]);
3351 oappend (names64
[rm
+ add
]);
3354 if (address_mode
== mode_64bit
)
3355 oappend (names64
[rm
+ add
]);
3357 oappend (names32
[rm
+ add
]);
3360 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3362 oappend (names64
[rm
+ add
]);
3363 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3371 USED_REX (REX_MODE64
);
3372 if (rex
& REX_MODE64
)
3373 oappend (names64
[rm
+ add
]);
3374 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
3375 oappend (names32
[rm
+ add
]);
3377 oappend (names16
[rm
+ add
]);
3378 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3383 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3391 intel_operand_size (bytemode
, sizeflag
);
3394 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
) /* 32 bit address mode */
3409 FETCH_DATA (the_info
, codep
+ 1);
3410 index
= (*codep
>> 3) & 7;
3411 if (address_mode
== mode_64bit
|| index
!= 0x4)
3412 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
3413 scale
= (*codep
>> 6) & 3;
3415 USED_REX (REX_EXTY
);
3425 if ((base
& 7) == 5)
3428 if (address_mode
== mode_64bit
&& !havesib
)
3434 FETCH_DATA (the_info
, codep
+ 1);
3436 if ((disp
& 0x80) != 0)
3445 if (mod
!= 0 || (base
& 7) == 5)
3447 print_operand_value (scratchbuf
, !riprel
, disp
);
3448 oappend (scratchbuf
);
3456 if (havebase
|| (havesib
&& (index
!= 4 || scale
!= 0)))
3458 *obufp
++ = open_char
;
3459 if (intel_syntax
&& riprel
)
3463 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
3464 ? names64
[base
] : names32
[base
]);
3469 if (!intel_syntax
|| havebase
)
3471 *obufp
++ = separator_char
;
3474 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
3475 ? names64
[index
] : names32
[index
]);
3477 if (scale
!= 0 || (!intel_syntax
&& index
!= 4))
3479 *obufp
++ = scale_char
;
3481 sprintf (scratchbuf
, "%d", 1 << scale
);
3482 oappend (scratchbuf
);
3485 if (intel_syntax
&& disp
)
3487 if ((bfd_signed_vma
) disp
> 0)
3496 disp
= - (bfd_signed_vma
) disp
;
3499 print_operand_value (scratchbuf
, mod
!= 1, disp
);
3500 oappend (scratchbuf
);
3503 *obufp
++ = close_char
;
3506 else if (intel_syntax
)
3508 if (mod
!= 0 || (base
& 7) == 5)
3510 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
3511 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
3515 oappend (names_seg
[ds_reg
- es_reg
]);
3518 print_operand_value (scratchbuf
, 1, disp
);
3519 oappend (scratchbuf
);
3524 { /* 16 bit address mode */
3531 if ((disp
& 0x8000) != 0)
3536 FETCH_DATA (the_info
, codep
+ 1);
3538 if ((disp
& 0x80) != 0)
3543 if ((disp
& 0x8000) != 0)
3549 if (mod
!= 0 || rm
== 6)
3551 print_operand_value (scratchbuf
, 0, disp
);
3552 oappend (scratchbuf
);
3555 if (mod
!= 0 || rm
!= 6)
3557 *obufp
++ = open_char
;
3559 oappend (index16
[rm
]);
3560 if (intel_syntax
&& disp
)
3562 if ((bfd_signed_vma
) disp
> 0)
3571 disp
= - (bfd_signed_vma
) disp
;
3574 print_operand_value (scratchbuf
, mod
!= 1, disp
);
3575 oappend (scratchbuf
);
3578 *obufp
++ = close_char
;
3581 else if (intel_syntax
)
3583 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
3584 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
3588 oappend (names_seg
[ds_reg
- es_reg
]);
3591 print_operand_value (scratchbuf
, 1, disp
& 0xffff);
3592 oappend (scratchbuf
);
3598 OP_G (int bytemode
, int sizeflag
)
3601 USED_REX (REX_EXTX
);
3609 oappend (names8rex
[reg
+ add
]);
3611 oappend (names8
[reg
+ add
]);
3614 oappend (names16
[reg
+ add
]);
3617 oappend (names32
[reg
+ add
]);
3620 oappend (names64
[reg
+ add
]);
3625 USED_REX (REX_MODE64
);
3626 if (rex
& REX_MODE64
)
3627 oappend (names64
[reg
+ add
]);
3628 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
3629 oappend (names32
[reg
+ add
]);
3631 oappend (names16
[reg
+ add
]);
3632 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3635 if (address_mode
== mode_64bit
)
3636 oappend (names64
[reg
+ add
]);
3638 oappend (names32
[reg
+ add
]);
3641 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3654 FETCH_DATA (the_info
, codep
+ 8);
3655 a
= *codep
++ & 0xff;
3656 a
|= (*codep
++ & 0xff) << 8;
3657 a
|= (*codep
++ & 0xff) << 16;
3658 a
|= (*codep
++ & 0xff) << 24;
3659 b
= *codep
++ & 0xff;
3660 b
|= (*codep
++ & 0xff) << 8;
3661 b
|= (*codep
++ & 0xff) << 16;
3662 b
|= (*codep
++ & 0xff) << 24;
3663 x
= a
+ ((bfd_vma
) b
<< 32);
3671 static bfd_signed_vma
3674 bfd_signed_vma x
= 0;
3676 FETCH_DATA (the_info
, codep
+ 4);
3677 x
= *codep
++ & (bfd_signed_vma
) 0xff;
3678 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
3679 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
3680 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
3684 static bfd_signed_vma
3687 bfd_signed_vma x
= 0;
3689 FETCH_DATA (the_info
, codep
+ 4);
3690 x
= *codep
++ & (bfd_signed_vma
) 0xff;
3691 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
3692 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
3693 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
3695 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
3705 FETCH_DATA (the_info
, codep
+ 2);
3706 x
= *codep
++ & 0xff;
3707 x
|= (*codep
++ & 0xff) << 8;
3712 set_op (bfd_vma op
, int riprel
)
3714 op_index
[op_ad
] = op_ad
;
3715 if (address_mode
== mode_64bit
)
3717 op_address
[op_ad
] = op
;
3718 op_riprel
[op_ad
] = riprel
;
3722 /* Mask to get a 32-bit address. */
3723 op_address
[op_ad
] = op
& 0xffffffff;
3724 op_riprel
[op_ad
] = riprel
& 0xffffffff;
3729 OP_REG (int code
, int sizeflag
)
3733 USED_REX (REX_EXTZ
);
3745 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
3746 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
3747 s
= names16
[code
- ax_reg
+ add
];
3749 case es_reg
: case ss_reg
: case cs_reg
:
3750 case ds_reg
: case fs_reg
: case gs_reg
:
3751 s
= names_seg
[code
- es_reg
+ add
];
3753 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
3754 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
3757 s
= names8rex
[code
- al_reg
+ add
];
3759 s
= names8
[code
- al_reg
];
3761 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
3762 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
3763 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3765 s
= names64
[code
- rAX_reg
+ add
];
3768 code
+= eAX_reg
- rAX_reg
;
3770 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
3771 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
3772 USED_REX (REX_MODE64
);
3773 if (rex
& REX_MODE64
)
3774 s
= names64
[code
- eAX_reg
+ add
];
3775 else if (sizeflag
& DFLAG
)
3776 s
= names32
[code
- eAX_reg
+ add
];
3778 s
= names16
[code
- eAX_reg
+ add
];
3779 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3782 s
= INTERNAL_DISASSEMBLER_ERROR
;
3789 OP_IMREG (int code
, int sizeflag
)
3801 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
3802 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
3803 s
= names16
[code
- ax_reg
];
3805 case es_reg
: case ss_reg
: case cs_reg
:
3806 case ds_reg
: case fs_reg
: case gs_reg
:
3807 s
= names_seg
[code
- es_reg
];
3809 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
3810 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
3813 s
= names8rex
[code
- al_reg
];
3815 s
= names8
[code
- al_reg
];
3817 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
3818 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
3819 USED_REX (REX_MODE64
);
3820 if (rex
& REX_MODE64
)
3821 s
= names64
[code
- eAX_reg
];
3822 else if (sizeflag
& DFLAG
)
3823 s
= names32
[code
- eAX_reg
];
3825 s
= names16
[code
- eAX_reg
];
3826 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3829 s
= INTERNAL_DISASSEMBLER_ERROR
;
3836 OP_I (int bytemode
, int sizeflag
)
3839 bfd_signed_vma mask
= -1;
3844 FETCH_DATA (the_info
, codep
+ 1);
3849 if (address_mode
== mode_64bit
)
3856 USED_REX (REX_MODE64
);
3857 if (rex
& REX_MODE64
)
3859 else if (sizeflag
& DFLAG
)
3869 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3880 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3885 scratchbuf
[0] = '$';
3886 print_operand_value (scratchbuf
+ 1, 1, op
);
3887 oappend (scratchbuf
+ intel_syntax
);
3888 scratchbuf
[0] = '\0';
3892 OP_I64 (int bytemode
, int sizeflag
)
3895 bfd_signed_vma mask
= -1;
3897 if (address_mode
!= mode_64bit
)
3899 OP_I (bytemode
, sizeflag
);
3906 FETCH_DATA (the_info
, codep
+ 1);
3911 USED_REX (REX_MODE64
);
3912 if (rex
& REX_MODE64
)
3914 else if (sizeflag
& DFLAG
)
3924 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3931 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3936 scratchbuf
[0] = '$';
3937 print_operand_value (scratchbuf
+ 1, 1, op
);
3938 oappend (scratchbuf
+ intel_syntax
);
3939 scratchbuf
[0] = '\0';
3943 OP_sI (int bytemode
, int sizeflag
)
3946 bfd_signed_vma mask
= -1;
3951 FETCH_DATA (the_info
, codep
+ 1);
3953 if ((op
& 0x80) != 0)
3958 USED_REX (REX_MODE64
);
3959 if (rex
& REX_MODE64
)
3961 else if (sizeflag
& DFLAG
)
3970 if ((op
& 0x8000) != 0)
3973 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3978 if ((op
& 0x8000) != 0)
3982 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3986 scratchbuf
[0] = '$';
3987 print_operand_value (scratchbuf
+ 1, 1, op
);
3988 oappend (scratchbuf
+ intel_syntax
);
3992 OP_J (int bytemode
, int sizeflag
)
4000 FETCH_DATA (the_info
, codep
+ 1);
4002 if ((disp
& 0x80) != 0)
4006 if ((sizeflag
& DFLAG
) || (rex
& REX_MODE64
))
4011 /* For some reason, a data16 prefix on a jump instruction
4012 means that the pc is masked to 16 bits after the
4013 displacement is added! */
4018 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4021 disp
= (start_pc
+ codep
- start_codep
+ disp
) & mask
;
4023 print_operand_value (scratchbuf
, 1, disp
);
4024 oappend (scratchbuf
);
4028 OP_SEG (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4030 oappend (names_seg
[reg
]);
4034 OP_DIR (int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
4038 if (sizeflag
& DFLAG
)
4048 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4050 sprintf (scratchbuf
, "0x%x:0x%x", seg
, offset
);
4052 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
4053 oappend (scratchbuf
);
4057 OP_OFF (int bytemode
, int sizeflag
)
4061 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4062 intel_operand_size (bytemode
, sizeflag
);
4065 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
4072 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4073 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4075 oappend (names_seg
[ds_reg
- es_reg
]);
4079 print_operand_value (scratchbuf
, 1, off
);
4080 oappend (scratchbuf
);
4084 OP_OFF64 (int bytemode
, int sizeflag
)
4088 if (address_mode
!= mode_64bit
)
4090 OP_OFF (bytemode
, sizeflag
);
4094 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4095 intel_operand_size (bytemode
, sizeflag
);
4102 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4103 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4105 oappend (names_seg
[ds_reg
- es_reg
]);
4109 print_operand_value (scratchbuf
, 1, off
);
4110 oappend (scratchbuf
);
4114 ptr_reg (int code
, int sizeflag
)
4118 *obufp
++ = open_char
;
4119 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4120 if (address_mode
== mode_64bit
)
4122 if (!(sizeflag
& AFLAG
))
4123 s
= names32
[code
- eAX_reg
];
4125 s
= names64
[code
- eAX_reg
];
4127 else if (sizeflag
& AFLAG
)
4128 s
= names32
[code
- eAX_reg
];
4130 s
= names16
[code
- eAX_reg
];
4132 *obufp
++ = close_char
;
4137 OP_ESreg (int code
, int sizeflag
)
4140 intel_operand_size (codep
[-1] & 1 ? v_mode
: b_mode
, sizeflag
);
4141 oappend ("%es:" + intel_syntax
);
4142 ptr_reg (code
, sizeflag
);
4146 OP_DSreg (int code
, int sizeflag
)
4149 intel_operand_size (codep
[-1] != 0xd7 && (codep
[-1] & 1)
4160 prefixes
|= PREFIX_DS
;
4162 ptr_reg (code
, sizeflag
);
4166 OP_C (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4171 USED_REX (REX_EXTX
);
4174 else if (address_mode
!= mode_64bit
&& (prefixes
& PREFIX_LOCK
))
4176 used_prefixes
|= PREFIX_LOCK
;
4179 sprintf (scratchbuf
, "%%cr%d", reg
+ add
);
4180 oappend (scratchbuf
+ intel_syntax
);
4184 OP_D (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4187 USED_REX (REX_EXTX
);
4191 sprintf (scratchbuf
, "db%d", reg
+ add
);
4193 sprintf (scratchbuf
, "%%db%d", reg
+ add
);
4194 oappend (scratchbuf
);
4198 OP_T (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4200 sprintf (scratchbuf
, "%%tr%d", reg
);
4201 oappend (scratchbuf
+ intel_syntax
);
4205 OP_Rd (int bytemode
, int sizeflag
)
4208 OP_E (bytemode
, sizeflag
);
4214 OP_MMX (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4216 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4217 if (prefixes
& PREFIX_DATA
)
4220 USED_REX (REX_EXTX
);
4223 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
4226 sprintf (scratchbuf
, "%%mm%d", reg
);
4227 oappend (scratchbuf
+ intel_syntax
);
4231 OP_XMM (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4234 USED_REX (REX_EXTX
);
4237 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
4238 oappend (scratchbuf
+ intel_syntax
);
4242 OP_EM (int bytemode
, int sizeflag
)
4246 if (intel_syntax
&& bytemode
== v_mode
)
4248 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
4249 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4251 OP_E (bytemode
, sizeflag
);
4255 /* Skip mod/rm byte. */
4258 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4259 if (prefixes
& PREFIX_DATA
)
4263 USED_REX (REX_EXTZ
);
4266 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
4269 sprintf (scratchbuf
, "%%mm%d", rm
);
4270 oappend (scratchbuf
+ intel_syntax
);
4274 OP_EX (int bytemode
, int sizeflag
)
4279 if (intel_syntax
&& bytemode
== v_mode
)
4281 switch (prefixes
& (PREFIX_DATA
|PREFIX_REPZ
|PREFIX_REPNZ
))
4283 case 0: bytemode
= x_mode
; break;
4284 case PREFIX_REPZ
: bytemode
= d_mode
; used_prefixes
|= PREFIX_REPZ
; break;
4285 case PREFIX_DATA
: bytemode
= x_mode
; used_prefixes
|= PREFIX_DATA
; break;
4286 case PREFIX_REPNZ
: bytemode
= q_mode
; used_prefixes
|= PREFIX_REPNZ
; break;
4287 default: bytemode
= 0; break;
4290 OP_E (bytemode
, sizeflag
);
4293 USED_REX (REX_EXTZ
);
4297 /* Skip mod/rm byte. */
4300 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
4301 oappend (scratchbuf
+ intel_syntax
);
4305 OP_MS (int bytemode
, int sizeflag
)
4308 OP_EM (bytemode
, sizeflag
);
4314 OP_XS (int bytemode
, int sizeflag
)
4317 OP_EX (bytemode
, sizeflag
);
4323 OP_M (int bytemode
, int sizeflag
)
4326 BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
4328 OP_E (bytemode
, sizeflag
);
4332 OP_0f07 (int bytemode
, int sizeflag
)
4334 if (mod
!= 3 || rm
!= 0)
4337 OP_E (bytemode
, sizeflag
);
4341 OP_0fae (int bytemode
, int sizeflag
)
4346 strcpy (obuf
+ strlen (obuf
) - sizeof ("clflush") + 1, "sfence");
4348 if (reg
< 5 || rm
!= 0)
4350 BadOp (); /* bad sfence, mfence, or lfence */
4356 BadOp (); /* bad clflush */
4360 OP_E (bytemode
, sizeflag
);
4364 NOP_Fixup (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4366 /* NOP with REPZ prefix is called PAUSE. */
4367 if (prefixes
== PREFIX_REPZ
)
4368 strcpy (obuf
, "pause");
4371 static const char *const Suffix3DNow
[] = {
4372 /* 00 */ NULL
, NULL
, NULL
, NULL
,
4373 /* 04 */ NULL
, NULL
, NULL
, NULL
,
4374 /* 08 */ NULL
, NULL
, NULL
, NULL
,
4375 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
4376 /* 10 */ NULL
, NULL
, NULL
, NULL
,
4377 /* 14 */ NULL
, NULL
, NULL
, NULL
,
4378 /* 18 */ NULL
, NULL
, NULL
, NULL
,
4379 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
4380 /* 20 */ NULL
, NULL
, NULL
, NULL
,
4381 /* 24 */ NULL
, NULL
, NULL
, NULL
,
4382 /* 28 */ NULL
, NULL
, NULL
, NULL
,
4383 /* 2C */ NULL
, NULL
, NULL
, NULL
,
4384 /* 30 */ NULL
, NULL
, NULL
, NULL
,
4385 /* 34 */ NULL
, NULL
, NULL
, NULL
,
4386 /* 38 */ NULL
, NULL
, NULL
, NULL
,
4387 /* 3C */ NULL
, NULL
, NULL
, NULL
,
4388 /* 40 */ NULL
, NULL
, NULL
, NULL
,
4389 /* 44 */ NULL
, NULL
, NULL
, NULL
,
4390 /* 48 */ NULL
, NULL
, NULL
, NULL
,
4391 /* 4C */ NULL
, NULL
, NULL
, NULL
,
4392 /* 50 */ NULL
, NULL
, NULL
, NULL
,
4393 /* 54 */ NULL
, NULL
, NULL
, NULL
,
4394 /* 58 */ NULL
, NULL
, NULL
, NULL
,
4395 /* 5C */ NULL
, NULL
, NULL
, NULL
,
4396 /* 60 */ NULL
, NULL
, NULL
, NULL
,
4397 /* 64 */ NULL
, NULL
, NULL
, NULL
,
4398 /* 68 */ NULL
, NULL
, NULL
, NULL
,
4399 /* 6C */ NULL
, NULL
, NULL
, NULL
,
4400 /* 70 */ NULL
, NULL
, NULL
, NULL
,
4401 /* 74 */ NULL
, NULL
, NULL
, NULL
,
4402 /* 78 */ NULL
, NULL
, NULL
, NULL
,
4403 /* 7C */ NULL
, NULL
, NULL
, NULL
,
4404 /* 80 */ NULL
, NULL
, NULL
, NULL
,
4405 /* 84 */ NULL
, NULL
, NULL
, NULL
,
4406 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
4407 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
4408 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
4409 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
4410 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
4411 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
4412 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
4413 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
4414 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
4415 /* AC */ NULL
, NULL
, "pfacc", NULL
,
4416 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
4417 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pfmulhrw",
4418 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
4419 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
4420 /* C0 */ NULL
, NULL
, NULL
, NULL
,
4421 /* C4 */ NULL
, NULL
, NULL
, NULL
,
4422 /* C8 */ NULL
, NULL
, NULL
, NULL
,
4423 /* CC */ NULL
, NULL
, NULL
, NULL
,
4424 /* D0 */ NULL
, NULL
, NULL
, NULL
,
4425 /* D4 */ NULL
, NULL
, NULL
, NULL
,
4426 /* D8 */ NULL
, NULL
, NULL
, NULL
,
4427 /* DC */ NULL
, NULL
, NULL
, NULL
,
4428 /* E0 */ NULL
, NULL
, NULL
, NULL
,
4429 /* E4 */ NULL
, NULL
, NULL
, NULL
,
4430 /* E8 */ NULL
, NULL
, NULL
, NULL
,
4431 /* EC */ NULL
, NULL
, NULL
, NULL
,
4432 /* F0 */ NULL
, NULL
, NULL
, NULL
,
4433 /* F4 */ NULL
, NULL
, NULL
, NULL
,
4434 /* F8 */ NULL
, NULL
, NULL
, NULL
,
4435 /* FC */ NULL
, NULL
, NULL
, NULL
,
4439 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4441 const char *mnemonic
;
4443 FETCH_DATA (the_info
, codep
+ 1);
4444 /* AMD 3DNow! instructions are specified by an opcode suffix in the
4445 place where an 8-bit immediate would normally go. ie. the last
4446 byte of the instruction. */
4447 obufp
= obuf
+ strlen (obuf
);
4448 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
4453 /* Since a variable sized modrm/sib chunk is between the start
4454 of the opcode (0x0f0f) and the opcode suffix, we need to do
4455 all the modrm processing first, and don't know until now that
4456 we have a bad opcode. This necessitates some cleaning up. */
4463 static const char *simd_cmp_op
[] = {
4475 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4477 unsigned int cmp_type
;
4479 FETCH_DATA (the_info
, codep
+ 1);
4480 obufp
= obuf
+ strlen (obuf
);
4481 cmp_type
= *codep
++ & 0xff;
4484 char suffix1
= 'p', suffix2
= 's';
4485 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
4486 if (prefixes
& PREFIX_REPZ
)
4490 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4491 if (prefixes
& PREFIX_DATA
)
4495 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
4496 if (prefixes
& PREFIX_REPNZ
)
4497 suffix1
= 's', suffix2
= 'd';
4500 sprintf (scratchbuf
, "cmp%s%c%c",
4501 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
4502 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
4503 oappend (scratchbuf
);
4507 /* We have a bad extension byte. Clean up. */
4515 SIMD_Fixup (int extrachar
, int sizeflag ATTRIBUTE_UNUSED
)
4517 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
4518 forms of these instructions. */
4521 char *p
= obuf
+ strlen (obuf
);
4524 *(p
- 1) = *(p
- 2);
4525 *(p
- 2) = *(p
- 3);
4526 *(p
- 3) = extrachar
;
4531 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
4533 if (mod
== 3 && reg
== 1 && rm
<= 1)
4535 /* Override "sidt". */
4536 size_t olen
= strlen (obuf
);
4537 char *p
= obuf
+ olen
- 4;
4538 const char **names
= (address_mode
== mode_64bit
4539 ? names64
: names32
);
4541 /* We might have a suffix when disassembling with -Msuffix. */
4545 /* Remove "addr16/addr32" if we aren't in Intel mode. */
4547 && (prefixes
& PREFIX_ADDR
)
4550 && strncmp (p
- 7, "addr", 4) == 0
4551 && (strncmp (p
- 3, "16", 2) == 0
4552 || strncmp (p
- 3, "32", 2) == 0))
4557 /* mwait %eax,%ecx */
4558 strcpy (p
, "mwait");
4560 strcpy (op1out
, names
[0]);
4564 /* monitor %eax,%ecx,%edx" */
4565 strcpy (p
, "monitor");
4568 const char **op1_names
;
4569 if (!(prefixes
& PREFIX_ADDR
))
4570 op1_names
= (address_mode
== mode_16bit
4574 op1_names
= (address_mode
!= mode_32bit
4575 ? names32
: names16
);
4576 used_prefixes
|= PREFIX_ADDR
;
4578 strcpy (op1out
, op1_names
[0]);
4579 strcpy (op3out
, names
[2]);
4584 strcpy (op2out
, names
[1]);
4595 SVME_Fixup (int bytemode
, int sizeflag
)
4627 OP_M (bytemode
, sizeflag
);
4630 /* Override "lidt". */
4631 p
= obuf
+ strlen (obuf
) - 4;
4632 /* We might have a suffix. */
4636 if (!(prefixes
& PREFIX_ADDR
))
4641 used_prefixes
|= PREFIX_ADDR
;
4645 strcpy (op2out
, names32
[1]);
4651 *obufp
++ = open_char
;
4652 if (address_mode
== mode_64bit
|| (sizeflag
& AFLAG
))
4656 strcpy (obufp
, alt
);
4657 obufp
+= strlen (alt
);
4658 *obufp
++ = close_char
;
4665 INVLPG_Fixup (int bytemode
, int sizeflag
)
4678 OP_M (bytemode
, sizeflag
);
4681 /* Override "invlpg". */
4682 strcpy (obuf
+ strlen (obuf
) - 6, alt
);
4689 /* Throw away prefixes and 1st. opcode byte. */
4690 codep
= insn_codep
+ 1;
4695 SEG_Fixup (int extrachar
, int sizeflag
)
4699 /* We need to add a proper suffix with
4710 if (prefixes
& PREFIX_DATA
)
4714 USED_REX (REX_MODE64
);
4715 if (rex
& REX_MODE64
)
4720 strcat (obuf
, suffix
);
4724 /* We need to fix the suffix for
4731 Override "mov[l|q]". */
4732 char *p
= obuf
+ strlen (obuf
) - 1;
4734 /* We might not have a suffix. */
4740 OP_E (extrachar
, sizeflag
);
4744 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
4746 if (mod
== 3 && reg
== 0 && rm
>=1 && rm
<= 4)
4748 /* Override "sgdt". */
4749 char *p
= obuf
+ strlen (obuf
) - 4;
4751 /* We might have a suffix when disassembling with -Msuffix. */
4758 strcpy (p
, "vmcall");
4761 strcpy (p
, "vmlaunch");
4764 strcpy (p
, "vmresume");
4767 strcpy (p
, "vmxoff");
4778 OP_VMX (int bytemode
, int sizeflag
)
4780 used_prefixes
|= (prefixes
& (PREFIX_DATA
| PREFIX_REPZ
));
4781 if (prefixes
& PREFIX_DATA
)
4782 strcpy (obuf
, "vmclear");
4783 else if (prefixes
& PREFIX_REPZ
)
4784 strcpy (obuf
, "vmxon");
4786 strcpy (obuf
, "vmptrld");
4787 OP_E (bytemode
, sizeflag
);
4791 REP_Fixup (int bytemode
, int sizeflag
)
4793 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
4797 if (prefixes
& PREFIX_REPZ
)
4798 switch (*insn_codep
)
4800 case 0x6e: /* outsb */
4801 case 0x6f: /* outsw/outsl */
4802 case 0xa4: /* movsb */
4803 case 0xa5: /* movsw/movsl/movsq */
4809 case 0xaa: /* stosb */
4810 case 0xab: /* stosw/stosl/stosq */
4811 case 0xac: /* lodsb */
4812 case 0xad: /* lodsw/lodsl/lodsq */
4813 if (!intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4818 case 0x6c: /* insb */
4819 case 0x6d: /* insl/insw */
4835 olen
= strlen (obuf
);
4836 p
= obuf
+ olen
- ilen
- 1 - 4;
4837 /* Handle "repz [addr16|addr32]". */
4838 if ((prefixes
& PREFIX_ADDR
))
4841 memmove (p
+ 3, p
+ 4, olen
- (p
+ 3 - obuf
));
4849 OP_IMREG (bytemode
, sizeflag
);
4852 OP_ESreg (bytemode
, sizeflag
);
4855 OP_DSreg (bytemode
, sizeflag
);