* configure.in (bfin-*-*): Support bfin.
[binutils.git] / opcodes / i386-dis.c
bloba3b205a49d8a77726561cc0ef44cc02e852bf941
1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
21 /* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
22 July 1988
23 modified by John Hassey (hassey@dg-rtp.dg.com)
24 x86-64 support added by Jan Hubicka (jh@suse.cz)
25 VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
27 /* The main tables describing the instructions is essentially a copy
28 of the "Opcode Map" chapter (Appendix A) of the Intel 80386
29 Programmers Manual. Usually, there is a capital letter, followed
30 by a small letter. The capital letter tell the addressing mode,
31 and the small letter tells about the operand size. Refer to
32 the Intel manual for details. */
34 #include "dis-asm.h"
35 #include "sysdep.h"
36 #include "opintl.h"
38 #define MAXLEN 20
40 #include <setjmp.h>
42 #ifndef UNIXWARE_COMPAT
43 /* Set non-zero for broken, compatible instructions. Set to zero for
44 non-broken opcodes. */
45 #define UNIXWARE_COMPAT 1
46 #endif
48 static int fetch_data (struct disassemble_info *, bfd_byte *);
49 static void ckprefix (void);
50 static const char *prefix_name (int, int);
51 static int print_insn (bfd_vma, disassemble_info *);
52 static void dofloat (int);
53 static void OP_ST (int, int);
54 static void OP_STi (int, int);
55 static int putop (const char *, int);
56 static void oappend (const char *);
57 static void append_seg (void);
58 static void OP_indirE (int, int);
59 static void print_operand_value (char *, int, bfd_vma);
60 static void OP_E (int, int);
61 static void OP_G (int, int);
62 static bfd_vma get64 (void);
63 static bfd_signed_vma get32 (void);
64 static bfd_signed_vma get32s (void);
65 static int get16 (void);
66 static void set_op (bfd_vma, int);
67 static void OP_REG (int, int);
68 static void OP_IMREG (int, int);
69 static void OP_I (int, int);
70 static void OP_I64 (int, int);
71 static void OP_sI (int, int);
72 static void OP_J (int, int);
73 static void OP_SEG (int, int);
74 static void OP_DIR (int, int);
75 static void OP_OFF (int, int);
76 static void OP_OFF64 (int, int);
77 static void ptr_reg (int, int);
78 static void OP_ESreg (int, int);
79 static void OP_DSreg (int, int);
80 static void OP_C (int, int);
81 static void OP_D (int, int);
82 static void OP_T (int, int);
83 static void OP_Rd (int, int);
84 static void OP_MMX (int, int);
85 static void OP_XMM (int, int);
86 static void OP_EM (int, int);
87 static void OP_EX (int, int);
88 static void OP_MS (int, int);
89 static void OP_XS (int, int);
90 static void OP_M (int, int);
91 static void OP_VMX (int, int);
92 static void OP_0fae (int, int);
93 static void OP_0f07 (int, int);
94 static void NOP_Fixup (int, int);
95 static void OP_3DNowSuffix (int, int);
96 static void OP_SIMD_Suffix (int, int);
97 static void SIMD_Fixup (int, int);
98 static void PNI_Fixup (int, int);
99 static void SVME_Fixup (int, int);
100 static void INVLPG_Fixup (int, int);
101 static void BadOp (void);
102 static void SEG_Fixup (int, int);
103 static void VMX_Fixup (int, int);
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 Eq OP_E, q_mode
201 #define Edq OP_E, dq_mode
202 #define Edqw OP_E, dqw_mode
203 #define indirEv OP_indirE, stack_v_mode
204 #define indirEp OP_indirE, f_mode
205 #define stackEv OP_E, stack_v_mode
206 #define Em OP_E, m_mode
207 #define Ew OP_E, w_mode
208 #define Ma OP_E, v_mode
209 #define M OP_M, 0 /* lea, lgdt, etc. */
210 #define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */
211 #define Gb OP_G, b_mode
212 #define Gv OP_G, v_mode
213 #define Gd OP_G, d_mode
214 #define Gdq OP_G, dq_mode
215 #define Gm OP_G, m_mode
216 #define Gw OP_G, w_mode
217 #define Rd OP_Rd, d_mode
218 #define Rm OP_Rd, m_mode
219 #define Ib OP_I, b_mode
220 #define sIb OP_sI, b_mode /* sign extened byte */
221 #define Iv OP_I, v_mode
222 #define Iq OP_I, q_mode
223 #define Iv64 OP_I64, v_mode
224 #define Iw OP_I, w_mode
225 #define I1 OP_I, const_1_mode
226 #define Jb OP_J, b_mode
227 #define Jv OP_J, v_mode
228 #define Cm OP_C, m_mode
229 #define Dm OP_D, m_mode
230 #define Td OP_T, d_mode
231 #define Sv SEG_Fixup, v_mode
233 #define RMeAX OP_REG, eAX_reg
234 #define RMeBX OP_REG, eBX_reg
235 #define RMeCX OP_REG, eCX_reg
236 #define RMeDX OP_REG, eDX_reg
237 #define RMeSP OP_REG, eSP_reg
238 #define RMeBP OP_REG, eBP_reg
239 #define RMeSI OP_REG, eSI_reg
240 #define RMeDI OP_REG, eDI_reg
241 #define RMrAX OP_REG, rAX_reg
242 #define RMrBX OP_REG, rBX_reg
243 #define RMrCX OP_REG, rCX_reg
244 #define RMrDX OP_REG, rDX_reg
245 #define RMrSP OP_REG, rSP_reg
246 #define RMrBP OP_REG, rBP_reg
247 #define RMrSI OP_REG, rSI_reg
248 #define RMrDI OP_REG, rDI_reg
249 #define RMAL OP_REG, al_reg
250 #define RMAL OP_REG, al_reg
251 #define RMCL OP_REG, cl_reg
252 #define RMDL OP_REG, dl_reg
253 #define RMBL OP_REG, bl_reg
254 #define RMAH OP_REG, ah_reg
255 #define RMCH OP_REG, ch_reg
256 #define RMDH OP_REG, dh_reg
257 #define RMBH OP_REG, bh_reg
258 #define RMAX OP_REG, ax_reg
259 #define RMDX OP_REG, dx_reg
261 #define eAX OP_IMREG, eAX_reg
262 #define eBX OP_IMREG, eBX_reg
263 #define eCX OP_IMREG, eCX_reg
264 #define eDX OP_IMREG, eDX_reg
265 #define eSP OP_IMREG, eSP_reg
266 #define eBP OP_IMREG, eBP_reg
267 #define eSI OP_IMREG, eSI_reg
268 #define eDI OP_IMREG, eDI_reg
269 #define AL OP_IMREG, al_reg
270 #define AL OP_IMREG, al_reg
271 #define CL OP_IMREG, cl_reg
272 #define DL OP_IMREG, dl_reg
273 #define BL OP_IMREG, bl_reg
274 #define AH OP_IMREG, ah_reg
275 #define CH OP_IMREG, ch_reg
276 #define DH OP_IMREG, dh_reg
277 #define BH OP_IMREG, bh_reg
278 #define AX OP_IMREG, ax_reg
279 #define DX OP_IMREG, dx_reg
280 #define indirDX OP_IMREG, indir_dx_reg
282 #define Sw OP_SEG, w_mode
283 #define Ap OP_DIR, 0
284 #define Ob OP_OFF64, b_mode
285 #define Ov OP_OFF64, v_mode
286 #define Xb OP_DSreg, eSI_reg
287 #define Xv OP_DSreg, eSI_reg
288 #define Yb OP_ESreg, eDI_reg
289 #define Yv OP_ESreg, eDI_reg
290 #define DSBX OP_DSreg, eBX_reg
292 #define es OP_REG, es_reg
293 #define ss OP_REG, ss_reg
294 #define cs OP_REG, cs_reg
295 #define ds OP_REG, ds_reg
296 #define fs OP_REG, fs_reg
297 #define gs OP_REG, gs_reg
299 #define MX OP_MMX, 0
300 #define XM OP_XMM, 0
301 #define EM OP_EM, v_mode
302 #define EX OP_EX, v_mode
303 #define MS OP_MS, v_mode
304 #define XS OP_XS, v_mode
305 #define VM OP_VMX, q_mode
306 #define OPSUF OP_3DNowSuffix, 0
307 #define OPSIMD OP_SIMD_Suffix, 0
309 #define cond_jump_flag NULL, cond_jump_mode
310 #define loop_jcxz_flag NULL, loop_jcxz_mode
312 /* bits in sizeflag */
313 #define SUFFIX_ALWAYS 4
314 #define AFLAG 2
315 #define DFLAG 1
317 #define b_mode 1 /* byte operand */
318 #define v_mode 2 /* operand size depends on prefixes */
319 #define w_mode 3 /* word operand */
320 #define d_mode 4 /* double word operand */
321 #define q_mode 5 /* quad word operand */
322 #define t_mode 6 /* ten-byte operand */
323 #define x_mode 7 /* 16-byte XMM operand */
324 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
325 #define cond_jump_mode 9
326 #define loop_jcxz_mode 10
327 #define dq_mode 11 /* operand size depends on REX prefixes. */
328 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
329 #define f_mode 13 /* 4- or 6-byte pointer operand */
330 #define const_1_mode 14
331 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
333 #define es_reg 100
334 #define cs_reg 101
335 #define ss_reg 102
336 #define ds_reg 103
337 #define fs_reg 104
338 #define gs_reg 105
340 #define eAX_reg 108
341 #define eCX_reg 109
342 #define eDX_reg 110
343 #define eBX_reg 111
344 #define eSP_reg 112
345 #define eBP_reg 113
346 #define eSI_reg 114
347 #define eDI_reg 115
349 #define al_reg 116
350 #define cl_reg 117
351 #define dl_reg 118
352 #define bl_reg 119
353 #define ah_reg 120
354 #define ch_reg 121
355 #define dh_reg 122
356 #define bh_reg 123
358 #define ax_reg 124
359 #define cx_reg 125
360 #define dx_reg 126
361 #define bx_reg 127
362 #define sp_reg 128
363 #define bp_reg 129
364 #define si_reg 130
365 #define di_reg 131
367 #define rAX_reg 132
368 #define rCX_reg 133
369 #define rDX_reg 134
370 #define rBX_reg 135
371 #define rSP_reg 136
372 #define rBP_reg 137
373 #define rSI_reg 138
374 #define rDI_reg 139
376 #define indir_dx_reg 150
378 #define FLOATCODE 1
379 #define USE_GROUPS 2
380 #define USE_PREFIX_USER_TABLE 3
381 #define X86_64_SPECIAL 4
383 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
385 #define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
386 #define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
387 #define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
388 #define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
389 #define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
390 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
391 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
392 #define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
393 #define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
394 #define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
395 #define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
396 #define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
397 #define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
398 #define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
399 #define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
400 #define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
401 #define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
402 #define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
403 #define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
404 #define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
405 #define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
406 #define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
407 #define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
408 #define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0
409 #define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0
411 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
412 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
413 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
414 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
415 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
416 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
417 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
418 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
419 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
420 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
421 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
422 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
423 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
424 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
425 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
426 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
427 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
428 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
429 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
430 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
431 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
432 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
433 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
434 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
435 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
436 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
437 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
438 #define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0
439 #define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0
440 #define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0
441 #define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0
442 #define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0
443 #define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0
445 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
447 typedef void (*op_rtn) (int bytemode, int sizeflag);
449 struct dis386 {
450 const char *name;
451 op_rtn op1;
452 int bytemode1;
453 op_rtn op2;
454 int bytemode2;
455 op_rtn op3;
456 int bytemode3;
459 /* Upper case letters in the instruction names here are macros.
460 'A' => print 'b' if no register operands or suffix_always is true
461 'B' => print 'b' if suffix_always is true
462 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
463 . size prefix
464 'E' => print 'e' if 32-bit form of jcxz
465 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
466 'H' => print ",pt" or ",pn" branch hint
467 'I' => honor following macro letter even in Intel mode (implemented only
468 . for some of the macro letters)
469 'J' => print 'l'
470 'L' => print 'l' if suffix_always is true
471 'N' => print 'n' if instruction has no wait "prefix"
472 'O' => print 'd', or 'o'
473 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
474 . or suffix_always is true. print 'q' if rex prefix is present.
475 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
476 . is true
477 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
478 'S' => print 'w', 'l' or 'q' if suffix_always is true
479 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
480 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
481 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
482 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
483 'X' => print 's', 'd' depending on data16 prefix (for XMM)
484 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
486 Many of the above letters print nothing in Intel mode. See "putop"
487 for the details.
489 Braces '{' and '}', and vertical bars '|', indicate alternative
490 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
491 modes. In cases where there are only two alternatives, the X86_64
492 instruction is reserved, and "(bad)" is printed.
495 static const struct dis386 dis386[] = {
496 /* 00 */
497 { "addB", Eb, Gb, XX },
498 { "addS", Ev, Gv, XX },
499 { "addB", Gb, Eb, XX },
500 { "addS", Gv, Ev, XX },
501 { "addB", AL, Ib, XX },
502 { "addS", eAX, Iv, XX },
503 { "push{T|}", es, XX, XX },
504 { "pop{T|}", es, XX, XX },
505 /* 08 */
506 { "orB", Eb, Gb, XX },
507 { "orS", Ev, Gv, XX },
508 { "orB", Gb, Eb, XX },
509 { "orS", Gv, Ev, XX },
510 { "orB", AL, Ib, XX },
511 { "orS", eAX, Iv, XX },
512 { "push{T|}", cs, XX, XX },
513 { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */
514 /* 10 */
515 { "adcB", Eb, Gb, XX },
516 { "adcS", Ev, Gv, XX },
517 { "adcB", Gb, Eb, XX },
518 { "adcS", Gv, Ev, XX },
519 { "adcB", AL, Ib, XX },
520 { "adcS", eAX, Iv, XX },
521 { "push{T|}", ss, XX, XX },
522 { "pop{T|}", ss, XX, XX },
523 /* 18 */
524 { "sbbB", Eb, Gb, XX },
525 { "sbbS", Ev, Gv, XX },
526 { "sbbB", Gb, Eb, XX },
527 { "sbbS", Gv, Ev, XX },
528 { "sbbB", AL, Ib, XX },
529 { "sbbS", eAX, Iv, XX },
530 { "push{T|}", ds, XX, XX },
531 { "pop{T|}", ds, XX, XX },
532 /* 20 */
533 { "andB", Eb, Gb, XX },
534 { "andS", Ev, Gv, XX },
535 { "andB", Gb, Eb, XX },
536 { "andS", Gv, Ev, XX },
537 { "andB", AL, Ib, XX },
538 { "andS", eAX, Iv, XX },
539 { "(bad)", XX, XX, XX }, /* SEG ES prefix */
540 { "daa{|}", XX, XX, XX },
541 /* 28 */
542 { "subB", Eb, Gb, XX },
543 { "subS", Ev, Gv, XX },
544 { "subB", Gb, Eb, XX },
545 { "subS", Gv, Ev, XX },
546 { "subB", AL, Ib, XX },
547 { "subS", eAX, Iv, XX },
548 { "(bad)", XX, XX, XX }, /* SEG CS prefix */
549 { "das{|}", XX, XX, XX },
550 /* 30 */
551 { "xorB", Eb, Gb, XX },
552 { "xorS", Ev, Gv, XX },
553 { "xorB", Gb, Eb, XX },
554 { "xorS", Gv, Ev, XX },
555 { "xorB", AL, Ib, XX },
556 { "xorS", eAX, Iv, XX },
557 { "(bad)", XX, XX, XX }, /* SEG SS prefix */
558 { "aaa{|}", XX, XX, XX },
559 /* 38 */
560 { "cmpB", Eb, Gb, XX },
561 { "cmpS", Ev, Gv, XX },
562 { "cmpB", Gb, Eb, XX },
563 { "cmpS", Gv, Ev, XX },
564 { "cmpB", AL, Ib, XX },
565 { "cmpS", eAX, Iv, XX },
566 { "(bad)", XX, XX, XX }, /* SEG DS prefix */
567 { "aas{|}", XX, XX, XX },
568 /* 40 */
569 { "inc{S|}", RMeAX, XX, XX },
570 { "inc{S|}", RMeCX, XX, XX },
571 { "inc{S|}", RMeDX, XX, XX },
572 { "inc{S|}", RMeBX, XX, XX },
573 { "inc{S|}", RMeSP, XX, XX },
574 { "inc{S|}", RMeBP, XX, XX },
575 { "inc{S|}", RMeSI, XX, XX },
576 { "inc{S|}", RMeDI, XX, XX },
577 /* 48 */
578 { "dec{S|}", RMeAX, XX, XX },
579 { "dec{S|}", RMeCX, XX, XX },
580 { "dec{S|}", RMeDX, XX, XX },
581 { "dec{S|}", RMeBX, XX, XX },
582 { "dec{S|}", RMeSP, XX, XX },
583 { "dec{S|}", RMeBP, XX, XX },
584 { "dec{S|}", RMeSI, XX, XX },
585 { "dec{S|}", RMeDI, XX, XX },
586 /* 50 */
587 { "pushV", RMrAX, XX, XX },
588 { "pushV", RMrCX, XX, XX },
589 { "pushV", RMrDX, XX, XX },
590 { "pushV", RMrBX, XX, XX },
591 { "pushV", RMrSP, XX, XX },
592 { "pushV", RMrBP, XX, XX },
593 { "pushV", RMrSI, XX, XX },
594 { "pushV", RMrDI, XX, XX },
595 /* 58 */
596 { "popV", RMrAX, XX, XX },
597 { "popV", RMrCX, XX, XX },
598 { "popV", RMrDX, XX, XX },
599 { "popV", RMrBX, XX, XX },
600 { "popV", RMrSP, XX, XX },
601 { "popV", RMrBP, XX, XX },
602 { "popV", RMrSI, XX, XX },
603 { "popV", RMrDI, XX, XX },
604 /* 60 */
605 { "pusha{P|}", XX, XX, XX },
606 { "popa{P|}", XX, XX, XX },
607 { "bound{S|}", Gv, Ma, XX },
608 { X86_64_0 },
609 { "(bad)", XX, XX, XX }, /* seg fs */
610 { "(bad)", XX, XX, XX }, /* seg gs */
611 { "(bad)", XX, XX, XX }, /* op size prefix */
612 { "(bad)", XX, XX, XX }, /* adr size prefix */
613 /* 68 */
614 { "pushT", Iq, XX, XX },
615 { "imulS", Gv, Ev, Iv },
616 { "pushT", sIb, XX, XX },
617 { "imulS", Gv, Ev, sIb },
618 { "ins{b||b|}", Yb, indirDX, XX },
619 { "ins{R||R|}", Yv, indirDX, XX },
620 { "outs{b||b|}", indirDX, Xb, XX },
621 { "outs{R||R|}", indirDX, Xv, XX },
622 /* 70 */
623 { "joH", Jb, XX, cond_jump_flag },
624 { "jnoH", Jb, XX, cond_jump_flag },
625 { "jbH", Jb, XX, cond_jump_flag },
626 { "jaeH", Jb, XX, cond_jump_flag },
627 { "jeH", Jb, XX, cond_jump_flag },
628 { "jneH", Jb, XX, cond_jump_flag },
629 { "jbeH", Jb, XX, cond_jump_flag },
630 { "jaH", Jb, XX, cond_jump_flag },
631 /* 78 */
632 { "jsH", Jb, XX, cond_jump_flag },
633 { "jnsH", Jb, XX, cond_jump_flag },
634 { "jpH", Jb, XX, cond_jump_flag },
635 { "jnpH", Jb, XX, cond_jump_flag },
636 { "jlH", Jb, XX, cond_jump_flag },
637 { "jgeH", Jb, XX, cond_jump_flag },
638 { "jleH", Jb, XX, cond_jump_flag },
639 { "jgH", Jb, XX, cond_jump_flag },
640 /* 80 */
641 { GRP1b },
642 { GRP1S },
643 { "(bad)", XX, XX, XX },
644 { GRP1Ss },
645 { "testB", Eb, Gb, XX },
646 { "testS", Ev, Gv, XX },
647 { "xchgB", Eb, Gb, XX },
648 { "xchgS", Ev, Gv, XX },
649 /* 88 */
650 { "movB", Eb, Gb, XX },
651 { "movS", Ev, Gv, XX },
652 { "movB", Gb, Eb, XX },
653 { "movS", Gv, Ev, XX },
654 { "movQ", Sv, Sw, XX },
655 { "leaS", Gv, M, XX },
656 { "movQ", Sw, Sv, XX },
657 { "popU", stackEv, XX, XX },
658 /* 90 */
659 { "nop", NOP_Fixup, 0, XX, XX },
660 { "xchgS", RMeCX, eAX, XX },
661 { "xchgS", RMeDX, eAX, XX },
662 { "xchgS", RMeBX, eAX, XX },
663 { "xchgS", RMeSP, eAX, XX },
664 { "xchgS", RMeBP, eAX, XX },
665 { "xchgS", RMeSI, eAX, XX },
666 { "xchgS", RMeDI, eAX, XX },
667 /* 98 */
668 { "cW{tR||tR|}", XX, XX, XX },
669 { "cR{tO||tO|}", XX, XX, XX },
670 { "Jcall{T|}", Ap, XX, XX },
671 { "(bad)", XX, XX, XX }, /* fwait */
672 { "pushfT", XX, XX, XX },
673 { "popfT", XX, XX, XX },
674 { "sahf{|}", XX, XX, XX },
675 { "lahf{|}", XX, XX, XX },
676 /* a0 */
677 { "movB", AL, Ob, XX },
678 { "movS", eAX, Ov, XX },
679 { "movB", Ob, AL, XX },
680 { "movS", Ov, eAX, XX },
681 { "movs{b||b|}", Yb, Xb, XX },
682 { "movs{R||R|}", Yv, Xv, XX },
683 { "cmps{b||b|}", Xb, Yb, XX },
684 { "cmps{R||R|}", Xv, Yv, XX },
685 /* a8 */
686 { "testB", AL, Ib, XX },
687 { "testS", eAX, Iv, XX },
688 { "stosB", Yb, AL, XX },
689 { "stosS", Yv, eAX, XX },
690 { "lodsB", AL, Xb, XX },
691 { "lodsS", eAX, Xv, XX },
692 { "scasB", AL, Yb, XX },
693 { "scasS", eAX, Yv, XX },
694 /* b0 */
695 { "movB", RMAL, Ib, XX },
696 { "movB", RMCL, Ib, XX },
697 { "movB", RMDL, Ib, XX },
698 { "movB", RMBL, Ib, XX },
699 { "movB", RMAH, Ib, XX },
700 { "movB", RMCH, Ib, XX },
701 { "movB", RMDH, Ib, XX },
702 { "movB", RMBH, Ib, XX },
703 /* b8 */
704 { "movS", RMeAX, Iv64, XX },
705 { "movS", RMeCX, Iv64, XX },
706 { "movS", RMeDX, Iv64, XX },
707 { "movS", RMeBX, Iv64, XX },
708 { "movS", RMeSP, Iv64, XX },
709 { "movS", RMeBP, Iv64, XX },
710 { "movS", RMeSI, Iv64, XX },
711 { "movS", RMeDI, Iv64, XX },
712 /* c0 */
713 { GRP2b },
714 { GRP2S },
715 { "retT", Iw, XX, XX },
716 { "retT", XX, XX, XX },
717 { "les{S|}", Gv, Mp, XX },
718 { "ldsS", Gv, Mp, XX },
719 { "movA", Eb, Ib, XX },
720 { "movQ", Ev, Iv, XX },
721 /* c8 */
722 { "enterT", Iw, Ib, XX },
723 { "leaveT", XX, XX, XX },
724 { "lretP", Iw, XX, XX },
725 { "lretP", XX, XX, XX },
726 { "int3", XX, XX, XX },
727 { "int", Ib, XX, XX },
728 { "into{|}", XX, XX, XX },
729 { "iretP", XX, XX, XX },
730 /* d0 */
731 { GRP2b_one },
732 { GRP2S_one },
733 { GRP2b_cl },
734 { GRP2S_cl },
735 { "aam{|}", sIb, XX, XX },
736 { "aad{|}", sIb, XX, XX },
737 { "(bad)", XX, XX, XX },
738 { "xlat", DSBX, XX, XX },
739 /* d8 */
740 { FLOAT },
741 { FLOAT },
742 { FLOAT },
743 { FLOAT },
744 { FLOAT },
745 { FLOAT },
746 { FLOAT },
747 { FLOAT },
748 /* e0 */
749 { "loopneFH", Jb, XX, loop_jcxz_flag },
750 { "loopeFH", Jb, XX, loop_jcxz_flag },
751 { "loopFH", Jb, XX, loop_jcxz_flag },
752 { "jEcxzH", Jb, XX, loop_jcxz_flag },
753 { "inB", AL, Ib, XX },
754 { "inS", eAX, Ib, XX },
755 { "outB", Ib, AL, XX },
756 { "outS", Ib, eAX, XX },
757 /* e8 */
758 { "callT", Jv, XX, XX },
759 { "jmpT", Jv, XX, XX },
760 { "Jjmp{T|}", Ap, XX, XX },
761 { "jmp", Jb, XX, XX },
762 { "inB", AL, indirDX, XX },
763 { "inS", eAX, indirDX, XX },
764 { "outB", indirDX, AL, XX },
765 { "outS", indirDX, eAX, XX },
766 /* f0 */
767 { "(bad)", XX, XX, XX }, /* lock prefix */
768 { "icebp", XX, XX, XX },
769 { "(bad)", XX, XX, XX }, /* repne */
770 { "(bad)", XX, XX, XX }, /* repz */
771 { "hlt", XX, XX, XX },
772 { "cmc", XX, XX, XX },
773 { GRP3b },
774 { GRP3S },
775 /* f8 */
776 { "clc", XX, XX, XX },
777 { "stc", XX, XX, XX },
778 { "cli", XX, XX, XX },
779 { "sti", XX, XX, XX },
780 { "cld", XX, XX, XX },
781 { "std", XX, XX, XX },
782 { GRP4 },
783 { GRP5 },
786 static const struct dis386 dis386_twobyte[] = {
787 /* 00 */
788 { GRP6 },
789 { GRP7 },
790 { "larS", Gv, Ew, XX },
791 { "lslS", Gv, Ew, XX },
792 { "(bad)", XX, XX, XX },
793 { "syscall", XX, XX, XX },
794 { "clts", XX, XX, XX },
795 { "sysretP", XX, XX, XX },
796 /* 08 */
797 { "invd", XX, XX, XX },
798 { "wbinvd", XX, XX, XX },
799 { "(bad)", XX, XX, XX },
800 { "ud2a", XX, XX, XX },
801 { "(bad)", XX, XX, XX },
802 { GRPAMD },
803 { "femms", XX, XX, XX },
804 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */
805 /* 10 */
806 { PREGRP8 },
807 { PREGRP9 },
808 { PREGRP30 },
809 { "movlpX", EX, XM, SIMD_Fixup, 'h' },
810 { "unpcklpX", XM, EX, XX },
811 { "unpckhpX", XM, EX, XX },
812 { PREGRP31 },
813 { "movhpX", EX, XM, SIMD_Fixup, 'l' },
814 /* 18 */
815 { GRP14 },
816 { "(bad)", XX, XX, XX },
817 { "(bad)", XX, XX, XX },
818 { "(bad)", XX, XX, XX },
819 { "(bad)", XX, XX, XX },
820 { "(bad)", XX, XX, XX },
821 { "(bad)", XX, XX, XX },
822 { "(bad)", XX, XX, XX },
823 /* 20 */
824 { "movL", Rm, Cm, XX },
825 { "movL", Rm, Dm, XX },
826 { "movL", Cm, Rm, XX },
827 { "movL", Dm, Rm, XX },
828 { "movL", Rd, Td, XX },
829 { "(bad)", XX, XX, XX },
830 { "movL", Td, Rd, XX },
831 { "(bad)", XX, XX, XX },
832 /* 28 */
833 { "movapX", XM, EX, XX },
834 { "movapX", EX, XM, XX },
835 { PREGRP2 },
836 { "movntpX", Ev, XM, XX },
837 { PREGRP4 },
838 { PREGRP3 },
839 { "ucomisX", XM,EX, XX },
840 { "comisX", XM,EX, XX },
841 /* 30 */
842 { "wrmsr", XX, XX, XX },
843 { "rdtsc", XX, XX, XX },
844 { "rdmsr", XX, XX, XX },
845 { "rdpmc", XX, XX, XX },
846 { "sysenter", XX, XX, XX },
847 { "sysexit", XX, XX, XX },
848 { "(bad)", XX, XX, XX },
849 { "(bad)", XX, XX, XX },
850 /* 38 */
851 { "(bad)", XX, XX, XX },
852 { "(bad)", XX, XX, XX },
853 { "(bad)", XX, XX, XX },
854 { "(bad)", XX, XX, XX },
855 { "(bad)", XX, XX, XX },
856 { "(bad)", XX, XX, XX },
857 { "(bad)", XX, XX, XX },
858 { "(bad)", XX, XX, XX },
859 /* 40 */
860 { "cmovo", Gv, Ev, XX },
861 { "cmovno", Gv, Ev, XX },
862 { "cmovb", Gv, Ev, XX },
863 { "cmovae", Gv, Ev, XX },
864 { "cmove", Gv, Ev, XX },
865 { "cmovne", Gv, Ev, XX },
866 { "cmovbe", Gv, Ev, XX },
867 { "cmova", Gv, Ev, XX },
868 /* 48 */
869 { "cmovs", Gv, Ev, XX },
870 { "cmovns", Gv, Ev, XX },
871 { "cmovp", Gv, Ev, XX },
872 { "cmovnp", Gv, Ev, XX },
873 { "cmovl", Gv, Ev, XX },
874 { "cmovge", Gv, Ev, XX },
875 { "cmovle", Gv, Ev, XX },
876 { "cmovg", Gv, Ev, XX },
877 /* 50 */
878 { "movmskpX", Gdq, XS, XX },
879 { PREGRP13 },
880 { PREGRP12 },
881 { PREGRP11 },
882 { "andpX", XM, EX, XX },
883 { "andnpX", XM, EX, XX },
884 { "orpX", XM, EX, XX },
885 { "xorpX", XM, EX, XX },
886 /* 58 */
887 { PREGRP0 },
888 { PREGRP10 },
889 { PREGRP17 },
890 { PREGRP16 },
891 { PREGRP14 },
892 { PREGRP7 },
893 { PREGRP5 },
894 { PREGRP6 },
895 /* 60 */
896 { "punpcklbw", MX, EM, XX },
897 { "punpcklwd", MX, EM, XX },
898 { "punpckldq", MX, EM, XX },
899 { "packsswb", MX, EM, XX },
900 { "pcmpgtb", MX, EM, XX },
901 { "pcmpgtw", MX, EM, XX },
902 { "pcmpgtd", MX, EM, XX },
903 { "packuswb", MX, EM, XX },
904 /* 68 */
905 { "punpckhbw", MX, EM, XX },
906 { "punpckhwd", MX, EM, XX },
907 { "punpckhdq", MX, EM, XX },
908 { "packssdw", MX, EM, XX },
909 { PREGRP26 },
910 { PREGRP24 },
911 { "movd", MX, Edq, XX },
912 { PREGRP19 },
913 /* 70 */
914 { PREGRP22 },
915 { GRP10 },
916 { GRP11 },
917 { GRP12 },
918 { "pcmpeqb", MX, EM, XX },
919 { "pcmpeqw", MX, EM, XX },
920 { "pcmpeqd", MX, EM, XX },
921 { "emms", XX, XX, XX },
922 /* 78 */
923 { "vmread", Em, Gm, XX },
924 { "vmwrite", Gm, Em, XX },
925 { "(bad)", XX, XX, XX },
926 { "(bad)", XX, XX, XX },
927 { PREGRP28 },
928 { PREGRP29 },
929 { PREGRP23 },
930 { PREGRP20 },
931 /* 80 */
932 { "joH", Jv, XX, cond_jump_flag },
933 { "jnoH", Jv, XX, cond_jump_flag },
934 { "jbH", Jv, XX, cond_jump_flag },
935 { "jaeH", Jv, XX, cond_jump_flag },
936 { "jeH", Jv, XX, cond_jump_flag },
937 { "jneH", Jv, XX, cond_jump_flag },
938 { "jbeH", Jv, XX, cond_jump_flag },
939 { "jaH", Jv, XX, cond_jump_flag },
940 /* 88 */
941 { "jsH", Jv, XX, cond_jump_flag },
942 { "jnsH", Jv, XX, cond_jump_flag },
943 { "jpH", Jv, XX, cond_jump_flag },
944 { "jnpH", Jv, XX, cond_jump_flag },
945 { "jlH", Jv, XX, cond_jump_flag },
946 { "jgeH", Jv, XX, cond_jump_flag },
947 { "jleH", Jv, XX, cond_jump_flag },
948 { "jgH", Jv, XX, cond_jump_flag },
949 /* 90 */
950 { "seto", Eb, XX, XX },
951 { "setno", Eb, XX, XX },
952 { "setb", Eb, XX, XX },
953 { "setae", Eb, XX, XX },
954 { "sete", Eb, XX, XX },
955 { "setne", Eb, XX, XX },
956 { "setbe", Eb, XX, XX },
957 { "seta", Eb, XX, XX },
958 /* 98 */
959 { "sets", Eb, XX, XX },
960 { "setns", Eb, XX, XX },
961 { "setp", Eb, XX, XX },
962 { "setnp", Eb, XX, XX },
963 { "setl", Eb, XX, XX },
964 { "setge", Eb, XX, XX },
965 { "setle", Eb, XX, XX },
966 { "setg", Eb, XX, XX },
967 /* a0 */
968 { "pushT", fs, XX, XX },
969 { "popT", fs, XX, XX },
970 { "cpuid", XX, XX, XX },
971 { "btS", Ev, Gv, XX },
972 { "shldS", Ev, Gv, Ib },
973 { "shldS", Ev, Gv, CL },
974 { GRPPADLCK2 },
975 { GRPPADLCK1 },
976 /* a8 */
977 { "pushT", gs, XX, XX },
978 { "popT", gs, XX, XX },
979 { "rsm", XX, XX, XX },
980 { "btsS", Ev, Gv, XX },
981 { "shrdS", Ev, Gv, Ib },
982 { "shrdS", Ev, Gv, CL },
983 { GRP13 },
984 { "imulS", Gv, Ev, XX },
985 /* b0 */
986 { "cmpxchgB", Eb, Gb, XX },
987 { "cmpxchgS", Ev, Gv, XX },
988 { "lssS", Gv, Mp, XX },
989 { "btrS", Ev, Gv, XX },
990 { "lfsS", Gv, Mp, XX },
991 { "lgsS", Gv, Mp, XX },
992 { "movz{bR|x|bR|x}", Gv, Eb, XX },
993 { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */
994 /* b8 */
995 { "(bad)", XX, XX, XX },
996 { "ud2b", XX, XX, XX },
997 { GRP8 },
998 { "btcS", Ev, Gv, XX },
999 { "bsfS", Gv, Ev, XX },
1000 { "bsrS", Gv, Ev, XX },
1001 { "movs{bR|x|bR|x}", Gv, Eb, XX },
1002 { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */
1003 /* c0 */
1004 { "xaddB", Eb, Gb, XX },
1005 { "xaddS", Ev, Gv, XX },
1006 { PREGRP1 },
1007 { "movntiS", Ev, Gv, XX },
1008 { "pinsrw", MX, Edqw, Ib },
1009 { "pextrw", Gdq, MS, Ib },
1010 { "shufpX", XM, EX, Ib },
1011 { GRP9 },
1012 /* c8 */
1013 { "bswap", RMeAX, XX, XX },
1014 { "bswap", RMeCX, XX, XX },
1015 { "bswap", RMeDX, XX, XX },
1016 { "bswap", RMeBX, XX, XX },
1017 { "bswap", RMeSP, XX, XX },
1018 { "bswap", RMeBP, XX, XX },
1019 { "bswap", RMeSI, XX, XX },
1020 { "bswap", RMeDI, XX, XX },
1021 /* d0 */
1022 { PREGRP27 },
1023 { "psrlw", MX, EM, XX },
1024 { "psrld", MX, EM, XX },
1025 { "psrlq", MX, EM, XX },
1026 { "paddq", MX, EM, XX },
1027 { "pmullw", MX, EM, XX },
1028 { PREGRP21 },
1029 { "pmovmskb", Gdq, MS, XX },
1030 /* d8 */
1031 { "psubusb", MX, EM, XX },
1032 { "psubusw", MX, EM, XX },
1033 { "pminub", MX, EM, XX },
1034 { "pand", MX, EM, XX },
1035 { "paddusb", MX, EM, XX },
1036 { "paddusw", MX, EM, XX },
1037 { "pmaxub", MX, EM, XX },
1038 { "pandn", MX, EM, XX },
1039 /* e0 */
1040 { "pavgb", MX, EM, XX },
1041 { "psraw", MX, EM, XX },
1042 { "psrad", MX, EM, XX },
1043 { "pavgw", MX, EM, XX },
1044 { "pmulhuw", MX, EM, XX },
1045 { "pmulhw", MX, EM, XX },
1046 { PREGRP15 },
1047 { PREGRP25 },
1048 /* e8 */
1049 { "psubsb", MX, EM, XX },
1050 { "psubsw", MX, EM, XX },
1051 { "pminsw", MX, EM, XX },
1052 { "por", MX, EM, XX },
1053 { "paddsb", MX, EM, XX },
1054 { "paddsw", MX, EM, XX },
1055 { "pmaxsw", MX, EM, XX },
1056 { "pxor", MX, EM, XX },
1057 /* f0 */
1058 { PREGRP32 },
1059 { "psllw", MX, EM, XX },
1060 { "pslld", MX, EM, XX },
1061 { "psllq", MX, EM, XX },
1062 { "pmuludq", MX, EM, XX },
1063 { "pmaddwd", MX, EM, XX },
1064 { "psadbw", MX, EM, XX },
1065 { PREGRP18 },
1066 /* f8 */
1067 { "psubb", MX, EM, XX },
1068 { "psubw", MX, EM, XX },
1069 { "psubd", MX, EM, XX },
1070 { "psubq", MX, EM, XX },
1071 { "paddb", MX, EM, XX },
1072 { "paddw", MX, EM, XX },
1073 { "paddd", MX, EM, XX },
1074 { "(bad)", XX, XX, XX }
1077 static const unsigned char onebyte_has_modrm[256] = {
1078 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1079 /* ------------------------------- */
1080 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1081 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1082 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1083 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1084 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1085 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1086 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1087 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1088 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1089 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1090 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1091 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1092 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1093 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1094 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1095 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1096 /* ------------------------------- */
1097 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1100 static const unsigned char twobyte_has_modrm[256] = {
1101 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1102 /* ------------------------------- */
1103 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1104 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1105 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1106 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1107 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1108 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1109 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1110 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1111 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1112 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1113 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1114 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1115 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1116 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1117 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1118 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1119 /* ------------------------------- */
1120 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1123 static const unsigned char twobyte_uses_SSE_prefix[256] = {
1124 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1125 /* ------------------------------- */
1126 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1127 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1128 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1129 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1130 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1131 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1132 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1133 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */
1134 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1135 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1136 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1137 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1138 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1139 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1140 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1141 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1142 /* ------------------------------- */
1143 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1146 static char obuf[100];
1147 static char *obufp;
1148 static char scratchbuf[100];
1149 static unsigned char *start_codep;
1150 static unsigned char *insn_codep;
1151 static unsigned char *codep;
1152 static disassemble_info *the_info;
1153 static int mod;
1154 static int rm;
1155 static int reg;
1156 static unsigned char need_modrm;
1158 /* If we are accessing mod/rm/reg without need_modrm set, then the
1159 values are stale. Hitting this abort likely indicates that you
1160 need to update onebyte_has_modrm or twobyte_has_modrm. */
1161 #define MODRM_CHECK if (!need_modrm) abort ()
1163 static const char **names64;
1164 static const char **names32;
1165 static const char **names16;
1166 static const char **names8;
1167 static const char **names8rex;
1168 static const char **names_seg;
1169 static const char **index16;
1171 static const char *intel_names64[] = {
1172 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1173 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1175 static const char *intel_names32[] = {
1176 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1177 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1179 static const char *intel_names16[] = {
1180 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1181 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1183 static const char *intel_names8[] = {
1184 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1186 static const char *intel_names8rex[] = {
1187 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1188 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1190 static const char *intel_names_seg[] = {
1191 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1193 static const char *intel_index16[] = {
1194 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1197 static const char *att_names64[] = {
1198 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1199 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1201 static const char *att_names32[] = {
1202 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1203 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1205 static const char *att_names16[] = {
1206 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1207 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1209 static const char *att_names8[] = {
1210 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1212 static const char *att_names8rex[] = {
1213 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1214 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1216 static const char *att_names_seg[] = {
1217 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1219 static const char *att_index16[] = {
1220 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1223 static const struct dis386 grps[][8] = {
1224 /* GRP1b */
1226 { "addA", Eb, Ib, XX },
1227 { "orA", Eb, Ib, XX },
1228 { "adcA", Eb, Ib, XX },
1229 { "sbbA", Eb, Ib, XX },
1230 { "andA", Eb, Ib, XX },
1231 { "subA", Eb, Ib, XX },
1232 { "xorA", Eb, Ib, XX },
1233 { "cmpA", Eb, Ib, XX }
1235 /* GRP1S */
1237 { "addQ", Ev, Iv, XX },
1238 { "orQ", Ev, Iv, XX },
1239 { "adcQ", Ev, Iv, XX },
1240 { "sbbQ", Ev, Iv, XX },
1241 { "andQ", Ev, Iv, XX },
1242 { "subQ", Ev, Iv, XX },
1243 { "xorQ", Ev, Iv, XX },
1244 { "cmpQ", Ev, Iv, XX }
1246 /* GRP1Ss */
1248 { "addQ", Ev, sIb, XX },
1249 { "orQ", Ev, sIb, XX },
1250 { "adcQ", Ev, sIb, XX },
1251 { "sbbQ", Ev, sIb, XX },
1252 { "andQ", Ev, sIb, XX },
1253 { "subQ", Ev, sIb, XX },
1254 { "xorQ", Ev, sIb, XX },
1255 { "cmpQ", Ev, sIb, XX }
1257 /* GRP2b */
1259 { "rolA", Eb, Ib, XX },
1260 { "rorA", Eb, Ib, XX },
1261 { "rclA", Eb, Ib, XX },
1262 { "rcrA", Eb, Ib, XX },
1263 { "shlA", Eb, Ib, XX },
1264 { "shrA", Eb, Ib, XX },
1265 { "(bad)", XX, XX, XX },
1266 { "sarA", Eb, Ib, XX },
1268 /* GRP2S */
1270 { "rolQ", Ev, Ib, XX },
1271 { "rorQ", Ev, Ib, XX },
1272 { "rclQ", Ev, Ib, XX },
1273 { "rcrQ", Ev, Ib, XX },
1274 { "shlQ", Ev, Ib, XX },
1275 { "shrQ", Ev, Ib, XX },
1276 { "(bad)", XX, XX, XX },
1277 { "sarQ", Ev, Ib, XX },
1279 /* GRP2b_one */
1281 { "rolA", Eb, I1, XX },
1282 { "rorA", Eb, I1, XX },
1283 { "rclA", Eb, I1, XX },
1284 { "rcrA", Eb, I1, XX },
1285 { "shlA", Eb, I1, XX },
1286 { "shrA", Eb, I1, XX },
1287 { "(bad)", XX, XX, XX },
1288 { "sarA", Eb, I1, XX },
1290 /* GRP2S_one */
1292 { "rolQ", Ev, I1, XX },
1293 { "rorQ", Ev, I1, XX },
1294 { "rclQ", Ev, I1, XX },
1295 { "rcrQ", Ev, I1, XX },
1296 { "shlQ", Ev, I1, XX },
1297 { "shrQ", Ev, I1, XX },
1298 { "(bad)", XX, XX, XX},
1299 { "sarQ", Ev, I1, XX },
1301 /* GRP2b_cl */
1303 { "rolA", Eb, CL, XX },
1304 { "rorA", Eb, CL, XX },
1305 { "rclA", Eb, CL, XX },
1306 { "rcrA", Eb, CL, XX },
1307 { "shlA", Eb, CL, XX },
1308 { "shrA", Eb, CL, XX },
1309 { "(bad)", XX, XX, XX },
1310 { "sarA", Eb, CL, XX },
1312 /* GRP2S_cl */
1314 { "rolQ", Ev, CL, XX },
1315 { "rorQ", Ev, CL, XX },
1316 { "rclQ", Ev, CL, XX },
1317 { "rcrQ", Ev, CL, XX },
1318 { "shlQ", Ev, CL, XX },
1319 { "shrQ", Ev, CL, XX },
1320 { "(bad)", XX, XX, XX },
1321 { "sarQ", Ev, CL, XX }
1323 /* GRP3b */
1325 { "testA", Eb, Ib, XX },
1326 { "(bad)", Eb, XX, XX },
1327 { "notA", Eb, XX, XX },
1328 { "negA", Eb, XX, XX },
1329 { "mulA", Eb, XX, XX }, /* Don't print the implicit %al register, */
1330 { "imulA", Eb, XX, XX }, /* to distinguish these opcodes from other */
1331 { "divA", Eb, XX, XX }, /* mul/imul opcodes. Do the same for div */
1332 { "idivA", Eb, XX, XX } /* and idiv for consistency. */
1334 /* GRP3S */
1336 { "testQ", Ev, Iv, XX },
1337 { "(bad)", XX, XX, XX },
1338 { "notQ", Ev, XX, XX },
1339 { "negQ", Ev, XX, XX },
1340 { "mulQ", Ev, XX, XX }, /* Don't print the implicit register. */
1341 { "imulQ", Ev, XX, XX },
1342 { "divQ", Ev, XX, XX },
1343 { "idivQ", Ev, XX, XX },
1345 /* GRP4 */
1347 { "incA", Eb, XX, XX },
1348 { "decA", Eb, XX, XX },
1349 { "(bad)", XX, XX, XX },
1350 { "(bad)", XX, XX, XX },
1351 { "(bad)", XX, XX, XX },
1352 { "(bad)", XX, XX, XX },
1353 { "(bad)", XX, XX, XX },
1354 { "(bad)", XX, XX, XX },
1356 /* GRP5 */
1358 { "incQ", Ev, XX, XX },
1359 { "decQ", Ev, XX, XX },
1360 { "callT", indirEv, XX, XX },
1361 { "JcallT", indirEp, XX, XX },
1362 { "jmpT", indirEv, XX, XX },
1363 { "JjmpT", indirEp, XX, XX },
1364 { "pushU", stackEv, XX, XX },
1365 { "(bad)", XX, XX, XX },
1367 /* GRP6 */
1369 { "sldtQ", Ev, XX, XX },
1370 { "strQ", Ev, XX, XX },
1371 { "lldt", Ew, XX, XX },
1372 { "ltr", Ew, XX, XX },
1373 { "verr", Ew, XX, XX },
1374 { "verw", Ew, XX, XX },
1375 { "(bad)", XX, XX, XX },
1376 { "(bad)", XX, XX, XX }
1378 /* GRP7 */
1380 { "sgdtIQ", VMX_Fixup, 0, XX, XX },
1381 { "sidtIQ", PNI_Fixup, 0, XX, XX },
1382 { "lgdt{Q|Q||}", M, XX, XX },
1383 { "lidt{Q|Q||}", SVME_Fixup, 0, XX, XX },
1384 { "smswQ", Ev, XX, XX },
1385 { "(bad)", XX, XX, XX },
1386 { "lmsw", Ew, XX, XX },
1387 { "invlpg", INVLPG_Fixup, w_mode, XX, XX },
1389 /* GRP8 */
1391 { "(bad)", XX, XX, XX },
1392 { "(bad)", XX, XX, XX },
1393 { "(bad)", XX, XX, XX },
1394 { "(bad)", XX, XX, XX },
1395 { "btQ", Ev, Ib, XX },
1396 { "btsQ", Ev, Ib, XX },
1397 { "btrQ", Ev, Ib, XX },
1398 { "btcQ", Ev, Ib, XX },
1400 /* GRP9 */
1402 { "(bad)", XX, XX, XX },
1403 { "cmpxchg8b", Eq, XX, XX },
1404 { "(bad)", XX, XX, XX },
1405 { "(bad)", XX, XX, XX },
1406 { "(bad)", XX, XX, XX },
1407 { "(bad)", XX, XX, XX },
1408 { "", VM, XX, XX }, /* See OP_VMX. */
1409 { "vmptrst", Eq, XX, XX },
1411 /* GRP10 */
1413 { "(bad)", XX, XX, XX },
1414 { "(bad)", XX, XX, XX },
1415 { "psrlw", MS, Ib, XX },
1416 { "(bad)", XX, XX, XX },
1417 { "psraw", MS, Ib, XX },
1418 { "(bad)", XX, XX, XX },
1419 { "psllw", MS, Ib, XX },
1420 { "(bad)", XX, XX, XX },
1422 /* GRP11 */
1424 { "(bad)", XX, XX, XX },
1425 { "(bad)", XX, XX, XX },
1426 { "psrld", MS, Ib, XX },
1427 { "(bad)", XX, XX, XX },
1428 { "psrad", MS, Ib, XX },
1429 { "(bad)", XX, XX, XX },
1430 { "pslld", MS, Ib, XX },
1431 { "(bad)", XX, XX, XX },
1433 /* GRP12 */
1435 { "(bad)", XX, XX, XX },
1436 { "(bad)", XX, XX, XX },
1437 { "psrlq", MS, Ib, XX },
1438 { "psrldq", MS, Ib, XX },
1439 { "(bad)", XX, XX, XX },
1440 { "(bad)", XX, XX, XX },
1441 { "psllq", MS, Ib, XX },
1442 { "pslldq", MS, Ib, XX },
1444 /* GRP13 */
1446 { "fxsave", Ev, XX, XX },
1447 { "fxrstor", Ev, XX, XX },
1448 { "ldmxcsr", Ev, XX, XX },
1449 { "stmxcsr", Ev, XX, XX },
1450 { "(bad)", XX, XX, XX },
1451 { "lfence", OP_0fae, 0, XX, XX },
1452 { "mfence", OP_0fae, 0, XX, XX },
1453 { "clflush", OP_0fae, 0, XX, XX },
1455 /* GRP14 */
1457 { "prefetchnta", Ev, XX, XX },
1458 { "prefetcht0", Ev, XX, XX },
1459 { "prefetcht1", Ev, XX, XX },
1460 { "prefetcht2", Ev, XX, XX },
1461 { "(bad)", XX, XX, XX },
1462 { "(bad)", XX, XX, XX },
1463 { "(bad)", XX, XX, XX },
1464 { "(bad)", XX, XX, XX },
1466 /* GRPAMD */
1468 { "prefetch", Eb, XX, XX },
1469 { "prefetchw", Eb, XX, XX },
1470 { "(bad)", XX, XX, XX },
1471 { "(bad)", XX, XX, XX },
1472 { "(bad)", XX, XX, XX },
1473 { "(bad)", XX, XX, XX },
1474 { "(bad)", XX, XX, XX },
1475 { "(bad)", XX, XX, XX },
1477 /* GRPPADLCK1 */
1479 { "xstore-rng", OP_0f07, 0, XX, XX },
1480 { "xcrypt-ecb", OP_0f07, 0, XX, XX },
1481 { "xcrypt-cbc", OP_0f07, 0, XX, XX },
1482 { "xcrypt-ctr", OP_0f07, 0, XX, XX },
1483 { "xcrypt-cfb", OP_0f07, 0, XX, XX },
1484 { "xcrypt-ofb", OP_0f07, 0, XX, XX },
1485 { "(bad)", OP_0f07, 0, XX, XX },
1486 { "(bad)", OP_0f07, 0, XX, XX },
1488 /* GRPPADLCK2 */
1490 { "montmul", OP_0f07, 0, XX, XX },
1491 { "xsha1", OP_0f07, 0, XX, XX },
1492 { "xsha256", OP_0f07, 0, XX, XX },
1493 { "(bad)", OP_0f07, 0, XX, XX },
1494 { "(bad)", OP_0f07, 0, XX, XX },
1495 { "(bad)", OP_0f07, 0, XX, XX },
1496 { "(bad)", OP_0f07, 0, XX, XX },
1497 { "(bad)", OP_0f07, 0, XX, XX },
1501 static const struct dis386 prefix_user_table[][4] = {
1502 /* PREGRP0 */
1504 { "addps", XM, EX, XX },
1505 { "addss", XM, EX, XX },
1506 { "addpd", XM, EX, XX },
1507 { "addsd", XM, EX, XX },
1509 /* PREGRP1 */
1511 { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */
1512 { "", XM, EX, OPSIMD },
1513 { "", XM, EX, OPSIMD },
1514 { "", XM, EX, OPSIMD },
1516 /* PREGRP2 */
1518 { "cvtpi2ps", XM, EM, XX },
1519 { "cvtsi2ssY", XM, Ev, XX },
1520 { "cvtpi2pd", XM, EM, XX },
1521 { "cvtsi2sdY", XM, Ev, XX },
1523 /* PREGRP3 */
1525 { "cvtps2pi", MX, EX, XX },
1526 { "cvtss2siY", Gv, EX, XX },
1527 { "cvtpd2pi", MX, EX, XX },
1528 { "cvtsd2siY", Gv, EX, XX },
1530 /* PREGRP4 */
1532 { "cvttps2pi", MX, EX, XX },
1533 { "cvttss2siY", Gv, EX, XX },
1534 { "cvttpd2pi", MX, EX, XX },
1535 { "cvttsd2siY", Gv, EX, XX },
1537 /* PREGRP5 */
1539 { "divps", XM, EX, XX },
1540 { "divss", XM, EX, XX },
1541 { "divpd", XM, EX, XX },
1542 { "divsd", XM, EX, XX },
1544 /* PREGRP6 */
1546 { "maxps", XM, EX, XX },
1547 { "maxss", XM, EX, XX },
1548 { "maxpd", XM, EX, XX },
1549 { "maxsd", XM, EX, XX },
1551 /* PREGRP7 */
1553 { "minps", XM, EX, XX },
1554 { "minss", XM, EX, XX },
1555 { "minpd", XM, EX, XX },
1556 { "minsd", XM, EX, XX },
1558 /* PREGRP8 */
1560 { "movups", XM, EX, XX },
1561 { "movss", XM, EX, XX },
1562 { "movupd", XM, EX, XX },
1563 { "movsd", XM, EX, XX },
1565 /* PREGRP9 */
1567 { "movups", EX, XM, XX },
1568 { "movss", EX, XM, XX },
1569 { "movupd", EX, XM, XX },
1570 { "movsd", EX, XM, XX },
1572 /* PREGRP10 */
1574 { "mulps", XM, EX, XX },
1575 { "mulss", XM, EX, XX },
1576 { "mulpd", XM, EX, XX },
1577 { "mulsd", XM, EX, XX },
1579 /* PREGRP11 */
1581 { "rcpps", XM, EX, XX },
1582 { "rcpss", XM, EX, XX },
1583 { "(bad)", XM, EX, XX },
1584 { "(bad)", XM, EX, XX },
1586 /* PREGRP12 */
1588 { "rsqrtps", XM, EX, XX },
1589 { "rsqrtss", XM, EX, XX },
1590 { "(bad)", XM, EX, XX },
1591 { "(bad)", XM, EX, XX },
1593 /* PREGRP13 */
1595 { "sqrtps", XM, EX, XX },
1596 { "sqrtss", XM, EX, XX },
1597 { "sqrtpd", XM, EX, XX },
1598 { "sqrtsd", XM, EX, XX },
1600 /* PREGRP14 */
1602 { "subps", XM, EX, XX },
1603 { "subss", XM, EX, XX },
1604 { "subpd", XM, EX, XX },
1605 { "subsd", XM, EX, XX },
1607 /* PREGRP15 */
1609 { "(bad)", XM, EX, XX },
1610 { "cvtdq2pd", XM, EX, XX },
1611 { "cvttpd2dq", XM, EX, XX },
1612 { "cvtpd2dq", XM, EX, XX },
1614 /* PREGRP16 */
1616 { "cvtdq2ps", XM, EX, XX },
1617 { "cvttps2dq",XM, EX, XX },
1618 { "cvtps2dq",XM, EX, XX },
1619 { "(bad)", XM, EX, XX },
1621 /* PREGRP17 */
1623 { "cvtps2pd", XM, EX, XX },
1624 { "cvtss2sd", XM, EX, XX },
1625 { "cvtpd2ps", XM, EX, XX },
1626 { "cvtsd2ss", XM, EX, XX },
1628 /* PREGRP18 */
1630 { "maskmovq", MX, MS, XX },
1631 { "(bad)", XM, EX, XX },
1632 { "maskmovdqu", XM, EX, XX },
1633 { "(bad)", XM, EX, XX },
1635 /* PREGRP19 */
1637 { "movq", MX, EM, XX },
1638 { "movdqu", XM, EX, XX },
1639 { "movdqa", XM, EX, XX },
1640 { "(bad)", XM, EX, XX },
1642 /* PREGRP20 */
1644 { "movq", EM, MX, XX },
1645 { "movdqu", EX, XM, XX },
1646 { "movdqa", EX, XM, XX },
1647 { "(bad)", EX, XM, XX },
1649 /* PREGRP21 */
1651 { "(bad)", EX, XM, XX },
1652 { "movq2dq", XM, MS, XX },
1653 { "movq", EX, XM, XX },
1654 { "movdq2q", MX, XS, XX },
1656 /* PREGRP22 */
1658 { "pshufw", MX, EM, Ib },
1659 { "pshufhw", XM, EX, Ib },
1660 { "pshufd", XM, EX, Ib },
1661 { "pshuflw", XM, EX, Ib },
1663 /* PREGRP23 */
1665 { "movd", Edq, MX, XX },
1666 { "movq", XM, EX, XX },
1667 { "movd", Edq, XM, XX },
1668 { "(bad)", Ed, XM, XX },
1670 /* PREGRP24 */
1672 { "(bad)", MX, EX, XX },
1673 { "(bad)", XM, EX, XX },
1674 { "punpckhqdq", XM, EX, XX },
1675 { "(bad)", XM, EX, XX },
1677 /* PREGRP25 */
1679 { "movntq", EM, MX, XX },
1680 { "(bad)", EM, XM, XX },
1681 { "movntdq", EM, XM, XX },
1682 { "(bad)", EM, XM, XX },
1684 /* PREGRP26 */
1686 { "(bad)", MX, EX, XX },
1687 { "(bad)", XM, EX, XX },
1688 { "punpcklqdq", XM, EX, XX },
1689 { "(bad)", XM, EX, XX },
1691 /* PREGRP27 */
1693 { "(bad)", MX, EX, XX },
1694 { "(bad)", XM, EX, XX },
1695 { "addsubpd", XM, EX, XX },
1696 { "addsubps", XM, EX, XX },
1698 /* PREGRP28 */
1700 { "(bad)", MX, EX, XX },
1701 { "(bad)", XM, EX, XX },
1702 { "haddpd", XM, EX, XX },
1703 { "haddps", XM, EX, XX },
1705 /* PREGRP29 */
1707 { "(bad)", MX, EX, XX },
1708 { "(bad)", XM, EX, XX },
1709 { "hsubpd", XM, EX, XX },
1710 { "hsubps", XM, EX, XX },
1712 /* PREGRP30 */
1714 { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
1715 { "movsldup", XM, EX, XX },
1716 { "movlpd", XM, EX, XX },
1717 { "movddup", XM, EX, XX },
1719 /* PREGRP31 */
1721 { "movhpX", XM, EX, SIMD_Fixup, 'l' },
1722 { "movshdup", XM, EX, XX },
1723 { "movhpd", XM, EX, XX },
1724 { "(bad)", XM, EX, XX },
1726 /* PREGRP32 */
1728 { "(bad)", XM, EX, XX },
1729 { "(bad)", XM, EX, XX },
1730 { "(bad)", XM, EX, XX },
1731 { "lddqu", XM, M, XX },
1735 static const struct dis386 x86_64_table[][2] = {
1737 { "arpl", Ew, Gw, XX },
1738 { "movs{||lq|xd}", Gv, Ed, XX },
1742 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1744 static void
1745 ckprefix (void)
1747 int newrex;
1748 rex = 0;
1749 prefixes = 0;
1750 used_prefixes = 0;
1751 rex_used = 0;
1752 while (1)
1754 FETCH_DATA (the_info, codep + 1);
1755 newrex = 0;
1756 switch (*codep)
1758 /* REX prefixes family. */
1759 case 0x40:
1760 case 0x41:
1761 case 0x42:
1762 case 0x43:
1763 case 0x44:
1764 case 0x45:
1765 case 0x46:
1766 case 0x47:
1767 case 0x48:
1768 case 0x49:
1769 case 0x4a:
1770 case 0x4b:
1771 case 0x4c:
1772 case 0x4d:
1773 case 0x4e:
1774 case 0x4f:
1775 if (mode_64bit)
1776 newrex = *codep;
1777 else
1778 return;
1779 break;
1780 case 0xf3:
1781 prefixes |= PREFIX_REPZ;
1782 break;
1783 case 0xf2:
1784 prefixes |= PREFIX_REPNZ;
1785 break;
1786 case 0xf0:
1787 prefixes |= PREFIX_LOCK;
1788 break;
1789 case 0x2e:
1790 prefixes |= PREFIX_CS;
1791 break;
1792 case 0x36:
1793 prefixes |= PREFIX_SS;
1794 break;
1795 case 0x3e:
1796 prefixes |= PREFIX_DS;
1797 break;
1798 case 0x26:
1799 prefixes |= PREFIX_ES;
1800 break;
1801 case 0x64:
1802 prefixes |= PREFIX_FS;
1803 break;
1804 case 0x65:
1805 prefixes |= PREFIX_GS;
1806 break;
1807 case 0x66:
1808 prefixes |= PREFIX_DATA;
1809 break;
1810 case 0x67:
1811 prefixes |= PREFIX_ADDR;
1812 break;
1813 case FWAIT_OPCODE:
1814 /* fwait is really an instruction. If there are prefixes
1815 before the fwait, they belong to the fwait, *not* to the
1816 following instruction. */
1817 if (prefixes)
1819 prefixes |= PREFIX_FWAIT;
1820 codep++;
1821 return;
1823 prefixes = PREFIX_FWAIT;
1824 break;
1825 default:
1826 return;
1828 /* Rex is ignored when followed by another prefix. */
1829 if (rex)
1831 oappend (prefix_name (rex, 0));
1832 oappend (" ");
1834 rex = newrex;
1835 codep++;
1839 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
1840 prefix byte. */
1842 static const char *
1843 prefix_name (int pref, int sizeflag)
1845 switch (pref)
1847 /* REX prefixes family. */
1848 case 0x40:
1849 return "rex";
1850 case 0x41:
1851 return "rexZ";
1852 case 0x42:
1853 return "rexY";
1854 case 0x43:
1855 return "rexYZ";
1856 case 0x44:
1857 return "rexX";
1858 case 0x45:
1859 return "rexXZ";
1860 case 0x46:
1861 return "rexXY";
1862 case 0x47:
1863 return "rexXYZ";
1864 case 0x48:
1865 return "rex64";
1866 case 0x49:
1867 return "rex64Z";
1868 case 0x4a:
1869 return "rex64Y";
1870 case 0x4b:
1871 return "rex64YZ";
1872 case 0x4c:
1873 return "rex64X";
1874 case 0x4d:
1875 return "rex64XZ";
1876 case 0x4e:
1877 return "rex64XY";
1878 case 0x4f:
1879 return "rex64XYZ";
1880 case 0xf3:
1881 return "repz";
1882 case 0xf2:
1883 return "repnz";
1884 case 0xf0:
1885 return "lock";
1886 case 0x2e:
1887 return "cs";
1888 case 0x36:
1889 return "ss";
1890 case 0x3e:
1891 return "ds";
1892 case 0x26:
1893 return "es";
1894 case 0x64:
1895 return "fs";
1896 case 0x65:
1897 return "gs";
1898 case 0x66:
1899 return (sizeflag & DFLAG) ? "data16" : "data32";
1900 case 0x67:
1901 if (mode_64bit)
1902 return (sizeflag & AFLAG) ? "addr32" : "addr64";
1903 else
1904 return (sizeflag & AFLAG) ? "addr16" : "addr32";
1905 case FWAIT_OPCODE:
1906 return "fwait";
1907 default:
1908 return NULL;
1912 static char op1out[100], op2out[100], op3out[100];
1913 static int op_ad, op_index[3];
1914 static int two_source_ops;
1915 static bfd_vma op_address[3];
1916 static bfd_vma op_riprel[3];
1917 static bfd_vma start_pc;
1920 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1921 * (see topic "Redundant prefixes" in the "Differences from 8086"
1922 * section of the "Virtual 8086 Mode" chapter.)
1923 * 'pc' should be the address of this instruction, it will
1924 * be used to print the target address if this is a relative jump or call
1925 * The function returns the length of this instruction in bytes.
1928 static char intel_syntax;
1929 static char open_char;
1930 static char close_char;
1931 static char separator_char;
1932 static char scale_char;
1934 /* Here for backwards compatibility. When gdb stops using
1935 print_insn_i386_att and print_insn_i386_intel these functions can
1936 disappear, and print_insn_i386 be merged into print_insn. */
1938 print_insn_i386_att (bfd_vma pc, disassemble_info *info)
1940 intel_syntax = 0;
1942 return print_insn (pc, info);
1946 print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
1948 intel_syntax = 1;
1950 return print_insn (pc, info);
1954 print_insn_i386 (bfd_vma pc, disassemble_info *info)
1956 intel_syntax = -1;
1958 return print_insn (pc, info);
1961 static int
1962 print_insn (bfd_vma pc, disassemble_info *info)
1964 const struct dis386 *dp;
1965 int i;
1966 char *first, *second, *third;
1967 int needcomma;
1968 unsigned char uses_SSE_prefix, uses_LOCK_prefix;
1969 int sizeflag;
1970 const char *p;
1971 struct dis_private priv;
1973 mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
1974 || info->mach == bfd_mach_x86_64);
1976 if (intel_syntax == (char) -1)
1977 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
1978 || info->mach == bfd_mach_x86_64_intel_syntax);
1980 if (info->mach == bfd_mach_i386_i386
1981 || info->mach == bfd_mach_x86_64
1982 || info->mach == bfd_mach_i386_i386_intel_syntax
1983 || info->mach == bfd_mach_x86_64_intel_syntax)
1984 priv.orig_sizeflag = AFLAG | DFLAG;
1985 else if (info->mach == bfd_mach_i386_i8086)
1986 priv.orig_sizeflag = 0;
1987 else
1988 abort ();
1990 for (p = info->disassembler_options; p != NULL; )
1992 if (strncmp (p, "x86-64", 6) == 0)
1994 mode_64bit = 1;
1995 priv.orig_sizeflag = AFLAG | DFLAG;
1997 else if (strncmp (p, "i386", 4) == 0)
1999 mode_64bit = 0;
2000 priv.orig_sizeflag = AFLAG | DFLAG;
2002 else if (strncmp (p, "i8086", 5) == 0)
2004 mode_64bit = 0;
2005 priv.orig_sizeflag = 0;
2007 else if (strncmp (p, "intel", 5) == 0)
2009 intel_syntax = 1;
2011 else if (strncmp (p, "att", 3) == 0)
2013 intel_syntax = 0;
2015 else if (strncmp (p, "addr", 4) == 0)
2017 if (p[4] == '1' && p[5] == '6')
2018 priv.orig_sizeflag &= ~AFLAG;
2019 else if (p[4] == '3' && p[5] == '2')
2020 priv.orig_sizeflag |= AFLAG;
2022 else if (strncmp (p, "data", 4) == 0)
2024 if (p[4] == '1' && p[5] == '6')
2025 priv.orig_sizeflag &= ~DFLAG;
2026 else if (p[4] == '3' && p[5] == '2')
2027 priv.orig_sizeflag |= DFLAG;
2029 else if (strncmp (p, "suffix", 6) == 0)
2030 priv.orig_sizeflag |= SUFFIX_ALWAYS;
2032 p = strchr (p, ',');
2033 if (p != NULL)
2034 p++;
2037 if (intel_syntax)
2039 names64 = intel_names64;
2040 names32 = intel_names32;
2041 names16 = intel_names16;
2042 names8 = intel_names8;
2043 names8rex = intel_names8rex;
2044 names_seg = intel_names_seg;
2045 index16 = intel_index16;
2046 open_char = '[';
2047 close_char = ']';
2048 separator_char = '+';
2049 scale_char = '*';
2051 else
2053 names64 = att_names64;
2054 names32 = att_names32;
2055 names16 = att_names16;
2056 names8 = att_names8;
2057 names8rex = att_names8rex;
2058 names_seg = att_names_seg;
2059 index16 = att_index16;
2060 open_char = '(';
2061 close_char = ')';
2062 separator_char = ',';
2063 scale_char = ',';
2066 /* The output looks better if we put 7 bytes on a line, since that
2067 puts most long word instructions on a single line. */
2068 info->bytes_per_line = 7;
2070 info->private_data = &priv;
2071 priv.max_fetched = priv.the_buffer;
2072 priv.insn_start = pc;
2074 obuf[0] = 0;
2075 op1out[0] = 0;
2076 op2out[0] = 0;
2077 op3out[0] = 0;
2079 op_index[0] = op_index[1] = op_index[2] = -1;
2081 the_info = info;
2082 start_pc = pc;
2083 start_codep = priv.the_buffer;
2084 codep = priv.the_buffer;
2086 if (setjmp (priv.bailout) != 0)
2088 const char *name;
2090 /* Getting here means we tried for data but didn't get it. That
2091 means we have an incomplete instruction of some sort. Just
2092 print the first byte as a prefix or a .byte pseudo-op. */
2093 if (codep > priv.the_buffer)
2095 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2096 if (name != NULL)
2097 (*info->fprintf_func) (info->stream, "%s", name);
2098 else
2100 /* Just print the first byte as a .byte instruction. */
2101 (*info->fprintf_func) (info->stream, ".byte 0x%x",
2102 (unsigned int) priv.the_buffer[0]);
2105 return 1;
2108 return -1;
2111 obufp = obuf;
2112 ckprefix ();
2114 insn_codep = codep;
2115 sizeflag = priv.orig_sizeflag;
2117 FETCH_DATA (info, codep + 1);
2118 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
2120 if ((prefixes & PREFIX_FWAIT)
2121 && ((*codep < 0xd8) || (*codep > 0xdf)))
2123 const char *name;
2125 /* fwait not followed by floating point instruction. Print the
2126 first prefix, which is probably fwait itself. */
2127 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2128 if (name == NULL)
2129 name = INTERNAL_DISASSEMBLER_ERROR;
2130 (*info->fprintf_func) (info->stream, "%s", name);
2131 return 1;
2134 if (*codep == 0x0f)
2136 FETCH_DATA (info, codep + 2);
2137 dp = &dis386_twobyte[*++codep];
2138 need_modrm = twobyte_has_modrm[*codep];
2139 uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
2140 uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
2142 else
2144 dp = &dis386[*codep];
2145 need_modrm = onebyte_has_modrm[*codep];
2146 uses_SSE_prefix = 0;
2147 uses_LOCK_prefix = 0;
2149 codep++;
2151 if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
2153 oappend ("repz ");
2154 used_prefixes |= PREFIX_REPZ;
2156 if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
2158 oappend ("repnz ");
2159 used_prefixes |= PREFIX_REPNZ;
2161 if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
2163 oappend ("lock ");
2164 used_prefixes |= PREFIX_LOCK;
2167 if (prefixes & PREFIX_ADDR)
2169 sizeflag ^= AFLAG;
2170 if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
2172 if ((sizeflag & AFLAG) || mode_64bit)
2173 oappend ("addr32 ");
2174 else
2175 oappend ("addr16 ");
2176 used_prefixes |= PREFIX_ADDR;
2180 if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
2182 sizeflag ^= DFLAG;
2183 if (dp->bytemode3 == cond_jump_mode
2184 && dp->bytemode1 == v_mode
2185 && !intel_syntax)
2187 if (sizeflag & DFLAG)
2188 oappend ("data32 ");
2189 else
2190 oappend ("data16 ");
2191 used_prefixes |= PREFIX_DATA;
2195 if (need_modrm)
2197 FETCH_DATA (info, codep + 1);
2198 mod = (*codep >> 6) & 3;
2199 reg = (*codep >> 3) & 7;
2200 rm = *codep & 7;
2203 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2205 dofloat (sizeflag);
2207 else
2209 int index;
2210 if (dp->name == NULL)
2212 switch (dp->bytemode1)
2214 case USE_GROUPS:
2215 dp = &grps[dp->bytemode2][reg];
2216 break;
2218 case USE_PREFIX_USER_TABLE:
2219 index = 0;
2220 used_prefixes |= (prefixes & PREFIX_REPZ);
2221 if (prefixes & PREFIX_REPZ)
2222 index = 1;
2223 else
2225 used_prefixes |= (prefixes & PREFIX_DATA);
2226 if (prefixes & PREFIX_DATA)
2227 index = 2;
2228 else
2230 used_prefixes |= (prefixes & PREFIX_REPNZ);
2231 if (prefixes & PREFIX_REPNZ)
2232 index = 3;
2235 dp = &prefix_user_table[dp->bytemode2][index];
2236 break;
2238 case X86_64_SPECIAL:
2239 dp = &x86_64_table[dp->bytemode2][mode_64bit];
2240 break;
2242 default:
2243 oappend (INTERNAL_DISASSEMBLER_ERROR);
2244 break;
2248 if (putop (dp->name, sizeflag) == 0)
2250 obufp = op1out;
2251 op_ad = 2;
2252 if (dp->op1)
2253 (*dp->op1) (dp->bytemode1, sizeflag);
2255 obufp = op2out;
2256 op_ad = 1;
2257 if (dp->op2)
2258 (*dp->op2) (dp->bytemode2, sizeflag);
2260 obufp = op3out;
2261 op_ad = 0;
2262 if (dp->op3)
2263 (*dp->op3) (dp->bytemode3, sizeflag);
2267 /* See if any prefixes were not used. If so, print the first one
2268 separately. If we don't do this, we'll wind up printing an
2269 instruction stream which does not precisely correspond to the
2270 bytes we are disassembling. */
2271 if ((prefixes & ~used_prefixes) != 0)
2273 const char *name;
2275 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2276 if (name == NULL)
2277 name = INTERNAL_DISASSEMBLER_ERROR;
2278 (*info->fprintf_func) (info->stream, "%s", name);
2279 return 1;
2281 if (rex & ~rex_used)
2283 const char *name;
2284 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
2285 if (name == NULL)
2286 name = INTERNAL_DISASSEMBLER_ERROR;
2287 (*info->fprintf_func) (info->stream, "%s ", name);
2290 obufp = obuf + strlen (obuf);
2291 for (i = strlen (obuf); i < 6; i++)
2292 oappend (" ");
2293 oappend (" ");
2294 (*info->fprintf_func) (info->stream, "%s", obuf);
2296 /* The enter and bound instructions are printed with operands in the same
2297 order as the intel book; everything else is printed in reverse order. */
2298 if (intel_syntax || two_source_ops)
2300 first = op1out;
2301 second = op2out;
2302 third = op3out;
2303 op_ad = op_index[0];
2304 op_index[0] = op_index[2];
2305 op_index[2] = op_ad;
2307 else
2309 first = op3out;
2310 second = op2out;
2311 third = op1out;
2313 needcomma = 0;
2314 if (*first)
2316 if (op_index[0] != -1 && !op_riprel[0])
2317 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
2318 else
2319 (*info->fprintf_func) (info->stream, "%s", first);
2320 needcomma = 1;
2322 if (*second)
2324 if (needcomma)
2325 (*info->fprintf_func) (info->stream, ",");
2326 if (op_index[1] != -1 && !op_riprel[1])
2327 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
2328 else
2329 (*info->fprintf_func) (info->stream, "%s", second);
2330 needcomma = 1;
2332 if (*third)
2334 if (needcomma)
2335 (*info->fprintf_func) (info->stream, ",");
2336 if (op_index[2] != -1 && !op_riprel[2])
2337 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
2338 else
2339 (*info->fprintf_func) (info->stream, "%s", third);
2341 for (i = 0; i < 3; i++)
2342 if (op_index[i] != -1 && op_riprel[i])
2344 (*info->fprintf_func) (info->stream, " # ");
2345 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
2346 + op_address[op_index[i]]), info);
2348 return codep - priv.the_buffer;
2351 static const char *float_mem[] = {
2352 /* d8 */
2353 "fadd{s||s|}",
2354 "fmul{s||s|}",
2355 "fcom{s||s|}",
2356 "fcomp{s||s|}",
2357 "fsub{s||s|}",
2358 "fsubr{s||s|}",
2359 "fdiv{s||s|}",
2360 "fdivr{s||s|}",
2361 /* d9 */
2362 "fld{s||s|}",
2363 "(bad)",
2364 "fst{s||s|}",
2365 "fstp{s||s|}",
2366 "fldenvIC",
2367 "fldcw",
2368 "fNstenvIC",
2369 "fNstcw",
2370 /* da */
2371 "fiadd{l||l|}",
2372 "fimul{l||l|}",
2373 "ficom{l||l|}",
2374 "ficomp{l||l|}",
2375 "fisub{l||l|}",
2376 "fisubr{l||l|}",
2377 "fidiv{l||l|}",
2378 "fidivr{l||l|}",
2379 /* db */
2380 "fild{l||l|}",
2381 "fisttp{l||l|}",
2382 "fist{l||l|}",
2383 "fistp{l||l|}",
2384 "(bad)",
2385 "fld{t||t|}",
2386 "(bad)",
2387 "fstp{t||t|}",
2388 /* dc */
2389 "fadd{l||l|}",
2390 "fmul{l||l|}",
2391 "fcom{l||l|}",
2392 "fcomp{l||l|}",
2393 "fsub{l||l|}",
2394 "fsubr{l||l|}",
2395 "fdiv{l||l|}",
2396 "fdivr{l||l|}",
2397 /* dd */
2398 "fld{l||l|}",
2399 "fisttp{ll||ll|}",
2400 "fst{l||l|}",
2401 "fstp{l||l|}",
2402 "frstorIC",
2403 "(bad)",
2404 "fNsaveIC",
2405 "fNstsw",
2406 /* de */
2407 "fiadd",
2408 "fimul",
2409 "ficom",
2410 "ficomp",
2411 "fisub",
2412 "fisubr",
2413 "fidiv",
2414 "fidivr",
2415 /* df */
2416 "fild",
2417 "fisttp",
2418 "fist",
2419 "fistp",
2420 "fbld",
2421 "fild{ll||ll|}",
2422 "fbstp",
2423 "fistp{ll||ll|}",
2426 static const unsigned char float_mem_mode[] = {
2427 /* d8 */
2428 d_mode,
2429 d_mode,
2430 d_mode,
2431 d_mode,
2432 d_mode,
2433 d_mode,
2434 d_mode,
2435 d_mode,
2436 /* d9 */
2437 d_mode,
2439 d_mode,
2440 d_mode,
2442 w_mode,
2444 w_mode,
2445 /* da */
2446 d_mode,
2447 d_mode,
2448 d_mode,
2449 d_mode,
2450 d_mode,
2451 d_mode,
2452 d_mode,
2453 d_mode,
2454 /* db */
2455 d_mode,
2456 d_mode,
2457 d_mode,
2458 d_mode,
2460 t_mode,
2462 t_mode,
2463 /* dc */
2464 q_mode,
2465 q_mode,
2466 q_mode,
2467 q_mode,
2468 q_mode,
2469 q_mode,
2470 q_mode,
2471 q_mode,
2472 /* dd */
2473 q_mode,
2474 q_mode,
2475 q_mode,
2476 q_mode,
2480 w_mode,
2481 /* de */
2482 w_mode,
2483 w_mode,
2484 w_mode,
2485 w_mode,
2486 w_mode,
2487 w_mode,
2488 w_mode,
2489 w_mode,
2490 /* df */
2491 w_mode,
2492 w_mode,
2493 w_mode,
2494 w_mode,
2495 t_mode,
2496 q_mode,
2497 t_mode,
2498 q_mode
2501 #define ST OP_ST, 0
2502 #define STi OP_STi, 0
2504 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
2505 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
2506 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
2507 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
2508 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
2509 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
2510 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
2511 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
2512 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
2514 static const struct dis386 float_reg[][8] = {
2515 /* d8 */
2517 { "fadd", ST, STi, XX },
2518 { "fmul", ST, STi, XX },
2519 { "fcom", STi, XX, XX },
2520 { "fcomp", STi, XX, XX },
2521 { "fsub", ST, STi, XX },
2522 { "fsubr", ST, STi, XX },
2523 { "fdiv", ST, STi, XX },
2524 { "fdivr", ST, STi, XX },
2526 /* d9 */
2528 { "fld", STi, XX, XX },
2529 { "fxch", STi, XX, XX },
2530 { FGRPd9_2 },
2531 { "(bad)", XX, XX, XX },
2532 { FGRPd9_4 },
2533 { FGRPd9_5 },
2534 { FGRPd9_6 },
2535 { FGRPd9_7 },
2537 /* da */
2539 { "fcmovb", ST, STi, XX },
2540 { "fcmove", ST, STi, XX },
2541 { "fcmovbe",ST, STi, XX },
2542 { "fcmovu", ST, STi, XX },
2543 { "(bad)", XX, XX, XX },
2544 { FGRPda_5 },
2545 { "(bad)", XX, XX, XX },
2546 { "(bad)", XX, XX, XX },
2548 /* db */
2550 { "fcmovnb",ST, STi, XX },
2551 { "fcmovne",ST, STi, XX },
2552 { "fcmovnbe",ST, STi, XX },
2553 { "fcmovnu",ST, STi, XX },
2554 { FGRPdb_4 },
2555 { "fucomi", ST, STi, XX },
2556 { "fcomi", ST, STi, XX },
2557 { "(bad)", XX, XX, XX },
2559 /* dc */
2561 { "fadd", STi, ST, XX },
2562 { "fmul", STi, ST, XX },
2563 { "(bad)", XX, XX, XX },
2564 { "(bad)", XX, XX, XX },
2565 #if UNIXWARE_COMPAT
2566 { "fsub", STi, ST, XX },
2567 { "fsubr", STi, ST, XX },
2568 { "fdiv", STi, ST, XX },
2569 { "fdivr", STi, ST, XX },
2570 #else
2571 { "fsubr", STi, ST, XX },
2572 { "fsub", STi, ST, XX },
2573 { "fdivr", STi, ST, XX },
2574 { "fdiv", STi, ST, XX },
2575 #endif
2577 /* dd */
2579 { "ffree", STi, XX, XX },
2580 { "(bad)", XX, XX, XX },
2581 { "fst", STi, XX, XX },
2582 { "fstp", STi, XX, XX },
2583 { "fucom", STi, XX, XX },
2584 { "fucomp", STi, XX, XX },
2585 { "(bad)", XX, XX, XX },
2586 { "(bad)", XX, XX, XX },
2588 /* de */
2590 { "faddp", STi, ST, XX },
2591 { "fmulp", STi, ST, XX },
2592 { "(bad)", XX, XX, XX },
2593 { FGRPde_3 },
2594 #if UNIXWARE_COMPAT
2595 { "fsubp", STi, ST, XX },
2596 { "fsubrp", STi, ST, XX },
2597 { "fdivp", STi, ST, XX },
2598 { "fdivrp", STi, ST, XX },
2599 #else
2600 { "fsubrp", STi, ST, XX },
2601 { "fsubp", STi, ST, XX },
2602 { "fdivrp", STi, ST, XX },
2603 { "fdivp", STi, ST, XX },
2604 #endif
2606 /* df */
2608 { "ffreep", STi, XX, XX },
2609 { "(bad)", XX, XX, XX },
2610 { "(bad)", XX, XX, XX },
2611 { "(bad)", XX, XX, XX },
2612 { FGRPdf_4 },
2613 { "fucomip",ST, STi, XX },
2614 { "fcomip", ST, STi, XX },
2615 { "(bad)", XX, XX, XX },
2619 static char *fgrps[][8] = {
2620 /* d9_2 0 */
2622 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2625 /* d9_4 1 */
2627 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2630 /* d9_5 2 */
2632 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2635 /* d9_6 3 */
2637 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2640 /* d9_7 4 */
2642 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2645 /* da_5 5 */
2647 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2650 /* db_4 6 */
2652 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2653 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2656 /* de_3 7 */
2658 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2661 /* df_4 8 */
2663 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2667 static void
2668 dofloat (int sizeflag)
2670 const struct dis386 *dp;
2671 unsigned char floatop;
2673 floatop = codep[-1];
2675 if (mod != 3)
2677 int fp_indx = (floatop - 0xd8) * 8 + reg;
2679 putop (float_mem[fp_indx], sizeflag);
2680 obufp = op1out;
2681 OP_E (float_mem_mode[fp_indx], sizeflag);
2682 return;
2684 /* Skip mod/rm byte. */
2685 MODRM_CHECK;
2686 codep++;
2688 dp = &float_reg[floatop - 0xd8][reg];
2689 if (dp->name == NULL)
2691 putop (fgrps[dp->bytemode1][rm], sizeflag);
2693 /* Instruction fnstsw is only one with strange arg. */
2694 if (floatop == 0xdf && codep[-1] == 0xe0)
2695 strcpy (op1out, names16[0]);
2697 else
2699 putop (dp->name, sizeflag);
2701 obufp = op1out;
2702 if (dp->op1)
2703 (*dp->op1) (dp->bytemode1, sizeflag);
2704 obufp = op2out;
2705 if (dp->op2)
2706 (*dp->op2) (dp->bytemode2, sizeflag);
2710 static void
2711 OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
2713 oappend ("%st");
2716 static void
2717 OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
2719 sprintf (scratchbuf, "%%st(%d)", rm);
2720 oappend (scratchbuf + intel_syntax);
2723 /* Capital letters in template are macros. */
2724 static int
2725 putop (const char *template, int sizeflag)
2727 const char *p;
2728 int alt = 0;
2730 for (p = template; *p; p++)
2732 switch (*p)
2734 default:
2735 *obufp++ = *p;
2736 break;
2737 case '{':
2738 alt = 0;
2739 if (intel_syntax)
2740 alt += 1;
2741 if (mode_64bit)
2742 alt += 2;
2743 while (alt != 0)
2745 while (*++p != '|')
2747 if (*p == '}')
2749 /* Alternative not valid. */
2750 strcpy (obuf, "(bad)");
2751 obufp = obuf + 5;
2752 return 1;
2754 else if (*p == '\0')
2755 abort ();
2757 alt--;
2759 /* Fall through. */
2760 case 'I':
2761 alt = 1;
2762 continue;
2763 case '|':
2764 while (*++p != '}')
2766 if (*p == '\0')
2767 abort ();
2769 break;
2770 case '}':
2771 break;
2772 case 'A':
2773 if (intel_syntax)
2774 break;
2775 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2776 *obufp++ = 'b';
2777 break;
2778 case 'B':
2779 if (intel_syntax)
2780 break;
2781 if (sizeflag & SUFFIX_ALWAYS)
2782 *obufp++ = 'b';
2783 break;
2784 case 'C':
2785 if (intel_syntax && !alt)
2786 break;
2787 if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
2789 if (sizeflag & DFLAG)
2790 *obufp++ = intel_syntax ? 'd' : 'l';
2791 else
2792 *obufp++ = intel_syntax ? 'w' : 's';
2793 used_prefixes |= (prefixes & PREFIX_DATA);
2795 break;
2796 case 'E': /* For jcxz/jecxz */
2797 if (mode_64bit)
2799 if (sizeflag & AFLAG)
2800 *obufp++ = 'r';
2801 else
2802 *obufp++ = 'e';
2804 else
2805 if (sizeflag & AFLAG)
2806 *obufp++ = 'e';
2807 used_prefixes |= (prefixes & PREFIX_ADDR);
2808 break;
2809 case 'F':
2810 if (intel_syntax)
2811 break;
2812 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
2814 if (sizeflag & AFLAG)
2815 *obufp++ = mode_64bit ? 'q' : 'l';
2816 else
2817 *obufp++ = mode_64bit ? 'l' : 'w';
2818 used_prefixes |= (prefixes & PREFIX_ADDR);
2820 break;
2821 case 'H':
2822 if (intel_syntax)
2823 break;
2824 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
2825 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
2827 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
2828 *obufp++ = ',';
2829 *obufp++ = 'p';
2830 if (prefixes & PREFIX_DS)
2831 *obufp++ = 't';
2832 else
2833 *obufp++ = 'n';
2835 break;
2836 case 'J':
2837 if (intel_syntax)
2838 break;
2839 *obufp++ = 'l';
2840 break;
2841 case 'L':
2842 if (intel_syntax)
2843 break;
2844 if (sizeflag & SUFFIX_ALWAYS)
2845 *obufp++ = 'l';
2846 break;
2847 case 'N':
2848 if ((prefixes & PREFIX_FWAIT) == 0)
2849 *obufp++ = 'n';
2850 else
2851 used_prefixes |= PREFIX_FWAIT;
2852 break;
2853 case 'O':
2854 USED_REX (REX_MODE64);
2855 if (rex & REX_MODE64)
2856 *obufp++ = 'o';
2857 else
2858 *obufp++ = 'd';
2859 break;
2860 case 'T':
2861 if (intel_syntax)
2862 break;
2863 if (mode_64bit && (sizeflag & DFLAG))
2865 *obufp++ = 'q';
2866 break;
2868 /* Fall through. */
2869 case 'P':
2870 if (intel_syntax)
2871 break;
2872 if ((prefixes & PREFIX_DATA)
2873 || (rex & REX_MODE64)
2874 || (sizeflag & SUFFIX_ALWAYS))
2876 USED_REX (REX_MODE64);
2877 if (rex & REX_MODE64)
2878 *obufp++ = 'q';
2879 else
2881 if (sizeflag & DFLAG)
2882 *obufp++ = 'l';
2883 else
2884 *obufp++ = 'w';
2886 used_prefixes |= (prefixes & PREFIX_DATA);
2888 break;
2889 case 'U':
2890 if (intel_syntax)
2891 break;
2892 if (mode_64bit && (sizeflag & DFLAG))
2894 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2895 *obufp++ = 'q';
2896 break;
2898 /* Fall through. */
2899 case 'Q':
2900 if (intel_syntax && !alt)
2901 break;
2902 USED_REX (REX_MODE64);
2903 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2905 if (rex & REX_MODE64)
2906 *obufp++ = 'q';
2907 else
2909 if (sizeflag & DFLAG)
2910 *obufp++ = intel_syntax ? 'd' : 'l';
2911 else
2912 *obufp++ = 'w';
2914 used_prefixes |= (prefixes & PREFIX_DATA);
2916 break;
2917 case 'R':
2918 USED_REX (REX_MODE64);
2919 if (intel_syntax)
2921 if (rex & REX_MODE64)
2923 *obufp++ = 'q';
2924 *obufp++ = 't';
2926 else if (sizeflag & DFLAG)
2928 *obufp++ = 'd';
2929 *obufp++ = 'q';
2931 else
2933 *obufp++ = 'w';
2934 *obufp++ = 'd';
2937 else
2939 if (rex & REX_MODE64)
2940 *obufp++ = 'q';
2941 else if (sizeflag & DFLAG)
2942 *obufp++ = 'l';
2943 else
2944 *obufp++ = 'w';
2946 if (!(rex & REX_MODE64))
2947 used_prefixes |= (prefixes & PREFIX_DATA);
2948 break;
2949 case 'V':
2950 if (intel_syntax)
2951 break;
2952 if (mode_64bit && (sizeflag & DFLAG))
2954 if (sizeflag & SUFFIX_ALWAYS)
2955 *obufp++ = 'q';
2956 break;
2958 /* Fall through. */
2959 case 'S':
2960 if (intel_syntax)
2961 break;
2962 if (sizeflag & SUFFIX_ALWAYS)
2964 if (rex & REX_MODE64)
2965 *obufp++ = 'q';
2966 else
2968 if (sizeflag & DFLAG)
2969 *obufp++ = 'l';
2970 else
2971 *obufp++ = 'w';
2972 used_prefixes |= (prefixes & PREFIX_DATA);
2975 break;
2976 case 'X':
2977 if (prefixes & PREFIX_DATA)
2978 *obufp++ = 'd';
2979 else
2980 *obufp++ = 's';
2981 used_prefixes |= (prefixes & PREFIX_DATA);
2982 break;
2983 case 'Y':
2984 if (intel_syntax)
2985 break;
2986 if (rex & REX_MODE64)
2988 USED_REX (REX_MODE64);
2989 *obufp++ = 'q';
2991 break;
2992 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
2993 case 'W':
2994 /* operand size flag for cwtl, cbtw */
2995 USED_REX (0);
2996 if (rex)
2997 *obufp++ = 'l';
2998 else if (sizeflag & DFLAG)
2999 *obufp++ = 'w';
3000 else
3001 *obufp++ = 'b';
3002 if (intel_syntax)
3004 if (rex)
3006 *obufp++ = 'q';
3007 *obufp++ = 'e';
3009 if (sizeflag & DFLAG)
3011 *obufp++ = 'd';
3012 *obufp++ = 'e';
3014 else
3016 *obufp++ = 'w';
3019 if (!rex)
3020 used_prefixes |= (prefixes & PREFIX_DATA);
3021 break;
3023 alt = 0;
3025 *obufp = 0;
3026 return 0;
3029 static void
3030 oappend (const char *s)
3032 strcpy (obufp, s);
3033 obufp += strlen (s);
3036 static void
3037 append_seg (void)
3039 if (prefixes & PREFIX_CS)
3041 used_prefixes |= PREFIX_CS;
3042 oappend ("%cs:" + intel_syntax);
3044 if (prefixes & PREFIX_DS)
3046 used_prefixes |= PREFIX_DS;
3047 oappend ("%ds:" + intel_syntax);
3049 if (prefixes & PREFIX_SS)
3051 used_prefixes |= PREFIX_SS;
3052 oappend ("%ss:" + intel_syntax);
3054 if (prefixes & PREFIX_ES)
3056 used_prefixes |= PREFIX_ES;
3057 oappend ("%es:" + intel_syntax);
3059 if (prefixes & PREFIX_FS)
3061 used_prefixes |= PREFIX_FS;
3062 oappend ("%fs:" + intel_syntax);
3064 if (prefixes & PREFIX_GS)
3066 used_prefixes |= PREFIX_GS;
3067 oappend ("%gs:" + intel_syntax);
3071 static void
3072 OP_indirE (int bytemode, int sizeflag)
3074 if (!intel_syntax)
3075 oappend ("*");
3076 OP_E (bytemode, sizeflag);
3079 static void
3080 print_operand_value (char *buf, int hex, bfd_vma disp)
3082 if (mode_64bit)
3084 if (hex)
3086 char tmp[30];
3087 int i;
3088 buf[0] = '0';
3089 buf[1] = 'x';
3090 sprintf_vma (tmp, disp);
3091 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
3092 strcpy (buf + 2, tmp + i);
3094 else
3096 bfd_signed_vma v = disp;
3097 char tmp[30];
3098 int i;
3099 if (v < 0)
3101 *(buf++) = '-';
3102 v = -disp;
3103 /* Check for possible overflow on 0x8000000000000000. */
3104 if (v < 0)
3106 strcpy (buf, "9223372036854775808");
3107 return;
3110 if (!v)
3112 strcpy (buf, "0");
3113 return;
3116 i = 0;
3117 tmp[29] = 0;
3118 while (v)
3120 tmp[28 - i] = (v % 10) + '0';
3121 v /= 10;
3122 i++;
3124 strcpy (buf, tmp + 29 - i);
3127 else
3129 if (hex)
3130 sprintf (buf, "0x%x", (unsigned int) disp);
3131 else
3132 sprintf (buf, "%d", (int) disp);
3136 static void
3137 intel_operand_size (int bytemode, int sizeflag)
3139 switch (bytemode)
3141 case b_mode:
3142 oappend ("BYTE PTR ");
3143 break;
3144 case w_mode:
3145 case dqw_mode:
3146 oappend ("WORD PTR ");
3147 break;
3148 case stack_v_mode:
3149 if (mode_64bit && (sizeflag & DFLAG))
3151 oappend ("QWORD PTR ");
3152 used_prefixes |= (prefixes & PREFIX_DATA);
3153 break;
3155 /* FALLTHRU */
3156 case v_mode:
3157 case dq_mode:
3158 USED_REX (REX_MODE64);
3159 if (rex & REX_MODE64)
3160 oappend ("QWORD PTR ");
3161 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
3162 oappend ("DWORD PTR ");
3163 else
3164 oappend ("WORD PTR ");
3165 used_prefixes |= (prefixes & PREFIX_DATA);
3166 break;
3167 case d_mode:
3168 oappend ("DWORD PTR ");
3169 break;
3170 case q_mode:
3171 oappend ("QWORD PTR ");
3172 break;
3173 case m_mode:
3174 if (mode_64bit)
3175 oappend ("QWORD PTR ");
3176 else
3177 oappend ("DWORD PTR ");
3178 break;
3179 case f_mode:
3180 if (sizeflag & DFLAG)
3181 oappend ("FWORD PTR ");
3182 else
3183 oappend ("DWORD PTR ");
3184 used_prefixes |= (prefixes & PREFIX_DATA);
3185 break;
3186 case t_mode:
3187 oappend ("TBYTE PTR ");
3188 break;
3189 case x_mode:
3190 oappend ("XMMWORD PTR ");
3191 break;
3192 default:
3193 break;
3197 static void
3198 OP_E (int bytemode, int sizeflag)
3200 bfd_vma disp;
3201 int add = 0;
3202 int riprel = 0;
3203 USED_REX (REX_EXTZ);
3204 if (rex & REX_EXTZ)
3205 add += 8;
3207 /* Skip mod/rm byte. */
3208 MODRM_CHECK;
3209 codep++;
3211 if (mod == 3)
3213 switch (bytemode)
3215 case b_mode:
3216 USED_REX (0);
3217 if (rex)
3218 oappend (names8rex[rm + add]);
3219 else
3220 oappend (names8[rm + add]);
3221 break;
3222 case w_mode:
3223 oappend (names16[rm + add]);
3224 break;
3225 case d_mode:
3226 oappend (names32[rm + add]);
3227 break;
3228 case q_mode:
3229 oappend (names64[rm + add]);
3230 break;
3231 case m_mode:
3232 if (mode_64bit)
3233 oappend (names64[rm + add]);
3234 else
3235 oappend (names32[rm + add]);
3236 break;
3237 case stack_v_mode:
3238 if (mode_64bit && (sizeflag & DFLAG))
3240 oappend (names64[rm + add]);
3241 used_prefixes |= (prefixes & PREFIX_DATA);
3242 break;
3244 bytemode = v_mode;
3245 /* FALLTHRU */
3246 case v_mode:
3247 case dq_mode:
3248 case dqw_mode:
3249 USED_REX (REX_MODE64);
3250 if (rex & REX_MODE64)
3251 oappend (names64[rm + add]);
3252 else if ((sizeflag & DFLAG) || bytemode != v_mode)
3253 oappend (names32[rm + add]);
3254 else
3255 oappend (names16[rm + add]);
3256 used_prefixes |= (prefixes & PREFIX_DATA);
3257 break;
3258 case 0:
3259 break;
3260 default:
3261 oappend (INTERNAL_DISASSEMBLER_ERROR);
3262 break;
3264 return;
3267 disp = 0;
3268 if (intel_syntax)
3269 intel_operand_size (bytemode, sizeflag);
3270 append_seg ();
3272 if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
3274 int havesib;
3275 int havebase;
3276 int base;
3277 int index = 0;
3278 int scale = 0;
3280 havesib = 0;
3281 havebase = 1;
3282 base = rm;
3284 if (base == 4)
3286 havesib = 1;
3287 FETCH_DATA (the_info, codep + 1);
3288 index = (*codep >> 3) & 7;
3289 if (mode_64bit || index != 0x4)
3290 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
3291 scale = (*codep >> 6) & 3;
3292 base = *codep & 7;
3293 USED_REX (REX_EXTY);
3294 if (rex & REX_EXTY)
3295 index += 8;
3296 codep++;
3298 base += add;
3300 switch (mod)
3302 case 0:
3303 if ((base & 7) == 5)
3305 havebase = 0;
3306 if (mode_64bit && !havesib)
3307 riprel = 1;
3308 disp = get32s ();
3310 break;
3311 case 1:
3312 FETCH_DATA (the_info, codep + 1);
3313 disp = *codep++;
3314 if ((disp & 0x80) != 0)
3315 disp -= 0x100;
3316 break;
3317 case 2:
3318 disp = get32s ();
3319 break;
3322 if (!intel_syntax)
3323 if (mod != 0 || (base & 7) == 5)
3325 print_operand_value (scratchbuf, !riprel, disp);
3326 oappend (scratchbuf);
3327 if (riprel)
3329 set_op (disp, 1);
3330 oappend ("(%rip)");
3334 if (havebase || (havesib && (index != 4 || scale != 0)))
3336 *obufp++ = open_char;
3337 if (intel_syntax && riprel)
3338 oappend ("rip + ");
3339 *obufp = '\0';
3340 if (havebase)
3341 oappend (mode_64bit && (sizeflag & AFLAG)
3342 ? names64[base] : names32[base]);
3343 if (havesib)
3345 if (index != 4)
3347 if (!intel_syntax || havebase)
3349 *obufp++ = separator_char;
3350 *obufp = '\0';
3352 oappend (mode_64bit && (sizeflag & AFLAG)
3353 ? names64[index] : names32[index]);
3355 if (scale != 0 || (!intel_syntax && index != 4))
3357 *obufp++ = scale_char;
3358 *obufp = '\0';
3359 sprintf (scratchbuf, "%d", 1 << scale);
3360 oappend (scratchbuf);
3363 if (intel_syntax && disp)
3365 if ((bfd_signed_vma) disp > 0)
3367 *obufp++ = '+';
3368 *obufp = '\0';
3370 else if (mod != 1)
3372 *obufp++ = '-';
3373 *obufp = '\0';
3374 disp = - (bfd_signed_vma) disp;
3377 print_operand_value (scratchbuf, mod != 1, disp);
3378 oappend (scratchbuf);
3381 *obufp++ = close_char;
3382 *obufp = '\0';
3384 else if (intel_syntax)
3386 if (mod != 0 || (base & 7) == 5)
3388 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3389 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
3391 else
3393 oappend (names_seg[ds_reg - es_reg]);
3394 oappend (":");
3396 print_operand_value (scratchbuf, 1, disp);
3397 oappend (scratchbuf);
3401 else
3402 { /* 16 bit address mode */
3403 switch (mod)
3405 case 0:
3406 if (rm == 6)
3408 disp = get16 ();
3409 if ((disp & 0x8000) != 0)
3410 disp -= 0x10000;
3412 break;
3413 case 1:
3414 FETCH_DATA (the_info, codep + 1);
3415 disp = *codep++;
3416 if ((disp & 0x80) != 0)
3417 disp -= 0x100;
3418 break;
3419 case 2:
3420 disp = get16 ();
3421 if ((disp & 0x8000) != 0)
3422 disp -= 0x10000;
3423 break;
3426 if (!intel_syntax)
3427 if (mod != 0 || rm == 6)
3429 print_operand_value (scratchbuf, 0, disp);
3430 oappend (scratchbuf);
3433 if (mod != 0 || rm != 6)
3435 *obufp++ = open_char;
3436 *obufp = '\0';
3437 oappend (index16[rm]);
3438 if (intel_syntax && disp)
3440 if ((bfd_signed_vma) disp > 0)
3442 *obufp++ = '+';
3443 *obufp = '\0';
3445 else if (mod != 1)
3447 *obufp++ = '-';
3448 *obufp = '\0';
3449 disp = - (bfd_signed_vma) disp;
3452 print_operand_value (scratchbuf, mod != 1, disp);
3453 oappend (scratchbuf);
3456 *obufp++ = close_char;
3457 *obufp = '\0';
3459 else if (intel_syntax)
3461 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3462 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
3464 else
3466 oappend (names_seg[ds_reg - es_reg]);
3467 oappend (":");
3469 print_operand_value (scratchbuf, 1, disp & 0xffff);
3470 oappend (scratchbuf);
3475 static void
3476 OP_G (int bytemode, int sizeflag)
3478 int add = 0;
3479 USED_REX (REX_EXTX);
3480 if (rex & REX_EXTX)
3481 add += 8;
3482 switch (bytemode)
3484 case b_mode:
3485 USED_REX (0);
3486 if (rex)
3487 oappend (names8rex[reg + add]);
3488 else
3489 oappend (names8[reg + add]);
3490 break;
3491 case w_mode:
3492 oappend (names16[reg + add]);
3493 break;
3494 case d_mode:
3495 oappend (names32[reg + add]);
3496 break;
3497 case q_mode:
3498 oappend (names64[reg + add]);
3499 break;
3500 case v_mode:
3501 case dq_mode:
3502 case dqw_mode:
3503 USED_REX (REX_MODE64);
3504 if (rex & REX_MODE64)
3505 oappend (names64[reg + add]);
3506 else if ((sizeflag & DFLAG) || bytemode != v_mode)
3507 oappend (names32[reg + add]);
3508 else
3509 oappend (names16[reg + add]);
3510 used_prefixes |= (prefixes & PREFIX_DATA);
3511 break;
3512 case m_mode:
3513 if (mode_64bit)
3514 oappend (names64[reg + add]);
3515 else
3516 oappend (names32[reg + add]);
3517 break;
3518 default:
3519 oappend (INTERNAL_DISASSEMBLER_ERROR);
3520 break;
3524 static bfd_vma
3525 get64 (void)
3527 bfd_vma x;
3528 #ifdef BFD64
3529 unsigned int a;
3530 unsigned int b;
3532 FETCH_DATA (the_info, codep + 8);
3533 a = *codep++ & 0xff;
3534 a |= (*codep++ & 0xff) << 8;
3535 a |= (*codep++ & 0xff) << 16;
3536 a |= (*codep++ & 0xff) << 24;
3537 b = *codep++ & 0xff;
3538 b |= (*codep++ & 0xff) << 8;
3539 b |= (*codep++ & 0xff) << 16;
3540 b |= (*codep++ & 0xff) << 24;
3541 x = a + ((bfd_vma) b << 32);
3542 #else
3543 abort ();
3544 x = 0;
3545 #endif
3546 return x;
3549 static bfd_signed_vma
3550 get32 (void)
3552 bfd_signed_vma x = 0;
3554 FETCH_DATA (the_info, codep + 4);
3555 x = *codep++ & (bfd_signed_vma) 0xff;
3556 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3557 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3558 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3559 return x;
3562 static bfd_signed_vma
3563 get32s (void)
3565 bfd_signed_vma x = 0;
3567 FETCH_DATA (the_info, codep + 4);
3568 x = *codep++ & (bfd_signed_vma) 0xff;
3569 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3570 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3571 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3573 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
3575 return x;
3578 static int
3579 get16 (void)
3581 int x = 0;
3583 FETCH_DATA (the_info, codep + 2);
3584 x = *codep++ & 0xff;
3585 x |= (*codep++ & 0xff) << 8;
3586 return x;
3589 static void
3590 set_op (bfd_vma op, int riprel)
3592 op_index[op_ad] = op_ad;
3593 if (mode_64bit)
3595 op_address[op_ad] = op;
3596 op_riprel[op_ad] = riprel;
3598 else
3600 /* Mask to get a 32-bit address. */
3601 op_address[op_ad] = op & 0xffffffff;
3602 op_riprel[op_ad] = riprel & 0xffffffff;
3606 static void
3607 OP_REG (int code, int sizeflag)
3609 const char *s;
3610 int add = 0;
3611 USED_REX (REX_EXTZ);
3612 if (rex & REX_EXTZ)
3613 add = 8;
3615 switch (code)
3617 case indir_dx_reg:
3618 if (intel_syntax)
3619 s = "[dx]";
3620 else
3621 s = "(%dx)";
3622 break;
3623 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3624 case sp_reg: case bp_reg: case si_reg: case di_reg:
3625 s = names16[code - ax_reg + add];
3626 break;
3627 case es_reg: case ss_reg: case cs_reg:
3628 case ds_reg: case fs_reg: case gs_reg:
3629 s = names_seg[code - es_reg + add];
3630 break;
3631 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3632 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3633 USED_REX (0);
3634 if (rex)
3635 s = names8rex[code - al_reg + add];
3636 else
3637 s = names8[code - al_reg];
3638 break;
3639 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
3640 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
3641 if (mode_64bit && (sizeflag & DFLAG))
3643 s = names64[code - rAX_reg + add];
3644 break;
3646 code += eAX_reg - rAX_reg;
3647 /* Fall through. */
3648 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3649 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3650 USED_REX (REX_MODE64);
3651 if (rex & REX_MODE64)
3652 s = names64[code - eAX_reg + add];
3653 else if (sizeflag & DFLAG)
3654 s = names32[code - eAX_reg + add];
3655 else
3656 s = names16[code - eAX_reg + add];
3657 used_prefixes |= (prefixes & PREFIX_DATA);
3658 break;
3659 default:
3660 s = INTERNAL_DISASSEMBLER_ERROR;
3661 break;
3663 oappend (s);
3666 static void
3667 OP_IMREG (int code, int sizeflag)
3669 const char *s;
3671 switch (code)
3673 case indir_dx_reg:
3674 if (intel_syntax)
3675 s = "[dx]";
3676 else
3677 s = "(%dx)";
3678 break;
3679 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3680 case sp_reg: case bp_reg: case si_reg: case di_reg:
3681 s = names16[code - ax_reg];
3682 break;
3683 case es_reg: case ss_reg: case cs_reg:
3684 case ds_reg: case fs_reg: case gs_reg:
3685 s = names_seg[code - es_reg];
3686 break;
3687 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3688 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3689 USED_REX (0);
3690 if (rex)
3691 s = names8rex[code - al_reg];
3692 else
3693 s = names8[code - al_reg];
3694 break;
3695 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3696 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3697 USED_REX (REX_MODE64);
3698 if (rex & REX_MODE64)
3699 s = names64[code - eAX_reg];
3700 else if (sizeflag & DFLAG)
3701 s = names32[code - eAX_reg];
3702 else
3703 s = names16[code - eAX_reg];
3704 used_prefixes |= (prefixes & PREFIX_DATA);
3705 break;
3706 default:
3707 s = INTERNAL_DISASSEMBLER_ERROR;
3708 break;
3710 oappend (s);
3713 static void
3714 OP_I (int bytemode, int sizeflag)
3716 bfd_signed_vma op;
3717 bfd_signed_vma mask = -1;
3719 switch (bytemode)
3721 case b_mode:
3722 FETCH_DATA (the_info, codep + 1);
3723 op = *codep++;
3724 mask = 0xff;
3725 break;
3726 case q_mode:
3727 if (mode_64bit)
3729 op = get32s ();
3730 break;
3732 /* Fall through. */
3733 case v_mode:
3734 USED_REX (REX_MODE64);
3735 if (rex & REX_MODE64)
3736 op = get32s ();
3737 else if (sizeflag & DFLAG)
3739 op = get32 ();
3740 mask = 0xffffffff;
3742 else
3744 op = get16 ();
3745 mask = 0xfffff;
3747 used_prefixes |= (prefixes & PREFIX_DATA);
3748 break;
3749 case w_mode:
3750 mask = 0xfffff;
3751 op = get16 ();
3752 break;
3753 case const_1_mode:
3754 if (intel_syntax)
3755 oappend ("1");
3756 return;
3757 default:
3758 oappend (INTERNAL_DISASSEMBLER_ERROR);
3759 return;
3762 op &= mask;
3763 scratchbuf[0] = '$';
3764 print_operand_value (scratchbuf + 1, 1, op);
3765 oappend (scratchbuf + intel_syntax);
3766 scratchbuf[0] = '\0';
3769 static void
3770 OP_I64 (int bytemode, int sizeflag)
3772 bfd_signed_vma op;
3773 bfd_signed_vma mask = -1;
3775 if (!mode_64bit)
3777 OP_I (bytemode, sizeflag);
3778 return;
3781 switch (bytemode)
3783 case b_mode:
3784 FETCH_DATA (the_info, codep + 1);
3785 op = *codep++;
3786 mask = 0xff;
3787 break;
3788 case v_mode:
3789 USED_REX (REX_MODE64);
3790 if (rex & REX_MODE64)
3791 op = get64 ();
3792 else if (sizeflag & DFLAG)
3794 op = get32 ();
3795 mask = 0xffffffff;
3797 else
3799 op = get16 ();
3800 mask = 0xfffff;
3802 used_prefixes |= (prefixes & PREFIX_DATA);
3803 break;
3804 case w_mode:
3805 mask = 0xfffff;
3806 op = get16 ();
3807 break;
3808 default:
3809 oappend (INTERNAL_DISASSEMBLER_ERROR);
3810 return;
3813 op &= mask;
3814 scratchbuf[0] = '$';
3815 print_operand_value (scratchbuf + 1, 1, op);
3816 oappend (scratchbuf + intel_syntax);
3817 scratchbuf[0] = '\0';
3820 static void
3821 OP_sI (int bytemode, int sizeflag)
3823 bfd_signed_vma op;
3824 bfd_signed_vma mask = -1;
3826 switch (bytemode)
3828 case b_mode:
3829 FETCH_DATA (the_info, codep + 1);
3830 op = *codep++;
3831 if ((op & 0x80) != 0)
3832 op -= 0x100;
3833 mask = 0xffffffff;
3834 break;
3835 case v_mode:
3836 USED_REX (REX_MODE64);
3837 if (rex & REX_MODE64)
3838 op = get32s ();
3839 else if (sizeflag & DFLAG)
3841 op = get32s ();
3842 mask = 0xffffffff;
3844 else
3846 mask = 0xffffffff;
3847 op = get16 ();
3848 if ((op & 0x8000) != 0)
3849 op -= 0x10000;
3851 used_prefixes |= (prefixes & PREFIX_DATA);
3852 break;
3853 case w_mode:
3854 op = get16 ();
3855 mask = 0xffffffff;
3856 if ((op & 0x8000) != 0)
3857 op -= 0x10000;
3858 break;
3859 default:
3860 oappend (INTERNAL_DISASSEMBLER_ERROR);
3861 return;
3864 scratchbuf[0] = '$';
3865 print_operand_value (scratchbuf + 1, 1, op);
3866 oappend (scratchbuf + intel_syntax);
3869 static void
3870 OP_J (int bytemode, int sizeflag)
3872 bfd_vma disp;
3873 bfd_vma mask = -1;
3875 switch (bytemode)
3877 case b_mode:
3878 FETCH_DATA (the_info, codep + 1);
3879 disp = *codep++;
3880 if ((disp & 0x80) != 0)
3881 disp -= 0x100;
3882 break;
3883 case v_mode:
3884 if ((sizeflag & DFLAG) || (rex & REX_MODE64))
3885 disp = get32s ();
3886 else
3888 disp = get16 ();
3889 /* For some reason, a data16 prefix on a jump instruction
3890 means that the pc is masked to 16 bits after the
3891 displacement is added! */
3892 mask = 0xffff;
3894 break;
3895 default:
3896 oappend (INTERNAL_DISASSEMBLER_ERROR);
3897 return;
3899 disp = (start_pc + codep - start_codep + disp) & mask;
3900 set_op (disp, 0);
3901 print_operand_value (scratchbuf, 1, disp);
3902 oappend (scratchbuf);
3905 static void
3906 OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3908 oappend (names_seg[reg]);
3911 static void
3912 OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
3914 int seg, offset;
3916 if (sizeflag & DFLAG)
3918 offset = get32 ();
3919 seg = get16 ();
3921 else
3923 offset = get16 ();
3924 seg = get16 ();
3926 used_prefixes |= (prefixes & PREFIX_DATA);
3927 if (intel_syntax)
3928 sprintf (scratchbuf, "0x%x:0x%x", seg, offset);
3929 else
3930 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3931 oappend (scratchbuf);
3934 static void
3935 OP_OFF (int bytemode, int sizeflag)
3937 bfd_vma off;
3939 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
3940 intel_operand_size (bytemode, sizeflag);
3941 append_seg ();
3943 if ((sizeflag & AFLAG) || mode_64bit)
3944 off = get32 ();
3945 else
3946 off = get16 ();
3948 if (intel_syntax)
3950 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3951 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3953 oappend (names_seg[ds_reg - es_reg]);
3954 oappend (":");
3957 print_operand_value (scratchbuf, 1, off);
3958 oappend (scratchbuf);
3961 static void
3962 OP_OFF64 (int bytemode, int sizeflag)
3964 bfd_vma off;
3966 if (!mode_64bit)
3968 OP_OFF (bytemode, sizeflag);
3969 return;
3972 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
3973 intel_operand_size (bytemode, sizeflag);
3974 append_seg ();
3976 off = get64 ();
3978 if (intel_syntax)
3980 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3981 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3983 oappend (names_seg[ds_reg - es_reg]);
3984 oappend (":");
3987 print_operand_value (scratchbuf, 1, off);
3988 oappend (scratchbuf);
3991 static void
3992 ptr_reg (int code, int sizeflag)
3994 const char *s;
3996 *obufp++ = open_char;
3997 used_prefixes |= (prefixes & PREFIX_ADDR);
3998 if (mode_64bit)
4000 if (!(sizeflag & AFLAG))
4001 s = names32[code - eAX_reg];
4002 else
4003 s = names64[code - eAX_reg];
4005 else if (sizeflag & AFLAG)
4006 s = names32[code - eAX_reg];
4007 else
4008 s = names16[code - eAX_reg];
4009 oappend (s);
4010 *obufp++ = close_char;
4011 *obufp = 0;
4014 static void
4015 OP_ESreg (int code, int sizeflag)
4017 if (intel_syntax)
4018 intel_operand_size (codep[-1] & 1 ? v_mode : b_mode, sizeflag);
4019 oappend ("%es:" + intel_syntax);
4020 ptr_reg (code, sizeflag);
4023 static void
4024 OP_DSreg (int code, int sizeflag)
4026 if (intel_syntax)
4027 intel_operand_size (codep[-1] != 0xd7 && (codep[-1] & 1)
4028 ? v_mode
4029 : b_mode,
4030 sizeflag);
4031 if ((prefixes
4032 & (PREFIX_CS
4033 | PREFIX_DS
4034 | PREFIX_SS
4035 | PREFIX_ES
4036 | PREFIX_FS
4037 | PREFIX_GS)) == 0)
4038 prefixes |= PREFIX_DS;
4039 append_seg ();
4040 ptr_reg (code, sizeflag);
4043 static void
4044 OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4046 int add = 0;
4047 if (rex & REX_EXTX)
4049 USED_REX (REX_EXTX);
4050 add = 8;
4052 else if (!mode_64bit && (prefixes & PREFIX_LOCK))
4054 used_prefixes |= PREFIX_LOCK;
4055 add = 8;
4057 sprintf (scratchbuf, "%%cr%d", reg + add);
4058 oappend (scratchbuf + intel_syntax);
4061 static void
4062 OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4064 int add = 0;
4065 USED_REX (REX_EXTX);
4066 if (rex & REX_EXTX)
4067 add = 8;
4068 if (intel_syntax)
4069 sprintf (scratchbuf, "db%d", reg + add);
4070 else
4071 sprintf (scratchbuf, "%%db%d", reg + add);
4072 oappend (scratchbuf);
4075 static void
4076 OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4078 sprintf (scratchbuf, "%%tr%d", reg);
4079 oappend (scratchbuf + intel_syntax);
4082 static void
4083 OP_Rd (int bytemode, int sizeflag)
4085 if (mod == 3)
4086 OP_E (bytemode, sizeflag);
4087 else
4088 BadOp ();
4091 static void
4092 OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4094 used_prefixes |= (prefixes & PREFIX_DATA);
4095 if (prefixes & PREFIX_DATA)
4097 int add = 0;
4098 USED_REX (REX_EXTX);
4099 if (rex & REX_EXTX)
4100 add = 8;
4101 sprintf (scratchbuf, "%%xmm%d", reg + add);
4103 else
4104 sprintf (scratchbuf, "%%mm%d", reg);
4105 oappend (scratchbuf + intel_syntax);
4108 static void
4109 OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4111 int add = 0;
4112 USED_REX (REX_EXTX);
4113 if (rex & REX_EXTX)
4114 add = 8;
4115 sprintf (scratchbuf, "%%xmm%d", reg + add);
4116 oappend (scratchbuf + intel_syntax);
4119 static void
4120 OP_EM (int bytemode, int sizeflag)
4122 if (mod != 3)
4124 if (intel_syntax && bytemode == v_mode)
4126 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
4127 used_prefixes |= (prefixes & PREFIX_DATA);
4129 OP_E (bytemode, sizeflag);
4130 return;
4133 /* Skip mod/rm byte. */
4134 MODRM_CHECK;
4135 codep++;
4136 used_prefixes |= (prefixes & PREFIX_DATA);
4137 if (prefixes & PREFIX_DATA)
4139 int add = 0;
4141 USED_REX (REX_EXTZ);
4142 if (rex & REX_EXTZ)
4143 add = 8;
4144 sprintf (scratchbuf, "%%xmm%d", rm + add);
4146 else
4147 sprintf (scratchbuf, "%%mm%d", rm);
4148 oappend (scratchbuf + intel_syntax);
4151 static void
4152 OP_EX (int bytemode, int sizeflag)
4154 int add = 0;
4155 if (mod != 3)
4157 if (intel_syntax && bytemode == v_mode)
4159 switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ))
4161 case 0: bytemode = x_mode; break;
4162 case PREFIX_REPZ: bytemode = d_mode; used_prefixes |= PREFIX_REPZ; break;
4163 case PREFIX_DATA: bytemode = x_mode; used_prefixes |= PREFIX_DATA; break;
4164 case PREFIX_REPNZ: bytemode = q_mode; used_prefixes |= PREFIX_REPNZ; break;
4165 default: bytemode = 0; break;
4168 OP_E (bytemode, sizeflag);
4169 return;
4171 USED_REX (REX_EXTZ);
4172 if (rex & REX_EXTZ)
4173 add = 8;
4175 /* Skip mod/rm byte. */
4176 MODRM_CHECK;
4177 codep++;
4178 sprintf (scratchbuf, "%%xmm%d", rm + add);
4179 oappend (scratchbuf + intel_syntax);
4182 static void
4183 OP_MS (int bytemode, int sizeflag)
4185 if (mod == 3)
4186 OP_EM (bytemode, sizeflag);
4187 else
4188 BadOp ();
4191 static void
4192 OP_XS (int bytemode, int sizeflag)
4194 if (mod == 3)
4195 OP_EX (bytemode, sizeflag);
4196 else
4197 BadOp ();
4200 static void
4201 OP_M (int bytemode, int sizeflag)
4203 if (mod == 3)
4204 BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
4205 else
4206 OP_E (bytemode, sizeflag);
4209 static void
4210 OP_0f07 (int bytemode, int sizeflag)
4212 if (mod != 3 || rm != 0)
4213 BadOp ();
4214 else
4215 OP_E (bytemode, sizeflag);
4218 static void
4219 OP_0fae (int bytemode, int sizeflag)
4221 if (mod == 3)
4223 if (reg == 7)
4224 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
4226 if (reg < 5 || rm != 0)
4228 BadOp (); /* bad sfence, mfence, or lfence */
4229 return;
4232 else if (reg != 7)
4234 BadOp (); /* bad clflush */
4235 return;
4238 OP_E (bytemode, sizeflag);
4241 static void
4242 NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4244 /* NOP with REPZ prefix is called PAUSE. */
4245 if (prefixes == PREFIX_REPZ)
4246 strcpy (obuf, "pause");
4249 static const char *const Suffix3DNow[] = {
4250 /* 00 */ NULL, NULL, NULL, NULL,
4251 /* 04 */ NULL, NULL, NULL, NULL,
4252 /* 08 */ NULL, NULL, NULL, NULL,
4253 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
4254 /* 10 */ NULL, NULL, NULL, NULL,
4255 /* 14 */ NULL, NULL, NULL, NULL,
4256 /* 18 */ NULL, NULL, NULL, NULL,
4257 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
4258 /* 20 */ NULL, NULL, NULL, NULL,
4259 /* 24 */ NULL, NULL, NULL, NULL,
4260 /* 28 */ NULL, NULL, NULL, NULL,
4261 /* 2C */ NULL, NULL, NULL, NULL,
4262 /* 30 */ NULL, NULL, NULL, NULL,
4263 /* 34 */ NULL, NULL, NULL, NULL,
4264 /* 38 */ NULL, NULL, NULL, NULL,
4265 /* 3C */ NULL, NULL, NULL, NULL,
4266 /* 40 */ NULL, NULL, NULL, NULL,
4267 /* 44 */ NULL, NULL, NULL, NULL,
4268 /* 48 */ NULL, NULL, NULL, NULL,
4269 /* 4C */ NULL, NULL, NULL, NULL,
4270 /* 50 */ NULL, NULL, NULL, NULL,
4271 /* 54 */ NULL, NULL, NULL, NULL,
4272 /* 58 */ NULL, NULL, NULL, NULL,
4273 /* 5C */ NULL, NULL, NULL, NULL,
4274 /* 60 */ NULL, NULL, NULL, NULL,
4275 /* 64 */ NULL, NULL, NULL, NULL,
4276 /* 68 */ NULL, NULL, NULL, NULL,
4277 /* 6C */ NULL, NULL, NULL, NULL,
4278 /* 70 */ NULL, NULL, NULL, NULL,
4279 /* 74 */ NULL, NULL, NULL, NULL,
4280 /* 78 */ NULL, NULL, NULL, NULL,
4281 /* 7C */ NULL, NULL, NULL, NULL,
4282 /* 80 */ NULL, NULL, NULL, NULL,
4283 /* 84 */ NULL, NULL, NULL, NULL,
4284 /* 88 */ NULL, NULL, "pfnacc", NULL,
4285 /* 8C */ NULL, NULL, "pfpnacc", NULL,
4286 /* 90 */ "pfcmpge", NULL, NULL, NULL,
4287 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
4288 /* 98 */ NULL, NULL, "pfsub", NULL,
4289 /* 9C */ NULL, NULL, "pfadd", NULL,
4290 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
4291 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
4292 /* A8 */ NULL, NULL, "pfsubr", NULL,
4293 /* AC */ NULL, NULL, "pfacc", NULL,
4294 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
4295 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
4296 /* B8 */ NULL, NULL, NULL, "pswapd",
4297 /* BC */ NULL, NULL, NULL, "pavgusb",
4298 /* C0 */ NULL, NULL, NULL, NULL,
4299 /* C4 */ NULL, NULL, NULL, NULL,
4300 /* C8 */ NULL, NULL, NULL, NULL,
4301 /* CC */ NULL, NULL, NULL, NULL,
4302 /* D0 */ NULL, NULL, NULL, NULL,
4303 /* D4 */ NULL, NULL, NULL, NULL,
4304 /* D8 */ NULL, NULL, NULL, NULL,
4305 /* DC */ NULL, NULL, NULL, NULL,
4306 /* E0 */ NULL, NULL, NULL, NULL,
4307 /* E4 */ NULL, NULL, NULL, NULL,
4308 /* E8 */ NULL, NULL, NULL, NULL,
4309 /* EC */ NULL, NULL, NULL, NULL,
4310 /* F0 */ NULL, NULL, NULL, NULL,
4311 /* F4 */ NULL, NULL, NULL, NULL,
4312 /* F8 */ NULL, NULL, NULL, NULL,
4313 /* FC */ NULL, NULL, NULL, NULL,
4316 static void
4317 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4319 const char *mnemonic;
4321 FETCH_DATA (the_info, codep + 1);
4322 /* AMD 3DNow! instructions are specified by an opcode suffix in the
4323 place where an 8-bit immediate would normally go. ie. the last
4324 byte of the instruction. */
4325 obufp = obuf + strlen (obuf);
4326 mnemonic = Suffix3DNow[*codep++ & 0xff];
4327 if (mnemonic)
4328 oappend (mnemonic);
4329 else
4331 /* Since a variable sized modrm/sib chunk is between the start
4332 of the opcode (0x0f0f) and the opcode suffix, we need to do
4333 all the modrm processing first, and don't know until now that
4334 we have a bad opcode. This necessitates some cleaning up. */
4335 op1out[0] = '\0';
4336 op2out[0] = '\0';
4337 BadOp ();
4341 static const char *simd_cmp_op[] = {
4342 "eq",
4343 "lt",
4344 "le",
4345 "unord",
4346 "neq",
4347 "nlt",
4348 "nle",
4349 "ord"
4352 static void
4353 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4355 unsigned int cmp_type;
4357 FETCH_DATA (the_info, codep + 1);
4358 obufp = obuf + strlen (obuf);
4359 cmp_type = *codep++ & 0xff;
4360 if (cmp_type < 8)
4362 char suffix1 = 'p', suffix2 = 's';
4363 used_prefixes |= (prefixes & PREFIX_REPZ);
4364 if (prefixes & PREFIX_REPZ)
4365 suffix1 = 's';
4366 else
4368 used_prefixes |= (prefixes & PREFIX_DATA);
4369 if (prefixes & PREFIX_DATA)
4370 suffix2 = 'd';
4371 else
4373 used_prefixes |= (prefixes & PREFIX_REPNZ);
4374 if (prefixes & PREFIX_REPNZ)
4375 suffix1 = 's', suffix2 = 'd';
4378 sprintf (scratchbuf, "cmp%s%c%c",
4379 simd_cmp_op[cmp_type], suffix1, suffix2);
4380 used_prefixes |= (prefixes & PREFIX_REPZ);
4381 oappend (scratchbuf);
4383 else
4385 /* We have a bad extension byte. Clean up. */
4386 op1out[0] = '\0';
4387 op2out[0] = '\0';
4388 BadOp ();
4392 static void
4393 SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
4395 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
4396 forms of these instructions. */
4397 if (mod == 3)
4399 char *p = obuf + strlen (obuf);
4400 *(p + 1) = '\0';
4401 *p = *(p - 1);
4402 *(p - 1) = *(p - 2);
4403 *(p - 2) = *(p - 3);
4404 *(p - 3) = extrachar;
4408 static void
4409 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
4411 if (mod == 3 && reg == 1 && rm <= 1)
4413 /* Override "sidt". */
4414 char *p = obuf + strlen (obuf) - 4;
4416 /* We might have a suffix when disassembling with -Msuffix. */
4417 if (*p == 'i')
4418 --p;
4420 if (rm)
4422 /* mwait %eax,%ecx */
4423 strcpy (p, "mwait");
4424 if (!intel_syntax)
4425 strcpy (op1out, names32[0]);
4427 else
4429 /* monitor %eax,%ecx,%edx" */
4430 strcpy (p, "monitor");
4431 if (!intel_syntax)
4433 if (!mode_64bit)
4434 strcpy (op1out, names32[0]);
4435 else if (!(prefixes & PREFIX_ADDR))
4436 strcpy (op1out, names64[0]);
4437 else
4439 strcpy (op1out, names32[0]);
4440 used_prefixes |= PREFIX_ADDR;
4442 strcpy (op3out, names32[2]);
4445 if (!intel_syntax)
4447 strcpy (op2out, names32[1]);
4448 two_source_ops = 1;
4451 codep++;
4453 else
4454 OP_M (0, sizeflag);
4457 static void
4458 SVME_Fixup (int bytemode, int sizeflag)
4460 const char *alt;
4461 char *p;
4463 switch (*codep)
4465 case 0xd8:
4466 alt = "vmrun";
4467 break;
4468 case 0xd9:
4469 alt = "vmmcall";
4470 break;
4471 case 0xda:
4472 alt = "vmload";
4473 break;
4474 case 0xdb:
4475 alt = "vmsave";
4476 break;
4477 case 0xdc:
4478 alt = "stgi";
4479 break;
4480 case 0xdd:
4481 alt = "clgi";
4482 break;
4483 case 0xde:
4484 alt = "skinit";
4485 break;
4486 case 0xdf:
4487 alt = "invlpga";
4488 break;
4489 default:
4490 OP_M (bytemode, sizeflag);
4491 return;
4493 /* Override "lidt". */
4494 p = obuf + strlen (obuf) - 4;
4495 /* We might have a suffix. */
4496 if (*p == 'i')
4497 --p;
4498 strcpy (p, alt);
4499 if (!(prefixes & PREFIX_ADDR))
4501 ++codep;
4502 return;
4504 used_prefixes |= PREFIX_ADDR;
4505 switch (*codep++)
4507 case 0xdf:
4508 strcpy (op2out, names32[1]);
4509 two_source_ops = 1;
4510 /* Fall through. */
4511 case 0xd8:
4512 case 0xda:
4513 case 0xdb:
4514 *obufp++ = open_char;
4515 if (mode_64bit || (sizeflag & AFLAG))
4516 alt = names32[0];
4517 else
4518 alt = names16[0];
4519 strcpy (obufp, alt);
4520 obufp += strlen (alt);
4521 *obufp++ = close_char;
4522 *obufp = '\0';
4523 break;
4527 static void
4528 INVLPG_Fixup (int bytemode, int sizeflag)
4530 const char *alt;
4532 switch (*codep)
4534 case 0xf8:
4535 alt = "swapgs";
4536 break;
4537 case 0xf9:
4538 alt = "rdtscp";
4539 break;
4540 default:
4541 OP_M (bytemode, sizeflag);
4542 return;
4544 /* Override "invlpg". */
4545 strcpy (obuf + strlen (obuf) - 6, alt);
4546 codep++;
4549 static void
4550 BadOp (void)
4552 /* Throw away prefixes and 1st. opcode byte. */
4553 codep = insn_codep + 1;
4554 oappend ("(bad)");
4557 static void
4558 SEG_Fixup (int extrachar, int sizeflag)
4560 if (mod == 3)
4562 /* We need to add a proper suffix with
4564 movw %ds,%ax
4565 movl %ds,%eax
4566 movq %ds,%rax
4567 movw %ax,%ds
4568 movl %eax,%ds
4569 movq %rax,%ds
4571 const char *suffix;
4573 if (prefixes & PREFIX_DATA)
4574 suffix = "w";
4575 else
4577 USED_REX (REX_MODE64);
4578 if (rex & REX_MODE64)
4579 suffix = "q";
4580 else
4581 suffix = "l";
4583 strcat (obuf, suffix);
4585 else
4587 /* We need to fix the suffix for
4589 movw %ds,(%eax)
4590 movw %ds,(%rax)
4591 movw (%eax),%ds
4592 movw (%rax),%ds
4594 Override "mov[l|q]". */
4595 char *p = obuf + strlen (obuf) - 1;
4597 /* We might not have a suffix. */
4598 if (*p == 'v')
4599 ++p;
4600 *p = 'w';
4603 OP_E (extrachar, sizeflag);
4606 static void
4607 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
4609 if (mod == 3 && reg == 0 && rm >=1 && rm <= 4)
4611 /* Override "sgdt". */
4612 char *p = obuf + strlen (obuf) - 4;
4614 /* We might have a suffix when disassembling with -Msuffix. */
4615 if (*p == 'g')
4616 --p;
4618 switch (rm)
4620 case 1:
4621 strcpy (p, "vmcall");
4622 break;
4623 case 2:
4624 strcpy (p, "vmlaunch");
4625 break;
4626 case 3:
4627 strcpy (p, "vmresume");
4628 break;
4629 case 4:
4630 strcpy (p, "vmxoff");
4631 break;
4634 codep++;
4636 else
4637 OP_E (0, sizeflag);
4640 static void
4641 OP_VMX (int bytemode, int sizeflag)
4643 used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
4644 if (prefixes & PREFIX_DATA)
4645 strcpy (obuf, "vmclear");
4646 else if (prefixes & PREFIX_REPZ)
4647 strcpy (obuf, "vmxon");
4648 else
4649 strcpy (obuf, "vmptrld");
4650 OP_E (bytemode, sizeflag);