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