* elf64-ppc.c (func_desc_adjust): Give undefined dot-symbols a value
[binutils.git] / opcodes / i386-dis.c
blob66fd388a4557502b646c0b488d84ac813d2ff8bd
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 GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0
393 #define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0
395 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
396 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
397 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
398 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
399 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
400 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
401 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
402 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
403 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
404 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
405 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
406 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
407 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
408 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
409 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
410 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
411 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
412 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
413 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
414 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
415 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
416 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
417 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
418 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
419 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
420 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
421 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
422 #define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0
423 #define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0
424 #define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0
425 #define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0
426 #define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0
427 #define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0
429 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
431 typedef void (*op_rtn) (int bytemode, int sizeflag);
433 struct dis386 {
434 const char *name;
435 op_rtn op1;
436 int bytemode1;
437 op_rtn op2;
438 int bytemode2;
439 op_rtn op3;
440 int bytemode3;
443 /* Upper case letters in the instruction names here are macros.
444 'A' => print 'b' if no register operands or suffix_always is true
445 'B' => print 'b' if suffix_always is true
446 'E' => print 'e' if 32-bit form of jcxz
447 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
448 'H' => print ",pt" or ",pn" branch hint
449 'L' => print 'l' if suffix_always is true
450 'N' => print 'n' if instruction has no wait "prefix"
451 'O' => print 'd', or 'o'
452 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
453 . or suffix_always is true. print 'q' if rex prefix is present.
454 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
455 . is true
456 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
457 'S' => print 'w', 'l' or 'q' if suffix_always is true
458 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
459 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
460 'X' => print 's', 'd' depending on data16 prefix (for XMM)
461 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
462 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
464 Many of the above letters print nothing in Intel mode. See "putop"
465 for the details.
467 Braces '{' and '}', and vertical bars '|', indicate alternative
468 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
469 modes. In cases where there are only two alternatives, the X86_64
470 instruction is reserved, and "(bad)" is printed.
473 static const struct dis386 dis386[] = {
474 /* 00 */
475 { "addB", Eb, Gb, XX },
476 { "addS", Ev, Gv, XX },
477 { "addB", Gb, Eb, XX },
478 { "addS", Gv, Ev, XX },
479 { "addB", AL, Ib, XX },
480 { "addS", eAX, Iv, XX },
481 { "push{T|}", es, XX, XX },
482 { "pop{T|}", es, XX, XX },
483 /* 08 */
484 { "orB", Eb, Gb, XX },
485 { "orS", Ev, Gv, XX },
486 { "orB", Gb, Eb, XX },
487 { "orS", Gv, Ev, XX },
488 { "orB", AL, Ib, XX },
489 { "orS", eAX, Iv, XX },
490 { "push{T|}", cs, XX, XX },
491 { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */
492 /* 10 */
493 { "adcB", Eb, Gb, XX },
494 { "adcS", Ev, Gv, XX },
495 { "adcB", Gb, Eb, XX },
496 { "adcS", Gv, Ev, XX },
497 { "adcB", AL, Ib, XX },
498 { "adcS", eAX, Iv, XX },
499 { "push{T|}", ss, XX, XX },
500 { "popT|}", ss, XX, XX },
501 /* 18 */
502 { "sbbB", Eb, Gb, XX },
503 { "sbbS", Ev, Gv, XX },
504 { "sbbB", Gb, Eb, XX },
505 { "sbbS", Gv, Ev, XX },
506 { "sbbB", AL, Ib, XX },
507 { "sbbS", eAX, Iv, XX },
508 { "push{T|}", ds, XX, XX },
509 { "pop{T|}", ds, XX, XX },
510 /* 20 */
511 { "andB", Eb, Gb, XX },
512 { "andS", Ev, Gv, XX },
513 { "andB", Gb, Eb, XX },
514 { "andS", Gv, Ev, XX },
515 { "andB", AL, Ib, XX },
516 { "andS", eAX, Iv, XX },
517 { "(bad)", XX, XX, XX }, /* SEG ES prefix */
518 { "daa{|}", XX, XX, XX },
519 /* 28 */
520 { "subB", Eb, Gb, XX },
521 { "subS", Ev, Gv, XX },
522 { "subB", Gb, Eb, XX },
523 { "subS", Gv, Ev, XX },
524 { "subB", AL, Ib, XX },
525 { "subS", eAX, Iv, XX },
526 { "(bad)", XX, XX, XX }, /* SEG CS prefix */
527 { "das{|}", XX, XX, XX },
528 /* 30 */
529 { "xorB", Eb, Gb, XX },
530 { "xorS", Ev, Gv, XX },
531 { "xorB", Gb, Eb, XX },
532 { "xorS", Gv, Ev, XX },
533 { "xorB", AL, Ib, XX },
534 { "xorS", eAX, Iv, XX },
535 { "(bad)", XX, XX, XX }, /* SEG SS prefix */
536 { "aaa{|}", XX, XX, XX },
537 /* 38 */
538 { "cmpB", Eb, Gb, XX },
539 { "cmpS", Ev, Gv, XX },
540 { "cmpB", Gb, Eb, XX },
541 { "cmpS", Gv, Ev, XX },
542 { "cmpB", AL, Ib, XX },
543 { "cmpS", eAX, Iv, XX },
544 { "(bad)", XX, XX, XX }, /* SEG DS prefix */
545 { "aas{|}", XX, XX, XX },
546 /* 40 */
547 { "inc{S|}", RMeAX, XX, XX },
548 { "inc{S|}", RMeCX, XX, XX },
549 { "inc{S|}", RMeDX, XX, XX },
550 { "inc{S|}", RMeBX, XX, XX },
551 { "inc{S|}", RMeSP, XX, XX },
552 { "inc{S|}", RMeBP, XX, XX },
553 { "inc{S|}", RMeSI, XX, XX },
554 { "inc{S|}", RMeDI, XX, XX },
555 /* 48 */
556 { "dec{S|}", RMeAX, XX, XX },
557 { "dec{S|}", RMeCX, XX, XX },
558 { "dec{S|}", RMeDX, XX, XX },
559 { "dec{S|}", RMeBX, XX, XX },
560 { "dec{S|}", RMeSP, XX, XX },
561 { "dec{S|}", RMeBP, XX, XX },
562 { "dec{S|}", RMeSI, XX, XX },
563 { "dec{S|}", RMeDI, XX, XX },
564 /* 50 */
565 { "pushS", RMrAX, XX, XX },
566 { "pushS", RMrCX, XX, XX },
567 { "pushS", RMrDX, XX, XX },
568 { "pushS", RMrBX, XX, XX },
569 { "pushS", RMrSP, XX, XX },
570 { "pushS", RMrBP, XX, XX },
571 { "pushS", RMrSI, XX, XX },
572 { "pushS", RMrDI, XX, XX },
573 /* 58 */
574 { "popS", RMrAX, XX, XX },
575 { "popS", RMrCX, XX, XX },
576 { "popS", RMrDX, XX, XX },
577 { "popS", RMrBX, XX, XX },
578 { "popS", RMrSP, XX, XX },
579 { "popS", RMrBP, XX, XX },
580 { "popS", RMrSI, XX, XX },
581 { "popS", RMrDI, XX, XX },
582 /* 60 */
583 { "pusha{P|}", XX, XX, XX },
584 { "popa{P|}", XX, XX, XX },
585 { "bound{S|}", Gv, Ma, XX },
586 { X86_64_0 },
587 { "(bad)", XX, XX, XX }, /* seg fs */
588 { "(bad)", XX, XX, XX }, /* seg gs */
589 { "(bad)", XX, XX, XX }, /* op size prefix */
590 { "(bad)", XX, XX, XX }, /* adr size prefix */
591 /* 68 */
592 { "pushT", Iq, XX, XX },
593 { "imulS", Gv, Ev, Iv },
594 { "pushT", sIb, XX, XX },
595 { "imulS", Gv, Ev, sIb },
596 { "ins{b||b|}", Yb, indirDX, XX },
597 { "ins{R||R|}", Yv, indirDX, XX },
598 { "outs{b||b|}", indirDX, Xb, XX },
599 { "outs{R||R|}", indirDX, Xv, XX },
600 /* 70 */
601 { "joH", Jb, XX, cond_jump_flag },
602 { "jnoH", Jb, XX, cond_jump_flag },
603 { "jbH", Jb, XX, cond_jump_flag },
604 { "jaeH", Jb, XX, cond_jump_flag },
605 { "jeH", Jb, XX, cond_jump_flag },
606 { "jneH", Jb, XX, cond_jump_flag },
607 { "jbeH", Jb, XX, cond_jump_flag },
608 { "jaH", Jb, XX, cond_jump_flag },
609 /* 78 */
610 { "jsH", Jb, XX, cond_jump_flag },
611 { "jnsH", Jb, XX, cond_jump_flag },
612 { "jpH", Jb, XX, cond_jump_flag },
613 { "jnpH", Jb, XX, cond_jump_flag },
614 { "jlH", Jb, XX, cond_jump_flag },
615 { "jgeH", Jb, XX, cond_jump_flag },
616 { "jleH", Jb, XX, cond_jump_flag },
617 { "jgH", Jb, XX, cond_jump_flag },
618 /* 80 */
619 { GRP1b },
620 { GRP1S },
621 { "(bad)", XX, XX, XX },
622 { GRP1Ss },
623 { "testB", Eb, Gb, XX },
624 { "testS", Ev, Gv, XX },
625 { "xchgB", Eb, Gb, XX },
626 { "xchgS", Ev, Gv, XX },
627 /* 88 */
628 { "movB", Eb, Gb, XX },
629 { "movS", Ev, Gv, XX },
630 { "movB", Gb, Eb, XX },
631 { "movS", Gv, Ev, XX },
632 { "movQ", Ev, Sw, XX },
633 { "leaS", Gv, M, XX },
634 { "movQ", Sw, Ev, XX },
635 { "popU", Ev, XX, XX },
636 /* 90 */
637 { "nop", NOP_Fixup, 0, XX, XX },
638 { "xchgS", RMeCX, eAX, XX },
639 { "xchgS", RMeDX, eAX, XX },
640 { "xchgS", RMeBX, eAX, XX },
641 { "xchgS", RMeSP, eAX, XX },
642 { "xchgS", RMeBP, eAX, XX },
643 { "xchgS", RMeSI, eAX, XX },
644 { "xchgS", RMeDI, eAX, XX },
645 /* 98 */
646 { "cW{tR||tR|}", XX, XX, XX },
647 { "cR{tO||tO|}", XX, XX, XX },
648 { "lcall{T|}", Ap, XX, XX },
649 { "(bad)", XX, XX, XX }, /* fwait */
650 { "pushfT", XX, XX, XX },
651 { "popfT", XX, XX, XX },
652 { "sahf{|}", XX, XX, XX },
653 { "lahf{|}", XX, XX, XX },
654 /* a0 */
655 { "movB", AL, Ob64, XX },
656 { "movS", eAX, Ov64, XX },
657 { "movB", Ob64, AL, XX },
658 { "movS", Ov64, eAX, XX },
659 { "movs{b||b|}", Yb, Xb, XX },
660 { "movs{R||R|}", Yv, Xv, XX },
661 { "cmps{b||b|}", Xb, Yb, XX },
662 { "cmps{R||R|}", Xv, Yv, XX },
663 /* a8 */
664 { "testB", AL, Ib, XX },
665 { "testS", eAX, Iv, XX },
666 { "stosB", Yb, AL, XX },
667 { "stosS", Yv, eAX, XX },
668 { "lodsB", AL, Xb, XX },
669 { "lodsS", eAX, Xv, XX },
670 { "scasB", AL, Yb, XX },
671 { "scasS", eAX, Yv, XX },
672 /* b0 */
673 { "movB", RMAL, Ib, XX },
674 { "movB", RMCL, Ib, XX },
675 { "movB", RMDL, Ib, XX },
676 { "movB", RMBL, Ib, XX },
677 { "movB", RMAH, Ib, XX },
678 { "movB", RMCH, Ib, XX },
679 { "movB", RMDH, Ib, XX },
680 { "movB", RMBH, Ib, XX },
681 /* b8 */
682 { "movS", RMeAX, Iv64, XX },
683 { "movS", RMeCX, Iv64, XX },
684 { "movS", RMeDX, Iv64, XX },
685 { "movS", RMeBX, Iv64, XX },
686 { "movS", RMeSP, Iv64, XX },
687 { "movS", RMeBP, Iv64, XX },
688 { "movS", RMeSI, Iv64, XX },
689 { "movS", RMeDI, Iv64, XX },
690 /* c0 */
691 { GRP2b },
692 { GRP2S },
693 { "retT", Iw, XX, XX },
694 { "retT", XX, XX, XX },
695 { "les{S|}", Gv, Mp, XX },
696 { "ldsS", Gv, Mp, XX },
697 { "movA", Eb, Ib, XX },
698 { "movQ", Ev, Iv, XX },
699 /* c8 */
700 { "enterT", Iw, Ib, XX },
701 { "leaveT", XX, XX, XX },
702 { "lretP", Iw, XX, XX },
703 { "lretP", XX, XX, XX },
704 { "int3", XX, XX, XX },
705 { "int", Ib, XX, XX },
706 { "into{|}", XX, XX, XX },
707 { "iretP", XX, XX, XX },
708 /* d0 */
709 { GRP2b_one },
710 { GRP2S_one },
711 { GRP2b_cl },
712 { GRP2S_cl },
713 { "aam{|}", sIb, XX, XX },
714 { "aad{|}", sIb, XX, XX },
715 { "(bad)", XX, XX, XX },
716 { "xlat", DSBX, XX, XX },
717 /* d8 */
718 { FLOAT },
719 { FLOAT },
720 { FLOAT },
721 { FLOAT },
722 { FLOAT },
723 { FLOAT },
724 { FLOAT },
725 { FLOAT },
726 /* e0 */
727 { "loopneFH", Jb, XX, loop_jcxz_flag },
728 { "loopeFH", Jb, XX, loop_jcxz_flag },
729 { "loopFH", Jb, XX, loop_jcxz_flag },
730 { "jEcxzH", Jb, XX, loop_jcxz_flag },
731 { "inB", AL, Ib, XX },
732 { "inS", eAX, Ib, XX },
733 { "outB", Ib, AL, XX },
734 { "outS", Ib, eAX, XX },
735 /* e8 */
736 { "callT", Jv, XX, XX },
737 { "jmpT", Jv, XX, XX },
738 { "ljmp{T|}", Ap, XX, XX },
739 { "jmp", Jb, XX, XX },
740 { "inB", AL, indirDX, XX },
741 { "inS", eAX, indirDX, XX },
742 { "outB", indirDX, AL, XX },
743 { "outS", indirDX, eAX, XX },
744 /* f0 */
745 { "(bad)", XX, XX, XX }, /* lock prefix */
746 { "icebp", XX, XX, XX },
747 { "(bad)", XX, XX, XX }, /* repne */
748 { "(bad)", XX, XX, XX }, /* repz */
749 { "hlt", XX, XX, XX },
750 { "cmc", XX, XX, XX },
751 { GRP3b },
752 { GRP3S },
753 /* f8 */
754 { "clc", XX, XX, XX },
755 { "stc", XX, XX, XX },
756 { "cli", XX, XX, XX },
757 { "sti", XX, XX, XX },
758 { "cld", XX, XX, XX },
759 { "std", XX, XX, XX },
760 { GRP4 },
761 { GRP5 },
764 static const struct dis386 dis386_twobyte[] = {
765 /* 00 */
766 { GRP6 },
767 { GRP7 },
768 { "larS", Gv, Ew, XX },
769 { "lslS", Gv, Ew, XX },
770 { "(bad)", XX, XX, XX },
771 { "syscall", XX, XX, XX },
772 { "clts", XX, XX, XX },
773 { "sysretP", XX, XX, XX },
774 /* 08 */
775 { "invd", XX, XX, XX },
776 { "wbinvd", XX, XX, XX },
777 { "(bad)", XX, XX, XX },
778 { "ud2a", XX, XX, XX },
779 { "(bad)", XX, XX, XX },
780 { GRPAMD },
781 { "femms", XX, XX, XX },
782 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */
783 /* 10 */
784 { PREGRP8 },
785 { PREGRP9 },
786 { PREGRP30 },
787 { "movlpX", EX, XM, SIMD_Fixup, 'h' },
788 { "unpcklpX", XM, EX, XX },
789 { "unpckhpX", XM, EX, XX },
790 { PREGRP31 },
791 { "movhpX", EX, XM, SIMD_Fixup, 'l' },
792 /* 18 */
793 { GRP14 },
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 { "(bad)", XX, XX, XX },
801 /* 20 */
802 { "movL", Rm, Cm, XX },
803 { "movL", Rm, Dm, XX },
804 { "movL", Cm, Rm, XX },
805 { "movL", Dm, Rm, XX },
806 { "movL", Rd, Td, XX },
807 { "(bad)", XX, XX, XX },
808 { "movL", Td, Rd, XX },
809 { "(bad)", XX, XX, XX },
810 /* 28 */
811 { "movapX", XM, EX, XX },
812 { "movapX", EX, XM, XX },
813 { PREGRP2 },
814 { "movntpX", Ev, XM, XX },
815 { PREGRP4 },
816 { PREGRP3 },
817 { "ucomisX", XM,EX, XX },
818 { "comisX", XM,EX, XX },
819 /* 30 */
820 { "wrmsr", XX, XX, XX },
821 { "rdtsc", XX, XX, XX },
822 { "rdmsr", XX, XX, XX },
823 { "rdpmc", XX, XX, XX },
824 { "sysenter", XX, XX, XX },
825 { "sysexit", XX, XX, XX },
826 { "(bad)", XX, XX, XX },
827 { "(bad)", XX, XX, XX },
828 /* 38 */
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 { "(bad)", XX, XX, XX },
837 /* 40 */
838 { "cmovo", Gv, Ev, XX },
839 { "cmovno", Gv, Ev, XX },
840 { "cmovb", Gv, Ev, XX },
841 { "cmovae", Gv, Ev, XX },
842 { "cmove", Gv, Ev, XX },
843 { "cmovne", Gv, Ev, XX },
844 { "cmovbe", Gv, Ev, XX },
845 { "cmova", Gv, Ev, XX },
846 /* 48 */
847 { "cmovs", Gv, Ev, XX },
848 { "cmovns", Gv, Ev, XX },
849 { "cmovp", Gv, Ev, XX },
850 { "cmovnp", Gv, Ev, XX },
851 { "cmovl", Gv, Ev, XX },
852 { "cmovge", Gv, Ev, XX },
853 { "cmovle", Gv, Ev, XX },
854 { "cmovg", Gv, Ev, XX },
855 /* 50 */
856 { "movmskpX", Gd, XS, XX },
857 { PREGRP13 },
858 { PREGRP12 },
859 { PREGRP11 },
860 { "andpX", XM, EX, XX },
861 { "andnpX", XM, EX, XX },
862 { "orpX", XM, EX, XX },
863 { "xorpX", XM, EX, XX },
864 /* 58 */
865 { PREGRP0 },
866 { PREGRP10 },
867 { PREGRP17 },
868 { PREGRP16 },
869 { PREGRP14 },
870 { PREGRP7 },
871 { PREGRP5 },
872 { PREGRP6 },
873 /* 60 */
874 { "punpcklbw", MX, EM, XX },
875 { "punpcklwd", MX, EM, XX },
876 { "punpckldq", MX, EM, XX },
877 { "packsswb", MX, EM, XX },
878 { "pcmpgtb", MX, EM, XX },
879 { "pcmpgtw", MX, EM, XX },
880 { "pcmpgtd", MX, EM, XX },
881 { "packuswb", MX, EM, XX },
882 /* 68 */
883 { "punpckhbw", MX, EM, XX },
884 { "punpckhwd", MX, EM, XX },
885 { "punpckhdq", MX, EM, XX },
886 { "packssdw", MX, EM, XX },
887 { PREGRP26 },
888 { PREGRP24 },
889 { "movd", MX, Edq, XX },
890 { PREGRP19 },
891 /* 70 */
892 { PREGRP22 },
893 { GRP10 },
894 { GRP11 },
895 { GRP12 },
896 { "pcmpeqb", MX, EM, XX },
897 { "pcmpeqw", MX, EM, XX },
898 { "pcmpeqd", MX, EM, XX },
899 { "emms", XX, XX, XX },
900 /* 78 */
901 { "(bad)", XX, XX, XX },
902 { "(bad)", XX, XX, XX },
903 { "(bad)", XX, XX, XX },
904 { "(bad)", XX, XX, XX },
905 { PREGRP28 },
906 { PREGRP29 },
907 { PREGRP23 },
908 { PREGRP20 },
909 /* 80 */
910 { "joH", Jv, XX, cond_jump_flag },
911 { "jnoH", Jv, XX, cond_jump_flag },
912 { "jbH", Jv, XX, cond_jump_flag },
913 { "jaeH", Jv, XX, cond_jump_flag },
914 { "jeH", Jv, XX, cond_jump_flag },
915 { "jneH", Jv, XX, cond_jump_flag },
916 { "jbeH", Jv, XX, cond_jump_flag },
917 { "jaH", Jv, XX, cond_jump_flag },
918 /* 88 */
919 { "jsH", Jv, XX, cond_jump_flag },
920 { "jnsH", Jv, XX, cond_jump_flag },
921 { "jpH", Jv, XX, cond_jump_flag },
922 { "jnpH", Jv, XX, cond_jump_flag },
923 { "jlH", Jv, XX, cond_jump_flag },
924 { "jgeH", Jv, XX, cond_jump_flag },
925 { "jleH", Jv, XX, cond_jump_flag },
926 { "jgH", Jv, XX, cond_jump_flag },
927 /* 90 */
928 { "seto", Eb, XX, XX },
929 { "setno", Eb, XX, XX },
930 { "setb", Eb, XX, XX },
931 { "setae", Eb, XX, XX },
932 { "sete", Eb, XX, XX },
933 { "setne", Eb, XX, XX },
934 { "setbe", Eb, XX, XX },
935 { "seta", Eb, XX, XX },
936 /* 98 */
937 { "sets", Eb, XX, XX },
938 { "setns", Eb, XX, XX },
939 { "setp", Eb, XX, XX },
940 { "setnp", Eb, XX, XX },
941 { "setl", Eb, XX, XX },
942 { "setge", Eb, XX, XX },
943 { "setle", Eb, XX, XX },
944 { "setg", Eb, XX, XX },
945 /* a0 */
946 { "pushT", fs, XX, XX },
947 { "popT", fs, XX, XX },
948 { "cpuid", XX, XX, XX },
949 { "btS", Ev, Gv, XX },
950 { "shldS", Ev, Gv, Ib },
951 { "shldS", Ev, Gv, CL },
952 { GRPPADLCK2 },
953 { GRPPADLCK1 },
954 /* a8 */
955 { "pushT", gs, XX, XX },
956 { "popT", gs, XX, XX },
957 { "rsm", XX, XX, XX },
958 { "btsS", Ev, Gv, XX },
959 { "shrdS", Ev, Gv, Ib },
960 { "shrdS", Ev, Gv, CL },
961 { GRP13 },
962 { "imulS", Gv, Ev, XX },
963 /* b0 */
964 { "cmpxchgB", Eb, Gb, XX },
965 { "cmpxchgS", Ev, Gv, XX },
966 { "lssS", Gv, Mp, XX },
967 { "btrS", Ev, Gv, XX },
968 { "lfsS", Gv, Mp, XX },
969 { "lgsS", Gv, Mp, XX },
970 { "movz{bR|x|bR|x}", Gv, Eb, XX },
971 { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */
972 /* b8 */
973 { "(bad)", XX, XX, XX },
974 { "ud2b", XX, XX, XX },
975 { GRP8 },
976 { "btcS", Ev, Gv, XX },
977 { "bsfS", Gv, Ev, XX },
978 { "bsrS", Gv, Ev, XX },
979 { "movs{bR|x|bR|x}", Gv, Eb, XX },
980 { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */
981 /* c0 */
982 { "xaddB", Eb, Gb, XX },
983 { "xaddS", Ev, Gv, XX },
984 { PREGRP1 },
985 { "movntiS", Ev, Gv, XX },
986 { "pinsrw", MX, Ed, Ib },
987 { "pextrw", Gd, MS, Ib },
988 { "shufpX", XM, EX, Ib },
989 { GRP9 },
990 /* c8 */
991 { "bswap", RMeAX, XX, XX },
992 { "bswap", RMeCX, XX, XX },
993 { "bswap", RMeDX, XX, XX },
994 { "bswap", RMeBX, XX, XX },
995 { "bswap", RMeSP, XX, XX },
996 { "bswap", RMeBP, XX, XX },
997 { "bswap", RMeSI, XX, XX },
998 { "bswap", RMeDI, XX, XX },
999 /* d0 */
1000 { PREGRP27 },
1001 { "psrlw", MX, EM, XX },
1002 { "psrld", MX, EM, XX },
1003 { "psrlq", MX, EM, XX },
1004 { "paddq", MX, EM, XX },
1005 { "pmullw", MX, EM, XX },
1006 { PREGRP21 },
1007 { "pmovmskb", Gd, MS, XX },
1008 /* d8 */
1009 { "psubusb", MX, EM, XX },
1010 { "psubusw", MX, EM, XX },
1011 { "pminub", MX, EM, XX },
1012 { "pand", MX, EM, XX },
1013 { "paddusb", MX, EM, XX },
1014 { "paddusw", MX, EM, XX },
1015 { "pmaxub", MX, EM, XX },
1016 { "pandn", MX, EM, XX },
1017 /* e0 */
1018 { "pavgb", MX, EM, XX },
1019 { "psraw", MX, EM, XX },
1020 { "psrad", MX, EM, XX },
1021 { "pavgw", MX, EM, XX },
1022 { "pmulhuw", MX, EM, XX },
1023 { "pmulhw", MX, EM, XX },
1024 { PREGRP15 },
1025 { PREGRP25 },
1026 /* e8 */
1027 { "psubsb", MX, EM, XX },
1028 { "psubsw", MX, EM, XX },
1029 { "pminsw", MX, EM, XX },
1030 { "por", MX, EM, XX },
1031 { "paddsb", MX, EM, XX },
1032 { "paddsw", MX, EM, XX },
1033 { "pmaxsw", MX, EM, XX },
1034 { "pxor", MX, EM, XX },
1035 /* f0 */
1036 { PREGRP32 },
1037 { "psllw", MX, EM, XX },
1038 { "pslld", MX, EM, XX },
1039 { "psllq", MX, EM, XX },
1040 { "pmuludq", MX, EM, XX },
1041 { "pmaddwd", MX, EM, XX },
1042 { "psadbw", MX, EM, XX },
1043 { PREGRP18 },
1044 /* f8 */
1045 { "psubb", MX, EM, XX },
1046 { "psubw", MX, EM, XX },
1047 { "psubd", MX, EM, XX },
1048 { "psubq", MX, EM, XX },
1049 { "paddb", MX, EM, XX },
1050 { "paddw", MX, EM, XX },
1051 { "paddd", MX, EM, XX },
1052 { "(bad)", XX, XX, XX }
1055 static const unsigned char onebyte_has_modrm[256] = {
1056 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1057 /* ------------------------------- */
1058 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1059 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1060 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1061 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1062 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1063 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1064 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1065 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1066 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1067 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1068 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1069 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1070 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1071 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1072 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1073 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1074 /* ------------------------------- */
1075 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1078 static const unsigned char twobyte_has_modrm[256] = {
1079 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1080 /* ------------------------------- */
1081 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1082 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1083 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1084 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1085 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1086 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1087 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1088 /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1, /* 7f */
1089 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1090 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1091 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1092 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1093 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1094 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1095 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1096 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1097 /* ------------------------------- */
1098 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1101 static const unsigned char twobyte_uses_SSE_prefix[256] = {
1102 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1103 /* ------------------------------- */
1104 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1105 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1106 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1107 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1108 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1109 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1110 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1111 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */
1112 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1113 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1114 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1115 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1116 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1117 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1118 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1119 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1120 /* ------------------------------- */
1121 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1124 static char obuf[100];
1125 static char *obufp;
1126 static char scratchbuf[100];
1127 static unsigned char *start_codep;
1128 static unsigned char *insn_codep;
1129 static unsigned char *codep;
1130 static disassemble_info *the_info;
1131 static int mod;
1132 static int rm;
1133 static int reg;
1134 static unsigned char need_modrm;
1136 /* If we are accessing mod/rm/reg without need_modrm set, then the
1137 values are stale. Hitting this abort likely indicates that you
1138 need to update onebyte_has_modrm or twobyte_has_modrm. */
1139 #define MODRM_CHECK if (!need_modrm) abort ()
1141 static const char **names64;
1142 static const char **names32;
1143 static const char **names16;
1144 static const char **names8;
1145 static const char **names8rex;
1146 static const char **names_seg;
1147 static const char **index16;
1149 static const char *intel_names64[] = {
1150 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1151 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1153 static const char *intel_names32[] = {
1154 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1155 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1157 static const char *intel_names16[] = {
1158 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1159 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1161 static const char *intel_names8[] = {
1162 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1164 static const char *intel_names8rex[] = {
1165 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1166 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1168 static const char *intel_names_seg[] = {
1169 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1171 static const char *intel_index16[] = {
1172 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1175 static const char *att_names64[] = {
1176 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1177 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1179 static const char *att_names32[] = {
1180 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1181 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1183 static const char *att_names16[] = {
1184 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1185 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1187 static const char *att_names8[] = {
1188 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1190 static const char *att_names8rex[] = {
1191 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1192 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1194 static const char *att_names_seg[] = {
1195 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1197 static const char *att_index16[] = {
1198 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1201 static const struct dis386 grps[][8] = {
1202 /* GRP1b */
1204 { "addA", Eb, Ib, XX },
1205 { "orA", Eb, Ib, XX },
1206 { "adcA", Eb, Ib, XX },
1207 { "sbbA", Eb, Ib, XX },
1208 { "andA", Eb, Ib, XX },
1209 { "subA", Eb, Ib, XX },
1210 { "xorA", Eb, Ib, XX },
1211 { "cmpA", Eb, Ib, XX }
1213 /* GRP1S */
1215 { "addQ", Ev, Iv, XX },
1216 { "orQ", Ev, Iv, XX },
1217 { "adcQ", Ev, Iv, XX },
1218 { "sbbQ", Ev, Iv, XX },
1219 { "andQ", Ev, Iv, XX },
1220 { "subQ", Ev, Iv, XX },
1221 { "xorQ", Ev, Iv, XX },
1222 { "cmpQ", Ev, Iv, XX }
1224 /* GRP1Ss */
1226 { "addQ", Ev, sIb, XX },
1227 { "orQ", Ev, sIb, XX },
1228 { "adcQ", Ev, sIb, XX },
1229 { "sbbQ", Ev, sIb, XX },
1230 { "andQ", Ev, sIb, XX },
1231 { "subQ", Ev, sIb, XX },
1232 { "xorQ", Ev, sIb, XX },
1233 { "cmpQ", Ev, sIb, XX }
1235 /* GRP2b */
1237 { "rolA", Eb, Ib, XX },
1238 { "rorA", Eb, Ib, XX },
1239 { "rclA", Eb, Ib, XX },
1240 { "rcrA", Eb, Ib, XX },
1241 { "shlA", Eb, Ib, XX },
1242 { "shrA", Eb, Ib, XX },
1243 { "(bad)", XX, XX, XX },
1244 { "sarA", Eb, Ib, XX },
1246 /* GRP2S */
1248 { "rolQ", Ev, Ib, XX },
1249 { "rorQ", Ev, Ib, XX },
1250 { "rclQ", Ev, Ib, XX },
1251 { "rcrQ", Ev, Ib, XX },
1252 { "shlQ", Ev, Ib, XX },
1253 { "shrQ", Ev, Ib, XX },
1254 { "(bad)", XX, XX, XX },
1255 { "sarQ", Ev, Ib, XX },
1257 /* GRP2b_one */
1259 { "rolA", Eb, XX, XX },
1260 { "rorA", Eb, XX, XX },
1261 { "rclA", Eb, XX, XX },
1262 { "rcrA", Eb, XX, XX },
1263 { "shlA", Eb, XX, XX },
1264 { "shrA", Eb, XX, XX },
1265 { "(bad)", XX, XX, XX },
1266 { "sarA", Eb, XX, XX },
1268 /* GRP2S_one */
1270 { "rolQ", Ev, XX, XX },
1271 { "rorQ", Ev, XX, XX },
1272 { "rclQ", Ev, XX, XX },
1273 { "rcrQ", Ev, XX, XX },
1274 { "shlQ", Ev, XX, XX },
1275 { "shrQ", Ev, XX, XX },
1276 { "(bad)", XX, XX, XX},
1277 { "sarQ", Ev, XX, XX },
1279 /* GRP2b_cl */
1281 { "rolA", Eb, CL, XX },
1282 { "rorA", Eb, CL, XX },
1283 { "rclA", Eb, CL, XX },
1284 { "rcrA", Eb, CL, XX },
1285 { "shlA", Eb, CL, XX },
1286 { "shrA", Eb, CL, XX },
1287 { "(bad)", XX, XX, XX },
1288 { "sarA", Eb, CL, XX },
1290 /* GRP2S_cl */
1292 { "rolQ", Ev, CL, XX },
1293 { "rorQ", Ev, CL, XX },
1294 { "rclQ", Ev, CL, XX },
1295 { "rcrQ", Ev, CL, XX },
1296 { "shlQ", Ev, CL, XX },
1297 { "shrQ", Ev, CL, XX },
1298 { "(bad)", XX, XX, XX },
1299 { "sarQ", Ev, CL, XX }
1301 /* GRP3b */
1303 { "testA", Eb, Ib, XX },
1304 { "(bad)", Eb, XX, XX },
1305 { "notA", Eb, XX, XX },
1306 { "negA", Eb, XX, XX },
1307 { "mulA", Eb, XX, XX }, /* Don't print the implicit %al register, */
1308 { "imulA", Eb, XX, XX }, /* to distinguish these opcodes from other */
1309 { "divA", Eb, XX, XX }, /* mul/imul opcodes. Do the same for div */
1310 { "idivA", Eb, XX, XX } /* and idiv for consistency. */
1312 /* GRP3S */
1314 { "testQ", Ev, Iv, XX },
1315 { "(bad)", XX, XX, XX },
1316 { "notQ", Ev, XX, XX },
1317 { "negQ", Ev, XX, XX },
1318 { "mulQ", Ev, XX, XX }, /* Don't print the implicit register. */
1319 { "imulQ", Ev, XX, XX },
1320 { "divQ", Ev, XX, XX },
1321 { "idivQ", Ev, XX, XX },
1323 /* GRP4 */
1325 { "incA", Eb, XX, XX },
1326 { "decA", Eb, 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 },
1332 { "(bad)", XX, XX, XX },
1334 /* GRP5 */
1336 { "incQ", Ev, XX, XX },
1337 { "decQ", Ev, XX, XX },
1338 { "callT", indirEv, XX, XX },
1339 { "lcallT", indirEv, XX, XX },
1340 { "jmpT", indirEv, XX, XX },
1341 { "ljmpT", indirEv, XX, XX },
1342 { "pushU", Ev, XX, XX },
1343 { "(bad)", XX, XX, XX },
1345 /* GRP6 */
1347 { "sldtQ", Ev, XX, XX },
1348 { "strQ", Ev, XX, XX },
1349 { "lldt", Ew, XX, XX },
1350 { "ltr", Ew, XX, XX },
1351 { "verr", Ew, XX, XX },
1352 { "verw", Ew, XX, XX },
1353 { "(bad)", XX, XX, XX },
1354 { "(bad)", XX, XX, XX }
1356 /* GRP7 */
1358 { "sgdtQ", M, XX, XX },
1359 { "sidtQ", PNI_Fixup, 0, XX, XX },
1360 { "lgdtQ", M, XX, XX },
1361 { "lidtQ", M, XX, XX },
1362 { "smswQ", Ev, XX, XX },
1363 { "(bad)", XX, XX, XX },
1364 { "lmsw", Ew, XX, XX },
1365 { "invlpg", INVLPG_Fixup, w_mode, XX, XX },
1367 /* GRP8 */
1369 { "(bad)", XX, XX, XX },
1370 { "(bad)", XX, XX, XX },
1371 { "(bad)", XX, XX, XX },
1372 { "(bad)", XX, XX, XX },
1373 { "btQ", Ev, Ib, XX },
1374 { "btsQ", Ev, Ib, XX },
1375 { "btrQ", Ev, Ib, XX },
1376 { "btcQ", Ev, Ib, XX },
1378 /* GRP9 */
1380 { "(bad)", XX, XX, XX },
1381 { "cmpxchg8b", Ev, 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 },
1387 { "(bad)", XX, XX, XX },
1389 /* GRP10 */
1391 { "(bad)", XX, XX, XX },
1392 { "(bad)", XX, XX, XX },
1393 { "psrlw", MS, Ib, XX },
1394 { "(bad)", XX, XX, XX },
1395 { "psraw", MS, Ib, XX },
1396 { "(bad)", XX, XX, XX },
1397 { "psllw", MS, Ib, XX },
1398 { "(bad)", XX, XX, XX },
1400 /* GRP11 */
1402 { "(bad)", XX, XX, XX },
1403 { "(bad)", XX, XX, XX },
1404 { "psrld", MS, Ib, XX },
1405 { "(bad)", XX, XX, XX },
1406 { "psrad", MS, Ib, XX },
1407 { "(bad)", XX, XX, XX },
1408 { "pslld", MS, Ib, XX },
1409 { "(bad)", XX, XX, XX },
1411 /* GRP12 */
1413 { "(bad)", XX, XX, XX },
1414 { "(bad)", XX, XX, XX },
1415 { "psrlq", MS, Ib, XX },
1416 { "psrldq", MS, Ib, XX },
1417 { "(bad)", XX, XX, XX },
1418 { "(bad)", XX, XX, XX },
1419 { "psllq", MS, Ib, XX },
1420 { "pslldq", MS, Ib, XX },
1422 /* GRP13 */
1424 { "fxsave", Ev, XX, XX },
1425 { "fxrstor", Ev, XX, XX },
1426 { "ldmxcsr", Ev, XX, XX },
1427 { "stmxcsr", Ev, XX, XX },
1428 { "(bad)", XX, XX, XX },
1429 { "lfence", OP_0fae, 0, XX, XX },
1430 { "mfence", OP_0fae, 0, XX, XX },
1431 { "clflush", OP_0fae, 0, XX, XX },
1433 /* GRP14 */
1435 { "prefetchnta", Ev, XX, XX },
1436 { "prefetcht0", Ev, XX, XX },
1437 { "prefetcht1", Ev, XX, XX },
1438 { "prefetcht2", Ev, XX, XX },
1439 { "(bad)", XX, XX, XX },
1440 { "(bad)", XX, XX, XX },
1441 { "(bad)", XX, XX, XX },
1442 { "(bad)", XX, XX, XX },
1444 /* GRPAMD */
1446 { "prefetch", Eb, XX, XX },
1447 { "prefetchw", Eb, 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 },
1453 { "(bad)", XX, XX, XX },
1455 /* GRPPADLCK1 */
1457 { "xstorerng", OP_0f07, 0, XX, XX },
1458 { "xcryptecb", OP_0f07, 0, XX, XX },
1459 { "xcryptcbc", OP_0f07, 0, XX, XX },
1460 { "(bad)", OP_0f07, 0, XX, XX },
1461 { "xcryptcfb", OP_0f07, 0, XX, XX },
1462 { "xcryptofb", OP_0f07, 0, XX, XX },
1463 { "(bad)", OP_0f07, 0, XX, XX },
1464 { "(bad)", OP_0f07, 0, XX, XX },
1466 /* GRPPADLCK2 */
1468 { "montmul", OP_0f07, 0, XX, XX },
1469 { "xsha1", OP_0f07, 0, XX, XX },
1470 { "xsha256", OP_0f07, 0, XX, XX },
1471 { "(bad)", OP_0f07, 0, XX, XX },
1472 { "(bad)", OP_0f07, 0, XX, XX },
1473 { "(bad)", OP_0f07, 0, XX, XX },
1474 { "(bad)", OP_0f07, 0, XX, XX },
1475 { "(bad)", OP_0f07, 0, XX, XX },
1479 static const struct dis386 prefix_user_table[][4] = {
1480 /* PREGRP0 */
1482 { "addps", XM, EX, XX },
1483 { "addss", XM, EX, XX },
1484 { "addpd", XM, EX, XX },
1485 { "addsd", XM, EX, XX },
1487 /* PREGRP1 */
1489 { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */
1490 { "", XM, EX, OPSIMD },
1491 { "", XM, EX, OPSIMD },
1492 { "", XM, EX, OPSIMD },
1494 /* PREGRP2 */
1496 { "cvtpi2ps", XM, EM, XX },
1497 { "cvtsi2ssY", XM, Ev, XX },
1498 { "cvtpi2pd", XM, EM, XX },
1499 { "cvtsi2sdY", XM, Ev, XX },
1501 /* PREGRP3 */
1503 { "cvtps2pi", MX, EX, XX },
1504 { "cvtss2siY", Gv, EX, XX },
1505 { "cvtpd2pi", MX, EX, XX },
1506 { "cvtsd2siY", Gv, EX, XX },
1508 /* PREGRP4 */
1510 { "cvttps2pi", MX, EX, XX },
1511 { "cvttss2siY", Gv, EX, XX },
1512 { "cvttpd2pi", MX, EX, XX },
1513 { "cvttsd2siY", Gv, EX, XX },
1515 /* PREGRP5 */
1517 { "divps", XM, EX, XX },
1518 { "divss", XM, EX, XX },
1519 { "divpd", XM, EX, XX },
1520 { "divsd", XM, EX, XX },
1522 /* PREGRP6 */
1524 { "maxps", XM, EX, XX },
1525 { "maxss", XM, EX, XX },
1526 { "maxpd", XM, EX, XX },
1527 { "maxsd", XM, EX, XX },
1529 /* PREGRP7 */
1531 { "minps", XM, EX, XX },
1532 { "minss", XM, EX, XX },
1533 { "minpd", XM, EX, XX },
1534 { "minsd", XM, EX, XX },
1536 /* PREGRP8 */
1538 { "movups", XM, EX, XX },
1539 { "movss", XM, EX, XX },
1540 { "movupd", XM, EX, XX },
1541 { "movsd", XM, EX, XX },
1543 /* PREGRP9 */
1545 { "movups", EX, XM, XX },
1546 { "movss", EX, XM, XX },
1547 { "movupd", EX, XM, XX },
1548 { "movsd", EX, XM, XX },
1550 /* PREGRP10 */
1552 { "mulps", XM, EX, XX },
1553 { "mulss", XM, EX, XX },
1554 { "mulpd", XM, EX, XX },
1555 { "mulsd", XM, EX, XX },
1557 /* PREGRP11 */
1559 { "rcpps", XM, EX, XX },
1560 { "rcpss", XM, EX, XX },
1561 { "(bad)", XM, EX, XX },
1562 { "(bad)", XM, EX, XX },
1564 /* PREGRP12 */
1566 { "rsqrtps", XM, EX, XX },
1567 { "rsqrtss", XM, EX, XX },
1568 { "(bad)", XM, EX, XX },
1569 { "(bad)", XM, EX, XX },
1571 /* PREGRP13 */
1573 { "sqrtps", XM, EX, XX },
1574 { "sqrtss", XM, EX, XX },
1575 { "sqrtpd", XM, EX, XX },
1576 { "sqrtsd", XM, EX, XX },
1578 /* PREGRP14 */
1580 { "subps", XM, EX, XX },
1581 { "subss", XM, EX, XX },
1582 { "subpd", XM, EX, XX },
1583 { "subsd", XM, EX, XX },
1585 /* PREGRP15 */
1587 { "(bad)", XM, EX, XX },
1588 { "cvtdq2pd", XM, EX, XX },
1589 { "cvttpd2dq", XM, EX, XX },
1590 { "cvtpd2dq", XM, EX, XX },
1592 /* PREGRP16 */
1594 { "cvtdq2ps", XM, EX, XX },
1595 { "cvttps2dq",XM, EX, XX },
1596 { "cvtps2dq",XM, EX, XX },
1597 { "(bad)", XM, EX, XX },
1599 /* PREGRP17 */
1601 { "cvtps2pd", XM, EX, XX },
1602 { "cvtss2sd", XM, EX, XX },
1603 { "cvtpd2ps", XM, EX, XX },
1604 { "cvtsd2ss", XM, EX, XX },
1606 /* PREGRP18 */
1608 { "maskmovq", MX, MS, XX },
1609 { "(bad)", XM, EX, XX },
1610 { "maskmovdqu", XM, EX, XX },
1611 { "(bad)", XM, EX, XX },
1613 /* PREGRP19 */
1615 { "movq", MX, EM, XX },
1616 { "movdqu", XM, EX, XX },
1617 { "movdqa", XM, EX, XX },
1618 { "(bad)", XM, EX, XX },
1620 /* PREGRP20 */
1622 { "movq", EM, MX, XX },
1623 { "movdqu", EX, XM, XX },
1624 { "movdqa", EX, XM, XX },
1625 { "(bad)", EX, XM, XX },
1627 /* PREGRP21 */
1629 { "(bad)", EX, XM, XX },
1630 { "movq2dq", XM, MS, XX },
1631 { "movq", EX, XM, XX },
1632 { "movdq2q", MX, XS, XX },
1634 /* PREGRP22 */
1636 { "pshufw", MX, EM, Ib },
1637 { "pshufhw", XM, EX, Ib },
1638 { "pshufd", XM, EX, Ib },
1639 { "pshuflw", XM, EX, Ib },
1641 /* PREGRP23 */
1643 { "movd", Edq, MX, XX },
1644 { "movq", XM, EX, XX },
1645 { "movd", Edq, XM, XX },
1646 { "(bad)", Ed, XM, XX },
1648 /* PREGRP24 */
1650 { "(bad)", MX, EX, XX },
1651 { "(bad)", XM, EX, XX },
1652 { "punpckhqdq", XM, EX, XX },
1653 { "(bad)", XM, EX, XX },
1655 /* PREGRP25 */
1657 { "movntq", Ev, MX, XX },
1658 { "(bad)", Ev, XM, XX },
1659 { "movntdq", Ev, XM, XX },
1660 { "(bad)", Ev, XM, XX },
1662 /* PREGRP26 */
1664 { "(bad)", MX, EX, XX },
1665 { "(bad)", XM, EX, XX },
1666 { "punpcklqdq", XM, EX, XX },
1667 { "(bad)", XM, EX, XX },
1669 /* PREGRP27 */
1671 { "(bad)", MX, EX, XX },
1672 { "(bad)", XM, EX, XX },
1673 { "addsubpd", XM, EX, XX },
1674 { "addsubps", XM, EX, XX },
1676 /* PREGRP28 */
1678 { "(bad)", MX, EX, XX },
1679 { "(bad)", XM, EX, XX },
1680 { "haddpd", XM, EX, XX },
1681 { "haddps", XM, EX, XX },
1683 /* PREGRP29 */
1685 { "(bad)", MX, EX, XX },
1686 { "(bad)", XM, EX, XX },
1687 { "hsubpd", XM, EX, XX },
1688 { "hsubps", XM, EX, XX },
1690 /* PREGRP30 */
1692 { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
1693 { "movsldup", XM, EX, XX },
1694 { "movlpd", XM, EX, XX },
1695 { "movddup", XM, EX, XX },
1697 /* PREGRP31 */
1699 { "movhpX", XM, EX, SIMD_Fixup, 'l' },
1700 { "movshdup", XM, EX, XX },
1701 { "movhpd", XM, EX, XX },
1702 { "(bad)", XM, EX, XX },
1704 /* PREGRP32 */
1706 { "(bad)", XM, EX, XX },
1707 { "(bad)", XM, EX, XX },
1708 { "(bad)", XM, EX, XX },
1709 { "lddqu", XM, M, XX },
1713 static const struct dis386 x86_64_table[][2] = {
1715 { "arpl", Ew, Gw, XX },
1716 { "movs{||lq|xd}", Gv, Ed, XX },
1720 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1722 static void
1723 ckprefix (void)
1725 int newrex;
1726 rex = 0;
1727 prefixes = 0;
1728 used_prefixes = 0;
1729 rex_used = 0;
1730 while (1)
1732 FETCH_DATA (the_info, codep + 1);
1733 newrex = 0;
1734 switch (*codep)
1736 /* REX prefixes family. */
1737 case 0x40:
1738 case 0x41:
1739 case 0x42:
1740 case 0x43:
1741 case 0x44:
1742 case 0x45:
1743 case 0x46:
1744 case 0x47:
1745 case 0x48:
1746 case 0x49:
1747 case 0x4a:
1748 case 0x4b:
1749 case 0x4c:
1750 case 0x4d:
1751 case 0x4e:
1752 case 0x4f:
1753 if (mode_64bit)
1754 newrex = *codep;
1755 else
1756 return;
1757 break;
1758 case 0xf3:
1759 prefixes |= PREFIX_REPZ;
1760 break;
1761 case 0xf2:
1762 prefixes |= PREFIX_REPNZ;
1763 break;
1764 case 0xf0:
1765 prefixes |= PREFIX_LOCK;
1766 break;
1767 case 0x2e:
1768 prefixes |= PREFIX_CS;
1769 break;
1770 case 0x36:
1771 prefixes |= PREFIX_SS;
1772 break;
1773 case 0x3e:
1774 prefixes |= PREFIX_DS;
1775 break;
1776 case 0x26:
1777 prefixes |= PREFIX_ES;
1778 break;
1779 case 0x64:
1780 prefixes |= PREFIX_FS;
1781 break;
1782 case 0x65:
1783 prefixes |= PREFIX_GS;
1784 break;
1785 case 0x66:
1786 prefixes |= PREFIX_DATA;
1787 break;
1788 case 0x67:
1789 prefixes |= PREFIX_ADDR;
1790 break;
1791 case FWAIT_OPCODE:
1792 /* fwait is really an instruction. If there are prefixes
1793 before the fwait, they belong to the fwait, *not* to the
1794 following instruction. */
1795 if (prefixes)
1797 prefixes |= PREFIX_FWAIT;
1798 codep++;
1799 return;
1801 prefixes = PREFIX_FWAIT;
1802 break;
1803 default:
1804 return;
1806 /* Rex is ignored when followed by another prefix. */
1807 if (rex)
1809 oappend (prefix_name (rex, 0));
1810 oappend (" ");
1812 rex = newrex;
1813 codep++;
1817 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
1818 prefix byte. */
1820 static const char *
1821 prefix_name (int pref, int sizeflag)
1823 switch (pref)
1825 /* REX prefixes family. */
1826 case 0x40:
1827 return "rex";
1828 case 0x41:
1829 return "rexZ";
1830 case 0x42:
1831 return "rexY";
1832 case 0x43:
1833 return "rexYZ";
1834 case 0x44:
1835 return "rexX";
1836 case 0x45:
1837 return "rexXZ";
1838 case 0x46:
1839 return "rexXY";
1840 case 0x47:
1841 return "rexXYZ";
1842 case 0x48:
1843 return "rex64";
1844 case 0x49:
1845 return "rex64Z";
1846 case 0x4a:
1847 return "rex64Y";
1848 case 0x4b:
1849 return "rex64YZ";
1850 case 0x4c:
1851 return "rex64X";
1852 case 0x4d:
1853 return "rex64XZ";
1854 case 0x4e:
1855 return "rex64XY";
1856 case 0x4f:
1857 return "rex64XYZ";
1858 case 0xf3:
1859 return "repz";
1860 case 0xf2:
1861 return "repnz";
1862 case 0xf0:
1863 return "lock";
1864 case 0x2e:
1865 return "cs";
1866 case 0x36:
1867 return "ss";
1868 case 0x3e:
1869 return "ds";
1870 case 0x26:
1871 return "es";
1872 case 0x64:
1873 return "fs";
1874 case 0x65:
1875 return "gs";
1876 case 0x66:
1877 return (sizeflag & DFLAG) ? "data16" : "data32";
1878 case 0x67:
1879 if (mode_64bit)
1880 return (sizeflag & AFLAG) ? "addr32" : "addr64";
1881 else
1882 return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32";
1883 case FWAIT_OPCODE:
1884 return "fwait";
1885 default:
1886 return NULL;
1890 static char op1out[100], op2out[100], op3out[100];
1891 static int op_ad, op_index[3];
1892 static int two_source_ops;
1893 static bfd_vma op_address[3];
1894 static bfd_vma op_riprel[3];
1895 static bfd_vma start_pc;
1898 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1899 * (see topic "Redundant prefixes" in the "Differences from 8086"
1900 * section of the "Virtual 8086 Mode" chapter.)
1901 * 'pc' should be the address of this instruction, it will
1902 * be used to print the target address if this is a relative jump or call
1903 * The function returns the length of this instruction in bytes.
1906 static char intel_syntax;
1907 static char open_char;
1908 static char close_char;
1909 static char separator_char;
1910 static char scale_char;
1912 /* Here for backwards compatibility. When gdb stops using
1913 print_insn_i386_att and print_insn_i386_intel these functions can
1914 disappear, and print_insn_i386 be merged into print_insn. */
1916 print_insn_i386_att (bfd_vma pc, disassemble_info *info)
1918 intel_syntax = 0;
1920 return print_insn (pc, info);
1924 print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
1926 intel_syntax = 1;
1928 return print_insn (pc, info);
1932 print_insn_i386 (bfd_vma pc, disassemble_info *info)
1934 intel_syntax = -1;
1936 return print_insn (pc, info);
1939 static int
1940 print_insn (bfd_vma pc, disassemble_info *info)
1942 const struct dis386 *dp;
1943 int i;
1944 char *first, *second, *third;
1945 int needcomma;
1946 unsigned char uses_SSE_prefix;
1947 int sizeflag;
1948 const char *p;
1949 struct dis_private priv;
1951 mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
1952 || info->mach == bfd_mach_x86_64);
1954 if (intel_syntax == (char) -1)
1955 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
1956 || info->mach == bfd_mach_x86_64_intel_syntax);
1958 if (info->mach == bfd_mach_i386_i386
1959 || info->mach == bfd_mach_x86_64
1960 || info->mach == bfd_mach_i386_i386_intel_syntax
1961 || info->mach == bfd_mach_x86_64_intel_syntax)
1962 priv.orig_sizeflag = AFLAG | DFLAG;
1963 else if (info->mach == bfd_mach_i386_i8086)
1964 priv.orig_sizeflag = 0;
1965 else
1966 abort ();
1968 for (p = info->disassembler_options; p != NULL; )
1970 if (strncmp (p, "x86-64", 6) == 0)
1972 mode_64bit = 1;
1973 priv.orig_sizeflag = AFLAG | DFLAG;
1975 else if (strncmp (p, "i386", 4) == 0)
1977 mode_64bit = 0;
1978 priv.orig_sizeflag = AFLAG | DFLAG;
1980 else if (strncmp (p, "i8086", 5) == 0)
1982 mode_64bit = 0;
1983 priv.orig_sizeflag = 0;
1985 else if (strncmp (p, "intel", 5) == 0)
1987 intel_syntax = 1;
1989 else if (strncmp (p, "att", 3) == 0)
1991 intel_syntax = 0;
1993 else if (strncmp (p, "addr", 4) == 0)
1995 if (p[4] == '1' && p[5] == '6')
1996 priv.orig_sizeflag &= ~AFLAG;
1997 else if (p[4] == '3' && p[5] == '2')
1998 priv.orig_sizeflag |= AFLAG;
2000 else if (strncmp (p, "data", 4) == 0)
2002 if (p[4] == '1' && p[5] == '6')
2003 priv.orig_sizeflag &= ~DFLAG;
2004 else if (p[4] == '3' && p[5] == '2')
2005 priv.orig_sizeflag |= DFLAG;
2007 else if (strncmp (p, "suffix", 6) == 0)
2008 priv.orig_sizeflag |= SUFFIX_ALWAYS;
2010 p = strchr (p, ',');
2011 if (p != NULL)
2012 p++;
2015 if (intel_syntax)
2017 names64 = intel_names64;
2018 names32 = intel_names32;
2019 names16 = intel_names16;
2020 names8 = intel_names8;
2021 names8rex = intel_names8rex;
2022 names_seg = intel_names_seg;
2023 index16 = intel_index16;
2024 open_char = '[';
2025 close_char = ']';
2026 separator_char = '+';
2027 scale_char = '*';
2029 else
2031 names64 = att_names64;
2032 names32 = att_names32;
2033 names16 = att_names16;
2034 names8 = att_names8;
2035 names8rex = att_names8rex;
2036 names_seg = att_names_seg;
2037 index16 = att_index16;
2038 open_char = '(';
2039 close_char = ')';
2040 separator_char = ',';
2041 scale_char = ',';
2044 /* The output looks better if we put 7 bytes on a line, since that
2045 puts most long word instructions on a single line. */
2046 info->bytes_per_line = 7;
2048 info->private_data = &priv;
2049 priv.max_fetched = priv.the_buffer;
2050 priv.insn_start = pc;
2052 obuf[0] = 0;
2053 op1out[0] = 0;
2054 op2out[0] = 0;
2055 op3out[0] = 0;
2057 op_index[0] = op_index[1] = op_index[2] = -1;
2059 the_info = info;
2060 start_pc = pc;
2061 start_codep = priv.the_buffer;
2062 codep = priv.the_buffer;
2064 if (setjmp (priv.bailout) != 0)
2066 const char *name;
2068 /* Getting here means we tried for data but didn't get it. That
2069 means we have an incomplete instruction of some sort. Just
2070 print the first byte as a prefix or a .byte pseudo-op. */
2071 if (codep > priv.the_buffer)
2073 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2074 if (name != NULL)
2075 (*info->fprintf_func) (info->stream, "%s", name);
2076 else
2078 /* Just print the first byte as a .byte instruction. */
2079 (*info->fprintf_func) (info->stream, ".byte 0x%x",
2080 (unsigned int) priv.the_buffer[0]);
2083 return 1;
2086 return -1;
2089 obufp = obuf;
2090 ckprefix ();
2092 insn_codep = codep;
2093 sizeflag = priv.orig_sizeflag;
2095 FETCH_DATA (info, codep + 1);
2096 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
2098 if ((prefixes & PREFIX_FWAIT)
2099 && ((*codep < 0xd8) || (*codep > 0xdf)))
2101 const char *name;
2103 /* fwait not followed by floating point instruction. Print the
2104 first prefix, which is probably fwait itself. */
2105 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2106 if (name == NULL)
2107 name = INTERNAL_DISASSEMBLER_ERROR;
2108 (*info->fprintf_func) (info->stream, "%s", name);
2109 return 1;
2112 if (*codep == 0x0f)
2114 FETCH_DATA (info, codep + 2);
2115 dp = &dis386_twobyte[*++codep];
2116 need_modrm = twobyte_has_modrm[*codep];
2117 uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
2119 else
2121 dp = &dis386[*codep];
2122 need_modrm = onebyte_has_modrm[*codep];
2123 uses_SSE_prefix = 0;
2125 codep++;
2127 if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
2129 oappend ("repz ");
2130 used_prefixes |= PREFIX_REPZ;
2132 if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
2134 oappend ("repnz ");
2135 used_prefixes |= PREFIX_REPNZ;
2137 if (prefixes & PREFIX_LOCK)
2139 oappend ("lock ");
2140 used_prefixes |= PREFIX_LOCK;
2143 if (prefixes & PREFIX_ADDR)
2145 sizeflag ^= AFLAG;
2146 if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
2148 if ((sizeflag & AFLAG) || mode_64bit)
2149 oappend ("addr32 ");
2150 else
2151 oappend ("addr16 ");
2152 used_prefixes |= PREFIX_ADDR;
2156 if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
2158 sizeflag ^= DFLAG;
2159 if (dp->bytemode3 == cond_jump_mode
2160 && dp->bytemode1 == v_mode
2161 && !intel_syntax)
2163 if (sizeflag & DFLAG)
2164 oappend ("data32 ");
2165 else
2166 oappend ("data16 ");
2167 used_prefixes |= PREFIX_DATA;
2171 if (need_modrm)
2173 FETCH_DATA (info, codep + 1);
2174 mod = (*codep >> 6) & 3;
2175 reg = (*codep >> 3) & 7;
2176 rm = *codep & 7;
2179 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2181 dofloat (sizeflag);
2183 else
2185 int index;
2186 if (dp->name == NULL)
2188 switch (dp->bytemode1)
2190 case USE_GROUPS:
2191 dp = &grps[dp->bytemode2][reg];
2192 break;
2194 case USE_PREFIX_USER_TABLE:
2195 index = 0;
2196 used_prefixes |= (prefixes & PREFIX_REPZ);
2197 if (prefixes & PREFIX_REPZ)
2198 index = 1;
2199 else
2201 used_prefixes |= (prefixes & PREFIX_DATA);
2202 if (prefixes & PREFIX_DATA)
2203 index = 2;
2204 else
2206 used_prefixes |= (prefixes & PREFIX_REPNZ);
2207 if (prefixes & PREFIX_REPNZ)
2208 index = 3;
2211 dp = &prefix_user_table[dp->bytemode2][index];
2212 break;
2214 case X86_64_SPECIAL:
2215 dp = &x86_64_table[dp->bytemode2][mode_64bit];
2216 break;
2218 default:
2219 oappend (INTERNAL_DISASSEMBLER_ERROR);
2220 break;
2224 if (putop (dp->name, sizeflag) == 0)
2226 obufp = op1out;
2227 op_ad = 2;
2228 if (dp->op1)
2229 (*dp->op1) (dp->bytemode1, sizeflag);
2231 obufp = op2out;
2232 op_ad = 1;
2233 if (dp->op2)
2234 (*dp->op2) (dp->bytemode2, sizeflag);
2236 obufp = op3out;
2237 op_ad = 0;
2238 if (dp->op3)
2239 (*dp->op3) (dp->bytemode3, sizeflag);
2243 /* See if any prefixes were not used. If so, print the first one
2244 separately. If we don't do this, we'll wind up printing an
2245 instruction stream which does not precisely correspond to the
2246 bytes we are disassembling. */
2247 if ((prefixes & ~used_prefixes) != 0)
2249 const char *name;
2251 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2252 if (name == NULL)
2253 name = INTERNAL_DISASSEMBLER_ERROR;
2254 (*info->fprintf_func) (info->stream, "%s", name);
2255 return 1;
2257 if (rex & ~rex_used)
2259 const char *name;
2260 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
2261 if (name == NULL)
2262 name = INTERNAL_DISASSEMBLER_ERROR;
2263 (*info->fprintf_func) (info->stream, "%s ", name);
2266 obufp = obuf + strlen (obuf);
2267 for (i = strlen (obuf); i < 6; i++)
2268 oappend (" ");
2269 oappend (" ");
2270 (*info->fprintf_func) (info->stream, "%s", obuf);
2272 /* The enter and bound instructions are printed with operands in the same
2273 order as the intel book; everything else is printed in reverse order. */
2274 if (intel_syntax || two_source_ops)
2276 first = op1out;
2277 second = op2out;
2278 third = op3out;
2279 op_ad = op_index[0];
2280 op_index[0] = op_index[2];
2281 op_index[2] = op_ad;
2283 else
2285 first = op3out;
2286 second = op2out;
2287 third = op1out;
2289 needcomma = 0;
2290 if (*first)
2292 if (op_index[0] != -1 && !op_riprel[0])
2293 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
2294 else
2295 (*info->fprintf_func) (info->stream, "%s", first);
2296 needcomma = 1;
2298 if (*second)
2300 if (needcomma)
2301 (*info->fprintf_func) (info->stream, ",");
2302 if (op_index[1] != -1 && !op_riprel[1])
2303 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
2304 else
2305 (*info->fprintf_func) (info->stream, "%s", second);
2306 needcomma = 1;
2308 if (*third)
2310 if (needcomma)
2311 (*info->fprintf_func) (info->stream, ",");
2312 if (op_index[2] != -1 && !op_riprel[2])
2313 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
2314 else
2315 (*info->fprintf_func) (info->stream, "%s", third);
2317 for (i = 0; i < 3; i++)
2318 if (op_index[i] != -1 && op_riprel[i])
2320 (*info->fprintf_func) (info->stream, " # ");
2321 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
2322 + op_address[op_index[i]]), info);
2324 return codep - priv.the_buffer;
2327 static const char *float_mem[] = {
2328 /* d8 */
2329 "fadd{s||s|}",
2330 "fmul{s||s|}",
2331 "fcom{s||s|}",
2332 "fcomp{s||s|}",
2333 "fsub{s||s|}",
2334 "fsubr{s||s|}",
2335 "fdiv{s||s|}",
2336 "fdivr{s||s|}",
2337 /* d9 */
2338 "fld{s||s|}",
2339 "(bad)",
2340 "fst{s||s|}",
2341 "fstp{s||s|}",
2342 "fldenv",
2343 "fldcw",
2344 "fNstenv",
2345 "fNstcw",
2346 /* da */
2347 "fiadd{l||l|}",
2348 "fimul{l||l|}",
2349 "ficom{l||l|}",
2350 "ficomp{l||l|}",
2351 "fisub{l||l|}",
2352 "fisubr{l||l|}",
2353 "fidiv{l||l|}",
2354 "fidivr{l||l|}",
2355 /* db */
2356 "fild{l||l|}",
2357 "fisttp{l||l|}",
2358 "fist{l||l|}",
2359 "fistp{l||l|}",
2360 "(bad)",
2361 "fld{t||t|}",
2362 "(bad)",
2363 "fstp{t||t|}",
2364 /* dc */
2365 "fadd{l||l|}",
2366 "fmul{l||l|}",
2367 "fcom{l||l|}",
2368 "fcomp{l||l|}",
2369 "fsub{l||l|}",
2370 "fsubr{l||l|}",
2371 "fdiv{l||l|}",
2372 "fdivr{l||l|}",
2373 /* dd */
2374 "fld{l||l|}",
2375 "fisttp{ll||ll|}",
2376 "fst{l||l|}",
2377 "fstp{l||l|}",
2378 "frstor",
2379 "(bad)",
2380 "fNsave",
2381 "fNstsw",
2382 /* de */
2383 "fiadd",
2384 "fimul",
2385 "ficom",
2386 "ficomp",
2387 "fisub",
2388 "fisubr",
2389 "fidiv",
2390 "fidivr",
2391 /* df */
2392 "fild",
2393 "fisttp",
2394 "fist",
2395 "fistp",
2396 "fbld",
2397 "fild{ll||ll|}",
2398 "fbstp",
2399 "fistp{ll||ll|}",
2402 static const unsigned char float_mem_mode[] = {
2403 /* d8 */
2404 d_mode,
2405 d_mode,
2406 d_mode,
2407 d_mode,
2408 d_mode,
2409 d_mode,
2410 d_mode,
2411 d_mode,
2412 /* d9 */
2413 d_mode,
2415 d_mode,
2416 d_mode,
2418 w_mode,
2420 w_mode,
2421 /* da */
2422 d_mode,
2423 d_mode,
2424 d_mode,
2425 d_mode,
2426 d_mode,
2427 d_mode,
2428 d_mode,
2429 d_mode,
2430 /* db */
2431 d_mode,
2432 d_mode,
2433 d_mode,
2434 d_mode,
2436 x_mode,
2438 x_mode,
2439 /* dc */
2440 q_mode,
2441 q_mode,
2442 q_mode,
2443 q_mode,
2444 q_mode,
2445 q_mode,
2446 q_mode,
2447 q_mode,
2448 /* dd */
2449 q_mode,
2450 q_mode,
2451 q_mode,
2452 q_mode,
2456 w_mode,
2457 /* de */
2458 w_mode,
2459 w_mode,
2460 w_mode,
2461 w_mode,
2462 w_mode,
2463 w_mode,
2464 w_mode,
2465 w_mode,
2466 /* df */
2467 w_mode,
2468 w_mode,
2469 w_mode,
2470 w_mode,
2471 x_mode,
2472 q_mode,
2473 x_mode,
2474 q_mode
2477 #define ST OP_ST, 0
2478 #define STi OP_STi, 0
2480 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
2481 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
2482 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
2483 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
2484 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
2485 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
2486 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
2487 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
2488 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
2490 static const struct dis386 float_reg[][8] = {
2491 /* d8 */
2493 { "fadd", ST, STi, XX },
2494 { "fmul", ST, STi, XX },
2495 { "fcom", STi, XX, XX },
2496 { "fcomp", STi, XX, XX },
2497 { "fsub", ST, STi, XX },
2498 { "fsubr", ST, STi, XX },
2499 { "fdiv", ST, STi, XX },
2500 { "fdivr", ST, STi, XX },
2502 /* d9 */
2504 { "fld", STi, XX, XX },
2505 { "fxch", STi, XX, XX },
2506 { FGRPd9_2 },
2507 { "(bad)", XX, XX, XX },
2508 { FGRPd9_4 },
2509 { FGRPd9_5 },
2510 { FGRPd9_6 },
2511 { FGRPd9_7 },
2513 /* da */
2515 { "fcmovb", ST, STi, XX },
2516 { "fcmove", ST, STi, XX },
2517 { "fcmovbe",ST, STi, XX },
2518 { "fcmovu", ST, STi, XX },
2519 { "(bad)", XX, XX, XX },
2520 { FGRPda_5 },
2521 { "(bad)", XX, XX, XX },
2522 { "(bad)", XX, XX, XX },
2524 /* db */
2526 { "fcmovnb",ST, STi, XX },
2527 { "fcmovne",ST, STi, XX },
2528 { "fcmovnbe",ST, STi, XX },
2529 { "fcmovnu",ST, STi, XX },
2530 { FGRPdb_4 },
2531 { "fucomi", ST, STi, XX },
2532 { "fcomi", ST, STi, XX },
2533 { "(bad)", XX, XX, XX },
2535 /* dc */
2537 { "fadd", STi, ST, XX },
2538 { "fmul", STi, ST, XX },
2539 { "(bad)", XX, XX, XX },
2540 { "(bad)", XX, XX, XX },
2541 #if UNIXWARE_COMPAT
2542 { "fsub", STi, ST, XX },
2543 { "fsubr", STi, ST, XX },
2544 { "fdiv", STi, ST, XX },
2545 { "fdivr", STi, ST, XX },
2546 #else
2547 { "fsubr", STi, ST, XX },
2548 { "fsub", STi, ST, XX },
2549 { "fdivr", STi, ST, XX },
2550 { "fdiv", STi, ST, XX },
2551 #endif
2553 /* dd */
2555 { "ffree", STi, XX, XX },
2556 { "(bad)", XX, XX, XX },
2557 { "fst", STi, XX, XX },
2558 { "fstp", STi, XX, XX },
2559 { "fucom", STi, XX, XX },
2560 { "fucomp", STi, XX, XX },
2561 { "(bad)", XX, XX, XX },
2562 { "(bad)", XX, XX, XX },
2564 /* de */
2566 { "faddp", STi, ST, XX },
2567 { "fmulp", STi, ST, XX },
2568 { "(bad)", XX, XX, XX },
2569 { FGRPde_3 },
2570 #if UNIXWARE_COMPAT
2571 { "fsubp", STi, ST, XX },
2572 { "fsubrp", STi, ST, XX },
2573 { "fdivp", STi, ST, XX },
2574 { "fdivrp", STi, ST, XX },
2575 #else
2576 { "fsubrp", STi, ST, XX },
2577 { "fsubp", STi, ST, XX },
2578 { "fdivrp", STi, ST, XX },
2579 { "fdivp", STi, ST, XX },
2580 #endif
2582 /* df */
2584 { "ffreep", STi, XX, XX },
2585 { "(bad)", XX, XX, XX },
2586 { "(bad)", XX, XX, XX },
2587 { "(bad)", XX, XX, XX },
2588 { FGRPdf_4 },
2589 { "fucomip",ST, STi, XX },
2590 { "fcomip", ST, STi, XX },
2591 { "(bad)", XX, XX, XX },
2595 static char *fgrps[][8] = {
2596 /* d9_2 0 */
2598 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2601 /* d9_4 1 */
2603 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2606 /* d9_5 2 */
2608 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2611 /* d9_6 3 */
2613 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2616 /* d9_7 4 */
2618 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2621 /* da_5 5 */
2623 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2626 /* db_4 6 */
2628 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2629 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2632 /* de_3 7 */
2634 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2637 /* df_4 8 */
2639 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2643 static void
2644 dofloat (int sizeflag)
2646 const struct dis386 *dp;
2647 unsigned char floatop;
2649 floatop = codep[-1];
2651 if (mod != 3)
2653 int fp_indx = (floatop - 0xd8) * 8 + reg;
2655 putop (float_mem[fp_indx], sizeflag);
2656 obufp = op1out;
2657 OP_E (float_mem_mode[fp_indx], sizeflag);
2658 return;
2660 /* Skip mod/rm byte. */
2661 MODRM_CHECK;
2662 codep++;
2664 dp = &float_reg[floatop - 0xd8][reg];
2665 if (dp->name == NULL)
2667 putop (fgrps[dp->bytemode1][rm], sizeflag);
2669 /* Instruction fnstsw is only one with strange arg. */
2670 if (floatop == 0xdf && codep[-1] == 0xe0)
2671 strcpy (op1out, names16[0]);
2673 else
2675 putop (dp->name, sizeflag);
2677 obufp = op1out;
2678 if (dp->op1)
2679 (*dp->op1) (dp->bytemode1, sizeflag);
2680 obufp = op2out;
2681 if (dp->op2)
2682 (*dp->op2) (dp->bytemode2, sizeflag);
2686 static void
2687 OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
2689 oappend ("%st");
2692 static void
2693 OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
2695 sprintf (scratchbuf, "%%st(%d)", rm);
2696 oappend (scratchbuf + intel_syntax);
2699 /* Capital letters in template are macros. */
2700 static int
2701 putop (const char *template, int sizeflag)
2703 const char *p;
2704 int alt;
2706 for (p = template; *p; p++)
2708 switch (*p)
2710 default:
2711 *obufp++ = *p;
2712 break;
2713 case '{':
2714 alt = 0;
2715 if (intel_syntax)
2716 alt += 1;
2717 if (mode_64bit)
2718 alt += 2;
2719 while (alt != 0)
2721 while (*++p != '|')
2723 if (*p == '}')
2725 /* Alternative not valid. */
2726 strcpy (obuf, "(bad)");
2727 obufp = obuf + 5;
2728 return 1;
2730 else if (*p == '\0')
2731 abort ();
2733 alt--;
2735 break;
2736 case '|':
2737 while (*++p != '}')
2739 if (*p == '\0')
2740 abort ();
2742 break;
2743 case '}':
2744 break;
2745 case 'A':
2746 if (intel_syntax)
2747 break;
2748 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2749 *obufp++ = 'b';
2750 break;
2751 case 'B':
2752 if (intel_syntax)
2753 break;
2754 if (sizeflag & SUFFIX_ALWAYS)
2755 *obufp++ = 'b';
2756 break;
2757 case 'E': /* For jcxz/jecxz */
2758 if (mode_64bit)
2760 if (sizeflag & AFLAG)
2761 *obufp++ = 'r';
2762 else
2763 *obufp++ = 'e';
2765 else
2766 if (sizeflag & AFLAG)
2767 *obufp++ = 'e';
2768 used_prefixes |= (prefixes & PREFIX_ADDR);
2769 break;
2770 case 'F':
2771 if (intel_syntax)
2772 break;
2773 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
2775 if (sizeflag & AFLAG)
2776 *obufp++ = mode_64bit ? 'q' : 'l';
2777 else
2778 *obufp++ = mode_64bit ? 'l' : 'w';
2779 used_prefixes |= (prefixes & PREFIX_ADDR);
2781 break;
2782 case 'H':
2783 if (intel_syntax)
2784 break;
2785 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
2786 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
2788 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
2789 *obufp++ = ',';
2790 *obufp++ = 'p';
2791 if (prefixes & PREFIX_DS)
2792 *obufp++ = 't';
2793 else
2794 *obufp++ = 'n';
2796 break;
2797 case 'L':
2798 if (intel_syntax)
2799 break;
2800 if (sizeflag & SUFFIX_ALWAYS)
2801 *obufp++ = 'l';
2802 break;
2803 case 'N':
2804 if ((prefixes & PREFIX_FWAIT) == 0)
2805 *obufp++ = 'n';
2806 else
2807 used_prefixes |= PREFIX_FWAIT;
2808 break;
2809 case 'O':
2810 USED_REX (REX_MODE64);
2811 if (rex & REX_MODE64)
2812 *obufp++ = 'o';
2813 else
2814 *obufp++ = 'd';
2815 break;
2816 case 'T':
2817 if (intel_syntax)
2818 break;
2819 if (mode_64bit)
2821 *obufp++ = 'q';
2822 break;
2824 /* Fall through. */
2825 case 'P':
2826 if (intel_syntax)
2827 break;
2828 if ((prefixes & PREFIX_DATA)
2829 || (rex & REX_MODE64)
2830 || (sizeflag & SUFFIX_ALWAYS))
2832 USED_REX (REX_MODE64);
2833 if (rex & REX_MODE64)
2834 *obufp++ = 'q';
2835 else
2837 if (sizeflag & DFLAG)
2838 *obufp++ = 'l';
2839 else
2840 *obufp++ = 'w';
2841 used_prefixes |= (prefixes & PREFIX_DATA);
2844 break;
2845 case 'U':
2846 if (intel_syntax)
2847 break;
2848 if (mode_64bit)
2850 *obufp++ = 'q';
2851 break;
2853 /* Fall through. */
2854 case 'Q':
2855 if (intel_syntax)
2856 break;
2857 USED_REX (REX_MODE64);
2858 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2860 if (rex & REX_MODE64)
2861 *obufp++ = 'q';
2862 else
2864 if (sizeflag & DFLAG)
2865 *obufp++ = 'l';
2866 else
2867 *obufp++ = 'w';
2868 used_prefixes |= (prefixes & PREFIX_DATA);
2871 break;
2872 case 'R':
2873 USED_REX (REX_MODE64);
2874 if (intel_syntax)
2876 if (rex & REX_MODE64)
2878 *obufp++ = 'q';
2879 *obufp++ = 't';
2881 else if (sizeflag & DFLAG)
2883 *obufp++ = 'd';
2884 *obufp++ = 'q';
2886 else
2888 *obufp++ = 'w';
2889 *obufp++ = 'd';
2892 else
2894 if (rex & REX_MODE64)
2895 *obufp++ = 'q';
2896 else if (sizeflag & DFLAG)
2897 *obufp++ = 'l';
2898 else
2899 *obufp++ = 'w';
2901 if (!(rex & REX_MODE64))
2902 used_prefixes |= (prefixes & PREFIX_DATA);
2903 break;
2904 case 'S':
2905 if (intel_syntax)
2906 break;
2907 if (sizeflag & SUFFIX_ALWAYS)
2909 if (rex & REX_MODE64)
2910 *obufp++ = 'q';
2911 else
2913 if (sizeflag & DFLAG)
2914 *obufp++ = 'l';
2915 else
2916 *obufp++ = 'w';
2917 used_prefixes |= (prefixes & PREFIX_DATA);
2920 break;
2921 case 'X':
2922 if (prefixes & PREFIX_DATA)
2923 *obufp++ = 'd';
2924 else
2925 *obufp++ = 's';
2926 used_prefixes |= (prefixes & PREFIX_DATA);
2927 break;
2928 case 'Y':
2929 if (intel_syntax)
2930 break;
2931 if (rex & REX_MODE64)
2933 USED_REX (REX_MODE64);
2934 *obufp++ = 'q';
2936 break;
2937 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
2938 case 'W':
2939 /* operand size flag for cwtl, cbtw */
2940 USED_REX (0);
2941 if (rex)
2942 *obufp++ = 'l';
2943 else if (sizeflag & DFLAG)
2944 *obufp++ = 'w';
2945 else
2946 *obufp++ = 'b';
2947 if (intel_syntax)
2949 if (rex)
2951 *obufp++ = 'q';
2952 *obufp++ = 'e';
2954 if (sizeflag & DFLAG)
2956 *obufp++ = 'd';
2957 *obufp++ = 'e';
2959 else
2961 *obufp++ = 'w';
2964 if (!rex)
2965 used_prefixes |= (prefixes & PREFIX_DATA);
2966 break;
2969 *obufp = 0;
2970 return 0;
2973 static void
2974 oappend (const char *s)
2976 strcpy (obufp, s);
2977 obufp += strlen (s);
2980 static void
2981 append_seg (void)
2983 if (prefixes & PREFIX_CS)
2985 used_prefixes |= PREFIX_CS;
2986 oappend ("%cs:" + intel_syntax);
2988 if (prefixes & PREFIX_DS)
2990 used_prefixes |= PREFIX_DS;
2991 oappend ("%ds:" + intel_syntax);
2993 if (prefixes & PREFIX_SS)
2995 used_prefixes |= PREFIX_SS;
2996 oappend ("%ss:" + intel_syntax);
2998 if (prefixes & PREFIX_ES)
3000 used_prefixes |= PREFIX_ES;
3001 oappend ("%es:" + intel_syntax);
3003 if (prefixes & PREFIX_FS)
3005 used_prefixes |= PREFIX_FS;
3006 oappend ("%fs:" + intel_syntax);
3008 if (prefixes & PREFIX_GS)
3010 used_prefixes |= PREFIX_GS;
3011 oappend ("%gs:" + intel_syntax);
3015 static void
3016 OP_indirE (int bytemode, int sizeflag)
3018 if (!intel_syntax)
3019 oappend ("*");
3020 OP_E (bytemode, sizeflag);
3023 static void
3024 print_operand_value (char *buf, int hex, bfd_vma disp)
3026 if (mode_64bit)
3028 if (hex)
3030 char tmp[30];
3031 int i;
3032 buf[0] = '0';
3033 buf[1] = 'x';
3034 sprintf_vma (tmp, disp);
3035 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
3036 strcpy (buf + 2, tmp + i);
3038 else
3040 bfd_signed_vma v = disp;
3041 char tmp[30];
3042 int i;
3043 if (v < 0)
3045 *(buf++) = '-';
3046 v = -disp;
3047 /* Check for possible overflow on 0x8000000000000000. */
3048 if (v < 0)
3050 strcpy (buf, "9223372036854775808");
3051 return;
3054 if (!v)
3056 strcpy (buf, "0");
3057 return;
3060 i = 0;
3061 tmp[29] = 0;
3062 while (v)
3064 tmp[28 - i] = (v % 10) + '0';
3065 v /= 10;
3066 i++;
3068 strcpy (buf, tmp + 29 - i);
3071 else
3073 if (hex)
3074 sprintf (buf, "0x%x", (unsigned int) disp);
3075 else
3076 sprintf (buf, "%d", (int) disp);
3080 static void
3081 OP_E (int bytemode, int sizeflag)
3083 bfd_vma disp;
3084 int add = 0;
3085 int riprel = 0;
3086 USED_REX (REX_EXTZ);
3087 if (rex & REX_EXTZ)
3088 add += 8;
3090 /* Skip mod/rm byte. */
3091 MODRM_CHECK;
3092 codep++;
3094 if (mod == 3)
3096 switch (bytemode)
3098 case b_mode:
3099 USED_REX (0);
3100 if (rex)
3101 oappend (names8rex[rm + add]);
3102 else
3103 oappend (names8[rm + add]);
3104 break;
3105 case w_mode:
3106 oappend (names16[rm + add]);
3107 break;
3108 case d_mode:
3109 oappend (names32[rm + add]);
3110 break;
3111 case q_mode:
3112 oappend (names64[rm + add]);
3113 break;
3114 case m_mode:
3115 if (mode_64bit)
3116 oappend (names64[rm + add]);
3117 else
3118 oappend (names32[rm + add]);
3119 break;
3120 case v_mode:
3121 case dq_mode:
3122 USED_REX (REX_MODE64);
3123 if (rex & REX_MODE64)
3124 oappend (names64[rm + add]);
3125 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
3126 oappend (names32[rm + add]);
3127 else
3128 oappend (names16[rm + add]);
3129 used_prefixes |= (prefixes & PREFIX_DATA);
3130 break;
3131 case 0:
3132 break;
3133 default:
3134 oappend (INTERNAL_DISASSEMBLER_ERROR);
3135 break;
3137 return;
3140 disp = 0;
3141 append_seg ();
3143 if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
3145 int havesib;
3146 int havebase;
3147 int base;
3148 int index = 0;
3149 int scale = 0;
3151 havesib = 0;
3152 havebase = 1;
3153 base = rm;
3155 if (base == 4)
3157 havesib = 1;
3158 FETCH_DATA (the_info, codep + 1);
3159 scale = (*codep >> 6) & 3;
3160 index = (*codep >> 3) & 7;
3161 base = *codep & 7;
3162 USED_REX (REX_EXTY);
3163 USED_REX (REX_EXTZ);
3164 if (rex & REX_EXTY)
3165 index += 8;
3166 if (rex & REX_EXTZ)
3167 base += 8;
3168 codep++;
3171 switch (mod)
3173 case 0:
3174 if ((base & 7) == 5)
3176 havebase = 0;
3177 if (mode_64bit && !havesib)
3178 riprel = 1;
3179 disp = get32s ();
3181 break;
3182 case 1:
3183 FETCH_DATA (the_info, codep + 1);
3184 disp = *codep++;
3185 if ((disp & 0x80) != 0)
3186 disp -= 0x100;
3187 break;
3188 case 2:
3189 disp = get32s ();
3190 break;
3193 if (!intel_syntax)
3194 if (mod != 0 || (base & 7) == 5)
3196 print_operand_value (scratchbuf, !riprel, disp);
3197 oappend (scratchbuf);
3198 if (riprel)
3200 set_op (disp, 1);
3201 oappend ("(%rip)");
3205 if (havebase || (havesib && (index != 4 || scale != 0)))
3207 if (intel_syntax)
3209 switch (bytemode)
3211 case b_mode:
3212 oappend ("BYTE PTR ");
3213 break;
3214 case w_mode:
3215 oappend ("WORD PTR ");
3216 break;
3217 case v_mode:
3218 if (sizeflag & DFLAG)
3219 oappend ("DWORD PTR ");
3220 else
3221 oappend ("WORD PTR ");
3222 break;
3223 case d_mode:
3224 oappend ("DWORD PTR ");
3225 break;
3226 case q_mode:
3227 oappend ("QWORD PTR ");
3228 break;
3229 case m_mode:
3230 if (mode_64bit)
3231 oappend ("DWORD PTR ");
3232 else
3233 oappend ("QWORD PTR ");
3234 break;
3235 case x_mode:
3236 oappend ("XWORD PTR ");
3237 break;
3238 default:
3239 break;
3242 *obufp++ = open_char;
3243 if (intel_syntax && riprel)
3244 oappend ("rip + ");
3245 *obufp = '\0';
3246 USED_REX (REX_EXTZ);
3247 if (!havesib && (rex & REX_EXTZ))
3248 base += 8;
3249 if (havebase)
3250 oappend (mode_64bit && (sizeflag & AFLAG)
3251 ? names64[base] : names32[base]);
3252 if (havesib)
3254 if (index != 4)
3256 if (intel_syntax)
3258 if (havebase)
3260 *obufp++ = separator_char;
3261 *obufp = '\0';
3263 sprintf (scratchbuf, "%s",
3264 mode_64bit && (sizeflag & AFLAG)
3265 ? names64[index] : names32[index]);
3267 else
3268 sprintf (scratchbuf, ",%s",
3269 mode_64bit && (sizeflag & AFLAG)
3270 ? names64[index] : names32[index]);
3271 oappend (scratchbuf);
3273 if (scale != 0 || (!intel_syntax && index != 4))
3275 *obufp++ = scale_char;
3276 *obufp = '\0';
3277 sprintf (scratchbuf, "%d", 1 << scale);
3278 oappend (scratchbuf);
3281 if (intel_syntax)
3282 if (mod != 0 || (base & 7) == 5)
3284 /* Don't print zero displacements. */
3285 if (disp != 0)
3287 if ((bfd_signed_vma) disp > 0)
3289 *obufp++ = '+';
3290 *obufp = '\0';
3293 print_operand_value (scratchbuf, 0, disp);
3294 oappend (scratchbuf);
3298 *obufp++ = close_char;
3299 *obufp = '\0';
3301 else if (intel_syntax)
3303 if (mod != 0 || (base & 7) == 5)
3305 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3306 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
3308 else
3310 oappend (names_seg[ds_reg - es_reg]);
3311 oappend (":");
3313 print_operand_value (scratchbuf, 1, disp);
3314 oappend (scratchbuf);
3318 else
3319 { /* 16 bit address mode */
3320 switch (mod)
3322 case 0:
3323 if ((rm & 7) == 6)
3325 disp = get16 ();
3326 if ((disp & 0x8000) != 0)
3327 disp -= 0x10000;
3329 break;
3330 case 1:
3331 FETCH_DATA (the_info, codep + 1);
3332 disp = *codep++;
3333 if ((disp & 0x80) != 0)
3334 disp -= 0x100;
3335 break;
3336 case 2:
3337 disp = get16 ();
3338 if ((disp & 0x8000) != 0)
3339 disp -= 0x10000;
3340 break;
3343 if (!intel_syntax)
3344 if (mod != 0 || (rm & 7) == 6)
3346 print_operand_value (scratchbuf, 0, disp);
3347 oappend (scratchbuf);
3350 if (mod != 0 || (rm & 7) != 6)
3352 *obufp++ = open_char;
3353 *obufp = '\0';
3354 oappend (index16[rm + add]);
3355 *obufp++ = close_char;
3356 *obufp = '\0';
3361 static void
3362 OP_G (int bytemode, int sizeflag)
3364 int add = 0;
3365 USED_REX (REX_EXTX);
3366 if (rex & REX_EXTX)
3367 add += 8;
3368 switch (bytemode)
3370 case b_mode:
3371 USED_REX (0);
3372 if (rex)
3373 oappend (names8rex[reg + add]);
3374 else
3375 oappend (names8[reg + add]);
3376 break;
3377 case w_mode:
3378 oappend (names16[reg + add]);
3379 break;
3380 case d_mode:
3381 oappend (names32[reg + add]);
3382 break;
3383 case q_mode:
3384 oappend (names64[reg + add]);
3385 break;
3386 case v_mode:
3387 USED_REX (REX_MODE64);
3388 if (rex & REX_MODE64)
3389 oappend (names64[reg + add]);
3390 else if (sizeflag & DFLAG)
3391 oappend (names32[reg + add]);
3392 else
3393 oappend (names16[reg + add]);
3394 used_prefixes |= (prefixes & PREFIX_DATA);
3395 break;
3396 default:
3397 oappend (INTERNAL_DISASSEMBLER_ERROR);
3398 break;
3402 static bfd_vma
3403 get64 (void)
3405 bfd_vma x;
3406 #ifdef BFD64
3407 unsigned int a;
3408 unsigned int b;
3410 FETCH_DATA (the_info, codep + 8);
3411 a = *codep++ & 0xff;
3412 a |= (*codep++ & 0xff) << 8;
3413 a |= (*codep++ & 0xff) << 16;
3414 a |= (*codep++ & 0xff) << 24;
3415 b = *codep++ & 0xff;
3416 b |= (*codep++ & 0xff) << 8;
3417 b |= (*codep++ & 0xff) << 16;
3418 b |= (*codep++ & 0xff) << 24;
3419 x = a + ((bfd_vma) b << 32);
3420 #else
3421 abort ();
3422 x = 0;
3423 #endif
3424 return x;
3427 static bfd_signed_vma
3428 get32 (void)
3430 bfd_signed_vma x = 0;
3432 FETCH_DATA (the_info, codep + 4);
3433 x = *codep++ & (bfd_signed_vma) 0xff;
3434 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3435 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3436 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3437 return x;
3440 static bfd_signed_vma
3441 get32s (void)
3443 bfd_signed_vma x = 0;
3445 FETCH_DATA (the_info, codep + 4);
3446 x = *codep++ & (bfd_signed_vma) 0xff;
3447 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3448 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3449 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3451 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
3453 return x;
3456 static int
3457 get16 (void)
3459 int x = 0;
3461 FETCH_DATA (the_info, codep + 2);
3462 x = *codep++ & 0xff;
3463 x |= (*codep++ & 0xff) << 8;
3464 return x;
3467 static void
3468 set_op (bfd_vma op, int riprel)
3470 op_index[op_ad] = op_ad;
3471 if (mode_64bit)
3473 op_address[op_ad] = op;
3474 op_riprel[op_ad] = riprel;
3476 else
3478 /* Mask to get a 32-bit address. */
3479 op_address[op_ad] = op & 0xffffffff;
3480 op_riprel[op_ad] = riprel & 0xffffffff;
3484 static void
3485 OP_REG (int code, int sizeflag)
3487 const char *s;
3488 int add = 0;
3489 USED_REX (REX_EXTZ);
3490 if (rex & REX_EXTZ)
3491 add = 8;
3493 switch (code)
3495 case indir_dx_reg:
3496 if (intel_syntax)
3497 s = "[dx]";
3498 else
3499 s = "(%dx)";
3500 break;
3501 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3502 case sp_reg: case bp_reg: case si_reg: case di_reg:
3503 s = names16[code - ax_reg + add];
3504 break;
3505 case es_reg: case ss_reg: case cs_reg:
3506 case ds_reg: case fs_reg: case gs_reg:
3507 s = names_seg[code - es_reg + add];
3508 break;
3509 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3510 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3511 USED_REX (0);
3512 if (rex)
3513 s = names8rex[code - al_reg + add];
3514 else
3515 s = names8[code - al_reg];
3516 break;
3517 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
3518 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
3519 if (mode_64bit)
3521 s = names64[code - rAX_reg + add];
3522 break;
3524 code += eAX_reg - rAX_reg;
3525 /* Fall through. */
3526 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3527 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3528 USED_REX (REX_MODE64);
3529 if (rex & REX_MODE64)
3530 s = names64[code - eAX_reg + add];
3531 else if (sizeflag & DFLAG)
3532 s = names32[code - eAX_reg + add];
3533 else
3534 s = names16[code - eAX_reg + add];
3535 used_prefixes |= (prefixes & PREFIX_DATA);
3536 break;
3537 default:
3538 s = INTERNAL_DISASSEMBLER_ERROR;
3539 break;
3541 oappend (s);
3544 static void
3545 OP_IMREG (int code, int sizeflag)
3547 const char *s;
3549 switch (code)
3551 case indir_dx_reg:
3552 if (intel_syntax)
3553 s = "[dx]";
3554 else
3555 s = "(%dx)";
3556 break;
3557 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3558 case sp_reg: case bp_reg: case si_reg: case di_reg:
3559 s = names16[code - ax_reg];
3560 break;
3561 case es_reg: case ss_reg: case cs_reg:
3562 case ds_reg: case fs_reg: case gs_reg:
3563 s = names_seg[code - es_reg];
3564 break;
3565 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3566 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3567 USED_REX (0);
3568 if (rex)
3569 s = names8rex[code - al_reg];
3570 else
3571 s = names8[code - al_reg];
3572 break;
3573 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3574 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3575 USED_REX (REX_MODE64);
3576 if (rex & REX_MODE64)
3577 s = names64[code - eAX_reg];
3578 else if (sizeflag & DFLAG)
3579 s = names32[code - eAX_reg];
3580 else
3581 s = names16[code - eAX_reg];
3582 used_prefixes |= (prefixes & PREFIX_DATA);
3583 break;
3584 default:
3585 s = INTERNAL_DISASSEMBLER_ERROR;
3586 break;
3588 oappend (s);
3591 static void
3592 OP_I (int bytemode, int sizeflag)
3594 bfd_signed_vma op;
3595 bfd_signed_vma mask = -1;
3597 switch (bytemode)
3599 case b_mode:
3600 FETCH_DATA (the_info, codep + 1);
3601 op = *codep++;
3602 mask = 0xff;
3603 break;
3604 case q_mode:
3605 if (mode_64bit)
3607 op = get32s ();
3608 break;
3610 /* Fall through. */
3611 case v_mode:
3612 USED_REX (REX_MODE64);
3613 if (rex & REX_MODE64)
3614 op = get32s ();
3615 else if (sizeflag & DFLAG)
3617 op = get32 ();
3618 mask = 0xffffffff;
3620 else
3622 op = get16 ();
3623 mask = 0xfffff;
3625 used_prefixes |= (prefixes & PREFIX_DATA);
3626 break;
3627 case w_mode:
3628 mask = 0xfffff;
3629 op = get16 ();
3630 break;
3631 default:
3632 oappend (INTERNAL_DISASSEMBLER_ERROR);
3633 return;
3636 op &= mask;
3637 scratchbuf[0] = '$';
3638 print_operand_value (scratchbuf + 1, 1, op);
3639 oappend (scratchbuf + intel_syntax);
3640 scratchbuf[0] = '\0';
3643 static void
3644 OP_I64 (int bytemode, int sizeflag)
3646 bfd_signed_vma op;
3647 bfd_signed_vma mask = -1;
3649 if (!mode_64bit)
3651 OP_I (bytemode, sizeflag);
3652 return;
3655 switch (bytemode)
3657 case b_mode:
3658 FETCH_DATA (the_info, codep + 1);
3659 op = *codep++;
3660 mask = 0xff;
3661 break;
3662 case v_mode:
3663 USED_REX (REX_MODE64);
3664 if (rex & REX_MODE64)
3665 op = get64 ();
3666 else if (sizeflag & DFLAG)
3668 op = get32 ();
3669 mask = 0xffffffff;
3671 else
3673 op = get16 ();
3674 mask = 0xfffff;
3676 used_prefixes |= (prefixes & PREFIX_DATA);
3677 break;
3678 case w_mode:
3679 mask = 0xfffff;
3680 op = get16 ();
3681 break;
3682 default:
3683 oappend (INTERNAL_DISASSEMBLER_ERROR);
3684 return;
3687 op &= mask;
3688 scratchbuf[0] = '$';
3689 print_operand_value (scratchbuf + 1, 1, op);
3690 oappend (scratchbuf + intel_syntax);
3691 scratchbuf[0] = '\0';
3694 static void
3695 OP_sI (int bytemode, int sizeflag)
3697 bfd_signed_vma op;
3698 bfd_signed_vma mask = -1;
3700 switch (bytemode)
3702 case b_mode:
3703 FETCH_DATA (the_info, codep + 1);
3704 op = *codep++;
3705 if ((op & 0x80) != 0)
3706 op -= 0x100;
3707 mask = 0xffffffff;
3708 break;
3709 case v_mode:
3710 USED_REX (REX_MODE64);
3711 if (rex & REX_MODE64)
3712 op = get32s ();
3713 else if (sizeflag & DFLAG)
3715 op = get32s ();
3716 mask = 0xffffffff;
3718 else
3720 mask = 0xffffffff;
3721 op = get16 ();
3722 if ((op & 0x8000) != 0)
3723 op -= 0x10000;
3725 used_prefixes |= (prefixes & PREFIX_DATA);
3726 break;
3727 case w_mode:
3728 op = get16 ();
3729 mask = 0xffffffff;
3730 if ((op & 0x8000) != 0)
3731 op -= 0x10000;
3732 break;
3733 default:
3734 oappend (INTERNAL_DISASSEMBLER_ERROR);
3735 return;
3738 scratchbuf[0] = '$';
3739 print_operand_value (scratchbuf + 1, 1, op);
3740 oappend (scratchbuf + intel_syntax);
3743 static void
3744 OP_J (int bytemode, int sizeflag)
3746 bfd_vma disp;
3747 bfd_vma mask = -1;
3749 switch (bytemode)
3751 case b_mode:
3752 FETCH_DATA (the_info, codep + 1);
3753 disp = *codep++;
3754 if ((disp & 0x80) != 0)
3755 disp -= 0x100;
3756 break;
3757 case v_mode:
3758 if (sizeflag & DFLAG)
3759 disp = get32s ();
3760 else
3762 disp = get16 ();
3763 /* For some reason, a data16 prefix on a jump instruction
3764 means that the pc is masked to 16 bits after the
3765 displacement is added! */
3766 mask = 0xffff;
3768 break;
3769 default:
3770 oappend (INTERNAL_DISASSEMBLER_ERROR);
3771 return;
3773 disp = (start_pc + codep - start_codep + disp) & mask;
3774 set_op (disp, 0);
3775 print_operand_value (scratchbuf, 1, disp);
3776 oappend (scratchbuf);
3779 static void
3780 OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3782 oappend (names_seg[reg]);
3785 static void
3786 OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
3788 int seg, offset;
3790 if (sizeflag & DFLAG)
3792 offset = get32 ();
3793 seg = get16 ();
3795 else
3797 offset = get16 ();
3798 seg = get16 ();
3800 used_prefixes |= (prefixes & PREFIX_DATA);
3801 if (intel_syntax)
3802 sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
3803 else
3804 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3805 oappend (scratchbuf);
3808 static void
3809 OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag)
3811 bfd_vma off;
3813 append_seg ();
3815 if ((sizeflag & AFLAG) || mode_64bit)
3816 off = get32 ();
3817 else
3818 off = get16 ();
3820 if (intel_syntax)
3822 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3823 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3825 oappend (names_seg[ds_reg - es_reg]);
3826 oappend (":");
3829 print_operand_value (scratchbuf, 1, off);
3830 oappend (scratchbuf);
3833 static void
3834 OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3836 bfd_vma off;
3838 if (!mode_64bit)
3840 OP_OFF (bytemode, sizeflag);
3841 return;
3844 append_seg ();
3846 off = get64 ();
3848 if (intel_syntax)
3850 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3851 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3853 oappend (names_seg[ds_reg - es_reg]);
3854 oappend (":");
3857 print_operand_value (scratchbuf, 1, off);
3858 oappend (scratchbuf);
3861 static void
3862 ptr_reg (int code, int sizeflag)
3864 const char *s;
3866 *obufp++ = open_char;
3867 used_prefixes |= (prefixes & PREFIX_ADDR);
3868 if (mode_64bit)
3870 if (!(sizeflag & AFLAG))
3871 s = names32[code - eAX_reg];
3872 else
3873 s = names64[code - eAX_reg];
3875 else if (sizeflag & AFLAG)
3876 s = names32[code - eAX_reg];
3877 else
3878 s = names16[code - eAX_reg];
3879 oappend (s);
3880 *obufp++ = close_char;
3881 *obufp = 0;
3884 static void
3885 OP_ESreg (int code, int sizeflag)
3887 oappend ("%es:" + intel_syntax);
3888 ptr_reg (code, sizeflag);
3891 static void
3892 OP_DSreg (int code, int sizeflag)
3894 if ((prefixes
3895 & (PREFIX_CS
3896 | PREFIX_DS
3897 | PREFIX_SS
3898 | PREFIX_ES
3899 | PREFIX_FS
3900 | PREFIX_GS)) == 0)
3901 prefixes |= PREFIX_DS;
3902 append_seg ();
3903 ptr_reg (code, sizeflag);
3906 static void
3907 OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3909 int add = 0;
3910 USED_REX (REX_EXTX);
3911 if (rex & REX_EXTX)
3912 add = 8;
3913 sprintf (scratchbuf, "%%cr%d", reg + add);
3914 oappend (scratchbuf + intel_syntax);
3917 static void
3918 OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3920 int add = 0;
3921 USED_REX (REX_EXTX);
3922 if (rex & REX_EXTX)
3923 add = 8;
3924 if (intel_syntax)
3925 sprintf (scratchbuf, "db%d", reg + add);
3926 else
3927 sprintf (scratchbuf, "%%db%d", reg + add);
3928 oappend (scratchbuf);
3931 static void
3932 OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3934 sprintf (scratchbuf, "%%tr%d", reg);
3935 oappend (scratchbuf + intel_syntax);
3938 static void
3939 OP_Rd (int bytemode, int sizeflag)
3941 if (mod == 3)
3942 OP_E (bytemode, sizeflag);
3943 else
3944 BadOp ();
3947 static void
3948 OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3950 used_prefixes |= (prefixes & PREFIX_DATA);
3951 if (prefixes & PREFIX_DATA)
3953 int add = 0;
3954 USED_REX (REX_EXTX);
3955 if (rex & REX_EXTX)
3956 add = 8;
3957 sprintf (scratchbuf, "%%xmm%d", reg + add);
3959 else
3960 sprintf (scratchbuf, "%%mm%d", reg);
3961 oappend (scratchbuf + intel_syntax);
3964 static void
3965 OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3967 int add = 0;
3968 USED_REX (REX_EXTX);
3969 if (rex & REX_EXTX)
3970 add = 8;
3971 sprintf (scratchbuf, "%%xmm%d", reg + add);
3972 oappend (scratchbuf + intel_syntax);
3975 static void
3976 OP_EM (int bytemode, int sizeflag)
3978 if (mod != 3)
3980 OP_E (bytemode, sizeflag);
3981 return;
3984 /* Skip mod/rm byte. */
3985 MODRM_CHECK;
3986 codep++;
3987 used_prefixes |= (prefixes & PREFIX_DATA);
3988 if (prefixes & PREFIX_DATA)
3990 int add = 0;
3992 USED_REX (REX_EXTZ);
3993 if (rex & REX_EXTZ)
3994 add = 8;
3995 sprintf (scratchbuf, "%%xmm%d", rm + add);
3997 else
3998 sprintf (scratchbuf, "%%mm%d", rm);
3999 oappend (scratchbuf + intel_syntax);
4002 static void
4003 OP_EX (int bytemode, int sizeflag)
4005 int add = 0;
4006 if (mod != 3)
4008 OP_E (bytemode, sizeflag);
4009 return;
4011 USED_REX (REX_EXTZ);
4012 if (rex & REX_EXTZ)
4013 add = 8;
4015 /* Skip mod/rm byte. */
4016 MODRM_CHECK;
4017 codep++;
4018 sprintf (scratchbuf, "%%xmm%d", rm + add);
4019 oappend (scratchbuf + intel_syntax);
4022 static void
4023 OP_MS (int bytemode, int sizeflag)
4025 if (mod == 3)
4026 OP_EM (bytemode, sizeflag);
4027 else
4028 BadOp ();
4031 static void
4032 OP_XS (int bytemode, int sizeflag)
4034 if (mod == 3)
4035 OP_EX (bytemode, sizeflag);
4036 else
4037 BadOp ();
4040 static void
4041 OP_M (int bytemode, int sizeflag)
4043 if (mod == 3)
4044 BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
4045 else
4046 OP_E (bytemode, sizeflag);
4049 static void
4050 OP_0f07 (int bytemode, int sizeflag)
4052 if (mod != 3 || rm != 0)
4053 BadOp ();
4054 else
4055 OP_E (bytemode, sizeflag);
4058 static void
4059 OP_0fae (int bytemode, int sizeflag)
4061 if (mod == 3)
4063 if (reg == 7)
4064 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
4066 if (reg < 5 || rm != 0)
4068 BadOp (); /* bad sfence, mfence, or lfence */
4069 return;
4072 else if (reg != 7)
4074 BadOp (); /* bad clflush */
4075 return;
4078 OP_E (bytemode, sizeflag);
4081 static void
4082 NOP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4084 /* NOP with REPZ prefix is called PAUSE. */
4085 if (prefixes == PREFIX_REPZ)
4086 strcpy (obuf, "pause");
4089 static const char *const Suffix3DNow[] = {
4090 /* 00 */ NULL, NULL, NULL, NULL,
4091 /* 04 */ NULL, NULL, NULL, NULL,
4092 /* 08 */ NULL, NULL, NULL, NULL,
4093 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
4094 /* 10 */ NULL, NULL, NULL, NULL,
4095 /* 14 */ NULL, NULL, NULL, NULL,
4096 /* 18 */ NULL, NULL, NULL, NULL,
4097 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
4098 /* 20 */ NULL, NULL, NULL, NULL,
4099 /* 24 */ NULL, NULL, NULL, NULL,
4100 /* 28 */ NULL, NULL, NULL, NULL,
4101 /* 2C */ NULL, NULL, NULL, NULL,
4102 /* 30 */ NULL, NULL, NULL, NULL,
4103 /* 34 */ NULL, NULL, NULL, NULL,
4104 /* 38 */ NULL, NULL, NULL, NULL,
4105 /* 3C */ NULL, NULL, NULL, NULL,
4106 /* 40 */ NULL, NULL, NULL, NULL,
4107 /* 44 */ NULL, NULL, NULL, NULL,
4108 /* 48 */ NULL, NULL, NULL, NULL,
4109 /* 4C */ NULL, NULL, NULL, NULL,
4110 /* 50 */ NULL, NULL, NULL, NULL,
4111 /* 54 */ NULL, NULL, NULL, NULL,
4112 /* 58 */ NULL, NULL, NULL, NULL,
4113 /* 5C */ NULL, NULL, NULL, NULL,
4114 /* 60 */ NULL, NULL, NULL, NULL,
4115 /* 64 */ NULL, NULL, NULL, NULL,
4116 /* 68 */ NULL, NULL, NULL, NULL,
4117 /* 6C */ NULL, NULL, NULL, NULL,
4118 /* 70 */ NULL, NULL, NULL, NULL,
4119 /* 74 */ NULL, NULL, NULL, NULL,
4120 /* 78 */ NULL, NULL, NULL, NULL,
4121 /* 7C */ NULL, NULL, NULL, NULL,
4122 /* 80 */ NULL, NULL, NULL, NULL,
4123 /* 84 */ NULL, NULL, NULL, NULL,
4124 /* 88 */ NULL, NULL, "pfnacc", NULL,
4125 /* 8C */ NULL, NULL, "pfpnacc", NULL,
4126 /* 90 */ "pfcmpge", NULL, NULL, NULL,
4127 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
4128 /* 98 */ NULL, NULL, "pfsub", NULL,
4129 /* 9C */ NULL, NULL, "pfadd", NULL,
4130 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
4131 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
4132 /* A8 */ NULL, NULL, "pfsubr", NULL,
4133 /* AC */ NULL, NULL, "pfacc", NULL,
4134 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
4135 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
4136 /* B8 */ NULL, NULL, NULL, "pswapd",
4137 /* BC */ NULL, NULL, NULL, "pavgusb",
4138 /* C0 */ NULL, NULL, NULL, NULL,
4139 /* C4 */ NULL, NULL, NULL, NULL,
4140 /* C8 */ NULL, NULL, NULL, NULL,
4141 /* CC */ NULL, NULL, NULL, NULL,
4142 /* D0 */ NULL, NULL, NULL, NULL,
4143 /* D4 */ NULL, NULL, NULL, NULL,
4144 /* D8 */ NULL, NULL, NULL, NULL,
4145 /* DC */ NULL, NULL, NULL, NULL,
4146 /* E0 */ NULL, NULL, NULL, NULL,
4147 /* E4 */ NULL, NULL, NULL, NULL,
4148 /* E8 */ NULL, NULL, NULL, NULL,
4149 /* EC */ NULL, NULL, NULL, NULL,
4150 /* F0 */ NULL, NULL, NULL, NULL,
4151 /* F4 */ NULL, NULL, NULL, NULL,
4152 /* F8 */ NULL, NULL, NULL, NULL,
4153 /* FC */ NULL, NULL, NULL, NULL,
4156 static void
4157 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4159 const char *mnemonic;
4161 FETCH_DATA (the_info, codep + 1);
4162 /* AMD 3DNow! instructions are specified by an opcode suffix in the
4163 place where an 8-bit immediate would normally go. ie. the last
4164 byte of the instruction. */
4165 obufp = obuf + strlen (obuf);
4166 mnemonic = Suffix3DNow[*codep++ & 0xff];
4167 if (mnemonic)
4168 oappend (mnemonic);
4169 else
4171 /* Since a variable sized modrm/sib chunk is between the start
4172 of the opcode (0x0f0f) and the opcode suffix, we need to do
4173 all the modrm processing first, and don't know until now that
4174 we have a bad opcode. This necessitates some cleaning up. */
4175 op1out[0] = '\0';
4176 op2out[0] = '\0';
4177 BadOp ();
4181 static const char *simd_cmp_op[] = {
4182 "eq",
4183 "lt",
4184 "le",
4185 "unord",
4186 "neq",
4187 "nlt",
4188 "nle",
4189 "ord"
4192 static void
4193 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4195 unsigned int cmp_type;
4197 FETCH_DATA (the_info, codep + 1);
4198 obufp = obuf + strlen (obuf);
4199 cmp_type = *codep++ & 0xff;
4200 if (cmp_type < 8)
4202 char suffix1 = 'p', suffix2 = 's';
4203 used_prefixes |= (prefixes & PREFIX_REPZ);
4204 if (prefixes & PREFIX_REPZ)
4205 suffix1 = 's';
4206 else
4208 used_prefixes |= (prefixes & PREFIX_DATA);
4209 if (prefixes & PREFIX_DATA)
4210 suffix2 = 'd';
4211 else
4213 used_prefixes |= (prefixes & PREFIX_REPNZ);
4214 if (prefixes & PREFIX_REPNZ)
4215 suffix1 = 's', suffix2 = 'd';
4218 sprintf (scratchbuf, "cmp%s%c%c",
4219 simd_cmp_op[cmp_type], suffix1, suffix2);
4220 used_prefixes |= (prefixes & PREFIX_REPZ);
4221 oappend (scratchbuf);
4223 else
4225 /* We have a bad extension byte. Clean up. */
4226 op1out[0] = '\0';
4227 op2out[0] = '\0';
4228 BadOp ();
4232 static void
4233 SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
4235 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
4236 forms of these instructions. */
4237 if (mod == 3)
4239 char *p = obuf + strlen (obuf);
4240 *(p + 1) = '\0';
4241 *p = *(p - 1);
4242 *(p - 1) = *(p - 2);
4243 *(p - 2) = *(p - 3);
4244 *(p - 3) = extrachar;
4248 static void
4249 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
4251 if (mod == 3 && reg == 1 && rm <= 1)
4253 /* Override "sidt". */
4254 char *p = obuf + strlen (obuf) - 4;
4256 /* We might have a suffix. */
4257 if (*p == 'i')
4258 --p;
4260 if (rm)
4262 /* mwait %eax,%ecx */
4263 strcpy (p, "mwait");
4265 else
4267 /* monitor %eax,%ecx,%edx" */
4268 strcpy (p, "monitor");
4269 strcpy (op3out, names32[2]);
4271 strcpy (op1out, names32[0]);
4272 strcpy (op2out, names32[1]);
4273 two_source_ops = 1;
4275 codep++;
4277 else
4278 OP_E (0, sizeflag);
4281 static void
4282 INVLPG_Fixup (int bytemode, int sizeflag)
4284 if (*codep == 0xf8)
4286 char *p = obuf + strlen (obuf);
4288 /* Override "invlpg". */
4289 strcpy (p - 6, "swapgs");
4290 codep++;
4292 else
4293 OP_E (bytemode, sizeflag);
4296 static void
4297 BadOp (void)
4299 /* Throw away prefixes and 1st. opcode byte. */
4300 codep = insn_codep + 1;
4301 oappend ("(bad)");