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