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