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