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