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