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