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