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