ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/disass/i386-dis.c
Revision: 1.4
Committed: 2008-01-01T14:58:01Z (16 years, 11 months ago) by gbeauche
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +3089 -1448 lines
Log Message:
Merge with GNU x86 disassembler as part of binutils 2.17.50.0.9 which brings
everything up to SSSE3 support.

File Contents

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