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);
106 /* Points to first byte not fetched. */
107 bfd_byte
*max_fetched
;
108 bfd_byte the_buffer
[MAXLEN
];
114 /* The opcode for the fwait instruction, which we treat as a prefix
116 #define FWAIT_OPCODE (0x9b)
125 enum address_mode address_mode
;
127 /* Flags for the prefixes for the current instruction. See below. */
130 /* REX prefix the current instruction. See below. */
132 /* Bits of REX we've already used. */
138 /* Mark parts used in the REX prefix. When we are testing for
139 empty prefix (for 8bit register REX extension), just mask it
140 out. Otherwise test for REX bit is excuse for existence of REX
141 only in case value is nonzero. */
142 #define USED_REX(value) \
145 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
150 /* Flags for prefixes which we somehow handled when printing the
151 current instruction. */
152 static int used_prefixes
;
154 /* Flags stored in PREFIXES. */
155 #define PREFIX_REPZ 1
156 #define PREFIX_REPNZ 2
157 #define PREFIX_LOCK 4
159 #define PREFIX_SS 0x10
160 #define PREFIX_DS 0x20
161 #define PREFIX_ES 0x40
162 #define PREFIX_FS 0x80
163 #define PREFIX_GS 0x100
164 #define PREFIX_DATA 0x200
165 #define PREFIX_ADDR 0x400
166 #define PREFIX_FWAIT 0x800
168 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
169 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
171 #define FETCH_DATA(info, addr) \
172 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
173 ? 1 : fetch_data ((info), (addr)))
176 fetch_data (struct disassemble_info
*info
, bfd_byte
*addr
)
179 struct dis_private
*priv
= (struct dis_private
*) info
->private_data
;
180 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
182 if (addr
<= priv
->the_buffer
+ MAXLEN
)
183 status
= (*info
->read_memory_func
) (start
,
185 addr
- priv
->max_fetched
,
191 /* If we did manage to read at least one byte, then
192 print_insn_i386 will do something sensible. Otherwise, print
193 an error. We do that here because this is where we know
195 if (priv
->max_fetched
== priv
->the_buffer
)
196 (*info
->memory_error_func
) (status
, start
, info
);
197 longjmp (priv
->bailout
, 1);
200 priv
->max_fetched
= addr
;
206 #define Eb OP_E, b_mode
207 #define Ev OP_E, v_mode
208 #define Ed OP_E, d_mode
209 #define Eq OP_E, q_mode
210 #define Edq OP_E, dq_mode
211 #define Edqw OP_E, dqw_mode
212 #define indirEv OP_indirE, stack_v_mode
213 #define indirEp OP_indirE, f_mode
214 #define stackEv OP_E, stack_v_mode
215 #define Em OP_E, m_mode
216 #define Ew OP_E, w_mode
217 #define Ma OP_E, v_mode
218 #define M OP_M, 0 /* lea, lgdt, etc. */
219 #define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */
220 #define Gb OP_G, b_mode
221 #define Gv OP_G, v_mode
222 #define Gd OP_G, d_mode
223 #define Gdq OP_G, dq_mode
224 #define Gm OP_G, m_mode
225 #define Gw OP_G, w_mode
226 #define Rd OP_Rd, d_mode
227 #define Rm OP_Rd, m_mode
228 #define Ib OP_I, b_mode
229 #define sIb OP_sI, b_mode /* sign extened byte */
230 #define Iv OP_I, v_mode
231 #define Iq OP_I, q_mode
232 #define Iv64 OP_I64, v_mode
233 #define Iw OP_I, w_mode
234 #define I1 OP_I, const_1_mode
235 #define Jb OP_J, b_mode
236 #define Jv OP_J, v_mode
237 #define Cm OP_C, m_mode
238 #define Dm OP_D, m_mode
239 #define Td OP_T, d_mode
240 #define Sv SEG_Fixup, v_mode
242 #define RMeAX OP_REG, eAX_reg
243 #define RMeBX OP_REG, eBX_reg
244 #define RMeCX OP_REG, eCX_reg
245 #define RMeDX OP_REG, eDX_reg
246 #define RMeSP OP_REG, eSP_reg
247 #define RMeBP OP_REG, eBP_reg
248 #define RMeSI OP_REG, eSI_reg
249 #define RMeDI OP_REG, eDI_reg
250 #define RMrAX OP_REG, rAX_reg
251 #define RMrBX OP_REG, rBX_reg
252 #define RMrCX OP_REG, rCX_reg
253 #define RMrDX OP_REG, rDX_reg
254 #define RMrSP OP_REG, rSP_reg
255 #define RMrBP OP_REG, rBP_reg
256 #define RMrSI OP_REG, rSI_reg
257 #define RMrDI OP_REG, rDI_reg
258 #define RMAL OP_REG, al_reg
259 #define RMAL OP_REG, al_reg
260 #define RMCL OP_REG, cl_reg
261 #define RMDL OP_REG, dl_reg
262 #define RMBL OP_REG, bl_reg
263 #define RMAH OP_REG, ah_reg
264 #define RMCH OP_REG, ch_reg
265 #define RMDH OP_REG, dh_reg
266 #define RMBH OP_REG, bh_reg
267 #define RMAX OP_REG, ax_reg
268 #define RMDX OP_REG, dx_reg
270 #define eAX OP_IMREG, eAX_reg
271 #define eBX OP_IMREG, eBX_reg
272 #define eCX OP_IMREG, eCX_reg
273 #define eDX OP_IMREG, eDX_reg
274 #define eSP OP_IMREG, eSP_reg
275 #define eBP OP_IMREG, eBP_reg
276 #define eSI OP_IMREG, eSI_reg
277 #define eDI OP_IMREG, eDI_reg
278 #define AL OP_IMREG, al_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 #define cond_jump_flag NULL, cond_jump_mode
319 #define loop_jcxz_flag NULL, loop_jcxz_mode
321 /* bits in sizeflag */
322 #define SUFFIX_ALWAYS 4
326 #define b_mode 1 /* byte operand */
327 #define v_mode 2 /* operand size depends on prefixes */
328 #define w_mode 3 /* word operand */
329 #define d_mode 4 /* double word operand */
330 #define q_mode 5 /* quad word operand */
331 #define t_mode 6 /* ten-byte operand */
332 #define x_mode 7 /* 16-byte XMM operand */
333 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
334 #define cond_jump_mode 9
335 #define loop_jcxz_mode 10
336 #define dq_mode 11 /* operand size depends on REX prefixes. */
337 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
338 #define f_mode 13 /* 4- or 6-byte pointer operand */
339 #define const_1_mode 14
340 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
385 #define indir_dx_reg 150
389 #define USE_PREFIX_USER_TABLE 3
390 #define X86_64_SPECIAL 4
391 #define IS_3BYTE_OPCODE 5
393 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
395 #define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
396 #define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
397 #define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
398 #define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
399 #define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
400 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
401 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
402 #define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
403 #define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
404 #define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
405 #define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
406 #define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
407 #define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
408 #define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
409 #define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
410 #define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
411 #define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
412 #define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
413 #define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
414 #define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
415 #define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
416 #define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
417 #define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
418 #define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0
419 #define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0
421 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
422 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
423 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
424 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
425 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
426 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
427 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
428 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
429 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
430 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
431 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
432 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
433 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
434 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
435 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
436 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
437 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
438 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
439 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
440 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
441 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
442 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
443 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
444 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
445 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
446 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
447 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
448 #define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0
449 #define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0
450 #define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0
451 #define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0
452 #define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0
453 #define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0
455 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
457 #define THREE_BYTE_0 NULL, NULL, IS_3BYTE_OPCODE, NULL, 0, NULL, 0
458 #define THREE_BYTE_1 NULL, NULL, IS_3BYTE_OPCODE, NULL, 1, NULL, 0
460 typedef void (*op_rtn
) (int bytemode
, int sizeflag
);
472 /* Upper case letters in the instruction names here are macros.
473 'A' => print 'b' if no register operands or suffix_always is true
474 'B' => print 'b' if suffix_always is true
475 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
477 'E' => print 'e' if 32-bit form of jcxz
478 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
479 'H' => print ",pt" or ",pn" branch hint
480 'I' => honor following macro letter even in Intel mode (implemented only
481 . for some of the macro letters)
483 'L' => print 'l' if suffix_always is true
484 'N' => print 'n' if instruction has no wait "prefix"
485 'O' => print 'd', or 'o'
486 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
487 . or suffix_always is true. print 'q' if rex prefix is present.
488 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
490 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
491 'S' => print 'w', 'l' or 'q' if suffix_always is true
492 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
493 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
494 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
495 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
496 'X' => print 's', 'd' depending on data16 prefix (for XMM)
497 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
498 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
500 Many of the above letters print nothing in Intel mode. See "putop"
503 Braces '{' and '}', and vertical bars '|', indicate alternative
504 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
505 modes. In cases where there are only two alternatives, the X86_64
506 instruction is reserved, and "(bad)" is printed.
509 static const struct dis386 dis386
[] = {
511 { "addB", Eb
, Gb
, XX
},
512 { "addS", Ev
, Gv
, XX
},
513 { "addB", Gb
, Eb
, XX
},
514 { "addS", Gv
, Ev
, XX
},
515 { "addB", AL
, Ib
, XX
},
516 { "addS", eAX
, Iv
, XX
},
517 { "push{T|}", es
, XX
, XX
},
518 { "pop{T|}", es
, XX
, XX
},
520 { "orB", Eb
, Gb
, XX
},
521 { "orS", Ev
, Gv
, XX
},
522 { "orB", Gb
, Eb
, XX
},
523 { "orS", Gv
, Ev
, XX
},
524 { "orB", AL
, Ib
, XX
},
525 { "orS", eAX
, Iv
, XX
},
526 { "push{T|}", cs
, XX
, XX
},
527 { "(bad)", XX
, XX
, XX
}, /* 0x0f extended opcode escape */
529 { "adcB", Eb
, Gb
, XX
},
530 { "adcS", Ev
, Gv
, XX
},
531 { "adcB", Gb
, Eb
, XX
},
532 { "adcS", Gv
, Ev
, XX
},
533 { "adcB", AL
, Ib
, XX
},
534 { "adcS", eAX
, Iv
, XX
},
535 { "push{T|}", ss
, XX
, XX
},
536 { "pop{T|}", ss
, XX
, XX
},
538 { "sbbB", Eb
, Gb
, XX
},
539 { "sbbS", Ev
, Gv
, XX
},
540 { "sbbB", Gb
, Eb
, XX
},
541 { "sbbS", Gv
, Ev
, XX
},
542 { "sbbB", AL
, Ib
, XX
},
543 { "sbbS", eAX
, Iv
, XX
},
544 { "push{T|}", ds
, XX
, XX
},
545 { "pop{T|}", ds
, XX
, XX
},
547 { "andB", Eb
, Gb
, XX
},
548 { "andS", Ev
, Gv
, XX
},
549 { "andB", Gb
, Eb
, XX
},
550 { "andS", Gv
, Ev
, XX
},
551 { "andB", AL
, Ib
, XX
},
552 { "andS", eAX
, Iv
, XX
},
553 { "(bad)", XX
, XX
, XX
}, /* SEG ES prefix */
554 { "daa{|}", XX
, XX
, XX
},
556 { "subB", Eb
, Gb
, XX
},
557 { "subS", Ev
, Gv
, XX
},
558 { "subB", Gb
, Eb
, XX
},
559 { "subS", Gv
, Ev
, XX
},
560 { "subB", AL
, Ib
, XX
},
561 { "subS", eAX
, Iv
, XX
},
562 { "(bad)", XX
, XX
, XX
}, /* SEG CS prefix */
563 { "das{|}", XX
, XX
, XX
},
565 { "xorB", Eb
, Gb
, XX
},
566 { "xorS", Ev
, Gv
, XX
},
567 { "xorB", Gb
, Eb
, XX
},
568 { "xorS", Gv
, Ev
, XX
},
569 { "xorB", AL
, Ib
, XX
},
570 { "xorS", eAX
, Iv
, XX
},
571 { "(bad)", XX
, XX
, XX
}, /* SEG SS prefix */
572 { "aaa{|}", XX
, XX
, XX
},
574 { "cmpB", Eb
, Gb
, XX
},
575 { "cmpS", Ev
, Gv
, XX
},
576 { "cmpB", Gb
, Eb
, XX
},
577 { "cmpS", Gv
, Ev
, XX
},
578 { "cmpB", AL
, Ib
, XX
},
579 { "cmpS", eAX
, Iv
, XX
},
580 { "(bad)", XX
, XX
, XX
}, /* SEG DS prefix */
581 { "aas{|}", XX
, XX
, XX
},
583 { "inc{S|}", RMeAX
, XX
, XX
},
584 { "inc{S|}", RMeCX
, XX
, XX
},
585 { "inc{S|}", RMeDX
, XX
, XX
},
586 { "inc{S|}", RMeBX
, XX
, XX
},
587 { "inc{S|}", RMeSP
, XX
, XX
},
588 { "inc{S|}", RMeBP
, XX
, XX
},
589 { "inc{S|}", RMeSI
, XX
, XX
},
590 { "inc{S|}", RMeDI
, XX
, XX
},
592 { "dec{S|}", RMeAX
, XX
, XX
},
593 { "dec{S|}", RMeCX
, XX
, XX
},
594 { "dec{S|}", RMeDX
, XX
, XX
},
595 { "dec{S|}", RMeBX
, XX
, XX
},
596 { "dec{S|}", RMeSP
, XX
, XX
},
597 { "dec{S|}", RMeBP
, XX
, XX
},
598 { "dec{S|}", RMeSI
, XX
, XX
},
599 { "dec{S|}", RMeDI
, XX
, XX
},
601 { "pushV", RMrAX
, XX
, XX
},
602 { "pushV", RMrCX
, XX
, XX
},
603 { "pushV", RMrDX
, XX
, XX
},
604 { "pushV", RMrBX
, XX
, XX
},
605 { "pushV", RMrSP
, XX
, XX
},
606 { "pushV", RMrBP
, XX
, XX
},
607 { "pushV", RMrSI
, XX
, XX
},
608 { "pushV", RMrDI
, XX
, XX
},
610 { "popV", RMrAX
, XX
, XX
},
611 { "popV", RMrCX
, XX
, XX
},
612 { "popV", RMrDX
, XX
, XX
},
613 { "popV", RMrBX
, XX
, XX
},
614 { "popV", RMrSP
, XX
, XX
},
615 { "popV", RMrBP
, XX
, XX
},
616 { "popV", RMrSI
, XX
, XX
},
617 { "popV", RMrDI
, XX
, XX
},
619 { "pusha{P|}", XX
, XX
, XX
},
620 { "popa{P|}", XX
, XX
, XX
},
621 { "bound{S|}", Gv
, Ma
, XX
},
623 { "(bad)", XX
, XX
, XX
}, /* seg fs */
624 { "(bad)", XX
, XX
, XX
}, /* seg gs */
625 { "(bad)", XX
, XX
, XX
}, /* op size prefix */
626 { "(bad)", XX
, XX
, XX
}, /* adr size prefix */
628 { "pushT", Iq
, XX
, XX
},
629 { "imulS", Gv
, Ev
, Iv
},
630 { "pushT", sIb
, XX
, XX
},
631 { "imulS", Gv
, Ev
, sIb
},
632 { "ins{b||b|}", Yb
, indirDX
, XX
},
633 { "ins{R||R|}", Yv
, indirDX
, XX
},
634 { "outs{b||b|}", indirDX
, Xb
, XX
},
635 { "outs{R||R|}", indirDX
, Xv
, XX
},
637 { "joH", Jb
, XX
, cond_jump_flag
},
638 { "jnoH", Jb
, XX
, cond_jump_flag
},
639 { "jbH", Jb
, XX
, cond_jump_flag
},
640 { "jaeH", Jb
, XX
, cond_jump_flag
},
641 { "jeH", Jb
, XX
, cond_jump_flag
},
642 { "jneH", Jb
, XX
, cond_jump_flag
},
643 { "jbeH", Jb
, XX
, cond_jump_flag
},
644 { "jaH", Jb
, XX
, cond_jump_flag
},
646 { "jsH", Jb
, XX
, cond_jump_flag
},
647 { "jnsH", Jb
, XX
, cond_jump_flag
},
648 { "jpH", Jb
, XX
, cond_jump_flag
},
649 { "jnpH", Jb
, XX
, cond_jump_flag
},
650 { "jlH", Jb
, XX
, cond_jump_flag
},
651 { "jgeH", Jb
, XX
, cond_jump_flag
},
652 { "jleH", Jb
, XX
, cond_jump_flag
},
653 { "jgH", Jb
, XX
, cond_jump_flag
},
657 { "(bad)", XX
, XX
, XX
},
659 { "testB", Eb
, Gb
, XX
},
660 { "testS", Ev
, Gv
, XX
},
661 { "xchgB", Eb
, Gb
, XX
},
662 { "xchgS", Ev
, Gv
, XX
},
664 { "movB", Eb
, Gb
, XX
},
665 { "movS", Ev
, Gv
, XX
},
666 { "movB", Gb
, Eb
, XX
},
667 { "movS", Gv
, Ev
, XX
},
668 { "movQ", Sv
, Sw
, XX
},
669 { "leaS", Gv
, M
, XX
},
670 { "movQ", Sw
, Sv
, XX
},
671 { "popU", stackEv
, XX
, XX
},
673 { "nop", NOP_Fixup
, 0, XX
, XX
},
674 { "xchgS", RMeCX
, eAX
, XX
},
675 { "xchgS", RMeDX
, eAX
, XX
},
676 { "xchgS", RMeBX
, eAX
, XX
},
677 { "xchgS", RMeSP
, eAX
, XX
},
678 { "xchgS", RMeBP
, eAX
, XX
},
679 { "xchgS", RMeSI
, eAX
, XX
},
680 { "xchgS", RMeDI
, eAX
, XX
},
682 { "cW{tR||tR|}", XX
, XX
, XX
},
683 { "cR{tO||tO|}", XX
, XX
, XX
},
684 { "Jcall{T|}", Ap
, XX
, XX
},
685 { "(bad)", XX
, XX
, XX
}, /* fwait */
686 { "pushfT", XX
, XX
, XX
},
687 { "popfT", XX
, XX
, XX
},
688 { "sahf{|}", XX
, XX
, XX
},
689 { "lahf{|}", XX
, XX
, XX
},
691 { "movB", AL
, Ob
, XX
},
692 { "movS", eAX
, Ov
, XX
},
693 { "movB", Ob
, AL
, XX
},
694 { "movS", Ov
, eAX
, XX
},
695 { "movs{b||b|}", Yb
, Xb
, XX
},
696 { "movs{R||R|}", Yv
, Xv
, XX
},
697 { "cmps{b||b|}", Xb
, Yb
, XX
},
698 { "cmps{R||R|}", Xv
, Yv
, XX
},
700 { "testB", AL
, Ib
, XX
},
701 { "testS", eAX
, Iv
, XX
},
702 { "stosB", Yb
, AL
, XX
},
703 { "stosS", Yv
, eAX
, XX
},
704 { "lodsB", AL
, Xb
, XX
},
705 { "lodsS", eAX
, Xv
, XX
},
706 { "scasB", AL
, Yb
, XX
},
707 { "scasS", eAX
, Yv
, XX
},
709 { "movB", RMAL
, Ib
, XX
},
710 { "movB", RMCL
, Ib
, XX
},
711 { "movB", RMDL
, Ib
, XX
},
712 { "movB", RMBL
, Ib
, XX
},
713 { "movB", RMAH
, Ib
, XX
},
714 { "movB", RMCH
, Ib
, XX
},
715 { "movB", RMDH
, Ib
, XX
},
716 { "movB", RMBH
, Ib
, XX
},
718 { "movS", RMeAX
, Iv64
, XX
},
719 { "movS", RMeCX
, Iv64
, XX
},
720 { "movS", RMeDX
, Iv64
, XX
},
721 { "movS", RMeBX
, Iv64
, XX
},
722 { "movS", RMeSP
, Iv64
, XX
},
723 { "movS", RMeBP
, Iv64
, XX
},
724 { "movS", RMeSI
, Iv64
, XX
},
725 { "movS", RMeDI
, Iv64
, XX
},
729 { "retT", Iw
, XX
, XX
},
730 { "retT", XX
, XX
, XX
},
731 { "les{S|}", Gv
, Mp
, XX
},
732 { "ldsS", Gv
, Mp
, XX
},
733 { "movA", Eb
, Ib
, XX
},
734 { "movQ", Ev
, Iv
, XX
},
736 { "enterT", Iw
, Ib
, XX
},
737 { "leaveT", XX
, XX
, XX
},
738 { "lretP", Iw
, XX
, XX
},
739 { "lretP", XX
, XX
, XX
},
740 { "int3", XX
, XX
, XX
},
741 { "int", Ib
, XX
, XX
},
742 { "into{|}", XX
, XX
, XX
},
743 { "iretP", XX
, XX
, XX
},
749 { "aam{|}", sIb
, XX
, XX
},
750 { "aad{|}", sIb
, XX
, XX
},
751 { "(bad)", XX
, XX
, XX
},
752 { "xlat", DSBX
, XX
, XX
},
763 { "loopneFH", Jb
, XX
, loop_jcxz_flag
},
764 { "loopeFH", Jb
, XX
, loop_jcxz_flag
},
765 { "loopFH", Jb
, XX
, loop_jcxz_flag
},
766 { "jEcxzH", Jb
, XX
, loop_jcxz_flag
},
767 { "inB", AL
, Ib
, XX
},
768 { "inS", eAX
, Ib
, XX
},
769 { "outB", Ib
, AL
, XX
},
770 { "outS", Ib
, eAX
, XX
},
772 { "callT", Jv
, XX
, XX
},
773 { "jmpT", Jv
, XX
, XX
},
774 { "Jjmp{T|}", Ap
, XX
, XX
},
775 { "jmp", Jb
, XX
, XX
},
776 { "inB", AL
, indirDX
, XX
},
777 { "inS", eAX
, indirDX
, XX
},
778 { "outB", indirDX
, AL
, XX
},
779 { "outS", indirDX
, eAX
, XX
},
781 { "(bad)", XX
, XX
, XX
}, /* lock prefix */
782 { "icebp", XX
, XX
, XX
},
783 { "(bad)", XX
, XX
, XX
}, /* repne */
784 { "(bad)", XX
, XX
, XX
}, /* repz */
785 { "hlt", XX
, XX
, XX
},
786 { "cmc", XX
, XX
, XX
},
790 { "clc", XX
, XX
, XX
},
791 { "stc", XX
, XX
, XX
},
792 { "cli", XX
, XX
, XX
},
793 { "sti", XX
, XX
, XX
},
794 { "cld", XX
, XX
, XX
},
795 { "std", XX
, XX
, XX
},
800 static const struct dis386 dis386_twobyte
[] = {
804 { "larS", Gv
, Ew
, XX
},
805 { "lslS", Gv
, Ew
, XX
},
806 { "(bad)", XX
, XX
, XX
},
807 { "syscall", XX
, XX
, XX
},
808 { "clts", XX
, XX
, XX
},
809 { "sysretP", XX
, XX
, XX
},
811 { "invd", XX
, XX
, XX
},
812 { "wbinvd", XX
, XX
, XX
},
813 { "(bad)", XX
, XX
, XX
},
814 { "ud2a", XX
, XX
, XX
},
815 { "(bad)", XX
, XX
, XX
},
817 { "femms", XX
, XX
, XX
},
818 { "", MX
, EM
, OPSUF
}, /* See OP_3DNowSuffix. */
823 { "movlpX", EX
, XM
, SIMD_Fixup
, 'h' },
824 { "unpcklpX", XM
, EX
, XX
},
825 { "unpckhpX", XM
, EX
, XX
},
827 { "movhpX", EX
, XM
, SIMD_Fixup
, 'l' },
830 { "(bad)", XX
, XX
, XX
},
831 { "(bad)", XX
, XX
, XX
},
832 { "(bad)", XX
, XX
, XX
},
833 { "(bad)", XX
, XX
, XX
},
834 { "(bad)", XX
, XX
, XX
},
835 { "(bad)", XX
, XX
, XX
},
836 { "(bad)", XX
, XX
, XX
},
838 { "movZ", Rm
, Cm
, XX
},
839 { "movZ", Rm
, Dm
, XX
},
840 { "movZ", Cm
, Rm
, XX
},
841 { "movZ", Dm
, Rm
, XX
},
842 { "movL", Rd
, Td
, XX
},
843 { "(bad)", XX
, XX
, XX
},
844 { "movL", Td
, Rd
, XX
},
845 { "(bad)", XX
, XX
, XX
},
847 { "movapX", XM
, EX
, XX
},
848 { "movapX", EX
, XM
, XX
},
850 { "movntpX", Ev
, XM
, XX
},
853 { "ucomisX", XM
,EX
, XX
},
854 { "comisX", XM
,EX
, XX
},
856 { "wrmsr", XX
, XX
, XX
},
857 { "rdtsc", XX
, XX
, XX
},
858 { "rdmsr", XX
, XX
, XX
},
859 { "rdpmc", XX
, XX
, XX
},
860 { "sysenter", XX
, XX
, XX
},
861 { "sysexit", XX
, XX
, XX
},
862 { "(bad)", XX
, XX
, XX
},
863 { "(bad)", XX
, XX
, XX
},
866 { "(bad)", XX
, XX
, XX
},
868 { "(bad)", XX
, XX
, XX
},
869 { "(bad)", XX
, XX
, XX
},
870 { "(bad)", XX
, XX
, XX
},
871 { "(bad)", XX
, XX
, XX
},
872 { "(bad)", XX
, XX
, XX
},
874 { "cmovo", Gv
, Ev
, XX
},
875 { "cmovno", Gv
, Ev
, XX
},
876 { "cmovb", Gv
, Ev
, XX
},
877 { "cmovae", Gv
, Ev
, XX
},
878 { "cmove", Gv
, Ev
, XX
},
879 { "cmovne", Gv
, Ev
, XX
},
880 { "cmovbe", Gv
, Ev
, XX
},
881 { "cmova", Gv
, Ev
, XX
},
883 { "cmovs", Gv
, Ev
, XX
},
884 { "cmovns", Gv
, Ev
, XX
},
885 { "cmovp", Gv
, Ev
, XX
},
886 { "cmovnp", Gv
, Ev
, XX
},
887 { "cmovl", Gv
, Ev
, XX
},
888 { "cmovge", Gv
, Ev
, XX
},
889 { "cmovle", Gv
, Ev
, XX
},
890 { "cmovg", Gv
, Ev
, XX
},
892 { "movmskpX", Gdq
, XS
, XX
},
896 { "andpX", XM
, EX
, XX
},
897 { "andnpX", XM
, EX
, XX
},
898 { "orpX", XM
, EX
, XX
},
899 { "xorpX", XM
, EX
, XX
},
910 { "punpcklbw", MX
, EM
, XX
},
911 { "punpcklwd", MX
, EM
, XX
},
912 { "punpckldq", MX
, EM
, XX
},
913 { "packsswb", MX
, EM
, XX
},
914 { "pcmpgtb", MX
, EM
, XX
},
915 { "pcmpgtw", MX
, EM
, XX
},
916 { "pcmpgtd", MX
, EM
, XX
},
917 { "packuswb", MX
, EM
, XX
},
919 { "punpckhbw", MX
, EM
, XX
},
920 { "punpckhwd", MX
, EM
, XX
},
921 { "punpckhdq", MX
, EM
, XX
},
922 { "packssdw", MX
, EM
, XX
},
925 { "movd", MX
, Edq
, XX
},
932 { "pcmpeqb", MX
, EM
, XX
},
933 { "pcmpeqw", MX
, EM
, XX
},
934 { "pcmpeqd", MX
, EM
, XX
},
935 { "emms", XX
, XX
, XX
},
937 { "vmread", Em
, Gm
, XX
},
938 { "vmwrite", Gm
, Em
, XX
},
939 { "(bad)", XX
, XX
, XX
},
940 { "(bad)", XX
, XX
, XX
},
946 { "joH", Jv
, XX
, cond_jump_flag
},
947 { "jnoH", Jv
, XX
, cond_jump_flag
},
948 { "jbH", Jv
, XX
, cond_jump_flag
},
949 { "jaeH", Jv
, XX
, cond_jump_flag
},
950 { "jeH", Jv
, XX
, cond_jump_flag
},
951 { "jneH", Jv
, XX
, cond_jump_flag
},
952 { "jbeH", Jv
, XX
, cond_jump_flag
},
953 { "jaH", Jv
, XX
, cond_jump_flag
},
955 { "jsH", Jv
, XX
, cond_jump_flag
},
956 { "jnsH", Jv
, XX
, cond_jump_flag
},
957 { "jpH", Jv
, XX
, cond_jump_flag
},
958 { "jnpH", Jv
, XX
, cond_jump_flag
},
959 { "jlH", Jv
, XX
, cond_jump_flag
},
960 { "jgeH", Jv
, XX
, cond_jump_flag
},
961 { "jleH", Jv
, XX
, cond_jump_flag
},
962 { "jgH", Jv
, XX
, cond_jump_flag
},
964 { "seto", Eb
, XX
, XX
},
965 { "setno", Eb
, XX
, XX
},
966 { "setb", Eb
, XX
, XX
},
967 { "setae", Eb
, XX
, XX
},
968 { "sete", Eb
, XX
, XX
},
969 { "setne", Eb
, XX
, XX
},
970 { "setbe", Eb
, XX
, XX
},
971 { "seta", Eb
, XX
, XX
},
973 { "sets", Eb
, XX
, XX
},
974 { "setns", Eb
, XX
, XX
},
975 { "setp", Eb
, XX
, XX
},
976 { "setnp", Eb
, XX
, XX
},
977 { "setl", Eb
, XX
, XX
},
978 { "setge", Eb
, XX
, XX
},
979 { "setle", Eb
, XX
, XX
},
980 { "setg", Eb
, XX
, XX
},
982 { "pushT", fs
, XX
, XX
},
983 { "popT", fs
, XX
, XX
},
984 { "cpuid", XX
, XX
, XX
},
985 { "btS", Ev
, Gv
, XX
},
986 { "shldS", Ev
, Gv
, Ib
},
987 { "shldS", Ev
, Gv
, CL
},
991 { "pushT", gs
, XX
, XX
},
992 { "popT", gs
, XX
, XX
},
993 { "rsm", XX
, XX
, XX
},
994 { "btsS", Ev
, Gv
, XX
},
995 { "shrdS", Ev
, Gv
, Ib
},
996 { "shrdS", Ev
, Gv
, CL
},
998 { "imulS", Gv
, Ev
, XX
},
1000 { "cmpxchgB", Eb
, Gb
, XX
},
1001 { "cmpxchgS", Ev
, Gv
, XX
},
1002 { "lssS", Gv
, Mp
, XX
},
1003 { "btrS", Ev
, Gv
, XX
},
1004 { "lfsS", Gv
, Mp
, XX
},
1005 { "lgsS", Gv
, Mp
, XX
},
1006 { "movz{bR|x|bR|x}", Gv
, Eb
, XX
},
1007 { "movz{wR|x|wR|x}", Gv
, Ew
, XX
}, /* yes, there really is movzww ! */
1009 { "(bad)", XX
, XX
, XX
},
1010 { "ud2b", XX
, XX
, XX
},
1012 { "btcS", Ev
, Gv
, XX
},
1013 { "bsfS", Gv
, Ev
, XX
},
1014 { "bsrS", Gv
, Ev
, XX
},
1015 { "movs{bR|x|bR|x}", Gv
, Eb
, XX
},
1016 { "movs{wR|x|wR|x}", Gv
, Ew
, XX
}, /* yes, there really is movsww ! */
1018 { "xaddB", Eb
, Gb
, XX
},
1019 { "xaddS", Ev
, Gv
, XX
},
1021 { "movntiS", Ev
, Gv
, XX
},
1022 { "pinsrw", MX
, Edqw
, Ib
},
1023 { "pextrw", Gdq
, MS
, Ib
},
1024 { "shufpX", XM
, EX
, Ib
},
1027 { "bswap", RMeAX
, XX
, XX
},
1028 { "bswap", RMeCX
, XX
, XX
},
1029 { "bswap", RMeDX
, XX
, XX
},
1030 { "bswap", RMeBX
, XX
, XX
},
1031 { "bswap", RMeSP
, XX
, XX
},
1032 { "bswap", RMeBP
, XX
, XX
},
1033 { "bswap", RMeSI
, XX
, XX
},
1034 { "bswap", RMeDI
, XX
, XX
},
1037 { "psrlw", MX
, EM
, XX
},
1038 { "psrld", MX
, EM
, XX
},
1039 { "psrlq", MX
, EM
, XX
},
1040 { "paddq", MX
, EM
, XX
},
1041 { "pmullw", MX
, EM
, XX
},
1043 { "pmovmskb", Gdq
, MS
, XX
},
1045 { "psubusb", MX
, EM
, XX
},
1046 { "psubusw", MX
, EM
, XX
},
1047 { "pminub", MX
, EM
, XX
},
1048 { "pand", MX
, EM
, XX
},
1049 { "paddusb", MX
, EM
, XX
},
1050 { "paddusw", MX
, EM
, XX
},
1051 { "pmaxub", MX
, EM
, XX
},
1052 { "pandn", MX
, EM
, XX
},
1054 { "pavgb", MX
, EM
, XX
},
1055 { "psraw", MX
, EM
, XX
},
1056 { "psrad", MX
, EM
, XX
},
1057 { "pavgw", MX
, EM
, XX
},
1058 { "pmulhuw", MX
, EM
, XX
},
1059 { "pmulhw", MX
, EM
, XX
},
1063 { "psubsb", MX
, EM
, XX
},
1064 { "psubsw", MX
, EM
, XX
},
1065 { "pminsw", MX
, EM
, XX
},
1066 { "por", MX
, EM
, XX
},
1067 { "paddsb", MX
, EM
, XX
},
1068 { "paddsw", MX
, EM
, XX
},
1069 { "pmaxsw", MX
, EM
, XX
},
1070 { "pxor", MX
, EM
, XX
},
1073 { "psllw", MX
, EM
, XX
},
1074 { "pslld", MX
, EM
, XX
},
1075 { "psllq", MX
, EM
, XX
},
1076 { "pmuludq", MX
, EM
, XX
},
1077 { "pmaddwd", MX
, EM
, XX
},
1078 { "psadbw", MX
, EM
, XX
},
1081 { "psubb", MX
, EM
, XX
},
1082 { "psubw", MX
, EM
, XX
},
1083 { "psubd", MX
, EM
, XX
},
1084 { "psubq", MX
, EM
, XX
},
1085 { "paddb", MX
, EM
, XX
},
1086 { "paddw", MX
, EM
, XX
},
1087 { "paddd", MX
, EM
, XX
},
1088 { "(bad)", XX
, XX
, XX
}
1091 static const unsigned char onebyte_has_modrm
[256] = {
1092 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1093 /* ------------------------------- */
1094 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1095 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1096 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1097 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1098 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1099 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1100 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1101 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1102 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1103 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1104 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1105 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1106 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1107 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1108 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1109 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1110 /* ------------------------------- */
1111 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1114 static const unsigned char twobyte_has_modrm
[256] = {
1115 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1116 /* ------------------------------- */
1117 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1118 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1119 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1120 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1121 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1122 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1123 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1124 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1125 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1126 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1127 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1128 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1129 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1130 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1131 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1132 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1133 /* ------------------------------- */
1134 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1137 static const unsigned char twobyte_uses_SSE_prefix
[256] = {
1138 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1139 /* ------------------------------- */
1140 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1141 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1142 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1143 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1144 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1145 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1146 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1147 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */
1148 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1149 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1150 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1151 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1152 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1153 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1154 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1155 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1156 /* ------------------------------- */
1157 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1160 static char obuf
[100];
1162 static char scratchbuf
[100];
1163 static unsigned char *start_codep
;
1164 static unsigned char *insn_codep
;
1165 static unsigned char *codep
;
1166 static disassemble_info
*the_info
;
1170 static unsigned char need_modrm
;
1172 /* If we are accessing mod/rm/reg without need_modrm set, then the
1173 values are stale. Hitting this abort likely indicates that you
1174 need to update onebyte_has_modrm or twobyte_has_modrm. */
1175 #define MODRM_CHECK if (!need_modrm) abort ()
1177 static const char **names64
;
1178 static const char **names32
;
1179 static const char **names16
;
1180 static const char **names8
;
1181 static const char **names8rex
;
1182 static const char **names_seg
;
1183 static const char **index16
;
1185 static const char *intel_names64
[] = {
1186 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1187 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1189 static const char *intel_names32
[] = {
1190 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1191 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1193 static const char *intel_names16
[] = {
1194 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1195 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1197 static const char *intel_names8
[] = {
1198 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1200 static const char *intel_names8rex
[] = {
1201 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1202 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1204 static const char *intel_names_seg
[] = {
1205 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1207 static const char *intel_index16
[] = {
1208 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1211 static const char *att_names64
[] = {
1212 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1213 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1215 static const char *att_names32
[] = {
1216 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1217 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1219 static const char *att_names16
[] = {
1220 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1221 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1223 static const char *att_names8
[] = {
1224 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1226 static const char *att_names8rex
[] = {
1227 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1228 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1230 static const char *att_names_seg
[] = {
1231 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1233 static const char *att_index16
[] = {
1234 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1237 static const struct dis386 grps
[][8] = {
1240 { "addA", Eb
, Ib
, XX
},
1241 { "orA", Eb
, Ib
, XX
},
1242 { "adcA", Eb
, Ib
, XX
},
1243 { "sbbA", Eb
, Ib
, XX
},
1244 { "andA", Eb
, Ib
, XX
},
1245 { "subA", Eb
, Ib
, XX
},
1246 { "xorA", Eb
, Ib
, XX
},
1247 { "cmpA", Eb
, Ib
, XX
}
1251 { "addQ", Ev
, Iv
, XX
},
1252 { "orQ", Ev
, Iv
, XX
},
1253 { "adcQ", Ev
, Iv
, XX
},
1254 { "sbbQ", Ev
, Iv
, XX
},
1255 { "andQ", Ev
, Iv
, XX
},
1256 { "subQ", Ev
, Iv
, XX
},
1257 { "xorQ", Ev
, Iv
, XX
},
1258 { "cmpQ", Ev
, Iv
, XX
}
1262 { "addQ", Ev
, sIb
, XX
},
1263 { "orQ", Ev
, sIb
, XX
},
1264 { "adcQ", Ev
, sIb
, XX
},
1265 { "sbbQ", Ev
, sIb
, XX
},
1266 { "andQ", Ev
, sIb
, XX
},
1267 { "subQ", Ev
, sIb
, XX
},
1268 { "xorQ", Ev
, sIb
, XX
},
1269 { "cmpQ", Ev
, sIb
, XX
}
1273 { "rolA", Eb
, Ib
, XX
},
1274 { "rorA", Eb
, Ib
, XX
},
1275 { "rclA", Eb
, Ib
, XX
},
1276 { "rcrA", Eb
, Ib
, XX
},
1277 { "shlA", Eb
, Ib
, XX
},
1278 { "shrA", Eb
, Ib
, XX
},
1279 { "(bad)", XX
, XX
, XX
},
1280 { "sarA", Eb
, Ib
, XX
},
1284 { "rolQ", Ev
, Ib
, XX
},
1285 { "rorQ", Ev
, Ib
, XX
},
1286 { "rclQ", Ev
, Ib
, XX
},
1287 { "rcrQ", Ev
, Ib
, XX
},
1288 { "shlQ", Ev
, Ib
, XX
},
1289 { "shrQ", Ev
, Ib
, XX
},
1290 { "(bad)", XX
, XX
, XX
},
1291 { "sarQ", Ev
, Ib
, XX
},
1295 { "rolA", Eb
, I1
, XX
},
1296 { "rorA", Eb
, I1
, XX
},
1297 { "rclA", Eb
, I1
, XX
},
1298 { "rcrA", Eb
, I1
, XX
},
1299 { "shlA", Eb
, I1
, XX
},
1300 { "shrA", Eb
, I1
, XX
},
1301 { "(bad)", XX
, XX
, XX
},
1302 { "sarA", Eb
, I1
, XX
},
1306 { "rolQ", Ev
, I1
, XX
},
1307 { "rorQ", Ev
, I1
, XX
},
1308 { "rclQ", Ev
, I1
, XX
},
1309 { "rcrQ", Ev
, I1
, XX
},
1310 { "shlQ", Ev
, I1
, XX
},
1311 { "shrQ", Ev
, I1
, XX
},
1312 { "(bad)", XX
, XX
, XX
},
1313 { "sarQ", Ev
, I1
, XX
},
1317 { "rolA", Eb
, CL
, XX
},
1318 { "rorA", Eb
, CL
, XX
},
1319 { "rclA", Eb
, CL
, XX
},
1320 { "rcrA", Eb
, CL
, XX
},
1321 { "shlA", Eb
, CL
, XX
},
1322 { "shrA", Eb
, CL
, XX
},
1323 { "(bad)", XX
, XX
, XX
},
1324 { "sarA", Eb
, CL
, XX
},
1328 { "rolQ", Ev
, CL
, XX
},
1329 { "rorQ", Ev
, CL
, XX
},
1330 { "rclQ", Ev
, CL
, XX
},
1331 { "rcrQ", Ev
, CL
, XX
},
1332 { "shlQ", Ev
, CL
, XX
},
1333 { "shrQ", Ev
, CL
, XX
},
1334 { "(bad)", XX
, XX
, XX
},
1335 { "sarQ", Ev
, CL
, XX
}
1339 { "testA", Eb
, Ib
, XX
},
1340 { "(bad)", Eb
, XX
, XX
},
1341 { "notA", Eb
, XX
, XX
},
1342 { "negA", Eb
, XX
, XX
},
1343 { "mulA", Eb
, XX
, XX
}, /* Don't print the implicit %al register, */
1344 { "imulA", Eb
, XX
, XX
}, /* to distinguish these opcodes from other */
1345 { "divA", Eb
, XX
, XX
}, /* mul/imul opcodes. Do the same for div */
1346 { "idivA", Eb
, XX
, XX
} /* and idiv for consistency. */
1350 { "testQ", Ev
, Iv
, XX
},
1351 { "(bad)", XX
, XX
, XX
},
1352 { "notQ", Ev
, XX
, XX
},
1353 { "negQ", Ev
, XX
, XX
},
1354 { "mulQ", Ev
, XX
, XX
}, /* Don't print the implicit register. */
1355 { "imulQ", Ev
, XX
, XX
},
1356 { "divQ", Ev
, XX
, XX
},
1357 { "idivQ", Ev
, XX
, XX
},
1361 { "incA", Eb
, XX
, XX
},
1362 { "decA", Eb
, XX
, XX
},
1363 { "(bad)", XX
, XX
, XX
},
1364 { "(bad)", XX
, XX
, XX
},
1365 { "(bad)", XX
, XX
, XX
},
1366 { "(bad)", XX
, XX
, XX
},
1367 { "(bad)", XX
, XX
, XX
},
1368 { "(bad)", XX
, XX
, XX
},
1372 { "incQ", Ev
, XX
, XX
},
1373 { "decQ", Ev
, XX
, XX
},
1374 { "callT", indirEv
, XX
, XX
},
1375 { "JcallT", indirEp
, XX
, XX
},
1376 { "jmpT", indirEv
, XX
, XX
},
1377 { "JjmpT", indirEp
, XX
, XX
},
1378 { "pushU", stackEv
, XX
, XX
},
1379 { "(bad)", XX
, XX
, XX
},
1383 { "sldtQ", Ev
, XX
, XX
},
1384 { "strQ", Ev
, XX
, XX
},
1385 { "lldt", Ew
, XX
, XX
},
1386 { "ltr", Ew
, XX
, XX
},
1387 { "verr", Ew
, XX
, XX
},
1388 { "verw", Ew
, XX
, XX
},
1389 { "(bad)", XX
, XX
, XX
},
1390 { "(bad)", XX
, XX
, XX
}
1394 { "sgdtIQ", VMX_Fixup
, 0, XX
, XX
},
1395 { "sidtIQ", PNI_Fixup
, 0, XX
, XX
},
1396 { "lgdt{Q|Q||}", M
, XX
, XX
},
1397 { "lidt{Q|Q||}", SVME_Fixup
, 0, XX
, XX
},
1398 { "smswQ", Ev
, XX
, XX
},
1399 { "(bad)", XX
, XX
, XX
},
1400 { "lmsw", Ew
, XX
, XX
},
1401 { "invlpg", INVLPG_Fixup
, w_mode
, XX
, XX
},
1405 { "(bad)", XX
, XX
, XX
},
1406 { "(bad)", XX
, XX
, XX
},
1407 { "(bad)", XX
, XX
, XX
},
1408 { "(bad)", XX
, XX
, XX
},
1409 { "btQ", Ev
, Ib
, XX
},
1410 { "btsQ", Ev
, Ib
, XX
},
1411 { "btrQ", Ev
, Ib
, XX
},
1412 { "btcQ", Ev
, Ib
, XX
},
1416 { "(bad)", XX
, XX
, XX
},
1417 { "cmpxchg8b", Eq
, XX
, XX
},
1418 { "(bad)", XX
, XX
, XX
},
1419 { "(bad)", XX
, XX
, XX
},
1420 { "(bad)", XX
, XX
, XX
},
1421 { "(bad)", XX
, XX
, XX
},
1422 { "", VM
, XX
, XX
}, /* See OP_VMX. */
1423 { "vmptrst", Eq
, XX
, XX
},
1427 { "(bad)", XX
, XX
, XX
},
1428 { "(bad)", XX
, XX
, XX
},
1429 { "psrlw", MS
, Ib
, XX
},
1430 { "(bad)", XX
, XX
, XX
},
1431 { "psraw", MS
, Ib
, XX
},
1432 { "(bad)", XX
, XX
, XX
},
1433 { "psllw", MS
, Ib
, XX
},
1434 { "(bad)", XX
, XX
, XX
},
1438 { "(bad)", XX
, XX
, XX
},
1439 { "(bad)", XX
, XX
, XX
},
1440 { "psrld", MS
, Ib
, XX
},
1441 { "(bad)", XX
, XX
, XX
},
1442 { "psrad", MS
, Ib
, XX
},
1443 { "(bad)", XX
, XX
, XX
},
1444 { "pslld", MS
, Ib
, XX
},
1445 { "(bad)", XX
, XX
, XX
},
1449 { "(bad)", XX
, XX
, XX
},
1450 { "(bad)", XX
, XX
, XX
},
1451 { "psrlq", MS
, Ib
, XX
},
1452 { "psrldq", MS
, Ib
, XX
},
1453 { "(bad)", XX
, XX
, XX
},
1454 { "(bad)", XX
, XX
, XX
},
1455 { "psllq", MS
, Ib
, XX
},
1456 { "pslldq", MS
, Ib
, XX
},
1460 { "fxsave", Ev
, XX
, XX
},
1461 { "fxrstor", Ev
, XX
, XX
},
1462 { "ldmxcsr", Ev
, XX
, XX
},
1463 { "stmxcsr", Ev
, XX
, XX
},
1464 { "(bad)", XX
, XX
, XX
},
1465 { "lfence", OP_0fae
, 0, XX
, XX
},
1466 { "mfence", OP_0fae
, 0, XX
, XX
},
1467 { "clflush", OP_0fae
, 0, XX
, XX
},
1471 { "prefetchnta", Ev
, XX
, XX
},
1472 { "prefetcht0", Ev
, XX
, XX
},
1473 { "prefetcht1", Ev
, XX
, XX
},
1474 { "prefetcht2", Ev
, XX
, XX
},
1475 { "(bad)", XX
, XX
, XX
},
1476 { "(bad)", XX
, XX
, XX
},
1477 { "(bad)", XX
, XX
, XX
},
1478 { "(bad)", XX
, XX
, XX
},
1482 { "prefetch", Eb
, XX
, XX
},
1483 { "prefetchw", Eb
, XX
, XX
},
1484 { "(bad)", XX
, XX
, XX
},
1485 { "(bad)", XX
, XX
, XX
},
1486 { "(bad)", XX
, XX
, XX
},
1487 { "(bad)", XX
, XX
, XX
},
1488 { "(bad)", XX
, XX
, XX
},
1489 { "(bad)", XX
, XX
, XX
},
1493 { "xstore-rng", OP_0f07
, 0, XX
, XX
},
1494 { "xcrypt-ecb", OP_0f07
, 0, XX
, XX
},
1495 { "xcrypt-cbc", OP_0f07
, 0, XX
, XX
},
1496 { "xcrypt-ctr", OP_0f07
, 0, XX
, XX
},
1497 { "xcrypt-cfb", OP_0f07
, 0, XX
, XX
},
1498 { "xcrypt-ofb", OP_0f07
, 0, XX
, XX
},
1499 { "(bad)", OP_0f07
, 0, XX
, XX
},
1500 { "(bad)", OP_0f07
, 0, XX
, XX
},
1504 { "montmul", OP_0f07
, 0, XX
, XX
},
1505 { "xsha1", OP_0f07
, 0, XX
, XX
},
1506 { "xsha256", OP_0f07
, 0, XX
, XX
},
1507 { "(bad)", OP_0f07
, 0, XX
, XX
},
1508 { "(bad)", OP_0f07
, 0, XX
, XX
},
1509 { "(bad)", OP_0f07
, 0, XX
, XX
},
1510 { "(bad)", OP_0f07
, 0, XX
, XX
},
1511 { "(bad)", OP_0f07
, 0, XX
, XX
},
1515 static const struct dis386 prefix_user_table
[][4] = {
1518 { "addps", XM
, EX
, XX
},
1519 { "addss", XM
, EX
, XX
},
1520 { "addpd", XM
, EX
, XX
},
1521 { "addsd", XM
, EX
, XX
},
1525 { "", XM
, EX
, OPSIMD
}, /* See OP_SIMD_SUFFIX. */
1526 { "", XM
, EX
, OPSIMD
},
1527 { "", XM
, EX
, OPSIMD
},
1528 { "", XM
, EX
, OPSIMD
},
1532 { "cvtpi2ps", XM
, EM
, XX
},
1533 { "cvtsi2ssY", XM
, Ev
, XX
},
1534 { "cvtpi2pd", XM
, EM
, XX
},
1535 { "cvtsi2sdY", XM
, Ev
, XX
},
1539 { "cvtps2pi", MX
, EX
, XX
},
1540 { "cvtss2siY", Gv
, EX
, XX
},
1541 { "cvtpd2pi", MX
, EX
, XX
},
1542 { "cvtsd2siY", Gv
, EX
, XX
},
1546 { "cvttps2pi", MX
, EX
, XX
},
1547 { "cvttss2siY", Gv
, EX
, XX
},
1548 { "cvttpd2pi", MX
, EX
, XX
},
1549 { "cvttsd2siY", Gv
, EX
, XX
},
1553 { "divps", XM
, EX
, XX
},
1554 { "divss", XM
, EX
, XX
},
1555 { "divpd", XM
, EX
, XX
},
1556 { "divsd", XM
, EX
, XX
},
1560 { "maxps", XM
, EX
, XX
},
1561 { "maxss", XM
, EX
, XX
},
1562 { "maxpd", XM
, EX
, XX
},
1563 { "maxsd", XM
, EX
, XX
},
1567 { "minps", XM
, EX
, XX
},
1568 { "minss", XM
, EX
, XX
},
1569 { "minpd", XM
, EX
, XX
},
1570 { "minsd", XM
, EX
, XX
},
1574 { "movups", XM
, EX
, XX
},
1575 { "movss", XM
, EX
, XX
},
1576 { "movupd", XM
, EX
, XX
},
1577 { "movsd", XM
, EX
, XX
},
1581 { "movups", EX
, XM
, XX
},
1582 { "movss", EX
, XM
, XX
},
1583 { "movupd", EX
, XM
, XX
},
1584 { "movsd", EX
, XM
, XX
},
1588 { "mulps", XM
, EX
, XX
},
1589 { "mulss", XM
, EX
, XX
},
1590 { "mulpd", XM
, EX
, XX
},
1591 { "mulsd", XM
, EX
, XX
},
1595 { "rcpps", XM
, EX
, XX
},
1596 { "rcpss", XM
, EX
, XX
},
1597 { "(bad)", XM
, EX
, XX
},
1598 { "(bad)", XM
, EX
, XX
},
1602 { "rsqrtps", XM
, EX
, XX
},
1603 { "rsqrtss", XM
, EX
, XX
},
1604 { "(bad)", XM
, EX
, XX
},
1605 { "(bad)", XM
, EX
, XX
},
1609 { "sqrtps", XM
, EX
, XX
},
1610 { "sqrtss", XM
, EX
, XX
},
1611 { "sqrtpd", XM
, EX
, XX
},
1612 { "sqrtsd", XM
, EX
, XX
},
1616 { "subps", XM
, EX
, XX
},
1617 { "subss", XM
, EX
, XX
},
1618 { "subpd", XM
, EX
, XX
},
1619 { "subsd", XM
, EX
, XX
},
1623 { "(bad)", XM
, EX
, XX
},
1624 { "cvtdq2pd", XM
, EX
, XX
},
1625 { "cvttpd2dq", XM
, EX
, XX
},
1626 { "cvtpd2dq", XM
, EX
, XX
},
1630 { "cvtdq2ps", XM
, EX
, XX
},
1631 { "cvttps2dq",XM
, EX
, XX
},
1632 { "cvtps2dq",XM
, EX
, XX
},
1633 { "(bad)", XM
, EX
, XX
},
1637 { "cvtps2pd", XM
, EX
, XX
},
1638 { "cvtss2sd", XM
, EX
, XX
},
1639 { "cvtpd2ps", XM
, EX
, XX
},
1640 { "cvtsd2ss", XM
, EX
, XX
},
1644 { "maskmovq", MX
, MS
, XX
},
1645 { "(bad)", XM
, EX
, XX
},
1646 { "maskmovdqu", XM
, EX
, XX
},
1647 { "(bad)", XM
, EX
, XX
},
1651 { "movq", MX
, EM
, XX
},
1652 { "movdqu", XM
, EX
, XX
},
1653 { "movdqa", XM
, EX
, XX
},
1654 { "(bad)", XM
, EX
, XX
},
1658 { "movq", EM
, MX
, XX
},
1659 { "movdqu", EX
, XM
, XX
},
1660 { "movdqa", EX
, XM
, XX
},
1661 { "(bad)", EX
, XM
, XX
},
1665 { "(bad)", EX
, XM
, XX
},
1666 { "movq2dq", XM
, MS
, XX
},
1667 { "movq", EX
, XM
, XX
},
1668 { "movdq2q", MX
, XS
, XX
},
1672 { "pshufw", MX
, EM
, Ib
},
1673 { "pshufhw", XM
, EX
, Ib
},
1674 { "pshufd", XM
, EX
, Ib
},
1675 { "pshuflw", XM
, EX
, Ib
},
1679 { "movd", Edq
, MX
, XX
},
1680 { "movq", XM
, EX
, XX
},
1681 { "movd", Edq
, XM
, XX
},
1682 { "(bad)", Ed
, XM
, XX
},
1686 { "(bad)", MX
, EX
, XX
},
1687 { "(bad)", XM
, EX
, XX
},
1688 { "punpckhqdq", XM
, EX
, XX
},
1689 { "(bad)", XM
, EX
, XX
},
1693 { "movntq", EM
, MX
, XX
},
1694 { "(bad)", EM
, XM
, XX
},
1695 { "movntdq", EM
, XM
, XX
},
1696 { "(bad)", EM
, XM
, XX
},
1700 { "(bad)", MX
, EX
, XX
},
1701 { "(bad)", XM
, EX
, XX
},
1702 { "punpcklqdq", XM
, EX
, XX
},
1703 { "(bad)", XM
, EX
, XX
},
1707 { "(bad)", MX
, EX
, XX
},
1708 { "(bad)", XM
, EX
, XX
},
1709 { "addsubpd", XM
, EX
, XX
},
1710 { "addsubps", XM
, EX
, XX
},
1714 { "(bad)", MX
, EX
, XX
},
1715 { "(bad)", XM
, EX
, XX
},
1716 { "haddpd", XM
, EX
, XX
},
1717 { "haddps", XM
, EX
, XX
},
1721 { "(bad)", MX
, EX
, XX
},
1722 { "(bad)", XM
, EX
, XX
},
1723 { "hsubpd", XM
, EX
, XX
},
1724 { "hsubps", XM
, EX
, XX
},
1728 { "movlpX", XM
, EX
, SIMD_Fixup
, 'h' }, /* really only 2 operands */
1729 { "movsldup", XM
, EX
, XX
},
1730 { "movlpd", XM
, EX
, XX
},
1731 { "movddup", XM
, EX
, XX
},
1735 { "movhpX", XM
, EX
, SIMD_Fixup
, 'l' },
1736 { "movshdup", XM
, EX
, XX
},
1737 { "movhpd", XM
, EX
, XX
},
1738 { "(bad)", XM
, EX
, XX
},
1742 { "(bad)", XM
, EX
, XX
},
1743 { "(bad)", XM
, EX
, XX
},
1744 { "(bad)", XM
, EX
, XX
},
1745 { "lddqu", XM
, M
, XX
},
1749 static const struct dis386 x86_64_table
[][2] = {
1751 { "arpl", Ew
, Gw
, XX
},
1752 { "movs{||lq|xd}", Gv
, Ed
, XX
},
1756 static const struct dis386 three_byte_table
[][32] = {
1759 { "pshufb", MX
, EM
, XX
},
1760 { "phaddw", MX
, EM
, XX
},
1761 { "phaddd", MX
, EM
, XX
},
1762 { "phaddsw", MX
, EM
, XX
},
1763 { "pmaddubsw", MX
, EM
, XX
},
1764 { "phsubw", MX
, EM
, XX
},
1765 { "phsubd", MX
, EM
, XX
},
1766 { "phsubsw", MX
, EM
, XX
},
1767 { "psignb", MX
, EM
, XX
},
1768 { "psignw", MX
, EM
, XX
},
1769 { "psignd", MX
, EM
, XX
},
1770 { "pmulhrsw", MX
, EM
, XX
},
1771 { "(bad)", XX
, XX
, XX
},
1772 { "(bad)", XX
, XX
, XX
},
1773 { "(bad)", XX
, XX
, XX
},
1774 { "(bad)", XX
, XX
, XX
},
1775 { "(bad)", XX
, XX
, XX
},
1776 { "(bad)", XX
, XX
, XX
},
1777 { "(bad)", XX
, XX
, XX
},
1778 { "(bad)", XX
, XX
, XX
},
1779 { "(bad)", XX
, XX
, 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 { "pabsb", MX
, EM
, XX
},
1788 { "pabsw", MX
, EM
, XX
},
1789 { "pabsd", MX
, EM
, XX
},
1790 { "(bad)", XX
, XX
, XX
}
1794 { "(bad)", XX
, XX
, XX
},
1795 { "(bad)", XX
, XX
, XX
},
1796 { "(bad)", XX
, XX
, XX
},
1797 { "(bad)", XX
, XX
, XX
},
1798 { "(bad)", XX
, XX
, XX
},
1799 { "(bad)", XX
, XX
, XX
},
1800 { "(bad)", XX
, XX
, XX
},
1801 { "(bad)", XX
, XX
, XX
},
1802 { "(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 { "palignr", MX
, EM
, Ib
},
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 { "(bad)", XX
, XX
, XX
},
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
}
1829 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1841 FETCH_DATA (the_info
, codep
+ 1);
1845 /* REX prefixes family. */
1862 if (address_mode
== mode_64bit
)
1868 prefixes
|= PREFIX_REPZ
;
1871 prefixes
|= PREFIX_REPNZ
;
1874 prefixes
|= PREFIX_LOCK
;
1877 prefixes
|= PREFIX_CS
;
1880 prefixes
|= PREFIX_SS
;
1883 prefixes
|= PREFIX_DS
;
1886 prefixes
|= PREFIX_ES
;
1889 prefixes
|= PREFIX_FS
;
1892 prefixes
|= PREFIX_GS
;
1895 prefixes
|= PREFIX_DATA
;
1898 prefixes
|= PREFIX_ADDR
;
1901 /* fwait is really an instruction. If there are prefixes
1902 before the fwait, they belong to the fwait, *not* to the
1903 following instruction. */
1904 if (prefixes
|| rex
)
1906 prefixes
|= PREFIX_FWAIT
;
1910 prefixes
= PREFIX_FWAIT
;
1915 /* Rex is ignored when followed by another prefix. */
1926 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
1930 prefix_name (int pref
, int sizeflag
)
1934 /* REX prefixes family. */
1986 return (sizeflag
& DFLAG
) ? "data16" : "data32";
1988 if (address_mode
== mode_64bit
)
1989 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
1991 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
1999 static char op1out
[100], op2out
[100], op3out
[100];
2000 static int op_ad
, op_index
[3];
2001 static int two_source_ops
;
2002 static bfd_vma op_address
[3];
2003 static bfd_vma op_riprel
[3];
2004 static bfd_vma start_pc
;
2007 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
2008 * (see topic "Redundant prefixes" in the "Differences from 8086"
2009 * section of the "Virtual 8086 Mode" chapter.)
2010 * 'pc' should be the address of this instruction, it will
2011 * be used to print the target address if this is a relative jump or call
2012 * The function returns the length of this instruction in bytes.
2015 static char intel_syntax
;
2016 static char open_char
;
2017 static char close_char
;
2018 static char separator_char
;
2019 static char scale_char
;
2021 /* Here for backwards compatibility. When gdb stops using
2022 print_insn_i386_att and print_insn_i386_intel these functions can
2023 disappear, and print_insn_i386 be merged into print_insn. */
2025 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
2029 return print_insn (pc
, info
);
2033 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
2037 return print_insn (pc
, info
);
2041 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
2045 return print_insn (pc
, info
);
2049 print_insn (bfd_vma pc
, disassemble_info
*info
)
2051 const struct dis386
*dp
;
2053 char *first
, *second
, *third
;
2055 unsigned char uses_SSE_prefix
, uses_LOCK_prefix
;
2058 struct dis_private priv
;
2060 if (info
->mach
== bfd_mach_x86_64_intel_syntax
2061 || info
->mach
== bfd_mach_x86_64
)
2062 address_mode
= mode_64bit
;
2064 address_mode
= mode_32bit
;
2066 if (intel_syntax
== (char) -1)
2067 intel_syntax
= (info
->mach
== bfd_mach_i386_i386_intel_syntax
2068 || info
->mach
== bfd_mach_x86_64_intel_syntax
);
2070 if (info
->mach
== bfd_mach_i386_i386
2071 || info
->mach
== bfd_mach_x86_64
2072 || info
->mach
== bfd_mach_i386_i386_intel_syntax
2073 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
2074 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2075 else if (info
->mach
== bfd_mach_i386_i8086
)
2076 priv
.orig_sizeflag
= 0;
2080 for (p
= info
->disassembler_options
; p
!= NULL
; )
2082 if (strncmp (p
, "x86-64", 6) == 0)
2084 address_mode
= mode_64bit
;
2085 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2087 else if (strncmp (p
, "i386", 4) == 0)
2089 address_mode
= mode_32bit
;
2090 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2092 else if (strncmp (p
, "i8086", 5) == 0)
2094 address_mode
= mode_16bit
;
2095 priv
.orig_sizeflag
= 0;
2097 else if (strncmp (p
, "intel", 5) == 0)
2101 else if (strncmp (p
, "att", 3) == 0)
2105 else if (strncmp (p
, "addr", 4) == 0)
2107 if (p
[4] == '1' && p
[5] == '6')
2108 priv
.orig_sizeflag
&= ~AFLAG
;
2109 else if (p
[4] == '3' && p
[5] == '2')
2110 priv
.orig_sizeflag
|= AFLAG
;
2112 else if (strncmp (p
, "data", 4) == 0)
2114 if (p
[4] == '1' && p
[5] == '6')
2115 priv
.orig_sizeflag
&= ~DFLAG
;
2116 else if (p
[4] == '3' && p
[5] == '2')
2117 priv
.orig_sizeflag
|= DFLAG
;
2119 else if (strncmp (p
, "suffix", 6) == 0)
2120 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
2122 p
= strchr (p
, ',');
2129 names64
= intel_names64
;
2130 names32
= intel_names32
;
2131 names16
= intel_names16
;
2132 names8
= intel_names8
;
2133 names8rex
= intel_names8rex
;
2134 names_seg
= intel_names_seg
;
2135 index16
= intel_index16
;
2138 separator_char
= '+';
2143 names64
= att_names64
;
2144 names32
= att_names32
;
2145 names16
= att_names16
;
2146 names8
= att_names8
;
2147 names8rex
= att_names8rex
;
2148 names_seg
= att_names_seg
;
2149 index16
= att_index16
;
2152 separator_char
= ',';
2156 /* The output looks better if we put 7 bytes on a line, since that
2157 puts most long word instructions on a single line. */
2158 info
->bytes_per_line
= 7;
2160 info
->private_data
= &priv
;
2161 priv
.max_fetched
= priv
.the_buffer
;
2162 priv
.insn_start
= pc
;
2169 op_index
[0] = op_index
[1] = op_index
[2] = -1;
2173 start_codep
= priv
.the_buffer
;
2174 codep
= priv
.the_buffer
;
2176 if (setjmp (priv
.bailout
) != 0)
2180 /* Getting here means we tried for data but didn't get it. That
2181 means we have an incomplete instruction of some sort. Just
2182 print the first byte as a prefix or a .byte pseudo-op. */
2183 if (codep
> priv
.the_buffer
)
2185 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2187 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
2190 /* Just print the first byte as a .byte instruction. */
2191 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
2192 (unsigned int) priv
.the_buffer
[0]);
2205 sizeflag
= priv
.orig_sizeflag
;
2207 FETCH_DATA (info
, codep
+ 1);
2208 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
2210 if (((prefixes
& PREFIX_FWAIT
)
2211 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
2212 || (rex
&& rex_used
))
2216 /* fwait not followed by floating point instruction, or rex followed
2217 by other prefixes. Print the first prefix. */
2218 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2220 name
= INTERNAL_DISASSEMBLER_ERROR
;
2221 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
2227 FETCH_DATA (info
, codep
+ 2);
2228 dp
= &dis386_twobyte
[*++codep
];
2229 need_modrm
= twobyte_has_modrm
[*codep
];
2230 uses_SSE_prefix
= twobyte_uses_SSE_prefix
[*codep
];
2231 uses_LOCK_prefix
= (*codep
& ~0x02) == 0x20;
2235 dp
= &dis386
[*codep
];
2236 need_modrm
= onebyte_has_modrm
[*codep
];
2237 uses_SSE_prefix
= 0;
2238 uses_LOCK_prefix
= 0;
2242 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_REPZ
))
2245 used_prefixes
|= PREFIX_REPZ
;
2247 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_REPNZ
))
2250 used_prefixes
|= PREFIX_REPNZ
;
2252 if (!uses_LOCK_prefix
&& (prefixes
& PREFIX_LOCK
))
2255 used_prefixes
|= PREFIX_LOCK
;
2258 if (prefixes
& PREFIX_ADDR
)
2261 if (dp
->bytemode3
!= loop_jcxz_mode
|| intel_syntax
)
2263 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
2264 oappend ("addr32 ");
2266 oappend ("addr16 ");
2267 used_prefixes
|= PREFIX_ADDR
;
2271 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_DATA
))
2274 if (dp
->bytemode3
== cond_jump_mode
2275 && dp
->bytemode1
== v_mode
2278 if (sizeflag
& DFLAG
)
2279 oappend ("data32 ");
2281 oappend ("data16 ");
2282 used_prefixes
|= PREFIX_DATA
;
2286 if (dp
->name
== NULL
&& dp
->bytemode1
== IS_3BYTE_OPCODE
)
2288 FETCH_DATA (info
, codep
+ 2);
2289 dp
= &three_byte_table
[dp
->bytemode2
][*codep
++];
2290 mod
= (*codep
>> 6) & 3;
2291 reg
= (*codep
>> 3) & 7;
2294 else if (need_modrm
)
2296 FETCH_DATA (info
, codep
+ 1);
2297 mod
= (*codep
>> 6) & 3;
2298 reg
= (*codep
>> 3) & 7;
2302 if (dp
->name
== NULL
&& dp
->bytemode1
== FLOATCODE
)
2309 if (dp
->name
== NULL
)
2311 switch (dp
->bytemode1
)
2314 dp
= &grps
[dp
->bytemode2
][reg
];
2317 case USE_PREFIX_USER_TABLE
:
2319 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
2320 if (prefixes
& PREFIX_REPZ
)
2324 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2325 if (prefixes
& PREFIX_DATA
)
2329 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
2330 if (prefixes
& PREFIX_REPNZ
)
2334 dp
= &prefix_user_table
[dp
->bytemode2
][index
];
2337 case X86_64_SPECIAL
:
2338 index
= address_mode
== mode_64bit
? 1 : 0;
2339 dp
= &x86_64_table
[dp
->bytemode2
][index
];
2343 oappend (INTERNAL_DISASSEMBLER_ERROR
);
2348 if (putop (dp
->name
, sizeflag
) == 0)
2353 (*dp
->op1
) (dp
->bytemode1
, sizeflag
);
2358 (*dp
->op2
) (dp
->bytemode2
, sizeflag
);
2363 (*dp
->op3
) (dp
->bytemode3
, sizeflag
);
2367 /* See if any prefixes were not used. If so, print the first one
2368 separately. If we don't do this, we'll wind up printing an
2369 instruction stream which does not precisely correspond to the
2370 bytes we are disassembling. */
2371 if ((prefixes
& ~used_prefixes
) != 0)
2375 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2377 name
= INTERNAL_DISASSEMBLER_ERROR
;
2378 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
2381 if (rex
& ~rex_used
)
2384 name
= prefix_name (rex
| 0x40, priv
.orig_sizeflag
);
2386 name
= INTERNAL_DISASSEMBLER_ERROR
;
2387 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
2390 obufp
= obuf
+ strlen (obuf
);
2391 for (i
= strlen (obuf
); i
< 6; i
++)
2394 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
2396 /* The enter and bound instructions are printed with operands in the same
2397 order as the intel book; everything else is printed in reverse order. */
2398 if (intel_syntax
|| two_source_ops
)
2403 op_ad
= op_index
[0];
2404 op_index
[0] = op_index
[2];
2405 op_index
[2] = op_ad
;
2416 if (op_index
[0] != -1 && !op_riprel
[0])
2417 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[0]], info
);
2419 (*info
->fprintf_func
) (info
->stream
, "%s", first
);
2425 (*info
->fprintf_func
) (info
->stream
, ",");
2426 if (op_index
[1] != -1 && !op_riprel
[1])
2427 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[1]], info
);
2429 (*info
->fprintf_func
) (info
->stream
, "%s", second
);
2435 (*info
->fprintf_func
) (info
->stream
, ",");
2436 if (op_index
[2] != -1 && !op_riprel
[2])
2437 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[2]], info
);
2439 (*info
->fprintf_func
) (info
->stream
, "%s", third
);
2441 for (i
= 0; i
< 3; i
++)
2442 if (op_index
[i
] != -1 && op_riprel
[i
])
2444 (*info
->fprintf_func
) (info
->stream
, " # ");
2445 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
2446 + op_address
[op_index
[i
]]), info
);
2448 return codep
- priv
.the_buffer
;
2451 static const char *float_mem
[] = {
2526 static const unsigned char float_mem_mode
[] = {
2602 #define STi OP_STi, 0
2604 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
2605 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
2606 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
2607 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
2608 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
2609 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
2610 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
2611 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
2612 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
2614 static const struct dis386 float_reg
[][8] = {
2617 { "fadd", ST
, STi
, XX
},
2618 { "fmul", ST
, STi
, XX
},
2619 { "fcom", STi
, XX
, XX
},
2620 { "fcomp", STi
, XX
, XX
},
2621 { "fsub", ST
, STi
, XX
},
2622 { "fsubr", ST
, STi
, XX
},
2623 { "fdiv", ST
, STi
, XX
},
2624 { "fdivr", ST
, STi
, XX
},
2628 { "fld", STi
, XX
, XX
},
2629 { "fxch", STi
, XX
, XX
},
2631 { "(bad)", XX
, XX
, XX
},
2639 { "fcmovb", ST
, STi
, XX
},
2640 { "fcmove", ST
, STi
, XX
},
2641 { "fcmovbe",ST
, STi
, XX
},
2642 { "fcmovu", ST
, STi
, XX
},
2643 { "(bad)", XX
, XX
, XX
},
2645 { "(bad)", XX
, XX
, XX
},
2646 { "(bad)", XX
, XX
, XX
},
2650 { "fcmovnb",ST
, STi
, XX
},
2651 { "fcmovne",ST
, STi
, XX
},
2652 { "fcmovnbe",ST
, STi
, XX
},
2653 { "fcmovnu",ST
, STi
, XX
},
2655 { "fucomi", ST
, STi
, XX
},
2656 { "fcomi", ST
, STi
, XX
},
2657 { "(bad)", XX
, XX
, XX
},
2661 { "fadd", STi
, ST
, XX
},
2662 { "fmul", STi
, ST
, XX
},
2663 { "(bad)", XX
, XX
, XX
},
2664 { "(bad)", XX
, XX
, XX
},
2666 { "fsub", STi
, ST
, XX
},
2667 { "fsubr", STi
, ST
, XX
},
2668 { "fdiv", STi
, ST
, XX
},
2669 { "fdivr", STi
, ST
, XX
},
2671 { "fsubr", STi
, ST
, XX
},
2672 { "fsub", STi
, ST
, XX
},
2673 { "fdivr", STi
, ST
, XX
},
2674 { "fdiv", STi
, ST
, XX
},
2679 { "ffree", STi
, XX
, XX
},
2680 { "(bad)", XX
, XX
, XX
},
2681 { "fst", STi
, XX
, XX
},
2682 { "fstp", STi
, XX
, XX
},
2683 { "fucom", STi
, XX
, XX
},
2684 { "fucomp", STi
, XX
, XX
},
2685 { "(bad)", XX
, XX
, XX
},
2686 { "(bad)", XX
, XX
, XX
},
2690 { "faddp", STi
, ST
, XX
},
2691 { "fmulp", STi
, ST
, XX
},
2692 { "(bad)", XX
, XX
, XX
},
2695 { "fsubp", STi
, ST
, XX
},
2696 { "fsubrp", STi
, ST
, XX
},
2697 { "fdivp", STi
, ST
, XX
},
2698 { "fdivrp", STi
, ST
, XX
},
2700 { "fsubrp", STi
, ST
, XX
},
2701 { "fsubp", STi
, ST
, XX
},
2702 { "fdivrp", STi
, ST
, XX
},
2703 { "fdivp", STi
, ST
, XX
},
2708 { "ffreep", STi
, XX
, XX
},
2709 { "(bad)", XX
, XX
, XX
},
2710 { "(bad)", XX
, XX
, XX
},
2711 { "(bad)", XX
, XX
, XX
},
2713 { "fucomip",ST
, STi
, XX
},
2714 { "fcomip", ST
, STi
, XX
},
2715 { "(bad)", XX
, XX
, XX
},
2719 static char *fgrps
[][8] = {
2722 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2727 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2732 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2737 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2742 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2747 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2752 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2753 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2758 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2763 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2768 dofloat (int sizeflag
)
2770 const struct dis386
*dp
;
2771 unsigned char floatop
;
2773 floatop
= codep
[-1];
2777 int fp_indx
= (floatop
- 0xd8) * 8 + reg
;
2779 putop (float_mem
[fp_indx
], sizeflag
);
2782 OP_E (float_mem_mode
[fp_indx
], sizeflag
);
2785 /* Skip mod/rm byte. */
2789 dp
= &float_reg
[floatop
- 0xd8][reg
];
2790 if (dp
->name
== NULL
)
2792 putop (fgrps
[dp
->bytemode1
][rm
], sizeflag
);
2794 /* Instruction fnstsw is only one with strange arg. */
2795 if (floatop
== 0xdf && codep
[-1] == 0xe0)
2796 strcpy (op1out
, names16
[0]);
2800 putop (dp
->name
, sizeflag
);
2805 (*dp
->op1
) (dp
->bytemode1
, sizeflag
);
2810 (*dp
->op2
) (dp
->bytemode2
, sizeflag
);
2815 OP_ST (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
2817 oappend ("%st" + intel_syntax
);
2821 OP_STi (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
2823 sprintf (scratchbuf
, "%%st(%d)", rm
);
2824 oappend (scratchbuf
+ intel_syntax
);
2827 /* Capital letters in template are macros. */
2829 putop (const char *template, int sizeflag
)
2834 for (p
= template; *p
; p
++)
2845 if (address_mode
== mode_64bit
)
2853 /* Alternative not valid. */
2854 strcpy (obuf
, "(bad)");
2858 else if (*p
== '\0')
2879 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
2885 if (sizeflag
& SUFFIX_ALWAYS
)
2889 if (intel_syntax
&& !alt
)
2891 if ((prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
2893 if (sizeflag
& DFLAG
)
2894 *obufp
++ = intel_syntax
? 'd' : 'l';
2896 *obufp
++ = intel_syntax
? 'w' : 's';
2897 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2900 case 'E': /* For jcxz/jecxz */
2901 if (address_mode
== mode_64bit
)
2903 if (sizeflag
& AFLAG
)
2909 if (sizeflag
& AFLAG
)
2911 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
2916 if ((prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
2918 if (sizeflag
& AFLAG
)
2919 *obufp
++ = address_mode
== mode_64bit
? 'q' : 'l';
2921 *obufp
++ = address_mode
== mode_64bit
? 'l' : 'w';
2922 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
2928 if ((prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
2929 || (prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
2931 used_prefixes
|= prefixes
& (PREFIX_CS
| PREFIX_DS
);
2934 if (prefixes
& PREFIX_DS
)
2948 if (address_mode
== mode_64bit
&& (sizeflag
& SUFFIX_ALWAYS
))
2957 if (sizeflag
& SUFFIX_ALWAYS
)
2961 if ((prefixes
& PREFIX_FWAIT
) == 0)
2964 used_prefixes
|= PREFIX_FWAIT
;
2967 USED_REX (REX_MODE64
);
2968 if (rex
& REX_MODE64
)
2976 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
2985 if ((prefixes
& PREFIX_DATA
)
2986 || (rex
& REX_MODE64
)
2987 || (sizeflag
& SUFFIX_ALWAYS
))
2989 USED_REX (REX_MODE64
);
2990 if (rex
& REX_MODE64
)
2994 if (sizeflag
& DFLAG
)
2999 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3005 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3007 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3013 if (intel_syntax
&& !alt
)
3015 USED_REX (REX_MODE64
);
3016 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
3018 if (rex
& REX_MODE64
)
3022 if (sizeflag
& DFLAG
)
3023 *obufp
++ = intel_syntax
? 'd' : 'l';
3027 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3031 USED_REX (REX_MODE64
);
3034 if (rex
& REX_MODE64
)
3039 else if (sizeflag
& DFLAG
)
3052 if (rex
& REX_MODE64
)
3054 else if (sizeflag
& DFLAG
)
3059 if (!(rex
& REX_MODE64
))
3060 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3065 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3067 if (sizeflag
& SUFFIX_ALWAYS
)
3075 if (sizeflag
& SUFFIX_ALWAYS
)
3077 if (rex
& REX_MODE64
)
3081 if (sizeflag
& DFLAG
)
3085 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3090 if (prefixes
& PREFIX_DATA
)
3094 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3099 if (rex
& REX_MODE64
)
3101 USED_REX (REX_MODE64
);
3105 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
3107 /* operand size flag for cwtl, cbtw */
3111 else if (sizeflag
& DFLAG
)
3122 if (sizeflag
& DFLAG
)
3133 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3143 oappend (const char *s
)
3146 obufp
+= strlen (s
);
3152 if (prefixes
& PREFIX_CS
)
3154 used_prefixes
|= PREFIX_CS
;
3155 oappend ("%cs:" + intel_syntax
);
3157 if (prefixes
& PREFIX_DS
)
3159 used_prefixes
|= PREFIX_DS
;
3160 oappend ("%ds:" + intel_syntax
);
3162 if (prefixes
& PREFIX_SS
)
3164 used_prefixes
|= PREFIX_SS
;
3165 oappend ("%ss:" + intel_syntax
);
3167 if (prefixes
& PREFIX_ES
)
3169 used_prefixes
|= PREFIX_ES
;
3170 oappend ("%es:" + intel_syntax
);
3172 if (prefixes
& PREFIX_FS
)
3174 used_prefixes
|= PREFIX_FS
;
3175 oappend ("%fs:" + intel_syntax
);
3177 if (prefixes
& PREFIX_GS
)
3179 used_prefixes
|= PREFIX_GS
;
3180 oappend ("%gs:" + intel_syntax
);
3185 OP_indirE (int bytemode
, int sizeflag
)
3189 OP_E (bytemode
, sizeflag
);
3193 print_operand_value (char *buf
, int hex
, bfd_vma disp
)
3195 if (address_mode
== mode_64bit
)
3203 sprintf_vma (tmp
, disp
);
3204 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+ 1]; i
++);
3205 strcpy (buf
+ 2, tmp
+ i
);
3209 bfd_signed_vma v
= disp
;
3216 /* Check for possible overflow on 0x8000000000000000. */
3219 strcpy (buf
, "9223372036854775808");
3233 tmp
[28 - i
] = (v
% 10) + '0';
3237 strcpy (buf
, tmp
+ 29 - i
);
3243 sprintf (buf
, "0x%x", (unsigned int) disp
);
3245 sprintf (buf
, "%d", (int) disp
);
3250 intel_operand_size (int bytemode
, int sizeflag
)
3255 oappend ("BYTE PTR ");
3259 oappend ("WORD PTR ");
3262 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3264 oappend ("QWORD PTR ");
3265 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3271 USED_REX (REX_MODE64
);
3272 if (rex
& REX_MODE64
)
3273 oappend ("QWORD PTR ");
3274 else if ((sizeflag
& DFLAG
) || bytemode
== dq_mode
)
3275 oappend ("DWORD PTR ");
3277 oappend ("WORD PTR ");
3278 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3281 oappend ("DWORD PTR ");
3284 oappend ("QWORD PTR ");
3287 if (address_mode
== mode_64bit
)
3288 oappend ("QWORD PTR ");
3290 oappend ("DWORD PTR ");
3293 if (sizeflag
& DFLAG
)
3294 oappend ("FWORD PTR ");
3296 oappend ("DWORD PTR ");
3297 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3300 oappend ("TBYTE PTR ");
3303 oappend ("XMMWORD PTR ");
3311 OP_E (int bytemode
, int sizeflag
)
3316 USED_REX (REX_EXTZ
);
3320 /* Skip mod/rm byte. */
3331 oappend (names8rex
[rm
+ add
]);
3333 oappend (names8
[rm
+ add
]);
3336 oappend (names16
[rm
+ add
]);
3339 oappend (names32
[rm
+ add
]);
3342 oappend (names64
[rm
+ add
]);
3345 if (address_mode
== mode_64bit
)
3346 oappend (names64
[rm
+ add
]);
3348 oappend (names32
[rm
+ add
]);
3351 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3353 oappend (names64
[rm
+ add
]);
3354 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3362 USED_REX (REX_MODE64
);
3363 if (rex
& REX_MODE64
)
3364 oappend (names64
[rm
+ add
]);
3365 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
3366 oappend (names32
[rm
+ add
]);
3368 oappend (names16
[rm
+ add
]);
3369 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3374 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3382 intel_operand_size (bytemode
, sizeflag
);
3385 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
) /* 32 bit address mode */
3400 FETCH_DATA (the_info
, codep
+ 1);
3401 index
= (*codep
>> 3) & 7;
3402 if (address_mode
== mode_64bit
|| index
!= 0x4)
3403 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
3404 scale
= (*codep
>> 6) & 3;
3406 USED_REX (REX_EXTY
);
3416 if ((base
& 7) == 5)
3419 if (address_mode
== mode_64bit
&& !havesib
)
3425 FETCH_DATA (the_info
, codep
+ 1);
3427 if ((disp
& 0x80) != 0)
3436 if (mod
!= 0 || (base
& 7) == 5)
3438 print_operand_value (scratchbuf
, !riprel
, disp
);
3439 oappend (scratchbuf
);
3447 if (havebase
|| (havesib
&& (index
!= 4 || scale
!= 0)))
3449 *obufp
++ = open_char
;
3450 if (intel_syntax
&& riprel
)
3454 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
3455 ? names64
[base
] : names32
[base
]);
3460 if (!intel_syntax
|| havebase
)
3462 *obufp
++ = separator_char
;
3465 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
3466 ? names64
[index
] : names32
[index
]);
3468 if (scale
!= 0 || (!intel_syntax
&& index
!= 4))
3470 *obufp
++ = scale_char
;
3472 sprintf (scratchbuf
, "%d", 1 << scale
);
3473 oappend (scratchbuf
);
3476 if (intel_syntax
&& disp
)
3478 if ((bfd_signed_vma
) disp
> 0)
3487 disp
= - (bfd_signed_vma
) disp
;
3490 print_operand_value (scratchbuf
, mod
!= 1, disp
);
3491 oappend (scratchbuf
);
3494 *obufp
++ = close_char
;
3497 else if (intel_syntax
)
3499 if (mod
!= 0 || (base
& 7) == 5)
3501 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
3502 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
3506 oappend (names_seg
[ds_reg
- es_reg
]);
3509 print_operand_value (scratchbuf
, 1, disp
);
3510 oappend (scratchbuf
);
3515 { /* 16 bit address mode */
3522 if ((disp
& 0x8000) != 0)
3527 FETCH_DATA (the_info
, codep
+ 1);
3529 if ((disp
& 0x80) != 0)
3534 if ((disp
& 0x8000) != 0)
3540 if (mod
!= 0 || rm
== 6)
3542 print_operand_value (scratchbuf
, 0, disp
);
3543 oappend (scratchbuf
);
3546 if (mod
!= 0 || rm
!= 6)
3548 *obufp
++ = open_char
;
3550 oappend (index16
[rm
]);
3551 if (intel_syntax
&& disp
)
3553 if ((bfd_signed_vma
) disp
> 0)
3562 disp
= - (bfd_signed_vma
) disp
;
3565 print_operand_value (scratchbuf
, mod
!= 1, disp
);
3566 oappend (scratchbuf
);
3569 *obufp
++ = close_char
;
3572 else if (intel_syntax
)
3574 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
3575 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
3579 oappend (names_seg
[ds_reg
- es_reg
]);
3582 print_operand_value (scratchbuf
, 1, disp
& 0xffff);
3583 oappend (scratchbuf
);
3589 OP_G (int bytemode
, int sizeflag
)
3592 USED_REX (REX_EXTX
);
3600 oappend (names8rex
[reg
+ add
]);
3602 oappend (names8
[reg
+ add
]);
3605 oappend (names16
[reg
+ add
]);
3608 oappend (names32
[reg
+ add
]);
3611 oappend (names64
[reg
+ add
]);
3616 USED_REX (REX_MODE64
);
3617 if (rex
& REX_MODE64
)
3618 oappend (names64
[reg
+ add
]);
3619 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
3620 oappend (names32
[reg
+ add
]);
3622 oappend (names16
[reg
+ add
]);
3623 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3626 if (address_mode
== mode_64bit
)
3627 oappend (names64
[reg
+ add
]);
3629 oappend (names32
[reg
+ add
]);
3632 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3645 FETCH_DATA (the_info
, codep
+ 8);
3646 a
= *codep
++ & 0xff;
3647 a
|= (*codep
++ & 0xff) << 8;
3648 a
|= (*codep
++ & 0xff) << 16;
3649 a
|= (*codep
++ & 0xff) << 24;
3650 b
= *codep
++ & 0xff;
3651 b
|= (*codep
++ & 0xff) << 8;
3652 b
|= (*codep
++ & 0xff) << 16;
3653 b
|= (*codep
++ & 0xff) << 24;
3654 x
= a
+ ((bfd_vma
) b
<< 32);
3662 static bfd_signed_vma
3665 bfd_signed_vma x
= 0;
3667 FETCH_DATA (the_info
, codep
+ 4);
3668 x
= *codep
++ & (bfd_signed_vma
) 0xff;
3669 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
3670 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
3671 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
3675 static bfd_signed_vma
3678 bfd_signed_vma x
= 0;
3680 FETCH_DATA (the_info
, codep
+ 4);
3681 x
= *codep
++ & (bfd_signed_vma
) 0xff;
3682 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
3683 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
3684 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
3686 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
3696 FETCH_DATA (the_info
, codep
+ 2);
3697 x
= *codep
++ & 0xff;
3698 x
|= (*codep
++ & 0xff) << 8;
3703 set_op (bfd_vma op
, int riprel
)
3705 op_index
[op_ad
] = op_ad
;
3706 if (address_mode
== mode_64bit
)
3708 op_address
[op_ad
] = op
;
3709 op_riprel
[op_ad
] = riprel
;
3713 /* Mask to get a 32-bit address. */
3714 op_address
[op_ad
] = op
& 0xffffffff;
3715 op_riprel
[op_ad
] = riprel
& 0xffffffff;
3720 OP_REG (int code
, int sizeflag
)
3724 USED_REX (REX_EXTZ
);
3736 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
3737 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
3738 s
= names16
[code
- ax_reg
+ add
];
3740 case es_reg
: case ss_reg
: case cs_reg
:
3741 case ds_reg
: case fs_reg
: case gs_reg
:
3742 s
= names_seg
[code
- es_reg
+ add
];
3744 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
3745 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
3748 s
= names8rex
[code
- al_reg
+ add
];
3750 s
= names8
[code
- al_reg
];
3752 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
3753 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
3754 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3756 s
= names64
[code
- rAX_reg
+ add
];
3759 code
+= eAX_reg
- rAX_reg
;
3761 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
3762 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
3763 USED_REX (REX_MODE64
);
3764 if (rex
& REX_MODE64
)
3765 s
= names64
[code
- eAX_reg
+ add
];
3766 else if (sizeflag
& DFLAG
)
3767 s
= names32
[code
- eAX_reg
+ add
];
3769 s
= names16
[code
- eAX_reg
+ add
];
3770 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3773 s
= INTERNAL_DISASSEMBLER_ERROR
;
3780 OP_IMREG (int code
, int sizeflag
)
3792 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
3793 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
3794 s
= names16
[code
- ax_reg
];
3796 case es_reg
: case ss_reg
: case cs_reg
:
3797 case ds_reg
: case fs_reg
: case gs_reg
:
3798 s
= names_seg
[code
- es_reg
];
3800 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
3801 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
3804 s
= names8rex
[code
- al_reg
];
3806 s
= names8
[code
- al_reg
];
3808 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
3809 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
3810 USED_REX (REX_MODE64
);
3811 if (rex
& REX_MODE64
)
3812 s
= names64
[code
- eAX_reg
];
3813 else if (sizeflag
& DFLAG
)
3814 s
= names32
[code
- eAX_reg
];
3816 s
= names16
[code
- eAX_reg
];
3817 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3820 s
= INTERNAL_DISASSEMBLER_ERROR
;
3827 OP_I (int bytemode
, int sizeflag
)
3830 bfd_signed_vma mask
= -1;
3835 FETCH_DATA (the_info
, codep
+ 1);
3840 if (address_mode
== mode_64bit
)
3847 USED_REX (REX_MODE64
);
3848 if (rex
& REX_MODE64
)
3850 else if (sizeflag
& DFLAG
)
3860 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3871 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3876 scratchbuf
[0] = '$';
3877 print_operand_value (scratchbuf
+ 1, 1, op
);
3878 oappend (scratchbuf
+ intel_syntax
);
3879 scratchbuf
[0] = '\0';
3883 OP_I64 (int bytemode
, int sizeflag
)
3886 bfd_signed_vma mask
= -1;
3888 if (address_mode
!= mode_64bit
)
3890 OP_I (bytemode
, sizeflag
);
3897 FETCH_DATA (the_info
, codep
+ 1);
3902 USED_REX (REX_MODE64
);
3903 if (rex
& REX_MODE64
)
3905 else if (sizeflag
& DFLAG
)
3915 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3922 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3927 scratchbuf
[0] = '$';
3928 print_operand_value (scratchbuf
+ 1, 1, op
);
3929 oappend (scratchbuf
+ intel_syntax
);
3930 scratchbuf
[0] = '\0';
3934 OP_sI (int bytemode
, int sizeflag
)
3937 bfd_signed_vma mask
= -1;
3942 FETCH_DATA (the_info
, codep
+ 1);
3944 if ((op
& 0x80) != 0)
3949 USED_REX (REX_MODE64
);
3950 if (rex
& REX_MODE64
)
3952 else if (sizeflag
& DFLAG
)
3961 if ((op
& 0x8000) != 0)
3964 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3969 if ((op
& 0x8000) != 0)
3973 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3977 scratchbuf
[0] = '$';
3978 print_operand_value (scratchbuf
+ 1, 1, op
);
3979 oappend (scratchbuf
+ intel_syntax
);
3983 OP_J (int bytemode
, int sizeflag
)
3991 FETCH_DATA (the_info
, codep
+ 1);
3993 if ((disp
& 0x80) != 0)
3997 if ((sizeflag
& DFLAG
) || (rex
& REX_MODE64
))
4002 /* For some reason, a data16 prefix on a jump instruction
4003 means that the pc is masked to 16 bits after the
4004 displacement is added! */
4009 oappend (INTERNAL_DISASSEMBLER_ERROR
);
4012 disp
= (start_pc
+ codep
- start_codep
+ disp
) & mask
;
4014 print_operand_value (scratchbuf
, 1, disp
);
4015 oappend (scratchbuf
);
4019 OP_SEG (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4021 oappend (names_seg
[reg
]);
4025 OP_DIR (int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
4029 if (sizeflag
& DFLAG
)
4039 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4041 sprintf (scratchbuf
, "0x%x:0x%x", seg
, offset
);
4043 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
4044 oappend (scratchbuf
);
4048 OP_OFF (int bytemode
, int sizeflag
)
4052 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4053 intel_operand_size (bytemode
, sizeflag
);
4056 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
4063 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4064 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4066 oappend (names_seg
[ds_reg
- es_reg
]);
4070 print_operand_value (scratchbuf
, 1, off
);
4071 oappend (scratchbuf
);
4075 OP_OFF64 (int bytemode
, int sizeflag
)
4079 if (address_mode
!= mode_64bit
)
4081 OP_OFF (bytemode
, sizeflag
);
4085 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4086 intel_operand_size (bytemode
, sizeflag
);
4093 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4094 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4096 oappend (names_seg
[ds_reg
- es_reg
]);
4100 print_operand_value (scratchbuf
, 1, off
);
4101 oappend (scratchbuf
);
4105 ptr_reg (int code
, int sizeflag
)
4109 *obufp
++ = open_char
;
4110 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4111 if (address_mode
== mode_64bit
)
4113 if (!(sizeflag
& AFLAG
))
4114 s
= names32
[code
- eAX_reg
];
4116 s
= names64
[code
- eAX_reg
];
4118 else if (sizeflag
& AFLAG
)
4119 s
= names32
[code
- eAX_reg
];
4121 s
= names16
[code
- eAX_reg
];
4123 *obufp
++ = close_char
;
4128 OP_ESreg (int code
, int sizeflag
)
4131 intel_operand_size (codep
[-1] & 1 ? v_mode
: b_mode
, sizeflag
);
4132 oappend ("%es:" + intel_syntax
);
4133 ptr_reg (code
, sizeflag
);
4137 OP_DSreg (int code
, int sizeflag
)
4140 intel_operand_size (codep
[-1] != 0xd7 && (codep
[-1] & 1)
4151 prefixes
|= PREFIX_DS
;
4153 ptr_reg (code
, sizeflag
);
4157 OP_C (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4162 USED_REX (REX_EXTX
);
4165 else if (address_mode
!= mode_64bit
&& (prefixes
& PREFIX_LOCK
))
4167 used_prefixes
|= PREFIX_LOCK
;
4170 sprintf (scratchbuf
, "%%cr%d", reg
+ add
);
4171 oappend (scratchbuf
+ intel_syntax
);
4175 OP_D (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4178 USED_REX (REX_EXTX
);
4182 sprintf (scratchbuf
, "db%d", reg
+ add
);
4184 sprintf (scratchbuf
, "%%db%d", reg
+ add
);
4185 oappend (scratchbuf
);
4189 OP_T (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4191 sprintf (scratchbuf
, "%%tr%d", reg
);
4192 oappend (scratchbuf
+ intel_syntax
);
4196 OP_Rd (int bytemode
, int sizeflag
)
4199 OP_E (bytemode
, sizeflag
);
4205 OP_MMX (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4207 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4208 if (prefixes
& PREFIX_DATA
)
4211 USED_REX (REX_EXTX
);
4214 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
4217 sprintf (scratchbuf
, "%%mm%d", reg
);
4218 oappend (scratchbuf
+ intel_syntax
);
4222 OP_XMM (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4225 USED_REX (REX_EXTX
);
4228 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
4229 oappend (scratchbuf
+ intel_syntax
);
4233 OP_EM (int bytemode
, int sizeflag
)
4237 if (intel_syntax
&& bytemode
== v_mode
)
4239 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
4240 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4242 OP_E (bytemode
, sizeflag
);
4246 /* Skip mod/rm byte. */
4249 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4250 if (prefixes
& PREFIX_DATA
)
4254 USED_REX (REX_EXTZ
);
4257 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
4260 sprintf (scratchbuf
, "%%mm%d", rm
);
4261 oappend (scratchbuf
+ intel_syntax
);
4265 OP_EX (int bytemode
, int sizeflag
)
4270 if (intel_syntax
&& bytemode
== v_mode
)
4272 switch (prefixes
& (PREFIX_DATA
|PREFIX_REPZ
|PREFIX_REPNZ
))
4274 case 0: bytemode
= x_mode
; break;
4275 case PREFIX_REPZ
: bytemode
= d_mode
; used_prefixes
|= PREFIX_REPZ
; break;
4276 case PREFIX_DATA
: bytemode
= x_mode
; used_prefixes
|= PREFIX_DATA
; break;
4277 case PREFIX_REPNZ
: bytemode
= q_mode
; used_prefixes
|= PREFIX_REPNZ
; break;
4278 default: bytemode
= 0; break;
4281 OP_E (bytemode
, sizeflag
);
4284 USED_REX (REX_EXTZ
);
4288 /* Skip mod/rm byte. */
4291 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
4292 oappend (scratchbuf
+ intel_syntax
);
4296 OP_MS (int bytemode
, int sizeflag
)
4299 OP_EM (bytemode
, sizeflag
);
4305 OP_XS (int bytemode
, int sizeflag
)
4308 OP_EX (bytemode
, sizeflag
);
4314 OP_M (int bytemode
, int sizeflag
)
4317 BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
4319 OP_E (bytemode
, sizeflag
);
4323 OP_0f07 (int bytemode
, int sizeflag
)
4325 if (mod
!= 3 || rm
!= 0)
4328 OP_E (bytemode
, sizeflag
);
4332 OP_0fae (int bytemode
, int sizeflag
)
4337 strcpy (obuf
+ strlen (obuf
) - sizeof ("clflush") + 1, "sfence");
4339 if (reg
< 5 || rm
!= 0)
4341 BadOp (); /* bad sfence, mfence, or lfence */
4347 BadOp (); /* bad clflush */
4351 OP_E (bytemode
, sizeflag
);
4355 NOP_Fixup (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4357 /* NOP with REPZ prefix is called PAUSE. */
4358 if (prefixes
== PREFIX_REPZ
)
4359 strcpy (obuf
, "pause");
4362 static const char *const Suffix3DNow
[] = {
4363 /* 00 */ NULL
, NULL
, NULL
, NULL
,
4364 /* 04 */ NULL
, NULL
, NULL
, NULL
,
4365 /* 08 */ NULL
, NULL
, NULL
, NULL
,
4366 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
4367 /* 10 */ NULL
, NULL
, NULL
, NULL
,
4368 /* 14 */ NULL
, NULL
, NULL
, NULL
,
4369 /* 18 */ NULL
, NULL
, NULL
, NULL
,
4370 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
4371 /* 20 */ NULL
, NULL
, NULL
, NULL
,
4372 /* 24 */ NULL
, NULL
, NULL
, NULL
,
4373 /* 28 */ NULL
, NULL
, NULL
, NULL
,
4374 /* 2C */ NULL
, NULL
, NULL
, NULL
,
4375 /* 30 */ NULL
, NULL
, NULL
, NULL
,
4376 /* 34 */ NULL
, NULL
, NULL
, NULL
,
4377 /* 38 */ NULL
, NULL
, NULL
, NULL
,
4378 /* 3C */ NULL
, NULL
, NULL
, NULL
,
4379 /* 40 */ NULL
, NULL
, NULL
, NULL
,
4380 /* 44 */ NULL
, NULL
, NULL
, NULL
,
4381 /* 48 */ NULL
, NULL
, NULL
, NULL
,
4382 /* 4C */ NULL
, NULL
, NULL
, NULL
,
4383 /* 50 */ NULL
, NULL
, NULL
, NULL
,
4384 /* 54 */ NULL
, NULL
, NULL
, NULL
,
4385 /* 58 */ NULL
, NULL
, NULL
, NULL
,
4386 /* 5C */ NULL
, NULL
, NULL
, NULL
,
4387 /* 60 */ NULL
, NULL
, NULL
, NULL
,
4388 /* 64 */ NULL
, NULL
, NULL
, NULL
,
4389 /* 68 */ NULL
, NULL
, NULL
, NULL
,
4390 /* 6C */ NULL
, NULL
, NULL
, NULL
,
4391 /* 70 */ NULL
, NULL
, NULL
, NULL
,
4392 /* 74 */ NULL
, NULL
, NULL
, NULL
,
4393 /* 78 */ NULL
, NULL
, NULL
, NULL
,
4394 /* 7C */ NULL
, NULL
, NULL
, NULL
,
4395 /* 80 */ NULL
, NULL
, NULL
, NULL
,
4396 /* 84 */ NULL
, NULL
, NULL
, NULL
,
4397 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
4398 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
4399 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
4400 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
4401 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
4402 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
4403 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
4404 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
4405 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
4406 /* AC */ NULL
, NULL
, "pfacc", NULL
,
4407 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
4408 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pfmulhrw",
4409 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
4410 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
4411 /* C0 */ NULL
, NULL
, NULL
, NULL
,
4412 /* C4 */ NULL
, NULL
, NULL
, NULL
,
4413 /* C8 */ NULL
, NULL
, NULL
, NULL
,
4414 /* CC */ NULL
, NULL
, NULL
, NULL
,
4415 /* D0 */ NULL
, NULL
, NULL
, NULL
,
4416 /* D4 */ NULL
, NULL
, NULL
, NULL
,
4417 /* D8 */ NULL
, NULL
, NULL
, NULL
,
4418 /* DC */ NULL
, NULL
, NULL
, NULL
,
4419 /* E0 */ NULL
, NULL
, NULL
, NULL
,
4420 /* E4 */ NULL
, NULL
, NULL
, NULL
,
4421 /* E8 */ NULL
, NULL
, NULL
, NULL
,
4422 /* EC */ NULL
, NULL
, NULL
, NULL
,
4423 /* F0 */ NULL
, NULL
, NULL
, NULL
,
4424 /* F4 */ NULL
, NULL
, NULL
, NULL
,
4425 /* F8 */ NULL
, NULL
, NULL
, NULL
,
4426 /* FC */ NULL
, NULL
, NULL
, NULL
,
4430 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4432 const char *mnemonic
;
4434 FETCH_DATA (the_info
, codep
+ 1);
4435 /* AMD 3DNow! instructions are specified by an opcode suffix in the
4436 place where an 8-bit immediate would normally go. ie. the last
4437 byte of the instruction. */
4438 obufp
= obuf
+ strlen (obuf
);
4439 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
4444 /* Since a variable sized modrm/sib chunk is between the start
4445 of the opcode (0x0f0f) and the opcode suffix, we need to do
4446 all the modrm processing first, and don't know until now that
4447 we have a bad opcode. This necessitates some cleaning up. */
4454 static const char *simd_cmp_op
[] = {
4466 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4468 unsigned int cmp_type
;
4470 FETCH_DATA (the_info
, codep
+ 1);
4471 obufp
= obuf
+ strlen (obuf
);
4472 cmp_type
= *codep
++ & 0xff;
4475 char suffix1
= 'p', suffix2
= 's';
4476 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
4477 if (prefixes
& PREFIX_REPZ
)
4481 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4482 if (prefixes
& PREFIX_DATA
)
4486 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
4487 if (prefixes
& PREFIX_REPNZ
)
4488 suffix1
= 's', suffix2
= 'd';
4491 sprintf (scratchbuf
, "cmp%s%c%c",
4492 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
4493 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
4494 oappend (scratchbuf
);
4498 /* We have a bad extension byte. Clean up. */
4506 SIMD_Fixup (int extrachar
, int sizeflag ATTRIBUTE_UNUSED
)
4508 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
4509 forms of these instructions. */
4512 char *p
= obuf
+ strlen (obuf
);
4515 *(p
- 1) = *(p
- 2);
4516 *(p
- 2) = *(p
- 3);
4517 *(p
- 3) = extrachar
;
4522 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
4524 if (mod
== 3 && reg
== 1 && rm
<= 1)
4526 /* Override "sidt". */
4527 size_t olen
= strlen (obuf
);
4528 char *p
= obuf
+ olen
- 4;
4529 const char **names
= (address_mode
== mode_64bit
4530 ? names64
: names32
);
4532 /* We might have a suffix when disassembling with -Msuffix. */
4536 /* Remove "addr16/addr32" if we aren't in Intel mode. */
4538 && (prefixes
& PREFIX_ADDR
)
4541 && strncmp (p
- 7, "addr", 4) == 0
4542 && (strncmp (p
- 3, "16", 2) == 0
4543 || strncmp (p
- 3, "32", 2) == 0))
4548 /* mwait %eax,%ecx */
4549 strcpy (p
, "mwait");
4551 strcpy (op1out
, names
[0]);
4555 /* monitor %eax,%ecx,%edx" */
4556 strcpy (p
, "monitor");
4559 const char **op1_names
;
4560 if (!(prefixes
& PREFIX_ADDR
))
4561 op1_names
= (address_mode
== mode_16bit
4565 op1_names
= (address_mode
!= mode_32bit
4566 ? names32
: names16
);
4567 used_prefixes
|= PREFIX_ADDR
;
4569 strcpy (op1out
, op1_names
[0]);
4570 strcpy (op3out
, names
[2]);
4575 strcpy (op2out
, names
[1]);
4586 SVME_Fixup (int bytemode
, int sizeflag
)
4618 OP_M (bytemode
, sizeflag
);
4621 /* Override "lidt". */
4622 p
= obuf
+ strlen (obuf
) - 4;
4623 /* We might have a suffix. */
4627 if (!(prefixes
& PREFIX_ADDR
))
4632 used_prefixes
|= PREFIX_ADDR
;
4636 strcpy (op2out
, names32
[1]);
4642 *obufp
++ = open_char
;
4643 if (address_mode
== mode_64bit
|| (sizeflag
& AFLAG
))
4647 strcpy (obufp
, alt
);
4648 obufp
+= strlen (alt
);
4649 *obufp
++ = close_char
;
4656 INVLPG_Fixup (int bytemode
, int sizeflag
)
4669 OP_M (bytemode
, sizeflag
);
4672 /* Override "invlpg". */
4673 strcpy (obuf
+ strlen (obuf
) - 6, alt
);
4680 /* Throw away prefixes and 1st. opcode byte. */
4681 codep
= insn_codep
+ 1;
4686 SEG_Fixup (int extrachar
, int sizeflag
)
4690 /* We need to add a proper suffix with
4701 if (prefixes
& PREFIX_DATA
)
4705 USED_REX (REX_MODE64
);
4706 if (rex
& REX_MODE64
)
4711 strcat (obuf
, suffix
);
4715 /* We need to fix the suffix for
4722 Override "mov[l|q]". */
4723 char *p
= obuf
+ strlen (obuf
) - 1;
4725 /* We might not have a suffix. */
4731 OP_E (extrachar
, sizeflag
);
4735 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
4737 if (mod
== 3 && reg
== 0 && rm
>=1 && rm
<= 4)
4739 /* Override "sgdt". */
4740 char *p
= obuf
+ strlen (obuf
) - 4;
4742 /* We might have a suffix when disassembling with -Msuffix. */
4749 strcpy (p
, "vmcall");
4752 strcpy (p
, "vmlaunch");
4755 strcpy (p
, "vmresume");
4758 strcpy (p
, "vmxoff");
4769 OP_VMX (int bytemode
, int sizeflag
)
4771 used_prefixes
|= (prefixes
& (PREFIX_DATA
| PREFIX_REPZ
));
4772 if (prefixes
& PREFIX_DATA
)
4773 strcpy (obuf
, "vmclear");
4774 else if (prefixes
& PREFIX_REPZ
)
4775 strcpy (obuf
, "vmxon");
4777 strcpy (obuf
, "vmptrld");
4778 OP_E (bytemode
, sizeflag
);