Standardize comment headers. Patch by Trevor McCort
[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)
3309 ? names64[index] : names32[index]);
3310 }
3311 else
3312 sprintf (scratchbuf, ",%s",
3313 mode_64bit && (sizeflag & AFLAG)
3314 ? names64[index] : names32[index]);
3315 oappend (scratchbuf);
3316 }
3317 if (!intel_syntax
3318 || (intel_syntax
3319 && bytemode != b_mode
3320 && bytemode != w_mode
3321 && bytemode != v_mode))
3322 {
3323 *obufp++ = scale_char;
3324 *obufp = '\0';
3325 sprintf (scratchbuf, "%d", 1 << scale);
3326 oappend (scratchbuf);
3327 }
3328 }
3329 if (intel_syntax)
3330 if (mod != 0 || (base & 7) == 5)
3331 {
3332 /* Don't print zero displacements. */
3333 if (disp != 0)
3334 {
3335 if ((bfd_signed_vma) disp > 0)
3336 {
3337 *obufp++ = '+';
3338 *obufp = '\0';
3339 }
3340
3341 print_operand_value (scratchbuf, 0, disp);
3342 oappend (scratchbuf);
3343 }
3344 }
3345
3346 *obufp++ = close_char;
3347 *obufp = '\0';
3348 }
3349 else if (intel_syntax)
3350 {
3351 if (mod != 0 || (base & 7) == 5)
3352 {
3353 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3354 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
3355 ;
3356 else
3357 {
3358 oappend (names_seg[ds_reg - es_reg]);
3359 oappend (":");
3360 }
3361 print_operand_value (scratchbuf, 1, disp);
3362 oappend (scratchbuf);
3363 }
3364 }
3365 }
3366 else
3367 { /* 16 bit address mode */
3368 switch (mod)
3369 {
3370 case 0:
3371 if ((rm & 7) == 6)
3372 {
3373 disp = get16 ();
3374 if ((disp & 0x8000) != 0)
3375 disp -= 0x10000;
3376 }
3377 break;
3378 case 1:
3379 FETCH_DATA (the_info, codep + 1);
3380 disp = *codep++;
3381 if ((disp & 0x80) != 0)
3382 disp -= 0x100;
3383 break;
3384 case 2:
3385 disp = get16 ();
3386 if ((disp & 0x8000) != 0)
3387 disp -= 0x10000;
3388 break;
3389 }
3390
3391 if (!intel_syntax)
3392 if (mod != 0 || (rm & 7) == 6)
3393 {
3394 print_operand_value (scratchbuf, 0, disp);
3395 oappend (scratchbuf);
3396 }
3397
3398 if (mod != 0 || (rm & 7) != 6)
3399 {
3400 *obufp++ = open_char;
3401 *obufp = '\0';
3402 oappend (index16[rm + add]);
3403 *obufp++ = close_char;
3404 *obufp = '\0';
3405 }
3406 }
3407 }
3408
3409 static void
3410 OP_G (bytemode, sizeflag)
3411 int bytemode;
3412 int sizeflag;
3413 {
3414 int add = 0;
3415 USED_REX (REX_EXTX);
3416 if (rex & REX_EXTX)
3417 add += 8;
3418 switch (bytemode)
3419 {
3420 case b_mode:
3421 USED_REX (0);
3422 if (rex)
3423 oappend (names8rex[reg + add]);
3424 else
3425 oappend (names8[reg + add]);
3426 break;
3427 case w_mode:
3428 oappend (names16[reg + add]);
3429 break;
3430 case d_mode:
3431 oappend (names32[reg + add]);
3432 break;
3433 case q_mode:
3434 oappend (names64[reg + add]);
3435 break;
3436 case v_mode:
3437 USED_REX (REX_MODE64);
3438 if (rex & REX_MODE64)
3439 oappend (names64[reg + add]);
3440 else if (sizeflag & DFLAG)
3441 oappend (names32[reg + add]);
3442 else
3443 oappend (names16[reg + add]);
3444 used_prefixes |= (prefixes & PREFIX_DATA);
3445 break;
3446 default:
3447 oappend (INTERNAL_DISASSEMBLER_ERROR);
3448 break;
3449 }
3450 }
3451
3452 static bfd_vma
3453 get64 ()
3454 {
3455 bfd_vma x;
3456 #ifdef BFD64
3457 unsigned int a;
3458 unsigned int b;
3459
3460 FETCH_DATA (the_info, codep + 8);
3461 a = *codep++ & 0xff;
3462 a |= (*codep++ & 0xff) << 8;
3463 a |= (*codep++ & 0xff) << 16;
3464 a |= (*codep++ & 0xff) << 24;
3465 b = *codep++ & 0xff;
3466 b |= (*codep++ & 0xff) << 8;
3467 b |= (*codep++ & 0xff) << 16;
3468 b |= (*codep++ & 0xff) << 24;
3469 x = a + ((bfd_vma) b << 32);
3470 #else
3471 abort ();
3472 x = 0;
3473 #endif
3474 return x;
3475 }
3476
3477 static bfd_signed_vma
3478 get32 ()
3479 {
3480 bfd_signed_vma x = 0;
3481
3482 FETCH_DATA (the_info, codep + 4);
3483 x = *codep++ & (bfd_signed_vma) 0xff;
3484 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3485 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3486 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3487 return x;
3488 }
3489
3490 static bfd_signed_vma
3491 get32s ()
3492 {
3493 bfd_signed_vma x = 0;
3494
3495 FETCH_DATA (the_info, codep + 4);
3496 x = *codep++ & (bfd_signed_vma) 0xff;
3497 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3498 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3499 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3500
3501 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
3502
3503 return x;
3504 }
3505
3506 static int
3507 get16 ()
3508 {
3509 int x = 0;
3510
3511 FETCH_DATA (the_info, codep + 2);
3512 x = *codep++ & 0xff;
3513 x |= (*codep++ & 0xff) << 8;
3514 return x;
3515 }
3516
3517 static void
3518 set_op (op, riprel)
3519 bfd_vma op;
3520 int riprel;
3521 {
3522 op_index[op_ad] = op_ad;
3523 if (mode_64bit)
3524 {
3525 op_address[op_ad] = op;
3526 op_riprel[op_ad] = riprel;
3527 }
3528 else
3529 {
3530 /* Mask to get a 32-bit address. */
3531 op_address[op_ad] = op & 0xffffffff;
3532 op_riprel[op_ad] = riprel & 0xffffffff;
3533 }
3534 }
3535
3536 static void
3537 OP_REG (code, sizeflag)
3538 int code;
3539 int sizeflag;
3540 {
3541 const char *s;
3542 int add = 0;
3543 USED_REX (REX_EXTZ);
3544 if (rex & REX_EXTZ)
3545 add = 8;
3546
3547 switch (code)
3548 {
3549 case indir_dx_reg:
3550 if (intel_syntax)
3551 s = "[dx]";
3552 else
3553 s = "(%dx)";
3554 break;
3555 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3556 case sp_reg: case bp_reg: case si_reg: case di_reg:
3557 s = names16[code - ax_reg + add];
3558 break;
3559 case es_reg: case ss_reg: case cs_reg:
3560 case ds_reg: case fs_reg: case gs_reg:
3561 s = names_seg[code - es_reg + add];
3562 break;
3563 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3564 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3565 USED_REX (0);
3566 if (rex)
3567 s = names8rex[code - al_reg + add];
3568 else
3569 s = names8[code - al_reg];
3570 break;
3571 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
3572 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
3573 if (mode_64bit)
3574 {
3575 s = names64[code - rAX_reg + add];
3576 break;
3577 }
3578 code += eAX_reg - rAX_reg;
3579 /* Fall through. */
3580 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3581 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3582 USED_REX (REX_MODE64);
3583 if (rex & REX_MODE64)
3584 s = names64[code - eAX_reg + add];
3585 else if (sizeflag & DFLAG)
3586 s = names32[code - eAX_reg + add];
3587 else
3588 s = names16[code - eAX_reg + add];
3589 used_prefixes |= (prefixes & PREFIX_DATA);
3590 break;
3591 default:
3592 s = INTERNAL_DISASSEMBLER_ERROR;
3593 break;
3594 }
3595 oappend (s);
3596 }
3597
3598 static void
3599 OP_IMREG (code, sizeflag)
3600 int code;
3601 int sizeflag;
3602 {
3603 const char *s;
3604
3605 switch (code)
3606 {
3607 case indir_dx_reg:
3608 if (intel_syntax)
3609 s = "[dx]";
3610 else
3611 s = "(%dx)";
3612 break;
3613 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3614 case sp_reg: case bp_reg: case si_reg: case di_reg:
3615 s = names16[code - ax_reg];
3616 break;
3617 case es_reg: case ss_reg: case cs_reg:
3618 case ds_reg: case fs_reg: case gs_reg:
3619 s = names_seg[code - es_reg];
3620 break;
3621 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3622 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3623 USED_REX (0);
3624 if (rex)
3625 s = names8rex[code - al_reg];
3626 else
3627 s = names8[code - al_reg];
3628 break;
3629 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3630 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3631 USED_REX (REX_MODE64);
3632 if (rex & REX_MODE64)
3633 s = names64[code - eAX_reg];
3634 else if (sizeflag & DFLAG)
3635 s = names32[code - eAX_reg];
3636 else
3637 s = names16[code - eAX_reg];
3638 used_prefixes |= (prefixes & PREFIX_DATA);
3639 break;
3640 default:
3641 s = INTERNAL_DISASSEMBLER_ERROR;
3642 break;
3643 }
3644 oappend (s);
3645 }
3646
3647 static void
3648 OP_I (bytemode, sizeflag)
3649 int bytemode;
3650 int sizeflag;
3651 {
3652 bfd_signed_vma op;
3653 bfd_signed_vma mask = -1;
3654
3655 switch (bytemode)
3656 {
3657 case b_mode:
3658 FETCH_DATA (the_info, codep + 1);
3659 op = *codep++;
3660 mask = 0xff;
3661 break;
3662 case q_mode:
3663 if (mode_64bit)
3664 {
3665 op = get32s ();
3666 break;
3667 }
3668 /* Fall through. */
3669 case v_mode:
3670 USED_REX (REX_MODE64);
3671 if (rex & REX_MODE64)
3672 op = get32s ();
3673 else if (sizeflag & DFLAG)
3674 {
3675 op = get32 ();
3676 mask = 0xffffffff;
3677 }
3678 else
3679 {
3680 op = get16 ();
3681 mask = 0xfffff;
3682 }
3683 used_prefixes |= (prefixes & PREFIX_DATA);
3684 break;
3685 case w_mode:
3686 mask = 0xfffff;
3687 op = get16 ();
3688 break;
3689 default:
3690 oappend (INTERNAL_DISASSEMBLER_ERROR);
3691 return;
3692 }
3693
3694 op &= mask;
3695 scratchbuf[0] = '$';
3696 print_operand_value (scratchbuf + 1, 1, op);
3697 oappend (scratchbuf + intel_syntax);
3698 scratchbuf[0] = '\0';
3699 }
3700
3701 static void
3702 OP_I64 (bytemode, sizeflag)
3703 int bytemode;
3704 int sizeflag;
3705 {
3706 bfd_signed_vma op;
3707 bfd_signed_vma mask = -1;
3708
3709 if (!mode_64bit)
3710 {
3711 OP_I (bytemode, sizeflag);
3712 return;
3713 }
3714
3715 switch (bytemode)
3716 {
3717 case b_mode:
3718 FETCH_DATA (the_info, codep + 1);
3719 op = *codep++;
3720 mask = 0xff;
3721 break;
3722 case v_mode:
3723 USED_REX (REX_MODE64);
3724 if (rex & REX_MODE64)
3725 op = get64 ();
3726 else if (sizeflag & DFLAG)
3727 {
3728 op = get32 ();
3729 mask = 0xffffffff;
3730 }
3731 else
3732 {
3733 op = get16 ();
3734 mask = 0xfffff;
3735 }
3736 used_prefixes |= (prefixes & PREFIX_DATA);
3737 break;
3738 case w_mode:
3739 mask = 0xfffff;
3740 op = get16 ();
3741 break;
3742 default:
3743 oappend (INTERNAL_DISASSEMBLER_ERROR);
3744 return;
3745 }
3746
3747 op &= mask;
3748 scratchbuf[0] = '$';
3749 print_operand_value (scratchbuf + 1, 1, op);
3750 oappend (scratchbuf + intel_syntax);
3751 scratchbuf[0] = '\0';
3752 }
3753
3754 static void
3755 OP_sI (bytemode, sizeflag)
3756 int bytemode;
3757 int sizeflag;
3758 {
3759 bfd_signed_vma op;
3760 bfd_signed_vma mask = -1;
3761
3762 switch (bytemode)
3763 {
3764 case b_mode:
3765 FETCH_DATA (the_info, codep + 1);
3766 op = *codep++;
3767 if ((op & 0x80) != 0)
3768 op -= 0x100;
3769 mask = 0xffffffff;
3770 break;
3771 case v_mode:
3772 USED_REX (REX_MODE64);
3773 if (rex & REX_MODE64)
3774 op = get32s ();
3775 else if (sizeflag & DFLAG)
3776 {
3777 op = get32s ();
3778 mask = 0xffffffff;
3779 }
3780 else
3781 {
3782 mask = 0xffffffff;
3783 op = get16 ();
3784 if ((op & 0x8000) != 0)
3785 op -= 0x10000;
3786 }
3787 used_prefixes |= (prefixes & PREFIX_DATA);
3788 break;
3789 case w_mode:
3790 op = get16 ();
3791 mask = 0xffffffff;
3792 if ((op & 0x8000) != 0)
3793 op -= 0x10000;
3794 break;
3795 default:
3796 oappend (INTERNAL_DISASSEMBLER_ERROR);
3797 return;
3798 }
3799
3800 scratchbuf[0] = '$';
3801 print_operand_value (scratchbuf + 1, 1, op);
3802 oappend (scratchbuf + intel_syntax);
3803 }
3804
3805 static void
3806 OP_J (bytemode, sizeflag)
3807 int bytemode;
3808 int sizeflag;
3809 {
3810 bfd_vma disp;
3811 bfd_vma mask = -1;
3812
3813 switch (bytemode)
3814 {
3815 case b_mode:
3816 FETCH_DATA (the_info, codep + 1);
3817 disp = *codep++;
3818 if ((disp & 0x80) != 0)
3819 disp -= 0x100;
3820 break;
3821 case v_mode:
3822 if (sizeflag & DFLAG)
3823 disp = get32s ();
3824 else
3825 {
3826 disp = get16 ();
3827 /* For some reason, a data16 prefix on a jump instruction
3828 means that the pc is masked to 16 bits after the
3829 displacement is added! */
3830 mask = 0xffff;
3831 }
3832 break;
3833 default:
3834 oappend (INTERNAL_DISASSEMBLER_ERROR);
3835 return;
3836 }
3837 disp = (start_pc + codep - start_codep + disp) & mask;
3838 set_op (disp, 0);
3839 print_operand_value (scratchbuf, 1, disp);
3840 oappend (scratchbuf);
3841 }
3842
3843 static void
3844 OP_SEG (dummy, sizeflag)
3845 int dummy ATTRIBUTE_UNUSED;
3846 int sizeflag ATTRIBUTE_UNUSED;
3847 {
3848 oappend (names_seg[reg]);
3849 }
3850
3851 static void
3852 OP_DIR (dummy, sizeflag)
3853 int dummy ATTRIBUTE_UNUSED;
3854 int sizeflag;
3855 {
3856 int seg, offset;
3857
3858 if (sizeflag & DFLAG)
3859 {
3860 offset = get32 ();
3861 seg = get16 ();
3862 }
3863 else
3864 {
3865 offset = get16 ();
3866 seg = get16 ();
3867 }
3868 used_prefixes |= (prefixes & PREFIX_DATA);
3869 if (intel_syntax)
3870 sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
3871 else
3872 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3873 oappend (scratchbuf);
3874 }
3875
3876 static void
3877 OP_OFF (bytemode, sizeflag)
3878 int bytemode ATTRIBUTE_UNUSED;
3879 int sizeflag;
3880 {
3881 bfd_vma off;
3882
3883 append_seg ();
3884
3885 if ((sizeflag & AFLAG) || mode_64bit)
3886 off = get32 ();
3887 else
3888 off = get16 ();
3889
3890 if (intel_syntax)
3891 {
3892 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3893 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3894 {
3895 oappend (names_seg[ds_reg - es_reg]);
3896 oappend (":");
3897 }
3898 }
3899 print_operand_value (scratchbuf, 1, off);
3900 oappend (scratchbuf);
3901 }
3902
3903 static void
3904 OP_OFF64 (bytemode, sizeflag)
3905 int bytemode ATTRIBUTE_UNUSED;
3906 int sizeflag ATTRIBUTE_UNUSED;
3907 {
3908 bfd_vma off;
3909
3910 if (!mode_64bit)
3911 {
3912 OP_OFF (bytemode, sizeflag);
3913 return;
3914 }
3915
3916 append_seg ();
3917
3918 off = get64 ();
3919
3920 if (intel_syntax)
3921 {
3922 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3923 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3924 {
3925 oappend (names_seg[ds_reg - es_reg]);
3926 oappend (":");
3927 }
3928 }
3929 print_operand_value (scratchbuf, 1, off);
3930 oappend (scratchbuf);
3931 }
3932
3933 static void
3934 ptr_reg (code, sizeflag)
3935 int code;
3936 int sizeflag;
3937 {
3938 const char *s;
3939 if (intel_syntax)
3940 oappend ("[");
3941 else
3942 oappend ("(");
3943
3944 USED_REX (REX_MODE64);
3945 if (rex & REX_MODE64)
3946 {
3947 if (!(sizeflag & AFLAG))
3948 s = names32[code - eAX_reg];
3949 else
3950 s = names64[code - eAX_reg];
3951 }
3952 else if (sizeflag & AFLAG)
3953 s = names32[code - eAX_reg];
3954 else
3955 s = names16[code - eAX_reg];
3956 oappend (s);
3957 if (intel_syntax)
3958 oappend ("]");
3959 else
3960 oappend (")");
3961 }
3962
3963 static void
3964 OP_ESreg (code, sizeflag)
3965 int code;
3966 int sizeflag;
3967 {
3968 oappend ("%es:" + intel_syntax);
3969 ptr_reg (code, sizeflag);
3970 }
3971
3972 static void
3973 OP_DSreg (code, sizeflag)
3974 int code;
3975 int sizeflag;
3976 {
3977 if ((prefixes
3978 & (PREFIX_CS
3979 | PREFIX_DS
3980 | PREFIX_SS
3981 | PREFIX_ES
3982 | PREFIX_FS
3983 | PREFIX_GS)) == 0)
3984 prefixes |= PREFIX_DS;
3985 append_seg ();
3986 ptr_reg (code, sizeflag);
3987 }
3988
3989 static void
3990 OP_C (dummy, sizeflag)
3991 int dummy ATTRIBUTE_UNUSED;
3992 int sizeflag ATTRIBUTE_UNUSED;
3993 {
3994 int add = 0;
3995 USED_REX (REX_EXTX);
3996 if (rex & REX_EXTX)
3997 add = 8;
3998 sprintf (scratchbuf, "%%cr%d", reg + add);
3999 oappend (scratchbuf + intel_syntax);
4000 }
4001
4002 static void
4003 OP_D (dummy, sizeflag)
4004 int dummy ATTRIBUTE_UNUSED;
4005 int sizeflag ATTRIBUTE_UNUSED;
4006 {
4007 int add = 0;
4008 USED_REX (REX_EXTX);
4009 if (rex & REX_EXTX)
4010 add = 8;
4011 if (intel_syntax)
4012 sprintf (scratchbuf, "db%d", reg + add);
4013 else
4014 sprintf (scratchbuf, "%%db%d", reg + add);
4015 oappend (scratchbuf);
4016 }
4017
4018 static void
4019 OP_T (dummy, sizeflag)
4020 int dummy ATTRIBUTE_UNUSED;
4021 int sizeflag ATTRIBUTE_UNUSED;
4022 {
4023 sprintf (scratchbuf, "%%tr%d", reg);
4024 oappend (scratchbuf + intel_syntax);
4025 }
4026
4027 static void
4028 OP_Rd (bytemode, sizeflag)
4029 int bytemode;
4030 int sizeflag;
4031 {
4032 if (mod == 3)
4033 OP_E (bytemode, sizeflag);
4034 else
4035 BadOp ();
4036 }
4037
4038 static void
4039 OP_MMX (bytemode, sizeflag)
4040 int bytemode ATTRIBUTE_UNUSED;
4041 int sizeflag ATTRIBUTE_UNUSED;
4042 {
4043 int add = 0;
4044 USED_REX (REX_EXTX);
4045 if (rex & REX_EXTX)
4046 add = 8;
4047 used_prefixes |= (prefixes & PREFIX_DATA);
4048 if (prefixes & PREFIX_DATA)
4049 sprintf (scratchbuf, "%%xmm%d", reg + add);
4050 else
4051 sprintf (scratchbuf, "%%mm%d", reg + add);
4052 oappend (scratchbuf + intel_syntax);
4053 }
4054
4055 static void
4056 OP_XMM (bytemode, sizeflag)
4057 int bytemode ATTRIBUTE_UNUSED;
4058 int sizeflag ATTRIBUTE_UNUSED;
4059 {
4060 int add = 0;
4061 USED_REX (REX_EXTX);
4062 if (rex & REX_EXTX)
4063 add = 8;
4064 sprintf (scratchbuf, "%%xmm%d", reg + add);
4065 oappend (scratchbuf + intel_syntax);
4066 }
4067
4068 static void
4069 OP_EM (bytemode, sizeflag)
4070 int bytemode;
4071 int sizeflag;
4072 {
4073 int add = 0;
4074 if (mod != 3)
4075 {
4076 OP_E (bytemode, sizeflag);
4077 return;
4078 }
4079 USED_REX (REX_EXTZ);
4080 if (rex & REX_EXTZ)
4081 add = 8;
4082
4083 /* Skip mod/rm byte. */
4084 MODRM_CHECK;
4085 codep++;
4086 used_prefixes |= (prefixes & PREFIX_DATA);
4087 if (prefixes & PREFIX_DATA)
4088 sprintf (scratchbuf, "%%xmm%d", rm + add);
4089 else
4090 sprintf (scratchbuf, "%%mm%d", rm + add);
4091 oappend (scratchbuf + intel_syntax);
4092 }
4093
4094 static void
4095 OP_EX (bytemode, sizeflag)
4096 int bytemode;
4097 int sizeflag;
4098 {
4099 int add = 0;
4100 if (mod != 3)
4101 {
4102 OP_E (bytemode, sizeflag);
4103 return;
4104 }
4105 USED_REX (REX_EXTZ);
4106 if (rex & REX_EXTZ)
4107 add = 8;
4108
4109 /* Skip mod/rm byte. */
4110 MODRM_CHECK;
4111 codep++;
4112 sprintf (scratchbuf, "%%xmm%d", rm + add);
4113 oappend (scratchbuf + intel_syntax);
4114 }
4115
4116 static void
4117 OP_MS (bytemode, sizeflag)
4118 int bytemode;
4119 int sizeflag;
4120 {
4121 if (mod == 3)
4122 OP_EM (bytemode, sizeflag);
4123 else
4124 BadOp ();
4125 }
4126
4127 static void
4128 OP_XS (bytemode, sizeflag)
4129 int bytemode;
4130 int sizeflag;
4131 {
4132 if (mod == 3)
4133 OP_EX (bytemode, sizeflag);
4134 else
4135 BadOp ();
4136 }
4137
4138 static const char *Suffix3DNow[] = {
4139 /* 00 */ NULL, NULL, NULL, NULL,
4140 /* 04 */ NULL, NULL, NULL, NULL,
4141 /* 08 */ NULL, NULL, NULL, NULL,
4142 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
4143 /* 10 */ NULL, NULL, NULL, NULL,
4144 /* 14 */ NULL, NULL, NULL, NULL,
4145 /* 18 */ NULL, NULL, NULL, NULL,
4146 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
4147 /* 20 */ NULL, NULL, NULL, NULL,
4148 /* 24 */ NULL, NULL, NULL, NULL,
4149 /* 28 */ NULL, NULL, NULL, NULL,
4150 /* 2C */ NULL, NULL, NULL, NULL,
4151 /* 30 */ NULL, NULL, NULL, NULL,
4152 /* 34 */ NULL, NULL, NULL, NULL,
4153 /* 38 */ NULL, NULL, NULL, NULL,
4154 /* 3C */ NULL, NULL, NULL, NULL,
4155 /* 40 */ NULL, NULL, NULL, NULL,
4156 /* 44 */ NULL, NULL, NULL, NULL,
4157 /* 48 */ NULL, NULL, NULL, NULL,
4158 /* 4C */ NULL, NULL, NULL, NULL,
4159 /* 50 */ NULL, NULL, NULL, NULL,
4160 /* 54 */ NULL, NULL, NULL, NULL,
4161 /* 58 */ NULL, NULL, NULL, NULL,
4162 /* 5C */ NULL, NULL, NULL, NULL,
4163 /* 60 */ NULL, NULL, NULL, NULL,
4164 /* 64 */ NULL, NULL, NULL, NULL,
4165 /* 68 */ NULL, NULL, NULL, NULL,
4166 /* 6C */ NULL, NULL, NULL, NULL,
4167 /* 70 */ NULL, NULL, NULL, NULL,
4168 /* 74 */ NULL, NULL, NULL, NULL,
4169 /* 78 */ NULL, NULL, NULL, NULL,
4170 /* 7C */ NULL, NULL, NULL, NULL,
4171 /* 80 */ NULL, NULL, NULL, NULL,
4172 /* 84 */ NULL, NULL, NULL, NULL,
4173 /* 88 */ NULL, NULL, "pfnacc", NULL,
4174 /* 8C */ NULL, NULL, "pfpnacc", NULL,
4175 /* 90 */ "pfcmpge", NULL, NULL, NULL,
4176 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
4177 /* 98 */ NULL, NULL, "pfsub", NULL,
4178 /* 9C */ NULL, NULL, "pfadd", NULL,
4179 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
4180 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
4181 /* A8 */ NULL, NULL, "pfsubr", NULL,
4182 /* AC */ NULL, NULL, "pfacc", NULL,
4183 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
4184 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
4185 /* B8 */ NULL, NULL, NULL, "pswapd",
4186 /* BC */ NULL, NULL, NULL, "pavgusb",
4187 /* C0 */ NULL, NULL, NULL, NULL,
4188 /* C4 */ NULL, NULL, NULL, NULL,
4189 /* C8 */ NULL, NULL, NULL, NULL,
4190 /* CC */ NULL, NULL, NULL, NULL,
4191 /* D0 */ NULL, NULL, NULL, NULL,
4192 /* D4 */ NULL, NULL, NULL, NULL,
4193 /* D8 */ NULL, NULL, NULL, NULL,
4194 /* DC */ NULL, NULL, NULL, NULL,
4195 /* E0 */ NULL, NULL, NULL, NULL,
4196 /* E4 */ NULL, NULL, NULL, NULL,
4197 /* E8 */ NULL, NULL, NULL, NULL,
4198 /* EC */ NULL, NULL, NULL, NULL,
4199 /* F0 */ NULL, NULL, NULL, NULL,
4200 /* F4 */ NULL, NULL, NULL, NULL,
4201 /* F8 */ NULL, NULL, NULL, NULL,
4202 /* FC */ NULL, NULL, NULL, NULL,
4203 };
4204
4205 static void
4206 OP_3DNowSuffix (bytemode, sizeflag)
4207 int bytemode ATTRIBUTE_UNUSED;
4208 int sizeflag ATTRIBUTE_UNUSED;
4209 {
4210 const char *mnemonic;
4211
4212 FETCH_DATA (the_info, codep + 1);
4213 /* AMD 3DNow! instructions are specified by an opcode suffix in the
4214 place where an 8-bit immediate would normally go. ie. the last
4215 byte of the instruction. */
4216 obufp = obuf + strlen (obuf);
4217 mnemonic = Suffix3DNow[*codep++ & 0xff];
4218 if (mnemonic)
4219 oappend (mnemonic);
4220 else
4221 {
4222 /* Since a variable sized modrm/sib chunk is between the start
4223 of the opcode (0x0f0f) and the opcode suffix, we need to do
4224 all the modrm processing first, and don't know until now that
4225 we have a bad opcode. This necessitates some cleaning up. */
4226 op1out[0] = '\0';
4227 op2out[0] = '\0';
4228 BadOp ();
4229 }
4230 }
4231
4232 static const char *simd_cmp_op[] = {
4233 "eq",
4234 "lt",
4235 "le",
4236 "unord",
4237 "neq",
4238 "nlt",
4239 "nle",
4240 "ord"
4241 };
4242
4243 static void
4244 OP_SIMD_Suffix (bytemode, sizeflag)
4245 int bytemode ATTRIBUTE_UNUSED;
4246 int sizeflag ATTRIBUTE_UNUSED;
4247 {
4248 unsigned int cmp_type;
4249
4250 FETCH_DATA (the_info, codep + 1);
4251 obufp = obuf + strlen (obuf);
4252 cmp_type = *codep++ & 0xff;
4253 if (cmp_type < 8)
4254 {
4255 char suffix1 = 'p', suffix2 = 's';
4256 used_prefixes |= (prefixes & PREFIX_REPZ);
4257 if (prefixes & PREFIX_REPZ)
4258 suffix1 = 's';
4259 else
4260 {
4261 used_prefixes |= (prefixes & PREFIX_DATA);
4262 if (prefixes & PREFIX_DATA)
4263 suffix2 = 'd';
4264 else
4265 {
4266 used_prefixes |= (prefixes & PREFIX_REPNZ);
4267 if (prefixes & PREFIX_REPNZ)
4268 suffix1 = 's', suffix2 = 'd';
4269 }
4270 }
4271 sprintf (scratchbuf, "cmp%s%c%c",
4272 simd_cmp_op[cmp_type], suffix1, suffix2);
4273 used_prefixes |= (prefixes & PREFIX_REPZ);
4274 oappend (scratchbuf);
4275 }
4276 else
4277 {
4278 /* We have a bad extension byte. Clean up. */
4279 op1out[0] = '\0';
4280 op2out[0] = '\0';
4281 BadOp ();
4282 }
4283 }
4284
4285 static void
4286 SIMD_Fixup (extrachar, sizeflag)
4287 int extrachar;
4288 int sizeflag ATTRIBUTE_UNUSED;
4289 {
4290 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
4291 forms of these instructions. */
4292 if (mod == 3)
4293 {
4294 char *p = obuf + strlen (obuf);
4295 *(p + 1) = '\0';
4296 *p = *(p - 1);
4297 *(p - 1) = *(p - 2);
4298 *(p - 2) = *(p - 3);
4299 *(p - 3) = extrachar;
4300 }
4301 }
4302
4303 static void
4304 BadOp (void)
4305 {
4306 /* Throw away prefixes and 1st. opcode byte. */
4307 codep = insn_codep + 1;
4308 oappend ("(bad)");
4309 }