ia64/xen-unstable

view tools/ioemu/i386-dis.c @ 15841:c5f735271e22

[IA64] Foreign p2m: Fix vti domain builder.

It should set arch_domain::convmem_end.

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