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