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 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
24 * modified by John Hassey (hassey@dg-rtp.dg.com)
25 * x86-64 support added by Jan Hubicka (jh@suse.cz)
26 * VIA PadLock support by Michal Ludvig (mludvig@suse.cz)
30 * The main tables describing the instructions is essentially a copy
31 * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
32 * Programmers Manual. Usually, there is a capital letter, followed
33 * by a small letter. The capital letter tell the addressing mode,
34 * and the small letter tells about the operand size. Refer to
35 * the Intel manual for details.
46 #ifndef UNIXWARE_COMPAT
47 /* Set non-zero for broken, compatible instructions. Set to zero for
48 non-broken opcodes. */
49 #define UNIXWARE_COMPAT 1
52 static int fetch_data (struct disassemble_info
*, bfd_byte
*);
53 static void ckprefix (void);
54 static const char *prefix_name (int, int);
55 static int print_insn (bfd_vma
, disassemble_info
*);
56 static void dofloat (int);
57 static void OP_ST (int, int);
58 static void OP_STi (int, int);
59 static int putop (const char *, int);
60 static void oappend (const char *);
61 static void append_seg (void);
62 static void OP_indirE (int, int);
63 static void print_operand_value (char *, int, bfd_vma
);
64 static void OP_E (int, int);
65 static void OP_G (int, int);
66 static bfd_vma
get64 (void);
67 static bfd_signed_vma
get32 (void);
68 static bfd_signed_vma
get32s (void);
69 static int get16 (void);
70 static void set_op (bfd_vma
, int);
71 static void OP_REG (int, int);
72 static void OP_IMREG (int, int);
73 static void OP_I (int, int);
74 static void OP_I64 (int, int);
75 static void OP_sI (int, int);
76 static void OP_J (int, int);
77 static void OP_SEG (int, int);
78 static void OP_DIR (int, int);
79 static void OP_OFF (int, int);
80 static void OP_OFF64 (int, int);
81 static void ptr_reg (int, int);
82 static void OP_ESreg (int, int);
83 static void OP_DSreg (int, int);
84 static void OP_C (int, int);
85 static void OP_D (int, int);
86 static void OP_T (int, int);
87 static void OP_Rd (int, int);
88 static void OP_MMX (int, int);
89 static void OP_XMM (int, int);
90 static void OP_EM (int, int);
91 static void OP_EX (int, int);
92 static void OP_MS (int, int);
93 static void OP_XS (int, int);
94 static void OP_M (int, int);
95 static void OP_0fae (int, int);
96 static void OP_0f07 (int, int);
97 static void NOP_Fixup (int, int);
98 static void OP_3DNowSuffix (int, int);
99 static void OP_SIMD_Suffix (int, int);
100 static void SIMD_Fixup (int, int);
101 static void PNI_Fixup (int, int);
102 static void INVLPG_Fixup (int, int);
103 static void BadOp (void);
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)
118 /* Set to 1 for 64bit mode disassembly. */
119 static int mode_64bit
;
121 /* Flags for the prefixes for the current instruction. See below. */
124 /* REX prefix the current instruction. See below. */
126 /* Bits of REX we've already used. */
132 /* Mark parts used in the REX prefix. When we are testing for
133 empty prefix (for 8bit register REX extension), just mask it
134 out. Otherwise test for REX bit is excuse for existence of REX
135 only in case value is nonzero. */
136 #define USED_REX(value) \
139 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
144 /* Flags for prefixes which we somehow handled when printing the
145 current instruction. */
146 static int used_prefixes
;
148 /* Flags stored in PREFIXES. */
149 #define PREFIX_REPZ 1
150 #define PREFIX_REPNZ 2
151 #define PREFIX_LOCK 4
153 #define PREFIX_SS 0x10
154 #define PREFIX_DS 0x20
155 #define PREFIX_ES 0x40
156 #define PREFIX_FS 0x80
157 #define PREFIX_GS 0x100
158 #define PREFIX_DATA 0x200
159 #define PREFIX_ADDR 0x400
160 #define PREFIX_FWAIT 0x800
162 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
163 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
165 #define FETCH_DATA(info, addr) \
166 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
167 ? 1 : fetch_data ((info), (addr)))
170 fetch_data (struct disassemble_info
*info
, bfd_byte
*addr
)
173 struct dis_private
*priv
= (struct dis_private
*) info
->private_data
;
174 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
176 status
= (*info
->read_memory_func
) (start
,
178 addr
- priv
->max_fetched
,
182 /* If we did manage to read at least one byte, then
183 print_insn_i386 will do something sensible. Otherwise, print
184 an error. We do that here because this is where we know
186 if (priv
->max_fetched
== priv
->the_buffer
)
187 (*info
->memory_error_func
) (status
, start
, info
);
188 longjmp (priv
->bailout
, 1);
191 priv
->max_fetched
= addr
;
197 #define Eb OP_E, b_mode
198 #define Ev OP_E, v_mode
199 #define Ed OP_E, d_mode
200 #define Edq OP_E, dq_mode
201 #define indirEb OP_indirE, b_mode
202 #define indirEv OP_indirE, v_mode
203 #define Ew OP_E, w_mode
204 #define Ma OP_E, v_mode
205 #define M OP_M, 0 /* lea, lgdt, etc. */
206 #define Mp OP_M, 0 /* 32 or 48 bit memory operand for LDS, LES etc */
207 #define Gb OP_G, b_mode
208 #define Gv OP_G, v_mode
209 #define Gd OP_G, d_mode
210 #define Gw OP_G, w_mode
211 #define Rd OP_Rd, d_mode
212 #define Rm OP_Rd, m_mode
213 #define Ib OP_I, b_mode
214 #define sIb OP_sI, b_mode /* sign extened byte */
215 #define Iv OP_I, v_mode
216 #define Iq OP_I, q_mode
217 #define Iv64 OP_I64, v_mode
218 #define Iw OP_I, w_mode
219 #define Jb OP_J, b_mode
220 #define Jv OP_J, v_mode
221 #define Cm OP_C, m_mode
222 #define Dm OP_D, m_mode
223 #define Td OP_T, d_mode
225 #define RMeAX OP_REG, eAX_reg
226 #define RMeBX OP_REG, eBX_reg
227 #define RMeCX OP_REG, eCX_reg
228 #define RMeDX OP_REG, eDX_reg
229 #define RMeSP OP_REG, eSP_reg
230 #define RMeBP OP_REG, eBP_reg
231 #define RMeSI OP_REG, eSI_reg
232 #define RMeDI OP_REG, eDI_reg
233 #define RMrAX OP_REG, rAX_reg
234 #define RMrBX OP_REG, rBX_reg
235 #define RMrCX OP_REG, rCX_reg
236 #define RMrDX OP_REG, rDX_reg
237 #define RMrSP OP_REG, rSP_reg
238 #define RMrBP OP_REG, rBP_reg
239 #define RMrSI OP_REG, rSI_reg
240 #define RMrDI OP_REG, rDI_reg
241 #define RMAL OP_REG, al_reg
242 #define RMAL OP_REG, al_reg
243 #define RMCL OP_REG, cl_reg
244 #define RMDL OP_REG, dl_reg
245 #define RMBL OP_REG, bl_reg
246 #define RMAH OP_REG, ah_reg
247 #define RMCH OP_REG, ch_reg
248 #define RMDH OP_REG, dh_reg
249 #define RMBH OP_REG, bh_reg
250 #define RMAX OP_REG, ax_reg
251 #define RMDX OP_REG, dx_reg
253 #define eAX OP_IMREG, eAX_reg
254 #define eBX OP_IMREG, eBX_reg
255 #define eCX OP_IMREG, eCX_reg
256 #define eDX OP_IMREG, eDX_reg
257 #define eSP OP_IMREG, eSP_reg
258 #define eBP OP_IMREG, eBP_reg
259 #define eSI OP_IMREG, eSI_reg
260 #define eDI OP_IMREG, eDI_reg
261 #define AL OP_IMREG, al_reg
262 #define AL OP_IMREG, al_reg
263 #define CL OP_IMREG, cl_reg
264 #define DL OP_IMREG, dl_reg
265 #define BL OP_IMREG, bl_reg
266 #define AH OP_IMREG, ah_reg
267 #define CH OP_IMREG, ch_reg
268 #define DH OP_IMREG, dh_reg
269 #define BH OP_IMREG, bh_reg
270 #define AX OP_IMREG, ax_reg
271 #define DX OP_IMREG, dx_reg
272 #define indirDX OP_IMREG, indir_dx_reg
274 #define Sw OP_SEG, w_mode
276 #define Ob OP_OFF, b_mode
277 #define Ob64 OP_OFF64, b_mode
278 #define Ov OP_OFF, v_mode
279 #define Ov64 OP_OFF64, v_mode
280 #define Xb OP_DSreg, eSI_reg
281 #define Xv OP_DSreg, eSI_reg
282 #define Yb OP_ESreg, eDI_reg
283 #define Yv OP_ESreg, eDI_reg
284 #define DSBX OP_DSreg, eBX_reg
286 #define es OP_REG, es_reg
287 #define ss OP_REG, ss_reg
288 #define cs OP_REG, cs_reg
289 #define ds OP_REG, ds_reg
290 #define fs OP_REG, fs_reg
291 #define gs OP_REG, gs_reg
295 #define EM OP_EM, v_mode
296 #define EX OP_EX, v_mode
297 #define MS OP_MS, v_mode
298 #define XS OP_XS, v_mode
299 #define OPSUF OP_3DNowSuffix, 0
300 #define OPSIMD OP_SIMD_Suffix, 0
302 #define cond_jump_flag NULL, cond_jump_mode
303 #define loop_jcxz_flag NULL, loop_jcxz_mode
305 /* bits in sizeflag */
306 #define SUFFIX_ALWAYS 4
310 #define b_mode 1 /* byte operand */
311 #define v_mode 2 /* operand size depends on prefixes */
312 #define w_mode 3 /* word operand */
313 #define d_mode 4 /* double word operand */
314 #define q_mode 5 /* quad word operand */
315 #define x_mode 6 /* 80 bit float operand */
316 #define m_mode 7 /* d_mode in 32bit, q_mode in 64bit mode. */
317 #define cond_jump_mode 8
318 #define loop_jcxz_mode 9
319 #define dq_mode 10 /* operand size depends on REX prefixes. */
364 #define indir_dx_reg 150
368 #define USE_PREFIX_USER_TABLE 3
369 #define X86_64_SPECIAL 4
371 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
373 #define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
374 #define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
375 #define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
376 #define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
377 #define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
378 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
379 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
380 #define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
381 #define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
382 #define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
383 #define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
384 #define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
385 #define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
386 #define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
387 #define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
388 #define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
389 #define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
390 #define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
391 #define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
392 #define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
393 #define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
394 #define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
395 #define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
396 #define GRPPADLCK NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0
398 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
399 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
400 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
401 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
402 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
403 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
404 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
405 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
406 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
407 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
408 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
409 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
410 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
411 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
412 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
413 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
414 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
415 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
416 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
417 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
418 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
419 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
420 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
421 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
422 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
423 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
424 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
425 #define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0
426 #define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0
427 #define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0
428 #define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0
429 #define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0
430 #define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0
432 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
434 typedef void (*op_rtn
) (int bytemode
, int sizeflag
);
446 /* Upper case letters in the instruction names here are macros.
447 'A' => print 'b' if no register operands or suffix_always is true
448 'B' => print 'b' if suffix_always is true
449 'E' => print 'e' if 32-bit form of jcxz
450 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
451 'H' => print ",pt" or ",pn" branch hint
452 'L' => print 'l' if suffix_always is true
453 'N' => print 'n' if instruction has no wait "prefix"
454 'O' => print 'd', or 'o'
455 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
456 . or suffix_always is true. print 'q' if rex prefix is present.
457 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
459 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
460 'S' => print 'w', 'l' or 'q' if suffix_always is true
461 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
462 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
463 'X' => print 's', 'd' depending on data16 prefix (for XMM)
464 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
465 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
467 Many of the above letters print nothing in Intel mode. See "putop"
470 Braces '{' and '}', and vertical bars '|', indicate alternative
471 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
472 modes. In cases where there are only two alternatives, the X86_64
473 instruction is reserved, and "(bad)" is printed.
476 static const struct dis386 dis386
[] = {
478 { "addB", Eb
, Gb
, XX
},
479 { "addS", Ev
, Gv
, XX
},
480 { "addB", Gb
, Eb
, XX
},
481 { "addS", Gv
, Ev
, XX
},
482 { "addB", AL
, Ib
, XX
},
483 { "addS", eAX
, Iv
, XX
},
484 { "push{T|}", es
, XX
, XX
},
485 { "pop{T|}", es
, XX
, XX
},
487 { "orB", Eb
, Gb
, XX
},
488 { "orS", Ev
, Gv
, XX
},
489 { "orB", Gb
, Eb
, XX
},
490 { "orS", Gv
, Ev
, XX
},
491 { "orB", AL
, Ib
, XX
},
492 { "orS", eAX
, Iv
, XX
},
493 { "push{T|}", cs
, XX
, XX
},
494 { "(bad)", XX
, XX
, XX
}, /* 0x0f extended opcode escape */
496 { "adcB", Eb
, Gb
, XX
},
497 { "adcS", Ev
, Gv
, XX
},
498 { "adcB", Gb
, Eb
, XX
},
499 { "adcS", Gv
, Ev
, XX
},
500 { "adcB", AL
, Ib
, XX
},
501 { "adcS", eAX
, Iv
, XX
},
502 { "push{T|}", ss
, XX
, XX
},
503 { "popT|}", ss
, XX
, XX
},
505 { "sbbB", Eb
, Gb
, XX
},
506 { "sbbS", Ev
, Gv
, XX
},
507 { "sbbB", Gb
, Eb
, XX
},
508 { "sbbS", Gv
, Ev
, XX
},
509 { "sbbB", AL
, Ib
, XX
},
510 { "sbbS", eAX
, Iv
, XX
},
511 { "push{T|}", ds
, XX
, XX
},
512 { "pop{T|}", ds
, XX
, XX
},
514 { "andB", Eb
, Gb
, XX
},
515 { "andS", Ev
, Gv
, XX
},
516 { "andB", Gb
, Eb
, XX
},
517 { "andS", Gv
, Ev
, XX
},
518 { "andB", AL
, Ib
, XX
},
519 { "andS", eAX
, Iv
, XX
},
520 { "(bad)", XX
, XX
, XX
}, /* SEG ES prefix */
521 { "daa{|}", XX
, XX
, XX
},
523 { "subB", Eb
, Gb
, XX
},
524 { "subS", Ev
, Gv
, XX
},
525 { "subB", Gb
, Eb
, XX
},
526 { "subS", Gv
, Ev
, XX
},
527 { "subB", AL
, Ib
, XX
},
528 { "subS", eAX
, Iv
, XX
},
529 { "(bad)", XX
, XX
, XX
}, /* SEG CS prefix */
530 { "das{|}", XX
, XX
, XX
},
532 { "xorB", Eb
, Gb
, XX
},
533 { "xorS", Ev
, Gv
, XX
},
534 { "xorB", Gb
, Eb
, XX
},
535 { "xorS", Gv
, Ev
, XX
},
536 { "xorB", AL
, Ib
, XX
},
537 { "xorS", eAX
, Iv
, XX
},
538 { "(bad)", XX
, XX
, XX
}, /* SEG SS prefix */
539 { "aaa{|}", XX
, XX
, XX
},
541 { "cmpB", Eb
, Gb
, XX
},
542 { "cmpS", Ev
, Gv
, XX
},
543 { "cmpB", Gb
, Eb
, XX
},
544 { "cmpS", Gv
, Ev
, XX
},
545 { "cmpB", AL
, Ib
, XX
},
546 { "cmpS", eAX
, Iv
, XX
},
547 { "(bad)", XX
, XX
, XX
}, /* SEG DS prefix */
548 { "aas{|}", XX
, XX
, XX
},
550 { "inc{S|}", RMeAX
, XX
, XX
},
551 { "inc{S|}", RMeCX
, XX
, XX
},
552 { "inc{S|}", RMeDX
, XX
, XX
},
553 { "inc{S|}", RMeBX
, XX
, XX
},
554 { "inc{S|}", RMeSP
, XX
, XX
},
555 { "inc{S|}", RMeBP
, XX
, XX
},
556 { "inc{S|}", RMeSI
, XX
, XX
},
557 { "inc{S|}", RMeDI
, XX
, XX
},
559 { "dec{S|}", RMeAX
, XX
, XX
},
560 { "dec{S|}", RMeCX
, XX
, XX
},
561 { "dec{S|}", RMeDX
, XX
, XX
},
562 { "dec{S|}", RMeBX
, XX
, XX
},
563 { "dec{S|}", RMeSP
, XX
, XX
},
564 { "dec{S|}", RMeBP
, XX
, XX
},
565 { "dec{S|}", RMeSI
, XX
, XX
},
566 { "dec{S|}", RMeDI
, XX
, XX
},
568 { "pushS", RMrAX
, XX
, XX
},
569 { "pushS", RMrCX
, XX
, XX
},
570 { "pushS", RMrDX
, XX
, XX
},
571 { "pushS", RMrBX
, XX
, XX
},
572 { "pushS", RMrSP
, XX
, XX
},
573 { "pushS", RMrBP
, XX
, XX
},
574 { "pushS", RMrSI
, XX
, XX
},
575 { "pushS", RMrDI
, XX
, XX
},
577 { "popS", RMrAX
, XX
, XX
},
578 { "popS", RMrCX
, XX
, XX
},
579 { "popS", RMrDX
, XX
, XX
},
580 { "popS", RMrBX
, XX
, XX
},
581 { "popS", RMrSP
, XX
, XX
},
582 { "popS", RMrBP
, XX
, XX
},
583 { "popS", RMrSI
, XX
, XX
},
584 { "popS", RMrDI
, XX
, XX
},
586 { "pusha{P|}", XX
, XX
, XX
},
587 { "popa{P|}", XX
, XX
, XX
},
588 { "bound{S|}", Gv
, Ma
, XX
},
590 { "(bad)", XX
, XX
, XX
}, /* seg fs */
591 { "(bad)", XX
, XX
, XX
}, /* seg gs */
592 { "(bad)", XX
, XX
, XX
}, /* op size prefix */
593 { "(bad)", XX
, XX
, XX
}, /* adr size prefix */
595 { "pushT", Iq
, XX
, XX
},
596 { "imulS", Gv
, Ev
, Iv
},
597 { "pushT", sIb
, XX
, XX
},
598 { "imulS", Gv
, Ev
, sIb
},
599 { "ins{b||b|}", Yb
, indirDX
, XX
},
600 { "ins{R||R|}", Yv
, indirDX
, XX
},
601 { "outs{b||b|}", indirDX
, Xb
, XX
},
602 { "outs{R||R|}", indirDX
, Xv
, XX
},
604 { "joH", Jb
, XX
, cond_jump_flag
},
605 { "jnoH", Jb
, XX
, cond_jump_flag
},
606 { "jbH", Jb
, XX
, cond_jump_flag
},
607 { "jaeH", Jb
, XX
, cond_jump_flag
},
608 { "jeH", Jb
, XX
, cond_jump_flag
},
609 { "jneH", Jb
, XX
, cond_jump_flag
},
610 { "jbeH", Jb
, XX
, cond_jump_flag
},
611 { "jaH", Jb
, XX
, cond_jump_flag
},
613 { "jsH", Jb
, XX
, cond_jump_flag
},
614 { "jnsH", Jb
, XX
, cond_jump_flag
},
615 { "jpH", Jb
, XX
, cond_jump_flag
},
616 { "jnpH", Jb
, XX
, cond_jump_flag
},
617 { "jlH", Jb
, XX
, cond_jump_flag
},
618 { "jgeH", Jb
, XX
, cond_jump_flag
},
619 { "jleH", Jb
, XX
, cond_jump_flag
},
620 { "jgH", Jb
, XX
, cond_jump_flag
},
624 { "(bad)", XX
, XX
, XX
},
626 { "testB", Eb
, Gb
, XX
},
627 { "testS", Ev
, Gv
, XX
},
628 { "xchgB", Eb
, Gb
, XX
},
629 { "xchgS", Ev
, Gv
, XX
},
631 { "movB", Eb
, Gb
, XX
},
632 { "movS", Ev
, Gv
, XX
},
633 { "movB", Gb
, Eb
, XX
},
634 { "movS", Gv
, Ev
, XX
},
635 { "movQ", Ev
, Sw
, XX
},
636 { "leaS", Gv
, M
, XX
},
637 { "movQ", Sw
, Ev
, XX
},
638 { "popU", Ev
, XX
, XX
},
640 { "nop", NOP_Fixup
, 0, XX
, XX
},
641 { "xchgS", RMeCX
, eAX
, XX
},
642 { "xchgS", RMeDX
, eAX
, XX
},
643 { "xchgS", RMeBX
, eAX
, XX
},
644 { "xchgS", RMeSP
, eAX
, XX
},
645 { "xchgS", RMeBP
, eAX
, XX
},
646 { "xchgS", RMeSI
, eAX
, XX
},
647 { "xchgS", RMeDI
, eAX
, XX
},
649 { "cW{tR||tR|}", XX
, XX
, XX
},
650 { "cR{tO||tO|}", XX
, XX
, XX
},
651 { "lcall{T|}", Ap
, XX
, XX
},
652 { "(bad)", XX
, XX
, XX
}, /* fwait */
653 { "pushfT", XX
, XX
, XX
},
654 { "popfT", XX
, XX
, XX
},
655 { "sahf{|}", XX
, XX
, XX
},
656 { "lahf{|}", XX
, XX
, XX
},
658 { "movB", AL
, Ob64
, XX
},
659 { "movS", eAX
, Ov64
, XX
},
660 { "movB", Ob64
, AL
, XX
},
661 { "movS", Ov64
, eAX
, XX
},
662 { "movs{b||b|}", Yb
, Xb
, XX
},
663 { "movs{R||R|}", Yv
, Xv
, XX
},
664 { "cmps{b||b|}", Xb
, Yb
, XX
},
665 { "cmps{R||R|}", Xv
, Yv
, XX
},
667 { "testB", AL
, Ib
, XX
},
668 { "testS", eAX
, Iv
, XX
},
669 { "stosB", Yb
, AL
, XX
},
670 { "stosS", Yv
, eAX
, XX
},
671 { "lodsB", AL
, Xb
, XX
},
672 { "lodsS", eAX
, Xv
, XX
},
673 { "scasB", AL
, Yb
, XX
},
674 { "scasS", eAX
, Yv
, XX
},
676 { "movB", RMAL
, Ib
, XX
},
677 { "movB", RMCL
, Ib
, XX
},
678 { "movB", RMDL
, Ib
, XX
},
679 { "movB", RMBL
, Ib
, XX
},
680 { "movB", RMAH
, Ib
, XX
},
681 { "movB", RMCH
, Ib
, XX
},
682 { "movB", RMDH
, Ib
, XX
},
683 { "movB", RMBH
, Ib
, XX
},
685 { "movS", RMeAX
, Iv64
, XX
},
686 { "movS", RMeCX
, Iv64
, XX
},
687 { "movS", RMeDX
, Iv64
, XX
},
688 { "movS", RMeBX
, Iv64
, XX
},
689 { "movS", RMeSP
, Iv64
, XX
},
690 { "movS", RMeBP
, Iv64
, XX
},
691 { "movS", RMeSI
, Iv64
, XX
},
692 { "movS", RMeDI
, Iv64
, XX
},
696 { "retT", Iw
, XX
, XX
},
697 { "retT", XX
, XX
, XX
},
698 { "les{S|}", Gv
, Mp
, XX
},
699 { "ldsS", Gv
, Mp
, XX
},
700 { "movA", Eb
, Ib
, XX
},
701 { "movQ", Ev
, Iv
, XX
},
703 { "enterT", Iw
, Ib
, XX
},
704 { "leaveT", XX
, XX
, XX
},
705 { "lretP", Iw
, XX
, XX
},
706 { "lretP", XX
, XX
, XX
},
707 { "int3", XX
, XX
, XX
},
708 { "int", Ib
, XX
, XX
},
709 { "into{|}", XX
, XX
, XX
},
710 { "iretP", XX
, XX
, XX
},
716 { "aam{|}", sIb
, XX
, XX
},
717 { "aad{|}", sIb
, XX
, XX
},
718 { "(bad)", XX
, XX
, XX
},
719 { "xlat", DSBX
, XX
, XX
},
730 { "loopneFH", Jb
, XX
, loop_jcxz_flag
},
731 { "loopeFH", Jb
, XX
, loop_jcxz_flag
},
732 { "loopFH", Jb
, XX
, loop_jcxz_flag
},
733 { "jEcxzH", Jb
, XX
, loop_jcxz_flag
},
734 { "inB", AL
, Ib
, XX
},
735 { "inS", eAX
, Ib
, XX
},
736 { "outB", Ib
, AL
, XX
},
737 { "outS", Ib
, eAX
, XX
},
739 { "callT", Jv
, XX
, XX
},
740 { "jmpT", Jv
, XX
, XX
},
741 { "ljmp{T|}", Ap
, XX
, XX
},
742 { "jmp", Jb
, XX
, XX
},
743 { "inB", AL
, indirDX
, XX
},
744 { "inS", eAX
, indirDX
, XX
},
745 { "outB", indirDX
, AL
, XX
},
746 { "outS", indirDX
, eAX
, XX
},
748 { "(bad)", XX
, XX
, XX
}, /* lock prefix */
749 { "icebp", XX
, XX
, XX
},
750 { "(bad)", XX
, XX
, XX
}, /* repne */
751 { "(bad)", XX
, XX
, XX
}, /* repz */
752 { "hlt", XX
, XX
, XX
},
753 { "cmc", XX
, XX
, XX
},
757 { "clc", XX
, XX
, XX
},
758 { "stc", XX
, XX
, XX
},
759 { "cli", XX
, XX
, XX
},
760 { "sti", XX
, XX
, XX
},
761 { "cld", XX
, XX
, XX
},
762 { "std", XX
, XX
, XX
},
767 static const struct dis386 dis386_twobyte
[] = {
771 { "larS", Gv
, Ew
, XX
},
772 { "lslS", Gv
, Ew
, XX
},
773 { "(bad)", XX
, XX
, XX
},
774 { "syscall", XX
, XX
, XX
},
775 { "clts", XX
, XX
, XX
},
776 { "sysretP", XX
, XX
, XX
},
778 { "invd", XX
, XX
, XX
},
779 { "wbinvd", XX
, XX
, XX
},
780 { "(bad)", XX
, XX
, XX
},
781 { "ud2a", XX
, XX
, XX
},
782 { "(bad)", XX
, XX
, XX
},
784 { "femms", XX
, XX
, XX
},
785 { "", MX
, EM
, OPSUF
}, /* See OP_3DNowSuffix. */
790 { "movlpX", EX
, XM
, SIMD_Fixup
, 'h' },
791 { "unpcklpX", XM
, EX
, XX
},
792 { "unpckhpX", XM
, EX
, XX
},
794 { "movhpX", EX
, XM
, SIMD_Fixup
, 'l' },
797 { "(bad)", XX
, XX
, XX
},
798 { "(bad)", XX
, XX
, XX
},
799 { "(bad)", XX
, XX
, XX
},
800 { "(bad)", XX
, XX
, XX
},
801 { "(bad)", XX
, XX
, XX
},
802 { "(bad)", XX
, XX
, XX
},
803 { "(bad)", XX
, XX
, XX
},
805 { "movL", Rm
, Cm
, XX
},
806 { "movL", Rm
, Dm
, XX
},
807 { "movL", Cm
, Rm
, XX
},
808 { "movL", Dm
, Rm
, XX
},
809 { "movL", Rd
, Td
, XX
},
810 { "(bad)", XX
, XX
, XX
},
811 { "movL", Td
, Rd
, XX
},
812 { "(bad)", XX
, XX
, XX
},
814 { "movapX", XM
, EX
, XX
},
815 { "movapX", EX
, XM
, XX
},
817 { "movntpX", Ev
, XM
, XX
},
820 { "ucomisX", XM
,EX
, XX
},
821 { "comisX", XM
,EX
, XX
},
823 { "wrmsr", XX
, XX
, XX
},
824 { "rdtsc", XX
, XX
, XX
},
825 { "rdmsr", XX
, XX
, XX
},
826 { "rdpmc", XX
, XX
, XX
},
827 { "sysenter", XX
, XX
, XX
},
828 { "sysexit", XX
, XX
, XX
},
829 { "(bad)", XX
, XX
, XX
},
830 { "(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
},
837 { "(bad)", XX
, XX
, XX
},
838 { "(bad)", XX
, XX
, XX
},
839 { "(bad)", XX
, XX
, XX
},
841 { "cmovo", Gv
, Ev
, XX
},
842 { "cmovno", Gv
, Ev
, XX
},
843 { "cmovb", Gv
, Ev
, XX
},
844 { "cmovae", Gv
, Ev
, XX
},
845 { "cmove", Gv
, Ev
, XX
},
846 { "cmovne", Gv
, Ev
, XX
},
847 { "cmovbe", Gv
, Ev
, XX
},
848 { "cmova", Gv
, Ev
, XX
},
850 { "cmovs", Gv
, Ev
, XX
},
851 { "cmovns", Gv
, Ev
, XX
},
852 { "cmovp", Gv
, Ev
, XX
},
853 { "cmovnp", Gv
, Ev
, XX
},
854 { "cmovl", Gv
, Ev
, XX
},
855 { "cmovge", Gv
, Ev
, XX
},
856 { "cmovle", Gv
, Ev
, XX
},
857 { "cmovg", Gv
, Ev
, XX
},
859 { "movmskpX", Gd
, XS
, XX
},
863 { "andpX", XM
, EX
, XX
},
864 { "andnpX", XM
, EX
, XX
},
865 { "orpX", XM
, EX
, XX
},
866 { "xorpX", XM
, EX
, XX
},
877 { "punpcklbw", MX
, EM
, XX
},
878 { "punpcklwd", MX
, EM
, XX
},
879 { "punpckldq", MX
, EM
, XX
},
880 { "packsswb", MX
, EM
, XX
},
881 { "pcmpgtb", MX
, EM
, XX
},
882 { "pcmpgtw", MX
, EM
, XX
},
883 { "pcmpgtd", MX
, EM
, XX
},
884 { "packuswb", MX
, EM
, XX
},
886 { "punpckhbw", MX
, EM
, XX
},
887 { "punpckhwd", MX
, EM
, XX
},
888 { "punpckhdq", MX
, EM
, XX
},
889 { "packssdw", MX
, EM
, XX
},
892 { "movd", MX
, Edq
, XX
},
899 { "pcmpeqb", MX
, EM
, XX
},
900 { "pcmpeqw", MX
, EM
, XX
},
901 { "pcmpeqd", MX
, EM
, XX
},
902 { "emms", XX
, XX
, XX
},
904 { "(bad)", XX
, XX
, XX
},
905 { "(bad)", XX
, XX
, XX
},
906 { "(bad)", XX
, XX
, XX
},
907 { "(bad)", XX
, XX
, XX
},
913 { "joH", Jv
, XX
, cond_jump_flag
},
914 { "jnoH", Jv
, XX
, cond_jump_flag
},
915 { "jbH", Jv
, XX
, cond_jump_flag
},
916 { "jaeH", Jv
, XX
, cond_jump_flag
},
917 { "jeH", Jv
, XX
, cond_jump_flag
},
918 { "jneH", Jv
, XX
, cond_jump_flag
},
919 { "jbeH", Jv
, XX
, cond_jump_flag
},
920 { "jaH", Jv
, XX
, cond_jump_flag
},
922 { "jsH", Jv
, XX
, cond_jump_flag
},
923 { "jnsH", Jv
, XX
, cond_jump_flag
},
924 { "jpH", Jv
, XX
, cond_jump_flag
},
925 { "jnpH", Jv
, XX
, cond_jump_flag
},
926 { "jlH", Jv
, XX
, cond_jump_flag
},
927 { "jgeH", Jv
, XX
, cond_jump_flag
},
928 { "jleH", Jv
, XX
, cond_jump_flag
},
929 { "jgH", Jv
, XX
, cond_jump_flag
},
931 { "seto", Eb
, XX
, XX
},
932 { "setno", Eb
, XX
, XX
},
933 { "setb", Eb
, XX
, XX
},
934 { "setae", Eb
, XX
, XX
},
935 { "sete", Eb
, XX
, XX
},
936 { "setne", Eb
, XX
, XX
},
937 { "setbe", Eb
, XX
, XX
},
938 { "seta", Eb
, XX
, XX
},
940 { "sets", Eb
, XX
, XX
},
941 { "setns", Eb
, XX
, XX
},
942 { "setp", Eb
, XX
, XX
},
943 { "setnp", Eb
, XX
, XX
},
944 { "setl", Eb
, XX
, XX
},
945 { "setge", Eb
, XX
, XX
},
946 { "setle", Eb
, XX
, XX
},
947 { "setg", Eb
, XX
, XX
},
949 { "pushT", fs
, XX
, XX
},
950 { "popT", fs
, XX
, XX
},
951 { "cpuid", XX
, XX
, XX
},
952 { "btS", Ev
, Gv
, XX
},
953 { "shldS", Ev
, Gv
, Ib
},
954 { "shldS", Ev
, Gv
, CL
},
955 { "(bad)", XX
, XX
, XX
},
958 { "pushT", gs
, XX
, XX
},
959 { "popT", gs
, XX
, XX
},
960 { "rsm", XX
, XX
, XX
},
961 { "btsS", Ev
, Gv
, XX
},
962 { "shrdS", Ev
, Gv
, Ib
},
963 { "shrdS", Ev
, Gv
, CL
},
965 { "imulS", Gv
, Ev
, XX
},
967 { "cmpxchgB", Eb
, Gb
, XX
},
968 { "cmpxchgS", Ev
, Gv
, XX
},
969 { "lssS", Gv
, Mp
, XX
},
970 { "btrS", Ev
, Gv
, XX
},
971 { "lfsS", Gv
, Mp
, XX
},
972 { "lgsS", Gv
, Mp
, XX
},
973 { "movz{bR|x|bR|x}", Gv
, Eb
, XX
},
974 { "movz{wR|x|wR|x}", Gv
, Ew
, XX
}, /* yes, there really is movzww ! */
976 { "(bad)", XX
, XX
, XX
},
977 { "ud2b", XX
, XX
, XX
},
979 { "btcS", Ev
, Gv
, XX
},
980 { "bsfS", Gv
, Ev
, XX
},
981 { "bsrS", Gv
, Ev
, XX
},
982 { "movs{bR|x|bR|x}", Gv
, Eb
, XX
},
983 { "movs{wR|x|wR|x}", Gv
, Ew
, XX
}, /* yes, there really is movsww ! */
985 { "xaddB", Eb
, Gb
, XX
},
986 { "xaddS", Ev
, Gv
, XX
},
988 { "movntiS", Ev
, Gv
, XX
},
989 { "pinsrw", MX
, Ed
, Ib
},
990 { "pextrw", Gd
, MS
, Ib
},
991 { "shufpX", XM
, EX
, Ib
},
994 { "bswap", RMeAX
, XX
, XX
},
995 { "bswap", RMeCX
, XX
, XX
},
996 { "bswap", RMeDX
, XX
, XX
},
997 { "bswap", RMeBX
, XX
, XX
},
998 { "bswap", RMeSP
, XX
, XX
},
999 { "bswap", RMeBP
, XX
, XX
},
1000 { "bswap", RMeSI
, XX
, XX
},
1001 { "bswap", RMeDI
, XX
, XX
},
1004 { "psrlw", MX
, EM
, XX
},
1005 { "psrld", MX
, EM
, XX
},
1006 { "psrlq", MX
, EM
, XX
},
1007 { "paddq", MX
, EM
, XX
},
1008 { "pmullw", MX
, EM
, XX
},
1010 { "pmovmskb", Gd
, MS
, XX
},
1012 { "psubusb", MX
, EM
, XX
},
1013 { "psubusw", MX
, EM
, XX
},
1014 { "pminub", MX
, EM
, XX
},
1015 { "pand", MX
, EM
, XX
},
1016 { "paddusb", MX
, EM
, XX
},
1017 { "paddusw", MX
, EM
, XX
},
1018 { "pmaxub", MX
, EM
, XX
},
1019 { "pandn", MX
, EM
, XX
},
1021 { "pavgb", MX
, EM
, XX
},
1022 { "psraw", MX
, EM
, XX
},
1023 { "psrad", MX
, EM
, XX
},
1024 { "pavgw", MX
, EM
, XX
},
1025 { "pmulhuw", MX
, EM
, XX
},
1026 { "pmulhw", MX
, EM
, XX
},
1030 { "psubsb", MX
, EM
, XX
},
1031 { "psubsw", MX
, EM
, XX
},
1032 { "pminsw", MX
, EM
, XX
},
1033 { "por", MX
, EM
, XX
},
1034 { "paddsb", MX
, EM
, XX
},
1035 { "paddsw", MX
, EM
, XX
},
1036 { "pmaxsw", MX
, EM
, XX
},
1037 { "pxor", MX
, EM
, XX
},
1040 { "psllw", MX
, EM
, XX
},
1041 { "pslld", MX
, EM
, XX
},
1042 { "psllq", MX
, EM
, XX
},
1043 { "pmuludq", MX
, EM
, XX
},
1044 { "pmaddwd", MX
, EM
, XX
},
1045 { "psadbw", MX
, EM
, XX
},
1048 { "psubb", MX
, EM
, XX
},
1049 { "psubw", MX
, EM
, XX
},
1050 { "psubd", MX
, EM
, XX
},
1051 { "psubq", MX
, EM
, XX
},
1052 { "paddb", MX
, EM
, XX
},
1053 { "paddw", MX
, EM
, XX
},
1054 { "paddd", MX
, EM
, XX
},
1055 { "(bad)", XX
, XX
, XX
}
1058 static const unsigned char onebyte_has_modrm
[256] = {
1059 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1060 /* ------------------------------- */
1061 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1062 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1063 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1064 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1065 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1066 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1067 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1068 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1069 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1070 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1071 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1072 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1073 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1074 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1075 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1076 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1077 /* ------------------------------- */
1078 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1081 static const unsigned char twobyte_has_modrm
[256] = {
1082 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1083 /* ------------------------------- */
1084 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1085 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1086 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1087 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1088 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1089 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1090 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1091 /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1, /* 7f */
1092 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1093 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1094 /* a0 */ 0,0,0,1,1,1,0,1,0,0,0,1,1,1,1,1, /* af */
1095 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1096 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1097 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1098 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1099 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1100 /* ------------------------------- */
1101 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1104 static const unsigned char twobyte_uses_SSE_prefix
[256] = {
1105 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1106 /* ------------------------------- */
1107 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1108 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1109 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1110 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1111 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1112 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1113 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1114 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */
1115 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1116 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1117 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1118 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1119 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1120 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1121 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1122 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1123 /* ------------------------------- */
1124 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1127 static char obuf
[100];
1129 static char scratchbuf
[100];
1130 static unsigned char *start_codep
;
1131 static unsigned char *insn_codep
;
1132 static unsigned char *codep
;
1133 static disassemble_info
*the_info
;
1137 static unsigned char need_modrm
;
1139 /* If we are accessing mod/rm/reg without need_modrm set, then the
1140 values are stale. Hitting this abort likely indicates that you
1141 need to update onebyte_has_modrm or twobyte_has_modrm. */
1142 #define MODRM_CHECK if (!need_modrm) abort ()
1144 static const char **names64
;
1145 static const char **names32
;
1146 static const char **names16
;
1147 static const char **names8
;
1148 static const char **names8rex
;
1149 static const char **names_seg
;
1150 static const char **index16
;
1152 static const char *intel_names64
[] = {
1153 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1154 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1156 static const char *intel_names32
[] = {
1157 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1158 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1160 static const char *intel_names16
[] = {
1161 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1162 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1164 static const char *intel_names8
[] = {
1165 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1167 static const char *intel_names8rex
[] = {
1168 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1169 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1171 static const char *intel_names_seg
[] = {
1172 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1174 static const char *intel_index16
[] = {
1175 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1178 static const char *att_names64
[] = {
1179 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1180 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1182 static const char *att_names32
[] = {
1183 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1184 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1186 static const char *att_names16
[] = {
1187 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1188 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1190 static const char *att_names8
[] = {
1191 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1193 static const char *att_names8rex
[] = {
1194 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1195 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1197 static const char *att_names_seg
[] = {
1198 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1200 static const char *att_index16
[] = {
1201 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1204 static const struct dis386 grps
[][8] = {
1207 { "addA", Eb
, Ib
, XX
},
1208 { "orA", Eb
, Ib
, XX
},
1209 { "adcA", Eb
, Ib
, XX
},
1210 { "sbbA", Eb
, Ib
, XX
},
1211 { "andA", Eb
, Ib
, XX
},
1212 { "subA", Eb
, Ib
, XX
},
1213 { "xorA", Eb
, Ib
, XX
},
1214 { "cmpA", Eb
, Ib
, XX
}
1218 { "addQ", Ev
, Iv
, XX
},
1219 { "orQ", Ev
, Iv
, XX
},
1220 { "adcQ", Ev
, Iv
, XX
},
1221 { "sbbQ", Ev
, Iv
, XX
},
1222 { "andQ", Ev
, Iv
, XX
},
1223 { "subQ", Ev
, Iv
, XX
},
1224 { "xorQ", Ev
, Iv
, XX
},
1225 { "cmpQ", Ev
, Iv
, XX
}
1229 { "addQ", Ev
, sIb
, XX
},
1230 { "orQ", Ev
, sIb
, XX
},
1231 { "adcQ", Ev
, sIb
, XX
},
1232 { "sbbQ", Ev
, sIb
, XX
},
1233 { "andQ", Ev
, sIb
, XX
},
1234 { "subQ", Ev
, sIb
, XX
},
1235 { "xorQ", Ev
, sIb
, XX
},
1236 { "cmpQ", Ev
, sIb
, XX
}
1240 { "rolA", Eb
, Ib
, XX
},
1241 { "rorA", Eb
, Ib
, XX
},
1242 { "rclA", Eb
, Ib
, XX
},
1243 { "rcrA", Eb
, Ib
, XX
},
1244 { "shlA", Eb
, Ib
, XX
},
1245 { "shrA", Eb
, Ib
, XX
},
1246 { "(bad)", XX
, XX
, XX
},
1247 { "sarA", Eb
, Ib
, XX
},
1251 { "rolQ", Ev
, Ib
, XX
},
1252 { "rorQ", Ev
, Ib
, XX
},
1253 { "rclQ", Ev
, Ib
, XX
},
1254 { "rcrQ", Ev
, Ib
, XX
},
1255 { "shlQ", Ev
, Ib
, XX
},
1256 { "shrQ", Ev
, Ib
, XX
},
1257 { "(bad)", XX
, XX
, XX
},
1258 { "sarQ", Ev
, Ib
, XX
},
1262 { "rolA", Eb
, XX
, XX
},
1263 { "rorA", Eb
, XX
, XX
},
1264 { "rclA", Eb
, XX
, XX
},
1265 { "rcrA", Eb
, XX
, XX
},
1266 { "shlA", Eb
, XX
, XX
},
1267 { "shrA", Eb
, XX
, XX
},
1268 { "(bad)", XX
, XX
, XX
},
1269 { "sarA", Eb
, XX
, XX
},
1273 { "rolQ", Ev
, XX
, XX
},
1274 { "rorQ", Ev
, XX
, XX
},
1275 { "rclQ", Ev
, XX
, XX
},
1276 { "rcrQ", Ev
, XX
, XX
},
1277 { "shlQ", Ev
, XX
, XX
},
1278 { "shrQ", Ev
, XX
, XX
},
1279 { "(bad)", XX
, XX
, XX
},
1280 { "sarQ", Ev
, XX
, XX
},
1284 { "rolA", Eb
, CL
, XX
},
1285 { "rorA", Eb
, CL
, XX
},
1286 { "rclA", Eb
, CL
, XX
},
1287 { "rcrA", Eb
, CL
, XX
},
1288 { "shlA", Eb
, CL
, XX
},
1289 { "shrA", Eb
, CL
, XX
},
1290 { "(bad)", XX
, XX
, XX
},
1291 { "sarA", Eb
, CL
, XX
},
1295 { "rolQ", Ev
, CL
, XX
},
1296 { "rorQ", Ev
, CL
, XX
},
1297 { "rclQ", Ev
, CL
, XX
},
1298 { "rcrQ", Ev
, CL
, XX
},
1299 { "shlQ", Ev
, CL
, XX
},
1300 { "shrQ", Ev
, CL
, XX
},
1301 { "(bad)", XX
, XX
, XX
},
1302 { "sarQ", Ev
, CL
, XX
}
1306 { "testA", Eb
, Ib
, XX
},
1307 { "(bad)", Eb
, XX
, XX
},
1308 { "notA", Eb
, XX
, XX
},
1309 { "negA", Eb
, XX
, XX
},
1310 { "mulA", Eb
, XX
, XX
}, /* Don't print the implicit %al register, */
1311 { "imulA", Eb
, XX
, XX
}, /* to distinguish these opcodes from other */
1312 { "divA", Eb
, XX
, XX
}, /* mul/imul opcodes. Do the same for div */
1313 { "idivA", Eb
, XX
, XX
} /* and idiv for consistency. */
1317 { "testQ", Ev
, Iv
, XX
},
1318 { "(bad)", XX
, XX
, XX
},
1319 { "notQ", Ev
, XX
, XX
},
1320 { "negQ", Ev
, XX
, XX
},
1321 { "mulQ", Ev
, XX
, XX
}, /* Don't print the implicit register. */
1322 { "imulQ", Ev
, XX
, XX
},
1323 { "divQ", Ev
, XX
, XX
},
1324 { "idivQ", Ev
, XX
, XX
},
1328 { "incA", Eb
, XX
, XX
},
1329 { "decA", Eb
, XX
, XX
},
1330 { "(bad)", XX
, XX
, XX
},
1331 { "(bad)", XX
, XX
, XX
},
1332 { "(bad)", XX
, XX
, XX
},
1333 { "(bad)", XX
, XX
, XX
},
1334 { "(bad)", XX
, XX
, XX
},
1335 { "(bad)", XX
, XX
, XX
},
1339 { "incQ", Ev
, XX
, XX
},
1340 { "decQ", Ev
, XX
, XX
},
1341 { "callT", indirEv
, XX
, XX
},
1342 { "lcallT", indirEv
, XX
, XX
},
1343 { "jmpT", indirEv
, XX
, XX
},
1344 { "ljmpT", indirEv
, XX
, XX
},
1345 { "pushU", Ev
, XX
, XX
},
1346 { "(bad)", XX
, XX
, XX
},
1350 { "sldtQ", Ev
, XX
, XX
},
1351 { "strQ", Ev
, XX
, XX
},
1352 { "lldt", Ew
, XX
, XX
},
1353 { "ltr", Ew
, XX
, XX
},
1354 { "verr", Ew
, XX
, XX
},
1355 { "verw", Ew
, XX
, XX
},
1356 { "(bad)", XX
, XX
, XX
},
1357 { "(bad)", XX
, XX
, XX
}
1361 { "sgdtQ", M
, XX
, XX
},
1362 { "sidtQ", PNI_Fixup
, 0, XX
, XX
},
1363 { "lgdtQ", M
, XX
, XX
},
1364 { "lidtQ", M
, XX
, XX
},
1365 { "smswQ", Ev
, XX
, XX
},
1366 { "(bad)", XX
, XX
, XX
},
1367 { "lmsw", Ew
, XX
, XX
},
1368 { "invlpg", INVLPG_Fixup
, w_mode
, XX
, XX
},
1372 { "(bad)", XX
, XX
, XX
},
1373 { "(bad)", XX
, XX
, XX
},
1374 { "(bad)", XX
, XX
, XX
},
1375 { "(bad)", XX
, XX
, XX
},
1376 { "btQ", Ev
, Ib
, XX
},
1377 { "btsQ", Ev
, Ib
, XX
},
1378 { "btrQ", Ev
, Ib
, XX
},
1379 { "btcQ", Ev
, Ib
, XX
},
1383 { "(bad)", XX
, XX
, XX
},
1384 { "cmpxchg8b", Ev
, XX
, XX
},
1385 { "(bad)", XX
, XX
, XX
},
1386 { "(bad)", XX
, XX
, XX
},
1387 { "(bad)", XX
, XX
, XX
},
1388 { "(bad)", XX
, XX
, XX
},
1389 { "(bad)", XX
, XX
, XX
},
1390 { "(bad)", XX
, XX
, XX
},
1394 { "(bad)", XX
, XX
, XX
},
1395 { "(bad)", XX
, XX
, XX
},
1396 { "psrlw", MS
, Ib
, XX
},
1397 { "(bad)", XX
, XX
, XX
},
1398 { "psraw", MS
, Ib
, XX
},
1399 { "(bad)", XX
, XX
, XX
},
1400 { "psllw", MS
, Ib
, XX
},
1401 { "(bad)", XX
, XX
, XX
},
1405 { "(bad)", XX
, XX
, XX
},
1406 { "(bad)", XX
, XX
, XX
},
1407 { "psrld", MS
, Ib
, XX
},
1408 { "(bad)", XX
, XX
, XX
},
1409 { "psrad", MS
, Ib
, XX
},
1410 { "(bad)", XX
, XX
, XX
},
1411 { "pslld", MS
, Ib
, XX
},
1412 { "(bad)", XX
, XX
, XX
},
1416 { "(bad)", XX
, XX
, XX
},
1417 { "(bad)", XX
, XX
, XX
},
1418 { "psrlq", MS
, Ib
, XX
},
1419 { "psrldq", MS
, Ib
, XX
},
1420 { "(bad)", XX
, XX
, XX
},
1421 { "(bad)", XX
, XX
, XX
},
1422 { "psllq", MS
, Ib
, XX
},
1423 { "pslldq", MS
, Ib
, XX
},
1427 { "fxsave", Ev
, XX
, XX
},
1428 { "fxrstor", Ev
, XX
, XX
},
1429 { "ldmxcsr", Ev
, XX
, XX
},
1430 { "stmxcsr", Ev
, XX
, XX
},
1431 { "(bad)", XX
, XX
, XX
},
1432 { "lfence", OP_0fae
, 0, XX
, XX
},
1433 { "mfence", OP_0fae
, 0, XX
, XX
},
1434 { "clflush", OP_0fae
, 0, XX
, XX
},
1438 { "prefetchnta", Ev
, XX
, XX
},
1439 { "prefetcht0", Ev
, XX
, XX
},
1440 { "prefetcht1", Ev
, XX
, XX
},
1441 { "prefetcht2", Ev
, XX
, XX
},
1442 { "(bad)", XX
, XX
, XX
},
1443 { "(bad)", XX
, XX
, XX
},
1444 { "(bad)", XX
, XX
, XX
},
1445 { "(bad)", XX
, XX
, XX
},
1449 { "prefetch", Eb
, XX
, XX
},
1450 { "prefetchw", Eb
, XX
, XX
},
1451 { "(bad)", XX
, XX
, XX
},
1452 { "(bad)", XX
, XX
, XX
},
1453 { "(bad)", XX
, XX
, XX
},
1454 { "(bad)", XX
, XX
, XX
},
1455 { "(bad)", XX
, XX
, XX
},
1456 { "(bad)", XX
, XX
, XX
},
1460 { "xstorerng", OP_0f07
, 0, XX
, XX
},
1461 { "xcryptecb", OP_0f07
, 0, XX
, XX
},
1462 { "xcryptcbc", OP_0f07
, 0, XX
, XX
},
1463 { "(bad)", OP_0f07
, 0, XX
, XX
},
1464 { "xcryptcfb", OP_0f07
, 0, XX
, XX
},
1465 { "xcryptofb", OP_0f07
, 0, XX
, XX
},
1466 { "(bad)", OP_0f07
, 0, XX
, XX
},
1467 { "(bad)", OP_0f07
, 0, XX
, XX
},
1471 static const struct dis386 prefix_user_table
[][4] = {
1474 { "addps", XM
, EX
, XX
},
1475 { "addss", XM
, EX
, XX
},
1476 { "addpd", XM
, EX
, XX
},
1477 { "addsd", XM
, EX
, XX
},
1481 { "", XM
, EX
, OPSIMD
}, /* See OP_SIMD_SUFFIX. */
1482 { "", XM
, EX
, OPSIMD
},
1483 { "", XM
, EX
, OPSIMD
},
1484 { "", XM
, EX
, OPSIMD
},
1488 { "cvtpi2ps", XM
, EM
, XX
},
1489 { "cvtsi2ssY", XM
, Ev
, XX
},
1490 { "cvtpi2pd", XM
, EM
, XX
},
1491 { "cvtsi2sdY", XM
, Ev
, XX
},
1495 { "cvtps2pi", MX
, EX
, XX
},
1496 { "cvtss2siY", Gv
, EX
, XX
},
1497 { "cvtpd2pi", MX
, EX
, XX
},
1498 { "cvtsd2siY", Gv
, EX
, XX
},
1502 { "cvttps2pi", MX
, EX
, XX
},
1503 { "cvttss2siY", Gv
, EX
, XX
},
1504 { "cvttpd2pi", MX
, EX
, XX
},
1505 { "cvttsd2siY", Gv
, EX
, XX
},
1509 { "divps", XM
, EX
, XX
},
1510 { "divss", XM
, EX
, XX
},
1511 { "divpd", XM
, EX
, XX
},
1512 { "divsd", XM
, EX
, XX
},
1516 { "maxps", XM
, EX
, XX
},
1517 { "maxss", XM
, EX
, XX
},
1518 { "maxpd", XM
, EX
, XX
},
1519 { "maxsd", XM
, EX
, XX
},
1523 { "minps", XM
, EX
, XX
},
1524 { "minss", XM
, EX
, XX
},
1525 { "minpd", XM
, EX
, XX
},
1526 { "minsd", XM
, EX
, XX
},
1530 { "movups", XM
, EX
, XX
},
1531 { "movss", XM
, EX
, XX
},
1532 { "movupd", XM
, EX
, XX
},
1533 { "movsd", XM
, EX
, XX
},
1537 { "movups", EX
, XM
, XX
},
1538 { "movss", EX
, XM
, XX
},
1539 { "movupd", EX
, XM
, XX
},
1540 { "movsd", EX
, XM
, XX
},
1544 { "mulps", XM
, EX
, XX
},
1545 { "mulss", XM
, EX
, XX
},
1546 { "mulpd", XM
, EX
, XX
},
1547 { "mulsd", XM
, EX
, XX
},
1551 { "rcpps", XM
, EX
, XX
},
1552 { "rcpss", XM
, EX
, XX
},
1553 { "(bad)", XM
, EX
, XX
},
1554 { "(bad)", XM
, EX
, XX
},
1558 { "rsqrtps", XM
, EX
, XX
},
1559 { "rsqrtss", XM
, EX
, XX
},
1560 { "(bad)", XM
, EX
, XX
},
1561 { "(bad)", XM
, EX
, XX
},
1565 { "sqrtps", XM
, EX
, XX
},
1566 { "sqrtss", XM
, EX
, XX
},
1567 { "sqrtpd", XM
, EX
, XX
},
1568 { "sqrtsd", XM
, EX
, XX
},
1572 { "subps", XM
, EX
, XX
},
1573 { "subss", XM
, EX
, XX
},
1574 { "subpd", XM
, EX
, XX
},
1575 { "subsd", XM
, EX
, XX
},
1579 { "(bad)", XM
, EX
, XX
},
1580 { "cvtdq2pd", XM
, EX
, XX
},
1581 { "cvttpd2dq", XM
, EX
, XX
},
1582 { "cvtpd2dq", XM
, EX
, XX
},
1586 { "cvtdq2ps", XM
, EX
, XX
},
1587 { "cvttps2dq",XM
, EX
, XX
},
1588 { "cvtps2dq",XM
, EX
, XX
},
1589 { "(bad)", XM
, EX
, XX
},
1593 { "cvtps2pd", XM
, EX
, XX
},
1594 { "cvtss2sd", XM
, EX
, XX
},
1595 { "cvtpd2ps", XM
, EX
, XX
},
1596 { "cvtsd2ss", XM
, EX
, XX
},
1600 { "maskmovq", MX
, MS
, XX
},
1601 { "(bad)", XM
, EX
, XX
},
1602 { "maskmovdqu", XM
, EX
, XX
},
1603 { "(bad)", XM
, EX
, XX
},
1607 { "movq", MX
, EM
, XX
},
1608 { "movdqu", XM
, EX
, XX
},
1609 { "movdqa", XM
, EX
, XX
},
1610 { "(bad)", XM
, EX
, XX
},
1614 { "movq", EM
, MX
, XX
},
1615 { "movdqu", EX
, XM
, XX
},
1616 { "movdqa", EX
, XM
, XX
},
1617 { "(bad)", EX
, XM
, XX
},
1621 { "(bad)", EX
, XM
, XX
},
1622 { "movq2dq", XM
, MS
, XX
},
1623 { "movq", EX
, XM
, XX
},
1624 { "movdq2q", MX
, XS
, XX
},
1628 { "pshufw", MX
, EM
, Ib
},
1629 { "pshufhw", XM
, EX
, Ib
},
1630 { "pshufd", XM
, EX
, Ib
},
1631 { "pshuflw", XM
, EX
, Ib
},
1635 { "movd", Edq
, MX
, XX
},
1636 { "movq", XM
, EX
, XX
},
1637 { "movd", Edq
, XM
, XX
},
1638 { "(bad)", Ed
, XM
, XX
},
1642 { "(bad)", MX
, EX
, XX
},
1643 { "(bad)", XM
, EX
, XX
},
1644 { "punpckhqdq", XM
, EX
, XX
},
1645 { "(bad)", XM
, EX
, XX
},
1649 { "movntq", Ev
, MX
, XX
},
1650 { "(bad)", Ev
, XM
, XX
},
1651 { "movntdq", Ev
, XM
, XX
},
1652 { "(bad)", Ev
, XM
, XX
},
1656 { "(bad)", MX
, EX
, XX
},
1657 { "(bad)", XM
, EX
, XX
},
1658 { "punpcklqdq", XM
, EX
, XX
},
1659 { "(bad)", XM
, EX
, XX
},
1663 { "(bad)", MX
, EX
, XX
},
1664 { "(bad)", XM
, EX
, XX
},
1665 { "addsubpd", XM
, EX
, XX
},
1666 { "addsubps", XM
, EX
, XX
},
1670 { "(bad)", MX
, EX
, XX
},
1671 { "(bad)", XM
, EX
, XX
},
1672 { "haddpd", XM
, EX
, XX
},
1673 { "haddps", XM
, EX
, XX
},
1677 { "(bad)", MX
, EX
, XX
},
1678 { "(bad)", XM
, EX
, XX
},
1679 { "hsubpd", XM
, EX
, XX
},
1680 { "hsubps", XM
, EX
, XX
},
1684 { "movlpX", XM
, EX
, SIMD_Fixup
, 'h' }, /* really only 2 operands */
1685 { "movsldup", XM
, EX
, XX
},
1686 { "movlpd", XM
, EX
, XX
},
1687 { "movddup", XM
, EX
, XX
},
1691 { "movhpX", XM
, EX
, SIMD_Fixup
, 'l' },
1692 { "movshdup", XM
, EX
, XX
},
1693 { "movhpd", XM
, EX
, XX
},
1694 { "(bad)", XM
, EX
, XX
},
1698 { "(bad)", XM
, EX
, XX
},
1699 { "(bad)", XM
, EX
, XX
},
1700 { "(bad)", XM
, EX
, XX
},
1701 { "lddqu", XM
, M
, XX
},
1705 static const struct dis386 x86_64_table
[][2] = {
1707 { "arpl", Ew
, Gw
, XX
},
1708 { "movs{||lq|xd}", Gv
, Ed
, XX
},
1712 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1724 FETCH_DATA (the_info
, codep
+ 1);
1728 /* REX prefixes family. */
1751 prefixes
|= PREFIX_REPZ
;
1754 prefixes
|= PREFIX_REPNZ
;
1757 prefixes
|= PREFIX_LOCK
;
1760 prefixes
|= PREFIX_CS
;
1763 prefixes
|= PREFIX_SS
;
1766 prefixes
|= PREFIX_DS
;
1769 prefixes
|= PREFIX_ES
;
1772 prefixes
|= PREFIX_FS
;
1775 prefixes
|= PREFIX_GS
;
1778 prefixes
|= PREFIX_DATA
;
1781 prefixes
|= PREFIX_ADDR
;
1784 /* fwait is really an instruction. If there are prefixes
1785 before the fwait, they belong to the fwait, *not* to the
1786 following instruction. */
1789 prefixes
|= PREFIX_FWAIT
;
1793 prefixes
= PREFIX_FWAIT
;
1798 /* Rex is ignored when followed by another prefix. */
1801 oappend (prefix_name (rex
, 0));
1809 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
1813 prefix_name (int pref
, int sizeflag
)
1817 /* REX prefixes family. */
1869 return (sizeflag
& DFLAG
) ? "data16" : "data32";
1872 return (sizeflag
& AFLAG
) ? "addr32" : "addr64";
1874 return ((sizeflag
& AFLAG
) && !mode_64bit
) ? "addr16" : "addr32";
1882 static char op1out
[100], op2out
[100], op3out
[100];
1883 static int op_ad
, op_index
[3];
1884 static int two_source_ops
;
1885 static bfd_vma op_address
[3];
1886 static bfd_vma op_riprel
[3];
1887 static bfd_vma start_pc
;
1890 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1891 * (see topic "Redundant prefixes" in the "Differences from 8086"
1892 * section of the "Virtual 8086 Mode" chapter.)
1893 * 'pc' should be the address of this instruction, it will
1894 * be used to print the target address if this is a relative jump or call
1895 * The function returns the length of this instruction in bytes.
1898 static char intel_syntax
;
1899 static char open_char
;
1900 static char close_char
;
1901 static char separator_char
;
1902 static char scale_char
;
1904 /* Here for backwards compatibility. When gdb stops using
1905 print_insn_i386_att and print_insn_i386_intel these functions can
1906 disappear, and print_insn_i386 be merged into print_insn. */
1908 print_insn_i386_att (bfd_vma pc
, disassemble_info
*info
)
1912 return print_insn (pc
, info
);
1916 print_insn_i386_intel (bfd_vma pc
, disassemble_info
*info
)
1920 return print_insn (pc
, info
);
1924 print_insn_i386 (bfd_vma pc
, disassemble_info
*info
)
1928 return print_insn (pc
, info
);
1932 print_insn (bfd_vma pc
, disassemble_info
*info
)
1934 const struct dis386
*dp
;
1936 char *first
, *second
, *third
;
1938 unsigned char uses_SSE_prefix
;
1941 struct dis_private priv
;
1943 mode_64bit
= (info
->mach
== bfd_mach_x86_64_intel_syntax
1944 || info
->mach
== bfd_mach_x86_64
);
1946 if (intel_syntax
== (char) -1)
1947 intel_syntax
= (info
->mach
== bfd_mach_i386_i386_intel_syntax
1948 || info
->mach
== bfd_mach_x86_64_intel_syntax
);
1950 if (info
->mach
== bfd_mach_i386_i386
1951 || info
->mach
== bfd_mach_x86_64
1952 || info
->mach
== bfd_mach_i386_i386_intel_syntax
1953 || info
->mach
== bfd_mach_x86_64_intel_syntax
)
1954 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
1955 else if (info
->mach
== bfd_mach_i386_i8086
)
1956 priv
.orig_sizeflag
= 0;
1960 for (p
= info
->disassembler_options
; p
!= NULL
; )
1962 if (strncmp (p
, "x86-64", 6) == 0)
1965 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
1967 else if (strncmp (p
, "i386", 4) == 0)
1970 priv
.orig_sizeflag
= AFLAG
| DFLAG
;
1972 else if (strncmp (p
, "i8086", 5) == 0)
1975 priv
.orig_sizeflag
= 0;
1977 else if (strncmp (p
, "intel", 5) == 0)
1981 else if (strncmp (p
, "att", 3) == 0)
1985 else if (strncmp (p
, "addr", 4) == 0)
1987 if (p
[4] == '1' && p
[5] == '6')
1988 priv
.orig_sizeflag
&= ~AFLAG
;
1989 else if (p
[4] == '3' && p
[5] == '2')
1990 priv
.orig_sizeflag
|= AFLAG
;
1992 else if (strncmp (p
, "data", 4) == 0)
1994 if (p
[4] == '1' && p
[5] == '6')
1995 priv
.orig_sizeflag
&= ~DFLAG
;
1996 else if (p
[4] == '3' && p
[5] == '2')
1997 priv
.orig_sizeflag
|= DFLAG
;
1999 else if (strncmp (p
, "suffix", 6) == 0)
2000 priv
.orig_sizeflag
|= SUFFIX_ALWAYS
;
2002 p
= strchr (p
, ',');
2009 names64
= intel_names64
;
2010 names32
= intel_names32
;
2011 names16
= intel_names16
;
2012 names8
= intel_names8
;
2013 names8rex
= intel_names8rex
;
2014 names_seg
= intel_names_seg
;
2015 index16
= intel_index16
;
2018 separator_char
= '+';
2023 names64
= att_names64
;
2024 names32
= att_names32
;
2025 names16
= att_names16
;
2026 names8
= att_names8
;
2027 names8rex
= att_names8rex
;
2028 names_seg
= att_names_seg
;
2029 index16
= att_index16
;
2032 separator_char
= ',';
2036 /* The output looks better if we put 7 bytes on a line, since that
2037 puts most long word instructions on a single line. */
2038 info
->bytes_per_line
= 7;
2040 info
->private_data
= &priv
;
2041 priv
.max_fetched
= priv
.the_buffer
;
2042 priv
.insn_start
= pc
;
2049 op_index
[0] = op_index
[1] = op_index
[2] = -1;
2053 start_codep
= priv
.the_buffer
;
2054 codep
= priv
.the_buffer
;
2056 if (setjmp (priv
.bailout
) != 0)
2060 /* Getting here means we tried for data but didn't get it. That
2061 means we have an incomplete instruction of some sort. Just
2062 print the first byte as a prefix or a .byte pseudo-op. */
2063 if (codep
> priv
.the_buffer
)
2065 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2067 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
2070 /* Just print the first byte as a .byte instruction. */
2071 (*info
->fprintf_func
) (info
->stream
, ".byte 0x%x",
2072 (unsigned int) priv
.the_buffer
[0]);
2085 sizeflag
= priv
.orig_sizeflag
;
2087 FETCH_DATA (info
, codep
+ 1);
2088 two_source_ops
= (*codep
== 0x62) || (*codep
== 0xc8);
2090 if ((prefixes
& PREFIX_FWAIT
)
2091 && ((*codep
< 0xd8) || (*codep
> 0xdf)))
2095 /* fwait not followed by floating point instruction. Print the
2096 first prefix, which is probably fwait itself. */
2097 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2099 name
= INTERNAL_DISASSEMBLER_ERROR
;
2100 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
2106 FETCH_DATA (info
, codep
+ 2);
2107 dp
= &dis386_twobyte
[*++codep
];
2108 need_modrm
= twobyte_has_modrm
[*codep
];
2109 uses_SSE_prefix
= twobyte_uses_SSE_prefix
[*codep
];
2113 dp
= &dis386
[*codep
];
2114 need_modrm
= onebyte_has_modrm
[*codep
];
2115 uses_SSE_prefix
= 0;
2119 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_REPZ
))
2122 used_prefixes
|= PREFIX_REPZ
;
2124 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_REPNZ
))
2127 used_prefixes
|= PREFIX_REPNZ
;
2129 if (prefixes
& PREFIX_LOCK
)
2132 used_prefixes
|= PREFIX_LOCK
;
2135 if (prefixes
& PREFIX_ADDR
)
2138 if (dp
->bytemode3
!= loop_jcxz_mode
|| intel_syntax
)
2140 if ((sizeflag
& AFLAG
) || mode_64bit
)
2141 oappend ("addr32 ");
2143 oappend ("addr16 ");
2144 used_prefixes
|= PREFIX_ADDR
;
2148 if (!uses_SSE_prefix
&& (prefixes
& PREFIX_DATA
))
2151 if (dp
->bytemode3
== cond_jump_mode
2152 && dp
->bytemode1
== v_mode
2155 if (sizeflag
& DFLAG
)
2156 oappend ("data32 ");
2158 oappend ("data16 ");
2159 used_prefixes
|= PREFIX_DATA
;
2165 FETCH_DATA (info
, codep
+ 1);
2166 mod
= (*codep
>> 6) & 3;
2167 reg
= (*codep
>> 3) & 7;
2171 if (dp
->name
== NULL
&& dp
->bytemode1
== FLOATCODE
)
2178 if (dp
->name
== NULL
)
2180 switch (dp
->bytemode1
)
2183 dp
= &grps
[dp
->bytemode2
][reg
];
2186 case USE_PREFIX_USER_TABLE
:
2188 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
2189 if (prefixes
& PREFIX_REPZ
)
2193 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2194 if (prefixes
& PREFIX_DATA
)
2198 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
2199 if (prefixes
& PREFIX_REPNZ
)
2203 dp
= &prefix_user_table
[dp
->bytemode2
][index
];
2206 case X86_64_SPECIAL
:
2207 dp
= &x86_64_table
[dp
->bytemode2
][mode_64bit
];
2211 oappend (INTERNAL_DISASSEMBLER_ERROR
);
2216 if (putop (dp
->name
, sizeflag
) == 0)
2221 (*dp
->op1
) (dp
->bytemode1
, sizeflag
);
2226 (*dp
->op2
) (dp
->bytemode2
, sizeflag
);
2231 (*dp
->op3
) (dp
->bytemode3
, sizeflag
);
2235 /* See if any prefixes were not used. If so, print the first one
2236 separately. If we don't do this, we'll wind up printing an
2237 instruction stream which does not precisely correspond to the
2238 bytes we are disassembling. */
2239 if ((prefixes
& ~used_prefixes
) != 0)
2243 name
= prefix_name (priv
.the_buffer
[0], priv
.orig_sizeflag
);
2245 name
= INTERNAL_DISASSEMBLER_ERROR
;
2246 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
2249 if (rex
& ~rex_used
)
2252 name
= prefix_name (rex
| 0x40, priv
.orig_sizeflag
);
2254 name
= INTERNAL_DISASSEMBLER_ERROR
;
2255 (*info
->fprintf_func
) (info
->stream
, "%s ", name
);
2258 obufp
= obuf
+ strlen (obuf
);
2259 for (i
= strlen (obuf
); i
< 6; i
++)
2262 (*info
->fprintf_func
) (info
->stream
, "%s", obuf
);
2264 /* The enter and bound instructions are printed with operands in the same
2265 order as the intel book; everything else is printed in reverse order. */
2266 if (intel_syntax
|| two_source_ops
)
2271 op_ad
= op_index
[0];
2272 op_index
[0] = op_index
[2];
2273 op_index
[2] = op_ad
;
2284 if (op_index
[0] != -1 && !op_riprel
[0])
2285 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[0]], info
);
2287 (*info
->fprintf_func
) (info
->stream
, "%s", first
);
2293 (*info
->fprintf_func
) (info
->stream
, ",");
2294 if (op_index
[1] != -1 && !op_riprel
[1])
2295 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[1]], info
);
2297 (*info
->fprintf_func
) (info
->stream
, "%s", second
);
2303 (*info
->fprintf_func
) (info
->stream
, ",");
2304 if (op_index
[2] != -1 && !op_riprel
[2])
2305 (*info
->print_address_func
) ((bfd_vma
) op_address
[op_index
[2]], info
);
2307 (*info
->fprintf_func
) (info
->stream
, "%s", third
);
2309 for (i
= 0; i
< 3; i
++)
2310 if (op_index
[i
] != -1 && op_riprel
[i
])
2312 (*info
->fprintf_func
) (info
->stream
, " # ");
2313 (*info
->print_address_func
) ((bfd_vma
) (start_pc
+ codep
- start_codep
2314 + op_address
[op_index
[i
]]), info
);
2316 return codep
- priv
.the_buffer
;
2319 static const char *float_mem
[] = {
2394 static const unsigned char float_mem_mode
[] = {
2470 #define STi OP_STi, 0
2472 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
2473 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
2474 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
2475 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
2476 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
2477 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
2478 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
2479 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
2480 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
2482 static const struct dis386 float_reg
[][8] = {
2485 { "fadd", ST
, STi
, XX
},
2486 { "fmul", ST
, STi
, XX
},
2487 { "fcom", STi
, XX
, XX
},
2488 { "fcomp", STi
, XX
, XX
},
2489 { "fsub", ST
, STi
, XX
},
2490 { "fsubr", ST
, STi
, XX
},
2491 { "fdiv", ST
, STi
, XX
},
2492 { "fdivr", ST
, STi
, XX
},
2496 { "fld", STi
, XX
, XX
},
2497 { "fxch", STi
, XX
, XX
},
2499 { "(bad)", XX
, XX
, XX
},
2507 { "fcmovb", ST
, STi
, XX
},
2508 { "fcmove", ST
, STi
, XX
},
2509 { "fcmovbe",ST
, STi
, XX
},
2510 { "fcmovu", ST
, STi
, XX
},
2511 { "(bad)", XX
, XX
, XX
},
2513 { "(bad)", XX
, XX
, XX
},
2514 { "(bad)", XX
, XX
, XX
},
2518 { "fcmovnb",ST
, STi
, XX
},
2519 { "fcmovne",ST
, STi
, XX
},
2520 { "fcmovnbe",ST
, STi
, XX
},
2521 { "fcmovnu",ST
, STi
, XX
},
2523 { "fucomi", ST
, STi
, XX
},
2524 { "fcomi", ST
, STi
, XX
},
2525 { "(bad)", XX
, XX
, XX
},
2529 { "fadd", STi
, ST
, XX
},
2530 { "fmul", STi
, ST
, XX
},
2531 { "(bad)", XX
, XX
, XX
},
2532 { "(bad)", XX
, XX
, XX
},
2534 { "fsub", STi
, ST
, XX
},
2535 { "fsubr", STi
, ST
, XX
},
2536 { "fdiv", STi
, ST
, XX
},
2537 { "fdivr", STi
, ST
, XX
},
2539 { "fsubr", STi
, ST
, XX
},
2540 { "fsub", STi
, ST
, XX
},
2541 { "fdivr", STi
, ST
, XX
},
2542 { "fdiv", STi
, ST
, XX
},
2547 { "ffree", STi
, XX
, XX
},
2548 { "(bad)", XX
, XX
, XX
},
2549 { "fst", STi
, XX
, XX
},
2550 { "fstp", STi
, XX
, XX
},
2551 { "fucom", STi
, XX
, XX
},
2552 { "fucomp", STi
, XX
, XX
},
2553 { "(bad)", XX
, XX
, XX
},
2554 { "(bad)", XX
, XX
, XX
},
2558 { "faddp", STi
, ST
, XX
},
2559 { "fmulp", STi
, ST
, XX
},
2560 { "(bad)", XX
, XX
, XX
},
2563 { "fsubp", STi
, ST
, XX
},
2564 { "fsubrp", STi
, ST
, XX
},
2565 { "fdivp", STi
, ST
, XX
},
2566 { "fdivrp", STi
, ST
, XX
},
2568 { "fsubrp", STi
, ST
, XX
},
2569 { "fsubp", STi
, ST
, XX
},
2570 { "fdivrp", STi
, ST
, XX
},
2571 { "fdivp", STi
, ST
, XX
},
2576 { "ffreep", STi
, XX
, XX
},
2577 { "(bad)", XX
, XX
, XX
},
2578 { "(bad)", XX
, XX
, XX
},
2579 { "(bad)", XX
, XX
, XX
},
2581 { "fucomip",ST
, STi
, XX
},
2582 { "fcomip", ST
, STi
, XX
},
2583 { "(bad)", XX
, XX
, XX
},
2587 static char *fgrps
[][8] = {
2590 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2595 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2600 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2605 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2610 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2615 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2620 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2621 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2626 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2631 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2636 dofloat (int sizeflag
)
2638 const struct dis386
*dp
;
2639 unsigned char floatop
;
2641 floatop
= codep
[-1];
2645 int fp_indx
= (floatop
- 0xd8) * 8 + reg
;
2647 putop (float_mem
[fp_indx
], sizeflag
);
2649 OP_E (float_mem_mode
[fp_indx
], sizeflag
);
2652 /* Skip mod/rm byte. */
2656 dp
= &float_reg
[floatop
- 0xd8][reg
];
2657 if (dp
->name
== NULL
)
2659 putop (fgrps
[dp
->bytemode1
][rm
], sizeflag
);
2661 /* Instruction fnstsw is only one with strange arg. */
2662 if (floatop
== 0xdf && codep
[-1] == 0xe0)
2663 strcpy (op1out
, names16
[0]);
2667 putop (dp
->name
, sizeflag
);
2671 (*dp
->op1
) (dp
->bytemode1
, sizeflag
);
2674 (*dp
->op2
) (dp
->bytemode2
, sizeflag
);
2679 OP_ST (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
2685 OP_STi (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
2687 sprintf (scratchbuf
, "%%st(%d)", rm
);
2688 oappend (scratchbuf
+ intel_syntax
);
2691 /* Capital letters in template are macros. */
2693 putop (const char *template, int sizeflag
)
2698 for (p
= template; *p
; p
++)
2717 /* Alternative not valid. */
2718 strcpy (obuf
, "(bad)");
2722 else if (*p
== '\0')
2740 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
2746 if (sizeflag
& SUFFIX_ALWAYS
)
2749 case 'E': /* For jcxz/jecxz */
2752 if (sizeflag
& AFLAG
)
2758 if (sizeflag
& AFLAG
)
2760 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
2765 if ((prefixes
& PREFIX_ADDR
) || (sizeflag
& SUFFIX_ALWAYS
))
2767 if (sizeflag
& AFLAG
)
2768 *obufp
++ = mode_64bit
? 'q' : 'l';
2770 *obufp
++ = mode_64bit
? 'l' : 'w';
2771 used_prefixes
|= (prefixes
& PREFIX_ADDR
);
2777 if ((prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_CS
2778 || (prefixes
& (PREFIX_CS
| PREFIX_DS
)) == PREFIX_DS
)
2780 used_prefixes
|= prefixes
& (PREFIX_CS
| PREFIX_DS
);
2783 if (prefixes
& PREFIX_DS
)
2792 if (sizeflag
& SUFFIX_ALWAYS
)
2796 if ((prefixes
& PREFIX_FWAIT
) == 0)
2799 used_prefixes
|= PREFIX_FWAIT
;
2802 USED_REX (REX_MODE64
);
2803 if (rex
& REX_MODE64
)
2820 if ((prefixes
& PREFIX_DATA
)
2821 || (rex
& REX_MODE64
)
2822 || (sizeflag
& SUFFIX_ALWAYS
))
2824 USED_REX (REX_MODE64
);
2825 if (rex
& REX_MODE64
)
2829 if (sizeflag
& DFLAG
)
2833 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2849 USED_REX (REX_MODE64
);
2850 if (mod
!= 3 || (sizeflag
& SUFFIX_ALWAYS
))
2852 if (rex
& REX_MODE64
)
2856 if (sizeflag
& DFLAG
)
2860 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2865 USED_REX (REX_MODE64
);
2868 if (rex
& REX_MODE64
)
2873 else if (sizeflag
& DFLAG
)
2886 if (rex
& REX_MODE64
)
2888 else if (sizeflag
& DFLAG
)
2893 if (!(rex
& REX_MODE64
))
2894 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2899 if (sizeflag
& SUFFIX_ALWAYS
)
2901 if (rex
& REX_MODE64
)
2905 if (sizeflag
& DFLAG
)
2909 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2914 if (prefixes
& PREFIX_DATA
)
2918 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2923 if (rex
& REX_MODE64
)
2925 USED_REX (REX_MODE64
);
2929 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
2931 /* operand size flag for cwtl, cbtw */
2935 else if (sizeflag
& DFLAG
)
2946 if (sizeflag
& DFLAG
)
2957 used_prefixes
|= (prefixes
& PREFIX_DATA
);
2966 oappend (const char *s
)
2969 obufp
+= strlen (s
);
2975 if (prefixes
& PREFIX_CS
)
2977 used_prefixes
|= PREFIX_CS
;
2978 oappend ("%cs:" + intel_syntax
);
2980 if (prefixes
& PREFIX_DS
)
2982 used_prefixes
|= PREFIX_DS
;
2983 oappend ("%ds:" + intel_syntax
);
2985 if (prefixes
& PREFIX_SS
)
2987 used_prefixes
|= PREFIX_SS
;
2988 oappend ("%ss:" + intel_syntax
);
2990 if (prefixes
& PREFIX_ES
)
2992 used_prefixes
|= PREFIX_ES
;
2993 oappend ("%es:" + intel_syntax
);
2995 if (prefixes
& PREFIX_FS
)
2997 used_prefixes
|= PREFIX_FS
;
2998 oappend ("%fs:" + intel_syntax
);
3000 if (prefixes
& PREFIX_GS
)
3002 used_prefixes
|= PREFIX_GS
;
3003 oappend ("%gs:" + intel_syntax
);
3008 OP_indirE (int bytemode
, int sizeflag
)
3012 OP_E (bytemode
, sizeflag
);
3016 print_operand_value (char *buf
, int hex
, bfd_vma disp
)
3026 sprintf_vma (tmp
, disp
);
3027 for (i
= 0; tmp
[i
] == '0' && tmp
[i
+ 1]; i
++);
3028 strcpy (buf
+ 2, tmp
+ i
);
3032 bfd_signed_vma v
= disp
;
3039 /* Check for possible overflow on 0x8000000000000000. */
3042 strcpy (buf
, "9223372036854775808");
3056 tmp
[28 - i
] = (v
% 10) + '0';
3060 strcpy (buf
, tmp
+ 29 - i
);
3066 sprintf (buf
, "0x%x", (unsigned int) disp
);
3068 sprintf (buf
, "%d", (int) disp
);
3073 OP_E (int bytemode
, int sizeflag
)
3078 USED_REX (REX_EXTZ
);
3082 /* Skip mod/rm byte. */
3093 oappend (names8rex
[rm
+ add
]);
3095 oappend (names8
[rm
+ add
]);
3098 oappend (names16
[rm
+ add
]);
3101 oappend (names32
[rm
+ add
]);
3104 oappend (names64
[rm
+ add
]);
3108 oappend (names64
[rm
+ add
]);
3110 oappend (names32
[rm
+ add
]);
3114 USED_REX (REX_MODE64
);
3115 if (rex
& REX_MODE64
)
3116 oappend (names64
[rm
+ add
]);
3117 else if ((sizeflag
& DFLAG
) || bytemode
== dq_mode
)
3118 oappend (names32
[rm
+ add
]);
3120 oappend (names16
[rm
+ add
]);
3121 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3126 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3135 if ((sizeflag
& AFLAG
) || mode_64bit
) /* 32 bit address mode */
3150 FETCH_DATA (the_info
, codep
+ 1);
3151 scale
= (*codep
>> 6) & 3;
3152 index
= (*codep
>> 3) & 7;
3154 USED_REX (REX_EXTY
);
3155 USED_REX (REX_EXTZ
);
3166 if ((base
& 7) == 5)
3169 if (mode_64bit
&& !havesib
&& (sizeflag
& AFLAG
))
3175 FETCH_DATA (the_info
, codep
+ 1);
3177 if ((disp
& 0x80) != 0)
3186 if (mod
!= 0 || (base
& 7) == 5)
3188 print_operand_value (scratchbuf
, !riprel
, disp
);
3189 oappend (scratchbuf
);
3197 if (havebase
|| (havesib
&& (index
!= 4 || scale
!= 0)))
3204 oappend ("BYTE PTR ");
3207 oappend ("WORD PTR ");
3210 if (sizeflag
& DFLAG
)
3211 oappend ("DWORD PTR ");
3213 oappend ("WORD PTR ");
3216 oappend ("DWORD PTR ");
3219 oappend ("QWORD PTR ");
3223 oappend ("DWORD PTR ");
3225 oappend ("QWORD PTR ");
3228 oappend ("XWORD PTR ");
3234 *obufp
++ = open_char
;
3235 if (intel_syntax
&& riprel
)
3238 USED_REX (REX_EXTZ
);
3239 if (!havesib
&& (rex
& REX_EXTZ
))
3242 oappend (mode_64bit
&& (sizeflag
& AFLAG
)
3243 ? names64
[base
] : names32
[base
]);
3252 *obufp
++ = separator_char
;
3255 sprintf (scratchbuf
, "%s",
3256 mode_64bit
&& (sizeflag
& AFLAG
)
3257 ? names64
[index
] : names32
[index
]);
3260 sprintf (scratchbuf
, ",%s",
3261 mode_64bit
&& (sizeflag
& AFLAG
)
3262 ? names64
[index
] : names32
[index
]);
3263 oappend (scratchbuf
);
3265 if (scale
!= 0 || (!intel_syntax
&& index
!= 4))
3267 *obufp
++ = scale_char
;
3269 sprintf (scratchbuf
, "%d", 1 << scale
);
3270 oappend (scratchbuf
);
3274 if (mod
!= 0 || (base
& 7) == 5)
3276 /* Don't print zero displacements. */
3279 if ((bfd_signed_vma
) disp
> 0)
3285 print_operand_value (scratchbuf
, 0, disp
);
3286 oappend (scratchbuf
);
3290 *obufp
++ = close_char
;
3293 else if (intel_syntax
)
3295 if (mod
!= 0 || (base
& 7) == 5)
3297 if (prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
3298 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
))
3302 oappend (names_seg
[ds_reg
- es_reg
]);
3305 print_operand_value (scratchbuf
, 1, disp
);
3306 oappend (scratchbuf
);
3311 { /* 16 bit address mode */
3318 if ((disp
& 0x8000) != 0)
3323 FETCH_DATA (the_info
, codep
+ 1);
3325 if ((disp
& 0x80) != 0)
3330 if ((disp
& 0x8000) != 0)
3336 if (mod
!= 0 || (rm
& 7) == 6)
3338 print_operand_value (scratchbuf
, 0, disp
);
3339 oappend (scratchbuf
);
3342 if (mod
!= 0 || (rm
& 7) != 6)
3344 *obufp
++ = open_char
;
3346 oappend (index16
[rm
+ add
]);
3347 *obufp
++ = close_char
;
3354 OP_G (int bytemode
, int sizeflag
)
3357 USED_REX (REX_EXTX
);
3365 oappend (names8rex
[reg
+ add
]);
3367 oappend (names8
[reg
+ add
]);
3370 oappend (names16
[reg
+ add
]);
3373 oappend (names32
[reg
+ add
]);
3376 oappend (names64
[reg
+ add
]);
3379 USED_REX (REX_MODE64
);
3380 if (rex
& REX_MODE64
)
3381 oappend (names64
[reg
+ add
]);
3382 else if (sizeflag
& DFLAG
)
3383 oappend (names32
[reg
+ add
]);
3385 oappend (names16
[reg
+ add
]);
3386 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3389 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3402 FETCH_DATA (the_info
, codep
+ 8);
3403 a
= *codep
++ & 0xff;
3404 a
|= (*codep
++ & 0xff) << 8;
3405 a
|= (*codep
++ & 0xff) << 16;
3406 a
|= (*codep
++ & 0xff) << 24;
3407 b
= *codep
++ & 0xff;
3408 b
|= (*codep
++ & 0xff) << 8;
3409 b
|= (*codep
++ & 0xff) << 16;
3410 b
|= (*codep
++ & 0xff) << 24;
3411 x
= a
+ ((bfd_vma
) b
<< 32);
3419 static bfd_signed_vma
3422 bfd_signed_vma x
= 0;
3424 FETCH_DATA (the_info
, codep
+ 4);
3425 x
= *codep
++ & (bfd_signed_vma
) 0xff;
3426 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
3427 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
3428 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
3432 static bfd_signed_vma
3435 bfd_signed_vma x
= 0;
3437 FETCH_DATA (the_info
, codep
+ 4);
3438 x
= *codep
++ & (bfd_signed_vma
) 0xff;
3439 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 8;
3440 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 16;
3441 x
|= (*codep
++ & (bfd_signed_vma
) 0xff) << 24;
3443 x
= (x
^ ((bfd_signed_vma
) 1 << 31)) - ((bfd_signed_vma
) 1 << 31);
3453 FETCH_DATA (the_info
, codep
+ 2);
3454 x
= *codep
++ & 0xff;
3455 x
|= (*codep
++ & 0xff) << 8;
3460 set_op (bfd_vma op
, int riprel
)
3462 op_index
[op_ad
] = op_ad
;
3465 op_address
[op_ad
] = op
;
3466 op_riprel
[op_ad
] = riprel
;
3470 /* Mask to get a 32-bit address. */
3471 op_address
[op_ad
] = op
& 0xffffffff;
3472 op_riprel
[op_ad
] = riprel
& 0xffffffff;
3477 OP_REG (int code
, int sizeflag
)
3481 USED_REX (REX_EXTZ
);
3493 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
3494 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
3495 s
= names16
[code
- ax_reg
+ add
];
3497 case es_reg
: case ss_reg
: case cs_reg
:
3498 case ds_reg
: case fs_reg
: case gs_reg
:
3499 s
= names_seg
[code
- es_reg
+ add
];
3501 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
3502 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
3505 s
= names8rex
[code
- al_reg
+ add
];
3507 s
= names8
[code
- al_reg
];
3509 case rAX_reg
: case rCX_reg
: case rDX_reg
: case rBX_reg
:
3510 case rSP_reg
: case rBP_reg
: case rSI_reg
: case rDI_reg
:
3513 s
= names64
[code
- rAX_reg
+ add
];
3516 code
+= eAX_reg
- rAX_reg
;
3518 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
3519 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
3520 USED_REX (REX_MODE64
);
3521 if (rex
& REX_MODE64
)
3522 s
= names64
[code
- eAX_reg
+ add
];
3523 else if (sizeflag
& DFLAG
)
3524 s
= names32
[code
- eAX_reg
+ add
];
3526 s
= names16
[code
- eAX_reg
+ add
];
3527 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3530 s
= INTERNAL_DISASSEMBLER_ERROR
;
3537 OP_IMREG (int code
, int sizeflag
)
3549 case ax_reg
: case cx_reg
: case dx_reg
: case bx_reg
:
3550 case sp_reg
: case bp_reg
: case si_reg
: case di_reg
:
3551 s
= names16
[code
- ax_reg
];
3553 case es_reg
: case ss_reg
: case cs_reg
:
3554 case ds_reg
: case fs_reg
: case gs_reg
:
3555 s
= names_seg
[code
- es_reg
];
3557 case al_reg
: case ah_reg
: case cl_reg
: case ch_reg
:
3558 case dl_reg
: case dh_reg
: case bl_reg
: case bh_reg
:
3561 s
= names8rex
[code
- al_reg
];
3563 s
= names8
[code
- al_reg
];
3565 case eAX_reg
: case eCX_reg
: case eDX_reg
: case eBX_reg
:
3566 case eSP_reg
: case eBP_reg
: case eSI_reg
: case eDI_reg
:
3567 USED_REX (REX_MODE64
);
3568 if (rex
& REX_MODE64
)
3569 s
= names64
[code
- eAX_reg
];
3570 else if (sizeflag
& DFLAG
)
3571 s
= names32
[code
- eAX_reg
];
3573 s
= names16
[code
- eAX_reg
];
3574 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3577 s
= INTERNAL_DISASSEMBLER_ERROR
;
3584 OP_I (int bytemode
, int sizeflag
)
3587 bfd_signed_vma mask
= -1;
3592 FETCH_DATA (the_info
, codep
+ 1);
3604 USED_REX (REX_MODE64
);
3605 if (rex
& REX_MODE64
)
3607 else if (sizeflag
& DFLAG
)
3617 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3624 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3629 scratchbuf
[0] = '$';
3630 print_operand_value (scratchbuf
+ 1, 1, op
);
3631 oappend (scratchbuf
+ intel_syntax
);
3632 scratchbuf
[0] = '\0';
3636 OP_I64 (int bytemode
, int sizeflag
)
3639 bfd_signed_vma mask
= -1;
3643 OP_I (bytemode
, sizeflag
);
3650 FETCH_DATA (the_info
, codep
+ 1);
3655 USED_REX (REX_MODE64
);
3656 if (rex
& REX_MODE64
)
3658 else if (sizeflag
& DFLAG
)
3668 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3675 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3680 scratchbuf
[0] = '$';
3681 print_operand_value (scratchbuf
+ 1, 1, op
);
3682 oappend (scratchbuf
+ intel_syntax
);
3683 scratchbuf
[0] = '\0';
3687 OP_sI (int bytemode
, int sizeflag
)
3690 bfd_signed_vma mask
= -1;
3695 FETCH_DATA (the_info
, codep
+ 1);
3697 if ((op
& 0x80) != 0)
3702 USED_REX (REX_MODE64
);
3703 if (rex
& REX_MODE64
)
3705 else if (sizeflag
& DFLAG
)
3714 if ((op
& 0x8000) != 0)
3717 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3722 if ((op
& 0x8000) != 0)
3726 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3730 scratchbuf
[0] = '$';
3731 print_operand_value (scratchbuf
+ 1, 1, op
);
3732 oappend (scratchbuf
+ intel_syntax
);
3736 OP_J (int bytemode
, int sizeflag
)
3744 FETCH_DATA (the_info
, codep
+ 1);
3746 if ((disp
& 0x80) != 0)
3750 if (sizeflag
& DFLAG
)
3755 /* For some reason, a data16 prefix on a jump instruction
3756 means that the pc is masked to 16 bits after the
3757 displacement is added! */
3762 oappend (INTERNAL_DISASSEMBLER_ERROR
);
3765 disp
= (start_pc
+ codep
- start_codep
+ disp
) & mask
;
3767 print_operand_value (scratchbuf
, 1, disp
);
3768 oappend (scratchbuf
);
3772 OP_SEG (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
3774 oappend (names_seg
[reg
]);
3778 OP_DIR (int dummy ATTRIBUTE_UNUSED
, int sizeflag
)
3782 if (sizeflag
& DFLAG
)
3792 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3794 sprintf (scratchbuf
, "0x%x,0x%x", seg
, offset
);
3796 sprintf (scratchbuf
, "$0x%x,$0x%x", seg
, offset
);
3797 oappend (scratchbuf
);
3801 OP_OFF (int bytemode ATTRIBUTE_UNUSED
, int sizeflag
)
3807 if ((sizeflag
& AFLAG
) || mode_64bit
)
3814 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
3815 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
3817 oappend (names_seg
[ds_reg
- es_reg
]);
3821 print_operand_value (scratchbuf
, 1, off
);
3822 oappend (scratchbuf
);
3826 OP_OFF64 (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
3832 OP_OFF (bytemode
, sizeflag
);
3842 if (!(prefixes
& (PREFIX_CS
| PREFIX_SS
| PREFIX_DS
3843 | PREFIX_ES
| PREFIX_FS
| PREFIX_GS
)))
3845 oappend (names_seg
[ds_reg
- es_reg
]);
3849 print_operand_value (scratchbuf
, 1, off
);
3850 oappend (scratchbuf
);
3854 ptr_reg (int code
, int sizeflag
)
3858 *obufp
++ = open_char
;
3859 USED_REX (REX_MODE64
);
3860 if (rex
& REX_MODE64
)
3862 if (!(sizeflag
& AFLAG
))
3863 s
= names32
[code
- eAX_reg
];
3865 s
= names64
[code
- eAX_reg
];
3867 else if (sizeflag
& AFLAG
)
3868 s
= names32
[code
- eAX_reg
];
3870 s
= names16
[code
- eAX_reg
];
3872 *obufp
++ = close_char
;
3877 OP_ESreg (int code
, int sizeflag
)
3879 oappend ("%es:" + intel_syntax
);
3880 ptr_reg (code
, sizeflag
);
3884 OP_DSreg (int code
, int sizeflag
)
3893 prefixes
|= PREFIX_DS
;
3895 ptr_reg (code
, sizeflag
);
3899 OP_C (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
3902 USED_REX (REX_EXTX
);
3905 sprintf (scratchbuf
, "%%cr%d", reg
+ add
);
3906 oappend (scratchbuf
+ intel_syntax
);
3910 OP_D (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
3913 USED_REX (REX_EXTX
);
3917 sprintf (scratchbuf
, "db%d", reg
+ add
);
3919 sprintf (scratchbuf
, "%%db%d", reg
+ add
);
3920 oappend (scratchbuf
);
3924 OP_T (int dummy ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
3926 sprintf (scratchbuf
, "%%tr%d", reg
);
3927 oappend (scratchbuf
+ intel_syntax
);
3931 OP_Rd (int bytemode
, int sizeflag
)
3934 OP_E (bytemode
, sizeflag
);
3940 OP_MMX (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
3943 USED_REX (REX_EXTX
);
3946 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3947 if (prefixes
& PREFIX_DATA
)
3948 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
3950 sprintf (scratchbuf
, "%%mm%d", reg
+ add
);
3951 oappend (scratchbuf
+ intel_syntax
);
3955 OP_XMM (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
3958 USED_REX (REX_EXTX
);
3961 sprintf (scratchbuf
, "%%xmm%d", reg
+ add
);
3962 oappend (scratchbuf
+ intel_syntax
);
3966 OP_EM (int bytemode
, int sizeflag
)
3971 OP_E (bytemode
, sizeflag
);
3974 USED_REX (REX_EXTZ
);
3978 /* Skip mod/rm byte. */
3981 used_prefixes
|= (prefixes
& PREFIX_DATA
);
3982 if (prefixes
& PREFIX_DATA
)
3983 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
3985 sprintf (scratchbuf
, "%%mm%d", rm
+ add
);
3986 oappend (scratchbuf
+ intel_syntax
);
3990 OP_EX (int bytemode
, int sizeflag
)
3995 OP_E (bytemode
, sizeflag
);
3998 USED_REX (REX_EXTZ
);
4002 /* Skip mod/rm byte. */
4005 sprintf (scratchbuf
, "%%xmm%d", rm
+ add
);
4006 oappend (scratchbuf
+ intel_syntax
);
4010 OP_MS (int bytemode
, int sizeflag
)
4013 OP_EM (bytemode
, sizeflag
);
4019 OP_XS (int bytemode
, int sizeflag
)
4022 OP_EX (bytemode
, sizeflag
);
4028 OP_M (int bytemode
, int sizeflag
)
4031 BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
4033 OP_E (bytemode
, sizeflag
);
4037 OP_0f07 (int bytemode
, int sizeflag
)
4039 if (mod
!= 3 || rm
!= 0)
4042 OP_E (bytemode
, sizeflag
);
4046 OP_0fae (int bytemode
, int sizeflag
)
4051 strcpy (obuf
+ strlen (obuf
) - sizeof ("clflush") + 1, "sfence");
4053 if (reg
< 5 || rm
!= 0)
4055 BadOp (); /* bad sfence, mfence, or lfence */
4061 BadOp (); /* bad clflush */
4065 OP_E (bytemode
, sizeflag
);
4069 NOP_Fixup (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4071 /* NOP with REPZ prefix is called PAUSE. */
4072 if (prefixes
== PREFIX_REPZ
)
4073 strcpy (obuf
, "pause");
4076 static const char *const Suffix3DNow
[] = {
4077 /* 00 */ NULL
, NULL
, NULL
, NULL
,
4078 /* 04 */ NULL
, NULL
, NULL
, NULL
,
4079 /* 08 */ NULL
, NULL
, NULL
, NULL
,
4080 /* 0C */ "pi2fw", "pi2fd", NULL
, NULL
,
4081 /* 10 */ NULL
, NULL
, NULL
, NULL
,
4082 /* 14 */ NULL
, NULL
, NULL
, NULL
,
4083 /* 18 */ NULL
, NULL
, NULL
, NULL
,
4084 /* 1C */ "pf2iw", "pf2id", NULL
, NULL
,
4085 /* 20 */ NULL
, NULL
, NULL
, NULL
,
4086 /* 24 */ NULL
, NULL
, NULL
, NULL
,
4087 /* 28 */ NULL
, NULL
, NULL
, NULL
,
4088 /* 2C */ NULL
, NULL
, NULL
, NULL
,
4089 /* 30 */ NULL
, NULL
, NULL
, NULL
,
4090 /* 34 */ NULL
, NULL
, NULL
, NULL
,
4091 /* 38 */ NULL
, NULL
, NULL
, NULL
,
4092 /* 3C */ NULL
, NULL
, NULL
, NULL
,
4093 /* 40 */ NULL
, NULL
, NULL
, NULL
,
4094 /* 44 */ NULL
, NULL
, NULL
, NULL
,
4095 /* 48 */ NULL
, NULL
, NULL
, NULL
,
4096 /* 4C */ NULL
, NULL
, NULL
, NULL
,
4097 /* 50 */ NULL
, NULL
, NULL
, NULL
,
4098 /* 54 */ NULL
, NULL
, NULL
, NULL
,
4099 /* 58 */ NULL
, NULL
, NULL
, NULL
,
4100 /* 5C */ NULL
, NULL
, NULL
, NULL
,
4101 /* 60 */ NULL
, NULL
, NULL
, NULL
,
4102 /* 64 */ NULL
, NULL
, NULL
, NULL
,
4103 /* 68 */ NULL
, NULL
, NULL
, NULL
,
4104 /* 6C */ NULL
, NULL
, NULL
, NULL
,
4105 /* 70 */ NULL
, NULL
, NULL
, NULL
,
4106 /* 74 */ NULL
, NULL
, NULL
, NULL
,
4107 /* 78 */ NULL
, NULL
, NULL
, NULL
,
4108 /* 7C */ NULL
, NULL
, NULL
, NULL
,
4109 /* 80 */ NULL
, NULL
, NULL
, NULL
,
4110 /* 84 */ NULL
, NULL
, NULL
, NULL
,
4111 /* 88 */ NULL
, NULL
, "pfnacc", NULL
,
4112 /* 8C */ NULL
, NULL
, "pfpnacc", NULL
,
4113 /* 90 */ "pfcmpge", NULL
, NULL
, NULL
,
4114 /* 94 */ "pfmin", NULL
, "pfrcp", "pfrsqrt",
4115 /* 98 */ NULL
, NULL
, "pfsub", NULL
,
4116 /* 9C */ NULL
, NULL
, "pfadd", NULL
,
4117 /* A0 */ "pfcmpgt", NULL
, NULL
, NULL
,
4118 /* A4 */ "pfmax", NULL
, "pfrcpit1", "pfrsqit1",
4119 /* A8 */ NULL
, NULL
, "pfsubr", NULL
,
4120 /* AC */ NULL
, NULL
, "pfacc", NULL
,
4121 /* B0 */ "pfcmpeq", NULL
, NULL
, NULL
,
4122 /* B4 */ "pfmul", NULL
, "pfrcpit2", "pfmulhrw",
4123 /* B8 */ NULL
, NULL
, NULL
, "pswapd",
4124 /* BC */ NULL
, NULL
, NULL
, "pavgusb",
4125 /* C0 */ NULL
, NULL
, NULL
, NULL
,
4126 /* C4 */ NULL
, NULL
, NULL
, NULL
,
4127 /* C8 */ NULL
, NULL
, NULL
, NULL
,
4128 /* CC */ NULL
, NULL
, NULL
, NULL
,
4129 /* D0 */ NULL
, NULL
, NULL
, NULL
,
4130 /* D4 */ NULL
, NULL
, NULL
, NULL
,
4131 /* D8 */ NULL
, NULL
, NULL
, NULL
,
4132 /* DC */ NULL
, NULL
, NULL
, NULL
,
4133 /* E0 */ NULL
, NULL
, NULL
, NULL
,
4134 /* E4 */ NULL
, NULL
, NULL
, NULL
,
4135 /* E8 */ NULL
, NULL
, NULL
, NULL
,
4136 /* EC */ NULL
, NULL
, NULL
, NULL
,
4137 /* F0 */ NULL
, NULL
, NULL
, NULL
,
4138 /* F4 */ NULL
, NULL
, NULL
, NULL
,
4139 /* F8 */ NULL
, NULL
, NULL
, NULL
,
4140 /* FC */ NULL
, NULL
, NULL
, NULL
,
4144 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4146 const char *mnemonic
;
4148 FETCH_DATA (the_info
, codep
+ 1);
4149 /* AMD 3DNow! instructions are specified by an opcode suffix in the
4150 place where an 8-bit immediate would normally go. ie. the last
4151 byte of the instruction. */
4152 obufp
= obuf
+ strlen (obuf
);
4153 mnemonic
= Suffix3DNow
[*codep
++ & 0xff];
4158 /* Since a variable sized modrm/sib chunk is between the start
4159 of the opcode (0x0f0f) and the opcode suffix, we need to do
4160 all the modrm processing first, and don't know until now that
4161 we have a bad opcode. This necessitates some cleaning up. */
4168 static const char *simd_cmp_op
[] = {
4180 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED
, int sizeflag ATTRIBUTE_UNUSED
)
4182 unsigned int cmp_type
;
4184 FETCH_DATA (the_info
, codep
+ 1);
4185 obufp
= obuf
+ strlen (obuf
);
4186 cmp_type
= *codep
++ & 0xff;
4189 char suffix1
= 'p', suffix2
= 's';
4190 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
4191 if (prefixes
& PREFIX_REPZ
)
4195 used_prefixes
|= (prefixes
& PREFIX_DATA
);
4196 if (prefixes
& PREFIX_DATA
)
4200 used_prefixes
|= (prefixes
& PREFIX_REPNZ
);
4201 if (prefixes
& PREFIX_REPNZ
)
4202 suffix1
= 's', suffix2
= 'd';
4205 sprintf (scratchbuf
, "cmp%s%c%c",
4206 simd_cmp_op
[cmp_type
], suffix1
, suffix2
);
4207 used_prefixes
|= (prefixes
& PREFIX_REPZ
);
4208 oappend (scratchbuf
);
4212 /* We have a bad extension byte. Clean up. */
4220 SIMD_Fixup (int extrachar
, int sizeflag ATTRIBUTE_UNUSED
)
4222 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
4223 forms of these instructions. */
4226 char *p
= obuf
+ strlen (obuf
);
4229 *(p
- 1) = *(p
- 2);
4230 *(p
- 2) = *(p
- 3);
4231 *(p
- 3) = extrachar
;
4236 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED
, int sizeflag
)
4238 if (mod
== 3 && reg
== 1 && rm
<= 1)
4240 /* Override "sidt". */
4241 char *p
= obuf
+ strlen (obuf
) - 4;
4243 /* We might have a suffix. */
4249 /* mwait %eax,%ecx */
4250 strcpy (p
, "mwait");
4254 /* monitor %eax,%ecx,%edx" */
4255 strcpy (p
, "monitor");
4256 strcpy (op3out
, names32
[2]);
4258 strcpy (op1out
, names32
[0]);
4259 strcpy (op2out
, names32
[1]);
4269 INVLPG_Fixup (int bytemode
, int sizeflag
)
4273 char *p
= obuf
+ strlen (obuf
);
4275 /* Override "invlpg". */
4276 strcpy (p
- 6, "swapgs");
4280 OP_E (bytemode
, sizeflag
);
4286 /* Throw away prefixes and 1st. opcode byte. */
4287 codep
= insn_codep
+ 1;