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