source: trunk/src/binutils/opcodes/i386-dis.c@ 10

Last change on this file since 10 was 10, checked in by bird, 22 years ago

Initial revision

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