Add support for marking ARM ELF binaries as support the Cirrus EP9312 Maverick
[binutils.git] / opcodes / i386-dis.c
blobf185b2858c4148458a8c710d04305c7b4e2e649e
1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2001, 2002, 2003 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
23 * July 1988
24 * modified by John Hassey (hassey@dg-rtp.dg.com)
25 * x86-64 support added by Jan Hubicka (jh@suse.cz)
29 * The main tables describing the instructions is essentially a copy
30 * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
31 * Programmers Manual. Usually, there is a capital letter, followed
32 * by a small letter. The capital letter tell the addressing mode,
33 * and the small letter tells about the operand size. Refer to
34 * the Intel manual for details.
37 #include "dis-asm.h"
38 #include "sysdep.h"
39 #include "opintl.h"
41 #define MAXLEN 20
43 #include <setjmp.h>
45 #ifndef UNIXWARE_COMPAT
46 /* Set non-zero for broken, compatible instructions. Set to zero for
47 non-broken opcodes. */
48 #define UNIXWARE_COMPAT 1
49 #endif
51 static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
52 static void ckprefix PARAMS ((void));
53 static const char *prefix_name PARAMS ((int, int));
54 static int print_insn PARAMS ((bfd_vma, disassemble_info *));
55 static void dofloat PARAMS ((int));
56 static void OP_ST PARAMS ((int, int));
57 static void OP_STi PARAMS ((int, int));
58 static int putop PARAMS ((const char *, int));
59 static void oappend PARAMS ((const char *));
60 static void append_seg PARAMS ((void));
61 static void OP_indirE PARAMS ((int, int));
62 static void print_operand_value PARAMS ((char *, int, bfd_vma));
63 static void OP_E PARAMS ((int, int));
64 static void OP_G PARAMS ((int, int));
65 static bfd_vma get64 PARAMS ((void));
66 static bfd_signed_vma get32 PARAMS ((void));
67 static bfd_signed_vma get32s PARAMS ((void));
68 static int get16 PARAMS ((void));
69 static void set_op PARAMS ((bfd_vma, int));
70 static void OP_REG PARAMS ((int, int));
71 static void OP_IMREG PARAMS ((int, int));
72 static void OP_I PARAMS ((int, int));
73 static void OP_I64 PARAMS ((int, int));
74 static void OP_sI PARAMS ((int, int));
75 static void OP_J PARAMS ((int, int));
76 static void OP_SEG PARAMS ((int, int));
77 static void OP_DIR PARAMS ((int, int));
78 static void OP_OFF PARAMS ((int, int));
79 static void OP_OFF64 PARAMS ((int, int));
80 static void ptr_reg PARAMS ((int, int));
81 static void OP_ESreg PARAMS ((int, int));
82 static void OP_DSreg PARAMS ((int, int));
83 static void OP_C PARAMS ((int, int));
84 static void OP_D PARAMS ((int, int));
85 static void OP_T PARAMS ((int, int));
86 static void OP_Rd PARAMS ((int, int));
87 static void OP_MMX PARAMS ((int, int));
88 static void OP_XMM PARAMS ((int, int));
89 static void OP_EM PARAMS ((int, int));
90 static void OP_EX PARAMS ((int, int));
91 static void OP_MS PARAMS ((int, int));
92 static void OP_XS PARAMS ((int, int));
93 static void OP_3DNowSuffix PARAMS ((int, int));
94 static void OP_SIMD_Suffix PARAMS ((int, int));
95 static void SIMD_Fixup PARAMS ((int, int));
96 static void BadOp PARAMS ((void));
98 struct dis_private {
99 /* Points to first byte not fetched. */
100 bfd_byte *max_fetched;
101 bfd_byte the_buffer[MAXLEN];
102 bfd_vma insn_start;
103 int orig_sizeflag;
104 jmp_buf bailout;
107 /* The opcode for the fwait instruction, which we treat as a prefix
108 when we can. */
109 #define FWAIT_OPCODE (0x9b)
111 /* Set to 1 for 64bit mode disassembly. */
112 static int mode_64bit;
114 /* Flags for the prefixes for the current instruction. See below. */
115 static int prefixes;
117 /* REX prefix the current instruction. See below. */
118 static int rex;
119 /* Bits of REX we've already used. */
120 static int rex_used;
121 #define REX_MODE64 8
122 #define REX_EXTX 4
123 #define REX_EXTY 2
124 #define REX_EXTZ 1
125 /* Mark parts used in the REX prefix. When we are testing for
126 empty prefix (for 8bit register REX extension), just mask it
127 out. Otherwise test for REX bit is excuse for existence of REX
128 only in case value is nonzero. */
129 #define USED_REX(value) \
131 if (value) \
132 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
133 else \
134 rex_used |= 0x40; \
137 /* Flags for prefixes which we somehow handled when printing the
138 current instruction. */
139 static int used_prefixes;
141 /* Flags stored in PREFIXES. */
142 #define PREFIX_REPZ 1
143 #define PREFIX_REPNZ 2
144 #define PREFIX_LOCK 4
145 #define PREFIX_CS 8
146 #define PREFIX_SS 0x10
147 #define PREFIX_DS 0x20
148 #define PREFIX_ES 0x40
149 #define PREFIX_FS 0x80
150 #define PREFIX_GS 0x100
151 #define PREFIX_DATA 0x200
152 #define PREFIX_ADDR 0x400
153 #define PREFIX_FWAIT 0x800
155 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
156 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
157 on error. */
158 #define FETCH_DATA(info, addr) \
159 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
160 ? 1 : fetch_data ((info), (addr)))
162 static int
163 fetch_data (info, addr)
164 struct disassemble_info *info;
165 bfd_byte *addr;
167 int status;
168 struct dis_private *priv = (struct dis_private *) info->private_data;
169 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
171 status = (*info->read_memory_func) (start,
172 priv->max_fetched,
173 addr - priv->max_fetched,
174 info);
175 if (status != 0)
177 /* If we did manage to read at least one byte, then
178 print_insn_i386 will do something sensible. Otherwise, print
179 an error. We do that here because this is where we know
180 STATUS. */
181 if (priv->max_fetched == priv->the_buffer)
182 (*info->memory_error_func) (status, start, info);
183 longjmp (priv->bailout, 1);
185 else
186 priv->max_fetched = addr;
187 return 1;
190 #define XX NULL, 0
192 #define Eb OP_E, b_mode
193 #define Ev OP_E, v_mode
194 #define Ed OP_E, d_mode
195 #define Edq OP_E, dq_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
315 #define dq_mode 10 /* operand size depends on REX prefixes. */
317 #define es_reg 100
318 #define cs_reg 101
319 #define ss_reg 102
320 #define ds_reg 103
321 #define fs_reg 104
322 #define gs_reg 105
324 #define eAX_reg 108
325 #define eCX_reg 109
326 #define eDX_reg 110
327 #define eBX_reg 111
328 #define eSP_reg 112
329 #define eBP_reg 113
330 #define eSI_reg 114
331 #define eDI_reg 115
333 #define al_reg 116
334 #define cl_reg 117
335 #define dl_reg 118
336 #define bl_reg 119
337 #define ah_reg 120
338 #define ch_reg 121
339 #define dh_reg 122
340 #define bh_reg 123
342 #define ax_reg 124
343 #define cx_reg 125
344 #define dx_reg 126
345 #define bx_reg 127
346 #define sp_reg 128
347 #define bp_reg 129
348 #define si_reg 130
349 #define di_reg 131
351 #define rAX_reg 132
352 #define rCX_reg 133
353 #define rDX_reg 134
354 #define rBX_reg 135
355 #define rSP_reg 136
356 #define rBP_reg 137
357 #define rSI_reg 138
358 #define rDI_reg 139
360 #define indir_dx_reg 150
362 #define FLOATCODE 1
363 #define USE_GROUPS 2
364 #define USE_PREFIX_USER_TABLE 3
365 #define X86_64_SPECIAL 4
367 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
369 #define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
370 #define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
371 #define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
372 #define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
373 #define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
374 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
375 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
376 #define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
377 #define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
378 #define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
379 #define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
380 #define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
381 #define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
382 #define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
383 #define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
384 #define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
385 #define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
386 #define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
387 #define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
388 #define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
389 #define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
390 #define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
391 #define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
393 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
394 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
395 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
396 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
397 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
398 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
399 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
400 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
401 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
402 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
403 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
404 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
405 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
406 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
407 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
408 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
409 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
410 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
411 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
412 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
413 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
414 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
415 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
416 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
417 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
418 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
419 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
421 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
423 typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag));
425 struct dis386 {
426 const char *name;
427 op_rtn op1;
428 int bytemode1;
429 op_rtn op2;
430 int bytemode2;
431 op_rtn op3;
432 int bytemode3;
435 /* Upper case letters in the instruction names here are macros.
436 'A' => print 'b' if no register operands or suffix_always is true
437 'B' => print 'b' if suffix_always is true
438 'E' => print 'e' if 32-bit form of jcxz
439 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
440 'H' => print ",pt" or ",pn" branch hint
441 'L' => print 'l' if suffix_always is true
442 'N' => print 'n' if instruction has no wait "prefix"
443 'O' => print 'd', or 'o'
444 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
445 . or suffix_always is true. print 'q' if rex prefix is present.
446 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
447 . is true
448 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
449 'S' => print 'w', 'l' or 'q' if suffix_always is true
450 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
451 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
452 'X' => print 's', 'd' depending on data16 prefix (for XMM)
453 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
454 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
456 Many of the above letters print nothing in Intel mode. See "putop"
457 for the details.
459 Braces '{' and '}', and vertical bars '|', indicate alternative
460 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
461 modes. In cases where there are only two alternatives, the X86_64
462 instruction is reserved, and "(bad)" is printed.
465 static const struct dis386 dis386[] = {
466 /* 00 */
467 { "addB", Eb, Gb, XX },
468 { "addS", Ev, Gv, XX },
469 { "addB", Gb, Eb, XX },
470 { "addS", Gv, Ev, XX },
471 { "addB", AL, Ib, XX },
472 { "addS", eAX, Iv, XX },
473 { "push{T|}", es, XX, XX },
474 { "pop{T|}", es, XX, XX },
475 /* 08 */
476 { "orB", Eb, Gb, XX },
477 { "orS", Ev, Gv, XX },
478 { "orB", Gb, Eb, XX },
479 { "orS", Gv, Ev, XX },
480 { "orB", AL, Ib, XX },
481 { "orS", eAX, Iv, XX },
482 { "push{T|}", cs, XX, XX },
483 { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */
484 /* 10 */
485 { "adcB", Eb, Gb, XX },
486 { "adcS", Ev, Gv, XX },
487 { "adcB", Gb, Eb, XX },
488 { "adcS", Gv, Ev, XX },
489 { "adcB", AL, Ib, XX },
490 { "adcS", eAX, Iv, XX },
491 { "push{T|}", ss, XX, XX },
492 { "popT|}", ss, XX, XX },
493 /* 18 */
494 { "sbbB", Eb, Gb, XX },
495 { "sbbS", Ev, Gv, XX },
496 { "sbbB", Gb, Eb, XX },
497 { "sbbS", Gv, Ev, XX },
498 { "sbbB", AL, Ib, XX },
499 { "sbbS", eAX, Iv, XX },
500 { "push{T|}", ds, XX, XX },
501 { "pop{T|}", ds, XX, XX },
502 /* 20 */
503 { "andB", Eb, Gb, XX },
504 { "andS", Ev, Gv, XX },
505 { "andB", Gb, Eb, XX },
506 { "andS", Gv, Ev, XX },
507 { "andB", AL, Ib, XX },
508 { "andS", eAX, Iv, XX },
509 { "(bad)", XX, XX, XX }, /* SEG ES prefix */
510 { "daa{|}", XX, XX, XX },
511 /* 28 */
512 { "subB", Eb, Gb, XX },
513 { "subS", Ev, Gv, XX },
514 { "subB", Gb, Eb, XX },
515 { "subS", Gv, Ev, XX },
516 { "subB", AL, Ib, XX },
517 { "subS", eAX, Iv, XX },
518 { "(bad)", XX, XX, XX }, /* SEG CS prefix */
519 { "das{|}", XX, XX, XX },
520 /* 30 */
521 { "xorB", Eb, Gb, XX },
522 { "xorS", Ev, Gv, XX },
523 { "xorB", Gb, Eb, XX },
524 { "xorS", Gv, Ev, XX },
525 { "xorB", AL, Ib, XX },
526 { "xorS", eAX, Iv, XX },
527 { "(bad)", XX, XX, XX }, /* SEG SS prefix */
528 { "aaa{|}", XX, XX, XX },
529 /* 38 */
530 { "cmpB", Eb, Gb, XX },
531 { "cmpS", Ev, Gv, XX },
532 { "cmpB", Gb, Eb, XX },
533 { "cmpS", Gv, Ev, XX },
534 { "cmpB", AL, Ib, XX },
535 { "cmpS", eAX, Iv, XX },
536 { "(bad)", XX, XX, XX }, /* SEG DS prefix */
537 { "aas{|}", XX, XX, XX },
538 /* 40 */
539 { "inc{S|}", RMeAX, XX, XX },
540 { "inc{S|}", RMeCX, XX, XX },
541 { "inc{S|}", RMeDX, XX, XX },
542 { "inc{S|}", RMeBX, XX, XX },
543 { "inc{S|}", RMeSP, XX, XX },
544 { "inc{S|}", RMeBP, XX, XX },
545 { "inc{S|}", RMeSI, XX, XX },
546 { "inc{S|}", RMeDI, XX, XX },
547 /* 48 */
548 { "dec{S|}", RMeAX, XX, XX },
549 { "dec{S|}", RMeCX, XX, XX },
550 { "dec{S|}", RMeDX, XX, XX },
551 { "dec{S|}", RMeBX, XX, XX },
552 { "dec{S|}", RMeSP, XX, XX },
553 { "dec{S|}", RMeBP, XX, XX },
554 { "dec{S|}", RMeSI, XX, XX },
555 { "dec{S|}", RMeDI, XX, XX },
556 /* 50 */
557 { "pushS", RMrAX, XX, XX },
558 { "pushS", RMrCX, XX, XX },
559 { "pushS", RMrDX, XX, XX },
560 { "pushS", RMrBX, XX, XX },
561 { "pushS", RMrSP, XX, XX },
562 { "pushS", RMrBP, XX, XX },
563 { "pushS", RMrSI, XX, XX },
564 { "pushS", RMrDI, XX, XX },
565 /* 58 */
566 { "popS", RMrAX, XX, XX },
567 { "popS", RMrCX, XX, XX },
568 { "popS", RMrDX, XX, XX },
569 { "popS", RMrBX, XX, XX },
570 { "popS", RMrSP, XX, XX },
571 { "popS", RMrBP, XX, XX },
572 { "popS", RMrSI, XX, XX },
573 { "popS", RMrDI, XX, XX },
574 /* 60 */
575 { "pusha{P|}", XX, XX, XX },
576 { "popa{P|}", XX, XX, XX },
577 { "bound{S|}", Gv, Ma, XX },
578 { X86_64_0 },
579 { "(bad)", XX, XX, XX }, /* seg fs */
580 { "(bad)", XX, XX, XX }, /* seg gs */
581 { "(bad)", XX, XX, XX }, /* op size prefix */
582 { "(bad)", XX, XX, XX }, /* adr size prefix */
583 /* 68 */
584 { "pushT", Iq, XX, XX },
585 { "imulS", Gv, Ev, Iv },
586 { "pushT", sIb, XX, XX },
587 { "imulS", Gv, Ev, sIb },
588 { "ins{b||b|}", Yb, indirDX, XX },
589 { "ins{R||R|}", Yv, indirDX, XX },
590 { "outs{b||b|}", indirDX, Xb, XX },
591 { "outs{R||R|}", indirDX, Xv, XX },
592 /* 70 */
593 { "joH", Jb, XX, cond_jump_flag },
594 { "jnoH", Jb, XX, cond_jump_flag },
595 { "jbH", Jb, XX, cond_jump_flag },
596 { "jaeH", Jb, XX, cond_jump_flag },
597 { "jeH", Jb, XX, cond_jump_flag },
598 { "jneH", Jb, XX, cond_jump_flag },
599 { "jbeH", Jb, XX, cond_jump_flag },
600 { "jaH", Jb, XX, cond_jump_flag },
601 /* 78 */
602 { "jsH", Jb, XX, cond_jump_flag },
603 { "jnsH", Jb, XX, cond_jump_flag },
604 { "jpH", Jb, XX, cond_jump_flag },
605 { "jnpH", Jb, XX, cond_jump_flag },
606 { "jlH", Jb, XX, cond_jump_flag },
607 { "jgeH", Jb, XX, cond_jump_flag },
608 { "jleH", Jb, XX, cond_jump_flag },
609 { "jgH", Jb, XX, cond_jump_flag },
610 /* 80 */
611 { GRP1b },
612 { GRP1S },
613 { "(bad)", XX, XX, XX },
614 { GRP1Ss },
615 { "testB", Eb, Gb, XX },
616 { "testS", Ev, Gv, XX },
617 { "xchgB", Eb, Gb, XX },
618 { "xchgS", Ev, Gv, XX },
619 /* 88 */
620 { "movB", Eb, Gb, XX },
621 { "movS", Ev, Gv, XX },
622 { "movB", Gb, Eb, XX },
623 { "movS", Gv, Ev, XX },
624 { "movQ", Ev, Sw, XX },
625 { "leaS", Gv, M, XX },
626 { "movQ", Sw, Ev, XX },
627 { "popU", Ev, XX, XX },
628 /* 90 */
629 { "nop", XX, XX, XX },
630 /* FIXME: NOP with REPz prefix is called PAUSE. */
631 { "xchgS", RMeCX, eAX, XX },
632 { "xchgS", RMeDX, eAX, XX },
633 { "xchgS", RMeBX, eAX, XX },
634 { "xchgS", RMeSP, eAX, XX },
635 { "xchgS", RMeBP, eAX, XX },
636 { "xchgS", RMeSI, eAX, XX },
637 { "xchgS", RMeDI, eAX, XX },
638 /* 98 */
639 { "cW{tR||tR|}", XX, XX, XX },
640 { "cR{tO||tO|}", XX, XX, XX },
641 { "lcall{T|}", Ap, XX, XX },
642 { "(bad)", XX, XX, XX }, /* fwait */
643 { "pushfT", XX, XX, XX },
644 { "popfT", XX, XX, XX },
645 { "sahf{|}", XX, XX, XX },
646 { "lahf{|}", XX, XX, XX },
647 /* a0 */
648 { "movB", AL, Ob64, XX },
649 { "movS", eAX, Ov64, XX },
650 { "movB", Ob64, AL, XX },
651 { "movS", Ov64, eAX, XX },
652 { "movs{b||b|}", Yb, Xb, XX },
653 { "movs{R||R|}", Yv, Xv, XX },
654 { "cmps{b||b|}", Xb, Yb, XX },
655 { "cmps{R||R|}", Xv, Yv, XX },
656 /* a8 */
657 { "testB", AL, Ib, XX },
658 { "testS", eAX, Iv, XX },
659 { "stosB", Yb, AL, XX },
660 { "stosS", Yv, eAX, XX },
661 { "lodsB", AL, Xb, XX },
662 { "lodsS", eAX, Xv, XX },
663 { "scasB", AL, Yb, XX },
664 { "scasS", eAX, Yv, XX },
665 /* b0 */
666 { "movB", RMAL, Ib, XX },
667 { "movB", RMCL, Ib, XX },
668 { "movB", RMDL, Ib, XX },
669 { "movB", RMBL, Ib, XX },
670 { "movB", RMAH, Ib, XX },
671 { "movB", RMCH, Ib, XX },
672 { "movB", RMDH, Ib, XX },
673 { "movB", RMBH, Ib, XX },
674 /* b8 */
675 { "movS", RMeAX, Iv64, XX },
676 { "movS", RMeCX, Iv64, XX },
677 { "movS", RMeDX, Iv64, XX },
678 { "movS", RMeBX, Iv64, XX },
679 { "movS", RMeSP, Iv64, XX },
680 { "movS", RMeBP, Iv64, XX },
681 { "movS", RMeSI, Iv64, XX },
682 { "movS", RMeDI, Iv64, XX },
683 /* c0 */
684 { GRP2b },
685 { GRP2S },
686 { "retT", Iw, XX, XX },
687 { "retT", XX, XX, XX },
688 { "les{S|}", Gv, Mp, XX },
689 { "ldsS", Gv, Mp, XX },
690 { "movA", Eb, Ib, XX },
691 { "movQ", Ev, Iv, XX },
692 /* c8 */
693 { "enterT", Iw, Ib, XX },
694 { "leaveT", XX, XX, XX },
695 { "lretP", Iw, XX, XX },
696 { "lretP", XX, XX, XX },
697 { "int3", XX, XX, XX },
698 { "int", Ib, XX, XX },
699 { "into{|}", XX, XX, XX },
700 { "iretP", XX, XX, XX },
701 /* d0 */
702 { GRP2b_one },
703 { GRP2S_one },
704 { GRP2b_cl },
705 { GRP2S_cl },
706 { "aam{|}", sIb, XX, XX },
707 { "aad{|}", sIb, XX, XX },
708 { "(bad)", XX, XX, XX },
709 { "xlat", DSBX, XX, XX },
710 /* d8 */
711 { FLOAT },
712 { FLOAT },
713 { FLOAT },
714 { FLOAT },
715 { FLOAT },
716 { FLOAT },
717 { FLOAT },
718 { FLOAT },
719 /* e0 */
720 { "loopneFH", Jb, XX, loop_jcxz_flag },
721 { "loopeFH", Jb, XX, loop_jcxz_flag },
722 { "loopFH", Jb, XX, loop_jcxz_flag },
723 { "jEcxzH", Jb, XX, loop_jcxz_flag },
724 { "inB", AL, Ib, XX },
725 { "inS", eAX, Ib, XX },
726 { "outB", Ib, AL, XX },
727 { "outS", Ib, eAX, XX },
728 /* e8 */
729 { "callT", Jv, XX, XX },
730 { "jmpT", Jv, XX, XX },
731 { "ljmp{T|}", Ap, XX, XX },
732 { "jmp", Jb, XX, XX },
733 { "inB", AL, indirDX, XX },
734 { "inS", eAX, indirDX, XX },
735 { "outB", indirDX, AL, XX },
736 { "outS", indirDX, eAX, XX },
737 /* f0 */
738 { "(bad)", XX, XX, XX }, /* lock prefix */
739 { "(bad)", XX, XX, XX },
740 { "(bad)", XX, XX, XX }, /* repne */
741 { "(bad)", XX, XX, XX }, /* repz */
742 { "hlt", XX, XX, XX },
743 { "cmc", XX, XX, XX },
744 { GRP3b },
745 { GRP3S },
746 /* f8 */
747 { "clc", XX, XX, XX },
748 { "stc", XX, XX, XX },
749 { "cli", XX, XX, XX },
750 { "sti", XX, XX, XX },
751 { "cld", XX, XX, XX },
752 { "std", XX, XX, XX },
753 { GRP4 },
754 { GRP5 },
757 static const struct dis386 dis386_twobyte[] = {
758 /* 00 */
759 { GRP6 },
760 { GRP7 },
761 { "larS", Gv, Ew, XX },
762 { "lslS", Gv, Ew, XX },
763 { "(bad)", XX, XX, XX },
764 { "syscall", XX, XX, XX },
765 { "clts", XX, XX, XX },
766 { "sysretP", XX, XX, XX },
767 /* 08 */
768 { "invd", XX, XX, XX },
769 { "wbinvd", XX, XX, XX },
770 { "(bad)", XX, XX, XX },
771 { "ud2a", XX, XX, XX },
772 { "(bad)", XX, XX, XX },
773 { GRPAMD },
774 { "femms", XX, XX, XX },
775 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */
776 /* 10 */
777 { PREGRP8 },
778 { PREGRP9 },
779 { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
780 { "movlpX", EX, XM, SIMD_Fixup, 'h' },
781 { "unpcklpX", XM, EX, XX },
782 { "unpckhpX", XM, EX, XX },
783 { "movhpX", XM, EX, SIMD_Fixup, 'l' },
784 { "movhpX", EX, XM, SIMD_Fixup, 'l' },
785 /* 18 */
786 { GRP14 },
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 { "(bad)", XX, XX, XX },
794 /* 20 */
795 { "movL", Rm, Cm, XX },
796 { "movL", Rm, Dm, XX },
797 { "movL", Cm, Rm, XX },
798 { "movL", Dm, Rm, XX },
799 { "movL", Rd, Td, XX },
800 { "(bad)", XX, XX, XX },
801 { "movL", Td, Rd, XX },
802 { "(bad)", XX, XX, XX },
803 /* 28 */
804 { "movapX", XM, EX, XX },
805 { "movapX", EX, XM, XX },
806 { PREGRP2 },
807 { "movntpX", Ev, XM, XX },
808 { PREGRP4 },
809 { PREGRP3 },
810 { "ucomisX", XM,EX, XX },
811 { "comisX", XM,EX, XX },
812 /* 30 */
813 { "wrmsr", XX, XX, XX },
814 { "rdtsc", XX, XX, XX },
815 { "rdmsr", XX, XX, XX },
816 { "rdpmc", XX, XX, XX },
817 { "sysenter", XX, XX, XX },
818 { "sysexit", XX, XX, XX },
819 { "(bad)", XX, XX, XX },
820 { "(bad)", XX, XX, XX },
821 /* 38 */
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 { "(bad)", XX, XX, XX },
830 /* 40 */
831 { "cmovo", Gv, Ev, XX },
832 { "cmovno", Gv, Ev, XX },
833 { "cmovb", Gv, Ev, XX },
834 { "cmovae", Gv, Ev, XX },
835 { "cmove", Gv, Ev, XX },
836 { "cmovne", Gv, Ev, XX },
837 { "cmovbe", Gv, Ev, XX },
838 { "cmova", Gv, Ev, XX },
839 /* 48 */
840 { "cmovs", Gv, Ev, XX },
841 { "cmovns", Gv, Ev, XX },
842 { "cmovp", Gv, Ev, XX },
843 { "cmovnp", Gv, Ev, XX },
844 { "cmovl", Gv, Ev, XX },
845 { "cmovge", Gv, Ev, XX },
846 { "cmovle", Gv, Ev, XX },
847 { "cmovg", Gv, Ev, XX },
848 /* 50 */
849 { "movmskpX", Gd, XS, XX },
850 { PREGRP13 },
851 { PREGRP12 },
852 { PREGRP11 },
853 { "andpX", XM, EX, XX },
854 { "andnpX", XM, EX, XX },
855 { "orpX", XM, EX, XX },
856 { "xorpX", XM, EX, XX },
857 /* 58 */
858 { PREGRP0 },
859 { PREGRP10 },
860 { PREGRP17 },
861 { PREGRP16 },
862 { PREGRP14 },
863 { PREGRP7 },
864 { PREGRP5 },
865 { PREGRP6 },
866 /* 60 */
867 { "punpcklbw", MX, EM, XX },
868 { "punpcklwd", MX, EM, XX },
869 { "punpckldq", MX, EM, XX },
870 { "packsswb", MX, EM, XX },
871 { "pcmpgtb", MX, EM, XX },
872 { "pcmpgtw", MX, EM, XX },
873 { "pcmpgtd", MX, EM, XX },
874 { "packuswb", MX, EM, XX },
875 /* 68 */
876 { "punpckhbw", MX, EM, XX },
877 { "punpckhwd", MX, EM, XX },
878 { "punpckhdq", MX, EM, XX },
879 { "packssdw", MX, EM, XX },
880 { PREGRP26 },
881 { PREGRP24 },
882 { "movd", MX, Edq, XX },
883 { PREGRP19 },
884 /* 70 */
885 { PREGRP22 },
886 { GRP10 },
887 { GRP11 },
888 { GRP12 },
889 { "pcmpeqb", MX, EM, XX },
890 { "pcmpeqw", MX, EM, XX },
891 { "pcmpeqd", MX, EM, XX },
892 { "emms", XX, XX, XX },
893 /* 78 */
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 { "(bad)", XX, XX, XX },
900 { PREGRP23 },
901 { PREGRP20 },
902 /* 80 */
903 { "joH", Jv, XX, cond_jump_flag },
904 { "jnoH", Jv, XX, cond_jump_flag },
905 { "jbH", Jv, XX, cond_jump_flag },
906 { "jaeH", Jv, XX, cond_jump_flag },
907 { "jeH", Jv, XX, cond_jump_flag },
908 { "jneH", Jv, XX, cond_jump_flag },
909 { "jbeH", Jv, XX, cond_jump_flag },
910 { "jaH", Jv, XX, cond_jump_flag },
911 /* 88 */
912 { "jsH", Jv, XX, cond_jump_flag },
913 { "jnsH", Jv, XX, cond_jump_flag },
914 { "jpH", Jv, XX, cond_jump_flag },
915 { "jnpH", Jv, XX, cond_jump_flag },
916 { "jlH", Jv, XX, cond_jump_flag },
917 { "jgeH", Jv, XX, cond_jump_flag },
918 { "jleH", Jv, XX, cond_jump_flag },
919 { "jgH", Jv, XX, cond_jump_flag },
920 /* 90 */
921 { "seto", Eb, XX, XX },
922 { "setno", Eb, XX, XX },
923 { "setb", Eb, XX, XX },
924 { "setae", Eb, XX, XX },
925 { "sete", Eb, XX, XX },
926 { "setne", Eb, XX, XX },
927 { "setbe", Eb, XX, XX },
928 { "seta", Eb, XX, XX },
929 /* 98 */
930 { "sets", Eb, XX, XX },
931 { "setns", Eb, XX, XX },
932 { "setp", Eb, XX, XX },
933 { "setnp", Eb, XX, XX },
934 { "setl", Eb, XX, XX },
935 { "setge", Eb, XX, XX },
936 { "setle", Eb, XX, XX },
937 { "setg", Eb, XX, XX },
938 /* a0 */
939 { "pushT", fs, XX, XX },
940 { "popT", fs, XX, XX },
941 { "cpuid", XX, XX, XX },
942 { "btS", Ev, Gv, XX },
943 { "shldS", Ev, Gv, Ib },
944 { "shldS", Ev, Gv, CL },
945 { "(bad)", XX, XX, XX },
946 { "(bad)", XX, XX, XX },
947 /* a8 */
948 { "pushT", gs, XX, XX },
949 { "popT", gs, XX, XX },
950 { "rsm", XX, XX, XX },
951 { "btsS", Ev, Gv, XX },
952 { "shrdS", Ev, Gv, Ib },
953 { "shrdS", Ev, Gv, CL },
954 { GRP13 },
955 { "imulS", Gv, Ev, XX },
956 /* b0 */
957 { "cmpxchgB", Eb, Gb, XX },
958 { "cmpxchgS", Ev, Gv, XX },
959 { "lssS", Gv, Mp, XX },
960 { "btrS", Ev, Gv, XX },
961 { "lfsS", Gv, Mp, XX },
962 { "lgsS", Gv, Mp, XX },
963 { "movz{bR|x|bR|x}", Gv, Eb, XX },
964 { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */
965 /* b8 */
966 { "(bad)", XX, XX, XX },
967 { "ud2b", XX, XX, XX },
968 { GRP8 },
969 { "btcS", Ev, Gv, XX },
970 { "bsfS", Gv, Ev, XX },
971 { "bsrS", Gv, Ev, XX },
972 { "movs{bR|x|bR|x}", Gv, Eb, XX },
973 { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */
974 /* c0 */
975 { "xaddB", Eb, Gb, XX },
976 { "xaddS", Ev, Gv, XX },
977 { PREGRP1 },
978 { "movntiS", Ev, Gv, XX },
979 { "pinsrw", MX, Ed, Ib },
980 { "pextrw", Gd, MS, Ib },
981 { "shufpX", XM, EX, Ib },
982 { GRP9 },
983 /* c8 */
984 { "bswap", RMeAX, XX, XX },
985 { "bswap", RMeCX, XX, XX },
986 { "bswap", RMeDX, XX, XX },
987 { "bswap", RMeBX, XX, XX },
988 { "bswap", RMeSP, XX, XX },
989 { "bswap", RMeBP, XX, XX },
990 { "bswap", RMeSI, XX, XX },
991 { "bswap", RMeDI, XX, XX },
992 /* d0 */
993 { "(bad)", XX, XX, XX },
994 { "psrlw", MX, EM, XX },
995 { "psrld", MX, EM, XX },
996 { "psrlq", MX, EM, XX },
997 { "paddq", MX, EM, XX },
998 { "pmullw", MX, EM, XX },
999 { PREGRP21 },
1000 { "pmovmskb", Gd, MS, XX },
1001 /* d8 */
1002 { "psubusb", MX, EM, XX },
1003 { "psubusw", MX, EM, XX },
1004 { "pminub", MX, EM, XX },
1005 { "pand", MX, EM, XX },
1006 { "paddusb", MX, EM, XX },
1007 { "paddusw", MX, EM, XX },
1008 { "pmaxub", MX, EM, XX },
1009 { "pandn", MX, EM, XX },
1010 /* e0 */
1011 { "pavgb", MX, EM, XX },
1012 { "psraw", MX, EM, XX },
1013 { "psrad", MX, EM, XX },
1014 { "pavgw", MX, EM, XX },
1015 { "pmulhuw", MX, EM, XX },
1016 { "pmulhw", MX, EM, XX },
1017 { PREGRP15 },
1018 { PREGRP25 },
1019 /* e8 */
1020 { "psubsb", MX, EM, XX },
1021 { "psubsw", MX, EM, XX },
1022 { "pminsw", MX, EM, XX },
1023 { "por", MX, EM, XX },
1024 { "paddsb", MX, EM, XX },
1025 { "paddsw", MX, EM, XX },
1026 { "pmaxsw", MX, EM, XX },
1027 { "pxor", MX, EM, XX },
1028 /* f0 */
1029 { "(bad)", XX, XX, XX },
1030 { "psllw", MX, EM, XX },
1031 { "pslld", MX, EM, XX },
1032 { "psllq", MX, EM, XX },
1033 { "pmuludq", MX, EM, XX },
1034 { "pmaddwd", MX, EM, XX },
1035 { "psadbw", MX, EM, XX },
1036 { PREGRP18 },
1037 /* f8 */
1038 { "psubb", MX, EM, XX },
1039 { "psubw", MX, EM, XX },
1040 { "psubd", MX, EM, XX },
1041 { "psubq", MX, EM, XX },
1042 { "paddb", MX, EM, XX },
1043 { "paddw", MX, EM, XX },
1044 { "paddd", MX, EM, XX },
1045 { "(bad)", XX, XX, XX }
1048 static const unsigned char onebyte_has_modrm[256] = {
1049 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1050 /* ------------------------------- */
1051 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1052 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1053 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1054 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1055 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1056 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1057 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1058 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1059 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1060 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1061 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1062 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1063 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1064 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1065 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1066 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1067 /* ------------------------------- */
1068 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1071 static const unsigned char twobyte_has_modrm[256] = {
1072 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1073 /* ------------------------------- */
1074 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1075 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1076 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1077 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1078 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1079 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1080 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1081 /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
1082 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1083 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1084 /* a0 */ 0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1, /* af */
1085 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1086 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1087 /* d0 */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1088 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1089 /* f0 */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1090 /* ------------------------------- */
1091 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1094 static const unsigned char twobyte_uses_SSE_prefix[256] = {
1095 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1096 /* ------------------------------- */
1097 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1098 /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1099 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1100 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1101 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1102 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1103 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1104 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1105 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1106 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1107 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1108 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1109 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1110 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1111 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1112 /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1113 /* ------------------------------- */
1114 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1117 static char obuf[100];
1118 static char *obufp;
1119 static char scratchbuf[100];
1120 static unsigned char *start_codep;
1121 static unsigned char *insn_codep;
1122 static unsigned char *codep;
1123 static disassemble_info *the_info;
1124 static int mod;
1125 static int rm;
1126 static int reg;
1127 static unsigned char need_modrm;
1129 /* If we are accessing mod/rm/reg without need_modrm set, then the
1130 values are stale. Hitting this abort likely indicates that you
1131 need to update onebyte_has_modrm or twobyte_has_modrm. */
1132 #define MODRM_CHECK if (!need_modrm) abort ()
1134 static const char **names64;
1135 static const char **names32;
1136 static const char **names16;
1137 static const char **names8;
1138 static const char **names8rex;
1139 static const char **names_seg;
1140 static const char **index16;
1142 static const char *intel_names64[] = {
1143 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1144 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1146 static const char *intel_names32[] = {
1147 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1148 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1150 static const char *intel_names16[] = {
1151 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1152 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1154 static const char *intel_names8[] = {
1155 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1157 static const char *intel_names8rex[] = {
1158 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1159 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1161 static const char *intel_names_seg[] = {
1162 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1164 static const char *intel_index16[] = {
1165 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1168 static const char *att_names64[] = {
1169 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1170 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1172 static const char *att_names32[] = {
1173 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1174 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1176 static const char *att_names16[] = {
1177 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1178 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1180 static const char *att_names8[] = {
1181 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1183 static const char *att_names8rex[] = {
1184 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1185 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1187 static const char *att_names_seg[] = {
1188 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1190 static const char *att_index16[] = {
1191 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1194 static const struct dis386 grps[][8] = {
1195 /* GRP1b */
1197 { "addA", Eb, Ib, XX },
1198 { "orA", Eb, Ib, XX },
1199 { "adcA", Eb, Ib, XX },
1200 { "sbbA", Eb, Ib, XX },
1201 { "andA", Eb, Ib, XX },
1202 { "subA", Eb, Ib, XX },
1203 { "xorA", Eb, Ib, XX },
1204 { "cmpA", Eb, Ib, XX }
1206 /* GRP1S */
1208 { "addQ", Ev, Iv, XX },
1209 { "orQ", Ev, Iv, XX },
1210 { "adcQ", Ev, Iv, XX },
1211 { "sbbQ", Ev, Iv, XX },
1212 { "andQ", Ev, Iv, XX },
1213 { "subQ", Ev, Iv, XX },
1214 { "xorQ", Ev, Iv, XX },
1215 { "cmpQ", Ev, Iv, XX }
1217 /* GRP1Ss */
1219 { "addQ", Ev, sIb, XX },
1220 { "orQ", Ev, sIb, XX },
1221 { "adcQ", Ev, sIb, XX },
1222 { "sbbQ", Ev, sIb, XX },
1223 { "andQ", Ev, sIb, XX },
1224 { "subQ", Ev, sIb, XX },
1225 { "xorQ", Ev, sIb, XX },
1226 { "cmpQ", Ev, sIb, XX }
1228 /* GRP2b */
1230 { "rolA", Eb, Ib, XX },
1231 { "rorA", Eb, Ib, XX },
1232 { "rclA", Eb, Ib, XX },
1233 { "rcrA", Eb, Ib, XX },
1234 { "shlA", Eb, Ib, XX },
1235 { "shrA", Eb, Ib, XX },
1236 { "(bad)", XX, XX, XX },
1237 { "sarA", Eb, Ib, XX },
1239 /* GRP2S */
1241 { "rolQ", Ev, Ib, XX },
1242 { "rorQ", Ev, Ib, XX },
1243 { "rclQ", Ev, Ib, XX },
1244 { "rcrQ", Ev, Ib, XX },
1245 { "shlQ", Ev, Ib, XX },
1246 { "shrQ", Ev, Ib, XX },
1247 { "(bad)", XX, XX, XX },
1248 { "sarQ", Ev, Ib, XX },
1250 /* GRP2b_one */
1252 { "rolA", Eb, XX, XX },
1253 { "rorA", Eb, XX, XX },
1254 { "rclA", Eb, XX, XX },
1255 { "rcrA", Eb, XX, XX },
1256 { "shlA", Eb, XX, XX },
1257 { "shrA", Eb, XX, XX },
1258 { "(bad)", XX, XX, XX },
1259 { "sarA", Eb, XX, XX },
1261 /* GRP2S_one */
1263 { "rolQ", Ev, XX, XX },
1264 { "rorQ", Ev, XX, XX },
1265 { "rclQ", Ev, XX, XX },
1266 { "rcrQ", Ev, XX, XX },
1267 { "shlQ", Ev, XX, XX },
1268 { "shrQ", Ev, XX, XX },
1269 { "(bad)", XX, XX, XX},
1270 { "sarQ", Ev, XX, XX },
1272 /* GRP2b_cl */
1274 { "rolA", Eb, CL, XX },
1275 { "rorA", Eb, CL, XX },
1276 { "rclA", Eb, CL, XX },
1277 { "rcrA", Eb, CL, XX },
1278 { "shlA", Eb, CL, XX },
1279 { "shrA", Eb, CL, XX },
1280 { "(bad)", XX, XX, XX },
1281 { "sarA", Eb, CL, XX },
1283 /* GRP2S_cl */
1285 { "rolQ", Ev, CL, XX },
1286 { "rorQ", Ev, CL, XX },
1287 { "rclQ", Ev, CL, XX },
1288 { "rcrQ", Ev, CL, XX },
1289 { "shlQ", Ev, CL, XX },
1290 { "shrQ", Ev, CL, XX },
1291 { "(bad)", XX, XX, XX },
1292 { "sarQ", Ev, CL, XX }
1294 /* GRP3b */
1296 { "testA", Eb, Ib, XX },
1297 { "(bad)", Eb, XX, XX },
1298 { "notA", Eb, XX, XX },
1299 { "negA", Eb, XX, XX },
1300 { "mulA", Eb, XX, XX }, /* Don't print the implicit %al register, */
1301 { "imulA", Eb, XX, XX }, /* to distinguish these opcodes from other */
1302 { "divA", Eb, XX, XX }, /* mul/imul opcodes. Do the same for div */
1303 { "idivA", Eb, XX, XX } /* and idiv for consistency. */
1305 /* GRP3S */
1307 { "testQ", Ev, Iv, XX },
1308 { "(bad)", XX, XX, XX },
1309 { "notQ", Ev, XX, XX },
1310 { "negQ", Ev, XX, XX },
1311 { "mulQ", Ev, XX, XX }, /* Don't print the implicit register. */
1312 { "imulQ", Ev, XX, XX },
1313 { "divQ", Ev, XX, XX },
1314 { "idivQ", Ev, XX, XX },
1316 /* GRP4 */
1318 { "incA", Eb, XX, XX },
1319 { "decA", Eb, 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 },
1325 { "(bad)", XX, XX, XX },
1327 /* GRP5 */
1329 { "incQ", Ev, XX, XX },
1330 { "decQ", Ev, XX, XX },
1331 { "callT", indirEv, XX, XX },
1332 { "lcallT", indirEv, XX, XX },
1333 { "jmpT", indirEv, XX, XX },
1334 { "ljmpT", indirEv, XX, XX },
1335 { "pushU", Ev, XX, XX },
1336 { "(bad)", XX, XX, XX },
1338 /* GRP6 */
1340 { "sldtQ", Ev, XX, XX },
1341 { "strQ", Ev, XX, XX },
1342 { "lldt", Ew, XX, XX },
1343 { "ltr", Ew, XX, XX },
1344 { "verr", Ew, XX, XX },
1345 { "verw", Ew, XX, XX },
1346 { "(bad)", XX, XX, XX },
1347 { "(bad)", XX, XX, XX }
1349 /* GRP7 */
1351 { "sgdtQ", M, XX, XX },
1352 { "sidtQ", M, XX, XX },
1353 { "lgdtQ", M, XX, XX },
1354 { "lidtQ", M, XX, XX },
1355 { "smswQ", Ev, XX, XX },
1356 { "(bad)", XX, XX, XX },
1357 { "lmsw", Ew, XX, XX },
1358 { "invlpg", Ew, XX, XX },
1360 /* GRP8 */
1362 { "(bad)", XX, XX, XX },
1363 { "(bad)", XX, XX, XX },
1364 { "(bad)", XX, XX, XX },
1365 { "(bad)", XX, XX, XX },
1366 { "btQ", Ev, Ib, XX },
1367 { "btsQ", Ev, Ib, XX },
1368 { "btrQ", Ev, Ib, XX },
1369 { "btcQ", Ev, Ib, XX },
1371 /* GRP9 */
1373 { "(bad)", XX, XX, XX },
1374 { "cmpxchg8b", Ev, 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 },
1380 { "(bad)", XX, XX, XX },
1382 /* GRP10 */
1384 { "(bad)", XX, XX, XX },
1385 { "(bad)", XX, XX, XX },
1386 { "psrlw", MS, Ib, XX },
1387 { "(bad)", XX, XX, XX },
1388 { "psraw", MS, Ib, XX },
1389 { "(bad)", XX, XX, XX },
1390 { "psllw", MS, Ib, XX },
1391 { "(bad)", XX, XX, XX },
1393 /* GRP11 */
1395 { "(bad)", XX, XX, XX },
1396 { "(bad)", XX, XX, XX },
1397 { "psrld", MS, Ib, XX },
1398 { "(bad)", XX, XX, XX },
1399 { "psrad", MS, Ib, XX },
1400 { "(bad)", XX, XX, XX },
1401 { "pslld", MS, Ib, XX },
1402 { "(bad)", XX, XX, XX },
1404 /* GRP12 */
1406 { "(bad)", XX, XX, XX },
1407 { "(bad)", XX, XX, XX },
1408 { "psrlq", MS, Ib, XX },
1409 { "psrldq", MS, Ib, XX },
1410 { "(bad)", XX, XX, XX },
1411 { "(bad)", XX, XX, XX },
1412 { "psllq", MS, Ib, XX },
1413 { "pslldq", MS, Ib, XX },
1415 /* GRP13 */
1417 { "fxsave", Ev, XX, XX },
1418 { "fxrstor", Ev, XX, XX },
1419 { "ldmxcsr", Ev, XX, XX },
1420 { "stmxcsr", Ev, XX, XX },
1421 { "(bad)", XX, XX, XX },
1422 { "lfence", None, XX, XX },
1423 { "mfence", None, XX, XX },
1424 { "sfence", None, XX, XX },
1425 /* FIXME: the sfence with memory operand is clflush! */
1427 /* GRP14 */
1429 { "prefetchnta", Ev, XX, XX },
1430 { "prefetcht0", Ev, XX, XX },
1431 { "prefetcht1", Ev, XX, XX },
1432 { "prefetcht2", Ev, XX, XX },
1433 { "(bad)", XX, XX, XX },
1434 { "(bad)", XX, XX, XX },
1435 { "(bad)", XX, XX, XX },
1436 { "(bad)", XX, XX, XX },
1438 /* GRPAMD */
1440 { "prefetch", Eb, XX, XX },
1441 { "prefetchw", Eb, 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 },
1447 { "(bad)", XX, XX, XX },
1451 static const struct dis386 prefix_user_table[][4] = {
1452 /* PREGRP0 */
1454 { "addps", XM, EX, XX },
1455 { "addss", XM, EX, XX },
1456 { "addpd", XM, EX, XX },
1457 { "addsd", XM, EX, XX },
1459 /* PREGRP1 */
1461 { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */
1462 { "", XM, EX, OPSIMD },
1463 { "", XM, EX, OPSIMD },
1464 { "", XM, EX, OPSIMD },
1466 /* PREGRP2 */
1468 { "cvtpi2ps", XM, EM, XX },
1469 { "cvtsi2ssY", XM, Ev, XX },
1470 { "cvtpi2pd", XM, EM, XX },
1471 { "cvtsi2sdY", XM, Ev, XX },
1473 /* PREGRP3 */
1475 { "cvtps2pi", MX, EX, XX },
1476 { "cvtss2siY", Gv, EX, XX },
1477 { "cvtpd2pi", MX, EX, XX },
1478 { "cvtsd2siY", Gv, EX, XX },
1480 /* PREGRP4 */
1482 { "cvttps2pi", MX, EX, XX },
1483 { "cvttss2siY", Gv, EX, XX },
1484 { "cvttpd2pi", MX, EX, XX },
1485 { "cvttsd2siY", Gv, EX, XX },
1487 /* PREGRP5 */
1489 { "divps", XM, EX, XX },
1490 { "divss", XM, EX, XX },
1491 { "divpd", XM, EX, XX },
1492 { "divsd", XM, EX, XX },
1494 /* PREGRP6 */
1496 { "maxps", XM, EX, XX },
1497 { "maxss", XM, EX, XX },
1498 { "maxpd", XM, EX, XX },
1499 { "maxsd", XM, EX, XX },
1501 /* PREGRP7 */
1503 { "minps", XM, EX, XX },
1504 { "minss", XM, EX, XX },
1505 { "minpd", XM, EX, XX },
1506 { "minsd", XM, EX, XX },
1508 /* PREGRP8 */
1510 { "movups", XM, EX, XX },
1511 { "movss", XM, EX, XX },
1512 { "movupd", XM, EX, XX },
1513 { "movsd", XM, EX, XX },
1515 /* PREGRP9 */
1517 { "movups", EX, XM, XX },
1518 { "movss", EX, XM, XX },
1519 { "movupd", EX, XM, XX },
1520 { "movsd", EX, XM, XX },
1522 /* PREGRP10 */
1524 { "mulps", XM, EX, XX },
1525 { "mulss", XM, EX, XX },
1526 { "mulpd", XM, EX, XX },
1527 { "mulsd", XM, EX, XX },
1529 /* PREGRP11 */
1531 { "rcpps", XM, EX, XX },
1532 { "rcpss", XM, EX, XX },
1533 { "(bad)", XM, EX, XX },
1534 { "(bad)", XM, EX, XX },
1536 /* PREGRP12 */
1538 { "rsqrtps", XM, EX, XX },
1539 { "rsqrtss", XM, EX, XX },
1540 { "(bad)", XM, EX, XX },
1541 { "(bad)", XM, EX, XX },
1543 /* PREGRP13 */
1545 { "sqrtps", XM, EX, XX },
1546 { "sqrtss", XM, EX, XX },
1547 { "sqrtpd", XM, EX, XX },
1548 { "sqrtsd", XM, EX, XX },
1550 /* PREGRP14 */
1552 { "subps", XM, EX, XX },
1553 { "subss", XM, EX, XX },
1554 { "subpd", XM, EX, XX },
1555 { "subsd", XM, EX, XX },
1557 /* PREGRP15 */
1559 { "(bad)", XM, EX, XX },
1560 { "cvtdq2pd", XM, EX, XX },
1561 { "cvttpd2dq", XM, EX, XX },
1562 { "cvtpd2dq", XM, EX, XX },
1564 /* PREGRP16 */
1566 { "cvtdq2ps", XM, EX, XX },
1567 { "cvttps2dq",XM, EX, XX },
1568 { "cvtps2dq",XM, EX, XX },
1569 { "(bad)", XM, EX, XX },
1571 /* PREGRP17 */
1573 { "cvtps2pd", XM, EX, XX },
1574 { "cvtss2sd", XM, EX, XX },
1575 { "cvtpd2ps", XM, EX, XX },
1576 { "cvtsd2ss", XM, EX, XX },
1578 /* PREGRP18 */
1580 { "maskmovq", MX, MS, XX },
1581 { "(bad)", XM, EX, XX },
1582 { "maskmovdqu", XM, EX, XX },
1583 { "(bad)", XM, EX, XX },
1585 /* PREGRP19 */
1587 { "movq", MX, EM, XX },
1588 { "movdqu", XM, EX, XX },
1589 { "movdqa", XM, EX, XX },
1590 { "(bad)", XM, EX, XX },
1592 /* PREGRP20 */
1594 { "movq", EM, MX, XX },
1595 { "movdqu", EX, XM, XX },
1596 { "movdqa", EX, XM, XX },
1597 { "(bad)", EX, XM, XX },
1599 /* PREGRP21 */
1601 { "(bad)", EX, XM, XX },
1602 { "movq2dq", XM, MS, XX },
1603 { "movq", EX, XM, XX },
1604 { "movdq2q", MX, XS, XX },
1606 /* PREGRP22 */
1608 { "pshufw", MX, EM, Ib },
1609 { "pshufhw", XM, EX, Ib },
1610 { "pshufd", XM, EX, Ib },
1611 { "pshuflw", XM, EX, Ib },
1613 /* PREGRP23 */
1615 { "movd", Edq, MX, XX },
1616 { "movq", XM, EX, XX },
1617 { "movd", Edq, XM, XX },
1618 { "(bad)", Ed, XM, XX },
1620 /* PREGRP24 */
1622 { "(bad)", MX, EX, XX },
1623 { "(bad)", XM, EX, XX },
1624 { "punpckhqdq", XM, EX, XX },
1625 { "(bad)", XM, EX, XX },
1627 /* PREGRP25 */
1629 { "movntq", Ev, MX, XX },
1630 { "(bad)", Ev, XM, XX },
1631 { "movntdq", Ev, XM, XX },
1632 { "(bad)", Ev, XM, XX },
1634 /* PREGRP26 */
1636 { "(bad)", MX, EX, XX },
1637 { "(bad)", XM, EX, XX },
1638 { "punpcklqdq", XM, EX, XX },
1639 { "(bad)", XM, EX, XX },
1643 static const struct dis386 x86_64_table[][2] = {
1645 { "arpl", Ew, Gw, XX },
1646 { "movs{||lq|xd}", Gv, Ed, XX },
1650 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1652 static void
1653 ckprefix ()
1655 int newrex;
1656 rex = 0;
1657 prefixes = 0;
1658 used_prefixes = 0;
1659 rex_used = 0;
1660 while (1)
1662 FETCH_DATA (the_info, codep + 1);
1663 newrex = 0;
1664 switch (*codep)
1666 /* REX prefixes family. */
1667 case 0x40:
1668 case 0x41:
1669 case 0x42:
1670 case 0x43:
1671 case 0x44:
1672 case 0x45:
1673 case 0x46:
1674 case 0x47:
1675 case 0x48:
1676 case 0x49:
1677 case 0x4a:
1678 case 0x4b:
1679 case 0x4c:
1680 case 0x4d:
1681 case 0x4e:
1682 case 0x4f:
1683 if (mode_64bit)
1684 newrex = *codep;
1685 else
1686 return;
1687 break;
1688 case 0xf3:
1689 prefixes |= PREFIX_REPZ;
1690 break;
1691 case 0xf2:
1692 prefixes |= PREFIX_REPNZ;
1693 break;
1694 case 0xf0:
1695 prefixes |= PREFIX_LOCK;
1696 break;
1697 case 0x2e:
1698 prefixes |= PREFIX_CS;
1699 break;
1700 case 0x36:
1701 prefixes |= PREFIX_SS;
1702 break;
1703 case 0x3e:
1704 prefixes |= PREFIX_DS;
1705 break;
1706 case 0x26:
1707 prefixes |= PREFIX_ES;
1708 break;
1709 case 0x64:
1710 prefixes |= PREFIX_FS;
1711 break;
1712 case 0x65:
1713 prefixes |= PREFIX_GS;
1714 break;
1715 case 0x66:
1716 prefixes |= PREFIX_DATA;
1717 break;
1718 case 0x67:
1719 prefixes |= PREFIX_ADDR;
1720 break;
1721 case FWAIT_OPCODE:
1722 /* fwait is really an instruction. If there are prefixes
1723 before the fwait, they belong to the fwait, *not* to the
1724 following instruction. */
1725 if (prefixes)
1727 prefixes |= PREFIX_FWAIT;
1728 codep++;
1729 return;
1731 prefixes = PREFIX_FWAIT;
1732 break;
1733 default:
1734 return;
1736 /* Rex is ignored when followed by another prefix. */
1737 if (rex)
1739 oappend (prefix_name (rex, 0));
1740 oappend (" ");
1742 rex = newrex;
1743 codep++;
1747 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
1748 prefix byte. */
1750 static const char *
1751 prefix_name (pref, sizeflag)
1752 int pref;
1753 int sizeflag;
1755 switch (pref)
1757 /* REX prefixes family. */
1758 case 0x40:
1759 return "rex";
1760 case 0x41:
1761 return "rexZ";
1762 case 0x42:
1763 return "rexY";
1764 case 0x43:
1765 return "rexYZ";
1766 case 0x44:
1767 return "rexX";
1768 case 0x45:
1769 return "rexXZ";
1770 case 0x46:
1771 return "rexXY";
1772 case 0x47:
1773 return "rexXYZ";
1774 case 0x48:
1775 return "rex64";
1776 case 0x49:
1777 return "rex64Z";
1778 case 0x4a:
1779 return "rex64Y";
1780 case 0x4b:
1781 return "rex64YZ";
1782 case 0x4c:
1783 return "rex64X";
1784 case 0x4d:
1785 return "rex64XZ";
1786 case 0x4e:
1787 return "rex64XY";
1788 case 0x4f:
1789 return "rex64XYZ";
1790 case 0xf3:
1791 return "repz";
1792 case 0xf2:
1793 return "repnz";
1794 case 0xf0:
1795 return "lock";
1796 case 0x2e:
1797 return "cs";
1798 case 0x36:
1799 return "ss";
1800 case 0x3e:
1801 return "ds";
1802 case 0x26:
1803 return "es";
1804 case 0x64:
1805 return "fs";
1806 case 0x65:
1807 return "gs";
1808 case 0x66:
1809 return (sizeflag & DFLAG) ? "data16" : "data32";
1810 case 0x67:
1811 if (mode_64bit)
1812 return (sizeflag & AFLAG) ? "addr32" : "addr64";
1813 else
1814 return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32";
1815 case FWAIT_OPCODE:
1816 return "fwait";
1817 default:
1818 return NULL;
1822 static char op1out[100], op2out[100], op3out[100];
1823 static int op_ad, op_index[3];
1824 static bfd_vma op_address[3];
1825 static bfd_vma op_riprel[3];
1826 static bfd_vma start_pc;
1829 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1830 * (see topic "Redundant prefixes" in the "Differences from 8086"
1831 * section of the "Virtual 8086 Mode" chapter.)
1832 * 'pc' should be the address of this instruction, it will
1833 * be used to print the target address if this is a relative jump or call
1834 * The function returns the length of this instruction in bytes.
1837 static char intel_syntax;
1838 static char open_char;
1839 static char close_char;
1840 static char separator_char;
1841 static char scale_char;
1843 /* Here for backwards compatibility. When gdb stops using
1844 print_insn_i386_att and print_insn_i386_intel these functions can
1845 disappear, and print_insn_i386 be merged into print_insn. */
1847 print_insn_i386_att (pc, info)
1848 bfd_vma pc;
1849 disassemble_info *info;
1851 intel_syntax = 0;
1853 return print_insn (pc, info);
1857 print_insn_i386_intel (pc, info)
1858 bfd_vma pc;
1859 disassemble_info *info;
1861 intel_syntax = 1;
1863 return print_insn (pc, info);
1867 print_insn_i386 (pc, info)
1868 bfd_vma pc;
1869 disassemble_info *info;
1871 intel_syntax = -1;
1873 return print_insn (pc, info);
1876 static int
1877 print_insn (pc, info)
1878 bfd_vma pc;
1879 disassemble_info *info;
1881 const struct dis386 *dp;
1882 int i;
1883 int two_source_ops;
1884 char *first, *second, *third;
1885 int needcomma;
1886 unsigned char uses_SSE_prefix;
1887 int sizeflag;
1888 const char *p;
1889 struct dis_private priv;
1891 mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
1892 || info->mach == bfd_mach_x86_64);
1894 if (intel_syntax == -1)
1895 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
1896 || info->mach == bfd_mach_x86_64_intel_syntax);
1898 if (info->mach == bfd_mach_i386_i386
1899 || info->mach == bfd_mach_x86_64
1900 || info->mach == bfd_mach_i386_i386_intel_syntax
1901 || info->mach == bfd_mach_x86_64_intel_syntax)
1902 priv.orig_sizeflag = AFLAG | DFLAG;
1903 else if (info->mach == bfd_mach_i386_i8086)
1904 priv.orig_sizeflag = 0;
1905 else
1906 abort ();
1908 for (p = info->disassembler_options; p != NULL; )
1910 if (strncmp (p, "x86-64", 6) == 0)
1912 mode_64bit = 1;
1913 priv.orig_sizeflag = AFLAG | DFLAG;
1915 else if (strncmp (p, "i386", 4) == 0)
1917 mode_64bit = 0;
1918 priv.orig_sizeflag = AFLAG | DFLAG;
1920 else if (strncmp (p, "i8086", 5) == 0)
1922 mode_64bit = 0;
1923 priv.orig_sizeflag = 0;
1925 else if (strncmp (p, "intel", 5) == 0)
1927 intel_syntax = 1;
1929 else if (strncmp (p, "att", 3) == 0)
1931 intel_syntax = 0;
1933 else if (strncmp (p, "addr", 4) == 0)
1935 if (p[4] == '1' && p[5] == '6')
1936 priv.orig_sizeflag &= ~AFLAG;
1937 else if (p[4] == '3' && p[5] == '2')
1938 priv.orig_sizeflag |= AFLAG;
1940 else if (strncmp (p, "data", 4) == 0)
1942 if (p[4] == '1' && p[5] == '6')
1943 priv.orig_sizeflag &= ~DFLAG;
1944 else if (p[4] == '3' && p[5] == '2')
1945 priv.orig_sizeflag |= DFLAG;
1947 else if (strncmp (p, "suffix", 6) == 0)
1948 priv.orig_sizeflag |= SUFFIX_ALWAYS;
1950 p = strchr (p, ',');
1951 if (p != NULL)
1952 p++;
1955 if (intel_syntax)
1957 names64 = intel_names64;
1958 names32 = intel_names32;
1959 names16 = intel_names16;
1960 names8 = intel_names8;
1961 names8rex = intel_names8rex;
1962 names_seg = intel_names_seg;
1963 index16 = intel_index16;
1964 open_char = '[';
1965 close_char = ']';
1966 separator_char = '+';
1967 scale_char = '*';
1969 else
1971 names64 = att_names64;
1972 names32 = att_names32;
1973 names16 = att_names16;
1974 names8 = att_names8;
1975 names8rex = att_names8rex;
1976 names_seg = att_names_seg;
1977 index16 = att_index16;
1978 open_char = '(';
1979 close_char = ')';
1980 separator_char = ',';
1981 scale_char = ',';
1984 /* The output looks better if we put 7 bytes on a line, since that
1985 puts most long word instructions on a single line. */
1986 info->bytes_per_line = 7;
1988 info->private_data = (PTR) &priv;
1989 priv.max_fetched = priv.the_buffer;
1990 priv.insn_start = pc;
1992 obuf[0] = 0;
1993 op1out[0] = 0;
1994 op2out[0] = 0;
1995 op3out[0] = 0;
1997 op_index[0] = op_index[1] = op_index[2] = -1;
1999 the_info = info;
2000 start_pc = pc;
2001 start_codep = priv.the_buffer;
2002 codep = priv.the_buffer;
2004 if (setjmp (priv.bailout) != 0)
2006 const char *name;
2008 /* Getting here means we tried for data but didn't get it. That
2009 means we have an incomplete instruction of some sort. Just
2010 print the first byte as a prefix or a .byte pseudo-op. */
2011 if (codep > priv.the_buffer)
2013 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2014 if (name != NULL)
2015 (*info->fprintf_func) (info->stream, "%s", name);
2016 else
2018 /* Just print the first byte as a .byte instruction. */
2019 (*info->fprintf_func) (info->stream, ".byte 0x%x",
2020 (unsigned int) priv.the_buffer[0]);
2023 return 1;
2026 return -1;
2029 obufp = obuf;
2030 ckprefix ();
2032 insn_codep = codep;
2033 sizeflag = priv.orig_sizeflag;
2035 FETCH_DATA (info, codep + 1);
2036 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
2038 if ((prefixes & PREFIX_FWAIT)
2039 && ((*codep < 0xd8) || (*codep > 0xdf)))
2041 const char *name;
2043 /* fwait not followed by floating point instruction. Print the
2044 first prefix, which is probably fwait itself. */
2045 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2046 if (name == NULL)
2047 name = INTERNAL_DISASSEMBLER_ERROR;
2048 (*info->fprintf_func) (info->stream, "%s", name);
2049 return 1;
2052 if (*codep == 0x0f)
2054 FETCH_DATA (info, codep + 2);
2055 dp = &dis386_twobyte[*++codep];
2056 need_modrm = twobyte_has_modrm[*codep];
2057 uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
2059 else
2061 dp = &dis386[*codep];
2062 need_modrm = onebyte_has_modrm[*codep];
2063 uses_SSE_prefix = 0;
2065 codep++;
2067 if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
2069 oappend ("repz ");
2070 used_prefixes |= PREFIX_REPZ;
2072 if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
2074 oappend ("repnz ");
2075 used_prefixes |= PREFIX_REPNZ;
2077 if (prefixes & PREFIX_LOCK)
2079 oappend ("lock ");
2080 used_prefixes |= PREFIX_LOCK;
2083 if (prefixes & PREFIX_ADDR)
2085 sizeflag ^= AFLAG;
2086 if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
2088 if ((sizeflag & AFLAG) || mode_64bit)
2089 oappend ("addr32 ");
2090 else
2091 oappend ("addr16 ");
2092 used_prefixes |= PREFIX_ADDR;
2096 if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
2098 sizeflag ^= DFLAG;
2099 if (dp->bytemode3 == cond_jump_mode
2100 && dp->bytemode1 == v_mode
2101 && !intel_syntax)
2103 if (sizeflag & DFLAG)
2104 oappend ("data32 ");
2105 else
2106 oappend ("data16 ");
2107 used_prefixes |= PREFIX_DATA;
2111 if (need_modrm)
2113 FETCH_DATA (info, codep + 1);
2114 mod = (*codep >> 6) & 3;
2115 reg = (*codep >> 3) & 7;
2116 rm = *codep & 7;
2119 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2121 dofloat (sizeflag);
2123 else
2125 int index;
2126 if (dp->name == NULL)
2128 switch (dp->bytemode1)
2130 case USE_GROUPS:
2131 dp = &grps[dp->bytemode2][reg];
2132 break;
2134 case USE_PREFIX_USER_TABLE:
2135 index = 0;
2136 used_prefixes |= (prefixes & PREFIX_REPZ);
2137 if (prefixes & PREFIX_REPZ)
2138 index = 1;
2139 else
2141 used_prefixes |= (prefixes & PREFIX_DATA);
2142 if (prefixes & PREFIX_DATA)
2143 index = 2;
2144 else
2146 used_prefixes |= (prefixes & PREFIX_REPNZ);
2147 if (prefixes & PREFIX_REPNZ)
2148 index = 3;
2151 dp = &prefix_user_table[dp->bytemode2][index];
2152 break;
2154 case X86_64_SPECIAL:
2155 dp = &x86_64_table[dp->bytemode2][mode_64bit];
2156 break;
2158 default:
2159 oappend (INTERNAL_DISASSEMBLER_ERROR);
2160 break;
2164 if (putop (dp->name, sizeflag) == 0)
2166 obufp = op1out;
2167 op_ad = 2;
2168 if (dp->op1)
2169 (*dp->op1) (dp->bytemode1, sizeflag);
2171 obufp = op2out;
2172 op_ad = 1;
2173 if (dp->op2)
2174 (*dp->op2) (dp->bytemode2, sizeflag);
2176 obufp = op3out;
2177 op_ad = 0;
2178 if (dp->op3)
2179 (*dp->op3) (dp->bytemode3, sizeflag);
2183 /* See if any prefixes were not used. If so, print the first one
2184 separately. If we don't do this, we'll wind up printing an
2185 instruction stream which does not precisely correspond to the
2186 bytes we are disassembling. */
2187 if ((prefixes & ~used_prefixes) != 0)
2189 const char *name;
2191 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
2192 if (name == NULL)
2193 name = INTERNAL_DISASSEMBLER_ERROR;
2194 (*info->fprintf_func) (info->stream, "%s", name);
2195 return 1;
2197 if (rex & ~rex_used)
2199 const char *name;
2200 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
2201 if (name == NULL)
2202 name = INTERNAL_DISASSEMBLER_ERROR;
2203 (*info->fprintf_func) (info->stream, "%s ", name);
2206 obufp = obuf + strlen (obuf);
2207 for (i = strlen (obuf); i < 6; i++)
2208 oappend (" ");
2209 oappend (" ");
2210 (*info->fprintf_func) (info->stream, "%s", obuf);
2212 /* The enter and bound instructions are printed with operands in the same
2213 order as the intel book; everything else is printed in reverse order. */
2214 if (intel_syntax || two_source_ops)
2216 first = op1out;
2217 second = op2out;
2218 third = op3out;
2219 op_ad = op_index[0];
2220 op_index[0] = op_index[2];
2221 op_index[2] = op_ad;
2223 else
2225 first = op3out;
2226 second = op2out;
2227 third = op1out;
2229 needcomma = 0;
2230 if (*first)
2232 if (op_index[0] != -1 && !op_riprel[0])
2233 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
2234 else
2235 (*info->fprintf_func) (info->stream, "%s", first);
2236 needcomma = 1;
2238 if (*second)
2240 if (needcomma)
2241 (*info->fprintf_func) (info->stream, ",");
2242 if (op_index[1] != -1 && !op_riprel[1])
2243 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
2244 else
2245 (*info->fprintf_func) (info->stream, "%s", second);
2246 needcomma = 1;
2248 if (*third)
2250 if (needcomma)
2251 (*info->fprintf_func) (info->stream, ",");
2252 if (op_index[2] != -1 && !op_riprel[2])
2253 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
2254 else
2255 (*info->fprintf_func) (info->stream, "%s", third);
2257 for (i = 0; i < 3; i++)
2258 if (op_index[i] != -1 && op_riprel[i])
2260 (*info->fprintf_func) (info->stream, " # ");
2261 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
2262 + op_address[op_index[i]]), info);
2264 return codep - priv.the_buffer;
2267 static const char *float_mem[] = {
2268 /* d8 */
2269 "fadd{s||s|}",
2270 "fmul{s||s|}",
2271 "fcom{s||s|}",
2272 "fcomp{s||s|}",
2273 "fsub{s||s|}",
2274 "fsubr{s||s|}",
2275 "fdiv{s||s|}",
2276 "fdivr{s||s|}",
2277 /* d9 */
2278 "fld{s||s|}",
2279 "(bad)",
2280 "fst{s||s|}",
2281 "fstp{s||s|}",
2282 "fldenv",
2283 "fldcw",
2284 "fNstenv",
2285 "fNstcw",
2286 /* da */
2287 "fiadd{l||l|}",
2288 "fimul{l||l|}",
2289 "ficom{l||l|}",
2290 "ficomp{l||l|}",
2291 "fisub{l||l|}",
2292 "fisubr{l||l|}",
2293 "fidiv{l||l|}",
2294 "fidivr{l||l|}",
2295 /* db */
2296 "fild{l||l|}",
2297 "(bad)",
2298 "fist{l||l|}",
2299 "fistp{l||l|}",
2300 "(bad)",
2301 "fld{t||t|}",
2302 "(bad)",
2303 "fstp{t||t|}",
2304 /* dc */
2305 "fadd{l||l|}",
2306 "fmul{l||l|}",
2307 "fcom{l||l|}",
2308 "fcomp{l||l|}",
2309 "fsub{l||l|}",
2310 "fsubr{l||l|}",
2311 "fdiv{l||l|}",
2312 "fdivr{l||l|}",
2313 /* dd */
2314 "fld{l||l|}",
2315 "(bad)",
2316 "fst{l||l|}",
2317 "fstp{l||l|}",
2318 "frstor",
2319 "(bad)",
2320 "fNsave",
2321 "fNstsw",
2322 /* de */
2323 "fiadd",
2324 "fimul",
2325 "ficom",
2326 "ficomp",
2327 "fisub",
2328 "fisubr",
2329 "fidiv",
2330 "fidivr",
2331 /* df */
2332 "fild",
2333 "(bad)",
2334 "fist",
2335 "fistp",
2336 "fbld",
2337 "fild{ll||ll|}",
2338 "fbstp",
2339 "fistpll",
2342 #define ST OP_ST, 0
2343 #define STi OP_STi, 0
2345 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
2346 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
2347 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
2348 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
2349 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
2350 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
2351 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
2352 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
2353 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
2355 static const struct dis386 float_reg[][8] = {
2356 /* d8 */
2358 { "fadd", ST, STi, XX },
2359 { "fmul", ST, STi, XX },
2360 { "fcom", STi, XX, XX },
2361 { "fcomp", STi, XX, XX },
2362 { "fsub", ST, STi, XX },
2363 { "fsubr", ST, STi, XX },
2364 { "fdiv", ST, STi, XX },
2365 { "fdivr", ST, STi, XX },
2367 /* d9 */
2369 { "fld", STi, XX, XX },
2370 { "fxch", STi, XX, XX },
2371 { FGRPd9_2 },
2372 { "(bad)", XX, XX, XX },
2373 { FGRPd9_4 },
2374 { FGRPd9_5 },
2375 { FGRPd9_6 },
2376 { FGRPd9_7 },
2378 /* da */
2380 { "fcmovb", ST, STi, XX },
2381 { "fcmove", ST, STi, XX },
2382 { "fcmovbe",ST, STi, XX },
2383 { "fcmovu", ST, STi, XX },
2384 { "(bad)", XX, XX, XX },
2385 { FGRPda_5 },
2386 { "(bad)", XX, XX, XX },
2387 { "(bad)", XX, XX, XX },
2389 /* db */
2391 { "fcmovnb",ST, STi, XX },
2392 { "fcmovne",ST, STi, XX },
2393 { "fcmovnbe",ST, STi, XX },
2394 { "fcmovnu",ST, STi, XX },
2395 { FGRPdb_4 },
2396 { "fucomi", ST, STi, XX },
2397 { "fcomi", ST, STi, XX },
2398 { "(bad)", XX, XX, XX },
2400 /* dc */
2402 { "fadd", STi, ST, XX },
2403 { "fmul", STi, ST, XX },
2404 { "(bad)", XX, XX, XX },
2405 { "(bad)", XX, XX, XX },
2406 #if UNIXWARE_COMPAT
2407 { "fsub", STi, ST, XX },
2408 { "fsubr", STi, ST, XX },
2409 { "fdiv", STi, ST, XX },
2410 { "fdivr", STi, ST, XX },
2411 #else
2412 { "fsubr", STi, ST, XX },
2413 { "fsub", STi, ST, XX },
2414 { "fdivr", STi, ST, XX },
2415 { "fdiv", STi, ST, XX },
2416 #endif
2418 /* dd */
2420 { "ffree", STi, XX, XX },
2421 { "(bad)", XX, XX, XX },
2422 { "fst", STi, XX, XX },
2423 { "fstp", STi, XX, XX },
2424 { "fucom", STi, XX, XX },
2425 { "fucomp", STi, XX, XX },
2426 { "(bad)", XX, XX, XX },
2427 { "(bad)", XX, XX, XX },
2429 /* de */
2431 { "faddp", STi, ST, XX },
2432 { "fmulp", STi, ST, XX },
2433 { "(bad)", XX, XX, XX },
2434 { FGRPde_3 },
2435 #if UNIXWARE_COMPAT
2436 { "fsubp", STi, ST, XX },
2437 { "fsubrp", STi, ST, XX },
2438 { "fdivp", STi, ST, XX },
2439 { "fdivrp", STi, ST, XX },
2440 #else
2441 { "fsubrp", STi, ST, XX },
2442 { "fsubp", STi, ST, XX },
2443 { "fdivrp", STi, ST, XX },
2444 { "fdivp", STi, ST, XX },
2445 #endif
2447 /* df */
2449 { "ffreep", STi, XX, XX },
2450 { "(bad)", XX, XX, XX },
2451 { "(bad)", XX, XX, XX },
2452 { "(bad)", XX, XX, XX },
2453 { FGRPdf_4 },
2454 { "fucomip",ST, STi, XX },
2455 { "fcomip", ST, STi, XX },
2456 { "(bad)", XX, XX, XX },
2460 static char *fgrps[][8] = {
2461 /* d9_2 0 */
2463 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2466 /* d9_4 1 */
2468 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2471 /* d9_5 2 */
2473 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2476 /* d9_6 3 */
2478 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2481 /* d9_7 4 */
2483 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2486 /* da_5 5 */
2488 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2491 /* db_4 6 */
2493 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2494 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2497 /* de_3 7 */
2499 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2502 /* df_4 8 */
2504 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2508 static void
2509 dofloat (sizeflag)
2510 int sizeflag;
2512 const struct dis386 *dp;
2513 unsigned char floatop;
2515 floatop = codep[-1];
2517 if (mod != 3)
2519 putop (float_mem[(floatop - 0xd8) * 8 + reg], sizeflag);
2520 obufp = op1out;
2521 if (floatop == 0xdb)
2522 OP_E (x_mode, sizeflag);
2523 else if (floatop == 0xdd)
2524 OP_E (d_mode, sizeflag);
2525 else
2526 OP_E (v_mode, sizeflag);
2527 return;
2529 /* Skip mod/rm byte. */
2530 MODRM_CHECK;
2531 codep++;
2533 dp = &float_reg[floatop - 0xd8][reg];
2534 if (dp->name == NULL)
2536 putop (fgrps[dp->bytemode1][rm], sizeflag);
2538 /* Instruction fnstsw is only one with strange arg. */
2539 if (floatop == 0xdf && codep[-1] == 0xe0)
2540 strcpy (op1out, names16[0]);
2542 else
2544 putop (dp->name, sizeflag);
2546 obufp = op1out;
2547 if (dp->op1)
2548 (*dp->op1) (dp->bytemode1, sizeflag);
2549 obufp = op2out;
2550 if (dp->op2)
2551 (*dp->op2) (dp->bytemode2, sizeflag);
2555 static void
2556 OP_ST (bytemode, sizeflag)
2557 int bytemode ATTRIBUTE_UNUSED;
2558 int sizeflag ATTRIBUTE_UNUSED;
2560 oappend ("%st");
2563 static void
2564 OP_STi (bytemode, sizeflag)
2565 int bytemode ATTRIBUTE_UNUSED;
2566 int sizeflag ATTRIBUTE_UNUSED;
2568 sprintf (scratchbuf, "%%st(%d)", rm);
2569 oappend (scratchbuf + intel_syntax);
2572 /* Capital letters in template are macros. */
2573 static int
2574 putop (template, sizeflag)
2575 const char *template;
2576 int sizeflag;
2578 const char *p;
2579 int alt;
2581 for (p = template; *p; p++)
2583 switch (*p)
2585 default:
2586 *obufp++ = *p;
2587 break;
2588 case '{':
2589 alt = 0;
2590 if (intel_syntax)
2591 alt += 1;
2592 if (mode_64bit)
2593 alt += 2;
2594 while (alt != 0)
2596 while (*++p != '|')
2598 if (*p == '}')
2600 /* Alternative not valid. */
2601 strcpy (obuf, "(bad)");
2602 obufp = obuf + 5;
2603 return 1;
2605 else if (*p == '\0')
2606 abort ();
2608 alt--;
2610 break;
2611 case '|':
2612 while (*++p != '}')
2614 if (*p == '\0')
2615 abort ();
2617 break;
2618 case '}':
2619 break;
2620 case 'A':
2621 if (intel_syntax)
2622 break;
2623 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2624 *obufp++ = 'b';
2625 break;
2626 case 'B':
2627 if (intel_syntax)
2628 break;
2629 if (sizeflag & SUFFIX_ALWAYS)
2630 *obufp++ = 'b';
2631 break;
2632 case 'E': /* For jcxz/jecxz */
2633 if (mode_64bit)
2635 if (sizeflag & AFLAG)
2636 *obufp++ = 'r';
2637 else
2638 *obufp++ = 'e';
2640 else
2641 if (sizeflag & AFLAG)
2642 *obufp++ = 'e';
2643 used_prefixes |= (prefixes & PREFIX_ADDR);
2644 break;
2645 case 'F':
2646 if (intel_syntax)
2647 break;
2648 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
2650 if (sizeflag & AFLAG)
2651 *obufp++ = mode_64bit ? 'q' : 'l';
2652 else
2653 *obufp++ = mode_64bit ? 'l' : 'w';
2654 used_prefixes |= (prefixes & PREFIX_ADDR);
2656 break;
2657 case 'H':
2658 if (intel_syntax)
2659 break;
2660 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
2661 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
2663 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
2664 *obufp++ = ',';
2665 *obufp++ = 'p';
2666 if (prefixes & PREFIX_DS)
2667 *obufp++ = 't';
2668 else
2669 *obufp++ = 'n';
2671 break;
2672 case 'L':
2673 if (intel_syntax)
2674 break;
2675 if (sizeflag & SUFFIX_ALWAYS)
2676 *obufp++ = 'l';
2677 break;
2678 case 'N':
2679 if ((prefixes & PREFIX_FWAIT) == 0)
2680 *obufp++ = 'n';
2681 else
2682 used_prefixes |= PREFIX_FWAIT;
2683 break;
2684 case 'O':
2685 USED_REX (REX_MODE64);
2686 if (rex & REX_MODE64)
2687 *obufp++ = 'o';
2688 else
2689 *obufp++ = 'd';
2690 break;
2691 case 'T':
2692 if (intel_syntax)
2693 break;
2694 if (mode_64bit)
2696 *obufp++ = 'q';
2697 break;
2699 /* Fall through. */
2700 case 'P':
2701 if (intel_syntax)
2702 break;
2703 if ((prefixes & PREFIX_DATA)
2704 || (rex & REX_MODE64)
2705 || (sizeflag & SUFFIX_ALWAYS))
2707 USED_REX (REX_MODE64);
2708 if (rex & REX_MODE64)
2709 *obufp++ = 'q';
2710 else
2712 if (sizeflag & DFLAG)
2713 *obufp++ = 'l';
2714 else
2715 *obufp++ = 'w';
2716 used_prefixes |= (prefixes & PREFIX_DATA);
2719 break;
2720 case 'U':
2721 if (intel_syntax)
2722 break;
2723 if (mode_64bit)
2725 *obufp++ = 'q';
2726 break;
2728 /* Fall through. */
2729 case 'Q':
2730 if (intel_syntax)
2731 break;
2732 USED_REX (REX_MODE64);
2733 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
2735 if (rex & REX_MODE64)
2736 *obufp++ = 'q';
2737 else
2739 if (sizeflag & DFLAG)
2740 *obufp++ = 'l';
2741 else
2742 *obufp++ = 'w';
2743 used_prefixes |= (prefixes & PREFIX_DATA);
2746 break;
2747 case 'R':
2748 USED_REX (REX_MODE64);
2749 if (intel_syntax)
2751 if (rex & REX_MODE64)
2753 *obufp++ = 'q';
2754 *obufp++ = 't';
2756 else if (sizeflag & DFLAG)
2758 *obufp++ = 'd';
2759 *obufp++ = 'q';
2761 else
2763 *obufp++ = 'w';
2764 *obufp++ = 'd';
2767 else
2769 if (rex & REX_MODE64)
2770 *obufp++ = 'q';
2771 else if (sizeflag & DFLAG)
2772 *obufp++ = 'l';
2773 else
2774 *obufp++ = 'w';
2776 if (!(rex & REX_MODE64))
2777 used_prefixes |= (prefixes & PREFIX_DATA);
2778 break;
2779 case 'S':
2780 if (intel_syntax)
2781 break;
2782 if (sizeflag & SUFFIX_ALWAYS)
2784 if (rex & REX_MODE64)
2785 *obufp++ = 'q';
2786 else
2788 if (sizeflag & DFLAG)
2789 *obufp++ = 'l';
2790 else
2791 *obufp++ = 'w';
2792 used_prefixes |= (prefixes & PREFIX_DATA);
2795 break;
2796 case 'X':
2797 if (prefixes & PREFIX_DATA)
2798 *obufp++ = 'd';
2799 else
2800 *obufp++ = 's';
2801 used_prefixes |= (prefixes & PREFIX_DATA);
2802 break;
2803 case 'Y':
2804 if (intel_syntax)
2805 break;
2806 if (rex & REX_MODE64)
2808 USED_REX (REX_MODE64);
2809 *obufp++ = 'q';
2811 break;
2812 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
2813 case 'W':
2814 /* operand size flag for cwtl, cbtw */
2815 USED_REX (0);
2816 if (rex)
2817 *obufp++ = 'l';
2818 else if (sizeflag & DFLAG)
2819 *obufp++ = 'w';
2820 else
2821 *obufp++ = 'b';
2822 if (intel_syntax)
2824 if (rex)
2826 *obufp++ = 'q';
2827 *obufp++ = 'e';
2829 if (sizeflag & DFLAG)
2831 *obufp++ = 'd';
2832 *obufp++ = 'e';
2834 else
2836 *obufp++ = 'w';
2839 if (!rex)
2840 used_prefixes |= (prefixes & PREFIX_DATA);
2841 break;
2844 *obufp = 0;
2845 return 0;
2848 static void
2849 oappend (s)
2850 const char *s;
2852 strcpy (obufp, s);
2853 obufp += strlen (s);
2856 static void
2857 append_seg ()
2859 if (prefixes & PREFIX_CS)
2861 used_prefixes |= PREFIX_CS;
2862 oappend ("%cs:" + intel_syntax);
2864 if (prefixes & PREFIX_DS)
2866 used_prefixes |= PREFIX_DS;
2867 oappend ("%ds:" + intel_syntax);
2869 if (prefixes & PREFIX_SS)
2871 used_prefixes |= PREFIX_SS;
2872 oappend ("%ss:" + intel_syntax);
2874 if (prefixes & PREFIX_ES)
2876 used_prefixes |= PREFIX_ES;
2877 oappend ("%es:" + intel_syntax);
2879 if (prefixes & PREFIX_FS)
2881 used_prefixes |= PREFIX_FS;
2882 oappend ("%fs:" + intel_syntax);
2884 if (prefixes & PREFIX_GS)
2886 used_prefixes |= PREFIX_GS;
2887 oappend ("%gs:" + intel_syntax);
2891 static void
2892 OP_indirE (bytemode, sizeflag)
2893 int bytemode;
2894 int sizeflag;
2896 if (!intel_syntax)
2897 oappend ("*");
2898 OP_E (bytemode, sizeflag);
2901 static void
2902 print_operand_value (buf, hex, disp)
2903 char *buf;
2904 int hex;
2905 bfd_vma disp;
2907 if (mode_64bit)
2909 if (hex)
2911 char tmp[30];
2912 int i;
2913 buf[0] = '0';
2914 buf[1] = 'x';
2915 sprintf_vma (tmp, disp);
2916 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
2917 strcpy (buf + 2, tmp + i);
2919 else
2921 bfd_signed_vma v = disp;
2922 char tmp[30];
2923 int i;
2924 if (v < 0)
2926 *(buf++) = '-';
2927 v = -disp;
2928 /* Check for possible overflow on 0x8000000000000000. */
2929 if (v < 0)
2931 strcpy (buf, "9223372036854775808");
2932 return;
2935 if (!v)
2937 strcpy (buf, "0");
2938 return;
2941 i = 0;
2942 tmp[29] = 0;
2943 while (v)
2945 tmp[28 - i] = (v % 10) + '0';
2946 v /= 10;
2947 i++;
2949 strcpy (buf, tmp + 29 - i);
2952 else
2954 if (hex)
2955 sprintf (buf, "0x%x", (unsigned int) disp);
2956 else
2957 sprintf (buf, "%d", (int) disp);
2961 static void
2962 OP_E (bytemode, sizeflag)
2963 int bytemode;
2964 int sizeflag;
2966 bfd_vma disp;
2967 int add = 0;
2968 int riprel = 0;
2969 USED_REX (REX_EXTZ);
2970 if (rex & REX_EXTZ)
2971 add += 8;
2973 /* Skip mod/rm byte. */
2974 MODRM_CHECK;
2975 codep++;
2977 if (mod == 3)
2979 switch (bytemode)
2981 case b_mode:
2982 USED_REX (0);
2983 if (rex)
2984 oappend (names8rex[rm + add]);
2985 else
2986 oappend (names8[rm + add]);
2987 break;
2988 case w_mode:
2989 oappend (names16[rm + add]);
2990 break;
2991 case d_mode:
2992 oappend (names32[rm + add]);
2993 break;
2994 case q_mode:
2995 oappend (names64[rm + add]);
2996 break;
2997 case m_mode:
2998 if (mode_64bit)
2999 oappend (names64[rm + add]);
3000 else
3001 oappend (names32[rm + add]);
3002 break;
3003 case v_mode:
3004 case dq_mode:
3005 USED_REX (REX_MODE64);
3006 if (rex & REX_MODE64)
3007 oappend (names64[rm + add]);
3008 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
3009 oappend (names32[rm + add]);
3010 else
3011 oappend (names16[rm + add]);
3012 used_prefixes |= (prefixes & PREFIX_DATA);
3013 break;
3014 case 0:
3015 if (!(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */)
3016 && !(codep[-2] == 0xAE && codep[-1] == 0xF0 /* mfence */)
3017 && !(codep[-2] == 0xAE && codep[-1] == 0xe8 /* lfence */))
3018 BadOp (); /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */
3019 break;
3020 default:
3021 oappend (INTERNAL_DISASSEMBLER_ERROR);
3022 break;
3024 return;
3027 disp = 0;
3028 append_seg ();
3030 if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
3032 int havesib;
3033 int havebase;
3034 int base;
3035 int index = 0;
3036 int scale = 0;
3038 havesib = 0;
3039 havebase = 1;
3040 base = rm;
3042 if (base == 4)
3044 havesib = 1;
3045 FETCH_DATA (the_info, codep + 1);
3046 scale = (*codep >> 6) & 3;
3047 index = (*codep >> 3) & 7;
3048 base = *codep & 7;
3049 USED_REX (REX_EXTY);
3050 USED_REX (REX_EXTZ);
3051 if (rex & REX_EXTY)
3052 index += 8;
3053 if (rex & REX_EXTZ)
3054 base += 8;
3055 codep++;
3058 switch (mod)
3060 case 0:
3061 if ((base & 7) == 5)
3063 havebase = 0;
3064 if (mode_64bit && !havesib && (sizeflag & AFLAG))
3065 riprel = 1;
3066 disp = get32s ();
3068 break;
3069 case 1:
3070 FETCH_DATA (the_info, codep + 1);
3071 disp = *codep++;
3072 if ((disp & 0x80) != 0)
3073 disp -= 0x100;
3074 break;
3075 case 2:
3076 disp = get32s ();
3077 break;
3080 if (!intel_syntax)
3081 if (mod != 0 || (base & 7) == 5)
3083 print_operand_value (scratchbuf, !riprel, disp);
3084 oappend (scratchbuf);
3085 if (riprel)
3087 set_op (disp, 1);
3088 oappend ("(%rip)");
3092 if (havebase || (havesib && (index != 4 || scale != 0)))
3094 if (intel_syntax)
3096 switch (bytemode)
3098 case b_mode:
3099 oappend ("BYTE PTR ");
3100 break;
3101 case w_mode:
3102 oappend ("WORD PTR ");
3103 break;
3104 case v_mode:
3105 oappend ("DWORD PTR ");
3106 break;
3107 case d_mode:
3108 oappend ("QWORD PTR ");
3109 break;
3110 case m_mode:
3111 if (mode_64bit)
3112 oappend ("DWORD PTR ");
3113 else
3114 oappend ("QWORD PTR ");
3115 break;
3116 case x_mode:
3117 oappend ("XWORD PTR ");
3118 break;
3119 default:
3120 break;
3123 *obufp++ = open_char;
3124 if (intel_syntax && riprel)
3125 oappend ("rip + ");
3126 *obufp = '\0';
3127 USED_REX (REX_EXTZ);
3128 if (!havesib && (rex & REX_EXTZ))
3129 base += 8;
3130 if (havebase)
3131 oappend (mode_64bit && (sizeflag & AFLAG)
3132 ? names64[base] : names32[base]);
3133 if (havesib)
3135 if (index != 4)
3137 if (intel_syntax)
3139 if (havebase)
3141 *obufp++ = separator_char;
3142 *obufp = '\0';
3144 sprintf (scratchbuf, "%s",
3145 mode_64bit && (sizeflag & AFLAG)
3146 ? names64[index] : names32[index]);
3148 else
3149 sprintf (scratchbuf, ",%s",
3150 mode_64bit && (sizeflag & AFLAG)
3151 ? names64[index] : names32[index]);
3152 oappend (scratchbuf);
3154 if (!intel_syntax
3155 || (intel_syntax
3156 && bytemode != b_mode
3157 && bytemode != w_mode
3158 && bytemode != v_mode))
3160 *obufp++ = scale_char;
3161 *obufp = '\0';
3162 sprintf (scratchbuf, "%d", 1 << scale);
3163 oappend (scratchbuf);
3166 if (intel_syntax)
3167 if (mod != 0 || (base & 7) == 5)
3169 /* Don't print zero displacements. */
3170 if (disp != 0)
3172 if ((bfd_signed_vma) disp > 0)
3174 *obufp++ = '+';
3175 *obufp = '\0';
3178 print_operand_value (scratchbuf, 0, disp);
3179 oappend (scratchbuf);
3183 *obufp++ = close_char;
3184 *obufp = '\0';
3186 else if (intel_syntax)
3188 if (mod != 0 || (base & 7) == 5)
3190 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3191 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
3193 else
3195 oappend (names_seg[ds_reg - es_reg]);
3196 oappend (":");
3198 print_operand_value (scratchbuf, 1, disp);
3199 oappend (scratchbuf);
3203 else
3204 { /* 16 bit address mode */
3205 switch (mod)
3207 case 0:
3208 if ((rm & 7) == 6)
3210 disp = get16 ();
3211 if ((disp & 0x8000) != 0)
3212 disp -= 0x10000;
3214 break;
3215 case 1:
3216 FETCH_DATA (the_info, codep + 1);
3217 disp = *codep++;
3218 if ((disp & 0x80) != 0)
3219 disp -= 0x100;
3220 break;
3221 case 2:
3222 disp = get16 ();
3223 if ((disp & 0x8000) != 0)
3224 disp -= 0x10000;
3225 break;
3228 if (!intel_syntax)
3229 if (mod != 0 || (rm & 7) == 6)
3231 print_operand_value (scratchbuf, 0, disp);
3232 oappend (scratchbuf);
3235 if (mod != 0 || (rm & 7) != 6)
3237 *obufp++ = open_char;
3238 *obufp = '\0';
3239 oappend (index16[rm + add]);
3240 *obufp++ = close_char;
3241 *obufp = '\0';
3246 static void
3247 OP_G (bytemode, sizeflag)
3248 int bytemode;
3249 int sizeflag;
3251 int add = 0;
3252 USED_REX (REX_EXTX);
3253 if (rex & REX_EXTX)
3254 add += 8;
3255 switch (bytemode)
3257 case b_mode:
3258 USED_REX (0);
3259 if (rex)
3260 oappend (names8rex[reg + add]);
3261 else
3262 oappend (names8[reg + add]);
3263 break;
3264 case w_mode:
3265 oappend (names16[reg + add]);
3266 break;
3267 case d_mode:
3268 oappend (names32[reg + add]);
3269 break;
3270 case q_mode:
3271 oappend (names64[reg + add]);
3272 break;
3273 case v_mode:
3274 USED_REX (REX_MODE64);
3275 if (rex & REX_MODE64)
3276 oappend (names64[reg + add]);
3277 else if (sizeflag & DFLAG)
3278 oappend (names32[reg + add]);
3279 else
3280 oappend (names16[reg + add]);
3281 used_prefixes |= (prefixes & PREFIX_DATA);
3282 break;
3283 default:
3284 oappend (INTERNAL_DISASSEMBLER_ERROR);
3285 break;
3289 static bfd_vma
3290 get64 ()
3292 bfd_vma x;
3293 #ifdef BFD64
3294 unsigned int a;
3295 unsigned int b;
3297 FETCH_DATA (the_info, codep + 8);
3298 a = *codep++ & 0xff;
3299 a |= (*codep++ & 0xff) << 8;
3300 a |= (*codep++ & 0xff) << 16;
3301 a |= (*codep++ & 0xff) << 24;
3302 b = *codep++ & 0xff;
3303 b |= (*codep++ & 0xff) << 8;
3304 b |= (*codep++ & 0xff) << 16;
3305 b |= (*codep++ & 0xff) << 24;
3306 x = a + ((bfd_vma) b << 32);
3307 #else
3308 abort ();
3309 x = 0;
3310 #endif
3311 return x;
3314 static bfd_signed_vma
3315 get32 ()
3317 bfd_signed_vma x = 0;
3319 FETCH_DATA (the_info, codep + 4);
3320 x = *codep++ & (bfd_signed_vma) 0xff;
3321 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3322 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3323 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3324 return x;
3327 static bfd_signed_vma
3328 get32s ()
3330 bfd_signed_vma x = 0;
3332 FETCH_DATA (the_info, codep + 4);
3333 x = *codep++ & (bfd_signed_vma) 0xff;
3334 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3335 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3336 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3338 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
3340 return x;
3343 static int
3344 get16 ()
3346 int x = 0;
3348 FETCH_DATA (the_info, codep + 2);
3349 x = *codep++ & 0xff;
3350 x |= (*codep++ & 0xff) << 8;
3351 return x;
3354 static void
3355 set_op (op, riprel)
3356 bfd_vma op;
3357 int riprel;
3359 op_index[op_ad] = op_ad;
3360 if (mode_64bit)
3362 op_address[op_ad] = op;
3363 op_riprel[op_ad] = riprel;
3365 else
3367 /* Mask to get a 32-bit address. */
3368 op_address[op_ad] = op & 0xffffffff;
3369 op_riprel[op_ad] = riprel & 0xffffffff;
3373 static void
3374 OP_REG (code, sizeflag)
3375 int code;
3376 int sizeflag;
3378 const char *s;
3379 int add = 0;
3380 USED_REX (REX_EXTZ);
3381 if (rex & REX_EXTZ)
3382 add = 8;
3384 switch (code)
3386 case indir_dx_reg:
3387 if (intel_syntax)
3388 s = "[dx]";
3389 else
3390 s = "(%dx)";
3391 break;
3392 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3393 case sp_reg: case bp_reg: case si_reg: case di_reg:
3394 s = names16[code - ax_reg + add];
3395 break;
3396 case es_reg: case ss_reg: case cs_reg:
3397 case ds_reg: case fs_reg: case gs_reg:
3398 s = names_seg[code - es_reg + add];
3399 break;
3400 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3401 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3402 USED_REX (0);
3403 if (rex)
3404 s = names8rex[code - al_reg + add];
3405 else
3406 s = names8[code - al_reg];
3407 break;
3408 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
3409 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
3410 if (mode_64bit)
3412 s = names64[code - rAX_reg + add];
3413 break;
3415 code += eAX_reg - rAX_reg;
3416 /* Fall through. */
3417 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3418 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3419 USED_REX (REX_MODE64);
3420 if (rex & REX_MODE64)
3421 s = names64[code - eAX_reg + add];
3422 else if (sizeflag & DFLAG)
3423 s = names32[code - eAX_reg + add];
3424 else
3425 s = names16[code - eAX_reg + add];
3426 used_prefixes |= (prefixes & PREFIX_DATA);
3427 break;
3428 default:
3429 s = INTERNAL_DISASSEMBLER_ERROR;
3430 break;
3432 oappend (s);
3435 static void
3436 OP_IMREG (code, sizeflag)
3437 int code;
3438 int sizeflag;
3440 const char *s;
3442 switch (code)
3444 case indir_dx_reg:
3445 if (intel_syntax)
3446 s = "[dx]";
3447 else
3448 s = "(%dx)";
3449 break;
3450 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3451 case sp_reg: case bp_reg: case si_reg: case di_reg:
3452 s = names16[code - ax_reg];
3453 break;
3454 case es_reg: case ss_reg: case cs_reg:
3455 case ds_reg: case fs_reg: case gs_reg:
3456 s = names_seg[code - es_reg];
3457 break;
3458 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3459 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3460 USED_REX (0);
3461 if (rex)
3462 s = names8rex[code - al_reg];
3463 else
3464 s = names8[code - al_reg];
3465 break;
3466 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3467 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3468 USED_REX (REX_MODE64);
3469 if (rex & REX_MODE64)
3470 s = names64[code - eAX_reg];
3471 else if (sizeflag & DFLAG)
3472 s = names32[code - eAX_reg];
3473 else
3474 s = names16[code - eAX_reg];
3475 used_prefixes |= (prefixes & PREFIX_DATA);
3476 break;
3477 default:
3478 s = INTERNAL_DISASSEMBLER_ERROR;
3479 break;
3481 oappend (s);
3484 static void
3485 OP_I (bytemode, sizeflag)
3486 int bytemode;
3487 int sizeflag;
3489 bfd_signed_vma op;
3490 bfd_signed_vma mask = -1;
3492 switch (bytemode)
3494 case b_mode:
3495 FETCH_DATA (the_info, codep + 1);
3496 op = *codep++;
3497 mask = 0xff;
3498 break;
3499 case q_mode:
3500 if (mode_64bit)
3502 op = get32s ();
3503 break;
3505 /* Fall through. */
3506 case v_mode:
3507 USED_REX (REX_MODE64);
3508 if (rex & REX_MODE64)
3509 op = get32s ();
3510 else if (sizeflag & DFLAG)
3512 op = get32 ();
3513 mask = 0xffffffff;
3515 else
3517 op = get16 ();
3518 mask = 0xfffff;
3520 used_prefixes |= (prefixes & PREFIX_DATA);
3521 break;
3522 case w_mode:
3523 mask = 0xfffff;
3524 op = get16 ();
3525 break;
3526 default:
3527 oappend (INTERNAL_DISASSEMBLER_ERROR);
3528 return;
3531 op &= mask;
3532 scratchbuf[0] = '$';
3533 print_operand_value (scratchbuf + 1, 1, op);
3534 oappend (scratchbuf + intel_syntax);
3535 scratchbuf[0] = '\0';
3538 static void
3539 OP_I64 (bytemode, sizeflag)
3540 int bytemode;
3541 int sizeflag;
3543 bfd_signed_vma op;
3544 bfd_signed_vma mask = -1;
3546 if (!mode_64bit)
3548 OP_I (bytemode, sizeflag);
3549 return;
3552 switch (bytemode)
3554 case b_mode:
3555 FETCH_DATA (the_info, codep + 1);
3556 op = *codep++;
3557 mask = 0xff;
3558 break;
3559 case v_mode:
3560 USED_REX (REX_MODE64);
3561 if (rex & REX_MODE64)
3562 op = get64 ();
3563 else if (sizeflag & DFLAG)
3565 op = get32 ();
3566 mask = 0xffffffff;
3568 else
3570 op = get16 ();
3571 mask = 0xfffff;
3573 used_prefixes |= (prefixes & PREFIX_DATA);
3574 break;
3575 case w_mode:
3576 mask = 0xfffff;
3577 op = get16 ();
3578 break;
3579 default:
3580 oappend (INTERNAL_DISASSEMBLER_ERROR);
3581 return;
3584 op &= mask;
3585 scratchbuf[0] = '$';
3586 print_operand_value (scratchbuf + 1, 1, op);
3587 oappend (scratchbuf + intel_syntax);
3588 scratchbuf[0] = '\0';
3591 static void
3592 OP_sI (bytemode, sizeflag)
3593 int bytemode;
3594 int sizeflag;
3596 bfd_signed_vma op;
3597 bfd_signed_vma mask = -1;
3599 switch (bytemode)
3601 case b_mode:
3602 FETCH_DATA (the_info, codep + 1);
3603 op = *codep++;
3604 if ((op & 0x80) != 0)
3605 op -= 0x100;
3606 mask = 0xffffffff;
3607 break;
3608 case v_mode:
3609 USED_REX (REX_MODE64);
3610 if (rex & REX_MODE64)
3611 op = get32s ();
3612 else if (sizeflag & DFLAG)
3614 op = get32s ();
3615 mask = 0xffffffff;
3617 else
3619 mask = 0xffffffff;
3620 op = get16 ();
3621 if ((op & 0x8000) != 0)
3622 op -= 0x10000;
3624 used_prefixes |= (prefixes & PREFIX_DATA);
3625 break;
3626 case w_mode:
3627 op = get16 ();
3628 mask = 0xffffffff;
3629 if ((op & 0x8000) != 0)
3630 op -= 0x10000;
3631 break;
3632 default:
3633 oappend (INTERNAL_DISASSEMBLER_ERROR);
3634 return;
3637 scratchbuf[0] = '$';
3638 print_operand_value (scratchbuf + 1, 1, op);
3639 oappend (scratchbuf + intel_syntax);
3642 static void
3643 OP_J (bytemode, sizeflag)
3644 int bytemode;
3645 int sizeflag;
3647 bfd_vma disp;
3648 bfd_vma mask = -1;
3650 switch (bytemode)
3652 case b_mode:
3653 FETCH_DATA (the_info, codep + 1);
3654 disp = *codep++;
3655 if ((disp & 0x80) != 0)
3656 disp -= 0x100;
3657 break;
3658 case v_mode:
3659 if (sizeflag & DFLAG)
3660 disp = get32s ();
3661 else
3663 disp = get16 ();
3664 /* For some reason, a data16 prefix on a jump instruction
3665 means that the pc is masked to 16 bits after the
3666 displacement is added! */
3667 mask = 0xffff;
3669 break;
3670 default:
3671 oappend (INTERNAL_DISASSEMBLER_ERROR);
3672 return;
3674 disp = (start_pc + codep - start_codep + disp) & mask;
3675 set_op (disp, 0);
3676 print_operand_value (scratchbuf, 1, disp);
3677 oappend (scratchbuf);
3680 static void
3681 OP_SEG (dummy, sizeflag)
3682 int dummy ATTRIBUTE_UNUSED;
3683 int sizeflag ATTRIBUTE_UNUSED;
3685 oappend (names_seg[reg]);
3688 static void
3689 OP_DIR (dummy, sizeflag)
3690 int dummy ATTRIBUTE_UNUSED;
3691 int sizeflag;
3693 int seg, offset;
3695 if (sizeflag & DFLAG)
3697 offset = get32 ();
3698 seg = get16 ();
3700 else
3702 offset = get16 ();
3703 seg = get16 ();
3705 used_prefixes |= (prefixes & PREFIX_DATA);
3706 if (intel_syntax)
3707 sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
3708 else
3709 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3710 oappend (scratchbuf);
3713 static void
3714 OP_OFF (bytemode, sizeflag)
3715 int bytemode ATTRIBUTE_UNUSED;
3716 int sizeflag;
3718 bfd_vma off;
3720 append_seg ();
3722 if ((sizeflag & AFLAG) || mode_64bit)
3723 off = get32 ();
3724 else
3725 off = get16 ();
3727 if (intel_syntax)
3729 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3730 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3732 oappend (names_seg[ds_reg - es_reg]);
3733 oappend (":");
3736 print_operand_value (scratchbuf, 1, off);
3737 oappend (scratchbuf);
3740 static void
3741 OP_OFF64 (bytemode, sizeflag)
3742 int bytemode ATTRIBUTE_UNUSED;
3743 int sizeflag ATTRIBUTE_UNUSED;
3745 bfd_vma off;
3747 if (!mode_64bit)
3749 OP_OFF (bytemode, sizeflag);
3750 return;
3753 append_seg ();
3755 off = get64 ();
3757 if (intel_syntax)
3759 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3760 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3762 oappend (names_seg[ds_reg - es_reg]);
3763 oappend (":");
3766 print_operand_value (scratchbuf, 1, off);
3767 oappend (scratchbuf);
3770 static void
3771 ptr_reg (code, sizeflag)
3772 int code;
3773 int sizeflag;
3775 const char *s;
3776 if (intel_syntax)
3777 oappend ("[");
3778 else
3779 oappend ("(");
3781 USED_REX (REX_MODE64);
3782 if (rex & REX_MODE64)
3784 if (!(sizeflag & AFLAG))
3785 s = names32[code - eAX_reg];
3786 else
3787 s = names64[code - eAX_reg];
3789 else if (sizeflag & AFLAG)
3790 s = names32[code - eAX_reg];
3791 else
3792 s = names16[code - eAX_reg];
3793 oappend (s);
3794 if (intel_syntax)
3795 oappend ("]");
3796 else
3797 oappend (")");
3800 static void
3801 OP_ESreg (code, sizeflag)
3802 int code;
3803 int sizeflag;
3805 oappend ("%es:" + intel_syntax);
3806 ptr_reg (code, sizeflag);
3809 static void
3810 OP_DSreg (code, sizeflag)
3811 int code;
3812 int sizeflag;
3814 if ((prefixes
3815 & (PREFIX_CS
3816 | PREFIX_DS
3817 | PREFIX_SS
3818 | PREFIX_ES
3819 | PREFIX_FS
3820 | PREFIX_GS)) == 0)
3821 prefixes |= PREFIX_DS;
3822 append_seg ();
3823 ptr_reg (code, sizeflag);
3826 static void
3827 OP_C (dummy, sizeflag)
3828 int dummy ATTRIBUTE_UNUSED;
3829 int sizeflag ATTRIBUTE_UNUSED;
3831 int add = 0;
3832 USED_REX (REX_EXTX);
3833 if (rex & REX_EXTX)
3834 add = 8;
3835 sprintf (scratchbuf, "%%cr%d", reg + add);
3836 oappend (scratchbuf + intel_syntax);
3839 static void
3840 OP_D (dummy, sizeflag)
3841 int dummy ATTRIBUTE_UNUSED;
3842 int sizeflag ATTRIBUTE_UNUSED;
3844 int add = 0;
3845 USED_REX (REX_EXTX);
3846 if (rex & REX_EXTX)
3847 add = 8;
3848 if (intel_syntax)
3849 sprintf (scratchbuf, "db%d", reg + add);
3850 else
3851 sprintf (scratchbuf, "%%db%d", reg + add);
3852 oappend (scratchbuf);
3855 static void
3856 OP_T (dummy, sizeflag)
3857 int dummy ATTRIBUTE_UNUSED;
3858 int sizeflag ATTRIBUTE_UNUSED;
3860 sprintf (scratchbuf, "%%tr%d", reg);
3861 oappend (scratchbuf + intel_syntax);
3864 static void
3865 OP_Rd (bytemode, sizeflag)
3866 int bytemode;
3867 int sizeflag;
3869 if (mod == 3)
3870 OP_E (bytemode, sizeflag);
3871 else
3872 BadOp ();
3875 static void
3876 OP_MMX (bytemode, sizeflag)
3877 int bytemode ATTRIBUTE_UNUSED;
3878 int sizeflag ATTRIBUTE_UNUSED;
3880 int add = 0;
3881 USED_REX (REX_EXTX);
3882 if (rex & REX_EXTX)
3883 add = 8;
3884 used_prefixes |= (prefixes & PREFIX_DATA);
3885 if (prefixes & PREFIX_DATA)
3886 sprintf (scratchbuf, "%%xmm%d", reg + add);
3887 else
3888 sprintf (scratchbuf, "%%mm%d", reg + add);
3889 oappend (scratchbuf + intel_syntax);
3892 static void
3893 OP_XMM (bytemode, sizeflag)
3894 int bytemode ATTRIBUTE_UNUSED;
3895 int sizeflag ATTRIBUTE_UNUSED;
3897 int add = 0;
3898 USED_REX (REX_EXTX);
3899 if (rex & REX_EXTX)
3900 add = 8;
3901 sprintf (scratchbuf, "%%xmm%d", reg + add);
3902 oappend (scratchbuf + intel_syntax);
3905 static void
3906 OP_EM (bytemode, sizeflag)
3907 int bytemode;
3908 int sizeflag;
3910 int add = 0;
3911 if (mod != 3)
3913 OP_E (bytemode, sizeflag);
3914 return;
3916 USED_REX (REX_EXTZ);
3917 if (rex & REX_EXTZ)
3918 add = 8;
3920 /* Skip mod/rm byte. */
3921 MODRM_CHECK;
3922 codep++;
3923 used_prefixes |= (prefixes & PREFIX_DATA);
3924 if (prefixes & PREFIX_DATA)
3925 sprintf (scratchbuf, "%%xmm%d", rm + add);
3926 else
3927 sprintf (scratchbuf, "%%mm%d", rm + add);
3928 oappend (scratchbuf + intel_syntax);
3931 static void
3932 OP_EX (bytemode, sizeflag)
3933 int bytemode;
3934 int sizeflag;
3936 int add = 0;
3937 if (mod != 3)
3939 OP_E (bytemode, sizeflag);
3940 return;
3942 USED_REX (REX_EXTZ);
3943 if (rex & REX_EXTZ)
3944 add = 8;
3946 /* Skip mod/rm byte. */
3947 MODRM_CHECK;
3948 codep++;
3949 sprintf (scratchbuf, "%%xmm%d", rm + add);
3950 oappend (scratchbuf + intel_syntax);
3953 static void
3954 OP_MS (bytemode, sizeflag)
3955 int bytemode;
3956 int sizeflag;
3958 if (mod == 3)
3959 OP_EM (bytemode, sizeflag);
3960 else
3961 BadOp ();
3964 static void
3965 OP_XS (bytemode, sizeflag)
3966 int bytemode;
3967 int sizeflag;
3969 if (mod == 3)
3970 OP_EX (bytemode, sizeflag);
3971 else
3972 BadOp ();
3975 static const char *const Suffix3DNow[] = {
3976 /* 00 */ NULL, NULL, NULL, NULL,
3977 /* 04 */ NULL, NULL, NULL, NULL,
3978 /* 08 */ NULL, NULL, NULL, NULL,
3979 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
3980 /* 10 */ NULL, NULL, NULL, NULL,
3981 /* 14 */ NULL, NULL, NULL, NULL,
3982 /* 18 */ NULL, NULL, NULL, NULL,
3983 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
3984 /* 20 */ NULL, NULL, NULL, NULL,
3985 /* 24 */ NULL, NULL, NULL, NULL,
3986 /* 28 */ NULL, NULL, NULL, NULL,
3987 /* 2C */ NULL, NULL, NULL, NULL,
3988 /* 30 */ NULL, NULL, NULL, NULL,
3989 /* 34 */ NULL, NULL, NULL, NULL,
3990 /* 38 */ NULL, NULL, NULL, NULL,
3991 /* 3C */ NULL, NULL, NULL, NULL,
3992 /* 40 */ NULL, NULL, NULL, NULL,
3993 /* 44 */ NULL, NULL, NULL, NULL,
3994 /* 48 */ NULL, NULL, NULL, NULL,
3995 /* 4C */ NULL, NULL, NULL, NULL,
3996 /* 50 */ NULL, NULL, NULL, NULL,
3997 /* 54 */ NULL, NULL, NULL, NULL,
3998 /* 58 */ NULL, NULL, NULL, NULL,
3999 /* 5C */ NULL, NULL, NULL, NULL,
4000 /* 60 */ NULL, NULL, NULL, NULL,
4001 /* 64 */ NULL, NULL, NULL, NULL,
4002 /* 68 */ NULL, NULL, NULL, NULL,
4003 /* 6C */ NULL, NULL, NULL, NULL,
4004 /* 70 */ NULL, NULL, NULL, NULL,
4005 /* 74 */ NULL, NULL, NULL, NULL,
4006 /* 78 */ NULL, NULL, NULL, NULL,
4007 /* 7C */ NULL, NULL, NULL, NULL,
4008 /* 80 */ NULL, NULL, NULL, NULL,
4009 /* 84 */ NULL, NULL, NULL, NULL,
4010 /* 88 */ NULL, NULL, "pfnacc", NULL,
4011 /* 8C */ NULL, NULL, "pfpnacc", NULL,
4012 /* 90 */ "pfcmpge", NULL, NULL, NULL,
4013 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
4014 /* 98 */ NULL, NULL, "pfsub", NULL,
4015 /* 9C */ NULL, NULL, "pfadd", NULL,
4016 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
4017 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
4018 /* A8 */ NULL, NULL, "pfsubr", NULL,
4019 /* AC */ NULL, NULL, "pfacc", NULL,
4020 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
4021 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
4022 /* B8 */ NULL, NULL, NULL, "pswapd",
4023 /* BC */ NULL, NULL, NULL, "pavgusb",
4024 /* C0 */ NULL, NULL, NULL, NULL,
4025 /* C4 */ NULL, NULL, NULL, NULL,
4026 /* C8 */ NULL, NULL, NULL, NULL,
4027 /* CC */ NULL, NULL, NULL, NULL,
4028 /* D0 */ NULL, NULL, NULL, NULL,
4029 /* D4 */ NULL, NULL, NULL, NULL,
4030 /* D8 */ NULL, NULL, NULL, NULL,
4031 /* DC */ NULL, NULL, NULL, NULL,
4032 /* E0 */ NULL, NULL, NULL, NULL,
4033 /* E4 */ NULL, NULL, NULL, NULL,
4034 /* E8 */ NULL, NULL, NULL, NULL,
4035 /* EC */ NULL, NULL, NULL, NULL,
4036 /* F0 */ NULL, NULL, NULL, NULL,
4037 /* F4 */ NULL, NULL, NULL, NULL,
4038 /* F8 */ NULL, NULL, NULL, NULL,
4039 /* FC */ NULL, NULL, NULL, NULL,
4042 static void
4043 OP_3DNowSuffix (bytemode, sizeflag)
4044 int bytemode ATTRIBUTE_UNUSED;
4045 int sizeflag ATTRIBUTE_UNUSED;
4047 const char *mnemonic;
4049 FETCH_DATA (the_info, codep + 1);
4050 /* AMD 3DNow! instructions are specified by an opcode suffix in the
4051 place where an 8-bit immediate would normally go. ie. the last
4052 byte of the instruction. */
4053 obufp = obuf + strlen (obuf);
4054 mnemonic = Suffix3DNow[*codep++ & 0xff];
4055 if (mnemonic)
4056 oappend (mnemonic);
4057 else
4059 /* Since a variable sized modrm/sib chunk is between the start
4060 of the opcode (0x0f0f) and the opcode suffix, we need to do
4061 all the modrm processing first, and don't know until now that
4062 we have a bad opcode. This necessitates some cleaning up. */
4063 op1out[0] = '\0';
4064 op2out[0] = '\0';
4065 BadOp ();
4069 static const char *simd_cmp_op[] = {
4070 "eq",
4071 "lt",
4072 "le",
4073 "unord",
4074 "neq",
4075 "nlt",
4076 "nle",
4077 "ord"
4080 static void
4081 OP_SIMD_Suffix (bytemode, sizeflag)
4082 int bytemode ATTRIBUTE_UNUSED;
4083 int sizeflag ATTRIBUTE_UNUSED;
4085 unsigned int cmp_type;
4087 FETCH_DATA (the_info, codep + 1);
4088 obufp = obuf + strlen (obuf);
4089 cmp_type = *codep++ & 0xff;
4090 if (cmp_type < 8)
4092 char suffix1 = 'p', suffix2 = 's';
4093 used_prefixes |= (prefixes & PREFIX_REPZ);
4094 if (prefixes & PREFIX_REPZ)
4095 suffix1 = 's';
4096 else
4098 used_prefixes |= (prefixes & PREFIX_DATA);
4099 if (prefixes & PREFIX_DATA)
4100 suffix2 = 'd';
4101 else
4103 used_prefixes |= (prefixes & PREFIX_REPNZ);
4104 if (prefixes & PREFIX_REPNZ)
4105 suffix1 = 's', suffix2 = 'd';
4108 sprintf (scratchbuf, "cmp%s%c%c",
4109 simd_cmp_op[cmp_type], suffix1, suffix2);
4110 used_prefixes |= (prefixes & PREFIX_REPZ);
4111 oappend (scratchbuf);
4113 else
4115 /* We have a bad extension byte. Clean up. */
4116 op1out[0] = '\0';
4117 op2out[0] = '\0';
4118 BadOp ();
4122 static void
4123 SIMD_Fixup (extrachar, sizeflag)
4124 int extrachar;
4125 int sizeflag ATTRIBUTE_UNUSED;
4127 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
4128 forms of these instructions. */
4129 if (mod == 3)
4131 char *p = obuf + strlen (obuf);
4132 *(p + 1) = '\0';
4133 *p = *(p - 1);
4134 *(p - 1) = *(p - 2);
4135 *(p - 2) = *(p - 3);
4136 *(p - 3) = extrachar;
4140 static void
4141 BadOp (void)
4143 /* Throw away prefixes and 1st. opcode byte. */
4144 codep = insn_codep + 1;
4145 oappend ("(bad)");