ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/disass/i386-dis.c
Revision: 1.3
Committed: 2003-02-06T10:20:49Z (21 years, 6 months ago) by gbeauche
Content type: text/plain
Branch: MAIN
CVS Tags: release_3-1, release_3-2
Changes since 1.2: +7 -4 lines
Log Message:
Fix disassembly of x86-64 movd with REX prefixes

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