2004-03-17 Paolo Bonzini <bonzini@gnu.org>
[binutils.git] / opcodes / i386-dis.c
bloba71eb0c9105a4c0b5dace6d4028c8daaf8ef912d
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
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 bfd_vma op_address[3];
1885 static bfd_vma op_riprel[3];
1886 static bfd_vma start_pc;
1889 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1890 * (see topic "Redundant prefixes" in the "Differences from 8086"
1891 * section of the "Virtual 8086 Mode" chapter.)
1892 * 'pc' should be the address of this instruction, it will
1893 * be used to print the target address if this is a relative jump or call
1894 * The function returns the length of this instruction in bytes.
1897 static char intel_syntax;
1898 static char open_char;
1899 static char close_char;
1900 static char separator_char;
1901 static char scale_char;
1903 /* Here for backwards compatibility. When gdb stops using
1904 print_insn_i386_att and print_insn_i386_intel these functions can
1905 disappear, and print_insn_i386 be merged into print_insn. */
1907 print_insn_i386_att (bfd_vma pc, disassemble_info *info)
1909 intel_syntax = 0;
1911 return print_insn (pc, info);
1915 print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
1917 intel_syntax = 1;
1919 return print_insn (pc, info);
1923 print_insn_i386 (bfd_vma pc, disassemble_info *info)
1925 intel_syntax = -1;
1927 return print_insn (pc, info);
1930 static int
1931 print_insn (bfd_vma pc, disassemble_info *info)
1933 const struct dis386 *dp;
1934 int i;
1935 int two_source_ops;
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 "fisttpll",
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 "fistpll",
2394 #define ST OP_ST, 0
2395 #define STi OP_STi, 0
2397 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
2398 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
2399 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
2400 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
2401 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
2402 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
2403 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
2404 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
2405 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
2407 static const struct dis386 float_reg[][8] = {
2408 /* d8 */
2410 { "fadd", ST, STi, XX },
2411 { "fmul", ST, STi, XX },
2412 { "fcom", STi, XX, XX },
2413 { "fcomp", STi, XX, XX },
2414 { "fsub", ST, STi, XX },
2415 { "fsubr", ST, STi, XX },
2416 { "fdiv", ST, STi, XX },
2417 { "fdivr", ST, STi, XX },
2419 /* d9 */
2421 { "fld", STi, XX, XX },
2422 { "fxch", STi, XX, XX },
2423 { FGRPd9_2 },
2424 { "(bad)", XX, XX, XX },
2425 { FGRPd9_4 },
2426 { FGRPd9_5 },
2427 { FGRPd9_6 },
2428 { FGRPd9_7 },
2430 /* da */
2432 { "fcmovb", ST, STi, XX },
2433 { "fcmove", ST, STi, XX },
2434 { "fcmovbe",ST, STi, XX },
2435 { "fcmovu", ST, STi, XX },
2436 { "(bad)", XX, XX, XX },
2437 { FGRPda_5 },
2438 { "(bad)", XX, XX, XX },
2439 { "(bad)", XX, XX, XX },
2441 /* db */
2443 { "fcmovnb",ST, STi, XX },
2444 { "fcmovne",ST, STi, XX },
2445 { "fcmovnbe",ST, STi, XX },
2446 { "fcmovnu",ST, STi, XX },
2447 { FGRPdb_4 },
2448 { "fucomi", ST, STi, XX },
2449 { "fcomi", ST, STi, XX },
2450 { "(bad)", XX, XX, XX },
2452 /* dc */
2454 { "fadd", STi, ST, XX },
2455 { "fmul", STi, ST, XX },
2456 { "(bad)", XX, XX, XX },
2457 { "(bad)", XX, XX, XX },
2458 #if UNIXWARE_COMPAT
2459 { "fsub", STi, ST, XX },
2460 { "fsubr", STi, ST, XX },
2461 { "fdiv", STi, ST, XX },
2462 { "fdivr", STi, ST, XX },
2463 #else
2464 { "fsubr", STi, ST, XX },
2465 { "fsub", STi, ST, XX },
2466 { "fdivr", STi, ST, XX },
2467 { "fdiv", STi, ST, XX },
2468 #endif
2470 /* dd */
2472 { "ffree", STi, XX, XX },
2473 { "(bad)", XX, XX, XX },
2474 { "fst", STi, XX, XX },
2475 { "fstp", STi, XX, XX },
2476 { "fucom", STi, XX, XX },
2477 { "fucomp", STi, XX, XX },
2478 { "(bad)", XX, XX, XX },
2479 { "(bad)", XX, XX, XX },
2481 /* de */
2483 { "faddp", STi, ST, XX },
2484 { "fmulp", STi, ST, XX },
2485 { "(bad)", XX, XX, XX },
2486 { FGRPde_3 },
2487 #if UNIXWARE_COMPAT
2488 { "fsubp", STi, ST, XX },
2489 { "fsubrp", STi, ST, XX },
2490 { "fdivp", STi, ST, XX },
2491 { "fdivrp", STi, ST, XX },
2492 #else
2493 { "fsubrp", STi, ST, XX },
2494 { "fsubp", STi, ST, XX },
2495 { "fdivrp", STi, ST, XX },
2496 { "fdivp", STi, ST, XX },
2497 #endif
2499 /* df */
2501 { "ffreep", STi, XX, XX },
2502 { "(bad)", XX, XX, XX },
2503 { "(bad)", XX, XX, XX },
2504 { "(bad)", XX, XX, XX },
2505 { FGRPdf_4 },
2506 { "fucomip",ST, STi, XX },
2507 { "fcomip", ST, STi, XX },
2508 { "(bad)", XX, XX, XX },
2512 static char *fgrps[][8] = {
2513 /* d9_2 0 */
2515 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2518 /* d9_4 1 */
2520 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2523 /* d9_5 2 */
2525 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2528 /* d9_6 3 */
2530 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2533 /* d9_7 4 */
2535 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2538 /* da_5 5 */
2540 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2543 /* db_4 6 */
2545 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2546 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2549 /* de_3 7 */
2551 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2554 /* df_4 8 */
2556 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2560 static void
2561 dofloat (int sizeflag)
2563 const struct dis386 *dp;
2564 unsigned char floatop;
2566 floatop = codep[-1];
2568 if (mod != 3)
2570 putop (float_mem[(floatop - 0xd8) * 8 + reg], sizeflag);
2571 obufp = op1out;
2572 if (floatop == 0xdb)
2573 OP_E (x_mode, sizeflag);
2574 else if (floatop == 0xdd)
2575 OP_E (d_mode, sizeflag);
2576 else
2577 OP_E (v_mode, sizeflag);
2578 return;
2580 /* Skip mod/rm byte. */
2581 MODRM_CHECK;
2582 codep++;
2584 dp = &float_reg[floatop - 0xd8][reg];
2585 if (dp->name == NULL)
2587 putop (fgrps[dp->bytemode1][rm], sizeflag);
2589 /* Instruction fnstsw is only one with strange arg. */
2590 if (floatop == 0xdf && codep[-1] == 0xe0)
2591 strcpy (op1out, names16[0]);
2593 else
2595 putop (dp->name, sizeflag);
2597 obufp = op1out;
2598 if (dp->op1)
2599 (*dp->op1) (dp->bytemode1, sizeflag);
2600 obufp = op2out;
2601 if (dp->op2)
2602 (*dp->op2) (dp->bytemode2, sizeflag);
2606 static void
2607 OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
2609 oappend ("%st");
2612 static void
2613 OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
2615 sprintf (scratchbuf, "%%st(%d)", rm);
2616 oappend (scratchbuf + intel_syntax);
2619 /* Capital letters in template are macros. */
2620 static int
2621 putop (const char *template, int sizeflag)
2623 const char *p;
2624 int alt;
2626 for (p = template; *p; p++)
2628 switch (*p)
2630 default:
2631 *obufp++ = *p;
2632 break;
2633 case '{':
2634 alt = 0;
2635 if (intel_syntax)
2636 alt += 1;
2637 if (mode_64bit)
2638 alt += 2;
2639 while (alt != 0)
2641 while (*++p != '|')
2643 if (*p == '}')
2645 /* Alternative not valid. */
2646 strcpy (obuf, "(bad)");
2647 obufp = obuf + 5;
2648 return 1;
2650 else if (*p == '\0')
2651 abort ();
2653 alt--;
2655 break;
2656 case '|':
2657 while (*++p != '}')
2659 if (*p == '\0')
2660 abort ();
2662 break;
2663 case '}':
2664 break;
2665 case 'A':
2666 if (intel_syntax)
2667 break;
2668 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2669 *obufp++ = 'b';
2670 break;
2671 case 'B':
2672 if (intel_syntax)
2673 break;
2674 if (sizeflag & SUFFIX_ALWAYS)
2675 *obufp++ = 'b';
2676 break;
2677 case 'E': /* For jcxz/jecxz */
2678 if (mode_64bit)
2680 if (sizeflag & AFLAG)
2681 *obufp++ = 'r';
2682 else
2683 *obufp++ = 'e';
2685 else
2686 if (sizeflag & AFLAG)
2687 *obufp++ = 'e';
2688 used_prefixes |= (prefixes & PREFIX_ADDR);
2689 break;
2690 case 'F':
2691 if (intel_syntax)
2692 break;
2693 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
2695 if (sizeflag & AFLAG)
2696 *obufp++ = mode_64bit ? 'q' : 'l';
2697 else
2698 *obufp++ = mode_64bit ? 'l' : 'w';
2699 used_prefixes |= (prefixes & PREFIX_ADDR);
2701 break;
2702 case 'H':
2703 if (intel_syntax)
2704 break;
2705 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
2706 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
2708 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
2709 *obufp++ = ',';
2710 *obufp++ = 'p';
2711 if (prefixes & PREFIX_DS)
2712 *obufp++ = 't';
2713 else
2714 *obufp++ = 'n';
2716 break;
2717 case 'L':
2718 if (intel_syntax)
2719 break;
2720 if (sizeflag & SUFFIX_ALWAYS)
2721 *obufp++ = 'l';
2722 break;
2723 case 'N':
2724 if ((prefixes & PREFIX_FWAIT) == 0)
2725 *obufp++ = 'n';
2726 else
2727 used_prefixes |= PREFIX_FWAIT;
2728 break;
2729 case 'O':
2730 USED_REX (REX_MODE64);
2731 if (rex & REX_MODE64)
2732 *obufp++ = 'o';
2733 else
2734 *obufp++ = 'd';
2735 break;
2736 case 'T':
2737 if (intel_syntax)
2738 break;
2739 if (mode_64bit)
2741 *obufp++ = 'q';
2742 break;
2744 /* Fall through. */
2745 case 'P':
2746 if (intel_syntax)
2747 break;
2748 if ((prefixes & PREFIX_DATA)
2749 || (rex & REX_MODE64)
2750 || (sizeflag & SUFFIX_ALWAYS))
2752 USED_REX (REX_MODE64);
2753 if (rex & REX_MODE64)
2754 *obufp++ = 'q';
2755 else
2757 if (sizeflag & DFLAG)
2758 *obufp++ = 'l';
2759 else
2760 *obufp++ = 'w';
2761 used_prefixes |= (prefixes & PREFIX_DATA);
2764 break;
2765 case 'U':
2766 if (intel_syntax)
2767 break;
2768 if (mode_64bit)
2770 *obufp++ = 'q';
2771 break;
2773 /* Fall through. */
2774 case 'Q':
2775 if (intel_syntax)
2776 break;
2777 USED_REX (REX_MODE64);
2778 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2780 if (rex & REX_MODE64)
2781 *obufp++ = 'q';
2782 else
2784 if (sizeflag & DFLAG)
2785 *obufp++ = 'l';
2786 else
2787 *obufp++ = 'w';
2788 used_prefixes |= (prefixes & PREFIX_DATA);
2791 break;
2792 case 'R':
2793 USED_REX (REX_MODE64);
2794 if (intel_syntax)
2796 if (rex & REX_MODE64)
2798 *obufp++ = 'q';
2799 *obufp++ = 't';
2801 else if (sizeflag & DFLAG)
2803 *obufp++ = 'd';
2804 *obufp++ = 'q';
2806 else
2808 *obufp++ = 'w';
2809 *obufp++ = 'd';
2812 else
2814 if (rex & REX_MODE64)
2815 *obufp++ = 'q';
2816 else if (sizeflag & DFLAG)
2817 *obufp++ = 'l';
2818 else
2819 *obufp++ = 'w';
2821 if (!(rex & REX_MODE64))
2822 used_prefixes |= (prefixes & PREFIX_DATA);
2823 break;
2824 case 'S':
2825 if (intel_syntax)
2826 break;
2827 if (sizeflag & SUFFIX_ALWAYS)
2829 if (rex & REX_MODE64)
2830 *obufp++ = 'q';
2831 else
2833 if (sizeflag & DFLAG)
2834 *obufp++ = 'l';
2835 else
2836 *obufp++ = 'w';
2837 used_prefixes |= (prefixes & PREFIX_DATA);
2840 break;
2841 case 'X':
2842 if (prefixes & PREFIX_DATA)
2843 *obufp++ = 'd';
2844 else
2845 *obufp++ = 's';
2846 used_prefixes |= (prefixes & PREFIX_DATA);
2847 break;
2848 case 'Y':
2849 if (intel_syntax)
2850 break;
2851 if (rex & REX_MODE64)
2853 USED_REX (REX_MODE64);
2854 *obufp++ = 'q';
2856 break;
2857 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
2858 case 'W':
2859 /* operand size flag for cwtl, cbtw */
2860 USED_REX (0);
2861 if (rex)
2862 *obufp++ = 'l';
2863 else if (sizeflag & DFLAG)
2864 *obufp++ = 'w';
2865 else
2866 *obufp++ = 'b';
2867 if (intel_syntax)
2869 if (rex)
2871 *obufp++ = 'q';
2872 *obufp++ = 'e';
2874 if (sizeflag & DFLAG)
2876 *obufp++ = 'd';
2877 *obufp++ = 'e';
2879 else
2881 *obufp++ = 'w';
2884 if (!rex)
2885 used_prefixes |= (prefixes & PREFIX_DATA);
2886 break;
2889 *obufp = 0;
2890 return 0;
2893 static void
2894 oappend (const char *s)
2896 strcpy (obufp, s);
2897 obufp += strlen (s);
2900 static void
2901 append_seg (void)
2903 if (prefixes & PREFIX_CS)
2905 used_prefixes |= PREFIX_CS;
2906 oappend ("%cs:" + intel_syntax);
2908 if (prefixes & PREFIX_DS)
2910 used_prefixes |= PREFIX_DS;
2911 oappend ("%ds:" + intel_syntax);
2913 if (prefixes & PREFIX_SS)
2915 used_prefixes |= PREFIX_SS;
2916 oappend ("%ss:" + intel_syntax);
2918 if (prefixes & PREFIX_ES)
2920 used_prefixes |= PREFIX_ES;
2921 oappend ("%es:" + intel_syntax);
2923 if (prefixes & PREFIX_FS)
2925 used_prefixes |= PREFIX_FS;
2926 oappend ("%fs:" + intel_syntax);
2928 if (prefixes & PREFIX_GS)
2930 used_prefixes |= PREFIX_GS;
2931 oappend ("%gs:" + intel_syntax);
2935 static void
2936 OP_indirE (int bytemode, int sizeflag)
2938 if (!intel_syntax)
2939 oappend ("*");
2940 OP_E (bytemode, sizeflag);
2943 static void
2944 print_operand_value (char *buf, int hex, bfd_vma disp)
2946 if (mode_64bit)
2948 if (hex)
2950 char tmp[30];
2951 int i;
2952 buf[0] = '0';
2953 buf[1] = 'x';
2954 sprintf_vma (tmp, disp);
2955 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
2956 strcpy (buf + 2, tmp + i);
2958 else
2960 bfd_signed_vma v = disp;
2961 char tmp[30];
2962 int i;
2963 if (v < 0)
2965 *(buf++) = '-';
2966 v = -disp;
2967 /* Check for possible overflow on 0x8000000000000000. */
2968 if (v < 0)
2970 strcpy (buf, "9223372036854775808");
2971 return;
2974 if (!v)
2976 strcpy (buf, "0");
2977 return;
2980 i = 0;
2981 tmp[29] = 0;
2982 while (v)
2984 tmp[28 - i] = (v % 10) + '0';
2985 v /= 10;
2986 i++;
2988 strcpy (buf, tmp + 29 - i);
2991 else
2993 if (hex)
2994 sprintf (buf, "0x%x", (unsigned int) disp);
2995 else
2996 sprintf (buf, "%d", (int) disp);
3000 static void
3001 OP_E (int bytemode, int sizeflag)
3003 bfd_vma disp;
3004 int add = 0;
3005 int riprel = 0;
3006 USED_REX (REX_EXTZ);
3007 if (rex & REX_EXTZ)
3008 add += 8;
3010 /* Skip mod/rm byte. */
3011 MODRM_CHECK;
3012 codep++;
3014 if (mod == 3)
3016 switch (bytemode)
3018 case b_mode:
3019 USED_REX (0);
3020 if (rex)
3021 oappend (names8rex[rm + add]);
3022 else
3023 oappend (names8[rm + add]);
3024 break;
3025 case w_mode:
3026 oappend (names16[rm + add]);
3027 break;
3028 case d_mode:
3029 oappend (names32[rm + add]);
3030 break;
3031 case q_mode:
3032 oappend (names64[rm + add]);
3033 break;
3034 case m_mode:
3035 if (mode_64bit)
3036 oappend (names64[rm + add]);
3037 else
3038 oappend (names32[rm + add]);
3039 break;
3040 case v_mode:
3041 case dq_mode:
3042 USED_REX (REX_MODE64);
3043 if (rex & REX_MODE64)
3044 oappend (names64[rm + add]);
3045 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
3046 oappend (names32[rm + add]);
3047 else
3048 oappend (names16[rm + add]);
3049 used_prefixes |= (prefixes & PREFIX_DATA);
3050 break;
3051 case 0:
3052 break;
3053 default:
3054 oappend (INTERNAL_DISASSEMBLER_ERROR);
3055 break;
3057 return;
3060 disp = 0;
3061 append_seg ();
3063 if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
3065 int havesib;
3066 int havebase;
3067 int base;
3068 int index = 0;
3069 int scale = 0;
3071 havesib = 0;
3072 havebase = 1;
3073 base = rm;
3075 if (base == 4)
3077 havesib = 1;
3078 FETCH_DATA (the_info, codep + 1);
3079 scale = (*codep >> 6) & 3;
3080 index = (*codep >> 3) & 7;
3081 base = *codep & 7;
3082 USED_REX (REX_EXTY);
3083 USED_REX (REX_EXTZ);
3084 if (rex & REX_EXTY)
3085 index += 8;
3086 if (rex & REX_EXTZ)
3087 base += 8;
3088 codep++;
3091 switch (mod)
3093 case 0:
3094 if ((base & 7) == 5)
3096 havebase = 0;
3097 if (mode_64bit && !havesib && (sizeflag & AFLAG))
3098 riprel = 1;
3099 disp = get32s ();
3101 break;
3102 case 1:
3103 FETCH_DATA (the_info, codep + 1);
3104 disp = *codep++;
3105 if ((disp & 0x80) != 0)
3106 disp -= 0x100;
3107 break;
3108 case 2:
3109 disp = get32s ();
3110 break;
3113 if (!intel_syntax)
3114 if (mod != 0 || (base & 7) == 5)
3116 print_operand_value (scratchbuf, !riprel, disp);
3117 oappend (scratchbuf);
3118 if (riprel)
3120 set_op (disp, 1);
3121 oappend ("(%rip)");
3125 if (havebase || (havesib && (index != 4 || scale != 0)))
3127 if (intel_syntax)
3129 switch (bytemode)
3131 case b_mode:
3132 oappend ("BYTE PTR ");
3133 break;
3134 case w_mode:
3135 oappend ("WORD PTR ");
3136 break;
3137 case v_mode:
3138 oappend ("DWORD PTR ");
3139 break;
3140 case d_mode:
3141 oappend ("QWORD PTR ");
3142 break;
3143 case m_mode:
3144 if (mode_64bit)
3145 oappend ("DWORD PTR ");
3146 else
3147 oappend ("QWORD PTR ");
3148 break;
3149 case x_mode:
3150 oappend ("XWORD PTR ");
3151 break;
3152 default:
3153 break;
3156 *obufp++ = open_char;
3157 if (intel_syntax && riprel)
3158 oappend ("rip + ");
3159 *obufp = '\0';
3160 USED_REX (REX_EXTZ);
3161 if (!havesib && (rex & REX_EXTZ))
3162 base += 8;
3163 if (havebase)
3164 oappend (mode_64bit && (sizeflag & AFLAG)
3165 ? names64[base] : names32[base]);
3166 if (havesib)
3168 if (index != 4)
3170 if (intel_syntax)
3172 if (havebase)
3174 *obufp++ = separator_char;
3175 *obufp = '\0';
3177 sprintf (scratchbuf, "%s",
3178 mode_64bit && (sizeflag & AFLAG)
3179 ? names64[index] : names32[index]);
3181 else
3182 sprintf (scratchbuf, ",%s",
3183 mode_64bit && (sizeflag & AFLAG)
3184 ? names64[index] : names32[index]);
3185 oappend (scratchbuf);
3187 if (scale != 0 || (!intel_syntax && index != 4))
3189 *obufp++ = scale_char;
3190 *obufp = '\0';
3191 sprintf (scratchbuf, "%d", 1 << scale);
3192 oappend (scratchbuf);
3195 if (intel_syntax)
3196 if (mod != 0 || (base & 7) == 5)
3198 /* Don't print zero displacements. */
3199 if (disp != 0)
3201 if ((bfd_signed_vma) disp > 0)
3203 *obufp++ = '+';
3204 *obufp = '\0';
3207 print_operand_value (scratchbuf, 0, disp);
3208 oappend (scratchbuf);
3212 *obufp++ = close_char;
3213 *obufp = '\0';
3215 else if (intel_syntax)
3217 if (mod != 0 || (base & 7) == 5)
3219 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3220 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
3222 else
3224 oappend (names_seg[ds_reg - es_reg]);
3225 oappend (":");
3227 print_operand_value (scratchbuf, 1, disp);
3228 oappend (scratchbuf);
3232 else
3233 { /* 16 bit address mode */
3234 switch (mod)
3236 case 0:
3237 if ((rm & 7) == 6)
3239 disp = get16 ();
3240 if ((disp & 0x8000) != 0)
3241 disp -= 0x10000;
3243 break;
3244 case 1:
3245 FETCH_DATA (the_info, codep + 1);
3246 disp = *codep++;
3247 if ((disp & 0x80) != 0)
3248 disp -= 0x100;
3249 break;
3250 case 2:
3251 disp = get16 ();
3252 if ((disp & 0x8000) != 0)
3253 disp -= 0x10000;
3254 break;
3257 if (!intel_syntax)
3258 if (mod != 0 || (rm & 7) == 6)
3260 print_operand_value (scratchbuf, 0, disp);
3261 oappend (scratchbuf);
3264 if (mod != 0 || (rm & 7) != 6)
3266 *obufp++ = open_char;
3267 *obufp = '\0';
3268 oappend (index16[rm + add]);
3269 *obufp++ = close_char;
3270 *obufp = '\0';
3275 static void
3276 OP_G (int bytemode, int sizeflag)
3278 int add = 0;
3279 USED_REX (REX_EXTX);
3280 if (rex & REX_EXTX)
3281 add += 8;
3282 switch (bytemode)
3284 case b_mode:
3285 USED_REX (0);
3286 if (rex)
3287 oappend (names8rex[reg + add]);
3288 else
3289 oappend (names8[reg + add]);
3290 break;
3291 case w_mode:
3292 oappend (names16[reg + add]);
3293 break;
3294 case d_mode:
3295 oappend (names32[reg + add]);
3296 break;
3297 case q_mode:
3298 oappend (names64[reg + add]);
3299 break;
3300 case v_mode:
3301 USED_REX (REX_MODE64);
3302 if (rex & REX_MODE64)
3303 oappend (names64[reg + add]);
3304 else if (sizeflag & DFLAG)
3305 oappend (names32[reg + add]);
3306 else
3307 oappend (names16[reg + add]);
3308 used_prefixes |= (prefixes & PREFIX_DATA);
3309 break;
3310 default:
3311 oappend (INTERNAL_DISASSEMBLER_ERROR);
3312 break;
3316 static bfd_vma
3317 get64 (void)
3319 bfd_vma x;
3320 #ifdef BFD64
3321 unsigned int a;
3322 unsigned int b;
3324 FETCH_DATA (the_info, codep + 8);
3325 a = *codep++ & 0xff;
3326 a |= (*codep++ & 0xff) << 8;
3327 a |= (*codep++ & 0xff) << 16;
3328 a |= (*codep++ & 0xff) << 24;
3329 b = *codep++ & 0xff;
3330 b |= (*codep++ & 0xff) << 8;
3331 b |= (*codep++ & 0xff) << 16;
3332 b |= (*codep++ & 0xff) << 24;
3333 x = a + ((bfd_vma) b << 32);
3334 #else
3335 abort ();
3336 x = 0;
3337 #endif
3338 return x;
3341 static bfd_signed_vma
3342 get32 (void)
3344 bfd_signed_vma x = 0;
3346 FETCH_DATA (the_info, codep + 4);
3347 x = *codep++ & (bfd_signed_vma) 0xff;
3348 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3349 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3350 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3351 return x;
3354 static bfd_signed_vma
3355 get32s (void)
3357 bfd_signed_vma x = 0;
3359 FETCH_DATA (the_info, codep + 4);
3360 x = *codep++ & (bfd_signed_vma) 0xff;
3361 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3362 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3363 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3365 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
3367 return x;
3370 static int
3371 get16 (void)
3373 int x = 0;
3375 FETCH_DATA (the_info, codep + 2);
3376 x = *codep++ & 0xff;
3377 x |= (*codep++ & 0xff) << 8;
3378 return x;
3381 static void
3382 set_op (bfd_vma op, int riprel)
3384 op_index[op_ad] = op_ad;
3385 if (mode_64bit)
3387 op_address[op_ad] = op;
3388 op_riprel[op_ad] = riprel;
3390 else
3392 /* Mask to get a 32-bit address. */
3393 op_address[op_ad] = op & 0xffffffff;
3394 op_riprel[op_ad] = riprel & 0xffffffff;
3398 static void
3399 OP_REG (int code, int sizeflag)
3401 const char *s;
3402 int add = 0;
3403 USED_REX (REX_EXTZ);
3404 if (rex & REX_EXTZ)
3405 add = 8;
3407 switch (code)
3409 case indir_dx_reg:
3410 if (intel_syntax)
3411 s = "[dx]";
3412 else
3413 s = "(%dx)";
3414 break;
3415 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3416 case sp_reg: case bp_reg: case si_reg: case di_reg:
3417 s = names16[code - ax_reg + add];
3418 break;
3419 case es_reg: case ss_reg: case cs_reg:
3420 case ds_reg: case fs_reg: case gs_reg:
3421 s = names_seg[code - es_reg + add];
3422 break;
3423 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3424 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3425 USED_REX (0);
3426 if (rex)
3427 s = names8rex[code - al_reg + add];
3428 else
3429 s = names8[code - al_reg];
3430 break;
3431 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
3432 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
3433 if (mode_64bit)
3435 s = names64[code - rAX_reg + add];
3436 break;
3438 code += eAX_reg - rAX_reg;
3439 /* Fall through. */
3440 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3441 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3442 USED_REX (REX_MODE64);
3443 if (rex & REX_MODE64)
3444 s = names64[code - eAX_reg + add];
3445 else if (sizeflag & DFLAG)
3446 s = names32[code - eAX_reg + add];
3447 else
3448 s = names16[code - eAX_reg + add];
3449 used_prefixes |= (prefixes & PREFIX_DATA);
3450 break;
3451 default:
3452 s = INTERNAL_DISASSEMBLER_ERROR;
3453 break;
3455 oappend (s);
3458 static void
3459 OP_IMREG (int code, int sizeflag)
3461 const char *s;
3463 switch (code)
3465 case indir_dx_reg:
3466 if (intel_syntax)
3467 s = "[dx]";
3468 else
3469 s = "(%dx)";
3470 break;
3471 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3472 case sp_reg: case bp_reg: case si_reg: case di_reg:
3473 s = names16[code - ax_reg];
3474 break;
3475 case es_reg: case ss_reg: case cs_reg:
3476 case ds_reg: case fs_reg: case gs_reg:
3477 s = names_seg[code - es_reg];
3478 break;
3479 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3480 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3481 USED_REX (0);
3482 if (rex)
3483 s = names8rex[code - al_reg];
3484 else
3485 s = names8[code - al_reg];
3486 break;
3487 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3488 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3489 USED_REX (REX_MODE64);
3490 if (rex & REX_MODE64)
3491 s = names64[code - eAX_reg];
3492 else if (sizeflag & DFLAG)
3493 s = names32[code - eAX_reg];
3494 else
3495 s = names16[code - eAX_reg];
3496 used_prefixes |= (prefixes & PREFIX_DATA);
3497 break;
3498 default:
3499 s = INTERNAL_DISASSEMBLER_ERROR;
3500 break;
3502 oappend (s);
3505 static void
3506 OP_I (int bytemode, int sizeflag)
3508 bfd_signed_vma op;
3509 bfd_signed_vma mask = -1;
3511 switch (bytemode)
3513 case b_mode:
3514 FETCH_DATA (the_info, codep + 1);
3515 op = *codep++;
3516 mask = 0xff;
3517 break;
3518 case q_mode:
3519 if (mode_64bit)
3521 op = get32s ();
3522 break;
3524 /* Fall through. */
3525 case v_mode:
3526 USED_REX (REX_MODE64);
3527 if (rex & REX_MODE64)
3528 op = get32s ();
3529 else if (sizeflag & DFLAG)
3531 op = get32 ();
3532 mask = 0xffffffff;
3534 else
3536 op = get16 ();
3537 mask = 0xfffff;
3539 used_prefixes |= (prefixes & PREFIX_DATA);
3540 break;
3541 case w_mode:
3542 mask = 0xfffff;
3543 op = get16 ();
3544 break;
3545 default:
3546 oappend (INTERNAL_DISASSEMBLER_ERROR);
3547 return;
3550 op &= mask;
3551 scratchbuf[0] = '$';
3552 print_operand_value (scratchbuf + 1, 1, op);
3553 oappend (scratchbuf + intel_syntax);
3554 scratchbuf[0] = '\0';
3557 static void
3558 OP_I64 (int bytemode, int sizeflag)
3560 bfd_signed_vma op;
3561 bfd_signed_vma mask = -1;
3563 if (!mode_64bit)
3565 OP_I (bytemode, sizeflag);
3566 return;
3569 switch (bytemode)
3571 case b_mode:
3572 FETCH_DATA (the_info, codep + 1);
3573 op = *codep++;
3574 mask = 0xff;
3575 break;
3576 case v_mode:
3577 USED_REX (REX_MODE64);
3578 if (rex & REX_MODE64)
3579 op = get64 ();
3580 else if (sizeflag & DFLAG)
3582 op = get32 ();
3583 mask = 0xffffffff;
3585 else
3587 op = get16 ();
3588 mask = 0xfffff;
3590 used_prefixes |= (prefixes & PREFIX_DATA);
3591 break;
3592 case w_mode:
3593 mask = 0xfffff;
3594 op = get16 ();
3595 break;
3596 default:
3597 oappend (INTERNAL_DISASSEMBLER_ERROR);
3598 return;
3601 op &= mask;
3602 scratchbuf[0] = '$';
3603 print_operand_value (scratchbuf + 1, 1, op);
3604 oappend (scratchbuf + intel_syntax);
3605 scratchbuf[0] = '\0';
3608 static void
3609 OP_sI (int bytemode, int sizeflag)
3611 bfd_signed_vma op;
3612 bfd_signed_vma mask = -1;
3614 switch (bytemode)
3616 case b_mode:
3617 FETCH_DATA (the_info, codep + 1);
3618 op = *codep++;
3619 if ((op & 0x80) != 0)
3620 op -= 0x100;
3621 mask = 0xffffffff;
3622 break;
3623 case v_mode:
3624 USED_REX (REX_MODE64);
3625 if (rex & REX_MODE64)
3626 op = get32s ();
3627 else if (sizeflag & DFLAG)
3629 op = get32s ();
3630 mask = 0xffffffff;
3632 else
3634 mask = 0xffffffff;
3635 op = get16 ();
3636 if ((op & 0x8000) != 0)
3637 op -= 0x10000;
3639 used_prefixes |= (prefixes & PREFIX_DATA);
3640 break;
3641 case w_mode:
3642 op = get16 ();
3643 mask = 0xffffffff;
3644 if ((op & 0x8000) != 0)
3645 op -= 0x10000;
3646 break;
3647 default:
3648 oappend (INTERNAL_DISASSEMBLER_ERROR);
3649 return;
3652 scratchbuf[0] = '$';
3653 print_operand_value (scratchbuf + 1, 1, op);
3654 oappend (scratchbuf + intel_syntax);
3657 static void
3658 OP_J (int bytemode, int sizeflag)
3660 bfd_vma disp;
3661 bfd_vma mask = -1;
3663 switch (bytemode)
3665 case b_mode:
3666 FETCH_DATA (the_info, codep + 1);
3667 disp = *codep++;
3668 if ((disp & 0x80) != 0)
3669 disp -= 0x100;
3670 break;
3671 case v_mode:
3672 if (sizeflag & DFLAG)
3673 disp = get32s ();
3674 else
3676 disp = get16 ();
3677 /* For some reason, a data16 prefix on a jump instruction
3678 means that the pc is masked to 16 bits after the
3679 displacement is added! */
3680 mask = 0xffff;
3682 break;
3683 default:
3684 oappend (INTERNAL_DISASSEMBLER_ERROR);
3685 return;
3687 disp = (start_pc + codep - start_codep + disp) & mask;
3688 set_op (disp, 0);
3689 print_operand_value (scratchbuf, 1, disp);
3690 oappend (scratchbuf);
3693 static void
3694 OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3696 oappend (names_seg[reg]);
3699 static void
3700 OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
3702 int seg, offset;
3704 if (sizeflag & DFLAG)
3706 offset = get32 ();
3707 seg = get16 ();
3709 else
3711 offset = get16 ();
3712 seg = get16 ();
3714 used_prefixes |= (prefixes & PREFIX_DATA);
3715 if (intel_syntax)
3716 sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
3717 else
3718 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3719 oappend (scratchbuf);
3722 static void
3723 OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag)
3725 bfd_vma off;
3727 append_seg ();
3729 if ((sizeflag & AFLAG) || mode_64bit)
3730 off = get32 ();
3731 else
3732 off = get16 ();
3734 if (intel_syntax)
3736 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3737 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3739 oappend (names_seg[ds_reg - es_reg]);
3740 oappend (":");
3743 print_operand_value (scratchbuf, 1, off);
3744 oappend (scratchbuf);
3747 static void
3748 OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3750 bfd_vma off;
3752 if (!mode_64bit)
3754 OP_OFF (bytemode, sizeflag);
3755 return;
3758 append_seg ();
3760 off = get64 ();
3762 if (intel_syntax)
3764 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3765 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3767 oappend (names_seg[ds_reg - es_reg]);
3768 oappend (":");
3771 print_operand_value (scratchbuf, 1, off);
3772 oappend (scratchbuf);
3775 static void
3776 ptr_reg (int code, int sizeflag)
3778 const char *s;
3779 if (intel_syntax)
3780 oappend ("[");
3781 else
3782 oappend ("(");
3784 USED_REX (REX_MODE64);
3785 if (rex & REX_MODE64)
3787 if (!(sizeflag & AFLAG))
3788 s = names32[code - eAX_reg];
3789 else
3790 s = names64[code - eAX_reg];
3792 else if (sizeflag & AFLAG)
3793 s = names32[code - eAX_reg];
3794 else
3795 s = names16[code - eAX_reg];
3796 oappend (s);
3797 if (intel_syntax)
3798 oappend ("]");
3799 else
3800 oappend (")");
3803 static void
3804 OP_ESreg (int code, int sizeflag)
3806 oappend ("%es:" + intel_syntax);
3807 ptr_reg (code, sizeflag);
3810 static void
3811 OP_DSreg (int code, int sizeflag)
3813 if ((prefixes
3814 & (PREFIX_CS
3815 | PREFIX_DS
3816 | PREFIX_SS
3817 | PREFIX_ES
3818 | PREFIX_FS
3819 | PREFIX_GS)) == 0)
3820 prefixes |= PREFIX_DS;
3821 append_seg ();
3822 ptr_reg (code, sizeflag);
3825 static void
3826 OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3828 int add = 0;
3829 USED_REX (REX_EXTX);
3830 if (rex & REX_EXTX)
3831 add = 8;
3832 sprintf (scratchbuf, "%%cr%d", reg + add);
3833 oappend (scratchbuf + intel_syntax);
3836 static void
3837 OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3839 int add = 0;
3840 USED_REX (REX_EXTX);
3841 if (rex & REX_EXTX)
3842 add = 8;
3843 if (intel_syntax)
3844 sprintf (scratchbuf, "db%d", reg + add);
3845 else
3846 sprintf (scratchbuf, "%%db%d", reg + add);
3847 oappend (scratchbuf);
3850 static void
3851 OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3853 sprintf (scratchbuf, "%%tr%d", reg);
3854 oappend (scratchbuf + intel_syntax);
3857 static void
3858 OP_Rd (int bytemode, int sizeflag)
3860 if (mod == 3)
3861 OP_E (bytemode, sizeflag);
3862 else
3863 BadOp ();
3866 static void
3867 OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3869 int add = 0;
3870 USED_REX (REX_EXTX);
3871 if (rex & REX_EXTX)
3872 add = 8;
3873 used_prefixes |= (prefixes & PREFIX_DATA);
3874 if (prefixes & PREFIX_DATA)
3875 sprintf (scratchbuf, "%%xmm%d", reg + add);
3876 else
3877 sprintf (scratchbuf, "%%mm%d", reg + add);
3878 oappend (scratchbuf + intel_syntax);
3881 static void
3882 OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3884 int add = 0;
3885 USED_REX (REX_EXTX);
3886 if (rex & REX_EXTX)
3887 add = 8;
3888 sprintf (scratchbuf, "%%xmm%d", reg + add);
3889 oappend (scratchbuf + intel_syntax);
3892 static void
3893 OP_EM (int bytemode, int sizeflag)
3895 int add = 0;
3896 if (mod != 3)
3898 OP_E (bytemode, sizeflag);
3899 return;
3901 USED_REX (REX_EXTZ);
3902 if (rex & REX_EXTZ)
3903 add = 8;
3905 /* Skip mod/rm byte. */
3906 MODRM_CHECK;
3907 codep++;
3908 used_prefixes |= (prefixes & PREFIX_DATA);
3909 if (prefixes & PREFIX_DATA)
3910 sprintf (scratchbuf, "%%xmm%d", rm + add);
3911 else
3912 sprintf (scratchbuf, "%%mm%d", rm + add);
3913 oappend (scratchbuf + intel_syntax);
3916 static void
3917 OP_EX (int bytemode, int sizeflag)
3919 int add = 0;
3920 if (mod != 3)
3922 OP_E (bytemode, sizeflag);
3923 return;
3925 USED_REX (REX_EXTZ);
3926 if (rex & REX_EXTZ)
3927 add = 8;
3929 /* Skip mod/rm byte. */
3930 MODRM_CHECK;
3931 codep++;
3932 sprintf (scratchbuf, "%%xmm%d", rm + add);
3933 oappend (scratchbuf + intel_syntax);
3936 static void
3937 OP_MS (int bytemode, int sizeflag)
3939 if (mod == 3)
3940 OP_EM (bytemode, sizeflag);
3941 else
3942 BadOp ();
3945 static void
3946 OP_XS (int bytemode, int sizeflag)
3948 if (mod == 3)
3949 OP_EX (bytemode, sizeflag);
3950 else
3951 BadOp ();
3954 static void
3955 OP_M (int bytemode, int sizeflag)
3957 if (mod == 3)
3958 BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
3959 else
3960 OP_E (bytemode, sizeflag);
3963 static void
3964 OP_0f07 (int bytemode, int sizeflag)
3966 if (mod != 3 || rm != 0)
3967 BadOp ();
3968 else
3969 OP_E (bytemode, sizeflag);
3972 static void
3973 OP_0fae (int bytemode, int sizeflag)
3975 if (mod == 3)
3977 if (reg == 7)
3978 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
3980 if (reg < 5 || rm != 0)
3982 BadOp (); /* bad sfence, mfence, or lfence */
3983 return;
3986 else if (reg != 7)
3988 BadOp (); /* bad clflush */
3989 return;
3992 OP_E (bytemode, sizeflag);
3995 static void
3996 NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3998 /* NOP with REPZ prefix is called PAUSE. */
3999 if (prefixes == PREFIX_REPZ)
4000 strcpy (obuf, "pause");
4003 static const char *const Suffix3DNow[] = {
4004 /* 00 */ NULL, NULL, NULL, NULL,
4005 /* 04 */ NULL, NULL, NULL, NULL,
4006 /* 08 */ NULL, NULL, NULL, NULL,
4007 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
4008 /* 10 */ NULL, NULL, NULL, NULL,
4009 /* 14 */ NULL, NULL, NULL, NULL,
4010 /* 18 */ NULL, NULL, NULL, NULL,
4011 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
4012 /* 20 */ NULL, NULL, NULL, NULL,
4013 /* 24 */ NULL, NULL, NULL, NULL,
4014 /* 28 */ NULL, NULL, NULL, NULL,
4015 /* 2C */ NULL, NULL, NULL, NULL,
4016 /* 30 */ NULL, NULL, NULL, NULL,
4017 /* 34 */ NULL, NULL, NULL, NULL,
4018 /* 38 */ NULL, NULL, NULL, NULL,
4019 /* 3C */ NULL, NULL, NULL, NULL,
4020 /* 40 */ NULL, NULL, NULL, NULL,
4021 /* 44 */ NULL, NULL, NULL, NULL,
4022 /* 48 */ NULL, NULL, NULL, NULL,
4023 /* 4C */ NULL, NULL, NULL, NULL,
4024 /* 50 */ NULL, NULL, NULL, NULL,
4025 /* 54 */ NULL, NULL, NULL, NULL,
4026 /* 58 */ NULL, NULL, NULL, NULL,
4027 /* 5C */ NULL, NULL, NULL, NULL,
4028 /* 60 */ NULL, NULL, NULL, NULL,
4029 /* 64 */ NULL, NULL, NULL, NULL,
4030 /* 68 */ NULL, NULL, NULL, NULL,
4031 /* 6C */ NULL, NULL, NULL, NULL,
4032 /* 70 */ NULL, NULL, NULL, NULL,
4033 /* 74 */ NULL, NULL, NULL, NULL,
4034 /* 78 */ NULL, NULL, NULL, NULL,
4035 /* 7C */ NULL, NULL, NULL, NULL,
4036 /* 80 */ NULL, NULL, NULL, NULL,
4037 /* 84 */ NULL, NULL, NULL, NULL,
4038 /* 88 */ NULL, NULL, "pfnacc", NULL,
4039 /* 8C */ NULL, NULL, "pfpnacc", NULL,
4040 /* 90 */ "pfcmpge", NULL, NULL, NULL,
4041 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
4042 /* 98 */ NULL, NULL, "pfsub", NULL,
4043 /* 9C */ NULL, NULL, "pfadd", NULL,
4044 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
4045 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
4046 /* A8 */ NULL, NULL, "pfsubr", NULL,
4047 /* AC */ NULL, NULL, "pfacc", NULL,
4048 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
4049 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
4050 /* B8 */ NULL, NULL, NULL, "pswapd",
4051 /* BC */ NULL, NULL, NULL, "pavgusb",
4052 /* C0 */ NULL, NULL, NULL, NULL,
4053 /* C4 */ NULL, NULL, NULL, NULL,
4054 /* C8 */ NULL, NULL, NULL, NULL,
4055 /* CC */ NULL, NULL, NULL, NULL,
4056 /* D0 */ NULL, NULL, NULL, NULL,
4057 /* D4 */ NULL, NULL, NULL, NULL,
4058 /* D8 */ NULL, NULL, NULL, NULL,
4059 /* DC */ NULL, NULL, NULL, NULL,
4060 /* E0 */ NULL, NULL, NULL, NULL,
4061 /* E4 */ NULL, NULL, NULL, NULL,
4062 /* E8 */ NULL, NULL, NULL, NULL,
4063 /* EC */ NULL, NULL, NULL, NULL,
4064 /* F0 */ NULL, NULL, NULL, NULL,
4065 /* F4 */ NULL, NULL, NULL, NULL,
4066 /* F8 */ NULL, NULL, NULL, NULL,
4067 /* FC */ NULL, NULL, NULL, NULL,
4070 static void
4071 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4073 const char *mnemonic;
4075 FETCH_DATA (the_info, codep + 1);
4076 /* AMD 3DNow! instructions are specified by an opcode suffix in the
4077 place where an 8-bit immediate would normally go. ie. the last
4078 byte of the instruction. */
4079 obufp = obuf + strlen (obuf);
4080 mnemonic = Suffix3DNow[*codep++ & 0xff];
4081 if (mnemonic)
4082 oappend (mnemonic);
4083 else
4085 /* Since a variable sized modrm/sib chunk is between the start
4086 of the opcode (0x0f0f) and the opcode suffix, we need to do
4087 all the modrm processing first, and don't know until now that
4088 we have a bad opcode. This necessitates some cleaning up. */
4089 op1out[0] = '\0';
4090 op2out[0] = '\0';
4091 BadOp ();
4095 static const char *simd_cmp_op[] = {
4096 "eq",
4097 "lt",
4098 "le",
4099 "unord",
4100 "neq",
4101 "nlt",
4102 "nle",
4103 "ord"
4106 static void
4107 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4109 unsigned int cmp_type;
4111 FETCH_DATA (the_info, codep + 1);
4112 obufp = obuf + strlen (obuf);
4113 cmp_type = *codep++ & 0xff;
4114 if (cmp_type < 8)
4116 char suffix1 = 'p', suffix2 = 's';
4117 used_prefixes |= (prefixes & PREFIX_REPZ);
4118 if (prefixes & PREFIX_REPZ)
4119 suffix1 = 's';
4120 else
4122 used_prefixes |= (prefixes & PREFIX_DATA);
4123 if (prefixes & PREFIX_DATA)
4124 suffix2 = 'd';
4125 else
4127 used_prefixes |= (prefixes & PREFIX_REPNZ);
4128 if (prefixes & PREFIX_REPNZ)
4129 suffix1 = 's', suffix2 = 'd';
4132 sprintf (scratchbuf, "cmp%s%c%c",
4133 simd_cmp_op[cmp_type], suffix1, suffix2);
4134 used_prefixes |= (prefixes & PREFIX_REPZ);
4135 oappend (scratchbuf);
4137 else
4139 /* We have a bad extension byte. Clean up. */
4140 op1out[0] = '\0';
4141 op2out[0] = '\0';
4142 BadOp ();
4146 static void
4147 SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
4149 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
4150 forms of these instructions. */
4151 if (mod == 3)
4153 char *p = obuf + strlen (obuf);
4154 *(p + 1) = '\0';
4155 *p = *(p - 1);
4156 *(p - 1) = *(p - 2);
4157 *(p - 2) = *(p - 3);
4158 *(p - 3) = extrachar;
4162 static void
4163 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
4165 if (mod == 3 && reg == 1)
4167 char *p = obuf + strlen (obuf);
4169 /* Override "sidt". */
4170 if (rm)
4172 /* mwait %eax,%ecx */
4173 strcpy (p - 4, "mwait %eax,%ecx");
4175 else
4177 /* monitor %eax,%ecx,%edx" */
4178 strcpy (p - 4, "monitor %eax,%ecx,%edx");
4181 codep++;
4183 else
4184 OP_E (0, sizeflag);
4187 static void
4188 INVLPG_Fixup (int bytemode, int sizeflag)
4190 if (*codep == 0xf8)
4192 char *p = obuf + strlen (obuf);
4194 /* Override "invlpg". */
4195 strcpy (p - 6, "swapgs");
4196 codep++;
4198 else
4199 OP_E (bytemode, sizeflag);
4202 static void
4203 BadOp (void)
4205 /* Throw away prefixes and 1st. opcode byte. */
4206 codep = insn_codep + 1;
4207 oappend ("(bad)");