Set BFD_VERSION_DATE to 20040722.
[binutils.git] / opcodes / i386-dis.c
blob733267c6400a168f9c7c761ce01d47ab7cf4d3db
1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
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);
101 struct dis_private {
102 /* Points to first byte not fetched. */
103 bfd_byte *max_fetched;
104 bfd_byte the_buffer[MAXLEN];
105 bfd_vma insn_start;
106 int orig_sizeflag;
107 jmp_buf bailout;
110 /* The opcode for the fwait instruction, which we treat as a prefix
111 when we can. */
112 #define FWAIT_OPCODE (0x9b)
114 /* Set to 1 for 64bit mode disassembly. */
115 static int mode_64bit;
117 /* Flags for the prefixes for the current instruction. See below. */
118 static int prefixes;
120 /* REX prefix the current instruction. See below. */
121 static int rex;
122 /* Bits of REX we've already used. */
123 static int rex_used;
124 #define REX_MODE64 8
125 #define REX_EXTX 4
126 #define REX_EXTY 2
127 #define REX_EXTZ 1
128 /* Mark parts used in the REX prefix. When we are testing for
129 empty prefix (for 8bit register REX extension), just mask it
130 out. Otherwise test for REX bit is excuse for existence of REX
131 only in case value is nonzero. */
132 #define USED_REX(value) \
134 if (value) \
135 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
136 else \
137 rex_used |= 0x40; \
140 /* Flags for prefixes which we somehow handled when printing the
141 current instruction. */
142 static int used_prefixes;
144 /* Flags stored in PREFIXES. */
145 #define PREFIX_REPZ 1
146 #define PREFIX_REPNZ 2
147 #define PREFIX_LOCK 4
148 #define PREFIX_CS 8
149 #define PREFIX_SS 0x10
150 #define PREFIX_DS 0x20
151 #define PREFIX_ES 0x40
152 #define PREFIX_FS 0x80
153 #define PREFIX_GS 0x100
154 #define PREFIX_DATA 0x200
155 #define PREFIX_ADDR 0x400
156 #define PREFIX_FWAIT 0x800
158 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
159 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
160 on error. */
161 #define FETCH_DATA(info, addr) \
162 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
163 ? 1 : fetch_data ((info), (addr)))
165 static int
166 fetch_data (struct disassemble_info *info, bfd_byte *addr)
168 int status;
169 struct dis_private *priv = (struct dis_private *) info->private_data;
170 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
172 status = (*info->read_memory_func) (start,
173 priv->max_fetched,
174 addr - priv->max_fetched,
175 info);
176 if (status != 0)
178 /* If we did manage to read at least one byte, then
179 print_insn_i386 will do something sensible. Otherwise, print
180 an error. We do that here because this is where we know
181 STATUS. */
182 if (priv->max_fetched == priv->the_buffer)
183 (*info->memory_error_func) (status, start, info);
184 longjmp (priv->bailout, 1);
186 else
187 priv->max_fetched = addr;
188 return 1;
191 #define XX NULL, 0
193 #define Eb OP_E, b_mode
194 #define Ev OP_E, v_mode
195 #define Ed OP_E, d_mode
196 #define Edq OP_E, dq_mode
197 #define indirEb OP_indirE, b_mode
198 #define indirEv OP_indirE, v_mode
199 #define Ew OP_E, w_mode
200 #define Ma OP_E, v_mode
201 #define M OP_M, 0 /* lea, lgdt, etc. */
202 #define Mp OP_M, 0 /* 32 or 48 bit memory operand for LDS, LES etc */
203 #define Gb OP_G, b_mode
204 #define Gv OP_G, v_mode
205 #define Gd OP_G, d_mode
206 #define Gw OP_G, w_mode
207 #define Rd OP_Rd, d_mode
208 #define Rm OP_Rd, m_mode
209 #define Ib OP_I, b_mode
210 #define sIb OP_sI, b_mode /* sign extened byte */
211 #define Iv OP_I, v_mode
212 #define Iq OP_I, q_mode
213 #define Iv64 OP_I64, v_mode
214 #define Iw OP_I, w_mode
215 #define Jb OP_J, b_mode
216 #define Jv OP_J, v_mode
217 #define Cm OP_C, m_mode
218 #define Dm OP_D, m_mode
219 #define Td OP_T, d_mode
221 #define RMeAX OP_REG, eAX_reg
222 #define RMeBX OP_REG, eBX_reg
223 #define RMeCX OP_REG, eCX_reg
224 #define RMeDX OP_REG, eDX_reg
225 #define RMeSP OP_REG, eSP_reg
226 #define RMeBP OP_REG, eBP_reg
227 #define RMeSI OP_REG, eSI_reg
228 #define RMeDI OP_REG, eDI_reg
229 #define RMrAX OP_REG, rAX_reg
230 #define RMrBX OP_REG, rBX_reg
231 #define RMrCX OP_REG, rCX_reg
232 #define RMrDX OP_REG, rDX_reg
233 #define RMrSP OP_REG, rSP_reg
234 #define RMrBP OP_REG, rBP_reg
235 #define RMrSI OP_REG, rSI_reg
236 #define RMrDI OP_REG, rDI_reg
237 #define RMAL OP_REG, al_reg
238 #define RMAL OP_REG, al_reg
239 #define RMCL OP_REG, cl_reg
240 #define RMDL OP_REG, dl_reg
241 #define RMBL OP_REG, bl_reg
242 #define RMAH OP_REG, ah_reg
243 #define RMCH OP_REG, ch_reg
244 #define RMDH OP_REG, dh_reg
245 #define RMBH OP_REG, bh_reg
246 #define RMAX OP_REG, ax_reg
247 #define RMDX OP_REG, dx_reg
249 #define eAX OP_IMREG, eAX_reg
250 #define eBX OP_IMREG, eBX_reg
251 #define eCX OP_IMREG, eCX_reg
252 #define eDX OP_IMREG, eDX_reg
253 #define eSP OP_IMREG, eSP_reg
254 #define eBP OP_IMREG, eBP_reg
255 #define eSI OP_IMREG, eSI_reg
256 #define eDI OP_IMREG, eDI_reg
257 #define AL OP_IMREG, al_reg
258 #define AL OP_IMREG, al_reg
259 #define CL OP_IMREG, cl_reg
260 #define DL OP_IMREG, dl_reg
261 #define BL OP_IMREG, bl_reg
262 #define AH OP_IMREG, ah_reg
263 #define CH OP_IMREG, ch_reg
264 #define DH OP_IMREG, dh_reg
265 #define BH OP_IMREG, bh_reg
266 #define AX OP_IMREG, ax_reg
267 #define DX OP_IMREG, dx_reg
268 #define indirDX OP_IMREG, indir_dx_reg
270 #define Sw OP_SEG, w_mode
271 #define Ap OP_DIR, 0
272 #define Ob OP_OFF, b_mode
273 #define Ob64 OP_OFF64, b_mode
274 #define Ov OP_OFF, v_mode
275 #define Ov64 OP_OFF64, v_mode
276 #define Xb OP_DSreg, eSI_reg
277 #define Xv OP_DSreg, eSI_reg
278 #define Yb OP_ESreg, eDI_reg
279 #define Yv OP_ESreg, eDI_reg
280 #define DSBX OP_DSreg, eBX_reg
282 #define es OP_REG, es_reg
283 #define ss OP_REG, ss_reg
284 #define cs OP_REG, cs_reg
285 #define ds OP_REG, ds_reg
286 #define fs OP_REG, fs_reg
287 #define gs OP_REG, gs_reg
289 #define MX OP_MMX, 0
290 #define XM OP_XMM, 0
291 #define EM OP_EM, v_mode
292 #define EX OP_EX, v_mode
293 #define MS OP_MS, v_mode
294 #define XS OP_XS, v_mode
295 #define OPSUF OP_3DNowSuffix, 0
296 #define OPSIMD OP_SIMD_Suffix, 0
298 #define cond_jump_flag NULL, cond_jump_mode
299 #define loop_jcxz_flag NULL, loop_jcxz_mode
301 /* bits in sizeflag */
302 #define SUFFIX_ALWAYS 4
303 #define AFLAG 2
304 #define DFLAG 1
306 #define b_mode 1 /* byte operand */
307 #define v_mode 2 /* operand size depends on prefixes */
308 #define w_mode 3 /* word operand */
309 #define d_mode 4 /* double word operand */
310 #define q_mode 5 /* quad word operand */
311 #define x_mode 6 /* 80 bit float operand */
312 #define m_mode 7 /* d_mode in 32bit, q_mode in 64bit mode. */
313 #define cond_jump_mode 8
314 #define loop_jcxz_mode 9
315 #define dq_mode 10 /* operand size depends on REX prefixes. */
317 #define es_reg 100
318 #define cs_reg 101
319 #define ss_reg 102
320 #define ds_reg 103
321 #define fs_reg 104
322 #define gs_reg 105
324 #define eAX_reg 108
325 #define eCX_reg 109
326 #define eDX_reg 110
327 #define eBX_reg 111
328 #define eSP_reg 112
329 #define eBP_reg 113
330 #define eSI_reg 114
331 #define eDI_reg 115
333 #define al_reg 116
334 #define cl_reg 117
335 #define dl_reg 118
336 #define bl_reg 119
337 #define ah_reg 120
338 #define ch_reg 121
339 #define dh_reg 122
340 #define bh_reg 123
342 #define ax_reg 124
343 #define cx_reg 125
344 #define dx_reg 126
345 #define bx_reg 127
346 #define sp_reg 128
347 #define bp_reg 129
348 #define si_reg 130
349 #define di_reg 131
351 #define rAX_reg 132
352 #define rCX_reg 133
353 #define rDX_reg 134
354 #define rBX_reg 135
355 #define rSP_reg 136
356 #define rBP_reg 137
357 #define rSI_reg 138
358 #define rDI_reg 139
360 #define indir_dx_reg 150
362 #define FLOATCODE 1
363 #define USE_GROUPS 2
364 #define USE_PREFIX_USER_TABLE 3
365 #define X86_64_SPECIAL 4
367 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
369 #define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
370 #define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
371 #define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
372 #define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
373 #define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
374 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
375 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
376 #define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
377 #define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
378 #define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
379 #define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
380 #define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
381 #define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
382 #define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
383 #define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
384 #define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
385 #define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
386 #define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
387 #define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
388 #define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
389 #define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
390 #define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
391 #define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
392 #define GRPPADLCK NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0
394 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
395 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
396 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
397 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
398 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
399 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
400 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
401 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
402 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
403 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
404 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
405 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
406 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
407 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
408 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
409 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
410 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
411 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
412 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
413 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
414 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
415 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
416 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
417 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
418 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
419 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
420 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
421 #define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0
422 #define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0
423 #define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0
424 #define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0
425 #define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0
426 #define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0
428 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
430 typedef void (*op_rtn) (int bytemode, int sizeflag);
432 struct dis386 {
433 const char *name;
434 op_rtn op1;
435 int bytemode1;
436 op_rtn op2;
437 int bytemode2;
438 op_rtn op3;
439 int bytemode3;
442 /* Upper case letters in the instruction names here are macros.
443 'A' => print 'b' if no register operands or suffix_always is true
444 'B' => print 'b' if suffix_always is true
445 'E' => print 'e' if 32-bit form of jcxz
446 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
447 'H' => print ",pt" or ",pn" branch hint
448 'L' => print 'l' if suffix_always is true
449 'N' => print 'n' if instruction has no wait "prefix"
450 'O' => print 'd', or 'o'
451 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
452 . or suffix_always is true. print 'q' if rex prefix is present.
453 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
454 . is true
455 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
456 'S' => print 'w', 'l' or 'q' if suffix_always is true
457 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
458 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
459 'X' => print 's', 'd' depending on data16 prefix (for XMM)
460 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
461 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
463 Many of the above letters print nothing in Intel mode. See "putop"
464 for the details.
466 Braces '{' and '}', and vertical bars '|', indicate alternative
467 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
468 modes. In cases where there are only two alternatives, the X86_64
469 instruction is reserved, and "(bad)" is printed.
472 static const struct dis386 dis386[] = {
473 /* 00 */
474 { "addB", Eb, Gb, XX },
475 { "addS", Ev, Gv, XX },
476 { "addB", Gb, Eb, XX },
477 { "addS", Gv, Ev, XX },
478 { "addB", AL, Ib, XX },
479 { "addS", eAX, Iv, XX },
480 { "push{T|}", es, XX, XX },
481 { "pop{T|}", es, XX, XX },
482 /* 08 */
483 { "orB", Eb, Gb, XX },
484 { "orS", Ev, Gv, XX },
485 { "orB", Gb, Eb, XX },
486 { "orS", Gv, Ev, XX },
487 { "orB", AL, Ib, XX },
488 { "orS", eAX, Iv, XX },
489 { "push{T|}", cs, XX, XX },
490 { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */
491 /* 10 */
492 { "adcB", Eb, Gb, XX },
493 { "adcS", Ev, Gv, XX },
494 { "adcB", Gb, Eb, XX },
495 { "adcS", Gv, Ev, XX },
496 { "adcB", AL, Ib, XX },
497 { "adcS", eAX, Iv, XX },
498 { "push{T|}", ss, XX, XX },
499 { "popT|}", ss, XX, XX },
500 /* 18 */
501 { "sbbB", Eb, Gb, XX },
502 { "sbbS", Ev, Gv, XX },
503 { "sbbB", Gb, Eb, XX },
504 { "sbbS", Gv, Ev, XX },
505 { "sbbB", AL, Ib, XX },
506 { "sbbS", eAX, Iv, XX },
507 { "push{T|}", ds, XX, XX },
508 { "pop{T|}", ds, XX, XX },
509 /* 20 */
510 { "andB", Eb, Gb, XX },
511 { "andS", Ev, Gv, XX },
512 { "andB", Gb, Eb, XX },
513 { "andS", Gv, Ev, XX },
514 { "andB", AL, Ib, XX },
515 { "andS", eAX, Iv, XX },
516 { "(bad)", XX, XX, XX }, /* SEG ES prefix */
517 { "daa{|}", XX, XX, XX },
518 /* 28 */
519 { "subB", Eb, Gb, XX },
520 { "subS", Ev, Gv, XX },
521 { "subB", Gb, Eb, XX },
522 { "subS", Gv, Ev, XX },
523 { "subB", AL, Ib, XX },
524 { "subS", eAX, Iv, XX },
525 { "(bad)", XX, XX, XX }, /* SEG CS prefix */
526 { "das{|}", XX, XX, XX },
527 /* 30 */
528 { "xorB", Eb, Gb, XX },
529 { "xorS", Ev, Gv, XX },
530 { "xorB", Gb, Eb, XX },
531 { "xorS", Gv, Ev, XX },
532 { "xorB", AL, Ib, XX },
533 { "xorS", eAX, Iv, XX },
534 { "(bad)", XX, XX, XX }, /* SEG SS prefix */
535 { "aaa{|}", XX, XX, XX },
536 /* 38 */
537 { "cmpB", Eb, Gb, XX },
538 { "cmpS", Ev, Gv, XX },
539 { "cmpB", Gb, Eb, XX },
540 { "cmpS", Gv, Ev, XX },
541 { "cmpB", AL, Ib, XX },
542 { "cmpS", eAX, Iv, XX },
543 { "(bad)", XX, XX, XX }, /* SEG DS prefix */
544 { "aas{|}", XX, XX, XX },
545 /* 40 */
546 { "inc{S|}", RMeAX, XX, XX },
547 { "inc{S|}", RMeCX, XX, XX },
548 { "inc{S|}", RMeDX, XX, XX },
549 { "inc{S|}", RMeBX, XX, XX },
550 { "inc{S|}", RMeSP, XX, XX },
551 { "inc{S|}", RMeBP, XX, XX },
552 { "inc{S|}", RMeSI, XX, XX },
553 { "inc{S|}", RMeDI, XX, XX },
554 /* 48 */
555 { "dec{S|}", RMeAX, XX, XX },
556 { "dec{S|}", RMeCX, XX, XX },
557 { "dec{S|}", RMeDX, XX, XX },
558 { "dec{S|}", RMeBX, XX, XX },
559 { "dec{S|}", RMeSP, XX, XX },
560 { "dec{S|}", RMeBP, XX, XX },
561 { "dec{S|}", RMeSI, XX, XX },
562 { "dec{S|}", RMeDI, XX, XX },
563 /* 50 */
564 { "pushS", RMrAX, XX, XX },
565 { "pushS", RMrCX, XX, XX },
566 { "pushS", RMrDX, XX, XX },
567 { "pushS", RMrBX, XX, XX },
568 { "pushS", RMrSP, XX, XX },
569 { "pushS", RMrBP, XX, XX },
570 { "pushS", RMrSI, XX, XX },
571 { "pushS", RMrDI, XX, XX },
572 /* 58 */
573 { "popS", RMrAX, XX, XX },
574 { "popS", RMrCX, XX, XX },
575 { "popS", RMrDX, XX, XX },
576 { "popS", RMrBX, XX, XX },
577 { "popS", RMrSP, XX, XX },
578 { "popS", RMrBP, XX, XX },
579 { "popS", RMrSI, XX, XX },
580 { "popS", RMrDI, XX, XX },
581 /* 60 */
582 { "pusha{P|}", XX, XX, XX },
583 { "popa{P|}", XX, XX, XX },
584 { "bound{S|}", Gv, Ma, XX },
585 { X86_64_0 },
586 { "(bad)", XX, XX, XX }, /* seg fs */
587 { "(bad)", XX, XX, XX }, /* seg gs */
588 { "(bad)", XX, XX, XX }, /* op size prefix */
589 { "(bad)", XX, XX, XX }, /* adr size prefix */
590 /* 68 */
591 { "pushT", Iq, XX, XX },
592 { "imulS", Gv, Ev, Iv },
593 { "pushT", sIb, XX, XX },
594 { "imulS", Gv, Ev, sIb },
595 { "ins{b||b|}", Yb, indirDX, XX },
596 { "ins{R||R|}", Yv, indirDX, XX },
597 { "outs{b||b|}", indirDX, Xb, XX },
598 { "outs{R||R|}", indirDX, Xv, XX },
599 /* 70 */
600 { "joH", Jb, XX, cond_jump_flag },
601 { "jnoH", Jb, XX, cond_jump_flag },
602 { "jbH", Jb, XX, cond_jump_flag },
603 { "jaeH", Jb, XX, cond_jump_flag },
604 { "jeH", Jb, XX, cond_jump_flag },
605 { "jneH", Jb, XX, cond_jump_flag },
606 { "jbeH", Jb, XX, cond_jump_flag },
607 { "jaH", Jb, XX, cond_jump_flag },
608 /* 78 */
609 { "jsH", Jb, XX, cond_jump_flag },
610 { "jnsH", Jb, XX, cond_jump_flag },
611 { "jpH", Jb, XX, cond_jump_flag },
612 { "jnpH", Jb, XX, cond_jump_flag },
613 { "jlH", Jb, XX, cond_jump_flag },
614 { "jgeH", Jb, XX, cond_jump_flag },
615 { "jleH", Jb, XX, cond_jump_flag },
616 { "jgH", Jb, XX, cond_jump_flag },
617 /* 80 */
618 { GRP1b },
619 { GRP1S },
620 { "(bad)", XX, XX, XX },
621 { GRP1Ss },
622 { "testB", Eb, Gb, XX },
623 { "testS", Ev, Gv, XX },
624 { "xchgB", Eb, Gb, XX },
625 { "xchgS", Ev, Gv, XX },
626 /* 88 */
627 { "movB", Eb, Gb, XX },
628 { "movS", Ev, Gv, XX },
629 { "movB", Gb, Eb, XX },
630 { "movS", Gv, Ev, XX },
631 { "movQ", Ev, Sw, XX },
632 { "leaS", Gv, M, XX },
633 { "movQ", Sw, Ev, XX },
634 { "popU", Ev, XX, XX },
635 /* 90 */
636 { "nop", NOP_Fixup, 0, XX, XX },
637 { "xchgS", RMeCX, eAX, XX },
638 { "xchgS", RMeDX, eAX, XX },
639 { "xchgS", RMeBX, eAX, XX },
640 { "xchgS", RMeSP, eAX, XX },
641 { "xchgS", RMeBP, eAX, XX },
642 { "xchgS", RMeSI, eAX, XX },
643 { "xchgS", RMeDI, eAX, XX },
644 /* 98 */
645 { "cW{tR||tR|}", XX, XX, XX },
646 { "cR{tO||tO|}", XX, XX, XX },
647 { "lcall{T|}", Ap, XX, XX },
648 { "(bad)", XX, XX, XX }, /* fwait */
649 { "pushfT", XX, XX, XX },
650 { "popfT", XX, XX, XX },
651 { "sahf{|}", XX, XX, XX },
652 { "lahf{|}", XX, XX, XX },
653 /* a0 */
654 { "movB", AL, Ob64, XX },
655 { "movS", eAX, Ov64, XX },
656 { "movB", Ob64, AL, XX },
657 { "movS", Ov64, eAX, XX },
658 { "movs{b||b|}", Yb, Xb, XX },
659 { "movs{R||R|}", Yv, Xv, XX },
660 { "cmps{b||b|}", Xb, Yb, XX },
661 { "cmps{R||R|}", Xv, Yv, XX },
662 /* a8 */
663 { "testB", AL, Ib, XX },
664 { "testS", eAX, Iv, XX },
665 { "stosB", Yb, AL, XX },
666 { "stosS", Yv, eAX, XX },
667 { "lodsB", AL, Xb, XX },
668 { "lodsS", eAX, Xv, XX },
669 { "scasB", AL, Yb, XX },
670 { "scasS", eAX, Yv, XX },
671 /* b0 */
672 { "movB", RMAL, Ib, XX },
673 { "movB", RMCL, Ib, XX },
674 { "movB", RMDL, Ib, XX },
675 { "movB", RMBL, Ib, XX },
676 { "movB", RMAH, Ib, XX },
677 { "movB", RMCH, Ib, XX },
678 { "movB", RMDH, Ib, XX },
679 { "movB", RMBH, Ib, XX },
680 /* b8 */
681 { "movS", RMeAX, Iv64, XX },
682 { "movS", RMeCX, Iv64, XX },
683 { "movS", RMeDX, Iv64, XX },
684 { "movS", RMeBX, Iv64, XX },
685 { "movS", RMeSP, Iv64, XX },
686 { "movS", RMeBP, Iv64, XX },
687 { "movS", RMeSI, Iv64, XX },
688 { "movS", RMeDI, Iv64, XX },
689 /* c0 */
690 { GRP2b },
691 { GRP2S },
692 { "retT", Iw, XX, XX },
693 { "retT", XX, XX, XX },
694 { "les{S|}", Gv, Mp, XX },
695 { "ldsS", Gv, Mp, XX },
696 { "movA", Eb, Ib, XX },
697 { "movQ", Ev, Iv, XX },
698 /* c8 */
699 { "enterT", Iw, Ib, XX },
700 { "leaveT", XX, XX, XX },
701 { "lretP", Iw, XX, XX },
702 { "lretP", XX, XX, XX },
703 { "int3", XX, XX, XX },
704 { "int", Ib, XX, XX },
705 { "into{|}", XX, XX, XX },
706 { "iretP", XX, XX, XX },
707 /* d0 */
708 { GRP2b_one },
709 { GRP2S_one },
710 { GRP2b_cl },
711 { GRP2S_cl },
712 { "aam{|}", sIb, XX, XX },
713 { "aad{|}", sIb, XX, XX },
714 { "(bad)", XX, XX, XX },
715 { "xlat", DSBX, XX, XX },
716 /* d8 */
717 { FLOAT },
718 { FLOAT },
719 { FLOAT },
720 { FLOAT },
721 { FLOAT },
722 { FLOAT },
723 { FLOAT },
724 { FLOAT },
725 /* e0 */
726 { "loopneFH", Jb, XX, loop_jcxz_flag },
727 { "loopeFH", Jb, XX, loop_jcxz_flag },
728 { "loopFH", Jb, XX, loop_jcxz_flag },
729 { "jEcxzH", Jb, XX, loop_jcxz_flag },
730 { "inB", AL, Ib, XX },
731 { "inS", eAX, Ib, XX },
732 { "outB", Ib, AL, XX },
733 { "outS", Ib, eAX, XX },
734 /* e8 */
735 { "callT", Jv, XX, XX },
736 { "jmpT", Jv, XX, XX },
737 { "ljmp{T|}", Ap, XX, XX },
738 { "jmp", Jb, XX, XX },
739 { "inB", AL, indirDX, XX },
740 { "inS", eAX, indirDX, XX },
741 { "outB", indirDX, AL, XX },
742 { "outS", indirDX, eAX, XX },
743 /* f0 */
744 { "(bad)", XX, XX, XX }, /* lock prefix */
745 { "icebp", XX, XX, XX },
746 { "(bad)", XX, XX, XX }, /* repne */
747 { "(bad)", XX, XX, XX }, /* repz */
748 { "hlt", XX, XX, XX },
749 { "cmc", XX, XX, XX },
750 { GRP3b },
751 { GRP3S },
752 /* f8 */
753 { "clc", XX, XX, XX },
754 { "stc", XX, XX, XX },
755 { "cli", XX, XX, XX },
756 { "sti", XX, XX, XX },
757 { "cld", XX, XX, XX },
758 { "std", XX, XX, XX },
759 { GRP4 },
760 { GRP5 },
763 static const struct dis386 dis386_twobyte[] = {
764 /* 00 */
765 { GRP6 },
766 { GRP7 },
767 { "larS", Gv, Ew, XX },
768 { "lslS", Gv, Ew, XX },
769 { "(bad)", XX, XX, XX },
770 { "syscall", XX, XX, XX },
771 { "clts", XX, XX, XX },
772 { "sysretP", XX, XX, XX },
773 /* 08 */
774 { "invd", XX, XX, XX },
775 { "wbinvd", XX, XX, XX },
776 { "(bad)", XX, XX, XX },
777 { "ud2a", XX, XX, XX },
778 { "(bad)", XX, XX, XX },
779 { GRPAMD },
780 { "femms", XX, XX, XX },
781 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */
782 /* 10 */
783 { PREGRP8 },
784 { PREGRP9 },
785 { PREGRP30 },
786 { "movlpX", EX, XM, SIMD_Fixup, 'h' },
787 { "unpcklpX", XM, EX, XX },
788 { "unpckhpX", XM, EX, XX },
789 { PREGRP31 },
790 { "movhpX", EX, XM, SIMD_Fixup, 'l' },
791 /* 18 */
792 { GRP14 },
793 { "(bad)", XX, XX, XX },
794 { "(bad)", XX, XX, XX },
795 { "(bad)", XX, XX, XX },
796 { "(bad)", XX, XX, XX },
797 { "(bad)", XX, XX, XX },
798 { "(bad)", XX, XX, XX },
799 { "(bad)", XX, XX, XX },
800 /* 20 */
801 { "movL", Rm, Cm, XX },
802 { "movL", Rm, Dm, XX },
803 { "movL", Cm, Rm, XX },
804 { "movL", Dm, Rm, XX },
805 { "movL", Rd, Td, XX },
806 { "(bad)", XX, XX, XX },
807 { "movL", Td, Rd, XX },
808 { "(bad)", XX, XX, XX },
809 /* 28 */
810 { "movapX", XM, EX, XX },
811 { "movapX", EX, XM, XX },
812 { PREGRP2 },
813 { "movntpX", Ev, XM, XX },
814 { PREGRP4 },
815 { PREGRP3 },
816 { "ucomisX", XM,EX, XX },
817 { "comisX", XM,EX, XX },
818 /* 30 */
819 { "wrmsr", XX, XX, XX },
820 { "rdtsc", XX, XX, XX },
821 { "rdmsr", XX, XX, XX },
822 { "rdpmc", XX, XX, XX },
823 { "sysenter", XX, XX, XX },
824 { "sysexit", XX, XX, XX },
825 { "(bad)", XX, XX, XX },
826 { "(bad)", XX, XX, XX },
827 /* 38 */
828 { "(bad)", XX, XX, XX },
829 { "(bad)", XX, XX, XX },
830 { "(bad)", XX, XX, XX },
831 { "(bad)", XX, XX, XX },
832 { "(bad)", XX, XX, XX },
833 { "(bad)", XX, XX, XX },
834 { "(bad)", XX, XX, XX },
835 { "(bad)", XX, XX, XX },
836 /* 40 */
837 { "cmovo", Gv, Ev, XX },
838 { "cmovno", Gv, Ev, XX },
839 { "cmovb", Gv, Ev, XX },
840 { "cmovae", Gv, Ev, XX },
841 { "cmove", Gv, Ev, XX },
842 { "cmovne", Gv, Ev, XX },
843 { "cmovbe", Gv, Ev, XX },
844 { "cmova", Gv, Ev, XX },
845 /* 48 */
846 { "cmovs", Gv, Ev, XX },
847 { "cmovns", Gv, Ev, XX },
848 { "cmovp", Gv, Ev, XX },
849 { "cmovnp", Gv, Ev, XX },
850 { "cmovl", Gv, Ev, XX },
851 { "cmovge", Gv, Ev, XX },
852 { "cmovle", Gv, Ev, XX },
853 { "cmovg", Gv, Ev, XX },
854 /* 50 */
855 { "movmskpX", Gd, XS, XX },
856 { PREGRP13 },
857 { PREGRP12 },
858 { PREGRP11 },
859 { "andpX", XM, EX, XX },
860 { "andnpX", XM, EX, XX },
861 { "orpX", XM, EX, XX },
862 { "xorpX", XM, EX, XX },
863 /* 58 */
864 { PREGRP0 },
865 { PREGRP10 },
866 { PREGRP17 },
867 { PREGRP16 },
868 { PREGRP14 },
869 { PREGRP7 },
870 { PREGRP5 },
871 { PREGRP6 },
872 /* 60 */
873 { "punpcklbw", MX, EM, XX },
874 { "punpcklwd", MX, EM, XX },
875 { "punpckldq", MX, EM, XX },
876 { "packsswb", MX, EM, XX },
877 { "pcmpgtb", MX, EM, XX },
878 { "pcmpgtw", MX, EM, XX },
879 { "pcmpgtd", MX, EM, XX },
880 { "packuswb", MX, EM, XX },
881 /* 68 */
882 { "punpckhbw", MX, EM, XX },
883 { "punpckhwd", MX, EM, XX },
884 { "punpckhdq", MX, EM, XX },
885 { "packssdw", MX, EM, XX },
886 { PREGRP26 },
887 { PREGRP24 },
888 { "movd", MX, Edq, XX },
889 { PREGRP19 },
890 /* 70 */
891 { PREGRP22 },
892 { GRP10 },
893 { GRP11 },
894 { GRP12 },
895 { "pcmpeqb", MX, EM, XX },
896 { "pcmpeqw", MX, EM, XX },
897 { "pcmpeqd", MX, EM, XX },
898 { "emms", XX, XX, XX },
899 /* 78 */
900 { "(bad)", XX, XX, XX },
901 { "(bad)", XX, XX, XX },
902 { "(bad)", XX, XX, XX },
903 { "(bad)", XX, XX, XX },
904 { PREGRP28 },
905 { PREGRP29 },
906 { PREGRP23 },
907 { PREGRP20 },
908 /* 80 */
909 { "joH", Jv, XX, cond_jump_flag },
910 { "jnoH", Jv, XX, cond_jump_flag },
911 { "jbH", Jv, XX, cond_jump_flag },
912 { "jaeH", Jv, XX, cond_jump_flag },
913 { "jeH", Jv, XX, cond_jump_flag },
914 { "jneH", Jv, XX, cond_jump_flag },
915 { "jbeH", Jv, XX, cond_jump_flag },
916 { "jaH", Jv, XX, cond_jump_flag },
917 /* 88 */
918 { "jsH", Jv, XX, cond_jump_flag },
919 { "jnsH", Jv, XX, cond_jump_flag },
920 { "jpH", Jv, XX, cond_jump_flag },
921 { "jnpH", Jv, XX, cond_jump_flag },
922 { "jlH", Jv, XX, cond_jump_flag },
923 { "jgeH", Jv, XX, cond_jump_flag },
924 { "jleH", Jv, XX, cond_jump_flag },
925 { "jgH", Jv, XX, cond_jump_flag },
926 /* 90 */
927 { "seto", Eb, XX, XX },
928 { "setno", Eb, XX, XX },
929 { "setb", Eb, XX, XX },
930 { "setae", Eb, XX, XX },
931 { "sete", Eb, XX, XX },
932 { "setne", Eb, XX, XX },
933 { "setbe", Eb, XX, XX },
934 { "seta", Eb, XX, XX },
935 /* 98 */
936 { "sets", Eb, XX, XX },
937 { "setns", Eb, XX, XX },
938 { "setp", Eb, XX, XX },
939 { "setnp", Eb, XX, XX },
940 { "setl", Eb, XX, XX },
941 { "setge", Eb, XX, XX },
942 { "setle", Eb, XX, XX },
943 { "setg", Eb, XX, XX },
944 /* a0 */
945 { "pushT", fs, XX, XX },
946 { "popT", fs, XX, XX },
947 { "cpuid", XX, XX, XX },
948 { "btS", Ev, Gv, XX },
949 { "shldS", Ev, Gv, Ib },
950 { "shldS", Ev, Gv, CL },
951 { "(bad)", XX, XX, XX },
952 { GRPPADLCK },
953 /* a8 */
954 { "pushT", gs, XX, XX },
955 { "popT", gs, XX, XX },
956 { "rsm", XX, XX, XX },
957 { "btsS", Ev, Gv, XX },
958 { "shrdS", Ev, Gv, Ib },
959 { "shrdS", Ev, Gv, CL },
960 { GRP13 },
961 { "imulS", Gv, Ev, XX },
962 /* b0 */
963 { "cmpxchgB", Eb, Gb, XX },
964 { "cmpxchgS", Ev, Gv, XX },
965 { "lssS", Gv, Mp, XX },
966 { "btrS", Ev, Gv, XX },
967 { "lfsS", Gv, Mp, XX },
968 { "lgsS", Gv, Mp, XX },
969 { "movz{bR|x|bR|x}", Gv, Eb, XX },
970 { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */
971 /* b8 */
972 { "(bad)", XX, XX, XX },
973 { "ud2b", XX, XX, XX },
974 { GRP8 },
975 { "btcS", Ev, Gv, XX },
976 { "bsfS", Gv, Ev, XX },
977 { "bsrS", Gv, Ev, XX },
978 { "movs{bR|x|bR|x}", Gv, Eb, XX },
979 { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */
980 /* c0 */
981 { "xaddB", Eb, Gb, XX },
982 { "xaddS", Ev, Gv, XX },
983 { PREGRP1 },
984 { "movntiS", Ev, Gv, XX },
985 { "pinsrw", MX, Ed, Ib },
986 { "pextrw", Gd, MS, Ib },
987 { "shufpX", XM, EX, Ib },
988 { GRP9 },
989 /* c8 */
990 { "bswap", RMeAX, XX, XX },
991 { "bswap", RMeCX, XX, XX },
992 { "bswap", RMeDX, XX, XX },
993 { "bswap", RMeBX, XX, XX },
994 { "bswap", RMeSP, XX, XX },
995 { "bswap", RMeBP, XX, XX },
996 { "bswap", RMeSI, XX, XX },
997 { "bswap", RMeDI, XX, XX },
998 /* d0 */
999 { PREGRP27 },
1000 { "psrlw", MX, EM, XX },
1001 { "psrld", MX, EM, XX },
1002 { "psrlq", MX, EM, XX },
1003 { "paddq", MX, EM, XX },
1004 { "pmullw", MX, EM, XX },
1005 { PREGRP21 },
1006 { "pmovmskb", Gd, MS, XX },
1007 /* d8 */
1008 { "psubusb", MX, EM, XX },
1009 { "psubusw", MX, EM, XX },
1010 { "pminub", MX, EM, XX },
1011 { "pand", MX, EM, XX },
1012 { "paddusb", MX, EM, XX },
1013 { "paddusw", MX, EM, XX },
1014 { "pmaxub", MX, EM, XX },
1015 { "pandn", MX, EM, XX },
1016 /* e0 */
1017 { "pavgb", MX, EM, XX },
1018 { "psraw", MX, EM, XX },
1019 { "psrad", MX, EM, XX },
1020 { "pavgw", MX, EM, XX },
1021 { "pmulhuw", MX, EM, XX },
1022 { "pmulhw", MX, EM, XX },
1023 { PREGRP15 },
1024 { PREGRP25 },
1025 /* e8 */
1026 { "psubsb", MX, EM, XX },
1027 { "psubsw", MX, EM, XX },
1028 { "pminsw", MX, EM, XX },
1029 { "por", MX, EM, XX },
1030 { "paddsb", MX, EM, XX },
1031 { "paddsw", MX, EM, XX },
1032 { "pmaxsw", MX, EM, XX },
1033 { "pxor", MX, EM, XX },
1034 /* f0 */
1035 { PREGRP32 },
1036 { "psllw", MX, EM, XX },
1037 { "pslld", MX, EM, XX },
1038 { "psllq", MX, EM, XX },
1039 { "pmuludq", MX, EM, XX },
1040 { "pmaddwd", MX, EM, XX },
1041 { "psadbw", MX, EM, XX },
1042 { PREGRP18 },
1043 /* f8 */
1044 { "psubb", MX, EM, XX },
1045 { "psubw", MX, EM, XX },
1046 { "psubd", MX, EM, XX },
1047 { "psubq", MX, EM, XX },
1048 { "paddb", MX, EM, XX },
1049 { "paddw", MX, EM, XX },
1050 { "paddd", MX, EM, XX },
1051 { "(bad)", XX, XX, XX }
1054 static const unsigned char onebyte_has_modrm[256] = {
1055 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1056 /* ------------------------------- */
1057 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1058 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1059 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1060 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1061 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1062 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1063 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1064 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1065 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1066 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1067 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1068 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1069 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1070 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1071 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1072 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1073 /* ------------------------------- */
1074 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1077 static const unsigned char twobyte_has_modrm[256] = {
1078 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1079 /* ------------------------------- */
1080 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1081 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1082 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1083 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1084 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1085 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1086 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1087 /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1, /* 7f */
1088 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1089 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1090 /* a0 */ 0,0,0,1,1,1,0,1,0,0,0,1,1,1,1,1, /* af */
1091 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1092 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1093 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1094 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1095 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1096 /* ------------------------------- */
1097 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1100 static const unsigned char twobyte_uses_SSE_prefix[256] = {
1101 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1102 /* ------------------------------- */
1103 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1104 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1105 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1106 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1107 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1108 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1109 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1110 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */
1111 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1112 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1113 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1114 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1115 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1116 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1117 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1118 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1119 /* ------------------------------- */
1120 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1123 static char obuf[100];
1124 static char *obufp;
1125 static char scratchbuf[100];
1126 static unsigned char *start_codep;
1127 static unsigned char *insn_codep;
1128 static unsigned char *codep;
1129 static disassemble_info *the_info;
1130 static int mod;
1131 static int rm;
1132 static int reg;
1133 static unsigned char need_modrm;
1135 /* If we are accessing mod/rm/reg without need_modrm set, then the
1136 values are stale. Hitting this abort likely indicates that you
1137 need to update onebyte_has_modrm or twobyte_has_modrm. */
1138 #define MODRM_CHECK if (!need_modrm) abort ()
1140 static const char **names64;
1141 static const char **names32;
1142 static const char **names16;
1143 static const char **names8;
1144 static const char **names8rex;
1145 static const char **names_seg;
1146 static const char **index16;
1148 static const char *intel_names64[] = {
1149 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1150 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1152 static const char *intel_names32[] = {
1153 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1154 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1156 static const char *intel_names16[] = {
1157 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1158 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1160 static const char *intel_names8[] = {
1161 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1163 static const char *intel_names8rex[] = {
1164 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1165 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1167 static const char *intel_names_seg[] = {
1168 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1170 static const char *intel_index16[] = {
1171 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1174 static const char *att_names64[] = {
1175 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1176 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1178 static const char *att_names32[] = {
1179 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1180 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1182 static const char *att_names16[] = {
1183 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1184 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1186 static const char *att_names8[] = {
1187 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1189 static const char *att_names8rex[] = {
1190 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1191 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1193 static const char *att_names_seg[] = {
1194 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1196 static const char *att_index16[] = {
1197 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1200 static const struct dis386 grps[][8] = {
1201 /* GRP1b */
1203 { "addA", Eb, Ib, XX },
1204 { "orA", Eb, Ib, XX },
1205 { "adcA", Eb, Ib, XX },
1206 { "sbbA", Eb, Ib, XX },
1207 { "andA", Eb, Ib, XX },
1208 { "subA", Eb, Ib, XX },
1209 { "xorA", Eb, Ib, XX },
1210 { "cmpA", Eb, Ib, XX }
1212 /* GRP1S */
1214 { "addQ", Ev, Iv, XX },
1215 { "orQ", Ev, Iv, XX },
1216 { "adcQ", Ev, Iv, XX },
1217 { "sbbQ", Ev, Iv, XX },
1218 { "andQ", Ev, Iv, XX },
1219 { "subQ", Ev, Iv, XX },
1220 { "xorQ", Ev, Iv, XX },
1221 { "cmpQ", Ev, Iv, XX }
1223 /* GRP1Ss */
1225 { "addQ", Ev, sIb, XX },
1226 { "orQ", Ev, sIb, XX },
1227 { "adcQ", Ev, sIb, XX },
1228 { "sbbQ", Ev, sIb, XX },
1229 { "andQ", Ev, sIb, XX },
1230 { "subQ", Ev, sIb, XX },
1231 { "xorQ", Ev, sIb, XX },
1232 { "cmpQ", Ev, sIb, XX }
1234 /* GRP2b */
1236 { "rolA", Eb, Ib, XX },
1237 { "rorA", Eb, Ib, XX },
1238 { "rclA", Eb, Ib, XX },
1239 { "rcrA", Eb, Ib, XX },
1240 { "shlA", Eb, Ib, XX },
1241 { "shrA", Eb, Ib, XX },
1242 { "(bad)", XX, XX, XX },
1243 { "sarA", Eb, Ib, XX },
1245 /* GRP2S */
1247 { "rolQ", Ev, Ib, XX },
1248 { "rorQ", Ev, Ib, XX },
1249 { "rclQ", Ev, Ib, XX },
1250 { "rcrQ", Ev, Ib, XX },
1251 { "shlQ", Ev, Ib, XX },
1252 { "shrQ", Ev, Ib, XX },
1253 { "(bad)", XX, XX, XX },
1254 { "sarQ", Ev, Ib, XX },
1256 /* GRP2b_one */
1258 { "rolA", Eb, XX, XX },
1259 { "rorA", Eb, XX, XX },
1260 { "rclA", Eb, XX, XX },
1261 { "rcrA", Eb, XX, XX },
1262 { "shlA", Eb, XX, XX },
1263 { "shrA", Eb, XX, XX },
1264 { "(bad)", XX, XX, XX },
1265 { "sarA", Eb, XX, XX },
1267 /* GRP2S_one */
1269 { "rolQ", Ev, XX, XX },
1270 { "rorQ", Ev, XX, XX },
1271 { "rclQ", Ev, XX, XX },
1272 { "rcrQ", Ev, XX, XX },
1273 { "shlQ", Ev, XX, XX },
1274 { "shrQ", Ev, XX, XX },
1275 { "(bad)", XX, XX, XX},
1276 { "sarQ", Ev, XX, XX },
1278 /* GRP2b_cl */
1280 { "rolA", Eb, CL, XX },
1281 { "rorA", Eb, CL, XX },
1282 { "rclA", Eb, CL, XX },
1283 { "rcrA", Eb, CL, XX },
1284 { "shlA", Eb, CL, XX },
1285 { "shrA", Eb, CL, XX },
1286 { "(bad)", XX, XX, XX },
1287 { "sarA", Eb, CL, XX },
1289 /* GRP2S_cl */
1291 { "rolQ", Ev, CL, XX },
1292 { "rorQ", Ev, CL, XX },
1293 { "rclQ", Ev, CL, XX },
1294 { "rcrQ", Ev, CL, XX },
1295 { "shlQ", Ev, CL, XX },
1296 { "shrQ", Ev, CL, XX },
1297 { "(bad)", XX, XX, XX },
1298 { "sarQ", Ev, CL, XX }
1300 /* GRP3b */
1302 { "testA", Eb, Ib, XX },
1303 { "(bad)", Eb, XX, XX },
1304 { "notA", Eb, XX, XX },
1305 { "negA", Eb, XX, XX },
1306 { "mulA", Eb, XX, XX }, /* Don't print the implicit %al register, */
1307 { "imulA", Eb, XX, XX }, /* to distinguish these opcodes from other */
1308 { "divA", Eb, XX, XX }, /* mul/imul opcodes. Do the same for div */
1309 { "idivA", Eb, XX, XX } /* and idiv for consistency. */
1311 /* GRP3S */
1313 { "testQ", Ev, Iv, XX },
1314 { "(bad)", XX, XX, XX },
1315 { "notQ", Ev, XX, XX },
1316 { "negQ", Ev, XX, XX },
1317 { "mulQ", Ev, XX, XX }, /* Don't print the implicit register. */
1318 { "imulQ", Ev, XX, XX },
1319 { "divQ", Ev, XX, XX },
1320 { "idivQ", Ev, XX, XX },
1322 /* GRP4 */
1324 { "incA", Eb, XX, XX },
1325 { "decA", Eb, XX, XX },
1326 { "(bad)", XX, XX, XX },
1327 { "(bad)", XX, XX, XX },
1328 { "(bad)", XX, XX, XX },
1329 { "(bad)", XX, XX, XX },
1330 { "(bad)", XX, XX, XX },
1331 { "(bad)", XX, XX, XX },
1333 /* GRP5 */
1335 { "incQ", Ev, XX, XX },
1336 { "decQ", Ev, XX, XX },
1337 { "callT", indirEv, XX, XX },
1338 { "lcallT", indirEv, XX, XX },
1339 { "jmpT", indirEv, XX, XX },
1340 { "ljmpT", indirEv, XX, XX },
1341 { "pushU", Ev, XX, XX },
1342 { "(bad)", XX, XX, XX },
1344 /* GRP6 */
1346 { "sldtQ", Ev, XX, XX },
1347 { "strQ", Ev, XX, XX },
1348 { "lldt", Ew, XX, XX },
1349 { "ltr", Ew, XX, XX },
1350 { "verr", Ew, XX, XX },
1351 { "verw", Ew, XX, XX },
1352 { "(bad)", XX, XX, XX },
1353 { "(bad)", XX, XX, XX }
1355 /* GRP7 */
1357 { "sgdtQ", M, XX, XX },
1358 { "sidtQ", PNI_Fixup, 0, XX, XX },
1359 { "lgdtQ", M, XX, XX },
1360 { "lidtQ", M, XX, XX },
1361 { "smswQ", Ev, XX, XX },
1362 { "(bad)", XX, XX, XX },
1363 { "lmsw", Ew, XX, XX },
1364 { "invlpg", INVLPG_Fixup, w_mode, XX, XX },
1366 /* GRP8 */
1368 { "(bad)", XX, XX, XX },
1369 { "(bad)", XX, XX, XX },
1370 { "(bad)", XX, XX, XX },
1371 { "(bad)", XX, XX, XX },
1372 { "btQ", Ev, Ib, XX },
1373 { "btsQ", Ev, Ib, XX },
1374 { "btrQ", Ev, Ib, XX },
1375 { "btcQ", Ev, Ib, XX },
1377 /* GRP9 */
1379 { "(bad)", XX, XX, XX },
1380 { "cmpxchg8b", Ev, XX, XX },
1381 { "(bad)", XX, XX, XX },
1382 { "(bad)", XX, XX, XX },
1383 { "(bad)", XX, XX, XX },
1384 { "(bad)", XX, XX, XX },
1385 { "(bad)", XX, XX, XX },
1386 { "(bad)", XX, XX, XX },
1388 /* GRP10 */
1390 { "(bad)", XX, XX, XX },
1391 { "(bad)", XX, XX, XX },
1392 { "psrlw", MS, Ib, XX },
1393 { "(bad)", XX, XX, XX },
1394 { "psraw", MS, Ib, XX },
1395 { "(bad)", XX, XX, XX },
1396 { "psllw", MS, Ib, XX },
1397 { "(bad)", XX, XX, XX },
1399 /* GRP11 */
1401 { "(bad)", XX, XX, XX },
1402 { "(bad)", XX, XX, XX },
1403 { "psrld", MS, Ib, XX },
1404 { "(bad)", XX, XX, XX },
1405 { "psrad", MS, Ib, XX },
1406 { "(bad)", XX, XX, XX },
1407 { "pslld", MS, Ib, XX },
1408 { "(bad)", XX, XX, XX },
1410 /* GRP12 */
1412 { "(bad)", XX, XX, XX },
1413 { "(bad)", XX, XX, XX },
1414 { "psrlq", MS, Ib, XX },
1415 { "psrldq", MS, Ib, XX },
1416 { "(bad)", XX, XX, XX },
1417 { "(bad)", XX, XX, XX },
1418 { "psllq", MS, Ib, XX },
1419 { "pslldq", MS, Ib, XX },
1421 /* GRP13 */
1423 { "fxsave", Ev, XX, XX },
1424 { "fxrstor", Ev, XX, XX },
1425 { "ldmxcsr", Ev, XX, XX },
1426 { "stmxcsr", Ev, XX, XX },
1427 { "(bad)", XX, XX, XX },
1428 { "lfence", OP_0fae, 0, XX, XX },
1429 { "mfence", OP_0fae, 0, XX, XX },
1430 { "clflush", OP_0fae, 0, XX, XX },
1432 /* GRP14 */
1434 { "prefetchnta", Ev, XX, XX },
1435 { "prefetcht0", Ev, XX, XX },
1436 { "prefetcht1", Ev, XX, XX },
1437 { "prefetcht2", Ev, XX, XX },
1438 { "(bad)", XX, XX, XX },
1439 { "(bad)", XX, XX, XX },
1440 { "(bad)", XX, XX, XX },
1441 { "(bad)", XX, XX, XX },
1443 /* GRPAMD */
1445 { "prefetch", Eb, XX, XX },
1446 { "prefetchw", Eb, XX, XX },
1447 { "(bad)", XX, XX, XX },
1448 { "(bad)", XX, XX, XX },
1449 { "(bad)", XX, XX, XX },
1450 { "(bad)", XX, XX, XX },
1451 { "(bad)", XX, XX, XX },
1452 { "(bad)", XX, XX, XX },
1454 /* GRPPADLCK */
1456 { "xstorerng", OP_0f07, 0, XX, XX },
1457 { "xcryptecb", OP_0f07, 0, XX, XX },
1458 { "xcryptcbc", OP_0f07, 0, XX, XX },
1459 { "(bad)", OP_0f07, 0, XX, XX },
1460 { "xcryptcfb", OP_0f07, 0, XX, XX },
1461 { "xcryptofb", OP_0f07, 0, XX, XX },
1462 { "(bad)", OP_0f07, 0, XX, XX },
1463 { "(bad)", OP_0f07, 0, XX, XX },
1467 static const struct dis386 prefix_user_table[][4] = {
1468 /* PREGRP0 */
1470 { "addps", XM, EX, XX },
1471 { "addss", XM, EX, XX },
1472 { "addpd", XM, EX, XX },
1473 { "addsd", XM, EX, XX },
1475 /* PREGRP1 */
1477 { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */
1478 { "", XM, EX, OPSIMD },
1479 { "", XM, EX, OPSIMD },
1480 { "", XM, EX, OPSIMD },
1482 /* PREGRP2 */
1484 { "cvtpi2ps", XM, EM, XX },
1485 { "cvtsi2ssY", XM, Ev, XX },
1486 { "cvtpi2pd", XM, EM, XX },
1487 { "cvtsi2sdY", XM, Ev, XX },
1489 /* PREGRP3 */
1491 { "cvtps2pi", MX, EX, XX },
1492 { "cvtss2siY", Gv, EX, XX },
1493 { "cvtpd2pi", MX, EX, XX },
1494 { "cvtsd2siY", Gv, EX, XX },
1496 /* PREGRP4 */
1498 { "cvttps2pi", MX, EX, XX },
1499 { "cvttss2siY", Gv, EX, XX },
1500 { "cvttpd2pi", MX, EX, XX },
1501 { "cvttsd2siY", Gv, EX, XX },
1503 /* PREGRP5 */
1505 { "divps", XM, EX, XX },
1506 { "divss", XM, EX, XX },
1507 { "divpd", XM, EX, XX },
1508 { "divsd", XM, EX, XX },
1510 /* PREGRP6 */
1512 { "maxps", XM, EX, XX },
1513 { "maxss", XM, EX, XX },
1514 { "maxpd", XM, EX, XX },
1515 { "maxsd", XM, EX, XX },
1517 /* PREGRP7 */
1519 { "minps", XM, EX, XX },
1520 { "minss", XM, EX, XX },
1521 { "minpd", XM, EX, XX },
1522 { "minsd", XM, EX, XX },
1524 /* PREGRP8 */
1526 { "movups", XM, EX, XX },
1527 { "movss", XM, EX, XX },
1528 { "movupd", XM, EX, XX },
1529 { "movsd", XM, EX, XX },
1531 /* PREGRP9 */
1533 { "movups", EX, XM, XX },
1534 { "movss", EX, XM, XX },
1535 { "movupd", EX, XM, XX },
1536 { "movsd", EX, XM, XX },
1538 /* PREGRP10 */
1540 { "mulps", XM, EX, XX },
1541 { "mulss", XM, EX, XX },
1542 { "mulpd", XM, EX, XX },
1543 { "mulsd", XM, EX, XX },
1545 /* PREGRP11 */
1547 { "rcpps", XM, EX, XX },
1548 { "rcpss", XM, EX, XX },
1549 { "(bad)", XM, EX, XX },
1550 { "(bad)", XM, EX, XX },
1552 /* PREGRP12 */
1554 { "rsqrtps", XM, EX, XX },
1555 { "rsqrtss", XM, EX, XX },
1556 { "(bad)", XM, EX, XX },
1557 { "(bad)", XM, EX, XX },
1559 /* PREGRP13 */
1561 { "sqrtps", XM, EX, XX },
1562 { "sqrtss", XM, EX, XX },
1563 { "sqrtpd", XM, EX, XX },
1564 { "sqrtsd", XM, EX, XX },
1566 /* PREGRP14 */
1568 { "subps", XM, EX, XX },
1569 { "subss", XM, EX, XX },
1570 { "subpd", XM, EX, XX },
1571 { "subsd", XM, EX, XX },
1573 /* PREGRP15 */
1575 { "(bad)", XM, EX, XX },
1576 { "cvtdq2pd", XM, EX, XX },
1577 { "cvttpd2dq", XM, EX, XX },
1578 { "cvtpd2dq", XM, EX, XX },
1580 /* PREGRP16 */
1582 { "cvtdq2ps", XM, EX, XX },
1583 { "cvttps2dq",XM, EX, XX },
1584 { "cvtps2dq",XM, EX, XX },
1585 { "(bad)", XM, EX, XX },
1587 /* PREGRP17 */
1589 { "cvtps2pd", XM, EX, XX },
1590 { "cvtss2sd", XM, EX, XX },
1591 { "cvtpd2ps", XM, EX, XX },
1592 { "cvtsd2ss", XM, EX, XX },
1594 /* PREGRP18 */
1596 { "maskmovq", MX, MS, XX },
1597 { "(bad)", XM, EX, XX },
1598 { "maskmovdqu", XM, EX, XX },
1599 { "(bad)", XM, EX, XX },
1601 /* PREGRP19 */
1603 { "movq", MX, EM, XX },
1604 { "movdqu", XM, EX, XX },
1605 { "movdqa", XM, EX, XX },
1606 { "(bad)", XM, EX, XX },
1608 /* PREGRP20 */
1610 { "movq", EM, MX, XX },
1611 { "movdqu", EX, XM, XX },
1612 { "movdqa", EX, XM, XX },
1613 { "(bad)", EX, XM, XX },
1615 /* PREGRP21 */
1617 { "(bad)", EX, XM, XX },
1618 { "movq2dq", XM, MS, XX },
1619 { "movq", EX, XM, XX },
1620 { "movdq2q", MX, XS, XX },
1622 /* PREGRP22 */
1624 { "pshufw", MX, EM, Ib },
1625 { "pshufhw", XM, EX, Ib },
1626 { "pshufd", XM, EX, Ib },
1627 { "pshuflw", XM, EX, Ib },
1629 /* PREGRP23 */
1631 { "movd", Edq, MX, XX },
1632 { "movq", XM, EX, XX },
1633 { "movd", Edq, XM, XX },
1634 { "(bad)", Ed, XM, XX },
1636 /* PREGRP24 */
1638 { "(bad)", MX, EX, XX },
1639 { "(bad)", XM, EX, XX },
1640 { "punpckhqdq", XM, EX, XX },
1641 { "(bad)", XM, EX, XX },
1643 /* PREGRP25 */
1645 { "movntq", Ev, MX, XX },
1646 { "(bad)", Ev, XM, XX },
1647 { "movntdq", Ev, XM, XX },
1648 { "(bad)", Ev, XM, XX },
1650 /* PREGRP26 */
1652 { "(bad)", MX, EX, XX },
1653 { "(bad)", XM, EX, XX },
1654 { "punpcklqdq", XM, EX, XX },
1655 { "(bad)", XM, EX, XX },
1657 /* PREGRP27 */
1659 { "(bad)", MX, EX, XX },
1660 { "(bad)", XM, EX, XX },
1661 { "addsubpd", XM, EX, XX },
1662 { "addsubps", XM, EX, XX },
1664 /* PREGRP28 */
1666 { "(bad)", MX, EX, XX },
1667 { "(bad)", XM, EX, XX },
1668 { "haddpd", XM, EX, XX },
1669 { "haddps", XM, EX, XX },
1671 /* PREGRP29 */
1673 { "(bad)", MX, EX, XX },
1674 { "(bad)", XM, EX, XX },
1675 { "hsubpd", XM, EX, XX },
1676 { "hsubps", XM, EX, XX },
1678 /* PREGRP30 */
1680 { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
1681 { "movsldup", XM, EX, XX },
1682 { "movlpd", XM, EX, XX },
1683 { "movddup", XM, EX, XX },
1685 /* PREGRP31 */
1687 { "movhpX", XM, EX, SIMD_Fixup, 'l' },
1688 { "movshdup", XM, EX, XX },
1689 { "movhpd", XM, EX, XX },
1690 { "(bad)", XM, EX, XX },
1692 /* PREGRP32 */
1694 { "(bad)", XM, EX, XX },
1695 { "(bad)", XM, EX, XX },
1696 { "(bad)", XM, EX, XX },
1697 { "lddqu", XM, M, XX },
1701 static const struct dis386 x86_64_table[][2] = {
1703 { "arpl", Ew, Gw, XX },
1704 { "movs{||lq|xd}", Gv, Ed, XX },
1708 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1710 static void
1711 ckprefix (void)
1713 int newrex;
1714 rex = 0;
1715 prefixes = 0;
1716 used_prefixes = 0;
1717 rex_used = 0;
1718 while (1)
1720 FETCH_DATA (the_info, codep + 1);
1721 newrex = 0;
1722 switch (*codep)
1724 /* REX prefixes family. */
1725 case 0x40:
1726 case 0x41:
1727 case 0x42:
1728 case 0x43:
1729 case 0x44:
1730 case 0x45:
1731 case 0x46:
1732 case 0x47:
1733 case 0x48:
1734 case 0x49:
1735 case 0x4a:
1736 case 0x4b:
1737 case 0x4c:
1738 case 0x4d:
1739 case 0x4e:
1740 case 0x4f:
1741 if (mode_64bit)
1742 newrex = *codep;
1743 else
1744 return;
1745 break;
1746 case 0xf3:
1747 prefixes |= PREFIX_REPZ;
1748 break;
1749 case 0xf2:
1750 prefixes |= PREFIX_REPNZ;
1751 break;
1752 case 0xf0:
1753 prefixes |= PREFIX_LOCK;
1754 break;
1755 case 0x2e:
1756 prefixes |= PREFIX_CS;
1757 break;
1758 case 0x36:
1759 prefixes |= PREFIX_SS;
1760 break;
1761 case 0x3e:
1762 prefixes |= PREFIX_DS;
1763 break;
1764 case 0x26:
1765 prefixes |= PREFIX_ES;
1766 break;
1767 case 0x64:
1768 prefixes |= PREFIX_FS;
1769 break;
1770 case 0x65:
1771 prefixes |= PREFIX_GS;
1772 break;
1773 case 0x66:
1774 prefixes |= PREFIX_DATA;
1775 break;
1776 case 0x67:
1777 prefixes |= PREFIX_ADDR;
1778 break;
1779 case FWAIT_OPCODE:
1780 /* fwait is really an instruction. If there are prefixes
1781 before the fwait, they belong to the fwait, *not* to the
1782 following instruction. */
1783 if (prefixes)
1785 prefixes |= PREFIX_FWAIT;
1786 codep++;
1787 return;
1789 prefixes = PREFIX_FWAIT;
1790 break;
1791 default:
1792 return;
1794 /* Rex is ignored when followed by another prefix. */
1795 if (rex)
1797 oappend (prefix_name (rex, 0));
1798 oappend (" ");
1800 rex = newrex;
1801 codep++;
1805 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
1806 prefix byte. */
1808 static const char *
1809 prefix_name (int pref, int sizeflag)
1811 switch (pref)
1813 /* REX prefixes family. */
1814 case 0x40:
1815 return "rex";
1816 case 0x41:
1817 return "rexZ";
1818 case 0x42:
1819 return "rexY";
1820 case 0x43:
1821 return "rexYZ";
1822 case 0x44:
1823 return "rexX";
1824 case 0x45:
1825 return "rexXZ";
1826 case 0x46:
1827 return "rexXY";
1828 case 0x47:
1829 return "rexXYZ";
1830 case 0x48:
1831 return "rex64";
1832 case 0x49:
1833 return "rex64Z";
1834 case 0x4a:
1835 return "rex64Y";
1836 case 0x4b:
1837 return "rex64YZ";
1838 case 0x4c:
1839 return "rex64X";
1840 case 0x4d:
1841 return "rex64XZ";
1842 case 0x4e:
1843 return "rex64XY";
1844 case 0x4f:
1845 return "rex64XYZ";
1846 case 0xf3:
1847 return "repz";
1848 case 0xf2:
1849 return "repnz";
1850 case 0xf0:
1851 return "lock";
1852 case 0x2e:
1853 return "cs";
1854 case 0x36:
1855 return "ss";
1856 case 0x3e:
1857 return "ds";
1858 case 0x26:
1859 return "es";
1860 case 0x64:
1861 return "fs";
1862 case 0x65:
1863 return "gs";
1864 case 0x66:
1865 return (sizeflag & DFLAG) ? "data16" : "data32";
1866 case 0x67:
1867 if (mode_64bit)
1868 return (sizeflag & AFLAG) ? "addr32" : "addr64";
1869 else
1870 return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32";
1871 case FWAIT_OPCODE:
1872 return "fwait";
1873 default:
1874 return NULL;
1878 static char op1out[100], op2out[100], op3out[100];
1879 static int op_ad, op_index[3];
1880 static int two_source_ops;
1881 static bfd_vma op_address[3];
1882 static bfd_vma op_riprel[3];
1883 static bfd_vma start_pc;
1886 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1887 * (see topic "Redundant prefixes" in the "Differences from 8086"
1888 * section of the "Virtual 8086 Mode" chapter.)
1889 * 'pc' should be the address of this instruction, it will
1890 * be used to print the target address if this is a relative jump or call
1891 * The function returns the length of this instruction in bytes.
1894 static char intel_syntax;
1895 static char open_char;
1896 static char close_char;
1897 static char separator_char;
1898 static char scale_char;
1900 /* Here for backwards compatibility. When gdb stops using
1901 print_insn_i386_att and print_insn_i386_intel these functions can
1902 disappear, and print_insn_i386 be merged into print_insn. */
1904 print_insn_i386_att (bfd_vma pc, disassemble_info *info)
1906 intel_syntax = 0;
1908 return print_insn (pc, info);
1912 print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
1914 intel_syntax = 1;
1916 return print_insn (pc, info);
1920 print_insn_i386 (bfd_vma pc, disassemble_info *info)
1922 intel_syntax = -1;
1924 return print_insn (pc, info);
1927 static int
1928 print_insn (bfd_vma pc, disassemble_info *info)
1930 const struct dis386 *dp;
1931 int i;
1932 char *first, *second, *third;
1933 int needcomma;
1934 unsigned char uses_SSE_prefix;
1935 int sizeflag;
1936 const char *p;
1937 struct dis_private priv;
1939 mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
1940 || info->mach == bfd_mach_x86_64);
1942 if (intel_syntax == (char) -1)
1943 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
1944 || info->mach == bfd_mach_x86_64_intel_syntax);
1946 if (info->mach == bfd_mach_i386_i386
1947 || info->mach == bfd_mach_x86_64
1948 || info->mach == bfd_mach_i386_i386_intel_syntax
1949 || info->mach == bfd_mach_x86_64_intel_syntax)
1950 priv.orig_sizeflag = AFLAG | DFLAG;
1951 else if (info->mach == bfd_mach_i386_i8086)
1952 priv.orig_sizeflag = 0;
1953 else
1954 abort ();
1956 for (p = info->disassembler_options; p != NULL; )
1958 if (strncmp (p, "x86-64", 6) == 0)
1960 mode_64bit = 1;
1961 priv.orig_sizeflag = AFLAG | DFLAG;
1963 else if (strncmp (p, "i386", 4) == 0)
1965 mode_64bit = 0;
1966 priv.orig_sizeflag = AFLAG | DFLAG;
1968 else if (strncmp (p, "i8086", 5) == 0)
1970 mode_64bit = 0;
1971 priv.orig_sizeflag = 0;
1973 else if (strncmp (p, "intel", 5) == 0)
1975 intel_syntax = 1;
1977 else if (strncmp (p, "att", 3) == 0)
1979 intel_syntax = 0;
1981 else if (strncmp (p, "addr", 4) == 0)
1983 if (p[4] == '1' && p[5] == '6')
1984 priv.orig_sizeflag &= ~AFLAG;
1985 else if (p[4] == '3' && p[5] == '2')
1986 priv.orig_sizeflag |= AFLAG;
1988 else if (strncmp (p, "data", 4) == 0)
1990 if (p[4] == '1' && p[5] == '6')
1991 priv.orig_sizeflag &= ~DFLAG;
1992 else if (p[4] == '3' && p[5] == '2')
1993 priv.orig_sizeflag |= DFLAG;
1995 else if (strncmp (p, "suffix", 6) == 0)
1996 priv.orig_sizeflag |= SUFFIX_ALWAYS;
1998 p = strchr (p, ',');
1999 if (p != NULL)
2000 p++;
2003 if (intel_syntax)
2005 names64 = intel_names64;
2006 names32 = intel_names32;
2007 names16 = intel_names16;
2008 names8 = intel_names8;
2009 names8rex = intel_names8rex;
2010 names_seg = intel_names_seg;
2011 index16 = intel_index16;
2012 open_char = '[';
2013 close_char = ']';
2014 separator_char = '+';
2015 scale_char = '*';
2017 else
2019 names64 = att_names64;
2020 names32 = att_names32;
2021 names16 = att_names16;
2022 names8 = att_names8;
2023 names8rex = att_names8rex;
2024 names_seg = att_names_seg;
2025 index16 = att_index16;
2026 open_char = '(';
2027 close_char = ')';
2028 separator_char = ',';
2029 scale_char = ',';
2032 /* The output looks better if we put 7 bytes on a line, since that
2033 puts most long word instructions on a single line. */
2034 info->bytes_per_line = 7;
2036 info->private_data = &priv;
2037 priv.max_fetched = priv.the_buffer;
2038 priv.insn_start = pc;
2040 obuf[0] = 0;
2041 op1out[0] = 0;
2042 op2out[0] = 0;
2043 op3out[0] = 0;
2045 op_index[0] = op_index[1] = op_index[2] = -1;
2047 the_info = info;
2048 start_pc = pc;
2049 start_codep = priv.the_buffer;
2050 codep = priv.the_buffer;
2052 if (setjmp (priv.bailout) != 0)
2054 const char *name;
2056 /* Getting here means we tried for data but didn't get it. That
2057 means we have an incomplete instruction of some sort. Just
2058 print the first byte as a prefix or a .byte pseudo-op. */
2059 if (codep > priv.the_buffer)
2061 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2062 if (name != NULL)
2063 (*info->fprintf_func) (info->stream, "%s", name);
2064 else
2066 /* Just print the first byte as a .byte instruction. */
2067 (*info->fprintf_func) (info->stream, ".byte 0x%x",
2068 (unsigned int) priv.the_buffer[0]);
2071 return 1;
2074 return -1;
2077 obufp = obuf;
2078 ckprefix ();
2080 insn_codep = codep;
2081 sizeflag = priv.orig_sizeflag;
2083 FETCH_DATA (info, codep + 1);
2084 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
2086 if ((prefixes & PREFIX_FWAIT)
2087 && ((*codep < 0xd8) || (*codep > 0xdf)))
2089 const char *name;
2091 /* fwait not followed by floating point instruction. Print the
2092 first prefix, which is probably fwait itself. */
2093 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2094 if (name == NULL)
2095 name = INTERNAL_DISASSEMBLER_ERROR;
2096 (*info->fprintf_func) (info->stream, "%s", name);
2097 return 1;
2100 if (*codep == 0x0f)
2102 FETCH_DATA (info, codep + 2);
2103 dp = &dis386_twobyte[*++codep];
2104 need_modrm = twobyte_has_modrm[*codep];
2105 uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
2107 else
2109 dp = &dis386[*codep];
2110 need_modrm = onebyte_has_modrm[*codep];
2111 uses_SSE_prefix = 0;
2113 codep++;
2115 if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
2117 oappend ("repz ");
2118 used_prefixes |= PREFIX_REPZ;
2120 if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
2122 oappend ("repnz ");
2123 used_prefixes |= PREFIX_REPNZ;
2125 if (prefixes & PREFIX_LOCK)
2127 oappend ("lock ");
2128 used_prefixes |= PREFIX_LOCK;
2131 if (prefixes & PREFIX_ADDR)
2133 sizeflag ^= AFLAG;
2134 if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
2136 if ((sizeflag & AFLAG) || mode_64bit)
2137 oappend ("addr32 ");
2138 else
2139 oappend ("addr16 ");
2140 used_prefixes |= PREFIX_ADDR;
2144 if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
2146 sizeflag ^= DFLAG;
2147 if (dp->bytemode3 == cond_jump_mode
2148 && dp->bytemode1 == v_mode
2149 && !intel_syntax)
2151 if (sizeflag & DFLAG)
2152 oappend ("data32 ");
2153 else
2154 oappend ("data16 ");
2155 used_prefixes |= PREFIX_DATA;
2159 if (need_modrm)
2161 FETCH_DATA (info, codep + 1);
2162 mod = (*codep >> 6) & 3;
2163 reg = (*codep >> 3) & 7;
2164 rm = *codep & 7;
2167 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2169 dofloat (sizeflag);
2171 else
2173 int index;
2174 if (dp->name == NULL)
2176 switch (dp->bytemode1)
2178 case USE_GROUPS:
2179 dp = &grps[dp->bytemode2][reg];
2180 break;
2182 case USE_PREFIX_USER_TABLE:
2183 index = 0;
2184 used_prefixes |= (prefixes & PREFIX_REPZ);
2185 if (prefixes & PREFIX_REPZ)
2186 index = 1;
2187 else
2189 used_prefixes |= (prefixes & PREFIX_DATA);
2190 if (prefixes & PREFIX_DATA)
2191 index = 2;
2192 else
2194 used_prefixes |= (prefixes & PREFIX_REPNZ);
2195 if (prefixes & PREFIX_REPNZ)
2196 index = 3;
2199 dp = &prefix_user_table[dp->bytemode2][index];
2200 break;
2202 case X86_64_SPECIAL:
2203 dp = &x86_64_table[dp->bytemode2][mode_64bit];
2204 break;
2206 default:
2207 oappend (INTERNAL_DISASSEMBLER_ERROR);
2208 break;
2212 if (putop (dp->name, sizeflag) == 0)
2214 obufp = op1out;
2215 op_ad = 2;
2216 if (dp->op1)
2217 (*dp->op1) (dp->bytemode1, sizeflag);
2219 obufp = op2out;
2220 op_ad = 1;
2221 if (dp->op2)
2222 (*dp->op2) (dp->bytemode2, sizeflag);
2224 obufp = op3out;
2225 op_ad = 0;
2226 if (dp->op3)
2227 (*dp->op3) (dp->bytemode3, sizeflag);
2231 /* See if any prefixes were not used. If so, print the first one
2232 separately. If we don't do this, we'll wind up printing an
2233 instruction stream which does not precisely correspond to the
2234 bytes we are disassembling. */
2235 if ((prefixes & ~used_prefixes) != 0)
2237 const char *name;
2239 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2240 if (name == NULL)
2241 name = INTERNAL_DISASSEMBLER_ERROR;
2242 (*info->fprintf_func) (info->stream, "%s", name);
2243 return 1;
2245 if (rex & ~rex_used)
2247 const char *name;
2248 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
2249 if (name == NULL)
2250 name = INTERNAL_DISASSEMBLER_ERROR;
2251 (*info->fprintf_func) (info->stream, "%s ", name);
2254 obufp = obuf + strlen (obuf);
2255 for (i = strlen (obuf); i < 6; i++)
2256 oappend (" ");
2257 oappend (" ");
2258 (*info->fprintf_func) (info->stream, "%s", obuf);
2260 /* The enter and bound instructions are printed with operands in the same
2261 order as the intel book; everything else is printed in reverse order. */
2262 if (intel_syntax || two_source_ops)
2264 first = op1out;
2265 second = op2out;
2266 third = op3out;
2267 op_ad = op_index[0];
2268 op_index[0] = op_index[2];
2269 op_index[2] = op_ad;
2271 else
2273 first = op3out;
2274 second = op2out;
2275 third = op1out;
2277 needcomma = 0;
2278 if (*first)
2280 if (op_index[0] != -1 && !op_riprel[0])
2281 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
2282 else
2283 (*info->fprintf_func) (info->stream, "%s", first);
2284 needcomma = 1;
2286 if (*second)
2288 if (needcomma)
2289 (*info->fprintf_func) (info->stream, ",");
2290 if (op_index[1] != -1 && !op_riprel[1])
2291 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
2292 else
2293 (*info->fprintf_func) (info->stream, "%s", second);
2294 needcomma = 1;
2296 if (*third)
2298 if (needcomma)
2299 (*info->fprintf_func) (info->stream, ",");
2300 if (op_index[2] != -1 && !op_riprel[2])
2301 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
2302 else
2303 (*info->fprintf_func) (info->stream, "%s", third);
2305 for (i = 0; i < 3; i++)
2306 if (op_index[i] != -1 && op_riprel[i])
2308 (*info->fprintf_func) (info->stream, " # ");
2309 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
2310 + op_address[op_index[i]]), info);
2312 return codep - priv.the_buffer;
2315 static const char *float_mem[] = {
2316 /* d8 */
2317 "fadd{s||s|}",
2318 "fmul{s||s|}",
2319 "fcom{s||s|}",
2320 "fcomp{s||s|}",
2321 "fsub{s||s|}",
2322 "fsubr{s||s|}",
2323 "fdiv{s||s|}",
2324 "fdivr{s||s|}",
2325 /* d9 */
2326 "fld{s||s|}",
2327 "(bad)",
2328 "fst{s||s|}",
2329 "fstp{s||s|}",
2330 "fldenv",
2331 "fldcw",
2332 "fNstenv",
2333 "fNstcw",
2334 /* da */
2335 "fiadd{l||l|}",
2336 "fimul{l||l|}",
2337 "ficom{l||l|}",
2338 "ficomp{l||l|}",
2339 "fisub{l||l|}",
2340 "fisubr{l||l|}",
2341 "fidiv{l||l|}",
2342 "fidivr{l||l|}",
2343 /* db */
2344 "fild{l||l|}",
2345 "fisttp{l||l|}",
2346 "fist{l||l|}",
2347 "fistp{l||l|}",
2348 "(bad)",
2349 "fld{t||t|}",
2350 "(bad)",
2351 "fstp{t||t|}",
2352 /* dc */
2353 "fadd{l||l|}",
2354 "fmul{l||l|}",
2355 "fcom{l||l|}",
2356 "fcomp{l||l|}",
2357 "fsub{l||l|}",
2358 "fsubr{l||l|}",
2359 "fdiv{l||l|}",
2360 "fdivr{l||l|}",
2361 /* dd */
2362 "fld{l||l|}",
2363 "fisttp{ll||ll|}",
2364 "fst{l||l|}",
2365 "fstp{l||l|}",
2366 "frstor",
2367 "(bad)",
2368 "fNsave",
2369 "fNstsw",
2370 /* de */
2371 "fiadd",
2372 "fimul",
2373 "ficom",
2374 "ficomp",
2375 "fisub",
2376 "fisubr",
2377 "fidiv",
2378 "fidivr",
2379 /* df */
2380 "fild",
2381 "fisttp",
2382 "fist",
2383 "fistp",
2384 "fbld",
2385 "fild{ll||ll|}",
2386 "fbstp",
2387 "fistp{ll||ll|}",
2390 static const unsigned char float_mem_mode[] = {
2391 /* d8 */
2392 d_mode,
2393 d_mode,
2394 d_mode,
2395 d_mode,
2396 d_mode,
2397 d_mode,
2398 d_mode,
2399 d_mode,
2400 /* d9 */
2401 d_mode,
2403 d_mode,
2404 d_mode,
2406 w_mode,
2408 w_mode,
2409 /* da */
2410 d_mode,
2411 d_mode,
2412 d_mode,
2413 d_mode,
2414 d_mode,
2415 d_mode,
2416 d_mode,
2417 d_mode,
2418 /* db */
2419 d_mode,
2420 d_mode,
2421 d_mode,
2422 d_mode,
2424 x_mode,
2426 x_mode,
2427 /* dc */
2428 q_mode,
2429 q_mode,
2430 q_mode,
2431 q_mode,
2432 q_mode,
2433 q_mode,
2434 q_mode,
2435 q_mode,
2436 /* dd */
2437 q_mode,
2438 q_mode,
2439 q_mode,
2440 q_mode,
2444 w_mode,
2445 /* de */
2446 w_mode,
2447 w_mode,
2448 w_mode,
2449 w_mode,
2450 w_mode,
2451 w_mode,
2452 w_mode,
2453 w_mode,
2454 /* df */
2455 w_mode,
2456 w_mode,
2457 w_mode,
2458 w_mode,
2459 x_mode,
2460 q_mode,
2461 x_mode,
2462 q_mode
2465 #define ST OP_ST, 0
2466 #define STi OP_STi, 0
2468 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
2469 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
2470 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
2471 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
2472 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
2473 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
2474 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
2475 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
2476 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
2478 static const struct dis386 float_reg[][8] = {
2479 /* d8 */
2481 { "fadd", ST, STi, XX },
2482 { "fmul", ST, STi, XX },
2483 { "fcom", STi, XX, XX },
2484 { "fcomp", STi, XX, XX },
2485 { "fsub", ST, STi, XX },
2486 { "fsubr", ST, STi, XX },
2487 { "fdiv", ST, STi, XX },
2488 { "fdivr", ST, STi, XX },
2490 /* d9 */
2492 { "fld", STi, XX, XX },
2493 { "fxch", STi, XX, XX },
2494 { FGRPd9_2 },
2495 { "(bad)", XX, XX, XX },
2496 { FGRPd9_4 },
2497 { FGRPd9_5 },
2498 { FGRPd9_6 },
2499 { FGRPd9_7 },
2501 /* da */
2503 { "fcmovb", ST, STi, XX },
2504 { "fcmove", ST, STi, XX },
2505 { "fcmovbe",ST, STi, XX },
2506 { "fcmovu", ST, STi, XX },
2507 { "(bad)", XX, XX, XX },
2508 { FGRPda_5 },
2509 { "(bad)", XX, XX, XX },
2510 { "(bad)", XX, XX, XX },
2512 /* db */
2514 { "fcmovnb",ST, STi, XX },
2515 { "fcmovne",ST, STi, XX },
2516 { "fcmovnbe",ST, STi, XX },
2517 { "fcmovnu",ST, STi, XX },
2518 { FGRPdb_4 },
2519 { "fucomi", ST, STi, XX },
2520 { "fcomi", ST, STi, XX },
2521 { "(bad)", XX, XX, XX },
2523 /* dc */
2525 { "fadd", STi, ST, XX },
2526 { "fmul", STi, ST, XX },
2527 { "(bad)", XX, XX, XX },
2528 { "(bad)", XX, XX, XX },
2529 #if UNIXWARE_COMPAT
2530 { "fsub", STi, ST, XX },
2531 { "fsubr", STi, ST, XX },
2532 { "fdiv", STi, ST, XX },
2533 { "fdivr", STi, ST, XX },
2534 #else
2535 { "fsubr", STi, ST, XX },
2536 { "fsub", STi, ST, XX },
2537 { "fdivr", STi, ST, XX },
2538 { "fdiv", STi, ST, XX },
2539 #endif
2541 /* dd */
2543 { "ffree", STi, XX, XX },
2544 { "(bad)", XX, XX, XX },
2545 { "fst", STi, XX, XX },
2546 { "fstp", STi, XX, XX },
2547 { "fucom", STi, XX, XX },
2548 { "fucomp", STi, XX, XX },
2549 { "(bad)", XX, XX, XX },
2550 { "(bad)", XX, XX, XX },
2552 /* de */
2554 { "faddp", STi, ST, XX },
2555 { "fmulp", STi, ST, XX },
2556 { "(bad)", XX, XX, XX },
2557 { FGRPde_3 },
2558 #if UNIXWARE_COMPAT
2559 { "fsubp", STi, ST, XX },
2560 { "fsubrp", STi, ST, XX },
2561 { "fdivp", STi, ST, XX },
2562 { "fdivrp", STi, ST, XX },
2563 #else
2564 { "fsubrp", STi, ST, XX },
2565 { "fsubp", STi, ST, XX },
2566 { "fdivrp", STi, ST, XX },
2567 { "fdivp", STi, ST, XX },
2568 #endif
2570 /* df */
2572 { "ffreep", STi, XX, XX },
2573 { "(bad)", XX, XX, XX },
2574 { "(bad)", XX, XX, XX },
2575 { "(bad)", XX, XX, XX },
2576 { FGRPdf_4 },
2577 { "fucomip",ST, STi, XX },
2578 { "fcomip", ST, STi, XX },
2579 { "(bad)", XX, XX, XX },
2583 static char *fgrps[][8] = {
2584 /* d9_2 0 */
2586 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2589 /* d9_4 1 */
2591 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2594 /* d9_5 2 */
2596 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2599 /* d9_6 3 */
2601 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2604 /* d9_7 4 */
2606 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2609 /* da_5 5 */
2611 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2614 /* db_4 6 */
2616 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2617 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2620 /* de_3 7 */
2622 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2625 /* df_4 8 */
2627 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2631 static void
2632 dofloat (int sizeflag)
2634 const struct dis386 *dp;
2635 unsigned char floatop;
2637 floatop = codep[-1];
2639 if (mod != 3)
2641 int fp_indx = (floatop - 0xd8) * 8 + reg;
2643 putop (float_mem[fp_indx], sizeflag);
2644 obufp = op1out;
2645 OP_E (float_mem_mode[fp_indx], sizeflag);
2646 return;
2648 /* Skip mod/rm byte. */
2649 MODRM_CHECK;
2650 codep++;
2652 dp = &float_reg[floatop - 0xd8][reg];
2653 if (dp->name == NULL)
2655 putop (fgrps[dp->bytemode1][rm], sizeflag);
2657 /* Instruction fnstsw is only one with strange arg. */
2658 if (floatop == 0xdf && codep[-1] == 0xe0)
2659 strcpy (op1out, names16[0]);
2661 else
2663 putop (dp->name, sizeflag);
2665 obufp = op1out;
2666 if (dp->op1)
2667 (*dp->op1) (dp->bytemode1, sizeflag);
2668 obufp = op2out;
2669 if (dp->op2)
2670 (*dp->op2) (dp->bytemode2, sizeflag);
2674 static void
2675 OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
2677 oappend ("%st");
2680 static void
2681 OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
2683 sprintf (scratchbuf, "%%st(%d)", rm);
2684 oappend (scratchbuf + intel_syntax);
2687 /* Capital letters in template are macros. */
2688 static int
2689 putop (const char *template, int sizeflag)
2691 const char *p;
2692 int alt;
2694 for (p = template; *p; p++)
2696 switch (*p)
2698 default:
2699 *obufp++ = *p;
2700 break;
2701 case '{':
2702 alt = 0;
2703 if (intel_syntax)
2704 alt += 1;
2705 if (mode_64bit)
2706 alt += 2;
2707 while (alt != 0)
2709 while (*++p != '|')
2711 if (*p == '}')
2713 /* Alternative not valid. */
2714 strcpy (obuf, "(bad)");
2715 obufp = obuf + 5;
2716 return 1;
2718 else if (*p == '\0')
2719 abort ();
2721 alt--;
2723 break;
2724 case '|':
2725 while (*++p != '}')
2727 if (*p == '\0')
2728 abort ();
2730 break;
2731 case '}':
2732 break;
2733 case 'A':
2734 if (intel_syntax)
2735 break;
2736 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2737 *obufp++ = 'b';
2738 break;
2739 case 'B':
2740 if (intel_syntax)
2741 break;
2742 if (sizeflag & SUFFIX_ALWAYS)
2743 *obufp++ = 'b';
2744 break;
2745 case 'E': /* For jcxz/jecxz */
2746 if (mode_64bit)
2748 if (sizeflag & AFLAG)
2749 *obufp++ = 'r';
2750 else
2751 *obufp++ = 'e';
2753 else
2754 if (sizeflag & AFLAG)
2755 *obufp++ = 'e';
2756 used_prefixes |= (prefixes & PREFIX_ADDR);
2757 break;
2758 case 'F':
2759 if (intel_syntax)
2760 break;
2761 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
2763 if (sizeflag & AFLAG)
2764 *obufp++ = mode_64bit ? 'q' : 'l';
2765 else
2766 *obufp++ = mode_64bit ? 'l' : 'w';
2767 used_prefixes |= (prefixes & PREFIX_ADDR);
2769 break;
2770 case 'H':
2771 if (intel_syntax)
2772 break;
2773 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
2774 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
2776 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
2777 *obufp++ = ',';
2778 *obufp++ = 'p';
2779 if (prefixes & PREFIX_DS)
2780 *obufp++ = 't';
2781 else
2782 *obufp++ = 'n';
2784 break;
2785 case 'L':
2786 if (intel_syntax)
2787 break;
2788 if (sizeflag & SUFFIX_ALWAYS)
2789 *obufp++ = 'l';
2790 break;
2791 case 'N':
2792 if ((prefixes & PREFIX_FWAIT) == 0)
2793 *obufp++ = 'n';
2794 else
2795 used_prefixes |= PREFIX_FWAIT;
2796 break;
2797 case 'O':
2798 USED_REX (REX_MODE64);
2799 if (rex & REX_MODE64)
2800 *obufp++ = 'o';
2801 else
2802 *obufp++ = 'd';
2803 break;
2804 case 'T':
2805 if (intel_syntax)
2806 break;
2807 if (mode_64bit)
2809 *obufp++ = 'q';
2810 break;
2812 /* Fall through. */
2813 case 'P':
2814 if (intel_syntax)
2815 break;
2816 if ((prefixes & PREFIX_DATA)
2817 || (rex & REX_MODE64)
2818 || (sizeflag & SUFFIX_ALWAYS))
2820 USED_REX (REX_MODE64);
2821 if (rex & REX_MODE64)
2822 *obufp++ = 'q';
2823 else
2825 if (sizeflag & DFLAG)
2826 *obufp++ = 'l';
2827 else
2828 *obufp++ = 'w';
2829 used_prefixes |= (prefixes & PREFIX_DATA);
2832 break;
2833 case 'U':
2834 if (intel_syntax)
2835 break;
2836 if (mode_64bit)
2838 *obufp++ = 'q';
2839 break;
2841 /* Fall through. */
2842 case 'Q':
2843 if (intel_syntax)
2844 break;
2845 USED_REX (REX_MODE64);
2846 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2848 if (rex & REX_MODE64)
2849 *obufp++ = 'q';
2850 else
2852 if (sizeflag & DFLAG)
2853 *obufp++ = 'l';
2854 else
2855 *obufp++ = 'w';
2856 used_prefixes |= (prefixes & PREFIX_DATA);
2859 break;
2860 case 'R':
2861 USED_REX (REX_MODE64);
2862 if (intel_syntax)
2864 if (rex & REX_MODE64)
2866 *obufp++ = 'q';
2867 *obufp++ = 't';
2869 else if (sizeflag & DFLAG)
2871 *obufp++ = 'd';
2872 *obufp++ = 'q';
2874 else
2876 *obufp++ = 'w';
2877 *obufp++ = 'd';
2880 else
2882 if (rex & REX_MODE64)
2883 *obufp++ = 'q';
2884 else if (sizeflag & DFLAG)
2885 *obufp++ = 'l';
2886 else
2887 *obufp++ = 'w';
2889 if (!(rex & REX_MODE64))
2890 used_prefixes |= (prefixes & PREFIX_DATA);
2891 break;
2892 case 'S':
2893 if (intel_syntax)
2894 break;
2895 if (sizeflag & SUFFIX_ALWAYS)
2897 if (rex & REX_MODE64)
2898 *obufp++ = 'q';
2899 else
2901 if (sizeflag & DFLAG)
2902 *obufp++ = 'l';
2903 else
2904 *obufp++ = 'w';
2905 used_prefixes |= (prefixes & PREFIX_DATA);
2908 break;
2909 case 'X':
2910 if (prefixes & PREFIX_DATA)
2911 *obufp++ = 'd';
2912 else
2913 *obufp++ = 's';
2914 used_prefixes |= (prefixes & PREFIX_DATA);
2915 break;
2916 case 'Y':
2917 if (intel_syntax)
2918 break;
2919 if (rex & REX_MODE64)
2921 USED_REX (REX_MODE64);
2922 *obufp++ = 'q';
2924 break;
2925 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
2926 case 'W':
2927 /* operand size flag for cwtl, cbtw */
2928 USED_REX (0);
2929 if (rex)
2930 *obufp++ = 'l';
2931 else if (sizeflag & DFLAG)
2932 *obufp++ = 'w';
2933 else
2934 *obufp++ = 'b';
2935 if (intel_syntax)
2937 if (rex)
2939 *obufp++ = 'q';
2940 *obufp++ = 'e';
2942 if (sizeflag & DFLAG)
2944 *obufp++ = 'd';
2945 *obufp++ = 'e';
2947 else
2949 *obufp++ = 'w';
2952 if (!rex)
2953 used_prefixes |= (prefixes & PREFIX_DATA);
2954 break;
2957 *obufp = 0;
2958 return 0;
2961 static void
2962 oappend (const char *s)
2964 strcpy (obufp, s);
2965 obufp += strlen (s);
2968 static void
2969 append_seg (void)
2971 if (prefixes & PREFIX_CS)
2973 used_prefixes |= PREFIX_CS;
2974 oappend ("%cs:" + intel_syntax);
2976 if (prefixes & PREFIX_DS)
2978 used_prefixes |= PREFIX_DS;
2979 oappend ("%ds:" + intel_syntax);
2981 if (prefixes & PREFIX_SS)
2983 used_prefixes |= PREFIX_SS;
2984 oappend ("%ss:" + intel_syntax);
2986 if (prefixes & PREFIX_ES)
2988 used_prefixes |= PREFIX_ES;
2989 oappend ("%es:" + intel_syntax);
2991 if (prefixes & PREFIX_FS)
2993 used_prefixes |= PREFIX_FS;
2994 oappend ("%fs:" + intel_syntax);
2996 if (prefixes & PREFIX_GS)
2998 used_prefixes |= PREFIX_GS;
2999 oappend ("%gs:" + intel_syntax);
3003 static void
3004 OP_indirE (int bytemode, int sizeflag)
3006 if (!intel_syntax)
3007 oappend ("*");
3008 OP_E (bytemode, sizeflag);
3011 static void
3012 print_operand_value (char *buf, int hex, bfd_vma disp)
3014 if (mode_64bit)
3016 if (hex)
3018 char tmp[30];
3019 int i;
3020 buf[0] = '0';
3021 buf[1] = 'x';
3022 sprintf_vma (tmp, disp);
3023 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
3024 strcpy (buf + 2, tmp + i);
3026 else
3028 bfd_signed_vma v = disp;
3029 char tmp[30];
3030 int i;
3031 if (v < 0)
3033 *(buf++) = '-';
3034 v = -disp;
3035 /* Check for possible overflow on 0x8000000000000000. */
3036 if (v < 0)
3038 strcpy (buf, "9223372036854775808");
3039 return;
3042 if (!v)
3044 strcpy (buf, "0");
3045 return;
3048 i = 0;
3049 tmp[29] = 0;
3050 while (v)
3052 tmp[28 - i] = (v % 10) + '0';
3053 v /= 10;
3054 i++;
3056 strcpy (buf, tmp + 29 - i);
3059 else
3061 if (hex)
3062 sprintf (buf, "0x%x", (unsigned int) disp);
3063 else
3064 sprintf (buf, "%d", (int) disp);
3068 static void
3069 OP_E (int bytemode, int sizeflag)
3071 bfd_vma disp;
3072 int add = 0;
3073 int riprel = 0;
3074 USED_REX (REX_EXTZ);
3075 if (rex & REX_EXTZ)
3076 add += 8;
3078 /* Skip mod/rm byte. */
3079 MODRM_CHECK;
3080 codep++;
3082 if (mod == 3)
3084 switch (bytemode)
3086 case b_mode:
3087 USED_REX (0);
3088 if (rex)
3089 oappend (names8rex[rm + add]);
3090 else
3091 oappend (names8[rm + add]);
3092 break;
3093 case w_mode:
3094 oappend (names16[rm + add]);
3095 break;
3096 case d_mode:
3097 oappend (names32[rm + add]);
3098 break;
3099 case q_mode:
3100 oappend (names64[rm + add]);
3101 break;
3102 case m_mode:
3103 if (mode_64bit)
3104 oappend (names64[rm + add]);
3105 else
3106 oappend (names32[rm + add]);
3107 break;
3108 case v_mode:
3109 case dq_mode:
3110 USED_REX (REX_MODE64);
3111 if (rex & REX_MODE64)
3112 oappend (names64[rm + add]);
3113 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
3114 oappend (names32[rm + add]);
3115 else
3116 oappend (names16[rm + add]);
3117 used_prefixes |= (prefixes & PREFIX_DATA);
3118 break;
3119 case 0:
3120 break;
3121 default:
3122 oappend (INTERNAL_DISASSEMBLER_ERROR);
3123 break;
3125 return;
3128 disp = 0;
3129 append_seg ();
3131 if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
3133 int havesib;
3134 int havebase;
3135 int base;
3136 int index = 0;
3137 int scale = 0;
3139 havesib = 0;
3140 havebase = 1;
3141 base = rm;
3143 if (base == 4)
3145 havesib = 1;
3146 FETCH_DATA (the_info, codep + 1);
3147 scale = (*codep >> 6) & 3;
3148 index = (*codep >> 3) & 7;
3149 base = *codep & 7;
3150 USED_REX (REX_EXTY);
3151 USED_REX (REX_EXTZ);
3152 if (rex & REX_EXTY)
3153 index += 8;
3154 if (rex & REX_EXTZ)
3155 base += 8;
3156 codep++;
3159 switch (mod)
3161 case 0:
3162 if ((base & 7) == 5)
3164 havebase = 0;
3165 if (mode_64bit && !havesib)
3166 riprel = 1;
3167 disp = get32s ();
3169 break;
3170 case 1:
3171 FETCH_DATA (the_info, codep + 1);
3172 disp = *codep++;
3173 if ((disp & 0x80) != 0)
3174 disp -= 0x100;
3175 break;
3176 case 2:
3177 disp = get32s ();
3178 break;
3181 if (!intel_syntax)
3182 if (mod != 0 || (base & 7) == 5)
3184 print_operand_value (scratchbuf, !riprel, disp);
3185 oappend (scratchbuf);
3186 if (riprel)
3188 set_op (disp, 1);
3189 oappend ("(%rip)");
3193 if (havebase || (havesib && (index != 4 || scale != 0)))
3195 if (intel_syntax)
3197 switch (bytemode)
3199 case b_mode:
3200 oappend ("BYTE PTR ");
3201 break;
3202 case w_mode:
3203 oappend ("WORD PTR ");
3204 break;
3205 case v_mode:
3206 if (sizeflag & DFLAG)
3207 oappend ("DWORD PTR ");
3208 else
3209 oappend ("WORD PTR ");
3210 break;
3211 case d_mode:
3212 oappend ("DWORD PTR ");
3213 break;
3214 case q_mode:
3215 oappend ("QWORD PTR ");
3216 break;
3217 case m_mode:
3218 if (mode_64bit)
3219 oappend ("DWORD PTR ");
3220 else
3221 oappend ("QWORD PTR ");
3222 break;
3223 case x_mode:
3224 oappend ("XWORD PTR ");
3225 break;
3226 default:
3227 break;
3230 *obufp++ = open_char;
3231 if (intel_syntax && riprel)
3232 oappend ("rip + ");
3233 *obufp = '\0';
3234 USED_REX (REX_EXTZ);
3235 if (!havesib && (rex & REX_EXTZ))
3236 base += 8;
3237 if (havebase)
3238 oappend (mode_64bit && (sizeflag & AFLAG)
3239 ? names64[base] : names32[base]);
3240 if (havesib)
3242 if (index != 4)
3244 if (intel_syntax)
3246 if (havebase)
3248 *obufp++ = separator_char;
3249 *obufp = '\0';
3251 sprintf (scratchbuf, "%s",
3252 mode_64bit && (sizeflag & AFLAG)
3253 ? names64[index] : names32[index]);
3255 else
3256 sprintf (scratchbuf, ",%s",
3257 mode_64bit && (sizeflag & AFLAG)
3258 ? names64[index] : names32[index]);
3259 oappend (scratchbuf);
3261 if (scale != 0 || (!intel_syntax && index != 4))
3263 *obufp++ = scale_char;
3264 *obufp = '\0';
3265 sprintf (scratchbuf, "%d", 1 << scale);
3266 oappend (scratchbuf);
3269 if (intel_syntax)
3270 if (mod != 0 || (base & 7) == 5)
3272 /* Don't print zero displacements. */
3273 if (disp != 0)
3275 if ((bfd_signed_vma) disp > 0)
3277 *obufp++ = '+';
3278 *obufp = '\0';
3281 print_operand_value (scratchbuf, 0, disp);
3282 oappend (scratchbuf);
3286 *obufp++ = close_char;
3287 *obufp = '\0';
3289 else if (intel_syntax)
3291 if (mod != 0 || (base & 7) == 5)
3293 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3294 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
3296 else
3298 oappend (names_seg[ds_reg - es_reg]);
3299 oappend (":");
3301 print_operand_value (scratchbuf, 1, disp);
3302 oappend (scratchbuf);
3306 else
3307 { /* 16 bit address mode */
3308 switch (mod)
3310 case 0:
3311 if ((rm & 7) == 6)
3313 disp = get16 ();
3314 if ((disp & 0x8000) != 0)
3315 disp -= 0x10000;
3317 break;
3318 case 1:
3319 FETCH_DATA (the_info, codep + 1);
3320 disp = *codep++;
3321 if ((disp & 0x80) != 0)
3322 disp -= 0x100;
3323 break;
3324 case 2:
3325 disp = get16 ();
3326 if ((disp & 0x8000) != 0)
3327 disp -= 0x10000;
3328 break;
3331 if (!intel_syntax)
3332 if (mod != 0 || (rm & 7) == 6)
3334 print_operand_value (scratchbuf, 0, disp);
3335 oappend (scratchbuf);
3338 if (mod != 0 || (rm & 7) != 6)
3340 *obufp++ = open_char;
3341 *obufp = '\0';
3342 oappend (index16[rm + add]);
3343 *obufp++ = close_char;
3344 *obufp = '\0';
3349 static void
3350 OP_G (int bytemode, int sizeflag)
3352 int add = 0;
3353 USED_REX (REX_EXTX);
3354 if (rex & REX_EXTX)
3355 add += 8;
3356 switch (bytemode)
3358 case b_mode:
3359 USED_REX (0);
3360 if (rex)
3361 oappend (names8rex[reg + add]);
3362 else
3363 oappend (names8[reg + add]);
3364 break;
3365 case w_mode:
3366 oappend (names16[reg + add]);
3367 break;
3368 case d_mode:
3369 oappend (names32[reg + add]);
3370 break;
3371 case q_mode:
3372 oappend (names64[reg + add]);
3373 break;
3374 case v_mode:
3375 USED_REX (REX_MODE64);
3376 if (rex & REX_MODE64)
3377 oappend (names64[reg + add]);
3378 else if (sizeflag & DFLAG)
3379 oappend (names32[reg + add]);
3380 else
3381 oappend (names16[reg + add]);
3382 used_prefixes |= (prefixes & PREFIX_DATA);
3383 break;
3384 default:
3385 oappend (INTERNAL_DISASSEMBLER_ERROR);
3386 break;
3390 static bfd_vma
3391 get64 (void)
3393 bfd_vma x;
3394 #ifdef BFD64
3395 unsigned int a;
3396 unsigned int b;
3398 FETCH_DATA (the_info, codep + 8);
3399 a = *codep++ & 0xff;
3400 a |= (*codep++ & 0xff) << 8;
3401 a |= (*codep++ & 0xff) << 16;
3402 a |= (*codep++ & 0xff) << 24;
3403 b = *codep++ & 0xff;
3404 b |= (*codep++ & 0xff) << 8;
3405 b |= (*codep++ & 0xff) << 16;
3406 b |= (*codep++ & 0xff) << 24;
3407 x = a + ((bfd_vma) b << 32);
3408 #else
3409 abort ();
3410 x = 0;
3411 #endif
3412 return x;
3415 static bfd_signed_vma
3416 get32 (void)
3418 bfd_signed_vma x = 0;
3420 FETCH_DATA (the_info, codep + 4);
3421 x = *codep++ & (bfd_signed_vma) 0xff;
3422 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3423 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3424 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3425 return x;
3428 static bfd_signed_vma
3429 get32s (void)
3431 bfd_signed_vma x = 0;
3433 FETCH_DATA (the_info, codep + 4);
3434 x = *codep++ & (bfd_signed_vma) 0xff;
3435 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3436 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3437 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3439 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
3441 return x;
3444 static int
3445 get16 (void)
3447 int x = 0;
3449 FETCH_DATA (the_info, codep + 2);
3450 x = *codep++ & 0xff;
3451 x |= (*codep++ & 0xff) << 8;
3452 return x;
3455 static void
3456 set_op (bfd_vma op, int riprel)
3458 op_index[op_ad] = op_ad;
3459 if (mode_64bit)
3461 op_address[op_ad] = op;
3462 op_riprel[op_ad] = riprel;
3464 else
3466 /* Mask to get a 32-bit address. */
3467 op_address[op_ad] = op & 0xffffffff;
3468 op_riprel[op_ad] = riprel & 0xffffffff;
3472 static void
3473 OP_REG (int code, int sizeflag)
3475 const char *s;
3476 int add = 0;
3477 USED_REX (REX_EXTZ);
3478 if (rex & REX_EXTZ)
3479 add = 8;
3481 switch (code)
3483 case indir_dx_reg:
3484 if (intel_syntax)
3485 s = "[dx]";
3486 else
3487 s = "(%dx)";
3488 break;
3489 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3490 case sp_reg: case bp_reg: case si_reg: case di_reg:
3491 s = names16[code - ax_reg + add];
3492 break;
3493 case es_reg: case ss_reg: case cs_reg:
3494 case ds_reg: case fs_reg: case gs_reg:
3495 s = names_seg[code - es_reg + add];
3496 break;
3497 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3498 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3499 USED_REX (0);
3500 if (rex)
3501 s = names8rex[code - al_reg + add];
3502 else
3503 s = names8[code - al_reg];
3504 break;
3505 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
3506 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
3507 if (mode_64bit)
3509 s = names64[code - rAX_reg + add];
3510 break;
3512 code += eAX_reg - rAX_reg;
3513 /* Fall through. */
3514 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3515 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3516 USED_REX (REX_MODE64);
3517 if (rex & REX_MODE64)
3518 s = names64[code - eAX_reg + add];
3519 else if (sizeflag & DFLAG)
3520 s = names32[code - eAX_reg + add];
3521 else
3522 s = names16[code - eAX_reg + add];
3523 used_prefixes |= (prefixes & PREFIX_DATA);
3524 break;
3525 default:
3526 s = INTERNAL_DISASSEMBLER_ERROR;
3527 break;
3529 oappend (s);
3532 static void
3533 OP_IMREG (int code, int sizeflag)
3535 const char *s;
3537 switch (code)
3539 case indir_dx_reg:
3540 if (intel_syntax)
3541 s = "[dx]";
3542 else
3543 s = "(%dx)";
3544 break;
3545 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3546 case sp_reg: case bp_reg: case si_reg: case di_reg:
3547 s = names16[code - ax_reg];
3548 break;
3549 case es_reg: case ss_reg: case cs_reg:
3550 case ds_reg: case fs_reg: case gs_reg:
3551 s = names_seg[code - es_reg];
3552 break;
3553 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3554 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3555 USED_REX (0);
3556 if (rex)
3557 s = names8rex[code - al_reg];
3558 else
3559 s = names8[code - al_reg];
3560 break;
3561 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3562 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3563 USED_REX (REX_MODE64);
3564 if (rex & REX_MODE64)
3565 s = names64[code - eAX_reg];
3566 else if (sizeflag & DFLAG)
3567 s = names32[code - eAX_reg];
3568 else
3569 s = names16[code - eAX_reg];
3570 used_prefixes |= (prefixes & PREFIX_DATA);
3571 break;
3572 default:
3573 s = INTERNAL_DISASSEMBLER_ERROR;
3574 break;
3576 oappend (s);
3579 static void
3580 OP_I (int bytemode, int sizeflag)
3582 bfd_signed_vma op;
3583 bfd_signed_vma mask = -1;
3585 switch (bytemode)
3587 case b_mode:
3588 FETCH_DATA (the_info, codep + 1);
3589 op = *codep++;
3590 mask = 0xff;
3591 break;
3592 case q_mode:
3593 if (mode_64bit)
3595 op = get32s ();
3596 break;
3598 /* Fall through. */
3599 case v_mode:
3600 USED_REX (REX_MODE64);
3601 if (rex & REX_MODE64)
3602 op = get32s ();
3603 else if (sizeflag & DFLAG)
3605 op = get32 ();
3606 mask = 0xffffffff;
3608 else
3610 op = get16 ();
3611 mask = 0xfffff;
3613 used_prefixes |= (prefixes & PREFIX_DATA);
3614 break;
3615 case w_mode:
3616 mask = 0xfffff;
3617 op = get16 ();
3618 break;
3619 default:
3620 oappend (INTERNAL_DISASSEMBLER_ERROR);
3621 return;
3624 op &= mask;
3625 scratchbuf[0] = '$';
3626 print_operand_value (scratchbuf + 1, 1, op);
3627 oappend (scratchbuf + intel_syntax);
3628 scratchbuf[0] = '\0';
3631 static void
3632 OP_I64 (int bytemode, int sizeflag)
3634 bfd_signed_vma op;
3635 bfd_signed_vma mask = -1;
3637 if (!mode_64bit)
3639 OP_I (bytemode, sizeflag);
3640 return;
3643 switch (bytemode)
3645 case b_mode:
3646 FETCH_DATA (the_info, codep + 1);
3647 op = *codep++;
3648 mask = 0xff;
3649 break;
3650 case v_mode:
3651 USED_REX (REX_MODE64);
3652 if (rex & REX_MODE64)
3653 op = get64 ();
3654 else if (sizeflag & DFLAG)
3656 op = get32 ();
3657 mask = 0xffffffff;
3659 else
3661 op = get16 ();
3662 mask = 0xfffff;
3664 used_prefixes |= (prefixes & PREFIX_DATA);
3665 break;
3666 case w_mode:
3667 mask = 0xfffff;
3668 op = get16 ();
3669 break;
3670 default:
3671 oappend (INTERNAL_DISASSEMBLER_ERROR);
3672 return;
3675 op &= mask;
3676 scratchbuf[0] = '$';
3677 print_operand_value (scratchbuf + 1, 1, op);
3678 oappend (scratchbuf + intel_syntax);
3679 scratchbuf[0] = '\0';
3682 static void
3683 OP_sI (int bytemode, int sizeflag)
3685 bfd_signed_vma op;
3686 bfd_signed_vma mask = -1;
3688 switch (bytemode)
3690 case b_mode:
3691 FETCH_DATA (the_info, codep + 1);
3692 op = *codep++;
3693 if ((op & 0x80) != 0)
3694 op -= 0x100;
3695 mask = 0xffffffff;
3696 break;
3697 case v_mode:
3698 USED_REX (REX_MODE64);
3699 if (rex & REX_MODE64)
3700 op = get32s ();
3701 else if (sizeflag & DFLAG)
3703 op = get32s ();
3704 mask = 0xffffffff;
3706 else
3708 mask = 0xffffffff;
3709 op = get16 ();
3710 if ((op & 0x8000) != 0)
3711 op -= 0x10000;
3713 used_prefixes |= (prefixes & PREFIX_DATA);
3714 break;
3715 case w_mode:
3716 op = get16 ();
3717 mask = 0xffffffff;
3718 if ((op & 0x8000) != 0)
3719 op -= 0x10000;
3720 break;
3721 default:
3722 oappend (INTERNAL_DISASSEMBLER_ERROR);
3723 return;
3726 scratchbuf[0] = '$';
3727 print_operand_value (scratchbuf + 1, 1, op);
3728 oappend (scratchbuf + intel_syntax);
3731 static void
3732 OP_J (int bytemode, int sizeflag)
3734 bfd_vma disp;
3735 bfd_vma mask = -1;
3737 switch (bytemode)
3739 case b_mode:
3740 FETCH_DATA (the_info, codep + 1);
3741 disp = *codep++;
3742 if ((disp & 0x80) != 0)
3743 disp -= 0x100;
3744 break;
3745 case v_mode:
3746 if (sizeflag & DFLAG)
3747 disp = get32s ();
3748 else
3750 disp = get16 ();
3751 /* For some reason, a data16 prefix on a jump instruction
3752 means that the pc is masked to 16 bits after the
3753 displacement is added! */
3754 mask = 0xffff;
3756 break;
3757 default:
3758 oappend (INTERNAL_DISASSEMBLER_ERROR);
3759 return;
3761 disp = (start_pc + codep - start_codep + disp) & mask;
3762 set_op (disp, 0);
3763 print_operand_value (scratchbuf, 1, disp);
3764 oappend (scratchbuf);
3767 static void
3768 OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3770 oappend (names_seg[reg]);
3773 static void
3774 OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
3776 int seg, offset;
3778 if (sizeflag & DFLAG)
3780 offset = get32 ();
3781 seg = get16 ();
3783 else
3785 offset = get16 ();
3786 seg = get16 ();
3788 used_prefixes |= (prefixes & PREFIX_DATA);
3789 if (intel_syntax)
3790 sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
3791 else
3792 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3793 oappend (scratchbuf);
3796 static void
3797 OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag)
3799 bfd_vma off;
3801 append_seg ();
3803 if ((sizeflag & AFLAG) || mode_64bit)
3804 off = get32 ();
3805 else
3806 off = get16 ();
3808 if (intel_syntax)
3810 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3811 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3813 oappend (names_seg[ds_reg - es_reg]);
3814 oappend (":");
3817 print_operand_value (scratchbuf, 1, off);
3818 oappend (scratchbuf);
3821 static void
3822 OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3824 bfd_vma off;
3826 if (!mode_64bit)
3828 OP_OFF (bytemode, sizeflag);
3829 return;
3832 append_seg ();
3834 off = get64 ();
3836 if (intel_syntax)
3838 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3839 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3841 oappend (names_seg[ds_reg - es_reg]);
3842 oappend (":");
3845 print_operand_value (scratchbuf, 1, off);
3846 oappend (scratchbuf);
3849 static void
3850 ptr_reg (int code, int sizeflag)
3852 const char *s;
3854 *obufp++ = open_char;
3855 used_prefixes |= (prefixes & PREFIX_ADDR);
3856 if (mode_64bit)
3858 if (!(sizeflag & AFLAG))
3859 s = names32[code - eAX_reg];
3860 else
3861 s = names64[code - eAX_reg];
3863 else if (sizeflag & AFLAG)
3864 s = names32[code - eAX_reg];
3865 else
3866 s = names16[code - eAX_reg];
3867 oappend (s);
3868 *obufp++ = close_char;
3869 *obufp = 0;
3872 static void
3873 OP_ESreg (int code, int sizeflag)
3875 oappend ("%es:" + intel_syntax);
3876 ptr_reg (code, sizeflag);
3879 static void
3880 OP_DSreg (int code, int sizeflag)
3882 if ((prefixes
3883 & (PREFIX_CS
3884 | PREFIX_DS
3885 | PREFIX_SS
3886 | PREFIX_ES
3887 | PREFIX_FS
3888 | PREFIX_GS)) == 0)
3889 prefixes |= PREFIX_DS;
3890 append_seg ();
3891 ptr_reg (code, sizeflag);
3894 static void
3895 OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3897 int add = 0;
3898 USED_REX (REX_EXTX);
3899 if (rex & REX_EXTX)
3900 add = 8;
3901 sprintf (scratchbuf, "%%cr%d", reg + add);
3902 oappend (scratchbuf + intel_syntax);
3905 static void
3906 OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3908 int add = 0;
3909 USED_REX (REX_EXTX);
3910 if (rex & REX_EXTX)
3911 add = 8;
3912 if (intel_syntax)
3913 sprintf (scratchbuf, "db%d", reg + add);
3914 else
3915 sprintf (scratchbuf, "%%db%d", reg + add);
3916 oappend (scratchbuf);
3919 static void
3920 OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3922 sprintf (scratchbuf, "%%tr%d", reg);
3923 oappend (scratchbuf + intel_syntax);
3926 static void
3927 OP_Rd (int bytemode, int sizeflag)
3929 if (mod == 3)
3930 OP_E (bytemode, sizeflag);
3931 else
3932 BadOp ();
3935 static void
3936 OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3938 used_prefixes |= (prefixes & PREFIX_DATA);
3939 if (prefixes & PREFIX_DATA)
3941 int add = 0;
3942 USED_REX (REX_EXTX);
3943 if (rex & REX_EXTX)
3944 add = 8;
3945 sprintf (scratchbuf, "%%xmm%d", reg + add);
3947 else
3948 sprintf (scratchbuf, "%%mm%d", reg);
3949 oappend (scratchbuf + intel_syntax);
3952 static void
3953 OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3955 int add = 0;
3956 USED_REX (REX_EXTX);
3957 if (rex & REX_EXTX)
3958 add = 8;
3959 sprintf (scratchbuf, "%%xmm%d", reg + add);
3960 oappend (scratchbuf + intel_syntax);
3963 static void
3964 OP_EM (int bytemode, int sizeflag)
3966 if (mod != 3)
3968 OP_E (bytemode, sizeflag);
3969 return;
3972 /* Skip mod/rm byte. */
3973 MODRM_CHECK;
3974 codep++;
3975 used_prefixes |= (prefixes & PREFIX_DATA);
3976 if (prefixes & PREFIX_DATA)
3978 int add = 0;
3980 USED_REX (REX_EXTZ);
3981 if (rex & REX_EXTZ)
3982 add = 8;
3983 sprintf (scratchbuf, "%%xmm%d", rm + add);
3985 else
3986 sprintf (scratchbuf, "%%mm%d", rm);
3987 oappend (scratchbuf + intel_syntax);
3990 static void
3991 OP_EX (int bytemode, int sizeflag)
3993 int add = 0;
3994 if (mod != 3)
3996 OP_E (bytemode, sizeflag);
3997 return;
3999 USED_REX (REX_EXTZ);
4000 if (rex & REX_EXTZ)
4001 add = 8;
4003 /* Skip mod/rm byte. */
4004 MODRM_CHECK;
4005 codep++;
4006 sprintf (scratchbuf, "%%xmm%d", rm + add);
4007 oappend (scratchbuf + intel_syntax);
4010 static void
4011 OP_MS (int bytemode, int sizeflag)
4013 if (mod == 3)
4014 OP_EM (bytemode, sizeflag);
4015 else
4016 BadOp ();
4019 static void
4020 OP_XS (int bytemode, int sizeflag)
4022 if (mod == 3)
4023 OP_EX (bytemode, sizeflag);
4024 else
4025 BadOp ();
4028 static void
4029 OP_M (int bytemode, int sizeflag)
4031 if (mod == 3)
4032 BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
4033 else
4034 OP_E (bytemode, sizeflag);
4037 static void
4038 OP_0f07 (int bytemode, int sizeflag)
4040 if (mod != 3 || rm != 0)
4041 BadOp ();
4042 else
4043 OP_E (bytemode, sizeflag);
4046 static void
4047 OP_0fae (int bytemode, int sizeflag)
4049 if (mod == 3)
4051 if (reg == 7)
4052 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
4054 if (reg < 5 || rm != 0)
4056 BadOp (); /* bad sfence, mfence, or lfence */
4057 return;
4060 else if (reg != 7)
4062 BadOp (); /* bad clflush */
4063 return;
4066 OP_E (bytemode, sizeflag);
4069 static void
4070 NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4072 /* NOP with REPZ prefix is called PAUSE. */
4073 if (prefixes == PREFIX_REPZ)
4074 strcpy (obuf, "pause");
4077 static const char *const Suffix3DNow[] = {
4078 /* 00 */ NULL, NULL, NULL, NULL,
4079 /* 04 */ NULL, NULL, NULL, NULL,
4080 /* 08 */ NULL, NULL, NULL, NULL,
4081 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
4082 /* 10 */ NULL, NULL, NULL, NULL,
4083 /* 14 */ NULL, NULL, NULL, NULL,
4084 /* 18 */ NULL, NULL, NULL, NULL,
4085 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
4086 /* 20 */ NULL, NULL, NULL, NULL,
4087 /* 24 */ NULL, NULL, NULL, NULL,
4088 /* 28 */ NULL, NULL, NULL, NULL,
4089 /* 2C */ NULL, NULL, NULL, NULL,
4090 /* 30 */ NULL, NULL, NULL, NULL,
4091 /* 34 */ NULL, NULL, NULL, NULL,
4092 /* 38 */ NULL, NULL, NULL, NULL,
4093 /* 3C */ NULL, NULL, NULL, NULL,
4094 /* 40 */ NULL, NULL, NULL, NULL,
4095 /* 44 */ NULL, NULL, NULL, NULL,
4096 /* 48 */ NULL, NULL, NULL, NULL,
4097 /* 4C */ NULL, NULL, NULL, NULL,
4098 /* 50 */ NULL, NULL, NULL, NULL,
4099 /* 54 */ NULL, NULL, NULL, NULL,
4100 /* 58 */ NULL, NULL, NULL, NULL,
4101 /* 5C */ NULL, NULL, NULL, NULL,
4102 /* 60 */ NULL, NULL, NULL, NULL,
4103 /* 64 */ NULL, NULL, NULL, NULL,
4104 /* 68 */ NULL, NULL, NULL, NULL,
4105 /* 6C */ NULL, NULL, NULL, NULL,
4106 /* 70 */ NULL, NULL, NULL, NULL,
4107 /* 74 */ NULL, NULL, NULL, NULL,
4108 /* 78 */ NULL, NULL, NULL, NULL,
4109 /* 7C */ NULL, NULL, NULL, NULL,
4110 /* 80 */ NULL, NULL, NULL, NULL,
4111 /* 84 */ NULL, NULL, NULL, NULL,
4112 /* 88 */ NULL, NULL, "pfnacc", NULL,
4113 /* 8C */ NULL, NULL, "pfpnacc", NULL,
4114 /* 90 */ "pfcmpge", NULL, NULL, NULL,
4115 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
4116 /* 98 */ NULL, NULL, "pfsub", NULL,
4117 /* 9C */ NULL, NULL, "pfadd", NULL,
4118 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
4119 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
4120 /* A8 */ NULL, NULL, "pfsubr", NULL,
4121 /* AC */ NULL, NULL, "pfacc", NULL,
4122 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
4123 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
4124 /* B8 */ NULL, NULL, NULL, "pswapd",
4125 /* BC */ NULL, NULL, NULL, "pavgusb",
4126 /* C0 */ NULL, NULL, NULL, NULL,
4127 /* C4 */ NULL, NULL, NULL, NULL,
4128 /* C8 */ NULL, NULL, NULL, NULL,
4129 /* CC */ NULL, NULL, NULL, NULL,
4130 /* D0 */ NULL, NULL, NULL, NULL,
4131 /* D4 */ NULL, NULL, NULL, NULL,
4132 /* D8 */ NULL, NULL, NULL, NULL,
4133 /* DC */ NULL, NULL, NULL, NULL,
4134 /* E0 */ NULL, NULL, NULL, NULL,
4135 /* E4 */ NULL, NULL, NULL, NULL,
4136 /* E8 */ NULL, NULL, NULL, NULL,
4137 /* EC */ NULL, NULL, NULL, NULL,
4138 /* F0 */ NULL, NULL, NULL, NULL,
4139 /* F4 */ NULL, NULL, NULL, NULL,
4140 /* F8 */ NULL, NULL, NULL, NULL,
4141 /* FC */ NULL, NULL, NULL, NULL,
4144 static void
4145 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4147 const char *mnemonic;
4149 FETCH_DATA (the_info, codep + 1);
4150 /* AMD 3DNow! instructions are specified by an opcode suffix in the
4151 place where an 8-bit immediate would normally go. ie. the last
4152 byte of the instruction. */
4153 obufp = obuf + strlen (obuf);
4154 mnemonic = Suffix3DNow[*codep++ & 0xff];
4155 if (mnemonic)
4156 oappend (mnemonic);
4157 else
4159 /* Since a variable sized modrm/sib chunk is between the start
4160 of the opcode (0x0f0f) and the opcode suffix, we need to do
4161 all the modrm processing first, and don't know until now that
4162 we have a bad opcode. This necessitates some cleaning up. */
4163 op1out[0] = '\0';
4164 op2out[0] = '\0';
4165 BadOp ();
4169 static const char *simd_cmp_op[] = {
4170 "eq",
4171 "lt",
4172 "le",
4173 "unord",
4174 "neq",
4175 "nlt",
4176 "nle",
4177 "ord"
4180 static void
4181 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4183 unsigned int cmp_type;
4185 FETCH_DATA (the_info, codep + 1);
4186 obufp = obuf + strlen (obuf);
4187 cmp_type = *codep++ & 0xff;
4188 if (cmp_type < 8)
4190 char suffix1 = 'p', suffix2 = 's';
4191 used_prefixes |= (prefixes & PREFIX_REPZ);
4192 if (prefixes & PREFIX_REPZ)
4193 suffix1 = 's';
4194 else
4196 used_prefixes |= (prefixes & PREFIX_DATA);
4197 if (prefixes & PREFIX_DATA)
4198 suffix2 = 'd';
4199 else
4201 used_prefixes |= (prefixes & PREFIX_REPNZ);
4202 if (prefixes & PREFIX_REPNZ)
4203 suffix1 = 's', suffix2 = 'd';
4206 sprintf (scratchbuf, "cmp%s%c%c",
4207 simd_cmp_op[cmp_type], suffix1, suffix2);
4208 used_prefixes |= (prefixes & PREFIX_REPZ);
4209 oappend (scratchbuf);
4211 else
4213 /* We have a bad extension byte. Clean up. */
4214 op1out[0] = '\0';
4215 op2out[0] = '\0';
4216 BadOp ();
4220 static void
4221 SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
4223 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
4224 forms of these instructions. */
4225 if (mod == 3)
4227 char *p = obuf + strlen (obuf);
4228 *(p + 1) = '\0';
4229 *p = *(p - 1);
4230 *(p - 1) = *(p - 2);
4231 *(p - 2) = *(p - 3);
4232 *(p - 3) = extrachar;
4236 static void
4237 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
4239 if (mod == 3 && reg == 1 && rm <= 1)
4241 /* Override "sidt". */
4242 char *p = obuf + strlen (obuf) - 4;
4244 /* We might have a suffix. */
4245 if (*p == 'i')
4246 --p;
4248 if (rm)
4250 /* mwait %eax,%ecx */
4251 strcpy (p, "mwait");
4253 else
4255 /* monitor %eax,%ecx,%edx" */
4256 strcpy (p, "monitor");
4257 strcpy (op3out, names32[2]);
4259 strcpy (op1out, names32[0]);
4260 strcpy (op2out, names32[1]);
4261 two_source_ops = 1;
4263 codep++;
4265 else
4266 OP_E (0, sizeflag);
4269 static void
4270 INVLPG_Fixup (int bytemode, int sizeflag)
4272 if (*codep == 0xf8)
4274 char *p = obuf + strlen (obuf);
4276 /* Override "invlpg". */
4277 strcpy (p - 6, "swapgs");
4278 codep++;
4280 else
4281 OP_E (bytemode, sizeflag);
4284 static void
4285 BadOp (void)
4287 /* Throw away prefixes and 1st. opcode byte. */
4288 codep = insn_codep + 1;
4289 oappend ("(bad)");