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