* gprof.c (main): For line-by-line profiling, there is no need to
[binutils.git] / opcodes / i386-dis.c
blob0bcd107d379187025753ae131e7ebe25be5b3949
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)
23 * July 1988
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.
38 #include "dis-asm.h"
39 #include "sysdep.h"
40 #include "opintl.h"
42 #define MAXLEN 20
44 #include <setjmp.h>
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
50 #endif
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);
105 struct dis_private {
106 /* Points to first byte not fetched. */
107 bfd_byte *max_fetched;
108 bfd_byte the_buffer[MAXLEN];
109 bfd_vma insn_start;
110 int orig_sizeflag;
111 jmp_buf bailout;
114 /* The opcode for the fwait instruction, which we treat as a prefix
115 when we can. */
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. */
122 static int prefixes;
124 /* REX prefix the current instruction. See below. */
125 static int rex;
126 /* Bits of REX we've already used. */
127 static int rex_used;
128 #define REX_MODE64 8
129 #define REX_EXTX 4
130 #define REX_EXTY 2
131 #define REX_EXTZ 1
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) \
138 if (value) \
139 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
140 else \
141 rex_used |= 0x40; \
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
152 #define PREFIX_CS 8
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
164 on error. */
165 #define FETCH_DATA(info, addr) \
166 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
167 ? 1 : fetch_data ((info), (addr)))
169 static int
170 fetch_data (struct disassemble_info *info, bfd_byte *addr)
172 int status;
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,
177 priv->max_fetched,
178 addr - priv->max_fetched,
179 info);
180 if (status != 0)
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
185 STATUS. */
186 if (priv->max_fetched == priv->the_buffer)
187 (*info->memory_error_func) (status, start, info);
188 longjmp (priv->bailout, 1);
190 else
191 priv->max_fetched = addr;
192 return 1;
195 #define XX NULL, 0
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
275 #define Ap OP_DIR, 0
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
293 #define MX OP_MMX, 0
294 #define XM OP_XMM, 0
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
307 #define AFLAG 2
308 #define DFLAG 1
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. */
321 #define es_reg 100
322 #define cs_reg 101
323 #define ss_reg 102
324 #define ds_reg 103
325 #define fs_reg 104
326 #define gs_reg 105
328 #define eAX_reg 108
329 #define eCX_reg 109
330 #define eDX_reg 110
331 #define eBX_reg 111
332 #define eSP_reg 112
333 #define eBP_reg 113
334 #define eSI_reg 114
335 #define eDI_reg 115
337 #define al_reg 116
338 #define cl_reg 117
339 #define dl_reg 118
340 #define bl_reg 119
341 #define ah_reg 120
342 #define ch_reg 121
343 #define dh_reg 122
344 #define bh_reg 123
346 #define ax_reg 124
347 #define cx_reg 125
348 #define dx_reg 126
349 #define bx_reg 127
350 #define sp_reg 128
351 #define bp_reg 129
352 #define si_reg 130
353 #define di_reg 131
355 #define rAX_reg 132
356 #define rCX_reg 133
357 #define rDX_reg 134
358 #define rBX_reg 135
359 #define rSP_reg 136
360 #define rBP_reg 137
361 #define rSI_reg 138
362 #define rDI_reg 139
364 #define indir_dx_reg 150
366 #define FLOATCODE 1
367 #define USE_GROUPS 2
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);
436 struct dis386 {
437 const char *name;
438 op_rtn op1;
439 int bytemode1;
440 op_rtn op2;
441 int bytemode2;
442 op_rtn op3;
443 int bytemode3;
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
458 . is true
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"
468 for the details.
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[] = {
477 /* 00 */
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 },
486 /* 08 */
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 */
495 /* 10 */
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 },
504 /* 18 */
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 },
513 /* 20 */
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 },
522 /* 28 */
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 },
531 /* 30 */
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 },
540 /* 38 */
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 },
549 /* 40 */
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 },
558 /* 48 */
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 },
567 /* 50 */
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 },
576 /* 58 */
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 },
585 /* 60 */
586 { "pusha{P|}", XX, XX, XX },
587 { "popa{P|}", XX, XX, XX },
588 { "bound{S|}", Gv, Ma, XX },
589 { X86_64_0 },
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 */
594 /* 68 */
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 },
603 /* 70 */
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 },
612 /* 78 */
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 },
621 /* 80 */
622 { GRP1b },
623 { GRP1S },
624 { "(bad)", XX, XX, XX },
625 { GRP1Ss },
626 { "testB", Eb, Gb, XX },
627 { "testS", Ev, Gv, XX },
628 { "xchgB", Eb, Gb, XX },
629 { "xchgS", Ev, Gv, XX },
630 /* 88 */
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 },
639 /* 90 */
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 },
648 /* 98 */
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 },
657 /* a0 */
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 },
666 /* a8 */
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 },
675 /* b0 */
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 },
684 /* b8 */
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 },
693 /* c0 */
694 { GRP2b },
695 { GRP2S },
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 },
702 /* c8 */
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 },
711 /* d0 */
712 { GRP2b_one },
713 { GRP2S_one },
714 { GRP2b_cl },
715 { GRP2S_cl },
716 { "aam{|}", sIb, XX, XX },
717 { "aad{|}", sIb, XX, XX },
718 { "(bad)", XX, XX, XX },
719 { "xlat", DSBX, XX, XX },
720 /* d8 */
721 { FLOAT },
722 { FLOAT },
723 { FLOAT },
724 { FLOAT },
725 { FLOAT },
726 { FLOAT },
727 { FLOAT },
728 { FLOAT },
729 /* e0 */
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 },
738 /* e8 */
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 },
747 /* f0 */
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 },
754 { GRP3b },
755 { GRP3S },
756 /* f8 */
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 },
763 { GRP4 },
764 { GRP5 },
767 static const struct dis386 dis386_twobyte[] = {
768 /* 00 */
769 { GRP6 },
770 { GRP7 },
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 },
777 /* 08 */
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 },
783 { GRPAMD },
784 { "femms", XX, XX, XX },
785 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */
786 /* 10 */
787 { PREGRP8 },
788 { PREGRP9 },
789 { PREGRP30 },
790 { "movlpX", EX, XM, SIMD_Fixup, 'h' },
791 { "unpcklpX", XM, EX, XX },
792 { "unpckhpX", XM, EX, XX },
793 { PREGRP31 },
794 { "movhpX", EX, XM, SIMD_Fixup, 'l' },
795 /* 18 */
796 { GRP14 },
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 },
804 /* 20 */
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 },
813 /* 28 */
814 { "movapX", XM, EX, XX },
815 { "movapX", EX, XM, XX },
816 { PREGRP2 },
817 { "movntpX", Ev, XM, XX },
818 { PREGRP4 },
819 { PREGRP3 },
820 { "ucomisX", XM,EX, XX },
821 { "comisX", XM,EX, XX },
822 /* 30 */
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 },
831 /* 38 */
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 },
840 /* 40 */
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 },
849 /* 48 */
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 },
858 /* 50 */
859 { "movmskpX", Gd, XS, XX },
860 { PREGRP13 },
861 { PREGRP12 },
862 { PREGRP11 },
863 { "andpX", XM, EX, XX },
864 { "andnpX", XM, EX, XX },
865 { "orpX", XM, EX, XX },
866 { "xorpX", XM, EX, XX },
867 /* 58 */
868 { PREGRP0 },
869 { PREGRP10 },
870 { PREGRP17 },
871 { PREGRP16 },
872 { PREGRP14 },
873 { PREGRP7 },
874 { PREGRP5 },
875 { PREGRP6 },
876 /* 60 */
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 },
885 /* 68 */
886 { "punpckhbw", MX, EM, XX },
887 { "punpckhwd", MX, EM, XX },
888 { "punpckhdq", MX, EM, XX },
889 { "packssdw", MX, EM, XX },
890 { PREGRP26 },
891 { PREGRP24 },
892 { "movd", MX, Edq, XX },
893 { PREGRP19 },
894 /* 70 */
895 { PREGRP22 },
896 { GRP10 },
897 { GRP11 },
898 { GRP12 },
899 { "pcmpeqb", MX, EM, XX },
900 { "pcmpeqw", MX, EM, XX },
901 { "pcmpeqd", MX, EM, XX },
902 { "emms", XX, XX, XX },
903 /* 78 */
904 { "(bad)", XX, XX, XX },
905 { "(bad)", XX, XX, XX },
906 { "(bad)", XX, XX, XX },
907 { "(bad)", XX, XX, XX },
908 { PREGRP28 },
909 { PREGRP29 },
910 { PREGRP23 },
911 { PREGRP20 },
912 /* 80 */
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 },
921 /* 88 */
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 },
930 /* 90 */
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 },
939 /* 98 */
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 },
948 /* a0 */
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 },
956 { GRPPADLCK },
957 /* a8 */
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 },
964 { GRP13 },
965 { "imulS", Gv, Ev, XX },
966 /* b0 */
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 ! */
975 /* b8 */
976 { "(bad)", XX, XX, XX },
977 { "ud2b", XX, XX, XX },
978 { GRP8 },
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 ! */
984 /* c0 */
985 { "xaddB", Eb, Gb, XX },
986 { "xaddS", Ev, Gv, XX },
987 { PREGRP1 },
988 { "movntiS", Ev, Gv, XX },
989 { "pinsrw", MX, Ed, Ib },
990 { "pextrw", Gd, MS, Ib },
991 { "shufpX", XM, EX, Ib },
992 { GRP9 },
993 /* c8 */
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 },
1002 /* d0 */
1003 { PREGRP27 },
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 },
1009 { PREGRP21 },
1010 { "pmovmskb", Gd, MS, XX },
1011 /* d8 */
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 },
1020 /* e0 */
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 },
1027 { PREGRP15 },
1028 { PREGRP25 },
1029 /* e8 */
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 },
1038 /* f0 */
1039 { PREGRP32 },
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 },
1046 { PREGRP18 },
1047 /* f8 */
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];
1128 static char *obufp;
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;
1134 static int mod;
1135 static int rm;
1136 static int reg;
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] = {
1205 /* GRP1b */
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 }
1216 /* GRP1S */
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 }
1227 /* GRP1Ss */
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 }
1238 /* GRP2b */
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 },
1249 /* GRP2S */
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 },
1260 /* GRP2b_one */
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 },
1271 /* GRP2S_one */
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 },
1282 /* GRP2b_cl */
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 },
1293 /* GRP2S_cl */
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 }
1304 /* GRP3b */
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. */
1315 /* GRP3S */
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 },
1326 /* GRP4 */
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 },
1337 /* GRP5 */
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 },
1348 /* GRP6 */
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 }
1359 /* GRP7 */
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 },
1370 /* GRP8 */
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 },
1381 /* GRP9 */
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 },
1392 /* GRP10 */
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 },
1403 /* GRP11 */
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 },
1414 /* GRP12 */
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 },
1425 /* GRP13 */
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 },
1436 /* GRP14 */
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 },
1447 /* GRPAMD */
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 },
1458 /* GRPPADLCK */
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] = {
1472 /* PREGRP0 */
1474 { "addps", XM, EX, XX },
1475 { "addss", XM, EX, XX },
1476 { "addpd", XM, EX, XX },
1477 { "addsd", XM, EX, XX },
1479 /* PREGRP1 */
1481 { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */
1482 { "", XM, EX, OPSIMD },
1483 { "", XM, EX, OPSIMD },
1484 { "", XM, EX, OPSIMD },
1486 /* PREGRP2 */
1488 { "cvtpi2ps", XM, EM, XX },
1489 { "cvtsi2ssY", XM, Ev, XX },
1490 { "cvtpi2pd", XM, EM, XX },
1491 { "cvtsi2sdY", XM, Ev, XX },
1493 /* PREGRP3 */
1495 { "cvtps2pi", MX, EX, XX },
1496 { "cvtss2siY", Gv, EX, XX },
1497 { "cvtpd2pi", MX, EX, XX },
1498 { "cvtsd2siY", Gv, EX, XX },
1500 /* PREGRP4 */
1502 { "cvttps2pi", MX, EX, XX },
1503 { "cvttss2siY", Gv, EX, XX },
1504 { "cvttpd2pi", MX, EX, XX },
1505 { "cvttsd2siY", Gv, EX, XX },
1507 /* PREGRP5 */
1509 { "divps", XM, EX, XX },
1510 { "divss", XM, EX, XX },
1511 { "divpd", XM, EX, XX },
1512 { "divsd", XM, EX, XX },
1514 /* PREGRP6 */
1516 { "maxps", XM, EX, XX },
1517 { "maxss", XM, EX, XX },
1518 { "maxpd", XM, EX, XX },
1519 { "maxsd", XM, EX, XX },
1521 /* PREGRP7 */
1523 { "minps", XM, EX, XX },
1524 { "minss", XM, EX, XX },
1525 { "minpd", XM, EX, XX },
1526 { "minsd", XM, EX, XX },
1528 /* PREGRP8 */
1530 { "movups", XM, EX, XX },
1531 { "movss", XM, EX, XX },
1532 { "movupd", XM, EX, XX },
1533 { "movsd", XM, EX, XX },
1535 /* PREGRP9 */
1537 { "movups", EX, XM, XX },
1538 { "movss", EX, XM, XX },
1539 { "movupd", EX, XM, XX },
1540 { "movsd", EX, XM, XX },
1542 /* PREGRP10 */
1544 { "mulps", XM, EX, XX },
1545 { "mulss", XM, EX, XX },
1546 { "mulpd", XM, EX, XX },
1547 { "mulsd", XM, EX, XX },
1549 /* PREGRP11 */
1551 { "rcpps", XM, EX, XX },
1552 { "rcpss", XM, EX, XX },
1553 { "(bad)", XM, EX, XX },
1554 { "(bad)", XM, EX, XX },
1556 /* PREGRP12 */
1558 { "rsqrtps", XM, EX, XX },
1559 { "rsqrtss", XM, EX, XX },
1560 { "(bad)", XM, EX, XX },
1561 { "(bad)", XM, EX, XX },
1563 /* PREGRP13 */
1565 { "sqrtps", XM, EX, XX },
1566 { "sqrtss", XM, EX, XX },
1567 { "sqrtpd", XM, EX, XX },
1568 { "sqrtsd", XM, EX, XX },
1570 /* PREGRP14 */
1572 { "subps", XM, EX, XX },
1573 { "subss", XM, EX, XX },
1574 { "subpd", XM, EX, XX },
1575 { "subsd", XM, EX, XX },
1577 /* PREGRP15 */
1579 { "(bad)", XM, EX, XX },
1580 { "cvtdq2pd", XM, EX, XX },
1581 { "cvttpd2dq", XM, EX, XX },
1582 { "cvtpd2dq", XM, EX, XX },
1584 /* PREGRP16 */
1586 { "cvtdq2ps", XM, EX, XX },
1587 { "cvttps2dq",XM, EX, XX },
1588 { "cvtps2dq",XM, EX, XX },
1589 { "(bad)", XM, EX, XX },
1591 /* PREGRP17 */
1593 { "cvtps2pd", XM, EX, XX },
1594 { "cvtss2sd", XM, EX, XX },
1595 { "cvtpd2ps", XM, EX, XX },
1596 { "cvtsd2ss", XM, EX, XX },
1598 /* PREGRP18 */
1600 { "maskmovq", MX, MS, XX },
1601 { "(bad)", XM, EX, XX },
1602 { "maskmovdqu", XM, EX, XX },
1603 { "(bad)", XM, EX, XX },
1605 /* PREGRP19 */
1607 { "movq", MX, EM, XX },
1608 { "movdqu", XM, EX, XX },
1609 { "movdqa", XM, EX, XX },
1610 { "(bad)", XM, EX, XX },
1612 /* PREGRP20 */
1614 { "movq", EM, MX, XX },
1615 { "movdqu", EX, XM, XX },
1616 { "movdqa", EX, XM, XX },
1617 { "(bad)", EX, XM, XX },
1619 /* PREGRP21 */
1621 { "(bad)", EX, XM, XX },
1622 { "movq2dq", XM, MS, XX },
1623 { "movq", EX, XM, XX },
1624 { "movdq2q", MX, XS, XX },
1626 /* PREGRP22 */
1628 { "pshufw", MX, EM, Ib },
1629 { "pshufhw", XM, EX, Ib },
1630 { "pshufd", XM, EX, Ib },
1631 { "pshuflw", XM, EX, Ib },
1633 /* PREGRP23 */
1635 { "movd", Edq, MX, XX },
1636 { "movq", XM, EX, XX },
1637 { "movd", Edq, XM, XX },
1638 { "(bad)", Ed, XM, XX },
1640 /* PREGRP24 */
1642 { "(bad)", MX, EX, XX },
1643 { "(bad)", XM, EX, XX },
1644 { "punpckhqdq", XM, EX, XX },
1645 { "(bad)", XM, EX, XX },
1647 /* PREGRP25 */
1649 { "movntq", Ev, MX, XX },
1650 { "(bad)", Ev, XM, XX },
1651 { "movntdq", Ev, XM, XX },
1652 { "(bad)", Ev, XM, XX },
1654 /* PREGRP26 */
1656 { "(bad)", MX, EX, XX },
1657 { "(bad)", XM, EX, XX },
1658 { "punpcklqdq", XM, EX, XX },
1659 { "(bad)", XM, EX, XX },
1661 /* PREGRP27 */
1663 { "(bad)", MX, EX, XX },
1664 { "(bad)", XM, EX, XX },
1665 { "addsubpd", XM, EX, XX },
1666 { "addsubps", XM, EX, XX },
1668 /* PREGRP28 */
1670 { "(bad)", MX, EX, XX },
1671 { "(bad)", XM, EX, XX },
1672 { "haddpd", XM, EX, XX },
1673 { "haddps", XM, EX, XX },
1675 /* PREGRP29 */
1677 { "(bad)", MX, EX, XX },
1678 { "(bad)", XM, EX, XX },
1679 { "hsubpd", XM, EX, XX },
1680 { "hsubps", XM, EX, XX },
1682 /* PREGRP30 */
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 },
1689 /* PREGRP31 */
1691 { "movhpX", XM, EX, SIMD_Fixup, 'l' },
1692 { "movshdup", XM, EX, XX },
1693 { "movhpd", XM, EX, XX },
1694 { "(bad)", XM, EX, XX },
1696 /* PREGRP32 */
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>")
1714 static void
1715 ckprefix (void)
1717 int newrex;
1718 rex = 0;
1719 prefixes = 0;
1720 used_prefixes = 0;
1721 rex_used = 0;
1722 while (1)
1724 FETCH_DATA (the_info, codep + 1);
1725 newrex = 0;
1726 switch (*codep)
1728 /* REX prefixes family. */
1729 case 0x40:
1730 case 0x41:
1731 case 0x42:
1732 case 0x43:
1733 case 0x44:
1734 case 0x45:
1735 case 0x46:
1736 case 0x47:
1737 case 0x48:
1738 case 0x49:
1739 case 0x4a:
1740 case 0x4b:
1741 case 0x4c:
1742 case 0x4d:
1743 case 0x4e:
1744 case 0x4f:
1745 if (mode_64bit)
1746 newrex = *codep;
1747 else
1748 return;
1749 break;
1750 case 0xf3:
1751 prefixes |= PREFIX_REPZ;
1752 break;
1753 case 0xf2:
1754 prefixes |= PREFIX_REPNZ;
1755 break;
1756 case 0xf0:
1757 prefixes |= PREFIX_LOCK;
1758 break;
1759 case 0x2e:
1760 prefixes |= PREFIX_CS;
1761 break;
1762 case 0x36:
1763 prefixes |= PREFIX_SS;
1764 break;
1765 case 0x3e:
1766 prefixes |= PREFIX_DS;
1767 break;
1768 case 0x26:
1769 prefixes |= PREFIX_ES;
1770 break;
1771 case 0x64:
1772 prefixes |= PREFIX_FS;
1773 break;
1774 case 0x65:
1775 prefixes |= PREFIX_GS;
1776 break;
1777 case 0x66:
1778 prefixes |= PREFIX_DATA;
1779 break;
1780 case 0x67:
1781 prefixes |= PREFIX_ADDR;
1782 break;
1783 case FWAIT_OPCODE:
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. */
1787 if (prefixes)
1789 prefixes |= PREFIX_FWAIT;
1790 codep++;
1791 return;
1793 prefixes = PREFIX_FWAIT;
1794 break;
1795 default:
1796 return;
1798 /* Rex is ignored when followed by another prefix. */
1799 if (rex)
1801 oappend (prefix_name (rex, 0));
1802 oappend (" ");
1804 rex = newrex;
1805 codep++;
1809 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
1810 prefix byte. */
1812 static const char *
1813 prefix_name (int pref, int sizeflag)
1815 switch (pref)
1817 /* REX prefixes family. */
1818 case 0x40:
1819 return "rex";
1820 case 0x41:
1821 return "rexZ";
1822 case 0x42:
1823 return "rexY";
1824 case 0x43:
1825 return "rexYZ";
1826 case 0x44:
1827 return "rexX";
1828 case 0x45:
1829 return "rexXZ";
1830 case 0x46:
1831 return "rexXY";
1832 case 0x47:
1833 return "rexXYZ";
1834 case 0x48:
1835 return "rex64";
1836 case 0x49:
1837 return "rex64Z";
1838 case 0x4a:
1839 return "rex64Y";
1840 case 0x4b:
1841 return "rex64YZ";
1842 case 0x4c:
1843 return "rex64X";
1844 case 0x4d:
1845 return "rex64XZ";
1846 case 0x4e:
1847 return "rex64XY";
1848 case 0x4f:
1849 return "rex64XYZ";
1850 case 0xf3:
1851 return "repz";
1852 case 0xf2:
1853 return "repnz";
1854 case 0xf0:
1855 return "lock";
1856 case 0x2e:
1857 return "cs";
1858 case 0x36:
1859 return "ss";
1860 case 0x3e:
1861 return "ds";
1862 case 0x26:
1863 return "es";
1864 case 0x64:
1865 return "fs";
1866 case 0x65:
1867 return "gs";
1868 case 0x66:
1869 return (sizeflag & DFLAG) ? "data16" : "data32";
1870 case 0x67:
1871 if (mode_64bit)
1872 return (sizeflag & AFLAG) ? "addr32" : "addr64";
1873 else
1874 return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32";
1875 case FWAIT_OPCODE:
1876 return "fwait";
1877 default:
1878 return NULL;
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)
1910 intel_syntax = 0;
1912 return print_insn (pc, info);
1916 print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
1918 intel_syntax = 1;
1920 return print_insn (pc, info);
1924 print_insn_i386 (bfd_vma pc, disassemble_info *info)
1926 intel_syntax = -1;
1928 return print_insn (pc, info);
1931 static int
1932 print_insn (bfd_vma pc, disassemble_info *info)
1934 const struct dis386 *dp;
1935 int i;
1936 char *first, *second, *third;
1937 int needcomma;
1938 unsigned char uses_SSE_prefix;
1939 int sizeflag;
1940 const char *p;
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;
1957 else
1958 abort ();
1960 for (p = info->disassembler_options; p != NULL; )
1962 if (strncmp (p, "x86-64", 6) == 0)
1964 mode_64bit = 1;
1965 priv.orig_sizeflag = AFLAG | DFLAG;
1967 else if (strncmp (p, "i386", 4) == 0)
1969 mode_64bit = 0;
1970 priv.orig_sizeflag = AFLAG | DFLAG;
1972 else if (strncmp (p, "i8086", 5) == 0)
1974 mode_64bit = 0;
1975 priv.orig_sizeflag = 0;
1977 else if (strncmp (p, "intel", 5) == 0)
1979 intel_syntax = 1;
1981 else if (strncmp (p, "att", 3) == 0)
1983 intel_syntax = 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, ',');
2003 if (p != NULL)
2004 p++;
2007 if (intel_syntax)
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;
2016 open_char = '[';
2017 close_char = ']';
2018 separator_char = '+';
2019 scale_char = '*';
2021 else
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;
2030 open_char = '(';
2031 close_char = ')';
2032 separator_char = ',';
2033 scale_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;
2044 obuf[0] = 0;
2045 op1out[0] = 0;
2046 op2out[0] = 0;
2047 op3out[0] = 0;
2049 op_index[0] = op_index[1] = op_index[2] = -1;
2051 the_info = info;
2052 start_pc = pc;
2053 start_codep = priv.the_buffer;
2054 codep = priv.the_buffer;
2056 if (setjmp (priv.bailout) != 0)
2058 const char *name;
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);
2066 if (name != NULL)
2067 (*info->fprintf_func) (info->stream, "%s", name);
2068 else
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]);
2075 return 1;
2078 return -1;
2081 obufp = obuf;
2082 ckprefix ();
2084 insn_codep = codep;
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)))
2093 const char *name;
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);
2098 if (name == NULL)
2099 name = INTERNAL_DISASSEMBLER_ERROR;
2100 (*info->fprintf_func) (info->stream, "%s", name);
2101 return 1;
2104 if (*codep == 0x0f)
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];
2111 else
2113 dp = &dis386[*codep];
2114 need_modrm = onebyte_has_modrm[*codep];
2115 uses_SSE_prefix = 0;
2117 codep++;
2119 if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
2121 oappend ("repz ");
2122 used_prefixes |= PREFIX_REPZ;
2124 if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
2126 oappend ("repnz ");
2127 used_prefixes |= PREFIX_REPNZ;
2129 if (prefixes & PREFIX_LOCK)
2131 oappend ("lock ");
2132 used_prefixes |= PREFIX_LOCK;
2135 if (prefixes & PREFIX_ADDR)
2137 sizeflag ^= AFLAG;
2138 if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
2140 if ((sizeflag & AFLAG) || mode_64bit)
2141 oappend ("addr32 ");
2142 else
2143 oappend ("addr16 ");
2144 used_prefixes |= PREFIX_ADDR;
2148 if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
2150 sizeflag ^= DFLAG;
2151 if (dp->bytemode3 == cond_jump_mode
2152 && dp->bytemode1 == v_mode
2153 && !intel_syntax)
2155 if (sizeflag & DFLAG)
2156 oappend ("data32 ");
2157 else
2158 oappend ("data16 ");
2159 used_prefixes |= PREFIX_DATA;
2163 if (need_modrm)
2165 FETCH_DATA (info, codep + 1);
2166 mod = (*codep >> 6) & 3;
2167 reg = (*codep >> 3) & 7;
2168 rm = *codep & 7;
2171 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2173 dofloat (sizeflag);
2175 else
2177 int index;
2178 if (dp->name == NULL)
2180 switch (dp->bytemode1)
2182 case USE_GROUPS:
2183 dp = &grps[dp->bytemode2][reg];
2184 break;
2186 case USE_PREFIX_USER_TABLE:
2187 index = 0;
2188 used_prefixes |= (prefixes & PREFIX_REPZ);
2189 if (prefixes & PREFIX_REPZ)
2190 index = 1;
2191 else
2193 used_prefixes |= (prefixes & PREFIX_DATA);
2194 if (prefixes & PREFIX_DATA)
2195 index = 2;
2196 else
2198 used_prefixes |= (prefixes & PREFIX_REPNZ);
2199 if (prefixes & PREFIX_REPNZ)
2200 index = 3;
2203 dp = &prefix_user_table[dp->bytemode2][index];
2204 break;
2206 case X86_64_SPECIAL:
2207 dp = &x86_64_table[dp->bytemode2][mode_64bit];
2208 break;
2210 default:
2211 oappend (INTERNAL_DISASSEMBLER_ERROR);
2212 break;
2216 if (putop (dp->name, sizeflag) == 0)
2218 obufp = op1out;
2219 op_ad = 2;
2220 if (dp->op1)
2221 (*dp->op1) (dp->bytemode1, sizeflag);
2223 obufp = op2out;
2224 op_ad = 1;
2225 if (dp->op2)
2226 (*dp->op2) (dp->bytemode2, sizeflag);
2228 obufp = op3out;
2229 op_ad = 0;
2230 if (dp->op3)
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)
2241 const char *name;
2243 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2244 if (name == NULL)
2245 name = INTERNAL_DISASSEMBLER_ERROR;
2246 (*info->fprintf_func) (info->stream, "%s", name);
2247 return 1;
2249 if (rex & ~rex_used)
2251 const char *name;
2252 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
2253 if (name == NULL)
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++)
2260 oappend (" ");
2261 oappend (" ");
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)
2268 first = op1out;
2269 second = op2out;
2270 third = op3out;
2271 op_ad = op_index[0];
2272 op_index[0] = op_index[2];
2273 op_index[2] = op_ad;
2275 else
2277 first = op3out;
2278 second = op2out;
2279 third = op1out;
2281 needcomma = 0;
2282 if (*first)
2284 if (op_index[0] != -1 && !op_riprel[0])
2285 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
2286 else
2287 (*info->fprintf_func) (info->stream, "%s", first);
2288 needcomma = 1;
2290 if (*second)
2292 if (needcomma)
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);
2296 else
2297 (*info->fprintf_func) (info->stream, "%s", second);
2298 needcomma = 1;
2300 if (*third)
2302 if (needcomma)
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);
2306 else
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[] = {
2320 /* d8 */
2321 "fadd{s||s|}",
2322 "fmul{s||s|}",
2323 "fcom{s||s|}",
2324 "fcomp{s||s|}",
2325 "fsub{s||s|}",
2326 "fsubr{s||s|}",
2327 "fdiv{s||s|}",
2328 "fdivr{s||s|}",
2329 /* d9 */
2330 "fld{s||s|}",
2331 "(bad)",
2332 "fst{s||s|}",
2333 "fstp{s||s|}",
2334 "fldenv",
2335 "fldcw",
2336 "fNstenv",
2337 "fNstcw",
2338 /* da */
2339 "fiadd{l||l|}",
2340 "fimul{l||l|}",
2341 "ficom{l||l|}",
2342 "ficomp{l||l|}",
2343 "fisub{l||l|}",
2344 "fisubr{l||l|}",
2345 "fidiv{l||l|}",
2346 "fidivr{l||l|}",
2347 /* db */
2348 "fild{l||l|}",
2349 "fisttp{l||l|}",
2350 "fist{l||l|}",
2351 "fistp{l||l|}",
2352 "(bad)",
2353 "fld{t||t|}",
2354 "(bad)",
2355 "fstp{t||t|}",
2356 /* dc */
2357 "fadd{l||l|}",
2358 "fmul{l||l|}",
2359 "fcom{l||l|}",
2360 "fcomp{l||l|}",
2361 "fsub{l||l|}",
2362 "fsubr{l||l|}",
2363 "fdiv{l||l|}",
2364 "fdivr{l||l|}",
2365 /* dd */
2366 "fld{l||l|}",
2367 "fisttp{ll||ll|}",
2368 "fst{l||l|}",
2369 "fstp{l||l|}",
2370 "frstor",
2371 "(bad)",
2372 "fNsave",
2373 "fNstsw",
2374 /* de */
2375 "fiadd",
2376 "fimul",
2377 "ficom",
2378 "ficomp",
2379 "fisub",
2380 "fisubr",
2381 "fidiv",
2382 "fidivr",
2383 /* df */
2384 "fild",
2385 "fisttp",
2386 "fist",
2387 "fistp",
2388 "fbld",
2389 "fild{ll||ll|}",
2390 "fbstp",
2391 "fistp{ll||ll|}",
2394 static const unsigned char float_mem_mode[] = {
2395 /* d8 */
2396 d_mode,
2397 d_mode,
2398 d_mode,
2399 d_mode,
2400 d_mode,
2401 d_mode,
2402 d_mode,
2403 d_mode,
2404 /* d9 */
2405 d_mode,
2407 d_mode,
2408 d_mode,
2410 w_mode,
2412 w_mode,
2413 /* da */
2414 d_mode,
2415 d_mode,
2416 d_mode,
2417 d_mode,
2418 d_mode,
2419 d_mode,
2420 d_mode,
2421 d_mode,
2422 /* db */
2423 d_mode,
2424 d_mode,
2425 d_mode,
2426 d_mode,
2428 x_mode,
2430 x_mode,
2431 /* dc */
2432 q_mode,
2433 q_mode,
2434 q_mode,
2435 q_mode,
2436 q_mode,
2437 q_mode,
2438 q_mode,
2439 q_mode,
2440 /* dd */
2441 q_mode,
2442 q_mode,
2443 q_mode,
2444 q_mode,
2448 w_mode,
2449 /* de */
2450 w_mode,
2451 w_mode,
2452 w_mode,
2453 w_mode,
2454 w_mode,
2455 w_mode,
2456 w_mode,
2457 w_mode,
2458 /* df */
2459 w_mode,
2460 w_mode,
2461 w_mode,
2462 w_mode,
2463 x_mode,
2464 q_mode,
2465 x_mode,
2466 q_mode
2469 #define ST OP_ST, 0
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] = {
2483 /* d8 */
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 },
2494 /* d9 */
2496 { "fld", STi, XX, XX },
2497 { "fxch", STi, XX, XX },
2498 { FGRPd9_2 },
2499 { "(bad)", XX, XX, XX },
2500 { FGRPd9_4 },
2501 { FGRPd9_5 },
2502 { FGRPd9_6 },
2503 { FGRPd9_7 },
2505 /* da */
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 },
2512 { FGRPda_5 },
2513 { "(bad)", XX, XX, XX },
2514 { "(bad)", XX, XX, XX },
2516 /* db */
2518 { "fcmovnb",ST, STi, XX },
2519 { "fcmovne",ST, STi, XX },
2520 { "fcmovnbe",ST, STi, XX },
2521 { "fcmovnu",ST, STi, XX },
2522 { FGRPdb_4 },
2523 { "fucomi", ST, STi, XX },
2524 { "fcomi", ST, STi, XX },
2525 { "(bad)", XX, XX, XX },
2527 /* dc */
2529 { "fadd", STi, ST, XX },
2530 { "fmul", STi, ST, XX },
2531 { "(bad)", XX, XX, XX },
2532 { "(bad)", XX, XX, XX },
2533 #if UNIXWARE_COMPAT
2534 { "fsub", STi, ST, XX },
2535 { "fsubr", STi, ST, XX },
2536 { "fdiv", STi, ST, XX },
2537 { "fdivr", STi, ST, XX },
2538 #else
2539 { "fsubr", STi, ST, XX },
2540 { "fsub", STi, ST, XX },
2541 { "fdivr", STi, ST, XX },
2542 { "fdiv", STi, ST, XX },
2543 #endif
2545 /* dd */
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 },
2556 /* de */
2558 { "faddp", STi, ST, XX },
2559 { "fmulp", STi, ST, XX },
2560 { "(bad)", XX, XX, XX },
2561 { FGRPde_3 },
2562 #if UNIXWARE_COMPAT
2563 { "fsubp", STi, ST, XX },
2564 { "fsubrp", STi, ST, XX },
2565 { "fdivp", STi, ST, XX },
2566 { "fdivrp", STi, ST, XX },
2567 #else
2568 { "fsubrp", STi, ST, XX },
2569 { "fsubp", STi, ST, XX },
2570 { "fdivrp", STi, ST, XX },
2571 { "fdivp", STi, ST, XX },
2572 #endif
2574 /* df */
2576 { "ffreep", STi, XX, XX },
2577 { "(bad)", XX, XX, XX },
2578 { "(bad)", XX, XX, XX },
2579 { "(bad)", XX, XX, XX },
2580 { FGRPdf_4 },
2581 { "fucomip",ST, STi, XX },
2582 { "fcomip", ST, STi, XX },
2583 { "(bad)", XX, XX, XX },
2587 static char *fgrps[][8] = {
2588 /* d9_2 0 */
2590 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2593 /* d9_4 1 */
2595 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2598 /* d9_5 2 */
2600 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2603 /* d9_6 3 */
2605 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2608 /* d9_7 4 */
2610 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2613 /* da_5 5 */
2615 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2618 /* db_4 6 */
2620 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2621 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2624 /* de_3 7 */
2626 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2629 /* df_4 8 */
2631 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2635 static void
2636 dofloat (int sizeflag)
2638 const struct dis386 *dp;
2639 unsigned char floatop;
2641 floatop = codep[-1];
2643 if (mod != 3)
2645 int fp_indx = (floatop - 0xd8) * 8 + reg;
2647 putop (float_mem[fp_indx], sizeflag);
2648 obufp = op1out;
2649 OP_E (float_mem_mode[fp_indx], sizeflag);
2650 return;
2652 /* Skip mod/rm byte. */
2653 MODRM_CHECK;
2654 codep++;
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]);
2665 else
2667 putop (dp->name, sizeflag);
2669 obufp = op1out;
2670 if (dp->op1)
2671 (*dp->op1) (dp->bytemode1, sizeflag);
2672 obufp = op2out;
2673 if (dp->op2)
2674 (*dp->op2) (dp->bytemode2, sizeflag);
2678 static void
2679 OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
2681 oappend ("%st");
2684 static void
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. */
2692 static int
2693 putop (const char *template, int sizeflag)
2695 const char *p;
2696 int alt;
2698 for (p = template; *p; p++)
2700 switch (*p)
2702 default:
2703 *obufp++ = *p;
2704 break;
2705 case '{':
2706 alt = 0;
2707 if (intel_syntax)
2708 alt += 1;
2709 if (mode_64bit)
2710 alt += 2;
2711 while (alt != 0)
2713 while (*++p != '|')
2715 if (*p == '}')
2717 /* Alternative not valid. */
2718 strcpy (obuf, "(bad)");
2719 obufp = obuf + 5;
2720 return 1;
2722 else if (*p == '\0')
2723 abort ();
2725 alt--;
2727 break;
2728 case '|':
2729 while (*++p != '}')
2731 if (*p == '\0')
2732 abort ();
2734 break;
2735 case '}':
2736 break;
2737 case 'A':
2738 if (intel_syntax)
2739 break;
2740 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2741 *obufp++ = 'b';
2742 break;
2743 case 'B':
2744 if (intel_syntax)
2745 break;
2746 if (sizeflag & SUFFIX_ALWAYS)
2747 *obufp++ = 'b';
2748 break;
2749 case 'E': /* For jcxz/jecxz */
2750 if (mode_64bit)
2752 if (sizeflag & AFLAG)
2753 *obufp++ = 'r';
2754 else
2755 *obufp++ = 'e';
2757 else
2758 if (sizeflag & AFLAG)
2759 *obufp++ = 'e';
2760 used_prefixes |= (prefixes & PREFIX_ADDR);
2761 break;
2762 case 'F':
2763 if (intel_syntax)
2764 break;
2765 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
2767 if (sizeflag & AFLAG)
2768 *obufp++ = mode_64bit ? 'q' : 'l';
2769 else
2770 *obufp++ = mode_64bit ? 'l' : 'w';
2771 used_prefixes |= (prefixes & PREFIX_ADDR);
2773 break;
2774 case 'H':
2775 if (intel_syntax)
2776 break;
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);
2781 *obufp++ = ',';
2782 *obufp++ = 'p';
2783 if (prefixes & PREFIX_DS)
2784 *obufp++ = 't';
2785 else
2786 *obufp++ = 'n';
2788 break;
2789 case 'L':
2790 if (intel_syntax)
2791 break;
2792 if (sizeflag & SUFFIX_ALWAYS)
2793 *obufp++ = 'l';
2794 break;
2795 case 'N':
2796 if ((prefixes & PREFIX_FWAIT) == 0)
2797 *obufp++ = 'n';
2798 else
2799 used_prefixes |= PREFIX_FWAIT;
2800 break;
2801 case 'O':
2802 USED_REX (REX_MODE64);
2803 if (rex & REX_MODE64)
2804 *obufp++ = 'o';
2805 else
2806 *obufp++ = 'd';
2807 break;
2808 case 'T':
2809 if (intel_syntax)
2810 break;
2811 if (mode_64bit)
2813 *obufp++ = 'q';
2814 break;
2816 /* Fall through. */
2817 case 'P':
2818 if (intel_syntax)
2819 break;
2820 if ((prefixes & PREFIX_DATA)
2821 || (rex & REX_MODE64)
2822 || (sizeflag & SUFFIX_ALWAYS))
2824 USED_REX (REX_MODE64);
2825 if (rex & REX_MODE64)
2826 *obufp++ = 'q';
2827 else
2829 if (sizeflag & DFLAG)
2830 *obufp++ = 'l';
2831 else
2832 *obufp++ = 'w';
2833 used_prefixes |= (prefixes & PREFIX_DATA);
2836 break;
2837 case 'U':
2838 if (intel_syntax)
2839 break;
2840 if (mode_64bit)
2842 *obufp++ = 'q';
2843 break;
2845 /* Fall through. */
2846 case 'Q':
2847 if (intel_syntax)
2848 break;
2849 USED_REX (REX_MODE64);
2850 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2852 if (rex & REX_MODE64)
2853 *obufp++ = 'q';
2854 else
2856 if (sizeflag & DFLAG)
2857 *obufp++ = 'l';
2858 else
2859 *obufp++ = 'w';
2860 used_prefixes |= (prefixes & PREFIX_DATA);
2863 break;
2864 case 'R':
2865 USED_REX (REX_MODE64);
2866 if (intel_syntax)
2868 if (rex & REX_MODE64)
2870 *obufp++ = 'q';
2871 *obufp++ = 't';
2873 else if (sizeflag & DFLAG)
2875 *obufp++ = 'd';
2876 *obufp++ = 'q';
2878 else
2880 *obufp++ = 'w';
2881 *obufp++ = 'd';
2884 else
2886 if (rex & REX_MODE64)
2887 *obufp++ = 'q';
2888 else if (sizeflag & DFLAG)
2889 *obufp++ = 'l';
2890 else
2891 *obufp++ = 'w';
2893 if (!(rex & REX_MODE64))
2894 used_prefixes |= (prefixes & PREFIX_DATA);
2895 break;
2896 case 'S':
2897 if (intel_syntax)
2898 break;
2899 if (sizeflag & SUFFIX_ALWAYS)
2901 if (rex & REX_MODE64)
2902 *obufp++ = 'q';
2903 else
2905 if (sizeflag & DFLAG)
2906 *obufp++ = 'l';
2907 else
2908 *obufp++ = 'w';
2909 used_prefixes |= (prefixes & PREFIX_DATA);
2912 break;
2913 case 'X':
2914 if (prefixes & PREFIX_DATA)
2915 *obufp++ = 'd';
2916 else
2917 *obufp++ = 's';
2918 used_prefixes |= (prefixes & PREFIX_DATA);
2919 break;
2920 case 'Y':
2921 if (intel_syntax)
2922 break;
2923 if (rex & REX_MODE64)
2925 USED_REX (REX_MODE64);
2926 *obufp++ = 'q';
2928 break;
2929 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
2930 case 'W':
2931 /* operand size flag for cwtl, cbtw */
2932 USED_REX (0);
2933 if (rex)
2934 *obufp++ = 'l';
2935 else if (sizeflag & DFLAG)
2936 *obufp++ = 'w';
2937 else
2938 *obufp++ = 'b';
2939 if (intel_syntax)
2941 if (rex)
2943 *obufp++ = 'q';
2944 *obufp++ = 'e';
2946 if (sizeflag & DFLAG)
2948 *obufp++ = 'd';
2949 *obufp++ = 'e';
2951 else
2953 *obufp++ = 'w';
2956 if (!rex)
2957 used_prefixes |= (prefixes & PREFIX_DATA);
2958 break;
2961 *obufp = 0;
2962 return 0;
2965 static void
2966 oappend (const char *s)
2968 strcpy (obufp, s);
2969 obufp += strlen (s);
2972 static void
2973 append_seg (void)
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);
3007 static void
3008 OP_indirE (int bytemode, int sizeflag)
3010 if (!intel_syntax)
3011 oappend ("*");
3012 OP_E (bytemode, sizeflag);
3015 static void
3016 print_operand_value (char *buf, int hex, bfd_vma disp)
3018 if (mode_64bit)
3020 if (hex)
3022 char tmp[30];
3023 int i;
3024 buf[0] = '0';
3025 buf[1] = 'x';
3026 sprintf_vma (tmp, disp);
3027 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
3028 strcpy (buf + 2, tmp + i);
3030 else
3032 bfd_signed_vma v = disp;
3033 char tmp[30];
3034 int i;
3035 if (v < 0)
3037 *(buf++) = '-';
3038 v = -disp;
3039 /* Check for possible overflow on 0x8000000000000000. */
3040 if (v < 0)
3042 strcpy (buf, "9223372036854775808");
3043 return;
3046 if (!v)
3048 strcpy (buf, "0");
3049 return;
3052 i = 0;
3053 tmp[29] = 0;
3054 while (v)
3056 tmp[28 - i] = (v % 10) + '0';
3057 v /= 10;
3058 i++;
3060 strcpy (buf, tmp + 29 - i);
3063 else
3065 if (hex)
3066 sprintf (buf, "0x%x", (unsigned int) disp);
3067 else
3068 sprintf (buf, "%d", (int) disp);
3072 static void
3073 OP_E (int bytemode, int sizeflag)
3075 bfd_vma disp;
3076 int add = 0;
3077 int riprel = 0;
3078 USED_REX (REX_EXTZ);
3079 if (rex & REX_EXTZ)
3080 add += 8;
3082 /* Skip mod/rm byte. */
3083 MODRM_CHECK;
3084 codep++;
3086 if (mod == 3)
3088 switch (bytemode)
3090 case b_mode:
3091 USED_REX (0);
3092 if (rex)
3093 oappend (names8rex[rm + add]);
3094 else
3095 oappend (names8[rm + add]);
3096 break;
3097 case w_mode:
3098 oappend (names16[rm + add]);
3099 break;
3100 case d_mode:
3101 oappend (names32[rm + add]);
3102 break;
3103 case q_mode:
3104 oappend (names64[rm + add]);
3105 break;
3106 case m_mode:
3107 if (mode_64bit)
3108 oappend (names64[rm + add]);
3109 else
3110 oappend (names32[rm + add]);
3111 break;
3112 case v_mode:
3113 case dq_mode:
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]);
3119 else
3120 oappend (names16[rm + add]);
3121 used_prefixes |= (prefixes & PREFIX_DATA);
3122 break;
3123 case 0:
3124 break;
3125 default:
3126 oappend (INTERNAL_DISASSEMBLER_ERROR);
3127 break;
3129 return;
3132 disp = 0;
3133 append_seg ();
3135 if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
3137 int havesib;
3138 int havebase;
3139 int base;
3140 int index = 0;
3141 int scale = 0;
3143 havesib = 0;
3144 havebase = 1;
3145 base = rm;
3147 if (base == 4)
3149 havesib = 1;
3150 FETCH_DATA (the_info, codep + 1);
3151 scale = (*codep >> 6) & 3;
3152 index = (*codep >> 3) & 7;
3153 base = *codep & 7;
3154 USED_REX (REX_EXTY);
3155 USED_REX (REX_EXTZ);
3156 if (rex & REX_EXTY)
3157 index += 8;
3158 if (rex & REX_EXTZ)
3159 base += 8;
3160 codep++;
3163 switch (mod)
3165 case 0:
3166 if ((base & 7) == 5)
3168 havebase = 0;
3169 if (mode_64bit && !havesib && (sizeflag & AFLAG))
3170 riprel = 1;
3171 disp = get32s ();
3173 break;
3174 case 1:
3175 FETCH_DATA (the_info, codep + 1);
3176 disp = *codep++;
3177 if ((disp & 0x80) != 0)
3178 disp -= 0x100;
3179 break;
3180 case 2:
3181 disp = get32s ();
3182 break;
3185 if (!intel_syntax)
3186 if (mod != 0 || (base & 7) == 5)
3188 print_operand_value (scratchbuf, !riprel, disp);
3189 oappend (scratchbuf);
3190 if (riprel)
3192 set_op (disp, 1);
3193 oappend ("(%rip)");
3197 if (havebase || (havesib && (index != 4 || scale != 0)))
3199 if (intel_syntax)
3201 switch (bytemode)
3203 case b_mode:
3204 oappend ("BYTE PTR ");
3205 break;
3206 case w_mode:
3207 oappend ("WORD PTR ");
3208 break;
3209 case v_mode:
3210 if (sizeflag & DFLAG)
3211 oappend ("DWORD PTR ");
3212 else
3213 oappend ("WORD PTR ");
3214 break;
3215 case d_mode:
3216 oappend ("DWORD PTR ");
3217 break;
3218 case q_mode:
3219 oappend ("QWORD PTR ");
3220 break;
3221 case m_mode:
3222 if (mode_64bit)
3223 oappend ("DWORD PTR ");
3224 else
3225 oappend ("QWORD PTR ");
3226 break;
3227 case x_mode:
3228 oappend ("XWORD PTR ");
3229 break;
3230 default:
3231 break;
3234 *obufp++ = open_char;
3235 if (intel_syntax && riprel)
3236 oappend ("rip + ");
3237 *obufp = '\0';
3238 USED_REX (REX_EXTZ);
3239 if (!havesib && (rex & REX_EXTZ))
3240 base += 8;
3241 if (havebase)
3242 oappend (mode_64bit && (sizeflag & AFLAG)
3243 ? names64[base] : names32[base]);
3244 if (havesib)
3246 if (index != 4)
3248 if (intel_syntax)
3250 if (havebase)
3252 *obufp++ = separator_char;
3253 *obufp = '\0';
3255 sprintf (scratchbuf, "%s",
3256 mode_64bit && (sizeflag & AFLAG)
3257 ? names64[index] : names32[index]);
3259 else
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;
3268 *obufp = '\0';
3269 sprintf (scratchbuf, "%d", 1 << scale);
3270 oappend (scratchbuf);
3273 if (intel_syntax)
3274 if (mod != 0 || (base & 7) == 5)
3276 /* Don't print zero displacements. */
3277 if (disp != 0)
3279 if ((bfd_signed_vma) disp > 0)
3281 *obufp++ = '+';
3282 *obufp = '\0';
3285 print_operand_value (scratchbuf, 0, disp);
3286 oappend (scratchbuf);
3290 *obufp++ = close_char;
3291 *obufp = '\0';
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))
3300 else
3302 oappend (names_seg[ds_reg - es_reg]);
3303 oappend (":");
3305 print_operand_value (scratchbuf, 1, disp);
3306 oappend (scratchbuf);
3310 else
3311 { /* 16 bit address mode */
3312 switch (mod)
3314 case 0:
3315 if ((rm & 7) == 6)
3317 disp = get16 ();
3318 if ((disp & 0x8000) != 0)
3319 disp -= 0x10000;
3321 break;
3322 case 1:
3323 FETCH_DATA (the_info, codep + 1);
3324 disp = *codep++;
3325 if ((disp & 0x80) != 0)
3326 disp -= 0x100;
3327 break;
3328 case 2:
3329 disp = get16 ();
3330 if ((disp & 0x8000) != 0)
3331 disp -= 0x10000;
3332 break;
3335 if (!intel_syntax)
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;
3345 *obufp = '\0';
3346 oappend (index16[rm + add]);
3347 *obufp++ = close_char;
3348 *obufp = '\0';
3353 static void
3354 OP_G (int bytemode, int sizeflag)
3356 int add = 0;
3357 USED_REX (REX_EXTX);
3358 if (rex & REX_EXTX)
3359 add += 8;
3360 switch (bytemode)
3362 case b_mode:
3363 USED_REX (0);
3364 if (rex)
3365 oappend (names8rex[reg + add]);
3366 else
3367 oappend (names8[reg + add]);
3368 break;
3369 case w_mode:
3370 oappend (names16[reg + add]);
3371 break;
3372 case d_mode:
3373 oappend (names32[reg + add]);
3374 break;
3375 case q_mode:
3376 oappend (names64[reg + add]);
3377 break;
3378 case v_mode:
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]);
3384 else
3385 oappend (names16[reg + add]);
3386 used_prefixes |= (prefixes & PREFIX_DATA);
3387 break;
3388 default:
3389 oappend (INTERNAL_DISASSEMBLER_ERROR);
3390 break;
3394 static bfd_vma
3395 get64 (void)
3397 bfd_vma x;
3398 #ifdef BFD64
3399 unsigned int a;
3400 unsigned int b;
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);
3412 #else
3413 abort ();
3414 x = 0;
3415 #endif
3416 return x;
3419 static bfd_signed_vma
3420 get32 (void)
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;
3429 return x;
3432 static bfd_signed_vma
3433 get32s (void)
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);
3445 return x;
3448 static int
3449 get16 (void)
3451 int x = 0;
3453 FETCH_DATA (the_info, codep + 2);
3454 x = *codep++ & 0xff;
3455 x |= (*codep++ & 0xff) << 8;
3456 return x;
3459 static void
3460 set_op (bfd_vma op, int riprel)
3462 op_index[op_ad] = op_ad;
3463 if (mode_64bit)
3465 op_address[op_ad] = op;
3466 op_riprel[op_ad] = riprel;
3468 else
3470 /* Mask to get a 32-bit address. */
3471 op_address[op_ad] = op & 0xffffffff;
3472 op_riprel[op_ad] = riprel & 0xffffffff;
3476 static void
3477 OP_REG (int code, int sizeflag)
3479 const char *s;
3480 int add = 0;
3481 USED_REX (REX_EXTZ);
3482 if (rex & REX_EXTZ)
3483 add = 8;
3485 switch (code)
3487 case indir_dx_reg:
3488 if (intel_syntax)
3489 s = "[dx]";
3490 else
3491 s = "(%dx)";
3492 break;
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];
3496 break;
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];
3500 break;
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:
3503 USED_REX (0);
3504 if (rex)
3505 s = names8rex[code - al_reg + add];
3506 else
3507 s = names8[code - al_reg];
3508 break;
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:
3511 if (mode_64bit)
3513 s = names64[code - rAX_reg + add];
3514 break;
3516 code += eAX_reg - rAX_reg;
3517 /* Fall through. */
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];
3525 else
3526 s = names16[code - eAX_reg + add];
3527 used_prefixes |= (prefixes & PREFIX_DATA);
3528 break;
3529 default:
3530 s = INTERNAL_DISASSEMBLER_ERROR;
3531 break;
3533 oappend (s);
3536 static void
3537 OP_IMREG (int code, int sizeflag)
3539 const char *s;
3541 switch (code)
3543 case indir_dx_reg:
3544 if (intel_syntax)
3545 s = "[dx]";
3546 else
3547 s = "(%dx)";
3548 break;
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];
3552 break;
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];
3556 break;
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:
3559 USED_REX (0);
3560 if (rex)
3561 s = names8rex[code - al_reg];
3562 else
3563 s = names8[code - al_reg];
3564 break;
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];
3572 else
3573 s = names16[code - eAX_reg];
3574 used_prefixes |= (prefixes & PREFIX_DATA);
3575 break;
3576 default:
3577 s = INTERNAL_DISASSEMBLER_ERROR;
3578 break;
3580 oappend (s);
3583 static void
3584 OP_I (int bytemode, int sizeflag)
3586 bfd_signed_vma op;
3587 bfd_signed_vma mask = -1;
3589 switch (bytemode)
3591 case b_mode:
3592 FETCH_DATA (the_info, codep + 1);
3593 op = *codep++;
3594 mask = 0xff;
3595 break;
3596 case q_mode:
3597 if (mode_64bit)
3599 op = get32s ();
3600 break;
3602 /* Fall through. */
3603 case v_mode:
3604 USED_REX (REX_MODE64);
3605 if (rex & REX_MODE64)
3606 op = get32s ();
3607 else if (sizeflag & DFLAG)
3609 op = get32 ();
3610 mask = 0xffffffff;
3612 else
3614 op = get16 ();
3615 mask = 0xfffff;
3617 used_prefixes |= (prefixes & PREFIX_DATA);
3618 break;
3619 case w_mode:
3620 mask = 0xfffff;
3621 op = get16 ();
3622 break;
3623 default:
3624 oappend (INTERNAL_DISASSEMBLER_ERROR);
3625 return;
3628 op &= mask;
3629 scratchbuf[0] = '$';
3630 print_operand_value (scratchbuf + 1, 1, op);
3631 oappend (scratchbuf + intel_syntax);
3632 scratchbuf[0] = '\0';
3635 static void
3636 OP_I64 (int bytemode, int sizeflag)
3638 bfd_signed_vma op;
3639 bfd_signed_vma mask = -1;
3641 if (!mode_64bit)
3643 OP_I (bytemode, sizeflag);
3644 return;
3647 switch (bytemode)
3649 case b_mode:
3650 FETCH_DATA (the_info, codep + 1);
3651 op = *codep++;
3652 mask = 0xff;
3653 break;
3654 case v_mode:
3655 USED_REX (REX_MODE64);
3656 if (rex & REX_MODE64)
3657 op = get64 ();
3658 else if (sizeflag & DFLAG)
3660 op = get32 ();
3661 mask = 0xffffffff;
3663 else
3665 op = get16 ();
3666 mask = 0xfffff;
3668 used_prefixes |= (prefixes & PREFIX_DATA);
3669 break;
3670 case w_mode:
3671 mask = 0xfffff;
3672 op = get16 ();
3673 break;
3674 default:
3675 oappend (INTERNAL_DISASSEMBLER_ERROR);
3676 return;
3679 op &= mask;
3680 scratchbuf[0] = '$';
3681 print_operand_value (scratchbuf + 1, 1, op);
3682 oappend (scratchbuf + intel_syntax);
3683 scratchbuf[0] = '\0';
3686 static void
3687 OP_sI (int bytemode, int sizeflag)
3689 bfd_signed_vma op;
3690 bfd_signed_vma mask = -1;
3692 switch (bytemode)
3694 case b_mode:
3695 FETCH_DATA (the_info, codep + 1);
3696 op = *codep++;
3697 if ((op & 0x80) != 0)
3698 op -= 0x100;
3699 mask = 0xffffffff;
3700 break;
3701 case v_mode:
3702 USED_REX (REX_MODE64);
3703 if (rex & REX_MODE64)
3704 op = get32s ();
3705 else if (sizeflag & DFLAG)
3707 op = get32s ();
3708 mask = 0xffffffff;
3710 else
3712 mask = 0xffffffff;
3713 op = get16 ();
3714 if ((op & 0x8000) != 0)
3715 op -= 0x10000;
3717 used_prefixes |= (prefixes & PREFIX_DATA);
3718 break;
3719 case w_mode:
3720 op = get16 ();
3721 mask = 0xffffffff;
3722 if ((op & 0x8000) != 0)
3723 op -= 0x10000;
3724 break;
3725 default:
3726 oappend (INTERNAL_DISASSEMBLER_ERROR);
3727 return;
3730 scratchbuf[0] = '$';
3731 print_operand_value (scratchbuf + 1, 1, op);
3732 oappend (scratchbuf + intel_syntax);
3735 static void
3736 OP_J (int bytemode, int sizeflag)
3738 bfd_vma disp;
3739 bfd_vma mask = -1;
3741 switch (bytemode)
3743 case b_mode:
3744 FETCH_DATA (the_info, codep + 1);
3745 disp = *codep++;
3746 if ((disp & 0x80) != 0)
3747 disp -= 0x100;
3748 break;
3749 case v_mode:
3750 if (sizeflag & DFLAG)
3751 disp = get32s ();
3752 else
3754 disp = get16 ();
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! */
3758 mask = 0xffff;
3760 break;
3761 default:
3762 oappend (INTERNAL_DISASSEMBLER_ERROR);
3763 return;
3765 disp = (start_pc + codep - start_codep + disp) & mask;
3766 set_op (disp, 0);
3767 print_operand_value (scratchbuf, 1, disp);
3768 oappend (scratchbuf);
3771 static void
3772 OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3774 oappend (names_seg[reg]);
3777 static void
3778 OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
3780 int seg, offset;
3782 if (sizeflag & DFLAG)
3784 offset = get32 ();
3785 seg = get16 ();
3787 else
3789 offset = get16 ();
3790 seg = get16 ();
3792 used_prefixes |= (prefixes & PREFIX_DATA);
3793 if (intel_syntax)
3794 sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
3795 else
3796 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3797 oappend (scratchbuf);
3800 static void
3801 OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag)
3803 bfd_vma off;
3805 append_seg ();
3807 if ((sizeflag & AFLAG) || mode_64bit)
3808 off = get32 ();
3809 else
3810 off = get16 ();
3812 if (intel_syntax)
3814 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3815 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3817 oappend (names_seg[ds_reg - es_reg]);
3818 oappend (":");
3821 print_operand_value (scratchbuf, 1, off);
3822 oappend (scratchbuf);
3825 static void
3826 OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3828 bfd_vma off;
3830 if (!mode_64bit)
3832 OP_OFF (bytemode, sizeflag);
3833 return;
3836 append_seg ();
3838 off = get64 ();
3840 if (intel_syntax)
3842 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3843 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3845 oappend (names_seg[ds_reg - es_reg]);
3846 oappend (":");
3849 print_operand_value (scratchbuf, 1, off);
3850 oappend (scratchbuf);
3853 static void
3854 ptr_reg (int code, int sizeflag)
3856 const char *s;
3858 *obufp++ = open_char;
3859 USED_REX (REX_MODE64);
3860 if (rex & REX_MODE64)
3862 if (!(sizeflag & AFLAG))
3863 s = names32[code - eAX_reg];
3864 else
3865 s = names64[code - eAX_reg];
3867 else if (sizeflag & AFLAG)
3868 s = names32[code - eAX_reg];
3869 else
3870 s = names16[code - eAX_reg];
3871 oappend (s);
3872 *obufp++ = close_char;
3873 *obufp = 0;
3876 static void
3877 OP_ESreg (int code, int sizeflag)
3879 oappend ("%es:" + intel_syntax);
3880 ptr_reg (code, sizeflag);
3883 static void
3884 OP_DSreg (int code, int sizeflag)
3886 if ((prefixes
3887 & (PREFIX_CS
3888 | PREFIX_DS
3889 | PREFIX_SS
3890 | PREFIX_ES
3891 | PREFIX_FS
3892 | PREFIX_GS)) == 0)
3893 prefixes |= PREFIX_DS;
3894 append_seg ();
3895 ptr_reg (code, sizeflag);
3898 static void
3899 OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3901 int add = 0;
3902 USED_REX (REX_EXTX);
3903 if (rex & REX_EXTX)
3904 add = 8;
3905 sprintf (scratchbuf, "%%cr%d", reg + add);
3906 oappend (scratchbuf + intel_syntax);
3909 static void
3910 OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3912 int add = 0;
3913 USED_REX (REX_EXTX);
3914 if (rex & REX_EXTX)
3915 add = 8;
3916 if (intel_syntax)
3917 sprintf (scratchbuf, "db%d", reg + add);
3918 else
3919 sprintf (scratchbuf, "%%db%d", reg + add);
3920 oappend (scratchbuf);
3923 static void
3924 OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3926 sprintf (scratchbuf, "%%tr%d", reg);
3927 oappend (scratchbuf + intel_syntax);
3930 static void
3931 OP_Rd (int bytemode, int sizeflag)
3933 if (mod == 3)
3934 OP_E (bytemode, sizeflag);
3935 else
3936 BadOp ();
3939 static void
3940 OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3942 int add = 0;
3943 USED_REX (REX_EXTX);
3944 if (rex & REX_EXTX)
3945 add = 8;
3946 used_prefixes |= (prefixes & PREFIX_DATA);
3947 if (prefixes & PREFIX_DATA)
3948 sprintf (scratchbuf, "%%xmm%d", reg + add);
3949 else
3950 sprintf (scratchbuf, "%%mm%d", reg + add);
3951 oappend (scratchbuf + intel_syntax);
3954 static void
3955 OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3957 int add = 0;
3958 USED_REX (REX_EXTX);
3959 if (rex & REX_EXTX)
3960 add = 8;
3961 sprintf (scratchbuf, "%%xmm%d", reg + add);
3962 oappend (scratchbuf + intel_syntax);
3965 static void
3966 OP_EM (int bytemode, int sizeflag)
3968 int add = 0;
3969 if (mod != 3)
3971 OP_E (bytemode, sizeflag);
3972 return;
3974 USED_REX (REX_EXTZ);
3975 if (rex & REX_EXTZ)
3976 add = 8;
3978 /* Skip mod/rm byte. */
3979 MODRM_CHECK;
3980 codep++;
3981 used_prefixes |= (prefixes & PREFIX_DATA);
3982 if (prefixes & PREFIX_DATA)
3983 sprintf (scratchbuf, "%%xmm%d", rm + add);
3984 else
3985 sprintf (scratchbuf, "%%mm%d", rm + add);
3986 oappend (scratchbuf + intel_syntax);
3989 static void
3990 OP_EX (int bytemode, int sizeflag)
3992 int add = 0;
3993 if (mod != 3)
3995 OP_E (bytemode, sizeflag);
3996 return;
3998 USED_REX (REX_EXTZ);
3999 if (rex & REX_EXTZ)
4000 add = 8;
4002 /* Skip mod/rm byte. */
4003 MODRM_CHECK;
4004 codep++;
4005 sprintf (scratchbuf, "%%xmm%d", rm + add);
4006 oappend (scratchbuf + intel_syntax);
4009 static void
4010 OP_MS (int bytemode, int sizeflag)
4012 if (mod == 3)
4013 OP_EM (bytemode, sizeflag);
4014 else
4015 BadOp ();
4018 static void
4019 OP_XS (int bytemode, int sizeflag)
4021 if (mod == 3)
4022 OP_EX (bytemode, sizeflag);
4023 else
4024 BadOp ();
4027 static void
4028 OP_M (int bytemode, int sizeflag)
4030 if (mod == 3)
4031 BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
4032 else
4033 OP_E (bytemode, sizeflag);
4036 static void
4037 OP_0f07 (int bytemode, int sizeflag)
4039 if (mod != 3 || rm != 0)
4040 BadOp ();
4041 else
4042 OP_E (bytemode, sizeflag);
4045 static void
4046 OP_0fae (int bytemode, int sizeflag)
4048 if (mod == 3)
4050 if (reg == 7)
4051 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
4053 if (reg < 5 || rm != 0)
4055 BadOp (); /* bad sfence, mfence, or lfence */
4056 return;
4059 else if (reg != 7)
4061 BadOp (); /* bad clflush */
4062 return;
4065 OP_E (bytemode, sizeflag);
4068 static void
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,
4143 static void
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];
4154 if (mnemonic)
4155 oappend (mnemonic);
4156 else
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. */
4162 op1out[0] = '\0';
4163 op2out[0] = '\0';
4164 BadOp ();
4168 static const char *simd_cmp_op[] = {
4169 "eq",
4170 "lt",
4171 "le",
4172 "unord",
4173 "neq",
4174 "nlt",
4175 "nle",
4176 "ord"
4179 static void
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;
4187 if (cmp_type < 8)
4189 char suffix1 = 'p', suffix2 = 's';
4190 used_prefixes |= (prefixes & PREFIX_REPZ);
4191 if (prefixes & PREFIX_REPZ)
4192 suffix1 = 's';
4193 else
4195 used_prefixes |= (prefixes & PREFIX_DATA);
4196 if (prefixes & PREFIX_DATA)
4197 suffix2 = 'd';
4198 else
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);
4210 else
4212 /* We have a bad extension byte. Clean up. */
4213 op1out[0] = '\0';
4214 op2out[0] = '\0';
4215 BadOp ();
4219 static void
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. */
4224 if (mod == 3)
4226 char *p = obuf + strlen (obuf);
4227 *(p + 1) = '\0';
4228 *p = *(p - 1);
4229 *(p - 1) = *(p - 2);
4230 *(p - 2) = *(p - 3);
4231 *(p - 3) = extrachar;
4235 static void
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. */
4244 if (*p == 'i')
4245 --p;
4247 if (rm)
4249 /* mwait %eax,%ecx */
4250 strcpy (p, "mwait");
4252 else
4254 /* monitor %eax,%ecx,%edx" */
4255 strcpy (p, "monitor");
4256 strcpy (op3out, names32[2]);
4258 strcpy (op1out, names32[0]);
4259 strcpy (op2out, names32[1]);
4260 two_source_ops = 1;
4262 codep++;
4264 else
4265 OP_E (0, sizeflag);
4268 static void
4269 INVLPG_Fixup (int bytemode, int sizeflag)
4271 if (*codep == 0xf8)
4273 char *p = obuf + strlen (obuf);
4275 /* Override "invlpg". */
4276 strcpy (p - 6, "swapgs");
4277 codep++;
4279 else
4280 OP_E (bytemode, sizeflag);
4283 static void
4284 BadOp (void)
4286 /* Throw away prefixes and 1st. opcode byte. */
4287 codep = insn_codep + 1;
4288 oappend ("(bad)");