gas/ChangeLog:
[binutils.git] / opcodes / i386-dis.c
blob24620d0ef0bffc69b1fec1c2cfa6cb1343fc4796
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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_0fae (int, int);
92 static void OP_0f07 (int, int);
93 static void NOP_Fixup (int, int);
94 static void OP_3DNowSuffix (int, int);
95 static void OP_SIMD_Suffix (int, int);
96 static void SIMD_Fixup (int, int);
97 static void PNI_Fixup (int, int);
98 static void INVLPG_Fixup (int, int);
99 static void BadOp (void);
100 static void SEG_Fixup (int, int);
102 struct dis_private {
103 /* Points to first byte not fetched. */
104 bfd_byte *max_fetched;
105 bfd_byte the_buffer[MAXLEN];
106 bfd_vma insn_start;
107 int orig_sizeflag;
108 jmp_buf bailout;
111 /* The opcode for the fwait instruction, which we treat as a prefix
112 when we can. */
113 #define FWAIT_OPCODE (0x9b)
115 /* Set to 1 for 64bit mode disassembly. */
116 static int mode_64bit;
118 /* Flags for the prefixes for the current instruction. See below. */
119 static int prefixes;
121 /* REX prefix the current instruction. See below. */
122 static int rex;
123 /* Bits of REX we've already used. */
124 static int rex_used;
125 #define REX_MODE64 8
126 #define REX_EXTX 4
127 #define REX_EXTY 2
128 #define REX_EXTZ 1
129 /* Mark parts used in the REX prefix. When we are testing for
130 empty prefix (for 8bit register REX extension), just mask it
131 out. Otherwise test for REX bit is excuse for existence of REX
132 only in case value is nonzero. */
133 #define USED_REX(value) \
135 if (value) \
136 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
137 else \
138 rex_used |= 0x40; \
141 /* Flags for prefixes which we somehow handled when printing the
142 current instruction. */
143 static int used_prefixes;
145 /* Flags stored in PREFIXES. */
146 #define PREFIX_REPZ 1
147 #define PREFIX_REPNZ 2
148 #define PREFIX_LOCK 4
149 #define PREFIX_CS 8
150 #define PREFIX_SS 0x10
151 #define PREFIX_DS 0x20
152 #define PREFIX_ES 0x40
153 #define PREFIX_FS 0x80
154 #define PREFIX_GS 0x100
155 #define PREFIX_DATA 0x200
156 #define PREFIX_ADDR 0x400
157 #define PREFIX_FWAIT 0x800
159 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
160 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
161 on error. */
162 #define FETCH_DATA(info, addr) \
163 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
164 ? 1 : fetch_data ((info), (addr)))
166 static int
167 fetch_data (struct disassemble_info *info, bfd_byte *addr)
169 int status;
170 struct dis_private *priv = (struct dis_private *) info->private_data;
171 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
173 status = (*info->read_memory_func) (start,
174 priv->max_fetched,
175 addr - priv->max_fetched,
176 info);
177 if (status != 0)
179 /* If we did manage to read at least one byte, then
180 print_insn_i386 will do something sensible. Otherwise, print
181 an error. We do that here because this is where we know
182 STATUS. */
183 if (priv->max_fetched == priv->the_buffer)
184 (*info->memory_error_func) (status, start, info);
185 longjmp (priv->bailout, 1);
187 else
188 priv->max_fetched = addr;
189 return 1;
192 #define XX NULL, 0
194 #define Eb OP_E, b_mode
195 #define Ev OP_E, v_mode
196 #define Ed OP_E, d_mode
197 #define Eq OP_E, q_mode
198 #define Edq OP_E, dq_mode
199 #define Edqw OP_E, dqw_mode
200 #define indirEv OP_indirE, v_mode
201 #define indirEp OP_indirE, f_mode
202 #define Ew OP_E, w_mode
203 #define Ma OP_E, v_mode
204 #define M OP_M, 0 /* lea, lgdt, etc. */
205 #define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */
206 #define Gb OP_G, b_mode
207 #define Gv OP_G, v_mode
208 #define Gd OP_G, d_mode
209 #define Gdq OP_G, dq_mode
210 #define Gw OP_G, w_mode
211 #define Rd OP_Rd, d_mode
212 #define Rm OP_Rd, m_mode
213 #define Ib OP_I, b_mode
214 #define sIb OP_sI, b_mode /* sign extened byte */
215 #define Iv OP_I, v_mode
216 #define Iq OP_I, q_mode
217 #define Iv64 OP_I64, v_mode
218 #define Iw OP_I, w_mode
219 #define I1 OP_I, const_1_mode
220 #define Jb OP_J, b_mode
221 #define Jv OP_J, v_mode
222 #define Cm OP_C, m_mode
223 #define Dm OP_D, m_mode
224 #define Td OP_T, d_mode
225 #define Sv SEG_Fixup, v_mode
227 #define RMeAX OP_REG, eAX_reg
228 #define RMeBX OP_REG, eBX_reg
229 #define RMeCX OP_REG, eCX_reg
230 #define RMeDX OP_REG, eDX_reg
231 #define RMeSP OP_REG, eSP_reg
232 #define RMeBP OP_REG, eBP_reg
233 #define RMeSI OP_REG, eSI_reg
234 #define RMeDI OP_REG, eDI_reg
235 #define RMrAX OP_REG, rAX_reg
236 #define RMrBX OP_REG, rBX_reg
237 #define RMrCX OP_REG, rCX_reg
238 #define RMrDX OP_REG, rDX_reg
239 #define RMrSP OP_REG, rSP_reg
240 #define RMrBP OP_REG, rBP_reg
241 #define RMrSI OP_REG, rSI_reg
242 #define RMrDI OP_REG, rDI_reg
243 #define RMAL OP_REG, al_reg
244 #define RMAL OP_REG, al_reg
245 #define RMCL OP_REG, cl_reg
246 #define RMDL OP_REG, dl_reg
247 #define RMBL OP_REG, bl_reg
248 #define RMAH OP_REG, ah_reg
249 #define RMCH OP_REG, ch_reg
250 #define RMDH OP_REG, dh_reg
251 #define RMBH OP_REG, bh_reg
252 #define RMAX OP_REG, ax_reg
253 #define RMDX OP_REG, dx_reg
255 #define eAX OP_IMREG, eAX_reg
256 #define eBX OP_IMREG, eBX_reg
257 #define eCX OP_IMREG, eCX_reg
258 #define eDX OP_IMREG, eDX_reg
259 #define eSP OP_IMREG, eSP_reg
260 #define eBP OP_IMREG, eBP_reg
261 #define eSI OP_IMREG, eSI_reg
262 #define eDI OP_IMREG, eDI_reg
263 #define AL OP_IMREG, al_reg
264 #define AL OP_IMREG, al_reg
265 #define CL OP_IMREG, cl_reg
266 #define DL OP_IMREG, dl_reg
267 #define BL OP_IMREG, bl_reg
268 #define AH OP_IMREG, ah_reg
269 #define CH OP_IMREG, ch_reg
270 #define DH OP_IMREG, dh_reg
271 #define BH OP_IMREG, bh_reg
272 #define AX OP_IMREG, ax_reg
273 #define DX OP_IMREG, dx_reg
274 #define indirDX OP_IMREG, indir_dx_reg
276 #define Sw OP_SEG, w_mode
277 #define Ap OP_DIR, 0
278 #define Ob OP_OFF, b_mode
279 #define Ob64 OP_OFF64, b_mode
280 #define Ov OP_OFF, v_mode
281 #define Ov64 OP_OFF64, v_mode
282 #define Xb OP_DSreg, eSI_reg
283 #define Xv OP_DSreg, eSI_reg
284 #define Yb OP_ESreg, eDI_reg
285 #define Yv OP_ESreg, eDI_reg
286 #define DSBX OP_DSreg, eBX_reg
288 #define es OP_REG, es_reg
289 #define ss OP_REG, ss_reg
290 #define cs OP_REG, cs_reg
291 #define ds OP_REG, ds_reg
292 #define fs OP_REG, fs_reg
293 #define gs OP_REG, gs_reg
295 #define MX OP_MMX, 0
296 #define XM OP_XMM, 0
297 #define EM OP_EM, v_mode
298 #define EX OP_EX, v_mode
299 #define MS OP_MS, v_mode
300 #define XS OP_XS, v_mode
301 #define OPSUF OP_3DNowSuffix, 0
302 #define OPSIMD OP_SIMD_Suffix, 0
304 #define cond_jump_flag NULL, cond_jump_mode
305 #define loop_jcxz_flag NULL, loop_jcxz_mode
307 /* bits in sizeflag */
308 #define SUFFIX_ALWAYS 4
309 #define AFLAG 2
310 #define DFLAG 1
312 #define b_mode 1 /* byte operand */
313 #define v_mode 2 /* operand size depends on prefixes */
314 #define w_mode 3 /* word operand */
315 #define d_mode 4 /* double word operand */
316 #define q_mode 5 /* quad word operand */
317 #define t_mode 6 /* ten-byte operand */
318 #define x_mode 7 /* 16-byte XMM operand */
319 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
320 #define cond_jump_mode 9
321 #define loop_jcxz_mode 10
322 #define dq_mode 11 /* operand size depends on REX prefixes. */
323 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
324 #define f_mode 13 /* 4- or 6-byte pointer operand */
325 #define const_1_mode 14
327 #define es_reg 100
328 #define cs_reg 101
329 #define ss_reg 102
330 #define ds_reg 103
331 #define fs_reg 104
332 #define gs_reg 105
334 #define eAX_reg 108
335 #define eCX_reg 109
336 #define eDX_reg 110
337 #define eBX_reg 111
338 #define eSP_reg 112
339 #define eBP_reg 113
340 #define eSI_reg 114
341 #define eDI_reg 115
343 #define al_reg 116
344 #define cl_reg 117
345 #define dl_reg 118
346 #define bl_reg 119
347 #define ah_reg 120
348 #define ch_reg 121
349 #define dh_reg 122
350 #define bh_reg 123
352 #define ax_reg 124
353 #define cx_reg 125
354 #define dx_reg 126
355 #define bx_reg 127
356 #define sp_reg 128
357 #define bp_reg 129
358 #define si_reg 130
359 #define di_reg 131
361 #define rAX_reg 132
362 #define rCX_reg 133
363 #define rDX_reg 134
364 #define rBX_reg 135
365 #define rSP_reg 136
366 #define rBP_reg 137
367 #define rSI_reg 138
368 #define rDI_reg 139
370 #define indir_dx_reg 150
372 #define FLOATCODE 1
373 #define USE_GROUPS 2
374 #define USE_PREFIX_USER_TABLE 3
375 #define X86_64_SPECIAL 4
377 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
379 #define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
380 #define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
381 #define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
382 #define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
383 #define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
384 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
385 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
386 #define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
387 #define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
388 #define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
389 #define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
390 #define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
391 #define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
392 #define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
393 #define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
394 #define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
395 #define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
396 #define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
397 #define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
398 #define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
399 #define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
400 #define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
401 #define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
402 #define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0
403 #define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0
405 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
406 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
407 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
408 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
409 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
410 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
411 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
412 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
413 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
414 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
415 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
416 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
417 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
418 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
419 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
420 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
421 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
422 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
423 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
424 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
425 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
426 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
427 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
428 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
429 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
430 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
431 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
432 #define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0
433 #define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0
434 #define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0
435 #define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0
436 #define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0
437 #define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0
439 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
441 typedef void (*op_rtn) (int bytemode, int sizeflag);
443 struct dis386 {
444 const char *name;
445 op_rtn op1;
446 int bytemode1;
447 op_rtn op2;
448 int bytemode2;
449 op_rtn op3;
450 int bytemode3;
453 /* Upper case letters in the instruction names here are macros.
454 'A' => print 'b' if no register operands or suffix_always is true
455 'B' => print 'b' if suffix_always is true
456 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
457 . size prefix
458 'E' => print 'e' if 32-bit form of jcxz
459 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
460 'H' => print ",pt" or ",pn" branch hint
461 'I' => honor following macro letter even in Intel mode (implemented only
462 . for some of the macro letters)
463 'J' => print 'l'
464 'L' => print 'l' if suffix_always is true
465 'N' => print 'n' if instruction has no wait "prefix"
466 'O' => print 'd', or 'o'
467 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
468 . or suffix_always is true. print 'q' if rex prefix is present.
469 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
470 . is true
471 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
472 'S' => print 'w', 'l' or 'q' if suffix_always is true
473 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
474 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
475 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
476 'X' => print 's', 'd' depending on data16 prefix (for XMM)
477 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
479 Many of the above letters print nothing in Intel mode. See "putop"
480 for the details.
482 Braces '{' and '}', and vertical bars '|', indicate alternative
483 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
484 modes. In cases where there are only two alternatives, the X86_64
485 instruction is reserved, and "(bad)" is printed.
488 static const struct dis386 dis386[] = {
489 /* 00 */
490 { "addB", Eb, Gb, XX },
491 { "addS", Ev, Gv, XX },
492 { "addB", Gb, Eb, XX },
493 { "addS", Gv, Ev, XX },
494 { "addB", AL, Ib, XX },
495 { "addS", eAX, Iv, XX },
496 { "push{T|}", es, XX, XX },
497 { "pop{T|}", es, XX, XX },
498 /* 08 */
499 { "orB", Eb, Gb, XX },
500 { "orS", Ev, Gv, XX },
501 { "orB", Gb, Eb, XX },
502 { "orS", Gv, Ev, XX },
503 { "orB", AL, Ib, XX },
504 { "orS", eAX, Iv, XX },
505 { "push{T|}", cs, XX, XX },
506 { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */
507 /* 10 */
508 { "adcB", Eb, Gb, XX },
509 { "adcS", Ev, Gv, XX },
510 { "adcB", Gb, Eb, XX },
511 { "adcS", Gv, Ev, XX },
512 { "adcB", AL, Ib, XX },
513 { "adcS", eAX, Iv, XX },
514 { "push{T|}", ss, XX, XX },
515 { "popT|}", ss, XX, XX },
516 /* 18 */
517 { "sbbB", Eb, Gb, XX },
518 { "sbbS", Ev, Gv, XX },
519 { "sbbB", Gb, Eb, XX },
520 { "sbbS", Gv, Ev, XX },
521 { "sbbB", AL, Ib, XX },
522 { "sbbS", eAX, Iv, XX },
523 { "push{T|}", ds, XX, XX },
524 { "pop{T|}", ds, XX, XX },
525 /* 20 */
526 { "andB", Eb, Gb, XX },
527 { "andS", Ev, Gv, XX },
528 { "andB", Gb, Eb, XX },
529 { "andS", Gv, Ev, XX },
530 { "andB", AL, Ib, XX },
531 { "andS", eAX, Iv, XX },
532 { "(bad)", XX, XX, XX }, /* SEG ES prefix */
533 { "daa{|}", XX, XX, XX },
534 /* 28 */
535 { "subB", Eb, Gb, XX },
536 { "subS", Ev, Gv, XX },
537 { "subB", Gb, Eb, XX },
538 { "subS", Gv, Ev, XX },
539 { "subB", AL, Ib, XX },
540 { "subS", eAX, Iv, XX },
541 { "(bad)", XX, XX, XX }, /* SEG CS prefix */
542 { "das{|}", XX, XX, XX },
543 /* 30 */
544 { "xorB", Eb, Gb, XX },
545 { "xorS", Ev, Gv, XX },
546 { "xorB", Gb, Eb, XX },
547 { "xorS", Gv, Ev, XX },
548 { "xorB", AL, Ib, XX },
549 { "xorS", eAX, Iv, XX },
550 { "(bad)", XX, XX, XX }, /* SEG SS prefix */
551 { "aaa{|}", XX, XX, XX },
552 /* 38 */
553 { "cmpB", Eb, Gb, XX },
554 { "cmpS", Ev, Gv, XX },
555 { "cmpB", Gb, Eb, XX },
556 { "cmpS", Gv, Ev, XX },
557 { "cmpB", AL, Ib, XX },
558 { "cmpS", eAX, Iv, XX },
559 { "(bad)", XX, XX, XX }, /* SEG DS prefix */
560 { "aas{|}", XX, XX, XX },
561 /* 40 */
562 { "inc{S|}", RMeAX, XX, XX },
563 { "inc{S|}", RMeCX, XX, XX },
564 { "inc{S|}", RMeDX, XX, XX },
565 { "inc{S|}", RMeBX, XX, XX },
566 { "inc{S|}", RMeSP, XX, XX },
567 { "inc{S|}", RMeBP, XX, XX },
568 { "inc{S|}", RMeSI, XX, XX },
569 { "inc{S|}", RMeDI, XX, XX },
570 /* 48 */
571 { "dec{S|}", RMeAX, XX, XX },
572 { "dec{S|}", RMeCX, XX, XX },
573 { "dec{S|}", RMeDX, XX, XX },
574 { "dec{S|}", RMeBX, XX, XX },
575 { "dec{S|}", RMeSP, XX, XX },
576 { "dec{S|}", RMeBP, XX, XX },
577 { "dec{S|}", RMeSI, XX, XX },
578 { "dec{S|}", RMeDI, XX, XX },
579 /* 50 */
580 { "pushS", RMrAX, XX, XX },
581 { "pushS", RMrCX, XX, XX },
582 { "pushS", RMrDX, XX, XX },
583 { "pushS", RMrBX, XX, XX },
584 { "pushS", RMrSP, XX, XX },
585 { "pushS", RMrBP, XX, XX },
586 { "pushS", RMrSI, XX, XX },
587 { "pushS", RMrDI, XX, XX },
588 /* 58 */
589 { "popS", RMrAX, XX, XX },
590 { "popS", RMrCX, XX, XX },
591 { "popS", RMrDX, XX, XX },
592 { "popS", RMrBX, XX, XX },
593 { "popS", RMrSP, XX, XX },
594 { "popS", RMrBP, XX, XX },
595 { "popS", RMrSI, XX, XX },
596 { "popS", RMrDI, XX, XX },
597 /* 60 */
598 { "pusha{P|}", XX, XX, XX },
599 { "popa{P|}", XX, XX, XX },
600 { "bound{S|}", Gv, Ma, XX },
601 { X86_64_0 },
602 { "(bad)", XX, XX, XX }, /* seg fs */
603 { "(bad)", XX, XX, XX }, /* seg gs */
604 { "(bad)", XX, XX, XX }, /* op size prefix */
605 { "(bad)", XX, XX, XX }, /* adr size prefix */
606 /* 68 */
607 { "pushT", Iq, XX, XX },
608 { "imulS", Gv, Ev, Iv },
609 { "pushT", sIb, XX, XX },
610 { "imulS", Gv, Ev, sIb },
611 { "ins{b||b|}", Yb, indirDX, XX },
612 { "ins{R||R|}", Yv, indirDX, XX },
613 { "outs{b||b|}", indirDX, Xb, XX },
614 { "outs{R||R|}", indirDX, Xv, XX },
615 /* 70 */
616 { "joH", Jb, XX, cond_jump_flag },
617 { "jnoH", Jb, XX, cond_jump_flag },
618 { "jbH", Jb, XX, cond_jump_flag },
619 { "jaeH", Jb, XX, cond_jump_flag },
620 { "jeH", Jb, XX, cond_jump_flag },
621 { "jneH", Jb, XX, cond_jump_flag },
622 { "jbeH", Jb, XX, cond_jump_flag },
623 { "jaH", Jb, XX, cond_jump_flag },
624 /* 78 */
625 { "jsH", Jb, XX, cond_jump_flag },
626 { "jnsH", Jb, XX, cond_jump_flag },
627 { "jpH", Jb, XX, cond_jump_flag },
628 { "jnpH", Jb, XX, cond_jump_flag },
629 { "jlH", Jb, XX, cond_jump_flag },
630 { "jgeH", Jb, XX, cond_jump_flag },
631 { "jleH", Jb, XX, cond_jump_flag },
632 { "jgH", Jb, XX, cond_jump_flag },
633 /* 80 */
634 { GRP1b },
635 { GRP1S },
636 { "(bad)", XX, XX, XX },
637 { GRP1Ss },
638 { "testB", Eb, Gb, XX },
639 { "testS", Ev, Gv, XX },
640 { "xchgB", Eb, Gb, XX },
641 { "xchgS", Ev, Gv, XX },
642 /* 88 */
643 { "movB", Eb, Gb, XX },
644 { "movS", Ev, Gv, XX },
645 { "movB", Gb, Eb, XX },
646 { "movS", Gv, Ev, XX },
647 { "movQ", Sv, Sw, XX },
648 { "leaS", Gv, M, XX },
649 { "movQ", Sw, Sv, XX },
650 { "popU", Ev, XX, XX },
651 /* 90 */
652 { "nop", NOP_Fixup, 0, XX, XX },
653 { "xchgS", RMeCX, eAX, XX },
654 { "xchgS", RMeDX, eAX, XX },
655 { "xchgS", RMeBX, eAX, XX },
656 { "xchgS", RMeSP, eAX, XX },
657 { "xchgS", RMeBP, eAX, XX },
658 { "xchgS", RMeSI, eAX, XX },
659 { "xchgS", RMeDI, eAX, XX },
660 /* 98 */
661 { "cW{tR||tR|}", XX, XX, XX },
662 { "cR{tO||tO|}", XX, XX, XX },
663 { "Jcall{T|}", Ap, XX, XX },
664 { "(bad)", XX, XX, XX }, /* fwait */
665 { "pushfT", XX, XX, XX },
666 { "popfT", XX, XX, XX },
667 { "sahf{|}", XX, XX, XX },
668 { "lahf{|}", XX, XX, XX },
669 /* a0 */
670 { "movB", AL, Ob64, XX },
671 { "movS", eAX, Ov64, XX },
672 { "movB", Ob64, AL, XX },
673 { "movS", Ov64, eAX, XX },
674 { "movs{b||b|}", Yb, Xb, XX },
675 { "movs{R||R|}", Yv, Xv, XX },
676 { "cmps{b||b|}", Xb, Yb, XX },
677 { "cmps{R||R|}", Xv, Yv, XX },
678 /* a8 */
679 { "testB", AL, Ib, XX },
680 { "testS", eAX, Iv, XX },
681 { "stosB", Yb, AL, XX },
682 { "stosS", Yv, eAX, XX },
683 { "lodsB", AL, Xb, XX },
684 { "lodsS", eAX, Xv, XX },
685 { "scasB", AL, Yb, XX },
686 { "scasS", eAX, Yv, XX },
687 /* b0 */
688 { "movB", RMAL, Ib, XX },
689 { "movB", RMCL, Ib, XX },
690 { "movB", RMDL, Ib, XX },
691 { "movB", RMBL, Ib, XX },
692 { "movB", RMAH, Ib, XX },
693 { "movB", RMCH, Ib, XX },
694 { "movB", RMDH, Ib, XX },
695 { "movB", RMBH, Ib, XX },
696 /* b8 */
697 { "movS", RMeAX, Iv64, XX },
698 { "movS", RMeCX, Iv64, XX },
699 { "movS", RMeDX, Iv64, XX },
700 { "movS", RMeBX, Iv64, XX },
701 { "movS", RMeSP, Iv64, XX },
702 { "movS", RMeBP, Iv64, XX },
703 { "movS", RMeSI, Iv64, XX },
704 { "movS", RMeDI, Iv64, XX },
705 /* c0 */
706 { GRP2b },
707 { GRP2S },
708 { "retT", Iw, XX, XX },
709 { "retT", XX, XX, XX },
710 { "les{S|}", Gv, Mp, XX },
711 { "ldsS", Gv, Mp, XX },
712 { "movA", Eb, Ib, XX },
713 { "movQ", Ev, Iv, XX },
714 /* c8 */
715 { "enterT", Iw, Ib, XX },
716 { "leaveT", XX, XX, XX },
717 { "lretP", Iw, XX, XX },
718 { "lretP", XX, XX, XX },
719 { "int3", XX, XX, XX },
720 { "int", Ib, XX, XX },
721 { "into{|}", XX, XX, XX },
722 { "iretP", XX, XX, XX },
723 /* d0 */
724 { GRP2b_one },
725 { GRP2S_one },
726 { GRP2b_cl },
727 { GRP2S_cl },
728 { "aam{|}", sIb, XX, XX },
729 { "aad{|}", sIb, XX, XX },
730 { "(bad)", XX, XX, XX },
731 { "xlat", DSBX, XX, XX },
732 /* d8 */
733 { FLOAT },
734 { FLOAT },
735 { FLOAT },
736 { FLOAT },
737 { FLOAT },
738 { FLOAT },
739 { FLOAT },
740 { FLOAT },
741 /* e0 */
742 { "loopneFH", Jb, XX, loop_jcxz_flag },
743 { "loopeFH", Jb, XX, loop_jcxz_flag },
744 { "loopFH", Jb, XX, loop_jcxz_flag },
745 { "jEcxzH", Jb, XX, loop_jcxz_flag },
746 { "inB", AL, Ib, XX },
747 { "inS", eAX, Ib, XX },
748 { "outB", Ib, AL, XX },
749 { "outS", Ib, eAX, XX },
750 /* e8 */
751 { "callT", Jv, XX, XX },
752 { "jmpT", Jv, XX, XX },
753 { "Jjmp{T|}", Ap, XX, XX },
754 { "jmp", Jb, XX, XX },
755 { "inB", AL, indirDX, XX },
756 { "inS", eAX, indirDX, XX },
757 { "outB", indirDX, AL, XX },
758 { "outS", indirDX, eAX, XX },
759 /* f0 */
760 { "(bad)", XX, XX, XX }, /* lock prefix */
761 { "icebp", XX, XX, XX },
762 { "(bad)", XX, XX, XX }, /* repne */
763 { "(bad)", XX, XX, XX }, /* repz */
764 { "hlt", XX, XX, XX },
765 { "cmc", XX, XX, XX },
766 { GRP3b },
767 { GRP3S },
768 /* f8 */
769 { "clc", XX, XX, XX },
770 { "stc", XX, XX, XX },
771 { "cli", XX, XX, XX },
772 { "sti", XX, XX, XX },
773 { "cld", XX, XX, XX },
774 { "std", XX, XX, XX },
775 { GRP4 },
776 { GRP5 },
779 static const struct dis386 dis386_twobyte[] = {
780 /* 00 */
781 { GRP6 },
782 { GRP7 },
783 { "larS", Gv, Ew, XX },
784 { "lslS", Gv, Ew, XX },
785 { "(bad)", XX, XX, XX },
786 { "syscall", XX, XX, XX },
787 { "clts", XX, XX, XX },
788 { "sysretP", XX, XX, XX },
789 /* 08 */
790 { "invd", XX, XX, XX },
791 { "wbinvd", XX, XX, XX },
792 { "(bad)", XX, XX, XX },
793 { "ud2a", XX, XX, XX },
794 { "(bad)", XX, XX, XX },
795 { GRPAMD },
796 { "femms", XX, XX, XX },
797 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */
798 /* 10 */
799 { PREGRP8 },
800 { PREGRP9 },
801 { PREGRP30 },
802 { "movlpX", EX, XM, SIMD_Fixup, 'h' },
803 { "unpcklpX", XM, EX, XX },
804 { "unpckhpX", XM, EX, XX },
805 { PREGRP31 },
806 { "movhpX", EX, XM, SIMD_Fixup, 'l' },
807 /* 18 */
808 { GRP14 },
809 { "(bad)", XX, XX, XX },
810 { "(bad)", XX, XX, XX },
811 { "(bad)", XX, XX, XX },
812 { "(bad)", XX, XX, XX },
813 { "(bad)", XX, XX, XX },
814 { "(bad)", XX, XX, XX },
815 { "(bad)", XX, XX, XX },
816 /* 20 */
817 { "movL", Rm, Cm, XX },
818 { "movL", Rm, Dm, XX },
819 { "movL", Cm, Rm, XX },
820 { "movL", Dm, Rm, XX },
821 { "movL", Rd, Td, XX },
822 { "(bad)", XX, XX, XX },
823 { "movL", Td, Rd, XX },
824 { "(bad)", XX, XX, XX },
825 /* 28 */
826 { "movapX", XM, EX, XX },
827 { "movapX", EX, XM, XX },
828 { PREGRP2 },
829 { "movntpX", Ev, XM, XX },
830 { PREGRP4 },
831 { PREGRP3 },
832 { "ucomisX", XM,EX, XX },
833 { "comisX", XM,EX, XX },
834 /* 30 */
835 { "wrmsr", XX, XX, XX },
836 { "rdtsc", XX, XX, XX },
837 { "rdmsr", XX, XX, XX },
838 { "rdpmc", XX, XX, XX },
839 { "sysenter", XX, XX, XX },
840 { "sysexit", XX, XX, XX },
841 { "(bad)", XX, XX, XX },
842 { "(bad)", XX, XX, XX },
843 /* 38 */
844 { "(bad)", XX, XX, XX },
845 { "(bad)", XX, XX, XX },
846 { "(bad)", XX, XX, XX },
847 { "(bad)", XX, XX, XX },
848 { "(bad)", XX, XX, XX },
849 { "(bad)", XX, XX, XX },
850 { "(bad)", XX, XX, XX },
851 { "(bad)", XX, XX, XX },
852 /* 40 */
853 { "cmovo", Gv, Ev, XX },
854 { "cmovno", Gv, Ev, XX },
855 { "cmovb", Gv, Ev, XX },
856 { "cmovae", Gv, Ev, XX },
857 { "cmove", Gv, Ev, XX },
858 { "cmovne", Gv, Ev, XX },
859 { "cmovbe", Gv, Ev, XX },
860 { "cmova", Gv, Ev, XX },
861 /* 48 */
862 { "cmovs", Gv, Ev, XX },
863 { "cmovns", Gv, Ev, XX },
864 { "cmovp", Gv, Ev, XX },
865 { "cmovnp", Gv, Ev, XX },
866 { "cmovl", Gv, Ev, XX },
867 { "cmovge", Gv, Ev, XX },
868 { "cmovle", Gv, Ev, XX },
869 { "cmovg", Gv, Ev, XX },
870 /* 50 */
871 { "movmskpX", Gdq, XS, XX },
872 { PREGRP13 },
873 { PREGRP12 },
874 { PREGRP11 },
875 { "andpX", XM, EX, XX },
876 { "andnpX", XM, EX, XX },
877 { "orpX", XM, EX, XX },
878 { "xorpX", XM, EX, XX },
879 /* 58 */
880 { PREGRP0 },
881 { PREGRP10 },
882 { PREGRP17 },
883 { PREGRP16 },
884 { PREGRP14 },
885 { PREGRP7 },
886 { PREGRP5 },
887 { PREGRP6 },
888 /* 60 */
889 { "punpcklbw", MX, EM, XX },
890 { "punpcklwd", MX, EM, XX },
891 { "punpckldq", MX, EM, XX },
892 { "packsswb", MX, EM, XX },
893 { "pcmpgtb", MX, EM, XX },
894 { "pcmpgtw", MX, EM, XX },
895 { "pcmpgtd", MX, EM, XX },
896 { "packuswb", MX, EM, XX },
897 /* 68 */
898 { "punpckhbw", MX, EM, XX },
899 { "punpckhwd", MX, EM, XX },
900 { "punpckhdq", MX, EM, XX },
901 { "packssdw", MX, EM, XX },
902 { PREGRP26 },
903 { PREGRP24 },
904 { "movd", MX, Edq, XX },
905 { PREGRP19 },
906 /* 70 */
907 { PREGRP22 },
908 { GRP10 },
909 { GRP11 },
910 { GRP12 },
911 { "pcmpeqb", MX, EM, XX },
912 { "pcmpeqw", MX, EM, XX },
913 { "pcmpeqd", MX, EM, XX },
914 { "emms", XX, XX, XX },
915 /* 78 */
916 { "(bad)", XX, XX, XX },
917 { "(bad)", XX, XX, XX },
918 { "(bad)", XX, XX, XX },
919 { "(bad)", XX, XX, XX },
920 { PREGRP28 },
921 { PREGRP29 },
922 { PREGRP23 },
923 { PREGRP20 },
924 /* 80 */
925 { "joH", Jv, XX, cond_jump_flag },
926 { "jnoH", Jv, XX, cond_jump_flag },
927 { "jbH", Jv, XX, cond_jump_flag },
928 { "jaeH", Jv, XX, cond_jump_flag },
929 { "jeH", Jv, XX, cond_jump_flag },
930 { "jneH", Jv, XX, cond_jump_flag },
931 { "jbeH", Jv, XX, cond_jump_flag },
932 { "jaH", Jv, XX, cond_jump_flag },
933 /* 88 */
934 { "jsH", Jv, XX, cond_jump_flag },
935 { "jnsH", Jv, XX, cond_jump_flag },
936 { "jpH", Jv, XX, cond_jump_flag },
937 { "jnpH", Jv, XX, cond_jump_flag },
938 { "jlH", Jv, XX, cond_jump_flag },
939 { "jgeH", Jv, XX, cond_jump_flag },
940 { "jleH", Jv, XX, cond_jump_flag },
941 { "jgH", Jv, XX, cond_jump_flag },
942 /* 90 */
943 { "seto", Eb, XX, XX },
944 { "setno", Eb, XX, XX },
945 { "setb", Eb, XX, XX },
946 { "setae", Eb, XX, XX },
947 { "sete", Eb, XX, XX },
948 { "setne", Eb, XX, XX },
949 { "setbe", Eb, XX, XX },
950 { "seta", Eb, XX, XX },
951 /* 98 */
952 { "sets", Eb, XX, XX },
953 { "setns", Eb, XX, XX },
954 { "setp", Eb, XX, XX },
955 { "setnp", Eb, XX, XX },
956 { "setl", Eb, XX, XX },
957 { "setge", Eb, XX, XX },
958 { "setle", Eb, XX, XX },
959 { "setg", Eb, XX, XX },
960 /* a0 */
961 { "pushT", fs, XX, XX },
962 { "popT", fs, XX, XX },
963 { "cpuid", XX, XX, XX },
964 { "btS", Ev, Gv, XX },
965 { "shldS", Ev, Gv, Ib },
966 { "shldS", Ev, Gv, CL },
967 { GRPPADLCK2 },
968 { GRPPADLCK1 },
969 /* a8 */
970 { "pushT", gs, XX, XX },
971 { "popT", gs, XX, XX },
972 { "rsm", XX, XX, XX },
973 { "btsS", Ev, Gv, XX },
974 { "shrdS", Ev, Gv, Ib },
975 { "shrdS", Ev, Gv, CL },
976 { GRP13 },
977 { "imulS", Gv, Ev, XX },
978 /* b0 */
979 { "cmpxchgB", Eb, Gb, XX },
980 { "cmpxchgS", Ev, Gv, XX },
981 { "lssS", Gv, Mp, XX },
982 { "btrS", Ev, Gv, XX },
983 { "lfsS", Gv, Mp, XX },
984 { "lgsS", Gv, Mp, XX },
985 { "movz{bR|x|bR|x}", Gv, Eb, XX },
986 { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */
987 /* b8 */
988 { "(bad)", XX, XX, XX },
989 { "ud2b", XX, XX, XX },
990 { GRP8 },
991 { "btcS", Ev, Gv, XX },
992 { "bsfS", Gv, Ev, XX },
993 { "bsrS", Gv, Ev, XX },
994 { "movs{bR|x|bR|x}", Gv, Eb, XX },
995 { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */
996 /* c0 */
997 { "xaddB", Eb, Gb, XX },
998 { "xaddS", Ev, Gv, XX },
999 { PREGRP1 },
1000 { "movntiS", Ev, Gv, XX },
1001 { "pinsrw", MX, Edqw, Ib },
1002 { "pextrw", Gdq, MS, Ib },
1003 { "shufpX", XM, EX, Ib },
1004 { GRP9 },
1005 /* c8 */
1006 { "bswap", RMeAX, XX, XX },
1007 { "bswap", RMeCX, XX, XX },
1008 { "bswap", RMeDX, XX, XX },
1009 { "bswap", RMeBX, XX, XX },
1010 { "bswap", RMeSP, XX, XX },
1011 { "bswap", RMeBP, XX, XX },
1012 { "bswap", RMeSI, XX, XX },
1013 { "bswap", RMeDI, XX, XX },
1014 /* d0 */
1015 { PREGRP27 },
1016 { "psrlw", MX, EM, XX },
1017 { "psrld", MX, EM, XX },
1018 { "psrlq", MX, EM, XX },
1019 { "paddq", MX, EM, XX },
1020 { "pmullw", MX, EM, XX },
1021 { PREGRP21 },
1022 { "pmovmskb", Gdq, MS, XX },
1023 /* d8 */
1024 { "psubusb", MX, EM, XX },
1025 { "psubusw", MX, EM, XX },
1026 { "pminub", MX, EM, XX },
1027 { "pand", MX, EM, XX },
1028 { "paddusb", MX, EM, XX },
1029 { "paddusw", MX, EM, XX },
1030 { "pmaxub", MX, EM, XX },
1031 { "pandn", MX, EM, XX },
1032 /* e0 */
1033 { "pavgb", MX, EM, XX },
1034 { "psraw", MX, EM, XX },
1035 { "psrad", MX, EM, XX },
1036 { "pavgw", MX, EM, XX },
1037 { "pmulhuw", MX, EM, XX },
1038 { "pmulhw", MX, EM, XX },
1039 { PREGRP15 },
1040 { PREGRP25 },
1041 /* e8 */
1042 { "psubsb", MX, EM, XX },
1043 { "psubsw", MX, EM, XX },
1044 { "pminsw", MX, EM, XX },
1045 { "por", MX, EM, XX },
1046 { "paddsb", MX, EM, XX },
1047 { "paddsw", MX, EM, XX },
1048 { "pmaxsw", MX, EM, XX },
1049 { "pxor", MX, EM, XX },
1050 /* f0 */
1051 { PREGRP32 },
1052 { "psllw", MX, EM, XX },
1053 { "pslld", MX, EM, XX },
1054 { "psllq", MX, EM, XX },
1055 { "pmuludq", MX, EM, XX },
1056 { "pmaddwd", MX, EM, XX },
1057 { "psadbw", MX, EM, XX },
1058 { PREGRP18 },
1059 /* f8 */
1060 { "psubb", MX, EM, XX },
1061 { "psubw", MX, EM, XX },
1062 { "psubd", MX, EM, XX },
1063 { "psubq", MX, EM, XX },
1064 { "paddb", MX, EM, XX },
1065 { "paddw", MX, EM, XX },
1066 { "paddd", MX, EM, XX },
1067 { "(bad)", XX, XX, XX }
1070 static const unsigned char onebyte_has_modrm[256] = {
1071 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1072 /* ------------------------------- */
1073 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1074 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1075 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1076 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1077 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1078 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1079 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1080 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1081 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1082 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1083 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1084 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1085 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1086 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1087 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1088 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1089 /* ------------------------------- */
1090 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1093 static const unsigned char twobyte_has_modrm[256] = {
1094 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1095 /* ------------------------------- */
1096 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1097 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1098 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1099 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1100 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1101 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1102 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1103 /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1, /* 7f */
1104 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1105 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1106 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1107 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1108 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1109 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1110 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1111 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1112 /* ------------------------------- */
1113 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1116 static const unsigned char twobyte_uses_SSE_prefix[256] = {
1117 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1118 /* ------------------------------- */
1119 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1120 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1121 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1122 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1123 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1124 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1125 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1126 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */
1127 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1128 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1129 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1130 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1131 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1132 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1133 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1134 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1135 /* ------------------------------- */
1136 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1139 static char obuf[100];
1140 static char *obufp;
1141 static char scratchbuf[100];
1142 static unsigned char *start_codep;
1143 static unsigned char *insn_codep;
1144 static unsigned char *codep;
1145 static disassemble_info *the_info;
1146 static int mod;
1147 static int rm;
1148 static int reg;
1149 static unsigned char need_modrm;
1151 /* If we are accessing mod/rm/reg without need_modrm set, then the
1152 values are stale. Hitting this abort likely indicates that you
1153 need to update onebyte_has_modrm or twobyte_has_modrm. */
1154 #define MODRM_CHECK if (!need_modrm) abort ()
1156 static const char **names64;
1157 static const char **names32;
1158 static const char **names16;
1159 static const char **names8;
1160 static const char **names8rex;
1161 static const char **names_seg;
1162 static const char **index16;
1164 static const char *intel_names64[] = {
1165 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1166 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1168 static const char *intel_names32[] = {
1169 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1170 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1172 static const char *intel_names16[] = {
1173 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1174 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1176 static const char *intel_names8[] = {
1177 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1179 static const char *intel_names8rex[] = {
1180 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1181 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1183 static const char *intel_names_seg[] = {
1184 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1186 static const char *intel_index16[] = {
1187 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1190 static const char *att_names64[] = {
1191 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1192 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1194 static const char *att_names32[] = {
1195 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1196 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1198 static const char *att_names16[] = {
1199 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1200 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1202 static const char *att_names8[] = {
1203 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1205 static const char *att_names8rex[] = {
1206 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1207 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1209 static const char *att_names_seg[] = {
1210 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1212 static const char *att_index16[] = {
1213 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1216 static const struct dis386 grps[][8] = {
1217 /* GRP1b */
1219 { "addA", Eb, Ib, XX },
1220 { "orA", Eb, Ib, XX },
1221 { "adcA", Eb, Ib, XX },
1222 { "sbbA", Eb, Ib, XX },
1223 { "andA", Eb, Ib, XX },
1224 { "subA", Eb, Ib, XX },
1225 { "xorA", Eb, Ib, XX },
1226 { "cmpA", Eb, Ib, XX }
1228 /* GRP1S */
1230 { "addQ", Ev, Iv, XX },
1231 { "orQ", Ev, Iv, XX },
1232 { "adcQ", Ev, Iv, XX },
1233 { "sbbQ", Ev, Iv, XX },
1234 { "andQ", Ev, Iv, XX },
1235 { "subQ", Ev, Iv, XX },
1236 { "xorQ", Ev, Iv, XX },
1237 { "cmpQ", Ev, Iv, XX }
1239 /* GRP1Ss */
1241 { "addQ", Ev, sIb, XX },
1242 { "orQ", Ev, sIb, XX },
1243 { "adcQ", Ev, sIb, XX },
1244 { "sbbQ", Ev, sIb, XX },
1245 { "andQ", Ev, sIb, XX },
1246 { "subQ", Ev, sIb, XX },
1247 { "xorQ", Ev, sIb, XX },
1248 { "cmpQ", Ev, sIb, XX }
1250 /* GRP2b */
1252 { "rolA", Eb, Ib, XX },
1253 { "rorA", Eb, Ib, XX },
1254 { "rclA", Eb, Ib, XX },
1255 { "rcrA", Eb, Ib, XX },
1256 { "shlA", Eb, Ib, XX },
1257 { "shrA", Eb, Ib, XX },
1258 { "(bad)", XX, XX, XX },
1259 { "sarA", Eb, Ib, XX },
1261 /* GRP2S */
1263 { "rolQ", Ev, Ib, XX },
1264 { "rorQ", Ev, Ib, XX },
1265 { "rclQ", Ev, Ib, XX },
1266 { "rcrQ", Ev, Ib, XX },
1267 { "shlQ", Ev, Ib, XX },
1268 { "shrQ", Ev, Ib, XX },
1269 { "(bad)", XX, XX, XX },
1270 { "sarQ", Ev, Ib, XX },
1272 /* GRP2b_one */
1274 { "rolA", Eb, I1, XX },
1275 { "rorA", Eb, I1, XX },
1276 { "rclA", Eb, I1, XX },
1277 { "rcrA", Eb, I1, XX },
1278 { "shlA", Eb, I1, XX },
1279 { "shrA", Eb, I1, XX },
1280 { "(bad)", XX, XX, XX },
1281 { "sarA", Eb, I1, XX },
1283 /* GRP2S_one */
1285 { "rolQ", Ev, I1, XX },
1286 { "rorQ", Ev, I1, XX },
1287 { "rclQ", Ev, I1, XX },
1288 { "rcrQ", Ev, I1, XX },
1289 { "shlQ", Ev, I1, XX },
1290 { "shrQ", Ev, I1, XX },
1291 { "(bad)", XX, XX, XX},
1292 { "sarQ", Ev, I1, XX },
1294 /* GRP2b_cl */
1296 { "rolA", Eb, CL, XX },
1297 { "rorA", Eb, CL, XX },
1298 { "rclA", Eb, CL, XX },
1299 { "rcrA", Eb, CL, XX },
1300 { "shlA", Eb, CL, XX },
1301 { "shrA", Eb, CL, XX },
1302 { "(bad)", XX, XX, XX },
1303 { "sarA", Eb, CL, XX },
1305 /* GRP2S_cl */
1307 { "rolQ", Ev, CL, XX },
1308 { "rorQ", Ev, CL, XX },
1309 { "rclQ", Ev, CL, XX },
1310 { "rcrQ", Ev, CL, XX },
1311 { "shlQ", Ev, CL, XX },
1312 { "shrQ", Ev, CL, XX },
1313 { "(bad)", XX, XX, XX },
1314 { "sarQ", Ev, CL, XX }
1316 /* GRP3b */
1318 { "testA", Eb, Ib, XX },
1319 { "(bad)", Eb, XX, XX },
1320 { "notA", Eb, XX, XX },
1321 { "negA", Eb, XX, XX },
1322 { "mulA", Eb, XX, XX }, /* Don't print the implicit %al register, */
1323 { "imulA", Eb, XX, XX }, /* to distinguish these opcodes from other */
1324 { "divA", Eb, XX, XX }, /* mul/imul opcodes. Do the same for div */
1325 { "idivA", Eb, XX, XX } /* and idiv for consistency. */
1327 /* GRP3S */
1329 { "testQ", Ev, Iv, XX },
1330 { "(bad)", XX, XX, XX },
1331 { "notQ", Ev, XX, XX },
1332 { "negQ", Ev, XX, XX },
1333 { "mulQ", Ev, XX, XX }, /* Don't print the implicit register. */
1334 { "imulQ", Ev, XX, XX },
1335 { "divQ", Ev, XX, XX },
1336 { "idivQ", Ev, XX, XX },
1338 /* GRP4 */
1340 { "incA", Eb, XX, XX },
1341 { "decA", Eb, XX, XX },
1342 { "(bad)", XX, XX, XX },
1343 { "(bad)", XX, XX, XX },
1344 { "(bad)", XX, XX, XX },
1345 { "(bad)", XX, XX, XX },
1346 { "(bad)", XX, XX, XX },
1347 { "(bad)", XX, XX, XX },
1349 /* GRP5 */
1351 { "incQ", Ev, XX, XX },
1352 { "decQ", Ev, XX, XX },
1353 { "callT", indirEv, XX, XX },
1354 { "JcallT", indirEp, XX, XX },
1355 { "jmpT", indirEv, XX, XX },
1356 { "JjmpT", indirEp, XX, XX },
1357 { "pushU", Ev, XX, XX },
1358 { "(bad)", XX, XX, XX },
1360 /* GRP6 */
1362 { "sldtQ", Ev, XX, XX },
1363 { "strQ", Ev, XX, XX },
1364 { "lldt", Ew, XX, XX },
1365 { "ltr", Ew, XX, XX },
1366 { "verr", Ew, XX, XX },
1367 { "verw", Ew, XX, XX },
1368 { "(bad)", XX, XX, XX },
1369 { "(bad)", XX, XX, XX }
1371 /* GRP7 */
1373 { "sgdtIQ", M, XX, XX },
1374 { "sidtIQ", PNI_Fixup, 0, XX, XX },
1375 { "lgdt{Q|Q||}", M, XX, XX },
1376 { "lidt{Q|Q||}", M, XX, XX },
1377 { "smswQ", Ev, XX, XX },
1378 { "(bad)", XX, XX, XX },
1379 { "lmsw", Ew, XX, XX },
1380 { "invlpg", INVLPG_Fixup, w_mode, XX, XX },
1382 /* GRP8 */
1384 { "(bad)", XX, XX, XX },
1385 { "(bad)", XX, XX, XX },
1386 { "(bad)", XX, XX, XX },
1387 { "(bad)", XX, XX, XX },
1388 { "btQ", Ev, Ib, XX },
1389 { "btsQ", Ev, Ib, XX },
1390 { "btrQ", Ev, Ib, XX },
1391 { "btcQ", Ev, Ib, XX },
1393 /* GRP9 */
1395 { "(bad)", XX, XX, XX },
1396 { "cmpxchg8b", Eq, XX, XX },
1397 { "(bad)", XX, XX, XX },
1398 { "(bad)", XX, XX, XX },
1399 { "(bad)", XX, XX, XX },
1400 { "(bad)", XX, XX, XX },
1401 { "(bad)", XX, XX, XX },
1402 { "(bad)", XX, XX, XX },
1404 /* GRP10 */
1406 { "(bad)", XX, XX, XX },
1407 { "(bad)", XX, XX, XX },
1408 { "psrlw", MS, Ib, XX },
1409 { "(bad)", XX, XX, XX },
1410 { "psraw", MS, Ib, XX },
1411 { "(bad)", XX, XX, XX },
1412 { "psllw", MS, Ib, XX },
1413 { "(bad)", XX, XX, XX },
1415 /* GRP11 */
1417 { "(bad)", XX, XX, XX },
1418 { "(bad)", XX, XX, XX },
1419 { "psrld", MS, Ib, XX },
1420 { "(bad)", XX, XX, XX },
1421 { "psrad", MS, Ib, XX },
1422 { "(bad)", XX, XX, XX },
1423 { "pslld", MS, Ib, XX },
1424 { "(bad)", XX, XX, XX },
1426 /* GRP12 */
1428 { "(bad)", XX, XX, XX },
1429 { "(bad)", XX, XX, XX },
1430 { "psrlq", MS, Ib, XX },
1431 { "psrldq", MS, Ib, XX },
1432 { "(bad)", XX, XX, XX },
1433 { "(bad)", XX, XX, XX },
1434 { "psllq", MS, Ib, XX },
1435 { "pslldq", MS, Ib, XX },
1437 /* GRP13 */
1439 { "fxsave", Ev, XX, XX },
1440 { "fxrstor", Ev, XX, XX },
1441 { "ldmxcsr", Ev, XX, XX },
1442 { "stmxcsr", Ev, XX, XX },
1443 { "(bad)", XX, XX, XX },
1444 { "lfence", OP_0fae, 0, XX, XX },
1445 { "mfence", OP_0fae, 0, XX, XX },
1446 { "clflush", OP_0fae, 0, XX, XX },
1448 /* GRP14 */
1450 { "prefetchnta", Ev, XX, XX },
1451 { "prefetcht0", Ev, XX, XX },
1452 { "prefetcht1", Ev, XX, XX },
1453 { "prefetcht2", Ev, XX, XX },
1454 { "(bad)", XX, XX, XX },
1455 { "(bad)", XX, XX, XX },
1456 { "(bad)", XX, XX, XX },
1457 { "(bad)", XX, XX, XX },
1459 /* GRPAMD */
1461 { "prefetch", Eb, XX, XX },
1462 { "prefetchw", Eb, XX, XX },
1463 { "(bad)", XX, XX, XX },
1464 { "(bad)", XX, XX, XX },
1465 { "(bad)", XX, XX, XX },
1466 { "(bad)", XX, XX, XX },
1467 { "(bad)", XX, XX, XX },
1468 { "(bad)", XX, XX, XX },
1470 /* GRPPADLCK1 */
1472 { "xstore-rng", OP_0f07, 0, XX, XX },
1473 { "xcrypt-ecb", OP_0f07, 0, XX, XX },
1474 { "xcrypt-cbc", OP_0f07, 0, XX, XX },
1475 { "xcrypt-ctr", OP_0f07, 0, XX, XX },
1476 { "xcrypt-cfb", OP_0f07, 0, XX, XX },
1477 { "xcrypt-ofb", OP_0f07, 0, XX, XX },
1478 { "(bad)", OP_0f07, 0, XX, XX },
1479 { "(bad)", OP_0f07, 0, XX, XX },
1481 /* GRPPADLCK2 */
1483 { "montmul", OP_0f07, 0, XX, XX },
1484 { "xsha1", OP_0f07, 0, XX, XX },
1485 { "xsha256", OP_0f07, 0, XX, XX },
1486 { "(bad)", OP_0f07, 0, XX, XX },
1487 { "(bad)", OP_0f07, 0, XX, XX },
1488 { "(bad)", OP_0f07, 0, XX, XX },
1489 { "(bad)", OP_0f07, 0, XX, XX },
1490 { "(bad)", OP_0f07, 0, XX, XX },
1494 static const struct dis386 prefix_user_table[][4] = {
1495 /* PREGRP0 */
1497 { "addps", XM, EX, XX },
1498 { "addss", XM, EX, XX },
1499 { "addpd", XM, EX, XX },
1500 { "addsd", XM, EX, XX },
1502 /* PREGRP1 */
1504 { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */
1505 { "", XM, EX, OPSIMD },
1506 { "", XM, EX, OPSIMD },
1507 { "", XM, EX, OPSIMD },
1509 /* PREGRP2 */
1511 { "cvtpi2ps", XM, EM, XX },
1512 { "cvtsi2ssY", XM, Ev, XX },
1513 { "cvtpi2pd", XM, EM, XX },
1514 { "cvtsi2sdY", XM, Ev, XX },
1516 /* PREGRP3 */
1518 { "cvtps2pi", MX, EX, XX },
1519 { "cvtss2siY", Gv, EX, XX },
1520 { "cvtpd2pi", MX, EX, XX },
1521 { "cvtsd2siY", Gv, EX, XX },
1523 /* PREGRP4 */
1525 { "cvttps2pi", MX, EX, XX },
1526 { "cvttss2siY", Gv, EX, XX },
1527 { "cvttpd2pi", MX, EX, XX },
1528 { "cvttsd2siY", Gv, EX, XX },
1530 /* PREGRP5 */
1532 { "divps", XM, EX, XX },
1533 { "divss", XM, EX, XX },
1534 { "divpd", XM, EX, XX },
1535 { "divsd", XM, EX, XX },
1537 /* PREGRP6 */
1539 { "maxps", XM, EX, XX },
1540 { "maxss", XM, EX, XX },
1541 { "maxpd", XM, EX, XX },
1542 { "maxsd", XM, EX, XX },
1544 /* PREGRP7 */
1546 { "minps", XM, EX, XX },
1547 { "minss", XM, EX, XX },
1548 { "minpd", XM, EX, XX },
1549 { "minsd", XM, EX, XX },
1551 /* PREGRP8 */
1553 { "movups", XM, EX, XX },
1554 { "movss", XM, EX, XX },
1555 { "movupd", XM, EX, XX },
1556 { "movsd", XM, EX, XX },
1558 /* PREGRP9 */
1560 { "movups", EX, XM, XX },
1561 { "movss", EX, XM, XX },
1562 { "movupd", EX, XM, XX },
1563 { "movsd", EX, XM, XX },
1565 /* PREGRP10 */
1567 { "mulps", XM, EX, XX },
1568 { "mulss", XM, EX, XX },
1569 { "mulpd", XM, EX, XX },
1570 { "mulsd", XM, EX, XX },
1572 /* PREGRP11 */
1574 { "rcpps", XM, EX, XX },
1575 { "rcpss", XM, EX, XX },
1576 { "(bad)", XM, EX, XX },
1577 { "(bad)", XM, EX, XX },
1579 /* PREGRP12 */
1581 { "rsqrtps", XM, EX, XX },
1582 { "rsqrtss", XM, EX, XX },
1583 { "(bad)", XM, EX, XX },
1584 { "(bad)", XM, EX, XX },
1586 /* PREGRP13 */
1588 { "sqrtps", XM, EX, XX },
1589 { "sqrtss", XM, EX, XX },
1590 { "sqrtpd", XM, EX, XX },
1591 { "sqrtsd", XM, EX, XX },
1593 /* PREGRP14 */
1595 { "subps", XM, EX, XX },
1596 { "subss", XM, EX, XX },
1597 { "subpd", XM, EX, XX },
1598 { "subsd", XM, EX, XX },
1600 /* PREGRP15 */
1602 { "(bad)", XM, EX, XX },
1603 { "cvtdq2pd", XM, EX, XX },
1604 { "cvttpd2dq", XM, EX, XX },
1605 { "cvtpd2dq", XM, EX, XX },
1607 /* PREGRP16 */
1609 { "cvtdq2ps", XM, EX, XX },
1610 { "cvttps2dq",XM, EX, XX },
1611 { "cvtps2dq",XM, EX, XX },
1612 { "(bad)", XM, EX, XX },
1614 /* PREGRP17 */
1616 { "cvtps2pd", XM, EX, XX },
1617 { "cvtss2sd", XM, EX, XX },
1618 { "cvtpd2ps", XM, EX, XX },
1619 { "cvtsd2ss", XM, EX, XX },
1621 /* PREGRP18 */
1623 { "maskmovq", MX, MS, XX },
1624 { "(bad)", XM, EX, XX },
1625 { "maskmovdqu", XM, EX, XX },
1626 { "(bad)", XM, EX, XX },
1628 /* PREGRP19 */
1630 { "movq", MX, EM, XX },
1631 { "movdqu", XM, EX, XX },
1632 { "movdqa", XM, EX, XX },
1633 { "(bad)", XM, EX, XX },
1635 /* PREGRP20 */
1637 { "movq", EM, MX, XX },
1638 { "movdqu", EX, XM, XX },
1639 { "movdqa", EX, XM, XX },
1640 { "(bad)", EX, XM, XX },
1642 /* PREGRP21 */
1644 { "(bad)", EX, XM, XX },
1645 { "movq2dq", XM, MS, XX },
1646 { "movq", EX, XM, XX },
1647 { "movdq2q", MX, XS, XX },
1649 /* PREGRP22 */
1651 { "pshufw", MX, EM, Ib },
1652 { "pshufhw", XM, EX, Ib },
1653 { "pshufd", XM, EX, Ib },
1654 { "pshuflw", XM, EX, Ib },
1656 /* PREGRP23 */
1658 { "movd", Edq, MX, XX },
1659 { "movq", XM, EX, XX },
1660 { "movd", Edq, XM, XX },
1661 { "(bad)", Ed, XM, XX },
1663 /* PREGRP24 */
1665 { "(bad)", MX, EX, XX },
1666 { "(bad)", XM, EX, XX },
1667 { "punpckhqdq", XM, EX, XX },
1668 { "(bad)", XM, EX, XX },
1670 /* PREGRP25 */
1672 { "movntq", EM, MX, XX },
1673 { "(bad)", EM, XM, XX },
1674 { "movntdq", EM, XM, XX },
1675 { "(bad)", EM, XM, XX },
1677 /* PREGRP26 */
1679 { "(bad)", MX, EX, XX },
1680 { "(bad)", XM, EX, XX },
1681 { "punpcklqdq", XM, EX, XX },
1682 { "(bad)", XM, EX, XX },
1684 /* PREGRP27 */
1686 { "(bad)", MX, EX, XX },
1687 { "(bad)", XM, EX, XX },
1688 { "addsubpd", XM, EX, XX },
1689 { "addsubps", XM, EX, XX },
1691 /* PREGRP28 */
1693 { "(bad)", MX, EX, XX },
1694 { "(bad)", XM, EX, XX },
1695 { "haddpd", XM, EX, XX },
1696 { "haddps", XM, EX, XX },
1698 /* PREGRP29 */
1700 { "(bad)", MX, EX, XX },
1701 { "(bad)", XM, EX, XX },
1702 { "hsubpd", XM, EX, XX },
1703 { "hsubps", XM, EX, XX },
1705 /* PREGRP30 */
1707 { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
1708 { "movsldup", XM, EX, XX },
1709 { "movlpd", XM, EX, XX },
1710 { "movddup", XM, EX, XX },
1712 /* PREGRP31 */
1714 { "movhpX", XM, EX, SIMD_Fixup, 'l' },
1715 { "movshdup", XM, EX, XX },
1716 { "movhpd", XM, EX, XX },
1717 { "(bad)", XM, EX, XX },
1719 /* PREGRP32 */
1721 { "(bad)", XM, EX, XX },
1722 { "(bad)", XM, EX, XX },
1723 { "(bad)", XM, EX, XX },
1724 { "lddqu", XM, M, XX },
1728 static const struct dis386 x86_64_table[][2] = {
1730 { "arpl", Ew, Gw, XX },
1731 { "movs{||lq|xd}", Gv, Ed, XX },
1735 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1737 static void
1738 ckprefix (void)
1740 int newrex;
1741 rex = 0;
1742 prefixes = 0;
1743 used_prefixes = 0;
1744 rex_used = 0;
1745 while (1)
1747 FETCH_DATA (the_info, codep + 1);
1748 newrex = 0;
1749 switch (*codep)
1751 /* REX prefixes family. */
1752 case 0x40:
1753 case 0x41:
1754 case 0x42:
1755 case 0x43:
1756 case 0x44:
1757 case 0x45:
1758 case 0x46:
1759 case 0x47:
1760 case 0x48:
1761 case 0x49:
1762 case 0x4a:
1763 case 0x4b:
1764 case 0x4c:
1765 case 0x4d:
1766 case 0x4e:
1767 case 0x4f:
1768 if (mode_64bit)
1769 newrex = *codep;
1770 else
1771 return;
1772 break;
1773 case 0xf3:
1774 prefixes |= PREFIX_REPZ;
1775 break;
1776 case 0xf2:
1777 prefixes |= PREFIX_REPNZ;
1778 break;
1779 case 0xf0:
1780 prefixes |= PREFIX_LOCK;
1781 break;
1782 case 0x2e:
1783 prefixes |= PREFIX_CS;
1784 break;
1785 case 0x36:
1786 prefixes |= PREFIX_SS;
1787 break;
1788 case 0x3e:
1789 prefixes |= PREFIX_DS;
1790 break;
1791 case 0x26:
1792 prefixes |= PREFIX_ES;
1793 break;
1794 case 0x64:
1795 prefixes |= PREFIX_FS;
1796 break;
1797 case 0x65:
1798 prefixes |= PREFIX_GS;
1799 break;
1800 case 0x66:
1801 prefixes |= PREFIX_DATA;
1802 break;
1803 case 0x67:
1804 prefixes |= PREFIX_ADDR;
1805 break;
1806 case FWAIT_OPCODE:
1807 /* fwait is really an instruction. If there are prefixes
1808 before the fwait, they belong to the fwait, *not* to the
1809 following instruction. */
1810 if (prefixes)
1812 prefixes |= PREFIX_FWAIT;
1813 codep++;
1814 return;
1816 prefixes = PREFIX_FWAIT;
1817 break;
1818 default:
1819 return;
1821 /* Rex is ignored when followed by another prefix. */
1822 if (rex)
1824 oappend (prefix_name (rex, 0));
1825 oappend (" ");
1827 rex = newrex;
1828 codep++;
1832 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
1833 prefix byte. */
1835 static const char *
1836 prefix_name (int pref, int sizeflag)
1838 switch (pref)
1840 /* REX prefixes family. */
1841 case 0x40:
1842 return "rex";
1843 case 0x41:
1844 return "rexZ";
1845 case 0x42:
1846 return "rexY";
1847 case 0x43:
1848 return "rexYZ";
1849 case 0x44:
1850 return "rexX";
1851 case 0x45:
1852 return "rexXZ";
1853 case 0x46:
1854 return "rexXY";
1855 case 0x47:
1856 return "rexXYZ";
1857 case 0x48:
1858 return "rex64";
1859 case 0x49:
1860 return "rex64Z";
1861 case 0x4a:
1862 return "rex64Y";
1863 case 0x4b:
1864 return "rex64YZ";
1865 case 0x4c:
1866 return "rex64X";
1867 case 0x4d:
1868 return "rex64XZ";
1869 case 0x4e:
1870 return "rex64XY";
1871 case 0x4f:
1872 return "rex64XYZ";
1873 case 0xf3:
1874 return "repz";
1875 case 0xf2:
1876 return "repnz";
1877 case 0xf0:
1878 return "lock";
1879 case 0x2e:
1880 return "cs";
1881 case 0x36:
1882 return "ss";
1883 case 0x3e:
1884 return "ds";
1885 case 0x26:
1886 return "es";
1887 case 0x64:
1888 return "fs";
1889 case 0x65:
1890 return "gs";
1891 case 0x66:
1892 return (sizeflag & DFLAG) ? "data16" : "data32";
1893 case 0x67:
1894 if (mode_64bit)
1895 return (sizeflag & AFLAG) ? "addr32" : "addr64";
1896 else
1897 return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32";
1898 case FWAIT_OPCODE:
1899 return "fwait";
1900 default:
1901 return NULL;
1905 static char op1out[100], op2out[100], op3out[100];
1906 static int op_ad, op_index[3];
1907 static int two_source_ops;
1908 static bfd_vma op_address[3];
1909 static bfd_vma op_riprel[3];
1910 static bfd_vma start_pc;
1913 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1914 * (see topic "Redundant prefixes" in the "Differences from 8086"
1915 * section of the "Virtual 8086 Mode" chapter.)
1916 * 'pc' should be the address of this instruction, it will
1917 * be used to print the target address if this is a relative jump or call
1918 * The function returns the length of this instruction in bytes.
1921 static char intel_syntax;
1922 static char open_char;
1923 static char close_char;
1924 static char separator_char;
1925 static char scale_char;
1927 /* Here for backwards compatibility. When gdb stops using
1928 print_insn_i386_att and print_insn_i386_intel these functions can
1929 disappear, and print_insn_i386 be merged into print_insn. */
1931 print_insn_i386_att (bfd_vma pc, disassemble_info *info)
1933 intel_syntax = 0;
1935 return print_insn (pc, info);
1939 print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
1941 intel_syntax = 1;
1943 return print_insn (pc, info);
1947 print_insn_i386 (bfd_vma pc, disassemble_info *info)
1949 intel_syntax = -1;
1951 return print_insn (pc, info);
1954 static int
1955 print_insn (bfd_vma pc, disassemble_info *info)
1957 const struct dis386 *dp;
1958 int i;
1959 char *first, *second, *third;
1960 int needcomma;
1961 unsigned char uses_SSE_prefix, uses_LOCK_prefix;
1962 int sizeflag;
1963 const char *p;
1964 struct dis_private priv;
1966 mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
1967 || info->mach == bfd_mach_x86_64);
1969 if (intel_syntax == (char) -1)
1970 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
1971 || info->mach == bfd_mach_x86_64_intel_syntax);
1973 if (info->mach == bfd_mach_i386_i386
1974 || info->mach == bfd_mach_x86_64
1975 || info->mach == bfd_mach_i386_i386_intel_syntax
1976 || info->mach == bfd_mach_x86_64_intel_syntax)
1977 priv.orig_sizeflag = AFLAG | DFLAG;
1978 else if (info->mach == bfd_mach_i386_i8086)
1979 priv.orig_sizeflag = 0;
1980 else
1981 abort ();
1983 for (p = info->disassembler_options; p != NULL; )
1985 if (strncmp (p, "x86-64", 6) == 0)
1987 mode_64bit = 1;
1988 priv.orig_sizeflag = AFLAG | DFLAG;
1990 else if (strncmp (p, "i386", 4) == 0)
1992 mode_64bit = 0;
1993 priv.orig_sizeflag = AFLAG | DFLAG;
1995 else if (strncmp (p, "i8086", 5) == 0)
1997 mode_64bit = 0;
1998 priv.orig_sizeflag = 0;
2000 else if (strncmp (p, "intel", 5) == 0)
2002 intel_syntax = 1;
2004 else if (strncmp (p, "att", 3) == 0)
2006 intel_syntax = 0;
2008 else if (strncmp (p, "addr", 4) == 0)
2010 if (p[4] == '1' && p[5] == '6')
2011 priv.orig_sizeflag &= ~AFLAG;
2012 else if (p[4] == '3' && p[5] == '2')
2013 priv.orig_sizeflag |= AFLAG;
2015 else if (strncmp (p, "data", 4) == 0)
2017 if (p[4] == '1' && p[5] == '6')
2018 priv.orig_sizeflag &= ~DFLAG;
2019 else if (p[4] == '3' && p[5] == '2')
2020 priv.orig_sizeflag |= DFLAG;
2022 else if (strncmp (p, "suffix", 6) == 0)
2023 priv.orig_sizeflag |= SUFFIX_ALWAYS;
2025 p = strchr (p, ',');
2026 if (p != NULL)
2027 p++;
2030 if (intel_syntax)
2032 names64 = intel_names64;
2033 names32 = intel_names32;
2034 names16 = intel_names16;
2035 names8 = intel_names8;
2036 names8rex = intel_names8rex;
2037 names_seg = intel_names_seg;
2038 index16 = intel_index16;
2039 open_char = '[';
2040 close_char = ']';
2041 separator_char = '+';
2042 scale_char = '*';
2044 else
2046 names64 = att_names64;
2047 names32 = att_names32;
2048 names16 = att_names16;
2049 names8 = att_names8;
2050 names8rex = att_names8rex;
2051 names_seg = att_names_seg;
2052 index16 = att_index16;
2053 open_char = '(';
2054 close_char = ')';
2055 separator_char = ',';
2056 scale_char = ',';
2059 /* The output looks better if we put 7 bytes on a line, since that
2060 puts most long word instructions on a single line. */
2061 info->bytes_per_line = 7;
2063 info->private_data = &priv;
2064 priv.max_fetched = priv.the_buffer;
2065 priv.insn_start = pc;
2067 obuf[0] = 0;
2068 op1out[0] = 0;
2069 op2out[0] = 0;
2070 op3out[0] = 0;
2072 op_index[0] = op_index[1] = op_index[2] = -1;
2074 the_info = info;
2075 start_pc = pc;
2076 start_codep = priv.the_buffer;
2077 codep = priv.the_buffer;
2079 if (setjmp (priv.bailout) != 0)
2081 const char *name;
2083 /* Getting here means we tried for data but didn't get it. That
2084 means we have an incomplete instruction of some sort. Just
2085 print the first byte as a prefix or a .byte pseudo-op. */
2086 if (codep > priv.the_buffer)
2088 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2089 if (name != NULL)
2090 (*info->fprintf_func) (info->stream, "%s", name);
2091 else
2093 /* Just print the first byte as a .byte instruction. */
2094 (*info->fprintf_func) (info->stream, ".byte 0x%x",
2095 (unsigned int) priv.the_buffer[0]);
2098 return 1;
2101 return -1;
2104 obufp = obuf;
2105 ckprefix ();
2107 insn_codep = codep;
2108 sizeflag = priv.orig_sizeflag;
2110 FETCH_DATA (info, codep + 1);
2111 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
2113 if ((prefixes & PREFIX_FWAIT)
2114 && ((*codep < 0xd8) || (*codep > 0xdf)))
2116 const char *name;
2118 /* fwait not followed by floating point instruction. Print the
2119 first prefix, which is probably fwait itself. */
2120 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2121 if (name == NULL)
2122 name = INTERNAL_DISASSEMBLER_ERROR;
2123 (*info->fprintf_func) (info->stream, "%s", name);
2124 return 1;
2127 if (*codep == 0x0f)
2129 FETCH_DATA (info, codep + 2);
2130 dp = &dis386_twobyte[*++codep];
2131 need_modrm = twobyte_has_modrm[*codep];
2132 uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
2133 uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
2135 else
2137 dp = &dis386[*codep];
2138 need_modrm = onebyte_has_modrm[*codep];
2139 uses_SSE_prefix = 0;
2140 uses_LOCK_prefix = 0;
2142 codep++;
2144 if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
2146 oappend ("repz ");
2147 used_prefixes |= PREFIX_REPZ;
2149 if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
2151 oappend ("repnz ");
2152 used_prefixes |= PREFIX_REPNZ;
2154 if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
2156 oappend ("lock ");
2157 used_prefixes |= PREFIX_LOCK;
2160 if (prefixes & PREFIX_ADDR)
2162 sizeflag ^= AFLAG;
2163 if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
2165 if ((sizeflag & AFLAG) || mode_64bit)
2166 oappend ("addr32 ");
2167 else
2168 oappend ("addr16 ");
2169 used_prefixes |= PREFIX_ADDR;
2173 if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
2175 sizeflag ^= DFLAG;
2176 if (dp->bytemode3 == cond_jump_mode
2177 && dp->bytemode1 == v_mode
2178 && !intel_syntax)
2180 if (sizeflag & DFLAG)
2181 oappend ("data32 ");
2182 else
2183 oappend ("data16 ");
2184 used_prefixes |= PREFIX_DATA;
2188 if (need_modrm)
2190 FETCH_DATA (info, codep + 1);
2191 mod = (*codep >> 6) & 3;
2192 reg = (*codep >> 3) & 7;
2193 rm = *codep & 7;
2196 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2198 dofloat (sizeflag);
2200 else
2202 int index;
2203 if (dp->name == NULL)
2205 switch (dp->bytemode1)
2207 case USE_GROUPS:
2208 dp = &grps[dp->bytemode2][reg];
2209 break;
2211 case USE_PREFIX_USER_TABLE:
2212 index = 0;
2213 used_prefixes |= (prefixes & PREFIX_REPZ);
2214 if (prefixes & PREFIX_REPZ)
2215 index = 1;
2216 else
2218 used_prefixes |= (prefixes & PREFIX_DATA);
2219 if (prefixes & PREFIX_DATA)
2220 index = 2;
2221 else
2223 used_prefixes |= (prefixes & PREFIX_REPNZ);
2224 if (prefixes & PREFIX_REPNZ)
2225 index = 3;
2228 dp = &prefix_user_table[dp->bytemode2][index];
2229 break;
2231 case X86_64_SPECIAL:
2232 dp = &x86_64_table[dp->bytemode2][mode_64bit];
2233 break;
2235 default:
2236 oappend (INTERNAL_DISASSEMBLER_ERROR);
2237 break;
2241 if (putop (dp->name, sizeflag) == 0)
2243 obufp = op1out;
2244 op_ad = 2;
2245 if (dp->op1)
2246 (*dp->op1) (dp->bytemode1, sizeflag);
2248 obufp = op2out;
2249 op_ad = 1;
2250 if (dp->op2)
2251 (*dp->op2) (dp->bytemode2, sizeflag);
2253 obufp = op3out;
2254 op_ad = 0;
2255 if (dp->op3)
2256 (*dp->op3) (dp->bytemode3, sizeflag);
2260 /* See if any prefixes were not used. If so, print the first one
2261 separately. If we don't do this, we'll wind up printing an
2262 instruction stream which does not precisely correspond to the
2263 bytes we are disassembling. */
2264 if ((prefixes & ~used_prefixes) != 0)
2266 const char *name;
2268 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2269 if (name == NULL)
2270 name = INTERNAL_DISASSEMBLER_ERROR;
2271 (*info->fprintf_func) (info->stream, "%s", name);
2272 return 1;
2274 if (rex & ~rex_used)
2276 const char *name;
2277 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
2278 if (name == NULL)
2279 name = INTERNAL_DISASSEMBLER_ERROR;
2280 (*info->fprintf_func) (info->stream, "%s ", name);
2283 obufp = obuf + strlen (obuf);
2284 for (i = strlen (obuf); i < 6; i++)
2285 oappend (" ");
2286 oappend (" ");
2287 (*info->fprintf_func) (info->stream, "%s", obuf);
2289 /* The enter and bound instructions are printed with operands in the same
2290 order as the intel book; everything else is printed in reverse order. */
2291 if (intel_syntax || two_source_ops)
2293 first = op1out;
2294 second = op2out;
2295 third = op3out;
2296 op_ad = op_index[0];
2297 op_index[0] = op_index[2];
2298 op_index[2] = op_ad;
2300 else
2302 first = op3out;
2303 second = op2out;
2304 third = op1out;
2306 needcomma = 0;
2307 if (*first)
2309 if (op_index[0] != -1 && !op_riprel[0])
2310 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
2311 else
2312 (*info->fprintf_func) (info->stream, "%s", first);
2313 needcomma = 1;
2315 if (*second)
2317 if (needcomma)
2318 (*info->fprintf_func) (info->stream, ",");
2319 if (op_index[1] != -1 && !op_riprel[1])
2320 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
2321 else
2322 (*info->fprintf_func) (info->stream, "%s", second);
2323 needcomma = 1;
2325 if (*third)
2327 if (needcomma)
2328 (*info->fprintf_func) (info->stream, ",");
2329 if (op_index[2] != -1 && !op_riprel[2])
2330 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
2331 else
2332 (*info->fprintf_func) (info->stream, "%s", third);
2334 for (i = 0; i < 3; i++)
2335 if (op_index[i] != -1 && op_riprel[i])
2337 (*info->fprintf_func) (info->stream, " # ");
2338 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
2339 + op_address[op_index[i]]), info);
2341 return codep - priv.the_buffer;
2344 static const char *float_mem[] = {
2345 /* d8 */
2346 "fadd{s||s|}",
2347 "fmul{s||s|}",
2348 "fcom{s||s|}",
2349 "fcomp{s||s|}",
2350 "fsub{s||s|}",
2351 "fsubr{s||s|}",
2352 "fdiv{s||s|}",
2353 "fdivr{s||s|}",
2354 /* d9 */
2355 "fld{s||s|}",
2356 "(bad)",
2357 "fst{s||s|}",
2358 "fstp{s||s|}",
2359 "fldenvIC",
2360 "fldcw",
2361 "fNstenvIC",
2362 "fNstcw",
2363 /* da */
2364 "fiadd{l||l|}",
2365 "fimul{l||l|}",
2366 "ficom{l||l|}",
2367 "ficomp{l||l|}",
2368 "fisub{l||l|}",
2369 "fisubr{l||l|}",
2370 "fidiv{l||l|}",
2371 "fidivr{l||l|}",
2372 /* db */
2373 "fild{l||l|}",
2374 "fisttp{l||l|}",
2375 "fist{l||l|}",
2376 "fistp{l||l|}",
2377 "(bad)",
2378 "fld{t||t|}",
2379 "(bad)",
2380 "fstp{t||t|}",
2381 /* dc */
2382 "fadd{l||l|}",
2383 "fmul{l||l|}",
2384 "fcom{l||l|}",
2385 "fcomp{l||l|}",
2386 "fsub{l||l|}",
2387 "fsubr{l||l|}",
2388 "fdiv{l||l|}",
2389 "fdivr{l||l|}",
2390 /* dd */
2391 "fld{l||l|}",
2392 "fisttp{ll||ll|}",
2393 "fst{l||l|}",
2394 "fstp{l||l|}",
2395 "frstorIC",
2396 "(bad)",
2397 "fNsaveIC",
2398 "fNstsw",
2399 /* de */
2400 "fiadd",
2401 "fimul",
2402 "ficom",
2403 "ficomp",
2404 "fisub",
2405 "fisubr",
2406 "fidiv",
2407 "fidivr",
2408 /* df */
2409 "fild",
2410 "fisttp",
2411 "fist",
2412 "fistp",
2413 "fbld",
2414 "fild{ll||ll|}",
2415 "fbstp",
2416 "fistp{ll||ll|}",
2419 static const unsigned char float_mem_mode[] = {
2420 /* d8 */
2421 d_mode,
2422 d_mode,
2423 d_mode,
2424 d_mode,
2425 d_mode,
2426 d_mode,
2427 d_mode,
2428 d_mode,
2429 /* d9 */
2430 d_mode,
2432 d_mode,
2433 d_mode,
2435 w_mode,
2437 w_mode,
2438 /* da */
2439 d_mode,
2440 d_mode,
2441 d_mode,
2442 d_mode,
2443 d_mode,
2444 d_mode,
2445 d_mode,
2446 d_mode,
2447 /* db */
2448 d_mode,
2449 d_mode,
2450 d_mode,
2451 d_mode,
2453 t_mode,
2455 t_mode,
2456 /* dc */
2457 q_mode,
2458 q_mode,
2459 q_mode,
2460 q_mode,
2461 q_mode,
2462 q_mode,
2463 q_mode,
2464 q_mode,
2465 /* dd */
2466 q_mode,
2467 q_mode,
2468 q_mode,
2469 q_mode,
2473 w_mode,
2474 /* de */
2475 w_mode,
2476 w_mode,
2477 w_mode,
2478 w_mode,
2479 w_mode,
2480 w_mode,
2481 w_mode,
2482 w_mode,
2483 /* df */
2484 w_mode,
2485 w_mode,
2486 w_mode,
2487 w_mode,
2488 t_mode,
2489 q_mode,
2490 t_mode,
2491 q_mode
2494 #define ST OP_ST, 0
2495 #define STi OP_STi, 0
2497 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
2498 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
2499 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
2500 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
2501 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
2502 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
2503 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
2504 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
2505 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
2507 static const struct dis386 float_reg[][8] = {
2508 /* d8 */
2510 { "fadd", ST, STi, XX },
2511 { "fmul", ST, STi, XX },
2512 { "fcom", STi, XX, XX },
2513 { "fcomp", STi, XX, XX },
2514 { "fsub", ST, STi, XX },
2515 { "fsubr", ST, STi, XX },
2516 { "fdiv", ST, STi, XX },
2517 { "fdivr", ST, STi, XX },
2519 /* d9 */
2521 { "fld", STi, XX, XX },
2522 { "fxch", STi, XX, XX },
2523 { FGRPd9_2 },
2524 { "(bad)", XX, XX, XX },
2525 { FGRPd9_4 },
2526 { FGRPd9_5 },
2527 { FGRPd9_6 },
2528 { FGRPd9_7 },
2530 /* da */
2532 { "fcmovb", ST, STi, XX },
2533 { "fcmove", ST, STi, XX },
2534 { "fcmovbe",ST, STi, XX },
2535 { "fcmovu", ST, STi, XX },
2536 { "(bad)", XX, XX, XX },
2537 { FGRPda_5 },
2538 { "(bad)", XX, XX, XX },
2539 { "(bad)", XX, XX, XX },
2541 /* db */
2543 { "fcmovnb",ST, STi, XX },
2544 { "fcmovne",ST, STi, XX },
2545 { "fcmovnbe",ST, STi, XX },
2546 { "fcmovnu",ST, STi, XX },
2547 { FGRPdb_4 },
2548 { "fucomi", ST, STi, XX },
2549 { "fcomi", ST, STi, XX },
2550 { "(bad)", XX, XX, XX },
2552 /* dc */
2554 { "fadd", STi, ST, XX },
2555 { "fmul", STi, ST, XX },
2556 { "(bad)", XX, XX, XX },
2557 { "(bad)", XX, XX, XX },
2558 #if UNIXWARE_COMPAT
2559 { "fsub", STi, ST, XX },
2560 { "fsubr", STi, ST, XX },
2561 { "fdiv", STi, ST, XX },
2562 { "fdivr", STi, ST, XX },
2563 #else
2564 { "fsubr", STi, ST, XX },
2565 { "fsub", STi, ST, XX },
2566 { "fdivr", STi, ST, XX },
2567 { "fdiv", STi, ST, XX },
2568 #endif
2570 /* dd */
2572 { "ffree", STi, XX, XX },
2573 { "(bad)", XX, XX, XX },
2574 { "fst", STi, XX, XX },
2575 { "fstp", STi, XX, XX },
2576 { "fucom", STi, XX, XX },
2577 { "fucomp", STi, XX, XX },
2578 { "(bad)", XX, XX, XX },
2579 { "(bad)", XX, XX, XX },
2581 /* de */
2583 { "faddp", STi, ST, XX },
2584 { "fmulp", STi, ST, XX },
2585 { "(bad)", XX, XX, XX },
2586 { FGRPde_3 },
2587 #if UNIXWARE_COMPAT
2588 { "fsubp", STi, ST, XX },
2589 { "fsubrp", STi, ST, XX },
2590 { "fdivp", STi, ST, XX },
2591 { "fdivrp", STi, ST, XX },
2592 #else
2593 { "fsubrp", STi, ST, XX },
2594 { "fsubp", STi, ST, XX },
2595 { "fdivrp", STi, ST, XX },
2596 { "fdivp", STi, ST, XX },
2597 #endif
2599 /* df */
2601 { "ffreep", STi, XX, XX },
2602 { "(bad)", XX, XX, XX },
2603 { "(bad)", XX, XX, XX },
2604 { "(bad)", XX, XX, XX },
2605 { FGRPdf_4 },
2606 { "fucomip",ST, STi, XX },
2607 { "fcomip", ST, STi, XX },
2608 { "(bad)", XX, XX, XX },
2612 static char *fgrps[][8] = {
2613 /* d9_2 0 */
2615 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2618 /* d9_4 1 */
2620 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2623 /* d9_5 2 */
2625 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2628 /* d9_6 3 */
2630 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2633 /* d9_7 4 */
2635 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2638 /* da_5 5 */
2640 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2643 /* db_4 6 */
2645 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2646 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2649 /* de_3 7 */
2651 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2654 /* df_4 8 */
2656 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2660 static void
2661 dofloat (int sizeflag)
2663 const struct dis386 *dp;
2664 unsigned char floatop;
2666 floatop = codep[-1];
2668 if (mod != 3)
2670 int fp_indx = (floatop - 0xd8) * 8 + reg;
2672 putop (float_mem[fp_indx], sizeflag);
2673 obufp = op1out;
2674 OP_E (float_mem_mode[fp_indx], sizeflag);
2675 return;
2677 /* Skip mod/rm byte. */
2678 MODRM_CHECK;
2679 codep++;
2681 dp = &float_reg[floatop - 0xd8][reg];
2682 if (dp->name == NULL)
2684 putop (fgrps[dp->bytemode1][rm], sizeflag);
2686 /* Instruction fnstsw is only one with strange arg. */
2687 if (floatop == 0xdf && codep[-1] == 0xe0)
2688 strcpy (op1out, names16[0]);
2690 else
2692 putop (dp->name, sizeflag);
2694 obufp = op1out;
2695 if (dp->op1)
2696 (*dp->op1) (dp->bytemode1, sizeflag);
2697 obufp = op2out;
2698 if (dp->op2)
2699 (*dp->op2) (dp->bytemode2, sizeflag);
2703 static void
2704 OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
2706 oappend ("%st");
2709 static void
2710 OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
2712 sprintf (scratchbuf, "%%st(%d)", rm);
2713 oappend (scratchbuf + intel_syntax);
2716 /* Capital letters in template are macros. */
2717 static int
2718 putop (const char *template, int sizeflag)
2720 const char *p;
2721 int alt = 0;
2723 for (p = template; *p; p++)
2725 switch (*p)
2727 default:
2728 *obufp++ = *p;
2729 break;
2730 case '{':
2731 alt = 0;
2732 if (intel_syntax)
2733 alt += 1;
2734 if (mode_64bit)
2735 alt += 2;
2736 while (alt != 0)
2738 while (*++p != '|')
2740 if (*p == '}')
2742 /* Alternative not valid. */
2743 strcpy (obuf, "(bad)");
2744 obufp = obuf + 5;
2745 return 1;
2747 else if (*p == '\0')
2748 abort ();
2750 alt--;
2752 /* Fall through. */
2753 case 'I':
2754 alt = 1;
2755 continue;
2756 case '|':
2757 while (*++p != '}')
2759 if (*p == '\0')
2760 abort ();
2762 break;
2763 case '}':
2764 break;
2765 case 'A':
2766 if (intel_syntax)
2767 break;
2768 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2769 *obufp++ = 'b';
2770 break;
2771 case 'B':
2772 if (intel_syntax)
2773 break;
2774 if (sizeflag & SUFFIX_ALWAYS)
2775 *obufp++ = 'b';
2776 break;
2777 case 'C':
2778 if (intel_syntax && !alt)
2779 break;
2780 if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
2782 if (sizeflag & DFLAG)
2783 *obufp++ = intel_syntax ? 'd' : 'l';
2784 else
2785 *obufp++ = intel_syntax ? 'w' : 's';
2786 used_prefixes |= (prefixes & PREFIX_DATA);
2788 break;
2789 case 'E': /* For jcxz/jecxz */
2790 if (mode_64bit)
2792 if (sizeflag & AFLAG)
2793 *obufp++ = 'r';
2794 else
2795 *obufp++ = 'e';
2797 else
2798 if (sizeflag & AFLAG)
2799 *obufp++ = 'e';
2800 used_prefixes |= (prefixes & PREFIX_ADDR);
2801 break;
2802 case 'F':
2803 if (intel_syntax)
2804 break;
2805 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
2807 if (sizeflag & AFLAG)
2808 *obufp++ = mode_64bit ? 'q' : 'l';
2809 else
2810 *obufp++ = mode_64bit ? 'l' : 'w';
2811 used_prefixes |= (prefixes & PREFIX_ADDR);
2813 break;
2814 case 'H':
2815 if (intel_syntax)
2816 break;
2817 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
2818 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
2820 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
2821 *obufp++ = ',';
2822 *obufp++ = 'p';
2823 if (prefixes & PREFIX_DS)
2824 *obufp++ = 't';
2825 else
2826 *obufp++ = 'n';
2828 break;
2829 case 'J':
2830 if (intel_syntax)
2831 break;
2832 *obufp++ = 'l';
2833 break;
2834 case 'L':
2835 if (intel_syntax)
2836 break;
2837 if (sizeflag & SUFFIX_ALWAYS)
2838 *obufp++ = 'l';
2839 break;
2840 case 'N':
2841 if ((prefixes & PREFIX_FWAIT) == 0)
2842 *obufp++ = 'n';
2843 else
2844 used_prefixes |= PREFIX_FWAIT;
2845 break;
2846 case 'O':
2847 USED_REX (REX_MODE64);
2848 if (rex & REX_MODE64)
2849 *obufp++ = 'o';
2850 else
2851 *obufp++ = 'd';
2852 break;
2853 case 'T':
2854 if (intel_syntax)
2855 break;
2856 if (mode_64bit)
2858 *obufp++ = 'q';
2859 break;
2861 /* Fall through. */
2862 case 'P':
2863 if (intel_syntax)
2864 break;
2865 if ((prefixes & PREFIX_DATA)
2866 || (rex & REX_MODE64)
2867 || (sizeflag & SUFFIX_ALWAYS))
2869 USED_REX (REX_MODE64);
2870 if (rex & REX_MODE64)
2871 *obufp++ = 'q';
2872 else
2874 if (sizeflag & DFLAG)
2875 *obufp++ = 'l';
2876 else
2877 *obufp++ = 'w';
2878 used_prefixes |= (prefixes & PREFIX_DATA);
2881 break;
2882 case 'U':
2883 if (intel_syntax)
2884 break;
2885 if (mode_64bit)
2887 *obufp++ = 'q';
2888 break;
2890 /* Fall through. */
2891 case 'Q':
2892 if (intel_syntax && !alt)
2893 break;
2894 USED_REX (REX_MODE64);
2895 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2897 if (rex & REX_MODE64)
2898 *obufp++ = 'q';
2899 else
2901 if (sizeflag & DFLAG)
2902 *obufp++ = intel_syntax ? 'd' : 'l';
2903 else
2904 *obufp++ = 'w';
2905 used_prefixes |= (prefixes & PREFIX_DATA);
2908 break;
2909 case 'R':
2910 USED_REX (REX_MODE64);
2911 if (intel_syntax)
2913 if (rex & REX_MODE64)
2915 *obufp++ = 'q';
2916 *obufp++ = 't';
2918 else if (sizeflag & DFLAG)
2920 *obufp++ = 'd';
2921 *obufp++ = 'q';
2923 else
2925 *obufp++ = 'w';
2926 *obufp++ = 'd';
2929 else
2931 if (rex & REX_MODE64)
2932 *obufp++ = 'q';
2933 else if (sizeflag & DFLAG)
2934 *obufp++ = 'l';
2935 else
2936 *obufp++ = 'w';
2938 if (!(rex & REX_MODE64))
2939 used_prefixes |= (prefixes & PREFIX_DATA);
2940 break;
2941 case 'S':
2942 if (intel_syntax)
2943 break;
2944 if (sizeflag & SUFFIX_ALWAYS)
2946 if (rex & REX_MODE64)
2947 *obufp++ = 'q';
2948 else
2950 if (sizeflag & DFLAG)
2951 *obufp++ = 'l';
2952 else
2953 *obufp++ = 'w';
2954 used_prefixes |= (prefixes & PREFIX_DATA);
2957 break;
2958 case 'X':
2959 if (prefixes & PREFIX_DATA)
2960 *obufp++ = 'd';
2961 else
2962 *obufp++ = 's';
2963 used_prefixes |= (prefixes & PREFIX_DATA);
2964 break;
2965 case 'Y':
2966 if (intel_syntax)
2967 break;
2968 if (rex & REX_MODE64)
2970 USED_REX (REX_MODE64);
2971 *obufp++ = 'q';
2973 break;
2974 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
2975 case 'W':
2976 /* operand size flag for cwtl, cbtw */
2977 USED_REX (0);
2978 if (rex)
2979 *obufp++ = 'l';
2980 else if (sizeflag & DFLAG)
2981 *obufp++ = 'w';
2982 else
2983 *obufp++ = 'b';
2984 if (intel_syntax)
2986 if (rex)
2988 *obufp++ = 'q';
2989 *obufp++ = 'e';
2991 if (sizeflag & DFLAG)
2993 *obufp++ = 'd';
2994 *obufp++ = 'e';
2996 else
2998 *obufp++ = 'w';
3001 if (!rex)
3002 used_prefixes |= (prefixes & PREFIX_DATA);
3003 break;
3005 alt = 0;
3007 *obufp = 0;
3008 return 0;
3011 static void
3012 oappend (const char *s)
3014 strcpy (obufp, s);
3015 obufp += strlen (s);
3018 static void
3019 append_seg (void)
3021 if (prefixes & PREFIX_CS)
3023 used_prefixes |= PREFIX_CS;
3024 oappend ("%cs:" + intel_syntax);
3026 if (prefixes & PREFIX_DS)
3028 used_prefixes |= PREFIX_DS;
3029 oappend ("%ds:" + intel_syntax);
3031 if (prefixes & PREFIX_SS)
3033 used_prefixes |= PREFIX_SS;
3034 oappend ("%ss:" + intel_syntax);
3036 if (prefixes & PREFIX_ES)
3038 used_prefixes |= PREFIX_ES;
3039 oappend ("%es:" + intel_syntax);
3041 if (prefixes & PREFIX_FS)
3043 used_prefixes |= PREFIX_FS;
3044 oappend ("%fs:" + intel_syntax);
3046 if (prefixes & PREFIX_GS)
3048 used_prefixes |= PREFIX_GS;
3049 oappend ("%gs:" + intel_syntax);
3053 static void
3054 OP_indirE (int bytemode, int sizeflag)
3056 if (!intel_syntax)
3057 oappend ("*");
3058 OP_E (bytemode, sizeflag);
3061 static void
3062 print_operand_value (char *buf, int hex, bfd_vma disp)
3064 if (mode_64bit)
3066 if (hex)
3068 char tmp[30];
3069 int i;
3070 buf[0] = '0';
3071 buf[1] = 'x';
3072 sprintf_vma (tmp, disp);
3073 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
3074 strcpy (buf + 2, tmp + i);
3076 else
3078 bfd_signed_vma v = disp;
3079 char tmp[30];
3080 int i;
3081 if (v < 0)
3083 *(buf++) = '-';
3084 v = -disp;
3085 /* Check for possible overflow on 0x8000000000000000. */
3086 if (v < 0)
3088 strcpy (buf, "9223372036854775808");
3089 return;
3092 if (!v)
3094 strcpy (buf, "0");
3095 return;
3098 i = 0;
3099 tmp[29] = 0;
3100 while (v)
3102 tmp[28 - i] = (v % 10) + '0';
3103 v /= 10;
3104 i++;
3106 strcpy (buf, tmp + 29 - i);
3109 else
3111 if (hex)
3112 sprintf (buf, "0x%x", (unsigned int) disp);
3113 else
3114 sprintf (buf, "%d", (int) disp);
3118 static void
3119 OP_E (int bytemode, int sizeflag)
3121 bfd_vma disp;
3122 int add = 0;
3123 int riprel = 0;
3124 USED_REX (REX_EXTZ);
3125 if (rex & REX_EXTZ)
3126 add += 8;
3128 /* Skip mod/rm byte. */
3129 MODRM_CHECK;
3130 codep++;
3132 if (mod == 3)
3134 switch (bytemode)
3136 case b_mode:
3137 USED_REX (0);
3138 if (rex)
3139 oappend (names8rex[rm + add]);
3140 else
3141 oappend (names8[rm + add]);
3142 break;
3143 case w_mode:
3144 oappend (names16[rm + add]);
3145 break;
3146 case d_mode:
3147 oappend (names32[rm + add]);
3148 break;
3149 case q_mode:
3150 oappend (names64[rm + add]);
3151 break;
3152 case m_mode:
3153 if (mode_64bit)
3154 oappend (names64[rm + add]);
3155 else
3156 oappend (names32[rm + add]);
3157 break;
3158 case v_mode:
3159 case dq_mode:
3160 case dqw_mode:
3161 USED_REX (REX_MODE64);
3162 if (rex & REX_MODE64)
3163 oappend (names64[rm + add]);
3164 else if ((sizeflag & DFLAG) || bytemode != v_mode)
3165 oappend (names32[rm + add]);
3166 else
3167 oappend (names16[rm + add]);
3168 used_prefixes |= (prefixes & PREFIX_DATA);
3169 break;
3170 case 0:
3171 break;
3172 default:
3173 oappend (INTERNAL_DISASSEMBLER_ERROR);
3174 break;
3176 return;
3179 disp = 0;
3180 append_seg ();
3182 if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
3184 int havesib;
3185 int havebase;
3186 int base;
3187 int index = 0;
3188 int scale = 0;
3190 havesib = 0;
3191 havebase = 1;
3192 base = rm;
3194 if (base == 4)
3196 havesib = 1;
3197 FETCH_DATA (the_info, codep + 1);
3198 index = (*codep >> 3) & 7;
3199 if (mode_64bit || index != 0x4)
3200 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
3201 scale = (*codep >> 6) & 3;
3202 base = *codep & 7;
3203 USED_REX (REX_EXTY);
3204 USED_REX (REX_EXTZ);
3205 if (rex & REX_EXTY)
3206 index += 8;
3207 if (rex & REX_EXTZ)
3208 base += 8;
3209 codep++;
3212 switch (mod)
3214 case 0:
3215 if ((base & 7) == 5)
3217 havebase = 0;
3218 if (mode_64bit && !havesib)
3219 riprel = 1;
3220 disp = get32s ();
3222 break;
3223 case 1:
3224 FETCH_DATA (the_info, codep + 1);
3225 disp = *codep++;
3226 if ((disp & 0x80) != 0)
3227 disp -= 0x100;
3228 break;
3229 case 2:
3230 disp = get32s ();
3231 break;
3234 if (!intel_syntax)
3235 if (mod != 0 || (base & 7) == 5)
3237 print_operand_value (scratchbuf, !riprel, disp);
3238 oappend (scratchbuf);
3239 if (riprel)
3241 set_op (disp, 1);
3242 oappend ("(%rip)");
3246 if (havebase || (havesib && (index != 4 || scale != 0)))
3248 if (intel_syntax)
3250 switch (bytemode)
3252 case b_mode:
3253 oappend ("BYTE PTR ");
3254 break;
3255 case w_mode:
3256 case dqw_mode:
3257 oappend ("WORD PTR ");
3258 break;
3259 case v_mode:
3260 case dq_mode:
3261 USED_REX (REX_MODE64);
3262 if (rex & REX_MODE64)
3263 oappend ("QWORD PTR ");
3264 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
3265 oappend ("DWORD PTR ");
3266 else
3267 oappend ("WORD PTR ");
3268 used_prefixes |= (prefixes & PREFIX_DATA);
3269 break;
3270 case d_mode:
3271 oappend ("DWORD PTR ");
3272 break;
3273 case q_mode:
3274 oappend ("QWORD PTR ");
3275 break;
3276 case m_mode:
3277 if (mode_64bit)
3278 oappend ("QWORD PTR ");
3279 else
3280 oappend ("DWORD PTR ");
3281 break;
3282 case f_mode:
3283 if (sizeflag & DFLAG)
3285 used_prefixes |= (prefixes & PREFIX_DATA);
3286 oappend ("FWORD PTR ");
3288 else
3289 oappend ("DWORD PTR ");
3290 break;
3291 case t_mode:
3292 oappend ("TBYTE PTR ");
3293 break;
3294 case x_mode:
3295 oappend ("XMMWORD PTR ");
3296 break;
3297 default:
3298 break;
3301 *obufp++ = open_char;
3302 if (intel_syntax && riprel)
3303 oappend ("rip + ");
3304 *obufp = '\0';
3305 USED_REX (REX_EXTZ);
3306 if (!havesib && (rex & REX_EXTZ))
3307 base += 8;
3308 if (havebase)
3309 oappend (mode_64bit && (sizeflag & AFLAG)
3310 ? names64[base] : names32[base]);
3311 if (havesib)
3313 if (index != 4)
3315 if (!intel_syntax || havebase)
3317 *obufp++ = separator_char;
3318 *obufp = '\0';
3320 oappend (mode_64bit && (sizeflag & AFLAG)
3321 ? names64[index] : names32[index]);
3323 if (scale != 0 || (!intel_syntax && index != 4))
3325 *obufp++ = scale_char;
3326 *obufp = '\0';
3327 sprintf (scratchbuf, "%d", 1 << scale);
3328 oappend (scratchbuf);
3331 if (intel_syntax)
3332 if (mod != 0 || (base & 7) == 5)
3334 /* Don't print zero displacements. */
3335 if (disp != 0)
3337 if ((bfd_signed_vma) disp > 0)
3339 *obufp++ = '+';
3340 *obufp = '\0';
3343 print_operand_value (scratchbuf, 0, disp);
3344 oappend (scratchbuf);
3348 *obufp++ = close_char;
3349 *obufp = '\0';
3351 else if (intel_syntax)
3353 if (mod != 0 || (base & 7) == 5)
3355 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3356 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
3358 else
3360 oappend (names_seg[ds_reg - es_reg]);
3361 oappend (":");
3363 print_operand_value (scratchbuf, 1, disp);
3364 oappend (scratchbuf);
3368 else
3369 { /* 16 bit address mode */
3370 switch (mod)
3372 case 0:
3373 if ((rm & 7) == 6)
3375 disp = get16 ();
3376 if ((disp & 0x8000) != 0)
3377 disp -= 0x10000;
3379 break;
3380 case 1:
3381 FETCH_DATA (the_info, codep + 1);
3382 disp = *codep++;
3383 if ((disp & 0x80) != 0)
3384 disp -= 0x100;
3385 break;
3386 case 2:
3387 disp = get16 ();
3388 if ((disp & 0x8000) != 0)
3389 disp -= 0x10000;
3390 break;
3393 if (!intel_syntax)
3394 if (mod != 0 || (rm & 7) == 6)
3396 print_operand_value (scratchbuf, 0, disp);
3397 oappend (scratchbuf);
3400 if (mod != 0 || (rm & 7) != 6)
3402 *obufp++ = open_char;
3403 *obufp = '\0';
3404 oappend (index16[rm + add]);
3405 *obufp++ = close_char;
3406 *obufp = '\0';
3411 static void
3412 OP_G (int bytemode, int sizeflag)
3414 int add = 0;
3415 USED_REX (REX_EXTX);
3416 if (rex & REX_EXTX)
3417 add += 8;
3418 switch (bytemode)
3420 case b_mode:
3421 USED_REX (0);
3422 if (rex)
3423 oappend (names8rex[reg + add]);
3424 else
3425 oappend (names8[reg + add]);
3426 break;
3427 case w_mode:
3428 oappend (names16[reg + add]);
3429 break;
3430 case d_mode:
3431 oappend (names32[reg + add]);
3432 break;
3433 case q_mode:
3434 oappend (names64[reg + add]);
3435 break;
3436 case v_mode:
3437 case dq_mode:
3438 case dqw_mode:
3439 USED_REX (REX_MODE64);
3440 if (rex & REX_MODE64)
3441 oappend (names64[reg + add]);
3442 else if ((sizeflag & DFLAG) || bytemode != v_mode)
3443 oappend (names32[reg + add]);
3444 else
3445 oappend (names16[reg + add]);
3446 used_prefixes |= (prefixes & PREFIX_DATA);
3447 break;
3448 default:
3449 oappend (INTERNAL_DISASSEMBLER_ERROR);
3450 break;
3454 static bfd_vma
3455 get64 (void)
3457 bfd_vma x;
3458 #ifdef BFD64
3459 unsigned int a;
3460 unsigned int b;
3462 FETCH_DATA (the_info, codep + 8);
3463 a = *codep++ & 0xff;
3464 a |= (*codep++ & 0xff) << 8;
3465 a |= (*codep++ & 0xff) << 16;
3466 a |= (*codep++ & 0xff) << 24;
3467 b = *codep++ & 0xff;
3468 b |= (*codep++ & 0xff) << 8;
3469 b |= (*codep++ & 0xff) << 16;
3470 b |= (*codep++ & 0xff) << 24;
3471 x = a + ((bfd_vma) b << 32);
3472 #else
3473 abort ();
3474 x = 0;
3475 #endif
3476 return x;
3479 static bfd_signed_vma
3480 get32 (void)
3482 bfd_signed_vma x = 0;
3484 FETCH_DATA (the_info, codep + 4);
3485 x = *codep++ & (bfd_signed_vma) 0xff;
3486 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3487 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3488 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3489 return x;
3492 static bfd_signed_vma
3493 get32s (void)
3495 bfd_signed_vma x = 0;
3497 FETCH_DATA (the_info, codep + 4);
3498 x = *codep++ & (bfd_signed_vma) 0xff;
3499 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3500 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3501 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3503 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
3505 return x;
3508 static int
3509 get16 (void)
3511 int x = 0;
3513 FETCH_DATA (the_info, codep + 2);
3514 x = *codep++ & 0xff;
3515 x |= (*codep++ & 0xff) << 8;
3516 return x;
3519 static void
3520 set_op (bfd_vma op, int riprel)
3522 op_index[op_ad] = op_ad;
3523 if (mode_64bit)
3525 op_address[op_ad] = op;
3526 op_riprel[op_ad] = riprel;
3528 else
3530 /* Mask to get a 32-bit address. */
3531 op_address[op_ad] = op & 0xffffffff;
3532 op_riprel[op_ad] = riprel & 0xffffffff;
3536 static void
3537 OP_REG (int code, int sizeflag)
3539 const char *s;
3540 int add = 0;
3541 USED_REX (REX_EXTZ);
3542 if (rex & REX_EXTZ)
3543 add = 8;
3545 switch (code)
3547 case indir_dx_reg:
3548 if (intel_syntax)
3549 s = "[dx]";
3550 else
3551 s = "(%dx)";
3552 break;
3553 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3554 case sp_reg: case bp_reg: case si_reg: case di_reg:
3555 s = names16[code - ax_reg + add];
3556 break;
3557 case es_reg: case ss_reg: case cs_reg:
3558 case ds_reg: case fs_reg: case gs_reg:
3559 s = names_seg[code - es_reg + add];
3560 break;
3561 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3562 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3563 USED_REX (0);
3564 if (rex)
3565 s = names8rex[code - al_reg + add];
3566 else
3567 s = names8[code - al_reg];
3568 break;
3569 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
3570 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
3571 if (mode_64bit)
3573 s = names64[code - rAX_reg + add];
3574 break;
3576 code += eAX_reg - rAX_reg;
3577 /* Fall through. */
3578 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3579 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3580 USED_REX (REX_MODE64);
3581 if (rex & REX_MODE64)
3582 s = names64[code - eAX_reg + add];
3583 else if (sizeflag & DFLAG)
3584 s = names32[code - eAX_reg + add];
3585 else
3586 s = names16[code - eAX_reg + add];
3587 used_prefixes |= (prefixes & PREFIX_DATA);
3588 break;
3589 default:
3590 s = INTERNAL_DISASSEMBLER_ERROR;
3591 break;
3593 oappend (s);
3596 static void
3597 OP_IMREG (int code, int sizeflag)
3599 const char *s;
3601 switch (code)
3603 case indir_dx_reg:
3604 if (intel_syntax)
3605 s = "[dx]";
3606 else
3607 s = "(%dx)";
3608 break;
3609 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3610 case sp_reg: case bp_reg: case si_reg: case di_reg:
3611 s = names16[code - ax_reg];
3612 break;
3613 case es_reg: case ss_reg: case cs_reg:
3614 case ds_reg: case fs_reg: case gs_reg:
3615 s = names_seg[code - es_reg];
3616 break;
3617 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3618 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3619 USED_REX (0);
3620 if (rex)
3621 s = names8rex[code - al_reg];
3622 else
3623 s = names8[code - al_reg];
3624 break;
3625 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3626 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3627 USED_REX (REX_MODE64);
3628 if (rex & REX_MODE64)
3629 s = names64[code - eAX_reg];
3630 else if (sizeflag & DFLAG)
3631 s = names32[code - eAX_reg];
3632 else
3633 s = names16[code - eAX_reg];
3634 used_prefixes |= (prefixes & PREFIX_DATA);
3635 break;
3636 default:
3637 s = INTERNAL_DISASSEMBLER_ERROR;
3638 break;
3640 oappend (s);
3643 static void
3644 OP_I (int bytemode, int sizeflag)
3646 bfd_signed_vma op;
3647 bfd_signed_vma mask = -1;
3649 switch (bytemode)
3651 case b_mode:
3652 FETCH_DATA (the_info, codep + 1);
3653 op = *codep++;
3654 mask = 0xff;
3655 break;
3656 case q_mode:
3657 if (mode_64bit)
3659 op = get32s ();
3660 break;
3662 /* Fall through. */
3663 case v_mode:
3664 USED_REX (REX_MODE64);
3665 if (rex & REX_MODE64)
3666 op = get32s ();
3667 else if (sizeflag & DFLAG)
3669 op = get32 ();
3670 mask = 0xffffffff;
3672 else
3674 op = get16 ();
3675 mask = 0xfffff;
3677 used_prefixes |= (prefixes & PREFIX_DATA);
3678 break;
3679 case w_mode:
3680 mask = 0xfffff;
3681 op = get16 ();
3682 break;
3683 case const_1_mode:
3684 if (intel_syntax)
3685 oappend ("1");
3686 return;
3687 default:
3688 oappend (INTERNAL_DISASSEMBLER_ERROR);
3689 return;
3692 op &= mask;
3693 scratchbuf[0] = '$';
3694 print_operand_value (scratchbuf + 1, 1, op);
3695 oappend (scratchbuf + intel_syntax);
3696 scratchbuf[0] = '\0';
3699 static void
3700 OP_I64 (int bytemode, int sizeflag)
3702 bfd_signed_vma op;
3703 bfd_signed_vma mask = -1;
3705 if (!mode_64bit)
3707 OP_I (bytemode, sizeflag);
3708 return;
3711 switch (bytemode)
3713 case b_mode:
3714 FETCH_DATA (the_info, codep + 1);
3715 op = *codep++;
3716 mask = 0xff;
3717 break;
3718 case v_mode:
3719 USED_REX (REX_MODE64);
3720 if (rex & REX_MODE64)
3721 op = get64 ();
3722 else if (sizeflag & DFLAG)
3724 op = get32 ();
3725 mask = 0xffffffff;
3727 else
3729 op = get16 ();
3730 mask = 0xfffff;
3732 used_prefixes |= (prefixes & PREFIX_DATA);
3733 break;
3734 case w_mode:
3735 mask = 0xfffff;
3736 op = get16 ();
3737 break;
3738 default:
3739 oappend (INTERNAL_DISASSEMBLER_ERROR);
3740 return;
3743 op &= mask;
3744 scratchbuf[0] = '$';
3745 print_operand_value (scratchbuf + 1, 1, op);
3746 oappend (scratchbuf + intel_syntax);
3747 scratchbuf[0] = '\0';
3750 static void
3751 OP_sI (int bytemode, int sizeflag)
3753 bfd_signed_vma op;
3754 bfd_signed_vma mask = -1;
3756 switch (bytemode)
3758 case b_mode:
3759 FETCH_DATA (the_info, codep + 1);
3760 op = *codep++;
3761 if ((op & 0x80) != 0)
3762 op -= 0x100;
3763 mask = 0xffffffff;
3764 break;
3765 case v_mode:
3766 USED_REX (REX_MODE64);
3767 if (rex & REX_MODE64)
3768 op = get32s ();
3769 else if (sizeflag & DFLAG)
3771 op = get32s ();
3772 mask = 0xffffffff;
3774 else
3776 mask = 0xffffffff;
3777 op = get16 ();
3778 if ((op & 0x8000) != 0)
3779 op -= 0x10000;
3781 used_prefixes |= (prefixes & PREFIX_DATA);
3782 break;
3783 case w_mode:
3784 op = get16 ();
3785 mask = 0xffffffff;
3786 if ((op & 0x8000) != 0)
3787 op -= 0x10000;
3788 break;
3789 default:
3790 oappend (INTERNAL_DISASSEMBLER_ERROR);
3791 return;
3794 scratchbuf[0] = '$';
3795 print_operand_value (scratchbuf + 1, 1, op);
3796 oappend (scratchbuf + intel_syntax);
3799 static void
3800 OP_J (int bytemode, int sizeflag)
3802 bfd_vma disp;
3803 bfd_vma mask = -1;
3805 switch (bytemode)
3807 case b_mode:
3808 FETCH_DATA (the_info, codep + 1);
3809 disp = *codep++;
3810 if ((disp & 0x80) != 0)
3811 disp -= 0x100;
3812 break;
3813 case v_mode:
3814 if (sizeflag & DFLAG)
3815 disp = get32s ();
3816 else
3818 disp = get16 ();
3819 /* For some reason, a data16 prefix on a jump instruction
3820 means that the pc is masked to 16 bits after the
3821 displacement is added! */
3822 mask = 0xffff;
3824 break;
3825 default:
3826 oappend (INTERNAL_DISASSEMBLER_ERROR);
3827 return;
3829 disp = (start_pc + codep - start_codep + disp) & mask;
3830 set_op (disp, 0);
3831 print_operand_value (scratchbuf, 1, disp);
3832 oappend (scratchbuf);
3835 static void
3836 OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3838 oappend (names_seg[reg]);
3841 static void
3842 OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
3844 int seg, offset;
3846 if (sizeflag & DFLAG)
3848 offset = get32 ();
3849 seg = get16 ();
3851 else
3853 offset = get16 ();
3854 seg = get16 ();
3856 used_prefixes |= (prefixes & PREFIX_DATA);
3857 if (intel_syntax)
3858 sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
3859 else
3860 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3861 oappend (scratchbuf);
3864 static void
3865 OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag)
3867 bfd_vma off;
3869 append_seg ();
3871 if ((sizeflag & AFLAG) || mode_64bit)
3872 off = get32 ();
3873 else
3874 off = get16 ();
3876 if (intel_syntax)
3878 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3879 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3881 oappend (names_seg[ds_reg - es_reg]);
3882 oappend (":");
3885 print_operand_value (scratchbuf, 1, off);
3886 oappend (scratchbuf);
3889 static void
3890 OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3892 bfd_vma off;
3894 if (!mode_64bit)
3896 OP_OFF (bytemode, sizeflag);
3897 return;
3900 append_seg ();
3902 off = get64 ();
3904 if (intel_syntax)
3906 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3907 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3909 oappend (names_seg[ds_reg - es_reg]);
3910 oappend (":");
3913 print_operand_value (scratchbuf, 1, off);
3914 oappend (scratchbuf);
3917 static void
3918 ptr_reg (int code, int sizeflag)
3920 const char *s;
3922 *obufp++ = open_char;
3923 used_prefixes |= (prefixes & PREFIX_ADDR);
3924 if (mode_64bit)
3926 if (!(sizeflag & AFLAG))
3927 s = names32[code - eAX_reg];
3928 else
3929 s = names64[code - eAX_reg];
3931 else if (sizeflag & AFLAG)
3932 s = names32[code - eAX_reg];
3933 else
3934 s = names16[code - eAX_reg];
3935 oappend (s);
3936 *obufp++ = close_char;
3937 *obufp = 0;
3940 static void
3941 OP_ESreg (int code, int sizeflag)
3943 if (intel_syntax)
3945 if (codep[-1] & 1)
3947 USED_REX (REX_MODE64);
3948 used_prefixes |= (prefixes & PREFIX_DATA);
3949 if (rex & REX_MODE64)
3950 oappend ("QWORD PTR ");
3951 else if ((sizeflag & DFLAG))
3952 oappend ("DWORD PTR ");
3953 else
3954 oappend ("WORD PTR ");
3956 else
3957 oappend ("BYTE PTR ");
3960 oappend ("%es:" + intel_syntax);
3961 ptr_reg (code, sizeflag);
3964 static void
3965 OP_DSreg (int code, int sizeflag)
3967 if (intel_syntax)
3969 if (codep[-1] != 0xd7 && (codep[-1] & 1))
3971 USED_REX (REX_MODE64);
3972 used_prefixes |= (prefixes & PREFIX_DATA);
3973 if (rex & REX_MODE64)
3974 oappend ("QWORD PTR ");
3975 else if ((sizeflag & DFLAG))
3976 oappend ("DWORD PTR ");
3977 else
3978 oappend ("WORD PTR ");
3980 else
3981 oappend ("BYTE PTR ");
3984 if ((prefixes
3985 & (PREFIX_CS
3986 | PREFIX_DS
3987 | PREFIX_SS
3988 | PREFIX_ES
3989 | PREFIX_FS
3990 | PREFIX_GS)) == 0)
3991 prefixes |= PREFIX_DS;
3992 append_seg ();
3993 ptr_reg (code, sizeflag);
3996 static void
3997 OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3999 int add = 0;
4000 if (rex & REX_EXTX)
4002 USED_REX (REX_EXTX);
4003 add = 8;
4005 else if (!mode_64bit && (prefixes & PREFIX_LOCK))
4007 used_prefixes |= PREFIX_LOCK;
4008 add = 8;
4010 sprintf (scratchbuf, "%%cr%d", reg + add);
4011 oappend (scratchbuf + intel_syntax);
4014 static void
4015 OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4017 int add = 0;
4018 USED_REX (REX_EXTX);
4019 if (rex & REX_EXTX)
4020 add = 8;
4021 if (intel_syntax)
4022 sprintf (scratchbuf, "db%d", reg + add);
4023 else
4024 sprintf (scratchbuf, "%%db%d", reg + add);
4025 oappend (scratchbuf);
4028 static void
4029 OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4031 sprintf (scratchbuf, "%%tr%d", reg);
4032 oappend (scratchbuf + intel_syntax);
4035 static void
4036 OP_Rd (int bytemode, int sizeflag)
4038 if (mod == 3)
4039 OP_E (bytemode, sizeflag);
4040 else
4041 BadOp ();
4044 static void
4045 OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4047 used_prefixes |= (prefixes & PREFIX_DATA);
4048 if (prefixes & PREFIX_DATA)
4050 int add = 0;
4051 USED_REX (REX_EXTX);
4052 if (rex & REX_EXTX)
4053 add = 8;
4054 sprintf (scratchbuf, "%%xmm%d", reg + add);
4056 else
4057 sprintf (scratchbuf, "%%mm%d", reg);
4058 oappend (scratchbuf + intel_syntax);
4061 static void
4062 OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4064 int add = 0;
4065 USED_REX (REX_EXTX);
4066 if (rex & REX_EXTX)
4067 add = 8;
4068 sprintf (scratchbuf, "%%xmm%d", reg + add);
4069 oappend (scratchbuf + intel_syntax);
4072 static void
4073 OP_EM (int bytemode, int sizeflag)
4075 if (mod != 3)
4077 if (intel_syntax && bytemode == v_mode)
4079 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
4080 used_prefixes |= (prefixes & PREFIX_DATA);
4082 OP_E (bytemode, sizeflag);
4083 return;
4086 /* Skip mod/rm byte. */
4087 MODRM_CHECK;
4088 codep++;
4089 used_prefixes |= (prefixes & PREFIX_DATA);
4090 if (prefixes & PREFIX_DATA)
4092 int add = 0;
4094 USED_REX (REX_EXTZ);
4095 if (rex & REX_EXTZ)
4096 add = 8;
4097 sprintf (scratchbuf, "%%xmm%d", rm + add);
4099 else
4100 sprintf (scratchbuf, "%%mm%d", rm);
4101 oappend (scratchbuf + intel_syntax);
4104 static void
4105 OP_EX (int bytemode, int sizeflag)
4107 int add = 0;
4108 if (mod != 3)
4110 if (intel_syntax && bytemode == v_mode)
4112 switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ))
4114 case 0: bytemode = x_mode; break;
4115 case PREFIX_REPZ: bytemode = d_mode; used_prefixes |= PREFIX_REPZ; break;
4116 case PREFIX_DATA: bytemode = x_mode; used_prefixes |= PREFIX_DATA; break;
4117 case PREFIX_REPNZ: bytemode = q_mode; used_prefixes |= PREFIX_REPNZ; break;
4118 default: bytemode = 0; break;
4121 OP_E (bytemode, sizeflag);
4122 return;
4124 USED_REX (REX_EXTZ);
4125 if (rex & REX_EXTZ)
4126 add = 8;
4128 /* Skip mod/rm byte. */
4129 MODRM_CHECK;
4130 codep++;
4131 sprintf (scratchbuf, "%%xmm%d", rm + add);
4132 oappend (scratchbuf + intel_syntax);
4135 static void
4136 OP_MS (int bytemode, int sizeflag)
4138 if (mod == 3)
4139 OP_EM (bytemode, sizeflag);
4140 else
4141 BadOp ();
4144 static void
4145 OP_XS (int bytemode, int sizeflag)
4147 if (mod == 3)
4148 OP_EX (bytemode, sizeflag);
4149 else
4150 BadOp ();
4153 static void
4154 OP_M (int bytemode, int sizeflag)
4156 if (mod == 3)
4157 BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
4158 else
4159 OP_E (bytemode, sizeflag);
4162 static void
4163 OP_0f07 (int bytemode, int sizeflag)
4165 if (mod != 3 || rm != 0)
4166 BadOp ();
4167 else
4168 OP_E (bytemode, sizeflag);
4171 static void
4172 OP_0fae (int bytemode, int sizeflag)
4174 if (mod == 3)
4176 if (reg == 7)
4177 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
4179 if (reg < 5 || rm != 0)
4181 BadOp (); /* bad sfence, mfence, or lfence */
4182 return;
4185 else if (reg != 7)
4187 BadOp (); /* bad clflush */
4188 return;
4191 OP_E (bytemode, sizeflag);
4194 static void
4195 NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4197 /* NOP with REPZ prefix is called PAUSE. */
4198 if (prefixes == PREFIX_REPZ)
4199 strcpy (obuf, "pause");
4202 static const char *const Suffix3DNow[] = {
4203 /* 00 */ NULL, NULL, NULL, NULL,
4204 /* 04 */ NULL, NULL, NULL, NULL,
4205 /* 08 */ NULL, NULL, NULL, NULL,
4206 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
4207 /* 10 */ NULL, NULL, NULL, NULL,
4208 /* 14 */ NULL, NULL, NULL, NULL,
4209 /* 18 */ NULL, NULL, NULL, NULL,
4210 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
4211 /* 20 */ NULL, NULL, NULL, NULL,
4212 /* 24 */ NULL, NULL, NULL, NULL,
4213 /* 28 */ NULL, NULL, NULL, NULL,
4214 /* 2C */ NULL, NULL, NULL, NULL,
4215 /* 30 */ NULL, NULL, NULL, NULL,
4216 /* 34 */ NULL, NULL, NULL, NULL,
4217 /* 38 */ NULL, NULL, NULL, NULL,
4218 /* 3C */ NULL, NULL, NULL, NULL,
4219 /* 40 */ NULL, NULL, NULL, NULL,
4220 /* 44 */ NULL, NULL, NULL, NULL,
4221 /* 48 */ NULL, NULL, NULL, NULL,
4222 /* 4C */ NULL, NULL, NULL, NULL,
4223 /* 50 */ NULL, NULL, NULL, NULL,
4224 /* 54 */ NULL, NULL, NULL, NULL,
4225 /* 58 */ NULL, NULL, NULL, NULL,
4226 /* 5C */ NULL, NULL, NULL, NULL,
4227 /* 60 */ NULL, NULL, NULL, NULL,
4228 /* 64 */ NULL, NULL, NULL, NULL,
4229 /* 68 */ NULL, NULL, NULL, NULL,
4230 /* 6C */ NULL, NULL, NULL, NULL,
4231 /* 70 */ NULL, NULL, NULL, NULL,
4232 /* 74 */ NULL, NULL, NULL, NULL,
4233 /* 78 */ NULL, NULL, NULL, NULL,
4234 /* 7C */ NULL, NULL, NULL, NULL,
4235 /* 80 */ NULL, NULL, NULL, NULL,
4236 /* 84 */ NULL, NULL, NULL, NULL,
4237 /* 88 */ NULL, NULL, "pfnacc", NULL,
4238 /* 8C */ NULL, NULL, "pfpnacc", NULL,
4239 /* 90 */ "pfcmpge", NULL, NULL, NULL,
4240 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
4241 /* 98 */ NULL, NULL, "pfsub", NULL,
4242 /* 9C */ NULL, NULL, "pfadd", NULL,
4243 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
4244 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
4245 /* A8 */ NULL, NULL, "pfsubr", NULL,
4246 /* AC */ NULL, NULL, "pfacc", NULL,
4247 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
4248 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
4249 /* B8 */ NULL, NULL, NULL, "pswapd",
4250 /* BC */ NULL, NULL, NULL, "pavgusb",
4251 /* C0 */ NULL, NULL, NULL, NULL,
4252 /* C4 */ NULL, NULL, NULL, NULL,
4253 /* C8 */ NULL, NULL, NULL, NULL,
4254 /* CC */ NULL, NULL, NULL, NULL,
4255 /* D0 */ NULL, NULL, NULL, NULL,
4256 /* D4 */ NULL, NULL, NULL, NULL,
4257 /* D8 */ NULL, NULL, NULL, NULL,
4258 /* DC */ NULL, NULL, NULL, NULL,
4259 /* E0 */ NULL, NULL, NULL, NULL,
4260 /* E4 */ NULL, NULL, NULL, NULL,
4261 /* E8 */ NULL, NULL, NULL, NULL,
4262 /* EC */ NULL, NULL, NULL, NULL,
4263 /* F0 */ NULL, NULL, NULL, NULL,
4264 /* F4 */ NULL, NULL, NULL, NULL,
4265 /* F8 */ NULL, NULL, NULL, NULL,
4266 /* FC */ NULL, NULL, NULL, NULL,
4269 static void
4270 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4272 const char *mnemonic;
4274 FETCH_DATA (the_info, codep + 1);
4275 /* AMD 3DNow! instructions are specified by an opcode suffix in the
4276 place where an 8-bit immediate would normally go. ie. the last
4277 byte of the instruction. */
4278 obufp = obuf + strlen (obuf);
4279 mnemonic = Suffix3DNow[*codep++ & 0xff];
4280 if (mnemonic)
4281 oappend (mnemonic);
4282 else
4284 /* Since a variable sized modrm/sib chunk is between the start
4285 of the opcode (0x0f0f) and the opcode suffix, we need to do
4286 all the modrm processing first, and don't know until now that
4287 we have a bad opcode. This necessitates some cleaning up. */
4288 op1out[0] = '\0';
4289 op2out[0] = '\0';
4290 BadOp ();
4294 static const char *simd_cmp_op[] = {
4295 "eq",
4296 "lt",
4297 "le",
4298 "unord",
4299 "neq",
4300 "nlt",
4301 "nle",
4302 "ord"
4305 static void
4306 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4308 unsigned int cmp_type;
4310 FETCH_DATA (the_info, codep + 1);
4311 obufp = obuf + strlen (obuf);
4312 cmp_type = *codep++ & 0xff;
4313 if (cmp_type < 8)
4315 char suffix1 = 'p', suffix2 = 's';
4316 used_prefixes |= (prefixes & PREFIX_REPZ);
4317 if (prefixes & PREFIX_REPZ)
4318 suffix1 = 's';
4319 else
4321 used_prefixes |= (prefixes & PREFIX_DATA);
4322 if (prefixes & PREFIX_DATA)
4323 suffix2 = 'd';
4324 else
4326 used_prefixes |= (prefixes & PREFIX_REPNZ);
4327 if (prefixes & PREFIX_REPNZ)
4328 suffix1 = 's', suffix2 = 'd';
4331 sprintf (scratchbuf, "cmp%s%c%c",
4332 simd_cmp_op[cmp_type], suffix1, suffix2);
4333 used_prefixes |= (prefixes & PREFIX_REPZ);
4334 oappend (scratchbuf);
4336 else
4338 /* We have a bad extension byte. Clean up. */
4339 op1out[0] = '\0';
4340 op2out[0] = '\0';
4341 BadOp ();
4345 static void
4346 SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
4348 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
4349 forms of these instructions. */
4350 if (mod == 3)
4352 char *p = obuf + strlen (obuf);
4353 *(p + 1) = '\0';
4354 *p = *(p - 1);
4355 *(p - 1) = *(p - 2);
4356 *(p - 2) = *(p - 3);
4357 *(p - 3) = extrachar;
4361 static void
4362 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
4364 if (mod == 3 && reg == 1 && rm <= 1)
4366 /* Override "sidt". */
4367 char *p = obuf + strlen (obuf) - 4;
4369 /* We might have a suffix. */
4370 if (*p == 'i')
4371 --p;
4373 if (rm)
4375 /* mwait %eax,%ecx */
4376 strcpy (p, "mwait");
4377 if (!intel_syntax)
4378 strcpy (op1out, names32[0]);
4380 else
4382 /* monitor %eax,%ecx,%edx" */
4383 strcpy (p, "monitor");
4384 if (!intel_syntax)
4386 if (!mode_64bit)
4387 strcpy (op1out, names32[0]);
4388 else if (!(prefixes & PREFIX_ADDR))
4389 strcpy (op1out, names64[0]);
4390 else
4392 strcpy (op1out, names32[0]);
4393 used_prefixes |= PREFIX_ADDR;
4395 strcpy (op3out, names32[2]);
4398 if (!intel_syntax)
4400 strcpy (op2out, names32[1]);
4401 two_source_ops = 1;
4404 codep++;
4406 else
4407 OP_E (0, sizeflag);
4410 static void
4411 INVLPG_Fixup (int bytemode, int sizeflag)
4413 const char *alt;
4415 switch (*codep)
4417 case 0xf8:
4418 alt = "swapgs";
4419 break;
4420 case 0xf9:
4421 alt = "rdtscp";
4422 break;
4423 default:
4424 OP_E (bytemode, sizeflag);
4425 return;
4427 /* Override "invlpg". */
4428 strcpy (obuf + strlen (obuf) - 6, alt);
4429 codep++;
4432 static void
4433 BadOp (void)
4435 /* Throw away prefixes and 1st. opcode byte. */
4436 codep = insn_codep + 1;
4437 oappend ("(bad)");
4440 static void
4441 SEG_Fixup (int extrachar, int sizeflag)
4443 if (mod == 3)
4445 /* We need to add a proper suffix with
4447 movw %ds,%ax
4448 movl %ds,%eax
4449 movq %ds,%rax
4450 movw %ax,%ds
4451 movl %eax,%ds
4452 movq %rax,%ds
4454 const char *suffix;
4456 if (prefixes & PREFIX_DATA)
4457 suffix = "w";
4458 else
4460 USED_REX (REX_MODE64);
4461 if (rex & REX_MODE64)
4462 suffix = "q";
4463 else
4464 suffix = "l";
4466 strcat (obuf, suffix);
4468 else
4470 /* We need to fix the suffix for
4472 movw %ds,(%eax)
4473 movw %ds,(%rax)
4474 movw (%eax),%ds
4475 movw (%rax),%ds
4477 Override "mov[l|q]". */
4478 char *p = obuf + strlen (obuf) - 1;
4480 /* We might not have a suffix. */
4481 if (*p == 'v')
4482 ++p;
4483 *p = 'w';
4486 OP_E (extrachar, sizeflag);