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