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
392 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
394 #define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
395 #define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
396 #define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
397 #define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
398 #define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
399 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
400 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
401 #define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
402 #define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
403 #define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
404 #define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
405 #define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
406 #define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
407 #define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
408 #define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
409 #define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
410 #define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
411 #define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
412 #define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
413 #define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
414 #define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
415 #define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
416 #define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
417 #define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0
418 #define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0
420 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
421 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
422 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
423 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
424 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
425 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
426 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
427 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
428 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
429 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
430 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
431 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
432 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
433 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
434 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
435 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
436 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
437 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
438 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
439 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
440 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
441 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
442 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
443 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
444 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
445 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
446 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
447 #define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0
448 #define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0
449 #define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0
450 #define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0
451 #define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0
452 #define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0
454 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
456 typedef void (*op_rtn
) (int bytemode
, int sizeflag
);
468 /* Upper case letters in the instruction names here are macros.
469 'A' => print 'b' if no register operands or suffix_always is true
470 'B' => print 'b' if suffix_always is true
471 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
473 'E' => print 'e' if 32-bit form of jcxz
474 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
475 'H' => print ",pt" or ",pn" branch hint
476 'I' => honor following macro letter even in Intel mode (implemented only
477 . for some of the macro letters)
479 'L' => print 'l' if suffix_always is true
480 'N' => print 'n' if instruction has no wait "prefix"
481 'O' => print 'd', or 'o'
482 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
483 . or suffix_always is true. print 'q' if rex prefix is present.
484 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
486 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
487 'S' => print 'w', 'l' or 'q' if suffix_always is true
488 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
489 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
490 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
491 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
492 'X' => print 's', 'd' depending on data16 prefix (for XMM)
493 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
494 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
496 Many of the above letters print nothing in Intel mode. See "putop"
499 Braces '{' and '}', and vertical bars '|', indicate alternative
500 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
501 modes. In cases where there are only two alternatives, the X86_64
502 instruction is reserved, and "(bad)" is printed.
505 static const struct dis386 dis386
[] = {
507 { "addB", Eb
, Gb
, XX
},
508 { "addS", Ev
, Gv
, XX
},
509 { "addB", Gb
, Eb
, XX
},
510 { "addS", Gv
, Ev
, XX
},
511 { "addB", AL
, Ib
, XX
},
512 { "addS", eAX
, Iv
, XX
},
513 { "push{T|}", es
, XX
, XX
},
514 { "pop{T|}", es
, XX
, XX
},
516 { "orB", Eb
, Gb
, XX
},
517 { "orS", Ev
, Gv
, XX
},
518 { "orB", Gb
, Eb
, XX
},
519 { "orS", Gv
, Ev
, XX
},
520 { "orB", AL
, Ib
, XX
},
521 { "orS", eAX
, Iv
, XX
},
522 { "push{T|}", cs
, XX
, XX
},
523 { "(bad)", XX
, XX
, XX
}, /* 0x0f extended opcode escape */
525 { "adcB", Eb
, Gb
, XX
},
526 { "adcS", Ev
, Gv
, XX
},
527 { "adcB", Gb
, Eb
, XX
},
528 { "adcS", Gv
, Ev
, XX
},
529 { "adcB", AL
, Ib
, XX
},
530 { "adcS", eAX
, Iv
, XX
},
531 { "push{T|}", ss
, XX
, XX
},
532 { "pop{T|}", ss
, XX
, XX
},
534 { "sbbB", Eb
, Gb
, XX
},
535 { "sbbS", Ev
, Gv
, XX
},
536 { "sbbB", Gb
, Eb
, XX
},
537 { "sbbS", Gv
, Ev
, XX
},
538 { "sbbB", AL
, Ib
, XX
},
539 { "sbbS", eAX
, Iv
, XX
},
540 { "push{T|}", ds
, XX
, XX
},
541 { "pop{T|}", ds
, XX
, XX
},
543 { "andB", Eb
, Gb
, XX
},
544 { "andS", Ev
, Gv
, XX
},
545 { "andB", Gb
, Eb
, XX
},
546 { "andS", Gv
, Ev
, XX
},
547 { "andB", AL
, Ib
, XX
},
548 { "andS", eAX
, Iv
, XX
},
549 { "(bad)", XX
, XX
, XX
}, /* SEG ES prefix */
550 { "daa{|}", XX
, XX
, XX
},
552 { "subB", Eb
, Gb
, XX
},
553 { "subS", Ev
, Gv
, XX
},
554 { "subB", Gb
, Eb
, XX
},
555 { "subS", Gv
, Ev
, XX
},
556 { "subB", AL
, Ib
, XX
},
557 { "subS", eAX
, Iv
, XX
},
558 { "(bad)", XX
, XX
, XX
}, /* SEG CS prefix */
559 { "das{|}", XX
, XX
, XX
},
561 { "xorB", Eb
, Gb
, XX
},
562 { "xorS", Ev
, Gv
, XX
},
563 { "xorB", Gb
, Eb
, XX
},
564 { "xorS", Gv
, Ev
, XX
},
565 { "xorB", AL
, Ib
, XX
},
566 { "xorS", eAX
, Iv
, XX
},
567 { "(bad)", XX
, XX
, XX
}, /* SEG SS prefix */
568 { "aaa{|}", XX
, XX
, XX
},
570 { "cmpB", Eb
, Gb
, XX
},
571 { "cmpS", Ev
, Gv
, XX
},
572 { "cmpB", Gb
, Eb
, XX
},
573 { "cmpS", Gv
, Ev
, XX
},
574 { "cmpB", AL
, Ib
, XX
},
575 { "cmpS", eAX
, Iv
, XX
},
576 { "(bad)", XX
, XX
, XX
}, /* SEG DS prefix */
577 { "aas{|}", XX
, XX
, XX
},
579 { "inc{S|}", RMeAX
, XX
, XX
},
580 { "inc{S|}", RMeCX
, XX
, XX
},
581 { "inc{S|}", RMeDX
, XX
, XX
},
582 { "inc{S|}", RMeBX
, XX
, XX
},
583 { "inc{S|}", RMeSP
, XX
, XX
},
584 { "inc{S|}", RMeBP
, XX
, XX
},
585 { "inc{S|}", RMeSI
, XX
, XX
},
586 { "inc{S|}", RMeDI
, XX
, XX
},
588 { "dec{S|}", RMeAX
, XX
, XX
},
589 { "dec{S|}", RMeCX
, XX
, XX
},
590 { "dec{S|}", RMeDX
, XX
, XX
},
591 { "dec{S|}", RMeBX
, XX
, XX
},
592 { "dec{S|}", RMeSP
, XX
, XX
},
593 { "dec{S|}", RMeBP
, XX
, XX
},
594 { "dec{S|}", RMeSI
, XX
, XX
},
595 { "dec{S|}", RMeDI
, XX
, XX
},
597 { "pushV", RMrAX
, XX
, XX
},
598 { "pushV", RMrCX
, XX
, XX
},
599 { "pushV", RMrDX
, XX
, XX
},
600 { "pushV", RMrBX
, XX
, XX
},
601 { "pushV", RMrSP
, XX
, XX
},
602 { "pushV", RMrBP
, XX
, XX
},
603 { "pushV", RMrSI
, XX
, XX
},
604 { "pushV", RMrDI
, XX
, XX
},
606 { "popV", RMrAX
, XX
, XX
},
607 { "popV", RMrCX
, XX
, XX
},
608 { "popV", RMrDX
, XX
, XX
},
609 { "popV", RMrBX
, XX
, XX
},
610 { "popV", RMrSP
, XX
, XX
},
611 { "popV", RMrBP
, XX
, XX
},
612 { "popV", RMrSI
, XX
, XX
},
613 { "popV", RMrDI
, XX
, XX
},
615 { "pusha{P|}", XX
, XX
, XX
},
616 { "popa{P|}", XX
, XX
, XX
},
617 { "bound{S|}", Gv
, Ma
, XX
},
619 { "(bad)", XX
, XX
, XX
}, /* seg fs */
620 { "(bad)", XX
, XX
, XX
}, /* seg gs */
621 { "(bad)", XX
, XX
, XX
}, /* op size prefix */
622 { "(bad)", XX
, XX
, XX
}, /* adr size prefix */
624 { "pushT", Iq
, XX
, XX
},
625 { "imulS", Gv
, Ev
, Iv
},
626 { "pushT", sIb
, XX
, XX
},
627 { "imulS", Gv
, Ev
, sIb
},
628 { "ins{b||b|}", Yb
, indirDX
, XX
},
629 { "ins{R||R|}", Yv
, indirDX
, XX
},
630 { "outs{b||b|}", indirDX
, Xb
, XX
},
631 { "outs{R||R|}", indirDX
, Xv
, XX
},
633 { "joH", Jb
, XX
, cond_jump_flag
},
634 { "jnoH", Jb
, XX
, cond_jump_flag
},
635 { "jbH", Jb
, XX
, cond_jump_flag
},
636 { "jaeH", Jb
, XX
, cond_jump_flag
},
637 { "jeH", Jb
, XX
, cond_jump_flag
},
638 { "jneH", Jb
, XX
, cond_jump_flag
},
639 { "jbeH", Jb
, XX
, cond_jump_flag
},
640 { "jaH", Jb
, XX
, cond_jump_flag
},
642 { "jsH", Jb
, XX
, cond_jump_flag
},
643 { "jnsH", Jb
, XX
, cond_jump_flag
},
644 { "jpH", Jb
, XX
, cond_jump_flag
},
645 { "jnpH", Jb
, XX
, cond_jump_flag
},
646 { "jlH", Jb
, XX
, cond_jump_flag
},
647 { "jgeH", Jb
, XX
, cond_jump_flag
},
648 { "jleH", Jb
, XX
, cond_jump_flag
},
649 { "jgH", Jb
, XX
, cond_jump_flag
},
653 { "(bad)", XX
, XX
, XX
},
655 { "testB", Eb
, Gb
, XX
},
656 { "testS", Ev
, Gv
, XX
},
657 { "xchgB", Eb
, Gb
, XX
},
658 { "xchgS", Ev
, Gv
, XX
},
660 { "movB", Eb
, Gb
, XX
},
661 { "movS", Ev
, Gv
, XX
},
662 { "movB", Gb
, Eb
, XX
},
663 { "movS", Gv
, Ev
, XX
},
664 { "movQ", Sv
, Sw
, XX
},
665 { "leaS", Gv
, M
, XX
},
666 { "movQ", Sw
, Sv
, XX
},
667 { "popU", stackEv
, XX
, XX
},
669 { "nop", NOP_Fixup
, 0, XX
, XX
},
670 { "xchgS", RMeCX
, eAX
, XX
},
671 { "xchgS", RMeDX
, eAX
, XX
},
672 { "xchgS", RMeBX
, eAX
, XX
},
673 { "xchgS", RMeSP
, eAX
, XX
},
674 { "xchgS", RMeBP
, eAX
, XX
},
675 { "xchgS", RMeSI
, eAX
, XX
},
676 { "xchgS", RMeDI
, eAX
, XX
},
678 { "cW{tR||tR|}", XX
, XX
, XX
},
679 { "cR{tO||tO|}", XX
, XX
, XX
},
680 { "Jcall{T|}", Ap
, XX
, XX
},
681 { "(bad)", XX
, XX
, XX
}, /* fwait */
682 { "pushfT", XX
, XX
, XX
},
683 { "popfT", XX
, XX
, XX
},
684 { "sahf{|}", XX
, XX
, XX
},
685 { "lahf{|}", XX
, XX
, XX
},
687 { "movB", AL
, Ob
, XX
},
688 { "movS", eAX
, Ov
, XX
},
689 { "movB", Ob
, AL
, XX
},
690 { "movS", Ov
, eAX
, XX
},
691 { "movs{b||b|}", Yb
, Xb
, XX
},
692 { "movs{R||R|}", Yv
, Xv
, XX
},
693 { "cmps{b||b|}", Xb
, Yb
, XX
},
694 { "cmps{R||R|}", Xv
, Yv
, XX
},
696 { "testB", AL
, Ib
, XX
},
697 { "testS", eAX
, Iv
, XX
},
698 { "stosB", Yb
, AL
, XX
},
699 { "stosS", Yv
, eAX
, XX
},
700 { "lodsB", AL
, Xb
, XX
},
701 { "lodsS", eAX
, Xv
, XX
},
702 { "scasB", AL
, Yb
, XX
},
703 { "scasS", eAX
, Yv
, XX
},
705 { "movB", RMAL
, Ib
, XX
},
706 { "movB", RMCL
, Ib
, XX
},
707 { "movB", RMDL
, Ib
, XX
},
708 { "movB", RMBL
, Ib
, XX
},
709 { "movB", RMAH
, Ib
, XX
},
710 { "movB", RMCH
, Ib
, XX
},
711 { "movB", RMDH
, Ib
, XX
},
712 { "movB", RMBH
, Ib
, XX
},
714 { "movS", RMeAX
, Iv64
, XX
},
715 { "movS", RMeCX
, Iv64
, XX
},
716 { "movS", RMeDX
, Iv64
, XX
},
717 { "movS", RMeBX
, Iv64
, XX
},
718 { "movS", RMeSP
, Iv64
, XX
},
719 { "movS", RMeBP
, Iv64
, XX
},
720 { "movS", RMeSI
, Iv64
, XX
},
721 { "movS", RMeDI
, Iv64
, XX
},
725 { "retT", Iw
, XX
, XX
},
726 { "retT", XX
, XX
, XX
},
727 { "les{S|}", Gv
, Mp
, XX
},
728 { "ldsS", Gv
, Mp
, XX
},
729 { "movA", Eb
, Ib
, XX
},
730 { "movQ", Ev
, Iv
, XX
},
732 { "enterT", Iw
, Ib
, XX
},
733 { "leaveT", XX
, XX
, XX
},
734 { "lretP", Iw
, XX
, XX
},
735 { "lretP", XX
, XX
, XX
},
736 { "int3", XX
, XX
, XX
},
737 { "int", Ib
, XX
, XX
},
738 { "into{|}", XX
, XX
, XX
},
739 { "iretP", XX
, XX
, XX
},
745 { "aam{|}", sIb
, XX
, XX
},
746 { "aad{|}", sIb
, XX
, XX
},
747 { "(bad)", XX
, XX
, XX
},
748 { "xlat", DSBX
, XX
, XX
},
759 { "loopneFH", Jb
, XX
, loop_jcxz_flag
},
760 { "loopeFH", Jb
, XX
, loop_jcxz_flag
},
761 { "loopFH", Jb
, XX
, loop_jcxz_flag
},
762 { "jEcxzH", Jb
, XX
, loop_jcxz_flag
},
763 { "inB", AL
, Ib
, XX
},
764 { "inS", eAX
, Ib
, XX
},
765 { "outB", Ib
, AL
, XX
},
766 { "outS", Ib
, eAX
, XX
},
768 { "callT", Jv
, XX
, XX
},
769 { "jmpT", Jv
, XX
, XX
},
770 { "Jjmp{T|}", Ap
, XX
, XX
},
771 { "jmp", Jb
, XX
, XX
},
772 { "inB", AL
, indirDX
, XX
},
773 { "inS", eAX
, indirDX
, XX
},
774 { "outB", indirDX
, AL
, XX
},
775 { "outS", indirDX
, eAX
, XX
},
777 { "(bad)", XX
, XX
, XX
}, /* lock prefix */
778 { "icebp", XX
, XX
, XX
},
779 { "(bad)", XX
, XX
, XX
}, /* repne */
780 { "(bad)", XX
, XX
, XX
}, /* repz */
781 { "hlt", XX
, XX
, XX
},
782 { "cmc", XX
, XX
, XX
},
786 { "clc", XX
, XX
, XX
},
787 { "stc", XX
, XX
, XX
},
788 { "cli", XX
, XX
, XX
},
789 { "sti", XX
, XX
, XX
},
790 { "cld", XX
, XX
, XX
},
791 { "std", XX
, XX
, XX
},
796 static const struct dis386 dis386_twobyte
[] = {
800 { "larS", Gv
, Ew
, XX
},
801 { "lslS", Gv
, Ew
, XX
},
802 { "(bad)", XX
, XX
, XX
},
803 { "syscall", XX
, XX
, XX
},
804 { "clts", XX
, XX
, XX
},
805 { "sysretP", XX
, XX
, XX
},
807 { "invd", XX
, XX
, XX
},
808 { "wbinvd", XX
, XX
, XX
},
809 { "(bad)", XX
, XX
, XX
},
810 { "ud2a", XX
, XX
, XX
},
811 { "(bad)", XX
, XX
, XX
},
813 { "femms", XX
, XX
, XX
},
814 { "", MX
, EM
, OPSUF
}, /* See OP_3DNowSuffix. */
819 { "movlpX", EX
, XM
, SIMD_Fixup
, 'h' },
820 { "unpcklpX", XM
, EX
, XX
},
821 { "unpckhpX", XM
, EX
, XX
},
823 { "movhpX", EX
, XM
, SIMD_Fixup
, 'l' },
826 { "(bad)", XX
, XX
, XX
},
827 { "(bad)", XX
, XX
, XX
},
828 { "(bad)", XX
, XX
, XX
},
829 { "(bad)", XX
, XX
, XX
},
830 { "(bad)", XX
, XX
, XX
},
831 { "(bad)", XX
, XX
, XX
},
832 { "(bad)", XX
, XX
, XX
},
834 { "movZ", Rm
, Cm
, XX
},
835 { "movZ", Rm
, Dm
, XX
},
836 { "movZ", Cm
, Rm
, XX
},
837 { "movZ", Dm
, Rm
, XX
},
838 { "movL", Rd
, Td
, XX
},
839 { "(bad)", XX
, XX
, XX
},
840 { "movL", Td
, Rd
, XX
},
841 { "(bad)", XX
, XX
, XX
},
843 { "movapX", XM
, EX
, XX
},
844 { "movapX", EX
, XM
, XX
},
846 { "movntpX", Ev
, XM
, XX
},
849 { "ucomisX", XM
,EX
, XX
},
850 { "comisX", XM
,EX
, XX
},
852 { "wrmsr", XX
, XX
, XX
},
853 { "rdtsc", XX
, XX
, XX
},
854 { "rdmsr", XX
, XX
, XX
},
855 { "rdpmc", XX
, XX
, XX
},
856 { "sysenter", XX
, XX
, XX
},
857 { "sysexit", XX
, XX
, XX
},
858 { "(bad)", XX
, XX
, XX
},
859 { "(bad)", XX
, XX
, XX
},
861 { "(bad)", XX
, XX
, XX
},
862 { "(bad)", XX
, XX
, XX
},
863 { "(bad)", XX
, XX
, XX
},
864 { "(bad)", XX
, XX
, XX
},
865 { "(bad)", XX
, XX
, XX
},
866 { "(bad)", XX
, XX
, XX
},
867 { "(bad)", XX
, XX
, XX
},
868 { "(bad)", XX
, XX
, XX
},
870 { "cmovo", Gv
, Ev
, XX
},
871 { "cmovno", Gv
, Ev
, XX
},
872 { "cmovb", Gv
, Ev
, XX
},
873 { "cmovae", Gv
, Ev
, XX
},
874 { "cmove", Gv
, Ev
, XX
},
875 { "cmovne", Gv
, Ev
, XX
},
876 { "cmovbe", Gv
, Ev
, XX
},
877 { "cmova", Gv
, Ev
, XX
},
879 { "cmovs", Gv
, Ev
, XX
},
880 { "cmovns", Gv
, Ev
, XX
},
881 { "cmovp", Gv
, Ev
, XX
},
882 { "cmovnp", Gv
, Ev
, XX
},
883 { "cmovl", Gv
, Ev
, XX
},
884 { "cmovge", Gv
, Ev
, XX
},
885 { "cmovle", Gv
, Ev
, XX
},
886 { "cmovg", Gv
, Ev
, XX
},
888 { "movmskpX", Gdq
, XS
, XX
},
892 { "andpX", XM
, EX
, XX
},
893 { "andnpX", XM
, EX
, XX
},
894 { "orpX", XM
, EX
, XX
},
895 { "xorpX", XM
, EX
, XX
},
906 { "punpcklbw", MX
, EM
, XX
},
907 { "punpcklwd", MX
, EM
, XX
},
908 { "punpckldq", MX
, EM
, XX
},
909 { "packsswb", MX
, EM
, XX
},
910 { "pcmpgtb", MX
, EM
, XX
},
911 { "pcmpgtw", MX
, EM
, XX
},
912 { "pcmpgtd", MX
, EM
, XX
},
913 { "packuswb", MX
, EM
, XX
},
915 { "punpckhbw", MX
, EM
, XX
},
916 { "punpckhwd", MX
, EM
, XX
},
917 { "punpckhdq", MX
, EM
, XX
},
918 { "packssdw", MX
, EM
, XX
},
921 { "movd", MX
, Edq
, XX
},
928 { "pcmpeqb", MX
, EM
, XX
},
929 { "pcmpeqw", MX
, EM
, XX
},
930 { "pcmpeqd", MX
, EM
, XX
},
931 { "emms", XX
, XX
, XX
},
933 { "vmread", Em
, Gm
, XX
},
934 { "vmwrite", Gm
, Em
, XX
},
935 { "(bad)", XX
, XX
, XX
},
936 { "(bad)", XX
, XX
, XX
},
942 { "joH", Jv
, XX
, cond_jump_flag
},
943 { "jnoH", Jv
, XX
, cond_jump_flag
},
944 { "jbH", Jv
, XX
, cond_jump_flag
},
945 { "jaeH", Jv
, XX
, cond_jump_flag
},
946 { "jeH", Jv
, XX
, cond_jump_flag
},
947 { "jneH", Jv
, XX
, cond_jump_flag
},
948 { "jbeH", Jv
, XX
, cond_jump_flag
},
949 { "jaH", Jv
, XX
, cond_jump_flag
},
951 { "jsH", Jv
, XX
, cond_jump_flag
},
952 { "jnsH", Jv
, XX
, cond_jump_flag
},
953 { "jpH", Jv
, XX
, cond_jump_flag
},
954 { "jnpH", Jv
, XX
, cond_jump_flag
},
955 { "jlH", Jv
, XX
, cond_jump_flag
},
956 { "jgeH", Jv
, XX
, cond_jump_flag
},
957 { "jleH", Jv
, XX
, cond_jump_flag
},
958 { "jgH", Jv
, XX
, cond_jump_flag
},
960 { "seto", Eb
, XX
, XX
},
961 { "setno", Eb
, XX
, XX
},
962 { "setb", Eb
, XX
, XX
},
963 { "setae", Eb
, XX
, XX
},
964 { "sete", Eb
, XX
, XX
},
965 { "setne", Eb
, XX
, XX
},
966 { "setbe", Eb
, XX
, XX
},
967 { "seta", Eb
, XX
, XX
},
969 { "sets", Eb
, XX
, XX
},
970 { "setns", Eb
, XX
, XX
},
971 { "setp", Eb
, XX
, XX
},
972 { "setnp", Eb
, XX
, XX
},
973 { "setl", Eb
, XX
, XX
},
974 { "setge", Eb
, XX
, XX
},
975 { "setle", Eb
, XX
, XX
},
976 { "setg", Eb
, XX
, XX
},
978 { "pushT", fs
, XX
, XX
},
979 { "popT", fs
, XX
, XX
},
980 { "cpuid", XX
, XX
, XX
},
981 { "btS", Ev
, Gv
, XX
},
982 { "shldS", Ev
, Gv
, Ib
},
983 { "shldS", Ev
, Gv
, CL
},
987 { "pushT", gs
, XX
, XX
},
988 { "popT", gs
, XX
, XX
},
989 { "rsm", XX
, XX
, XX
},
990 { "btsS", Ev
, Gv
, XX
},
991 { "shrdS", Ev
, Gv
, Ib
},
992 { "shrdS", Ev
, Gv
, CL
},
994 { "imulS", Gv
, Ev
, XX
},
996 { "cmpxchgB", Eb
, Gb
, XX
},
997 { "cmpxchgS", Ev
, Gv
, XX
},
998 { "lssS", Gv
, Mp
, XX
},
999 { "btrS", Ev
, Gv
, XX
},
1000 { "lfsS", Gv
, Mp
, XX
},
1001 { "lgsS", Gv
, Mp
, XX
},
1002 { "movz{bR|x|bR|x}", Gv
, Eb
, XX
},
1003 { "movz{wR|x|wR|x}", Gv
, Ew
, XX
}, /* yes, there really is movzww ! */
1005 { "(bad)", XX
, XX
, XX
},
1006 { "ud2b", XX
, XX
, XX
},
1008 { "btcS", Ev
, Gv
, XX
},
1009 { "bsfS", Gv
, Ev
, XX
},
1010 { "bsrS", Gv
, Ev
, XX
},
1011 { "movs{bR|x|bR|x}", Gv
, Eb
, XX
},
1012 { "movs{wR|x|wR|x}", Gv
, Ew
, XX
}, /* yes, there really is movsww ! */
1014 { "xaddB", Eb
, Gb
, XX
},
1015 { "xaddS", Ev
, Gv
, XX
},
1017 { "movntiS", Ev
, Gv
, XX
},
1018 { "pinsrw", MX
, Edqw
, Ib
},
1019 { "pextrw", Gdq
, MS
, Ib
},
1020 { "shufpX", XM
, EX
, Ib
},
1023 { "bswap", RMeAX
, XX
, XX
},
1024 { "bswap", RMeCX
, XX
, XX
},
1025 { "bswap", RMeDX
, XX
, XX
},
1026 { "bswap", RMeBX
, XX
, XX
},
1027 { "bswap", RMeSP
, XX
, XX
},
1028 { "bswap", RMeBP
, XX
, XX
},
1029 { "bswap", RMeSI
, XX
, XX
},
1030 { "bswap", RMeDI
, XX
, XX
},
1033 { "psrlw", MX
, EM
, XX
},
1034 { "psrld", MX
, EM
, XX
},
1035 { "psrlq", MX
, EM
, XX
},
1036 { "paddq", MX
, EM
, XX
},
1037 { "pmullw", MX
, EM
, XX
},
1039 { "pmovmskb", Gdq
, MS
, XX
},
1041 { "psubusb", MX
, EM
, XX
},
1042 { "psubusw", MX
, EM
, XX
},
1043 { "pminub", MX
, EM
, XX
},
1044 { "pand", MX
, EM
, XX
},
1045 { "paddusb", MX
, EM
, XX
},
1046 { "paddusw", MX
, EM
, XX
},
1047 { "pmaxub", MX
, EM
, XX
},
1048 { "pandn", MX
, EM
, XX
},
1050 { "pavgb", MX
, EM
, XX
},
1051 { "psraw", MX
, EM
, XX
},
1052 { "psrad", MX
, EM
, XX
},
1053 { "pavgw", MX
, EM
, XX
},
1054 { "pmulhuw", MX
, EM
, XX
},
1055 { "pmulhw", MX
, EM
, XX
},
1059 { "psubsb", MX
, EM
, XX
},
1060 { "psubsw", MX
, EM
, XX
},
1061 { "pminsw", MX
, EM
, XX
},
1062 { "por", MX
, EM
, XX
},
1063 { "paddsb", MX
, EM
, XX
},
1064 { "paddsw", MX
, EM
, XX
},
1065 { "pmaxsw", MX
, EM
, XX
},
1066 { "pxor", MX
, EM
, XX
},
1069 { "psllw", MX
, EM
, XX
},
1070 { "pslld", MX
, EM
, XX
},
1071 { "psllq", MX
, EM
, XX
},
1072 { "pmuludq", MX
, EM
, XX
},
1073 { "pmaddwd", MX
, EM
, XX
},
1074 { "psadbw", MX
, EM
, XX
},
1077 { "psubb", MX
, EM
, XX
},
1078 { "psubw", MX
, EM
, XX
},
1079 { "psubd", MX
, EM
, XX
},
1080 { "psubq", MX
, EM
, XX
},
1081 { "paddb", MX
, EM
, XX
},
1082 { "paddw", MX
, EM
, XX
},
1083 { "paddd", MX
, EM
, XX
},
1084 { "(bad)", XX
, XX
, XX
}
1087 static const unsigned char onebyte_has_modrm
[256] = {
1088 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1089 /* ------------------------------- */
1090 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1091 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1092 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1093 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1094 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1095 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1096 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1097 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1098 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1099 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1100 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1101 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1102 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1103 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1104 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1105 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1106 /* ------------------------------- */
1107 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1110 static const unsigned char twobyte_has_modrm
[256] = {
1111 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1112 /* ------------------------------- */
1113 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1114 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1115 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1116 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1117 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1118 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1119 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1120 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1121 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1122 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1123 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1124 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1125 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1126 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1127 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1128 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1129 /* ------------------------------- */
1130 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1133 static const unsigned char twobyte_uses_SSE_prefix
[256] = {
1134 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1135 /* ------------------------------- */
1136 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1137 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1138 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1139 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1140 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1141 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1142 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1143 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */
1144 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1145 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1146 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1147 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1148 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1149 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1150 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1151 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1152 /* ------------------------------- */
1153 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1156 static char obuf
[100];
1158 static char scratchbuf
[100];
1159 static unsigned char *start_codep
;
1160 static unsigned char *insn_codep
;
1161 static unsigned char *codep
;
1162 static disassemble_info
*the_info
;
1166 static unsigned char need_modrm
;
1168 /* If we are accessing mod/rm/reg without need_modrm set, then the
1169 values are stale. Hitting this abort likely indicates that you
1170 need to update onebyte_has_modrm or twobyte_has_modrm. */
1171 #define MODRM_CHECK if (!need_modrm) abort ()
1173 static const char **names64
;
1174 static const char **names32
;
1175 static const char **names16
;
1176 static const char **names8
;
1177 static const char **names8rex
;
1178 static const char **names_seg
;
1179 static const char **index16
;
1181 static const char *intel_names64
[] = {
1182 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1183 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1185 static const char *intel_names32
[] = {
1186 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1187 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1189 static const char *intel_names16
[] = {
1190 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1191 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1193 static const char *intel_names8
[] = {
1194 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1196 static const char *intel_names8rex
[] = {
1197 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1198 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1200 static const char *intel_names_seg
[] = {
1201 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1203 static const char *intel_index16
[] = {
1204 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1207 static const char *att_names64
[] = {
1208 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1209 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1211 static const char *att_names32
[] = {
1212 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1213 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1215 static const char *att_names16
[] = {
1216 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1217 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1219 static const char *att_names8
[] = {
1220 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1222 static const char *att_names8rex
[] = {
1223 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1224 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1226 static const char *att_names_seg
[] = {
1227 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1229 static const char *att_index16
[] = {
1230 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1233 static const struct dis386 grps
[][8] = {
1236 { "addA", Eb
, Ib
, XX
},
1237 { "orA", Eb
, Ib
, XX
},
1238 { "adcA", Eb
, Ib
, XX
},
1239 { "sbbA", Eb
, Ib
, XX
},
1240 { "andA", Eb
, Ib
, XX
},
1241 { "subA", Eb
, Ib
, XX
},
1242 { "xorA", Eb
, Ib
, XX
},
1243 { "cmpA", Eb
, Ib
, XX
}
1247 { "addQ", Ev
, Iv
, XX
},
1248 { "orQ", Ev
, Iv
, XX
},
1249 { "adcQ", Ev
, Iv
, XX
},
1250 { "sbbQ", Ev
, Iv
, XX
},
1251 { "andQ", Ev
, Iv
, XX
},
1252 { "subQ", Ev
, Iv
, XX
},
1253 { "xorQ", Ev
, Iv
, XX
},
1254 { "cmpQ", Ev
, Iv
, XX
}
1258 { "addQ", Ev
, sIb
, XX
},
1259 { "orQ", Ev
, sIb
, XX
},
1260 { "adcQ", Ev
, sIb
, XX
},
1261 { "sbbQ", Ev
, sIb
, XX
},
1262 { "andQ", Ev
, sIb
, XX
},
1263 { "subQ", Ev
, sIb
, XX
},
1264 { "xorQ", Ev
, sIb
, XX
},
1265 { "cmpQ", Ev
, sIb
, XX
}
1269 { "rolA", Eb
, Ib
, XX
},
1270 { "rorA", Eb
, Ib
, XX
},
1271 { "rclA", Eb
, Ib
, XX
},
1272 { "rcrA", Eb
, Ib
, XX
},
1273 { "shlA", Eb
, Ib
, XX
},
1274 { "shrA", Eb
, Ib
, XX
},
1275 { "(bad)", XX
, XX
, XX
},
1276 { "sarA", Eb
, Ib
, XX
},
1280 { "rolQ", Ev
, Ib
, XX
},
1281 { "rorQ", Ev
, Ib
, XX
},
1282 { "rclQ", Ev
, Ib
, XX
},
1283 { "rcrQ", Ev
, Ib
, XX
},
1284 { "shlQ", Ev
, Ib
, XX
},
1285 { "shrQ", Ev
, Ib
, XX
},
1286 { "(bad)", XX
, XX
, XX
},
1287 { "sarQ", Ev
, Ib
, XX
},
1291 { "rolA", Eb
, I1
, XX
},
1292 { "rorA", Eb
, I1
, XX
},
1293 { "rclA", Eb
, I1
, XX
},
1294 { "rcrA", Eb
, I1
, XX
},
1295 { "shlA", Eb
, I1
, XX
},
1296 { "shrA", Eb
, I1
, XX
},
1297 { "(bad)", XX
, XX
, XX
},
1298 { "sarA", Eb
, I1
, XX
},
1302 { "rolQ", Ev
, I1
, XX
},
1303 { "rorQ", Ev
, I1
, XX
},
1304 { "rclQ", Ev
, I1
, XX
},
1305 { "rcrQ", Ev
, I1
, XX
},
1306 { "shlQ", Ev
, I1
, XX
},
1307 { "shrQ", Ev
, I1
, XX
},
1308 { "(bad)", XX
, XX
, XX
},
1309 { "sarQ", Ev
, I1
, XX
},
1313 { "rolA", Eb
, CL
, XX
},
1314 { "rorA", Eb
, CL
, XX
},
1315 { "rclA", Eb
, CL
, XX
},
1316 { "rcrA", Eb
, CL
, XX
},
1317 { "shlA", Eb
, CL
, XX
},
1318 { "shrA", Eb
, CL
, XX
},
1319 { "(bad)", XX
, XX
, XX
},
1320 { "sarA", Eb
, CL
, XX
},
1324 { "rolQ", Ev
, CL
, XX
},
1325 { "rorQ", Ev
, CL
, XX
},
1326 { "rclQ", Ev
, CL
, XX
},
1327 { "rcrQ", Ev
, CL
, XX
},
1328 { "shlQ", Ev
, CL
, XX
},
1329 { "shrQ", Ev
, CL
, XX
},
1330 { "(bad)", XX
, XX
, XX
},
1331 { "sarQ", Ev
, CL
, XX
}
1335 { "testA", Eb
, Ib
, XX
},
1336 { "(bad)", Eb
, XX
, XX
},
1337 { "notA", Eb
, XX
, XX
},
1338 { "negA", Eb
, XX
, XX
},
1339 { "mulA", Eb
, XX
, XX
}, /* Don't print the implicit %al register, */
1340 { "imulA", Eb
, XX
, XX
}, /* to distinguish these opcodes from other */
1341 { "divA", Eb
, XX
, XX
}, /* mul/imul opcodes. Do the same for div */
1342 { "idivA", Eb
, XX
, XX
} /* and idiv for consistency. */
1346 { "testQ", Ev
, Iv
, XX
},
1347 { "(bad)", XX
, XX
, XX
},
1348 { "notQ", Ev
, XX
, XX
},
1349 { "negQ", Ev
, XX
, XX
},
1350 { "mulQ", Ev
, XX
, XX
}, /* Don't print the implicit register. */
1351 { "imulQ", Ev
, XX
, XX
},
1352 { "divQ", Ev
, XX
, XX
},
1353 { "idivQ", Ev
, XX
, XX
},
1357 { "incA", Eb
, XX
, XX
},
1358 { "decA", Eb
, XX
, XX
},
1359 { "(bad)", XX
, XX
, XX
},
1360 { "(bad)", XX
, XX
, XX
},
1361 { "(bad)", XX
, XX
, XX
},
1362 { "(bad)", XX
, XX
, XX
},
1363 { "(bad)", XX
, XX
, XX
},
1364 { "(bad)", XX
, XX
, XX
},
1368 { "incQ", Ev
, XX
, XX
},
1369 { "decQ", Ev
, XX
, XX
},
1370 { "callT", indirEv
, XX
, XX
},
1371 { "JcallT", indirEp
, XX
, XX
},
1372 { "jmpT", indirEv
, XX
, XX
},
1373 { "JjmpT", indirEp
, XX
, XX
},
1374 { "pushU", stackEv
, XX
, XX
},
1375 { "(bad)", XX
, XX
, XX
},
1379 { "sldtQ", Ev
, XX
, XX
},
1380 { "strQ", Ev
, XX
, XX
},
1381 { "lldt", Ew
, XX
, XX
},
1382 { "ltr", Ew
, XX
, XX
},
1383 { "verr", Ew
, XX
, XX
},
1384 { "verw", Ew
, XX
, XX
},
1385 { "(bad)", XX
, XX
, XX
},
1386 { "(bad)", XX
, XX
, XX
}
1390 { "sgdtIQ", VMX_Fixup
, 0, XX
, XX
},
1391 { "sidtIQ", PNI_Fixup
, 0, XX
, XX
},
1392 { "lgdt{Q|Q||}", M
, XX
, XX
},
1393 { "lidt{Q|Q||}", SVME_Fixup
, 0, XX
, XX
},
1394 { "smswQ", Ev
, XX
, XX
},
1395 { "(bad)", XX
, XX
, XX
},
1396 { "lmsw", Ew
, XX
, XX
},
1397 { "invlpg", INVLPG_Fixup
, w_mode
, XX
, XX
},
1401 { "(bad)", XX
, XX
, XX
},
1402 { "(bad)", XX
, XX
, XX
},
1403 { "(bad)", XX
, XX
, XX
},
1404 { "(bad)", XX
, XX
, XX
},
1405 { "btQ", Ev
, Ib
, XX
},
1406 { "btsQ", Ev
, Ib
, XX
},
1407 { "btrQ", Ev
, Ib
, XX
},
1408 { "btcQ", Ev
, Ib
, XX
},
1412 { "(bad)", XX
, XX
, XX
},
1413 { "cmpxchg8b", Eq
, XX
, XX
},
1414 { "(bad)", XX
, XX
, XX
},
1415 { "(bad)", XX
, XX
, XX
},
1416 { "(bad)", XX
, XX
, XX
},
1417 { "(bad)", XX
, XX
, XX
},
1418 { "", VM
, XX
, XX
}, /* See OP_VMX. */
1419 { "vmptrst", Eq
, XX
, XX
},
1423 { "(bad)", XX
, XX
, XX
},
1424 { "(bad)", XX
, XX
, XX
},
1425 { "psrlw", MS
, Ib
, XX
},
1426 { "(bad)", XX
, XX
, XX
},
1427 { "psraw", MS
, Ib
, XX
},
1428 { "(bad)", XX
, XX
, XX
},
1429 { "psllw", MS
, Ib
, XX
},
1430 { "(bad)", XX
, XX
, XX
},
1434 { "(bad)", XX
, XX
, XX
},
1435 { "(bad)", XX
, XX
, XX
},
1436 { "psrld", MS
, Ib
, XX
},
1437 { "(bad)", XX
, XX
, XX
},
1438 { "psrad", MS
, Ib
, XX
},
1439 { "(bad)", XX
, XX
, XX
},
1440 { "pslld", MS
, Ib
, XX
},
1441 { "(bad)", XX
, XX
, XX
},
1445 { "(bad)", XX
, XX
, XX
},
1446 { "(bad)", XX
, XX
, XX
},
1447 { "psrlq", MS
, Ib
, XX
},
1448 { "psrldq", MS
, Ib
, XX
},
1449 { "(bad)", XX
, XX
, XX
},
1450 { "(bad)", XX
, XX
, XX
},
1451 { "psllq", MS
, Ib
, XX
},
1452 { "pslldq", MS
, Ib
, XX
},
1456 { "fxsave", Ev
, XX
, XX
},
1457 { "fxrstor", Ev
, XX
, XX
},
1458 { "ldmxcsr", Ev
, XX
, XX
},
1459 { "stmxcsr", Ev
, XX
, XX
},
1460 { "(bad)", XX
, XX
, XX
},
1461 { "lfence", OP_0fae
, 0, XX
, XX
},
1462 { "mfence", OP_0fae
, 0, XX
, XX
},
1463 { "clflush", OP_0fae
, 0, XX
, XX
},
1467 { "prefetchnta", Ev
, XX
, XX
},
1468 { "prefetcht0", Ev
, XX
, XX
},
1469 { "prefetcht1", Ev
, XX
, XX
},
1470 { "prefetcht2", Ev
, XX
, XX
},
1471 { "(bad)", XX
, XX
, XX
},
1472 { "(bad)", XX
, XX
, XX
},
1473 { "(bad)", XX
, XX
, XX
},
1474 { "(bad)", XX
, XX
, XX
},
1478 { "prefetch", Eb
, XX
, XX
},
1479 { "prefetchw", Eb
, XX
, XX
},
1480 { "(bad)", XX
, XX
, XX
},
1481 { "(bad)", XX
, XX
, XX
},
1482 { "(bad)", XX
, XX
, XX
},
1483 { "(bad)", XX
, XX
, XX
},
1484 { "(bad)", XX
, XX
, XX
},
1485 { "(bad)", XX
, XX
, XX
},
1489 { "xstore-rng", OP_0f07
, 0, XX
, XX
},
1490 { "xcrypt-ecb", OP_0f07
, 0, XX
, XX
},
1491 { "xcrypt-cbc", OP_0f07
, 0, XX
, XX
},
1492 { "xcrypt-ctr", OP_0f07
, 0, XX
, XX
},
1493 { "xcrypt-cfb", OP_0f07
, 0, XX
, XX
},
1494 { "xcrypt-ofb", OP_0f07
, 0, XX
, XX
},
1495 { "(bad)", OP_0f07
, 0, XX
, XX
},
1496 { "(bad)", OP_0f07
, 0, XX
, XX
},
1500 { "montmul", OP_0f07
, 0, XX
, XX
},
1501 { "xsha1", OP_0f07
, 0, XX
, XX
},
1502 { "xsha256", OP_0f07
, 0, XX
, XX
},
1503 { "(bad)", OP_0f07
, 0, XX
, XX
},
1504 { "(bad)", OP_0f07
, 0, XX
, XX
},
1505 { "(bad)", OP_0f07
, 0, XX
, XX
},
1506 { "(bad)", OP_0f07
, 0, XX
, XX
},
1507 { "(bad)", OP_0f07
, 0, XX
, XX
},
1511 static const struct dis386 prefix_user_table
[][4] = {
1514 { "addps", XM
, EX
, XX
},
1515 { "addss", XM
, EX
, XX
},
1516 { "addpd", XM
, EX
, XX
},
1517 { "addsd", XM
, EX
, XX
},
1521 { "", XM
, EX
, OPSIMD
}, /* See OP_SIMD_SUFFIX. */
1522 { "", XM
, EX
, OPSIMD
},
1523 { "", XM
, EX
, OPSIMD
},
1524 { "", XM
, EX
, OPSIMD
},
1528 { "cvtpi2ps", XM
, EM
, XX
},
1529 { "cvtsi2ssY", XM
, Ev
, XX
},
1530 { "cvtpi2pd", XM
, EM
, XX
},
1531 { "cvtsi2sdY", XM
, Ev
, XX
},
1535 { "cvtps2pi", MX
, EX
, XX
},
1536 { "cvtss2siY", Gv
, EX
, XX
},
1537 { "cvtpd2pi", MX
, EX
, XX
},
1538 { "cvtsd2siY", Gv
, EX
, XX
},
1542 { "cvttps2pi", MX
, EX
, XX
},
1543 { "cvttss2siY", Gv
, EX
, XX
},
1544 { "cvttpd2pi", MX
, EX
, XX
},
1545 { "cvttsd2siY", Gv
, EX
, XX
},
1549 { "divps", XM
, EX
, XX
},
1550 { "divss", XM
, EX
, XX
},
1551 { "divpd", XM
, EX
, XX
},
1552 { "divsd", XM
, EX
, XX
},
1556 { "maxps", XM
, EX
, XX
},
1557 { "maxss", XM
, EX
, XX
},
1558 { "maxpd", XM
, EX
, XX
},
1559 { "maxsd", XM
, EX
, XX
},
1563 { "minps", XM
, EX
, XX
},
1564 { "minss", XM
, EX
, XX
},
1565 { "minpd", XM
, EX
, XX
},
1566 { "minsd", XM
, EX
, XX
},
1570 { "movups", XM
, EX
, XX
},
1571 { "movss", XM
, EX
, XX
},
1572 { "movupd", XM
, EX
, XX
},
1573 { "movsd", XM
, EX
, XX
},
1577 { "movups", EX
, XM
, XX
},
1578 { "movss", EX
, XM
, XX
},
1579 { "movupd", EX
, XM
, XX
},
1580 { "movsd", EX
, XM
, XX
},
1584 { "mulps", XM
, EX
, XX
},
1585 { "mulss", XM
, EX
, XX
},
1586 { "mulpd", XM
, EX
, XX
},
1587 { "mulsd", XM
, EX
, XX
},
1591 { "rcpps", XM
, EX
, XX
},
1592 { "rcpss", XM
, EX
, XX
},
1593 { "(bad)", XM
, EX
, XX
},
1594 { "(bad)", XM
, EX
, XX
},
1598 { "rsqrtps", XM
, EX
, XX
},
1599 { "rsqrtss", XM
, EX
, XX
},
1600 { "(bad)", XM
, EX
, XX
},
1601 { "(bad)", XM
, EX
, XX
},
1605 { "sqrtps", XM
, EX
, XX
},
1606 { "sqrtss", XM
, EX
, XX
},
1607 { "sqrtpd", XM
, EX
, XX
},
1608 { "sqrtsd", XM
, EX
, XX
},
1612 { "subps", XM
, EX
, XX
},
1613 { "subss", XM
, EX
, XX
},
1614 { "subpd", XM
, EX
, XX
},
1615 { "subsd", XM
, EX
, XX
},
1619 { "(bad)", XM
, EX
, XX
},
1620 { "cvtdq2pd", XM
, EX
, XX
},
1621 { "cvttpd2dq", XM
, EX
, XX
},
1622 { "cvtpd2dq", XM
, EX
, XX
},
1626 { "cvtdq2ps", XM
, EX
, XX
},
1627 { "cvttps2dq",XM
, EX
, XX
},
1628 { "cvtps2dq",XM
, EX
, XX
},
1629 { "(bad)", XM
, EX
, XX
},
1633 { "cvtps2pd", XM
, EX
, XX
},
1634 { "cvtss2sd", XM
, EX
, XX
},
1635 { "cvtpd2ps", XM
, EX
, XX
},
1636 { "cvtsd2ss", XM
, EX
, XX
},
1640 { "maskmovq", MX
, MS
, XX
},
1641 { "(bad)", XM
, EX
, XX
},
1642 { "maskmovdqu", XM
, EX
, XX
},
1643 { "(bad)", XM
, EX
, XX
},
1647 { "movq", MX
, EM
, XX
},
1648 { "movdqu", XM
, EX
, XX
},
1649 { "movdqa", XM
, EX
, XX
},
1650 { "(bad)", XM
, EX
, XX
},
1654 { "movq", EM
, MX
, XX
},
1655 { "movdqu", EX
, XM
, XX
},
1656 { "movdqa", EX
, XM
, XX
},
1657 { "(bad)", EX
, XM
, XX
},
1661 { "(bad)", EX
, XM
, XX
},
1662 { "movq2dq", XM
, MS
, XX
},
1663 { "movq", EX
, XM
, XX
},
1664 { "movdq2q", MX
, XS
, XX
},
1668 { "pshufw", MX
, EM
, Ib
},
1669 { "pshufhw", XM
, EX
, Ib
},
1670 { "pshufd", XM
, EX
, Ib
},
1671 { "pshuflw", XM
, EX
, Ib
},
1675 { "movd", Edq
, MX
, XX
},
1676 { "movq", XM
, EX
, XX
},
1677 { "movd", Edq
, XM
, XX
},
1678 { "(bad)", Ed
, XM
, XX
},
1682 { "(bad)", MX
, EX
, XX
},
1683 { "(bad)", XM
, EX
, XX
},
1684 { "punpckhqdq", XM
, EX
, XX
},
1685 { "(bad)", XM
, EX
, XX
},
1689 { "movntq", EM
, MX
, XX
},
1690 { "(bad)", EM
, XM
, XX
},
1691 { "movntdq", EM
, XM
, XX
},
1692 { "(bad)", EM
, XM
, XX
},
1696 { "(bad)", MX
, EX
, XX
},
1697 { "(bad)", XM
, EX
, XX
},
1698 { "punpcklqdq", XM
, EX
, XX
},
1699 { "(bad)", XM
, EX
, XX
},
1703 { "(bad)", MX
, EX
, XX
},
1704 { "(bad)", XM
, EX
, XX
},
1705 { "addsubpd", XM
, EX
, XX
},
1706 { "addsubps", XM
, EX
, XX
},
1710 { "(bad)", MX
, EX
, XX
},
1711 { "(bad)", XM
, EX
, XX
},
1712 { "haddpd", XM
, EX
, XX
},
1713 { "haddps", XM
, EX
, XX
},
1717 { "(bad)", MX
, EX
, XX
},
1718 { "(bad)", XM
, EX
, XX
},
1719 { "hsubpd", XM
, EX
, XX
},
1720 { "hsubps", XM
, EX
, XX
},
1724 { "movlpX", XM
, EX
, SIMD_Fixup
, 'h' }, /* really only 2 operands */
1725 { "movsldup", XM
, EX
, XX
},
1726 { "movlpd", XM
, EX
, XX
},
1727 { "movddup", XM
, EX
, XX
},
1731 { "movhpX", XM
, EX
, SIMD_Fixup
, 'l' },
1732 { "movshdup", XM
, EX
, XX
},
1733 { "movhpd", XM
, EX
, XX
},
1734 { "(bad)", XM
, EX
, XX
},
1738 { "(bad)", XM
, EX
, XX
},
1739 { "(bad)", XM
, EX
, XX
},
1740 { "(bad)", XM
, EX
, XX
},
1741 { "lddqu", XM
, M
, XX
},
1745 static const struct dis386 x86_64_table
[][2] = {
1747 { "arpl", Ew
, Gw
, XX
},
1748 { "movs{||lq|xd}", Gv
, Ed
, XX
},
1752 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1764 FETCH_DATA (the_info
, codep
+ 1);
1768 /* REX prefixes family. */
1785 if (address_mode
== mode_64bit
)
1791 prefixes
|= PREFIX_REPZ
;
1794 prefixes
|= PREFIX_REPNZ
;
1797 prefixes
|= PREFIX_LOCK
;
1800 prefixes
|= PREFIX_CS
;
1803 prefixes
|= PREFIX_SS
;
1806 prefixes
|= PREFIX_DS
;
1809 prefixes
|= PREFIX_ES
;
1812 prefixes
|= PREFIX_FS
;
1815 prefixes
|= PREFIX_GS
;
1818 prefixes
|= PREFIX_DATA
;
1821 prefixes
|= PREFIX_ADDR
;
1824 /* fwait is really an instruction. If there are prefixes
1825 before the fwait, they belong to the fwait, *not* to the
1826 following instruction. */
1827 if (prefixes
|| rex
)
1829 prefixes
|= PREFIX_FWAIT
;
1833 prefixes
= PREFIX_FWAIT
;
1838 /* Rex is ignored when followed by another prefix. */
1849 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
1853 prefix_name (int pref
, int sizeflag
)
1857 /* REX prefixes family. */
1909 return (sizeflag
& DFLAG
) ? "data16" : "data32";
1911 if (address_mode
== mode_64bit
)
1912 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
1914 return (sizeflag
& AFLAG
) ? "addr16" : "addr32";
1922 static char op1out
[100], op2out
[100], op3out
[100];
1923 static int op_ad
, op_index
[3];
1924 static int two_source_ops
;
1925 static bfd_vma op_address
[3];
1926 static bfd_vma op_riprel
[3];
1927 static bfd_vma start_pc
;
1930 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1931 * (see topic "Redundant prefixes" in the "Differences from 8086"
1932 * section of the "Virtual 8086 Mode" chapter.)
1933 * 'pc' should be the address of this instruction, it will
1934 * be used to print the target address if this is a relative jump or call
1935 * The function returns the length of this instruction in bytes.
1938 static char intel_syntax
;
1939 static char open_char
;
1940 static char close_char
;
1941 static char separator_char
;
1942 static char scale_char
;
1944 /* Here for backwards compatibility. When gdb stops using
1945 print_insn_i386_att and print_insn_i386_intel these functions can
1946 disappear, and print_insn_i386 be merged into print_insn. */
1948 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
1952 return print_insn (pc
, info
);
1956 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
1960 return print_insn (pc
, info
);
1964 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
1968 return print_insn (pc
, info
);
1972 print_insn (bfd_vma pc
, disassemble_info
*info
)
1974 const struct dis386
*dp
;
1976 char *first
, *second
, *third
;
1978 unsigned char uses_SSE_prefix
, uses_LOCK_prefix
;
1981 struct dis_private priv
;
1983 if (info
->mach
== bfd_mach_x86_64_intel_syntax
1984 || info
->mach
== bfd_mach_x86_64
)
1985 address_mode
= mode_64bit
;
1987 address_mode
= mode_32bit
;
1989 if (intel_syntax
== (char) -1)
1990 intel_syntax
= (info
->mach
== bfd_mach_i386_i386_intel_syntax
1991 || info
->mach
== bfd_mach_x86_64_intel_syntax
);
1993 if (info
->mach
== bfd_mach_i386_i386
1994 || info
->mach
== bfd_mach_x86_64
1995 || info
->mach
== bfd_mach_i386_i386_intel_syntax
1996 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
1997 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
1998 else if (info
->mach
== bfd_mach_i386_i8086
)
1999 priv
.orig_sizeflag
= 0;
2003 for (p
= info
->disassembler_options
; p
!= NULL
; )
2005 if (strncmp (p
, "x86-64", 6) == 0)
2007 address_mode
= mode_64bit
;
2008 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2010 else if (strncmp (p
, "i386", 4) == 0)
2012 address_mode
= mode_32bit
;
2013 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
2015 else if (strncmp (p
, "i8086", 5) == 0)
2017 address_mode
= mode_16bit
;
2018 priv
.orig_sizeflag
= 0;
2020 else if (strncmp (p
, "intel", 5) == 0)
2024 else if (strncmp (p
, "att", 3) == 0)
2028 else if (strncmp (p
, "addr", 4) == 0)
2030 if (p
[4] == '1' && p
[5] == '6')
2031 priv
.orig_sizeflag
&= ~AFLAG
;
2032 else if (p
[4] == '3' && p
[5] == '2')
2033 priv
.orig_sizeflag
|= AFLAG
;
2035 else if (strncmp (p
, "data", 4) == 0)
2037 if (p
[4] == '1' && p
[5] == '6')
2038 priv
.orig_sizeflag
&= ~DFLAG
;
2039 else if (p
[4] == '3' && p
[5] == '2')
2040 priv
.orig_sizeflag
|= DFLAG
;
2042 else if (strncmp (p
, "suffix", 6) == 0)
2043 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
2045 p
= strchr (p
, ',');
2052 names64
= intel_names64
;
2053 names32
= intel_names32
;
2054 names16
= intel_names16
;
2055 names8
= intel_names8
;
2056 names8rex
= intel_names8rex
;
2057 names_seg
= intel_names_seg
;
2058 index16
= intel_index16
;
2061 separator_char
= '+';
2066 names64
= att_names64
;
2067 names32
= att_names32
;
2068 names16
= att_names16
;
2069 names8
= att_names8
;
2070 names8rex
= att_names8rex
;
2071 names_seg
= att_names_seg
;
2072 index16
= att_index16
;
2075 separator_char
= ',';
2079 /* The output looks better if we put 7 bytes on a line, since that
2080 puts most long word instructions on a single line. */
2081 info
->bytes_per_line
= 7;
2083 info
->private_data
= &priv
;
2084 priv
.max_fetched
= priv
.the_buffer
;
2085 priv
.insn_start
= pc
;
2092 op_index
[0] = op_index
[1] = op_index
[2] = -1;
2096 start_codep
= priv
.the_buffer
;
2097 codep
= priv
.the_buffer
;
2099 if (setjmp (priv
.bailout
) != 0)
2103 /* Getting here means we tried for data but didn't get it. That
2104 means we have an incomplete instruction of some sort. Just
2105 print the first byte as a prefix or a .byte pseudo-op. */
2106 if (codep
> priv
.the_buffer
)
2108 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2110 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
2113 /* Just print the first byte as a .byte instruction. */
2114 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
2115 (unsigned int) priv
.the_buffer
[0]);
2128 sizeflag
= priv
.orig_sizeflag
;
2130 FETCH_DATA (info
, codep
+ 1);
2131 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
2133 if (((prefixes
& PREFIX_FWAIT
)
2134 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
2135 || (rex
&& rex_used
))
2139 /* fwait not followed by floating point instruction, or rex followed
2140 by other prefixes. Print the first prefix. */
2141 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2143 name
= INTERNAL_DISASSEMBLER_ERROR
;
2144 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
2150 FETCH_DATA (info
, codep
+ 2);
2151 dp
= &dis386_twobyte
[*++codep
];
2152 need_modrm
= twobyte_has_modrm
[*codep
];
2153 uses_SSE_prefix
= twobyte_uses_SSE_prefix
[*codep
];
2154 uses_LOCK_prefix
= (*codep
& ~0x02) == 0x20;
2158 dp
= &dis386
[*codep
];
2159 need_modrm
= onebyte_has_modrm
[*codep
];
2160 uses_SSE_prefix
= 0;
2161 uses_LOCK_prefix
= 0;
2165 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_REPZ
))
2168 used_prefixes
|= PREFIX_REPZ
;
2170 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_REPNZ
))
2173 used_prefixes
|= PREFIX_REPNZ
;
2175 if (!uses_LOCK_prefix
&& (prefixes
& PREFIX_LOCK
))
2178 used_prefixes
|= PREFIX_LOCK
;
2181 if (prefixes
& PREFIX_ADDR
)
2184 if (dp
->bytemode3
!= loop_jcxz_mode
|| intel_syntax
)
2186 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
2187 oappend ("addr32 ");
2189 oappend ("addr16 ");
2190 used_prefixes
|= PREFIX_ADDR
;
2194 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_DATA
))
2197 if (dp
->bytemode3
== cond_jump_mode
2198 && dp
->bytemode1
== v_mode
2201 if (sizeflag
& DFLAG
)
2202 oappend ("data32 ");
2204 oappend ("data16 ");
2205 used_prefixes
|= PREFIX_DATA
;
2211 FETCH_DATA (info
, codep
+ 1);
2212 mod
= (*codep
>> 6) & 3;
2213 reg
= (*codep
>> 3) & 7;
2217 if (dp
->name
== NULL
&& dp
->bytemode1
== FLOATCODE
)
2224 if (dp
->name
== NULL
)
2226 switch (dp
->bytemode1
)
2229 dp
= &grps
[dp
->bytemode2
][reg
];
2232 case USE_PREFIX_USER_TABLE
:
2234 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
2235 if (prefixes
& PREFIX_REPZ
)
2239 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2240 if (prefixes
& PREFIX_DATA
)
2244 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
2245 if (prefixes
& PREFIX_REPNZ
)
2249 dp
= &prefix_user_table
[dp
->bytemode2
][index
];
2252 case X86_64_SPECIAL
:
2253 index
= address_mode
== mode_64bit
? 1 : 0;
2254 dp
= &x86_64_table
[dp
->bytemode2
][index
];
2258 oappend (INTERNAL_DISASSEMBLER_ERROR
);
2263 if (putop (dp
->name
, sizeflag
) == 0)
2268 (*dp
->op1
) (dp
->bytemode1
, sizeflag
);
2273 (*dp
->op2
) (dp
->bytemode2
, sizeflag
);
2278 (*dp
->op3
) (dp
->bytemode3
, sizeflag
);
2282 /* See if any prefixes were not used. If so, print the first one
2283 separately. If we don't do this, we'll wind up printing an
2284 instruction stream which does not precisely correspond to the
2285 bytes we are disassembling. */
2286 if ((prefixes
& ~used_prefixes
) != 0)
2290 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2292 name
= INTERNAL_DISASSEMBLER_ERROR
;
2293 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
2296 if (rex
& ~rex_used
)
2299 name
= prefix_name (rex
| 0x40, priv
.orig_sizeflag
);
2301 name
= INTERNAL_DISASSEMBLER_ERROR
;
2302 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
2305 obufp
= obuf
+ strlen (obuf
);
2306 for (i
= strlen (obuf
); i
< 6; i
++)
2309 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
2311 /* The enter and bound instructions are printed with operands in the same
2312 order as the intel book; everything else is printed in reverse order. */
2313 if (intel_syntax
|| two_source_ops
)
2318 op_ad
= op_index
[0];
2319 op_index
[0] = op_index
[2];
2320 op_index
[2] = op_ad
;
2331 if (op_index
[0] != -1 && !op_riprel
[0])
2332 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[0]], info
);
2334 (*info
->fprintf_func
) (info
->stream
, "%s", first
);
2340 (*info
->fprintf_func
) (info
->stream
, ",");
2341 if (op_index
[1] != -1 && !op_riprel
[1])
2342 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[1]], info
);
2344 (*info
->fprintf_func
) (info
->stream
, "%s", second
);
2350 (*info
->fprintf_func
) (info
->stream
, ",");
2351 if (op_index
[2] != -1 && !op_riprel
[2])
2352 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[2]], info
);
2354 (*info
->fprintf_func
) (info
->stream
, "%s", third
);
2356 for (i
= 0; i
< 3; i
++)
2357 if (op_index
[i
] != -1 && op_riprel
[i
])
2359 (*info
->fprintf_func
) (info
->stream
, " # ");
2360 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
2361 + op_address
[op_index
[i
]]), info
);
2363 return codep
- priv
.the_buffer
;
2366 static const char *float_mem
[] = {
2441 static const unsigned char float_mem_mode
[] = {
2517 #define STi OP_STi, 0
2519 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
2520 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
2521 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
2522 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
2523 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
2524 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
2525 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
2526 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
2527 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
2529 static const struct dis386 float_reg
[][8] = {
2532 { "fadd", ST
, STi
, XX
},
2533 { "fmul", ST
, STi
, XX
},
2534 { "fcom", STi
, XX
, XX
},
2535 { "fcomp", STi
, XX
, XX
},
2536 { "fsub", ST
, STi
, XX
},
2537 { "fsubr", ST
, STi
, XX
},
2538 { "fdiv", ST
, STi
, XX
},
2539 { "fdivr", ST
, STi
, XX
},
2543 { "fld", STi
, XX
, XX
},
2544 { "fxch", STi
, XX
, XX
},
2546 { "(bad)", XX
, XX
, XX
},
2554 { "fcmovb", ST
, STi
, XX
},
2555 { "fcmove", ST
, STi
, XX
},
2556 { "fcmovbe",ST
, STi
, XX
},
2557 { "fcmovu", ST
, STi
, XX
},
2558 { "(bad)", XX
, XX
, XX
},
2560 { "(bad)", XX
, XX
, XX
},
2561 { "(bad)", XX
, XX
, XX
},
2565 { "fcmovnb",ST
, STi
, XX
},
2566 { "fcmovne",ST
, STi
, XX
},
2567 { "fcmovnbe",ST
, STi
, XX
},
2568 { "fcmovnu",ST
, STi
, XX
},
2570 { "fucomi", ST
, STi
, XX
},
2571 { "fcomi", ST
, STi
, XX
},
2572 { "(bad)", XX
, XX
, XX
},
2576 { "fadd", STi
, ST
, XX
},
2577 { "fmul", STi
, ST
, XX
},
2578 { "(bad)", XX
, XX
, XX
},
2579 { "(bad)", XX
, XX
, XX
},
2581 { "fsub", STi
, ST
, XX
},
2582 { "fsubr", STi
, ST
, XX
},
2583 { "fdiv", STi
, ST
, XX
},
2584 { "fdivr", STi
, ST
, XX
},
2586 { "fsubr", STi
, ST
, XX
},
2587 { "fsub", STi
, ST
, XX
},
2588 { "fdivr", STi
, ST
, XX
},
2589 { "fdiv", STi
, ST
, XX
},
2594 { "ffree", STi
, XX
, XX
},
2595 { "(bad)", XX
, XX
, XX
},
2596 { "fst", STi
, XX
, XX
},
2597 { "fstp", STi
, XX
, XX
},
2598 { "fucom", STi
, XX
, XX
},
2599 { "fucomp", STi
, XX
, XX
},
2600 { "(bad)", XX
, XX
, XX
},
2601 { "(bad)", XX
, XX
, XX
},
2605 { "faddp", STi
, ST
, XX
},
2606 { "fmulp", STi
, ST
, XX
},
2607 { "(bad)", XX
, XX
, XX
},
2610 { "fsubp", STi
, ST
, XX
},
2611 { "fsubrp", STi
, ST
, XX
},
2612 { "fdivp", STi
, ST
, XX
},
2613 { "fdivrp", STi
, ST
, XX
},
2615 { "fsubrp", STi
, ST
, XX
},
2616 { "fsubp", STi
, ST
, XX
},
2617 { "fdivrp", STi
, ST
, XX
},
2618 { "fdivp", STi
, ST
, XX
},
2623 { "ffreep", STi
, XX
, XX
},
2624 { "(bad)", XX
, XX
, XX
},
2625 { "(bad)", XX
, XX
, XX
},
2626 { "(bad)", XX
, XX
, XX
},
2628 { "fucomip",ST
, STi
, XX
},
2629 { "fcomip", ST
, STi
, XX
},
2630 { "(bad)", XX
, XX
, XX
},
2634 static char *fgrps
[][8] = {
2637 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2642 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2647 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2652 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2657 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2662 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2667 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2668 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2673 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2678 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2683 dofloat (int sizeflag
)
2685 const struct dis386
*dp
;
2686 unsigned char floatop
;
2688 floatop
= codep
[-1];
2692 int fp_indx
= (floatop
- 0xd8) * 8 + reg
;
2694 putop (float_mem
[fp_indx
], sizeflag
);
2697 OP_E (float_mem_mode
[fp_indx
], sizeflag
);
2700 /* Skip mod/rm byte. */
2704 dp
= &float_reg
[floatop
- 0xd8][reg
];
2705 if (dp
->name
== NULL
)
2707 putop (fgrps
[dp
->bytemode1
][rm
], sizeflag
);
2709 /* Instruction fnstsw is only one with strange arg. */
2710 if (floatop
== 0xdf && codep
[-1] == 0xe0)
2711 strcpy (op1out
, names16
[0]);
2715 putop (dp
->name
, sizeflag
);
2720 (*dp
->op1
) (dp
->bytemode1
, sizeflag
);
2725 (*dp
->op2
) (dp
->bytemode2
, sizeflag
);
2730 OP_ST (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
2732 oappend ("%st" + intel_syntax
);
2736 OP_STi (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
2738 sprintf (scratchbuf
, "%%st(%d)", rm
);
2739 oappend (scratchbuf
+ intel_syntax
);
2742 /* Capital letters in template are macros. */
2744 putop (const char *template, int sizeflag
)
2749 for (p
= template; *p
; p
++)
2760 if (address_mode
== mode_64bit
)
2768 /* Alternative not valid. */
2769 strcpy (obuf
, "(bad)");
2773 else if (*p
== '\0')
2794 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
2800 if (sizeflag
& SUFFIX_ALWAYS
)
2804 if (intel_syntax
&& !alt
)
2806 if ((prefixes
& PREFIX_DATA
) || (sizeflag
& SUFFIX_ALWAYS
))
2808 if (sizeflag
& DFLAG
)
2809 *obufp
++ = intel_syntax
? 'd' : 'l';
2811 *obufp
++ = intel_syntax
? 'w' : 's';
2812 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2815 case 'E': /* For jcxz/jecxz */
2816 if (address_mode
== mode_64bit
)
2818 if (sizeflag
& AFLAG
)
2824 if (sizeflag
& AFLAG
)
2826 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
2831 if ((prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
2833 if (sizeflag
& AFLAG
)
2834 *obufp
++ = address_mode
== mode_64bit
? 'q' : 'l';
2836 *obufp
++ = address_mode
== mode_64bit
? 'l' : 'w';
2837 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
2843 if ((prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
2844 || (prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
2846 used_prefixes
|= prefixes
& (PREFIX_CS
| PREFIX_DS
);
2849 if (prefixes
& PREFIX_DS
)
2863 if (address_mode
== mode_64bit
&& (sizeflag
& SUFFIX_ALWAYS
))
2872 if (sizeflag
& SUFFIX_ALWAYS
)
2876 if ((prefixes
& PREFIX_FWAIT
) == 0)
2879 used_prefixes
|= PREFIX_FWAIT
;
2882 USED_REX (REX_MODE64
);
2883 if (rex
& REX_MODE64
)
2891 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
2900 if ((prefixes
& PREFIX_DATA
)
2901 || (rex
& REX_MODE64
)
2902 || (sizeflag
& SUFFIX_ALWAYS
))
2904 USED_REX (REX_MODE64
);
2905 if (rex
& REX_MODE64
)
2909 if (sizeflag
& DFLAG
)
2914 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2920 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
2922 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
2928 if (intel_syntax
&& !alt
)
2930 USED_REX (REX_MODE64
);
2931 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
2933 if (rex
& REX_MODE64
)
2937 if (sizeflag
& DFLAG
)
2938 *obufp
++ = intel_syntax
? 'd' : 'l';
2942 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2946 USED_REX (REX_MODE64
);
2949 if (rex
& REX_MODE64
)
2954 else if (sizeflag
& DFLAG
)
2967 if (rex
& REX_MODE64
)
2969 else if (sizeflag
& DFLAG
)
2974 if (!(rex
& REX_MODE64
))
2975 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2980 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
2982 if (sizeflag
& SUFFIX_ALWAYS
)
2990 if (sizeflag
& SUFFIX_ALWAYS
)
2992 if (rex
& REX_MODE64
)
2996 if (sizeflag
& DFLAG
)
3000 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3005 if (prefixes
& PREFIX_DATA
)
3009 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3014 if (rex
& REX_MODE64
)
3016 USED_REX (REX_MODE64
);
3020 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
3022 /* operand size flag for cwtl, cbtw */
3026 else if (sizeflag
& DFLAG
)
3037 if (sizeflag
& DFLAG
)
3048 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3058 oappend (const char *s
)
3061 obufp
+= strlen (s
);
3067 if (prefixes
& PREFIX_CS
)
3069 used_prefixes
|= PREFIX_CS
;
3070 oappend ("%cs:" + intel_syntax
);
3072 if (prefixes
& PREFIX_DS
)
3074 used_prefixes
|= PREFIX_DS
;
3075 oappend ("%ds:" + intel_syntax
);
3077 if (prefixes
& PREFIX_SS
)
3079 used_prefixes
|= PREFIX_SS
;
3080 oappend ("%ss:" + intel_syntax
);
3082 if (prefixes
& PREFIX_ES
)
3084 used_prefixes
|= PREFIX_ES
;
3085 oappend ("%es:" + intel_syntax
);
3087 if (prefixes
& PREFIX_FS
)
3089 used_prefixes
|= PREFIX_FS
;
3090 oappend ("%fs:" + intel_syntax
);
3092 if (prefixes
& PREFIX_GS
)
3094 used_prefixes
|= PREFIX_GS
;
3095 oappend ("%gs:" + intel_syntax
);
3100 OP_indirE (int bytemode
, int sizeflag
)
3104 OP_E (bytemode
, sizeflag
);
3108 print_operand_value (char *buf
, int hex
, bfd_vma disp
)
3110 if (address_mode
== mode_64bit
)
3118 sprintf_vma (tmp
, disp
);
3119 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+ 1]; i
++);
3120 strcpy (buf
+ 2, tmp
+ i
);
3124 bfd_signed_vma v
= disp
;
3131 /* Check for possible overflow on 0x8000000000000000. */
3134 strcpy (buf
, "9223372036854775808");
3148 tmp
[28 - i
] = (v
% 10) + '0';
3152 strcpy (buf
, tmp
+ 29 - i
);
3158 sprintf (buf
, "0x%x", (unsigned int) disp
);
3160 sprintf (buf
, "%d", (int) disp
);
3165 intel_operand_size (int bytemode
, int sizeflag
)
3170 oappend ("BYTE PTR ");
3174 oappend ("WORD PTR ");
3177 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3179 oappend ("QWORD PTR ");
3180 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3186 USED_REX (REX_MODE64
);
3187 if (rex
& REX_MODE64
)
3188 oappend ("QWORD PTR ");
3189 else if ((sizeflag
& DFLAG
) || bytemode
== dq_mode
)
3190 oappend ("DWORD PTR ");
3192 oappend ("WORD PTR ");
3193 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3196 oappend ("DWORD PTR ");
3199 oappend ("QWORD PTR ");
3202 if (address_mode
== mode_64bit
)
3203 oappend ("QWORD PTR ");
3205 oappend ("DWORD PTR ");
3208 if (sizeflag
& DFLAG
)
3209 oappend ("FWORD PTR ");
3211 oappend ("DWORD PTR ");
3212 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3215 oappend ("TBYTE PTR ");
3218 oappend ("XMMWORD PTR ");
3226 OP_E (int bytemode
, int sizeflag
)
3231 USED_REX (REX_EXTZ
);
3235 /* Skip mod/rm byte. */
3246 oappend (names8rex
[rm
+ add
]);
3248 oappend (names8
[rm
+ add
]);
3251 oappend (names16
[rm
+ add
]);
3254 oappend (names32
[rm
+ add
]);
3257 oappend (names64
[rm
+ add
]);
3260 if (address_mode
== mode_64bit
)
3261 oappend (names64
[rm
+ add
]);
3263 oappend (names32
[rm
+ add
]);
3266 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3268 oappend (names64
[rm
+ add
]);
3269 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3277 USED_REX (REX_MODE64
);
3278 if (rex
& REX_MODE64
)
3279 oappend (names64
[rm
+ add
]);
3280 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
3281 oappend (names32
[rm
+ add
]);
3283 oappend (names16
[rm
+ add
]);
3284 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3289 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3297 intel_operand_size (bytemode
, sizeflag
);
3300 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
) /* 32 bit address mode */
3315 FETCH_DATA (the_info
, codep
+ 1);
3316 index
= (*codep
>> 3) & 7;
3317 if (address_mode
== mode_64bit
|| index
!= 0x4)
3318 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
3319 scale
= (*codep
>> 6) & 3;
3321 USED_REX (REX_EXTY
);
3331 if ((base
& 7) == 5)
3334 if (address_mode
== mode_64bit
&& !havesib
)
3340 FETCH_DATA (the_info
, codep
+ 1);
3342 if ((disp
& 0x80) != 0)
3351 if (mod
!= 0 || (base
& 7) == 5)
3353 print_operand_value (scratchbuf
, !riprel
, disp
);
3354 oappend (scratchbuf
);
3362 if (havebase
|| (havesib
&& (index
!= 4 || scale
!= 0)))
3364 *obufp
++ = open_char
;
3365 if (intel_syntax
&& riprel
)
3369 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
3370 ? names64
[base
] : names32
[base
]);
3375 if (!intel_syntax
|| havebase
)
3377 *obufp
++ = separator_char
;
3380 oappend (address_mode
== mode_64bit
&& (sizeflag
& AFLAG
)
3381 ? names64
[index
] : names32
[index
]);
3383 if (scale
!= 0 || (!intel_syntax
&& index
!= 4))
3385 *obufp
++ = scale_char
;
3387 sprintf (scratchbuf
, "%d", 1 << scale
);
3388 oappend (scratchbuf
);
3391 if (intel_syntax
&& disp
)
3393 if ((bfd_signed_vma
) disp
> 0)
3402 disp
= - (bfd_signed_vma
) disp
;
3405 print_operand_value (scratchbuf
, mod
!= 1, disp
);
3406 oappend (scratchbuf
);
3409 *obufp
++ = close_char
;
3412 else if (intel_syntax
)
3414 if (mod
!= 0 || (base
& 7) == 5)
3416 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
3417 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
3421 oappend (names_seg
[ds_reg
- es_reg
]);
3424 print_operand_value (scratchbuf
, 1, disp
);
3425 oappend (scratchbuf
);
3430 { /* 16 bit address mode */
3437 if ((disp
& 0x8000) != 0)
3442 FETCH_DATA (the_info
, codep
+ 1);
3444 if ((disp
& 0x80) != 0)
3449 if ((disp
& 0x8000) != 0)
3455 if (mod
!= 0 || rm
== 6)
3457 print_operand_value (scratchbuf
, 0, disp
);
3458 oappend (scratchbuf
);
3461 if (mod
!= 0 || rm
!= 6)
3463 *obufp
++ = open_char
;
3465 oappend (index16
[rm
]);
3466 if (intel_syntax
&& disp
)
3468 if ((bfd_signed_vma
) disp
> 0)
3477 disp
= - (bfd_signed_vma
) disp
;
3480 print_operand_value (scratchbuf
, mod
!= 1, disp
);
3481 oappend (scratchbuf
);
3484 *obufp
++ = close_char
;
3487 else if (intel_syntax
)
3489 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
3490 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
3494 oappend (names_seg
[ds_reg
- es_reg
]);
3497 print_operand_value (scratchbuf
, 1, disp
& 0xffff);
3498 oappend (scratchbuf
);
3504 OP_G (int bytemode
, int sizeflag
)
3507 USED_REX (REX_EXTX
);
3515 oappend (names8rex
[reg
+ add
]);
3517 oappend (names8
[reg
+ add
]);
3520 oappend (names16
[reg
+ add
]);
3523 oappend (names32
[reg
+ add
]);
3526 oappend (names64
[reg
+ add
]);
3531 USED_REX (REX_MODE64
);
3532 if (rex
& REX_MODE64
)
3533 oappend (names64
[reg
+ add
]);
3534 else if ((sizeflag
& DFLAG
) || bytemode
!= v_mode
)
3535 oappend (names32
[reg
+ add
]);
3537 oappend (names16
[reg
+ add
]);
3538 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3541 if (address_mode
== mode_64bit
)
3542 oappend (names64
[reg
+ add
]);
3544 oappend (names32
[reg
+ add
]);
3547 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3560 FETCH_DATA (the_info
, codep
+ 8);
3561 a
= *codep
++ & 0xff;
3562 a
|= (*codep
++ & 0xff) << 8;
3563 a
|= (*codep
++ & 0xff) << 16;
3564 a
|= (*codep
++ & 0xff) << 24;
3565 b
= *codep
++ & 0xff;
3566 b
|= (*codep
++ & 0xff) << 8;
3567 b
|= (*codep
++ & 0xff) << 16;
3568 b
|= (*codep
++ & 0xff) << 24;
3569 x
= a
+ ((bfd_vma
) b
<< 32);
3577 static bfd_signed_vma
3580 bfd_signed_vma x
= 0;
3582 FETCH_DATA (the_info
, codep
+ 4);
3583 x
= *codep
++ & (bfd_signed_vma
) 0xff;
3584 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
3585 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
3586 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
3590 static bfd_signed_vma
3593 bfd_signed_vma x
= 0;
3595 FETCH_DATA (the_info
, codep
+ 4);
3596 x
= *codep
++ & (bfd_signed_vma
) 0xff;
3597 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
3598 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
3599 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
3601 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
3611 FETCH_DATA (the_info
, codep
+ 2);
3612 x
= *codep
++ & 0xff;
3613 x
|= (*codep
++ & 0xff) << 8;
3618 set_op (bfd_vma op
, int riprel
)
3620 op_index
[op_ad
] = op_ad
;
3621 if (address_mode
== mode_64bit
)
3623 op_address
[op_ad
] = op
;
3624 op_riprel
[op_ad
] = riprel
;
3628 /* Mask to get a 32-bit address. */
3629 op_address
[op_ad
] = op
& 0xffffffff;
3630 op_riprel
[op_ad
] = riprel
& 0xffffffff;
3635 OP_REG (int code
, int sizeflag
)
3639 USED_REX (REX_EXTZ
);
3651 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
3652 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
3653 s
= names16
[code
- ax_reg
+ add
];
3655 case es_reg
: case ss_reg
: case cs_reg
:
3656 case ds_reg
: case fs_reg
: case gs_reg
:
3657 s
= names_seg
[code
- es_reg
+ add
];
3659 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
3660 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
3663 s
= names8rex
[code
- al_reg
+ add
];
3665 s
= names8
[code
- al_reg
];
3667 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
3668 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
3669 if (address_mode
== mode_64bit
&& (sizeflag
& DFLAG
))
3671 s
= names64
[code
- rAX_reg
+ add
];
3674 code
+= eAX_reg
- rAX_reg
;
3676 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
3677 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
3678 USED_REX (REX_MODE64
);
3679 if (rex
& REX_MODE64
)
3680 s
= names64
[code
- eAX_reg
+ add
];
3681 else if (sizeflag
& DFLAG
)
3682 s
= names32
[code
- eAX_reg
+ add
];
3684 s
= names16
[code
- eAX_reg
+ add
];
3685 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3688 s
= INTERNAL_DISASSEMBLER_ERROR
;
3695 OP_IMREG (int code
, int sizeflag
)
3707 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
3708 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
3709 s
= names16
[code
- ax_reg
];
3711 case es_reg
: case ss_reg
: case cs_reg
:
3712 case ds_reg
: case fs_reg
: case gs_reg
:
3713 s
= names_seg
[code
- es_reg
];
3715 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
3716 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
3719 s
= names8rex
[code
- al_reg
];
3721 s
= names8
[code
- al_reg
];
3723 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
3724 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
3725 USED_REX (REX_MODE64
);
3726 if (rex
& REX_MODE64
)
3727 s
= names64
[code
- eAX_reg
];
3728 else if (sizeflag
& DFLAG
)
3729 s
= names32
[code
- eAX_reg
];
3731 s
= names16
[code
- eAX_reg
];
3732 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3735 s
= INTERNAL_DISASSEMBLER_ERROR
;
3742 OP_I (int bytemode
, int sizeflag
)
3745 bfd_signed_vma mask
= -1;
3750 FETCH_DATA (the_info
, codep
+ 1);
3755 if (address_mode
== mode_64bit
)
3762 USED_REX (REX_MODE64
);
3763 if (rex
& REX_MODE64
)
3765 else if (sizeflag
& DFLAG
)
3775 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3786 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3791 scratchbuf
[0] = '$';
3792 print_operand_value (scratchbuf
+ 1, 1, op
);
3793 oappend (scratchbuf
+ intel_syntax
);
3794 scratchbuf
[0] = '\0';
3798 OP_I64 (int bytemode
, int sizeflag
)
3801 bfd_signed_vma mask
= -1;
3803 if (address_mode
!= mode_64bit
)
3805 OP_I (bytemode
, sizeflag
);
3812 FETCH_DATA (the_info
, codep
+ 1);
3817 USED_REX (REX_MODE64
);
3818 if (rex
& REX_MODE64
)
3820 else if (sizeflag
& DFLAG
)
3830 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3837 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3842 scratchbuf
[0] = '$';
3843 print_operand_value (scratchbuf
+ 1, 1, op
);
3844 oappend (scratchbuf
+ intel_syntax
);
3845 scratchbuf
[0] = '\0';
3849 OP_sI (int bytemode
, int sizeflag
)
3852 bfd_signed_vma mask
= -1;
3857 FETCH_DATA (the_info
, codep
+ 1);
3859 if ((op
& 0x80) != 0)
3864 USED_REX (REX_MODE64
);
3865 if (rex
& REX_MODE64
)
3867 else if (sizeflag
& DFLAG
)
3876 if ((op
& 0x8000) != 0)
3879 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3884 if ((op
& 0x8000) != 0)
3888 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3892 scratchbuf
[0] = '$';
3893 print_operand_value (scratchbuf
+ 1, 1, op
);
3894 oappend (scratchbuf
+ intel_syntax
);
3898 OP_J (int bytemode
, int sizeflag
)
3906 FETCH_DATA (the_info
, codep
+ 1);
3908 if ((disp
& 0x80) != 0)
3912 if ((sizeflag
& DFLAG
) || (rex
& REX_MODE64
))
3917 /* For some reason, a data16 prefix on a jump instruction
3918 means that the pc is masked to 16 bits after the
3919 displacement is added! */
3924 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3927 disp
= (start_pc
+ codep
- start_codep
+ disp
) & mask
;
3929 print_operand_value (scratchbuf
, 1, disp
);
3930 oappend (scratchbuf
);
3934 OP_SEG (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
3936 oappend (names_seg
[reg
]);
3940 OP_DIR (int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
3944 if (sizeflag
& DFLAG
)
3954 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3956 sprintf (scratchbuf
, "0x%x:0x%x", seg
, offset
);
3958 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
3959 oappend (scratchbuf
);
3963 OP_OFF (int bytemode
, int sizeflag
)
3967 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
3968 intel_operand_size (bytemode
, sizeflag
);
3971 if ((sizeflag
& AFLAG
) || address_mode
== mode_64bit
)
3978 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
3979 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
3981 oappend (names_seg
[ds_reg
- es_reg
]);
3985 print_operand_value (scratchbuf
, 1, off
);
3986 oappend (scratchbuf
);
3990 OP_OFF64 (int bytemode
, int sizeflag
)
3994 if (address_mode
!= mode_64bit
)
3996 OP_OFF (bytemode
, sizeflag
);
4000 if (intel_syntax
&& (sizeflag
& SUFFIX_ALWAYS
))
4001 intel_operand_size (bytemode
, sizeflag
);
4008 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
4009 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
4011 oappend (names_seg
[ds_reg
- es_reg
]);
4015 print_operand_value (scratchbuf
, 1, off
);
4016 oappend (scratchbuf
);
4020 ptr_reg (int code
, int sizeflag
)
4024 *obufp
++ = open_char
;
4025 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
4026 if (address_mode
== mode_64bit
)
4028 if (!(sizeflag
& AFLAG
))
4029 s
= names32
[code
- eAX_reg
];
4031 s
= names64
[code
- eAX_reg
];
4033 else if (sizeflag
& AFLAG
)
4034 s
= names32
[code
- eAX_reg
];
4036 s
= names16
[code
- eAX_reg
];
4038 *obufp
++ = close_char
;
4043 OP_ESreg (int code
, int sizeflag
)
4046 intel_operand_size (codep
[-1] & 1 ? v_mode
: b_mode
, sizeflag
);
4047 oappend ("%es:" + intel_syntax
);
4048 ptr_reg (code
, sizeflag
);
4052 OP_DSreg (int code
, int sizeflag
)
4055 intel_operand_size (codep
[-1] != 0xd7 && (codep
[-1] & 1)
4066 prefixes
|= PREFIX_DS
;
4068 ptr_reg (code
, sizeflag
);
4072 OP_C (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4077 USED_REX (REX_EXTX
);
4080 else if (address_mode
!= mode_64bit
&& (prefixes
& PREFIX_LOCK
))
4082 used_prefixes
|= PREFIX_LOCK
;
4085 sprintf (scratchbuf
, "%%cr%d", reg
+ add
);
4086 oappend (scratchbuf
+ intel_syntax
);
4090 OP_D (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4093 USED_REX (REX_EXTX
);
4097 sprintf (scratchbuf
, "db%d", reg
+ add
);
4099 sprintf (scratchbuf
, "%%db%d", reg
+ add
);
4100 oappend (scratchbuf
);
4104 OP_T (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4106 sprintf (scratchbuf
, "%%tr%d", reg
);
4107 oappend (scratchbuf
+ intel_syntax
);
4111 OP_Rd (int bytemode
, int sizeflag
)
4114 OP_E (bytemode
, sizeflag
);
4120 OP_MMX (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4122 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4123 if (prefixes
& PREFIX_DATA
)
4126 USED_REX (REX_EXTX
);
4129 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
4132 sprintf (scratchbuf
, "%%mm%d", reg
);
4133 oappend (scratchbuf
+ intel_syntax
);
4137 OP_XMM (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4140 USED_REX (REX_EXTX
);
4143 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
4144 oappend (scratchbuf
+ intel_syntax
);
4148 OP_EM (int bytemode
, int sizeflag
)
4152 if (intel_syntax
&& bytemode
== v_mode
)
4154 bytemode
= (prefixes
& PREFIX_DATA
) ? x_mode
: q_mode
;
4155 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4157 OP_E (bytemode
, sizeflag
);
4161 /* Skip mod/rm byte. */
4164 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4165 if (prefixes
& PREFIX_DATA
)
4169 USED_REX (REX_EXTZ
);
4172 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
4175 sprintf (scratchbuf
, "%%mm%d", rm
);
4176 oappend (scratchbuf
+ intel_syntax
);
4180 OP_EX (int bytemode
, int sizeflag
)
4185 if (intel_syntax
&& bytemode
== v_mode
)
4187 switch (prefixes
& (PREFIX_DATA
|PREFIX_REPZ
|PREFIX_REPNZ
))
4189 case 0: bytemode
= x_mode
; break;
4190 case PREFIX_REPZ
: bytemode
= d_mode
; used_prefixes
|= PREFIX_REPZ
; break;
4191 case PREFIX_DATA
: bytemode
= x_mode
; used_prefixes
|= PREFIX_DATA
; break;
4192 case PREFIX_REPNZ
: bytemode
= q_mode
; used_prefixes
|= PREFIX_REPNZ
; break;
4193 default: bytemode
= 0; break;
4196 OP_E (bytemode
, sizeflag
);
4199 USED_REX (REX_EXTZ
);
4203 /* Skip mod/rm byte. */
4206 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
4207 oappend (scratchbuf
+ intel_syntax
);
4211 OP_MS (int bytemode
, int sizeflag
)
4214 OP_EM (bytemode
, sizeflag
);
4220 OP_XS (int bytemode
, int sizeflag
)
4223 OP_EX (bytemode
, sizeflag
);
4229 OP_M (int bytemode
, int sizeflag
)
4232 BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
4234 OP_E (bytemode
, sizeflag
);
4238 OP_0f07 (int bytemode
, int sizeflag
)
4240 if (mod
!= 3 || rm
!= 0)
4243 OP_E (bytemode
, sizeflag
);
4247 OP_0fae (int bytemode
, int sizeflag
)
4252 strcpy (obuf
+ strlen (obuf
) - sizeof ("clflush") + 1, "sfence");
4254 if (reg
< 5 || rm
!= 0)
4256 BadOp (); /* bad sfence, mfence, or lfence */
4262 BadOp (); /* bad clflush */
4266 OP_E (bytemode
, sizeflag
);
4270 NOP_Fixup (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4272 /* NOP with REPZ prefix is called PAUSE. */
4273 if (prefixes
== PREFIX_REPZ
)
4274 strcpy (obuf
, "pause");
4277 static const char *const Suffix3DNow
[] = {
4278 /* 00 */ NULL
, NULL
, NULL
, NULL
,
4279 /* 04 */ NULL
, NULL
, NULL
, NULL
,
4280 /* 08 */ NULL
, NULL
, NULL
, NULL
,
4281 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
4282 /* 10 */ NULL
, NULL
, NULL
, NULL
,
4283 /* 14 */ NULL
, NULL
, NULL
, NULL
,
4284 /* 18 */ NULL
, NULL
, NULL
, NULL
,
4285 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
4286 /* 20 */ NULL
, NULL
, NULL
, NULL
,
4287 /* 24 */ NULL
, NULL
, NULL
, NULL
,
4288 /* 28 */ NULL
, NULL
, NULL
, NULL
,
4289 /* 2C */ NULL
, NULL
, NULL
, NULL
,
4290 /* 30 */ NULL
, NULL
, NULL
, NULL
,
4291 /* 34 */ NULL
, NULL
, NULL
, NULL
,
4292 /* 38 */ NULL
, NULL
, NULL
, NULL
,
4293 /* 3C */ NULL
, NULL
, NULL
, NULL
,
4294 /* 40 */ NULL
, NULL
, NULL
, NULL
,
4295 /* 44 */ NULL
, NULL
, NULL
, NULL
,
4296 /* 48 */ NULL
, NULL
, NULL
, NULL
,
4297 /* 4C */ NULL
, NULL
, NULL
, NULL
,
4298 /* 50 */ NULL
, NULL
, NULL
, NULL
,
4299 /* 54 */ NULL
, NULL
, NULL
, NULL
,
4300 /* 58 */ NULL
, NULL
, NULL
, NULL
,
4301 /* 5C */ NULL
, NULL
, NULL
, NULL
,
4302 /* 60 */ NULL
, NULL
, NULL
, NULL
,
4303 /* 64 */ NULL
, NULL
, NULL
, NULL
,
4304 /* 68 */ NULL
, NULL
, NULL
, NULL
,
4305 /* 6C */ NULL
, NULL
, NULL
, NULL
,
4306 /* 70 */ NULL
, NULL
, NULL
, NULL
,
4307 /* 74 */ NULL
, NULL
, NULL
, NULL
,
4308 /* 78 */ NULL
, NULL
, NULL
, NULL
,
4309 /* 7C */ NULL
, NULL
, NULL
, NULL
,
4310 /* 80 */ NULL
, NULL
, NULL
, NULL
,
4311 /* 84 */ NULL
, NULL
, NULL
, NULL
,
4312 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
4313 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
4314 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
4315 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
4316 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
4317 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
4318 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
4319 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
4320 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
4321 /* AC */ NULL
, NULL
, "pfacc", NULL
,
4322 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
4323 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pfmulhrw",
4324 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
4325 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
4326 /* C0 */ NULL
, NULL
, NULL
, NULL
,
4327 /* C4 */ NULL
, NULL
, NULL
, NULL
,
4328 /* C8 */ NULL
, NULL
, NULL
, NULL
,
4329 /* CC */ NULL
, NULL
, NULL
, NULL
,
4330 /* D0 */ NULL
, NULL
, NULL
, NULL
,
4331 /* D4 */ NULL
, NULL
, NULL
, NULL
,
4332 /* D8 */ NULL
, NULL
, NULL
, NULL
,
4333 /* DC */ NULL
, NULL
, NULL
, NULL
,
4334 /* E0 */ NULL
, NULL
, NULL
, NULL
,
4335 /* E4 */ NULL
, NULL
, NULL
, NULL
,
4336 /* E8 */ NULL
, NULL
, NULL
, NULL
,
4337 /* EC */ NULL
, NULL
, NULL
, NULL
,
4338 /* F0 */ NULL
, NULL
, NULL
, NULL
,
4339 /* F4 */ NULL
, NULL
, NULL
, NULL
,
4340 /* F8 */ NULL
, NULL
, NULL
, NULL
,
4341 /* FC */ NULL
, NULL
, NULL
, NULL
,
4345 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4347 const char *mnemonic
;
4349 FETCH_DATA (the_info
, codep
+ 1);
4350 /* AMD 3DNow! instructions are specified by an opcode suffix in the
4351 place where an 8-bit immediate would normally go. ie. the last
4352 byte of the instruction. */
4353 obufp
= obuf
+ strlen (obuf
);
4354 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
4359 /* Since a variable sized modrm/sib chunk is between the start
4360 of the opcode (0x0f0f) and the opcode suffix, we need to do
4361 all the modrm processing first, and don't know until now that
4362 we have a bad opcode. This necessitates some cleaning up. */
4369 static const char *simd_cmp_op
[] = {
4381 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4383 unsigned int cmp_type
;
4385 FETCH_DATA (the_info
, codep
+ 1);
4386 obufp
= obuf
+ strlen (obuf
);
4387 cmp_type
= *codep
++ & 0xff;
4390 char suffix1
= 'p', suffix2
= 's';
4391 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
4392 if (prefixes
& PREFIX_REPZ
)
4396 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4397 if (prefixes
& PREFIX_DATA
)
4401 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
4402 if (prefixes
& PREFIX_REPNZ
)
4403 suffix1
= 's', suffix2
= 'd';
4406 sprintf (scratchbuf
, "cmp%s%c%c",
4407 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
4408 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
4409 oappend (scratchbuf
);
4413 /* We have a bad extension byte. Clean up. */
4421 SIMD_Fixup (int extrachar
, int sizeflag ATTRIBUTE_UNUSED
)
4423 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
4424 forms of these instructions. */
4427 char *p
= obuf
+ strlen (obuf
);
4430 *(p
- 1) = *(p
- 2);
4431 *(p
- 2) = *(p
- 3);
4432 *(p
- 3) = extrachar
;
4437 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
4439 if (mod
== 3 && reg
== 1 && rm
<= 1)
4441 /* Override "sidt". */
4442 size_t olen
= strlen (obuf
);
4443 char *p
= obuf
+ olen
- 4;
4444 const char **names
= (address_mode
== mode_64bit
4445 ? names64
: names32
);
4447 /* We might have a suffix when disassembling with -Msuffix. */
4451 /* Remove "addr16/addr32" if we aren't in Intel mode. */
4453 && (prefixes
& PREFIX_ADDR
)
4456 && strncmp (p
- 7, "addr", 4) == 0
4457 && (strncmp (p
- 3, "16", 2) == 0
4458 || strncmp (p
- 3, "32", 2) == 0))
4463 /* mwait %eax,%ecx */
4464 strcpy (p
, "mwait");
4466 strcpy (op1out
, names
[0]);
4470 /* monitor %eax,%ecx,%edx" */
4471 strcpy (p
, "monitor");
4474 const char **op1_names
;
4475 if (!(prefixes
& PREFIX_ADDR
))
4476 op1_names
= (address_mode
== mode_16bit
4480 op1_names
= (address_mode
!= mode_32bit
4481 ? names32
: names16
);
4482 used_prefixes
|= PREFIX_ADDR
;
4484 strcpy (op1out
, op1_names
[0]);
4485 strcpy (op3out
, names
[2]);
4490 strcpy (op2out
, names
[1]);
4501 SVME_Fixup (int bytemode
, int sizeflag
)
4533 OP_M (bytemode
, sizeflag
);
4536 /* Override "lidt". */
4537 p
= obuf
+ strlen (obuf
) - 4;
4538 /* We might have a suffix. */
4542 if (!(prefixes
& PREFIX_ADDR
))
4547 used_prefixes
|= PREFIX_ADDR
;
4551 strcpy (op2out
, names32
[1]);
4557 *obufp
++ = open_char
;
4558 if (address_mode
== mode_64bit
|| (sizeflag
& AFLAG
))
4562 strcpy (obufp
, alt
);
4563 obufp
+= strlen (alt
);
4564 *obufp
++ = close_char
;
4571 INVLPG_Fixup (int bytemode
, int sizeflag
)
4584 OP_M (bytemode
, sizeflag
);
4587 /* Override "invlpg". */
4588 strcpy (obuf
+ strlen (obuf
) - 6, alt
);
4595 /* Throw away prefixes and 1st. opcode byte. */
4596 codep
= insn_codep
+ 1;
4601 SEG_Fixup (int extrachar
, int sizeflag
)
4605 /* We need to add a proper suffix with
4616 if (prefixes
& PREFIX_DATA
)
4620 USED_REX (REX_MODE64
);
4621 if (rex
& REX_MODE64
)
4626 strcat (obuf
, suffix
);
4630 /* We need to fix the suffix for
4637 Override "mov[l|q]". */
4638 char *p
= obuf
+ strlen (obuf
) - 1;
4640 /* We might not have a suffix. */
4646 OP_E (extrachar
, sizeflag
);
4650 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
4652 if (mod
== 3 && reg
== 0 && rm
>=1 && rm
<= 4)
4654 /* Override "sgdt". */
4655 char *p
= obuf
+ strlen (obuf
) - 4;
4657 /* We might have a suffix when disassembling with -Msuffix. */
4664 strcpy (p
, "vmcall");
4667 strcpy (p
, "vmlaunch");
4670 strcpy (p
, "vmresume");
4673 strcpy (p
, "vmxoff");
4684 OP_VMX (int bytemode
, int sizeflag
)
4686 used_prefixes
|= (prefixes
& (PREFIX_DATA
| PREFIX_REPZ
));
4687 if (prefixes
& PREFIX_DATA
)
4688 strcpy (obuf
, "vmclear");
4689 else if (prefixes
& PREFIX_REPZ
)
4690 strcpy (obuf
, "vmxon");
4692 strcpy (obuf
, "vmptrld");
4693 OP_E (bytemode
, sizeflag
);