2006-12-11 H.J. Lu <hongjiu.lu@intel.com>
[binutils-gdb.git] / opcodes / i386-dis.c
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, 2006 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
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.
11
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.
16
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. */
20
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). */
26
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. */
33
34 #include "dis-asm.h"
35 #include "sysdep.h"
36 #include "opintl.h"
37
38 #define MAXLEN 15
39
40 #include <setjmp.h>
41
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
47
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_EMC (int,int);
89 static void OP_MXC (int,int);
90 static void OP_MS (int, int);
91 static void OP_XS (int, int);
92 static void OP_M (int, int);
93 static void OP_VMX (int, int);
94 static void OP_0fae (int, int);
95 static void OP_0f07 (int, int);
96 static void NOP_Fixup1 (int, int);
97 static void NOP_Fixup2 (int, int);
98 static void OP_3DNowSuffix (int, int);
99 static void OP_SIMD_Suffix (int, int);
100 static void SIMD_Fixup (int, int);
101 static void PNI_Fixup (int, int);
102 static void SVME_Fixup (int, int);
103 static void INVLPG_Fixup (int, int);
104 static void BadOp (void);
105 static void VMX_Fixup (int, int);
106 static void REP_Fixup (int, int);
107
108 struct dis_private {
109 /* Points to first byte not fetched. */
110 bfd_byte *max_fetched;
111 bfd_byte the_buffer[MAXLEN];
112 bfd_vma insn_start;
113 int orig_sizeflag;
114 jmp_buf bailout;
115 };
116
117 /* The opcode for the fwait instruction, which we treat as a prefix
118 when we can. */
119 #define FWAIT_OPCODE (0x9b)
120
121 enum address_mode
122 {
123 mode_16bit,
124 mode_32bit,
125 mode_64bit
126 };
127
128 enum address_mode address_mode;
129
130 /* Flags for the prefixes for the current instruction. See below. */
131 static int prefixes;
132
133 /* REX prefix the current instruction. See below. */
134 static int rex;
135 /* Bits of REX we've already used. */
136 static int rex_used;
137 #define REX_MODE64 8
138 #define REX_EXTX 4
139 #define REX_EXTY 2
140 #define REX_EXTZ 1
141 /* Mark parts used in the REX prefix. When we are testing for
142 empty prefix (for 8bit register REX extension), just mask it
143 out. Otherwise test for REX bit is excuse for existence of REX
144 only in case value is nonzero. */
145 #define USED_REX(value) \
146 { \
147 if (value) \
148 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
149 else \
150 rex_used |= 0x40; \
151 }
152
153 /* Flags for prefixes which we somehow handled when printing the
154 current instruction. */
155 static int used_prefixes;
156
157 /* Flags stored in PREFIXES. */
158 #define PREFIX_REPZ 1
159 #define PREFIX_REPNZ 2
160 #define PREFIX_LOCK 4
161 #define PREFIX_CS 8
162 #define PREFIX_SS 0x10
163 #define PREFIX_DS 0x20
164 #define PREFIX_ES 0x40
165 #define PREFIX_FS 0x80
166 #define PREFIX_GS 0x100
167 #define PREFIX_DATA 0x200
168 #define PREFIX_ADDR 0x400
169 #define PREFIX_FWAIT 0x800
170
171 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
172 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
173 on error. */
174 #define FETCH_DATA(info, addr) \
175 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
176 ? 1 : fetch_data ((info), (addr)))
177
178 static int
179 fetch_data (struct disassemble_info *info, bfd_byte *addr)
180 {
181 int status;
182 struct dis_private *priv = (struct dis_private *) info->private_data;
183 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
184
185 if (addr <= priv->the_buffer + MAXLEN)
186 status = (*info->read_memory_func) (start,
187 priv->max_fetched,
188 addr - priv->max_fetched,
189 info);
190 else
191 status = -1;
192 if (status != 0)
193 {
194 /* If we did manage to read at least one byte, then
195 print_insn_i386 will do something sensible. Otherwise, print
196 an error. We do that here because this is where we know
197 STATUS. */
198 if (priv->max_fetched == priv->the_buffer)
199 (*info->memory_error_func) (status, start, info);
200 longjmp (priv->bailout, 1);
201 }
202 else
203 priv->max_fetched = addr;
204 return 1;
205 }
206
207 #define XX NULL, 0
208
209 #define Eb OP_E, b_mode
210 #define Ev OP_E, v_mode
211 #define Ed OP_E, d_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 M OP_M, 0 /* lea, lgdt, etc. */
220 #define Ma OP_M, v_mode
221 #define Mp OP_M, f_mode /* 32 or 48 bit memory operand for LDS, LES etc */
222 #define Mq OP_M, q_mode
223 #define Gb OP_G, b_mode
224 #define Gv OP_G, v_mode
225 #define Gd OP_G, d_mode
226 #define Gdq OP_G, dq_mode
227 #define Gm OP_G, m_mode
228 #define Gw OP_G, w_mode
229 #define Rd OP_Rd, d_mode
230 #define Rm OP_Rd, m_mode
231 #define Ib OP_I, b_mode
232 #define sIb OP_sI, b_mode /* sign extened byte */
233 #define Iv OP_I, v_mode
234 #define Iq OP_I, q_mode
235 #define Iv64 OP_I64, v_mode
236 #define Iw OP_I, w_mode
237 #define I1 OP_I, const_1_mode
238 #define Jb OP_J, b_mode
239 #define Jv OP_J, v_mode
240 #define Cm OP_C, m_mode
241 #define Dm OP_D, m_mode
242 #define Td OP_T, d_mode
243
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
271
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 zAX OP_IMREG, z_mode_ax_reg
291 #define indirDX OP_IMREG, indir_dx_reg
292
293 #define Sw OP_SEG, w_mode
294 #define Sv OP_SEG, v_mode
295 #define Ap OP_DIR, 0
296 #define Ob OP_OFF64, b_mode
297 #define Ov OP_OFF64, v_mode
298 #define Xb OP_DSreg, eSI_reg
299 #define Xv OP_DSreg, eSI_reg
300 #define Xz OP_DSreg, eSI_reg
301 #define Yb OP_ESreg, eDI_reg
302 #define Yv OP_ESreg, eDI_reg
303 #define DSBX OP_DSreg, eBX_reg
304
305 #define es OP_REG, es_reg
306 #define ss OP_REG, ss_reg
307 #define cs OP_REG, cs_reg
308 #define ds OP_REG, ds_reg
309 #define fs OP_REG, fs_reg
310 #define gs OP_REG, gs_reg
311
312 #define MX OP_MMX, 0
313 #define XM OP_XMM, 0
314 #define EM OP_EM, v_mode
315 #define EX OP_EX, v_mode
316 #define MS OP_MS, v_mode
317 #define XS OP_XS, v_mode
318 #define EMC OP_EMC, v_mode
319 #define MXC OP_MXC, 0
320 #define VM OP_VMX, q_mode
321 #define OPSUF OP_3DNowSuffix, 0
322 #define OPSIMD OP_SIMD_Suffix, 0
323
324 /* Used handle "rep" prefix for string instructions. */
325 #define Xbr REP_Fixup, eSI_reg
326 #define Xvr REP_Fixup, eSI_reg
327 #define Ybr REP_Fixup, eDI_reg
328 #define Yvr REP_Fixup, eDI_reg
329 #define Yzr REP_Fixup, eDI_reg
330 #define indirDXr REP_Fixup, indir_dx_reg
331 #define ALr REP_Fixup, al_reg
332 #define eAXr REP_Fixup, eAX_reg
333
334 #define cond_jump_flag NULL, cond_jump_mode
335 #define loop_jcxz_flag NULL, loop_jcxz_mode
336
337 /* bits in sizeflag */
338 #define SUFFIX_ALWAYS 4
339 #define AFLAG 2
340 #define DFLAG 1
341
342 #define b_mode 1 /* byte operand */
343 #define v_mode 2 /* operand size depends on prefixes */
344 #define w_mode 3 /* word operand */
345 #define d_mode 4 /* double word operand */
346 #define q_mode 5 /* quad word operand */
347 #define t_mode 6 /* ten-byte operand */
348 #define x_mode 7 /* 16-byte XMM operand */
349 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
350 #define cond_jump_mode 9
351 #define loop_jcxz_mode 10
352 #define dq_mode 11 /* operand size depends on REX prefixes. */
353 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
354 #define f_mode 13 /* 4- or 6-byte pointer operand */
355 #define const_1_mode 14
356 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
357 #define z_mode 16 /* non-quad operand size depends on prefixes */
358
359 #define es_reg 100
360 #define cs_reg 101
361 #define ss_reg 102
362 #define ds_reg 103
363 #define fs_reg 104
364 #define gs_reg 105
365
366 #define eAX_reg 108
367 #define eCX_reg 109
368 #define eDX_reg 110
369 #define eBX_reg 111
370 #define eSP_reg 112
371 #define eBP_reg 113
372 #define eSI_reg 114
373 #define eDI_reg 115
374
375 #define al_reg 116
376 #define cl_reg 117
377 #define dl_reg 118
378 #define bl_reg 119
379 #define ah_reg 120
380 #define ch_reg 121
381 #define dh_reg 122
382 #define bh_reg 123
383
384 #define ax_reg 124
385 #define cx_reg 125
386 #define dx_reg 126
387 #define bx_reg 127
388 #define sp_reg 128
389 #define bp_reg 129
390 #define si_reg 130
391 #define di_reg 131
392
393 #define rAX_reg 132
394 #define rCX_reg 133
395 #define rDX_reg 134
396 #define rBX_reg 135
397 #define rSP_reg 136
398 #define rBP_reg 137
399 #define rSI_reg 138
400 #define rDI_reg 139
401
402 #define z_mode_ax_reg 149
403 #define indir_dx_reg 150
404
405 #define FLOATCODE 1
406 #define USE_GROUPS 2
407 #define USE_PREFIX_USER_TABLE 3
408 #define X86_64_SPECIAL 4
409 #define IS_3BYTE_OPCODE 5
410
411 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0, NULL, 0
412
413 #define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0, NULL, 0
414 #define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0, NULL, 0
415 #define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0, NULL, 0
416 #define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0, NULL, 0
417 #define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0, NULL, 0
418 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0, NULL, 0
419 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0, NULL, 0
420 #define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0, NULL, 0
421 #define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0, NULL, 0
422 #define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0, NULL, 0
423 #define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0, NULL, 0
424 #define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0, NULL, 0
425 #define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0, NULL, 0
426 #define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0, NULL, 0
427 #define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0, NULL, 0
428 #define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0, NULL, 0
429 #define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0, NULL, 0
430 #define GRP11_C6 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0, NULL, 0
431 #define GRP11_C7 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0, NULL, 0
432 #define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0, NULL, 0
433 #define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0, NULL, 0
434 #define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0, NULL, 0
435 #define GRP15 NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0, NULL, 0
436 #define GRP16 NULL, NULL, USE_GROUPS, NULL, 23, NULL, 0, NULL, 0
437 #define GRPAMD NULL, NULL, USE_GROUPS, NULL, 24, NULL, 0, NULL, 0
438 #define GRPPADLCK1 NULL, NULL, USE_GROUPS, NULL, 25, NULL, 0, NULL, 0
439 #define GRPPADLCK2 NULL, NULL, USE_GROUPS, NULL, 26, NULL, 0, NULL, 0
440
441 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0, NULL, 0
442 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0, NULL, 0
443 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0, NULL, 0
444 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0, NULL, 0
445 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0, NULL, 0
446 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0, NULL, 0
447 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0, NULL, 0
448 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0, NULL, 0
449 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0, NULL, 0
450 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0, NULL, 0
451 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0, NULL, 0
452 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0, NULL, 0
453 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0, NULL, 0
454 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0, NULL, 0
455 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0, NULL, 0
456 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0, NULL, 0
457 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0, NULL, 0
458 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0, NULL, 0
459 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0, NULL, 0
460 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0, NULL, 0
461 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0, NULL, 0
462 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0, NULL, 0
463 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0, NULL, 0
464 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0, NULL, 0
465 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0, NULL, 0
466 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0, NULL, 0
467 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0, NULL, 0
468 #define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0, NULL, 0
469 #define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0, NULL, 0
470 #define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0, NULL, 0
471 #define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0, NULL, 0
472 #define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0, NULL, 0
473 #define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0, NULL, 0
474 #define PREGRP33 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 33, NULL, 0, NULL, 0
475 #define PREGRP34 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 34, NULL, 0, NULL, 0
476 #define PREGRP35 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 35, NULL, 0, NULL, 0
477 #define PREGRP36 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 36, NULL, 0, NULL, 0
478 #define PREGRP37 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 37, NULL, 0, NULL, 0
479
480
481 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0, NULL, 0
482 #define X86_64_1 NULL, NULL, X86_64_SPECIAL, NULL, 1, NULL, 0, NULL, 0
483 #define X86_64_2 NULL, NULL, X86_64_SPECIAL, NULL, 2, NULL, 0, NULL, 0
484 #define X86_64_3 NULL, NULL, X86_64_SPECIAL, NULL, 3, NULL, 0, NULL, 0
485
486 #define THREE_BYTE_0 NULL, NULL, IS_3BYTE_OPCODE, NULL, 0, NULL, 0, NULL, 0
487 #define THREE_BYTE_1 NULL, NULL, IS_3BYTE_OPCODE, NULL, 1, NULL, 0, NULL, 0
488
489 typedef void (*op_rtn) (int bytemode, int sizeflag);
490
491 struct dis386 {
492 const char *name;
493 op_rtn op1;
494 int bytemode1;
495 op_rtn op2;
496 int bytemode2;
497 op_rtn op3;
498 int bytemode3;
499 op_rtn op4;
500 int bytemode4;
501 };
502
503 /* Upper case letters in the instruction names here are macros.
504 'A' => print 'b' if no register operands or suffix_always is true
505 'B' => print 'b' if suffix_always is true
506 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
507 . size prefix
508 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
509 . suffix_always is true
510 'E' => print 'e' if 32-bit form of jcxz
511 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
512 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
513 'H' => print ",pt" or ",pn" branch hint
514 'I' => honor following macro letter even in Intel mode (implemented only
515 . for some of the macro letters)
516 'J' => print 'l'
517 'L' => print 'l' if suffix_always is true
518 'N' => print 'n' if instruction has no wait "prefix"
519 'O' => print 'd' or 'o' (or 'q' in Intel mode)
520 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
521 . or suffix_always is true. print 'q' if rex prefix is present.
522 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
523 . is true
524 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
525 'S' => print 'w', 'l' or 'q' if suffix_always is true
526 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
527 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
528 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
529 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
530 'X' => print 's', 'd' depending on data16 prefix (for XMM)
531 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
532 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
533
534 Many of the above letters print nothing in Intel mode. See "putop"
535 for the details.
536
537 Braces '{' and '}', and vertical bars '|', indicate alternative
538 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
539 modes. In cases where there are only two alternatives, the X86_64
540 instruction is reserved, and "(bad)" is printed.
541 */
542
543 static const struct dis386 dis386[] = {
544 /* 00 */
545 { "addB", Eb, Gb, XX, XX },
546 { "addS", Ev, Gv, XX, XX },
547 { "addB", Gb, Eb, XX, XX },
548 { "addS", Gv, Ev, XX, XX },
549 { "addB", AL, Ib, XX, XX },
550 { "addS", eAX, Iv, XX, XX },
551 { "push{T|}", es, XX, XX, XX },
552 { "pop{T|}", es, XX, XX, XX },
553 /* 08 */
554 { "orB", Eb, Gb, XX, XX },
555 { "orS", Ev, Gv, XX, XX },
556 { "orB", Gb, Eb, XX, XX },
557 { "orS", Gv, Ev, XX, XX },
558 { "orB", AL, Ib, XX, XX },
559 { "orS", eAX, Iv, XX, XX },
560 { "push{T|}", cs, XX, XX, XX },
561 { "(bad)", XX, XX, XX, XX }, /* 0x0f extended opcode escape */
562 /* 10 */
563 { "adcB", Eb, Gb, XX, XX },
564 { "adcS", Ev, Gv, XX, XX },
565 { "adcB", Gb, Eb, XX, XX },
566 { "adcS", Gv, Ev, XX, XX },
567 { "adcB", AL, Ib, XX, XX },
568 { "adcS", eAX, Iv, XX, XX },
569 { "push{T|}", ss, XX, XX, XX },
570 { "pop{T|}", ss, XX, XX, XX },
571 /* 18 */
572 { "sbbB", Eb, Gb, XX, XX },
573 { "sbbS", Ev, Gv, XX, XX },
574 { "sbbB", Gb, Eb, XX, XX },
575 { "sbbS", Gv, Ev, XX, XX },
576 { "sbbB", AL, Ib, XX, XX },
577 { "sbbS", eAX, Iv, XX, XX },
578 { "push{T|}", ds, XX, XX, XX },
579 { "pop{T|}", ds, XX, XX, XX },
580 /* 20 */
581 { "andB", Eb, Gb, XX, XX },
582 { "andS", Ev, Gv, XX, XX },
583 { "andB", Gb, Eb, XX, XX },
584 { "andS", Gv, Ev, XX, XX },
585 { "andB", AL, Ib, XX, XX },
586 { "andS", eAX, Iv, XX, XX },
587 { "(bad)", XX, XX, XX, XX }, /* SEG ES prefix */
588 { "daa{|}", XX, XX, XX, XX },
589 /* 28 */
590 { "subB", Eb, Gb, XX, XX },
591 { "subS", Ev, Gv, XX, XX },
592 { "subB", Gb, Eb, XX, XX },
593 { "subS", Gv, Ev, XX, XX },
594 { "subB", AL, Ib, XX, XX },
595 { "subS", eAX, Iv, XX, XX },
596 { "(bad)", XX, XX, XX, XX }, /* SEG CS prefix */
597 { "das{|}", XX, XX, XX, XX },
598 /* 30 */
599 { "xorB", Eb, Gb, XX, XX },
600 { "xorS", Ev, Gv, XX, XX },
601 { "xorB", Gb, Eb, XX, XX },
602 { "xorS", Gv, Ev, XX, XX },
603 { "xorB", AL, Ib, XX, XX },
604 { "xorS", eAX, Iv, XX, XX },
605 { "(bad)", XX, XX, XX, XX }, /* SEG SS prefix */
606 { "aaa{|}", XX, XX, XX, XX },
607 /* 38 */
608 { "cmpB", Eb, Gb, XX, XX },
609 { "cmpS", Ev, Gv, XX, XX },
610 { "cmpB", Gb, Eb, XX, XX },
611 { "cmpS", Gv, Ev, XX, XX },
612 { "cmpB", AL, Ib, XX, XX },
613 { "cmpS", eAX, Iv, XX, XX },
614 { "(bad)", XX, XX, XX, XX }, /* SEG DS prefix */
615 { "aas{|}", XX, XX, XX, XX },
616 /* 40 */
617 { "inc{S|}", RMeAX, XX, XX, XX },
618 { "inc{S|}", RMeCX, XX, XX, XX },
619 { "inc{S|}", RMeDX, XX, XX, XX },
620 { "inc{S|}", RMeBX, XX, XX, XX },
621 { "inc{S|}", RMeSP, XX, XX, XX },
622 { "inc{S|}", RMeBP, XX, XX, XX },
623 { "inc{S|}", RMeSI, XX, XX, XX },
624 { "inc{S|}", RMeDI, XX, XX, XX },
625 /* 48 */
626 { "dec{S|}", RMeAX, XX, XX, XX },
627 { "dec{S|}", RMeCX, XX, XX, XX },
628 { "dec{S|}", RMeDX, XX, XX, XX },
629 { "dec{S|}", RMeBX, XX, XX, XX },
630 { "dec{S|}", RMeSP, XX, XX, XX },
631 { "dec{S|}", RMeBP, XX, XX, XX },
632 { "dec{S|}", RMeSI, XX, XX, XX },
633 { "dec{S|}", RMeDI, XX, XX, XX },
634 /* 50 */
635 { "pushV", RMrAX, XX, XX, XX },
636 { "pushV", RMrCX, XX, XX, XX },
637 { "pushV", RMrDX, XX, XX, XX },
638 { "pushV", RMrBX, XX, XX, XX },
639 { "pushV", RMrSP, XX, XX, XX },
640 { "pushV", RMrBP, XX, XX, XX },
641 { "pushV", RMrSI, XX, XX, XX },
642 { "pushV", RMrDI, XX, XX, XX },
643 /* 58 */
644 { "popV", RMrAX, XX, XX, XX },
645 { "popV", RMrCX, XX, XX, XX },
646 { "popV", RMrDX, XX, XX, XX },
647 { "popV", RMrBX, XX, XX, XX },
648 { "popV", RMrSP, XX, XX, XX },
649 { "popV", RMrBP, XX, XX, XX },
650 { "popV", RMrSI, XX, XX, XX },
651 { "popV", RMrDI, XX, XX, XX },
652 /* 60 */
653 { X86_64_0 },
654 { X86_64_1 },
655 { X86_64_2 },
656 { X86_64_3 },
657 { "(bad)", XX, XX, XX, XX }, /* seg fs */
658 { "(bad)", XX, XX, XX, XX }, /* seg gs */
659 { "(bad)", XX, XX, XX, XX }, /* op size prefix */
660 { "(bad)", XX, XX, XX, XX }, /* adr size prefix */
661 /* 68 */
662 { "pushT", Iq, XX, XX, XX },
663 { "imulS", Gv, Ev, Iv, XX },
664 { "pushT", sIb, XX, XX, XX },
665 { "imulS", Gv, Ev, sIb, XX },
666 { "ins{b||b|}", Ybr, indirDX, XX, XX },
667 { "ins{R||G|}", Yzr, indirDX, XX, XX },
668 { "outs{b||b|}", indirDXr, Xb, XX, XX },
669 { "outs{R||G|}", indirDXr, Xz, XX, XX },
670 /* 70 */
671 { "joH", Jb, XX, cond_jump_flag, XX },
672 { "jnoH", Jb, XX, cond_jump_flag, XX },
673 { "jbH", Jb, XX, cond_jump_flag, XX },
674 { "jaeH", Jb, XX, cond_jump_flag, XX },
675 { "jeH", Jb, XX, cond_jump_flag, XX },
676 { "jneH", Jb, XX, cond_jump_flag, XX },
677 { "jbeH", Jb, XX, cond_jump_flag, XX },
678 { "jaH", Jb, XX, cond_jump_flag, XX },
679 /* 78 */
680 { "jsH", Jb, XX, cond_jump_flag, XX },
681 { "jnsH", Jb, XX, cond_jump_flag, XX },
682 { "jpH", Jb, XX, cond_jump_flag, XX },
683 { "jnpH", Jb, XX, cond_jump_flag, XX },
684 { "jlH", Jb, XX, cond_jump_flag, XX },
685 { "jgeH", Jb, XX, cond_jump_flag, XX },
686 { "jleH", Jb, XX, cond_jump_flag, XX },
687 { "jgH", Jb, XX, cond_jump_flag, XX },
688 /* 80 */
689 { GRP1b },
690 { GRP1S },
691 { "(bad)", XX, XX, XX, XX },
692 { GRP1Ss },
693 { "testB", Eb, Gb, XX, XX },
694 { "testS", Ev, Gv, XX, XX },
695 { "xchgB", Eb, Gb, XX, XX },
696 { "xchgS", Ev, Gv, XX, XX },
697 /* 88 */
698 { "movB", Eb, Gb, XX, XX },
699 { "movS", Ev, Gv, XX, XX },
700 { "movB", Gb, Eb, XX, XX },
701 { "movS", Gv, Ev, XX, XX },
702 { "movD", Sv, Sw, XX, XX },
703 { "leaS", Gv, M, XX, XX },
704 { "movD", Sw, Sv, XX, XX },
705 { "popU", stackEv, XX, XX, XX },
706 /* 90 */
707 { "xchgS", NOP_Fixup1, eAX_reg, NOP_Fixup2, eAX_reg, XX, XX },
708 { "xchgS", RMeCX, eAX, XX, XX },
709 { "xchgS", RMeDX, eAX, XX, XX },
710 { "xchgS", RMeBX, eAX, XX, XX },
711 { "xchgS", RMeSP, eAX, XX, XX },
712 { "xchgS", RMeBP, eAX, XX, XX },
713 { "xchgS", RMeSI, eAX, XX, XX },
714 { "xchgS", RMeDI, eAX, XX, XX },
715 /* 98 */
716 { "cW{t||t|}R", XX, XX, XX, XX },
717 { "cR{t||t|}O", XX, XX, XX, XX },
718 { "Jcall{T|}", Ap, XX, XX, XX },
719 { "(bad)", XX, XX, XX, XX }, /* fwait */
720 { "pushfT", XX, XX, XX, XX },
721 { "popfT", XX, XX, XX, XX },
722 { "sahf{|}", XX, XX, XX, XX },
723 { "lahf{|}", XX, XX, XX, XX },
724 /* a0 */
725 { "movB", AL, Ob, XX, XX },
726 { "movS", eAX, Ov, XX, XX },
727 { "movB", Ob, AL, XX, XX },
728 { "movS", Ov, eAX, XX, XX },
729 { "movs{b||b|}", Ybr, Xb, XX, XX },
730 { "movs{R||R|}", Yvr, Xv, XX, XX },
731 { "cmps{b||b|}", Xb, Yb, XX, XX },
732 { "cmps{R||R|}", Xv, Yv, XX, XX },
733 /* a8 */
734 { "testB", AL, Ib, XX, XX },
735 { "testS", eAX, Iv, XX, XX },
736 { "stosB", Ybr, AL, XX, XX },
737 { "stosS", Yvr, eAX, XX, XX },
738 { "lodsB", ALr, Xb, XX, XX },
739 { "lodsS", eAXr, Xv, XX, XX },
740 { "scasB", AL, Yb, XX, XX },
741 { "scasS", eAX, Yv, XX, XX },
742 /* b0 */
743 { "movB", RMAL, Ib, XX, XX },
744 { "movB", RMCL, Ib, XX, XX },
745 { "movB", RMDL, Ib, XX, XX },
746 { "movB", RMBL, Ib, XX, XX },
747 { "movB", RMAH, Ib, XX, XX },
748 { "movB", RMCH, Ib, XX, XX },
749 { "movB", RMDH, Ib, XX, XX },
750 { "movB", RMBH, Ib, XX, XX },
751 /* b8 */
752 { "movS", RMeAX, Iv64, XX, XX },
753 { "movS", RMeCX, Iv64, XX, XX },
754 { "movS", RMeDX, Iv64, XX, XX },
755 { "movS", RMeBX, Iv64, XX, XX },
756 { "movS", RMeSP, Iv64, XX, XX },
757 { "movS", RMeBP, Iv64, XX, XX },
758 { "movS", RMeSI, Iv64, XX, XX },
759 { "movS", RMeDI, Iv64, XX, XX },
760 /* c0 */
761 { GRP2b },
762 { GRP2S },
763 { "retT", Iw, XX, XX, XX },
764 { "retT", XX, XX, XX, XX },
765 { "les{S|}", Gv, Mp, XX, XX },
766 { "ldsS", Gv, Mp, XX, XX },
767 { GRP11_C6 },
768 { GRP11_C7 },
769 /* c8 */
770 { "enterT", Iw, Ib, XX, XX },
771 { "leaveT", XX, XX, XX, XX },
772 { "lretP", Iw, XX, XX, XX },
773 { "lretP", XX, XX, XX, XX },
774 { "int3", XX, XX, XX, XX },
775 { "int", Ib, XX, XX, XX },
776 { "into{|}", XX, XX, XX, XX },
777 { "iretP", XX, XX, XX, XX },
778 /* d0 */
779 { GRP2b_one },
780 { GRP2S_one },
781 { GRP2b_cl },
782 { GRP2S_cl },
783 { "aam{|}", sIb, XX, XX, XX },
784 { "aad{|}", sIb, XX, XX, XX },
785 { "(bad)", XX, XX, XX, XX },
786 { "xlat", DSBX, XX, XX, XX },
787 /* d8 */
788 { FLOAT },
789 { FLOAT },
790 { FLOAT },
791 { FLOAT },
792 { FLOAT },
793 { FLOAT },
794 { FLOAT },
795 { FLOAT },
796 /* e0 */
797 { "loopneFH", Jb, XX, loop_jcxz_flag, XX },
798 { "loopeFH", Jb, XX, loop_jcxz_flag, XX },
799 { "loopFH", Jb, XX, loop_jcxz_flag, XX },
800 { "jEcxzH", Jb, XX, loop_jcxz_flag, XX },
801 { "inB", AL, Ib, XX, XX },
802 { "inG", zAX, Ib, XX, XX },
803 { "outB", Ib, AL, XX, XX },
804 { "outG", Ib, zAX, XX, XX },
805 /* e8 */
806 { "callT", Jv, XX, XX, XX },
807 { "jmpT", Jv, XX, XX, XX },
808 { "Jjmp{T|}", Ap, XX, XX, XX },
809 { "jmp", Jb, XX, XX, XX },
810 { "inB", AL, indirDX, XX, XX },
811 { "inG", zAX, indirDX, XX, XX },
812 { "outB", indirDX, AL, XX, XX },
813 { "outG", indirDX, zAX, XX, XX },
814 /* f0 */
815 { "(bad)", XX, XX, XX, XX }, /* lock prefix */
816 { "icebp", XX, XX, XX, XX },
817 { "(bad)", XX, XX, XX, XX }, /* repne */
818 { "(bad)", XX, XX, XX, XX }, /* repz */
819 { "hlt", XX, XX, XX, XX },
820 { "cmc", XX, XX, XX, XX },
821 { GRP3b },
822 { GRP3S },
823 /* f8 */
824 { "clc", XX, XX, XX, XX },
825 { "stc", XX, XX, XX, XX },
826 { "cli", XX, XX, XX, XX },
827 { "sti", XX, XX, XX, XX },
828 { "cld", XX, XX, XX, XX },
829 { "std", XX, XX, XX, XX },
830 { GRP4 },
831 { GRP5 },
832 };
833
834 static const struct dis386 dis386_twobyte[] = {
835 /* 00 */
836 { GRP6 },
837 { GRP7 },
838 { "larS", Gv, Ew, XX, XX },
839 { "lslS", Gv, Ew, XX, XX },
840 { "(bad)", XX, XX, XX, XX },
841 { "syscall", XX, XX, XX, XX },
842 { "clts", XX, XX, XX, XX },
843 { "sysretP", XX, XX, XX, XX },
844 /* 08 */
845 { "invd", XX, XX, XX, XX },
846 { "wbinvd", XX, XX, XX, XX },
847 { "(bad)", XX, XX, XX, XX },
848 { "ud2a", XX, XX, XX, XX },
849 { "(bad)", XX, XX, XX, XX },
850 { GRPAMD },
851 { "femms", XX, XX, XX, XX },
852 { "", MX, EM, OPSUF, XX }, /* See OP_3DNowSuffix. */
853 /* 10 */
854 { PREGRP8 },
855 { PREGRP9 },
856 { PREGRP30 },
857 { "movlpX", EX, XM, SIMD_Fixup, 'h', XX },
858 { "unpcklpX", XM, EX, XX, XX },
859 { "unpckhpX", XM, EX, XX, XX },
860 { PREGRP31 },
861 { "movhpX", EX, XM, SIMD_Fixup, 'l', XX },
862 /* 18 */
863 { GRP16 },
864 { "(bad)", XX, XX, XX, XX },
865 { "(bad)", XX, XX, XX, XX },
866 { "(bad)", XX, XX, XX, XX },
867 { "(bad)", XX, XX, XX, XX },
868 { "(bad)", XX, XX, XX, XX },
869 { "(bad)", XX, XX, XX, XX },
870 { "nopQ", Ev, XX, XX, XX },
871 /* 20 */
872 { "movZ", Rm, Cm, XX, XX },
873 { "movZ", Rm, Dm, XX, XX },
874 { "movZ", Cm, Rm, XX, XX },
875 { "movZ", Dm, Rm, XX, XX },
876 { "movL", Rd, Td, XX, XX },
877 { "(bad)", XX, XX, XX, XX },
878 { "movL", Td, Rd, XX, XX },
879 { "(bad)", XX, XX, XX, XX },
880 /* 28 */
881 { "movapX", XM, EX, XX, XX },
882 { "movapX", EX, XM, XX, XX },
883 { PREGRP2 },
884 { PREGRP33 },
885 { PREGRP4 },
886 { PREGRP3 },
887 { "ucomisX", XM,EX, XX, XX },
888 { "comisX", XM,EX, XX, XX },
889 /* 30 */
890 { "wrmsr", XX, XX, XX, XX },
891 { "rdtsc", XX, XX, XX, XX },
892 { "rdmsr", XX, XX, XX, XX },
893 { "rdpmc", XX, XX, XX, XX },
894 { "sysenter", XX, XX, XX, XX },
895 { "sysexit", XX, XX, XX, XX },
896 { "(bad)", XX, XX, XX, XX },
897 { "(bad)", XX, XX, XX, XX },
898 /* 38 */
899 { THREE_BYTE_0 },
900 { "(bad)", XX, XX, XX, XX },
901 { THREE_BYTE_1 },
902 { "(bad)", XX, XX, XX, XX },
903 { "(bad)", XX, XX, XX, XX },
904 { "(bad)", XX, XX, XX, XX },
905 { "(bad)", XX, XX, XX, XX },
906 { "(bad)", XX, XX, XX, XX },
907 /* 40 */
908 { "cmovo", Gv, Ev, XX, XX },
909 { "cmovno", Gv, Ev, XX, XX },
910 { "cmovb", Gv, Ev, XX, XX },
911 { "cmovae", Gv, Ev, XX, XX },
912 { "cmove", Gv, Ev, XX, XX },
913 { "cmovne", Gv, Ev, XX, XX },
914 { "cmovbe", Gv, Ev, XX, XX },
915 { "cmova", Gv, Ev, XX, XX },
916 /* 48 */
917 { "cmovs", Gv, Ev, XX, XX },
918 { "cmovns", Gv, Ev, XX, XX },
919 { "cmovp", Gv, Ev, XX, XX },
920 { "cmovnp", Gv, Ev, XX, XX },
921 { "cmovl", Gv, Ev, XX, XX },
922 { "cmovge", Gv, Ev, XX, XX },
923 { "cmovle", Gv, Ev, XX, XX },
924 { "cmovg", Gv, Ev, XX, XX },
925 /* 50 */
926 { "movmskpX", Gdq, XS, XX, XX },
927 { PREGRP13 },
928 { PREGRP12 },
929 { PREGRP11 },
930 { "andpX", XM, EX, XX, XX },
931 { "andnpX", XM, EX, XX, XX },
932 { "orpX", XM, EX, XX, XX },
933 { "xorpX", XM, EX, XX, XX },
934 /* 58 */
935 { PREGRP0 },
936 { PREGRP10 },
937 { PREGRP17 },
938 { PREGRP16 },
939 { PREGRP14 },
940 { PREGRP7 },
941 { PREGRP5 },
942 { PREGRP6 },
943 /* 60 */
944 { "punpcklbw", MX, EM, XX, XX },
945 { "punpcklwd", MX, EM, XX, XX },
946 { "punpckldq", MX, EM, XX, XX },
947 { "packsswb", MX, EM, XX, XX },
948 { "pcmpgtb", MX, EM, XX, XX },
949 { "pcmpgtw", MX, EM, XX, XX },
950 { "pcmpgtd", MX, EM, XX, XX },
951 { "packuswb", MX, EM, XX, XX },
952 /* 68 */
953 { "punpckhbw", MX, EM, XX, XX },
954 { "punpckhwd", MX, EM, XX, XX },
955 { "punpckhdq", MX, EM, XX, XX },
956 { "packssdw", MX, EM, XX, XX },
957 { PREGRP26 },
958 { PREGRP24 },
959 { "movd", MX, Edq, XX, XX },
960 { PREGRP19 },
961 /* 70 */
962 { PREGRP22 },
963 { GRP12 },
964 { GRP13 },
965 { GRP14 },
966 { "pcmpeqb", MX, EM, XX, XX },
967 { "pcmpeqw", MX, EM, XX, XX },
968 { "pcmpeqd", MX, EM, XX, XX },
969 { "emms", XX, XX, XX, XX },
970 /* 78 */
971 { PREGRP34 },
972 { PREGRP35 },
973 { "(bad)", XX, XX, XX, XX },
974 { "(bad)", XX, XX, XX, XX },
975 { PREGRP28 },
976 { PREGRP29 },
977 { PREGRP23 },
978 { PREGRP20 },
979 /* 80 */
980 { "joH", Jv, XX, cond_jump_flag, XX },
981 { "jnoH", Jv, XX, cond_jump_flag, XX },
982 { "jbH", Jv, XX, cond_jump_flag, XX },
983 { "jaeH", Jv, XX, cond_jump_flag, XX },
984 { "jeH", Jv, XX, cond_jump_flag, XX },
985 { "jneH", Jv, XX, cond_jump_flag, XX },
986 { "jbeH", Jv, XX, cond_jump_flag, XX },
987 { "jaH", Jv, XX, cond_jump_flag, XX },
988 /* 88 */
989 { "jsH", Jv, XX, cond_jump_flag, XX },
990 { "jnsH", Jv, XX, cond_jump_flag, XX },
991 { "jpH", Jv, XX, cond_jump_flag, XX },
992 { "jnpH", Jv, XX, cond_jump_flag, XX },
993 { "jlH", Jv, XX, cond_jump_flag, XX },
994 { "jgeH", Jv, XX, cond_jump_flag, XX },
995 { "jleH", Jv, XX, cond_jump_flag, XX },
996 { "jgH", Jv, XX, cond_jump_flag, XX },
997 /* 90 */
998 { "seto", Eb, XX, XX, XX },
999 { "setno", Eb, XX, XX, XX },
1000 { "setb", Eb, XX, XX, XX },
1001 { "setae", Eb, XX, XX, XX },
1002 { "sete", Eb, XX, XX, XX },
1003 { "setne", Eb, XX, XX, XX },
1004 { "setbe", Eb, XX, XX, XX },
1005 { "seta", Eb, XX, XX, XX },
1006 /* 98 */
1007 { "sets", Eb, XX, XX, XX },
1008 { "setns", Eb, XX, XX, XX },
1009 { "setp", Eb, XX, XX, XX },
1010 { "setnp", Eb, XX, XX, XX },
1011 { "setl", Eb, XX, XX, XX },
1012 { "setge", Eb, XX, XX, XX },
1013 { "setle", Eb, XX, XX, XX },
1014 { "setg", Eb, XX, XX, XX },
1015 /* a0 */
1016 { "pushT", fs, XX, XX, XX },
1017 { "popT", fs, XX, XX, XX },
1018 { "cpuid", XX, XX, XX, XX },
1019 { "btS", Ev, Gv, XX, XX },
1020 { "shldS", Ev, Gv, Ib, XX },
1021 { "shldS", Ev, Gv, CL, XX },
1022 { GRPPADLCK2 },
1023 { GRPPADLCK1 },
1024 /* a8 */
1025 { "pushT", gs, XX, XX, XX },
1026 { "popT", gs, XX, XX, XX },
1027 { "rsm", XX, XX, XX, XX },
1028 { "btsS", Ev, Gv, XX, XX },
1029 { "shrdS", Ev, Gv, Ib, XX },
1030 { "shrdS", Ev, Gv, CL, XX },
1031 { GRP15 },
1032 { "imulS", Gv, Ev, XX, XX },
1033 /* b0 */
1034 { "cmpxchgB", Eb, Gb, XX, XX },
1035 { "cmpxchgS", Ev, Gv, XX, XX },
1036 { "lssS", Gv, Mp, XX, XX },
1037 { "btrS", Ev, Gv, XX, XX },
1038 { "lfsS", Gv, Mp, XX, XX },
1039 { "lgsS", Gv, Mp, XX, XX },
1040 { "movz{bR|x|bR|x}", Gv, Eb, XX, XX },
1041 { "movz{wR|x|wR|x}", Gv, Ew, XX, XX }, /* yes, there really is movzww ! */
1042 /* b8 */
1043 { PREGRP37 },
1044 { "ud2b", XX, XX, XX, XX },
1045 { GRP8 },
1046 { "btcS", Ev, Gv, XX, XX },
1047 { "bsfS", Gv, Ev, XX, XX },
1048 { PREGRP36 },
1049 { "movs{bR|x|bR|x}", Gv, Eb, XX, XX },
1050 { "movs{wR|x|wR|x}", Gv, Ew, XX, XX }, /* yes, there really is movsww ! */
1051 /* c0 */
1052 { "xaddB", Eb, Gb, XX, XX },
1053 { "xaddS", Ev, Gv, XX, XX },
1054 { PREGRP1 },
1055 { "movntiS", Ev, Gv, XX, XX },
1056 { "pinsrw", MX, Edqw, Ib, XX },
1057 { "pextrw", Gdq, MS, Ib, XX },
1058 { "shufpX", XM, EX, Ib, XX },
1059 { GRP9 },
1060 /* c8 */
1061 { "bswap", RMeAX, XX, XX, XX },
1062 { "bswap", RMeCX, XX, XX, XX },
1063 { "bswap", RMeDX, XX, XX, XX },
1064 { "bswap", RMeBX, XX, XX, XX },
1065 { "bswap", RMeSP, XX, XX, XX },
1066 { "bswap", RMeBP, XX, XX, XX },
1067 { "bswap", RMeSI, XX, XX, XX },
1068 { "bswap", RMeDI, XX, XX, XX },
1069 /* d0 */
1070 { PREGRP27 },
1071 { "psrlw", MX, EM, XX, XX },
1072 { "psrld", MX, EM, XX, XX },
1073 { "psrlq", MX, EM, XX, XX },
1074 { "paddq", MX, EM, XX, XX },
1075 { "pmullw", MX, EM, XX, XX },
1076 { PREGRP21 },
1077 { "pmovmskb", Gdq, MS, XX, XX },
1078 /* d8 */
1079 { "psubusb", MX, EM, XX, XX },
1080 { "psubusw", MX, EM, XX, XX },
1081 { "pminub", MX, EM, XX, XX },
1082 { "pand", MX, EM, XX, XX },
1083 { "paddusb", MX, EM, XX, XX },
1084 { "paddusw", MX, EM, XX, XX },
1085 { "pmaxub", MX, EM, XX, XX },
1086 { "pandn", MX, EM, XX, XX },
1087 /* e0 */
1088 { "pavgb", MX, EM, XX, XX },
1089 { "psraw", MX, EM, XX, XX },
1090 { "psrad", MX, EM, XX, XX },
1091 { "pavgw", MX, EM, XX, XX },
1092 { "pmulhuw", MX, EM, XX, XX },
1093 { "pmulhw", MX, EM, XX, XX },
1094 { PREGRP15 },
1095 { PREGRP25 },
1096 /* e8 */
1097 { "psubsb", MX, EM, XX, XX },
1098 { "psubsw", MX, EM, XX, XX },
1099 { "pminsw", MX, EM, XX, XX },
1100 { "por", MX, EM, XX, XX },
1101 { "paddsb", MX, EM, XX, XX },
1102 { "paddsw", MX, EM, XX, XX },
1103 { "pmaxsw", MX, EM, XX, XX },
1104 { "pxor", MX, EM, XX, XX },
1105 /* f0 */
1106 { PREGRP32 },
1107 { "psllw", MX, EM, XX, XX },
1108 { "pslld", MX, EM, XX, XX },
1109 { "psllq", MX, EM, XX, XX },
1110 { "pmuludq", MX, EM, XX, XX },
1111 { "pmaddwd", MX, EM, XX, XX },
1112 { "psadbw", MX, EM, XX, XX },
1113 { PREGRP18 },
1114 /* f8 */
1115 { "psubb", MX, EM, XX, XX },
1116 { "psubw", MX, EM, XX, XX },
1117 { "psubd", MX, EM, XX, XX },
1118 { "psubq", MX, EM, XX, XX },
1119 { "paddb", MX, EM, XX, XX },
1120 { "paddw", MX, EM, XX, XX },
1121 { "paddd", MX, EM, XX, XX },
1122 { "(bad)", XX, XX, XX, XX }
1123 };
1124
1125 static const unsigned char onebyte_has_modrm[256] = {
1126 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1127 /* ------------------------------- */
1128 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1129 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1130 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1131 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1132 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1133 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1134 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1135 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1136 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1137 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1138 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1139 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1140 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1141 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1142 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1143 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1144 /* ------------------------------- */
1145 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1146 };
1147
1148 static const unsigned char twobyte_has_modrm[256] = {
1149 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1150 /* ------------------------------- */
1151 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1152 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1153 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1154 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1155 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1156 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1157 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1158 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1159 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1160 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1161 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1162 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1163 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1164 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1165 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1166 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1167 /* ------------------------------- */
1168 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1169 };
1170
1171 static const unsigned char twobyte_uses_DATA_prefix[256] = {
1172 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1173 /* ------------------------------- */
1174 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1175 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1176 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1177 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1178 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1179 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1180 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1181 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
1182 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1183 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1184 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1185 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1186 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1187 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1188 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1189 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1190 /* ------------------------------- */
1191 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1192 };
1193
1194 static const unsigned char twobyte_uses_REPNZ_prefix[256] = {
1195 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1196 /* ------------------------------- */
1197 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1198 /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1199 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1200 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1201 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1202 /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1203 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1204 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1205 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1206 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1207 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1208 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1209 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1210 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1211 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1212 /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1213 /* ------------------------------- */
1214 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1215 };
1216
1217 static const unsigned char twobyte_uses_REPZ_prefix[256] = {
1218 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1219 /* ------------------------------- */
1220 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1221 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1222 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1223 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1224 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1225 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1226 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1227 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1228 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1229 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1230 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1231 /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1232 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1233 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1234 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1235 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1236 /* ------------------------------- */
1237 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1238 };
1239
1240 /* This is used to determine if opcode 0f 38 XX uses DATA prefix. */
1241 static const unsigned char threebyte_0x38_uses_DATA_prefix[256] = {
1242 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1243 /* ------------------------------- */
1244 /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1245 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0, /* 1f */
1246 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1247 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1248 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1249 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1250 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1251 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1252 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1253 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1254 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1255 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1256 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1257 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1258 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1259 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1260 /* ------------------------------- */
1261 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1262 };
1263
1264 /* This is used to determine if opcode 0f 38 XX uses REPNZ prefix. */
1265 static const unsigned char threebyte_0x38_uses_REPNZ_prefix[256] = {
1266 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1267 /* ------------------------------- */
1268 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1269 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1270 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1271 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1272 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1273 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1274 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1275 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1276 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1277 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1278 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1279 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1280 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1281 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1282 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1283 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1284 /* ------------------------------- */
1285 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1286 };
1287
1288 /* This is used to determine if opcode 0f 38 XX uses REPZ prefix. */
1289 static const unsigned char threebyte_0x38_uses_REPZ_prefix[256] = {
1290 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1291 /* ------------------------------- */
1292 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1293 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1294 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1295 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1296 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1297 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1298 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1299 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1300 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1301 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1302 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1303 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1304 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1305 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1306 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1307 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1308 /* ------------------------------- */
1309 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1310 };
1311
1312 /* This is used to determine if opcode 0f 3a XX uses DATA prefix. */
1313 static const unsigned char threebyte_0x3a_uses_DATA_prefix[256] = {
1314 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1315 /* ------------------------------- */
1316 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 0f */
1317 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1318 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1319 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1320 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1321 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1322 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1323 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1324 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1325 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1326 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1327 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1328 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1329 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1330 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1331 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1332 /* ------------------------------- */
1333 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1334 };
1335
1336 /* This is used to determine if opcode 0f 3a XX uses REPNZ prefix. */
1337 static const unsigned char threebyte_0x3a_uses_REPNZ_prefix[256] = {
1338 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1339 /* ------------------------------- */
1340 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1341 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1342 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1343 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1344 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1345 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1346 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1347 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1348 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1349 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1350 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1351 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1352 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1353 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1354 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1355 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1356 /* ------------------------------- */
1357 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1358 };
1359
1360 /* This is used to determine if opcode 0f 3a XX uses REPZ prefix. */
1361 static const unsigned char threebyte_0x3a_uses_REPZ_prefix[256] = {
1362 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1363 /* ------------------------------- */
1364 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1365 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1366 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1367 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1368 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1369 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1370 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1371 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1372 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1373 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1374 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1375 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1376 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1377 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1378 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1379 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1380 /* ------------------------------- */
1381 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1382 };
1383
1384 static char obuf[100];
1385 static char *obufp;
1386 static char scratchbuf[100];
1387 static unsigned char *start_codep;
1388 static unsigned char *insn_codep;
1389 static unsigned char *codep;
1390 static disassemble_info *the_info;
1391 static int mod;
1392 static int rm;
1393 static int reg;
1394 static unsigned char need_modrm;
1395
1396 /* If we are accessing mod/rm/reg without need_modrm set, then the
1397 values are stale. Hitting this abort likely indicates that you
1398 need to update onebyte_has_modrm or twobyte_has_modrm. */
1399 #define MODRM_CHECK if (!need_modrm) abort ()
1400
1401 static const char **names64;
1402 static const char **names32;
1403 static const char **names16;
1404 static const char **names8;
1405 static const char **names8rex;
1406 static const char **names_seg;
1407 static const char **index16;
1408
1409 static const char *intel_names64[] = {
1410 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1411 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1412 };
1413 static const char *intel_names32[] = {
1414 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1415 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1416 };
1417 static const char *intel_names16[] = {
1418 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1419 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1420 };
1421 static const char *intel_names8[] = {
1422 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1423 };
1424 static const char *intel_names8rex[] = {
1425 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1426 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1427 };
1428 static const char *intel_names_seg[] = {
1429 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1430 };
1431 static const char *intel_index16[] = {
1432 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1433 };
1434
1435 static const char *att_names64[] = {
1436 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1437 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1438 };
1439 static const char *att_names32[] = {
1440 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1441 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1442 };
1443 static const char *att_names16[] = {
1444 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1445 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1446 };
1447 static const char *att_names8[] = {
1448 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1449 };
1450 static const char *att_names8rex[] = {
1451 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1452 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1453 };
1454 static const char *att_names_seg[] = {
1455 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1456 };
1457 static const char *att_index16[] = {
1458 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1459 };
1460
1461 static const struct dis386 grps[][8] = {
1462 /* GRP1b */
1463 {
1464 { "addA", Eb, Ib, XX, XX },
1465 { "orA", Eb, Ib, XX, XX },
1466 { "adcA", Eb, Ib, XX, XX },
1467 { "sbbA", Eb, Ib, XX, XX },
1468 { "andA", Eb, Ib, XX, XX },
1469 { "subA", Eb, Ib, XX, XX },
1470 { "xorA", Eb, Ib, XX, XX },
1471 { "cmpA", Eb, Ib, XX, XX }
1472 },
1473 /* GRP1S */
1474 {
1475 { "addQ", Ev, Iv, XX, XX },
1476 { "orQ", Ev, Iv, XX, XX },
1477 { "adcQ", Ev, Iv, XX, XX },
1478 { "sbbQ", Ev, Iv, XX, XX },
1479 { "andQ", Ev, Iv, XX, XX },
1480 { "subQ", Ev, Iv, XX, XX },
1481 { "xorQ", Ev, Iv, XX, XX },
1482 { "cmpQ", Ev, Iv, XX, XX }
1483 },
1484 /* GRP1Ss */
1485 {
1486 { "addQ", Ev, sIb, XX, XX },
1487 { "orQ", Ev, sIb, XX, XX },
1488 { "adcQ", Ev, sIb, XX, XX },
1489 { "sbbQ", Ev, sIb, XX, XX },
1490 { "andQ", Ev, sIb, XX, XX },
1491 { "subQ", Ev, sIb, XX, XX },
1492 { "xorQ", Ev, sIb, XX, XX },
1493 { "cmpQ", Ev, sIb, XX, XX }
1494 },
1495 /* GRP2b */
1496 {
1497 { "rolA", Eb, Ib, XX, XX },
1498 { "rorA", Eb, Ib, XX, XX },
1499 { "rclA", Eb, Ib, XX, XX },
1500 { "rcrA", Eb, Ib, XX, XX },
1501 { "shlA", Eb, Ib, XX, XX },
1502 { "shrA", Eb, Ib, XX, XX },
1503 { "(bad)", XX, XX, XX, XX },
1504 { "sarA", Eb, Ib, XX, XX },
1505 },
1506 /* GRP2S */
1507 {
1508 { "rolQ", Ev, Ib, XX, XX },
1509 { "rorQ", Ev, Ib, XX, XX },
1510 { "rclQ", Ev, Ib, XX, XX },
1511 { "rcrQ", Ev, Ib, XX, XX },
1512 { "shlQ", Ev, Ib, XX, XX },
1513 { "shrQ", Ev, Ib, XX, XX },
1514 { "(bad)", XX, XX, XX, XX },
1515 { "sarQ", Ev, Ib, XX, XX },
1516 },
1517 /* GRP2b_one */
1518 {
1519 { "rolA", Eb, I1, XX, XX },
1520 { "rorA", Eb, I1, XX, XX },
1521 { "rclA", Eb, I1, XX, XX },
1522 { "rcrA", Eb, I1, XX, XX },
1523 { "shlA", Eb, I1, XX, XX },
1524 { "shrA", Eb, I1, XX, XX },
1525 { "(bad)", XX, XX, XX, XX },
1526 { "sarA", Eb, I1, XX, XX },
1527 },
1528 /* GRP2S_one */
1529 {
1530 { "rolQ", Ev, I1, XX, XX },
1531 { "rorQ", Ev, I1, XX, XX },
1532 { "rclQ", Ev, I1, XX, XX },
1533 { "rcrQ", Ev, I1, XX, XX },
1534 { "shlQ", Ev, I1, XX, XX },
1535 { "shrQ", Ev, I1, XX, XX },
1536 { "(bad)", XX, XX, XX, XX },
1537 { "sarQ", Ev, I1, XX, XX },
1538 },
1539 /* GRP2b_cl */
1540 {
1541 { "rolA", Eb, CL, XX, XX },
1542 { "rorA", Eb, CL, XX, XX },
1543 { "rclA", Eb, CL, XX, XX },
1544 { "rcrA", Eb, CL, XX, XX },
1545 { "shlA", Eb, CL, XX, XX },
1546 { "shrA", Eb, CL, XX, XX },
1547 { "(bad)", XX, XX, XX, XX },
1548 { "sarA", Eb, CL, XX, XX },
1549 },
1550 /* GRP2S_cl */
1551 {
1552 { "rolQ", Ev, CL, XX, XX },
1553 { "rorQ", Ev, CL, XX, XX },
1554 { "rclQ", Ev, CL, XX, XX },
1555 { "rcrQ", Ev, CL, XX, XX },
1556 { "shlQ", Ev, CL, XX, XX },
1557 { "shrQ", Ev, CL, XX, XX },
1558 { "(bad)", XX, XX, XX, XX },
1559 { "sarQ", Ev, CL, XX, XX }
1560 },
1561 /* GRP3b */
1562 {
1563 { "testA", Eb, Ib, XX, XX },
1564 { "(bad)", Eb, XX, XX, XX },
1565 { "notA", Eb, XX, XX, XX },
1566 { "negA", Eb, XX, XX, XX },
1567 { "mulA", Eb, XX, XX, XX }, /* Don't print the implicit %al register, */
1568 { "imulA", Eb, XX, XX, XX }, /* to distinguish these opcodes from other */
1569 { "divA", Eb, XX, XX, XX }, /* mul/imul opcodes. Do the same for div */
1570 { "idivA", Eb, XX, XX, XX } /* and idiv for consistency. */
1571 },
1572 /* GRP3S */
1573 {
1574 { "testQ", Ev, Iv, XX, XX },
1575 { "(bad)", XX, XX, XX, XX },
1576 { "notQ", Ev, XX, XX, XX },
1577 { "negQ", Ev, XX, XX, XX },
1578 { "mulQ", Ev, XX, XX, XX }, /* Don't print the implicit register. */
1579 { "imulQ", Ev, XX, XX, XX },
1580 { "divQ", Ev, XX, XX, XX },
1581 { "idivQ", Ev, XX, XX, XX },
1582 },
1583 /* GRP4 */
1584 {
1585 { "incA", Eb, XX, XX, XX },
1586 { "decA", Eb, XX, XX, XX },
1587 { "(bad)", XX, XX, XX, XX },
1588 { "(bad)", XX, XX, XX, XX },
1589 { "(bad)", XX, XX, XX, XX },
1590 { "(bad)", XX, XX, XX, XX },
1591 { "(bad)", XX, XX, XX, XX },
1592 { "(bad)", XX, XX, XX, XX },
1593 },
1594 /* GRP5 */
1595 {
1596 { "incQ", Ev, XX, XX, XX },
1597 { "decQ", Ev, XX, XX, XX },
1598 { "callT", indirEv, XX, XX, XX },
1599 { "JcallT", indirEp, XX, XX, XX },
1600 { "jmpT", indirEv, XX, XX, XX },
1601 { "JjmpT", indirEp, XX, XX, XX },
1602 { "pushU", stackEv, XX, XX, XX },
1603 { "(bad)", XX, XX, XX, XX },
1604 },
1605 /* GRP6 */
1606 {
1607 { "sldtD", Sv, XX, XX, XX },
1608 { "strD", Sv, XX, XX, XX },
1609 { "lldt", Ew, XX, XX, XX },
1610 { "ltr", Ew, XX, XX, XX },
1611 { "verr", Ew, XX, XX, XX },
1612 { "verw", Ew, XX, XX, XX },
1613 { "(bad)", XX, XX, XX, XX },
1614 { "(bad)", XX, XX, XX, XX }
1615 },
1616 /* GRP7 */
1617 {
1618 { "sgdt{Q|IQ||}", VMX_Fixup, 0, XX, XX, XX },
1619 { "sidt{Q|IQ||}", PNI_Fixup, 0, XX, XX, XX },
1620 { "lgdt{Q|Q||}", M, XX, XX, XX },
1621 { "lidt{Q|Q||}", SVME_Fixup, 0, XX, XX, XX },
1622 { "smswD", Sv, XX, XX, XX },
1623 { "(bad)", XX, XX, XX, XX },
1624 { "lmsw", Ew, XX, XX, XX },
1625 { "invlpg", INVLPG_Fixup, w_mode, XX, XX, XX },
1626 },
1627 /* GRP8 */
1628 {
1629 { "(bad)", XX, XX, XX, XX },
1630 { "(bad)", XX, XX, XX, XX },
1631 { "(bad)", XX, XX, XX, XX },
1632 { "(bad)", XX, XX, XX, XX },
1633 { "btQ", Ev, Ib, XX, XX },
1634 { "btsQ", Ev, Ib, XX, XX },
1635 { "btrQ", Ev, Ib, XX, XX },
1636 { "btcQ", Ev, Ib, XX, XX },
1637 },
1638 /* GRP9 */
1639 {
1640 { "(bad)", XX, XX, XX, XX },
1641 { "cmpxchg8b", Mq, XX, XX, XX },
1642 { "(bad)", XX, XX, XX, XX },
1643 { "(bad)", XX, XX, XX, XX },
1644 { "(bad)", XX, XX, XX, XX },
1645 { "(bad)", XX, XX, XX, XX },
1646 { "", VM, XX, XX, XX }, /* See OP_VMX. */
1647 { "vmptrst", Mq, XX, XX, XX },
1648 },
1649 /* GRP11_C6 */
1650 {
1651 { "movA", Eb, Ib, XX, XX },
1652 { "(bad)", XX, XX, XX, XX },
1653 { "(bad)", XX, XX, XX, XX },
1654 { "(bad)", XX, XX, XX, XX },
1655 { "(bad)", XX, XX, XX, XX },
1656 { "(bad)", XX, XX, XX, XX },
1657 { "(bad)", XX, XX, XX, XX },
1658 { "(bad)", XX, XX, XX, XX },
1659 },
1660 /* GRP11_C7 */
1661 {
1662 { "movQ", Ev, Iv, XX, XX },
1663 { "(bad)", XX, XX, XX, XX },
1664 { "(bad)", XX, XX, XX, XX },
1665 { "(bad)", XX, XX, XX, XX },
1666 { "(bad)", XX, XX, XX, XX },
1667 { "(bad)", XX, XX, XX, XX },
1668 { "(bad)", XX, XX, XX, XX },
1669 { "(bad)", XX, XX, XX, XX },
1670 },
1671 /* GRP12 */
1672 {
1673 { "(bad)", XX, XX, XX, XX },
1674 { "(bad)", XX, XX, XX, XX },
1675 { "psrlw", MS, Ib, XX, XX },
1676 { "(bad)", XX, XX, XX, XX },
1677 { "psraw", MS, Ib, XX, XX },
1678 { "(bad)", XX, XX, XX, XX },
1679 { "psllw", MS, Ib, XX, XX },
1680 { "(bad)", XX, XX, XX, XX },
1681 },
1682 /* GRP13 */
1683 {
1684 { "(bad)", XX, XX, XX, XX },
1685 { "(bad)", XX, XX, XX, XX },
1686 { "psrld", MS, Ib, XX, XX },
1687 { "(bad)", XX, XX, XX, XX },
1688 { "psrad", MS, Ib, XX, XX },
1689 { "(bad)", XX, XX, XX, XX },
1690 { "pslld", MS, Ib, XX, XX },
1691 { "(bad)", XX, XX, XX, XX },
1692 },
1693 /* GRP14 */
1694 {
1695 { "(bad)", XX, XX, XX, XX },
1696 { "(bad)", XX, XX, XX, XX },
1697 { "psrlq", MS, Ib, XX, XX },
1698 { "psrldq", MS, Ib, XX, XX },
1699 { "(bad)", XX, XX, XX, XX },
1700 { "(bad)", XX, XX, XX, XX },
1701 { "psllq", MS, Ib, XX, XX },
1702 { "pslldq", MS, Ib, XX, XX },
1703 },
1704 /* GRP15 */
1705 {
1706 { "fxsave", Ev, XX, XX, XX },
1707 { "fxrstor", Ev, XX, XX, XX },
1708 { "ldmxcsr", Ev, XX, XX, XX },
1709 { "stmxcsr", Ev, XX, XX, XX },
1710 { "(bad)", XX, XX, XX, XX },
1711 { "lfence", OP_0fae, 0, XX, XX, XX },
1712 { "mfence", OP_0fae, 0, XX, XX, XX },
1713 { "clflush", OP_0fae, 0, XX, XX, XX },
1714 },
1715 /* GRP16 */
1716 {
1717 { "prefetchnta", Ev, XX, XX, XX },
1718 { "prefetcht0", Ev, XX, XX, XX },
1719 { "prefetcht1", Ev, XX, XX, XX },
1720 { "prefetcht2", Ev, XX, XX, XX },
1721 { "(bad)", XX, XX, XX, XX },
1722 { "(bad)", XX, XX, XX, XX },
1723 { "(bad)", XX, XX, XX, XX },
1724 { "(bad)", XX, XX, XX, XX },
1725 },
1726 /* GRPAMD */
1727 {
1728 { "prefetch", Eb, XX, XX, XX },
1729 { "prefetchw", Eb, XX, XX, XX },
1730 { "(bad)", XX, XX, XX, XX },
1731 { "(bad)", XX, XX, XX, XX },
1732 { "(bad)", XX, XX, XX, XX },
1733 { "(bad)", XX, XX, XX, XX },
1734 { "(bad)", XX, XX, XX, XX },
1735 { "(bad)", XX, XX, XX, XX },
1736 },
1737 /* GRPPADLCK1 */
1738 {
1739 { "xstore-rng", OP_0f07, 0, XX, XX, XX },
1740 { "xcrypt-ecb", OP_0f07, 0, XX, XX, XX },
1741 { "xcrypt-cbc", OP_0f07, 0, XX, XX, XX },
1742 { "xcrypt-ctr", OP_0f07, 0, XX, XX, XX },
1743 { "xcrypt-cfb", OP_0f07, 0, XX, XX, XX },
1744 { "xcrypt-ofb", OP_0f07, 0, XX, XX, XX },
1745 { "(bad)", OP_0f07, 0, XX, XX, XX },
1746 { "(bad)", OP_0f07, 0, XX, XX, XX },
1747 },
1748 /* GRPPADLCK2 */
1749 {
1750 { "montmul", OP_0f07, 0, XX, XX, XX },
1751 { "xsha1", OP_0f07, 0, XX, XX, XX },
1752 { "xsha256", OP_0f07, 0, XX, XX, XX },
1753 { "(bad)", OP_0f07, 0, XX, XX, XX },
1754 { "(bad)", OP_0f07, 0, XX, XX, XX },
1755 { "(bad)", OP_0f07, 0, XX, XX, XX },
1756 { "(bad)", OP_0f07, 0, XX, XX, XX },
1757 { "(bad)", OP_0f07, 0, XX, XX, XX },
1758 }
1759 };
1760
1761 static const struct dis386 prefix_user_table[][4] = {
1762 /* PREGRP0 */
1763 {
1764 { "addps", XM, EX, XX, XX },
1765 { "addss", XM, EX, XX, XX },
1766 { "addpd", XM, EX, XX, XX },
1767 { "addsd", XM, EX, XX, XX },
1768 },
1769 /* PREGRP1 */
1770 {
1771 { "", XM, EX, OPSIMD, XX }, /* See OP_SIMD_SUFFIX. */
1772 { "", XM, EX, OPSIMD, XX },
1773 { "", XM, EX, OPSIMD, XX },
1774 { "", XM, EX, OPSIMD, XX },
1775 },
1776 /* PREGRP2 */
1777 {
1778 { "cvtpi2ps", XM, EMC, XX, XX },
1779 { "cvtsi2ssY", XM, Ev, XX, XX },
1780 { "cvtpi2pd", XM, EMC, XX, XX },
1781 { "cvtsi2sdY", XM, Ev, XX, XX },
1782 },
1783 /* PREGRP3 */
1784 {
1785 { "cvtps2pi", MXC, EX, XX, XX },
1786 { "cvtss2siY", Gv, EX, XX, XX },
1787 { "cvtpd2pi", MXC, EX, XX, XX },
1788 { "cvtsd2siY", Gv, EX, XX, XX },
1789 },
1790 /* PREGRP4 */
1791 {
1792 { "cvttps2pi", MXC, EX, XX, XX },
1793 { "cvttss2siY", Gv, EX, XX, XX },
1794 { "cvttpd2pi", MXC, EX, XX, XX },
1795 { "cvttsd2siY", Gv, EX, XX, XX },
1796 },
1797 /* PREGRP5 */
1798 {
1799 { "divps", XM, EX, XX, XX },
1800 { "divss", XM, EX, XX, XX },
1801 { "divpd", XM, EX, XX, XX },
1802 { "divsd", XM, EX, XX, XX },
1803 },
1804 /* PREGRP6 */
1805 {
1806 { "maxps", XM, EX, XX, XX },
1807 { "maxss", XM, EX, XX, XX },
1808 { "maxpd", XM, EX, XX, XX },
1809 { "maxsd", XM, EX, XX, XX },
1810 },
1811 /* PREGRP7 */
1812 {
1813 { "minps", XM, EX, XX, XX },
1814 { "minss", XM, EX, XX, XX },
1815 { "minpd", XM, EX, XX, XX },
1816 { "minsd", XM, EX, XX, XX },
1817 },
1818 /* PREGRP8 */
1819 {
1820 { "movups", XM, EX, XX, XX },
1821 { "movss", XM, EX, XX, XX },
1822 { "movupd", XM, EX, XX, XX },
1823 { "movsd", XM, EX, XX, XX },
1824 },
1825 /* PREGRP9 */
1826 {
1827 { "movups", EX, XM, XX, XX },
1828 { "movss", EX, XM, XX, XX },
1829 { "movupd", EX, XM, XX, XX },
1830 { "movsd", EX, XM, XX, XX },
1831 },
1832 /* PREGRP10 */
1833 {
1834 { "mulps", XM, EX, XX, XX },
1835 { "mulss", XM, EX, XX, XX },
1836 { "mulpd", XM, EX, XX, XX },
1837 { "mulsd", XM, EX, XX, XX },
1838 },
1839 /* PREGRP11 */
1840 {
1841 { "rcpps", XM, EX, XX, XX },
1842 { "rcpss", XM, EX, XX, XX },
1843 { "(bad)", XM, EX, XX, XX },
1844 { "(bad)", XM, EX, XX, XX },
1845 },
1846 /* PREGRP12 */
1847 {
1848 { "rsqrtps", XM, EX, XX, XX },
1849 { "rsqrtss", XM, EX, XX, XX },
1850 { "(bad)", XM, EX, XX, XX },
1851 { "(bad)", XM, EX, XX, XX },
1852 },
1853 /* PREGRP13 */
1854 {
1855 { "sqrtps", XM, EX, XX, XX },
1856 { "sqrtss", XM, EX, XX, XX },
1857 { "sqrtpd", XM, EX, XX, XX },
1858 { "sqrtsd", XM, EX, XX, XX },
1859 },
1860 /* PREGRP14 */
1861 {
1862 { "subps", XM, EX, XX, XX },
1863 { "subss", XM, EX, XX, XX },
1864 { "subpd", XM, EX, XX, XX },
1865 { "subsd", XM, EX, XX, XX },
1866 },
1867 /* PREGRP15 */
1868 {
1869 { "(bad)", XM, EX, XX, XX },
1870 { "cvtdq2pd", XM, EX, XX, XX },
1871 { "cvttpd2dq", XM, EX, XX, XX },
1872 { "cvtpd2dq", XM, EX, XX, XX },
1873 },
1874 /* PREGRP16 */
1875 {
1876 { "cvtdq2ps", XM, EX, XX, XX },
1877 { "cvttps2dq",XM, EX, XX, XX },
1878 { "cvtps2dq",XM, EX, XX, XX },
1879 { "(bad)", XM, EX, XX, XX },
1880 },
1881 /* PREGRP17 */
1882 {
1883 { "cvtps2pd", XM, EX, XX, XX },
1884 { "cvtss2sd", XM, EX, XX, XX },
1885 { "cvtpd2ps", XM, EX, XX, XX },
1886 { "cvtsd2ss", XM, EX, XX, XX },
1887 },
1888 /* PREGRP18 */
1889 {
1890 { "maskmovq", MX, MS, XX, XX },
1891 { "(bad)", XM, EX, XX, XX },
1892 { "maskmovdqu", XM, XS, XX, XX },
1893 { "(bad)", XM, EX, XX, XX },
1894 },
1895 /* PREGRP19 */
1896 {
1897 { "movq", MX, EM, XX, XX },
1898 { "movdqu", XM, EX, XX, XX },
1899 { "movdqa", XM, EX, XX, XX },
1900 { "(bad)", XM, EX, XX, XX },
1901 },
1902 /* PREGRP20 */
1903 {
1904 { "movq", EM, MX, XX, XX },
1905 { "movdqu", EX, XM, XX, XX },
1906 { "movdqa", EX, XM, XX, XX },
1907 { "(bad)", EX, XM, XX, XX },
1908 },
1909 /* PREGRP21 */
1910 {
1911 { "(bad)", EX, XM, XX, XX },
1912 { "movq2dq", XM, MS, XX, XX },
1913 { "movq", EX, XM, XX, XX },
1914 { "movdq2q", MX, XS, XX, XX },
1915 },
1916 /* PREGRP22 */
1917 {
1918 { "pshufw", MX, EM, Ib, XX },
1919 { "pshufhw", XM, EX, Ib, XX },
1920 { "pshufd", XM, EX, Ib, XX },
1921 { "pshuflw", XM, EX, Ib, XX },
1922 },
1923 /* PREGRP23 */
1924 {
1925 { "movd", Edq, MX, XX, XX },
1926 { "movq", XM, EX, XX, XX },
1927 { "movd", Edq, XM, XX, XX },
1928 { "(bad)", Ed, XM, XX, XX },
1929 },
1930 /* PREGRP24 */
1931 {
1932 { "(bad)", MX, EX, XX, XX },
1933 { "(bad)", XM, EX, XX, XX },
1934 { "punpckhqdq", XM, EX, XX, XX },
1935 { "(bad)", XM, EX, XX, XX },
1936 },
1937 /* PREGRP25 */
1938 {
1939 { "movntq", EM, MX, XX, XX },
1940 { "(bad)", EM, XM, XX, XX },
1941 { "movntdq", EM, XM, XX, XX },
1942 { "(bad)", EM, XM, XX, XX },
1943 },
1944 /* PREGRP26 */
1945 {
1946 { "(bad)", MX, EX, XX, XX },
1947 { "(bad)", XM, EX, XX, XX },
1948 { "punpcklqdq", XM, EX, XX, XX },
1949 { "(bad)", XM, EX, XX, XX },
1950 },
1951 /* PREGRP27 */
1952 {
1953 { "(bad)", MX, EX, XX, XX },
1954 { "(bad)", XM, EX, XX, XX },
1955 { "addsubpd", XM, EX, XX, XX },
1956 { "addsubps", XM, EX, XX, XX },
1957 },
1958 /* PREGRP28 */
1959 {
1960 { "(bad)", MX, EX, XX, XX },
1961 { "(bad)", XM, EX, XX, XX },
1962 { "haddpd", XM, EX, XX, XX },
1963 { "haddps", XM, EX, XX, XX },
1964 },
1965 /* PREGRP29 */
1966 {
1967 { "(bad)", MX, EX, XX, XX },
1968 { "(bad)", XM, EX, XX, XX },
1969 { "hsubpd", XM, EX, XX, XX },
1970 { "hsubps", XM, EX, XX, XX },
1971 },
1972 /* PREGRP30 */
1973 {
1974 { "movlpX", XM, EX, SIMD_Fixup, 'h', XX }, /* really only 2 operands */
1975 { "movsldup", XM, EX, XX, XX },
1976 { "movlpd", XM, EX, XX, XX },
1977 { "movddup", XM, EX, XX, XX },
1978 },
1979 /* PREGRP31 */
1980 {
1981 { "movhpX", XM, EX, SIMD_Fixup, 'l', XX },
1982 { "movshdup", XM, EX, XX, XX },
1983 { "movhpd", XM, EX, XX, XX },
1984 { "(bad)", XM, EX, XX, XX },
1985 },
1986 /* PREGRP32 */
1987 {
1988 { "(bad)", XM, EX, XX, XX },
1989 { "(bad)", XM, EX, XX, XX },
1990 { "(bad)", XM, EX, XX, XX },
1991 { "lddqu", XM, M, XX, XX },
1992 },
1993 /* PREGRP33 */
1994 {
1995 {"movntps",Ev, XM, XX, XX },
1996 {"movntss",Ev, XM, XX, XX },
1997 {"movntpd",Ev, XM, XX, XX },
1998 {"movntsd",Ev, XM, XX, XX },
1999 },
2000
2001 /* PREGRP34 */
2002 {
2003 {"vmread", Em, Gm, XX, XX },
2004 {"(bad)", XX, XX, XX, XX },
2005 {"extrq", XS, Ib, Ib, XX },
2006 {"insertq",XM, XS, Ib, Ib },
2007 },
2008
2009 /* PREGRP35 */
2010 {
2011 {"vmwrite", Gm, Em, XX, XX },
2012 {"(bad)", XX, XX, XX, XX },
2013 {"extrq", XM, XS, XX, XX },
2014 {"insertq", XM, XS, XX, XX },
2015 },
2016
2017 /* PREGRP36 */
2018 {
2019 { "bsrS", Gv, Ev, XX, XX },
2020 { "lzcntS", Gv, Ev, XX, XX },
2021 { "bsrS", Gv, Ev, XX, XX },
2022 { "(bad)", XX, XX, XX, XX },
2023 },
2024
2025 /* PREGRP37 */
2026 {
2027 { "(bad)", XX, XX, XX, XX },
2028 { "popcntS",Gv, Ev, XX, XX },
2029 { "(bad)", XX, XX, XX, XX },
2030 { "(bad)", XX, XX, XX, XX },
2031 },
2032 };
2033
2034 static const struct dis386 x86_64_table[][2] = {
2035 {
2036 { "pusha{P|}", XX, XX, XX, XX },
2037 { "(bad)", XX, XX, XX, XX },
2038 },
2039 {
2040 { "popa{P|}", XX, XX, XX, XX },
2041 { "(bad)", XX, XX, XX, XX },
2042 },
2043 {
2044 { "bound{S|}", Gv, Ma, XX, XX },
2045 { "(bad)", XX, XX, XX, XX },
2046 },
2047 {
2048 { "arpl", Ew, Gw, XX, XX },
2049 { "movs{||lq|xd}", Gv, Ed, XX, XX },
2050 },
2051 };
2052
2053 static const struct dis386 three_byte_table[][256] = {
2054 /* THREE_BYTE_0 */
2055 {
2056 /* 00 */
2057 { "pshufb", MX, EM, XX, XX },
2058 { "phaddw", MX, EM, XX, XX },
2059 { "phaddd", MX, EM, XX, XX },
2060 { "phaddsw", MX, EM, XX, XX },
2061 { "pmaddubsw", MX, EM, XX, XX },
2062 { "phsubw", MX, EM, XX, XX },
2063 { "phsubd", MX, EM, XX, XX },
2064 { "phsubsw", MX, EM, XX, XX },
2065 /* 08 */
2066 { "psignb", MX, EM, XX, XX },
2067 { "psignw", MX, EM, XX, XX },
2068 { "psignd", MX, EM, XX, XX },
2069 { "pmulhrsw", MX, EM, XX, XX },
2070 { "(bad)", XX, XX, XX, XX },
2071 { "(bad)", XX, XX, XX, XX },
2072 { "(bad)", XX, XX, XX, XX },
2073 { "(bad)", XX, XX, XX, XX },
2074 /* 10 */
2075 { "(bad)", XX, XX, XX, XX },
2076 { "(bad)", XX, XX, XX, XX },
2077 { "(bad)", XX, XX, XX, XX },
2078 { "(bad)", XX, XX, XX, XX },
2079 { "(bad)", XX, XX, XX, XX },
2080 { "(bad)", XX, XX, XX, XX },
2081 { "(bad)", XX, XX, XX, XX },
2082 { "(bad)", XX, XX, XX, XX },
2083 /* 18 */
2084 { "(bad)", XX, XX, XX, XX },
2085 { "(bad)", XX, XX, XX, XX },
2086 { "(bad)", XX, XX, XX, XX },
2087 { "(bad)", XX, XX, XX, XX },
2088 { "pabsb", MX, EM, XX, XX },
2089 { "pabsw", MX, EM, XX, XX },
2090 { "pabsd", MX, EM, XX, XX },
2091 { "(bad)", XX, XX, XX, XX },
2092 /* 20 */
2093 { "(bad)", XX, XX, XX, XX },
2094 { "(bad)", XX, XX, XX, XX },
2095 { "(bad)", XX, XX, XX, XX },
2096 { "(bad)", XX, XX, XX, XX },
2097 { "(bad)", XX, XX, XX, XX },
2098 { "(bad)", XX, XX, XX, XX },
2099 { "(bad)", XX, XX, XX, XX },
2100 { "(bad)", XX, XX, XX, XX },
2101 /* 28 */
2102 { "(bad)", XX, XX, XX, XX },
2103 { "(bad)", XX, XX, XX, XX },
2104 { "(bad)", XX, XX, XX, XX },
2105 { "(bad)", XX, XX, XX, XX },
2106 { "(bad)", XX, XX, XX, XX },
2107 { "(bad)", XX, XX, XX, XX },
2108 { "(bad)", XX, XX, XX, XX },
2109 { "(bad)", XX, XX, XX, XX },
2110 /* 30 */
2111 { "(bad)", XX, XX, XX, XX },
2112 { "(bad)", XX, XX, XX, XX },
2113 { "(bad)", XX, XX, XX, XX },
2114 { "(bad)", XX, XX, XX, XX },
2115 { "(bad)", XX, XX, XX, XX },
2116 { "(bad)", XX, XX, XX, XX },
2117 { "(bad)", XX, XX, XX, XX },
2118 { "(bad)", XX, XX, XX, XX },
2119 /* 38 */
2120 { "(bad)", XX, XX, XX, XX },
2121 { "(bad)", XX, XX, XX, XX },
2122 { "(bad)", XX, XX, XX, XX },
2123 { "(bad)", XX, XX, XX, XX },
2124 { "(bad)", XX, XX, XX, XX },
2125 { "(bad)", XX, XX, XX, XX },
2126 { "(bad)", XX, XX, XX, XX },
2127 { "(bad)", XX, XX, XX, XX },
2128 /* 40 */
2129 { "(bad)", XX, XX, XX, XX },
2130 { "(bad)", XX, XX, XX, XX },
2131 { "(bad)", XX, XX, XX, XX },
2132 { "(bad)", XX, XX, XX, XX },
2133 { "(bad)", XX, XX, XX, XX },
2134 { "(bad)", XX, XX, XX, XX },
2135 { "(bad)", XX, XX, XX, XX },
2136 { "(bad)", XX, XX, XX, XX },
2137 /* 48 */
2138 { "(bad)", XX, XX, XX, XX },
2139 { "(bad)", XX, XX, XX, XX },
2140 { "(bad)", XX, XX, XX, XX },
2141 { "(bad)", XX, XX, XX, XX },
2142 { "(bad)", XX, XX, XX, XX },
2143 { "(bad)", XX, XX, XX, XX },
2144 { "(bad)", XX, XX, XX, XX },
2145 { "(bad)", XX, XX, XX, XX },
2146 /* 50 */
2147 { "(bad)", XX, XX, XX, XX },
2148 { "(bad)", XX, XX, XX, XX },
2149 { "(bad)", XX, XX, XX, XX },
2150 { "(bad)", XX, XX, XX, XX },
2151 { "(bad)", XX, XX, XX, XX },
2152 { "(bad)", XX, XX, XX, XX },
2153 { "(bad)", XX, XX, XX, XX },
2154 { "(bad)", XX, XX, XX, XX },
2155 /* 58 */
2156 { "(bad)", XX, XX, XX, XX },
2157 { "(bad)", XX, XX, XX, XX },
2158 { "(bad)", XX, XX, XX, XX },
2159 { "(bad)", XX, XX, XX, XX },
2160 { "(bad)", XX, XX, XX, XX },
2161 { "(bad)", XX, XX, XX, XX },
2162 { "(bad)", XX, XX, XX, XX },
2163 { "(bad)", XX, XX, XX, XX },
2164 /* 60 */
2165 { "(bad)", XX, XX, XX, XX },
2166 { "(bad)", XX, XX, XX, XX },
2167 { "(bad)", XX, XX, XX, XX },
2168 { "(bad)", XX, XX, XX, XX },
2169 { "(bad)", XX, XX, XX, XX },
2170 { "(bad)", XX, XX, XX, XX },
2171 { "(bad)", XX, XX, XX, XX },
2172 { "(bad)", XX, XX, XX, XX },
2173 /* 68 */
2174 { "(bad)", XX, XX, XX, XX },
2175 { "(bad)", XX, XX, XX, XX },
2176 { "(bad)", XX, XX, XX, XX },
2177 { "(bad)", XX, XX, XX, XX },
2178 { "(bad)", XX, XX, XX, XX },
2179 { "(bad)", XX, XX, XX, XX },
2180 { "(bad)", XX, XX, XX, XX },
2181 { "(bad)", XX, XX, XX, XX },
2182 /* 70 */
2183 { "(bad)", XX, XX, XX, XX },
2184 { "(bad)", XX, XX, XX, XX },
2185 { "(bad)", XX, XX, XX, XX },
2186 { "(bad)", XX, XX, XX, XX },
2187 { "(bad)", XX, XX, XX, XX },
2188 { "(bad)", XX, XX, XX, XX },
2189 { "(bad)", XX, XX, XX, XX },
2190 { "(bad)", XX, XX, XX, XX },
2191 /* 78 */
2192 { "(bad)", XX, XX, XX, XX },
2193 { "(bad)", XX, XX, XX, XX },
2194 { "(bad)", XX, XX, XX, XX },
2195 { "(bad)", XX, XX, XX, XX },
2196 { "(bad)", XX, XX, XX, XX },
2197 { "(bad)", XX, XX, XX, XX },
2198 { "(bad)", XX, XX, XX, XX },
2199 { "(bad)", XX, XX, XX, XX },
2200 /* 80 */
2201 { "(bad)", XX, XX, XX, XX },
2202 { "(bad)", XX, XX, XX, XX },
2203 { "(bad)", XX, XX, XX, XX },
2204 { "(bad)", XX, XX, XX, XX },
2205 { "(bad)", XX, XX, XX, XX },
2206 { "(bad)", XX, XX, XX, XX },
2207 { "(bad)", XX, XX, XX, XX },
2208 { "(bad)", XX, XX, XX, XX },
2209 /* 88 */
2210 { "(bad)", XX, XX, XX, XX },
2211 { "(bad)", XX, XX, XX, XX },
2212 { "(bad)", XX, XX, XX, XX },
2213 { "(bad)", XX, XX, XX, XX },
2214 { "(bad)", XX, XX, XX, XX },
2215 { "(bad)", XX, XX, XX, XX },
2216 { "(bad)", XX, XX, XX, XX },
2217 { "(bad)", XX, XX, XX, XX },
2218 /* 90 */
2219 { "(bad)", XX, XX, XX, XX },
2220 { "(bad)", XX, XX, XX, XX },
2221 { "(bad)", XX, XX, XX, XX },
2222 { "(bad)", XX, XX, XX, XX },
2223 { "(bad)", XX, XX, XX, XX },
2224 { "(bad)", XX, XX, XX, XX },
2225 { "(bad)", XX, XX, XX, XX },
2226 { "(bad)", XX, XX, XX, XX },
2227 /* 98 */
2228 { "(bad)", XX, XX, XX, XX },
2229 { "(bad)", XX, XX, XX, XX },
2230 { "(bad)", XX, XX, XX, XX },
2231 { "(bad)", XX, XX, XX, XX },
2232 { "(bad)", XX, XX, XX, XX },
2233 { "(bad)", XX, XX, XX, XX },
2234 { "(bad)", XX, XX, XX, XX },
2235 { "(bad)", XX, XX, XX, XX },
2236 /* a0 */
2237 { "(bad)", XX, XX, XX, XX },
2238 { "(bad)", XX, XX, XX, XX },
2239 { "(bad)", XX, XX, XX, XX },
2240 { "(bad)", XX, XX, XX, XX },
2241 { "(bad)", XX, XX, XX, XX },
2242 { "(bad)", XX, XX, XX, XX },
2243 { "(bad)", XX, XX, XX, XX },
2244 { "(bad)", XX, XX, XX, XX },
2245 /* a8 */
2246 { "(bad)", XX, XX, XX, XX },
2247 { "(bad)", XX, XX, XX, XX },
2248 { "(bad)", XX, XX, XX, XX },
2249 { "(bad)", XX, XX, XX, XX },
2250 { "(bad)", XX, XX, XX, XX },
2251 { "(bad)", XX, XX, XX, XX },
2252 { "(bad)", XX, XX, XX, XX },
2253 { "(bad)", XX, XX, XX, XX },
2254 /* b0 */
2255 { "(bad)", XX, XX, XX, XX },
2256 { "(bad)", XX, XX, XX, XX },
2257 { "(bad)", XX, XX, XX, XX },
2258 { "(bad)", XX, XX, XX, XX },
2259 { "(bad)", XX, XX, XX, XX },
2260 { "(bad)", XX, XX, XX, XX },
2261 { "(bad)", XX, XX, XX, XX },
2262 { "(bad)", XX, XX, XX, XX },
2263 /* b8 */
2264 { "(bad)", XX, XX, XX, XX },
2265 { "(bad)", XX, XX, XX, XX },
2266 { "(bad)", XX, XX, XX, XX },
2267 { "(bad)", XX, XX, XX, XX },
2268 { "(bad)", XX, XX, XX, XX },
2269 { "(bad)", XX, XX, XX, XX },
2270 { "(bad)", XX, XX, XX, XX },
2271 { "(bad)", XX, XX, XX, XX },
2272 /* c0 */
2273 { "(bad)", XX, XX, XX, XX },
2274 { "(bad)", XX, XX, XX, XX },
2275 { "(bad)", XX, XX, XX, XX },
2276 { "(bad)", XX, XX, XX, XX },
2277 { "(bad)", XX, XX, XX, XX },
2278 { "(bad)", XX, XX, XX, XX },
2279 { "(bad)", XX, XX, XX, XX },
2280 { "(bad)", XX, XX, XX, XX },
2281 /* c8 */
2282 { "(bad)", XX, XX, XX, XX },
2283 { "(bad)", XX, XX, XX, XX },
2284 { "(bad)", XX, XX, XX, XX },
2285 { "(bad)", XX, XX, XX, XX },
2286 { "(bad)", XX, XX, XX, XX },
2287 { "(bad)", XX, XX, XX, XX },
2288 { "(bad)", XX, XX, XX, XX },
2289 { "(bad)", XX, XX, XX, XX },
2290 /* d0 */
2291 { "(bad)", XX, XX, XX, XX },
2292 { "(bad)", XX, XX, XX, XX },
2293 { "(bad)", XX, XX, XX, XX },
2294 { "(bad)", XX, XX, XX, XX },
2295 { "(bad)", XX, XX, XX, XX },
2296 { "(bad)", XX, XX, XX, XX },
2297 { "(bad)", XX, XX, XX, XX },
2298 { "(bad)", XX, XX, XX, XX },
2299 /* d8 */
2300 { "(bad)", XX, XX, XX, XX },
2301 { "(bad)", XX, XX, XX, XX },
2302 { "(bad)", XX, XX, XX, XX },
2303 { "(bad)", XX, XX, XX, XX },
2304 { "(bad)", XX, XX, XX, XX },
2305 { "(bad)", XX, XX, XX, XX },
2306 { "(bad)", XX, XX, XX, XX },
2307 { "(bad)", XX, XX, XX, XX },
2308 /* e0 */
2309 { "(bad)", XX, XX, XX, XX },
2310 { "(bad)", XX, XX, XX, XX },
2311 { "(bad)", XX, XX, XX, XX },
2312 { "(bad)", XX, XX, XX, XX },
2313 { "(bad)", XX, XX, XX, XX },
2314 { "(bad)", XX, XX, XX, XX },
2315 { "(bad)", XX, XX, XX, XX },
2316 { "(bad)", XX, XX, XX, XX },
2317 /* e8 */
2318 { "(bad)", XX, XX, XX, XX },
2319 { "(bad)", XX, XX, XX, XX },
2320 { "(bad)", XX, XX, XX, XX },
2321 { "(bad)", XX, XX, XX, XX },
2322 { "(bad)", XX, XX, XX, XX },
2323 { "(bad)", XX, XX, XX, XX },
2324 { "(bad)", XX, XX, XX, XX },
2325 { "(bad)", XX, XX, XX, XX },
2326 /* f0 */
2327 { "(bad)", XX, XX, XX, XX },
2328 { "(bad)", XX, XX, XX, XX },
2329 { "(bad)", XX, XX, XX, XX },
2330 { "(bad)", XX, XX, XX, XX },
2331 { "(bad)", XX, XX, XX, XX },
2332 { "(bad)", XX, XX, XX, XX },
2333 { "(bad)", XX, XX, XX, XX },
2334 { "(bad)", XX, XX, XX, XX },
2335 /* f8 */
2336 { "(bad)", XX, XX, XX, XX },
2337 { "(bad)", XX, XX, XX, XX },
2338 { "(bad)", XX, XX, XX, XX },
2339 { "(bad)", XX, XX, XX, XX },
2340 { "(bad)", XX, XX, XX, XX },
2341 { "(bad)", XX, XX, XX, XX },
2342 { "(bad)", XX, XX, XX, XX },
2343 { "(bad)", XX, XX, XX, XX }
2344 },
2345 /* THREE_BYTE_1 */
2346 {
2347 /* 00 */
2348 { "(bad)", XX, XX, XX, XX },
2349 { "(bad)", XX, XX, XX, XX },
2350 { "(bad)", XX, XX, XX, XX },
2351 { "(bad)", XX, XX, XX, XX },
2352 { "(bad)", XX, XX, XX, XX },
2353 { "(bad)", XX, XX, XX, XX },
2354 { "(bad)", XX, XX, XX, XX },
2355 { "(bad)", XX, XX, XX, XX },
2356 /* 08 */
2357 { "(bad)", XX, XX, XX, XX },
2358 { "(bad)", XX, XX, XX, XX },
2359 { "(bad)", XX, XX, XX, XX },
2360 { "(bad)", XX, XX, XX, XX },
2361 { "(bad)", XX, XX, XX, XX },
2362 { "(bad)", XX, XX, XX, XX },
2363 { "(bad)", XX, XX, XX, XX },
2364 { "palignr", MX, EM, Ib, XX },
2365 /* 10 */
2366 { "(bad)", XX, XX, XX, XX },
2367 { "(bad)", XX, XX, XX, XX },
2368 { "(bad)", XX, XX, XX, XX },
2369 { "(bad)", XX, XX, XX, XX },
2370 { "(bad)", XX, XX, XX, XX },
2371 { "(bad)", XX, XX, XX, XX },
2372 { "(bad)", XX, XX, XX, XX },
2373 { "(bad)", XX, XX, XX, XX },
2374 /* 18 */
2375 { "(bad)", XX, XX, XX, XX },
2376 { "(bad)", XX, XX, XX, XX },
2377 { "(bad)", XX, XX, XX, XX },
2378 { "(bad)", XX, XX, XX, XX },
2379 { "(bad)", XX, XX, XX, XX },
2380 { "(bad)", XX, XX, XX, XX },
2381 { "(bad)", XX, XX, XX, XX },
2382 { "(bad)", XX, XX, XX, XX },
2383 /* 20 */
2384 { "(bad)", XX, XX, XX, XX },
2385 { "(bad)", XX, XX, XX, XX },
2386 { "(bad)", XX, XX, XX, XX },
2387 { "(bad)", XX, XX, XX, XX },
2388 { "(bad)", XX, XX, XX, XX },
2389 { "(bad)", XX, XX, XX, XX },
2390 { "(bad)", XX, XX, XX, XX },
2391 { "(bad)", XX, XX, XX, XX },
2392 /* 28 */
2393 { "(bad)", XX, XX, XX, XX },
2394 { "(bad)", XX, XX, XX, XX },
2395 { "(bad)", XX, XX, XX, XX },
2396 { "(bad)", XX, XX, XX, XX },
2397 { "(bad)", XX, XX, XX, XX },
2398 { "(bad)", XX, XX, XX, XX },
2399 { "(bad)", XX, XX, XX, XX },
2400 { "(bad)", XX, XX, XX, XX },
2401 /* 30 */
2402 { "(bad)", XX, XX, XX, XX },
2403 { "(bad)", XX, XX, XX, XX },
2404 { "(bad)", XX, XX, XX, XX },
2405 { "(bad)", XX, XX, XX, XX },
2406 { "(bad)", XX, XX, XX, XX },
2407 { "(bad)", XX, XX, XX, XX },
2408 { "(bad)", XX, XX, XX, XX },
2409 { "(bad)", XX, XX, XX, XX },
2410 /* 38 */
2411 { "(bad)", XX, XX, XX, XX },
2412 { "(bad)", XX, XX, XX, XX },
2413 { "(bad)", XX, XX, XX, XX },
2414 { "(bad)", XX, XX, XX, XX },
2415 { "(bad)", XX, XX, XX, XX },
2416 { "(bad)", XX, XX, XX, XX },
2417 { "(bad)", XX, XX, XX, XX },
2418 { "(bad)", XX, XX, XX, XX },
2419 /* 40 */
2420 { "(bad)", XX, XX, XX, XX },
2421 { "(bad)", XX, XX, XX, XX },
2422 { "(bad)", XX, XX, XX, XX },
2423 { "(bad)", XX, XX, XX, XX },
2424 { "(bad)", XX, XX, XX, XX },
2425 { "(bad)", XX, XX, XX, XX },
2426 { "(bad)", XX, XX, XX, XX },
2427 { "(bad)", XX, XX, XX, XX },
2428 /* 48 */
2429 { "(bad)", XX, XX, XX, XX },
2430 { "(bad)", XX, XX, XX, XX },
2431 { "(bad)", XX, XX, XX, XX },
2432 { "(bad)", XX, XX, XX, XX },
2433 { "(bad)", XX, XX, XX, XX },
2434 { "(bad)", XX, XX, XX, XX },
2435 { "(bad)", XX, XX, XX, XX },
2436 { "(bad)", XX, XX, XX, XX },
2437 /* 50 */
2438 { "(bad)", XX, XX, XX, XX },
2439 { "(bad)", XX, XX, XX, XX },
2440 { "(bad)", XX, XX, XX, XX },
2441 { "(bad)", XX, XX, XX, XX },
2442 { "(bad)", XX, XX, XX, XX },
2443 { "(bad)", XX, XX, XX, XX },
2444 { "(bad)", XX, XX, XX, XX },
2445 { "(bad)", XX, XX, XX, XX },
2446 /* 58 */
2447 { "(bad)", XX, XX, XX, XX },
2448 { "(bad)", XX, XX, XX, XX },
2449 { "(bad)", XX, XX, XX, XX },
2450 { "(bad)", XX, XX, XX, XX },
2451 { "(bad)", XX, XX, XX, XX },
2452 { "(bad)", XX, XX, XX, XX },
2453 { "(bad)", XX, XX, XX, XX },
2454 { "(bad)", XX, XX, XX, XX },
2455 /* 60 */
2456 { "(bad)", XX, XX, XX, XX },
2457 { "(bad)", XX, XX, XX, XX },
2458 { "(bad)", XX, XX, XX, XX },
2459 { "(bad)", XX, XX, XX, XX },
2460 { "(bad)", XX, XX, XX, XX },
2461 { "(bad)", XX, XX, XX, XX },
2462 { "(bad)", XX, XX, XX, XX },
2463 { "(bad)", XX, XX, XX, XX },
2464 /* 68 */
2465 { "(bad)", XX, XX, XX, XX },
2466 { "(bad)", XX, XX, XX, XX },
2467 { "(bad)", XX, XX, XX, XX },
2468 { "(bad)", XX, XX, XX, XX },
2469 { "(bad)", XX, XX, XX, XX },
2470 { "(bad)", XX, XX, XX, XX },
2471 { "(bad)", XX, XX, XX, XX },
2472 { "(bad)", XX, XX, XX, XX },
2473 /* 70 */
2474 { "(bad)", XX, XX, XX, XX },
2475 { "(bad)", XX, XX, XX, XX },
2476 { "(bad)", XX, XX, XX, XX },
2477 { "(bad)", XX, XX, XX, XX },
2478 { "(bad)", XX, XX, XX, XX },
2479 { "(bad)", XX, XX, XX, XX },
2480 { "(bad)", XX, XX, XX, XX },
2481 { "(bad)", XX, XX, XX, XX },
2482 /* 78 */
2483 { "(bad)", XX, XX, XX, XX },
2484 { "(bad)", XX, XX, XX, XX },
2485 { "(bad)", XX, XX, XX, XX },
2486 { "(bad)", XX, XX, XX, XX },
2487 { "(bad)", XX, XX, XX, XX },
2488 { "(bad)", XX, XX, XX, XX },
2489 { "(bad)", XX, XX, XX, XX },
2490 { "(bad)", XX, XX, XX, XX },
2491 /* 80 */
2492 { "(bad)", XX, XX, XX, XX },
2493 { "(bad)", XX, XX, XX, XX },
2494 { "(bad)", XX, XX, XX, XX },
2495 { "(bad)", XX, XX, XX, XX },
2496 { "(bad)", XX, XX, XX, XX },
2497 { "(bad)", XX, XX, XX, XX },
2498 { "(bad)", XX, XX, XX, XX },
2499 { "(bad)", XX, XX, XX, XX },
2500 /* 88 */
2501 { "(bad)", XX, XX, XX, XX },
2502 { "(bad)", XX, XX, XX, XX },
2503 { "(bad)", XX, XX, XX, XX },
2504 { "(bad)", XX, XX, XX, XX },
2505 { "(bad)", XX, XX, XX, XX },
2506 { "(bad)", XX, XX, XX, XX },
2507 { "(bad)", XX, XX, XX, XX },
2508 { "(bad)", XX, XX, XX, XX },
2509 /* 90 */
2510 { "(bad)", XX, XX, XX, XX },
2511 { "(bad)", XX, XX, XX, XX },
2512 { "(bad)", XX, XX, XX, XX },
2513 { "(bad)", XX, XX, XX, XX },
2514 { "(bad)", XX, XX, XX, XX },
2515 { "(bad)", XX, XX, XX, XX },
2516 { "(bad)", XX, XX, XX, XX },
2517 { "(bad)", XX, XX, XX, XX },
2518 /* 98 */
2519 { "(bad)", XX, XX, XX, XX },
2520 { "(bad)", XX, XX, XX, XX },
2521 { "(bad)", XX, XX, XX, XX },
2522 { "(bad)", XX, XX, XX, XX },
2523 { "(bad)", XX, XX, XX, XX },
2524 { "(bad)", XX, XX, XX, XX },
2525 { "(bad)", XX, XX, XX, XX },
2526 { "(bad)", XX, XX, XX, XX },
2527 /* a0 */
2528 { "(bad)", XX, XX, XX, XX },
2529 { "(bad)", XX, XX, XX, XX },
2530 { "(bad)", XX, XX, XX, XX },
2531 { "(bad)", XX, XX, XX, XX },
2532 { "(bad)", XX, XX, XX, XX },
2533 { "(bad)", XX, XX, XX, XX },
2534 { "(bad)", XX, XX, XX, XX },
2535 { "(bad)", XX, XX, XX, XX },
2536 /* a8 */
2537 { "(bad)", XX, XX, XX, XX },
2538 { "(bad)", XX, XX, XX, XX },
2539 { "(bad)", XX, XX, XX, XX },
2540 { "(bad)", XX, XX, XX, XX },
2541 { "(bad)", XX, XX, XX, XX },
2542 { "(bad)", XX, XX, XX, XX },
2543 { "(bad)", XX, XX, XX, XX },
2544 { "(bad)", XX, XX, XX, XX },
2545 /* b0 */
2546 { "(bad)", XX, XX, XX, XX },
2547 { "(bad)", XX, XX, XX, XX },
2548 { "(bad)", XX, XX, XX, XX },
2549 { "(bad)", XX, XX, XX, XX },
2550 { "(bad)", XX, XX, XX, XX },
2551 { "(bad)", XX, XX, XX, XX },
2552 { "(bad)", XX, XX, XX, XX },
2553 { "(bad)", XX, XX, XX, XX },
2554 /* b8 */
2555 { "(bad)", XX, XX, XX, XX },
2556 { "(bad)", XX, XX, XX, XX },
2557 { "(bad)", XX, XX, XX, XX },
2558 { "(bad)", XX, XX, XX, XX },
2559 { "(bad)", XX, XX, XX, XX },
2560 { "(bad)", XX, XX, XX, XX },
2561 { "(bad)", XX, XX, XX, XX },
2562 { "(bad)", XX, XX, XX, XX },
2563 /* c0 */
2564 { "(bad)", XX, XX, XX, XX },
2565 { "(bad)", XX, XX, XX, XX },
2566 { "(bad)", XX, XX, XX, XX },
2567 { "(bad)", XX, XX, XX, XX },
2568 { "(bad)", XX, XX, XX, XX },
2569 { "(bad)", XX, XX, XX, XX },
2570 { "(bad)", XX, XX, XX, XX },
2571 { "(bad)", XX, XX, XX, XX },
2572 /* c8 */
2573 { "(bad)", XX, XX, XX, XX },
2574 { "(bad)", XX, XX, XX, XX },
2575 { "(bad)", XX, XX, XX, XX },
2576 { "(bad)", XX, XX, XX, XX },
2577 { "(bad)", XX, XX, XX, XX },
2578 { "(bad)", XX, XX, XX, XX },
2579 { "(bad)", XX, XX, XX, XX },
2580 { "(bad)", XX, XX, XX, XX },
2581 /* d0 */
2582 { "(bad)", XX, XX, XX, XX },
2583 { "(bad)", XX, XX, XX, XX },
2584 { "(bad)", XX, XX, XX, XX },
2585 { "(bad)", XX, XX, XX, XX },
2586 { "(bad)", XX, XX, XX, XX },
2587 { "(bad)", XX, XX, XX, XX },
2588 { "(bad)", XX, XX, XX, XX },
2589 { "(bad)", XX, XX, XX, XX },
2590 /* d8 */
2591 { "(bad)", XX, XX, XX, XX },
2592 { "(bad)", XX, XX, XX, XX },
2593 { "(bad)", XX, XX, XX, XX },
2594 { "(bad)", XX, XX, XX, XX },
2595 { "(bad)", XX, XX, XX, XX },
2596 { "(bad)", XX, XX, XX, XX },
2597 { "(bad)", XX, XX, XX, XX },
2598 { "(bad)", XX, XX, XX, XX },
2599 /* e0 */
2600 { "(bad)", XX, XX, XX, XX },
2601 { "(bad)", XX, XX, XX, XX },
2602 { "(bad)", XX, XX, XX, XX },
2603 { "(bad)", XX, XX, XX, XX },
2604 { "(bad)", XX, XX, XX, XX },
2605 { "(bad)", XX, XX, XX, XX },
2606 { "(bad)", XX, XX, XX, XX },
2607 { "(bad)", XX, XX, XX, XX },
2608 /* e8 */
2609 { "(bad)", XX, XX, XX, XX },
2610 { "(bad)", XX, XX, XX, XX },
2611 { "(bad)", XX, XX, XX, XX },
2612 { "(bad)", XX, XX, XX, XX },
2613 { "(bad)", XX, XX, XX, XX },
2614 { "(bad)", XX, XX, XX, XX },
2615 { "(bad)", XX, XX, XX, XX },
2616 { "(bad)", XX, XX, XX, XX },
2617 /* f0 */
2618 { "(bad)", XX, XX, XX, XX },
2619 { "(bad)", XX, XX, XX, XX },
2620 { "(bad)", XX, XX, XX, XX },
2621 { "(bad)", XX, XX, XX, XX },
2622 { "(bad)", XX, XX, XX, XX },
2623 { "(bad)", XX, XX, XX, XX },
2624 { "(bad)", XX, XX, XX, XX },
2625 { "(bad)", XX, XX, XX, XX },
2626 /* f8 */
2627 { "(bad)", XX, XX, XX, XX },
2628 { "(bad)", XX, XX, XX, XX },
2629 { "(bad)", XX, XX, XX, XX },
2630 { "(bad)", XX, XX, XX, XX },
2631 { "(bad)", XX, XX, XX, XX },
2632 { "(bad)", XX, XX, XX, XX },
2633 { "(bad)", XX, XX, XX, XX },
2634 { "(bad)", XX, XX, XX, XX }
2635 },
2636 };
2637
2638 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
2639
2640 static void
2641 ckprefix (void)
2642 {
2643 int newrex;
2644 rex = 0;
2645 prefixes = 0;
2646 used_prefixes = 0;
2647 rex_used = 0;
2648 while (1)
2649 {
2650 FETCH_DATA (the_info, codep + 1);
2651 newrex = 0;
2652 switch (*codep)
2653 {
2654 /* REX prefixes family. */
2655 case 0x40:
2656 case 0x41:
2657 case 0x42:
2658 case 0x43:
2659 case 0x44:
2660 case 0x45:
2661 case 0x46:
2662 case 0x47:
2663 case 0x48:
2664 case 0x49:
2665 case 0x4a:
2666 case 0x4b:
2667 case 0x4c:
2668 case 0x4d:
2669 case 0x4e:
2670 case 0x4f:
2671 if (address_mode == mode_64bit)
2672 newrex = *codep;
2673 else
2674 return;
2675 break;
2676 case 0xf3:
2677 prefixes |= PREFIX_REPZ;
2678 break;
2679 case 0xf2:
2680 prefixes |= PREFIX_REPNZ;
2681 break;
2682 case 0xf0:
2683 prefixes |= PREFIX_LOCK;
2684 break;
2685 case 0x2e:
2686 prefixes |= PREFIX_CS;
2687 break;
2688 case 0x36:
2689 prefixes |= PREFIX_SS;
2690 break;
2691 case 0x3e:
2692 prefixes |= PREFIX_DS;
2693 break;
2694 case 0x26:
2695 prefixes |= PREFIX_ES;
2696 break;
2697 case 0x64:
2698 prefixes |= PREFIX_FS;
2699 break;
2700 case 0x65:
2701 prefixes |= PREFIX_GS;
2702 break;
2703 case 0x66:
2704 prefixes |= PREFIX_DATA;
2705 break;
2706 case 0x67:
2707 prefixes |= PREFIX_ADDR;
2708 break;
2709 case FWAIT_OPCODE:
2710 /* fwait is really an instruction. If there are prefixes
2711 before the fwait, they belong to the fwait, *not* to the
2712 following instruction. */
2713 if (prefixes || rex)
2714 {
2715 prefixes |= PREFIX_FWAIT;
2716 codep++;
2717 return;
2718 }
2719 prefixes = PREFIX_FWAIT;
2720 break;
2721 default:
2722 return;
2723 }
2724 /* Rex is ignored when followed by another prefix. */
2725 if (rex)
2726 {
2727 rex_used = rex;
2728 return;
2729 }
2730 rex = newrex;
2731 codep++;
2732 }
2733 }
2734
2735 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
2736 prefix byte. */
2737
2738 static const char *
2739 prefix_name (int pref, int sizeflag)
2740 {
2741 switch (pref)
2742 {
2743 /* REX prefixes family. */
2744 case 0x40:
2745 return "rex";
2746 case 0x41:
2747 return "rexZ";
2748 case 0x42:
2749 return "rexY";
2750 case 0x43:
2751 return "rexYZ";
2752 case 0x44:
2753 return "rexX";
2754 case 0x45:
2755 return "rexXZ";
2756 case 0x46:
2757 return "rexXY";
2758 case 0x47:
2759 return "rexXYZ";
2760 case 0x48:
2761 return "rex64";
2762 case 0x49:
2763 return "rex64Z";
2764 case 0x4a:
2765 return "rex64Y";
2766 case 0x4b:
2767 return "rex64YZ";
2768 case 0x4c:
2769 return "rex64X";
2770 case 0x4d:
2771 return "rex64XZ";
2772 case 0x4e:
2773 return "rex64XY";
2774 case 0x4f:
2775 return "rex64XYZ";
2776 case 0xf3:
2777 return "repz";
2778 case 0xf2:
2779 return "repnz";
2780 case 0xf0:
2781 return "lock";
2782 case 0x2e:
2783 return "cs";
2784 case 0x36:
2785 return "ss";
2786 case 0x3e:
2787 return "ds";
2788 case 0x26:
2789 return "es";
2790 case 0x64:
2791 return "fs";
2792 case 0x65:
2793 return "gs";
2794 case 0x66:
2795 return (sizeflag & DFLAG) ? "data16" : "data32";
2796 case 0x67:
2797 if (address_mode == mode_64bit)
2798 return (sizeflag & AFLAG) ? "addr32" : "addr64";
2799 else
2800 return (sizeflag & AFLAG) ? "addr16" : "addr32";
2801 case FWAIT_OPCODE:
2802 return "fwait";
2803 default:
2804 return NULL;
2805 }
2806 }
2807
2808 static char op1out[100], op2out[100], op3out[100], op4out[100];
2809 static int op_ad, op_index[4];
2810 static int two_source_ops;
2811 static bfd_vma op_address[4];
2812 static bfd_vma op_riprel[4];
2813 static bfd_vma start_pc;
2814 \f
2815 /*
2816 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
2817 * (see topic "Redundant prefixes" in the "Differences from 8086"
2818 * section of the "Virtual 8086 Mode" chapter.)
2819 * 'pc' should be the address of this instruction, it will
2820 * be used to print the target address if this is a relative jump or call
2821 * The function returns the length of this instruction in bytes.
2822 */
2823
2824 static char intel_syntax;
2825 static char open_char;
2826 static char close_char;
2827 static char separator_char;
2828 static char scale_char;
2829
2830 /* Here for backwards compatibility. When gdb stops using
2831 print_insn_i386_att and print_insn_i386_intel these functions can
2832 disappear, and print_insn_i386 be merged into print_insn. */
2833 int
2834 print_insn_i386_att (bfd_vma pc, disassemble_info *info)
2835 {
2836 intel_syntax = 0;
2837
2838 return print_insn (pc, info);
2839 }
2840
2841 int
2842 print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
2843 {
2844 intel_syntax = 1;
2845
2846 return print_insn (pc, info);
2847 }
2848
2849 int
2850 print_insn_i386 (bfd_vma pc, disassemble_info *info)
2851 {
2852 intel_syntax = -1;
2853
2854 return print_insn (pc, info);
2855 }
2856
2857 static int
2858 print_insn (bfd_vma pc, disassemble_info *info)
2859 {
2860 const struct dis386 *dp;
2861 int i;
2862 char *first, *second, *third, *fourth;
2863 int needcomma;
2864 unsigned char uses_DATA_prefix, uses_LOCK_prefix;
2865 unsigned char uses_REPNZ_prefix, uses_REPZ_prefix;
2866 int sizeflag;
2867 const char *p;
2868 struct dis_private priv;
2869 unsigned char op;
2870
2871 if (info->mach == bfd_mach_x86_64_intel_syntax
2872 || info->mach == bfd_mach_x86_64)
2873 address_mode = mode_64bit;
2874 else
2875 address_mode = mode_32bit;
2876
2877 if (intel_syntax == (char) -1)
2878 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
2879 || info->mach == bfd_mach_x86_64_intel_syntax);
2880
2881 if (info->mach == bfd_mach_i386_i386
2882 || info->mach == bfd_mach_x86_64
2883 || info->mach == bfd_mach_i386_i386_intel_syntax
2884 || info->mach == bfd_mach_x86_64_intel_syntax)
2885 priv.orig_sizeflag = AFLAG | DFLAG;
2886 else if (info->mach == bfd_mach_i386_i8086)
2887 priv.orig_sizeflag = 0;
2888 else
2889 abort ();
2890
2891 for (p = info->disassembler_options; p != NULL; )
2892 {
2893 if (CONST_STRNEQ (p, "x86-64"))
2894 {
2895 address_mode = mode_64bit;
2896 priv.orig_sizeflag = AFLAG | DFLAG;
2897 }
2898 else if (CONST_STRNEQ (p, "i386"))
2899 {
2900 address_mode = mode_32bit;
2901 priv.orig_sizeflag = AFLAG | DFLAG;
2902 }
2903 else if (CONST_STRNEQ (p, "i8086"))
2904 {
2905 address_mode = mode_16bit;
2906 priv.orig_sizeflag = 0;
2907 }
2908 else if (CONST_STRNEQ (p, "intel"))
2909 {
2910 intel_syntax = 1;
2911 }
2912 else if (CONST_STRNEQ (p, "att"))
2913 {
2914 intel_syntax = 0;
2915 }
2916 else if (CONST_STRNEQ (p, "addr"))
2917 {
2918 if (p[4] == '1' && p[5] == '6')
2919 priv.orig_sizeflag &= ~AFLAG;
2920 else if (p[4] == '3' && p[5] == '2')
2921 priv.orig_sizeflag |= AFLAG;
2922 }
2923 else if (CONST_STRNEQ (p, "data"))
2924 {
2925 if (p[4] == '1' && p[5] == '6')
2926 priv.orig_sizeflag &= ~DFLAG;
2927 else if (p[4] == '3' && p[5] == '2')
2928 priv.orig_sizeflag |= DFLAG;
2929 }
2930 else if (CONST_STRNEQ (p, "suffix"))
2931 priv.orig_sizeflag |= SUFFIX_ALWAYS;
2932
2933 p = strchr (p, ',');
2934 if (p != NULL)
2935 p++;
2936 }
2937
2938 if (intel_syntax)
2939 {
2940 names64 = intel_names64;
2941 names32 = intel_names32;
2942 names16 = intel_names16;
2943 names8 = intel_names8;
2944 names8rex = intel_names8rex;
2945 names_seg = intel_names_seg;
2946 index16 = intel_index16;
2947 open_char = '[';
2948 close_char = ']';
2949 separator_char = '+';
2950 scale_char = '*';
2951 }
2952 else
2953 {
2954 names64 = att_names64;
2955 names32 = att_names32;
2956 names16 = att_names16;
2957 names8 = att_names8;
2958 names8rex = att_names8rex;
2959 names_seg = att_names_seg;
2960 index16 = att_index16;
2961 open_char = '(';
2962 close_char = ')';
2963 separator_char = ',';
2964 scale_char = ',';
2965 }
2966
2967 /* The output looks better if we put 7 bytes on a line, since that
2968 puts most long word instructions on a single line. */
2969 info->bytes_per_line = 7;
2970
2971 info->private_data = &priv;
2972 priv.max_fetched = priv.the_buffer;
2973 priv.insn_start = pc;
2974
2975 obuf[0] = 0;
2976 op1out[0] = 0;
2977 op2out[0] = 0;
2978 op3out[0] = 0;
2979 op4out[0] = 0;
2980
2981 op_index[0] = op_index[1] = op_index[2] = op_index[3] = -1;
2982
2983 the_info = info;
2984 start_pc = pc;
2985 start_codep = priv.the_buffer;
2986 codep = priv.the_buffer;
2987
2988 if (setjmp (priv.bailout) != 0)
2989 {
2990 const char *name;
2991
2992 /* Getting here means we tried for data but didn't get it. That
2993 means we have an incomplete instruction of some sort. Just
2994 print the first byte as a prefix or a .byte pseudo-op. */
2995 if (codep > priv.the_buffer)
2996 {
2997 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2998 if (name != NULL)
2999 (*info->fprintf_func) (info->stream, "%s", name);
3000 else
3001 {
3002 /* Just print the first byte as a .byte instruction. */
3003 (*info->fprintf_func) (info->stream, ".byte 0x%x",
3004 (unsigned int) priv.the_buffer[0]);
3005 }
3006
3007 return 1;
3008 }
3009
3010 return -1;
3011 }
3012
3013 obufp = obuf;
3014 ckprefix ();
3015
3016 insn_codep = codep;
3017 sizeflag = priv.orig_sizeflag;
3018
3019 FETCH_DATA (info, codep + 1);
3020 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
3021
3022 if (((prefixes & PREFIX_FWAIT)
3023 && ((*codep < 0xd8) || (*codep > 0xdf)))
3024 || (rex && rex_used))
3025 {
3026 const char *name;
3027
3028 /* fwait not followed by floating point instruction, or rex followed
3029 by other prefixes. Print the first prefix. */
3030 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3031 if (name == NULL)
3032 name = INTERNAL_DISASSEMBLER_ERROR;
3033 (*info->fprintf_func) (info->stream, "%s", name);
3034 return 1;
3035 }
3036
3037 op = 0;
3038 if (*codep == 0x0f)
3039 {
3040 unsigned char threebyte;
3041 FETCH_DATA (info, codep + 2);
3042 threebyte = *++codep;
3043 dp = &dis386_twobyte[threebyte];
3044 need_modrm = twobyte_has_modrm[*codep];
3045 uses_DATA_prefix = twobyte_uses_DATA_prefix[*codep];
3046 uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[*codep];
3047 uses_REPZ_prefix = twobyte_uses_REPZ_prefix[*codep];
3048 uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
3049 codep++;
3050 if (dp->name == NULL && dp->bytemode1 == IS_3BYTE_OPCODE)
3051 {
3052 FETCH_DATA (info, codep + 2);
3053 op = *codep++;
3054 switch (threebyte)
3055 {
3056 case 0x38:
3057 uses_DATA_prefix = threebyte_0x38_uses_DATA_prefix[op];
3058 uses_REPNZ_prefix = threebyte_0x38_uses_REPNZ_prefix[op];
3059 uses_REPZ_prefix = threebyte_0x38_uses_REPZ_prefix[op];
3060 break;
3061 case 0x3a:
3062 uses_DATA_prefix = threebyte_0x3a_uses_DATA_prefix[op];
3063 uses_REPNZ_prefix = threebyte_0x3a_uses_REPNZ_prefix[op];
3064 uses_REPZ_prefix = threebyte_0x3a_uses_REPZ_prefix[op];
3065 break;
3066 default:
3067 break;
3068 }
3069 }
3070 }
3071 else
3072 {
3073 dp = &dis386[*codep];
3074 need_modrm = onebyte_has_modrm[*codep];
3075 uses_DATA_prefix = 0;
3076 uses_REPNZ_prefix = 0;
3077 uses_REPZ_prefix = 0;
3078 uses_LOCK_prefix = 0;
3079 codep++;
3080 }
3081
3082 if (!uses_REPZ_prefix && (prefixes & PREFIX_REPZ))
3083 {
3084 oappend ("repz ");
3085 used_prefixes |= PREFIX_REPZ;
3086 }
3087 if (!uses_REPNZ_prefix && (prefixes & PREFIX_REPNZ))
3088 {
3089 oappend ("repnz ");
3090 used_prefixes |= PREFIX_REPNZ;
3091 }
3092
3093 if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
3094 {
3095 oappend ("lock ");
3096 used_prefixes |= PREFIX_LOCK;
3097 }
3098
3099 if (prefixes & PREFIX_ADDR)
3100 {
3101 sizeflag ^= AFLAG;
3102 if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
3103 {
3104 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
3105 oappend ("addr32 ");
3106 else
3107 oappend ("addr16 ");
3108 used_prefixes |= PREFIX_ADDR;
3109 }
3110 }
3111
3112 if (!uses_DATA_prefix && (prefixes & PREFIX_DATA))
3113 {
3114 sizeflag ^= DFLAG;
3115 if (dp->bytemode3 == cond_jump_mode
3116 && dp->bytemode1 == v_mode
3117 && !intel_syntax)
3118 {
3119 if (sizeflag & DFLAG)
3120 oappend ("data32 ");
3121 else
3122 oappend ("data16 ");
3123 used_prefixes |= PREFIX_DATA;
3124 }
3125 }
3126
3127 if (dp->name == NULL && dp->bytemode1 == IS_3BYTE_OPCODE)
3128 {
3129 dp = &three_byte_table[dp->bytemode2][op];
3130 mod = (*codep >> 6) & 3;
3131 reg = (*codep >> 3) & 7;
3132 rm = *codep & 7;
3133 }
3134 else if (need_modrm)
3135 {
3136 FETCH_DATA (info, codep + 1);
3137 mod = (*codep >> 6) & 3;
3138 reg = (*codep >> 3) & 7;
3139 rm = *codep & 7;
3140 }
3141
3142 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
3143 {
3144 dofloat (sizeflag);
3145 }
3146 else
3147 {
3148 int index;
3149 if (dp->name == NULL)
3150 {
3151 switch (dp->bytemode1)
3152 {
3153 case USE_GROUPS:
3154 dp = &grps[dp->bytemode2][reg];
3155 break;
3156
3157 case USE_PREFIX_USER_TABLE:
3158 index = 0;
3159 used_prefixes |= (prefixes & PREFIX_REPZ);
3160 if (prefixes & PREFIX_REPZ)
3161 index = 1;
3162 else
3163 {
3164 /* We should check PREFIX_REPNZ and PREFIX_REPZ
3165 before PREFIX_DATA. */
3166 used_prefixes |= (prefixes & PREFIX_REPNZ);
3167 if (prefixes & PREFIX_REPNZ)
3168 index = 3;
3169 else
3170 {
3171 used_prefixes |= (prefixes & PREFIX_DATA);
3172 if (prefixes & PREFIX_DATA)
3173 index = 2;
3174 }
3175 }
3176 dp = &prefix_user_table[dp->bytemode2][index];
3177 break;
3178
3179 case X86_64_SPECIAL:
3180 index = address_mode == mode_64bit ? 1 : 0;
3181 dp = &x86_64_table[dp->bytemode2][index];
3182 break;
3183
3184 default:
3185 oappend (INTERNAL_DISASSEMBLER_ERROR);
3186 break;
3187 }
3188 }
3189
3190 if (putop (dp->name, sizeflag) == 0)
3191 {
3192 obufp = op1out;
3193 op_ad = 3;
3194 if (dp->op1)
3195 (*dp->op1) (dp->bytemode1, sizeflag);
3196
3197 obufp = op2out;
3198 op_ad = 2;
3199 if (dp->op2)
3200 (*dp->op2) (dp->bytemode2, sizeflag);
3201
3202 obufp = op3out;
3203 op_ad = 1;
3204 if (dp->op3)
3205 (*dp->op3) (dp->bytemode3, sizeflag);
3206
3207 obufp = op4out;
3208 op_ad = 0;
3209 if (dp->op4)
3210 (*dp->op4) (dp->bytemode4, sizeflag);
3211 }
3212 }
3213
3214 /* See if any prefixes were not used. If so, print the first one
3215 separately. If we don't do this, we'll wind up printing an
3216 instruction stream which does not precisely correspond to the
3217 bytes we are disassembling. */
3218 if ((prefixes & ~used_prefixes) != 0)
3219 {
3220 const char *name;
3221
3222 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3223 if (name == NULL)
3224 name = INTERNAL_DISASSEMBLER_ERROR;
3225 (*info->fprintf_func) (info->stream, "%s", name);
3226 return 1;
3227 }
3228 if (rex & ~rex_used)
3229 {
3230 const char *name;
3231 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
3232 if (name == NULL)
3233 name = INTERNAL_DISASSEMBLER_ERROR;
3234 (*info->fprintf_func) (info->stream, "%s ", name);
3235 }
3236
3237 obufp = obuf + strlen (obuf);
3238 for (i = strlen (obuf); i < 6; i++)
3239 oappend (" ");
3240 oappend (" ");
3241 (*info->fprintf_func) (info->stream, "%s", obuf);
3242
3243 /* The enter and bound instructions are printed with operands in the same
3244 order as the intel book; everything else is printed in reverse order. */
3245 if (intel_syntax || two_source_ops)
3246 {
3247 first = op1out;
3248 second = op2out;
3249 third = op3out;
3250 fourth = op4out;
3251 op_ad = op_index[0];
3252 op_index[0] = op_index[3];
3253 op_index[3] = op_ad;
3254 op_ad = op_index[1];
3255 op_index[1] = op_index[2];
3256 op_index[2] = op_ad;
3257
3258 }
3259 else
3260 {
3261 first = op4out;
3262 second = op3out;
3263 third = op2out;
3264 fourth = op1out;
3265 }
3266 needcomma = 0;
3267 if (*first)
3268 {
3269 if (op_index[0] != -1 && !op_riprel[0])
3270 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
3271 else
3272 (*info->fprintf_func) (info->stream, "%s", first);
3273 needcomma = 1;
3274 }
3275
3276 if (*second)
3277 {
3278 if (needcomma)
3279 (*info->fprintf_func) (info->stream, ",");
3280 if (op_index[1] != -1 && !op_riprel[1])
3281 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
3282 else
3283 (*info->fprintf_func) (info->stream, "%s", second);
3284 needcomma = 1;
3285 }
3286
3287 if (*third)
3288 {
3289 if (needcomma)
3290 (*info->fprintf_func) (info->stream, ",");
3291 if (op_index[2] != -1 && !op_riprel[2])
3292 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
3293 else
3294 (*info->fprintf_func) (info->stream, "%s", third);
3295 needcomma = 1;
3296 }
3297
3298 if (*fourth)
3299 {
3300 if (needcomma)
3301 (*info->fprintf_func) (info->stream, ",");
3302 if (op_index[3] != -1 && !op_riprel[3])
3303 (*info->print_address_func) ((bfd_vma) op_address[op_index[3]], info);
3304 else
3305 (*info->fprintf_func) (info->stream, "%s", fourth);
3306 }
3307
3308 for (i = 0; i < 4; i++)
3309 if (op_index[i] != -1 && op_riprel[i])
3310 {
3311 (*info->fprintf_func) (info->stream, " # ");
3312 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
3313 + op_address[op_index[i]]), info);
3314 }
3315 return codep - priv.the_buffer;
3316 }
3317
3318 static const char *float_mem[] = {
3319 /* d8 */
3320 "fadd{s||s|}",
3321 "fmul{s||s|}",
3322 "fcom{s||s|}",
3323 "fcomp{s||s|}",
3324 "fsub{s||s|}",
3325 "fsubr{s||s|}",
3326 "fdiv{s||s|}",
3327 "fdivr{s||s|}",
3328 /* d9 */
3329 "fld{s||s|}",
3330 "(bad)",
3331 "fst{s||s|}",
3332 "fstp{s||s|}",
3333 "fldenvIC",
3334 "fldcw",
3335 "fNstenvIC",
3336 "fNstcw",
3337 /* da */
3338 "fiadd{l||l|}",
3339 "fimul{l||l|}",
3340 "ficom{l||l|}",
3341 "ficomp{l||l|}",
3342 "fisub{l||l|}",
3343 "fisubr{l||l|}",
3344 "fidiv{l||l|}",
3345 "fidivr{l||l|}",
3346 /* db */
3347 "fild{l||l|}",
3348 "fisttp{l||l|}",
3349 "fist{l||l|}",
3350 "fistp{l||l|}",
3351 "(bad)",
3352 "fld{t||t|}",
3353 "(bad)",
3354 "fstp{t||t|}",
3355 /* dc */
3356 "fadd{l||l|}",
3357 "fmul{l||l|}",
3358 "fcom{l||l|}",
3359 "fcomp{l||l|}",
3360 "fsub{l||l|}",
3361 "fsubr{l||l|}",
3362 "fdiv{l||l|}",
3363 "fdivr{l||l|}",
3364 /* dd */
3365 "fld{l||l|}",
3366 "fisttp{ll||ll|}",
3367 "fst{l||l|}",
3368 "fstp{l||l|}",
3369 "frstorIC",
3370 "(bad)",
3371 "fNsaveIC",
3372 "fNstsw",
3373 /* de */
3374 "fiadd",
3375 "fimul",
3376 "ficom",
3377 "ficomp",
3378 "fisub",
3379 "fisubr",
3380 "fidiv",
3381 "fidivr",
3382 /* df */
3383 "fild",
3384 "fisttp",
3385 "fist",
3386 "fistp",
3387 "fbld",
3388 "fild{ll||ll|}",
3389 "fbstp",
3390 "fistp{ll||ll|}",
3391 };
3392
3393 static const unsigned char float_mem_mode[] = {
3394 /* d8 */
3395 d_mode,
3396 d_mode,
3397 d_mode,
3398 d_mode,
3399 d_mode,
3400 d_mode,
3401 d_mode,
3402 d_mode,
3403 /* d9 */
3404 d_mode,
3405 0,
3406 d_mode,
3407 d_mode,
3408 0,
3409 w_mode,
3410 0,
3411 w_mode,
3412 /* da */
3413 d_mode,
3414 d_mode,
3415 d_mode,
3416 d_mode,
3417 d_mode,
3418 d_mode,
3419 d_mode,
3420 d_mode,
3421 /* db */
3422 d_mode,
3423 d_mode,
3424 d_mode,
3425 d_mode,
3426 0,
3427 t_mode,
3428 0,
3429 t_mode,
3430 /* dc */
3431 q_mode,
3432 q_mode,
3433 q_mode,
3434 q_mode,
3435 q_mode,
3436 q_mode,
3437 q_mode,
3438 q_mode,
3439 /* dd */
3440 q_mode,
3441 q_mode,
3442 q_mode,
3443 q_mode,
3444 0,
3445 0,
3446 0,
3447 w_mode,
3448 /* de */
3449 w_mode,
3450 w_mode,
3451 w_mode,
3452 w_mode,
3453 w_mode,
3454 w_mode,
3455 w_mode,
3456 w_mode,
3457 /* df */
3458 w_mode,
3459 w_mode,
3460 w_mode,
3461 w_mode,
3462 t_mode,
3463 q_mode,
3464 t_mode,
3465 q_mode
3466 };
3467
3468 #define ST OP_ST, 0
3469 #define STi OP_STi, 0
3470
3471 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0, NULL, 0
3472 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0, NULL, 0
3473 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0, NULL, 0
3474 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0, NULL, 0
3475 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0, NULL, 0
3476 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0, NULL, 0
3477 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0, NULL, 0
3478 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0, NULL, 0
3479 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0, NULL, 0
3480
3481 static const struct dis386 float_reg[][8] = {
3482 /* d8 */
3483 {
3484 { "fadd", ST, STi, XX, XX },
3485 { "fmul", ST, STi, XX, XX },
3486 { "fcom", STi, XX, XX, XX },
3487 { "fcomp", STi, XX, XX, XX },
3488 { "fsub", ST, STi, XX, XX },
3489 { "fsubr", ST, STi, XX, XX },
3490 { "fdiv", ST, STi, XX, XX },
3491 { "fdivr", ST, STi, XX, XX },
3492 },
3493 /* d9 */
3494 {
3495 { "fld", STi, XX, XX, XX },
3496 { "fxch", STi, XX, XX, XX },
3497 { FGRPd9_2 },
3498 { "(bad)", XX, XX, XX, XX },
3499 { FGRPd9_4 },
3500 { FGRPd9_5 },
3501 { FGRPd9_6 },
3502 { FGRPd9_7 },
3503 },
3504 /* da */
3505 {
3506 { "fcmovb", ST, STi, XX, XX },
3507 { "fcmove", ST, STi, XX, XX },
3508 { "fcmovbe",ST, STi, XX, XX },
3509 { "fcmovu", ST, STi, XX, XX },
3510 { "(bad)", XX, XX, XX, XX },
3511 { FGRPda_5 },
3512 { "(bad)", XX, XX, XX, XX },
3513 { "(bad)", XX, XX, XX, XX },
3514 },
3515 /* db */
3516 {
3517 { "fcmovnb",ST, STi, XX, XX },
3518 { "fcmovne",ST, STi, XX, XX },
3519 { "fcmovnbe",ST, STi, XX, XX },
3520 { "fcmovnu",ST, STi, XX, XX },
3521 { FGRPdb_4 },
3522 { "fucomi", ST, STi, XX, XX },
3523 { "fcomi", ST, STi, XX, XX },
3524 { "(bad)", XX, XX, XX, XX },
3525 },
3526 /* dc */
3527 {
3528 { "fadd", STi, ST, XX, XX },
3529 { "fmul", STi, ST, XX, XX },
3530 { "(bad)", XX, XX, XX, XX },
3531 { "(bad)", XX, XX, XX, XX },
3532 #if UNIXWARE_COMPAT
3533 { "fsub", STi, ST, XX, XX },
3534 { "fsubr", STi, ST, XX, XX },
3535 { "fdiv", STi, ST, XX, XX },
3536 { "fdivr", STi, ST, XX, XX },
3537 #else
3538 { "fsubr", STi, ST, XX, XX },
3539 { "fsub", STi, ST, XX, XX },
3540 { "fdivr", STi, ST, XX, XX },
3541 { "fdiv", STi, ST, XX, XX },
3542 #endif
3543 },
3544 /* dd */
3545 {
3546 { "ffree", STi, XX, XX, XX },
3547 { "(bad)", XX, XX, XX, XX },
3548 { "fst", STi, XX, XX, XX },
3549 { "fstp", STi, XX, XX, XX },
3550 { "fucom", STi, XX, XX, XX },
3551 { "fucomp", STi, XX, XX, XX },
3552 { "(bad)", XX, XX, XX, XX },
3553 { "(bad)", XX, XX, XX, XX },
3554 },
3555 /* de */
3556 {
3557 { "faddp", STi, ST, XX, XX },
3558 { "fmulp", STi, ST, XX, XX },
3559 { "(bad)", XX, XX, XX, XX },
3560 { FGRPde_3 },
3561 #if UNIXWARE_COMPAT
3562 { "fsubp", STi, ST, XX, XX },
3563 { "fsubrp", STi, ST, XX, XX },
3564 { "fdivp", STi, ST, XX, XX },
3565 { "fdivrp", STi, ST, XX, XX },
3566 #else
3567 { "fsubrp", STi, ST, XX, XX },
3568 { "fsubp", STi, ST, XX, XX },
3569 { "fdivrp", STi, ST, XX, XX },
3570 { "fdivp", STi, ST, XX, XX },
3571 #endif
3572 },
3573 /* df */
3574 {
3575 { "ffreep", STi, XX, XX, XX },
3576 { "(bad)", XX, XX, XX, XX },
3577 { "(bad)", XX, XX, XX, XX },
3578 { "(bad)", XX, XX, XX, XX },
3579 { FGRPdf_4 },
3580 { "fucomip",ST, STi, XX, XX },
3581 { "fcomip", ST, STi, XX, XX },
3582 { "(bad)", XX, XX, XX, XX },
3583 },
3584 };
3585
3586 static char *fgrps[][8] = {
3587 /* d9_2 0 */
3588 {
3589 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3590 },
3591
3592 /* d9_4 1 */
3593 {
3594 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
3595 },
3596
3597 /* d9_5 2 */
3598 {
3599 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
3600 },
3601
3602 /* d9_6 3 */
3603 {
3604 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
3605 },
3606
3607 /* d9_7 4 */
3608 {
3609 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
3610 },
3611
3612 /* da_5 5 */
3613 {
3614 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3615 },
3616
3617 /* db_4 6 */
3618 {
3619 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
3620 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
3621 },
3622
3623 /* de_3 7 */
3624 {
3625 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3626 },
3627
3628 /* df_4 8 */
3629 {
3630 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3631 },
3632 };
3633
3634 static void
3635 dofloat (int sizeflag)
3636 {
3637 const struct dis386 *dp;
3638 unsigned char floatop;
3639
3640 floatop = codep[-1];
3641
3642 if (mod != 3)
3643 {
3644 int fp_indx = (floatop - 0xd8) * 8 + reg;
3645
3646 putop (float_mem[fp_indx], sizeflag);
3647 obufp = op1out;
3648 op_ad = 2;
3649 OP_E (float_mem_mode[fp_indx], sizeflag);
3650 return;
3651 }
3652 /* Skip mod/rm byte. */
3653 MODRM_CHECK;
3654 codep++;
3655
3656 dp = &float_reg[floatop - 0xd8][reg];
3657 if (dp->name == NULL)
3658 {
3659 putop (fgrps[dp->bytemode1][rm], sizeflag);
3660
3661 /* Instruction fnstsw is only one with strange arg. */
3662 if (floatop == 0xdf && codep[-1] == 0xe0)
3663 strcpy (op1out, names16[0]);
3664 }
3665 else
3666 {
3667 putop (dp->name, sizeflag);
3668
3669 obufp = op1out;
3670 op_ad = 2;
3671 if (dp->op1)
3672 (*dp->op1) (dp->bytemode1, sizeflag);
3673
3674 obufp = op2out;
3675 op_ad = 1;
3676 if (dp->op2)
3677 (*dp->op2) (dp->bytemode2, sizeflag);
3678 }
3679 }
3680
3681 static void
3682 OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3683 {
3684 oappend ("%st" + intel_syntax);
3685 }
3686
3687 static void
3688 OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3689 {
3690 sprintf (scratchbuf, "%%st(%d)", rm);
3691 oappend (scratchbuf + intel_syntax);
3692 }
3693
3694 /* Capital letters in template are macros. */
3695 static int
3696 putop (const char *template, int sizeflag)
3697 {
3698 const char *p;
3699 int alt = 0;
3700
3701 for (p = template; *p; p++)
3702 {
3703 switch (*p)
3704 {
3705 default:
3706 *obufp++ = *p;
3707 break;
3708 case '{':
3709 alt = 0;
3710 if (intel_syntax)
3711 alt += 1;
3712 if (address_mode == mode_64bit)
3713 alt += 2;
3714 while (alt != 0)
3715 {
3716 while (*++p != '|')
3717 {
3718 if (*p == '}')
3719 {
3720 /* Alternative not valid. */
3721 strcpy (obuf, "(bad)");
3722 obufp = obuf + 5;
3723 return 1;
3724 }
3725 else if (*p == '\0')
3726 abort ();
3727 }
3728 alt--;
3729 }
3730 /* Fall through. */
3731 case 'I':
3732 alt = 1;
3733 continue;
3734 case '|':
3735 while (*++p != '}')
3736 {
3737 if (*p == '\0')
3738 abort ();
3739 }
3740 break;
3741 case '}':
3742 break;
3743 case 'A':
3744 if (intel_syntax)
3745 break;
3746 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
3747 *obufp++ = 'b';
3748 break;
3749 case 'B':
3750 if (intel_syntax)
3751 break;
3752 if (sizeflag & SUFFIX_ALWAYS)
3753 *obufp++ = 'b';
3754 break;
3755 case 'C':
3756 if (intel_syntax && !alt)
3757 break;
3758 if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
3759 {
3760 if (sizeflag & DFLAG)
3761 *obufp++ = intel_syntax ? 'd' : 'l';
3762 else
3763 *obufp++ = intel_syntax ? 'w' : 's';
3764 used_prefixes |= (prefixes & PREFIX_DATA);
3765 }
3766 break;
3767 case 'D':
3768 if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
3769 break;
3770 USED_REX (REX_MODE64);
3771 if (mod == 3)
3772 {
3773 if (rex & REX_MODE64)
3774 *obufp++ = 'q';
3775 else if (sizeflag & DFLAG)
3776 *obufp++ = intel_syntax ? 'd' : 'l';
3777 else
3778 *obufp++ = 'w';
3779 used_prefixes |= (prefixes & PREFIX_DATA);
3780 }
3781 else
3782 *obufp++ = 'w';
3783 break;
3784 case 'E': /* For jcxz/jecxz */
3785 if (address_mode == mode_64bit)
3786 {
3787 if (sizeflag & AFLAG)
3788 *obufp++ = 'r';
3789 else
3790 *obufp++ = 'e';
3791 }
3792 else
3793 if (sizeflag & AFLAG)
3794 *obufp++ = 'e';
3795 used_prefixes |= (prefixes & PREFIX_ADDR);
3796 break;
3797 case 'F':
3798 if (intel_syntax)
3799 break;
3800 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
3801 {
3802 if (sizeflag & AFLAG)
3803 *obufp++ = address_mode == mode_64bit ? 'q' : 'l';
3804 else
3805 *obufp++ = address_mode == mode_64bit ? 'l' : 'w';
3806 used_prefixes |= (prefixes & PREFIX_ADDR);
3807 }
3808 break;
3809 case 'G':
3810 if (intel_syntax || (obufp[-1] != 's' && !(sizeflag & SUFFIX_ALWAYS)))
3811 break;
3812 if ((rex & REX_MODE64) || (sizeflag & DFLAG))
3813 *obufp++ = 'l';
3814 else
3815 *obufp++ = 'w';
3816 if (!(rex & REX_MODE64))
3817 used_prefixes |= (prefixes & PREFIX_DATA);
3818 break;
3819 case 'H':
3820 if (intel_syntax)
3821 break;
3822 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
3823 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
3824 {
3825 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
3826 *obufp++ = ',';
3827 *obufp++ = 'p';
3828 if (prefixes & PREFIX_DS)
3829 *obufp++ = 't';
3830 else
3831 *obufp++ = 'n';
3832 }
3833 break;
3834 case 'J':
3835 if (intel_syntax)
3836 break;
3837 *obufp++ = 'l';
3838 break;
3839 case 'Z':
3840 if (intel_syntax)
3841 break;
3842 if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS))
3843 {
3844 *obufp++ = 'q';
3845 break;
3846 }
3847 /* Fall through. */
3848 case 'L':
3849 if (intel_syntax)
3850 break;
3851 if (sizeflag & SUFFIX_ALWAYS)
3852 *obufp++ = 'l';
3853 break;
3854 case 'N':
3855 if ((prefixes & PREFIX_FWAIT) == 0)
3856 *obufp++ = 'n';
3857 else
3858 used_prefixes |= PREFIX_FWAIT;
3859 break;
3860 case 'O':
3861 USED_REX (REX_MODE64);
3862 if (rex & REX_MODE64)
3863 *obufp++ = 'o';
3864 else if (intel_syntax && (sizeflag & DFLAG))
3865 *obufp++ = 'q';
3866 else
3867 *obufp++ = 'd';
3868 if (!(rex & REX_MODE64))
3869 used_prefixes |= (prefixes & PREFIX_DATA);
3870 break;
3871 case 'T':
3872 if (intel_syntax)
3873 break;
3874 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3875 {
3876 *obufp++ = 'q';
3877 break;
3878 }
3879 /* Fall through. */
3880 case 'P':
3881 if (intel_syntax)
3882 break;
3883 if ((prefixes & PREFIX_DATA)
3884 || (rex & REX_MODE64)
3885 || (sizeflag & SUFFIX_ALWAYS))
3886 {
3887 USED_REX (REX_MODE64);
3888 if (rex & REX_MODE64)
3889 *obufp++ = 'q';
3890 else
3891 {
3892 if (sizeflag & DFLAG)
3893 *obufp++ = 'l';
3894 else
3895 *obufp++ = 'w';
3896 }
3897 used_prefixes |= (prefixes & PREFIX_DATA);
3898 }
3899 break;
3900 case 'U':
3901 if (intel_syntax)
3902 break;
3903 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3904 {
3905 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
3906 *obufp++ = 'q';
3907 break;
3908 }
3909 /* Fall through. */
3910 case 'Q':
3911 if (intel_syntax && !alt)
3912 break;
3913 USED_REX (REX_MODE64);
3914 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
3915 {
3916 if (rex & REX_MODE64)
3917 *obufp++ = 'q';
3918 else
3919 {
3920 if (sizeflag & DFLAG)
3921 *obufp++ = intel_syntax ? 'd' : 'l';
3922 else
3923 *obufp++ = 'w';
3924 }
3925 used_prefixes |= (prefixes & PREFIX_DATA);
3926 }
3927 break;
3928 case 'R':
3929 USED_REX (REX_MODE64);
3930 if (rex & REX_MODE64)
3931 *obufp++ = 'q';
3932 else if (sizeflag & DFLAG)
3933 {
3934 if (intel_syntax)
3935 *obufp++ = 'd';
3936 else
3937 *obufp++ = 'l';
3938 }
3939 else
3940 *obufp++ = 'w';
3941 if (intel_syntax && !p[1]
3942 && ((rex & REX_MODE64) || (sizeflag & DFLAG)))
3943 *obufp++ = 'e';
3944 if (!(rex & REX_MODE64))
3945 used_prefixes |= (prefixes & PREFIX_DATA);
3946 break;
3947 case 'V':
3948 if (intel_syntax)
3949 break;
3950 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3951 {
3952 if (sizeflag & SUFFIX_ALWAYS)
3953 *obufp++ = 'q';
3954 break;
3955 }
3956 /* Fall through. */
3957 case 'S':
3958 if (intel_syntax)
3959 break;
3960 if (sizeflag & SUFFIX_ALWAYS)
3961 {
3962 if (rex & REX_MODE64)
3963 *obufp++ = 'q';
3964 else
3965 {
3966 if (sizeflag & DFLAG)
3967 *obufp++ = 'l';
3968 else
3969 *obufp++ = 'w';
3970 used_prefixes |= (prefixes & PREFIX_DATA);
3971 }
3972 }
3973 break;
3974 case 'X':
3975 if (prefixes & PREFIX_DATA)
3976 *obufp++ = 'd';
3977 else
3978 *obufp++ = 's';
3979 used_prefixes |= (prefixes & PREFIX_DATA);
3980 break;
3981 case 'Y':
3982 if (intel_syntax)
3983 break;
3984 if (rex & REX_MODE64)
3985 {
3986 USED_REX (REX_MODE64);
3987 *obufp++ = 'q';
3988 }
3989 break;
3990 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
3991 case 'W':
3992 /* operand size flag for cwtl, cbtw */
3993 USED_REX (REX_MODE64);
3994 if (rex & REX_MODE64)
3995 {
3996 if (intel_syntax)
3997 *obufp++ = 'd';
3998 else
3999 *obufp++ = 'l';
4000 }
4001 else if (sizeflag & DFLAG)
4002 *obufp++ = 'w';
4003 else
4004 *obufp++ = 'b';
4005 if (!(rex & REX_MODE64))
4006 used_prefixes |= (prefixes & PREFIX_DATA);
4007 break;
4008 }
4009 alt = 0;
4010 }
4011 *obufp = 0;
4012 return 0;
4013 }
4014
4015 static void
4016 oappend (const char *s)
4017 {
4018 strcpy (obufp, s);
4019 obufp += strlen (s);
4020 }
4021
4022 static void
4023 append_seg (void)
4024 {
4025 if (prefixes & PREFIX_CS)
4026 {
4027 used_prefixes |= PREFIX_CS;
4028 oappend ("%cs:" + intel_syntax);
4029 }
4030 if (prefixes & PREFIX_DS)
4031 {
4032 used_prefixes |= PREFIX_DS;
4033 oappend ("%ds:" + intel_syntax);
4034 }
4035 if (prefixes & PREFIX_SS)
4036 {
4037 used_prefixes |= PREFIX_SS;
4038 oappend ("%ss:" + intel_syntax);
4039 }
4040 if (prefixes & PREFIX_ES)
4041 {
4042 used_prefixes |= PREFIX_ES;
4043 oappend ("%es:" + intel_syntax);
4044 }
4045 if (prefixes & PREFIX_FS)
4046 {
4047 used_prefixes |= PREFIX_FS;
4048 oappend ("%fs:" + intel_syntax);
4049 }
4050 if (prefixes & PREFIX_GS)
4051 {
4052 used_prefixes |= PREFIX_GS;
4053 oappend ("%gs:" + intel_syntax);
4054 }
4055 }
4056
4057 static void
4058 OP_indirE (int bytemode, int sizeflag)
4059 {
4060 if (!intel_syntax)
4061 oappend ("*");
4062 OP_E (bytemode, sizeflag);
4063 }
4064
4065 static void
4066 print_operand_value (char *buf, int hex, bfd_vma disp)
4067 {
4068 if (address_mode == mode_64bit)
4069 {
4070 if (hex)
4071 {
4072 char tmp[30];
4073 int i;
4074 buf[0] = '0';
4075 buf[1] = 'x';
4076 sprintf_vma (tmp, disp);
4077 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
4078 strcpy (buf + 2, tmp + i);
4079 }
4080 else
4081 {
4082 bfd_signed_vma v = disp;
4083 char tmp[30];
4084 int i;
4085 if (v < 0)
4086 {
4087 *(buf++) = '-';
4088 v = -disp;
4089 /* Check for possible overflow on 0x8000000000000000. */
4090 if (v < 0)
4091 {
4092 strcpy (buf, "9223372036854775808");
4093 return;
4094 }
4095 }
4096 if (!v)
4097 {
4098 strcpy (buf, "0");
4099 return;
4100 }
4101
4102 i = 0;
4103 tmp[29] = 0;
4104 while (v)
4105 {
4106 tmp[28 - i] = (v % 10) + '0';
4107 v /= 10;
4108 i++;
4109 }
4110 strcpy (buf, tmp + 29 - i);
4111 }
4112 }
4113 else
4114 {
4115 if (hex)
4116 sprintf (buf, "0x%x", (unsigned int) disp);
4117 else
4118 sprintf (buf, "%d", (int) disp);
4119 }
4120 }
4121
4122 static void
4123 intel_operand_size (int bytemode, int sizeflag)
4124 {
4125 switch (bytemode)
4126 {
4127 case b_mode:
4128 oappend ("BYTE PTR ");
4129 break;
4130 case w_mode:
4131 case dqw_mode:
4132 oappend ("WORD PTR ");
4133 break;
4134 case stack_v_mode:
4135 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4136 {
4137 oappend ("QWORD PTR ");
4138 used_prefixes |= (prefixes & PREFIX_DATA);
4139 break;
4140 }
4141 /* FALLTHRU */
4142 case v_mode:
4143 case dq_mode:
4144 USED_REX (REX_MODE64);
4145 if (rex & REX_MODE64)
4146 oappend ("QWORD PTR ");
4147 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
4148 oappend ("DWORD PTR ");
4149 else
4150 oappend ("WORD PTR ");
4151 used_prefixes |= (prefixes & PREFIX_DATA);
4152 break;
4153 case z_mode:
4154 if ((rex & REX_MODE64) || (sizeflag & DFLAG))
4155 *obufp++ = 'D';
4156 oappend ("WORD PTR ");
4157 if (!(rex & REX_MODE64))
4158 used_prefixes |= (prefixes & PREFIX_DATA);
4159 break;
4160 case d_mode:
4161 oappend ("DWORD PTR ");
4162 break;
4163 case q_mode:
4164 oappend ("QWORD PTR ");
4165 break;
4166 case m_mode:
4167 if (address_mode == mode_64bit)
4168 oappend ("QWORD PTR ");
4169 else
4170 oappend ("DWORD PTR ");
4171 break;
4172 case f_mode:
4173 if (sizeflag & DFLAG)
4174 oappend ("FWORD PTR ");
4175 else
4176 oappend ("DWORD PTR ");
4177 used_prefixes |= (prefixes & PREFIX_DATA);
4178 break;
4179 case t_mode:
4180 oappend ("TBYTE PTR ");
4181 break;
4182 case x_mode:
4183 oappend ("XMMWORD PTR ");
4184 break;
4185 default:
4186 break;
4187 }
4188 }
4189
4190 static void
4191 OP_E (int bytemode, int sizeflag)
4192 {
4193 bfd_vma disp;
4194 int add = 0;
4195 int riprel = 0;
4196 USED_REX (REX_EXTZ);
4197 if (rex & REX_EXTZ)
4198 add += 8;
4199
4200 /* Skip mod/rm byte. */
4201 MODRM_CHECK;
4202 codep++;
4203
4204 if (mod == 3)
4205 {
4206 switch (bytemode)
4207 {
4208 case b_mode:
4209 USED_REX (0);
4210 if (rex)
4211 oappend (names8rex[rm + add]);
4212 else
4213 oappend (names8[rm + add]);
4214 break;
4215 case w_mode:
4216 oappend (names16[rm + add]);
4217 break;
4218 case d_mode:
4219 oappend (names32[rm + add]);
4220 break;
4221 case q_mode:
4222 oappend (names64[rm + add]);
4223 break;
4224 case m_mode:
4225 if (address_mode == mode_64bit)
4226 oappend (names64[rm + add]);
4227 else
4228 oappend (names32[rm + add]);
4229 break;
4230 case stack_v_mode:
4231 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4232 {
4233 oappend (names64[rm + add]);
4234 used_prefixes |= (prefixes & PREFIX_DATA);
4235 break;
4236 }
4237 bytemode = v_mode;
4238 /* FALLTHRU */
4239 case v_mode:
4240 case dq_mode:
4241 case dqw_mode:
4242 USED_REX (REX_MODE64);
4243 if (rex & REX_MODE64)
4244 oappend (names64[rm + add]);
4245 else if ((sizeflag & DFLAG) || bytemode != v_mode)
4246 oappend (names32[rm + add]);
4247 else
4248 oappend (names16[rm + add]);
4249 used_prefixes |= (prefixes & PREFIX_DATA);
4250 break;
4251 case 0:
4252 break;
4253 default:
4254 oappend (INTERNAL_DISASSEMBLER_ERROR);
4255 break;
4256 }
4257 return;
4258 }
4259
4260 disp = 0;
4261 if (intel_syntax)
4262 intel_operand_size (bytemode, sizeflag);
4263 append_seg ();
4264
4265 if ((sizeflag & AFLAG) || address_mode == mode_64bit) /* 32 bit address mode */
4266 {
4267 int havesib;
4268 int havebase;
4269 int base;
4270 int index = 0;
4271 int scale = 0;
4272
4273 havesib = 0;
4274 havebase = 1;
4275 base = rm;
4276
4277 if (base == 4)
4278 {
4279 havesib = 1;
4280 FETCH_DATA (the_info, codep + 1);
4281 index = (*codep >> 3) & 7;
4282 if (address_mode == mode_64bit || index != 0x4)
4283 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
4284 scale = (*codep >> 6) & 3;
4285 base = *codep & 7;
4286 USED_REX (REX_EXTY);
4287 if (rex & REX_EXTY)
4288 index += 8;
4289 codep++;
4290 }
4291 base += add;
4292
4293 switch (mod)
4294 {
4295 case 0:
4296 if ((base & 7) == 5)
4297 {
4298 havebase = 0;
4299 if (address_mode == mode_64bit && !havesib)
4300 riprel = 1;
4301 disp = get32s ();
4302 }
4303 break;
4304 case 1:
4305 FETCH_DATA (the_info, codep + 1);
4306 disp = *codep++;
4307 if ((disp & 0x80) != 0)
4308 disp -= 0x100;
4309 break;
4310 case 2:
4311 disp = get32s ();
4312 break;
4313 }
4314
4315 if (!intel_syntax)
4316 if (mod != 0 || (base & 7) == 5)
4317 {
4318 print_operand_value (scratchbuf, !riprel, disp);
4319 oappend (scratchbuf);
4320 if (riprel)
4321 {
4322 set_op (disp, 1);
4323 oappend ("(%rip)");
4324 }
4325 }
4326
4327 if (havebase || (havesib && (index != 4 || scale != 0)))
4328 {
4329 *obufp++ = open_char;
4330 if (intel_syntax && riprel)
4331 oappend ("rip + ");
4332 *obufp = '\0';
4333 if (havebase)
4334 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
4335 ? names64[base] : names32[base]);
4336 if (havesib)
4337 {
4338 if (index != 4)
4339 {
4340 if (!intel_syntax || havebase)
4341 {
4342 *obufp++ = separator_char;
4343 *obufp = '\0';
4344 }
4345 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
4346 ? names64[index] : names32[index]);
4347 }
4348 if (scale != 0 || (!intel_syntax && index != 4))
4349 {
4350 *obufp++ = scale_char;
4351 *obufp = '\0';
4352 sprintf (scratchbuf, "%d", 1 << scale);
4353 oappend (scratchbuf);
4354 }
4355 }
4356 if (intel_syntax && disp)
4357 {
4358 if ((bfd_signed_vma) disp > 0)
4359 {
4360 *obufp++ = '+';
4361 *obufp = '\0';
4362 }
4363 else if (mod != 1)
4364 {
4365 *obufp++ = '-';
4366 *obufp = '\0';
4367 disp = - (bfd_signed_vma) disp;
4368 }
4369
4370 print_operand_value (scratchbuf, mod != 1, disp);
4371 oappend (scratchbuf);
4372 }
4373
4374 *obufp++ = close_char;
4375 *obufp = '\0';
4376 }
4377 else if (intel_syntax)
4378 {
4379 if (mod != 0 || (base & 7) == 5)
4380 {
4381 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4382 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
4383 ;
4384 else
4385 {
4386 oappend (names_seg[ds_reg - es_reg]);
4387 oappend (":");
4388 }
4389 print_operand_value (scratchbuf, 1, disp);
4390 oappend (scratchbuf);
4391 }
4392 }
4393 }
4394 else
4395 { /* 16 bit address mode */
4396 switch (mod)
4397 {
4398 case 0:
4399 if (rm == 6)
4400 {
4401 disp = get16 ();
4402 if ((disp & 0x8000) != 0)
4403 disp -= 0x10000;
4404 }
4405 break;
4406 case 1:
4407 FETCH_DATA (the_info, codep + 1);
4408 disp = *codep++;
4409 if ((disp & 0x80) != 0)
4410 disp -= 0x100;
4411 break;
4412 case 2:
4413 disp = get16 ();
4414 if ((disp & 0x8000) != 0)
4415 disp -= 0x10000;
4416 break;
4417 }
4418
4419 if (!intel_syntax)
4420 if (mod != 0 || rm == 6)
4421 {
4422 print_operand_value (scratchbuf, 0, disp);
4423 oappend (scratchbuf);
4424 }
4425
4426 if (mod != 0 || rm != 6)
4427 {
4428 *obufp++ = open_char;
4429 *obufp = '\0';
4430 oappend (index16[rm]);
4431 if (intel_syntax && disp)
4432 {
4433 if ((bfd_signed_vma) disp > 0)
4434 {
4435 *obufp++ = '+';
4436 *obufp = '\0';
4437 }
4438 else if (mod != 1)
4439 {
4440 *obufp++ = '-';
4441 *obufp = '\0';
4442 disp = - (bfd_signed_vma) disp;
4443 }
4444
4445 print_operand_value (scratchbuf, mod != 1, disp);
4446 oappend (scratchbuf);
4447 }
4448
4449 *obufp++ = close_char;
4450 *obufp = '\0';
4451 }
4452 else if (intel_syntax)
4453 {
4454 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4455 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
4456 ;
4457 else
4458 {
4459 oappend (names_seg[ds_reg - es_reg]);
4460 oappend (":");
4461 }
4462 print_operand_value (scratchbuf, 1, disp & 0xffff);
4463 oappend (scratchbuf);
4464 }
4465 }
4466 }
4467
4468 static void
4469 OP_G (int bytemode, int sizeflag)
4470 {
4471 int add = 0;
4472 USED_REX (REX_EXTX);
4473 if (rex & REX_EXTX)
4474 add += 8;
4475 switch (bytemode)
4476 {
4477 case b_mode:
4478 USED_REX (0);
4479 if (rex)
4480 oappend (names8rex[reg + add]);
4481 else
4482 oappend (names8[reg + add]);
4483 break;
4484 case w_mode:
4485 oappend (names16[reg + add]);
4486 break;
4487 case d_mode:
4488 oappend (names32[reg + add]);
4489 break;
4490 case q_mode:
4491 oappend (names64[reg + add]);
4492 break;
4493 case v_mode:
4494 case dq_mode:
4495 case dqw_mode:
4496 USED_REX (REX_MODE64);
4497 if (rex & REX_MODE64)
4498 oappend (names64[reg + add]);
4499 else if ((sizeflag & DFLAG) || bytemode != v_mode)
4500 oappend (names32[reg + add]);
4501 else
4502 oappend (names16[reg + add]);
4503 used_prefixes |= (prefixes & PREFIX_DATA);
4504 break;
4505 case m_mode:
4506 if (address_mode == mode_64bit)
4507 oappend (names64[reg + add]);
4508 else
4509 oappend (names32[reg + add]);
4510 break;
4511 default:
4512 oappend (INTERNAL_DISASSEMBLER_ERROR);
4513 break;
4514 }
4515 }
4516
4517 static bfd_vma
4518 get64 (void)
4519 {
4520 bfd_vma x;
4521 #ifdef BFD64
4522 unsigned int a;
4523 unsigned int b;
4524
4525 FETCH_DATA (the_info, codep + 8);
4526 a = *codep++ & 0xff;
4527 a |= (*codep++ & 0xff) << 8;
4528 a |= (*codep++ & 0xff) << 16;
4529 a |= (*codep++ & 0xff) << 24;
4530 b = *codep++ & 0xff;
4531 b |= (*codep++ & 0xff) << 8;
4532 b |= (*codep++ & 0xff) << 16;
4533 b |= (*codep++ & 0xff) << 24;
4534 x = a + ((bfd_vma) b << 32);
4535 #else
4536 abort ();
4537 x = 0;
4538 #endif
4539 return x;
4540 }
4541
4542 static bfd_signed_vma
4543 get32 (void)
4544 {
4545 bfd_signed_vma x = 0;
4546
4547 FETCH_DATA (the_info, codep + 4);
4548 x = *codep++ & (bfd_signed_vma) 0xff;
4549 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
4550 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
4551 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
4552 return x;
4553 }
4554
4555 static bfd_signed_vma
4556 get32s (void)
4557 {
4558 bfd_signed_vma x = 0;
4559
4560 FETCH_DATA (the_info, codep + 4);
4561 x = *codep++ & (bfd_signed_vma) 0xff;
4562 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
4563 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
4564 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
4565
4566 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
4567
4568 return x;
4569 }
4570
4571 static int
4572 get16 (void)
4573 {
4574 int x = 0;
4575
4576 FETCH_DATA (the_info, codep + 2);
4577 x = *codep++ & 0xff;
4578 x |= (*codep++ & 0xff) << 8;
4579 return x;
4580 }
4581
4582 static void
4583 set_op (bfd_vma op, int riprel)
4584 {
4585 op_index[op_ad] = op_ad;
4586 if (address_mode == mode_64bit)
4587 {
4588 op_address[op_ad] = op;
4589 op_riprel[op_ad] = riprel;
4590 }
4591 else
4592 {
4593 /* Mask to get a 32-bit address. */
4594 op_address[op_ad] = op & 0xffffffff;
4595 op_riprel[op_ad] = riprel & 0xffffffff;
4596 }
4597 }
4598
4599 static void
4600 OP_REG (int code, int sizeflag)
4601 {
4602 const char *s;
4603 int add = 0;
4604 USED_REX (REX_EXTZ);
4605 if (rex & REX_EXTZ)
4606 add = 8;
4607
4608 switch (code)
4609 {
4610 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
4611 case sp_reg: case bp_reg: case si_reg: case di_reg:
4612 s = names16[code - ax_reg + add];
4613 break;
4614 case es_reg: case ss_reg: case cs_reg:
4615 case ds_reg: case fs_reg: case gs_reg:
4616 s = names_seg[code - es_reg + add];
4617 break;
4618 case al_reg: case ah_reg: case cl_reg: case ch_reg:
4619 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
4620 USED_REX (0);
4621 if (rex)
4622 s = names8rex[code - al_reg + add];
4623 else
4624 s = names8[code - al_reg];
4625 break;
4626 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
4627 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
4628 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4629 {
4630 s = names64[code - rAX_reg + add];
4631 break;
4632 }
4633 code += eAX_reg - rAX_reg;
4634 /* Fall through. */
4635 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
4636 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
4637 USED_REX (REX_MODE64);
4638 if (rex & REX_MODE64)
4639 s = names64[code - eAX_reg + add];
4640 else if (sizeflag & DFLAG)
4641 s = names32[code - eAX_reg + add];
4642 else
4643 s = names16[code - eAX_reg + add];
4644 used_prefixes |= (prefixes & PREFIX_DATA);
4645 break;
4646 default:
4647 s = INTERNAL_DISASSEMBLER_ERROR;
4648 break;
4649 }
4650 oappend (s);
4651 }
4652
4653 static void
4654 OP_IMREG (int code, int sizeflag)
4655 {
4656 const char *s;
4657
4658 switch (code)
4659 {
4660 case indir_dx_reg:
4661 if (intel_syntax)
4662 s = "dx";
4663 else
4664 s = "(%dx)";
4665 break;
4666 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
4667 case sp_reg: case bp_reg: case si_reg: case di_reg:
4668 s = names16[code - ax_reg];
4669 break;
4670 case es_reg: case ss_reg: case cs_reg:
4671 case ds_reg: case fs_reg: case gs_reg:
4672 s = names_seg[code - es_reg];
4673 break;
4674 case al_reg: case ah_reg: case cl_reg: case ch_reg:
4675 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
4676 USED_REX (0);
4677 if (rex)
4678 s = names8rex[code - al_reg];
4679 else
4680 s = names8[code - al_reg];
4681 break;
4682 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
4683 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
4684 USED_REX (REX_MODE64);
4685 if (rex & REX_MODE64)
4686 s = names64[code - eAX_reg];
4687 else if (sizeflag & DFLAG)
4688 s = names32[code - eAX_reg];
4689 else
4690 s = names16[code - eAX_reg];
4691 used_prefixes |= (prefixes & PREFIX_DATA);
4692 break;
4693 case z_mode_ax_reg:
4694 if ((rex & REX_MODE64) || (sizeflag & DFLAG))
4695 s = *names32;
4696 else
4697 s = *names16;
4698 if (!(rex & REX_MODE64))
4699 used_prefixes |= (prefixes & PREFIX_DATA);
4700 break;
4701 default:
4702 s = INTERNAL_DISASSEMBLER_ERROR;
4703 break;
4704 }
4705 oappend (s);
4706 }
4707
4708 static void
4709 OP_I (int bytemode, int sizeflag)
4710 {
4711 bfd_signed_vma op;
4712 bfd_signed_vma mask = -1;
4713
4714 switch (bytemode)
4715 {
4716 case b_mode:
4717 FETCH_DATA (the_info, codep + 1);
4718 op = *codep++;
4719 mask = 0xff;
4720 break;
4721 case q_mode:
4722 if (address_mode == mode_64bit)
4723 {
4724 op = get32s ();
4725 break;
4726 }
4727 /* Fall through. */
4728 case v_mode:
4729 USED_REX (REX_MODE64);
4730 if (rex & REX_MODE64)
4731 op = get32s ();
4732 else if (sizeflag & DFLAG)
4733 {
4734 op = get32 ();
4735 mask = 0xffffffff;
4736 }
4737 else
4738 {
4739 op = get16 ();
4740 mask = 0xfffff;
4741 }
4742 used_prefixes |= (prefixes & PREFIX_DATA);
4743 break;
4744 case w_mode:
4745 mask = 0xfffff;
4746 op = get16 ();
4747 break;
4748 case const_1_mode:
4749 if (intel_syntax)
4750 oappend ("1");
4751 return;
4752 default:
4753 oappend (INTERNAL_DISASSEMBLER_ERROR);
4754 return;
4755 }
4756
4757 op &= mask;
4758 scratchbuf[0] = '$';
4759 print_operand_value (scratchbuf + 1, 1, op);
4760 oappend (scratchbuf + intel_syntax);
4761 scratchbuf[0] = '\0';
4762 }
4763
4764 static void
4765 OP_I64 (int bytemode, int sizeflag)
4766 {
4767 bfd_signed_vma op;
4768 bfd_signed_vma mask = -1;
4769
4770 if (address_mode != mode_64bit)
4771 {
4772 OP_I (bytemode, sizeflag);
4773 return;
4774 }
4775
4776 switch (bytemode)
4777 {
4778 case b_mode:
4779 FETCH_DATA (the_info, codep + 1);
4780 op = *codep++;
4781 mask = 0xff;
4782 break;
4783 case v_mode:
4784 USED_REX (REX_MODE64);
4785 if (rex & REX_MODE64)
4786 op = get64 ();
4787 else if (sizeflag & DFLAG)
4788 {
4789 op = get32 ();
4790 mask = 0xffffffff;
4791 }
4792 else
4793 {
4794 op = get16 ();
4795 mask = 0xfffff;
4796 }
4797 used_prefixes |= (prefixes & PREFIX_DATA);
4798 break;
4799 case w_mode:
4800 mask = 0xfffff;
4801 op = get16 ();
4802 break;
4803 default:
4804 oappend (INTERNAL_DISASSEMBLER_ERROR);
4805 return;
4806 }
4807
4808 op &= mask;
4809 scratchbuf[0] = '$';
4810 print_operand_value (scratchbuf + 1, 1, op);
4811 oappend (scratchbuf + intel_syntax);
4812 scratchbuf[0] = '\0';
4813 }
4814
4815 static void
4816 OP_sI (int bytemode, int sizeflag)
4817 {
4818 bfd_signed_vma op;
4819 bfd_signed_vma mask = -1;
4820
4821 switch (bytemode)
4822 {
4823 case b_mode:
4824 FETCH_DATA (the_info, codep + 1);
4825 op = *codep++;
4826 if ((op & 0x80) != 0)
4827 op -= 0x100;
4828 mask = 0xffffffff;
4829 break;
4830 case v_mode:
4831 USED_REX (REX_MODE64);
4832 if (rex & REX_MODE64)
4833 op = get32s ();
4834 else if (sizeflag & DFLAG)
4835 {
4836 op = get32s ();
4837 mask = 0xffffffff;
4838 }
4839 else
4840 {
4841 mask = 0xffffffff;
4842 op = get16 ();
4843 if ((op & 0x8000) != 0)
4844 op -= 0x10000;
4845 }
4846 used_prefixes |= (prefixes & PREFIX_DATA);
4847 break;
4848 case w_mode:
4849 op = get16 ();
4850 mask = 0xffffffff;
4851 if ((op & 0x8000) != 0)
4852 op -= 0x10000;
4853 break;
4854 default:
4855 oappend (INTERNAL_DISASSEMBLER_ERROR);
4856 return;
4857 }
4858
4859 scratchbuf[0] = '$';
4860 print_operand_value (scratchbuf + 1, 1, op);
4861 oappend (scratchbuf + intel_syntax);
4862 }
4863
4864 static void
4865 OP_J (int bytemode, int sizeflag)
4866 {
4867 bfd_vma disp;
4868 bfd_vma mask = -1;
4869
4870 switch (bytemode)
4871 {
4872 case b_mode:
4873 FETCH_DATA (the_info, codep + 1);
4874 disp = *codep++;
4875 if ((disp & 0x80) != 0)
4876 disp -= 0x100;
4877 break;
4878 case v_mode:
4879 if ((sizeflag & DFLAG) || (rex & REX_MODE64))
4880 disp = get32s ();
4881 else
4882 {
4883 disp = get16 ();
4884 /* For some reason, a data16 prefix on a jump instruction
4885 means that the pc is masked to 16 bits after the
4886 displacement is added! */
4887 mask = 0xffff;
4888 }
4889 used_prefixes |= (prefixes & PREFIX_DATA);
4890 break;
4891 default:
4892 oappend (INTERNAL_DISASSEMBLER_ERROR);
4893 return;
4894 }
4895 disp = (start_pc + codep - start_codep + disp) & mask;
4896 set_op (disp, 0);
4897 print_operand_value (scratchbuf, 1, disp);
4898 oappend (scratchbuf);
4899 }
4900
4901 static void
4902 OP_SEG (int bytemode, int sizeflag)
4903 {
4904 if (bytemode == w_mode)
4905 oappend (names_seg[reg]);
4906 else
4907 OP_E (mod == 3 ? bytemode : w_mode, sizeflag);
4908 }
4909
4910 static void
4911 OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
4912 {
4913 int seg, offset;
4914
4915 if (sizeflag & DFLAG)
4916 {
4917 offset = get32 ();
4918 seg = get16 ();
4919 }
4920 else
4921 {
4922 offset = get16 ();
4923 seg = get16 ();
4924 }
4925 used_prefixes |= (prefixes & PREFIX_DATA);
4926 if (intel_syntax)
4927 sprintf (scratchbuf, "0x%x:0x%x", seg, offset);
4928 else
4929 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
4930 oappend (scratchbuf);
4931 }
4932
4933 static void
4934 OP_OFF (int bytemode, int sizeflag)
4935 {
4936 bfd_vma off;
4937
4938 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
4939 intel_operand_size (bytemode, sizeflag);
4940 append_seg ();
4941
4942 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
4943 off = get32 ();
4944 else
4945 off = get16 ();
4946
4947 if (intel_syntax)
4948 {
4949 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4950 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
4951 {
4952 oappend (names_seg[ds_reg - es_reg]);
4953 oappend (":");
4954 }
4955 }
4956 print_operand_value (scratchbuf, 1, off);
4957 oappend (scratchbuf);
4958 }
4959
4960 static void
4961 OP_OFF64 (int bytemode, int sizeflag)
4962 {
4963 bfd_vma off;
4964
4965 if (address_mode != mode_64bit
4966 || (prefixes & PREFIX_ADDR))
4967 {
4968 OP_OFF (bytemode, sizeflag);
4969 return;
4970 }
4971
4972 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
4973 intel_operand_size (bytemode, sizeflag);
4974 append_seg ();
4975
4976 off = get64 ();
4977
4978 if (intel_syntax)
4979 {
4980 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4981 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
4982 {
4983 oappend (names_seg[ds_reg - es_reg]);
4984 oappend (":");
4985 }
4986 }
4987 print_operand_value (scratchbuf, 1, off);
4988 oappend (scratchbuf);
4989 }
4990
4991 static void
4992 ptr_reg (int code, int sizeflag)
4993 {
4994 const char *s;
4995
4996 *obufp++ = open_char;
4997 used_prefixes |= (prefixes & PREFIX_ADDR);
4998 if (address_mode == mode_64bit)
4999 {
5000 if (!(sizeflag & AFLAG))
5001 s = names32[code - eAX_reg];
5002 else
5003 s = names64[code - eAX_reg];
5004 }
5005 else if (sizeflag & AFLAG)
5006 s = names32[code - eAX_reg];
5007 else
5008 s = names16[code - eAX_reg];
5009 oappend (s);
5010 *obufp++ = close_char;
5011 *obufp = 0;
5012 }
5013
5014 static void
5015 OP_ESreg (int code, int sizeflag)
5016 {
5017 if (intel_syntax)
5018 {
5019 switch (codep[-1])
5020 {
5021 case 0x6d: /* insw/insl */
5022 intel_operand_size (z_mode, sizeflag);
5023 break;
5024 case 0xa5: /* movsw/movsl/movsq */
5025 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5026 case 0xab: /* stosw/stosl */
5027 case 0xaf: /* scasw/scasl */
5028 intel_operand_size (v_mode, sizeflag);
5029 break;
5030 default:
5031 intel_operand_size (b_mode, sizeflag);
5032 }
5033 }
5034 oappend ("%es:" + intel_syntax);
5035 ptr_reg (code, sizeflag);
5036 }
5037
5038 static void
5039 OP_DSreg (int code, int sizeflag)
5040 {
5041 if (intel_syntax)
5042 {
5043 switch (codep[-1])
5044 {
5045 case 0x6f: /* outsw/outsl */
5046 intel_operand_size (z_mode, sizeflag);
5047 break;
5048 case 0xa5: /* movsw/movsl/movsq */
5049 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5050 case 0xad: /* lodsw/lodsl/lodsq */
5051 intel_operand_size (v_mode, sizeflag);
5052 break;
5053 default:
5054 intel_operand_size (b_mode, sizeflag);
5055 }
5056 }
5057 if ((prefixes
5058 & (PREFIX_CS
5059 | PREFIX_DS
5060 | PREFIX_SS
5061 | PREFIX_ES
5062 | PREFIX_FS
5063 | PREFIX_GS)) == 0)
5064 prefixes |= PREFIX_DS;
5065 append_seg ();
5066 ptr_reg (code, sizeflag);
5067 }
5068
5069 static void
5070 OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5071 {
5072 int add = 0;
5073 if (rex & REX_EXTX)
5074 {
5075 USED_REX (REX_EXTX);
5076 add = 8;
5077 }
5078 else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
5079 {
5080 used_prefixes |= PREFIX_LOCK;
5081 add = 8;
5082 }
5083 sprintf (scratchbuf, "%%cr%d", reg + add);
5084 oappend (scratchbuf + intel_syntax);
5085 }
5086
5087 static void
5088 OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5089 {
5090 int add = 0;
5091 USED_REX (REX_EXTX);
5092 if (rex & REX_EXTX)
5093 add = 8;
5094 if (intel_syntax)
5095 sprintf (scratchbuf, "db%d", reg + add);
5096 else
5097 sprintf (scratchbuf, "%%db%d", reg + add);
5098 oappend (scratchbuf);
5099 }
5100
5101 static void
5102 OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5103 {
5104 sprintf (scratchbuf, "%%tr%d", reg);
5105 oappend (scratchbuf + intel_syntax);
5106 }
5107
5108 static void
5109 OP_Rd (int bytemode, int sizeflag)
5110 {
5111 if (mod == 3)
5112 OP_E (bytemode, sizeflag);
5113 else
5114 BadOp ();
5115 }
5116
5117 static void
5118 OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5119 {
5120 used_prefixes |= (prefixes & PREFIX_DATA);
5121 if (prefixes & PREFIX_DATA)
5122 {
5123 int add = 0;
5124 USED_REX (REX_EXTX);
5125 if (rex & REX_EXTX)
5126 add = 8;
5127 sprintf (scratchbuf, "%%xmm%d", reg + add);
5128 }
5129 else
5130 sprintf (scratchbuf, "%%mm%d", reg);
5131 oappend (scratchbuf + intel_syntax);
5132 }
5133
5134 static void
5135 OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5136 {
5137 int add = 0;
5138 USED_REX (REX_EXTX);
5139 if (rex & REX_EXTX)
5140 add = 8;
5141 sprintf (scratchbuf, "%%xmm%d", reg + add);
5142 oappend (scratchbuf + intel_syntax);
5143 }
5144
5145 static void
5146 OP_EM (int bytemode, int sizeflag)
5147 {
5148 if (mod != 3)
5149 {
5150 if (intel_syntax && bytemode == v_mode)
5151 {
5152 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
5153 used_prefixes |= (prefixes & PREFIX_DATA);
5154 }
5155 OP_E (bytemode, sizeflag);
5156 return;
5157 }
5158
5159 /* Skip mod/rm byte. */
5160 MODRM_CHECK;
5161 codep++;
5162 used_prefixes |= (prefixes & PREFIX_DATA);
5163 if (prefixes & PREFIX_DATA)
5164 {
5165 int add = 0;
5166
5167 USED_REX (REX_EXTZ);
5168 if (rex & REX_EXTZ)
5169 add = 8;
5170 sprintf (scratchbuf, "%%xmm%d", rm + add);
5171 }
5172 else
5173 sprintf (scratchbuf, "%%mm%d", rm);
5174 oappend (scratchbuf + intel_syntax);
5175 }
5176
5177 /* cvt* are the only instructions in sse2 which have
5178 both SSE and MMX operands and also have 0x66 prefix
5179 in their opcode. 0x66 was originally used to differentiate
5180 between SSE and MMX instruction(operands). So we have to handle the
5181 cvt* separately using OP_EMC and OP_MXC */
5182 static void
5183 OP_EMC (int bytemode, int sizeflag)
5184 {
5185 if (mod != 3)
5186 {
5187 if (intel_syntax && bytemode == v_mode)
5188 {
5189 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
5190 used_prefixes |= (prefixes & PREFIX_DATA);
5191 }
5192 OP_E (bytemode, sizeflag);
5193 return;
5194 }
5195
5196 /* Skip mod/rm byte. */
5197 MODRM_CHECK;
5198 codep++;
5199 used_prefixes |= (prefixes & PREFIX_DATA);
5200 sprintf (scratchbuf, "%%mm%d", rm);
5201 oappend (scratchbuf + intel_syntax);
5202 }
5203
5204 static void
5205 OP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5206 {
5207 used_prefixes |= (prefixes & PREFIX_DATA);
5208 sprintf (scratchbuf, "%%mm%d", reg);
5209 oappend (scratchbuf + intel_syntax);
5210 }
5211
5212 static void
5213 OP_EX (int bytemode, int sizeflag)
5214 {
5215 int add = 0;
5216 if (mod != 3)
5217 {
5218 if (intel_syntax && bytemode == v_mode)
5219 {
5220 switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ))
5221 {
5222 case 0: bytemode = x_mode; break;
5223 case PREFIX_REPZ: bytemode = d_mode; used_prefixes |= PREFIX_REPZ; break;
5224 case PREFIX_DATA: bytemode = x_mode; used_prefixes |= PREFIX_DATA; break;
5225 case PREFIX_REPNZ: bytemode = q_mode; used_prefixes |= PREFIX_REPNZ; break;
5226 default: bytemode = 0; break;
5227 }
5228 }
5229 OP_E (bytemode, sizeflag);
5230 return;
5231 }
5232 USED_REX (REX_EXTZ);
5233 if (rex & REX_EXTZ)
5234 add = 8;
5235
5236 /* Skip mod/rm byte. */
5237 MODRM_CHECK;
5238 codep++;
5239 sprintf (scratchbuf, "%%xmm%d", rm + add);
5240 oappend (scratchbuf + intel_syntax);
5241 }
5242
5243 static void
5244 OP_MS (int bytemode, int sizeflag)
5245 {
5246 if (mod == 3)
5247 OP_EM (bytemode, sizeflag);
5248 else
5249 BadOp ();
5250 }
5251
5252 static void
5253 OP_XS (int bytemode, int sizeflag)
5254 {
5255 if (mod == 3)
5256 OP_EX (bytemode, sizeflag);
5257 else
5258 BadOp ();
5259 }
5260
5261 static void
5262 OP_M (int bytemode, int sizeflag)
5263 {
5264 if (mod == 3)
5265 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
5266 BadOp ();
5267 else
5268 OP_E (bytemode, sizeflag);
5269 }
5270
5271 static void
5272 OP_0f07 (int bytemode, int sizeflag)
5273 {
5274 if (mod != 3 || rm != 0)
5275 BadOp ();
5276 else
5277 OP_E (bytemode, sizeflag);
5278 }
5279
5280 static void
5281 OP_0fae (int bytemode, int sizeflag)
5282 {
5283 if (mod == 3)
5284 {
5285 if (reg == 7)
5286 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
5287
5288 if (reg < 5 || rm != 0)
5289 {
5290 BadOp (); /* bad sfence, mfence, or lfence */
5291 return;
5292 }
5293 }
5294 else if (reg != 7)
5295 {
5296 BadOp (); /* bad clflush */
5297 return;
5298 }
5299
5300 OP_E (bytemode, sizeflag);
5301 }
5302
5303 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
5304 32bit mode and "xchg %rax,%rax" in 64bit mode. NOP with REPZ prefix
5305 is called PAUSE. We display "xchg %ax,%ax" instead of "data16 nop".
5306 */
5307
5308 static void
5309 NOP_Fixup1 (int bytemode, int sizeflag)
5310 {
5311 if (prefixes == PREFIX_REPZ)
5312 strcpy (obuf, "pause");
5313 else if (prefixes == PREFIX_DATA
5314 || ((rex & REX_MODE64) && rex != 0x48))
5315 OP_REG (bytemode, sizeflag);
5316 else
5317 strcpy (obuf, "nop");
5318 }
5319
5320 static void
5321 NOP_Fixup2 (int bytemode, int sizeflag)
5322 {
5323 if (prefixes == PREFIX_DATA
5324 || ((rex & REX_MODE64) && rex != 0x48))
5325 OP_IMREG (bytemode, sizeflag);
5326 }
5327
5328 static const char *const Suffix3DNow[] = {
5329 /* 00 */ NULL, NULL, NULL, NULL,
5330 /* 04 */ NULL, NULL, NULL, NULL,
5331 /* 08 */ NULL, NULL, NULL, NULL,
5332 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
5333 /* 10 */ NULL, NULL, NULL, NULL,
5334 /* 14 */ NULL, NULL, NULL, NULL,
5335 /* 18 */ NULL, NULL, NULL, NULL,
5336 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
5337 /* 20 */ NULL, NULL, NULL, NULL,
5338 /* 24 */ NULL, NULL, NULL, NULL,
5339 /* 28 */ NULL, NULL, NULL, NULL,
5340 /* 2C */ NULL, NULL, NULL, NULL,
5341 /* 30 */ NULL, NULL, NULL, NULL,
5342 /* 34 */ NULL, NULL, NULL, NULL,
5343 /* 38 */ NULL, NULL, NULL, NULL,
5344 /* 3C */ NULL, NULL, NULL, NULL,
5345 /* 40 */ NULL, NULL, NULL, NULL,
5346 /* 44 */ NULL, NULL, NULL, NULL,
5347 /* 48 */ NULL, NULL, NULL, NULL,
5348 /* 4C */ NULL, NULL, NULL, NULL,
5349 /* 50 */ NULL, NULL, NULL, NULL,
5350 /* 54 */ NULL, NULL, NULL, NULL,
5351 /* 58 */ NULL, NULL, NULL, NULL,
5352 /* 5C */ NULL, NULL, NULL, NULL,
5353 /* 60 */ NULL, NULL, NULL, NULL,
5354 /* 64 */ NULL, NULL, NULL, NULL,
5355 /* 68 */ NULL, NULL, NULL, NULL,
5356 /* 6C */ NULL, NULL, NULL, NULL,
5357 /* 70 */ NULL, NULL, NULL, NULL,
5358 /* 74 */ NULL, NULL, NULL, NULL,
5359 /* 78 */ NULL, NULL, NULL, NULL,
5360 /* 7C */ NULL, NULL, NULL, NULL,
5361 /* 80 */ NULL, NULL, NULL, NULL,
5362 /* 84 */ NULL, NULL, NULL, NULL,
5363 /* 88 */ NULL, NULL, "pfnacc", NULL,
5364 /* 8C */ NULL, NULL, "pfpnacc", NULL,
5365 /* 90 */ "pfcmpge", NULL, NULL, NULL,
5366 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
5367 /* 98 */ NULL, NULL, "pfsub", NULL,
5368 /* 9C */ NULL, NULL, "pfadd", NULL,
5369 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
5370 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
5371 /* A8 */ NULL, NULL, "pfsubr", NULL,
5372 /* AC */ NULL, NULL, "pfacc", NULL,
5373 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
5374 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
5375 /* B8 */ NULL, NULL, NULL, "pswapd",
5376 /* BC */ NULL, NULL, NULL, "pavgusb",
5377 /* C0 */ NULL, NULL, NULL, NULL,
5378 /* C4 */ NULL, NULL, NULL, NULL,
5379 /* C8 */ NULL, NULL, NULL, NULL,
5380 /* CC */ NULL, NULL, NULL, NULL,
5381 /* D0 */ NULL, NULL, NULL, NULL,
5382 /* D4 */ NULL, NULL, NULL, NULL,
5383 /* D8 */ NULL, NULL, NULL, NULL,
5384 /* DC */ NULL, NULL, NULL, NULL,
5385 /* E0 */ NULL, NULL, NULL, NULL,
5386 /* E4 */ NULL, NULL, NULL, NULL,
5387 /* E8 */ NULL, NULL, NULL, NULL,
5388 /* EC */ NULL, NULL, NULL, NULL,
5389 /* F0 */ NULL, NULL, NULL, NULL,
5390 /* F4 */ NULL, NULL, NULL, NULL,
5391 /* F8 */ NULL, NULL, NULL, NULL,
5392 /* FC */ NULL, NULL, NULL, NULL,
5393 };
5394
5395 static void
5396 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5397 {
5398 const char *mnemonic;
5399
5400 FETCH_DATA (the_info, codep + 1);
5401 /* AMD 3DNow! instructions are specified by an opcode suffix in the
5402 place where an 8-bit immediate would normally go. ie. the last
5403 byte of the instruction. */
5404 obufp = obuf + strlen (obuf);
5405 mnemonic = Suffix3DNow[*codep++ & 0xff];
5406 if (mnemonic)
5407 oappend (mnemonic);
5408 else
5409 {
5410 /* Since a variable sized modrm/sib chunk is between the start
5411 of the opcode (0x0f0f) and the opcode suffix, we need to do
5412 all the modrm processing first, and don't know until now that
5413 we have a bad opcode. This necessitates some cleaning up. */
5414 op1out[0] = '\0';
5415 op2out[0] = '\0';
5416 BadOp ();
5417 }
5418 }
5419
5420 static const char *simd_cmp_op[] = {
5421 "eq",
5422 "lt",
5423 "le",
5424 "unord",
5425 "neq",
5426 "nlt",
5427 "nle",
5428 "ord"
5429 };
5430
5431 static void
5432 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5433 {
5434 unsigned int cmp_type;
5435
5436 FETCH_DATA (the_info, codep + 1);
5437 obufp = obuf + strlen (obuf);
5438 cmp_type = *codep++ & 0xff;
5439 if (cmp_type < 8)
5440 {
5441 char suffix1 = 'p', suffix2 = 's';
5442 used_prefixes |= (prefixes & PREFIX_REPZ);
5443 if (prefixes & PREFIX_REPZ)
5444 suffix1 = 's';
5445 else
5446 {
5447 used_prefixes |= (prefixes & PREFIX_DATA);
5448 if (prefixes & PREFIX_DATA)
5449 suffix2 = 'd';
5450 else
5451 {
5452 used_prefixes |= (prefixes & PREFIX_REPNZ);
5453 if (prefixes & PREFIX_REPNZ)
5454 suffix1 = 's', suffix2 = 'd';
5455 }
5456 }
5457 sprintf (scratchbuf, "cmp%s%c%c",
5458 simd_cmp_op[cmp_type], suffix1, suffix2);
5459 used_prefixes |= (prefixes & PREFIX_REPZ);
5460 oappend (scratchbuf);
5461 }
5462 else
5463 {
5464 /* We have a bad extension byte. Clean up. */
5465 op1out[0] = '\0';
5466 op2out[0] = '\0';
5467 BadOp ();
5468 }
5469 }
5470
5471 static void
5472 SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
5473 {
5474 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
5475 forms of these instructions. */
5476 if (mod == 3)
5477 {
5478 char *p = obuf + strlen (obuf);
5479 *(p + 1) = '\0';
5480 *p = *(p - 1);
5481 *(p - 1) = *(p - 2);
5482 *(p - 2) = *(p - 3);
5483 *(p - 3) = extrachar;
5484 }
5485 }
5486
5487 static void
5488 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
5489 {
5490 if (mod == 3 && reg == 1 && rm <= 1)
5491 {
5492 /* Override "sidt". */
5493 size_t olen = strlen (obuf);
5494 char *p = obuf + olen - 4;
5495 const char **names = (address_mode == mode_64bit
5496 ? names64 : names32);
5497
5498 /* We might have a suffix when disassembling with -Msuffix. */
5499 if (*p == 'i')
5500 --p;
5501
5502 /* Remove "addr16/addr32" if we aren't in Intel mode. */
5503 if (!intel_syntax
5504 && (prefixes & PREFIX_ADDR)
5505 && olen >= (4 + 7)
5506 && *(p - 1) == ' '
5507 && CONST_STRNEQ (p - 7, "addr")
5508 && (CONST_STRNEQ (p - 3, "16")
5509 || CONST_STRNEQ (p - 3, "32")))
5510 p -= 7;
5511
5512 if (rm)
5513 {
5514 /* mwait %eax,%ecx */
5515 strcpy (p, "mwait");
5516 if (!intel_syntax)
5517 strcpy (op1out, names[0]);
5518 }
5519 else
5520 {
5521 /* monitor %eax,%ecx,%edx" */
5522 strcpy (p, "monitor");
5523 if (!intel_syntax)
5524 {
5525 const char **op1_names;
5526 if (!(prefixes & PREFIX_ADDR))
5527 op1_names = (address_mode == mode_16bit
5528 ? names16 : names);
5529 else
5530 {
5531 op1_names = (address_mode != mode_32bit
5532 ? names32 : names16);
5533 used_prefixes |= PREFIX_ADDR;
5534 }
5535 strcpy (op1out, op1_names[0]);
5536 strcpy (op3out, names[2]);
5537 }
5538 }
5539 if (!intel_syntax)
5540 {
5541 strcpy (op2out, names[1]);
5542 two_source_ops = 1;
5543 }
5544
5545 codep++;
5546 }
5547 else
5548 OP_M (0, sizeflag);
5549 }
5550
5551 static void
5552 SVME_Fixup (int bytemode, int sizeflag)
5553 {
5554 const char *alt;
5555 char *p;
5556
5557 switch (*codep)
5558 {
5559 case 0xd8:
5560 alt = "vmrun";
5561 break;
5562 case 0xd9:
5563 alt = "vmmcall";
5564 break;
5565 case 0xda:
5566 alt = "vmload";
5567 break;
5568 case 0xdb:
5569 alt = "vmsave";
5570 break;
5571 case 0xdc:
5572 alt = "stgi";
5573 break;
5574 case 0xdd:
5575 alt = "clgi";
5576 break;
5577 case 0xde:
5578 alt = "skinit";
5579 break;
5580 case 0xdf:
5581 alt = "invlpga";
5582 break;
5583 default:
5584 OP_M (bytemode, sizeflag);
5585 return;
5586 }
5587 /* Override "lidt". */
5588 p = obuf + strlen (obuf) - 4;
5589 /* We might have a suffix. */
5590 if (*p == 'i')
5591 --p;
5592 strcpy (p, alt);
5593 if (!(prefixes & PREFIX_ADDR))
5594 {
5595 ++codep;
5596 return;
5597 }
5598 used_prefixes |= PREFIX_ADDR;
5599 switch (*codep++)
5600 {
5601 case 0xdf:
5602 strcpy (op2out, names32[1]);
5603 two_source_ops = 1;
5604 /* Fall through. */
5605 case 0xd8:
5606 case 0xda:
5607 case 0xdb:
5608 *obufp++ = open_char;
5609 if (address_mode == mode_64bit || (sizeflag & AFLAG))
5610 alt = names32[0];
5611 else
5612 alt = names16[0];
5613 strcpy (obufp, alt);
5614 obufp += strlen (alt);
5615 *obufp++ = close_char;
5616 *obufp = '\0';
5617 break;
5618 }
5619 }
5620
5621 static void
5622 INVLPG_Fixup (int bytemode, int sizeflag)
5623 {
5624 const char *alt;
5625
5626 switch (*codep)
5627 {
5628 case 0xf8:
5629 alt = "swapgs";
5630 break;
5631 case 0xf9:
5632 alt = "rdtscp";
5633 break;
5634 default:
5635 OP_M (bytemode, sizeflag);
5636 return;
5637 }
5638 /* Override "invlpg". */
5639 strcpy (obuf + strlen (obuf) - 6, alt);
5640 codep++;
5641 }
5642
5643 static void
5644 BadOp (void)
5645 {
5646 /* Throw away prefixes and 1st. opcode byte. */
5647 codep = insn_codep + 1;
5648 oappend ("(bad)");
5649 }
5650
5651 static void
5652 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
5653 {
5654 if (mod == 3 && reg == 0 && rm >=1 && rm <= 4)
5655 {
5656 /* Override "sgdt". */
5657 char *p = obuf + strlen (obuf) - 4;
5658
5659 /* We might have a suffix when disassembling with -Msuffix. */
5660 if (*p == 'g')
5661 --p;
5662
5663 switch (rm)
5664 {
5665 case 1:
5666 strcpy (p, "vmcall");
5667 break;
5668 case 2:
5669 strcpy (p, "vmlaunch");
5670 break;
5671 case 3:
5672 strcpy (p, "vmresume");
5673 break;
5674 case 4:
5675 strcpy (p, "vmxoff");
5676 break;
5677 }
5678
5679 codep++;
5680 }
5681 else
5682 OP_E (0, sizeflag);
5683 }
5684
5685 static void
5686 OP_VMX (int bytemode, int sizeflag)
5687 {
5688 used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
5689 if (prefixes & PREFIX_DATA)
5690 strcpy (obuf, "vmclear");
5691 else if (prefixes & PREFIX_REPZ)
5692 strcpy (obuf, "vmxon");
5693 else
5694 strcpy (obuf, "vmptrld");
5695 OP_E (bytemode, sizeflag);
5696 }
5697
5698 static void
5699 REP_Fixup (int bytemode, int sizeflag)
5700 {
5701 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
5702 lods and stos. */
5703 size_t ilen = 0;
5704
5705 if (prefixes & PREFIX_REPZ)
5706 switch (*insn_codep)
5707 {
5708 case 0x6e: /* outsb */
5709 case 0x6f: /* outsw/outsl */
5710 case 0xa4: /* movsb */
5711 case 0xa5: /* movsw/movsl/movsq */
5712 if (!intel_syntax)
5713 ilen = 5;
5714 else
5715 ilen = 4;
5716 break;
5717 case 0xaa: /* stosb */
5718 case 0xab: /* stosw/stosl/stosq */
5719 case 0xac: /* lodsb */
5720 case 0xad: /* lodsw/lodsl/lodsq */
5721 if (!intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5722 ilen = 5;
5723 else
5724 ilen = 4;
5725 break;
5726 case 0x6c: /* insb */
5727 case 0x6d: /* insl/insw */
5728 if (!intel_syntax)
5729 ilen = 4;
5730 else
5731 ilen = 3;
5732 break;
5733 default:
5734 abort ();
5735 break;
5736 }
5737
5738 if (ilen != 0)
5739 {
5740 size_t olen;
5741 char *p;
5742
5743 olen = strlen (obuf);
5744 p = obuf + olen - ilen - 1 - 4;
5745 /* Handle "repz [addr16|addr32]". */
5746 if ((prefixes & PREFIX_ADDR))
5747 p -= 1 + 6;
5748
5749 memmove (p + 3, p + 4, olen - (p + 3 - obuf));
5750 }
5751
5752 switch (bytemode)
5753 {
5754 case al_reg:
5755 case eAX_reg:
5756 case indir_dx_reg:
5757 OP_IMREG (bytemode, sizeflag);
5758 break;
5759 case eDI_reg:
5760 OP_ESreg (bytemode, sizeflag);
5761 break;
5762 case eSI_reg:
5763 OP_DSreg (bytemode, sizeflag);
5764 break;
5765 default:
5766 abort ();
5767 break;
5768 }
5769 }