ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/disass/i386-dis.c
(Generate patch)

Comparing mon/src/disass/i386-dis.c (file contents):
Revision 1.1 by cebix, 2000-09-25T12:44:37Z vs.
Revision 1.2 by gbeauche, 2002-09-07T12:48:15Z

# Line 1 | Line 1
1   /* Print i386 instructions for GDB, the GNU debugger.
2 <   Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 1998
2 >   Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 >   2001
4     Free Software Foundation, Inc.
5  
6   This file is part of GDB.
# Line 22 | Line 23 | Foundation, Inc., 59 Temple Place - Suit
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   /*
# Line 29 | Line 31 | Foundation, Inc., 59 Temple Place - Suit
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
34 > * and the small letter tells about the operand size.  Refer to
35   * the Intel manual for details.
36   */
37  
38   #include "dis-asm.h"
39 + #include "opintl.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 +
51   static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
52 + static void ckprefix PARAMS ((void));
53 + static const char *prefix_name PARAMS ((int, int));
54 + static int print_insn PARAMS ((bfd_vma, disassemble_info *));
55 + static void dofloat PARAMS ((int));
56 + static void OP_ST PARAMS ((int, int));
57 + static void OP_STi  PARAMS ((int, int));
58 + static int putop PARAMS ((const char *, int));
59 + static void oappend PARAMS ((const char *));
60 + static void append_seg PARAMS ((void));
61 + static void OP_indirE PARAMS ((int, int));
62 + static void print_operand_value PARAMS ((char *, int, bfd_vma));
63 + static void OP_E PARAMS ((int, int));
64 + static void OP_G PARAMS ((int, int));
65 + static bfd_vma get64 PARAMS ((void));
66 + static bfd_signed_vma get32 PARAMS ((void));
67 + static bfd_signed_vma get32s PARAMS ((void));
68 + static int get16 PARAMS ((void));
69 + static void set_op PARAMS ((bfd_vma, int));
70 + static void OP_REG PARAMS ((int, int));
71 + static void OP_IMREG PARAMS ((int, int));
72 + static void OP_I PARAMS ((int, int));
73 + static void OP_I64 PARAMS ((int, int));
74 + static void OP_sI PARAMS ((int, int));
75 + static void OP_J PARAMS ((int, int));
76 + static void OP_SEG PARAMS ((int, int));
77 + static void OP_DIR PARAMS ((int, int));
78 + static void OP_OFF PARAMS ((int, int));
79 + static void OP_OFF64 PARAMS ((int, int));
80 + static void ptr_reg PARAMS ((int, int));
81 + static void OP_ESreg PARAMS ((int, int));
82 + static void OP_DSreg PARAMS ((int, int));
83 + static void OP_C PARAMS ((int, int));
84 + static void OP_D PARAMS ((int, int));
85 + static void OP_T PARAMS ((int, int));
86 + static void OP_Rd PARAMS ((int, int));
87 + static void OP_MMX PARAMS ((int, int));
88 + static void OP_XMM PARAMS ((int, int));
89 + static void OP_EM PARAMS ((int, int));
90 + static void OP_EX PARAMS ((int, int));
91 + static void OP_MS PARAMS ((int, int));
92 + static void OP_XS PARAMS ((int, int));
93 + static void OP_3DNowSuffix PARAMS ((int, int));
94 + static void OP_SIMD_Suffix PARAMS ((int, int));
95 + static void SIMD_Fixup PARAMS ((int, int));
96 + static void BadOp PARAMS ((void));
97  
98 < struct dis_private
45 < {
98 > struct 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.  */
112 + static int mode_64bit;
113 +
114 + /* Flags for the prefixes for the current instruction.  See below.  */
115 + static int prefixes;
116 +
117 + /* REX prefix the current instruction.  See below.  */
118 + static int rex;
119 + /* Bits of REX we've already used.  */
120 + static 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.  */
139 + static 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 \
159 >  ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
160     ? 1 : fetch_data ((info), (addr)))
161  
162   static int
# Line 63 | Line 165 | fetch_data (info, addr)
165       bfd_byte *addr;
166   {
167    int status;
168 <  struct dis_private *priv = (struct dis_private *)info->private_data;
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,
# Line 72 | Line 174 | fetch_data (info, addr)
174                                        info);
175    if (status != 0)
176      {
177 <      (*info->memory_error_func) (status, start, info);
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
# Line 80 | Line 187 | fetch_data (info, addr)
187    return 1;
188   }
189  
190 + #define XX NULL, 0
191 +
192   #define Eb OP_E, b_mode
84 #define indirEb OP_indirE, b_mode
85 #define Gb OP_G, 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
200 < #define Mp OP_E, 0              /* ? */
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 Rw OP_rm, w_mode
206 < #define Rd OP_rm, d_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 < #if 0
216 < #define ONE OP_ONE, 0
104 < #endif
105 < #define Cd OP_C, d_mode
106 < #define Dd OP_D, d_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 eAX OP_REG, eAX_reg
220 < #define eBX OP_REG, eBX_reg
221 < #define eCX OP_REG, eCX_reg
222 < #define eDX OP_REG, eDX_reg
223 < #define eSP OP_REG, eSP_reg
224 < #define eBP OP_REG, eBP_reg
225 < #define eSI OP_REG, eSI_reg
226 < #define eDI OP_REG, eDI_reg
227 < #define AL OP_REG, al_reg
228 < #define CL OP_REG, cl_reg
229 < #define DL OP_REG, dl_reg
230 < #define BL OP_REG, bl_reg
231 < #define AH OP_REG, ah_reg
232 < #define CH OP_REG, ch_reg
233 < #define DH OP_REG, dh_reg
234 < #define BH OP_REG, bh_reg
235 < #define AX OP_REG, ax_reg
236 < #define DX OP_REG, dx_reg
237 < #define indirDX OP_REG, indir_dx_reg
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, lptr
131 < #define Av OP_DIR, v_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 Xb OP_DSSI, b_mode
274 < #define Xv OP_DSSI, v_mode
275 < #define Yb OP_ESDI, b_mode
276 < #define Yv OP_ESDI, 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
# Line 144 | Line 285 | fetch_data (info, addr)
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 MS OP_MS, b_mode
291 <
292 < typedef int (*op_rtn) PARAMS ((int bytemode, int aflag, int dflag));
293 <
294 < static int OP_E PARAMS ((int, int, int));
295 < static int OP_G PARAMS ((int, int, int));
296 < static int OP_I PARAMS ((int, int, int));
297 < static int OP_indirE PARAMS ((int, int, int));
298 < static int OP_sI PARAMS ((int, int, int));
299 < static int OP_REG PARAMS ((int, int, int));
300 < static int OP_J PARAMS ((int, int, int));
301 < static int OP_DIR PARAMS ((int, int, int));
302 < static int OP_OFF PARAMS ((int, int, int));
303 < static int OP_ESDI PARAMS ((int, int, int));
304 < static int OP_DSSI PARAMS ((int, int, int));
305 < static int OP_SEG PARAMS ((int, int, int));
306 < static int OP_C PARAMS ((int, int, int));
307 < static int OP_D PARAMS ((int, int, int));
308 < static int OP_T PARAMS ((int, int, int));
309 < static int OP_rm PARAMS ((int, int, int));
310 < static int OP_ST PARAMS ((int, int, int));
311 < static int OP_STi  PARAMS ((int, int, int));
312 < #if 0
313 < static int OP_ONE PARAMS ((int, int, int));
172 < #endif
173 < static int OP_MMX PARAMS ((int, int, int));
174 < static int OP_EM PARAMS ((int, int, int));
175 < static int OP_MS PARAMS ((int, int, int));
176 <
177 < static void append_prefix PARAMS ((void));
178 < static void set_op PARAMS ((int op));
179 < static void putop PARAMS ((char *template, int aflag, int dflag));
180 < static void dofloat PARAMS ((int aflag, int dflag));
181 < static int get16 PARAMS ((void));
182 < static int get32 PARAMS ((void));
183 < static void ckprefix PARAMS ((void));
184 <
185 < #define b_mode 1
186 < #define v_mode 2
187 < #define w_mode 3
188 < #define d_mode 4
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
# Line 193 | Line 318 | static void ckprefix PARAMS ((void));
318   #define ds_reg 103
319   #define fs_reg 104
320   #define gs_reg 105
196 #define eAX_reg 107
197 #define eCX_reg 108
198 #define eDX_reg 109
199 #define eBX_reg 110
200 #define eSP_reg 111
201 #define eBP_reg 112
202 #define eSI_reg 113
203 #define eDI_reg 114
321  
322 < #define lptr 115
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
# Line 222 | Line 346 | static void ckprefix PARAMS ((void));
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 GRP1b NULL, NULL, 0
361 < #define GRP1S NULL, NULL, 1
362 < #define GRP1Ss NULL, NULL, 2
363 < #define GRP2b NULL, NULL, 3
364 < #define GRP2S NULL, NULL, 4
365 < #define GRP2b_one NULL, NULL, 5
366 < #define GRP2S_one NULL, NULL, 6
367 < #define GRP2b_cl NULL, NULL, 7
368 < #define GRP2S_cl NULL, NULL, 8
369 < #define GRP3b NULL, NULL, 9
370 < #define GRP3S NULL, NULL, 10
371 < #define GRP4  NULL, NULL, 11
372 < #define GRP5  NULL, NULL, 12
373 < #define GRP6  NULL, NULL, 13
374 < #define GRP7 NULL, NULL, 14
375 < #define GRP8 NULL, NULL, 15
376 < #define GRP9 NULL, NULL, 16
377 < #define GRP10 NULL, NULL, 17
378 < #define GRP11 NULL, NULL, 18
379 < #define GRP12 NULL, NULL, 19
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  
421 < #define FLOATCODE 50
249 < #define FLOAT NULL, NULL, FLOATCODE
421 > typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag));
422  
423   struct dis386 {
424 <  char *name;
424 >  const char *name;
425    op_rtn op1;
426    int bytemode1;
427    op_rtn op2;
# Line 258 | Line 430 | struct dis386 {
430    int bytemode3;
431   };
432  
433 < static struct dis386 dis386[] = {
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 >
463 > static const struct dis386 dis386[] = {
464    /* 00 */
465 <  { "addb",     Eb, Gb },
466 <  { "addS",     Ev, Gv },
467 <  { "addb",     Gb, Eb },
468 <  { "addS",     Gv, Ev },
469 <  { "addb",     AL, Ib },
470 <  { "addS",     eAX, Iv },
471 <  { "pushS",    es },
472 <  { "popS",     es },
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 },
475 <  { "orS",      Ev, Gv },
476 <  { "orb",      Gb, Eb },
477 <  { "orS",      Gv, Ev },
478 <  { "orb",      AL, Ib },
479 <  { "orS",      eAX, Iv },
480 <  { "pushS",    cs },
481 <  { "(bad)" },  /* 0x0f extended opcode escape */
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 },
484 <  { "adcS",     Ev, Gv },
485 <  { "adcb",     Gb, Eb },
486 <  { "adcS",     Gv, Ev },
487 <  { "adcb",     AL, Ib },
488 <  { "adcS",     eAX, Iv },
489 <  { "pushS",    ss },
490 <  { "popS",     ss },
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 },
493 <  { "sbbS",     Ev, Gv },
494 <  { "sbbb",     Gb, Eb },
495 <  { "sbbS",     Gv, Ev },
496 <  { "sbbb",     AL, Ib },
497 <  { "sbbS",     eAX, Iv },
498 <  { "pushS",    ds },
499 <  { "popS",     ds },
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 },
502 <  { "andS",     Ev, Gv },
503 <  { "andb",     Gb, Eb },
504 <  { "andS",     Gv, Ev },
505 <  { "andb",     AL, Ib },
506 <  { "andS",     eAX, Iv },
507 <  { "(bad)" },                  /* SEG ES prefix */
508 <  { "daa" },
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 },
511 <  { "subS",     Ev, Gv },
512 <  { "subb",     Gb, Eb },
513 <  { "subS",     Gv, Ev },
514 <  { "subb",     AL, Ib },
515 <  { "subS",     eAX, Iv },
516 <  { "(bad)" },                  /* SEG CS prefix */
517 <  { "das" },
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 },
520 <  { "xorS",     Ev, Gv },
521 <  { "xorb",     Gb, Eb },
522 <  { "xorS",     Gv, Ev },
523 <  { "xorb",     AL, Ib },
524 <  { "xorS",     eAX, Iv },
525 <  { "(bad)" },                  /* SEG SS prefix */
526 <  { "aaa" },
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 },
529 <  { "cmpS",     Ev, Gv },
530 <  { "cmpb",     Gb, Eb },
531 <  { "cmpS",     Gv, Ev },
532 <  { "cmpb",     AL, Ib },
533 <  { "cmpS",     eAX, Iv },
534 <  { "(bad)" },                  /* SEG DS prefix */
535 <  { "aas" },
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 <  { "incS",     eAX },
538 <  { "incS",     eCX },
539 <  { "incS",     eDX },
540 <  { "incS",     eBX },
541 <  { "incS",     eSP },
542 <  { "incS",     eBP },
543 <  { "incS",     eSI },
544 <  { "incS",     eDI },
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 <  { "decS",     eAX },
547 <  { "decS",     eCX },
548 <  { "decS",     eDX },
549 <  { "decS",     eBX },
550 <  { "decS",     eSP },
551 <  { "decS",     eBP },
552 <  { "decS",     eSI },
553 <  { "decS",     eDI },
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",    eAX },
556 <  { "pushS",    eCX },
557 <  { "pushS",    eDX },
558 <  { "pushS",    eBX },
559 <  { "pushS",    eSP },
560 <  { "pushS",    eBP },
561 <  { "pushS",    eSI },
562 <  { "pushS",    eDI },
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",     eAX },
565 <  { "popS",     eCX },
566 <  { "popS",     eDX },
567 <  { "popS",     eBX },
568 <  { "popS",     eSP },
569 <  { "popS",     eBP },
570 <  { "popS",     eSI },
571 <  { "popS",     eDI },
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" },
574 <  { "popa" },
575 <  { "boundS",   Gv, Ma },
576 <  { "arpl",     Ew, Gw },
577 <  { "(bad)" },                  /* seg fs */
578 <  { "(bad)" },                  /* seg gs */
579 <  { "(bad)" },                  /* op size prefix */
580 <  { "(bad)" },                  /* adr size prefix */
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 <  { "pushS",    Iv },           /* 386 book wrong */
583 <  { "imulS",    Gv, Ev, Iv },
584 <  { "pushS",    sIb },          /* push of byte really pushes 2 or 4 bytes */
585 <  { "imulS",    Gv, Ev, Ib },
586 <  { "insb",     Yb, indirDX },
587 <  { "insS",     Yv, indirDX },
588 <  { "outsb",    indirDX, Xb },
589 <  { "outsS",    indirDX, Xv },
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 <  { "jo",       Jb },
592 <  { "jno",      Jb },
593 <  { "jb",       Jb },
594 <  { "jae",      Jb },
595 <  { "je",       Jb },
596 <  { "jne",      Jb },
597 <  { "jbe",      Jb },
598 <  { "ja",       Jb },
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 <  { "js",       Jb },
601 <  { "jns",      Jb },
602 <  { "jp",       Jb },
603 <  { "jnp",      Jb },
604 <  { "jl",       Jb },
605 <  { "jnl",      Jb },
606 <  { "jle",      Jb },
607 <  { "jg",       Jb },
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)" },
611 >  { "(bad)",            XX, XX, XX },
612    { GRP1Ss },
613 <  { "testb",    Eb, Gb },
614 <  { "testS",    Ev, Gv },
615 <  { "xchgb",    Eb, Gb },
616 <  { "xchgS",    Ev, Gv },
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 },
619 <  { "movS",     Ev, Gv },
620 <  { "movb",     Gb, Eb },
621 <  { "movS",     Gv, Ev },
622 <  { "movS",     Ev, Sw },
623 <  { "leaS",     Gv, M },
624 <  { "movS",     Sw, Ev },
625 <  { "popS",     Ev },
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" },
628 <  { "xchgS",    eCX, eAX },
629 <  { "xchgS",    eDX, eAX },
630 <  { "xchgS",    eBX, eAX },
631 <  { "xchgS",    eSP, eAX },
632 <  { "xchgS",    eBP, eAX },
633 <  { "xchgS",    eSI, eAX },
634 <  { "xchgS",    eDI, eAX },
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 <  { "cWtS" },
638 <  { "cStd" },
639 <  { "lcall",    Ap },
640 <  { "(bad)" },          /* fwait */
641 <  { "pushf" },
642 <  { "popf" },
643 <  { "sahf" },
644 <  { "lahf" },
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, Ob },
647 <  { "movS",     eAX, Ov },
648 <  { "movb",     Ob, AL },
649 <  { "movS",     Ov, eAX },
650 <  { "movsb",    Yb, Xb },
651 <  { "movsS",    Yv, Xv },
652 <  { "cmpsb",    Yb, Xb },
653 <  { "cmpsS",    Yv, Xv },
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 },
656 <  { "testS",    eAX, Iv },
657 <  { "stosb",    Yb, AL },
658 <  { "stosS",    Yv, eAX },
659 <  { "lodsb",    AL, Xb },
660 <  { "lodsS",    eAX, Xv },
661 <  { "scasb",    AL, Yb },
662 <  { "scasS",    eAX, Yv },
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",     AL, Ib },
665 <  { "movb",     CL, Ib },
666 <  { "movb",     DL, Ib },
667 <  { "movb",     BL, Ib },
668 <  { "movb",     AH, Ib },
669 <  { "movb",     CH, Ib },
670 <  { "movb",     DH, Ib },
671 <  { "movb",     BH, Ib },
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",     eAX, Iv },
674 <  { "movS",     eCX, Iv },
675 <  { "movS",     eDX, Iv },
676 <  { "movS",     eBX, Iv },
677 <  { "movS",     eSP, Iv },
678 <  { "movS",     eBP, Iv },
679 <  { "movS",     eSI, Iv },
680 <  { "movS",     eDI, Iv },
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 <  { "ret",      Iw },
685 <  { "ret" },
686 <  { "lesS",     Gv, Mp },
687 <  { "ldsS",     Gv, Mp },
688 <  { "movb",     Eb, Ib },
689 <  { "movS",     Ev, Iv },
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 <  { "enter",    Iw, Ib },
692 <  { "leave" },
693 <  { "lret",     Iw },
694 <  { "lret" },
695 <  { "int3" },
696 <  { "int",      Ib },
697 <  { "into" },
698 <  { "iret" },
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",      Ib },
705 <  { "aad",      Ib },
706 <  { "(bad)" },
707 <  { "xlat" },
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 },
# Line 512 | Line 715 | static struct dis386 dis386[] = {
715    { FLOAT },
716    { FLOAT },
717    /* e0 */
718 <  { "loopne",   Jb },
719 <  { "loope",    Jb },
720 <  { "loop",     Jb },
721 <  { "jCcxz",    Jb },
722 <  { "inb",      AL, Ib },
723 <  { "inS",      eAX, Ib },
724 <  { "outb",     Ib, AL },
725 <  { "outS",     Ib, eAX },
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 <  { "call",     Av },
728 <  { "jmp",      Jv },
729 <  { "ljmp",     Ap },
730 <  { "jmp",      Jb },
731 <  { "inb",      AL, indirDX },
732 <  { "inS",      eAX, indirDX },
733 <  { "outb",     indirDX, AL },
734 <  { "outS",     indirDX, eAX },
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)" },                  /* lock prefix */
737 <  { "(bad)" },
738 <  { "(bad)" },                  /* repne */
739 <  { "(bad)" },                  /* repz */
740 <  { "hlt" },
741 <  { "cmc" },
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" },
746 <  { "stc" },
747 <  { "cli" },
748 <  { "sti" },
749 <  { "cld" },
750 <  { "std" },
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  
755 < static struct dis386 dis386_twobyte[] = {
755 > static const struct dis386 dis386_twobyte[] = {
756    /* 00 */
757    { GRP6 },
758    { GRP7 },
759 <  { "larS", Gv, Ew },
760 <  { "lslS", Gv, Ew },  
761 <  { "(bad)" },
762 <  { "(bad)" },
763 <  { "clts" },
764 <  { "(bad)" },  
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" },
767 <  { "wbinvd" },
768 <  { "(bad)" },  { "ud2a" },  
769 <  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
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 <  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
776 <  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
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 <  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
785 <  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
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 <  /* these are all backward in appendix A of the intel book */
794 <  { "movl", Rd, Cd },
795 <  { "movl", Rd, Dd },
796 <  { "movl", Cd, Rd },
797 <  { "movl", Dd, Rd },  
798 <  { "movl", Rd, Td },
799 <  { "(bad)" },
800 <  { "movl", Td, Rd },
582 <  { "(bad)" },  
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 <  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
803 <  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
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" },  { "rdtsc" },  { "rdmsr" },  { "rdpmc" },  
812 <  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
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)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
821 <  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
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 }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
830 <  { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
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 }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
839 <  { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },  
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 <  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
848 <  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
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 <  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
857 <  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
856 >  { PREGRP0 },
857 >  { PREGRP10 },
858 >  { PREGRP17 },
859 >  { PREGRP16 },
860 >  { PREGRP14 },
861 >  { PREGRP7 },
862 >  { PREGRP5 },
863 >  { PREGRP6 },
864    /* 60 */
865 <  { "punpcklbw", MX, EM },
866 <  { "punpcklwd", MX, EM },
867 <  { "punpckldq", MX, EM },
868 <  { "packsswb", MX, EM },
869 <  { "pcmpgtb", MX, EM },
870 <  { "pcmpgtw", MX, EM },
871 <  { "pcmpgtd", MX, EM },
872 <  { "packuswb", MX, EM },
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 },
875 <  { "punpckhwd", MX, EM },
876 <  { "punpckhdq", MX, EM },
877 <  { "packssdw", MX, EM },
878 <  { "(bad)" },  { "(bad)" },
879 <  { "movd", MX, Ev },
880 <  { "movq", MX, EM },
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 <  { "(bad)" },
883 >  { PREGRP22 },
884    { GRP10 },
885    { GRP11 },
886    { GRP12 },
887 <  { "pcmpeqb", MX, EM },
888 <  { "pcmpeqw", MX, EM },
889 <  { "pcmpeqd", MX, EM },
890 <  { "emms" },
887 >  { "pcmpeqb",          MX, EM, XX },
888 >  { "pcmpeqw",          MX, EM, XX },
889 >  { "pcmpeqd",          MX, EM, XX },
890 >  { "emms",             XX, XX, XX },
891    /* 78 */
892 <  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
893 <  { "(bad)" },  { "(bad)" },
894 <  { "movd", Ev, MX },
895 <  { "movq", EM, MX },
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 <  { "jo", Jv },
902 <  { "jno", Jv },
903 <  { "jb", Jv },
904 <  { "jae", Jv },  
905 <  { "je", Jv },
906 <  { "jne", Jv },
907 <  { "jbe", Jv },
908 <  { "ja", Jv },  
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 <  { "js", Jv },
911 <  { "jns", Jv },
912 <  { "jp", Jv },
913 <  { "jnp", Jv },  
914 <  { "jl", Jv },
915 <  { "jge", Jv },
916 <  { "jle", Jv },
917 <  { "jg", Jv },  
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 },
920 <  { "setno", Eb },
921 <  { "setb", Eb },
922 <  { "setae", Eb },
923 <  { "sete", Eb },
924 <  { "setne", Eb },
925 <  { "setbe", Eb },
926 <  { "seta", Eb },
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 },
929 <  { "setns", Eb },
930 <  { "setp", Eb },
931 <  { "setnp", Eb },
932 <  { "setl", Eb },
933 <  { "setge", Eb },
934 <  { "setle", Eb },
935 <  { "setg", Eb },  
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 <  { "pushS", fs },
938 <  { "popS", fs },
939 <  { "cpuid" },
940 <  { "btS", Ev, Gv },  
941 <  { "shldS", Ev, Gv, Ib },
942 <  { "shldS", Ev, Gv, CL },
943 <  { "(bad)" },
944 <  { "(bad)" },  
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 <  { "pushS", gs },
947 <  { "popS", gs },
948 <  { "rsm" },
949 <  { "btsS", Ev, Gv },  
950 <  { "shrdS", Ev, Gv, Ib },
951 <  { "shrdS", Ev, Gv, CL },
952 <  { "(bad)" },
953 <  { "imulS", Gv, Ev },  
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 },
956 <  { "cmpxchgS", Ev, Gv },
957 <  { "lssS", Gv, Mp },   /* 386 lists only Mp */
958 <  { "btrS", Ev, Gv },  
959 <  { "lfsS", Gv, Mp },   /* 386 lists only Mp */
960 <  { "lgsS", Gv, Mp },   /* 386 lists only Mp */
961 <  { "movzbS", Gv, Eb },
962 <  { "movzwS", Gv, Ew },  
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 <  { "ud2b" },
965 <  { "(bad)" },
964 >  { "(bad)",            XX, XX, XX },
965 >  { "ud2b",             XX, XX, XX },
966    { GRP8 },
967 <  { "btcS", Ev, Gv },  
968 <  { "bsfS", Gv, Ev },
969 <  { "bsrS", Gv, Ev },
970 <  { "movsbS", Gv, Eb },
971 <  { "movswS", Gv, Ew },  
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 },
974 <  { "xaddS", Ev, Gv },
975 <  { "(bad)" },
976 <  { "(bad)" },  
977 <  { "(bad)" },
978 <  { "(bad)" },
979 <  { "(bad)" },
980 <  { GRP9 },  
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", eAX },
983 <  { "bswap", eCX },
984 <  { "bswap", eDX },
985 <  { "bswap", eBX },
986 <  { "bswap", eSP },
987 <  { "bswap", eBP },
988 <  { "bswap", eSI },
989 <  { "bswap", eDI },
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)" },
992 <  { "psrlw", MX, EM },
993 <  { "psrld", MX, EM },
994 <  { "psrlq", MX, EM },
995 <  { "(bad)" },
996 <  { "pmullw", MX, EM },
997 <  { "(bad)" },  { "(bad)" },  
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 },
1001 <  { "psubusw", MX, EM },
1002 <  { "(bad)" },
1003 <  { "pand", MX, EM },
1004 <  { "paddusb", MX, EM },
1005 <  { "paddusw", MX, EM },
1006 <  { "(bad)" },
1007 <  { "pandn", MX, EM },
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 <  { "(bad)" },
1010 <  { "psraw", MX, EM },
1011 <  { "psrad", MX, EM },
1012 <  { "(bad)" },
1013 <  { "(bad)" },
1014 <  { "pmulhw", MX, EM },
1015 <  { "(bad)" },  { "(bad)" },  
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 },
1019 <  { "psubsw", MX, EM },
1020 <  { "(bad)" },
1021 <  { "por", MX, EM },
1022 <  { "paddsb", MX, EM },
1023 <  { "paddsw", MX, EM },
1024 <  { "(bad)" },
1025 <  { "pxor", MX, EM },
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)" },
1028 <  { "psllw", MX, EM },
1029 <  { "pslld", MX, EM },
1030 <  { "psllq", MX, EM },
1031 <  { "(bad)" },
1032 <  { "pmaddwd", MX, EM },
1033 <  { "(bad)" },  { "(bad)" },  
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 },
1037 <  { "psubw", MX, EM },
1038 <  { "psubd", MX, EM },
1039 <  { "(bad)" },  
1040 <  { "paddb", MX, EM },
1041 <  { "paddw", MX, EM },
1042 <  { "paddd", MX, EM },
1043 <  { "(bad)" }
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  
1046   static const unsigned char onebyte_has_modrm[256] = {
1047 <  1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1048 <  1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1049 <  1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1050 <  1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
1051 <  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1052 <  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1053 <  0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
1054 <  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1055 <  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1056 <  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1057 <  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1058 <  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1059 <  1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
1060 <  1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
1061 <  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1062 <  0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
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  
1069   static const unsigned char twobyte_has_modrm[256] = {
1070 <  /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1071 <  /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1072 <  /* 20 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 2f */
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 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1078 <  /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
1079 <  /* 70 */ 0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
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,1,1,0,0,0,1,1,1,1,1, /* af */
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,0,1,0,0,1,1,0,1,1,1,0,1, /* df */
1086 <  /* e0 */ 0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,1, /* ef */
1087 <  /* f0 */ 0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0  /* ff */
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 >
1092 > static 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  
1115   static char obuf[100];
1116   static char *obufp;
1117   static char scratchbuf[100];
1118   static unsigned char *start_codep;
1119 + static unsigned char *insn_codep;
1120   static unsigned char *codep;
1121   static disassemble_info *the_info;
1122   static int mod;
1123   static int rm;
1124   static int reg;
1125 < static void oappend PARAMS ((char *s));
1125 > static unsigned char need_modrm;
1126  
1127 < static char *names32[]={
1128 <  "eax","ecx","edx","ebx", "esp","ebp","esi","edi",
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 >
1132 > static const char **names64;
1133 > static const char **names32;
1134 > static const char **names16;
1135 > static const char **names8;
1136 > static const char **names8rex;
1137 > static const char **names_seg;
1138 > static const char **index16;
1139 >
1140 > static const char *intel_names64[] = {
1141 >  "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1142 >  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1143 > };
1144 > static const char *intel_names32[] = {
1145 >  "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1146 >  "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1147   };
1148 < static char *names16[] = {
1149 <  "ax","cx","dx","bx","sp","bp","si","di",
1148 > static const char *intel_names16[] = {
1149 >  "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1150 >  "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1151   };
1152 < static char *names8[] = {
1153 <  "al","cl","dl","bl","ah","ch","dh","bh",
1152 > static const char *intel_names8[] = {
1153 >  "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1154   };
1155 < static char *names_seg[] = {
1156 <  "es","cs","ss","ds","fs","gs","?","?",
1155 > static const char *intel_names8rex[] = {
1156 >  "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1157 >  "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1158   };
1159 < static char *index16[] = {
1160 <  "bx+si","bx+di","bp+si","bp+di","si","di","bp","bx"
1159 > static const char *intel_names_seg[] = {
1160 >  "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1161 > };
1162 > static const char *intel_index16[] = {
1163 >  "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1164   };
1165  
1166 < static struct dis386 grps[][8] = {
1166 > static const char *att_names64[] = {
1167 >  "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1168 >  "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1169 > };
1170 > static const char *att_names32[] = {
1171 >  "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1172 >  "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1173 > };
1174 > static const char *att_names16[] = {
1175 >  "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1176 >  "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1177 > };
1178 > static const char *att_names8[] = {
1179 >  "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1180 > };
1181 > static const char *att_names8rex[] = {
1182 >  "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1183 >  "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1184 > };
1185 > static const char *att_names_seg[] = {
1186 >  "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1187 > };
1188 > static const char *att_index16[] = {
1189 >  "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1190 > };
1191 >
1192 > static const struct dis386 grps[][8] = {
1193    /* GRP1b */
1194    {
1195 <    { "addb",   Eb, Ib },
1196 <    { "orb",    Eb, Ib },
1197 <    { "adcb",   Eb, Ib },
1198 <    { "sbbb",   Eb, Ib },
1199 <    { "andb",   Eb, Ib },
1200 <    { "subb",   Eb, Ib },
1201 <    { "xorb",   Eb, Ib },
1202 <    { "cmpb",   Eb, Ib }
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 <    { "addS",   Ev, Iv },
1207 <    { "orS",    Ev, Iv },
1208 <    { "adcS",   Ev, Iv },
1209 <    { "sbbS",   Ev, Iv },
1210 <    { "andS",   Ev, Iv },
1211 <    { "subS",   Ev, Iv },
1212 <    { "xorS",   Ev, Iv },
1213 <    { "cmpS",   Ev, Iv }
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 <    { "addS",   Ev, sIb },
1218 <    { "orS",    Ev, sIb },
1219 <    { "adcS",   Ev, sIb },
1220 <    { "sbbS",   Ev, sIb },
1221 <    { "andS",   Ev, sIb },
1222 <    { "subS",   Ev, sIb },
1223 <    { "xorS",   Ev, sIb },
1224 <    { "cmpS",   Ev, sIb }
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 <    { "rolb",   Eb, Ib },
1229 <    { "rorb",   Eb, Ib },
1230 <    { "rclb",   Eb, Ib },
1231 <    { "rcrb",   Eb, Ib },
1232 <    { "shlb",   Eb, Ib },
1233 <    { "shrb",   Eb, Ib },
1234 <    { "(bad)" },
1235 <    { "sarb",   Eb, Ib },
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 <    { "rolS",   Ev, Ib },
1240 <    { "rorS",   Ev, Ib },
1241 <    { "rclS",   Ev, Ib },
1242 <    { "rcrS",   Ev, Ib },
1243 <    { "shlS",   Ev, Ib },
1244 <    { "shrS",   Ev, Ib },
1245 <    { "(bad)" },
1246 <    { "sarS",   Ev, Ib },
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 <    { "rolb",   Eb },
1251 <    { "rorb",   Eb },
1252 <    { "rclb",   Eb },
1253 <    { "rcrb",   Eb },
1254 <    { "shlb",   Eb },
1255 <    { "shrb",   Eb },
1256 <    { "(bad)" },
1257 <    { "sarb",   Eb },
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 <    { "rolS",   Ev },
1262 <    { "rorS",   Ev },
1263 <    { "rclS",   Ev },
1264 <    { "rcrS",   Ev },
1265 <    { "shlS",   Ev },
1266 <    { "shrS",   Ev },
1267 <    { "(bad)" },
1268 <    { "sarS",   Ev },
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 <    { "rolb",   Eb, CL },
1273 <    { "rorb",   Eb, CL },
1274 <    { "rclb",   Eb, CL },
1275 <    { "rcrb",   Eb, CL },
1276 <    { "shlb",   Eb, CL },
1277 <    { "shrb",   Eb, CL },
1278 <    { "(bad)" },
1279 <    { "sarb",   Eb, CL },
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 <    { "rolS",   Ev, CL },
1284 <    { "rorS",   Ev, CL },
1285 <    { "rclS",   Ev, CL },
1286 <    { "rcrS",   Ev, CL },
1287 <    { "shlS",   Ev, CL },
1288 <    { "shrS",   Ev, CL },
1289 <    { "(bad)" },
1290 <    { "sarS",   Ev, CL }
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 <    { "testb",  Eb, Ib },
1295 <    { "(bad)",  Eb },
1296 <    { "notb",   Eb },
1297 <    { "negb",   Eb },
1298 <    { "mulb",   AL, Eb },
1299 <    { "imulb",  AL, Eb },
1300 <    { "divb",   AL, Eb },
1301 <    { "idivb",  AL, Eb }
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 <    { "testS",  Ev, Iv },
1306 <    { "(bad)" },
1307 <    { "notS",   Ev },
1308 <    { "negS",   Ev },
1309 <    { "mulS",   eAX, Ev },
1310 <    { "imulS",  eAX, Ev },
1311 <    { "divS",   eAX, Ev },
1312 <    { "idivS",  eAX, Ev },
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 <    { "incb", Eb },
1317 <    { "decb", Eb },
1318 <    { "(bad)" },
1319 <    { "(bad)" },
1320 <    { "(bad)" },
1321 <    { "(bad)" },
1322 <    { "(bad)" },
1323 <    { "(bad)" },
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 <    { "incS",   Ev },
1328 <    { "decS",   Ev },
1329 <    { "call",   indirEv },
1330 <    { "lcall",  indirEv },
1331 <    { "jmp",    indirEv },
1332 <    { "ljmp",   indirEv },
1333 <    { "pushS",  Ev },
1334 <    { "(bad)" },
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 <    { "sldt",   Ew },
1339 <    { "str",    Ew },
1340 <    { "lldt",   Ew },
1341 <    { "ltr",    Ew },
1342 <    { "verr",   Ew },
1343 <    { "verw",   Ew },
1344 <    { "(bad)" },
1345 <    { "(bad)" }
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 <    { "sgdt", Ew },
1350 <    { "sidt", Ew },
1351 <    { "lgdt", Ew },
1352 <    { "lidt", Ew },
1353 <    { "smsw", Ew },
1354 <    { "(bad)" },
1355 <    { "lmsw", Ew },
1356 <    { "invlpg", Ew },
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)" },
1361 <    { "(bad)" },
1362 <    { "(bad)" },
1363 <    { "(bad)" },
1364 <    { "btS",    Ev, Ib },
1365 <    { "btsS",   Ev, Ib },
1366 <    { "btrS",   Ev, Ib },
1367 <    { "btcS",   Ev, Ib },
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)" },
1372 <    { "cmpxchg8b", Ev },
1373 <    { "(bad)" },
1374 <    { "(bad)" },
1375 <    { "(bad)" },
1376 <    { "(bad)" },
1377 <    { "(bad)" },
1378 <    { "(bad)" },
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)" },
1383 <    { "(bad)" },
1384 <    { "psrlw", MS, Ib },
1385 <    { "(bad)" },
1386 <    { "psraw", MS, Ib },
1387 <    { "(bad)" },
1388 <    { "psllw", MS, Ib },
1389 <    { "(bad)" },
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)" },
1394 <    { "(bad)" },
1395 <    { "psrld", MS, Ib },
1396 <    { "(bad)" },
1397 <    { "psrad", MS, Ib },
1398 <    { "(bad)" },
1399 <    { "pslld", MS, Ib },
1400 <    { "(bad)" },
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)" },
1405 <    { "(bad)" },
1406 <    { "psrlq", MS, Ib },
1407 <    { "(bad)" },
1408 <    { "(bad)" },
1409 <    { "(bad)" },
1410 <    { "psllq", MS, Ib },
1411 <    { "(bad)" },
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  
1449 < #define PREFIX_REPZ 1
1450 < #define PREFIX_REPNZ 2
1451 < #define PREFIX_LOCK 4
1452 < #define PREFIX_CS 8
1453 < #define PREFIX_SS 0x10
1454 < #define PREFIX_DS 0x20
1455 < #define PREFIX_ES 0x40
1456 < #define PREFIX_FS 0x80
1457 < #define PREFIX_GS 0x100
1458 < #define PREFIX_DATA 0x200
1459 < #define PREFIX_ADR 0x400
1460 < #define PREFIX_FWAIT 0x800
1449 > static 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  
1641 < static int prefixes;
1641 > static 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  
1650   static void
1651   ckprefix ()
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;
# Line 1118 | Line 1714 | ckprefix ()
1714            prefixes |= PREFIX_DATA;
1715            break;
1716          case 0x67:
1717 <          prefixes |= PREFIX_ADR;
1717 >          prefixes |= PREFIX_ADDR;
1718            break;
1719 <        case 0x9b:
1720 <          prefixes |= PREFIX_FWAIT;
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 < static char op1out[100], op2out[100], op3out[100];
1746 < static int op_address[3], op_ad, op_index[3];
1747 < static int start_pc;
1745 > /* Return the name of the prefix byte PREF, or NULL if PREF is not a
1746 >   prefix byte.  */
1747 >
1748 > static const char *
1749 > prefix_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  
1820 + static char op1out[100], op2out[100], op3out[100];
1821 + static int op_ad, op_index[3];
1822 + static bfd_vma op_address[3];
1823 + static bfd_vma op_riprel[3];
1824 + static bfd_vma start_pc;
1825  
1826   /*
1827   *   On the 386's of 1988, the maximum length of an instruction is 15 bytes.
# Line 1144 | Line 1832 | static int start_pc;
1832   * The function returns the length of this instruction in bytes.
1833   */
1834  
1835 < int print_insn_x86 PARAMS ((bfd_vma pc, disassemble_info *info, int aflag,
1836 <                            int dflag));
1835 > static char intel_syntax;
1836 > static char open_char;
1837 > static char close_char;
1838 > static char separator_char;
1839 > static 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.  */
1844   int
1845 < print_insn_i386 (pc, info)
1845 > print_insn_i386_att (pc, info)
1846       bfd_vma pc;
1847       disassemble_info *info;
1848   {
1849 <  if (info->mach == bfd_mach_i386_i386)
1850 <    return print_insn_x86 (pc, info, 1, 1);
1851 <  else if (info->mach == bfd_mach_i386_i8086)
1157 <    return print_insn_x86 (pc, info, 0, 0);
1158 <  else
1159 <    abort ();
1849 >  intel_syntax = 0;
1850 >
1851 >  return print_insn (pc, info);
1852   }
1853  
1854   int
1855 < print_insn_x86 (pc, info, aflag, dflag)
1855 > print_insn_i386_intel (pc, info)
1856       bfd_vma pc;
1857       disassemble_info *info;
1166     int aflag;
1167     int dflag;
1858   {
1859 <  struct dis386 *dp;
1859 >  intel_syntax = 1;
1860 >
1861 >  return print_insn (pc, info);
1862 > }
1863 >
1864 > int
1865 > print_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 >
1874 > static int
1875 > print_insn (pc, info)
1876 >     bfd_vma pc;
1877 >     disassemble_info *info;
1878 > {
1879 >  const struct dis386 *dp;
1880    int i;
1881 <  int enter_instruction;
1881 >  int two_source_ops;
1882    char *first, *second, *third;
1883    int needcomma;
1884 <  unsigned char need_modrm;
1885 <
1884 >  unsigned char uses_SSE_prefix;
1885 >  int sizeflag;
1886 >  const char *p;
1887    struct dis_private priv;
1177  bfd_byte *inbuf = priv.the_buffer;
1888  
1889 <  /* The output looks better if we put 5 bytes on a line, since that
1890 <     puts long word instructions on a single line.  */
1891 <  info->bytes_per_line = 5;
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;
1186  if (setjmp (priv.bailout) != 0)
1187    /* Error return.  */
1188    return -1;
1989  
1990    obuf[0] = 0;
1991    op1out[0] = 0;
# Line 1196 | Line 1996 | print_insn_x86 (pc, info, aflag, dflag)
1996  
1997    the_info = info;
1998    start_pc = pc;
1999 <  start_codep = inbuf;
2000 <  codep = inbuf;
2001 <  
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 <  if (*codep == 0xc8)
2035 <    enter_instruction = 1;
1207 <  else
1208 <    enter_instruction = 0;
1209 <  
1210 <  obufp = obuf;
1211 <  
1212 <  if (prefixes & PREFIX_REPZ)
1213 <    oappend ("repz ");
1214 <  if (prefixes & PREFIX_REPNZ)
1215 <    oappend ("repnz ");
1216 <  if (prefixes & PREFIX_LOCK)
1217 <    oappend ("lock ");
1218 <  
2034 >  two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
2035 >
2036    if ((prefixes & PREFIX_FWAIT)
2037        && ((*codep < 0xd8) || (*codep > 0xdf)))
2038      {
2039 <      /* fwait not followed by floating point instruction */
2040 <      (*info->fprintf_func) (info->stream, "fwait");
2041 <      return (1);
2042 <    }
2043 <  
2044 <  if (prefixes & PREFIX_DATA)
2045 <    dflag ^= 1;
2046 <  
2047 <  if (prefixes & PREFIX_ADR)
1231 <    {
1232 <      aflag ^= 1;
1233 <      if (aflag)
1234 <        oappend ("addr32 ");
1235 <      else
1236 <        oappend ("addr16 ");
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 <  
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);
# Line 1259 | Line 2116 | print_insn_x86 (pc, info, aflag, dflag)
2116  
2117    if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2118      {
2119 <      dofloat (aflag, dflag);
2119 >      dofloat (sizeflag);
2120      }
2121    else
2122      {
2123 +      int index;
2124        if (dp->name == NULL)
2125 <        dp = &grps[dp->bytemode1][reg];
2126 <      
2127 <      putop (dp->name, aflag, dflag);
2128 <      
2129 <      obufp = op1out;
2130 <      op_ad = 2;
2131 <      if (dp->op1)
2132 <        (*dp->op1)(dp->bytemode1, aflag, dflag);
2133 <      
2134 <      obufp = op2out;
2135 <      op_ad = 1;
2136 <      if (dp->op2)
2137 <        (*dp->op2)(dp->bytemode2, aflag, dflag);
2138 <      
2139 <      obufp = op3out;
2140 <      op_ad = 0;
2141 <      if (dp->op3)
2142 <        (*dp->op3)(dp->bytemode3, aflag, dflag);
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 <  
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 <  /* enter instruction is printed with operands in the
2211 <   * same order as the intel book; everything else
2212 <   * is printed in reverse order
1296 <   */
1297 <  if (enter_instruction)
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;
# Line 1312 | Line 2227 | print_insn_x86 (pc, info, aflag, dflag)
2227    needcomma = 0;
2228    if (*first)
2229      {
2230 <      if (op_index[0] != -1)
2231 <        (*info->print_address_func) (op_address[op_index[0]], info);
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;
# Line 1322 | Line 2237 | print_insn_x86 (pc, info, aflag, dflag)
2237      {
2238        if (needcomma)
2239          (*info->fprintf_func) (info->stream, ",");
2240 <      if (op_index[1] != -1)
2241 <        (*info->print_address_func) (op_address[op_index[1]], info);
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;
# Line 1332 | Line 2247 | print_insn_x86 (pc, info, aflag, dflag)
2247      {
2248        if (needcomma)
2249          (*info->fprintf_func) (info->stream, ",");
2250 <      if (op_index[2] != -1)
2251 <        (*info->print_address_func) (op_address[op_index[2]], info);
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 <  return (codep - inbuf);
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  
2265 < static char *float_mem[] = {
2265 > static const char *float_mem[] = {
2266    /* d8 */
2267 <  "fadds",
2268 <  "fmuls",
2269 <  "fcoms",
2270 <  "fcomps",
2271 <  "fsubs",
2272 <  "fsubrs",
2273 <  "fdivs",
2274 <  "fdivrs",
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 <  "flds",
2276 >  "fld{s||s|}",
2277    "(bad)",
2278 <  "fsts",
2279 <  "fstps",
2278 >  "fst{s||s|}",
2279 >  "fstp{s||s|}",
2280    "fldenv",
2281    "fldcw",
2282    "fNstenv",
2283    "fNstcw",
2284    /* da */
2285 <  "fiaddl",
2286 <  "fimull",
2287 <  "ficoml",
2288 <  "ficompl",
2289 <  "fisubl",
2290 <  "fisubrl",
2291 <  "fidivl",
2292 <  "fidivrl",
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 <  "fildl",
2294 >  "fild{l||l|}",
2295    "(bad)",
2296 <  "fistl",
2297 <  "fistpl",
2296 >  "fist{l||l|}",
2297 >  "fistp{l||l|}",
2298    "(bad)",
2299 <  "fldt",
2299 >  "fld{t||t|}",
2300    "(bad)",
2301 <  "fstpt",
2301 >  "fstp{t||t|}",
2302    /* dc */
2303 <  "faddl",
2304 <  "fmull",
2305 <  "fcoml",
2306 <  "fcompl",
2307 <  "fsubl",
2308 <  "fsubrl",
2309 <  "fdivl",
2310 <  "fdivrl",
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 <  "fldl",
2312 >  "fld{l||l|}",
2313    "(bad)",
2314 <  "fstl",
2315 <  "fstpl",
2314 >  "fst{l||l|}",
2315 >  "fstp{l||l|}",
2316    "frstor",
2317    "(bad)",
2318    "fNsave",
# Line 1410 | Line 2332 | static char *float_mem[] = {
2332    "fist",
2333    "fistp",
2334    "fbld",
2335 <  "fildll",
2335 >  "fild{ll||ll|}",
2336    "fbstp",
2337    "fistpll",
2338   };
# Line 1418 | Line 2340 | static char *float_mem[] = {
2340   #define ST OP_ST, 0
2341   #define STi OP_STi, 0
2342  
2343 < #define FGRPd9_2 NULL, NULL, 0
2344 < #define FGRPd9_4 NULL, NULL, 1
2345 < #define FGRPd9_5 NULL, NULL, 2
2346 < #define FGRPd9_6 NULL, NULL, 3
2347 < #define FGRPd9_7 NULL, NULL, 4
2348 < #define FGRPda_5 NULL, NULL, 5
2349 < #define FGRPdb_4 NULL, NULL, 6
2350 < #define FGRPde_3 NULL, NULL, 7
2351 < #define FGRPdf_4 NULL, NULL, 8
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  
2353 < static struct dis386 float_reg[][8] = {
2353 > static const struct dis386 float_reg[][8] = {
2354    /* d8 */
2355    {
2356 <    { "fadd",   ST, STi },
2357 <    { "fmul",   ST, STi },
2358 <    { "fcom",   STi },
2359 <    { "fcomp",  STi },
2360 <    { "fsub",   ST, STi },
2361 <    { "fsubr",  ST, STi },
2362 <    { "fdiv",   ST, STi },
2363 <    { "fdivr",  ST, STi },
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 },
2368 <    { "fxch",   STi },
2367 >    { "fld",    STi, XX, XX },
2368 >    { "fxch",   STi, XX, XX },
2369      { FGRPd9_2 },
2370 <    { "(bad)" },
2370 >    { "(bad)",  XX, XX, XX },
2371      { FGRPd9_4 },
2372      { FGRPd9_5 },
2373      { FGRPd9_6 },
# Line 1453 | Line 2375 | static struct dis386 float_reg[][8] = {
2375    },
2376    /* da */
2377    {
2378 <    { "fcmovb", ST, STi },
2379 <    { "fcmove", ST, STi },
2380 <    { "fcmovbe",ST, STi },
2381 <    { "fcmovu", ST, STi },
2382 <    { "(bad)" },
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)" },
2385 <    { "(bad)" },
2384 >    { "(bad)",  XX, XX, XX },
2385 >    { "(bad)",  XX, XX, XX },
2386    },
2387    /* db */
2388    {
2389 <    { "fcmovnb",ST, STi },
2390 <    { "fcmovne",ST, STi },
2391 <    { "fcmovnbe",ST, STi },
2392 <    { "fcmovnu",ST, STi },
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 },
2395 <    { "fcomi",  ST, STi },
2396 <    { "(bad)" },
2394 >    { "fucomi", ST, STi, XX },
2395 >    { "fcomi",  ST, STi, XX },
2396 >    { "(bad)",  XX, XX, XX },
2397    },
2398    /* dc */
2399    {
2400 <    { "fadd",   STi, ST },
2401 <    { "fmul",   STi, ST },
2402 <    { "(bad)" },
2403 <    { "(bad)" },
2404 <    { "fsub",   STi, ST },
2405 <    { "fsubr",  STi, ST },
2406 <    { "fdiv",   STi, ST },
2407 <    { "fdivr",  STi, ST },
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 },
2419 <    { "(bad)" },
2420 <    { "fst",    STi },
2421 <    { "fstp",   STi },
2422 <    { "fucom",  STi },
2423 <    { "fucomp", STi },
2424 <    { "(bad)" },
2425 <    { "(bad)" },
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 },
2430 <    { "fmulp",  STi, ST },
2431 <    { "(bad)" },
2429 >    { "faddp",  STi, ST, XX },
2430 >    { "fmulp",  STi, ST, XX },
2431 >    { "(bad)",  XX, XX, XX },
2432      { FGRPde_3 },
2433 <    { "fsubp",  STi, ST },
2434 <    { "fsubrp", STi, ST },
2435 <    { "fdivp",  STi, ST },
2436 <    { "fdivrp", STi, ST },
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 <    { "(bad)" },
2448 <    { "(bad)" },
2449 <    { "(bad)" },
2450 <    { "(bad)" },
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 },
2453 <    { "fcomip", ST, STi },
2454 <    { "(bad)" },
2452 >    { "fucomip",ST, STi, XX },
2453 >    { "fcomip", ST, STi, XX },
2454 >    { "(bad)",  XX, XX, XX },
2455    },
2456   };
2457  
1522
2458   static char *fgrps[][8] = {
2459    /* d9_2  0 */
2460    {
# Line 1569 | Line 2504 | static char *fgrps[][8] = {
2504   };
2505  
2506   static void
2507 < dofloat (aflag, dflag)
2508 <     int aflag;
1574 <     int dflag;
2507 > dofloat (sizeflag)
2508 >     int sizeflag;
2509   {
2510 <  struct dis386 *dp;
2510 >  const struct dis386 *dp;
2511    unsigned char floatop;
2512 <  
2512 >
2513    floatop = codep[-1];
2514 <  
2514 >
2515    if (mod != 3)
2516      {
2517 <      putop (float_mem[(floatop - 0xd8) * 8 + reg], aflag, dflag);
2517 >      putop (float_mem[(floatop - 0xd8) * 8 + reg], sizeflag);
2518        obufp = op1out;
2519 <      OP_E (v_mode, aflag, dflag);
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 <  
2530 >
2531    dp = &float_reg[floatop - 0xd8][reg];
2532    if (dp->name == NULL)
2533      {
2534 <      putop (fgrps[dp->bytemode1][rm], aflag, dflag);
2535 <      /* instruction fnstsw is only one with strange arg */
2536 <      if (floatop == 0xdf
2537 <          && FETCH_DATA (the_info, codep + 1)
2538 <          && *codep == 0xe0)
1598 <        strcpy (op1out, "eax");
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, aflag, dflag);
2542 >      putop (dp->name, sizeflag);
2543 >
2544        obufp = op1out;
2545        if (dp->op1)
2546 <        (*dp->op1)(dp->bytemode1, aflag, dflag);
2546 >        (*dp->op1) (dp->bytemode1, sizeflag);
2547        obufp = op2out;
2548        if (dp->op2)
2549 <        (*dp->op2)(dp->bytemode2, aflag, dflag);
2549 >        (*dp->op2) (dp->bytemode2, sizeflag);
2550      }
2551   }
2552  
2553 < /* ARGSUSED */
2554 < static int
2555 < OP_ST (ignore, aflag, dflag)
2556 <     int ignore;
1616 <     int aflag;
1617 <     int dflag;
2553 > static void
2554 > OP_ST (bytemode, sizeflag)
2555 >     int bytemode ATTRIBUTE_UNUSED;
2556 >     int sizeflag ATTRIBUTE_UNUSED;
2557   {
2558 <  oappend ("st");
1620 <  return (0);
2558 >  oappend ("%st");
2559   }
2560  
2561 < /* ARGSUSED */
2562 < static int
2563 < OP_STi (ignore, aflag, dflag)
2564 <     int ignore;
1627 <     int aflag;
1628 <     int dflag;
2561 > static void
2562 > OP_STi (bytemode, sizeflag)
2563 >     int bytemode ATTRIBUTE_UNUSED;
2564 >     int sizeflag ATTRIBUTE_UNUSED;
2565   {
2566 <  sprintf (scratchbuf, "st(%d)", rm);
2567 <  oappend (scratchbuf);
1632 <  return (0);
2566 >  sprintf (scratchbuf, "%%st(%d)", rm);
2567 >  oappend (scratchbuf + intel_syntax);
2568   }
2569  
2570 <
2571 < /* capital letters in template are macros */
2572 < static void
2573 < putop (template, aflag, dflag)
2574 <     char *template;
1640 <     int aflag;
1641 <     int dflag;
2570 > /* Capital letters in template are macros.  */
2571 > static int
2572 > putop (template, sizeflag)
2573 >     const char *template;
2574 >     int sizeflag;
2575   {
2576 <  char *p;
2577 <  
2576 >  const char *p;
2577 >  int alt;
2578 >
2579    for (p = template; *p; p++)
2580      {
2581        switch (*p)
# Line 1649 | Line 2583 | putop (template, aflag, dflag)
2583          default:
2584            *obufp++ = *p;
2585            break;
2586 <        case 'C':               /* For jcxz/jecxz */
2587 <          if (aflag)
2588 <            *obufp++ = 'e';
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 <          /* operand size flag */
2779 <          if (dflag)
2780 <            *obufp++ = 'l';
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++ = 'w';
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 <          if (dflag)
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  
2846   static void
2847   oappend (s)
2848 <     char *s;
2848 >     const char *s;
2849   {
2850    strcpy (obufp, s);
2851    obufp += strlen (s);
1685  *obufp = 0;
2852   }
2853  
2854   static void
2855 < append_prefix ()
2855 > append_seg ()
2856   {
2857    if (prefixes & PREFIX_CS)
2858 <    oappend ("cs:");
2858 >    {
2859 >      used_prefixes |= PREFIX_CS;
2860 >      oappend ("%cs:" + intel_syntax);
2861 >    }
2862    if (prefixes & PREFIX_DS)
2863 <    oappend ("ds:");
2863 >    {
2864 >      used_prefixes |= PREFIX_DS;
2865 >      oappend ("%ds:" + intel_syntax);
2866 >    }
2867    if (prefixes & PREFIX_SS)
2868 <    oappend ("ss:");
2868 >    {
2869 >      used_prefixes |= PREFIX_SS;
2870 >      oappend ("%ss:" + intel_syntax);
2871 >    }
2872    if (prefixes & PREFIX_ES)
2873 <    oappend ("es:");
2873 >    {
2874 >      used_prefixes |= PREFIX_ES;
2875 >      oappend ("%es:" + intel_syntax);
2876 >    }
2877    if (prefixes & PREFIX_FS)
2878 <    oappend ("fs:");
2878 >    {
2879 >      used_prefixes |= PREFIX_FS;
2880 >      oappend ("%fs:" + intel_syntax);
2881 >    }
2882    if (prefixes & PREFIX_GS)
2883 <    oappend ("gs:");
2883 >    {
2884 >      used_prefixes |= PREFIX_GS;
2885 >      oappend ("%gs:" + intel_syntax);
2886 >    }
2887   }
2888  
2889 < static int
2890 < OP_indirE (bytemode, aflag, dflag)
2889 > static void
2890 > OP_indirE (bytemode, sizeflag)
2891       int bytemode;
2892 <     int aflag;
1709 <     int dflag;
2892 >     int sizeflag;
2893   {
2894 <  oappend ("*");
2895 <  return OP_E (bytemode, aflag, dflag);
2894 >  if (!intel_syntax)
2895 >    oappend ("*");
2896 >  OP_E (bytemode, sizeflag);
2897   }
2898  
2899 < static int
2900 < OP_E (bytemode, aflag, dflag)
2899 > static void
2900 > print_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 >
2959 > static void
2960 > OP_E (bytemode, sizeflag)
2961       int bytemode;
2962 <     int aflag;
1719 <     int dflag;
2962 >     int sizeflag;
2963   {
2964 <  int disp;
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 */
2971 >  /* Skip mod/rm byte.  */
2972 >  MODRM_CHECK;
2973    codep++;
2974  
2975    if (mod == 3)
# Line 1728 | Line 2977 | OP_E (bytemode, aflag, dflag)
2977        switch (bytemode)
2978          {
2979          case b_mode:
2980 <          oappend (names8[rm]);
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]);
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 <          if (dflag)
3003 <            oappend (names32[rm]);
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]);
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 ("<bad dis table>");
3018 >          oappend (INTERNAL_DISASSEMBLER_ERROR);
3019            break;
3020          }
3021 <      return 0;
3021 >      return;
3022      }
3023  
3024    disp = 0;
3025 <  append_prefix ();
3025 >  append_seg ();
3026  
3027 <  if (aflag) /* 32 bit address mode */
3027 >  if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
3028      {
3029        int havesib;
3030        int havebase;
# Line 1768 | Line 3043 | OP_E (bytemode, aflag, dflag)
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 == 5)
3058 >          if ((base & 7) == 5)
3059              {
3060                havebase = 0;
3061 <              disp = get32 ();
3061 >              if (mode_64bit && !havesib && (sizeflag & AFLAG))
3062 >                riprel = 1;
3063 >              disp = get32s ();
3064              }
3065            break;
3066          case 1:
# Line 1787 | Line 3070 | OP_E (bytemode, aflag, dflag)
3070              disp -= 0x100;
3071            break;
3072          case 2:
3073 <          disp = get32 ();
3073 >          disp = get32s ();
3074            break;
3075          }
3076  
3077 <      if (mod != 0 || base == 5)
3078 <        {
3079 <          sprintf (scratchbuf, "$%08x", disp);
3080 <          oappend (scratchbuf);
3081 <        }
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 <          oappend ("(");
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 (names32[base]);
3128 >            oappend (mode_64bit && (sizeflag & AFLAG)
3129 >                     ? names64[base] : names32[base]);
3130            if (havesib)
3131              {
3132                if (index != 4)
3133                  {
3134 <                  sprintf (scratchbuf, ",%s", names32[index]);
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 <              sprintf (scratchbuf, "*%d", 1 << scale);
3152 <              oappend (scratchbuf);
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 <          oappend (")");
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 == 6)
3205 >          if ((rm & 7) == 6)
3206              {
3207                disp = get16 ();
3208                if ((disp & 0x8000) != 0)
# Line 1840 | Line 3222 | OP_E (bytemode, aflag, dflag)
3222            break;
3223          }
3224  
3225 <      if (mod != 0 || rm == 6)
3226 <        {
3227 <          sprintf (scratchbuf, "$%04x", disp);
3228 <          oappend (scratchbuf);
3229 <        }
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 != 6)
3232 >      if (mod != 0 || (rm & 7) != 6)
3233          {
3234 <          oappend ("(");
3235 <          oappend (index16[rm]);
3236 <          oappend (")");
3234 >          *obufp++ = open_char;
3235 >          *obufp = '\0';
3236 >          oappend (index16[rm + add]);
3237 >          *obufp++ = close_char;
3238 >          *obufp = '\0';
3239          }
3240      }
1856  return 0;
3241   }
3242  
3243 < static int
3244 < OP_G (bytemode, aflag, dflag)
3243 > static void
3244 > OP_G (bytemode, sizeflag)
3245       int bytemode;
3246 <     int aflag;
1863 <     int dflag;
3246 >     int sizeflag;
3247   {
3248 <  switch (bytemode)
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 <      oappend (names8[reg]);
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]);
3262 >      oappend (names16[reg + add]);
3263        break;
3264      case d_mode:
3265 <      oappend (names32[reg]);
3265 >      oappend (names32[reg + add]);
3266 >      break;
3267 >    case q_mode:
3268 >      oappend (names64[reg + add]);
3269        break;
3270      case v_mode:
3271 <      if (dflag)
3272 <        oappend (names32[reg]);
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]);
3277 >        oappend (names16[reg + add]);
3278 >      used_prefixes |= (prefixes & PREFIX_DATA);
3279        break;
3280      default:
3281 <      oappend ("<internal disassembler error>");
3281 >      oappend (INTERNAL_DISASSEMBLER_ERROR);
3282        break;
3283      }
1886  return (0);
3284   }
3285  
3286 < static int
3286 > static bfd_vma
3287 > get64 ()
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 >
3311 > static bfd_signed_vma
3312   get32 ()
3313   {
3314 <  int x = 0;
3314 >  bfd_signed_vma x = 0;
3315  
3316    FETCH_DATA (the_info, codep + 4);
3317 <  x = *codep++ & 0xff;
3318 <  x |= (*codep++ & 0xff) << 8;
3319 <  x |= (*codep++ & 0xff) << 16;
3320 <  x |= (*codep++ & 0xff) << 24;
3321 <  return (x);
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 >
3324 > static bfd_signed_vma
3325 > get32s ()
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  
3340   static int
# Line 1907 | Line 3345 | get16 ()
3345    FETCH_DATA (the_info, codep + 2);
3346    x = *codep++ & 0xff;
3347    x |= (*codep++ & 0xff) << 8;
3348 <  return (x);
3348 >  return x;
3349   }
3350  
3351   static void
3352 < set_op (op)
3353 <     int op;
3352 > set_op (op, riprel)
3353 >     bfd_vma op;
3354 >     int riprel;
3355   {
3356    op_index[op_ad] = op_ad;
3357 <  op_address[op_ad] = op;
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  
3370 < static int
3371 < OP_REG (code, aflag, dflag)
3370 > static void
3371 > OP_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 >
3432 > static void
3433 > OP_IMREG (code, sizeflag)
3434       int code;
3435 <     int aflag;
1925 <     int dflag;
3435 >     int sizeflag;
3436   {
3437 <  char *s;
3438 <  
3439 <  switch (code)
3440 <    {
3441 <    case indir_dx_reg: s = "(dx)"; break;
3442 <        case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3443 <        case sp_reg: case bp_reg: case si_reg: case di_reg:
3444 <                s = names16[code - ax_reg];
3445 <                break;
3446 <        case es_reg: case ss_reg: case cs_reg:
3447 <        case ds_reg: case fs_reg: case gs_reg:
3448 <                s = names_seg[code - es_reg];
3449 <                break;
3450 <        case al_reg: case ah_reg: case cl_reg: case ch_reg:
3451 <        case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3452 <                s = names8[code - al_reg];
3453 <                break;
3454 <        case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3455 <        case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3456 <      if (dflag)
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>";
3475 >      s = INTERNAL_DISASSEMBLER_ERROR;
3476        break;
3477      }
3478    oappend (s);
1956  return (0);
3479   }
3480  
3481 < static int
3482 < OP_I (bytemode, aflag, dflag)
3481 > static void
3482 > OP_I (bytemode, sizeflag)
3483       int bytemode;
3484 <     int aflag;
1963 <     int dflag;
3484 >     int sizeflag;
3485   {
3486 <  int op;
3487 <  
3488 <  switch (bytemode)
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++ & 0xff;
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 <      if (dflag)
3505 <        op = get32 ();
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 <        op = get16 ();
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 (0);
3524 >      oappend (INTERNAL_DISASSEMBLER_ERROR);
3525 >      return;
3526      }
3527 <  sprintf (scratchbuf, "#$%08x", op);
3528 <  oappend (scratchbuf);
3529 <  return (0);
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  
3535 < static int
3536 < OP_sI (bytemode, aflag, dflag)
3535 > static void
3536 > OP_I64 (bytemode, sizeflag)
3537       int bytemode;
3538 <     int aflag;
1995 <     int dflag;
3538 >     int sizeflag;
3539   {
3540 <  int op;
3541 <  
3542 <  switch (bytemode)
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 >
3588 > static void
3589 > OP_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 <      if (dflag)
3607 <        op = get32 ();
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 <          op = get16();
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 (0);
3630 >      oappend (INTERNAL_DISASSEMBLER_ERROR);
3631 >      return;
3632      }
3633 <  sprintf (scratchbuf, "#$%08x", op);
3634 <  oappend (scratchbuf);
3635 <  return (0);
3633 >
3634 >  scratchbuf[0] = '$';
3635 >  print_operand_value (scratchbuf + 1, 1, op);
3636 >  oappend (scratchbuf + intel_syntax);
3637   }
3638  
3639 < static int
3640 < OP_J (bytemode, aflag, dflag)
3639 > static void
3640 > OP_J (bytemode, sizeflag)
3641       int bytemode;
3642 <     int aflag;
2035 <     int dflag;
3642 >     int sizeflag;
3643   {
3644 <  int disp;
3645 <  int mask = -1;
3646 <  
3647 <  switch (bytemode)
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);
# Line 2046 | Line 3653 | OP_J (bytemode, aflag, dflag)
3653          disp -= 0x100;
3654        break;
3655      case v_mode:
3656 <      if (dflag)
3657 <        disp = get32 ();
3656 >      if (sizeflag & DFLAG)
3657 >        disp = get32s ();
3658        else
3659          {
3660            disp = get16 ();
3661 <          if ((disp & 0x8000) != 0)
2055 <            disp -= 0x10000;
2056 <          /* for some reason, a data16 prefix on a jump instruction
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 (0);
3668 >      oappend (INTERNAL_DISASSEMBLER_ERROR);
3669 >      return;
3670      }
3671    disp = (start_pc + codep - start_codep + disp) & mask;
3672 <  set_op (disp);
3673 <  sprintf (scratchbuf, "$%08x", disp);
3672 >  set_op (disp, 0);
3673 >  print_operand_value (scratchbuf, 1, disp);
3674    oappend (scratchbuf);
2070  return (0);
3675   }
3676  
3677 < /* ARGSUSED */
3678 < static int
3679 < OP_SEG (dummy, aflag, dflag)
3680 <     int dummy;
3681 <     int aflag;
3682 <     int dflag;
2079 < {
2080 <  static char *sreg[] = {
2081 <    "es","cs","ss","ds","fs","gs","?","?",
2082 <  };
2083 <
2084 <  oappend (sreg[reg]);
2085 <  return (0);
3677 > static void
3678 > OP_SEG (dummy, sizeflag)
3679 >     int dummy ATTRIBUTE_UNUSED;
3680 >     int sizeflag ATTRIBUTE_UNUSED;
3681 > {
3682 >  oappend (names_seg[reg]);
3683   }
3684  
3685 < static int
3686 < OP_DIR (size, aflag, dflag)
3687 <     int size;
3688 <     int aflag;
2092 <     int dflag;
3685 > static void
3686 > OP_DIR (dummy, sizeflag)
3687 >     int dummy ATTRIBUTE_UNUSED;
3688 >     int sizeflag;
3689   {
3690    int seg, offset;
3691 <  
3692 <  switch (size)
3691 >
3692 >  if (sizeflag & DFLAG)
3693      {
3694 <    case lptr:
3695 <      if (aflag)
3696 <        {
3697 <          offset = get32 ();
3698 <          seg = get16 ();
3699 <        }
3700 <      else
2105 <        {
2106 <          offset = get16 ();
2107 <          seg = get16 ();
2108 <        }
2109 <      sprintf (scratchbuf, "$%04x,$%08x", seg, offset);
2110 <      oappend (scratchbuf);
2111 <      break;
2112 <    case v_mode:
2113 <      if (aflag)
2114 <        offset = get32 ();
2115 <      else
2116 <        {
2117 <          offset = get16 ();
2118 <          if ((offset & 0x8000) != 0)
2119 <            offset -= 0x10000;
2120 <        }
2121 <      
2122 <      offset = start_pc + codep - start_codep + offset;
2123 <      set_op (offset);
2124 <      sprintf (scratchbuf, "$%08x", offset);
2125 <      oappend (scratchbuf);
2126 <      break;
2127 <    default:
2128 <      oappend ("<internal disassembler error>");
2129 <      break;
3694 >      offset = get32 ();
3695 >      seg = get16 ();
3696 >    }
3697 >  else
3698 >    {
3699 >      offset = get16 ();
3700 >      seg = get16 ();
3701      }
3702 <  return (0);
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  
3710 < /* ARGSUSED */
3711 < static int
3712 < OP_OFF (bytemode, aflag, dflag)
3713 <     int bytemode;
2138 <     int aflag;
2139 <     int dflag;
3710 > static void
3711 > OP_OFF (bytemode, sizeflag)
3712 >     int bytemode ATTRIBUTE_UNUSED;
3713 >     int sizeflag;
3714   {
3715 <  int off;
3715 >  bfd_vma off;
3716  
3717 <  append_prefix ();
3717 >  append_seg ();
3718  
3719 <  if (aflag)
3719 >  if ((sizeflag & AFLAG) || mode_64bit)
3720      off = get32 ();
3721    else
3722      off = get16 ();
3723 <  
3724 <  sprintf (scratchbuf, "$%08x", off);
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);
2152  return (0);
3735   }
3736  
3737 < /* ARGSUSED */
3738 < static int
3739 < OP_ESDI (dummy, aflag, dflag)
3740 <     int dummy;
3741 <     int aflag;
3742 <     int dflag;
3743 < {
3744 <  oappend ("es:(");
3745 <  oappend (aflag ? "edi" : "di");
3746 <  oappend (")");
3747 <  return (0);
3737 > static void
3738 > OP_OFF64 (bytemode, sizeflag)
3739 >     int bytemode ATTRIBUTE_UNUSED;
3740 >     int sizeflag ATTRIBUTE_UNUSED;
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  
3767 < /* ARGSUSED */
3768 < static int
3769 < OP_DSSI (dummy, aflag, dflag)
3770 <     int dummy;
3771 <     int aflag;
3772 <     int dflag;
3767 > static void
3768 > ptr_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 >
3797 > static void
3798 > OP_ESreg (code, sizeflag)
3799 >     int code;
3800 >     int sizeflag;
3801 > {
3802 >  oappend ("%es:" + intel_syntax);
3803 >  ptr_reg (code, sizeflag);
3804 > }
3805 >
3806 > static void
3807 > OP_DSreg (code, sizeflag)
3808 >     int code;
3809 >     int sizeflag;
3810   {
3811    if ((prefixes
3812         & (PREFIX_CS
# Line 2180 | Line 3816 | OP_DSSI (dummy, aflag, dflag)
3816            | PREFIX_FS
3817            | PREFIX_GS)) == 0)
3818      prefixes |= PREFIX_DS;
3819 <  append_prefix ();
3820 <  oappend ("(");
2185 <  oappend (aflag ? "esi" : "si");
2186 <  oappend (")");
2187 <  return (0);
3819 >  append_seg ();
3820 >  ptr_reg (code, sizeflag);
3821   }
3822  
3823 < #if 0
3824 < /* Not used.  */
3823 > static void
3824 > OP_C (dummy, sizeflag)
3825 >     int dummy ATTRIBUTE_UNUSED;
3826 >     int sizeflag ATTRIBUTE_UNUSED;
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  
3836 < /* ARGSUSED */
3837 < static int
3838 < OP_ONE (dummy, aflag, dflag)
3839 <     int dummy;
2197 <     int aflag;
2198 <     int dflag;
3836 > static void
3837 > OP_D (dummy, sizeflag)
3838 >     int dummy ATTRIBUTE_UNUSED;
3839 >     int sizeflag ATTRIBUTE_UNUSED;
3840   {
3841 <  oappend ("1");
3842 <  return (0);
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  
3852 < #endif
3852 > static void
3853 > OP_T (dummy, sizeflag)
3854 >     int dummy ATTRIBUTE_UNUSED;
3855 >     int sizeflag ATTRIBUTE_UNUSED;
3856 > {
3857 >  sprintf (scratchbuf, "%%tr%d", reg);
3858 >  oappend (scratchbuf + intel_syntax);
3859 > }
3860  
3861 < /* ARGSUSED */
3862 < static int
3863 < OP_C (dummy, aflag, dflag)
3864 <     int dummy;
2210 <     int aflag;
2211 <     int dflag;
3861 > static void
3862 > OP_Rd (bytemode, sizeflag)
3863 >     int bytemode;
3864 >     int sizeflag;
3865   {
3866 <  codep++; /* skip mod/rm */
3867 <  sprintf (scratchbuf, "cr%d", reg);
3868 <  oappend (scratchbuf);
3869 <  return (0);
3866 >  if (mod == 3)
3867 >    OP_E (bytemode, sizeflag);
3868 >  else
3869 >    BadOp ();
3870   }
3871  
3872 < /* ARGSUSED */
3873 < static int
3874 < OP_D (dummy, aflag, dflag)
3875 <     int dummy;
2223 <     int aflag;
2224 <     int dflag;
3872 > static void
3873 > OP_MMX (bytemode, sizeflag)
3874 >     int bytemode ATTRIBUTE_UNUSED;
3875 >     int sizeflag ATTRIBUTE_UNUSED;
3876   {
3877 <  codep++; /* skip mod/rm */
3878 <  sprintf (scratchbuf, "dr%d", reg);
3879 <  oappend (scratchbuf);
3880 <  return (0);
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  
3889 < /* ARGSUSED */
3890 < static int
3891 < OP_T (dummy, aflag, dflag)
3892 <     int dummy;
2236 <     int aflag;
2237 <     int dflag;
3889 > static void
3890 > OP_XMM (bytemode, sizeflag)
3891 >     int bytemode ATTRIBUTE_UNUSED;
3892 >     int sizeflag ATTRIBUTE_UNUSED;
3893   {
3894 <  codep++; /* skip mod/rm */
3895 <  sprintf (scratchbuf, "tr%d", reg);
3896 <  oappend (scratchbuf);
3897 <  return (0);
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  
3902 < static int
3903 < OP_rm (bytemode, aflag, dflag)
3902 > static void
3903 > OP_EM (bytemode, sizeflag)
3904       int bytemode;
3905 <     int aflag;
2249 <     int dflag;
3905 >     int sizeflag;
3906   {
3907 <  switch (bytemode)
3907 >  int add = 0;
3908 >  if (mod != 3)
3909      {
3910 <    case d_mode:
3911 <      oappend (names32[rm]);
2255 <      break;
2256 <    case w_mode:
2257 <      oappend (names16[rm]);
2258 <      break;
3910 >      OP_E (bytemode, sizeflag);
3911 >      return;
3912      }
3913 <  return (0);
3914 < }
3913 >  USED_REX (REX_EXTZ);
3914 >  if (rex & REX_EXTZ)
3915 >    add = 8;
3916  
3917 < static int
3918 < OP_MMX (bytemode, aflag, dflag)
3919 <     int bytemode;
3920 <     int aflag;
3921 <     int dflag;
3922 < {
3923 <  sprintf (scratchbuf, "mm%d", reg);
3924 <  oappend (scratchbuf);
3925 <  return 0;
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  
3928 < static int
3929 < OP_EM (bytemode, aflag, dflag)
3928 > static void
3929 > OP_EX (bytemode, sizeflag)
3930       int bytemode;
3931 <     int aflag;
2278 <     int dflag;
3931 >     int sizeflag;
3932   {
3933 +  int add = 0;
3934    if (mod != 3)
3935 <    return OP_E (bytemode, aflag, dflag);
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, "mm%d", rm);
3947 <  oappend (scratchbuf);
2286 <  return 0;
3946 >  sprintf (scratchbuf, "%%xmm%d", rm + add);
3947 >  oappend (scratchbuf + intel_syntax);
3948   }
3949  
3950 < static int
3951 < OP_MS (bytemode, aflag, dflag)
3950 > static void
3951 > OP_MS (bytemode, sizeflag)
3952       int bytemode;
3953 <     int aflag;
2293 <     int dflag;
3953 >     int sizeflag;
3954   {
3955 <  ++codep;
3956 <  sprintf (scratchbuf, "mm%d", rm);
3957 <  oappend (scratchbuf);
3958 <  return 0;
3955 >  if (mod == 3)
3956 >    OP_EM (bytemode, sizeflag);
3957 >  else
3958 >    BadOp ();
3959 > }
3960 >
3961 > static void
3962 > OP_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 >
3972 > static 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 >
4039 > static void
4040 > OP_3DNowSuffix (bytemode, sizeflag)
4041 >     int bytemode ATTRIBUTE_UNUSED;
4042 >     int sizeflag ATTRIBUTE_UNUSED;
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 >
4066 > static const char *simd_cmp_op[] = {
4067 >  "eq",
4068 >  "lt",
4069 >  "le",
4070 >  "unord",
4071 >  "neq",
4072 >  "nlt",
4073 >  "nle",
4074 >  "ord"
4075 > };
4076 >
4077 > static void
4078 > OP_SIMD_Suffix (bytemode, sizeflag)
4079 >     int bytemode ATTRIBUTE_UNUSED;
4080 >     int sizeflag ATTRIBUTE_UNUSED;
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 >
4119 > static void
4120 > SIMD_Fixup (extrachar, sizeflag)
4121 >     int extrachar;
4122 >     int sizeflag ATTRIBUTE_UNUSED;
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 >
4137 > static void
4138 > BadOp (void)
4139 > {
4140 >  /* Throw away prefixes and 1st. opcode byte.  */
4141 >  codep = insn_codep + 1;
4142 >  oappend ("(bad)");
4143   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines