source: trunk/packages/xen-3.1/xen-3.1/tools/ioemu/i386-dis.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 97.1 KB
Line 
1/* Print i386 instructions for GDB, the GNU debugger.
2   Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3   2001
4   Free Software Foundation, Inc.
5
6This file is part of GDB.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
22/*
23 * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
24 * July 1988
25 *  modified by John Hassey (hassey@dg-rtp.dg.com)
26 *  x86-64 support added by Jan Hubicka (jh@suse.cz)
27 */
28
29/*
30 * The main tables describing the instructions is essentially a copy
31 * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
32 * Programmers Manual.  Usually, there is a capital letter, followed
33 * by a small letter.  The capital letter tell the addressing mode,
34 * and the small letter tells about the operand size.  Refer to
35 * the Intel manual for details.
36 */
37
38#include <stdlib.h>
39#include "dis-asm.h"
40
41#define MAXLEN 20
42
43#include <setjmp.h>
44
45#ifndef UNIXWARE_COMPAT
46/* Set non-zero for broken, compatible instructions.  Set to zero for
47   non-broken opcodes.  */
48#define UNIXWARE_COMPAT 1
49#endif
50
51static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
52static void ckprefix PARAMS ((void));
53static const char *prefix_name PARAMS ((int, int));
54static int print_insn PARAMS ((bfd_vma, disassemble_info *));
55static void dofloat PARAMS ((int));
56static void OP_ST PARAMS ((int, int));
57static void OP_STi  PARAMS ((int, int));
58static int putop PARAMS ((const char *, int));
59static void oappend PARAMS ((const char *));
60static void append_seg PARAMS ((void));
61static void OP_indirE PARAMS ((int, int));
62static void print_operand_value PARAMS ((char *, int, bfd_vma));
63static void OP_E PARAMS ((int, int));
64static void OP_G PARAMS ((int, int));
65static bfd_vma get64 PARAMS ((void));
66static bfd_signed_vma get32 PARAMS ((void));
67static bfd_signed_vma get32s PARAMS ((void));
68static int get16 PARAMS ((void));
69static void set_op PARAMS ((bfd_vma, int));
70static void OP_REG PARAMS ((int, int));
71static void OP_IMREG PARAMS ((int, int));
72static void OP_I PARAMS ((int, int));
73static void OP_I64 PARAMS ((int, int));
74static void OP_sI PARAMS ((int, int));
75static void OP_J PARAMS ((int, int));
76static void OP_SEG PARAMS ((int, int));
77static void OP_DIR PARAMS ((int, int));
78static void OP_OFF PARAMS ((int, int));
79static void OP_OFF64 PARAMS ((int, int));
80static void ptr_reg PARAMS ((int, int));
81static void OP_ESreg PARAMS ((int, int));
82static void OP_DSreg PARAMS ((int, int));
83static void OP_C PARAMS ((int, int));
84static void OP_D PARAMS ((int, int));
85static void OP_T PARAMS ((int, int));
86static void OP_Rd PARAMS ((int, int));
87static void OP_MMX PARAMS ((int, int));
88static void OP_XMM PARAMS ((int, int));
89static void OP_EM PARAMS ((int, int));
90static void OP_EX PARAMS ((int, int));
91static void OP_MS PARAMS ((int, int));
92static void OP_XS PARAMS ((int, int));
93static void OP_3DNowSuffix PARAMS ((int, int));
94static void OP_SIMD_Suffix PARAMS ((int, int));
95static void SIMD_Fixup PARAMS ((int, int));
96static void BadOp PARAMS ((void));
97
98struct dis_private {
99  /* Points to first byte not fetched.  */
100  bfd_byte *max_fetched;
101  bfd_byte the_buffer[MAXLEN];
102  bfd_vma insn_start;
103  int orig_sizeflag;
104  jmp_buf bailout;
105};
106
107/* The opcode for the fwait instruction, which we treat as a prefix
108   when we can.  */
109#define FWAIT_OPCODE (0x9b)
110
111/* Set to 1 for 64bit mode disassembly.  */
112static int mode_64bit;
113
114/* Flags for the prefixes for the current instruction.  See below.  */
115static int prefixes;
116
117/* REX prefix the current instruction.  See below.  */
118static int rex;
119/* Bits of REX we've already used.  */
120static int rex_used;
121#define REX_MODE64      8
122#define REX_EXTX        4
123#define REX_EXTY        2
124#define REX_EXTZ        1
125/* Mark parts used in the REX prefix.  When we are testing for
126   empty prefix (for 8bit register REX extension), just mask it
127   out.  Otherwise test for REX bit is excuse for existence of REX
128   only in case value is nonzero.  */
129#define USED_REX(value)                                 \
130  {                                                     \
131    if (value)                                          \
132      rex_used |= (rex & value) ? (value) | 0x40 : 0;   \
133    else                                                \
134      rex_used |= 0x40;                                 \
135  }
136
137/* Flags for prefixes which we somehow handled when printing the
138   current instruction.  */
139static int used_prefixes;
140
141/* Flags stored in PREFIXES.  */
142#define PREFIX_REPZ 1
143#define PREFIX_REPNZ 2
144#define PREFIX_LOCK 4
145#define PREFIX_CS 8
146#define PREFIX_SS 0x10
147#define PREFIX_DS 0x20
148#define PREFIX_ES 0x40
149#define PREFIX_FS 0x80
150#define PREFIX_GS 0x100
151#define PREFIX_DATA 0x200
152#define PREFIX_ADDR 0x400
153#define PREFIX_FWAIT 0x800
154
155/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
156   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
157   on error.  */
158#define FETCH_DATA(info, addr) \
159  ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
160   ? 1 : fetch_data ((info), (addr)))
161
162static int
163fetch_data (info, addr)
164     struct disassemble_info *info;
165     bfd_byte *addr;
166{
167  int status;
168  struct dis_private *priv = (struct dis_private *) info->private_data;
169  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
170
171  status = (*info->read_memory_func) (start,
172                                      priv->max_fetched,
173                                      addr - priv->max_fetched,
174                                      info);
175  if (status != 0)
176    {
177      /* If we did manage to read at least one byte, then
178         print_insn_i386 will do something sensible.  Otherwise, print
179         an error.  We do that here because this is where we know
180         STATUS.  */
181      if (priv->max_fetched == priv->the_buffer)
182        (*info->memory_error_func) (status, start, info);
183      longjmp (priv->bailout, 1);
184    }
185  else
186    priv->max_fetched = addr;
187  return 1;
188}
189
190#define XX NULL, 0
191
192#define Eb OP_E, b_mode
193#define Ev OP_E, v_mode
194#define Ed OP_E, d_mode
195#define indirEb OP_indirE, b_mode
196#define indirEv OP_indirE, v_mode
197#define Ew OP_E, w_mode
198#define Ma OP_E, v_mode
199#define M OP_E, 0               /* lea, lgdt, etc. */
200#define Mp OP_E, 0              /* 32 or 48 bit memory operand for LDS, LES etc */
201#define Gb OP_G, b_mode
202#define Gv OP_G, v_mode
203#define Gd OP_G, d_mode
204#define Gw OP_G, w_mode
205#define Rd OP_Rd, d_mode
206#define Rm OP_Rd, m_mode
207#define Ib OP_I, b_mode
208#define sIb OP_sI, b_mode       /* sign extened byte */
209#define Iv OP_I, v_mode
210#define Iq OP_I, q_mode
211#define Iv64 OP_I64, v_mode
212#define Iw OP_I, w_mode
213#define Jb OP_J, b_mode
214#define Jv OP_J, v_mode
215#define Cm OP_C, m_mode
216#define Dm OP_D, m_mode
217#define Td OP_T, d_mode
218
219#define RMeAX OP_REG, eAX_reg
220#define RMeBX OP_REG, eBX_reg
221#define RMeCX OP_REG, eCX_reg
222#define RMeDX OP_REG, eDX_reg
223#define RMeSP OP_REG, eSP_reg
224#define RMeBP OP_REG, eBP_reg
225#define RMeSI OP_REG, eSI_reg
226#define RMeDI OP_REG, eDI_reg
227#define RMrAX OP_REG, rAX_reg
228#define RMrBX OP_REG, rBX_reg
229#define RMrCX OP_REG, rCX_reg
230#define RMrDX OP_REG, rDX_reg
231#define RMrSP OP_REG, rSP_reg
232#define RMrBP OP_REG, rBP_reg
233#define RMrSI OP_REG, rSI_reg
234#define RMrDI OP_REG, rDI_reg
235#define RMAL OP_REG, al_reg
236#define RMAL OP_REG, al_reg
237#define RMCL OP_REG, cl_reg
238#define RMDL OP_REG, dl_reg
239#define RMBL OP_REG, bl_reg
240#define RMAH OP_REG, ah_reg
241#define RMCH OP_REG, ch_reg
242#define RMDH OP_REG, dh_reg
243#define RMBH OP_REG, bh_reg
244#define RMAX OP_REG, ax_reg
245#define RMDX OP_REG, dx_reg
246
247#define eAX OP_IMREG, eAX_reg
248#define eBX OP_IMREG, eBX_reg
249#define eCX OP_IMREG, eCX_reg
250#define eDX OP_IMREG, eDX_reg
251#define eSP OP_IMREG, eSP_reg
252#define eBP OP_IMREG, eBP_reg
253#define eSI OP_IMREG, eSI_reg
254#define eDI OP_IMREG, eDI_reg
255#define AL OP_IMREG, al_reg
256#define AL OP_IMREG, al_reg
257#define CL OP_IMREG, cl_reg
258#define DL OP_IMREG, dl_reg
259#define BL OP_IMREG, bl_reg
260#define AH OP_IMREG, ah_reg
261#define CH OP_IMREG, ch_reg
262#define DH OP_IMREG, dh_reg
263#define BH OP_IMREG, bh_reg
264#define AX OP_IMREG, ax_reg
265#define DX OP_IMREG, dx_reg
266#define indirDX OP_IMREG, indir_dx_reg
267
268#define Sw OP_SEG, w_mode
269#define Ap OP_DIR, 0
270#define Ob OP_OFF, b_mode
271#define Ob64 OP_OFF64, b_mode
272#define Ov OP_OFF, v_mode
273#define Ov64 OP_OFF64, v_mode
274#define Xb OP_DSreg, eSI_reg
275#define Xv OP_DSreg, eSI_reg
276#define Yb OP_ESreg, eDI_reg
277#define Yv OP_ESreg, eDI_reg
278#define DSBX OP_DSreg, eBX_reg
279
280#define es OP_REG, es_reg
281#define ss OP_REG, ss_reg
282#define cs OP_REG, cs_reg
283#define ds OP_REG, ds_reg
284#define fs OP_REG, fs_reg
285#define gs OP_REG, gs_reg
286
287#define MX OP_MMX, 0
288#define XM OP_XMM, 0
289#define EM OP_EM, v_mode
290#define EX OP_EX, v_mode
291#define MS OP_MS, v_mode
292#define XS OP_XS, v_mode
293#define None OP_E, 0
294#define OPSUF OP_3DNowSuffix, 0
295#define OPSIMD OP_SIMD_Suffix, 0
296
297#define cond_jump_flag NULL, cond_jump_mode
298#define loop_jcxz_flag NULL, loop_jcxz_mode
299
300/* bits in sizeflag */
301#define SUFFIX_ALWAYS 4
302#define AFLAG 2
303#define DFLAG 1
304
305#define b_mode 1  /* byte operand */
306#define v_mode 2  /* operand size depends on prefixes */
307#define w_mode 3  /* word operand */
308#define d_mode 4  /* double word operand  */
309#define q_mode 5  /* quad word operand */
310#define x_mode 6
311#define m_mode 7  /* d_mode in 32bit, q_mode in 64bit mode.  */
312#define cond_jump_mode 8
313#define loop_jcxz_mode 9
314
315#define es_reg 100
316#define cs_reg 101
317#define ss_reg 102
318#define ds_reg 103
319#define fs_reg 104
320#define gs_reg 105
321
322#define eAX_reg 108
323#define eCX_reg 109
324#define eDX_reg 110
325#define eBX_reg 111
326#define eSP_reg 112
327#define eBP_reg 113
328#define eSI_reg 114
329#define eDI_reg 115
330
331#define al_reg 116
332#define cl_reg 117
333#define dl_reg 118
334#define bl_reg 119
335#define ah_reg 120
336#define ch_reg 121
337#define dh_reg 122
338#define bh_reg 123
339
340#define ax_reg 124
341#define cx_reg 125
342#define dx_reg 126
343#define bx_reg 127
344#define sp_reg 128
345#define bp_reg 129
346#define si_reg 130
347#define di_reg 131
348
349#define rAX_reg 132
350#define rCX_reg 133
351#define rDX_reg 134
352#define rBX_reg 135
353#define rSP_reg 136
354#define rBP_reg 137
355#define rSI_reg 138
356#define rDI_reg 139
357
358#define indir_dx_reg 150
359
360#define FLOATCODE 1
361#define USE_GROUPS 2
362#define USE_PREFIX_USER_TABLE 3
363#define X86_64_SPECIAL 4
364
365#define FLOAT     NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
366
367#define GRP1b     NULL, NULL, USE_GROUPS, NULL,  0, NULL, 0
368#define GRP1S     NULL, NULL, USE_GROUPS, NULL,  1, NULL, 0
369#define GRP1Ss    NULL, NULL, USE_GROUPS, NULL,  2, NULL, 0
370#define GRP2b     NULL, NULL, USE_GROUPS, NULL,  3, NULL, 0
371#define GRP2S     NULL, NULL, USE_GROUPS, NULL,  4, NULL, 0
372#define GRP2b_one NULL, NULL, USE_GROUPS, NULL,  5, NULL, 0
373#define GRP2S_one NULL, NULL, USE_GROUPS, NULL,  6, NULL, 0
374#define GRP2b_cl  NULL, NULL, USE_GROUPS, NULL,  7, NULL, 0
375#define GRP2S_cl  NULL, NULL, USE_GROUPS, NULL,  8, NULL, 0
376#define GRP3b     NULL, NULL, USE_GROUPS, NULL,  9, NULL, 0
377#define GRP3S     NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
378#define GRP4      NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
379#define GRP5      NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
380#define GRP6      NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
381#define GRP7      NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
382#define GRP8      NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
383#define GRP9      NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
384#define GRP10     NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
385#define GRP11     NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
386#define GRP12     NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
387#define GRP13     NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
388#define GRP14     NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
389#define GRPAMD    NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
390
391#define PREGRP0   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  0, NULL, 0
392#define PREGRP1   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  1, NULL, 0
393#define PREGRP2   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  2, NULL, 0
394#define PREGRP3   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  3, NULL, 0
395#define PREGRP4   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  4, NULL, 0
396#define PREGRP5   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  5, NULL, 0
397#define PREGRP6   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  6, NULL, 0
398#define PREGRP7   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  7, NULL, 0
399#define PREGRP8   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  8, NULL, 0
400#define PREGRP9   NULL, NULL, USE_PREFIX_USER_TABLE, NULL,  9, NULL, 0
401#define PREGRP10  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
402#define PREGRP11  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
403#define PREGRP12  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
404#define PREGRP13  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
405#define PREGRP14  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
406#define PREGRP15  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
407#define PREGRP16  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
408#define PREGRP17  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
409#define PREGRP18  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
410#define PREGRP19  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
411#define PREGRP20  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
412#define PREGRP21  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
413#define PREGRP22  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
414#define PREGRP23  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
415#define PREGRP24  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
416#define PREGRP25  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
417#define PREGRP26  NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
418
419#define X86_64_0  NULL, NULL, X86_64_SPECIAL, NULL,  0, NULL, 0
420
421typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag));
422
423struct dis386 {
424  const char *name;
425  op_rtn op1;
426  int bytemode1;
427  op_rtn op2;
428  int bytemode2;
429  op_rtn op3;
430  int bytemode3;
431};
432
433/* Upper case letters in the instruction names here are macros.
434   'A' => print 'b' if no register operands or suffix_always is true
435   'B' => print 'b' if suffix_always is true
436   'E' => print 'e' if 32-bit form of jcxz
437   'F' => print 'w' or 'l' depending on address size prefix (loop insns)
438   'H' => print ",pt" or ",pn" branch hint
439   'L' => print 'l' if suffix_always is true
440   'N' => print 'n' if instruction has no wait "prefix"
441   'O' => print 'd', or 'o'
442   'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
443   .      or suffix_always is true.  print 'q' if rex prefix is present.
444   'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
445   .      is true
446   'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
447   'S' => print 'w', 'l' or 'q' if suffix_always is true
448   'T' => print 'q' in 64bit mode and behave as 'P' otherwise
449   'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
450   'X' => print 's', 'd' depending on data16 prefix (for XMM)
451   'W' => print 'b' or 'w' ("w" or "de" in intel mode)
452   'Y' => 'q' if instruction has an REX 64bit overwrite prefix
453
454   Many of the above letters print nothing in Intel mode.  See "putop"
455   for the details.
456
457   Braces '{' and '}', and vertical bars '|', indicate alternative
458   mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
459   modes.  In cases where there are only two alternatives, the X86_64
460   instruction is reserved, and "(bad)" is printed.
461*/
462
463static const struct dis386 dis386[] = {
464  /* 00 */
465  { "addB",             Eb, Gb, XX },
466  { "addS",             Ev, Gv, XX },
467  { "addB",             Gb, Eb, XX },
468  { "addS",             Gv, Ev, XX },
469  { "addB",             AL, Ib, XX },
470  { "addS",             eAX, Iv, XX },
471  { "push{T|}",         es, XX, XX },
472  { "pop{T|}",          es, XX, XX },
473  /* 08 */
474  { "orB",              Eb, Gb, XX },
475  { "orS",              Ev, Gv, XX },
476  { "orB",              Gb, Eb, XX },
477  { "orS",              Gv, Ev, XX },
478  { "orB",              AL, Ib, XX },
479  { "orS",              eAX, Iv, XX },
480  { "push{T|}",         cs, XX, XX },
481  { "(bad)",            XX, XX, XX },   /* 0x0f extended opcode escape */
482  /* 10 */
483  { "adcB",             Eb, Gb, XX },
484  { "adcS",             Ev, Gv, XX },
485  { "adcB",             Gb, Eb, XX },
486  { "adcS",             Gv, Ev, XX },
487  { "adcB",             AL, Ib, XX },
488  { "adcS",             eAX, Iv, XX },
489  { "push{T|}",         ss, XX, XX },
490  { "popT|}",           ss, XX, XX },
491  /* 18 */
492  { "sbbB",             Eb, Gb, XX },
493  { "sbbS",             Ev, Gv, XX },
494  { "sbbB",             Gb, Eb, XX },
495  { "sbbS",             Gv, Ev, XX },
496  { "sbbB",             AL, Ib, XX },
497  { "sbbS",             eAX, Iv, XX },
498  { "push{T|}",         ds, XX, XX },
499  { "pop{T|}",          ds, XX, XX },
500  /* 20 */
501  { "andB",             Eb, Gb, XX },
502  { "andS",             Ev, Gv, XX },
503  { "andB",             Gb, Eb, XX },
504  { "andS",             Gv, Ev, XX },
505  { "andB",             AL, Ib, XX },
506  { "andS",             eAX, Iv, XX },
507  { "(bad)",            XX, XX, XX },   /* SEG ES prefix */
508  { "daa{|}",           XX, XX, XX },
509  /* 28 */
510  { "subB",             Eb, Gb, XX },
511  { "subS",             Ev, Gv, XX },
512  { "subB",             Gb, Eb, XX },
513  { "subS",             Gv, Ev, XX },
514  { "subB",             AL, Ib, XX },
515  { "subS",             eAX, Iv, XX },
516  { "(bad)",            XX, XX, XX },   /* SEG CS prefix */
517  { "das{|}",           XX, XX, XX },
518  /* 30 */
519  { "xorB",             Eb, Gb, XX },
520  { "xorS",             Ev, Gv, XX },
521  { "xorB",             Gb, Eb, XX },
522  { "xorS",             Gv, Ev, XX },
523  { "xorB",             AL, Ib, XX },
524  { "xorS",             eAX, Iv, XX },
525  { "(bad)",            XX, XX, XX },   /* SEG SS prefix */
526  { "aaa{|}",           XX, XX, XX },
527  /* 38 */
528  { "cmpB",             Eb, Gb, XX },
529  { "cmpS",             Ev, Gv, XX },
530  { "cmpB",             Gb, Eb, XX },
531  { "cmpS",             Gv, Ev, XX },
532  { "cmpB",             AL, Ib, XX },
533  { "cmpS",             eAX, Iv, XX },
534  { "(bad)",            XX, XX, XX },   /* SEG DS prefix */
535  { "aas{|}",           XX, XX, XX },
536  /* 40 */
537  { "inc{S|}",          RMeAX, XX, XX },
538  { "inc{S|}",          RMeCX, XX, XX },
539  { "inc{S|}",          RMeDX, XX, XX },
540  { "inc{S|}",          RMeBX, XX, XX },
541  { "inc{S|}",          RMeSP, XX, XX },
542  { "inc{S|}",          RMeBP, XX, XX },
543  { "inc{S|}",          RMeSI, XX, XX },
544  { "inc{S|}",          RMeDI, XX, XX },
545  /* 48 */
546  { "dec{S|}",          RMeAX, XX, XX },
547  { "dec{S|}",          RMeCX, XX, XX },
548  { "dec{S|}",          RMeDX, XX, XX },
549  { "dec{S|}",          RMeBX, XX, XX },
550  { "dec{S|}",          RMeSP, XX, XX },
551  { "dec{S|}",          RMeBP, XX, XX },
552  { "dec{S|}",          RMeSI, XX, XX },
553  { "dec{S|}",          RMeDI, XX, XX },
554  /* 50 */
555  { "pushS",            RMrAX, XX, XX },
556  { "pushS",            RMrCX, XX, XX },
557  { "pushS",            RMrDX, XX, XX },
558  { "pushS",            RMrBX, XX, XX },
559  { "pushS",            RMrSP, XX, XX },
560  { "pushS",            RMrBP, XX, XX },
561  { "pushS",            RMrSI, XX, XX },
562  { "pushS",            RMrDI, XX, XX },
563  /* 58 */
564  { "popS",             RMrAX, XX, XX },
565  { "popS",             RMrCX, XX, XX },
566  { "popS",             RMrDX, XX, XX },
567  { "popS",             RMrBX, XX, XX },
568  { "popS",             RMrSP, XX, XX },
569  { "popS",             RMrBP, XX, XX },
570  { "popS",             RMrSI, XX, XX },
571  { "popS",             RMrDI, XX, XX },
572  /* 60 */
573  { "pusha{P|}",        XX, XX, XX },
574  { "popa{P|}",         XX, XX, XX },
575  { "bound{S|}",        Gv, Ma, XX },
576  { X86_64_0 },
577  { "(bad)",            XX, XX, XX },   /* seg fs */
578  { "(bad)",            XX, XX, XX },   /* seg gs */
579  { "(bad)",            XX, XX, XX },   /* op size prefix */
580  { "(bad)",            XX, XX, XX },   /* adr size prefix */
581  /* 68 */
582  { "pushT",            Iq, XX, XX },
583  { "imulS",            Gv, Ev, Iv },
584  { "pushT",            sIb, XX, XX },
585  { "imulS",            Gv, Ev, sIb },
586  { "ins{b||b|}",       Yb, indirDX, XX },
587  { "ins{R||R|}",       Yv, indirDX, XX },
588  { "outs{b||b|}",      indirDX, Xb, XX },
589  { "outs{R||R|}",      indirDX, Xv, XX },
590  /* 70 */
591  { "joH",              Jb, XX, cond_jump_flag },
592  { "jnoH",             Jb, XX, cond_jump_flag },
593  { "jbH",              Jb, XX, cond_jump_flag },
594  { "jaeH",             Jb, XX, cond_jump_flag },
595  { "jeH",              Jb, XX, cond_jump_flag },
596  { "jneH",             Jb, XX, cond_jump_flag },
597  { "jbeH",             Jb, XX, cond_jump_flag },
598  { "jaH",              Jb, XX, cond_jump_flag },
599  /* 78 */
600  { "jsH",              Jb, XX, cond_jump_flag },
601  { "jnsH",             Jb, XX, cond_jump_flag },
602  { "jpH",              Jb, XX, cond_jump_flag },
603  { "jnpH",             Jb, XX, cond_jump_flag },
604  { "jlH",              Jb, XX, cond_jump_flag },
605  { "jgeH",             Jb, XX, cond_jump_flag },
606  { "jleH",             Jb, XX, cond_jump_flag },
607  { "jgH",              Jb, XX, cond_jump_flag },
608  /* 80 */
609  { GRP1b },
610  { GRP1S },
611  { "(bad)",            XX, XX, XX },
612  { GRP1Ss },
613  { "testB",            Eb, Gb, XX },
614  { "testS",            Ev, Gv, XX },
615  { "xchgB",            Eb, Gb, XX },
616  { "xchgS",            Ev, Gv, XX },
617  /* 88 */
618  { "movB",             Eb, Gb, XX },
619  { "movS",             Ev, Gv, XX },
620  { "movB",             Gb, Eb, XX },
621  { "movS",             Gv, Ev, XX },
622  { "movQ",             Ev, Sw, XX },
623  { "leaS",             Gv, M, XX },
624  { "movQ",             Sw, Ev, XX },
625  { "popU",             Ev, XX, XX },
626  /* 90 */
627  { "nop",              XX, XX, XX },
628  /* FIXME: NOP with REPz prefix is called PAUSE.  */
629  { "xchgS",            RMeCX, eAX, XX },
630  { "xchgS",            RMeDX, eAX, XX },
631  { "xchgS",            RMeBX, eAX, XX },
632  { "xchgS",            RMeSP, eAX, XX },
633  { "xchgS",            RMeBP, eAX, XX },
634  { "xchgS",            RMeSI, eAX, XX },
635  { "xchgS",            RMeDI, eAX, XX },
636  /* 98 */
637  { "cW{tR||tR|}",      XX, XX, XX },
638  { "cR{tO||tO|}",      XX, XX, XX },
639  { "lcall{T|}",        Ap, XX, XX },
640  { "(bad)",            XX, XX, XX },   /* fwait */
641  { "pushfT",           XX, XX, XX },
642  { "popfT",            XX, XX, XX },
643  { "sahf{|}",          XX, XX, XX },
644  { "lahf{|}",          XX, XX, XX },
645  /* a0 */
646  { "movB",             AL, Ob64, XX },
647  { "movS",             eAX, Ov64, XX },
648  { "movB",             Ob64, AL, XX },
649  { "movS",             Ov64, eAX, XX },
650  { "movs{b||b|}",      Yb, Xb, XX },
651  { "movs{R||R|}",      Yv, Xv, XX },
652  { "cmps{b||b|}",      Xb, Yb, XX },
653  { "cmps{R||R|}",      Xv, Yv, XX },
654  /* a8 */
655  { "testB",            AL, Ib, XX },
656  { "testS",            eAX, Iv, XX },
657  { "stosB",            Yb, AL, XX },
658  { "stosS",            Yv, eAX, XX },
659  { "lodsB",            AL, Xb, XX },
660  { "lodsS",            eAX, Xv, XX },
661  { "scasB",            AL, Yb, XX },
662  { "scasS",            eAX, Yv, XX },
663  /* b0 */
664  { "movB",             RMAL, Ib, XX },
665  { "movB",             RMCL, Ib, XX },
666  { "movB",             RMDL, Ib, XX },
667  { "movB",             RMBL, Ib, XX },
668  { "movB",             RMAH, Ib, XX },
669  { "movB",             RMCH, Ib, XX },
670  { "movB",             RMDH, Ib, XX },
671  { "movB",             RMBH, Ib, XX },
672  /* b8 */
673  { "movS",             RMeAX, Iv64, XX },
674  { "movS",             RMeCX, Iv64, XX },
675  { "movS",             RMeDX, Iv64, XX },
676  { "movS",             RMeBX, Iv64, XX },
677  { "movS",             RMeSP, Iv64, XX },
678  { "movS",             RMeBP, Iv64, XX },
679  { "movS",             RMeSI, Iv64, XX },
680  { "movS",             RMeDI, Iv64, XX },
681  /* c0 */
682  { GRP2b },
683  { GRP2S },
684  { "retT",             Iw, XX, XX },
685  { "retT",             XX, XX, XX },
686  { "les{S|}",          Gv, Mp, XX },
687  { "ldsS",             Gv, Mp, XX },
688  { "movA",             Eb, Ib, XX },
689  { "movQ",             Ev, Iv, XX },
690  /* c8 */
691  { "enterT",           Iw, Ib, XX },
692  { "leaveT",           XX, XX, XX },
693  { "lretP",            Iw, XX, XX },
694  { "lretP",            XX, XX, XX },
695  { "int3",             XX, XX, XX },
696  { "int",              Ib, XX, XX },
697  { "into{|}",          XX, XX, XX },
698  { "iretP",            XX, XX, XX },
699  /* d0 */
700  { GRP2b_one },
701  { GRP2S_one },
702  { GRP2b_cl },
703  { GRP2S_cl },
704  { "aam{|}",           sIb, XX, XX },
705  { "aad{|}",           sIb, XX, XX },
706  { "(bad)",            XX, XX, XX },
707  { "xlat",             DSBX, XX, XX },
708  /* d8 */
709  { FLOAT },
710  { FLOAT },
711  { FLOAT },
712  { FLOAT },
713  { FLOAT },
714  { FLOAT },
715  { FLOAT },
716  { FLOAT },
717  /* e0 */
718  { "loopneFH",         Jb, XX, loop_jcxz_flag },
719  { "loopeFH",          Jb, XX, loop_jcxz_flag },
720  { "loopFH",           Jb, XX, loop_jcxz_flag },
721  { "jEcxzH",           Jb, XX, loop_jcxz_flag },
722  { "inB",              AL, Ib, XX },
723  { "inS",              eAX, Ib, XX },
724  { "outB",             Ib, AL, XX },
725  { "outS",             Ib, eAX, XX },
726  /* e8 */
727  { "callT",            Jv, XX, XX },
728  { "jmpT",             Jv, XX, XX },
729  { "ljmp{T|}",         Ap, XX, XX },
730  { "jmp",              Jb, XX, XX },
731  { "inB",              AL, indirDX, XX },
732  { "inS",              eAX, indirDX, XX },
733  { "outB",             indirDX, AL, XX },
734  { "outS",             indirDX, eAX, XX },
735  /* f0 */
736  { "(bad)",            XX, XX, XX },   /* lock prefix */
737  { "(bad)",            XX, XX, XX },
738  { "(bad)",            XX, XX, XX },   /* repne */
739  { "(bad)",            XX, XX, XX },   /* repz */
740  { "hlt",              XX, XX, XX },
741  { "cmc",              XX, XX, XX },
742  { GRP3b },
743  { GRP3S },
744  /* f8 */
745  { "clc",              XX, XX, XX },
746  { "stc",              XX, XX, XX },
747  { "cli",              XX, XX, XX },
748  { "sti",              XX, XX, XX },
749  { "cld",              XX, XX, XX },
750  { "std",              XX, XX, XX },
751  { GRP4 },
752  { GRP5 },
753};
754
755static const struct dis386 dis386_twobyte[] = {
756  /* 00 */
757  { GRP6 },
758  { GRP7 },
759  { "larS",             Gv, Ew, XX },
760  { "lslS",             Gv, Ew, XX },
761  { "(bad)",            XX, XX, XX },
762  { "syscall",          XX, XX, XX },
763  { "clts",             XX, XX, XX },
764  { "sysretP",          XX, XX, XX },
765  /* 08 */
766  { "invd",             XX, XX, XX },
767  { "wbinvd",           XX, XX, XX },
768  { "(bad)",            XX, XX, XX },
769  { "ud2a",             XX, XX, XX },
770  { "(bad)",            XX, XX, XX },
771  { GRPAMD },
772  { "femms",            XX, XX, XX },
773  { "",                 MX, EM, OPSUF }, /* See OP_3DNowSuffix.  */
774  /* 10 */
775  { PREGRP8 },
776  { PREGRP9 },
777  { "movlpX",           XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
778  { "movlpX",           EX, XM, SIMD_Fixup, 'h' },
779  { "unpcklpX",         XM, EX, XX },
780  { "unpckhpX",         XM, EX, XX },
781  { "movhpX",           XM, EX, SIMD_Fixup, 'l' },
782  { "movhpX",           EX, XM, SIMD_Fixup, 'l' },
783  /* 18 */
784  { GRP14 },
785  { "(bad)",            XX, XX, XX },
786  { "(bad)",            XX, XX, XX },
787  { "(bad)",            XX, XX, XX },
788  { "(bad)",            XX, XX, XX },
789  { "(bad)",            XX, XX, XX },
790  { "(bad)",            XX, XX, XX },
791  { "(bad)",            XX, XX, XX },
792  /* 20 */
793  { "movL",             Rm, Cm, XX },
794  { "movL",             Rm, Dm, XX },
795  { "movL",             Cm, Rm, XX },
796  { "movL",             Dm, Rm, XX },
797  { "movL",             Rd, Td, XX },
798  { "(bad)",            XX, XX, XX },
799  { "movL",             Td, Rd, XX },
800  { "(bad)",            XX, XX, XX },
801  /* 28 */
802  { "movapX",           XM, EX, XX },
803  { "movapX",           EX, XM, XX },
804  { PREGRP2 },
805  { "movntpX",          Ev, XM, XX },
806  { PREGRP4 },
807  { PREGRP3 },
808  { "ucomisX",          XM,EX, XX },
809  { "comisX",           XM,EX, XX },
810  /* 30 */
811  { "wrmsr",            XX, XX, XX },
812  { "rdtsc",            XX, XX, XX },
813  { "rdmsr",            XX, XX, XX },
814  { "rdpmc",            XX, XX, XX },
815  { "sysenter",         XX, XX, XX },
816  { "sysexit",          XX, XX, XX },
817  { "(bad)",            XX, XX, XX },
818  { "(bad)",            XX, XX, XX },
819  /* 38 */
820  { "(bad)",            XX, XX, XX },
821  { "(bad)",            XX, XX, XX },
822  { "(bad)",            XX, XX, XX },
823  { "(bad)",            XX, XX, XX },
824  { "(bad)",            XX, XX, XX },
825  { "(bad)",            XX, XX, XX },
826  { "(bad)",            XX, XX, XX },
827  { "(bad)",            XX, XX, XX },
828  /* 40 */
829  { "cmovo",            Gv, Ev, XX },
830  { "cmovno",           Gv, Ev, XX },
831  { "cmovb",            Gv, Ev, XX },
832  { "cmovae",           Gv, Ev, XX },
833  { "cmove",            Gv, Ev, XX },
834  { "cmovne",           Gv, Ev, XX },
835  { "cmovbe",           Gv, Ev, XX },
836  { "cmova",            Gv, Ev, XX },
837  /* 48 */
838  { "cmovs",            Gv, Ev, XX },
839  { "cmovns",           Gv, Ev, XX },
840  { "cmovp",            Gv, Ev, XX },
841  { "cmovnp",           Gv, Ev, XX },
842  { "cmovl",            Gv, Ev, XX },
843  { "cmovge",           Gv, Ev, XX },
844  { "cmovle",           Gv, Ev, XX },
845  { "cmovg",            Gv, Ev, XX },
846  /* 50 */
847  { "movmskpX",         Gd, XS, XX },
848  { PREGRP13 },
849  { PREGRP12 },
850  { PREGRP11 },
851  { "andpX",            XM, EX, XX },
852  { "andnpX",           XM, EX, XX },
853  { "orpX",             XM, EX, XX },
854  { "xorpX",            XM, EX, XX },
855  /* 58 */
856  { PREGRP0 },
857  { PREGRP10 },
858  { PREGRP17 },
859  { PREGRP16 },
860  { PREGRP14 },
861  { PREGRP7 },
862  { PREGRP5 },
863  { PREGRP6 },
864  /* 60 */
865  { "punpcklbw",        MX, EM, XX },
866  { "punpcklwd",        MX, EM, XX },
867  { "punpckldq",        MX, EM, XX },
868  { "packsswb",         MX, EM, XX },
869  { "pcmpgtb",          MX, EM, XX },
870  { "pcmpgtw",          MX, EM, XX },
871  { "pcmpgtd",          MX, EM, XX },
872  { "packuswb",         MX, EM, XX },
873  /* 68 */
874  { "punpckhbw",        MX, EM, XX },
875  { "punpckhwd",        MX, EM, XX },
876  { "punpckhdq",        MX, EM, XX },
877  { "packssdw",         MX, EM, XX },
878  { PREGRP26 },
879  { PREGRP24 },
880  { "movd",             MX, Ed, XX },
881  { PREGRP19 },
882  /* 70 */
883  { PREGRP22 },
884  { GRP10 },
885  { GRP11 },
886  { GRP12 },
887  { "pcmpeqb",          MX, EM, XX },
888  { "pcmpeqw",          MX, EM, XX },
889  { "pcmpeqd",          MX, EM, XX },
890  { "emms",             XX, XX, XX },
891  /* 78 */
892  { "(bad)",            XX, XX, XX },
893  { "(bad)",            XX, XX, XX },
894  { "(bad)",            XX, XX, XX },
895  { "(bad)",            XX, XX, XX },
896  { "(bad)",            XX, XX, XX },
897  { "(bad)",            XX, XX, XX },
898  { PREGRP23 },
899  { PREGRP20 },
900  /* 80 */
901  { "joH",              Jv, XX, cond_jump_flag },
902  { "jnoH",             Jv, XX, cond_jump_flag },
903  { "jbH",              Jv, XX, cond_jump_flag },
904  { "jaeH",             Jv, XX, cond_jump_flag },
905  { "jeH",              Jv, XX, cond_jump_flag },
906  { "jneH",             Jv, XX, cond_jump_flag },
907  { "jbeH",             Jv, XX, cond_jump_flag },
908  { "jaH",              Jv, XX, cond_jump_flag },
909  /* 88 */
910  { "jsH",              Jv, XX, cond_jump_flag },
911  { "jnsH",             Jv, XX, cond_jump_flag },
912  { "jpH",              Jv, XX, cond_jump_flag },
913  { "jnpH",             Jv, XX, cond_jump_flag },
914  { "jlH",              Jv, XX, cond_jump_flag },
915  { "jgeH",             Jv, XX, cond_jump_flag },
916  { "jleH",             Jv, XX, cond_jump_flag },
917  { "jgH",              Jv, XX, cond_jump_flag },
918  /* 90 */
919  { "seto",             Eb, XX, XX },
920  { "setno",            Eb, XX, XX },
921  { "setb",             Eb, XX, XX },
922  { "setae",            Eb, XX, XX },
923  { "sete",             Eb, XX, XX },
924  { "setne",            Eb, XX, XX },
925  { "setbe",            Eb, XX, XX },
926  { "seta",             Eb, XX, XX },
927  /* 98 */
928  { "sets",             Eb, XX, XX },
929  { "setns",            Eb, XX, XX },
930  { "setp",             Eb, XX, XX },
931  { "setnp",            Eb, XX, XX },
932  { "setl",             Eb, XX, XX },
933  { "setge",            Eb, XX, XX },
934  { "setle",            Eb, XX, XX },
935  { "setg",             Eb, XX, XX },
936  /* a0 */
937  { "pushT",            fs, XX, XX },
938  { "popT",             fs, XX, XX },
939  { "cpuid",            XX, XX, XX },
940  { "btS",              Ev, Gv, XX },
941  { "shldS",            Ev, Gv, Ib },
942  { "shldS",            Ev, Gv, CL },
943  { "(bad)",            XX, XX, XX },
944  { "(bad)",            XX, XX, XX },
945  /* a8 */
946  { "pushT",            gs, XX, XX },
947  { "popT",             gs, XX, XX },
948  { "rsm",              XX, XX, XX },
949  { "btsS",             Ev, Gv, XX },
950  { "shrdS",            Ev, Gv, Ib },
951  { "shrdS",            Ev, Gv, CL },
952  { GRP13 },
953  { "imulS",            Gv, Ev, XX },
954  /* b0 */
955  { "cmpxchgB",         Eb, Gb, XX },
956  { "cmpxchgS",         Ev, Gv, XX },
957  { "lssS",             Gv, Mp, XX },
958  { "btrS",             Ev, Gv, XX },
959  { "lfsS",             Gv, Mp, XX },
960  { "lgsS",             Gv, Mp, XX },
961  { "movz{bR|x|bR|x}",  Gv, Eb, XX },
962  { "movz{wR|x|wR|x}",  Gv, Ew, XX }, /* yes, there really is movzww ! */
963  /* b8 */
964  { "(bad)",            XX, XX, XX },
965  { "ud2b",             XX, XX, XX },
966  { GRP8 },
967  { "btcS",             Ev, Gv, XX },
968  { "bsfS",             Gv, Ev, XX },
969  { "bsrS",             Gv, Ev, XX },
970  { "movs{bR|x|bR|x}",  Gv, Eb, XX },
971  { "movs{wR|x|wR|x}",  Gv, Ew, XX }, /* yes, there really is movsww ! */
972  /* c0 */
973  { "xaddB",            Eb, Gb, XX },
974  { "xaddS",            Ev, Gv, XX },
975  { PREGRP1 },
976  { "movntiS",          Ev, Gv, XX },
977  { "pinsrw",           MX, Ed, Ib },
978  { "pextrw",           Gd, MS, Ib },
979  { "shufpX",           XM, EX, Ib },
980  { GRP9 },
981  /* c8 */
982  { "bswap",            RMeAX, XX, XX },
983  { "bswap",            RMeCX, XX, XX },
984  { "bswap",            RMeDX, XX, XX },
985  { "bswap",            RMeBX, XX, XX },
986  { "bswap",            RMeSP, XX, XX },
987  { "bswap",            RMeBP, XX, XX },
988  { "bswap",            RMeSI, XX, XX },
989  { "bswap",            RMeDI, XX, XX },
990  /* d0 */
991  { "(bad)",            XX, XX, XX },
992  { "psrlw",            MX, EM, XX },
993  { "psrld",            MX, EM, XX },
994  { "psrlq",            MX, EM, XX },
995  { "paddq",            MX, EM, XX },
996  { "pmullw",           MX, EM, XX },
997  { PREGRP21 },
998  { "pmovmskb",         Gd, MS, XX },
999  /* d8 */
1000  { "psubusb",          MX, EM, XX },
1001  { "psubusw",          MX, EM, XX },
1002  { "pminub",           MX, EM, XX },
1003  { "pand",             MX, EM, XX },
1004  { "paddusb",          MX, EM, XX },
1005  { "paddusw",          MX, EM, XX },
1006  { "pmaxub",           MX, EM, XX },
1007  { "pandn",            MX, EM, XX },
1008  /* e0 */
1009  { "pavgb",            MX, EM, XX },
1010  { "psraw",            MX, EM, XX },
1011  { "psrad",            MX, EM, XX },
1012  { "pavgw",            MX, EM, XX },
1013  { "pmulhuw",          MX, EM, XX },
1014  { "pmulhw",           MX, EM, XX },
1015  { PREGRP15 },
1016  { PREGRP25 },
1017  /* e8 */
1018  { "psubsb",           MX, EM, XX },
1019  { "psubsw",           MX, EM, XX },
1020  { "pminsw",           MX, EM, XX },
1021  { "por",              MX, EM, XX },
1022  { "paddsb",           MX, EM, XX },
1023  { "paddsw",           MX, EM, XX },
1024  { "pmaxsw",           MX, EM, XX },
1025  { "pxor",             MX, EM, XX },
1026  /* f0 */
1027  { "(bad)",            XX, XX, XX },
1028  { "psllw",            MX, EM, XX },
1029  { "pslld",            MX, EM, XX },
1030  { "psllq",            MX, EM, XX },
1031  { "pmuludq",          MX, EM, XX },
1032  { "pmaddwd",          MX, EM, XX },
1033  { "psadbw",           MX, EM, XX },
1034  { PREGRP18 },
1035  /* f8 */
1036  { "psubb",            MX, EM, XX },
1037  { "psubw",            MX, EM, XX },
1038  { "psubd",            MX, EM, XX },
1039  { "psubq",            MX, EM, XX },
1040  { "paddb",            MX, EM, XX },
1041  { "paddw",            MX, EM, XX },
1042  { "paddd",            MX, EM, XX },
1043  { "(bad)",            XX, XX, XX }
1044};
1045
1046static const unsigned char onebyte_has_modrm[256] = {
1047  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1048  /*       -------------------------------        */
1049  /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1050  /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1051  /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1052  /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1053  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1054  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1055  /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1056  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1057  /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1058  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1059  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1060  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1061  /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1062  /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1063  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1064  /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1  /* f0 */
1065  /*       -------------------------------        */
1066  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1067};
1068
1069static const unsigned char twobyte_has_modrm[256] = {
1070  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1071  /*       -------------------------------        */
1072  /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1073  /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1074  /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1075  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1076  /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1077  /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1078  /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1079  /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
1080  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1081  /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1082  /* a0 */ 0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1, /* af */
1083  /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1084  /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1085  /* d0 */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1086  /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1087  /* f0 */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0  /* ff */
1088  /*       -------------------------------        */
1089  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1090};
1091
1092static const unsigned char twobyte_uses_SSE_prefix[256] = {
1093  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1094  /*       -------------------------------        */
1095  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1096  /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1097  /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1098  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1099  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1100  /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1101  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1102  /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1103  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1104  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1105  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1106  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1107  /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1108  /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1109  /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1110  /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0  /* ff */
1111  /*       -------------------------------        */
1112  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1113};
1114
1115static char obuf[100];
1116static char *obufp;
1117static char scratchbuf[100];
1118static unsigned char *start_codep;
1119static unsigned char *insn_codep;
1120static unsigned char *codep;
1121static disassemble_info *the_info;
1122static int mod;
1123static int rm;
1124static int reg;
1125static unsigned char need_modrm;
1126
1127/* If we are accessing mod/rm/reg without need_modrm set, then the
1128   values are stale.  Hitting this abort likely indicates that you
1129   need to update onebyte_has_modrm or twobyte_has_modrm.  */
1130#define MODRM_CHECK  if (!need_modrm) abort ()
1131
1132static const char **names64;
1133static const char **names32;
1134static const char **names16;
1135static const char **names8;
1136static const char **names8rex;
1137static const char **names_seg;
1138static const char **index16;
1139
1140static const char *intel_names64[] = {
1141  "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1142  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1143};
1144static const char *intel_names32[] = {
1145  "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1146  "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1147};
1148static const char *intel_names16[] = {
1149  "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1150  "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1151};
1152static const char *intel_names8[] = {
1153  "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1154};
1155static const char *intel_names8rex[] = {
1156  "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1157  "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1158};
1159static const char *intel_names_seg[] = {
1160  "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1161};
1162static const char *intel_index16[] = {
1163  "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1164};
1165
1166static const char *att_names64[] = {
1167  "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1168  "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1169};
1170static const char *att_names32[] = {
1171  "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1172  "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1173};
1174static const char *att_names16[] = {
1175  "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1176  "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1177};
1178static const char *att_names8[] = {
1179  "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1180};
1181static const char *att_names8rex[] = {
1182  "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1183  "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1184};
1185static const char *att_names_seg[] = {
1186  "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1187};
1188static const char *att_index16[] = {
1189  "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1190};
1191
1192static const struct dis386 grps[][8] = {
1193  /* GRP1b */
1194  {
1195    { "addA",   Eb, Ib, XX },
1196    { "orA",    Eb, Ib, XX },
1197    { "adcA",   Eb, Ib, XX },
1198    { "sbbA",   Eb, Ib, XX },
1199    { "andA",   Eb, Ib, XX },
1200    { "subA",   Eb, Ib, XX },
1201    { "xorA",   Eb, Ib, XX },
1202    { "cmpA",   Eb, Ib, XX }
1203  },
1204  /* GRP1S */
1205  {
1206    { "addQ",   Ev, Iv, XX },
1207    { "orQ",    Ev, Iv, XX },
1208    { "adcQ",   Ev, Iv, XX },
1209    { "sbbQ",   Ev, Iv, XX },
1210    { "andQ",   Ev, Iv, XX },
1211    { "subQ",   Ev, Iv, XX },
1212    { "xorQ",   Ev, Iv, XX },
1213    { "cmpQ",   Ev, Iv, XX }
1214  },
1215  /* GRP1Ss */
1216  {
1217    { "addQ",   Ev, sIb, XX },
1218    { "orQ",    Ev, sIb, XX },
1219    { "adcQ",   Ev, sIb, XX },
1220    { "sbbQ",   Ev, sIb, XX },
1221    { "andQ",   Ev, sIb, XX },
1222    { "subQ",   Ev, sIb, XX },
1223    { "xorQ",   Ev, sIb, XX },
1224    { "cmpQ",   Ev, sIb, XX }
1225  },
1226  /* GRP2b */
1227  {
1228    { "rolA",   Eb, Ib, XX },
1229    { "rorA",   Eb, Ib, XX },
1230    { "rclA",   Eb, Ib, XX },
1231    { "rcrA",   Eb, Ib, XX },
1232    { "shlA",   Eb, Ib, XX },
1233    { "shrA",   Eb, Ib, XX },
1234    { "(bad)",  XX, XX, XX },
1235    { "sarA",   Eb, Ib, XX },
1236  },
1237  /* GRP2S */
1238  {
1239    { "rolQ",   Ev, Ib, XX },
1240    { "rorQ",   Ev, Ib, XX },
1241    { "rclQ",   Ev, Ib, XX },
1242    { "rcrQ",   Ev, Ib, XX },
1243    { "shlQ",   Ev, Ib, XX },
1244    { "shrQ",   Ev, Ib, XX },
1245    { "(bad)",  XX, XX, XX },
1246    { "sarQ",   Ev, Ib, XX },
1247  },
1248  /* GRP2b_one */
1249  {
1250    { "rolA",   Eb, XX, XX },
1251    { "rorA",   Eb, XX, XX },
1252    { "rclA",   Eb, XX, XX },
1253    { "rcrA",   Eb, XX, XX },
1254    { "shlA",   Eb, XX, XX },
1255    { "shrA",   Eb, XX, XX },
1256    { "(bad)",  XX, XX, XX },
1257    { "sarA",   Eb, XX, XX },
1258  },
1259  /* GRP2S_one */
1260  {
1261    { "rolQ",   Ev, XX, XX },
1262    { "rorQ",   Ev, XX, XX },
1263    { "rclQ",   Ev, XX, XX },
1264    { "rcrQ",   Ev, XX, XX },
1265    { "shlQ",   Ev, XX, XX },
1266    { "shrQ",   Ev, XX, XX },
1267    { "(bad)",  XX, XX, XX},
1268    { "sarQ",   Ev, XX, XX },
1269  },
1270  /* GRP2b_cl */
1271  {
1272    { "rolA",   Eb, CL, XX },
1273    { "rorA",   Eb, CL, XX },
1274    { "rclA",   Eb, CL, XX },
1275    { "rcrA",   Eb, CL, XX },
1276    { "shlA",   Eb, CL, XX },
1277    { "shrA",   Eb, CL, XX },
1278    { "(bad)",  XX, XX, XX },
1279    { "sarA",   Eb, CL, XX },
1280  },
1281  /* GRP2S_cl */
1282  {
1283    { "rolQ",   Ev, CL, XX },
1284    { "rorQ",   Ev, CL, XX },
1285    { "rclQ",   Ev, CL, XX },
1286    { "rcrQ",   Ev, CL, XX },
1287    { "shlQ",   Ev, CL, XX },
1288    { "shrQ",   Ev, CL, XX },
1289    { "(bad)",  XX, XX, XX },
1290    { "sarQ",   Ev, CL, XX }
1291  },
1292  /* GRP3b */
1293  {
1294    { "testA",  Eb, Ib, XX },
1295    { "(bad)",  Eb, XX, XX },
1296    { "notA",   Eb, XX, XX },
1297    { "negA",   Eb, XX, XX },
1298    { "mulA",   Eb, XX, XX },   /* Don't print the implicit %al register,  */
1299    { "imulA",  Eb, XX, XX },   /* to distinguish these opcodes from other */
1300    { "divA",   Eb, XX, XX },   /* mul/imul opcodes.  Do the same for div  */
1301    { "idivA",  Eb, XX, XX }    /* and idiv for consistency.               */
1302  },
1303  /* GRP3S */
1304  {
1305    { "testQ",  Ev, Iv, XX },
1306    { "(bad)",  XX, XX, XX },
1307    { "notQ",   Ev, XX, XX },
1308    { "negQ",   Ev, XX, XX },
1309    { "mulQ",   Ev, XX, XX },   /* Don't print the implicit register.  */
1310    { "imulQ",  Ev, XX, XX },
1311    { "divQ",   Ev, XX, XX },
1312    { "idivQ",  Ev, XX, XX },
1313  },
1314  /* GRP4 */
1315  {
1316    { "incA",   Eb, XX, XX },
1317    { "decA",   Eb, XX, XX },
1318    { "(bad)",  XX, XX, XX },
1319    { "(bad)",  XX, XX, XX },
1320    { "(bad)",  XX, XX, XX },
1321    { "(bad)",  XX, XX, XX },
1322    { "(bad)",  XX, XX, XX },
1323    { "(bad)",  XX, XX, XX },
1324  },
1325  /* GRP5 */
1326  {
1327    { "incQ",   Ev, XX, XX },
1328    { "decQ",   Ev, XX, XX },
1329    { "callT",  indirEv, XX, XX },
1330    { "lcallT", indirEv, XX, XX },
1331    { "jmpT",   indirEv, XX, XX },
1332    { "ljmpT",  indirEv, XX, XX },
1333    { "pushU",  Ev, XX, XX },
1334    { "(bad)",  XX, XX, XX },
1335  },
1336  /* GRP6 */
1337  {
1338    { "sldtQ",  Ev, XX, XX },
1339    { "strQ",   Ev, XX, XX },
1340    { "lldt",   Ew, XX, XX },
1341    { "ltr",    Ew, XX, XX },
1342    { "verr",   Ew, XX, XX },
1343    { "verw",   Ew, XX, XX },
1344    { "(bad)",  XX, XX, XX },
1345    { "(bad)",  XX, XX, XX }
1346  },
1347  /* GRP7 */
1348  {
1349    { "sgdtQ",   M, XX, XX },
1350    { "sidtQ",   M, XX, XX },
1351    { "lgdtQ",   M, XX, XX },
1352    { "lidtQ",   M, XX, XX },
1353    { "smswQ",  Ev, XX, XX },
1354    { "(bad)",  XX, XX, XX },
1355    { "lmsw",   Ew, XX, XX },
1356    { "invlpg", Ew, XX, XX },
1357  },
1358  /* GRP8 */
1359  {
1360    { "(bad)",  XX, XX, XX },
1361    { "(bad)",  XX, XX, XX },
1362    { "(bad)",  XX, XX, XX },
1363    { "(bad)",  XX, XX, XX },
1364    { "btQ",    Ev, Ib, XX },
1365    { "btsQ",   Ev, Ib, XX },
1366    { "btrQ",   Ev, Ib, XX },
1367    { "btcQ",   Ev, Ib, XX },
1368  },
1369  /* GRP9 */
1370  {
1371    { "(bad)",  XX, XX, XX },
1372    { "cmpxchg8b", Ev, XX, XX },
1373    { "(bad)",  XX, XX, XX },
1374    { "(bad)",  XX, XX, XX },
1375    { "(bad)",  XX, XX, XX },
1376    { "(bad)",  XX, XX, XX },
1377    { "(bad)",  XX, XX, XX },
1378    { "(bad)",  XX, XX, XX },
1379  },
1380  /* GRP10 */
1381  {
1382    { "(bad)",  XX, XX, XX },
1383    { "(bad)",  XX, XX, XX },
1384    { "psrlw",  MS, Ib, XX },
1385    { "(bad)",  XX, XX, XX },
1386    { "psraw",  MS, Ib, XX },
1387    { "(bad)",  XX, XX, XX },
1388    { "psllw",  MS, Ib, XX },
1389    { "(bad)",  XX, XX, XX },
1390  },
1391  /* GRP11 */
1392  {
1393    { "(bad)",  XX, XX, XX },
1394    { "(bad)",  XX, XX, XX },
1395    { "psrld",  MS, Ib, XX },
1396    { "(bad)",  XX, XX, XX },
1397    { "psrad",  MS, Ib, XX },
1398    { "(bad)",  XX, XX, XX },
1399    { "pslld",  MS, Ib, XX },
1400    { "(bad)",  XX, XX, XX },
1401  },
1402  /* GRP12 */
1403  {
1404    { "(bad)",  XX, XX, XX },
1405    { "(bad)",  XX, XX, XX },
1406    { "psrlq",  MS, Ib, XX },
1407    { "psrldq", MS, Ib, XX },
1408    { "(bad)",  XX, XX, XX },
1409    { "(bad)",  XX, XX, XX },
1410    { "psllq",  MS, Ib, XX },
1411    { "pslldq", MS, Ib, XX },
1412  },
1413  /* GRP13 */
1414  {
1415    { "fxsave", Ev, XX, XX },
1416    { "fxrstor", Ev, XX, XX },
1417    { "ldmxcsr", Ev, XX, XX },
1418    { "stmxcsr", Ev, XX, XX },
1419    { "(bad)",  XX, XX, XX },
1420    { "lfence", None, XX, XX },
1421    { "mfence", None, XX, XX },
1422    { "sfence", None, XX, XX },
1423    /* FIXME: the sfence with memory operand is clflush!  */
1424  },
1425  /* GRP14 */
1426  {
1427    { "prefetchnta", Ev, XX, XX },
1428    { "prefetcht0", Ev, XX, XX },
1429    { "prefetcht1", Ev, XX, XX },
1430    { "prefetcht2", Ev, XX, XX },
1431    { "(bad)",  XX, XX, XX },
1432    { "(bad)",  XX, XX, XX },
1433    { "(bad)",  XX, XX, XX },
1434    { "(bad)",  XX, XX, XX },
1435  },
1436  /* GRPAMD */
1437  {
1438    { "prefetch", Eb, XX, XX },
1439    { "prefetchw", Eb, XX, XX },
1440    { "(bad)",  XX, XX, XX },
1441    { "(bad)",  XX, XX, XX },
1442    { "(bad)",  XX, XX, XX },
1443    { "(bad)",  XX, XX, XX },
1444    { "(bad)",  XX, XX, XX },
1445    { "(bad)",  XX, XX, XX },
1446  }
1447};
1448
1449static const struct dis386 prefix_user_table[][4] = {
1450  /* PREGRP0 */
1451  {
1452    { "addps", XM, EX, XX },
1453    { "addss", XM, EX, XX },
1454    { "addpd", XM, EX, XX },
1455    { "addsd", XM, EX, XX },
1456  },
1457  /* PREGRP1 */
1458  {
1459    { "", XM, EX, OPSIMD },     /* See OP_SIMD_SUFFIX.  */
1460    { "", XM, EX, OPSIMD },
1461    { "", XM, EX, OPSIMD },
1462    { "", XM, EX, OPSIMD },
1463  },
1464  /* PREGRP2 */
1465  {
1466    { "cvtpi2ps", XM, EM, XX },
1467    { "cvtsi2ssY", XM, Ev, XX },
1468    { "cvtpi2pd", XM, EM, XX },
1469    { "cvtsi2sdY", XM, Ev, XX },
1470  },
1471  /* PREGRP3 */
1472  {
1473    { "cvtps2pi", MX, EX, XX },
1474    { "cvtss2siY", Gv, EX, XX },
1475    { "cvtpd2pi", MX, EX, XX },
1476    { "cvtsd2siY", Gv, EX, XX },
1477  },
1478  /* PREGRP4 */
1479  {
1480    { "cvttps2pi", MX, EX, XX },
1481    { "cvttss2siY", Gv, EX, XX },
1482    { "cvttpd2pi", MX, EX, XX },
1483    { "cvttsd2siY", Gv, EX, XX },
1484  },
1485  /* PREGRP5 */
1486  {
1487    { "divps", XM, EX, XX },
1488    { "divss", XM, EX, XX },
1489    { "divpd", XM, EX, XX },
1490    { "divsd", XM, EX, XX },
1491  },
1492  /* PREGRP6 */
1493  {
1494    { "maxps", XM, EX, XX },
1495    { "maxss", XM, EX, XX },
1496    { "maxpd", XM, EX, XX },
1497    { "maxsd", XM, EX, XX },
1498  },
1499  /* PREGRP7 */
1500  {
1501    { "minps", XM, EX, XX },
1502    { "minss", XM, EX, XX },
1503    { "minpd", XM, EX, XX },
1504    { "minsd", XM, EX, XX },
1505  },
1506  /* PREGRP8 */
1507  {
1508    { "movups", XM, EX, XX },
1509    { "movss", XM, EX, XX },
1510    { "movupd", XM, EX, XX },
1511    { "movsd", XM, EX, XX },
1512  },
1513  /* PREGRP9 */
1514  {
1515    { "movups", EX, XM, XX },
1516    { "movss", EX, XM, XX },
1517    { "movupd", EX, XM, XX },
1518    { "movsd", EX, XM, XX },
1519  },
1520  /* PREGRP10 */
1521  {
1522    { "mulps", XM, EX, XX },
1523    { "mulss", XM, EX, XX },
1524    { "mulpd", XM, EX, XX },
1525    { "mulsd", XM, EX, XX },
1526  },
1527  /* PREGRP11 */
1528  {
1529    { "rcpps", XM, EX, XX },
1530    { "rcpss", XM, EX, XX },
1531    { "(bad)", XM, EX, XX },
1532    { "(bad)", XM, EX, XX },
1533  },
1534  /* PREGRP12 */
1535  {
1536    { "rsqrtps", XM, EX, XX },
1537    { "rsqrtss", XM, EX, XX },
1538    { "(bad)", XM, EX, XX },
1539    { "(bad)", XM, EX, XX },
1540  },
1541  /* PREGRP13 */
1542  {
1543    { "sqrtps", XM, EX, XX },
1544    { "sqrtss", XM, EX, XX },
1545    { "sqrtpd", XM, EX, XX },
1546    { "sqrtsd", XM, EX, XX },
1547  },
1548  /* PREGRP14 */
1549  {
1550    { "subps", XM, EX, XX },
1551    { "subss", XM, EX, XX },
1552    { "subpd", XM, EX, XX },
1553    { "subsd", XM, EX, XX },
1554  },
1555  /* PREGRP15 */
1556  {
1557    { "(bad)", XM, EX, XX },
1558    { "cvtdq2pd", XM, EX, XX },
1559    { "cvttpd2dq", XM, EX, XX },
1560    { "cvtpd2dq", XM, EX, XX },
1561  },
1562  /* PREGRP16 */
1563  {
1564    { "cvtdq2ps", XM, EX, XX },
1565    { "cvttps2dq",XM, EX, XX },
1566    { "cvtps2dq",XM, EX, XX },
1567    { "(bad)", XM, EX, XX },
1568  },
1569  /* PREGRP17 */
1570  {
1571    { "cvtps2pd", XM, EX, XX },
1572    { "cvtss2sd", XM, EX, XX },
1573    { "cvtpd2ps", XM, EX, XX },
1574    { "cvtsd2ss", XM, EX, XX },
1575  },
1576  /* PREGRP18 */
1577  {
1578    { "maskmovq", MX, MS, XX },
1579    { "(bad)", XM, EX, XX },
1580    { "maskmovdqu", XM, EX, XX },
1581    { "(bad)", XM, EX, XX },
1582  },
1583  /* PREGRP19 */
1584  {
1585    { "movq", MX, EM, XX },
1586    { "movdqu", XM, EX, XX },
1587    { "movdqa", XM, EX, XX },
1588    { "(bad)", XM, EX, XX },
1589  },
1590  /* PREGRP20 */
1591  {
1592    { "movq", EM, MX, XX },
1593    { "movdqu", EX, XM, XX },
1594    { "movdqa", EX, XM, XX },
1595    { "(bad)", EX, XM, XX },
1596  },
1597  /* PREGRP21 */
1598  {
1599    { "(bad)", EX, XM, XX },
1600    { "movq2dq", XM, MS, XX },
1601    { "movq", EX, XM, XX },
1602    { "movdq2q", MX, XS, XX },
1603  },
1604  /* PREGRP22 */
1605  {
1606    { "pshufw", MX, EM, Ib },
1607    { "pshufhw", XM, EX, Ib },
1608    { "pshufd", XM, EX, Ib },
1609    { "pshuflw", XM, EX, Ib },
1610  },
1611  /* PREGRP23 */
1612  {
1613    { "movd", Ed, MX, XX },
1614    { "movq", XM, EX, XX },
1615    { "movd", Ed, XM, XX },
1616    { "(bad)", Ed, XM, XX },
1617  },
1618  /* PREGRP24 */
1619  {
1620    { "(bad)", MX, EX, XX },
1621    { "(bad)", XM, EX, XX },
1622    { "punpckhqdq", XM, EX, XX },
1623    { "(bad)", XM, EX, XX },
1624  },
1625  /* PREGRP25 */
1626  {
1627  { "movntq", Ev, MX, XX },
1628  { "(bad)", Ev, XM, XX },
1629  { "movntdq", Ev, XM, XX },
1630  { "(bad)", Ev, XM, XX },
1631  },
1632  /* PREGRP26 */
1633  {
1634    { "(bad)", MX, EX, XX },
1635    { "(bad)", XM, EX, XX },
1636    { "punpcklqdq", XM, EX, XX },
1637    { "(bad)", XM, EX, XX },
1638  },
1639};
1640
1641static const struct dis386 x86_64_table[][2] = {
1642  {
1643    { "arpl", Ew, Gw, XX },
1644    { "movs{||lq|xd}", Gv, Ed, XX },
1645  },
1646};
1647
1648#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1649
1650static void
1651ckprefix ()
1652{
1653  int newrex;
1654  rex = 0;
1655  prefixes = 0;
1656  used_prefixes = 0;
1657  rex_used = 0;
1658  while (1)
1659    {
1660      FETCH_DATA (the_info, codep + 1);
1661      newrex = 0;
1662      switch (*codep)
1663        {
1664        /* REX prefixes family.  */
1665        case 0x40:
1666        case 0x41:
1667        case 0x42:
1668        case 0x43:
1669        case 0x44:
1670        case 0x45:
1671        case 0x46:
1672        case 0x47:
1673        case 0x48:
1674        case 0x49:
1675        case 0x4a:
1676        case 0x4b:
1677        case 0x4c:
1678        case 0x4d:
1679        case 0x4e:
1680        case 0x4f:
1681            if (mode_64bit)
1682              newrex = *codep;
1683            else
1684              return;
1685          break;
1686        case 0xf3:
1687          prefixes |= PREFIX_REPZ;
1688          break;
1689        case 0xf2:
1690          prefixes |= PREFIX_REPNZ;
1691          break;
1692        case 0xf0:
1693          prefixes |= PREFIX_LOCK;
1694          break;
1695        case 0x2e:
1696          prefixes |= PREFIX_CS;
1697          break;
1698        case 0x36:
1699          prefixes |= PREFIX_SS;
1700          break;
1701        case 0x3e:
1702          prefixes |= PREFIX_DS;
1703          break;
1704        case 0x26:
1705          prefixes |= PREFIX_ES;
1706          break;
1707        case 0x64:
1708          prefixes |= PREFIX_FS;
1709          break;
1710        case 0x65:
1711          prefixes |= PREFIX_GS;
1712          break;
1713        case 0x66:
1714          prefixes |= PREFIX_DATA;
1715          break;
1716        case 0x67:
1717          prefixes |= PREFIX_ADDR;
1718          break;
1719        case FWAIT_OPCODE:
1720          /* fwait is really an instruction.  If there are prefixes
1721             before the fwait, they belong to the fwait, *not* to the
1722             following instruction.  */
1723          if (prefixes)
1724            {
1725              prefixes |= PREFIX_FWAIT;
1726              codep++;
1727              return;
1728            }
1729          prefixes = PREFIX_FWAIT;
1730          break;
1731        default:
1732          return;
1733        }
1734      /* Rex is ignored when followed by another prefix.  */
1735      if (rex)
1736        {
1737          oappend (prefix_name (rex, 0));
1738          oappend (" ");
1739        }
1740      rex = newrex;
1741      codep++;
1742    }
1743}
1744
1745/* Return the name of the prefix byte PREF, or NULL if PREF is not a
1746   prefix byte.  */
1747
1748static const char *
1749prefix_name (pref, sizeflag)
1750     int pref;
1751     int sizeflag;
1752{
1753  switch (pref)
1754    {
1755    /* REX prefixes family.  */
1756    case 0x40:
1757      return "rex";
1758    case 0x41:
1759      return "rexZ";
1760    case 0x42:
1761      return "rexY";
1762    case 0x43:
1763      return "rexYZ";
1764    case 0x44:
1765      return "rexX";
1766    case 0x45:
1767      return "rexXZ";
1768    case 0x46:
1769      return "rexXY";
1770    case 0x47:
1771      return "rexXYZ";
1772    case 0x48:
1773      return "rex64";
1774    case 0x49:
1775      return "rex64Z";
1776    case 0x4a:
1777      return "rex64Y";
1778    case 0x4b:
1779      return "rex64YZ";
1780    case 0x4c:
1781      return "rex64X";
1782    case 0x4d:
1783      return "rex64XZ";
1784    case 0x4e:
1785      return "rex64XY";
1786    case 0x4f:
1787      return "rex64XYZ";
1788    case 0xf3:
1789      return "repz";
1790    case 0xf2:
1791      return "repnz";
1792    case 0xf0:
1793      return "lock";
1794    case 0x2e:
1795      return "cs";
1796    case 0x36:
1797      return "ss";
1798    case 0x3e:
1799      return "ds";
1800    case 0x26:
1801      return "es";
1802    case 0x64:
1803      return "fs";
1804    case 0x65:
1805      return "gs";
1806    case 0x66:
1807      return (sizeflag & DFLAG) ? "data16" : "data32";
1808    case 0x67:
1809      if (mode_64bit)
1810        return (sizeflag & AFLAG) ? "addr32" : "addr64";
1811      else
1812        return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32";
1813    case FWAIT_OPCODE:
1814      return "fwait";
1815    default:
1816      return NULL;
1817    }
1818}
1819
1820static char op1out[100], op2out[100], op3out[100];
1821static int op_ad, op_index[3];
1822static bfd_vma op_address[3];
1823static bfd_vma op_riprel[3];
1824static bfd_vma start_pc;
1825
1826/*
1827 *   On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1828 *   (see topic "Redundant prefixes" in the "Differences from 8086"
1829 *   section of the "Virtual 8086 Mode" chapter.)
1830 * 'pc' should be the address of this instruction, it will
1831 *   be used to print the target address if this is a relative jump or call
1832 * The function returns the length of this instruction in bytes.
1833 */
1834
1835static int8_t intel_syntax;
1836static char open_char;
1837static char close_char;
1838static char separator_char;
1839static char scale_char;
1840
1841/* Here for backwards compatibility.  When gdb stops using
1842   print_insn_i386_att and print_insn_i386_intel these functions can
1843   disappear, and print_insn_i386 be merged into print_insn.  */
1844int
1845print_insn_i386_att (pc, info)
1846     bfd_vma pc;
1847     disassemble_info *info;
1848{
1849  intel_syntax = 0;
1850
1851  return print_insn (pc, info);
1852}
1853
1854int
1855print_insn_i386_intel (pc, info)
1856     bfd_vma pc;
1857     disassemble_info *info;
1858{
1859  intel_syntax = 1;
1860
1861  return print_insn (pc, info);
1862}
1863
1864int
1865print_insn_i386 (pc, info)
1866     bfd_vma pc;
1867     disassemble_info *info;
1868{
1869  intel_syntax = -1;
1870
1871  return print_insn (pc, info);
1872}
1873
1874static int
1875print_insn (pc, info)
1876     bfd_vma pc;
1877     disassemble_info *info;
1878{
1879  const struct dis386 *dp;
1880  int i;
1881  int two_source_ops;
1882  char *first, *second, *third;
1883  int needcomma;
1884  unsigned char uses_SSE_prefix;
1885  int sizeflag;
1886  const char *p;
1887  struct dis_private priv;
1888
1889  mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
1890                || info->mach == bfd_mach_x86_64);
1891
1892  if (intel_syntax == -1)
1893    intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
1894                    || info->mach == bfd_mach_x86_64_intel_syntax);
1895
1896  if (info->mach == bfd_mach_i386_i386
1897      || info->mach == bfd_mach_x86_64
1898      || info->mach == bfd_mach_i386_i386_intel_syntax
1899      || info->mach == bfd_mach_x86_64_intel_syntax)
1900    priv.orig_sizeflag = AFLAG | DFLAG;
1901  else if (info->mach == bfd_mach_i386_i8086)
1902    priv.orig_sizeflag = 0;
1903  else
1904    abort ();
1905
1906  for (p = info->disassembler_options; p != NULL; )
1907    {
1908      if (strncmp (p, "x86-64", 6) == 0)
1909        {
1910          mode_64bit = 1;
1911          priv.orig_sizeflag = AFLAG | DFLAG;
1912        }
1913      else if (strncmp (p, "i386", 4) == 0)
1914        {
1915          mode_64bit = 0;
1916          priv.orig_sizeflag = AFLAG | DFLAG;
1917        }
1918      else if (strncmp (p, "i8086", 5) == 0)
1919        {
1920          mode_64bit = 0;
1921          priv.orig_sizeflag = 0;
1922        }
1923      else if (strncmp (p, "intel", 5) == 0)
1924        {
1925          intel_syntax = 1;
1926        }
1927      else if (strncmp (p, "att", 3) == 0)
1928        {
1929          intel_syntax = 0;
1930        }
1931      else if (strncmp (p, "addr", 4) == 0)
1932        {
1933          if (p[4] == '1' && p[5] == '6')
1934            priv.orig_sizeflag &= ~AFLAG;
1935          else if (p[4] == '3' && p[5] == '2')
1936            priv.orig_sizeflag |= AFLAG;
1937        }
1938      else if (strncmp (p, "data", 4) == 0)
1939        {
1940          if (p[4] == '1' && p[5] == '6')
1941            priv.orig_sizeflag &= ~DFLAG;
1942          else if (p[4] == '3' && p[5] == '2')
1943            priv.orig_sizeflag |= DFLAG;
1944        }
1945      else if (strncmp (p, "suffix", 6) == 0)
1946        priv.orig_sizeflag |= SUFFIX_ALWAYS;
1947
1948      p = strchr (p, ',');
1949      if (p != NULL)
1950        p++;
1951    }
1952
1953  if (intel_syntax)
1954    {
1955      names64 = intel_names64;
1956      names32 = intel_names32;
1957      names16 = intel_names16;
1958      names8 = intel_names8;
1959      names8rex = intel_names8rex;
1960      names_seg = intel_names_seg;
1961      index16 = intel_index16;
1962      open_char = '[';
1963      close_char = ']';
1964      separator_char = '+';
1965      scale_char = '*';
1966    }
1967  else
1968    {
1969      names64 = att_names64;
1970      names32 = att_names32;
1971      names16 = att_names16;
1972      names8 = att_names8;
1973      names8rex = att_names8rex;
1974      names_seg = att_names_seg;
1975      index16 = att_index16;
1976      open_char = '(';
1977      close_char =  ')';
1978      separator_char = ',';
1979      scale_char = ',';
1980    }
1981
1982  /* The output looks better if we put 7 bytes on a line, since that
1983     puts most long word instructions on a single line.  */
1984  info->bytes_per_line = 7;
1985
1986  info->private_data = (PTR) &priv;
1987  priv.max_fetched = priv.the_buffer;
1988  priv.insn_start = pc;
1989
1990  obuf[0] = 0;
1991  op1out[0] = 0;
1992  op2out[0] = 0;
1993  op3out[0] = 0;
1994
1995  op_index[0] = op_index[1] = op_index[2] = -1;
1996
1997  the_info = info;
1998  start_pc = pc;
1999  start_codep = priv.the_buffer;
2000  codep = priv.the_buffer;
2001
2002  if (setjmp (priv.bailout) != 0)
2003    {
2004      const char *name;
2005
2006      /* Getting here means we tried for data but didn't get it.  That
2007         means we have an incomplete instruction of some sort.  Just
2008         print the first byte as a prefix or a .byte pseudo-op.  */
2009      if (codep > priv.the_buffer)
2010        {
2011          name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2012          if (name != NULL)
2013            (*info->fprintf_func) (info->stream, "%s", name);
2014          else
2015            {
2016              /* Just print the first byte as a .byte instruction.  */
2017              (*info->fprintf_func) (info->stream, ".byte 0x%x",
2018                                     (unsigned int) priv.the_buffer[0]);
2019            }
2020
2021          return 1;
2022        }
2023
2024      return -1;
2025    }
2026
2027  obufp = obuf;
2028  ckprefix ();
2029
2030  insn_codep = codep;
2031  sizeflag = priv.orig_sizeflag;
2032
2033  FETCH_DATA (info, codep + 1);
2034  two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
2035
2036  if ((prefixes & PREFIX_FWAIT)
2037      && ((*codep < 0xd8) || (*codep > 0xdf)))
2038    {
2039      const char *name;
2040
2041      /* fwait not followed by floating point instruction.  Print the
2042         first prefix, which is probably fwait itself.  */
2043      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2044      if (name == NULL)
2045        name = INTERNAL_DISASSEMBLER_ERROR;
2046      (*info->fprintf_func) (info->stream, "%s", name);
2047      return 1;
2048    }
2049
2050  if (*codep == 0x0f)
2051    {
2052      FETCH_DATA (info, codep + 2);
2053      dp = &dis386_twobyte[*++codep];
2054      need_modrm = twobyte_has_modrm[*codep];
2055      uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
2056    }
2057  else
2058    {
2059      dp = &dis386[*codep];
2060      need_modrm = onebyte_has_modrm[*codep];
2061      uses_SSE_prefix = 0;
2062    }
2063  codep++;
2064
2065  if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
2066    {
2067      oappend ("repz ");
2068      used_prefixes |= PREFIX_REPZ;
2069    }
2070  if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
2071    {
2072      oappend ("repnz ");
2073      used_prefixes |= PREFIX_REPNZ;
2074    }
2075  if (prefixes & PREFIX_LOCK)
2076    {
2077      oappend ("lock ");
2078      used_prefixes |= PREFIX_LOCK;
2079    }
2080
2081  if (prefixes & PREFIX_ADDR)
2082    {
2083      sizeflag ^= AFLAG;
2084      if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
2085        {
2086          if ((sizeflag & AFLAG) || mode_64bit)
2087            oappend ("addr32 ");
2088          else
2089            oappend ("addr16 ");
2090          used_prefixes |= PREFIX_ADDR;
2091        }
2092    }
2093
2094  if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
2095    {
2096      sizeflag ^= DFLAG;
2097      if (dp->bytemode3 == cond_jump_mode
2098          && dp->bytemode1 == v_mode
2099          && !intel_syntax)
2100        {
2101          if (sizeflag & DFLAG)
2102            oappend ("data32 ");
2103          else
2104            oappend ("data16 ");
2105          used_prefixes |= PREFIX_DATA;
2106        }
2107    }
2108
2109  if (need_modrm)
2110    {
2111      FETCH_DATA (info, codep + 1);
2112      mod = (*codep >> 6) & 3;
2113      reg = (*codep >> 3) & 7;
2114      rm = *codep & 7;
2115    }
2116
2117  if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2118    {
2119      dofloat (sizeflag);
2120    }
2121  else
2122    {
2123      int index;
2124      if (dp->name == NULL)
2125        {
2126          switch (dp->bytemode1)
2127            {
2128            case USE_GROUPS:
2129              dp = &grps[dp->bytemode2][reg];
2130              break;
2131
2132            case USE_PREFIX_USER_TABLE:
2133              index = 0;
2134              used_prefixes |= (prefixes & PREFIX_REPZ);
2135              if (prefixes & PREFIX_REPZ)
2136                index = 1;
2137              else
2138                {
2139                  used_prefixes |= (prefixes & PREFIX_DATA);
2140                  if (prefixes & PREFIX_DATA)
2141                    index = 2;
2142                  else
2143                    {
2144                      used_prefixes |= (prefixes & PREFIX_REPNZ);
2145                      if (prefixes & PREFIX_REPNZ)
2146                        index = 3;
2147                    }
2148                }
2149              dp = &prefix_user_table[dp->bytemode2][index];
2150              break;
2151
2152            case X86_64_SPECIAL:
2153              dp = &x86_64_table[dp->bytemode2][mode_64bit];
2154              break;
2155
2156            default:
2157              oappend (INTERNAL_DISASSEMBLER_ERROR);
2158              break;
2159            }
2160        }
2161
2162      if (putop (dp->name, sizeflag) == 0)
2163        {
2164          obufp = op1out;
2165          op_ad = 2;
2166          if (dp->op1)
2167            (*dp->op1) (dp->bytemode1, sizeflag);
2168
2169          obufp = op2out;
2170          op_ad = 1;
2171          if (dp->op2)
2172            (*dp->op2) (dp->bytemode2, sizeflag);
2173
2174          obufp = op3out;
2175          op_ad = 0;
2176          if (dp->op3)
2177            (*dp->op3) (dp->bytemode3, sizeflag);
2178        }
2179    }
2180
2181  /* See if any prefixes were not used.  If so, print the first one
2182     separately.  If we don't do this, we'll wind up printing an
2183     instruction stream which does not precisely correspond to the
2184     bytes we are disassembling.  */
2185  if ((prefixes & ~used_prefixes) != 0)
2186    {
2187      const char *name;
2188
2189      name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2190      if (name == NULL)
2191        name = INTERNAL_DISASSEMBLER_ERROR;
2192      (*info->fprintf_func) (info->stream, "%s", name);
2193      return 1;
2194    }
2195  if (rex & ~rex_used)
2196    {
2197      const char *name;
2198      name = prefix_name (rex | 0x40, priv.orig_sizeflag);
2199      if (name == NULL)
2200        name = INTERNAL_DISASSEMBLER_ERROR;
2201      (*info->fprintf_func) (info->stream, "%s ", name);
2202    }
2203
2204  obufp = obuf + strlen (obuf);
2205  for (i = strlen (obuf); i < 6; i++)
2206    oappend (" ");
2207  oappend (" ");
2208  (*info->fprintf_func) (info->stream, "%s", obuf);
2209
2210  /* The enter and bound instructions are printed with operands in the same
2211     order as the intel book; everything else is printed in reverse order.  */
2212  if (intel_syntax || two_source_ops)
2213    {
2214      first = op1out;
2215      second = op2out;
2216      third = op3out;
2217      op_ad = op_index[0];
2218      op_index[0] = op_index[2];
2219      op_index[2] = op_ad;
2220    }
2221  else
2222    {
2223      first = op3out;
2224      second = op2out;
2225      third = op1out;
2226    }
2227  needcomma = 0;
2228  if (*first)
2229    {
2230      if (op_index[0] != -1 && !op_riprel[0])
2231        (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
2232      else
2233        (*info->fprintf_func) (info->stream, "%s", first);
2234      needcomma = 1;
2235    }
2236  if (*second)
2237    {
2238      if (needcomma)
2239        (*info->fprintf_func) (info->stream, ",");
2240      if (op_index[1] != -1 && !op_riprel[1])
2241        (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
2242      else
2243        (*info->fprintf_func) (info->stream, "%s", second);
2244      needcomma = 1;
2245    }
2246  if (*third)
2247    {
2248      if (needcomma)
2249        (*info->fprintf_func) (info->stream, ",");
2250      if (op_index[2] != -1 && !op_riprel[2])
2251        (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
2252      else
2253        (*info->fprintf_func) (info->stream, "%s", third);
2254    }
2255  for (i = 0; i < 3; i++)
2256    if (op_index[i] != -1 && op_riprel[i])
2257      {
2258        (*info->fprintf_func) (info->stream, "        # ");
2259        (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
2260                                                + op_address[op_index[i]]), info);
2261      }
2262  return codep - priv.the_buffer;
2263}
2264
2265static const char *float_mem[] = {
2266  /* d8 */
2267  "fadd{s||s|}",
2268  "fmul{s||s|}",
2269  "fcom{s||s|}",
2270  "fcomp{s||s|}",
2271  "fsub{s||s|}",
2272  "fsubr{s||s|}",
2273  "fdiv{s||s|}",
2274  "fdivr{s||s|}",
2275  /*  d9 */
2276  "fld{s||s|}",
2277  "(bad)",
2278  "fst{s||s|}",
2279  "fstp{s||s|}",
2280  "fldenv",
2281  "fldcw",
2282  "fNstenv",
2283  "fNstcw",
2284  /* da */
2285  "fiadd{l||l|}",
2286  "fimul{l||l|}",
2287  "ficom{l||l|}",
2288  "ficomp{l||l|}",
2289  "fisub{l||l|}",
2290  "fisubr{l||l|}",
2291  "fidiv{l||l|}",
2292  "fidivr{l||l|}",
2293  /* db */
2294  "fild{l||l|}",
2295  "(bad)",
2296  "fist{l||l|}",
2297  "fistp{l||l|}",
2298  "(bad)",
2299  "fld{t||t|}",
2300  "(bad)",
2301  "fstp{t||t|}",
2302  /* dc */
2303  "fadd{l||l|}",
2304  "fmul{l||l|}",
2305  "fcom{l||l|}",
2306  "fcomp{l||l|}",
2307  "fsub{l||l|}",
2308  "fsubr{l||l|}",
2309  "fdiv{l||l|}",
2310  "fdivr{l||l|}",
2311  /* dd */
2312  "fld{l||l|}",
2313  "(bad)",
2314  "fst{l||l|}",
2315  "fstp{l||l|}",
2316  "frstor",
2317  "(bad)",
2318  "fNsave",
2319  "fNstsw",
2320  /* de */
2321  "fiadd",
2322  "fimul",
2323  "ficom",
2324  "ficomp",
2325  "fisub",
2326  "fisubr",
2327  "fidiv",
2328  "fidivr",
2329  /* df */
2330  "fild",
2331  "(bad)",
2332  "fist",
2333  "fistp",
2334  "fbld",
2335  "fild{ll||ll|}",
2336  "fbstp",
2337  "fistpll",
2338};
2339
2340#define ST OP_ST, 0
2341#define STi OP_STi, 0
2342
2343#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
2344#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
2345#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
2346#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
2347#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
2348#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
2349#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
2350#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
2351#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
2352
2353static const struct dis386 float_reg[][8] = {
2354  /* d8 */
2355  {
2356    { "fadd",   ST, STi, XX },
2357    { "fmul",   ST, STi, XX },
2358    { "fcom",   STi, XX, XX },
2359    { "fcomp",  STi, XX, XX },
2360    { "fsub",   ST, STi, XX },
2361    { "fsubr",  ST, STi, XX },
2362    { "fdiv",   ST, STi, XX },
2363    { "fdivr",  ST, STi, XX },
2364  },
2365  /* d9 */
2366  {
2367    { "fld",    STi, XX, XX },
2368    { "fxch",   STi, XX, XX },
2369    { FGRPd9_2 },
2370    { "(bad)",  XX, XX, XX },
2371    { FGRPd9_4 },
2372    { FGRPd9_5 },
2373    { FGRPd9_6 },
2374    { FGRPd9_7 },
2375  },
2376  /* da */
2377  {
2378    { "fcmovb", ST, STi, XX },
2379    { "fcmove", ST, STi, XX },
2380    { "fcmovbe",ST, STi, XX },
2381    { "fcmovu", ST, STi, XX },
2382    { "(bad)",  XX, XX, XX },
2383    { FGRPda_5 },
2384    { "(bad)",  XX, XX, XX },
2385    { "(bad)",  XX, XX, XX },
2386  },
2387  /* db */
2388  {
2389    { "fcmovnb",ST, STi, XX },
2390    { "fcmovne",ST, STi, XX },
2391    { "fcmovnbe",ST, STi, XX },
2392    { "fcmovnu",ST, STi, XX },
2393    { FGRPdb_4 },
2394    { "fucomi", ST, STi, XX },
2395    { "fcomi",  ST, STi, XX },
2396    { "(bad)",  XX, XX, XX },
2397  },
2398  /* dc */
2399  {
2400    { "fadd",   STi, ST, XX },
2401    { "fmul",   STi, ST, XX },
2402    { "(bad)",  XX, XX, XX },
2403    { "(bad)",  XX, XX, XX },
2404#if UNIXWARE_COMPAT
2405    { "fsub",   STi, ST, XX },
2406    { "fsubr",  STi, ST, XX },
2407    { "fdiv",   STi, ST, XX },
2408    { "fdivr",  STi, ST, XX },
2409#else
2410    { "fsubr",  STi, ST, XX },
2411    { "fsub",   STi, ST, XX },
2412    { "fdivr",  STi, ST, XX },
2413    { "fdiv",   STi, ST, XX },
2414#endif
2415  },
2416  /* dd */
2417  {
2418    { "ffree",  STi, XX, XX },
2419    { "(bad)",  XX, XX, XX },
2420    { "fst",    STi, XX, XX },
2421    { "fstp",   STi, XX, XX },
2422    { "fucom",  STi, XX, XX },
2423    { "fucomp", STi, XX, XX },
2424    { "(bad)",  XX, XX, XX },
2425    { "(bad)",  XX, XX, XX },
2426  },
2427  /* de */
2428  {
2429    { "faddp",  STi, ST, XX },
2430    { "fmulp",  STi, ST, XX },
2431    { "(bad)",  XX, XX, XX },
2432    { FGRPde_3 },
2433#if UNIXWARE_COMPAT
2434    { "fsubp",  STi, ST, XX },
2435    { "fsubrp", STi, ST, XX },
2436    { "fdivp",  STi, ST, XX },
2437    { "fdivrp", STi, ST, XX },
2438#else
2439    { "fsubrp", STi, ST, XX },
2440    { "fsubp",  STi, ST, XX },
2441    { "fdivrp", STi, ST, XX },
2442    { "fdivp",  STi, ST, XX },
2443#endif
2444  },
2445  /* df */
2446  {
2447    { "ffreep", STi, XX, XX },
2448    { "(bad)",  XX, XX, XX },
2449    { "(bad)",  XX, XX, XX },
2450    { "(bad)",  XX, XX, XX },
2451    { FGRPdf_4 },
2452    { "fucomip",ST, STi, XX },
2453    { "fcomip", ST, STi, XX },
2454    { "(bad)",  XX, XX, XX },
2455  },
2456};
2457
2458static char *fgrps[][8] = {
2459  /* d9_2  0 */
2460  {
2461    "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2462  },
2463
2464  /* d9_4  1 */
2465  {
2466    "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2467  },
2468
2469  /* d9_5  2 */
2470  {
2471    "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2472  },
2473
2474  /* d9_6  3 */
2475  {
2476    "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2477  },
2478
2479  /* d9_7  4 */
2480  {
2481    "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2482  },
2483
2484  /* da_5  5 */
2485  {
2486    "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2487  },
2488
2489  /* db_4  6 */
2490  {
2491    "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2492    "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2493  },
2494
2495  /* de_3  7 */
2496  {
2497    "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2498  },
2499
2500  /* df_4  8 */
2501  {
2502    "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2503  },
2504};
2505
2506static void
2507dofloat (sizeflag)
2508     int sizeflag;
2509{
2510  const struct dis386 *dp;
2511  unsigned char floatop;
2512
2513  floatop = codep[-1];
2514
2515  if (mod != 3)
2516    {
2517      putop (float_mem[(floatop - 0xd8) * 8 + reg], sizeflag);
2518      obufp = op1out;
2519      if (floatop == 0xdb)
2520        OP_E (x_mode, sizeflag);
2521      else if (floatop == 0xdd)
2522        OP_E (d_mode, sizeflag);
2523      else
2524        OP_E (v_mode, sizeflag);
2525      return;
2526    }
2527  /* Skip mod/rm byte.  */
2528  MODRM_CHECK;
2529  codep++;
2530
2531  dp = &float_reg[floatop - 0xd8][reg];
2532  if (dp->name == NULL)
2533    {
2534      putop (fgrps[dp->bytemode1][rm], sizeflag);
2535
2536      /* Instruction fnstsw is only one with strange arg.  */
2537      if (floatop == 0xdf && codep[-1] == 0xe0)
2538        strcpy (op1out, names16[0]);
2539    }
2540  else
2541    {
2542      putop (dp->name, sizeflag);
2543
2544      obufp = op1out;
2545      if (dp->op1)
2546        (*dp->op1) (dp->bytemode1, sizeflag);
2547      obufp = op2out;
2548      if (dp->op2)
2549        (*dp->op2) (dp->bytemode2, sizeflag);
2550    }
2551}
2552
2553static void
2554OP_ST (bytemode, sizeflag)
2555     int bytemode;
2556     int sizeflag;
2557{
2558  oappend ("%st");
2559}
2560
2561static void
2562OP_STi (bytemode, sizeflag)
2563     int bytemode;
2564     int sizeflag;
2565{
2566  sprintf (scratchbuf, "%%st(%d)", rm);
2567  oappend (scratchbuf + intel_syntax);
2568}
2569
2570/* Capital letters in template are macros.  */
2571static int
2572putop (template, sizeflag)
2573     const char *template;
2574     int sizeflag;
2575{
2576  const char *p;
2577  int alt;
2578
2579  for (p = template; *p; p++)
2580    {
2581      switch (*p)
2582        {
2583        default:
2584          *obufp++ = *p;
2585          break;
2586        case '{':
2587          alt = 0;
2588          if (intel_syntax)
2589            alt += 1;
2590          if (mode_64bit)
2591            alt += 2;
2592          while (alt != 0)
2593            {
2594              while (*++p != '|')
2595                {
2596                  if (*p == '}')
2597                    {
2598                      /* Alternative not valid.  */
2599                      strcpy (obuf, "(bad)");
2600                      obufp = obuf + 5;
2601                      return 1;
2602                    }
2603                  else if (*p == '\0')
2604                    abort ();
2605                }
2606              alt--;
2607            }
2608          break;
2609        case '|':
2610          while (*++p != '}')
2611            {
2612              if (*p == '\0')
2613                abort ();
2614            }
2615          break;
2616        case '}':
2617          break;
2618        case 'A':
2619          if (intel_syntax)
2620            break;
2621          if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2622            *obufp++ = 'b';
2623          break;
2624        case 'B':
2625          if (intel_syntax)
2626            break;
2627          if (sizeflag & SUFFIX_ALWAYS)
2628            *obufp++ = 'b';
2629          break;
2630        case 'E':               /* For jcxz/jecxz */
2631          if (mode_64bit)
2632            {
2633              if (sizeflag & AFLAG)
2634                *obufp++ = 'r';
2635              else
2636                *obufp++ = 'e';
2637            }
2638          else
2639            if (sizeflag & AFLAG)
2640              *obufp++ = 'e';
2641          used_prefixes |= (prefixes & PREFIX_ADDR);
2642          break;
2643        case 'F':
2644          if (intel_syntax)
2645            break;
2646          if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
2647            {
2648              if (sizeflag & AFLAG)
2649                *obufp++ = mode_64bit ? 'q' : 'l';
2650              else
2651                *obufp++ = mode_64bit ? 'l' : 'w';
2652              used_prefixes |= (prefixes & PREFIX_ADDR);
2653            }
2654          break;
2655        case 'H':
2656          if (intel_syntax)
2657            break;
2658          if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
2659              || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
2660            {
2661              used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
2662              *obufp++ = ',';
2663              *obufp++ = 'p';
2664              if (prefixes & PREFIX_DS)
2665                *obufp++ = 't';
2666              else
2667                *obufp++ = 'n';
2668            }
2669          break;
2670        case 'L':
2671          if (intel_syntax)
2672            break;
2673          if (sizeflag & SUFFIX_ALWAYS)
2674            *obufp++ = 'l';
2675          break;
2676        case 'N':
2677          if ((prefixes & PREFIX_FWAIT) == 0)
2678            *obufp++ = 'n';
2679          else
2680            used_prefixes |= PREFIX_FWAIT;
2681          break;
2682        case 'O':
2683          USED_REX (REX_MODE64);
2684          if (rex & REX_MODE64)
2685            *obufp++ = 'o';
2686          else
2687            *obufp++ = 'd';
2688          break;
2689        case 'T':
2690          if (intel_syntax)
2691            break;
2692          if (mode_64bit)
2693            {
2694              *obufp++ = 'q';
2695              break;
2696            }
2697          /* Fall through.  */
2698        case 'P':
2699          if (intel_syntax)
2700            break;
2701          if ((prefixes & PREFIX_DATA)
2702              || (rex & REX_MODE64)
2703              || (sizeflag & SUFFIX_ALWAYS))
2704            {
2705              USED_REX (REX_MODE64);
2706              if (rex & REX_MODE64)
2707                *obufp++ = 'q';
2708              else
2709                {
2710                   if (sizeflag & DFLAG)
2711                      *obufp++ = 'l';
2712                   else
2713                     *obufp++ = 'w';
2714                   used_prefixes |= (prefixes & PREFIX_DATA);
2715                }
2716            }
2717          break;
2718        case 'U':
2719          if (intel_syntax)
2720            break;
2721          if (mode_64bit)
2722            {
2723              *obufp++ = 'q';
2724              break;
2725            }
2726          /* Fall through.  */
2727        case 'Q':
2728          if (intel_syntax)
2729            break;
2730          USED_REX (REX_MODE64);
2731          if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2732            {
2733              if (rex & REX_MODE64)
2734                *obufp++ = 'q';
2735              else
2736                {
2737                  if (sizeflag & DFLAG)
2738                    *obufp++ = 'l';
2739                  else
2740                    *obufp++ = 'w';
2741                  used_prefixes |= (prefixes & PREFIX_DATA);
2742                }
2743            }
2744          break;
2745        case 'R':
2746          USED_REX (REX_MODE64);
2747          if (intel_syntax)
2748            {
2749              if (rex & REX_MODE64)
2750                {
2751                  *obufp++ = 'q';
2752                  *obufp++ = 't';
2753                }
2754              else if (sizeflag & DFLAG)
2755                {
2756                  *obufp++ = 'd';
2757                  *obufp++ = 'q';
2758                }
2759              else
2760                {
2761                  *obufp++ = 'w';
2762                  *obufp++ = 'd';
2763                }
2764            }
2765          else
2766            {
2767              if (rex & REX_MODE64)
2768                *obufp++ = 'q';
2769              else if (sizeflag & DFLAG)
2770                *obufp++ = 'l';
2771              else
2772                *obufp++ = 'w';
2773            }
2774          if (!(rex & REX_MODE64))
2775            used_prefixes |= (prefixes & PREFIX_DATA);
2776          break;
2777        case 'S':
2778          if (intel_syntax)
2779            break;
2780          if (sizeflag & SUFFIX_ALWAYS)
2781            {
2782              if (rex & REX_MODE64)
2783                *obufp++ = 'q';
2784              else
2785                {
2786                  if (sizeflag & DFLAG)
2787                    *obufp++ = 'l';
2788                  else
2789                    *obufp++ = 'w';
2790                  used_prefixes |= (prefixes & PREFIX_DATA);
2791                }
2792            }
2793          break;
2794        case 'X':
2795          if (prefixes & PREFIX_DATA)
2796            *obufp++ = 'd';
2797          else
2798            *obufp++ = 's';
2799          used_prefixes |= (prefixes & PREFIX_DATA);
2800          break;
2801        case 'Y':
2802          if (intel_syntax)
2803            break;
2804          if (rex & REX_MODE64)
2805            {
2806              USED_REX (REX_MODE64);
2807              *obufp++ = 'q';
2808            }
2809          break;
2810          /* implicit operand size 'l' for i386 or 'q' for x86-64 */
2811        case 'W':
2812          /* operand size flag for cwtl, cbtw */
2813          USED_REX (0);
2814          if (rex)
2815            *obufp++ = 'l';
2816          else if (sizeflag & DFLAG)
2817            *obufp++ = 'w';
2818          else
2819            *obufp++ = 'b';
2820          if (intel_syntax)
2821            {
2822              if (rex)
2823                {
2824                  *obufp++ = 'q';
2825                  *obufp++ = 'e';
2826                }
2827              if (sizeflag & DFLAG)
2828                {
2829                  *obufp++ = 'd';
2830                  *obufp++ = 'e';
2831                }
2832              else
2833                {
2834                  *obufp++ = 'w';
2835                }
2836            }
2837          if (!rex)
2838            used_prefixes |= (prefixes & PREFIX_DATA);
2839          break;
2840        }
2841    }
2842  *obufp = 0;
2843  return 0;
2844}
2845
2846static void
2847oappend (s)
2848     const char *s;
2849{
2850  strcpy (obufp, s);
2851  obufp += strlen (s);
2852}
2853
2854static void
2855append_seg ()
2856{
2857  if (prefixes & PREFIX_CS)
2858    {
2859      used_prefixes |= PREFIX_CS;
2860      oappend ("%cs:" + intel_syntax);
2861    }
2862  if (prefixes & PREFIX_DS)
2863    {
2864      used_prefixes |= PREFIX_DS;
2865      oappend ("%ds:" + intel_syntax);
2866    }
2867  if (prefixes & PREFIX_SS)
2868    {
2869      used_prefixes |= PREFIX_SS;
2870      oappend ("%ss:" + intel_syntax);
2871    }
2872  if (prefixes & PREFIX_ES)
2873    {
2874      used_prefixes |= PREFIX_ES;
2875      oappend ("%es:" + intel_syntax);
2876    }
2877  if (prefixes & PREFIX_FS)
2878    {
2879      used_prefixes |= PREFIX_FS;
2880      oappend ("%fs:" + intel_syntax);
2881    }
2882  if (prefixes & PREFIX_GS)
2883    {
2884      used_prefixes |= PREFIX_GS;
2885      oappend ("%gs:" + intel_syntax);
2886    }
2887}
2888
2889static void
2890OP_indirE (bytemode, sizeflag)
2891     int bytemode;
2892     int sizeflag;
2893{
2894  if (!intel_syntax)
2895    oappend ("*");
2896  OP_E (bytemode, sizeflag);
2897}
2898
2899static void
2900print_operand_value (buf, hex, disp)
2901  char *buf;
2902  int hex;
2903  bfd_vma disp;
2904{
2905  if (mode_64bit)
2906    {
2907      if (hex)
2908        {
2909          char tmp[30];
2910          int i;
2911          buf[0] = '0';
2912          buf[1] = 'x';
2913          sprintf_vma (tmp, disp);
2914          for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
2915          strcpy (buf + 2, tmp + i);
2916        }
2917      else
2918        {
2919          bfd_signed_vma v = disp;
2920          char tmp[30];
2921          int i;
2922          if (v < 0)
2923            {
2924              *(buf++) = '-';
2925              v = -disp;
2926              /* Check for possible overflow on 0x8000000000000000.  */
2927              if (v < 0)
2928                {
2929                  strcpy (buf, "9223372036854775808");
2930                  return;
2931                }
2932            }
2933          if (!v)
2934            {
2935              strcpy (buf, "0");
2936              return;
2937            }
2938
2939          i = 0;
2940          tmp[29] = 0;
2941          while (v)
2942            {
2943              tmp[28 - i] = (v % 10) + '0';
2944              v /= 10;
2945              i++;
2946            }
2947          strcpy (buf, tmp + 29 - i);
2948        }
2949    }
2950  else
2951    {
2952      if (hex)
2953        sprintf (buf, "0x%x", (unsigned int) disp);
2954      else
2955        sprintf (buf, "%d", (int) disp);
2956    }
2957}
2958
2959static void
2960OP_E (bytemode, sizeflag)
2961     int bytemode;
2962     int sizeflag;
2963{
2964  bfd_vma disp;
2965  int add = 0;
2966  int riprel = 0;
2967  USED_REX (REX_EXTZ);
2968  if (rex & REX_EXTZ)
2969    add += 8;
2970
2971  /* Skip mod/rm byte.  */
2972  MODRM_CHECK;
2973  codep++;
2974
2975  if (mod == 3)
2976    {
2977      switch (bytemode)
2978        {
2979        case b_mode:
2980          USED_REX (0);
2981          if (rex)
2982            oappend (names8rex[rm + add]);
2983          else
2984            oappend (names8[rm + add]);
2985          break;
2986        case w_mode:
2987          oappend (names16[rm + add]);
2988          break;
2989        case d_mode:
2990          oappend (names32[rm + add]);
2991          break;
2992        case q_mode:
2993          oappend (names64[rm + add]);
2994          break;
2995        case m_mode:
2996          if (mode_64bit)
2997            oappend (names64[rm + add]);
2998          else
2999            oappend (names32[rm + add]);
3000          break;
3001        case v_mode:
3002          USED_REX (REX_MODE64);
3003          if (rex & REX_MODE64)
3004            oappend (names64[rm + add]);
3005          else if (sizeflag & DFLAG)
3006            oappend (names32[rm + add]);
3007          else
3008            oappend (names16[rm + add]);
3009          used_prefixes |= (prefixes & PREFIX_DATA);
3010          break;
3011        case 0:
3012          if (!(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */)
3013              && !(codep[-2] == 0xAE && codep[-1] == 0xF0 /* mfence */)
3014              && !(codep[-2] == 0xAE && codep[-1] == 0xe8 /* lfence */))
3015            BadOp ();   /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */
3016          break;
3017        default:
3018          oappend (INTERNAL_DISASSEMBLER_ERROR);
3019          break;
3020        }
3021      return;
3022    }
3023
3024  disp = 0;
3025  append_seg ();
3026
3027  if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
3028    {
3029      int havesib;
3030      int havebase;
3031      int base;
3032      int index = 0;
3033      int scale = 0;
3034
3035      havesib = 0;
3036      havebase = 1;
3037      base = rm;
3038
3039      if (base == 4)
3040        {
3041          havesib = 1;
3042          FETCH_DATA (the_info, codep + 1);
3043          scale = (*codep >> 6) & 3;
3044          index = (*codep >> 3) & 7;
3045          base = *codep & 7;
3046          USED_REX (REX_EXTY);
3047          USED_REX (REX_EXTZ);
3048          if (rex & REX_EXTY)
3049            index += 8;
3050          if (rex & REX_EXTZ)
3051            base += 8;
3052          codep++;
3053        }
3054
3055      switch (mod)
3056        {
3057        case 0:
3058          if ((base & 7) == 5)
3059            {
3060              havebase = 0;
3061              if (mode_64bit && !havesib && (sizeflag & AFLAG))
3062                riprel = 1;
3063              disp = get32s ();
3064            }
3065          break;
3066        case 1:
3067          FETCH_DATA (the_info, codep + 1);
3068          disp = *codep++;
3069          if ((disp & 0x80) != 0)
3070            disp -= 0x100;
3071          break;
3072        case 2:
3073          disp = get32s ();
3074          break;
3075        }
3076
3077      if (!intel_syntax)
3078        if (mod != 0 || (base & 7) == 5)
3079          {
3080            print_operand_value (scratchbuf, !riprel, disp);
3081            oappend (scratchbuf);
3082            if (riprel)
3083              {
3084                set_op (disp, 1);
3085                oappend ("(%rip)");
3086              }
3087          }
3088
3089      if (havebase || (havesib && (index != 4 || scale != 0)))
3090        {
3091          if (intel_syntax)
3092            {
3093              switch (bytemode)
3094                {
3095                case b_mode:
3096                  oappend ("BYTE PTR ");
3097                  break;
3098                case w_mode:
3099                  oappend ("WORD PTR ");
3100                  break;
3101                case v_mode:
3102                  oappend ("DWORD PTR ");
3103                  break;
3104                case d_mode:
3105                  oappend ("QWORD PTR ");
3106                  break;
3107                case m_mode:
3108                  if (mode_64bit)
3109                    oappend ("DWORD PTR ");
3110                  else
3111                    oappend ("QWORD PTR ");
3112                  break;
3113                case x_mode:
3114                  oappend ("XWORD PTR ");
3115                  break;
3116                default:
3117                  break;
3118                }
3119             }
3120          *obufp++ = open_char;
3121          if (intel_syntax && riprel)
3122            oappend ("rip + ");
3123          *obufp = '\0';
3124          USED_REX (REX_EXTZ);
3125          if (!havesib && (rex & REX_EXTZ))
3126            base += 8;
3127          if (havebase)
3128            oappend (mode_64bit && (sizeflag & AFLAG)
3129                     ? names64[base] : names32[base]);
3130          if (havesib)
3131            {
3132              if (index != 4)
3133                {
3134                  if (intel_syntax)
3135                    {
3136                      if (havebase)
3137                        {
3138                          *obufp++ = separator_char;
3139                          *obufp = '\0';
3140                        }
3141                      sprintf (scratchbuf, "%s",
3142                               mode_64bit && (sizeflag & AFLAG)
3143                               ? names64[index] : names32[index]);
3144                    }
3145                  else
3146                    sprintf (scratchbuf, ",%s",
3147                             mode_64bit && (sizeflag & AFLAG)
3148                             ? names64[index] : names32[index]);
3149                  oappend (scratchbuf);
3150                }
3151              if (!intel_syntax
3152                  || (intel_syntax
3153                      && bytemode != b_mode
3154                      && bytemode != w_mode
3155                      && bytemode != v_mode))
3156                {
3157                  *obufp++ = scale_char;
3158                  *obufp = '\0';
3159                  sprintf (scratchbuf, "%d", 1 << scale);
3160                  oappend (scratchbuf);
3161                }
3162            }
3163          if (intel_syntax)
3164            if (mod != 0 || (base & 7) == 5)
3165              {
3166                /* Don't print zero displacements.  */
3167                if (disp != 0)
3168                  {
3169                    if ((bfd_signed_vma) disp > 0)
3170                      {
3171                        *obufp++ = '+';
3172                        *obufp = '\0';
3173                      }
3174
3175                    print_operand_value (scratchbuf, 0, disp);
3176                    oappend (scratchbuf);
3177                  }
3178              }
3179
3180          *obufp++ = close_char;
3181          *obufp = '\0';
3182        }
3183      else if (intel_syntax)
3184        {
3185          if (mod != 0 || (base & 7) == 5)
3186            {
3187              if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3188                              | PREFIX_ES | PREFIX_FS | PREFIX_GS))
3189                ;
3190              else
3191                {
3192                  oappend (names_seg[ds_reg - es_reg]);
3193                  oappend (":");
3194                }
3195              print_operand_value (scratchbuf, 1, disp);
3196              oappend (scratchbuf);
3197            }
3198        }
3199    }
3200  else
3201    { /* 16 bit address mode */
3202      switch (mod)
3203        {
3204        case 0:
3205          if ((rm & 7) == 6)
3206            {
3207              disp = get16 ();
3208              if ((disp & 0x8000) != 0)
3209                disp -= 0x10000;
3210            }
3211          break;
3212        case 1:
3213          FETCH_DATA (the_info, codep + 1);
3214          disp = *codep++;
3215          if ((disp & 0x80) != 0)
3216            disp -= 0x100;
3217          break;
3218        case 2:
3219          disp = get16 ();
3220          if ((disp & 0x8000) != 0)
3221            disp -= 0x10000;
3222          break;
3223        }
3224
3225      if (!intel_syntax)
3226        if (mod != 0 || (rm & 7) == 6)
3227          {
3228            print_operand_value (scratchbuf, 0, disp);
3229            oappend (scratchbuf);
3230          }
3231
3232      if (mod != 0 || (rm & 7) != 6)
3233        {
3234          *obufp++ = open_char;
3235          *obufp = '\0';
3236          oappend (index16[rm + add]);
3237          *obufp++ = close_char;
3238          *obufp = '\0';
3239        }
3240    }
3241}
3242
3243static void
3244OP_G (bytemode, sizeflag)
3245     int bytemode;
3246     int sizeflag;
3247{
3248  int add = 0;
3249  USED_REX (REX_EXTX);
3250  if (rex & REX_EXTX)
3251    add += 8;
3252  switch (bytemode)
3253    {
3254    case b_mode:
3255      USED_REX (0);
3256      if (rex)
3257        oappend (names8rex[reg + add]);
3258      else
3259        oappend (names8[reg + add]);
3260      break;
3261    case w_mode:
3262      oappend (names16[reg + add]);
3263      break;
3264    case d_mode:
3265      oappend (names32[reg + add]);
3266      break;
3267    case q_mode:
3268      oappend (names64[reg + add]);
3269      break;
3270    case v_mode:
3271      USED_REX (REX_MODE64);
3272      if (rex & REX_MODE64)
3273        oappend (names64[reg + add]);
3274      else if (sizeflag & DFLAG)
3275        oappend (names32[reg + add]);
3276      else
3277        oappend (names16[reg + add]);
3278      used_prefixes |= (prefixes & PREFIX_DATA);
3279      break;
3280    default:
3281      oappend (INTERNAL_DISASSEMBLER_ERROR);
3282      break;
3283    }
3284}
3285
3286static bfd_vma
3287get64 ()
3288{
3289  bfd_vma x;
3290#ifdef BFD64
3291  unsigned int a;
3292  unsigned int b;
3293
3294  FETCH_DATA (the_info, codep + 8);
3295  a = *codep++ & 0xff;
3296  a |= (*codep++ & 0xff) << 8;
3297  a |= (*codep++ & 0xff) << 16;
3298  a |= (*codep++ & 0xff) << 24;
3299  b = *codep++ & 0xff;
3300  b |= (*codep++ & 0xff) << 8;
3301  b |= (*codep++ & 0xff) << 16;
3302  b |= (*codep++ & 0xff) << 24;
3303  x = a + ((bfd_vma) b << 32);
3304#else
3305  abort ();
3306  x = 0;
3307#endif
3308  return x;
3309}
3310
3311static bfd_signed_vma
3312get32 ()
3313{
3314  bfd_signed_vma x = 0;
3315
3316  FETCH_DATA (the_info, codep + 4);
3317  x = *codep++ & (bfd_signed_vma) 0xff;
3318  x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3319  x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3320  x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3321  return x;
3322}
3323
3324static bfd_signed_vma
3325get32s ()
3326{
3327  bfd_signed_vma x = 0;
3328
3329  FETCH_DATA (the_info, codep + 4);
3330  x = *codep++ & (bfd_signed_vma) 0xff;
3331  x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3332  x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3333  x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3334
3335  x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
3336
3337  return x;
3338}
3339
3340static int
3341get16 ()
3342{
3343  int x = 0;
3344
3345  FETCH_DATA (the_info, codep + 2);
3346  x = *codep++ & 0xff;
3347  x |= (*codep++ & 0xff) << 8;
3348  return x;
3349}
3350
3351static void
3352set_op (op, riprel)
3353     bfd_vma op;
3354     int riprel;
3355{
3356  op_index[op_ad] = op_ad;
3357  if (mode_64bit)
3358    {
3359      op_address[op_ad] = op;
3360      op_riprel[op_ad] = riprel;
3361    }
3362  else
3363    {
3364      /* Mask to get a 32-bit address.  */
3365      op_address[op_ad] = op & 0xffffffff;
3366      op_riprel[op_ad] = riprel & 0xffffffff;
3367    }
3368}
3369
3370static void
3371OP_REG (code, sizeflag)
3372     int code;
3373     int sizeflag;
3374{
3375  const char *s;
3376  int add = 0;
3377  USED_REX (REX_EXTZ);
3378  if (rex & REX_EXTZ)
3379    add = 8;
3380
3381  switch (code)
3382    {
3383    case indir_dx_reg:
3384      if (intel_syntax)
3385        s = "[dx]";
3386      else
3387        s = "(%dx)";
3388      break;
3389    case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3390    case sp_reg: case bp_reg: case si_reg: case di_reg:
3391      s = names16[code - ax_reg + add];
3392      break;
3393    case es_reg: case ss_reg: case cs_reg:
3394    case ds_reg: case fs_reg: case gs_reg:
3395      s = names_seg[code - es_reg + add];
3396      break;
3397    case al_reg: case ah_reg: case cl_reg: case ch_reg:
3398    case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3399      USED_REX (0);
3400      if (rex)
3401        s = names8rex[code - al_reg + add];
3402      else
3403        s = names8[code - al_reg];
3404      break;
3405    case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
3406    case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
3407      if (mode_64bit)
3408        {
3409          s = names64[code - rAX_reg + add];
3410          break;
3411        }
3412      code += eAX_reg - rAX_reg;
3413      /* Fall through.  */
3414    case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3415    case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3416      USED_REX (REX_MODE64);
3417      if (rex & REX_MODE64)
3418        s = names64[code - eAX_reg + add];
3419      else if (sizeflag & DFLAG)
3420        s = names32[code - eAX_reg + add];
3421      else
3422        s = names16[code - eAX_reg + add];
3423      used_prefixes |= (prefixes & PREFIX_DATA);
3424      break;
3425    default:
3426      s = INTERNAL_DISASSEMBLER_ERROR;
3427      break;
3428    }
3429  oappend (s);
3430}
3431
3432static void
3433OP_IMREG (code, sizeflag)
3434     int code;
3435     int sizeflag;
3436{
3437  const char *s;
3438
3439  switch (code)
3440    {
3441    case indir_dx_reg:
3442      if (intel_syntax)
3443        s = "[dx]";
3444      else
3445        s = "(%dx)";
3446      break;
3447    case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3448    case sp_reg: case bp_reg: case si_reg: case di_reg:
3449      s = names16[code - ax_reg];
3450      break;
3451    case es_reg: case ss_reg: case cs_reg:
3452    case ds_reg: case fs_reg: case gs_reg:
3453      s = names_seg[code - es_reg];
3454      break;
3455    case al_reg: case ah_reg: case cl_reg: case ch_reg:
3456    case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3457      USED_REX (0);
3458      if (rex)
3459        s = names8rex[code - al_reg];
3460      else
3461        s = names8[code - al_reg];
3462      break;
3463    case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3464    case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3465      USED_REX (REX_MODE64);
3466      if (rex & REX_MODE64)
3467        s = names64[code - eAX_reg];
3468      else if (sizeflag & DFLAG)
3469        s = names32[code - eAX_reg];
3470      else
3471        s = names16[code - eAX_reg];
3472      used_prefixes |= (prefixes & PREFIX_DATA);
3473      break;
3474    default:
3475      s = INTERNAL_DISASSEMBLER_ERROR;
3476      break;
3477    }
3478  oappend (s);
3479}
3480
3481static void
3482OP_I (bytemode, sizeflag)
3483     int bytemode;
3484     int sizeflag;
3485{
3486  bfd_signed_vma op;
3487  bfd_signed_vma mask = -1;
3488
3489  switch (bytemode)
3490    {
3491    case b_mode:
3492      FETCH_DATA (the_info, codep + 1);
3493      op = *codep++;
3494      mask = 0xff;
3495      break;
3496    case q_mode:
3497      if (mode_64bit)
3498        {
3499          op = get32s ();
3500          break;
3501        }
3502      /* Fall through.  */
3503    case v_mode:
3504      USED_REX (REX_MODE64);
3505      if (rex & REX_MODE64)
3506        op = get32s ();
3507      else if (sizeflag & DFLAG)
3508        {
3509          op = get32 ();
3510          mask = 0xffffffff;
3511        }
3512      else
3513        {
3514          op = get16 ();
3515          mask = 0xfffff;
3516        }
3517      used_prefixes |= (prefixes & PREFIX_DATA);
3518      break;
3519    case w_mode:
3520      mask = 0xfffff;
3521      op = get16 ();
3522      break;
3523    default:
3524      oappend (INTERNAL_DISASSEMBLER_ERROR);
3525      return;
3526    }
3527
3528  op &= mask;
3529  scratchbuf[0] = '$';
3530  print_operand_value (scratchbuf + 1, 1, op);
3531  oappend (scratchbuf + intel_syntax);
3532  scratchbuf[0] = '\0';
3533}
3534
3535static void
3536OP_I64 (bytemode, sizeflag)
3537     int bytemode;
3538     int sizeflag;
3539{
3540  bfd_signed_vma op;
3541  bfd_signed_vma mask = -1;
3542
3543  if (!mode_64bit)
3544    {
3545      OP_I (bytemode, sizeflag);
3546      return;
3547    }
3548
3549  switch (bytemode)
3550    {
3551    case b_mode:
3552      FETCH_DATA (the_info, codep + 1);
3553      op = *codep++;
3554      mask = 0xff;
3555      break;
3556    case v_mode:
3557      USED_REX (REX_MODE64);
3558      if (rex & REX_MODE64)
3559        op = get64 ();
3560      else if (sizeflag & DFLAG)
3561        {
3562          op = get32 ();
3563          mask = 0xffffffff;
3564        }
3565      else
3566        {
3567          op = get16 ();
3568          mask = 0xfffff;
3569        }
3570      used_prefixes |= (prefixes & PREFIX_DATA);
3571      break;
3572    case w_mode:
3573      mask = 0xfffff;
3574      op = get16 ();
3575      break;
3576    default:
3577      oappend (INTERNAL_DISASSEMBLER_ERROR);
3578      return;
3579    }
3580
3581  op &= mask;
3582  scratchbuf[0] = '$';
3583  print_operand_value (scratchbuf + 1, 1, op);
3584  oappend (scratchbuf + intel_syntax);
3585  scratchbuf[0] = '\0';
3586}
3587
3588static void
3589OP_sI (bytemode, sizeflag)
3590     int bytemode;
3591     int sizeflag;
3592{
3593  bfd_signed_vma op;
3594  bfd_signed_vma mask = -1;
3595
3596  switch (bytemode)
3597    {
3598    case b_mode:
3599      FETCH_DATA (the_info, codep + 1);
3600      op = *codep++;
3601      if ((op & 0x80) != 0)
3602        op -= 0x100;
3603      mask = 0xffffffff;
3604      break;
3605    case v_mode:
3606      USED_REX (REX_MODE64);
3607      if (rex & REX_MODE64)
3608        op = get32s ();
3609      else if (sizeflag & DFLAG)
3610        {
3611          op = get32s ();
3612          mask = 0xffffffff;
3613        }
3614      else
3615        {
3616          mask = 0xffffffff;
3617          op = get16 ();
3618          if ((op & 0x8000) != 0)
3619            op -= 0x10000;
3620        }
3621      used_prefixes |= (prefixes & PREFIX_DATA);
3622      break;
3623    case w_mode:
3624      op = get16 ();
3625      mask = 0xffffffff;
3626      if ((op & 0x8000) != 0)
3627        op -= 0x10000;
3628      break;
3629    default:
3630      oappend (INTERNAL_DISASSEMBLER_ERROR);
3631      return;
3632    }
3633
3634  scratchbuf[0] = '$';
3635  print_operand_value (scratchbuf + 1, 1, op);
3636  oappend (scratchbuf + intel_syntax);
3637}
3638
3639static void
3640OP_J (bytemode, sizeflag)
3641     int bytemode;
3642     int sizeflag;
3643{
3644  bfd_vma disp;
3645  bfd_vma mask = -1;
3646
3647  switch (bytemode)
3648    {
3649    case b_mode:
3650      FETCH_DATA (the_info, codep + 1);
3651      disp = *codep++;
3652      if ((disp & 0x80) != 0)
3653        disp -= 0x100;
3654      break;
3655    case v_mode:
3656      if (sizeflag & DFLAG)
3657        disp = get32s ();
3658      else
3659        {
3660          disp = get16 ();
3661          /* For some reason, a data16 prefix on a jump instruction
3662             means that the pc is masked to 16 bits after the
3663             displacement is added!  */
3664          mask = 0xffff;
3665        }
3666      break;
3667    default:
3668      oappend (INTERNAL_DISASSEMBLER_ERROR);
3669      return;
3670    }
3671  disp = (start_pc + codep - start_codep + disp) & mask;
3672  set_op (disp, 0);
3673  print_operand_value (scratchbuf, 1, disp);
3674  oappend (scratchbuf);
3675}
3676
3677static void
3678OP_SEG (dummy, sizeflag)
3679     int dummy;
3680     int sizeflag;
3681{
3682  oappend (names_seg[reg]);
3683}
3684
3685static void
3686OP_DIR (dummy, sizeflag)
3687     int dummy;
3688     int sizeflag;
3689{
3690  int seg, offset;
3691
3692  if (sizeflag & DFLAG)
3693    {
3694      offset = get32 ();
3695      seg = get16 ();
3696    }
3697  else
3698    {
3699      offset = get16 ();
3700      seg = get16 ();
3701    }
3702  used_prefixes |= (prefixes & PREFIX_DATA);
3703  if (intel_syntax)
3704    sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
3705  else
3706    sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3707  oappend (scratchbuf);
3708}
3709
3710static void
3711OP_OFF (bytemode, sizeflag)
3712     int bytemode;
3713     int sizeflag;
3714{
3715  bfd_vma off;
3716
3717  append_seg ();
3718
3719  if ((sizeflag & AFLAG) || mode_64bit)
3720    off = get32 ();
3721  else
3722    off = get16 ();
3723
3724  if (intel_syntax)
3725    {
3726      if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3727                        | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3728        {
3729          oappend (names_seg[ds_reg - es_reg]);
3730          oappend (":");
3731        }
3732    }
3733  print_operand_value (scratchbuf, 1, off);
3734  oappend (scratchbuf);
3735}
3736
3737static void
3738OP_OFF64 (bytemode, sizeflag)
3739     int bytemode;
3740     int sizeflag;
3741{
3742  bfd_vma off;
3743
3744  if (!mode_64bit)
3745    {
3746      OP_OFF (bytemode, sizeflag);
3747      return;
3748    }
3749
3750  append_seg ();
3751
3752  off = get64 ();
3753
3754  if (intel_syntax)
3755    {
3756      if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3757                        | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3758        {
3759          oappend (names_seg[ds_reg - es_reg]);
3760          oappend (":");
3761        }
3762    }
3763  print_operand_value (scratchbuf, 1, off);
3764  oappend (scratchbuf);
3765}
3766
3767static void
3768ptr_reg (code, sizeflag)
3769     int code;
3770     int sizeflag;
3771{
3772  const char *s;
3773  if (intel_syntax)
3774    oappend ("[");
3775  else
3776    oappend ("(");
3777
3778  USED_REX (REX_MODE64);
3779  if (rex & REX_MODE64)
3780    {
3781      if (!(sizeflag & AFLAG))
3782        s = names32[code - eAX_reg];
3783      else
3784        s = names64[code - eAX_reg];
3785    }
3786  else if (sizeflag & AFLAG)
3787    s = names32[code - eAX_reg];
3788  else
3789    s = names16[code - eAX_reg];
3790  oappend (s);
3791  if (intel_syntax)
3792    oappend ("]");
3793  else
3794    oappend (")");
3795}
3796
3797static void
3798OP_ESreg (code, sizeflag)
3799     int code;
3800     int sizeflag;
3801{
3802  oappend ("%es:" + intel_syntax);
3803  ptr_reg (code, sizeflag);
3804}
3805
3806static void
3807OP_DSreg (code, sizeflag)
3808     int code;
3809     int sizeflag;
3810{
3811  if ((prefixes
3812       & (PREFIX_CS
3813          | PREFIX_DS
3814          | PREFIX_SS
3815          | PREFIX_ES
3816          | PREFIX_FS
3817          | PREFIX_GS)) == 0)
3818    prefixes |= PREFIX_DS;
3819  append_seg ();
3820  ptr_reg (code, sizeflag);
3821}
3822
3823static void
3824OP_C (dummy, sizeflag)
3825     int dummy;
3826     int sizeflag;
3827{
3828  int add = 0;
3829  USED_REX (REX_EXTX);
3830  if (rex & REX_EXTX)
3831    add = 8;
3832  sprintf (scratchbuf, "%%cr%d", reg + add);
3833  oappend (scratchbuf + intel_syntax);
3834}
3835
3836static void
3837OP_D (dummy, sizeflag)
3838     int dummy;
3839     int sizeflag;
3840{
3841  int add = 0;
3842  USED_REX (REX_EXTX);
3843  if (rex & REX_EXTX)
3844    add = 8;
3845  if (intel_syntax)
3846    sprintf (scratchbuf, "db%d", reg + add);
3847  else
3848    sprintf (scratchbuf, "%%db%d", reg + add);
3849  oappend (scratchbuf);
3850}
3851
3852static void
3853OP_T (dummy, sizeflag)
3854     int dummy;
3855     int sizeflag;
3856{
3857  sprintf (scratchbuf, "%%tr%d", reg);
3858  oappend (scratchbuf + intel_syntax);
3859}
3860
3861static void
3862OP_Rd (bytemode, sizeflag)
3863     int bytemode;
3864     int sizeflag;
3865{
3866  if (mod == 3)
3867    OP_E (bytemode, sizeflag);
3868  else
3869    BadOp ();
3870}
3871
3872static void
3873OP_MMX (bytemode, sizeflag)
3874     int bytemode;
3875     int sizeflag;
3876{
3877  int add = 0;
3878  USED_REX (REX_EXTX);
3879  if (rex & REX_EXTX)
3880    add = 8;
3881  used_prefixes |= (prefixes & PREFIX_DATA);
3882  if (prefixes & PREFIX_DATA)
3883    sprintf (scratchbuf, "%%xmm%d", reg + add);
3884  else
3885    sprintf (scratchbuf, "%%mm%d", reg + add);
3886  oappend (scratchbuf + intel_syntax);
3887}
3888
3889static void
3890OP_XMM (bytemode, sizeflag)
3891     int bytemode;
3892     int sizeflag;
3893{
3894  int add = 0;
3895  USED_REX (REX_EXTX);
3896  if (rex & REX_EXTX)
3897    add = 8;
3898  sprintf (scratchbuf, "%%xmm%d", reg + add);
3899  oappend (scratchbuf + intel_syntax);
3900}
3901
3902static void
3903OP_EM (bytemode, sizeflag)
3904     int bytemode;
3905     int sizeflag;
3906{
3907  int add = 0;
3908  if (mod != 3)
3909    {
3910      OP_E (bytemode, sizeflag);
3911      return;
3912    }
3913  USED_REX (REX_EXTZ);
3914  if (rex & REX_EXTZ)
3915    add = 8;
3916
3917  /* Skip mod/rm byte.  */
3918  MODRM_CHECK;
3919  codep++;
3920  used_prefixes |= (prefixes & PREFIX_DATA);
3921  if (prefixes & PREFIX_DATA)
3922    sprintf (scratchbuf, "%%xmm%d", rm + add);
3923  else
3924    sprintf (scratchbuf, "%%mm%d", rm + add);
3925  oappend (scratchbuf + intel_syntax);
3926}
3927
3928static void
3929OP_EX (bytemode, sizeflag)
3930     int bytemode;
3931     int sizeflag;
3932{
3933  int add = 0;
3934  if (mod != 3)
3935    {
3936      OP_E (bytemode, sizeflag);
3937      return;
3938    }
3939  USED_REX (REX_EXTZ);
3940  if (rex & REX_EXTZ)
3941    add = 8;
3942
3943  /* Skip mod/rm byte.  */
3944  MODRM_CHECK;
3945  codep++;
3946  sprintf (scratchbuf, "%%xmm%d", rm + add);
3947  oappend (scratchbuf + intel_syntax);
3948}
3949
3950static void
3951OP_MS (bytemode, sizeflag)
3952     int bytemode;
3953     int sizeflag;
3954{
3955  if (mod == 3)
3956    OP_EM (bytemode, sizeflag);
3957  else
3958    BadOp ();
3959}
3960
3961static void
3962OP_XS (bytemode, sizeflag)
3963     int bytemode;
3964     int sizeflag;
3965{
3966  if (mod == 3)
3967    OP_EX (bytemode, sizeflag);
3968  else
3969    BadOp ();
3970}
3971
3972static const char *Suffix3DNow[] = {
3973/* 00 */        NULL,           NULL,           NULL,           NULL,
3974/* 04 */        NULL,           NULL,           NULL,           NULL,
3975/* 08 */        NULL,           NULL,           NULL,           NULL,
3976/* 0C */        "pi2fw",        "pi2fd",        NULL,           NULL,
3977/* 10 */        NULL,           NULL,           NULL,           NULL,
3978/* 14 */        NULL,           NULL,           NULL,           NULL,
3979/* 18 */        NULL,           NULL,           NULL,           NULL,
3980/* 1C */        "pf2iw",        "pf2id",        NULL,           NULL,
3981/* 20 */        NULL,           NULL,           NULL,           NULL,
3982/* 24 */        NULL,           NULL,           NULL,           NULL,
3983/* 28 */        NULL,           NULL,           NULL,           NULL,
3984/* 2C */        NULL,           NULL,           NULL,           NULL,
3985/* 30 */        NULL,           NULL,           NULL,           NULL,
3986/* 34 */        NULL,           NULL,           NULL,           NULL,
3987/* 38 */        NULL,           NULL,           NULL,           NULL,
3988/* 3C */        NULL,           NULL,           NULL,           NULL,
3989/* 40 */        NULL,           NULL,           NULL,           NULL,
3990/* 44 */        NULL,           NULL,           NULL,           NULL,
3991/* 48 */        NULL,           NULL,           NULL,           NULL,
3992/* 4C */        NULL,           NULL,           NULL,           NULL,
3993/* 50 */        NULL,           NULL,           NULL,           NULL,
3994/* 54 */        NULL,           NULL,           NULL,           NULL,
3995/* 58 */        NULL,           NULL,           NULL,           NULL,
3996/* 5C */        NULL,           NULL,           NULL,           NULL,
3997/* 60 */        NULL,           NULL,           NULL,           NULL,
3998/* 64 */        NULL,           NULL,           NULL,           NULL,
3999/* 68 */        NULL,           NULL,           NULL,           NULL,
4000/* 6C */        NULL,           NULL,           NULL,           NULL,
4001/* 70 */        NULL,           NULL,           NULL,           NULL,
4002/* 74 */        NULL,           NULL,           NULL,           NULL,
4003/* 78 */        NULL,           NULL,           NULL,           NULL,
4004/* 7C */        NULL,           NULL,           NULL,           NULL,
4005/* 80 */        NULL,           NULL,           NULL,           NULL,
4006/* 84 */        NULL,           NULL,           NULL,           NULL,
4007/* 88 */        NULL,           NULL,           "pfnacc",       NULL,
4008/* 8C */        NULL,           NULL,           "pfpnacc",      NULL,
4009/* 90 */        "pfcmpge",      NULL,           NULL,           NULL,
4010/* 94 */        "pfmin",        NULL,           "pfrcp",        "pfrsqrt",
4011/* 98 */        NULL,           NULL,           "pfsub",        NULL,
4012/* 9C */        NULL,           NULL,           "pfadd",        NULL,
4013/* A0 */        "pfcmpgt",      NULL,           NULL,           NULL,
4014/* A4 */        "pfmax",        NULL,           "pfrcpit1",     "pfrsqit1",
4015/* A8 */        NULL,           NULL,           "pfsubr",       NULL,
4016/* AC */        NULL,           NULL,           "pfacc",        NULL,
4017/* B0 */        "pfcmpeq",      NULL,           NULL,           NULL,
4018/* B4 */        "pfmul",        NULL,           "pfrcpit2",     "pfmulhrw",
4019/* B8 */        NULL,           NULL,           NULL,           "pswapd",
4020/* BC */        NULL,           NULL,           NULL,           "pavgusb",
4021/* C0 */        NULL,           NULL,           NULL,           NULL,
4022/* C4 */        NULL,           NULL,           NULL,           NULL,
4023/* C8 */        NULL,           NULL,           NULL,           NULL,
4024/* CC */        NULL,           NULL,           NULL,           NULL,
4025/* D0 */        NULL,           NULL,           NULL,           NULL,
4026/* D4 */        NULL,           NULL,           NULL,           NULL,
4027/* D8 */        NULL,           NULL,           NULL,           NULL,
4028/* DC */        NULL,           NULL,           NULL,           NULL,
4029/* E0 */        NULL,           NULL,           NULL,           NULL,
4030/* E4 */        NULL,           NULL,           NULL,           NULL,
4031/* E8 */        NULL,           NULL,           NULL,           NULL,
4032/* EC */        NULL,           NULL,           NULL,           NULL,
4033/* F0 */        NULL,           NULL,           NULL,           NULL,
4034/* F4 */        NULL,           NULL,           NULL,           NULL,
4035/* F8 */        NULL,           NULL,           NULL,           NULL,
4036/* FC */        NULL,           NULL,           NULL,           NULL,
4037};
4038
4039static void
4040OP_3DNowSuffix (bytemode, sizeflag)
4041     int bytemode;
4042     int sizeflag;
4043{
4044  const char *mnemonic;
4045
4046  FETCH_DATA (the_info, codep + 1);
4047  /* AMD 3DNow! instructions are specified by an opcode suffix in the
4048     place where an 8-bit immediate would normally go.  ie. the last
4049     byte of the instruction.  */
4050  obufp = obuf + strlen (obuf);
4051  mnemonic = Suffix3DNow[*codep++ & 0xff];
4052  if (mnemonic)
4053    oappend (mnemonic);
4054  else
4055    {
4056      /* Since a variable sized modrm/sib chunk is between the start
4057         of the opcode (0x0f0f) and the opcode suffix, we need to do
4058         all the modrm processing first, and don't know until now that
4059         we have a bad opcode.  This necessitates some cleaning up.  */
4060      op1out[0] = '\0';
4061      op2out[0] = '\0';
4062      BadOp ();
4063    }
4064}
4065
4066static const char *simd_cmp_op[] = {
4067  "eq",
4068  "lt",
4069  "le",
4070  "unord",
4071  "neq",
4072  "nlt",
4073  "nle",
4074  "ord"
4075};
4076
4077static void
4078OP_SIMD_Suffix (bytemode, sizeflag)
4079     int bytemode;
4080     int sizeflag;
4081{
4082  unsigned int cmp_type;
4083
4084  FETCH_DATA (the_info, codep + 1);
4085  obufp = obuf + strlen (obuf);
4086  cmp_type = *codep++ & 0xff;
4087  if (cmp_type < 8)
4088    {
4089      char suffix1 = 'p', suffix2 = 's';
4090      used_prefixes |= (prefixes & PREFIX_REPZ);
4091      if (prefixes & PREFIX_REPZ)
4092        suffix1 = 's';
4093      else
4094        {
4095          used_prefixes |= (prefixes & PREFIX_DATA);
4096          if (prefixes & PREFIX_DATA)
4097            suffix2 = 'd';
4098          else
4099            {
4100              used_prefixes |= (prefixes & PREFIX_REPNZ);
4101              if (prefixes & PREFIX_REPNZ)
4102                suffix1 = 's', suffix2 = 'd';
4103            }
4104        }
4105      sprintf (scratchbuf, "cmp%s%c%c",
4106               simd_cmp_op[cmp_type], suffix1, suffix2);
4107      used_prefixes |= (prefixes & PREFIX_REPZ);
4108      oappend (scratchbuf);
4109    }
4110  else
4111    {
4112      /* We have a bad extension byte.  Clean up.  */
4113      op1out[0] = '\0';
4114      op2out[0] = '\0';
4115      BadOp ();
4116    }
4117}
4118
4119static void
4120SIMD_Fixup (extrachar, sizeflag)
4121     int extrachar;
4122     int sizeflag;
4123{
4124  /* Change movlps/movhps to movhlps/movlhps for 2 register operand
4125     forms of these instructions.  */
4126  if (mod == 3)
4127    {
4128      char *p = obuf + strlen (obuf);
4129      *(p + 1) = '\0';
4130      *p       = *(p - 1);
4131      *(p - 1) = *(p - 2);
4132      *(p - 2) = *(p - 3);
4133      *(p - 3) = extrachar;
4134    }
4135}
4136
4137static void
4138BadOp (void)
4139{
4140  /* Throw away prefixes and 1st. opcode byte.  */
4141  codep = insn_codep + 1;
4142  oappend ("(bad)");
4143}
Note: See TracBrowser for help on using the repository browser.