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