* elflink.c (bfd_elf_size_dynsym_hash_dynstr): Move declarations
[binutils.git] / opcodes / i386-dis.c
blob6f5ac41b2f72c9d8bf1da54784f1922076be67dd
1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
21 /* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
22 July 1988
23 modified by John Hassey (hassey@dg-rtp.dg.com)
24 x86-64 support added by Jan Hubicka (jh@suse.cz)
25 VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
27 /* The main tables describing the instructions is essentially a copy
28 of the "Opcode Map" chapter (Appendix A) of the Intel 80386
29 Programmers Manual. Usually, there is a capital letter, followed
30 by a small letter. The capital letter tell the addressing mode,
31 and the small letter tells about the operand size. Refer to
32 the Intel manual for details. */
34 #include "dis-asm.h"
35 #include "sysdep.h"
36 #include "opintl.h"
38 #define MAXLEN 15
40 #include <setjmp.h>
42 #ifndef UNIXWARE_COMPAT
43 /* Set non-zero for broken, compatible instructions. Set to zero for
44 non-broken opcodes. */
45 #define UNIXWARE_COMPAT 1
46 #endif
48 static int fetch_data (struct disassemble_info *, bfd_byte *);
49 static void ckprefix (void);
50 static const char *prefix_name (int, int);
51 static int print_insn (bfd_vma, disassemble_info *);
52 static void dofloat (int);
53 static void OP_ST (int, int);
54 static void OP_STi (int, int);
55 static int putop (const char *, int);
56 static void oappend (const char *);
57 static void append_seg (void);
58 static void OP_indirE (int, int);
59 static void print_operand_value (char *, int, bfd_vma);
60 static void OP_E (int, int);
61 static void OP_G (int, int);
62 static bfd_vma get64 (void);
63 static bfd_signed_vma get32 (void);
64 static bfd_signed_vma get32s (void);
65 static int get16 (void);
66 static void set_op (bfd_vma, int);
67 static void OP_REG (int, int);
68 static void OP_IMREG (int, int);
69 static void OP_I (int, int);
70 static void OP_I64 (int, int);
71 static void OP_sI (int, int);
72 static void OP_J (int, int);
73 static void OP_SEG (int, int);
74 static void OP_DIR (int, int);
75 static void OP_OFF (int, int);
76 static void OP_OFF64 (int, int);
77 static void ptr_reg (int, int);
78 static void OP_ESreg (int, int);
79 static void OP_DSreg (int, int);
80 static void OP_C (int, int);
81 static void OP_D (int, int);
82 static void OP_T (int, int);
83 static void OP_Rd (int, int);
84 static void OP_MMX (int, int);
85 static void OP_XMM (int, int);
86 static void OP_EM (int, int);
87 static void OP_EX (int, int);
88 static void OP_MS (int, int);
89 static void OP_XS (int, int);
90 static void OP_M (int, int);
91 static void OP_VMX (int, int);
92 static void OP_0fae (int, int);
93 static void OP_0f07 (int, int);
94 static void NOP_Fixup1 (int, int);
95 static void NOP_Fixup2 (int, int);
96 static void OP_3DNowSuffix (int, int);
97 static void OP_SIMD_Suffix (int, int);
98 static void SIMD_Fixup (int, int);
99 static void PNI_Fixup (int, int);
100 static void SVME_Fixup (int, int);
101 static void INVLPG_Fixup (int, int);
102 static void BadOp (void);
103 static void SEG_Fixup (int, int);
104 static void VMX_Fixup (int, int);
105 static void REP_Fixup (int, int);
107 struct dis_private {
108 /* Points to first byte not fetched. */
109 bfd_byte *max_fetched;
110 bfd_byte the_buffer[MAXLEN];
111 bfd_vma insn_start;
112 int orig_sizeflag;
113 jmp_buf bailout;
116 /* The opcode for the fwait instruction, which we treat as a prefix
117 when we can. */
118 #define FWAIT_OPCODE (0x9b)
120 enum address_mode
122 mode_16bit,
123 mode_32bit,
124 mode_64bit
127 enum address_mode address_mode;
129 /* Flags for the prefixes for the current instruction. See below. */
130 static int prefixes;
132 /* REX prefix the current instruction. See below. */
133 static int rex;
134 /* Bits of REX we've already used. */
135 static int rex_used;
136 #define REX_MODE64 8
137 #define REX_EXTX 4
138 #define REX_EXTY 2
139 #define REX_EXTZ 1
140 /* Mark parts used in the REX prefix. When we are testing for
141 empty prefix (for 8bit register REX extension), just mask it
142 out. Otherwise test for REX bit is excuse for existence of REX
143 only in case value is nonzero. */
144 #define USED_REX(value) \
146 if (value) \
147 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
148 else \
149 rex_used |= 0x40; \
152 /* Flags for prefixes which we somehow handled when printing the
153 current instruction. */
154 static int used_prefixes;
156 /* Flags stored in PREFIXES. */
157 #define PREFIX_REPZ 1
158 #define PREFIX_REPNZ 2
159 #define PREFIX_LOCK 4
160 #define PREFIX_CS 8
161 #define PREFIX_SS 0x10
162 #define PREFIX_DS 0x20
163 #define PREFIX_ES 0x40
164 #define PREFIX_FS 0x80
165 #define PREFIX_GS 0x100
166 #define PREFIX_DATA 0x200
167 #define PREFIX_ADDR 0x400
168 #define PREFIX_FWAIT 0x800
170 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
171 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
172 on error. */
173 #define FETCH_DATA(info, addr) \
174 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
175 ? 1 : fetch_data ((info), (addr)))
177 static int
178 fetch_data (struct disassemble_info *info, bfd_byte *addr)
180 int status;
181 struct dis_private *priv = (struct dis_private *) info->private_data;
182 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
184 if (addr <= priv->the_buffer + MAXLEN)
185 status = (*info->read_memory_func) (start,
186 priv->max_fetched,
187 addr - priv->max_fetched,
188 info);
189 else
190 status = -1;
191 if (status != 0)
193 /* If we did manage to read at least one byte, then
194 print_insn_i386 will do something sensible. Otherwise, print
195 an error. We do that here because this is where we know
196 STATUS. */
197 if (priv->max_fetched == priv->the_buffer)
198 (*info->memory_error_func) (status, start, info);
199 longjmp (priv->bailout, 1);
201 else
202 priv->max_fetched = addr;
203 return 1;
206 #define XX NULL, 0
208 #define Eb OP_E, b_mode
209 #define Ev OP_E, v_mode
210 #define Ed OP_E, d_mode
211 #define Eq OP_E, q_mode
212 #define Edq OP_E, dq_mode
213 #define Edqw OP_E, dqw_mode
214 #define indirEv OP_indirE, stack_v_mode
215 #define indirEp OP_indirE, f_mode
216 #define stackEv OP_E, stack_v_mode
217 #define Em OP_E, m_mode
218 #define Ew OP_E, w_mode
219 #define Ma OP_E, v_mode
220 #define M OP_M, 0 /* lea, lgdt, etc. */
221 #define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */
222 #define Gb OP_G, b_mode
223 #define Gv OP_G, v_mode
224 #define Gd OP_G, d_mode
225 #define Gdq OP_G, dq_mode
226 #define Gm OP_G, m_mode
227 #define Gw OP_G, w_mode
228 #define Rd OP_Rd, d_mode
229 #define Rm OP_Rd, m_mode
230 #define Ib OP_I, b_mode
231 #define sIb OP_sI, b_mode /* sign extened byte */
232 #define Iv OP_I, v_mode
233 #define Iq OP_I, q_mode
234 #define Iv64 OP_I64, v_mode
235 #define Iw OP_I, w_mode
236 #define I1 OP_I, const_1_mode
237 #define Jb OP_J, b_mode
238 #define Jv OP_J, v_mode
239 #define Cm OP_C, m_mode
240 #define Dm OP_D, m_mode
241 #define Td OP_T, d_mode
242 #define Sv SEG_Fixup, v_mode
244 #define RMeAX OP_REG, eAX_reg
245 #define RMeBX OP_REG, eBX_reg
246 #define RMeCX OP_REG, eCX_reg
247 #define RMeDX OP_REG, eDX_reg
248 #define RMeSP OP_REG, eSP_reg
249 #define RMeBP OP_REG, eBP_reg
250 #define RMeSI OP_REG, eSI_reg
251 #define RMeDI OP_REG, eDI_reg
252 #define RMrAX OP_REG, rAX_reg
253 #define RMrBX OP_REG, rBX_reg
254 #define RMrCX OP_REG, rCX_reg
255 #define RMrDX OP_REG, rDX_reg
256 #define RMrSP OP_REG, rSP_reg
257 #define RMrBP OP_REG, rBP_reg
258 #define RMrSI OP_REG, rSI_reg
259 #define RMrDI OP_REG, rDI_reg
260 #define RMAL OP_REG, al_reg
261 #define RMAL OP_REG, al_reg
262 #define RMCL OP_REG, cl_reg
263 #define RMDL OP_REG, dl_reg
264 #define RMBL OP_REG, bl_reg
265 #define RMAH OP_REG, ah_reg
266 #define RMCH OP_REG, ch_reg
267 #define RMDH OP_REG, dh_reg
268 #define RMBH OP_REG, bh_reg
269 #define RMAX OP_REG, ax_reg
270 #define RMDX OP_REG, dx_reg
272 #define eAX OP_IMREG, eAX_reg
273 #define eBX OP_IMREG, eBX_reg
274 #define eCX OP_IMREG, eCX_reg
275 #define eDX OP_IMREG, eDX_reg
276 #define eSP OP_IMREG, eSP_reg
277 #define eBP OP_IMREG, eBP_reg
278 #define eSI OP_IMREG, eSI_reg
279 #define eDI OP_IMREG, eDI_reg
280 #define AL OP_IMREG, al_reg
281 #define CL OP_IMREG, cl_reg
282 #define DL OP_IMREG, dl_reg
283 #define BL OP_IMREG, bl_reg
284 #define AH OP_IMREG, ah_reg
285 #define CH OP_IMREG, ch_reg
286 #define DH OP_IMREG, dh_reg
287 #define BH OP_IMREG, bh_reg
288 #define AX OP_IMREG, ax_reg
289 #define DX OP_IMREG, dx_reg
290 #define indirDX OP_IMREG, indir_dx_reg
292 #define Sw OP_SEG, w_mode
293 #define Ap OP_DIR, 0
294 #define Ob OP_OFF64, b_mode
295 #define Ov OP_OFF64, v_mode
296 #define Xb OP_DSreg, eSI_reg
297 #define Xv OP_DSreg, eSI_reg
298 #define Yb OP_ESreg, eDI_reg
299 #define Yv OP_ESreg, eDI_reg
300 #define DSBX OP_DSreg, eBX_reg
302 #define es OP_REG, es_reg
303 #define ss OP_REG, ss_reg
304 #define cs OP_REG, cs_reg
305 #define ds OP_REG, ds_reg
306 #define fs OP_REG, fs_reg
307 #define gs OP_REG, gs_reg
309 #define MX OP_MMX, 0
310 #define XM OP_XMM, 0
311 #define EM OP_EM, v_mode
312 #define EX OP_EX, v_mode
313 #define MS OP_MS, v_mode
314 #define XS OP_XS, v_mode
315 #define VM OP_VMX, q_mode
316 #define OPSUF OP_3DNowSuffix, 0
317 #define OPSIMD OP_SIMD_Suffix, 0
319 /* Used handle "rep" prefix for string instructions. */
320 #define Xbr REP_Fixup, eSI_reg
321 #define Xvr REP_Fixup, eSI_reg
322 #define Ybr REP_Fixup, eDI_reg
323 #define Yvr REP_Fixup, eDI_reg
324 #define indirDXr REP_Fixup, indir_dx_reg
325 #define ALr REP_Fixup, al_reg
326 #define eAXr REP_Fixup, eAX_reg
328 #define cond_jump_flag NULL, cond_jump_mode
329 #define loop_jcxz_flag NULL, loop_jcxz_mode
331 /* bits in sizeflag */
332 #define SUFFIX_ALWAYS 4
333 #define AFLAG 2
334 #define DFLAG 1
336 #define b_mode 1 /* byte operand */
337 #define v_mode 2 /* operand size depends on prefixes */
338 #define w_mode 3 /* word operand */
339 #define d_mode 4 /* double word operand */
340 #define q_mode 5 /* quad word operand */
341 #define t_mode 6 /* ten-byte operand */
342 #define x_mode 7 /* 16-byte XMM operand */
343 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
344 #define cond_jump_mode 9
345 #define loop_jcxz_mode 10
346 #define dq_mode 11 /* operand size depends on REX prefixes. */
347 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
348 #define f_mode 13 /* 4- or 6-byte pointer operand */
349 #define const_1_mode 14
350 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
352 #define es_reg 100
353 #define cs_reg 101
354 #define ss_reg 102
355 #define ds_reg 103
356 #define fs_reg 104
357 #define gs_reg 105
359 #define eAX_reg 108
360 #define eCX_reg 109
361 #define eDX_reg 110
362 #define eBX_reg 111
363 #define eSP_reg 112
364 #define eBP_reg 113
365 #define eSI_reg 114
366 #define eDI_reg 115
368 #define al_reg 116
369 #define cl_reg 117
370 #define dl_reg 118
371 #define bl_reg 119
372 #define ah_reg 120
373 #define ch_reg 121
374 #define dh_reg 122
375 #define bh_reg 123
377 #define ax_reg 124
378 #define cx_reg 125
379 #define dx_reg 126
380 #define bx_reg 127
381 #define sp_reg 128
382 #define bp_reg 129
383 #define si_reg 130
384 #define di_reg 131
386 #define rAX_reg 132
387 #define rCX_reg 133
388 #define rDX_reg 134
389 #define rBX_reg 135
390 #define rSP_reg 136
391 #define rBP_reg 137
392 #define rSI_reg 138
393 #define rDI_reg 139
395 #define indir_dx_reg 150
397 #define FLOATCODE 1
398 #define USE_GROUPS 2
399 #define USE_PREFIX_USER_TABLE 3
400 #define X86_64_SPECIAL 4
401 #define IS_3BYTE_OPCODE 5
403 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0, NULL, 0
405 #define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0, NULL, 0
406 #define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0, NULL, 0
407 #define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0, NULL, 0
408 #define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0, NULL, 0
409 #define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0, NULL, 0
410 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0, NULL, 0
411 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0, NULL, 0
412 #define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0, NULL, 0
413 #define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0, NULL, 0
414 #define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0, NULL, 0
415 #define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0, NULL, 0
416 #define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0, NULL, 0
417 #define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0, NULL, 0
418 #define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0, NULL, 0
419 #define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0, NULL, 0
420 #define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0, NULL, 0
421 #define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0, NULL, 0
422 #define GRP12 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0, NULL, 0
423 #define GRP13 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0, NULL, 0
424 #define GRP14 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0, NULL, 0
425 #define GRP15 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0, NULL, 0
426 #define GRP16 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0, NULL, 0
427 #define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0, NULL, 0
428 #define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0, NULL, 0
429 #define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0, NULL, 0
431 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0, NULL, 0
432 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0, NULL, 0
433 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0, NULL, 0
434 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0, NULL, 0
435 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0, NULL, 0
436 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0, NULL, 0
437 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0, NULL, 0
438 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0, NULL, 0
439 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0, NULL, 0
440 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0, NULL, 0
441 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0, NULL, 0
442 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0, NULL, 0
443 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0, NULL, 0
444 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0, NULL, 0
445 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0, NULL, 0
446 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0, NULL, 0
447 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0, NULL, 0
448 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0, NULL, 0
449 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0, NULL, 0
450 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0, NULL, 0
451 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0, NULL, 0
452 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0, NULL, 0
453 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0, NULL, 0
454 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0, NULL, 0
455 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0, NULL, 0
456 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0, NULL, 0
457 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0, NULL, 0
458 #define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0, NULL, 0
459 #define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0, NULL, 0
460 #define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0, NULL, 0
461 #define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0, NULL, 0
462 #define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0, NULL, 0
463 #define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0, NULL, 0
464 #define PREGRP33 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 33, NULL, 0, NULL, 0
465 #define PREGRP34 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 34, NULL, 0, NULL, 0
466 #define PREGRP35 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 35, NULL, 0, NULL, 0
467 #define PREGRP36 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 36, NULL, 0, NULL, 0
469 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0, NULL, 0
471 #define THREE_BYTE_0 NULL, NULL, IS_3BYTE_OPCODE, NULL, 0, NULL, 0, NULL, 0
472 #define THREE_BYTE_1 NULL, NULL, IS_3BYTE_OPCODE, NULL, 1, NULL, 0, NULL, 0
474 typedef void (*op_rtn) (int bytemode, int sizeflag);
476 struct dis386 {
477 const char *name;
478 op_rtn op1;
479 int bytemode1;
480 op_rtn op2;
481 int bytemode2;
482 op_rtn op3;
483 int bytemode3;
484 op_rtn op4;
485 int bytemode4;
488 /* Upper case letters in the instruction names here are macros.
489 'A' => print 'b' if no register operands or suffix_always is true
490 'B' => print 'b' if suffix_always is true
491 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
492 . size prefix
493 'E' => print 'e' if 32-bit form of jcxz
494 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
495 'H' => print ",pt" or ",pn" branch hint
496 'I' => honor following macro letter even in Intel mode (implemented only
497 . for some of the macro letters)
498 'J' => print 'l'
499 'L' => print 'l' if suffix_always is true
500 'N' => print 'n' if instruction has no wait "prefix"
501 'O' => print 'd', or 'o'
502 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
503 . or suffix_always is true. print 'q' if rex prefix is present.
504 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
505 . is true
506 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
507 'S' => print 'w', 'l' or 'q' if suffix_always is true
508 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
509 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
510 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
511 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
512 'X' => print 's', 'd' depending on data16 prefix (for XMM)
513 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
514 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
516 Many of the above letters print nothing in Intel mode. See "putop"
517 for the details.
519 Braces '{' and '}', and vertical bars '|', indicate alternative
520 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
521 modes. In cases where there are only two alternatives, the X86_64
522 instruction is reserved, and "(bad)" is printed.
525 static const struct dis386 dis386[] = {
526 /* 00 */
527 { "addB", Eb, Gb, XX, XX },
528 { "addS", Ev, Gv, XX, XX },
529 { "addB", Gb, Eb, XX, XX },
530 { "addS", Gv, Ev, XX, XX },
531 { "addB", AL, Ib, XX, XX },
532 { "addS", eAX, Iv, XX, XX },
533 { "push{T|}", es, XX, XX, XX },
534 { "pop{T|}", es, XX, XX, XX },
535 /* 08 */
536 { "orB", Eb, Gb, XX, XX },
537 { "orS", Ev, Gv, XX, XX },
538 { "orB", Gb, Eb, XX, XX },
539 { "orS", Gv, Ev, XX , XX},
540 { "orB", AL, Ib, XX, XX },
541 { "orS", eAX, Iv, XX, XX },
542 { "push{T|}", cs, XX, XX, XX },
543 { "(bad)", XX, XX, XX, XX }, /* 0x0f extended opcode escape */
544 /* 10 */
545 { "adcB", Eb, Gb, XX, XX },
546 { "adcS", Ev, Gv, XX, XX },
547 { "adcB", Gb, Eb, XX, XX },
548 { "adcS", Gv, Ev, XX, XX },
549 { "adcB", AL, Ib, XX, XX },
550 { "adcS", eAX, Iv, XX, XX },
551 { "push{T|}", ss, XX, XX, XX },
552 { "pop{T|}", ss, XX, XX, XX },
553 /* 18 */
554 { "sbbB", Eb, Gb, XX, XX },
555 { "sbbS", Ev, Gv, XX, XX },
556 { "sbbB", Gb, Eb, XX, XX },
557 { "sbbS", Gv, Ev, XX, XX },
558 { "sbbB", AL, Ib, XX, XX },
559 { "sbbS", eAX, Iv, XX, XX },
560 { "push{T|}", ds, XX, XX, XX },
561 { "pop{T|}", ds, XX, XX, XX },
562 /* 20 */
563 { "andB", Eb, Gb, XX, XX },
564 { "andS", Ev, Gv, XX, XX },
565 { "andB", Gb, Eb, XX, XX },
566 { "andS", Gv, Ev, XX, XX },
567 { "andB", AL, Ib, XX, XX },
568 { "andS", eAX, Iv, XX, XX },
569 { "(bad)", XX, XX, XX, XX }, /* SEG ES prefix */
570 { "daa{|}", XX, XX, XX, XX },
571 /* 28 */
572 { "subB", Eb, Gb, XX, XX },
573 { "subS", Ev, Gv, XX, XX},
574 { "subB", Gb, Eb, XX, XX },
575 { "subS", Gv, Ev, XX, XX },
576 { "subB", AL, Ib, XX, XX },
577 { "subS", eAX, Iv, XX, XX },
578 { "(bad)", XX, XX, XX, XX }, /* SEG CS prefix */
579 { "das{|}", XX, XX, XX, XX },
580 /* 30 */
581 { "xorB", Eb, Gb, XX, XX },
582 { "xorS", Ev, Gv, XX, XX },
583 { "xorB", Gb, Eb, XX, XX },
584 { "xorS", Gv, Ev, XX, XX },
585 { "xorB", AL, Ib, XX, XX },
586 { "xorS", eAX, Iv, XX, XX },
587 { "(bad)", XX, XX, XX, XX }, /* SEG SS prefix */
588 { "aaa{|}", XX, XX, XX, XX },
589 /* 38 */
590 { "cmpB", Eb, Gb, XX, XX },
591 { "cmpS", Ev, Gv, XX, XX },
592 { "cmpB", Gb, Eb, XX, XX },
593 { "cmpS", Gv, Ev, XX, XX },
594 { "cmpB", AL, Ib, XX, XX },
595 { "cmpS", eAX, Iv, XX, XX },
596 { "(bad)", XX, XX, XX, XX }, /* SEG DS prefix */
597 { "aas{|}", XX, XX, XX, XX },
598 /* 40 */
599 { "inc{S|}", RMeAX, XX, XX, XX },
600 { "inc{S|}", RMeCX, XX, XX, XX },
601 { "inc{S|}", RMeDX, XX, XX, XX },
602 { "inc{S|}", RMeBX, XX, XX, XX },
603 { "inc{S|}", RMeSP, XX, XX, XX },
604 { "inc{S|}", RMeBP, XX, XX, XX },
605 { "inc{S|}", RMeSI, XX, XX, XX },
606 { "inc{S|}", RMeDI, XX, XX, XX },
607 /* 48 */
608 { "dec{S|}", RMeAX, XX, XX, XX },
609 { "dec{S|}", RMeCX, XX, XX, XX },
610 { "dec{S|}", RMeDX, XX, XX, XX },
611 { "dec{S|}", RMeBX, XX, XX, XX },
612 { "dec{S|}", RMeSP, XX, XX, XX },
613 { "dec{S|}", RMeBP, XX, XX, XX },
614 { "dec{S|}", RMeSI, XX, XX, XX },
615 { "dec{S|}", RMeDI, XX, XX, XX },
616 /* 50 */
617 { "pushV", RMrAX, XX, XX, XX },
618 { "pushV", RMrCX, XX, XX, XX },
619 { "pushV", RMrDX, XX, XX, XX },
620 { "pushV", RMrBX, XX, XX, XX },
621 { "pushV", RMrSP, XX, XX, XX },
622 { "pushV", RMrBP, XX, XX, XX },
623 { "pushV", RMrSI, XX, XX, XX },
624 { "pushV", RMrDI, XX, XX, XX },
625 /* 58 */
626 { "popV", RMrAX, XX, XX, XX },
627 { "popV", RMrCX, XX, XX, XX },
628 { "popV", RMrDX, XX, XX, XX },
629 { "popV", RMrBX, XX, XX, XX },
630 { "popV", RMrSP, XX, XX, XX },
631 { "popV", RMrBP, XX, XX, XX },
632 { "popV", RMrSI, XX, XX, XX },
633 { "popV", RMrDI, XX, XX, XX },
634 /* 60 */
635 { "pusha{P|}", XX, XX, XX, XX},
636 { "popa{P|}", XX, XX, XX, XX },
637 { "bound{S|}", Gv, Ma, XX, XX },
638 { X86_64_0 },
639 { "(bad)", XX, XX, XX, XX }, /* seg fs */
640 { "(bad)", XX, XX, XX, XX }, /* seg gs */
641 { "(bad)", XX, XX, XX, XX }, /* op size prefix */
642 { "(bad)", XX, XX, XX, XX }, /* adr size prefix */
643 /* 68 */
644 { "pushT", Iq, XX, XX, XX },
645 { "imulS", Gv, Ev, Iv, XX },
646 { "pushT", sIb, XX, XX, XX },
647 { "imulS", Gv, Ev, sIb, XX },
648 { "ins{b||b|}", Ybr, indirDX, XX, XX },
649 { "ins{R||R|}", Yvr, indirDX, XX, XX },
650 { "outs{b||b|}", indirDXr, Xb, XX, XX },
651 { "outs{R||R|}", indirDXr, Xv, XX, XX },
652 /* 70 */
653 { "joH", Jb, XX, cond_jump_flag, XX },
654 { "jnoH", Jb, XX, cond_jump_flag, XX },
655 { "jbH", Jb, XX, cond_jump_flag, XX },
656 { "jaeH", Jb, XX, cond_jump_flag, XX },
657 { "jeH", Jb, XX, cond_jump_flag, XX },
658 { "jneH", Jb, XX, cond_jump_flag, XX },
659 { "jbeH", Jb, XX, cond_jump_flag, XX },
660 { "jaH", Jb, XX, cond_jump_flag, XX },
661 /* 78 */
662 { "jsH", Jb, XX, cond_jump_flag, XX },
663 { "jnsH", Jb, XX, cond_jump_flag, XX },
664 { "jpH", Jb, XX, cond_jump_flag, XX },
665 { "jnpH", Jb, XX, cond_jump_flag, XX },
666 { "jlH", Jb, XX, cond_jump_flag, XX },
667 { "jgeH", Jb, XX, cond_jump_flag, XX },
668 { "jleH", Jb, XX, cond_jump_flag, XX },
669 { "jgH", Jb, XX, cond_jump_flag, XX },
670 /* 80 */
671 { GRP1b },
672 { GRP1S },
673 { "(bad)", XX, XX, XX, XX },
674 { GRP1Ss },
675 { "testB", Eb, Gb, XX, XX },
676 { "testS", Ev, Gv, XX, XX },
677 { "xchgB", Eb, Gb, XX, XX },
678 { "xchgS", Ev, Gv, XX, XX },
679 /* 88 */
680 { "movB", Eb, Gb, XX, XX },
681 { "movS", Ev, Gv, XX, XX },
682 { "movB", Gb, Eb, XX, XX },
683 { "movS", Gv, Ev, XX, XX },
684 { "movQ", Sv, Sw, XX, XX },
685 { "leaS", Gv, M, XX, XX },
686 { "movQ", Sw, Sv, XX, XX },
687 { "popU", stackEv, XX, XX, XX },
688 /* 90 */
689 { "xchgS", NOP_Fixup1, eAX_reg, NOP_Fixup2, eAX_reg, XX, XX },
690 { "xchgS", RMeCX, eAX, XX, XX },
691 { "xchgS", RMeDX, eAX, XX, XX },
692 { "xchgS", RMeBX, eAX, XX, XX },
693 { "xchgS", RMeSP, eAX, XX, XX },
694 { "xchgS", RMeBP, eAX, XX, XX },
695 { "xchgS", RMeSI, eAX, XX, XX },
696 { "xchgS", RMeDI, eAX, XX, XX },
697 /* 98 */
698 { "cW{tR||tR|}", XX, XX, XX, XX },
699 { "cR{tO||tO|}", XX, XX, XX, XX },
700 { "Jcall{T|}", Ap, XX, XX, XX },
701 { "(bad)", XX, XX, XX, XX }, /* fwait */
702 { "pushfT", XX, XX, XX, XX },
703 { "popfT", XX, XX, XX, XX },
704 { "sahf{|}", XX, XX, XX, XX },
705 { "lahf{|}", XX, XX, XX, XX },
706 /* a0 */
707 { "movB", AL, Ob, XX, XX },
708 { "movS", eAX, Ov, XX, XX },
709 { "movB", Ob, AL, XX, XX },
710 { "movS", Ov, eAX, XX, XX },
711 { "movs{b||b|}", Ybr, Xb, XX, XX },
712 { "movs{R||R|}", Yvr, Xv, XX, XX },
713 { "cmps{b||b|}", Xb, Yb, XX, XX },
714 { "cmps{R||R|}", Xv, Yv, XX, XX },
715 /* a8 */
716 { "testB", AL, Ib, XX, XX },
717 { "testS", eAX, Iv, XX, XX },
718 { "stosB", Ybr, AL, XX, XX },
719 { "stosS", Yvr, eAX, XX, XX },
720 { "lodsB", ALr, Xb, XX, XX },
721 { "lodsS", eAXr, Xv, XX, XX },
722 { "scasB", AL, Yb, XX, XX },
723 { "scasS", eAX, Yv, XX, XX },
724 /* b0 */
725 { "movB", RMAL, Ib, XX, XX },
726 { "movB", RMCL, Ib, XX, XX },
727 { "movB", RMDL, Ib, XX, XX },
728 { "movB", RMBL, Ib, XX, XX },
729 { "movB", RMAH, Ib, XX, XX },
730 { "movB", RMCH, Ib, XX, XX },
731 { "movB", RMDH, Ib, XX, XX },
732 { "movB", RMBH, Ib, XX, XX },
733 /* b8 */
734 { "movS", RMeAX, Iv64, XX, XX },
735 { "movS", RMeCX, Iv64, XX, XX },
736 { "movS", RMeDX, Iv64, XX, XX },
737 { "movS", RMeBX, Iv64, XX, XX },
738 { "movS", RMeSP, Iv64, XX, XX },
739 { "movS", RMeBP, Iv64, XX, XX },
740 { "movS", RMeSI, Iv64, XX, XX },
741 { "movS", RMeDI, Iv64, XX, XX },
742 /* c0 */
743 { GRP2b },
744 { GRP2S },
745 { "retT", Iw, XX, XX, XX },
746 { "retT", XX, XX, XX, XX },
747 { "les{S|}", Gv, Mp, XX, XX },
748 { "ldsS", Gv, Mp, XX, XX },
749 { "movA", Eb, Ib, XX, XX },
750 { "movQ", Ev, Iv, XX, XX },
751 /* c8 */
752 { "enterT", Iw, Ib, XX, XX },
753 { "leaveT", XX, XX, XX, XX },
754 { "lretP", Iw, XX, XX, XX },
755 { "lretP", XX, XX, XX, XX },
756 { "int3", XX, XX, XX, XX },
757 { "int", Ib, XX, XX, XX },
758 { "into{|}", XX, XX, XX, XX },
759 { "iretP", XX, XX, XX, XX },
760 /* d0 */
761 { GRP2b_one },
762 { GRP2S_one },
763 { GRP2b_cl },
764 { GRP2S_cl },
765 { "aam{|}", sIb, XX, XX, XX },
766 { "aad{|}", sIb, XX, XX, XX },
767 { "(bad)", XX, XX, XX, XX },
768 { "xlat", DSBX, XX, XX, XX },
769 /* d8 */
770 { FLOAT },
771 { FLOAT },
772 { FLOAT },
773 { FLOAT },
774 { FLOAT },
775 { FLOAT },
776 { FLOAT },
777 { FLOAT },
778 /* e0 */
779 { "loopneFH", Jb, XX, loop_jcxz_flag, XX },
780 { "loopeFH", Jb, XX, loop_jcxz_flag, XX },
781 { "loopFH", Jb, XX, loop_jcxz_flag, XX },
782 { "jEcxzH", Jb, XX, loop_jcxz_flag, XX },
783 { "inB", AL, Ib, XX, XX },
784 { "inS", eAX, Ib, XX, XX },
785 { "outB", Ib, AL, XX, XX },
786 { "outS", Ib, eAX, XX, XX },
787 /* e8 */
788 { "callT", Jv, XX, XX, XX },
789 { "jmpT", Jv, XX, XX, XX },
790 { "Jjmp{T|}", Ap, XX, XX, XX },
791 { "jmp", Jb, XX, XX, XX },
792 { "inB", AL, indirDX, XX, XX },
793 { "inS", eAX, indirDX, XX, XX },
794 { "outB", indirDX, AL, XX, XX },
795 { "outS", indirDX, eAX, XX, XX },
796 /* f0 */
797 { "(bad)", XX, XX, XX, XX }, /* lock prefix */
798 { "icebp", XX, XX, XX, XX },
799 { "(bad)", XX, XX, XX, XX }, /* repne */
800 { "(bad)", XX, XX, XX, XX }, /* repz */
801 { "hlt", XX, XX, XX, XX },
802 { "cmc", XX, XX, XX, XX },
803 { GRP3b },
804 { GRP3S },
805 /* f8 */
806 { "clc", XX, XX, XX, XX },
807 { "stc", XX, XX, XX, XX },
808 { "cli", XX, XX, XX, XX },
809 { "sti", XX, XX, XX, XX },
810 { "cld", XX, XX, XX, XX },
811 { "std", XX, XX, XX, XX },
812 { GRP4 },
813 { GRP5 },
816 static const struct dis386 dis386_twobyte[] = {
817 /* 00 */
818 { GRP6 },
819 { GRP7 },
820 { "larS", Gv, Ew, XX, XX },
821 { "lslS", Gv, Ew, XX, XX },
822 { "(bad)", XX, XX, XX, XX },
823 { "syscall", XX, XX, XX, XX },
824 { "clts", XX, XX, XX, XX },
825 { "sysretP", XX, XX, XX, XX },
826 /* 08 */
827 { "invd", XX, XX, XX, XX},
828 { "wbinvd", XX, XX, XX, XX },
829 { "(bad)", XX, XX, XX, XX },
830 { "ud2a", XX, XX, XX, XX },
831 { "(bad)", XX, XX, XX, XX },
832 { GRPAMD },
833 { "femms", XX, XX, XX, XX },
834 { "", MX, EM, OPSUF, XX }, /* See OP_3DNowSuffix. */
835 /* 10 */
836 { PREGRP8 },
837 { PREGRP9 },
838 { PREGRP30 },
839 { "movlpX", EX, XM, SIMD_Fixup, 'h', XX },
840 { "unpcklpX", XM, EX, XX, XX },
841 { "unpckhpX", XM, EX, XX, XX },
842 { PREGRP31 },
843 { "movhpX", EX, XM, SIMD_Fixup, 'l', XX },
844 /* 18 */
845 { GRP16 },
846 { "(bad)", XX, XX, XX, XX },
847 { "(bad)", XX, XX, XX, XX },
848 { "(bad)", XX, XX, XX, XX },
849 { "(bad)", XX, XX, XX, XX },
850 { "(bad)", XX, XX, XX, XX },
851 { "(bad)", XX, XX, XX, XX },
852 { "nopQ", Ev, XX, XX, XX },
853 /* 20 */
854 { "movZ", Rm, Cm, XX, XX },
855 { "movZ", Rm, Dm, XX, XX },
856 { "movZ", Cm, Rm, XX, XX },
857 { "movZ", Dm, Rm, XX, XX },
858 { "movL", Rd, Td, XX, XX },
859 { "(bad)", XX, XX, XX, XX },
860 { "movL", Td, Rd, XX, XX },
861 { "(bad)", XX, XX, XX, XX },
862 /* 28 */
863 { "movapX", XM, EX, XX, XX },
864 { "movapX", EX, XM, XX, XX },
865 { PREGRP2 },
866 { PREGRP33 },
867 { PREGRP4 },
868 { PREGRP3 },
869 { "ucomisX", XM,EX, XX, XX },
870 { "comisX", XM,EX, XX, XX },
871 /* 30 */
872 { "wrmsr", XX, XX, XX, XX },
873 { "rdtsc", XX, XX, XX, XX },
874 { "rdmsr", XX, XX, XX, XX },
875 { "rdpmc", XX, XX, XX, XX },
876 { "sysenter", XX, XX, XX, XX },
877 { "sysexit", XX, XX, XX, XX },
878 { "(bad)", XX, XX, XX, XX },
879 { "(bad)", XX, XX, XX, XX },
880 /* 38 */
881 { THREE_BYTE_0 },
882 { "(bad)", XX, XX, XX, XX },
883 { THREE_BYTE_1 },
884 { "(bad)", XX, XX, XX, XX },
885 { "(bad)", XX, XX, XX, XX },
886 { "(bad)", XX, XX, XX, XX },
887 { "(bad)", XX, XX, XX, XX },
888 { "(bad)", XX, XX, XX, XX },
889 /* 40 */
890 { "cmovo", Gv, Ev, XX, XX },
891 { "cmovno", Gv, Ev, XX, XX },
892 { "cmovb", Gv, Ev, XX, XX },
893 { "cmovae", Gv, Ev, XX, XX },
894 { "cmove", Gv, Ev, XX, XX },
895 { "cmovne", Gv, Ev, XX, XX },
896 { "cmovbe", Gv, Ev, XX, XX },
897 { "cmova", Gv, Ev, XX, XX },
898 /* 48 */
899 { "cmovs", Gv, Ev, XX, XX },
900 { "cmovns", Gv, Ev, XX, XX },
901 { "cmovp", Gv, Ev, XX, XX },
902 { "cmovnp", Gv, Ev, XX, XX },
903 { "cmovl", Gv, Ev, XX, XX },
904 { "cmovge", Gv, Ev, XX, XX },
905 { "cmovle", Gv, Ev, XX, XX },
906 { "cmovg", Gv, Ev, XX, XX },
907 /* 50 */
908 { "movmskpX", Gdq, XS, XX, XX },
909 { PREGRP13 },
910 { PREGRP12 },
911 { PREGRP11 },
912 { "andpX", XM, EX, XX, XX },
913 { "andnpX", XM, EX, XX, XX },
914 { "orpX", XM, EX, XX, XX },
915 { "xorpX", XM, EX, XX, XX },
916 /* 58 */
917 { PREGRP0 },
918 { PREGRP10 },
919 { PREGRP17 },
920 { PREGRP16 },
921 { PREGRP14 },
922 { PREGRP7 },
923 { PREGRP5 },
924 { PREGRP6 },
925 /* 60 */
926 { "punpcklbw", MX, EM, XX, XX },
927 { "punpcklwd", MX, EM, XX, XX },
928 { "punpckldq", MX, EM, XX, XX },
929 { "packsswb", MX, EM, XX, XX },
930 { "pcmpgtb", MX, EM, XX, XX },
931 { "pcmpgtw", MX, EM, XX, XX },
932 { "pcmpgtd", MX, EM, XX, XX },
933 { "packuswb", MX, EM, XX, XX },
934 /* 68 */
935 { "punpckhbw", MX, EM, XX, XX },
936 { "punpckhwd", MX, EM, XX, XX },
937 { "punpckhdq", MX, EM, XX, XX },
938 { "packssdw", MX, EM, XX, XX },
939 { PREGRP26 },
940 { PREGRP24 },
941 { "movd", MX, Edq, XX, XX },
942 { PREGRP19 },
943 /* 70 */
944 { PREGRP22 },
945 { GRP12 },
946 { GRP13 },
947 { GRP14 },
948 { "pcmpeqb", MX, EM, XX, XX },
949 { "pcmpeqw", MX, EM, XX, XX },
950 { "pcmpeqd", MX, EM, XX, XX },
951 { "emms", XX, XX, XX, XX },
952 /* 78 */
953 { PREGRP34 },
954 { PREGRP35 },
955 { "(bad)", XX, XX, XX, XX },
956 { "(bad)", XX, XX, XX, XX },
957 { PREGRP28 },
958 { PREGRP29 },
959 { PREGRP23 },
960 { PREGRP20 },
961 /* 80 */
962 { "joH", Jv, XX, cond_jump_flag, XX },
963 { "jnoH", Jv, XX, cond_jump_flag, XX },
964 { "jbH", Jv, XX, cond_jump_flag, XX },
965 { "jaeH", Jv, XX, cond_jump_flag, XX },
966 { "jeH", Jv, XX, cond_jump_flag, XX },
967 { "jneH", Jv, XX, cond_jump_flag, XX },
968 { "jbeH", Jv, XX, cond_jump_flag, XX },
969 { "jaH", Jv, XX, cond_jump_flag, XX },
970 /* 88 */
971 { "jsH", Jv, XX, cond_jump_flag, XX },
972 { "jnsH", Jv, XX, cond_jump_flag, XX },
973 { "jpH", Jv, XX, cond_jump_flag, XX },
974 { "jnpH", Jv, XX, cond_jump_flag, XX },
975 { "jlH", Jv, XX, cond_jump_flag, XX },
976 { "jgeH", Jv, XX, cond_jump_flag, XX },
977 { "jleH", Jv, XX, cond_jump_flag, XX },
978 { "jgH", Jv, XX, cond_jump_flag, XX },
979 /* 90 */
980 { "seto", Eb, XX, XX, XX },
981 { "setno", Eb, XX, XX, XX },
982 { "setb", Eb, XX, XX, XX },
983 { "setae", Eb, XX, XX, XX },
984 { "sete", Eb, XX, XX, XX },
985 { "setne", Eb, XX, XX, XX },
986 { "setbe", Eb, XX, XX, XX },
987 { "seta", Eb, XX, XX, XX },
988 /* 98 */
989 { "sets", Eb, XX, XX, XX },
990 { "setns", Eb, XX, XX, XX },
991 { "setp", Eb, XX, XX, XX },
992 { "setnp", Eb, XX, XX, XX },
993 { "setl", Eb, XX, XX, XX },
994 { "setge", Eb, XX, XX, XX },
995 { "setle", Eb, XX, XX, XX },
996 { "setg", Eb, XX, XX, XX },
997 /* a0 */
998 { "pushT", fs, XX, XX, XX },
999 { "popT", fs, XX, XX, XX },
1000 { "cpuid", XX, XX, XX, XX },
1001 { "btS", Ev, Gv, XX, XX },
1002 { "shldS", Ev, Gv, Ib, XX },
1003 { "shldS", Ev, Gv, CL, XX },
1004 { GRPPADLCK2 },
1005 { GRPPADLCK1 },
1006 /* a8 */
1007 { "pushT", gs, XX, XX, XX },
1008 { "popT", gs, XX, XX, XX },
1009 { "rsm", XX, XX, XX, XX },
1010 { "btsS", Ev, Gv, XX, XX },
1011 { "shrdS", Ev, Gv, Ib, XX },
1012 { "shrdS", Ev, Gv, CL, XX },
1013 { GRP15 },
1014 { "imulS", Gv, Ev, XX, XX },
1015 /* b0 */
1016 { "cmpxchgB", Eb, Gb, XX, XX },
1017 { "cmpxchgS", Ev, Gv, XX, XX },
1018 { "lssS", Gv, Mp, XX, XX },
1019 { "btrS", Ev, Gv, XX, XX },
1020 { "lfsS", Gv, Mp, XX, XX },
1021 { "lgsS", Gv, Mp, XX, XX },
1022 { "movz{bR|x|bR|x}", Gv, Eb, XX, XX },
1023 { "movz{wR|x|wR|x}", Gv, Ew, XX, XX }, /* yes, there really is movzww ! */
1024 /* b8 */
1025 { "popcntS", Gv, Ev, XX, XX },
1026 { "ud2b", XX, XX, XX, XX },
1027 { GRP8 },
1028 { "btcS", Ev, Gv, XX, XX },
1029 { "bsfS", Gv, Ev, XX, XX },
1030 { PREGRP36 },
1031 { "movs{bR|x|bR|x}", Gv, Eb, XX, XX },
1032 { "movs{wR|x|wR|x}", Gv, Ew, XX, XX }, /* yes, there really is movsww ! */
1033 /* c0 */
1034 { "xaddB", Eb, Gb, XX, XX },
1035 { "xaddS", Ev, Gv, XX, XX },
1036 { PREGRP1 },
1037 { "movntiS", Ev, Gv, XX, XX },
1038 { "pinsrw", MX, Edqw, Ib, XX },
1039 { "pextrw", Gdq, MS, Ib, XX },
1040 { "shufpX", XM, EX, Ib, XX },
1041 { GRP9 },
1042 /* c8 */
1043 { "bswap", RMeAX, XX, XX, XX },
1044 { "bswap", RMeCX, XX, XX, XX },
1045 { "bswap", RMeDX, XX, XX, XX },
1046 { "bswap", RMeBX, XX, XX, XX },
1047 { "bswap", RMeSP, XX, XX, XX },
1048 { "bswap", RMeBP, XX, XX, XX },
1049 { "bswap", RMeSI, XX, XX, XX },
1050 { "bswap", RMeDI, XX, XX, XX },
1051 /* d0 */
1052 { PREGRP27 },
1053 { "psrlw", MX, EM, XX, XX },
1054 { "psrld", MX, EM, XX, XX },
1055 { "psrlq", MX, EM, XX, XX },
1056 { "paddq", MX, EM, XX, XX },
1057 { "pmullw", MX, EM, XX, XX },
1058 { PREGRP21 },
1059 { "pmovmskb", Gdq, MS, XX, XX },
1060 /* d8 */
1061 { "psubusb", MX, EM, XX, XX },
1062 { "psubusw", MX, EM, XX, XX },
1063 { "pminub", MX, EM, XX, XX },
1064 { "pand", MX, EM, XX, XX },
1065 { "paddusb", MX, EM, XX, XX },
1066 { "paddusw", MX, EM, XX, XX },
1067 { "pmaxub", MX, EM, XX, XX },
1068 { "pandn", MX, EM, XX, XX },
1069 /* e0 */
1070 { "pavgb", MX, EM, XX, XX },
1071 { "psraw", MX, EM, XX, XX },
1072 { "psrad", MX, EM, XX, XX },
1073 { "pavgw", MX, EM, XX, XX },
1074 { "pmulhuw", MX, EM, XX, XX },
1075 { "pmulhw", MX, EM, XX, XX },
1076 { PREGRP15 },
1077 { PREGRP25 },
1078 /* e8 */
1079 { "psubsb", MX, EM, XX, XX },
1080 { "psubsw", MX, EM, XX, XX },
1081 { "pminsw", MX, EM, XX, XX },
1082 { "por", MX, EM, XX, XX },
1083 { "paddsb", MX, EM, XX, XX },
1084 { "paddsw", MX, EM, XX, XX },
1085 { "pmaxsw", MX, EM, XX, XX },
1086 { "pxor", MX, EM, XX, XX },
1087 /* f0 */
1088 { PREGRP32 },
1089 { "psllw", MX, EM, XX, XX },
1090 { "pslld", MX, EM, XX, XX },
1091 { "psllq", MX, EM, XX, XX },
1092 { "pmuludq", MX, EM, XX, XX },
1093 { "pmaddwd", MX, EM, XX, XX },
1094 { "psadbw", MX, EM, XX, XX },
1095 { PREGRP18 },
1096 /* f8 */
1097 { "psubb", MX, EM, XX, XX },
1098 { "psubw", MX, EM, XX, XX },
1099 { "psubd", MX, EM, XX, XX },
1100 { "psubq", MX, EM, XX, XX },
1101 { "paddb", MX, EM, XX, XX },
1102 { "paddw", MX, EM, XX, XX },
1103 { "paddd", MX, EM, XX, XX },
1104 { "(bad)", XX, XX, XX, XX }
1107 static const unsigned char onebyte_has_modrm[256] = {
1108 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1109 /* ------------------------------- */
1110 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1111 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1112 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1113 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1114 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1115 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1116 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1117 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1118 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1119 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1120 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1121 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1122 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1123 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1124 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1125 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1126 /* ------------------------------- */
1127 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1130 static const unsigned char twobyte_has_modrm[256] = {
1131 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1132 /* ------------------------------- */
1133 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1134 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1135 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1136 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1137 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1138 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1139 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1140 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1141 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1142 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1143 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1144 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1145 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1146 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1147 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1148 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1149 /* ------------------------------- */
1150 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1153 static const unsigned char twobyte_uses_SSE_prefix[256] = {
1154 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1155 /* ------------------------------- */
1156 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1157 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1158 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1159 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1160 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1161 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1162 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1163 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
1164 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1165 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1166 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1167 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1168 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1169 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1170 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1171 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1172 /* ------------------------------- */
1173 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1176 static char obuf[100];
1177 static char *obufp;
1178 static char scratchbuf[100];
1179 static unsigned char *start_codep;
1180 static unsigned char *insn_codep;
1181 static unsigned char *codep;
1182 static disassemble_info *the_info;
1183 static int mod;
1184 static int rm;
1185 static int reg;
1186 static unsigned char need_modrm;
1188 /* If we are accessing mod/rm/reg without need_modrm set, then the
1189 values are stale. Hitting this abort likely indicates that you
1190 need to update onebyte_has_modrm or twobyte_has_modrm. */
1191 #define MODRM_CHECK if (!need_modrm) abort ()
1193 static const char **names64;
1194 static const char **names32;
1195 static const char **names16;
1196 static const char **names8;
1197 static const char **names8rex;
1198 static const char **names_seg;
1199 static const char **index16;
1201 static const char *intel_names64[] = {
1202 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1203 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1205 static const char *intel_names32[] = {
1206 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1207 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1209 static const char *intel_names16[] = {
1210 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1211 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1213 static const char *intel_names8[] = {
1214 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1216 static const char *intel_names8rex[] = {
1217 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1218 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1220 static const char *intel_names_seg[] = {
1221 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1223 static const char *intel_index16[] = {
1224 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1227 static const char *att_names64[] = {
1228 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1229 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1231 static const char *att_names32[] = {
1232 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1233 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1235 static const char *att_names16[] = {
1236 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1237 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1239 static const char *att_names8[] = {
1240 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1242 static const char *att_names8rex[] = {
1243 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1244 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1246 static const char *att_names_seg[] = {
1247 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1249 static const char *att_index16[] = {
1250 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1253 static const struct dis386 grps[][8] = {
1254 /* GRP1b */
1256 { "addA", Eb, Ib, XX, XX },
1257 { "orA", Eb, Ib, XX, XX },
1258 { "adcA", Eb, Ib, XX, XX },
1259 { "sbbA", Eb, Ib, XX, XX },
1260 { "andA", Eb, Ib, XX, XX },
1261 { "subA", Eb, Ib, XX, XX },
1262 { "xorA", Eb, Ib, XX, XX },
1263 { "cmpA", Eb, Ib, XX, XX }
1265 /* GRP1S */
1267 { "addQ", Ev, Iv, XX, XX },
1268 { "orQ", Ev, Iv, XX, XX },
1269 { "adcQ", Ev, Iv, XX, XX },
1270 { "sbbQ", Ev, Iv, XX, XX },
1271 { "andQ", Ev, Iv, XX, XX },
1272 { "subQ", Ev, Iv, XX, XX },
1273 { "xorQ", Ev, Iv, XX, XX },
1274 { "cmpQ", Ev, Iv, XX, XX }
1276 /* GRP1Ss */
1278 { "addQ", Ev, sIb, XX, XX },
1279 { "orQ", Ev, sIb, XX, XX },
1280 { "adcQ", Ev, sIb, XX, XX },
1281 { "sbbQ", Ev, sIb, XX, XX },
1282 { "andQ", Ev, sIb, XX, XX },
1283 { "subQ", Ev, sIb, XX, XX },
1284 { "xorQ", Ev, sIb, XX, XX },
1285 { "cmpQ", Ev, sIb, XX, XX }
1287 /* GRP2b */
1289 { "rolA", Eb, Ib, XX, XX },
1290 { "rorA", Eb, Ib, XX, XX },
1291 { "rclA", Eb, Ib, XX, XX },
1292 { "rcrA", Eb, Ib, XX, XX },
1293 { "shlA", Eb, Ib, XX, XX },
1294 { "shrA", Eb, Ib, XX, XX },
1295 { "(bad)", XX, XX, XX, XX },
1296 { "sarA", Eb, Ib, XX, XX },
1298 /* GRP2S */
1300 { "rolQ", Ev, Ib, XX, XX },
1301 { "rorQ", Ev, Ib, XX, XX },
1302 { "rclQ", Ev, Ib, XX, XX },
1303 { "rcrQ", Ev, Ib, XX, XX },
1304 { "shlQ", Ev, Ib, XX, XX },
1305 { "shrQ", Ev, Ib, XX, XX },
1306 { "(bad)", XX, XX, XX, XX },
1307 { "sarQ", Ev, Ib, XX, XX },
1309 /* GRP2b_one */
1311 { "rolA", Eb, I1, XX, XX },
1312 { "rorA", Eb, I1, XX, XX },
1313 { "rclA", Eb, I1, XX, XX },
1314 { "rcrA", Eb, I1, XX, XX },
1315 { "shlA", Eb, I1, XX, XX },
1316 { "shrA", Eb, I1, XX, XX },
1317 { "(bad)", XX, XX, XX, XX },
1318 { "sarA", Eb, I1, XX, XX },
1320 /* GRP2S_one */
1322 { "rolQ", Ev, I1, XX, XX },
1323 { "rorQ", Ev, I1, XX, XX },
1324 { "rclQ", Ev, I1, XX, XX },
1325 { "rcrQ", Ev, I1, XX, XX },
1326 { "shlQ", Ev, I1, XX, XX },
1327 { "shrQ", Ev, I1, XX, XX },
1328 { "(bad)", XX, XX, XX, XX },
1329 { "sarQ", Ev, I1, XX, XX },
1331 /* GRP2b_cl */
1333 { "rolA", Eb, CL, XX, XX },
1334 { "rorA", Eb, CL, XX, XX },
1335 { "rclA", Eb, CL, XX, XX },
1336 { "rcrA", Eb, CL, XX, XX },
1337 { "shlA", Eb, CL, XX, XX },
1338 { "shrA", Eb, CL, XX, XX },
1339 { "(bad)", XX, XX, XX, XX },
1340 { "sarA", Eb, CL, XX, XX },
1342 /* GRP2S_cl */
1344 { "rolQ", Ev, CL, XX, XX },
1345 { "rorQ", Ev, CL, XX, XX },
1346 { "rclQ", Ev, CL, XX, XX },
1347 { "rcrQ", Ev, CL, XX, XX },
1348 { "shlQ", Ev, CL, XX, XX },
1349 { "shrQ", Ev, CL, XX, XX },
1350 { "(bad)", XX, XX, XX, XX },
1351 { "sarQ", Ev, CL, XX, XX }
1353 /* GRP3b */
1355 { "testA", Eb, Ib, XX, XX },
1356 { "(bad)", Eb, XX, XX, XX },
1357 { "notA", Eb, XX, XX, XX },
1358 { "negA", Eb, XX, XX, XX },
1359 { "mulA", Eb, XX, XX, XX }, /* Don't print the implicit %al register, */
1360 { "imulA", Eb, XX, XX, XX }, /* to distinguish these opcodes from other */
1361 { "divA", Eb, XX, XX, XX }, /* mul/imul opcodes. Do the same for div */
1362 { "idivA", Eb, XX, XX, XX } /* and idiv for consistency. */
1364 /* GRP3S */
1366 { "testQ", Ev, Iv, XX, XX },
1367 { "(bad)", XX, XX, XX, XX },
1368 { "notQ", Ev, XX, XX, XX },
1369 { "negQ", Ev, XX, XX, XX },
1370 { "mulQ", Ev, XX, XX, XX }, /* Don't print the implicit register. */
1371 { "imulQ", Ev, XX, XX, XX },
1372 { "divQ", Ev, XX, XX, XX },
1373 { "idivQ", Ev, XX, XX, XX },
1375 /* GRP4 */
1377 { "incA", Eb, XX, XX, XX },
1378 { "decA", Eb, XX, XX, XX },
1379 { "(bad)", XX, XX, XX, XX },
1380 { "(bad)", XX, XX, XX, XX },
1381 { "(bad)", XX, XX, XX, XX },
1382 { "(bad)", XX, XX, XX, XX },
1383 { "(bad)", XX, XX, XX, XX },
1384 { "(bad)", XX, XX, XX, XX },
1386 /* GRP5 */
1388 { "incQ", Ev, XX, XX, XX },
1389 { "decQ", Ev, XX, XX, XX },
1390 { "callT", indirEv, XX, XX, XX },
1391 { "JcallT", indirEp, XX, XX, XX },
1392 { "jmpT", indirEv, XX, XX, XX },
1393 { "JjmpT", indirEp, XX, XX, XX },
1394 { "pushU", stackEv, XX, XX, XX },
1395 { "(bad)", XX, XX, XX, XX },
1397 /* GRP6 */
1399 { "sldtQ", Ev, XX, XX, XX },
1400 { "strQ", Ev, XX, XX, XX },
1401 { "lldt", Ew, XX, XX, XX },
1402 { "ltr", Ew, XX, XX, XX },
1403 { "verr", Ew, XX, XX, XX },
1404 { "verw", Ew, XX, XX, XX },
1405 { "(bad)", XX, XX, XX, XX },
1406 { "(bad)", XX, XX, XX, XX }
1408 /* GRP7 */
1410 { "sgdt{Q|IQ||}", VMX_Fixup, 0, XX, XX, XX },
1411 { "sidt{Q|IQ||}", PNI_Fixup, 0, XX, XX, XX },
1412 { "lgdt{Q|Q||}", M, XX, XX, XX },
1413 { "lidt{Q|Q||}", SVME_Fixup, 0, XX, XX, XX },
1414 { "smswQ", Ev, XX, XX, XX },
1415 { "(bad)", XX, XX, XX, XX },
1416 { "lmsw", Ew, XX, XX, XX },
1417 { "invlpg", INVLPG_Fixup, w_mode, XX, XX, XX },
1419 /* GRP8 */
1421 { "(bad)", XX, XX, XX, XX },
1422 { "(bad)", XX, XX, XX, XX },
1423 { "(bad)", XX, XX, XX, XX },
1424 { "(bad)", XX, XX, XX, XX },
1425 { "btQ", Ev, Ib, XX, XX },
1426 { "btsQ", Ev, Ib, XX, XX },
1427 { "btrQ", Ev, Ib, XX, XX },
1428 { "btcQ", Ev, Ib, XX, XX },
1430 /* GRP9 */
1432 { "(bad)", XX, XX, XX, XX },
1433 { "cmpxchg8b", Eq, XX, XX, XX },
1434 { "(bad)", XX, XX, XX, XX },
1435 { "(bad)", XX, XX, XX, XX },
1436 { "(bad)", XX, XX, XX, XX },
1437 { "(bad)", XX, XX, XX, XX },
1438 { "", VM, XX, XX, XX }, /* See OP_VMX. */
1439 { "vmptrst", Eq, XX, XX, XX },
1441 /* GRP12 */
1443 { "(bad)", XX, XX, XX, XX },
1444 { "(bad)", XX, XX, XX, XX },
1445 { "psrlw", MS, Ib, XX, XX },
1446 { "(bad)", XX, XX, XX, XX },
1447 { "psraw", MS, Ib, XX, XX },
1448 { "(bad)", XX, XX, XX, XX },
1449 { "psllw", MS, Ib, XX, XX },
1450 { "(bad)", XX, XX, XX, XX },
1452 /* GRP13 */
1454 { "(bad)", XX, XX, XX, XX },
1455 { "(bad)", XX, XX, XX, XX },
1456 { "psrld", MS, Ib, XX, XX },
1457 { "(bad)", XX, XX, XX, XX },
1458 { "psrad", MS, Ib, XX, XX },
1459 { "(bad)", XX, XX, XX, XX },
1460 { "pslld", MS, Ib, XX, XX },
1461 { "(bad)", XX, XX, XX, XX },
1463 /* GRP14 */
1465 { "(bad)", XX, XX, XX, XX },
1466 { "(bad)", XX, XX, XX, XX },
1467 { "psrlq", MS, Ib, XX, XX },
1468 { "psrldq", MS, Ib, XX, XX },
1469 { "(bad)", XX, XX, XX, XX },
1470 { "(bad)", XX, XX, XX, XX },
1471 { "psllq", MS, Ib, XX, XX },
1472 { "pslldq", MS, Ib, XX, XX },
1474 /* GRP15 */
1476 { "fxsave", Ev, XX, XX, XX },
1477 { "fxrstor", Ev, XX, XX, XX },
1478 { "ldmxcsr", Ev, XX, XX, XX },
1479 { "stmxcsr", Ev, XX, XX, XX },
1480 { "(bad)", XX, XX, XX, XX },
1481 { "lfence", OP_0fae, 0, XX, XX, XX },
1482 { "mfence", OP_0fae, 0, XX, XX, XX },
1483 { "clflush", OP_0fae, 0, XX, XX, XX },
1485 /* GRP16 */
1487 { "prefetchnta", Ev, XX, XX, XX },
1488 { "prefetcht0", Ev, XX, XX, XX },
1489 { "prefetcht1", Ev, XX, XX, XX },
1490 { "prefetcht2", Ev, XX, XX, XX },
1491 { "(bad)", XX, XX, XX, XX },
1492 { "(bad)", XX, XX, XX, XX },
1493 { "(bad)", XX, XX, XX, XX },
1494 { "(bad)", XX, XX, XX, XX },
1496 /* GRPAMD */
1498 { "prefetch", Eb, XX, XX, XX },
1499 { "prefetchw", Eb, XX, XX, XX },
1500 { "(bad)", XX, XX, XX, XX },
1501 { "(bad)", XX, XX, XX, XX },
1502 { "(bad)", XX, XX, XX, XX },
1503 { "(bad)", XX, XX, XX, XX },
1504 { "(bad)", XX, XX, XX, XX },
1505 { "(bad)", XX, XX, XX, XX },
1507 /* GRPPADLCK1 */
1509 { "xstore-rng", OP_0f07, 0, XX, XX, XX },
1510 { "xcrypt-ecb", OP_0f07, 0, XX, XX, XX },
1511 { "xcrypt-cbc", OP_0f07, 0, XX, XX, XX },
1512 { "xcrypt-ctr", OP_0f07, 0, XX, XX, XX },
1513 { "xcrypt-cfb", OP_0f07, 0, XX, XX, XX },
1514 { "xcrypt-ofb", OP_0f07, 0, XX, XX, XX },
1515 { "(bad)", OP_0f07, 0, XX, XX, XX },
1516 { "(bad)", OP_0f07, 0, XX, XX, XX },
1518 /* GRPPADLCK2 */
1520 { "montmul", OP_0f07, 0, XX, XX, XX },
1521 { "xsha1", OP_0f07, 0, XX, XX, XX },
1522 { "xsha256", OP_0f07, 0, XX, XX, XX },
1523 { "(bad)", OP_0f07, 0, XX, XX, XX },
1524 { "(bad)", OP_0f07, 0, XX, XX, XX },
1525 { "(bad)", OP_0f07, 0, XX, XX, XX },
1526 { "(bad)", OP_0f07, 0, XX, XX, XX },
1527 { "(bad)", OP_0f07, 0, XX, XX, XX },
1531 static const struct dis386 prefix_user_table[][4] = {
1532 /* PREGRP0 */
1534 { "addps", XM, EX, XX, XX },
1535 { "addss", XM, EX, XX, XX },
1536 { "addpd", XM, EX, XX, XX },
1537 { "addsd", XM, EX, XX, XX },
1539 /* PREGRP1 */
1541 { "", XM, EX, OPSIMD, XX }, /* See OP_SIMD_SUFFIX. */
1542 { "", XM, EX, OPSIMD, XX },
1543 { "", XM, EX, OPSIMD, XX },
1544 { "", XM, EX, OPSIMD, XX },
1546 /* PREGRP2 */
1548 { "cvtpi2ps", XM, EM, XX, XX },
1549 { "cvtsi2ssY", XM, Ev, XX, XX },
1550 { "cvtpi2pd", XM, EM, XX, XX },
1551 { "cvtsi2sdY", XM, Ev, XX, XX },
1553 /* PREGRP3 */
1555 { "cvtps2pi", MX, EX, XX, XX },
1556 { "cvtss2siY", Gv, EX, XX, XX },
1557 { "cvtpd2pi", MX, EX, XX, XX },
1558 { "cvtsd2siY", Gv, EX, XX, XX },
1560 /* PREGRP4 */
1562 { "cvttps2pi", MX, EX, XX, XX },
1563 { "cvttss2siY", Gv, EX, XX, XX },
1564 { "cvttpd2pi", MX, EX, XX, XX },
1565 { "cvttsd2siY", Gv, EX, XX, XX },
1567 /* PREGRP5 */
1569 { "divps", XM, EX, XX, XX },
1570 { "divss", XM, EX, XX, XX },
1571 { "divpd", XM, EX, XX, XX },
1572 { "divsd", XM, EX, XX, XX },
1574 /* PREGRP6 */
1576 { "maxps", XM, EX, XX, XX },
1577 { "maxss", XM, EX, XX, XX },
1578 { "maxpd", XM, EX, XX, XX },
1579 { "maxsd", XM, EX, XX, XX },
1581 /* PREGRP7 */
1583 { "minps", XM, EX, XX, XX },
1584 { "minss", XM, EX, XX, XX },
1585 { "minpd", XM, EX, XX, XX },
1586 { "minsd", XM, EX, XX, XX },
1588 /* PREGRP8 */
1590 { "movups", XM, EX, XX, XX },
1591 { "movss", XM, EX, XX, XX },
1592 { "movupd", XM, EX, XX, XX },
1593 { "movsd", XM, EX, XX, XX },
1595 /* PREGRP9 */
1597 { "movups", EX, XM, XX, XX },
1598 { "movss", EX, XM, XX, XX },
1599 { "movupd", EX, XM, XX, XX },
1600 { "movsd", EX, XM, XX, XX },
1602 /* PREGRP10 */
1604 { "mulps", XM, EX, XX, XX },
1605 { "mulss", XM, EX, XX, XX },
1606 { "mulpd", XM, EX, XX, XX },
1607 { "mulsd", XM, EX, XX, XX },
1609 /* PREGRP11 */
1611 { "rcpps", XM, EX, XX, XX },
1612 { "rcpss", XM, EX, XX, XX },
1613 { "(bad)", XM, EX, XX, XX },
1614 { "(bad)", XM, EX, XX, XX },
1616 /* PREGRP12 */
1618 { "rsqrtps", XM, EX, XX, XX },
1619 { "rsqrtss", XM, EX, XX, XX },
1620 { "(bad)", XM, EX, XX, XX },
1621 { "(bad)", XM, EX, XX, XX },
1623 /* PREGRP13 */
1625 { "sqrtps", XM, EX, XX, XX },
1626 { "sqrtss", XM, EX, XX, XX },
1627 { "sqrtpd", XM, EX, XX, XX },
1628 { "sqrtsd", XM, EX, XX, XX },
1630 /* PREGRP14 */
1632 { "subps", XM, EX, XX, XX },
1633 { "subss", XM, EX, XX, XX },
1634 { "subpd", XM, EX, XX, XX },
1635 { "subsd", XM, EX, XX, XX },
1637 /* PREGRP15 */
1639 { "(bad)", XM, EX, XX, XX},
1640 { "cvtdq2pd", XM, EX, XX, XX },
1641 { "cvttpd2dq", XM, EX, XX, XX },
1642 { "cvtpd2dq", XM, EX, XX, XX },
1644 /* PREGRP16 */
1646 { "cvtdq2ps", XM, EX, XX, XX },
1647 { "cvttps2dq",XM, EX, XX, XX },
1648 { "cvtps2dq",XM, EX, XX, XX },
1649 { "(bad)", XM, EX, XX, XX },
1651 /* PREGRP17 */
1653 { "cvtps2pd", XM, EX, XX, XX },
1654 { "cvtss2sd", XM, EX, XX, XX },
1655 { "cvtpd2ps", XM, EX, XX, XX },
1656 { "cvtsd2ss", XM, EX, XX, XX },
1658 /* PREGRP18 */
1660 { "maskmovq", MX, MS, XX, XX },
1661 { "(bad)", XM, EX, XX, XX },
1662 { "maskmovdqu", XM, EX, XX, XX },
1663 { "(bad)", XM, EX, XX, XX },
1665 /* PREGRP19 */
1667 { "movq", MX, EM, XX, XX },
1668 { "movdqu", XM, EX, XX, XX },
1669 { "movdqa", XM, EX, XX, XX },
1670 { "(bad)", XM, EX, XX, XX },
1672 /* PREGRP20 */
1674 { "movq", EM, MX, XX, XX },
1675 { "movdqu", EX, XM, XX, XX },
1676 { "movdqa", EX, XM, XX, XX },
1677 { "(bad)", EX, XM, XX, XX },
1679 /* PREGRP21 */
1681 { "(bad)", EX, XM, XX, XX },
1682 { "movq2dq", XM, MS, XX, XX },
1683 { "movq", EX, XM, XX, XX },
1684 { "movdq2q", MX, XS, XX, XX },
1686 /* PREGRP22 */
1688 { "pshufw", MX, EM, Ib, XX },
1689 { "pshufhw", XM, EX, Ib, XX },
1690 { "pshufd", XM, EX, Ib, XX },
1691 { "pshuflw", XM, EX, Ib, XX},
1693 /* PREGRP23 */
1695 { "movd", Edq, MX, XX, XX },
1696 { "movq", XM, EX, XX, XX },
1697 { "movd", Edq, XM, XX, XX },
1698 { "(bad)", Ed, XM, XX, XX },
1700 /* PREGRP24 */
1702 { "(bad)", MX, EX, XX, XX },
1703 { "(bad)", XM, EX, XX, XX },
1704 { "punpckhqdq", XM, EX, XX, XX },
1705 { "(bad)", XM, EX, XX, XX },
1707 /* PREGRP25 */
1709 { "movntq", EM, MX, XX, XX },
1710 { "(bad)", EM, XM, XX, XX },
1711 { "movntdq", EM, XM, XX, XX },
1712 { "(bad)", EM, XM, XX, XX },
1714 /* PREGRP26 */
1716 { "(bad)", MX, EX, XX, XX },
1717 { "(bad)", XM, EX, XX, XX },
1718 { "punpcklqdq", XM, EX, XX, XX },
1719 { "(bad)", XM, EX, XX, XX },
1721 /* PREGRP27 */
1723 { "(bad)", MX, EX, XX, XX },
1724 { "(bad)", XM, EX, XX, XX },
1725 { "addsubpd", XM, EX, XX, XX },
1726 { "addsubps", XM, EX, XX, XX },
1728 /* PREGRP28 */
1730 { "(bad)", MX, EX, XX, XX },
1731 { "(bad)", XM, EX, XX, XX },
1732 { "haddpd", XM, EX, XX, XX },
1733 { "haddps", XM, EX, XX, XX },
1735 /* PREGRP29 */
1737 { "(bad)", MX, EX, XX, XX },
1738 { "(bad)", XM, EX, XX, XX },
1739 { "hsubpd", XM, EX, XX, XX },
1740 { "hsubps", XM, EX, XX, XX },
1742 /* PREGRP30 */
1744 { "movlpX", XM, EX, SIMD_Fixup, 'h', XX }, /* really only 2 operands */
1745 { "movsldup", XM, EX, XX, XX },
1746 { "movlpd", XM, EX, XX, XX },
1747 { "movddup", XM, EX, XX, XX },
1749 /* PREGRP31 */
1751 { "movhpX", XM, EX, SIMD_Fixup, 'l', XX },
1752 { "movshdup", XM, EX, XX, XX },
1753 { "movhpd", XM, EX, XX, XX },
1754 { "(bad)", XM, EX, XX, XX },
1756 /* PREGRP32 */
1758 { "(bad)", XM, EX, XX, XX },
1759 { "(bad)", XM, EX, XX, XX },
1760 { "(bad)", XM, EX, XX, XX },
1761 { "lddqu", XM, M, XX, XX },
1763 /* PREGRP33 */
1765 {"movntps",Ev, XM, XX, XX},
1766 {"movntss",Ev, XM, XX, XX},
1767 {"movntpd",Ev, XM, XX, XX},
1768 {"movntsd",Ev, XM, XX, XX},
1771 /* PREGRP34 */
1773 {"vmread", Em, Gm, XX, XX},
1774 {"(bad)", XX, XX, XX, XX},
1775 {"extrq", XS, Ib, Ib, XX},
1776 {"insertq",XM, XS, Ib, Ib},
1779 /* PREGRP35 */
1781 {"vmwrite", Gm, Em, XX, XX},
1782 {"(bad)", XX, XX, XX, XX},
1783 {"extrq", XM, XS, XX, XX},
1784 {"insertq", XM, XS, XX, XX},
1787 /* PREGRP36 */
1789 { "bsrS", Gv, Ev, XX, XX },
1790 { "lzcntS", Gv, Ev, XX, XX },
1791 { "bsrS", Gv, Ev, XX, XX },
1792 { "(bad)", XX, XX, XX, XX },
1797 static const struct dis386 x86_64_table[][2] = {
1799 { "arpl", Ew, Gw, XX, XX },
1800 { "movs{||lq|xd}", Gv, Ed, XX, XX },
1804 static const struct dis386 three_byte_table[][32] = {
1805 /* THREE_BYTE_0 */
1807 { "pshufb", MX, EM, XX, XX },
1808 { "phaddw", MX, EM, XX, XX },
1809 { "phaddd", MX, EM, XX, XX },
1810 { "phaddsw", MX, EM, XX, XX },
1811 { "pmaddubsw", MX, EM, XX, XX },
1812 { "phsubw", MX, EM, XX, XX },
1813 { "phsubd", MX, EM, XX, XX },
1814 { "phsubsw", MX, EM, XX, XX },
1815 { "psignb", MX, EM, XX, XX },
1816 { "psignw", MX, EM, XX, XX },
1817 { "psignd", MX, EM, XX, XX },
1818 { "pmulhrsw", MX, EM, XX, XX },
1819 { "(bad)", XX, XX, XX, XX },
1820 { "(bad)", XX, XX, XX, XX },
1821 { "(bad)", XX, XX, XX, XX },
1822 { "(bad)", XX, XX, XX, XX },
1823 { "(bad)", XX, XX, XX, XX },
1824 { "(bad)", XX, XX, XX, XX },
1825 { "(bad)", XX, XX, XX, XX },
1826 { "(bad)", XX, XX, XX, XX },
1827 { "(bad)", XX, XX, XX, XX },
1828 { "(bad)", XX, XX, XX, XX },
1829 { "(bad)", XX, XX, XX, XX },
1830 { "(bad)", XX, XX, XX, XX },
1831 { "(bad)", XX, XX, XX, XX },
1832 { "(bad)", XX, XX, XX, XX },
1833 { "(bad)", XX, XX, XX, XX },
1834 { "(bad)", XX, XX, XX, XX },
1835 { "pabsb", MX, EM, XX, XX },
1836 { "pabsw", MX, EM, XX, XX },
1837 { "pabsd", MX, EM, XX, XX },
1838 { "(bad)", XX, XX, XX, XX }
1840 /* THREE_BYTE_1 */
1842 { "(bad)", XX, XX, XX, XX },
1843 { "(bad)", XX, XX, XX, XX },
1844 { "(bad)", XX, XX, XX, XX },
1845 { "(bad)", XX, XX, XX, XX },
1846 { "(bad)", XX, XX, XX, XX },
1847 { "(bad)", XX, XX, XX, XX },
1848 { "(bad)", XX, XX, XX, XX },
1849 { "(bad)", XX, XX, XX, XX },
1850 { "(bad)", XX, XX, XX, XX },
1851 { "(bad)", XX, XX, XX, XX },
1852 { "(bad)", XX, XX, XX, XX },
1853 { "(bad)", XX, XX, XX, XX },
1854 { "(bad)", XX, XX, XX, XX },
1855 { "(bad)", XX, XX, XX, XX },
1856 { "(bad)", XX, XX, XX, XX },
1857 { "palignr", MX, EM, Ib, XX },
1858 { "(bad)", XX, XX, XX, XX },
1859 { "(bad)", XX, XX, XX, XX },
1860 { "(bad)", XX, XX, XX, XX },
1861 { "(bad)", XX, XX, XX, XX },
1862 { "(bad)", XX, XX, XX, XX },
1863 { "(bad)", XX, XX, XX, XX },
1864 { "(bad)", XX, XX, XX, XX },
1865 { "(bad)", XX, XX, XX, XX },
1866 { "(bad)", XX, XX, XX, XX },
1867 { "(bad)", XX, XX, XX, XX },
1868 { "(bad)", XX, XX, XX, XX },
1869 { "(bad)", XX, XX, XX, XX },
1870 { "(bad)", XX, XX, XX, XX },
1871 { "(bad)", XX, XX, XX, XX },
1872 { "(bad)", XX, XX, XX, XX },
1873 { "(bad)", XX, XX, XX, XX }
1877 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1879 static void
1880 ckprefix (void)
1882 int newrex;
1883 rex = 0;
1884 prefixes = 0;
1885 used_prefixes = 0;
1886 rex_used = 0;
1887 while (1)
1889 FETCH_DATA (the_info, codep + 1);
1890 newrex = 0;
1891 switch (*codep)
1893 /* REX prefixes family. */
1894 case 0x40:
1895 case 0x41:
1896 case 0x42:
1897 case 0x43:
1898 case 0x44:
1899 case 0x45:
1900 case 0x46:
1901 case 0x47:
1902 case 0x48:
1903 case 0x49:
1904 case 0x4a:
1905 case 0x4b:
1906 case 0x4c:
1907 case 0x4d:
1908 case 0x4e:
1909 case 0x4f:
1910 if (address_mode == mode_64bit)
1911 newrex = *codep;
1912 else
1913 return;
1914 break;
1915 case 0xf3:
1916 prefixes |= PREFIX_REPZ;
1917 break;
1918 case 0xf2:
1919 prefixes |= PREFIX_REPNZ;
1920 break;
1921 case 0xf0:
1922 prefixes |= PREFIX_LOCK;
1923 break;
1924 case 0x2e:
1925 prefixes |= PREFIX_CS;
1926 break;
1927 case 0x36:
1928 prefixes |= PREFIX_SS;
1929 break;
1930 case 0x3e:
1931 prefixes |= PREFIX_DS;
1932 break;
1933 case 0x26:
1934 prefixes |= PREFIX_ES;
1935 break;
1936 case 0x64:
1937 prefixes |= PREFIX_FS;
1938 break;
1939 case 0x65:
1940 prefixes |= PREFIX_GS;
1941 break;
1942 case 0x66:
1943 prefixes |= PREFIX_DATA;
1944 break;
1945 case 0x67:
1946 prefixes |= PREFIX_ADDR;
1947 break;
1948 case FWAIT_OPCODE:
1949 /* fwait is really an instruction. If there are prefixes
1950 before the fwait, they belong to the fwait, *not* to the
1951 following instruction. */
1952 if (prefixes || rex)
1954 prefixes |= PREFIX_FWAIT;
1955 codep++;
1956 return;
1958 prefixes = PREFIX_FWAIT;
1959 break;
1960 default:
1961 return;
1963 /* Rex is ignored when followed by another prefix. */
1964 if (rex)
1966 rex_used = rex;
1967 return;
1969 rex = newrex;
1970 codep++;
1974 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
1975 prefix byte. */
1977 static const char *
1978 prefix_name (int pref, int sizeflag)
1980 switch (pref)
1982 /* REX prefixes family. */
1983 case 0x40:
1984 return "rex";
1985 case 0x41:
1986 return "rexZ";
1987 case 0x42:
1988 return "rexY";
1989 case 0x43:
1990 return "rexYZ";
1991 case 0x44:
1992 return "rexX";
1993 case 0x45:
1994 return "rexXZ";
1995 case 0x46:
1996 return "rexXY";
1997 case 0x47:
1998 return "rexXYZ";
1999 case 0x48:
2000 return "rex64";
2001 case 0x49:
2002 return "rex64Z";
2003 case 0x4a:
2004 return "rex64Y";
2005 case 0x4b:
2006 return "rex64YZ";
2007 case 0x4c:
2008 return "rex64X";
2009 case 0x4d:
2010 return "rex64XZ";
2011 case 0x4e:
2012 return "rex64XY";
2013 case 0x4f:
2014 return "rex64XYZ";
2015 case 0xf3:
2016 return "repz";
2017 case 0xf2:
2018 return "repnz";
2019 case 0xf0:
2020 return "lock";
2021 case 0x2e:
2022 return "cs";
2023 case 0x36:
2024 return "ss";
2025 case 0x3e:
2026 return "ds";
2027 case 0x26:
2028 return "es";
2029 case 0x64:
2030 return "fs";
2031 case 0x65:
2032 return "gs";
2033 case 0x66:
2034 return (sizeflag & DFLAG) ? "data16" : "data32";
2035 case 0x67:
2036 if (address_mode == mode_64bit)
2037 return (sizeflag & AFLAG) ? "addr32" : "addr64";
2038 else
2039 return (sizeflag & AFLAG) ? "addr16" : "addr32";
2040 case FWAIT_OPCODE:
2041 return "fwait";
2042 default:
2043 return NULL;
2047 static char op1out[100], op2out[100], op3out[100], op4out[100];
2048 static int op_ad, op_index[4];
2049 static int two_source_ops;
2050 static bfd_vma op_address[4];
2051 static bfd_vma op_riprel[4];
2052 static bfd_vma start_pc;
2055 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
2056 * (see topic "Redundant prefixes" in the "Differences from 8086"
2057 * section of the "Virtual 8086 Mode" chapter.)
2058 * 'pc' should be the address of this instruction, it will
2059 * be used to print the target address if this is a relative jump or call
2060 * The function returns the length of this instruction in bytes.
2063 static char intel_syntax;
2064 static char open_char;
2065 static char close_char;
2066 static char separator_char;
2067 static char scale_char;
2069 /* Here for backwards compatibility. When gdb stops using
2070 print_insn_i386_att and print_insn_i386_intel these functions can
2071 disappear, and print_insn_i386 be merged into print_insn. */
2073 print_insn_i386_att (bfd_vma pc, disassemble_info *info)
2075 intel_syntax = 0;
2077 return print_insn (pc, info);
2081 print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
2083 intel_syntax = 1;
2085 return print_insn (pc, info);
2089 print_insn_i386 (bfd_vma pc, disassemble_info *info)
2091 intel_syntax = -1;
2093 return print_insn (pc, info);
2096 static int
2097 print_insn (bfd_vma pc, disassemble_info *info)
2099 const struct dis386 *dp;
2100 int i;
2101 char *first, *second, *third, *fourth;
2102 int needcomma;
2103 unsigned char uses_SSE_prefix, uses_LOCK_prefix;
2104 int sizeflag;
2105 const char *p;
2106 struct dis_private priv;
2108 if (info->mach == bfd_mach_x86_64_intel_syntax
2109 || info->mach == bfd_mach_x86_64)
2110 address_mode = mode_64bit;
2111 else
2112 address_mode = mode_32bit;
2114 if (intel_syntax == (char) -1)
2115 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
2116 || info->mach == bfd_mach_x86_64_intel_syntax);
2118 if (info->mach == bfd_mach_i386_i386
2119 || info->mach == bfd_mach_x86_64
2120 || info->mach == bfd_mach_i386_i386_intel_syntax
2121 || info->mach == bfd_mach_x86_64_intel_syntax)
2122 priv.orig_sizeflag = AFLAG | DFLAG;
2123 else if (info->mach == bfd_mach_i386_i8086)
2124 priv.orig_sizeflag = 0;
2125 else
2126 abort ();
2128 for (p = info->disassembler_options; p != NULL; )
2130 if (strncmp (p, "x86-64", 6) == 0)
2132 address_mode = mode_64bit;
2133 priv.orig_sizeflag = AFLAG | DFLAG;
2135 else if (strncmp (p, "i386", 4) == 0)
2137 address_mode = mode_32bit;
2138 priv.orig_sizeflag = AFLAG | DFLAG;
2140 else if (strncmp (p, "i8086", 5) == 0)
2142 address_mode = mode_16bit;
2143 priv.orig_sizeflag = 0;
2145 else if (strncmp (p, "intel", 5) == 0)
2147 intel_syntax = 1;
2149 else if (strncmp (p, "att", 3) == 0)
2151 intel_syntax = 0;
2153 else if (strncmp (p, "addr", 4) == 0)
2155 if (p[4] == '1' && p[5] == '6')
2156 priv.orig_sizeflag &= ~AFLAG;
2157 else if (p[4] == '3' && p[5] == '2')
2158 priv.orig_sizeflag |= AFLAG;
2160 else if (strncmp (p, "data", 4) == 0)
2162 if (p[4] == '1' && p[5] == '6')
2163 priv.orig_sizeflag &= ~DFLAG;
2164 else if (p[4] == '3' && p[5] == '2')
2165 priv.orig_sizeflag |= DFLAG;
2167 else if (strncmp (p, "suffix", 6) == 0)
2168 priv.orig_sizeflag |= SUFFIX_ALWAYS;
2170 p = strchr (p, ',');
2171 if (p != NULL)
2172 p++;
2175 if (intel_syntax)
2177 names64 = intel_names64;
2178 names32 = intel_names32;
2179 names16 = intel_names16;
2180 names8 = intel_names8;
2181 names8rex = intel_names8rex;
2182 names_seg = intel_names_seg;
2183 index16 = intel_index16;
2184 open_char = '[';
2185 close_char = ']';
2186 separator_char = '+';
2187 scale_char = '*';
2189 else
2191 names64 = att_names64;
2192 names32 = att_names32;
2193 names16 = att_names16;
2194 names8 = att_names8;
2195 names8rex = att_names8rex;
2196 names_seg = att_names_seg;
2197 index16 = att_index16;
2198 open_char = '(';
2199 close_char = ')';
2200 separator_char = ',';
2201 scale_char = ',';
2204 /* The output looks better if we put 7 bytes on a line, since that
2205 puts most long word instructions on a single line. */
2206 info->bytes_per_line = 7;
2208 info->private_data = &priv;
2209 priv.max_fetched = priv.the_buffer;
2210 priv.insn_start = pc;
2212 obuf[0] = 0;
2213 op1out[0] = 0;
2214 op2out[0] = 0;
2215 op3out[0] = 0;
2216 op4out[0] = 0;
2218 op_index[0] = op_index[1] = op_index[2] = op_index[3] = -1;
2220 the_info = info;
2221 start_pc = pc;
2222 start_codep = priv.the_buffer;
2223 codep = priv.the_buffer;
2225 if (setjmp (priv.bailout) != 0)
2227 const char *name;
2229 /* Getting here means we tried for data but didn't get it. That
2230 means we have an incomplete instruction of some sort. Just
2231 print the first byte as a prefix or a .byte pseudo-op. */
2232 if (codep > priv.the_buffer)
2234 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2235 if (name != NULL)
2236 (*info->fprintf_func) (info->stream, "%s", name);
2237 else
2239 /* Just print the first byte as a .byte instruction. */
2240 (*info->fprintf_func) (info->stream, ".byte 0x%x",
2241 (unsigned int) priv.the_buffer[0]);
2244 return 1;
2247 return -1;
2250 obufp = obuf;
2251 ckprefix ();
2253 insn_codep = codep;
2254 sizeflag = priv.orig_sizeflag;
2256 FETCH_DATA (info, codep + 1);
2257 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
2259 if (((prefixes & PREFIX_FWAIT)
2260 && ((*codep < 0xd8) || (*codep > 0xdf)))
2261 || (rex && rex_used))
2263 const char *name;
2265 /* fwait not followed by floating point instruction, or rex followed
2266 by other prefixes. Print the first prefix. */
2267 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2268 if (name == NULL)
2269 name = INTERNAL_DISASSEMBLER_ERROR;
2270 (*info->fprintf_func) (info->stream, "%s", name);
2271 return 1;
2274 if (*codep == 0x0f)
2276 FETCH_DATA (info, codep + 2);
2277 dp = &dis386_twobyte[*++codep];
2278 need_modrm = twobyte_has_modrm[*codep];
2279 uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
2280 uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
2282 else
2284 dp = &dis386[*codep];
2285 need_modrm = onebyte_has_modrm[*codep];
2286 uses_SSE_prefix = 0;
2287 uses_LOCK_prefix = 0;
2290 /*"lzcnt"=0xBD is the only non-sse instruction which uses F3 in the opcode without any "rep(z|nz)"*/
2291 if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ) && *codep !=0xBD)
2293 oappend ("repz ");
2294 used_prefixes |= PREFIX_REPZ;
2296 if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ) && *codep !=0xBD)
2298 oappend ("repnz ");
2299 used_prefixes |= PREFIX_REPNZ;
2302 codep++;
2304 if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
2306 oappend ("lock ");
2307 used_prefixes |= PREFIX_LOCK;
2310 if (prefixes & PREFIX_ADDR)
2312 sizeflag ^= AFLAG;
2313 if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
2315 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
2316 oappend ("addr32 ");
2317 else
2318 oappend ("addr16 ");
2319 used_prefixes |= PREFIX_ADDR;
2323 if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
2325 sizeflag ^= DFLAG;
2326 if (dp->bytemode3 == cond_jump_mode
2327 && dp->bytemode1 == v_mode
2328 && !intel_syntax)
2330 if (sizeflag & DFLAG)
2331 oappend ("data32 ");
2332 else
2333 oappend ("data16 ");
2334 used_prefixes |= PREFIX_DATA;
2338 if (dp->name == NULL && dp->bytemode1 == IS_3BYTE_OPCODE)
2340 FETCH_DATA (info, codep + 2);
2341 dp = &three_byte_table[dp->bytemode2][*codep++];
2342 mod = (*codep >> 6) & 3;
2343 reg = (*codep >> 3) & 7;
2344 rm = *codep & 7;
2346 else if (need_modrm)
2348 FETCH_DATA (info, codep + 1);
2349 mod = (*codep >> 6) & 3;
2350 reg = (*codep >> 3) & 7;
2351 rm = *codep & 7;
2354 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2356 dofloat (sizeflag);
2358 else
2360 int index;
2361 if (dp->name == NULL)
2363 switch (dp->bytemode1)
2365 case USE_GROUPS:
2366 dp = &grps[dp->bytemode2][reg];
2367 break;
2369 case USE_PREFIX_USER_TABLE:
2370 index = 0;
2371 used_prefixes |= (prefixes & PREFIX_REPZ);
2372 if (prefixes & PREFIX_REPZ)
2373 index = 1;
2374 else
2376 used_prefixes |= (prefixes & PREFIX_DATA);
2377 if (prefixes & PREFIX_DATA)
2378 index = 2;
2379 else
2381 used_prefixes |= (prefixes & PREFIX_REPNZ);
2382 if (prefixes & PREFIX_REPNZ)
2383 index = 3;
2386 dp = &prefix_user_table[dp->bytemode2][index];
2387 break;
2389 case X86_64_SPECIAL:
2390 index = address_mode == mode_64bit ? 1 : 0;
2391 dp = &x86_64_table[dp->bytemode2][index];
2392 break;
2394 default:
2395 oappend (INTERNAL_DISASSEMBLER_ERROR);
2396 break;
2400 if (putop (dp->name, sizeflag) == 0)
2402 obufp = op1out;
2403 op_ad = 3;
2404 if (dp->op1)
2405 (*dp->op1) (dp->bytemode1, sizeflag);
2407 obufp = op2out;
2408 op_ad = 2;
2409 if (dp->op2)
2410 (*dp->op2) (dp->bytemode2, sizeflag);
2412 obufp = op3out;
2413 op_ad = 1;
2414 if (dp->op3)
2415 (*dp->op3) (dp->bytemode3, sizeflag);
2417 obufp = op4out;
2418 op_ad = 0;
2419 if (dp->op4)
2420 (*dp->op4) (dp->bytemode4, sizeflag);
2424 /* See if any prefixes were not used. If so, print the first one
2425 separately. If we don't do this, we'll wind up printing an
2426 instruction stream which does not precisely correspond to the
2427 bytes we are disassembling. */
2428 if ((prefixes & ~used_prefixes) != 0)
2430 const char *name;
2432 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2433 if (name == NULL)
2434 name = INTERNAL_DISASSEMBLER_ERROR;
2435 (*info->fprintf_func) (info->stream, "%s", name);
2436 return 1;
2438 if (rex & ~rex_used)
2440 const char *name;
2441 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
2442 if (name == NULL)
2443 name = INTERNAL_DISASSEMBLER_ERROR;
2444 (*info->fprintf_func) (info->stream, "%s ", name);
2447 obufp = obuf + strlen (obuf);
2448 for (i = strlen (obuf); i < 6; i++)
2449 oappend (" ");
2450 oappend (" ");
2451 (*info->fprintf_func) (info->stream, "%s", obuf);
2453 /* The enter and bound instructions are printed with operands in the same
2454 order as the intel book; everything else is printed in reverse order. */
2455 if (intel_syntax || two_source_ops)
2457 first = op1out;
2458 second = op2out;
2459 third = op3out;
2460 fourth = op4out;
2461 op_ad = op_index[0];
2462 op_index[0] = op_index[3];
2463 op_index[3] = op_ad;
2464 op_ad = op_index[1];
2465 op_index[1] = op_index[2];
2466 op_index[2] = op_ad;
2469 else
2471 first = op4out;
2472 second = op3out;
2473 third = op2out;
2474 fourth = op1out;
2476 needcomma = 0;
2477 if (*first)
2479 if (op_index[0] != -1 && !op_riprel[0])
2480 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
2481 else
2482 (*info->fprintf_func) (info->stream, "%s", first);
2483 needcomma = 1;
2486 if (*second)
2488 if (needcomma)
2489 (*info->fprintf_func) (info->stream, ",");
2490 if (op_index[1] != -1 && !op_riprel[1])
2491 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
2492 else
2493 (*info->fprintf_func) (info->stream, "%s", second);
2494 needcomma = 1;
2497 if (*third)
2499 if (needcomma)
2500 (*info->fprintf_func) (info->stream, ",");
2501 if (op_index[2] != -1 && !op_riprel[2])
2502 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
2503 else
2504 (*info->fprintf_func) (info->stream, "%s", third);
2505 needcomma = 1;
2508 if (*fourth)
2510 if (needcomma)
2511 (*info->fprintf_func) (info->stream, ",");
2512 if (op_index[3] != -1 && !op_riprel[3])
2513 (*info->print_address_func) ((bfd_vma) op_address[op_index[3]], info);
2514 else
2515 (*info->fprintf_func) (info->stream, "%s", fourth);
2518 for (i = 0; i < 4; i++)
2519 if (op_index[i] != -1 && op_riprel[i])
2521 (*info->fprintf_func) (info->stream, " # ");
2522 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
2523 + op_address[op_index[i]]), info);
2525 return codep - priv.the_buffer;
2528 static const char *float_mem[] = {
2529 /* d8 */
2530 "fadd{s||s|}",
2531 "fmul{s||s|}",
2532 "fcom{s||s|}",
2533 "fcomp{s||s|}",
2534 "fsub{s||s|}",
2535 "fsubr{s||s|}",
2536 "fdiv{s||s|}",
2537 "fdivr{s||s|}",
2538 /* d9 */
2539 "fld{s||s|}",
2540 "(bad)",
2541 "fst{s||s|}",
2542 "fstp{s||s|}",
2543 "fldenvIC",
2544 "fldcw",
2545 "fNstenvIC",
2546 "fNstcw",
2547 /* da */
2548 "fiadd{l||l|}",
2549 "fimul{l||l|}",
2550 "ficom{l||l|}",
2551 "ficomp{l||l|}",
2552 "fisub{l||l|}",
2553 "fisubr{l||l|}",
2554 "fidiv{l||l|}",
2555 "fidivr{l||l|}",
2556 /* db */
2557 "fild{l||l|}",
2558 "fisttp{l||l|}",
2559 "fist{l||l|}",
2560 "fistp{l||l|}",
2561 "(bad)",
2562 "fld{t||t|}",
2563 "(bad)",
2564 "fstp{t||t|}",
2565 /* dc */
2566 "fadd{l||l|}",
2567 "fmul{l||l|}",
2568 "fcom{l||l|}",
2569 "fcomp{l||l|}",
2570 "fsub{l||l|}",
2571 "fsubr{l||l|}",
2572 "fdiv{l||l|}",
2573 "fdivr{l||l|}",
2574 /* dd */
2575 "fld{l||l|}",
2576 "fisttp{ll||ll|}",
2577 "fst{l||l|}",
2578 "fstp{l||l|}",
2579 "frstorIC",
2580 "(bad)",
2581 "fNsaveIC",
2582 "fNstsw",
2583 /* de */
2584 "fiadd",
2585 "fimul",
2586 "ficom",
2587 "ficomp",
2588 "fisub",
2589 "fisubr",
2590 "fidiv",
2591 "fidivr",
2592 /* df */
2593 "fild",
2594 "fisttp",
2595 "fist",
2596 "fistp",
2597 "fbld",
2598 "fild{ll||ll|}",
2599 "fbstp",
2600 "fistp{ll||ll|}",
2603 static const unsigned char float_mem_mode[] = {
2604 /* d8 */
2605 d_mode,
2606 d_mode,
2607 d_mode,
2608 d_mode,
2609 d_mode,
2610 d_mode,
2611 d_mode,
2612 d_mode,
2613 /* d9 */
2614 d_mode,
2616 d_mode,
2617 d_mode,
2619 w_mode,
2621 w_mode,
2622 /* da */
2623 d_mode,
2624 d_mode,
2625 d_mode,
2626 d_mode,
2627 d_mode,
2628 d_mode,
2629 d_mode,
2630 d_mode,
2631 /* db */
2632 d_mode,
2633 d_mode,
2634 d_mode,
2635 d_mode,
2637 t_mode,
2639 t_mode,
2640 /* dc */
2641 q_mode,
2642 q_mode,
2643 q_mode,
2644 q_mode,
2645 q_mode,
2646 q_mode,
2647 q_mode,
2648 q_mode,
2649 /* dd */
2650 q_mode,
2651 q_mode,
2652 q_mode,
2653 q_mode,
2657 w_mode,
2658 /* de */
2659 w_mode,
2660 w_mode,
2661 w_mode,
2662 w_mode,
2663 w_mode,
2664 w_mode,
2665 w_mode,
2666 w_mode,
2667 /* df */
2668 w_mode,
2669 w_mode,
2670 w_mode,
2671 w_mode,
2672 t_mode,
2673 q_mode,
2674 t_mode,
2675 q_mode
2678 #define ST OP_ST, 0
2679 #define STi OP_STi, 0
2681 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0, NULL, 0
2682 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0, NULL, 0
2683 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0, NULL, 0
2684 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0, NULL, 0
2685 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0, NULL, 0
2686 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0, NULL, 0
2687 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0, NULL, 0
2688 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0, NULL, 0
2689 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0, NULL, 0
2691 static const struct dis386 float_reg[][8] = {
2692 /* d8 */
2694 { "fadd", ST, STi, XX, XX },
2695 { "fmul", ST, STi, XX, XX },
2696 { "fcom", STi, XX, XX, XX },
2697 { "fcomp", STi, XX, XX, XX },
2698 { "fsub", ST, STi, XX, XX },
2699 { "fsubr", ST, STi, XX, XX },
2700 { "fdiv", ST, STi, XX, XX },
2701 { "fdivr", ST, STi, XX, XX },
2703 /* d9 */
2705 { "fld", STi, XX, XX, XX },
2706 { "fxch", STi, XX, XX, XX },
2707 { FGRPd9_2 },
2708 { "(bad)", XX, XX, XX, XX },
2709 { FGRPd9_4 },
2710 { FGRPd9_5 },
2711 { FGRPd9_6 },
2712 { FGRPd9_7 },
2714 /* da */
2716 { "fcmovb", ST, STi, XX, XX },
2717 { "fcmove", ST, STi, XX, XX },
2718 { "fcmovbe",ST, STi, XX, XX },
2719 { "fcmovu", ST, STi, XX, XX },
2720 { "(bad)", XX, XX, XX, XX },
2721 { FGRPda_5 },
2722 { "(bad)", XX, XX, XX, XX },
2723 { "(bad)", XX, XX, XX, XX },
2725 /* db */
2727 { "fcmovnb",ST, STi, XX, XX },
2728 { "fcmovne",ST, STi, XX, XX },
2729 { "fcmovnbe",ST, STi, XX, XX },
2730 { "fcmovnu",ST, STi, XX, XX },
2731 { FGRPdb_4 },
2732 { "fucomi", ST, STi, XX, XX },
2733 { "fcomi", ST, STi, XX, XX },
2734 { "(bad)", XX, XX, XX, XX },
2736 /* dc */
2738 { "fadd", STi, ST, XX, XX },
2739 { "fmul", STi, ST, XX, XX },
2740 { "(bad)", XX, XX, XX, XX },
2741 { "(bad)", XX, XX, XX, XX },
2742 #if UNIXWARE_COMPAT
2743 { "fsub", STi, ST, XX, XX },
2744 { "fsubr", STi, ST, XX, XX },
2745 { "fdiv", STi, ST, XX, XX },
2746 { "fdivr", STi, ST, XX, XX },
2747 #else
2748 { "fsubr", STi, ST, XX, XX },
2749 { "fsub", STi, ST, XX, XX },
2750 { "fdivr", STi, ST, XX, XX },
2751 { "fdiv", STi, ST, XX, XX },
2752 #endif
2754 /* dd */
2756 { "ffree", STi, XX, XX, XX },
2757 { "(bad)", XX, XX, XX, XX },
2758 { "fst", STi, XX, XX, XX },
2759 { "fstp", STi, XX, XX, XX },
2760 { "fucom", STi, XX, XX, XX },
2761 { "fucomp", STi, XX, XX, XX },
2762 { "(bad)", XX, XX, XX, XX },
2763 { "(bad)", XX, XX, XX, XX },
2765 /* de */
2767 { "faddp", STi, ST, XX, XX },
2768 { "fmulp", STi, ST, XX, XX },
2769 { "(bad)", XX, XX, XX, XX },
2770 { FGRPde_3 },
2771 #if UNIXWARE_COMPAT
2772 { "fsubp", STi, ST, XX, XX },
2773 { "fsubrp", STi, ST, XX, XX },
2774 { "fdivp", STi, ST, XX, XX },
2775 { "fdivrp", STi, ST, XX, XX },
2776 #else
2777 { "fsubrp", STi, ST, XX, XX },
2778 { "fsubp", STi, ST, XX, XX },
2779 { "fdivrp", STi, ST, XX, XX },
2780 { "fdivp", STi, ST, XX, XX },
2781 #endif
2783 /* df */
2785 { "ffreep", STi, XX, XX, XX },
2786 { "(bad)", XX, XX, XX, XX },
2787 { "(bad)", XX, XX, XX, XX },
2788 { "(bad)", XX, XX, XX, XX },
2789 { FGRPdf_4 },
2790 { "fucomip",ST, STi, XX, XX },
2791 { "fcomip", ST, STi, XX, XX },
2792 { "(bad)", XX, XX, XX, XX },
2796 static char *fgrps[][8] = {
2797 /* d9_2 0 */
2799 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2802 /* d9_4 1 */
2804 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2807 /* d9_5 2 */
2809 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2812 /* d9_6 3 */
2814 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2817 /* d9_7 4 */
2819 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2822 /* da_5 5 */
2824 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2827 /* db_4 6 */
2829 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2830 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2833 /* de_3 7 */
2835 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2838 /* df_4 8 */
2840 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2844 static void
2845 dofloat (int sizeflag)
2847 const struct dis386 *dp;
2848 unsigned char floatop;
2850 floatop = codep[-1];
2852 if (mod != 3)
2854 int fp_indx = (floatop - 0xd8) * 8 + reg;
2856 putop (float_mem[fp_indx], sizeflag);
2857 obufp = op1out;
2858 op_ad = 2;
2859 OP_E (float_mem_mode[fp_indx], sizeflag);
2860 return;
2862 /* Skip mod/rm byte. */
2863 MODRM_CHECK;
2864 codep++;
2866 dp = &float_reg[floatop - 0xd8][reg];
2867 if (dp->name == NULL)
2869 putop (fgrps[dp->bytemode1][rm], sizeflag);
2871 /* Instruction fnstsw is only one with strange arg. */
2872 if (floatop == 0xdf && codep[-1] == 0xe0)
2873 strcpy (op1out, names16[0]);
2875 else
2877 putop (dp->name, sizeflag);
2879 obufp = op1out;
2880 op_ad = 2;
2881 if (dp->op1)
2882 (*dp->op1) (dp->bytemode1, sizeflag);
2884 obufp = op2out;
2885 op_ad = 1;
2886 if (dp->op2)
2887 (*dp->op2) (dp->bytemode2, sizeflag);
2891 static void
2892 OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
2894 oappend ("%st" + intel_syntax);
2897 static void
2898 OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
2900 sprintf (scratchbuf, "%%st(%d)", rm);
2901 oappend (scratchbuf + intel_syntax);
2904 /* Capital letters in template are macros. */
2905 static int
2906 putop (const char *template, int sizeflag)
2908 const char *p;
2909 int alt = 0;
2911 for (p = template; *p; p++)
2913 switch (*p)
2915 default:
2916 *obufp++ = *p;
2917 break;
2918 case '{':
2919 alt = 0;
2920 if (intel_syntax)
2921 alt += 1;
2922 if (address_mode == mode_64bit)
2923 alt += 2;
2924 while (alt != 0)
2926 while (*++p != '|')
2928 if (*p == '}')
2930 /* Alternative not valid. */
2931 strcpy (obuf, "(bad)");
2932 obufp = obuf + 5;
2933 return 1;
2935 else if (*p == '\0')
2936 abort ();
2938 alt--;
2940 /* Fall through. */
2941 case 'I':
2942 alt = 1;
2943 continue;
2944 case '|':
2945 while (*++p != '}')
2947 if (*p == '\0')
2948 abort ();
2950 break;
2951 case '}':
2952 break;
2953 case 'A':
2954 if (intel_syntax)
2955 break;
2956 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2957 *obufp++ = 'b';
2958 break;
2959 case 'B':
2960 if (intel_syntax)
2961 break;
2962 if (sizeflag & SUFFIX_ALWAYS)
2963 *obufp++ = 'b';
2964 break;
2965 case 'C':
2966 if (intel_syntax && !alt)
2967 break;
2968 if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
2970 if (sizeflag & DFLAG)
2971 *obufp++ = intel_syntax ? 'd' : 'l';
2972 else
2973 *obufp++ = intel_syntax ? 'w' : 's';
2974 used_prefixes |= (prefixes & PREFIX_DATA);
2976 break;
2977 case 'E': /* For jcxz/jecxz */
2978 if (address_mode == mode_64bit)
2980 if (sizeflag & AFLAG)
2981 *obufp++ = 'r';
2982 else
2983 *obufp++ = 'e';
2985 else
2986 if (sizeflag & AFLAG)
2987 *obufp++ = 'e';
2988 used_prefixes |= (prefixes & PREFIX_ADDR);
2989 break;
2990 case 'F':
2991 if (intel_syntax)
2992 break;
2993 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
2995 if (sizeflag & AFLAG)
2996 *obufp++ = address_mode == mode_64bit ? 'q' : 'l';
2997 else
2998 *obufp++ = address_mode == mode_64bit ? 'l' : 'w';
2999 used_prefixes |= (prefixes & PREFIX_ADDR);
3001 break;
3002 case 'H':
3003 if (intel_syntax)
3004 break;
3005 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
3006 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
3008 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
3009 *obufp++ = ',';
3010 *obufp++ = 'p';
3011 if (prefixes & PREFIX_DS)
3012 *obufp++ = 't';
3013 else
3014 *obufp++ = 'n';
3016 break;
3017 case 'J':
3018 if (intel_syntax)
3019 break;
3020 *obufp++ = 'l';
3021 break;
3022 case 'Z':
3023 if (intel_syntax)
3024 break;
3025 if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS))
3027 *obufp++ = 'q';
3028 break;
3030 /* Fall through. */
3031 case 'L':
3032 if (intel_syntax)
3033 break;
3034 if (sizeflag & SUFFIX_ALWAYS)
3035 *obufp++ = 'l';
3036 break;
3037 case 'N':
3038 if ((prefixes & PREFIX_FWAIT) == 0)
3039 *obufp++ = 'n';
3040 else
3041 used_prefixes |= PREFIX_FWAIT;
3042 break;
3043 case 'O':
3044 USED_REX (REX_MODE64);
3045 if (rex & REX_MODE64)
3046 *obufp++ = 'o';
3047 else
3048 *obufp++ = 'd';
3049 break;
3050 case 'T':
3051 if (intel_syntax)
3052 break;
3053 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3055 *obufp++ = 'q';
3056 break;
3058 /* Fall through. */
3059 case 'P':
3060 if (intel_syntax)
3061 break;
3062 if ((prefixes & PREFIX_DATA)
3063 || (rex & REX_MODE64)
3064 || (sizeflag & SUFFIX_ALWAYS))
3066 USED_REX (REX_MODE64);
3067 if (rex & REX_MODE64)
3068 *obufp++ = 'q';
3069 else
3071 if (sizeflag & DFLAG)
3072 *obufp++ = 'l';
3073 else
3074 *obufp++ = 'w';
3076 used_prefixes |= (prefixes & PREFIX_DATA);
3078 break;
3079 case 'U':
3080 if (intel_syntax)
3081 break;
3082 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3084 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
3085 *obufp++ = 'q';
3086 break;
3088 /* Fall through. */
3089 case 'Q':
3090 if (intel_syntax && !alt)
3091 break;
3092 USED_REX (REX_MODE64);
3093 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
3095 if (rex & REX_MODE64)
3096 *obufp++ = 'q';
3097 else
3099 if (sizeflag & DFLAG)
3100 *obufp++ = intel_syntax ? 'd' : 'l';
3101 else
3102 *obufp++ = 'w';
3104 used_prefixes |= (prefixes & PREFIX_DATA);
3106 break;
3107 case 'R':
3108 USED_REX (REX_MODE64);
3109 if (intel_syntax)
3111 if (rex & REX_MODE64)
3113 *obufp++ = 'q';
3114 *obufp++ = 't';
3116 else if (sizeflag & DFLAG)
3118 *obufp++ = 'd';
3119 *obufp++ = 'q';
3121 else
3123 *obufp++ = 'w';
3124 *obufp++ = 'd';
3127 else
3129 if (rex & REX_MODE64)
3130 *obufp++ = 'q';
3131 else if (sizeflag & DFLAG)
3132 *obufp++ = 'l';
3133 else
3134 *obufp++ = 'w';
3136 if (!(rex & REX_MODE64))
3137 used_prefixes |= (prefixes & PREFIX_DATA);
3138 break;
3139 case 'V':
3140 if (intel_syntax)
3141 break;
3142 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3144 if (sizeflag & SUFFIX_ALWAYS)
3145 *obufp++ = 'q';
3146 break;
3148 /* Fall through. */
3149 case 'S':
3150 if (intel_syntax)
3151 break;
3152 if (sizeflag & SUFFIX_ALWAYS)
3154 if (rex & REX_MODE64)
3155 *obufp++ = 'q';
3156 else
3158 if (sizeflag & DFLAG)
3159 *obufp++ = 'l';
3160 else
3161 *obufp++ = 'w';
3162 used_prefixes |= (prefixes & PREFIX_DATA);
3165 break;
3166 case 'X':
3167 if (prefixes & PREFIX_DATA)
3168 *obufp++ = 'd';
3169 else
3170 *obufp++ = 's';
3171 used_prefixes |= (prefixes & PREFIX_DATA);
3172 break;
3173 case 'Y':
3174 if (intel_syntax)
3175 break;
3176 if (rex & REX_MODE64)
3178 USED_REX (REX_MODE64);
3179 *obufp++ = 'q';
3181 break;
3182 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
3183 case 'W':
3184 /* operand size flag for cwtl, cbtw */
3185 USED_REX (0);
3186 if (rex)
3187 *obufp++ = 'l';
3188 else if (sizeflag & DFLAG)
3189 *obufp++ = 'w';
3190 else
3191 *obufp++ = 'b';
3192 if (intel_syntax)
3194 if (rex)
3196 *obufp++ = 'q';
3197 *obufp++ = 'e';
3199 if (sizeflag & DFLAG)
3201 *obufp++ = 'd';
3202 *obufp++ = 'e';
3204 else
3206 *obufp++ = 'w';
3209 if (!rex)
3210 used_prefixes |= (prefixes & PREFIX_DATA);
3211 break;
3213 alt = 0;
3215 *obufp = 0;
3216 return 0;
3219 static void
3220 oappend (const char *s)
3222 strcpy (obufp, s);
3223 obufp += strlen (s);
3226 static void
3227 append_seg (void)
3229 if (prefixes & PREFIX_CS)
3231 used_prefixes |= PREFIX_CS;
3232 oappend ("%cs:" + intel_syntax);
3234 if (prefixes & PREFIX_DS)
3236 used_prefixes |= PREFIX_DS;
3237 oappend ("%ds:" + intel_syntax);
3239 if (prefixes & PREFIX_SS)
3241 used_prefixes |= PREFIX_SS;
3242 oappend ("%ss:" + intel_syntax);
3244 if (prefixes & PREFIX_ES)
3246 used_prefixes |= PREFIX_ES;
3247 oappend ("%es:" + intel_syntax);
3249 if (prefixes & PREFIX_FS)
3251 used_prefixes |= PREFIX_FS;
3252 oappend ("%fs:" + intel_syntax);
3254 if (prefixes & PREFIX_GS)
3256 used_prefixes |= PREFIX_GS;
3257 oappend ("%gs:" + intel_syntax);
3261 static void
3262 OP_indirE (int bytemode, int sizeflag)
3264 if (!intel_syntax)
3265 oappend ("*");
3266 OP_E (bytemode, sizeflag);
3269 static void
3270 print_operand_value (char *buf, int hex, bfd_vma disp)
3272 if (address_mode == mode_64bit)
3274 if (hex)
3276 char tmp[30];
3277 int i;
3278 buf[0] = '0';
3279 buf[1] = 'x';
3280 sprintf_vma (tmp, disp);
3281 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
3282 strcpy (buf + 2, tmp + i);
3284 else
3286 bfd_signed_vma v = disp;
3287 char tmp[30];
3288 int i;
3289 if (v < 0)
3291 *(buf++) = '-';
3292 v = -disp;
3293 /* Check for possible overflow on 0x8000000000000000. */
3294 if (v < 0)
3296 strcpy (buf, "9223372036854775808");
3297 return;
3300 if (!v)
3302 strcpy (buf, "0");
3303 return;
3306 i = 0;
3307 tmp[29] = 0;
3308 while (v)
3310 tmp[28 - i] = (v % 10) + '0';
3311 v /= 10;
3312 i++;
3314 strcpy (buf, tmp + 29 - i);
3317 else
3319 if (hex)
3320 sprintf (buf, "0x%x", (unsigned int) disp);
3321 else
3322 sprintf (buf, "%d", (int) disp);
3326 static void
3327 intel_operand_size (int bytemode, int sizeflag)
3329 switch (bytemode)
3331 case b_mode:
3332 oappend ("BYTE PTR ");
3333 break;
3334 case w_mode:
3335 case dqw_mode:
3336 oappend ("WORD PTR ");
3337 break;
3338 case stack_v_mode:
3339 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3341 oappend ("QWORD PTR ");
3342 used_prefixes |= (prefixes & PREFIX_DATA);
3343 break;
3345 /* FALLTHRU */
3346 case v_mode:
3347 case dq_mode:
3348 USED_REX (REX_MODE64);
3349 if (rex & REX_MODE64)
3350 oappend ("QWORD PTR ");
3351 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
3352 oappend ("DWORD PTR ");
3353 else
3354 oappend ("WORD PTR ");
3355 used_prefixes |= (prefixes & PREFIX_DATA);
3356 break;
3357 case d_mode:
3358 oappend ("DWORD PTR ");
3359 break;
3360 case q_mode:
3361 oappend ("QWORD PTR ");
3362 break;
3363 case m_mode:
3364 if (address_mode == mode_64bit)
3365 oappend ("QWORD PTR ");
3366 else
3367 oappend ("DWORD PTR ");
3368 break;
3369 case f_mode:
3370 if (sizeflag & DFLAG)
3371 oappend ("FWORD PTR ");
3372 else
3373 oappend ("DWORD PTR ");
3374 used_prefixes |= (prefixes & PREFIX_DATA);
3375 break;
3376 case t_mode:
3377 oappend ("TBYTE PTR ");
3378 break;
3379 case x_mode:
3380 oappend ("XMMWORD PTR ");
3381 break;
3382 default:
3383 break;
3387 static void
3388 OP_E (int bytemode, int sizeflag)
3390 bfd_vma disp;
3391 int add = 0;
3392 int riprel = 0;
3393 USED_REX (REX_EXTZ);
3394 if (rex & REX_EXTZ)
3395 add += 8;
3397 /* Skip mod/rm byte. */
3398 MODRM_CHECK;
3399 codep++;
3401 if (mod == 3)
3403 switch (bytemode)
3405 case b_mode:
3406 USED_REX (0);
3407 if (rex)
3408 oappend (names8rex[rm + add]);
3409 else
3410 oappend (names8[rm + add]);
3411 break;
3412 case w_mode:
3413 oappend (names16[rm + add]);
3414 break;
3415 case d_mode:
3416 oappend (names32[rm + add]);
3417 break;
3418 case q_mode:
3419 oappend (names64[rm + add]);
3420 break;
3421 case m_mode:
3422 if (address_mode == mode_64bit)
3423 oappend (names64[rm + add]);
3424 else
3425 oappend (names32[rm + add]);
3426 break;
3427 case stack_v_mode:
3428 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3430 oappend (names64[rm + add]);
3431 used_prefixes |= (prefixes & PREFIX_DATA);
3432 break;
3434 bytemode = v_mode;
3435 /* FALLTHRU */
3436 case v_mode:
3437 case dq_mode:
3438 case dqw_mode:
3439 USED_REX (REX_MODE64);
3440 if (rex & REX_MODE64)
3441 oappend (names64[rm + add]);
3442 else if ((sizeflag & DFLAG) || bytemode != v_mode)
3443 oappend (names32[rm + add]);
3444 else
3445 oappend (names16[rm + add]);
3446 used_prefixes |= (prefixes & PREFIX_DATA);
3447 break;
3448 case 0:
3449 break;
3450 default:
3451 oappend (INTERNAL_DISASSEMBLER_ERROR);
3452 break;
3454 return;
3457 disp = 0;
3458 if (intel_syntax)
3459 intel_operand_size (bytemode, sizeflag);
3460 append_seg ();
3462 if ((sizeflag & AFLAG) || address_mode == mode_64bit) /* 32 bit address mode */
3464 int havesib;
3465 int havebase;
3466 int base;
3467 int index = 0;
3468 int scale = 0;
3470 havesib = 0;
3471 havebase = 1;
3472 base = rm;
3474 if (base == 4)
3476 havesib = 1;
3477 FETCH_DATA (the_info, codep + 1);
3478 index = (*codep >> 3) & 7;
3479 if (address_mode == mode_64bit || index != 0x4)
3480 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
3481 scale = (*codep >> 6) & 3;
3482 base = *codep & 7;
3483 USED_REX (REX_EXTY);
3484 if (rex & REX_EXTY)
3485 index += 8;
3486 codep++;
3488 base += add;
3490 switch (mod)
3492 case 0:
3493 if ((base & 7) == 5)
3495 havebase = 0;
3496 if (address_mode == mode_64bit && !havesib)
3497 riprel = 1;
3498 disp = get32s ();
3500 break;
3501 case 1:
3502 FETCH_DATA (the_info, codep + 1);
3503 disp = *codep++;
3504 if ((disp & 0x80) != 0)
3505 disp -= 0x100;
3506 break;
3507 case 2:
3508 disp = get32s ();
3509 break;
3512 if (!intel_syntax)
3513 if (mod != 0 || (base & 7) == 5)
3515 print_operand_value (scratchbuf, !riprel, disp);
3516 oappend (scratchbuf);
3517 if (riprel)
3519 set_op (disp, 1);
3520 oappend ("(%rip)");
3524 if (havebase || (havesib && (index != 4 || scale != 0)))
3526 *obufp++ = open_char;
3527 if (intel_syntax && riprel)
3528 oappend ("rip + ");
3529 *obufp = '\0';
3530 if (havebase)
3531 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
3532 ? names64[base] : names32[base]);
3533 if (havesib)
3535 if (index != 4)
3537 if (!intel_syntax || havebase)
3539 *obufp++ = separator_char;
3540 *obufp = '\0';
3542 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
3543 ? names64[index] : names32[index]);
3545 if (scale != 0 || (!intel_syntax && index != 4))
3547 *obufp++ = scale_char;
3548 *obufp = '\0';
3549 sprintf (scratchbuf, "%d", 1 << scale);
3550 oappend (scratchbuf);
3553 if (intel_syntax && disp)
3555 if ((bfd_signed_vma) disp > 0)
3557 *obufp++ = '+';
3558 *obufp = '\0';
3560 else if (mod != 1)
3562 *obufp++ = '-';
3563 *obufp = '\0';
3564 disp = - (bfd_signed_vma) disp;
3567 print_operand_value (scratchbuf, mod != 1, disp);
3568 oappend (scratchbuf);
3571 *obufp++ = close_char;
3572 *obufp = '\0';
3574 else if (intel_syntax)
3576 if (mod != 0 || (base & 7) == 5)
3578 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3579 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
3581 else
3583 oappend (names_seg[ds_reg - es_reg]);
3584 oappend (":");
3586 print_operand_value (scratchbuf, 1, disp);
3587 oappend (scratchbuf);
3591 else
3592 { /* 16 bit address mode */
3593 switch (mod)
3595 case 0:
3596 if (rm == 6)
3598 disp = get16 ();
3599 if ((disp & 0x8000) != 0)
3600 disp -= 0x10000;
3602 break;
3603 case 1:
3604 FETCH_DATA (the_info, codep + 1);
3605 disp = *codep++;
3606 if ((disp & 0x80) != 0)
3607 disp -= 0x100;
3608 break;
3609 case 2:
3610 disp = get16 ();
3611 if ((disp & 0x8000) != 0)
3612 disp -= 0x10000;
3613 break;
3616 if (!intel_syntax)
3617 if (mod != 0 || rm == 6)
3619 print_operand_value (scratchbuf, 0, disp);
3620 oappend (scratchbuf);
3623 if (mod != 0 || rm != 6)
3625 *obufp++ = open_char;
3626 *obufp = '\0';
3627 oappend (index16[rm]);
3628 if (intel_syntax && disp)
3630 if ((bfd_signed_vma) disp > 0)
3632 *obufp++ = '+';
3633 *obufp = '\0';
3635 else if (mod != 1)
3637 *obufp++ = '-';
3638 *obufp = '\0';
3639 disp = - (bfd_signed_vma) disp;
3642 print_operand_value (scratchbuf, mod != 1, disp);
3643 oappend (scratchbuf);
3646 *obufp++ = close_char;
3647 *obufp = '\0';
3649 else if (intel_syntax)
3651 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3652 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
3654 else
3656 oappend (names_seg[ds_reg - es_reg]);
3657 oappend (":");
3659 print_operand_value (scratchbuf, 1, disp & 0xffff);
3660 oappend (scratchbuf);
3665 static void
3666 OP_G (int bytemode, int sizeflag)
3668 int add = 0;
3669 USED_REX (REX_EXTX);
3670 if (rex & REX_EXTX)
3671 add += 8;
3672 switch (bytemode)
3674 case b_mode:
3675 USED_REX (0);
3676 if (rex)
3677 oappend (names8rex[reg + add]);
3678 else
3679 oappend (names8[reg + add]);
3680 break;
3681 case w_mode:
3682 oappend (names16[reg + add]);
3683 break;
3684 case d_mode:
3685 oappend (names32[reg + add]);
3686 break;
3687 case q_mode:
3688 oappend (names64[reg + add]);
3689 break;
3690 case v_mode:
3691 case dq_mode:
3692 case dqw_mode:
3693 USED_REX (REX_MODE64);
3694 if (rex & REX_MODE64)
3695 oappend (names64[reg + add]);
3696 else if ((sizeflag & DFLAG) || bytemode != v_mode)
3697 oappend (names32[reg + add]);
3698 else
3699 oappend (names16[reg + add]);
3700 used_prefixes |= (prefixes & PREFIX_DATA);
3701 break;
3702 case m_mode:
3703 if (address_mode == mode_64bit)
3704 oappend (names64[reg + add]);
3705 else
3706 oappend (names32[reg + add]);
3707 break;
3708 default:
3709 oappend (INTERNAL_DISASSEMBLER_ERROR);
3710 break;
3714 static bfd_vma
3715 get64 (void)
3717 bfd_vma x;
3718 #ifdef BFD64
3719 unsigned int a;
3720 unsigned int b;
3722 FETCH_DATA (the_info, codep + 8);
3723 a = *codep++ & 0xff;
3724 a |= (*codep++ & 0xff) << 8;
3725 a |= (*codep++ & 0xff) << 16;
3726 a |= (*codep++ & 0xff) << 24;
3727 b = *codep++ & 0xff;
3728 b |= (*codep++ & 0xff) << 8;
3729 b |= (*codep++ & 0xff) << 16;
3730 b |= (*codep++ & 0xff) << 24;
3731 x = a + ((bfd_vma) b << 32);
3732 #else
3733 abort ();
3734 x = 0;
3735 #endif
3736 return x;
3739 static bfd_signed_vma
3740 get32 (void)
3742 bfd_signed_vma x = 0;
3744 FETCH_DATA (the_info, codep + 4);
3745 x = *codep++ & (bfd_signed_vma) 0xff;
3746 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3747 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3748 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3749 return x;
3752 static bfd_signed_vma
3753 get32s (void)
3755 bfd_signed_vma x = 0;
3757 FETCH_DATA (the_info, codep + 4);
3758 x = *codep++ & (bfd_signed_vma) 0xff;
3759 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3760 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3761 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3763 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
3765 return x;
3768 static int
3769 get16 (void)
3771 int x = 0;
3773 FETCH_DATA (the_info, codep + 2);
3774 x = *codep++ & 0xff;
3775 x |= (*codep++ & 0xff) << 8;
3776 return x;
3779 static void
3780 set_op (bfd_vma op, int riprel)
3782 op_index[op_ad] = op_ad;
3783 if (address_mode == mode_64bit)
3785 op_address[op_ad] = op;
3786 op_riprel[op_ad] = riprel;
3788 else
3790 /* Mask to get a 32-bit address. */
3791 op_address[op_ad] = op & 0xffffffff;
3792 op_riprel[op_ad] = riprel & 0xffffffff;
3796 static void
3797 OP_REG (int code, int sizeflag)
3799 const char *s;
3800 int add = 0;
3801 USED_REX (REX_EXTZ);
3802 if (rex & REX_EXTZ)
3803 add = 8;
3805 switch (code)
3807 case indir_dx_reg:
3808 if (intel_syntax)
3809 s = "[dx]";
3810 else
3811 s = "(%dx)";
3812 break;
3813 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3814 case sp_reg: case bp_reg: case si_reg: case di_reg:
3815 s = names16[code - ax_reg + add];
3816 break;
3817 case es_reg: case ss_reg: case cs_reg:
3818 case ds_reg: case fs_reg: case gs_reg:
3819 s = names_seg[code - es_reg + add];
3820 break;
3821 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3822 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3823 USED_REX (0);
3824 if (rex)
3825 s = names8rex[code - al_reg + add];
3826 else
3827 s = names8[code - al_reg];
3828 break;
3829 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
3830 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
3831 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3833 s = names64[code - rAX_reg + add];
3834 break;
3836 code += eAX_reg - rAX_reg;
3837 /* Fall through. */
3838 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3839 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3840 USED_REX (REX_MODE64);
3841 if (rex & REX_MODE64)
3842 s = names64[code - eAX_reg + add];
3843 else if (sizeflag & DFLAG)
3844 s = names32[code - eAX_reg + add];
3845 else
3846 s = names16[code - eAX_reg + add];
3847 used_prefixes |= (prefixes & PREFIX_DATA);
3848 break;
3849 default:
3850 s = INTERNAL_DISASSEMBLER_ERROR;
3851 break;
3853 oappend (s);
3856 static void
3857 OP_IMREG (int code, int sizeflag)
3859 const char *s;
3861 switch (code)
3863 case indir_dx_reg:
3864 if (intel_syntax)
3865 s = "[dx]";
3866 else
3867 s = "(%dx)";
3868 break;
3869 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3870 case sp_reg: case bp_reg: case si_reg: case di_reg:
3871 s = names16[code - ax_reg];
3872 break;
3873 case es_reg: case ss_reg: case cs_reg:
3874 case ds_reg: case fs_reg: case gs_reg:
3875 s = names_seg[code - es_reg];
3876 break;
3877 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3878 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3879 USED_REX (0);
3880 if (rex)
3881 s = names8rex[code - al_reg];
3882 else
3883 s = names8[code - al_reg];
3884 break;
3885 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3886 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3887 USED_REX (REX_MODE64);
3888 if (rex & REX_MODE64)
3889 s = names64[code - eAX_reg];
3890 else if (sizeflag & DFLAG)
3891 s = names32[code - eAX_reg];
3892 else
3893 s = names16[code - eAX_reg];
3894 used_prefixes |= (prefixes & PREFIX_DATA);
3895 break;
3896 default:
3897 s = INTERNAL_DISASSEMBLER_ERROR;
3898 break;
3900 oappend (s);
3903 static void
3904 OP_I (int bytemode, int sizeflag)
3906 bfd_signed_vma op;
3907 bfd_signed_vma mask = -1;
3909 switch (bytemode)
3911 case b_mode:
3912 FETCH_DATA (the_info, codep + 1);
3913 op = *codep++;
3914 mask = 0xff;
3915 break;
3916 case q_mode:
3917 if (address_mode == mode_64bit)
3919 op = get32s ();
3920 break;
3922 /* Fall through. */
3923 case v_mode:
3924 USED_REX (REX_MODE64);
3925 if (rex & REX_MODE64)
3926 op = get32s ();
3927 else if (sizeflag & DFLAG)
3929 op = get32 ();
3930 mask = 0xffffffff;
3932 else
3934 op = get16 ();
3935 mask = 0xfffff;
3937 used_prefixes |= (prefixes & PREFIX_DATA);
3938 break;
3939 case w_mode:
3940 mask = 0xfffff;
3941 op = get16 ();
3942 break;
3943 case const_1_mode:
3944 if (intel_syntax)
3945 oappend ("1");
3946 return;
3947 default:
3948 oappend (INTERNAL_DISASSEMBLER_ERROR);
3949 return;
3952 op &= mask;
3953 scratchbuf[0] = '$';
3954 print_operand_value (scratchbuf + 1, 1, op);
3955 oappend (scratchbuf + intel_syntax);
3956 scratchbuf[0] = '\0';
3959 static void
3960 OP_I64 (int bytemode, int sizeflag)
3962 bfd_signed_vma op;
3963 bfd_signed_vma mask = -1;
3965 if (address_mode != mode_64bit)
3967 OP_I (bytemode, sizeflag);
3968 return;
3971 switch (bytemode)
3973 case b_mode:
3974 FETCH_DATA (the_info, codep + 1);
3975 op = *codep++;
3976 mask = 0xff;
3977 break;
3978 case v_mode:
3979 USED_REX (REX_MODE64);
3980 if (rex & REX_MODE64)
3981 op = get64 ();
3982 else if (sizeflag & DFLAG)
3984 op = get32 ();
3985 mask = 0xffffffff;
3987 else
3989 op = get16 ();
3990 mask = 0xfffff;
3992 used_prefixes |= (prefixes & PREFIX_DATA);
3993 break;
3994 case w_mode:
3995 mask = 0xfffff;
3996 op = get16 ();
3997 break;
3998 default:
3999 oappend (INTERNAL_DISASSEMBLER_ERROR);
4000 return;
4003 op &= mask;
4004 scratchbuf[0] = '$';
4005 print_operand_value (scratchbuf + 1, 1, op);
4006 oappend (scratchbuf + intel_syntax);
4007 scratchbuf[0] = '\0';
4010 static void
4011 OP_sI (int bytemode, int sizeflag)
4013 bfd_signed_vma op;
4014 bfd_signed_vma mask = -1;
4016 switch (bytemode)
4018 case b_mode:
4019 FETCH_DATA (the_info, codep + 1);
4020 op = *codep++;
4021 if ((op & 0x80) != 0)
4022 op -= 0x100;
4023 mask = 0xffffffff;
4024 break;
4025 case v_mode:
4026 USED_REX (REX_MODE64);
4027 if (rex & REX_MODE64)
4028 op = get32s ();
4029 else if (sizeflag & DFLAG)
4031 op = get32s ();
4032 mask = 0xffffffff;
4034 else
4036 mask = 0xffffffff;
4037 op = get16 ();
4038 if ((op & 0x8000) != 0)
4039 op -= 0x10000;
4041 used_prefixes |= (prefixes & PREFIX_DATA);
4042 break;
4043 case w_mode:
4044 op = get16 ();
4045 mask = 0xffffffff;
4046 if ((op & 0x8000) != 0)
4047 op -= 0x10000;
4048 break;
4049 default:
4050 oappend (INTERNAL_DISASSEMBLER_ERROR);
4051 return;
4054 scratchbuf[0] = '$';
4055 print_operand_value (scratchbuf + 1, 1, op);
4056 oappend (scratchbuf + intel_syntax);
4059 static void
4060 OP_J (int bytemode, int sizeflag)
4062 bfd_vma disp;
4063 bfd_vma mask = -1;
4065 switch (bytemode)
4067 case b_mode:
4068 FETCH_DATA (the_info, codep + 1);
4069 disp = *codep++;
4070 if ((disp & 0x80) != 0)
4071 disp -= 0x100;
4072 break;
4073 case v_mode:
4074 if ((sizeflag & DFLAG) || (rex & REX_MODE64))
4075 disp = get32s ();
4076 else
4078 disp = get16 ();
4079 /* For some reason, a data16 prefix on a jump instruction
4080 means that the pc is masked to 16 bits after the
4081 displacement is added! */
4082 mask = 0xffff;
4084 break;
4085 default:
4086 oappend (INTERNAL_DISASSEMBLER_ERROR);
4087 return;
4089 disp = (start_pc + codep - start_codep + disp) & mask;
4090 set_op (disp, 0);
4091 print_operand_value (scratchbuf, 1, disp);
4092 oappend (scratchbuf);
4095 static void
4096 OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4098 oappend (names_seg[reg]);
4101 static void
4102 OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
4104 int seg, offset;
4106 if (sizeflag & DFLAG)
4108 offset = get32 ();
4109 seg = get16 ();
4111 else
4113 offset = get16 ();
4114 seg = get16 ();
4116 used_prefixes |= (prefixes & PREFIX_DATA);
4117 if (intel_syntax)
4118 sprintf (scratchbuf, "0x%x:0x%x", seg, offset);
4119 else
4120 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
4121 oappend (scratchbuf);
4124 static void
4125 OP_OFF (int bytemode, int sizeflag)
4127 bfd_vma off;
4129 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
4130 intel_operand_size (bytemode, sizeflag);
4131 append_seg ();
4133 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
4134 off = get32 ();
4135 else
4136 off = get16 ();
4138 if (intel_syntax)
4140 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4141 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
4143 oappend (names_seg[ds_reg - es_reg]);
4144 oappend (":");
4147 print_operand_value (scratchbuf, 1, off);
4148 oappend (scratchbuf);
4151 static void
4152 OP_OFF64 (int bytemode, int sizeflag)
4154 bfd_vma off;
4156 if (address_mode != mode_64bit)
4158 OP_OFF (bytemode, sizeflag);
4159 return;
4162 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
4163 intel_operand_size (bytemode, sizeflag);
4164 append_seg ();
4166 off = get64 ();
4168 if (intel_syntax)
4170 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4171 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
4173 oappend (names_seg[ds_reg - es_reg]);
4174 oappend (":");
4177 print_operand_value (scratchbuf, 1, off);
4178 oappend (scratchbuf);
4181 static void
4182 ptr_reg (int code, int sizeflag)
4184 const char *s;
4186 *obufp++ = open_char;
4187 used_prefixes |= (prefixes & PREFIX_ADDR);
4188 if (address_mode == mode_64bit)
4190 if (!(sizeflag & AFLAG))
4191 s = names32[code - eAX_reg];
4192 else
4193 s = names64[code - eAX_reg];
4195 else if (sizeflag & AFLAG)
4196 s = names32[code - eAX_reg];
4197 else
4198 s = names16[code - eAX_reg];
4199 oappend (s);
4200 *obufp++ = close_char;
4201 *obufp = 0;
4204 static void
4205 OP_ESreg (int code, int sizeflag)
4207 if (intel_syntax)
4208 intel_operand_size (codep[-1] & 1 ? v_mode : b_mode, sizeflag);
4209 oappend ("%es:" + intel_syntax);
4210 ptr_reg (code, sizeflag);
4213 static void
4214 OP_DSreg (int code, int sizeflag)
4216 if (intel_syntax)
4217 intel_operand_size (codep[-1] != 0xd7 && (codep[-1] & 1)
4218 ? v_mode
4219 : b_mode,
4220 sizeflag);
4221 if ((prefixes
4222 & (PREFIX_CS
4223 | PREFIX_DS
4224 | PREFIX_SS
4225 | PREFIX_ES
4226 | PREFIX_FS
4227 | PREFIX_GS)) == 0)
4228 prefixes |= PREFIX_DS;
4229 append_seg ();
4230 ptr_reg (code, sizeflag);
4233 static void
4234 OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4236 int add = 0;
4237 if (rex & REX_EXTX)
4239 USED_REX (REX_EXTX);
4240 add = 8;
4242 else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
4244 used_prefixes |= PREFIX_LOCK;
4245 add = 8;
4247 sprintf (scratchbuf, "%%cr%d", reg + add);
4248 oappend (scratchbuf + intel_syntax);
4251 static void
4252 OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4254 int add = 0;
4255 USED_REX (REX_EXTX);
4256 if (rex & REX_EXTX)
4257 add = 8;
4258 if (intel_syntax)
4259 sprintf (scratchbuf, "db%d", reg + add);
4260 else
4261 sprintf (scratchbuf, "%%db%d", reg + add);
4262 oappend (scratchbuf);
4265 static void
4266 OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4268 sprintf (scratchbuf, "%%tr%d", reg);
4269 oappend (scratchbuf + intel_syntax);
4272 static void
4273 OP_Rd (int bytemode, int sizeflag)
4275 if (mod == 3)
4276 OP_E (bytemode, sizeflag);
4277 else
4278 BadOp ();
4281 static void
4282 OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4284 used_prefixes |= (prefixes & PREFIX_DATA);
4285 if (prefixes & PREFIX_DATA)
4287 int add = 0;
4288 USED_REX (REX_EXTX);
4289 if (rex & REX_EXTX)
4290 add = 8;
4291 sprintf (scratchbuf, "%%xmm%d", reg + add);
4293 else
4294 sprintf (scratchbuf, "%%mm%d", reg);
4295 oappend (scratchbuf + intel_syntax);
4298 static void
4299 OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4301 int add = 0;
4302 USED_REX (REX_EXTX);
4303 if (rex & REX_EXTX)
4304 add = 8;
4305 sprintf (scratchbuf, "%%xmm%d", reg + add);
4306 oappend (scratchbuf + intel_syntax);
4309 static void
4310 OP_EM (int bytemode, int sizeflag)
4312 if (mod != 3)
4314 if (intel_syntax && bytemode == v_mode)
4316 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
4317 used_prefixes |= (prefixes & PREFIX_DATA);
4319 OP_E (bytemode, sizeflag);
4320 return;
4323 /* Skip mod/rm byte. */
4324 MODRM_CHECK;
4325 codep++;
4326 used_prefixes |= (prefixes & PREFIX_DATA);
4327 if (prefixes & PREFIX_DATA)
4329 int add = 0;
4331 USED_REX (REX_EXTZ);
4332 if (rex & REX_EXTZ)
4333 add = 8;
4334 sprintf (scratchbuf, "%%xmm%d", rm + add);
4336 else
4337 sprintf (scratchbuf, "%%mm%d", rm);
4338 oappend (scratchbuf + intel_syntax);
4341 static void
4342 OP_EX (int bytemode, int sizeflag)
4344 int add = 0;
4345 if (mod != 3)
4347 if (intel_syntax && bytemode == v_mode)
4349 switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ))
4351 case 0: bytemode = x_mode; break;
4352 case PREFIX_REPZ: bytemode = d_mode; used_prefixes |= PREFIX_REPZ; break;
4353 case PREFIX_DATA: bytemode = x_mode; used_prefixes |= PREFIX_DATA; break;
4354 case PREFIX_REPNZ: bytemode = q_mode; used_prefixes |= PREFIX_REPNZ; break;
4355 default: bytemode = 0; break;
4358 OP_E (bytemode, sizeflag);
4359 return;
4361 USED_REX (REX_EXTZ);
4362 if (rex & REX_EXTZ)
4363 add = 8;
4365 /* Skip mod/rm byte. */
4366 MODRM_CHECK;
4367 codep++;
4368 sprintf (scratchbuf, "%%xmm%d", rm + add);
4369 oappend (scratchbuf + intel_syntax);
4372 static void
4373 OP_MS (int bytemode, int sizeflag)
4375 if (mod == 3)
4376 OP_EM (bytemode, sizeflag);
4377 else
4378 BadOp ();
4381 static void
4382 OP_XS (int bytemode, int sizeflag)
4384 if (mod == 3)
4385 OP_EX (bytemode, sizeflag);
4386 else
4387 BadOp ();
4390 static void
4391 OP_M (int bytemode, int sizeflag)
4393 if (mod == 3)
4394 BadOp (); /* bad lea,lds,les,lfs,lgs,lss modrm */
4395 else
4396 OP_E (bytemode, sizeflag);
4399 static void
4400 OP_0f07 (int bytemode, int sizeflag)
4402 if (mod != 3 || rm != 0)
4403 BadOp ();
4404 else
4405 OP_E (bytemode, sizeflag);
4408 static void
4409 OP_0fae (int bytemode, int sizeflag)
4411 if (mod == 3)
4413 if (reg == 7)
4414 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
4416 if (reg < 5 || rm != 0)
4418 BadOp (); /* bad sfence, mfence, or lfence */
4419 return;
4422 else if (reg != 7)
4424 BadOp (); /* bad clflush */
4425 return;
4428 OP_E (bytemode, sizeflag);
4431 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
4432 32bit mode and "xchg %rax,%rax" in 64bit mode. NOP with REPZ prefix
4433 is called PAUSE. We display "xchg %ax,%ax" instead of "data16 nop".
4436 static void
4437 NOP_Fixup1 (int bytemode, int sizeflag)
4439 if (prefixes == PREFIX_REPZ)
4440 strcpy (obuf, "pause");
4441 else if (prefixes == PREFIX_DATA
4442 || ((rex & REX_MODE64) && rex != 0x48))
4443 OP_REG (bytemode, sizeflag);
4444 else
4445 strcpy (obuf, "nop");
4448 static void
4449 NOP_Fixup2 (int bytemode, int sizeflag)
4451 if (prefixes == PREFIX_DATA
4452 || ((rex & REX_MODE64) && rex != 0x48))
4453 OP_IMREG (bytemode, sizeflag);
4456 static const char *const Suffix3DNow[] = {
4457 /* 00 */ NULL, NULL, NULL, NULL,
4458 /* 04 */ NULL, NULL, NULL, NULL,
4459 /* 08 */ NULL, NULL, NULL, NULL,
4460 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
4461 /* 10 */ NULL, NULL, NULL, NULL,
4462 /* 14 */ NULL, NULL, NULL, NULL,
4463 /* 18 */ NULL, NULL, NULL, NULL,
4464 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
4465 /* 20 */ NULL, NULL, NULL, NULL,
4466 /* 24 */ NULL, NULL, NULL, NULL,
4467 /* 28 */ NULL, NULL, NULL, NULL,
4468 /* 2C */ NULL, NULL, NULL, NULL,
4469 /* 30 */ NULL, NULL, NULL, NULL,
4470 /* 34 */ NULL, NULL, NULL, NULL,
4471 /* 38 */ NULL, NULL, NULL, NULL,
4472 /* 3C */ NULL, NULL, NULL, NULL,
4473 /* 40 */ NULL, NULL, NULL, NULL,
4474 /* 44 */ NULL, NULL, NULL, NULL,
4475 /* 48 */ NULL, NULL, NULL, NULL,
4476 /* 4C */ NULL, NULL, NULL, NULL,
4477 /* 50 */ NULL, NULL, NULL, NULL,
4478 /* 54 */ NULL, NULL, NULL, NULL,
4479 /* 58 */ NULL, NULL, NULL, NULL,
4480 /* 5C */ NULL, NULL, NULL, NULL,
4481 /* 60 */ NULL, NULL, NULL, NULL,
4482 /* 64 */ NULL, NULL, NULL, NULL,
4483 /* 68 */ NULL, NULL, NULL, NULL,
4484 /* 6C */ NULL, NULL, NULL, NULL,
4485 /* 70 */ NULL, NULL, NULL, NULL,
4486 /* 74 */ NULL, NULL, NULL, NULL,
4487 /* 78 */ NULL, NULL, NULL, NULL,
4488 /* 7C */ NULL, NULL, NULL, NULL,
4489 /* 80 */ NULL, NULL, NULL, NULL,
4490 /* 84 */ NULL, NULL, NULL, NULL,
4491 /* 88 */ NULL, NULL, "pfnacc", NULL,
4492 /* 8C */ NULL, NULL, "pfpnacc", NULL,
4493 /* 90 */ "pfcmpge", NULL, NULL, NULL,
4494 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
4495 /* 98 */ NULL, NULL, "pfsub", NULL,
4496 /* 9C */ NULL, NULL, "pfadd", NULL,
4497 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
4498 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
4499 /* A8 */ NULL, NULL, "pfsubr", NULL,
4500 /* AC */ NULL, NULL, "pfacc", NULL,
4501 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
4502 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
4503 /* B8 */ NULL, NULL, NULL, "pswapd",
4504 /* BC */ NULL, NULL, NULL, "pavgusb",
4505 /* C0 */ NULL, NULL, NULL, NULL,
4506 /* C4 */ NULL, NULL, NULL, NULL,
4507 /* C8 */ NULL, NULL, NULL, NULL,
4508 /* CC */ NULL, NULL, NULL, NULL,
4509 /* D0 */ NULL, NULL, NULL, NULL,
4510 /* D4 */ NULL, NULL, NULL, NULL,
4511 /* D8 */ NULL, NULL, NULL, NULL,
4512 /* DC */ NULL, NULL, NULL, NULL,
4513 /* E0 */ NULL, NULL, NULL, NULL,
4514 /* E4 */ NULL, NULL, NULL, NULL,
4515 /* E8 */ NULL, NULL, NULL, NULL,
4516 /* EC */ NULL, NULL, NULL, NULL,
4517 /* F0 */ NULL, NULL, NULL, NULL,
4518 /* F4 */ NULL, NULL, NULL, NULL,
4519 /* F8 */ NULL, NULL, NULL, NULL,
4520 /* FC */ NULL, NULL, NULL, NULL,
4523 static void
4524 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4526 const char *mnemonic;
4528 FETCH_DATA (the_info, codep + 1);
4529 /* AMD 3DNow! instructions are specified by an opcode suffix in the
4530 place where an 8-bit immediate would normally go. ie. the last
4531 byte of the instruction. */
4532 obufp = obuf + strlen (obuf);
4533 mnemonic = Suffix3DNow[*codep++ & 0xff];
4534 if (mnemonic)
4535 oappend (mnemonic);
4536 else
4538 /* Since a variable sized modrm/sib chunk is between the start
4539 of the opcode (0x0f0f) and the opcode suffix, we need to do
4540 all the modrm processing first, and don't know until now that
4541 we have a bad opcode. This necessitates some cleaning up. */
4542 op1out[0] = '\0';
4543 op2out[0] = '\0';
4544 BadOp ();
4548 static const char *simd_cmp_op[] = {
4549 "eq",
4550 "lt",
4551 "le",
4552 "unord",
4553 "neq",
4554 "nlt",
4555 "nle",
4556 "ord"
4559 static void
4560 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
4562 unsigned int cmp_type;
4564 FETCH_DATA (the_info, codep + 1);
4565 obufp = obuf + strlen (obuf);
4566 cmp_type = *codep++ & 0xff;
4567 if (cmp_type < 8)
4569 char suffix1 = 'p', suffix2 = 's';
4570 used_prefixes |= (prefixes & PREFIX_REPZ);
4571 if (prefixes & PREFIX_REPZ)
4572 suffix1 = 's';
4573 else
4575 used_prefixes |= (prefixes & PREFIX_DATA);
4576 if (prefixes & PREFIX_DATA)
4577 suffix2 = 'd';
4578 else
4580 used_prefixes |= (prefixes & PREFIX_REPNZ);
4581 if (prefixes & PREFIX_REPNZ)
4582 suffix1 = 's', suffix2 = 'd';
4585 sprintf (scratchbuf, "cmp%s%c%c",
4586 simd_cmp_op[cmp_type], suffix1, suffix2);
4587 used_prefixes |= (prefixes & PREFIX_REPZ);
4588 oappend (scratchbuf);
4590 else
4592 /* We have a bad extension byte. Clean up. */
4593 op1out[0] = '\0';
4594 op2out[0] = '\0';
4595 BadOp ();
4599 static void
4600 SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
4602 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
4603 forms of these instructions. */
4604 if (mod == 3)
4606 char *p = obuf + strlen (obuf);
4607 *(p + 1) = '\0';
4608 *p = *(p - 1);
4609 *(p - 1) = *(p - 2);
4610 *(p - 2) = *(p - 3);
4611 *(p - 3) = extrachar;
4615 static void
4616 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
4618 if (mod == 3 && reg == 1 && rm <= 1)
4620 /* Override "sidt". */
4621 size_t olen = strlen (obuf);
4622 char *p = obuf + olen - 4;
4623 const char **names = (address_mode == mode_64bit
4624 ? names64 : names32);
4626 /* We might have a suffix when disassembling with -Msuffix. */
4627 if (*p == 'i')
4628 --p;
4630 /* Remove "addr16/addr32" if we aren't in Intel mode. */
4631 if (!intel_syntax
4632 && (prefixes & PREFIX_ADDR)
4633 && olen >= (4 + 7)
4634 && *(p - 1) == ' '
4635 && strncmp (p - 7, "addr", 4) == 0
4636 && (strncmp (p - 3, "16", 2) == 0
4637 || strncmp (p - 3, "32", 2) == 0))
4638 p -= 7;
4640 if (rm)
4642 /* mwait %eax,%ecx */
4643 strcpy (p, "mwait");
4644 if (!intel_syntax)
4645 strcpy (op1out, names[0]);
4647 else
4649 /* monitor %eax,%ecx,%edx" */
4650 strcpy (p, "monitor");
4651 if (!intel_syntax)
4653 const char **op1_names;
4654 if (!(prefixes & PREFIX_ADDR))
4655 op1_names = (address_mode == mode_16bit
4656 ? names16 : names);
4657 else
4659 op1_names = (address_mode != mode_32bit
4660 ? names32 : names16);
4661 used_prefixes |= PREFIX_ADDR;
4663 strcpy (op1out, op1_names[0]);
4664 strcpy (op3out, names[2]);
4667 if (!intel_syntax)
4669 strcpy (op2out, names[1]);
4670 two_source_ops = 1;
4673 codep++;
4675 else
4676 OP_M (0, sizeflag);
4679 static void
4680 SVME_Fixup (int bytemode, int sizeflag)
4682 const char *alt;
4683 char *p;
4685 switch (*codep)
4687 case 0xd8:
4688 alt = "vmrun";
4689 break;
4690 case 0xd9:
4691 alt = "vmmcall";
4692 break;
4693 case 0xda:
4694 alt = "vmload";
4695 break;
4696 case 0xdb:
4697 alt = "vmsave";
4698 break;
4699 case 0xdc:
4700 alt = "stgi";
4701 break;
4702 case 0xdd:
4703 alt = "clgi";
4704 break;
4705 case 0xde:
4706 alt = "skinit";
4707 break;
4708 case 0xdf:
4709 alt = "invlpga";
4710 break;
4711 default:
4712 OP_M (bytemode, sizeflag);
4713 return;
4715 /* Override "lidt". */
4716 p = obuf + strlen (obuf) - 4;
4717 /* We might have a suffix. */
4718 if (*p == 'i')
4719 --p;
4720 strcpy (p, alt);
4721 if (!(prefixes & PREFIX_ADDR))
4723 ++codep;
4724 return;
4726 used_prefixes |= PREFIX_ADDR;
4727 switch (*codep++)
4729 case 0xdf:
4730 strcpy (op2out, names32[1]);
4731 two_source_ops = 1;
4732 /* Fall through. */
4733 case 0xd8:
4734 case 0xda:
4735 case 0xdb:
4736 *obufp++ = open_char;
4737 if (address_mode == mode_64bit || (sizeflag & AFLAG))
4738 alt = names32[0];
4739 else
4740 alt = names16[0];
4741 strcpy (obufp, alt);
4742 obufp += strlen (alt);
4743 *obufp++ = close_char;
4744 *obufp = '\0';
4745 break;
4749 static void
4750 INVLPG_Fixup (int bytemode, int sizeflag)
4752 const char *alt;
4754 switch (*codep)
4756 case 0xf8:
4757 alt = "swapgs";
4758 break;
4759 case 0xf9:
4760 alt = "rdtscp";
4761 break;
4762 default:
4763 OP_M (bytemode, sizeflag);
4764 return;
4766 /* Override "invlpg". */
4767 strcpy (obuf + strlen (obuf) - 6, alt);
4768 codep++;
4771 static void
4772 BadOp (void)
4774 /* Throw away prefixes and 1st. opcode byte. */
4775 codep = insn_codep + 1;
4776 oappend ("(bad)");
4779 static void
4780 SEG_Fixup (int extrachar, int sizeflag)
4782 if (mod == 3)
4784 /* We need to add a proper suffix with
4786 movw %ds,%ax
4787 movl %ds,%eax
4788 movq %ds,%rax
4789 movw %ax,%ds
4790 movl %eax,%ds
4791 movq %rax,%ds
4793 const char *suffix;
4795 if (prefixes & PREFIX_DATA)
4796 suffix = "w";
4797 else
4799 USED_REX (REX_MODE64);
4800 if (rex & REX_MODE64)
4801 suffix = "q";
4802 else
4803 suffix = "l";
4805 strcat (obuf, suffix);
4807 else
4809 /* We need to fix the suffix for
4811 movw %ds,(%eax)
4812 movw %ds,(%rax)
4813 movw (%eax),%ds
4814 movw (%rax),%ds
4816 Override "mov[l|q]". */
4817 char *p = obuf + strlen (obuf) - 1;
4819 /* We might not have a suffix. */
4820 if (*p == 'v')
4821 ++p;
4822 *p = 'w';
4825 OP_E (extrachar, sizeflag);
4828 static void
4829 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
4831 if (mod == 3 && reg == 0 && rm >=1 && rm <= 4)
4833 /* Override "sgdt". */
4834 char *p = obuf + strlen (obuf) - 4;
4836 /* We might have a suffix when disassembling with -Msuffix. */
4837 if (*p == 'g')
4838 --p;
4840 switch (rm)
4842 case 1:
4843 strcpy (p, "vmcall");
4844 break;
4845 case 2:
4846 strcpy (p, "vmlaunch");
4847 break;
4848 case 3:
4849 strcpy (p, "vmresume");
4850 break;
4851 case 4:
4852 strcpy (p, "vmxoff");
4853 break;
4856 codep++;
4858 else
4859 OP_E (0, sizeflag);
4862 static void
4863 OP_VMX (int bytemode, int sizeflag)
4865 used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
4866 if (prefixes & PREFIX_DATA)
4867 strcpy (obuf, "vmclear");
4868 else if (prefixes & PREFIX_REPZ)
4869 strcpy (obuf, "vmxon");
4870 else
4871 strcpy (obuf, "vmptrld");
4872 OP_E (bytemode, sizeflag);
4875 static void
4876 REP_Fixup (int bytemode, int sizeflag)
4878 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
4879 lods and stos. */
4880 size_t ilen = 0;
4882 if (prefixes & PREFIX_REPZ)
4883 switch (*insn_codep)
4885 case 0x6e: /* outsb */
4886 case 0x6f: /* outsw/outsl */
4887 case 0xa4: /* movsb */
4888 case 0xa5: /* movsw/movsl/movsq */
4889 if (!intel_syntax)
4890 ilen = 5;
4891 else
4892 ilen = 4;
4893 break;
4894 case 0xaa: /* stosb */
4895 case 0xab: /* stosw/stosl/stosq */
4896 case 0xac: /* lodsb */
4897 case 0xad: /* lodsw/lodsl/lodsq */
4898 if (!intel_syntax && (sizeflag & SUFFIX_ALWAYS))
4899 ilen = 5;
4900 else
4901 ilen = 4;
4902 break;
4903 case 0x6c: /* insb */
4904 case 0x6d: /* insl/insw */
4905 if (!intel_syntax)
4906 ilen = 4;
4907 else
4908 ilen = 3;
4909 break;
4910 default:
4911 abort ();
4912 break;
4915 if (ilen != 0)
4917 size_t olen;
4918 char *p;
4920 olen = strlen (obuf);
4921 p = obuf + olen - ilen - 1 - 4;
4922 /* Handle "repz [addr16|addr32]". */
4923 if ((prefixes & PREFIX_ADDR))
4924 p -= 1 + 6;
4926 memmove (p + 3, p + 4, olen - (p + 3 - obuf));
4929 switch (bytemode)
4931 case al_reg:
4932 case eAX_reg:
4933 case indir_dx_reg:
4934 OP_IMREG (bytemode, sizeflag);
4935 break;
4936 case eDI_reg:
4937 OP_ESreg (bytemode, sizeflag);
4938 break;
4939 case eSI_reg:
4940 OP_DSreg (bytemode, sizeflag);
4941 break;
4942 default:
4943 abort ();
4944 break;