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