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