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