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