source: vendor/binutils/current/opcodes/i386-dis.c

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

binutils v2.14 - offical sources.

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