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