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