* Many files: Changes to avoid gcc warnings: Add ATTRIBUTE_UNUSED
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
CommitLineData
252b5132
RH
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
5This file is part of GDB.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, 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 */
26
27/*
28 * The main tables describing the instructions is essentially a copy
29 * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
30 * Programmers Manual. Usually, there is a capital letter, followed
31 * by a small letter. The capital letter tell the addressing mode,
32 * and the small letter tells about the operand size. Refer to
33 * the Intel manual for details.
34 */
35
36#include "dis-asm.h"
37#include "sysdep.h"
38#include "opintl.h"
39
40#define MAXLEN 20
41
42#include <setjmp.h>
43
44#ifndef UNIXWARE_COMPAT
45/* Set non-zero for broken, compatible instructions. Set to zero for
46 non-broken opcodes. */
47#define UNIXWARE_COMPAT 1
48#endif
49
252b5132
RH
50static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
51
52struct dis_private
53{
54 /* Points to first byte not fetched. */
55 bfd_byte *max_fetched;
56 bfd_byte the_buffer[MAXLEN];
57 bfd_vma insn_start;
58 jmp_buf bailout;
59};
60
5076851f
ILT
61/* The opcode for the fwait instruction, which we treat as a prefix
62 when we can. */
63#define FWAIT_OPCODE (0x9b)
64
65/* Flags for the prefixes for the current instruction. See below. */
66static int prefixes;
67
7d421014
ILT
68/* Flags for prefixes which we somehow handled when printing the
69 current instruction. */
70static int used_prefixes;
71
5076851f
ILT
72/* Flags stored in PREFIXES. */
73#define PREFIX_REPZ 1
74#define PREFIX_REPNZ 2
75#define PREFIX_LOCK 4
76#define PREFIX_CS 8
77#define PREFIX_SS 0x10
78#define PREFIX_DS 0x20
79#define PREFIX_ES 0x40
80#define PREFIX_FS 0x80
81#define PREFIX_GS 0x100
82#define PREFIX_DATA 0x200
83#define PREFIX_ADDR 0x400
84#define PREFIX_FWAIT 0x800
85
252b5132
RH
86/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
87 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
88 on error. */
89#define FETCH_DATA(info, addr) \
90 ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
91 ? 1 : fetch_data ((info), (addr)))
92
93static int
94fetch_data (info, addr)
95 struct disassemble_info *info;
96 bfd_byte *addr;
97{
98 int status;
99 struct dis_private *priv = (struct dis_private *)info->private_data;
100 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
101
102 status = (*info->read_memory_func) (start,
103 priv->max_fetched,
104 addr - priv->max_fetched,
105 info);
106 if (status != 0)
107 {
7d421014
ILT
108 /* If we did manage to read at least one byte, then
109 print_insn_i386 will do something sensible. Otherwise, print
110 an error. We do that here because this is where we know
111 STATUS. */
112 if (priv->max_fetched == priv->the_buffer)
5076851f 113 (*info->memory_error_func) (status, start, info);
252b5132
RH
114 longjmp (priv->bailout, 1);
115 }
116 else
117 priv->max_fetched = addr;
118 return 1;
119}
120
121#define Eb OP_E, b_mode
122#define indirEb OP_indirE, b_mode
123#define Gb OP_G, b_mode
124#define Ev OP_E, v_mode
2da11e11 125#define Ed OP_E, d_mode
252b5132
RH
126#define indirEv OP_indirE, v_mode
127#define Ew OP_E, w_mode
128#define Ma OP_E, v_mode
2da11e11
AM
129#define M OP_E, 0 /* lea */
130#define Mp OP_E, 0 /* 32 or 48 bit memory operand for LDS, LES etc */
252b5132
RH
131#define Gv OP_G, v_mode
132#define Gw OP_G, w_mode
2da11e11 133#define Rd OP_Rd, d_mode
252b5132
RH
134#define Ib OP_I, b_mode
135#define sIb OP_sI, b_mode /* sign extened byte */
136#define Iv OP_I, v_mode
137#define Iw OP_I, w_mode
138#define Jb OP_J, b_mode
139#define Jv OP_J, v_mode
252b5132
RH
140#define Cd OP_C, d_mode
141#define Dd OP_D, d_mode
142#define Td OP_T, d_mode
143
144#define eAX OP_REG, eAX_reg
145#define eBX OP_REG, eBX_reg
146#define eCX OP_REG, eCX_reg
147#define eDX OP_REG, eDX_reg
148#define eSP OP_REG, eSP_reg
149#define eBP OP_REG, eBP_reg
150#define eSI OP_REG, eSI_reg
151#define eDI OP_REG, eDI_reg
152#define AL OP_REG, al_reg
153#define CL OP_REG, cl_reg
154#define DL OP_REG, dl_reg
155#define BL OP_REG, bl_reg
156#define AH OP_REG, ah_reg
157#define CH OP_REG, ch_reg
158#define DH OP_REG, dh_reg
159#define BH OP_REG, bh_reg
160#define AX OP_REG, ax_reg
161#define DX OP_REG, dx_reg
162#define indirDX OP_REG, indir_dx_reg
163
164#define Sw OP_SEG, w_mode
c608c12e 165#define Ap OP_DIR, 0
252b5132
RH
166#define Ob OP_OFF, b_mode
167#define Ov OP_OFF, v_mode
168#define Xb OP_DSreg, eSI_reg
169#define Xv OP_DSreg, eSI_reg
170#define Yb OP_ESreg, eDI_reg
171#define Yv OP_ESreg, eDI_reg
172#define DSBX OP_DSreg, eBX_reg
173
174#define es OP_REG, es_reg
175#define ss OP_REG, ss_reg
176#define cs OP_REG, cs_reg
177#define ds OP_REG, ds_reg
178#define fs OP_REG, fs_reg
179#define gs OP_REG, gs_reg
180
181#define MX OP_MMX, 0
c608c12e 182#define XM OP_XMM, 0
252b5132 183#define EM OP_EM, v_mode
c608c12e 184#define EX OP_EX, v_mode
2da11e11 185#define MS OP_MS, v_mode
c608c12e 186#define None OP_E, 0
252b5132 187#define OPSUF OP_3DNowSuffix, 0
c608c12e 188#define OPSIMD OP_SIMD_Suffix, 0
252b5132
RH
189
190/* bits in sizeflag */
191#if 0 /* leave undefined until someone adds the extra flag to objdump */
192#define SUFFIX_ALWAYS 4
193#endif
194#define AFLAG 2
195#define DFLAG 1
196
2da11e11 197typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag));
252b5132
RH
198
199static void OP_E PARAMS ((int, int));
200static void OP_G PARAMS ((int, int));
201static void OP_I PARAMS ((int, int));
202static void OP_indirE PARAMS ((int, int));
203static void OP_sI PARAMS ((int, int));
204static void OP_REG PARAMS ((int, int));
205static void OP_J PARAMS ((int, int));
206static void OP_DIR PARAMS ((int, int));
207static void OP_OFF PARAMS ((int, int));
208static void OP_ESreg PARAMS ((int, int));
209static void OP_DSreg PARAMS ((int, int));
210static void OP_SEG PARAMS ((int, int));
211static void OP_C PARAMS ((int, int));
212static void OP_D PARAMS ((int, int));
213static void OP_T PARAMS ((int, int));
2da11e11 214static void OP_Rd PARAMS ((int, int));
252b5132
RH
215static void OP_ST PARAMS ((int, int));
216static void OP_STi PARAMS ((int, int));
252b5132 217static void OP_MMX PARAMS ((int, int));
c608c12e 218static void OP_XMM PARAMS ((int, int));
252b5132 219static void OP_EM PARAMS ((int, int));
c608c12e 220static void OP_EX PARAMS ((int, int));
252b5132
RH
221static void OP_MS PARAMS ((int, int));
222static void OP_3DNowSuffix PARAMS ((int, int));
c608c12e
AM
223static void OP_SIMD_Suffix PARAMS ((int, int));
224static void SIMD_Fixup PARAMS ((int, int));
252b5132
RH
225
226static void append_seg PARAMS ((void));
227static void set_op PARAMS ((unsigned int op));
2da11e11 228static void putop PARAMS ((const char *template, int sizeflag));
252b5132
RH
229static void dofloat PARAMS ((int sizeflag));
230static int get16 PARAMS ((void));
231static int get32 PARAMS ((void));
232static void ckprefix PARAMS ((void));
7d421014 233static const char *prefix_name PARAMS ((int, int));
252b5132 234static void ptr_reg PARAMS ((int, int));
2da11e11 235static void BadOp PARAMS ((void));
252b5132
RH
236
237#define b_mode 1
238#define v_mode 2
239#define w_mode 3
240#define d_mode 4
241#define x_mode 5
242
243#define es_reg 100
244#define cs_reg 101
245#define ss_reg 102
246#define ds_reg 103
247#define fs_reg 104
248#define gs_reg 105
252b5132 249
c608c12e
AM
250#define eAX_reg 108
251#define eCX_reg 109
252#define eDX_reg 110
253#define eBX_reg 111
254#define eSP_reg 112
255#define eBP_reg 113
256#define eSI_reg 114
257#define eDI_reg 115
252b5132
RH
258
259#define al_reg 116
260#define cl_reg 117
261#define dl_reg 118
262#define bl_reg 119
263#define ah_reg 120
264#define ch_reg 121
265#define dh_reg 122
266#define bh_reg 123
267
268#define ax_reg 124
269#define cx_reg 125
270#define dx_reg 126
271#define bx_reg 127
272#define sp_reg 128
273#define bp_reg 129
274#define si_reg 130
275#define di_reg 131
276
277#define indir_dx_reg 150
278
c608c12e
AM
279#define USE_GROUPS 1
280#define USE_PREFIX_USER_TABLE 2
281
282#define GRP1b NULL, NULL, 0, NULL, USE_GROUPS
283#define GRP1S NULL, NULL, 1, NULL, USE_GROUPS
284#define GRP1Ss NULL, NULL, 2, NULL, USE_GROUPS
285#define GRP2b NULL, NULL, 3, NULL, USE_GROUPS
286#define GRP2S NULL, NULL, 4, NULL, USE_GROUPS
287#define GRP2b_one NULL, NULL, 5, NULL, USE_GROUPS
288#define GRP2S_one NULL, NULL, 6, NULL, USE_GROUPS
289#define GRP2b_cl NULL, NULL, 7, NULL, USE_GROUPS
290#define GRP2S_cl NULL, NULL, 8, NULL, USE_GROUPS
291#define GRP3b NULL, NULL, 9, NULL, USE_GROUPS
292#define GRP3S NULL, NULL, 10, NULL, USE_GROUPS
293#define GRP4 NULL, NULL, 11, NULL, USE_GROUPS
294#define GRP5 NULL, NULL, 12, NULL, USE_GROUPS
295#define GRP6 NULL, NULL, 13, NULL, USE_GROUPS
296#define GRP7 NULL, NULL, 14, NULL, USE_GROUPS
297#define GRP8 NULL, NULL, 15, NULL, USE_GROUPS
298#define GRP9 NULL, NULL, 16, NULL, USE_GROUPS
299#define GRP10 NULL, NULL, 17, NULL, USE_GROUPS
300#define GRP11 NULL, NULL, 18, NULL, USE_GROUPS
301#define GRP12 NULL, NULL, 19, NULL, USE_GROUPS
302#define GRP13 NULL, NULL, 20, NULL, USE_GROUPS
303#define GRP14 NULL, NULL, 21, NULL, USE_GROUPS
304#define GRPAMD NULL, NULL, 22, NULL, USE_GROUPS
305
306#define PREGRP0 NULL, NULL, 0, NULL, USE_PREFIX_USER_TABLE
307#define PREGRP1 NULL, NULL, 1, NULL, USE_PREFIX_USER_TABLE
308#define PREGRP2 NULL, NULL, 2, NULL, USE_PREFIX_USER_TABLE
309#define PREGRP3 NULL, NULL, 3, NULL, USE_PREFIX_USER_TABLE
310#define PREGRP4 NULL, NULL, 4, NULL, USE_PREFIX_USER_TABLE
311#define PREGRP5 NULL, NULL, 5, NULL, USE_PREFIX_USER_TABLE
312#define PREGRP6 NULL, NULL, 6, NULL, USE_PREFIX_USER_TABLE
313#define PREGRP7 NULL, NULL, 7, NULL, USE_PREFIX_USER_TABLE
314#define PREGRP8 NULL, NULL, 8, NULL, USE_PREFIX_USER_TABLE
315#define PREGRP9 NULL, NULL, 9, NULL, USE_PREFIX_USER_TABLE
316#define PREGRP10 NULL, NULL, 10, NULL, USE_PREFIX_USER_TABLE
317#define PREGRP11 NULL, NULL, 11, NULL, USE_PREFIX_USER_TABLE
318#define PREGRP12 NULL, NULL, 12, NULL, USE_PREFIX_USER_TABLE
319#define PREGRP13 NULL, NULL, 13, NULL, USE_PREFIX_USER_TABLE
320#define PREGRP14 NULL, NULL, 14, NULL, USE_PREFIX_USER_TABLE
252b5132
RH
321
322#define FLOATCODE 50
323#define FLOAT NULL, NULL, FLOATCODE
324
325struct dis386 {
2da11e11 326 const char *name;
252b5132
RH
327 op_rtn op1;
328 int bytemode1;
329 op_rtn op2;
330 int bytemode2;
331 op_rtn op3;
332 int bytemode3;
333};
334
335/* Upper case letters in the instruction names here are macros.
336 'A' => print 'b' if no register operands or suffix_always is true
337 'B' => print 'b' if suffix_always is true
338 'E' => print 'e' if 32-bit form of jcxz
339 'L' => print 'l' if suffix_always is true
340 'N' => print 'n' if instruction has no wait "prefix"
341 'P' => print 'w' or 'l' if instruction has an operand size prefix,
342 or suffix_always is true
343 'Q' => print 'w' or 'l' if no register operands or suffix_always is true
10084519 344 'R' => print 'w' or 'l' ("wd" or "dq" in intel mode)
252b5132 345 'S' => print 'w' or 'l' if suffix_always is true
10084519 346 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
252b5132
RH
347*/
348
2da11e11 349static const struct dis386 dis386_att[] = {
252b5132
RH
350 /* 00 */
351 { "addB", Eb, Gb },
352 { "addS", Ev, Gv },
353 { "addB", Gb, Eb },
354 { "addS", Gv, Ev },
355 { "addB", AL, Ib },
356 { "addS", eAX, Iv },
357 { "pushP", es },
358 { "popP", es },
359 /* 08 */
360 { "orB", Eb, Gb },
361 { "orS", Ev, Gv },
362 { "orB", Gb, Eb },
363 { "orS", Gv, Ev },
364 { "orB", AL, Ib },
365 { "orS", eAX, Iv },
366 { "pushP", cs },
367 { "(bad)" }, /* 0x0f extended opcode escape */
368 /* 10 */
369 { "adcB", Eb, Gb },
370 { "adcS", Ev, Gv },
371 { "adcB", Gb, Eb },
372 { "adcS", Gv, Ev },
373 { "adcB", AL, Ib },
374 { "adcS", eAX, Iv },
375 { "pushP", ss },
376 { "popP", ss },
377 /* 18 */
378 { "sbbB", Eb, Gb },
379 { "sbbS", Ev, Gv },
380 { "sbbB", Gb, Eb },
381 { "sbbS", Gv, Ev },
382 { "sbbB", AL, Ib },
383 { "sbbS", eAX, Iv },
384 { "pushP", ds },
385 { "popP", ds },
386 /* 20 */
387 { "andB", Eb, Gb },
388 { "andS", Ev, Gv },
389 { "andB", Gb, Eb },
390 { "andS", Gv, Ev },
391 { "andB", AL, Ib },
392 { "andS", eAX, Iv },
393 { "(bad)" }, /* SEG ES prefix */
394 { "daa" },
395 /* 28 */
396 { "subB", Eb, Gb },
397 { "subS", Ev, Gv },
398 { "subB", Gb, Eb },
399 { "subS", Gv, Ev },
400 { "subB", AL, Ib },
401 { "subS", eAX, Iv },
402 { "(bad)" }, /* SEG CS prefix */
403 { "das" },
404 /* 30 */
405 { "xorB", Eb, Gb },
406 { "xorS", Ev, Gv },
407 { "xorB", Gb, Eb },
408 { "xorS", Gv, Ev },
409 { "xorB", AL, Ib },
410 { "xorS", eAX, Iv },
411 { "(bad)" }, /* SEG SS prefix */
412 { "aaa" },
413 /* 38 */
414 { "cmpB", Eb, Gb },
415 { "cmpS", Ev, Gv },
416 { "cmpB", Gb, Eb },
417 { "cmpS", Gv, Ev },
418 { "cmpB", AL, Ib },
419 { "cmpS", eAX, Iv },
420 { "(bad)" }, /* SEG DS prefix */
421 { "aas" },
422 /* 40 */
423 { "incS", eAX },
424 { "incS", eCX },
425 { "incS", eDX },
426 { "incS", eBX },
427 { "incS", eSP },
428 { "incS", eBP },
429 { "incS", eSI },
430 { "incS", eDI },
431 /* 48 */
432 { "decS", eAX },
433 { "decS", eCX },
434 { "decS", eDX },
435 { "decS", eBX },
436 { "decS", eSP },
437 { "decS", eBP },
438 { "decS", eSI },
439 { "decS", eDI },
440 /* 50 */
441 { "pushS", eAX },
442 { "pushS", eCX },
443 { "pushS", eDX },
444 { "pushS", eBX },
445 { "pushS", eSP },
446 { "pushS", eBP },
447 { "pushS", eSI },
448 { "pushS", eDI },
449 /* 58 */
450 { "popS", eAX },
451 { "popS", eCX },
452 { "popS", eDX },
453 { "popS", eBX },
454 { "popS", eSP },
455 { "popS", eBP },
456 { "popS", eSI },
457 { "popS", eDI },
458 /* 60 */
459 { "pushaP" },
460 { "popaP" },
461 { "boundS", Gv, Ma },
462 { "arpl", Ew, Gw },
463 { "(bad)" }, /* seg fs */
464 { "(bad)" }, /* seg gs */
465 { "(bad)" }, /* op size prefix */
466 { "(bad)" }, /* adr size prefix */
467 /* 68 */
468 { "pushP", Iv }, /* 386 book wrong */
469 { "imulS", Gv, Ev, Iv },
470 { "pushP", sIb }, /* push of byte really pushes 2 or 4 bytes */
471 { "imulS", Gv, Ev, sIb },
472 { "insb", Yb, indirDX },
473 { "insR", Yv, indirDX },
474 { "outsb", indirDX, Xb },
475 { "outsR", indirDX, Xv },
476 /* 70 */
477 { "jo", Jb },
478 { "jno", Jb },
479 { "jb", Jb },
480 { "jae", Jb },
481 { "je", Jb },
482 { "jne", Jb },
483 { "jbe", Jb },
484 { "ja", Jb },
485 /* 78 */
486 { "js", Jb },
487 { "jns", Jb },
488 { "jp", Jb },
489 { "jnp", Jb },
490 { "jl", Jb },
491 { "jge", Jb },
492 { "jle", Jb },
493 { "jg", Jb },
494 /* 80 */
495 { GRP1b },
496 { GRP1S },
497 { "(bad)" },
498 { GRP1Ss },
499 { "testB", Eb, Gb },
500 { "testS", Ev, Gv },
501 { "xchgB", Eb, Gb },
502 { "xchgS", Ev, Gv },
503 /* 88 */
504 { "movB", Eb, Gb },
505 { "movS", Ev, Gv },
506 { "movB", Gb, Eb },
507 { "movS", Gv, Ev },
508 { "movQ", Ev, Sw },
509 { "leaS", Gv, M },
510 { "movQ", Sw, Ev },
511 { "popQ", Ev },
512 /* 90 */
513 { "nop" },
514 { "xchgS", eCX, eAX },
515 { "xchgS", eDX, eAX },
516 { "xchgS", eBX, eAX },
517 { "xchgS", eSP, eAX },
518 { "xchgS", eBP, eAX },
519 { "xchgS", eSI, eAX },
520 { "xchgS", eDI, eAX },
521 /* 98 */
522 { "cWtR" },
523 { "cRtd" },
524 { "lcallP", Ap },
525 { "(bad)" }, /* fwait */
526 { "pushfP" },
527 { "popfP" },
528 { "sahf" },
529 { "lahf" },
530 /* a0 */
531 { "movB", AL, Ob },
532 { "movS", eAX, Ov },
533 { "movB", Ob, AL },
534 { "movS", Ov, eAX },
535 { "movsb", Yb, Xb },
536 { "movsR", Yv, Xv },
537 { "cmpsb", Xb, Yb },
538 { "cmpsR", Xv, Yv },
539 /* a8 */
540 { "testB", AL, Ib },
541 { "testS", eAX, Iv },
542 { "stosB", Yb, AL },
543 { "stosS", Yv, eAX },
544 { "lodsB", AL, Xb },
545 { "lodsS", eAX, Xv },
546 { "scasB", AL, Yb },
547 { "scasS", eAX, Yv },
548 /* b0 */
549 { "movB", AL, Ib },
550 { "movB", CL, Ib },
551 { "movB", DL, Ib },
552 { "movB", BL, Ib },
553 { "movB", AH, Ib },
554 { "movB", CH, Ib },
555 { "movB", DH, Ib },
556 { "movB", BH, Ib },
557 /* b8 */
558 { "movS", eAX, Iv },
559 { "movS", eCX, Iv },
560 { "movS", eDX, Iv },
561 { "movS", eBX, Iv },
562 { "movS", eSP, Iv },
563 { "movS", eBP, Iv },
564 { "movS", eSI, Iv },
565 { "movS", eDI, Iv },
566 /* c0 */
567 { GRP2b },
568 { GRP2S },
569 { "retP", Iw },
570 { "retP" },
571 { "lesS", Gv, Mp },
572 { "ldsS", Gv, Mp },
573 { "movA", Eb, Ib },
574 { "movQ", Ev, Iv },
575 /* c8 */
576 { "enterP", Iw, Ib },
577 { "leaveP" },
578 { "lretP", Iw },
579 { "lretP" },
580 { "int3" },
581 { "int", Ib },
582 { "into" },
583 { "iretP" },
584 /* d0 */
585 { GRP2b_one },
586 { GRP2S_one },
587 { GRP2b_cl },
588 { GRP2S_cl },
589 { "aam", sIb },
590 { "aad", sIb },
591 { "(bad)" },
592 { "xlat", DSBX },
593 /* d8 */
594 { FLOAT },
595 { FLOAT },
596 { FLOAT },
597 { FLOAT },
598 { FLOAT },
599 { FLOAT },
600 { FLOAT },
601 { FLOAT },
602 /* e0 */
603 { "loopne", Jb },
604 { "loope", Jb },
605 { "loop", Jb },
606 { "jEcxz", Jb },
607 { "inB", AL, Ib },
608 { "inS", eAX, Ib },
609 { "outB", Ib, AL },
610 { "outS", Ib, eAX },
611 /* e8 */
c608c12e 612 { "callP", Jv },
252b5132
RH
613 { "jmpP", Jv },
614 { "ljmpP", Ap },
615 { "jmp", Jb },
616 { "inB", AL, indirDX },
617 { "inS", eAX, indirDX },
618 { "outB", indirDX, AL },
619 { "outS", indirDX, eAX },
620 /* f0 */
621 { "(bad)" }, /* lock prefix */
622 { "(bad)" },
623 { "(bad)" }, /* repne */
624 { "(bad)" }, /* repz */
625 { "hlt" },
626 { "cmc" },
627 { GRP3b },
628 { GRP3S },
629 /* f8 */
630 { "clc" },
631 { "stc" },
632 { "cli" },
633 { "sti" },
634 { "cld" },
635 { "std" },
636 { GRP4 },
637 { GRP5 },
638};
639
2da11e11 640static const struct dis386 dis386_intel[] = {
252b5132 641 /* 00 */
c608c12e
AM
642 { "add", Eb, Gb },
643 { "add", Ev, Gv },
644 { "add", Gb, Eb },
645 { "add", Gv, Ev },
646 { "add", AL, Ib },
647 { "add", eAX, Iv },
648 { "push", es },
649 { "pop", es },
252b5132 650 /* 08 */
c608c12e
AM
651 { "or", Eb, Gb },
652 { "or", Ev, Gv },
653 { "or", Gb, Eb },
654 { "or", Gv, Ev },
655 { "or", AL, Ib },
656 { "or", eAX, Iv },
657 { "push", cs },
252b5132
RH
658 { "(bad)" }, /* 0x0f extended opcode escape */
659 /* 10 */
c608c12e
AM
660 { "adc", Eb, Gb },
661 { "adc", Ev, Gv },
662 { "adc", Gb, Eb },
663 { "adc", Gv, Ev },
664 { "adc", AL, Ib },
665 { "adc", eAX, Iv },
666 { "push", ss },
667 { "pop", ss },
252b5132 668 /* 18 */
c608c12e
AM
669 { "sbb", Eb, Gb },
670 { "sbb", Ev, Gv },
671 { "sbb", Gb, Eb },
672 { "sbb", Gv, Ev },
673 { "sbb", AL, Ib },
674 { "sbb", eAX, Iv },
675 { "push", ds },
676 { "pop", ds },
252b5132 677 /* 20 */
c608c12e
AM
678 { "and", Eb, Gb },
679 { "and", Ev, Gv },
680 { "and", Gb, Eb },
681 { "and", Gv, Ev },
682 { "and", AL, Ib },
683 { "and", eAX, Iv },
252b5132
RH
684 { "(bad)" }, /* SEG ES prefix */
685 { "daa" },
686 /* 28 */
c608c12e
AM
687 { "sub", Eb, Gb },
688 { "sub", Ev, Gv },
689 { "sub", Gb, Eb },
690 { "sub", Gv, Ev },
691 { "sub", AL, Ib },
692 { "sub", eAX, Iv },
252b5132
RH
693 { "(bad)" }, /* SEG CS prefix */
694 { "das" },
695 /* 30 */
c608c12e
AM
696 { "xor", Eb, Gb },
697 { "xor", Ev, Gv },
698 { "xor", Gb, Eb },
699 { "xor", Gv, Ev },
700 { "xor", AL, Ib },
701 { "xor", eAX, Iv },
252b5132
RH
702 { "(bad)" }, /* SEG SS prefix */
703 { "aaa" },
704 /* 38 */
c608c12e
AM
705 { "cmp", Eb, Gb },
706 { "cmp", Ev, Gv },
707 { "cmp", Gb, Eb },
708 { "cmp", Gv, Ev },
709 { "cmp", AL, Ib },
710 { "cmp", eAX, Iv },
252b5132
RH
711 { "(bad)" }, /* SEG DS prefix */
712 { "aas" },
713 /* 40 */
c608c12e
AM
714 { "inc", eAX },
715 { "inc", eCX },
716 { "inc", eDX },
717 { "inc", eBX },
718 { "inc", eSP },
719 { "inc", eBP },
720 { "inc", eSI },
721 { "inc", eDI },
252b5132 722 /* 48 */
c608c12e
AM
723 { "dec", eAX },
724 { "dec", eCX },
725 { "dec", eDX },
726 { "dec", eBX },
727 { "dec", eSP },
728 { "dec", eBP },
729 { "dec", eSI },
730 { "dec", eDI },
252b5132 731 /* 50 */
c608c12e
AM
732 { "push", eAX },
733 { "push", eCX },
734 { "push", eDX },
735 { "push", eBX },
736 { "push", eSP },
737 { "push", eBP },
738 { "push", eSI },
739 { "push", eDI },
252b5132 740 /* 58 */
c608c12e
AM
741 { "pop", eAX },
742 { "pop", eCX },
743 { "pop", eDX },
744 { "pop", eBX },
745 { "pop", eSP },
746 { "pop", eBP },
747 { "pop", eSI },
748 { "pop", eDI },
252b5132 749 /* 60 */
c608c12e
AM
750 { "pusha" },
751 { "popa" },
752 { "bound", Gv, Ma },
252b5132
RH
753 { "arpl", Ew, Gw },
754 { "(bad)" }, /* seg fs */
755 { "(bad)" }, /* seg gs */
756 { "(bad)" }, /* op size prefix */
757 { "(bad)" }, /* adr size prefix */
758 /* 68 */
c608c12e
AM
759 { "push", Iv }, /* 386 book wrong */
760 { "imul", Gv, Ev, Iv },
761 { "push", sIb }, /* push of byte really pushes 2 or 4 bytes */
762 { "imul", Gv, Ev, sIb },
763 { "ins", Yb, indirDX },
764 { "ins", Yv, indirDX },
765 { "outs", indirDX, Xb },
766 { "outs", indirDX, Xv },
252b5132
RH
767 /* 70 */
768 { "jo", Jb },
769 { "jno", Jb },
770 { "jb", Jb },
771 { "jae", Jb },
772 { "je", Jb },
773 { "jne", Jb },
774 { "jbe", Jb },
775 { "ja", Jb },
776 /* 78 */
777 { "js", Jb },
778 { "jns", Jb },
779 { "jp", Jb },
780 { "jnp", Jb },
781 { "jl", Jb },
782 { "jge", Jb },
783 { "jle", Jb },
784 { "jg", Jb },
785 /* 80 */
786 { GRP1b },
787 { GRP1S },
788 { "(bad)" },
789 { GRP1Ss },
c608c12e
AM
790 { "test", Eb, Gb },
791 { "test", Ev, Gv },
792 { "xchg", Eb, Gb },
793 { "xchg", Ev, Gv },
252b5132 794 /* 88 */
c608c12e
AM
795 { "mov", Eb, Gb },
796 { "mov", Ev, Gv },
797 { "mov", Gb, Eb },
798 { "mov", Gv, Ev },
799 { "mov", Ev, Sw },
800 { "lea", Gv, M },
801 { "mov", Sw, Ev },
802 { "pop", Ev },
252b5132
RH
803 /* 90 */
804 { "nop" },
c608c12e
AM
805 { "xchg", eCX, eAX },
806 { "xchg", eDX, eAX },
807 { "xchg", eBX, eAX },
808 { "xchg", eSP, eAX },
809 { "xchg", eBP, eAX },
810 { "xchg", eSI, eAX },
811 { "xchg", eDI, eAX },
252b5132 812 /* 98 */
c608c12e
AM
813 { "cW" }, /* cwde and cbw */
814 { "cR" }, /* cdq and cwd */
815 { "lcall", Ap },
252b5132 816 { "(bad)" }, /* fwait */
c608c12e
AM
817 { "pushf" },
818 { "popf" },
252b5132
RH
819 { "sahf" },
820 { "lahf" },
821 /* a0 */
c608c12e
AM
822 { "mov", AL, Ob },
823 { "mov", eAX, Ov },
824 { "mov", Ob, AL },
825 { "mov", Ov, eAX },
826 { "movs", Yb, Xb },
827 { "movs", Yv, Xv },
828 { "cmps", Xb, Yb },
829 { "cmps", Xv, Yv },
252b5132 830 /* a8 */
c608c12e
AM
831 { "test", AL, Ib },
832 { "test", eAX, Iv },
833 { "stos", Yb, AL },
834 { "stos", Yv, eAX },
835 { "lods", AL, Xb },
836 { "lods", eAX, Xv },
837 { "scas", AL, Yb },
838 { "scas", eAX, Yv },
252b5132 839 /* b0 */
c608c12e
AM
840 { "mov", AL, Ib },
841 { "mov", CL, Ib },
842 { "mov", DL, Ib },
843 { "mov", BL, Ib },
844 { "mov", AH, Ib },
845 { "mov", CH, Ib },
846 { "mov", DH, Ib },
847 { "mov", BH, Ib },
252b5132 848 /* b8 */
c608c12e
AM
849 { "mov", eAX, Iv },
850 { "mov", eCX, Iv },
851 { "mov", eDX, Iv },
852 { "mov", eBX, Iv },
853 { "mov", eSP, Iv },
854 { "mov", eBP, Iv },
855 { "mov", eSI, Iv },
856 { "mov", eDI, Iv },
252b5132
RH
857 /* c0 */
858 { GRP2b },
859 { GRP2S },
c608c12e
AM
860 { "ret", Iw },
861 { "ret" },
862 { "les", Gv, Mp },
863 { "lds", Gv, Mp },
864 { "mov", Eb, Ib },
865 { "mov", Ev, Iv },
252b5132 866 /* c8 */
c608c12e
AM
867 { "enter", Iw, Ib },
868 { "leave" },
869 { "lret", Iw },
870 { "lret" },
252b5132
RH
871 { "int3" },
872 { "int", Ib },
873 { "into" },
c608c12e 874 { "iret" },
252b5132
RH
875 /* d0 */
876 { GRP2b_one },
877 { GRP2S_one },
878 { GRP2b_cl },
879 { GRP2S_cl },
880 { "aam", sIb },
881 { "aad", sIb },
882 { "(bad)" },
883 { "xlat", DSBX },
884 /* d8 */
885 { FLOAT },
886 { FLOAT },
887 { FLOAT },
888 { FLOAT },
889 { FLOAT },
890 { FLOAT },
891 { FLOAT },
892 { FLOAT },
893 /* e0 */
894 { "loopne", Jb },
895 { "loope", Jb },
896 { "loop", Jb },
897 { "jEcxz", Jb },
c608c12e
AM
898 { "in", AL, Ib },
899 { "in", eAX, Ib },
900 { "out", Ib, AL },
901 { "out", Ib, eAX },
252b5132 902 /* e8 */
c608c12e
AM
903 { "call", Jv },
904 { "jmp", Jv },
905 { "ljmp", Ap },
252b5132 906 { "jmp", Jb },
c608c12e
AM
907 { "in", AL, indirDX },
908 { "in", eAX, indirDX },
909 { "out", indirDX, AL },
910 { "out", indirDX, eAX },
252b5132
RH
911 /* f0 */
912 { "(bad)" }, /* lock prefix */
913 { "(bad)" },
914 { "(bad)" }, /* repne */
915 { "(bad)" }, /* repz */
916 { "hlt" },
917 { "cmc" },
918 { GRP3b },
919 { GRP3S },
920 /* f8 */
921 { "clc" },
922 { "stc" },
923 { "cli" },
924 { "sti" },
925 { "cld" },
926 { "std" },
927 { GRP4 },
928 { GRP5 },
929};
930
2da11e11 931static const struct dis386 dis386_twobyte_att[] = {
252b5132
RH
932 /* 00 */
933 { GRP6 },
934 { GRP7 },
935 { "larS", Gv, Ew },
936 { "lslS", Gv, Ew },
937 { "(bad)" },
938 { "(bad)" },
939 { "clts" },
940 { "(bad)" },
941 /* 08 */
942 { "invd" },
943 { "wbinvd" },
944 { "(bad)" },
945 { "ud2a" },
946 { "(bad)" },
c608c12e 947 { GRPAMD },
252b5132
RH
948 { "femms" },
949 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
950 /* 10 */
c608c12e
AM
951 { PREGRP8 },
952 { PREGRP9 },
953 { "movlps", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
954 { "movlps", EX, XM, SIMD_Fixup, 'h' },
955 { "unpcklps", XM, EX },
956 { "unpckhps", XM, EX },
957 { "movhps", XM, EX, SIMD_Fixup, 'l' },
958 { "movhps", EX, XM, SIMD_Fixup, 'l' },
252b5132 959 /* 18 */
c608c12e 960 { GRP14 },
2da11e11 961 { "(bad)" }, { "(bad)" }, { "(bad)" },
252b5132
RH
962 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
963 /* 20 */
964 /* these are all backward in appendix A of the intel book */
965 { "movL", Rd, Cd },
966 { "movL", Rd, Dd },
967 { "movL", Cd, Rd },
968 { "movL", Dd, Rd },
969 { "movL", Rd, Td },
970 { "(bad)" },
971 { "movL", Td, Rd },
972 { "(bad)" },
973 /* 28 */
c608c12e
AM
974 { "movaps", XM, EX },
975 { "movaps", EX, XM },
976 { PREGRP2 },
977 { "movntps", Ev, XM },
2da11e11 978 { PREGRP4 },
c608c12e
AM
979 { PREGRP3 },
980 { "ucomiss", XM, EX },
2da11e11 981 { "comiss", XM, EX },
252b5132
RH
982 /* 30 */
983 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
984 { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
985 /* 38 */
986 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
987 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
988 /* 40 */
989 { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
990 { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
991 /* 48 */
992 { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
993 { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
994 /* 50 */
c608c12e
AM
995 { "movmskps", Gv, EX },
996 { PREGRP13 },
997 { PREGRP12 },
998 { PREGRP11 },
999 { "andps", XM, EX },
1000 { "andnps", XM, EX },
1001 { "orps", XM, EX },
2da11e11 1002 { "xorps", XM, EX },
252b5132 1003 /* 58 */
c608c12e
AM
1004 { PREGRP0 },
1005 { PREGRP10 },
1006 { "(bad)" },
2da11e11 1007 { "(bad)" },
c608c12e
AM
1008 { PREGRP14 },
1009 { PREGRP7 },
1010 { PREGRP5 },
2da11e11 1011 { PREGRP6 },
252b5132
RH
1012 /* 60 */
1013 { "punpcklbw", MX, EM },
1014 { "punpcklwd", MX, EM },
1015 { "punpckldq", MX, EM },
1016 { "packsswb", MX, EM },
1017 { "pcmpgtb", MX, EM },
1018 { "pcmpgtw", MX, EM },
1019 { "pcmpgtd", MX, EM },
1020 { "packuswb", MX, EM },
1021 /* 68 */
1022 { "punpckhbw", MX, EM },
1023 { "punpckhwd", MX, EM },
1024 { "punpckhdq", MX, EM },
1025 { "packssdw", MX, EM },
1026 { "(bad)" }, { "(bad)" },
2da11e11 1027 { "movd", MX, Ed },
252b5132
RH
1028 { "movq", MX, EM },
1029 /* 70 */
c608c12e 1030 { "pshufw", MX, EM, Ib },
252b5132
RH
1031 { GRP10 },
1032 { GRP11 },
1033 { GRP12 },
1034 { "pcmpeqb", MX, EM },
1035 { "pcmpeqw", MX, EM },
1036 { "pcmpeqd", MX, EM },
1037 { "emms" },
1038 /* 78 */
1039 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1040 { "(bad)" }, { "(bad)" },
2da11e11 1041 { "movd", Ed, MX },
252b5132
RH
1042 { "movq", EM, MX },
1043 /* 80 */
1044 { "jo", Jv },
1045 { "jno", Jv },
1046 { "jb", Jv },
1047 { "jae", Jv },
1048 { "je", Jv },
1049 { "jne", Jv },
1050 { "jbe", Jv },
1051 { "ja", Jv },
1052 /* 88 */
1053 { "js", Jv },
1054 { "jns", Jv },
1055 { "jp", Jv },
1056 { "jnp", Jv },
1057 { "jl", Jv },
1058 { "jge", Jv },
1059 { "jle", Jv },
1060 { "jg", Jv },
1061 /* 90 */
1062 { "seto", Eb },
1063 { "setno", Eb },
1064 { "setb", Eb },
1065 { "setae", Eb },
1066 { "sete", Eb },
1067 { "setne", Eb },
1068 { "setbe", Eb },
1069 { "seta", Eb },
1070 /* 98 */
1071 { "sets", Eb },
1072 { "setns", Eb },
1073 { "setp", Eb },
1074 { "setnp", Eb },
1075 { "setl", Eb },
1076 { "setge", Eb },
1077 { "setle", Eb },
1078 { "setg", Eb },
1079 /* a0 */
1080 { "pushP", fs },
1081 { "popP", fs },
1082 { "cpuid" },
1083 { "btS", Ev, Gv },
1084 { "shldS", Ev, Gv, Ib },
1085 { "shldS", Ev, Gv, CL },
1086 { "(bad)" },
1087 { "(bad)" },
1088 /* a8 */
1089 { "pushP", gs },
1090 { "popP", gs },
1091 { "rsm" },
1092 { "btsS", Ev, Gv },
1093 { "shrdS", Ev, Gv, Ib },
1094 { "shrdS", Ev, Gv, CL },
1095 { GRP13 },
1096 { "imulS", Gv, Ev },
1097 /* b0 */
1098 { "cmpxchgB", Eb, Gb },
1099 { "cmpxchgS", Ev, Gv },
2da11e11 1100 { "lssS", Gv, Mp },
252b5132 1101 { "btrS", Ev, Gv },
2da11e11
AM
1102 { "lfsS", Gv, Mp },
1103 { "lgsS", Gv, Mp },
252b5132
RH
1104 { "movzbR", Gv, Eb },
1105 { "movzwR", Gv, Ew }, /* yes, there really is movzww ! */
1106 /* b8 */
1107 { "(bad)" },
1108 { "ud2b" },
1109 { GRP8 },
1110 { "btcS", Ev, Gv },
1111 { "bsfS", Gv, Ev },
1112 { "bsrS", Gv, Ev },
1113 { "movsbR", Gv, Eb },
1114 { "movswR", Gv, Ew }, /* yes, there really is movsww ! */
1115 /* c0 */
1116 { "xaddB", Eb, Gb },
1117 { "xaddS", Ev, Gv },
c608c12e 1118 { PREGRP1 },
252b5132 1119 { "(bad)" },
c608c12e
AM
1120 { "pinsrw", MX, Ev, Ib },
1121 { "pextrw", Ev, MX, Ib },
1122 { "shufps", XM, EX, Ib },
252b5132
RH
1123 { GRP9 },
1124 /* c8 */
1125 { "bswap", eAX }, /* bswap doesn't support 16 bit regs */
1126 { "bswap", eCX },
1127 { "bswap", eDX },
1128 { "bswap", eBX },
1129 { "bswap", eSP },
1130 { "bswap", eBP },
1131 { "bswap", eSI },
1132 { "bswap", eDI },
1133 /* d0 */
1134 { "(bad)" },
1135 { "psrlw", MX, EM },
1136 { "psrld", MX, EM },
1137 { "psrlq", MX, EM },
1138 { "(bad)" },
1139 { "pmullw", MX, EM },
c608c12e 1140 { "(bad)" },
2da11e11 1141 { "pmovmskb", Ev, MX },
252b5132
RH
1142 /* d8 */
1143 { "psubusb", MX, EM },
1144 { "psubusw", MX, EM },
c608c12e 1145 { "pminub", MX, EM },
252b5132
RH
1146 { "pand", MX, EM },
1147 { "paddusb", MX, EM },
1148 { "paddusw", MX, EM },
c608c12e 1149 { "pmaxub", MX, EM },
252b5132
RH
1150 { "pandn", MX, EM },
1151 /* e0 */
c608c12e 1152 { "pavgb", MX, EM },
252b5132
RH
1153 { "psraw", MX, EM },
1154 { "psrad", MX, EM },
c608c12e
AM
1155 { "pavgw", MX, EM },
1156 { "pmulhuw", MX, EM },
252b5132 1157 { "pmulhw", MX, EM },
c608c12e 1158 { "(bad)" },
2da11e11 1159 { "movntq", Ev, MX },
252b5132
RH
1160 /* e8 */
1161 { "psubsb", MX, EM },
1162 { "psubsw", MX, EM },
c608c12e 1163 { "pminsw", MX, EM },
252b5132
RH
1164 { "por", MX, EM },
1165 { "paddsb", MX, EM },
1166 { "paddsw", MX, EM },
c608c12e 1167 { "pmaxsw", MX, EM },
252b5132
RH
1168 { "pxor", MX, EM },
1169 /* f0 */
1170 { "(bad)" },
1171 { "psllw", MX, EM },
1172 { "pslld", MX, EM },
1173 { "psllq", MX, EM },
1174 { "(bad)" },
1175 { "pmaddwd", MX, EM },
c608c12e 1176 { "psadbw", MX, EM },
2da11e11 1177 { "maskmovq", MX, EM },
252b5132
RH
1178 /* f8 */
1179 { "psubb", MX, EM },
1180 { "psubw", MX, EM },
1181 { "psubd", MX, EM },
1182 { "(bad)" },
1183 { "paddb", MX, EM },
1184 { "paddw", MX, EM },
1185 { "paddd", MX, EM },
1186 { "(bad)" }
1187};
1188
2da11e11 1189static const struct dis386 dis386_twobyte_intel[] = {
252b5132
RH
1190 /* 00 */
1191 { GRP6 },
1192 { GRP7 },
c608c12e
AM
1193 { "lar", Gv, Ew },
1194 { "lsl", Gv, Ew },
252b5132
RH
1195 { "(bad)" },
1196 { "(bad)" },
1197 { "clts" },
1198 { "(bad)" },
1199 /* 08 */
1200 { "invd" },
1201 { "wbinvd" },
1202 { "(bad)" },
1203 { "ud2a" },
1204 { "(bad)" },
c608c12e 1205 { GRPAMD },
252b5132
RH
1206 { "femms" },
1207 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
1208 /* 10 */
c608c12e
AM
1209 { PREGRP8 },
1210 { PREGRP9 },
1211 { "movlps", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
1212 { "movlps", EX, XM, SIMD_Fixup, 'h' },
1213 { "unpcklps", XM, EX },
1214 { "unpckhps", XM, EX },
1215 { "movhps", XM, EX, SIMD_Fixup, 'l' },
1216 { "movhps", EX, XM, SIMD_Fixup, 'l' },
252b5132 1217 /* 18 */
c608c12e 1218 { GRP14 },
2da11e11 1219 { "(bad)" }, { "(bad)" }, { "(bad)" },
252b5132
RH
1220 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1221 /* 20 */
1222 /* these are all backward in appendix A of the intel book */
c608c12e
AM
1223 { "mov", Rd, Cd },
1224 { "mov", Rd, Dd },
1225 { "mov", Cd, Rd },
1226 { "mov", Dd, Rd },
1227 { "mov", Rd, Td },
252b5132 1228 { "(bad)" },
c608c12e 1229 { "mov", Td, Rd },
252b5132
RH
1230 { "(bad)" },
1231 /* 28 */
c608c12e
AM
1232 { "movaps", XM, EX },
1233 { "movaps", EX, XM },
1234 { PREGRP2 },
1235 { "movntps", Ev, XM },
2da11e11 1236 { PREGRP4 },
c608c12e
AM
1237 { PREGRP3 },
1238 { "ucomiss", XM, EX },
2da11e11 1239 { "comiss", XM, EX },
252b5132
RH
1240 /* 30 */
1241 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
1242 { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
1243 /* 38 */
1244 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1245 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1246 /* 40 */
1247 { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
1248 { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
1249 /* 48 */
1250 { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
1251 { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
1252 /* 50 */
c608c12e
AM
1253 { "movmskps", Gv, EX },
1254 { PREGRP13 },
1255 { PREGRP12 },
1256 { PREGRP11 },
1257 { "andps", XM, EX },
1258 { "andnps", XM, EX },
1259 { "orps", XM, EX },
2da11e11 1260 { "xorps", XM, EX },
252b5132 1261 /* 58 */
c608c12e
AM
1262 { PREGRP0 },
1263 { PREGRP10 },
1264 { "(bad)" },
2da11e11 1265 { "(bad)" },
c608c12e
AM
1266 { PREGRP14 },
1267 { PREGRP7 },
1268 { PREGRP5 },
2da11e11 1269 { PREGRP6 },
252b5132
RH
1270 /* 60 */
1271 { "punpcklbw", MX, EM },
1272 { "punpcklwd", MX, EM },
1273 { "punpckldq", MX, EM },
1274 { "packsswb", MX, EM },
1275 { "pcmpgtb", MX, EM },
1276 { "pcmpgtw", MX, EM },
1277 { "pcmpgtd", MX, EM },
1278 { "packuswb", MX, EM },
1279 /* 68 */
1280 { "punpckhbw", MX, EM },
1281 { "punpckhwd", MX, EM },
1282 { "punpckhdq", MX, EM },
1283 { "packssdw", MX, EM },
1284 { "(bad)" }, { "(bad)" },
2da11e11 1285 { "movd", MX, Ed },
252b5132
RH
1286 { "movq", MX, EM },
1287 /* 70 */
c608c12e 1288 { "pshufw", MX, EM, Ib },
252b5132
RH
1289 { GRP10 },
1290 { GRP11 },
1291 { GRP12 },
1292 { "pcmpeqb", MX, EM },
1293 { "pcmpeqw", MX, EM },
1294 { "pcmpeqd", MX, EM },
1295 { "emms" },
1296 /* 78 */
1297 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1298 { "(bad)" }, { "(bad)" },
2da11e11 1299 { "movd", Ed, MX },
252b5132
RH
1300 { "movq", EM, MX },
1301 /* 80 */
1302 { "jo", Jv },
1303 { "jno", Jv },
1304 { "jb", Jv },
1305 { "jae", Jv },
1306 { "je", Jv },
1307 { "jne", Jv },
1308 { "jbe", Jv },
1309 { "ja", Jv },
1310 /* 88 */
1311 { "js", Jv },
1312 { "jns", Jv },
1313 { "jp", Jv },
1314 { "jnp", Jv },
1315 { "jl", Jv },
1316 { "jge", Jv },
1317 { "jle", Jv },
1318 { "jg", Jv },
1319 /* 90 */
1320 { "seto", Eb },
1321 { "setno", Eb },
1322 { "setb", Eb },
1323 { "setae", Eb },
1324 { "sete", Eb },
1325 { "setne", Eb },
1326 { "setbe", Eb },
1327 { "seta", Eb },
1328 /* 98 */
1329 { "sets", Eb },
1330 { "setns", Eb },
1331 { "setp", Eb },
1332 { "setnp", Eb },
1333 { "setl", Eb },
1334 { "setge", Eb },
1335 { "setle", Eb },
1336 { "setg", Eb },
1337 /* a0 */
c608c12e
AM
1338 { "push", fs },
1339 { "pop", fs },
252b5132 1340 { "cpuid" },
c608c12e
AM
1341 { "bt", Ev, Gv },
1342 { "shld", Ev, Gv, Ib },
1343 { "shld", Ev, Gv, CL },
252b5132
RH
1344 { "(bad)" },
1345 { "(bad)" },
1346 /* a8 */
c608c12e
AM
1347 { "push", gs },
1348 { "pop", gs },
252b5132 1349 { "rsm" },
c608c12e
AM
1350 { "bts", Ev, Gv },
1351 { "shrd", Ev, Gv, Ib },
1352 { "shrd", Ev, Gv, CL },
252b5132 1353 { GRP13 },
c608c12e 1354 { "imul", Gv, Ev },
252b5132 1355 /* b0 */
c608c12e
AM
1356 { "cmpxchg", Eb, Gb },
1357 { "cmpxchg", Ev, Gv },
2da11e11 1358 { "lss", Gv, Mp },
c608c12e 1359 { "btr", Ev, Gv },
2da11e11
AM
1360 { "lfs", Gv, Mp },
1361 { "lgs", Gv, Mp },
252b5132
RH
1362 { "movzx", Gv, Eb },
1363 { "movzx", Gv, Ew },
1364 /* b8 */
1365 { "(bad)" },
1366 { "ud2b" },
1367 { GRP8 },
c608c12e
AM
1368 { "btc", Ev, Gv },
1369 { "bsf", Gv, Ev },
1370 { "bsr", Gv, Ev },
252b5132
RH
1371 { "movsx", Gv, Eb },
1372 { "movsx", Gv, Ew },
1373 /* c0 */
c608c12e
AM
1374 { "xadd", Eb, Gb },
1375 { "xadd", Ev, Gv },
1376 { PREGRP1 },
252b5132 1377 { "(bad)" },
c608c12e
AM
1378 { "pinsrw", MX, Ev, Ib },
1379 { "pextrw", Ev, MX, Ib },
1380 { "shufps", XM, EX, Ib },
252b5132
RH
1381 { GRP9 },
1382 /* c8 */
1383 { "bswap", eAX }, /* bswap doesn't support 16 bit regs */
1384 { "bswap", eCX },
1385 { "bswap", eDX },
1386 { "bswap", eBX },
1387 { "bswap", eSP },
1388 { "bswap", eBP },
1389 { "bswap", eSI },
1390 { "bswap", eDI },
1391 /* d0 */
1392 { "(bad)" },
1393 { "psrlw", MX, EM },
1394 { "psrld", MX, EM },
1395 { "psrlq", MX, EM },
1396 { "(bad)" },
1397 { "pmullw", MX, EM },
c608c12e 1398 { "(bad)" },
2da11e11 1399 { "pmovmskb", Ev, MX },
252b5132
RH
1400 /* d8 */
1401 { "psubusb", MX, EM },
1402 { "psubusw", MX, EM },
c608c12e 1403 { "pminub", MX, EM },
252b5132
RH
1404 { "pand", MX, EM },
1405 { "paddusb", MX, EM },
1406 { "paddusw", MX, EM },
c608c12e 1407 { "pmaxub", MX, EM },
252b5132
RH
1408 { "pandn", MX, EM },
1409 /* e0 */
c608c12e 1410 { "pavgb", MX, EM },
252b5132
RH
1411 { "psraw", MX, EM },
1412 { "psrad", MX, EM },
c608c12e
AM
1413 { "pavgw", MX, EM },
1414 { "pmulhuw", MX, EM },
252b5132 1415 { "pmulhw", MX, EM },
c608c12e 1416 { "(bad)" },
2da11e11 1417 { "movntq", Ev, MX },
252b5132
RH
1418 /* e8 */
1419 { "psubsb", MX, EM },
1420 { "psubsw", MX, EM },
c608c12e 1421 { "pminsw", MX, EM },
252b5132
RH
1422 { "por", MX, EM },
1423 { "paddsb", MX, EM },
1424 { "paddsw", MX, EM },
c608c12e 1425 { "pmaxsw", MX, EM },
252b5132
RH
1426 { "pxor", MX, EM },
1427 /* f0 */
1428 { "(bad)" },
1429 { "psllw", MX, EM },
1430 { "pslld", MX, EM },
1431 { "psllq", MX, EM },
1432 { "(bad)" },
1433 { "pmaddwd", MX, EM },
c608c12e 1434 { "psadbw", MX, EM },
2da11e11 1435 { "maskmovq", MX, EM },
252b5132
RH
1436 /* f8 */
1437 { "psubb", MX, EM },
1438 { "psubw", MX, EM },
1439 { "psubd", MX, EM },
1440 { "(bad)" },
1441 { "paddb", MX, EM },
1442 { "paddw", MX, EM },
1443 { "paddd", MX, EM },
1444 { "(bad)" }
1445};
1446
1447static const unsigned char onebyte_has_modrm[256] = {
c608c12e
AM
1448 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1449 /* ------------------------------- */
1450 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1451 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1452 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1453 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1454 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1455 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1456 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1457 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1458 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1459 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1460 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1461 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1462 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1463 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1464 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1465 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1466 /* ------------------------------- */
1467 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
252b5132
RH
1468};
1469
1470static const unsigned char twobyte_has_modrm[256] = {
c608c12e
AM
1471 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1472 /* ------------------------------- */
252b5132 1473 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
c608c12e
AM
1474 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1475 /* 20 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 2f */
252b5132
RH
1476 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1477 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
c608c12e 1478 /* 50 */ 1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1, /* 5f */
252b5132 1479 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
c608c12e 1480 /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
252b5132
RH
1481 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1482 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1483 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1484 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1485 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
c608c12e
AM
1486 /* d0 */ 0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, /* df */
1487 /* e0 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* ef */
1488 /* f0 */ 0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0 /* ff */
1489 /* ------------------------------- */
1490 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1491};
1492
1493static const unsigned char twobyte_uses_f3_prefix[256] = {
1494 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1495 /* ------------------------------- */
1496 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1497 /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1498 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1499 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1500 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1501 /* 50 */ 0,1,1,1,0,0,0,0,1,1,0,0,1,1,1,1, /* 5f */
1502 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1503 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1504 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1505 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1506 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1507 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1508 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1509 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1510 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1511 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* ff */
1512 /* ------------------------------- */
1513 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
252b5132
RH
1514};
1515
1516static char obuf[100];
1517static char *obufp;
1518static char scratchbuf[100];
1519static unsigned char *start_codep;
1520static unsigned char *insn_codep;
1521static unsigned char *codep;
1522static disassemble_info *the_info;
1523static int mod;
1524static int rm;
1525static int reg;
2da11e11 1526static void oappend PARAMS ((const char *s));
252b5132 1527
2da11e11 1528static const char *names32[]={
252b5132
RH
1529 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
1530};
2da11e11 1531static const char *names16[] = {
252b5132
RH
1532 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
1533};
2da11e11 1534static const char *names8[] = {
252b5132
RH
1535 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
1536};
2da11e11 1537static const char *names_seg[] = {
252b5132
RH
1538 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1539};
2da11e11 1540static const char *index16[] = {
252b5132
RH
1541 "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx"
1542};
1543
2da11e11 1544static const struct dis386 grps[][8] = {
252b5132
RH
1545 /* GRP1b */
1546 {
1547 { "addA", Eb, Ib },
1548 { "orA", Eb, Ib },
1549 { "adcA", Eb, Ib },
1550 { "sbbA", Eb, Ib },
1551 { "andA", Eb, Ib },
1552 { "subA", Eb, Ib },
1553 { "xorA", Eb, Ib },
1554 { "cmpA", Eb, Ib }
1555 },
1556 /* GRP1S */
1557 {
1558 { "addQ", Ev, Iv },
1559 { "orQ", Ev, Iv },
1560 { "adcQ", Ev, Iv },
1561 { "sbbQ", Ev, Iv },
1562 { "andQ", Ev, Iv },
1563 { "subQ", Ev, Iv },
1564 { "xorQ", Ev, Iv },
1565 { "cmpQ", Ev, Iv }
1566 },
1567 /* GRP1Ss */
1568 {
1569 { "addQ", Ev, sIb },
1570 { "orQ", Ev, sIb },
1571 { "adcQ", Ev, sIb },
1572 { "sbbQ", Ev, sIb },
1573 { "andQ", Ev, sIb },
1574 { "subQ", Ev, sIb },
1575 { "xorQ", Ev, sIb },
1576 { "cmpQ", Ev, sIb }
1577 },
1578 /* GRP2b */
1579 {
1580 { "rolA", Eb, Ib },
1581 { "rorA", Eb, Ib },
1582 { "rclA", Eb, Ib },
1583 { "rcrA", Eb, Ib },
1584 { "shlA", Eb, Ib },
1585 { "shrA", Eb, Ib },
1586 { "(bad)" },
1587 { "sarA", Eb, Ib },
1588 },
1589 /* GRP2S */
1590 {
1591 { "rolQ", Ev, Ib },
1592 { "rorQ", Ev, Ib },
1593 { "rclQ", Ev, Ib },
1594 { "rcrQ", Ev, Ib },
1595 { "shlQ", Ev, Ib },
1596 { "shrQ", Ev, Ib },
1597 { "(bad)" },
1598 { "sarQ", Ev, Ib },
1599 },
1600 /* GRP2b_one */
1601 {
1602 { "rolA", Eb },
1603 { "rorA", Eb },
1604 { "rclA", Eb },
1605 { "rcrA", Eb },
1606 { "shlA", Eb },
1607 { "shrA", Eb },
1608 { "(bad)" },
1609 { "sarA", Eb },
1610 },
1611 /* GRP2S_one */
1612 {
1613 { "rolQ", Ev },
1614 { "rorQ", Ev },
1615 { "rclQ", Ev },
1616 { "rcrQ", Ev },
1617 { "shlQ", Ev },
1618 { "shrQ", Ev },
1619 { "(bad)" },
1620 { "sarQ", Ev },
1621 },
1622 /* GRP2b_cl */
1623 {
1624 { "rolA", Eb, CL },
1625 { "rorA", Eb, CL },
1626 { "rclA", Eb, CL },
1627 { "rcrA", Eb, CL },
1628 { "shlA", Eb, CL },
1629 { "shrA", Eb, CL },
1630 { "(bad)" },
1631 { "sarA", Eb, CL },
1632 },
1633 /* GRP2S_cl */
1634 {
1635 { "rolQ", Ev, CL },
1636 { "rorQ", Ev, CL },
1637 { "rclQ", Ev, CL },
1638 { "rcrQ", Ev, CL },
1639 { "shlQ", Ev, CL },
1640 { "shrQ", Ev, CL },
1641 { "(bad)" },
1642 { "sarQ", Ev, CL }
1643 },
1644 /* GRP3b */
1645 {
1646 { "testA", Eb, Ib },
1647 { "(bad)", Eb },
1648 { "notA", Eb },
1649 { "negA", Eb },
1650 { "mulB", AL, Eb },
1651 { "imulB", AL, Eb },
1652 { "divB", AL, Eb },
1653 { "idivB", AL, Eb }
1654 },
1655 /* GRP3S */
1656 {
1657 { "testQ", Ev, Iv },
1658 { "(bad)" },
1659 { "notQ", Ev },
1660 { "negQ", Ev },
1661 { "mulS", eAX, Ev },
1662 { "imulS", eAX, Ev },
1663 { "divS", eAX, Ev },
1664 { "idivS", eAX, Ev },
1665 },
1666 /* GRP4 */
1667 {
1668 { "incA", Eb },
1669 { "decA", Eb },
1670 { "(bad)" },
1671 { "(bad)" },
1672 { "(bad)" },
1673 { "(bad)" },
1674 { "(bad)" },
1675 { "(bad)" },
1676 },
1677 /* GRP5 */
1678 {
1679 { "incQ", Ev },
1680 { "decQ", Ev },
1681 { "callP", indirEv },
1682 { "callP", indirEv },
1683 { "jmpP", indirEv },
1684 { "ljmpP", indirEv },
1685 { "pushQ", Ev },
1686 { "(bad)" },
1687 },
1688 /* GRP6 */
1689 {
1690 { "sldt", Ew },
1691 { "str", Ew },
1692 { "lldt", Ew },
1693 { "ltr", Ew },
1694 { "verr", Ew },
1695 { "verw", Ew },
1696 { "(bad)" },
1697 { "(bad)" }
1698 },
1699 /* GRP7 */
1700 {
1701 { "sgdt", Ew },
1702 { "sidt", Ew },
1703 { "lgdt", Ew },
1704 { "lidt", Ew },
1705 { "smsw", Ew },
1706 { "(bad)" },
1707 { "lmsw", Ew },
1708 { "invlpg", Ew },
1709 },
1710 /* GRP8 */
1711 {
1712 { "(bad)" },
1713 { "(bad)" },
1714 { "(bad)" },
1715 { "(bad)" },
1716 { "btQ", Ev, Ib },
1717 { "btsQ", Ev, Ib },
1718 { "btrQ", Ev, Ib },
1719 { "btcQ", Ev, Ib },
1720 },
1721 /* GRP9 */
1722 {
1723 { "(bad)" },
1724 { "cmpxchg8b", Ev },
1725 { "(bad)" },
1726 { "(bad)" },
1727 { "(bad)" },
1728 { "(bad)" },
1729 { "(bad)" },
1730 { "(bad)" },
1731 },
1732 /* GRP10 */
1733 {
1734 { "(bad)" },
1735 { "(bad)" },
1736 { "psrlw", MS, Ib },
1737 { "(bad)" },
1738 { "psraw", MS, Ib },
1739 { "(bad)" },
1740 { "psllw", MS, Ib },
1741 { "(bad)" },
1742 },
1743 /* GRP11 */
1744 {
1745 { "(bad)" },
1746 { "(bad)" },
1747 { "psrld", MS, Ib },
1748 { "(bad)" },
1749 { "psrad", MS, Ib },
1750 { "(bad)" },
1751 { "pslld", MS, Ib },
1752 { "(bad)" },
1753 },
1754 /* GRP12 */
1755 {
1756 { "(bad)" },
1757 { "(bad)" },
1758 { "psrlq", MS, Ib },
1759 { "(bad)" },
1760 { "(bad)" },
1761 { "(bad)" },
1762 { "psllq", MS, Ib },
1763 { "(bad)" },
1764 },
1765 /* GRP13 */
1766 {
1767 { "fxsave", Ev },
1768 { "fxrstor", Ev },
c608c12e
AM
1769 { "ldmxcsr", Ev },
1770 { "stmxcsr", Ev },
1771 { "(bad)" },
252b5132
RH
1772 { "(bad)" },
1773 { "(bad)" },
c608c12e
AM
1774 { "sfence", None },
1775 },
1776 /* GRP14 */
1777 {
1778 { "prefetchnta", Ev },
1779 { "prefetcht0", Ev },
1780 { "prefetcht1", Ev },
1781 { "prefetcht2", Ev },
252b5132
RH
1782 { "(bad)" },
1783 { "(bad)" },
1784 { "(bad)" },
1785 { "(bad)" },
1786 },
c608c12e 1787 /* GRPAMD */
252b5132
RH
1788 {
1789 { "prefetch", Eb },
1790 { "prefetchw", Eb },
1791 { "(bad)" },
1792 { "(bad)" },
1793 { "(bad)" },
1794 { "(bad)" },
1795 { "(bad)" },
1796 { "(bad)" },
1797 }
1798
1799};
1800
2da11e11 1801static const struct dis386 prefix_user_table[][2] = {
c608c12e
AM
1802 /* PREGRP0 */
1803 {
1804 { "addps", XM, EX },
1805 { "addss", XM, EX },
1806 },
1807 /* PREGRP1 */
1808 {
1809 { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX */
1810 { "", XM, EX, OPSIMD },
1811 },
1812 /* PREGRP2 */
1813 {
1814 { "cvtpi2ps", XM, EM },
1815 { "cvtsi2ss", XM, Ev },
1816 },
1817 /* PREGRP3 */
1818 {
1819 { "cvtps2pi", MX, EX },
1820 { "cvtss2si", Gv, EX },
1821 },
1822 /* PREGRP4 */
1823 {
2da11e11
AM
1824 { "cvttps2pi", MX, EX },
1825 { "cvttss2si", Gv, EX },
c608c12e
AM
1826 },
1827 /* PREGRP5 */
1828 {
1829 { "divps", XM, EX },
1830 { "divss", XM, EX },
1831 },
1832 /* PREGRP6 */
1833 {
1834 { "maxps", XM, EX },
1835 { "maxss", XM, EX },
1836 },
1837 /* PREGRP7 */
1838 {
1839 { "minps", XM, EX },
1840 { "minss", XM, EX },
1841 },
1842 /* PREGRP8 */
1843 {
1844 { "movups", XM, EX },
1845 { "movss", XM, EX },
1846 },
1847 /* PREGRP9 */
1848 {
1849 { "movups", EX, XM },
1850 { "movss", EX, XM },
1851 },
1852 /* PREGRP10 */
1853 {
1854 { "mulps", XM, EX },
1855 { "mulss", XM, EX },
1856 },
1857 /* PREGRP11 */
1858 {
1859 { "rcpps", XM, EX },
1860 { "rcpss", XM, EX },
1861 },
1862 /* PREGRP12 */
1863 {
1864 { "rsqrtps", XM, EX },
1865 { "rsqrtss", XM, EX },
1866 },
1867 /* PREGRP13 */
1868 {
1869 { "sqrtps", XM, EX },
1870 { "sqrtss", XM, EX },
1871 },
1872 /* PREGRP14 */
1873 {
1874 { "subps", XM, EX },
1875 { "subss", XM, EX },
1876 }
1877};
1878
1879#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1880
252b5132
RH
1881static void
1882ckprefix ()
1883{
1884 prefixes = 0;
7d421014 1885 used_prefixes = 0;
252b5132
RH
1886 while (1)
1887 {
1888 FETCH_DATA (the_info, codep + 1);
1889 switch (*codep)
1890 {
1891 case 0xf3:
1892 prefixes |= PREFIX_REPZ;
1893 break;
1894 case 0xf2:
1895 prefixes |= PREFIX_REPNZ;
1896 break;
1897 case 0xf0:
1898 prefixes |= PREFIX_LOCK;
1899 break;
1900 case 0x2e:
1901 prefixes |= PREFIX_CS;
1902 break;
1903 case 0x36:
1904 prefixes |= PREFIX_SS;
1905 break;
1906 case 0x3e:
1907 prefixes |= PREFIX_DS;
1908 break;
1909 case 0x26:
1910 prefixes |= PREFIX_ES;
1911 break;
1912 case 0x64:
1913 prefixes |= PREFIX_FS;
1914 break;
1915 case 0x65:
1916 prefixes |= PREFIX_GS;
1917 break;
1918 case 0x66:
1919 prefixes |= PREFIX_DATA;
1920 break;
1921 case 0x67:
1922 prefixes |= PREFIX_ADDR;
1923 break;
5076851f 1924 case FWAIT_OPCODE:
252b5132
RH
1925 /* fwait is really an instruction. If there are prefixes
1926 before the fwait, they belong to the fwait, *not* to the
1927 following instruction. */
1928 if (prefixes)
1929 {
1930 prefixes |= PREFIX_FWAIT;
1931 codep++;
1932 return;
1933 }
1934 prefixes = PREFIX_FWAIT;
1935 break;
1936 default:
1937 return;
1938 }
1939 codep++;
1940 }
1941}
1942
7d421014
ILT
1943/* Return the name of the prefix byte PREF, or NULL if PREF is not a
1944 prefix byte. */
1945
1946static const char *
1947prefix_name (pref, sizeflag)
1948 int pref;
1949 int sizeflag;
1950{
1951 switch (pref)
1952 {
1953 case 0xf3:
1954 return "repz";
1955 case 0xf2:
1956 return "repnz";
1957 case 0xf0:
1958 return "lock";
1959 case 0x2e:
1960 return "cs";
1961 case 0x36:
1962 return "ss";
1963 case 0x3e:
1964 return "ds";
1965 case 0x26:
1966 return "es";
1967 case 0x64:
1968 return "fs";
1969 case 0x65:
1970 return "gs";
1971 case 0x66:
1972 return (sizeflag & DFLAG) ? "data16" : "data32";
1973 case 0x67:
1974 return (sizeflag & AFLAG) ? "addr16" : "addr32";
1975 case FWAIT_OPCODE:
1976 return "fwait";
1977 default:
1978 return NULL;
1979 }
1980}
1981
252b5132
RH
1982static char op1out[100], op2out[100], op3out[100];
1983static int op_ad, op_index[3];
1984static unsigned int op_address[3];
1985static unsigned int start_pc;
1986
1987\f
1988/*
1989 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1990 * (see topic "Redundant prefixes" in the "Differences from 8086"
1991 * section of the "Virtual 8086 Mode" chapter.)
1992 * 'pc' should be the address of this instruction, it will
1993 * be used to print the target address if this is a relative jump or call
1994 * The function returns the length of this instruction in bytes.
1995 */
1996
252b5132
RH
1997static int print_insn_i386
1998 PARAMS ((bfd_vma pc, disassemble_info *info));
1999
2000static char intel_syntax;
2001static char open_char;
2002static char close_char;
2003static char separator_char;
2004static char scale_char;
2005
2006int
2007print_insn_i386_att (pc, info)
2008 bfd_vma pc;
2009 disassemble_info *info;
2010{
2011 intel_syntax = 0;
2012 open_char = '(';
2013 close_char = ')';
2014 separator_char = ',';
2015 scale_char = ',';
2016
2017 return print_insn_i386 (pc, info);
2018}
2019
2020int
2021print_insn_i386_intel (pc, info)
2022 bfd_vma pc;
2023 disassemble_info *info;
2024{
2025 intel_syntax = 1;
2026 open_char = '[';
2027 close_char = ']';
2028 separator_char = '+';
2029 scale_char = '*';
2030
2031 return print_insn_i386 (pc, info);
2032}
2033
2034static int
2035print_insn_i386 (pc, info)
2036 bfd_vma pc;
2037 disassemble_info *info;
2038{
2da11e11 2039 const struct dis386 *dp;
252b5132
RH
2040 int i;
2041 int two_source_ops;
2042 char *first, *second, *third;
2043 int needcomma;
2044 unsigned char need_modrm;
c608c12e 2045 unsigned char uses_f3_prefix;
7d421014 2046 int sizeflag, orig_sizeflag;
252b5132
RH
2047
2048 struct dis_private priv;
2049 bfd_byte *inbuf = priv.the_buffer;
2050
2da11e11
AM
2051 if (info->mach == bfd_mach_i386_i386
2052 || info->mach == bfd_mach_i386_i386_intel_syntax)
2053 sizeflag = AFLAG|DFLAG;
2054 else if (info->mach == bfd_mach_i386_i8086)
2055 sizeflag = 0;
2056 else
2057 abort ();
7d421014 2058 orig_sizeflag = sizeflag;
2da11e11 2059
c608c12e
AM
2060 /* The output looks better if we put 6 bytes on a line, since that
2061 puts most long word instructions on a single line. */
2062 info->bytes_per_line = 6;
252b5132
RH
2063
2064 info->private_data = (PTR) &priv;
2065 priv.max_fetched = priv.the_buffer;
2066 priv.insn_start = pc;
252b5132
RH
2067
2068 obuf[0] = 0;
2069 op1out[0] = 0;
2070 op2out[0] = 0;
2071 op3out[0] = 0;
2072
2073 op_index[0] = op_index[1] = op_index[2] = -1;
2074
2075 the_info = info;
2076 start_pc = pc;
2077 start_codep = inbuf;
2078 codep = inbuf;
2079
5076851f
ILT
2080 if (setjmp (priv.bailout) != 0)
2081 {
7d421014
ILT
2082 const char *name;
2083
5076851f 2084 /* Getting here means we tried for data but didn't get it. That
7d421014
ILT
2085 means we have an incomplete instruction of some sort. Just
2086 print the first byte as a prefix or a .byte pseudo-op. */
2087 if (codep > inbuf)
5076851f 2088 {
7d421014
ILT
2089 name = prefix_name (inbuf[0], orig_sizeflag);
2090 if (name != NULL)
2091 (*info->fprintf_func) (info->stream, "%s", name);
2092 else
5076851f 2093 {
7d421014
ILT
2094 /* Just print the first byte as a .byte instruction. */
2095 (*info->fprintf_func) (info->stream, ".byte 0x%x",
2096 (unsigned int) inbuf[0]);
5076851f 2097 }
5076851f 2098
7d421014 2099 return 1;
5076851f
ILT
2100 }
2101
2102 return -1;
2103 }
2104
252b5132
RH
2105 ckprefix ();
2106
2107 insn_codep = codep;
2108
2109 FETCH_DATA (info, codep + 1);
2110 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
2111
2112 obufp = obuf;
2113
2114 if ((prefixes & PREFIX_FWAIT)
2115 && ((*codep < 0xd8) || (*codep > 0xdf)))
2116 {
7d421014
ILT
2117 const char *name;
2118
2119 /* fwait not followed by floating point instruction. Print the
2120 first prefix, which is probably fwait itself. */
2121 name = prefix_name (inbuf[0], orig_sizeflag);
2122 if (name == NULL)
2123 name = INTERNAL_DISASSEMBLER_ERROR;
2124 (*info->fprintf_func) (info->stream, "%s", name);
2125 return 1;
252b5132
RH
2126 }
2127
252b5132
RH
2128 if (*codep == 0x0f)
2129 {
2130 FETCH_DATA (info, codep + 2);
2131 if (intel_syntax)
2132 dp = &dis386_twobyte_intel[*++codep];
2133 else
2134 dp = &dis386_twobyte_att[*++codep];
2135 need_modrm = twobyte_has_modrm[*codep];
c608c12e 2136 uses_f3_prefix = twobyte_uses_f3_prefix[*codep];
252b5132
RH
2137 }
2138 else
2139 {
2140 if (intel_syntax)
2141 dp = &dis386_intel[*codep];
2142 else
2143 dp = &dis386_att[*codep];
2144 need_modrm = onebyte_has_modrm[*codep];
c608c12e 2145 uses_f3_prefix = 0;
252b5132
RH
2146 }
2147 codep++;
2148
c608c12e 2149 if (!uses_f3_prefix && (prefixes & PREFIX_REPZ))
7d421014
ILT
2150 {
2151 oappend ("repz ");
2152 used_prefixes |= PREFIX_REPZ;
2153 }
c608c12e 2154 if (prefixes & PREFIX_REPNZ)
7d421014
ILT
2155 {
2156 oappend ("repnz ");
2157 used_prefixes |= PREFIX_REPNZ;
2158 }
c608c12e 2159 if (prefixes & PREFIX_LOCK)
7d421014
ILT
2160 {
2161 oappend ("lock ");
2162 used_prefixes |= PREFIX_LOCK;
2163 }
c608c12e
AM
2164
2165 if (prefixes & PREFIX_DATA)
2166 sizeflag ^= DFLAG;
2167
2168 if (prefixes & PREFIX_ADDR)
2169 {
2170 sizeflag ^= AFLAG;
2171 if (sizeflag & AFLAG)
2172 oappend ("addr32 ");
2173 else
2174 oappend ("addr16 ");
7d421014 2175 used_prefixes |= PREFIX_ADDR;
c608c12e
AM
2176 }
2177
252b5132
RH
2178 if (need_modrm)
2179 {
2180 FETCH_DATA (info, codep + 1);
2181 mod = (*codep >> 6) & 3;
2182 reg = (*codep >> 3) & 7;
2183 rm = *codep & 7;
2184 }
2185
2186 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2187 {
2188 dofloat (sizeflag);
2189 }
2190 else
2191 {
2192 if (dp->name == NULL)
c608c12e
AM
2193 {
2194 switch(dp->bytemode2)
2195 {
2196 case USE_GROUPS:
2197 dp = &grps[dp->bytemode1][reg];
2198 break;
2199 case USE_PREFIX_USER_TABLE:
2200 dp = &prefix_user_table[dp->bytemode1][prefixes & PREFIX_REPZ ? 1 : 0];
7d421014 2201 used_prefixes |= (prefixes & PREFIX_REPZ);
c608c12e
AM
2202 break;
2203 default:
2204 oappend (INTERNAL_DISASSEMBLER_ERROR);
2205 break;
2206 }
2207 }
252b5132
RH
2208
2209 putop (dp->name, sizeflag);
2210
2211 obufp = op1out;
2212 op_ad = 2;
2213 if (dp->op1)
2214 (*dp->op1)(dp->bytemode1, sizeflag);
2215
2216 obufp = op2out;
2217 op_ad = 1;
2218 if (dp->op2)
2219 (*dp->op2)(dp->bytemode2, sizeflag);
2220
2221 obufp = op3out;
2222 op_ad = 0;
2223 if (dp->op3)
2224 (*dp->op3)(dp->bytemode3, sizeflag);
2225 }
2226
7d421014
ILT
2227 /* See if any prefixes were not used. If so, print the first one
2228 separately. If we don't do this, we'll wind up printing an
2229 instruction stream which does not precisely correspond to the
2230 bytes we are disassembling. */
2231 if ((prefixes & ~used_prefixes) != 0)
2232 {
2233 const char *name;
2234
2235 name = prefix_name (inbuf[0], orig_sizeflag);
2236 if (name == NULL)
2237 name = INTERNAL_DISASSEMBLER_ERROR;
2238 (*info->fprintf_func) (info->stream, "%s", name);
2239 return 1;
2240 }
2241
252b5132
RH
2242 obufp = obuf + strlen (obuf);
2243 for (i = strlen (obuf); i < 6; i++)
2244 oappend (" ");
2245 oappend (" ");
2246 (*info->fprintf_func) (info->stream, "%s", obuf);
2247
2248 /* The enter and bound instructions are printed with operands in the same
2249 order as the intel book; everything else is printed in reverse order. */
2da11e11 2250 if (intel_syntax || two_source_ops)
252b5132
RH
2251 {
2252 first = op1out;
2253 second = op2out;
2254 third = op3out;
2255 op_ad = op_index[0];
2256 op_index[0] = op_index[2];
2257 op_index[2] = op_ad;
2258 }
2259 else
2260 {
2261 first = op3out;
2262 second = op2out;
2263 third = op1out;
2264 }
2265 needcomma = 0;
2266 if (*first)
2267 {
2268 if (op_index[0] != -1)
2269 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
2270 else
2271 (*info->fprintf_func) (info->stream, "%s", first);
2272 needcomma = 1;
2273 }
2274 if (*second)
2275 {
2276 if (needcomma)
2277 (*info->fprintf_func) (info->stream, ",");
2278 if (op_index[1] != -1)
2279 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
2280 else
2281 (*info->fprintf_func) (info->stream, "%s", second);
2282 needcomma = 1;
2283 }
2284 if (*third)
2285 {
2286 if (needcomma)
2287 (*info->fprintf_func) (info->stream, ",");
2288 if (op_index[2] != -1)
2289 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
2290 else
2291 (*info->fprintf_func) (info->stream, "%s", third);
2292 }
2293 return codep - inbuf;
2294}
2295
2da11e11 2296static const char *float_mem_att[] = {
252b5132
RH
2297 /* d8 */
2298 "fadds",
2299 "fmuls",
2300 "fcoms",
2301 "fcomps",
2302 "fsubs",
2303 "fsubrs",
2304 "fdivs",
2305 "fdivrs",
2306 /* d9 */
2307 "flds",
2308 "(bad)",
2309 "fsts",
2310 "fstps",
2311 "fldenv",
2312 "fldcw",
2313 "fNstenv",
2314 "fNstcw",
2315 /* da */
2316 "fiaddl",
2317 "fimull",
2318 "ficoml",
2319 "ficompl",
2320 "fisubl",
2321 "fisubrl",
2322 "fidivl",
2323 "fidivrl",
2324 /* db */
2325 "fildl",
2326 "(bad)",
2327 "fistl",
2328 "fistpl",
2329 "(bad)",
2330 "fldt",
2331 "(bad)",
2332 "fstpt",
2333 /* dc */
2334 "faddl",
2335 "fmull",
2336 "fcoml",
2337 "fcompl",
2338 "fsubl",
2339 "fsubrl",
2340 "fdivl",
2341 "fdivrl",
2342 /* dd */
2343 "fldl",
2344 "(bad)",
2345 "fstl",
2346 "fstpl",
2347 "frstor",
2348 "(bad)",
2349 "fNsave",
2350 "fNstsw",
2351 /* de */
2352 "fiadd",
2353 "fimul",
2354 "ficom",
2355 "ficomp",
2356 "fisub",
2357 "fisubr",
2358 "fidiv",
2359 "fidivr",
2360 /* df */
2361 "fild",
2362 "(bad)",
2363 "fist",
2364 "fistp",
2365 "fbld",
2366 "fildll",
2367 "fbstp",
2368 "fistpll",
2369};
2370
2da11e11 2371static const char *float_mem_intel[] = {
252b5132
RH
2372 /* d8 */
2373 "fadd",
2374 "fmul",
2375 "fcom",
2376 "fcomp",
2377 "fsub",
2378 "fsubr",
2379 "fdiv",
2380 "fdivr",
2381 /* d9 */
2382 "fld",
2383 "(bad)",
2384 "fst",
2385 "fstp",
2386 "fldenv",
2387 "fldcw",
2388 "fNstenv",
2389 "fNstcw",
2390 /* da */
2391 "fiadd",
2392 "fimul",
2393 "ficom",
2394 "ficomp",
2395 "fisub",
2396 "fisubr",
2397 "fidiv",
2398 "fidivr",
2399 /* db */
2400 "fild",
2401 "(bad)",
2402 "fist",
2403 "fistp",
2404 "(bad)",
2405 "fld",
2406 "(bad)",
2407 "fstp",
2408 /* dc */
2409 "fadd",
2410 "fmul",
2411 "fcom",
2412 "fcomp",
2413 "fsub",
2414 "fsubr",
2415 "fdiv",
2416 "fdivr",
2417 /* dd */
2418 "fld",
2419 "(bad)",
2420 "fst",
2421 "fstp",
2422 "frstor",
2423 "(bad)",
2424 "fNsave",
2425 "fNstsw",
2426 /* de */
2427 "fiadd",
2428 "fimul",
2429 "ficom",
2430 "ficomp",
2431 "fisub",
2432 "fisubr",
2433 "fidiv",
2434 "fidivr",
2435 /* df */
2436 "fild",
2437 "(bad)",
2438 "fist",
2439 "fistp",
2440 "fbld",
2441 "fild",
2442 "fbstp",
2443 "fistpll",
2444};
2445
2446#define ST OP_ST, 0
2447#define STi OP_STi, 0
2448
2449#define FGRPd9_2 NULL, NULL, 0
2450#define FGRPd9_4 NULL, NULL, 1
2451#define FGRPd9_5 NULL, NULL, 2
2452#define FGRPd9_6 NULL, NULL, 3
2453#define FGRPd9_7 NULL, NULL, 4
2454#define FGRPda_5 NULL, NULL, 5
2455#define FGRPdb_4 NULL, NULL, 6
2456#define FGRPde_3 NULL, NULL, 7
2457#define FGRPdf_4 NULL, NULL, 8
2458
2da11e11 2459static const struct dis386 float_reg[][8] = {
252b5132
RH
2460 /* d8 */
2461 {
2462 { "fadd", ST, STi },
2463 { "fmul", ST, STi },
2464 { "fcom", STi },
2465 { "fcomp", STi },
2466 { "fsub", ST, STi },
2467 { "fsubr", ST, STi },
2468 { "fdiv", ST, STi },
2469 { "fdivr", ST, STi },
2470 },
2471 /* d9 */
2472 {
2473 { "fld", STi },
2474 { "fxch", STi },
2475 { FGRPd9_2 },
2476 { "(bad)" },
2477 { FGRPd9_4 },
2478 { FGRPd9_5 },
2479 { FGRPd9_6 },
2480 { FGRPd9_7 },
2481 },
2482 /* da */
2483 {
2484 { "fcmovb", ST, STi },
2485 { "fcmove", ST, STi },
2486 { "fcmovbe",ST, STi },
2487 { "fcmovu", ST, STi },
2488 { "(bad)" },
2489 { FGRPda_5 },
2490 { "(bad)" },
2491 { "(bad)" },
2492 },
2493 /* db */
2494 {
2495 { "fcmovnb",ST, STi },
2496 { "fcmovne",ST, STi },
2497 { "fcmovnbe",ST, STi },
2498 { "fcmovnu",ST, STi },
2499 { FGRPdb_4 },
2500 { "fucomi", ST, STi },
2501 { "fcomi", ST, STi },
2502 { "(bad)" },
2503 },
2504 /* dc */
2505 {
2506 { "fadd", STi, ST },
2507 { "fmul", STi, ST },
2508 { "(bad)" },
2509 { "(bad)" },
2510#if UNIXWARE_COMPAT
2511 { "fsub", STi, ST },
2512 { "fsubr", STi, ST },
2513 { "fdiv", STi, ST },
2514 { "fdivr", STi, ST },
2515#else
2516 { "fsubr", STi, ST },
2517 { "fsub", STi, ST },
2518 { "fdivr", STi, ST },
2519 { "fdiv", STi, ST },
2520#endif
2521 },
2522 /* dd */
2523 {
2524 { "ffree", STi },
2525 { "(bad)" },
2526 { "fst", STi },
2527 { "fstp", STi },
2528 { "fucom", STi },
2529 { "fucomp", STi },
2530 { "(bad)" },
2531 { "(bad)" },
2532 },
2533 /* de */
2534 {
2535 { "faddp", STi, ST },
2536 { "fmulp", STi, ST },
2537 { "(bad)" },
2538 { FGRPde_3 },
2539#if UNIXWARE_COMPAT
2540 { "fsubp", STi, ST },
2541 { "fsubrp", STi, ST },
2542 { "fdivp", STi, ST },
2543 { "fdivrp", STi, ST },
2544#else
2545 { "fsubrp", STi, ST },
2546 { "fsubp", STi, ST },
2547 { "fdivrp", STi, ST },
2548 { "fdivp", STi, ST },
2549#endif
2550 },
2551 /* df */
2552 {
2553 { "(bad)" },
2554 { "(bad)" },
2555 { "(bad)" },
2556 { "(bad)" },
2557 { FGRPdf_4 },
2558 { "fucomip",ST, STi },
2559 { "fcomip", ST, STi },
2560 { "(bad)" },
2561 },
2562};
2563
2564
2565static char *fgrps[][8] = {
2566 /* d9_2 0 */
2567 {
2568 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2569 },
2570
2571 /* d9_4 1 */
2572 {
2573 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2574 },
2575
2576 /* d9_5 2 */
2577 {
2578 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2579 },
2580
2581 /* d9_6 3 */
2582 {
2583 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2584 },
2585
2586 /* d9_7 4 */
2587 {
2588 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2589 },
2590
2591 /* da_5 5 */
2592 {
2593 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2594 },
2595
2596 /* db_4 6 */
2597 {
2598 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2599 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2600 },
2601
2602 /* de_3 7 */
2603 {
2604 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2605 },
2606
2607 /* df_4 8 */
2608 {
2609 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2610 },
2611};
2612
2613static void
2614dofloat (sizeflag)
2615 int sizeflag;
2616{
2da11e11 2617 const struct dis386 *dp;
252b5132
RH
2618 unsigned char floatop;
2619
2620 floatop = codep[-1];
2621
2622 if (mod != 3)
2623 {
2624 if (intel_syntax)
2625 putop (float_mem_intel[(floatop - 0xd8 ) * 8 + reg], sizeflag);
2626 else
2627 putop (float_mem_att[(floatop - 0xd8 ) * 8 + reg], sizeflag);
2628 obufp = op1out;
2629 if (floatop == 0xdb)
2630 OP_E (x_mode, sizeflag);
2631 else if (floatop == 0xdd)
2632 OP_E (d_mode, sizeflag);
2da11e11 2633 else
252b5132
RH
2634 OP_E (v_mode, sizeflag);
2635 return;
2636 }
2637 codep++;
2638
2639 dp = &float_reg[floatop - 0xd8][reg];
2640 if (dp->name == NULL)
2641 {
2642 putop (fgrps[dp->bytemode1][rm], sizeflag);
2643
2644 /* instruction fnstsw is only one with strange arg */
2645 if (floatop == 0xdf && codep[-1] == 0xe0)
2646 strcpy (op1out, names16[0]);
2647 }
2648 else
2649 {
2650 putop (dp->name, sizeflag);
2651
2652 obufp = op1out;
2653 if (dp->op1)
2654 (*dp->op1)(dp->bytemode1, sizeflag);
2655 obufp = op2out;
2656 if (dp->op2)
2657 (*dp->op2)(dp->bytemode2, sizeflag);
2658 }
2659}
2660
2661/* ARGSUSED */
2662static void
2663OP_ST (ignore, sizeflag)
2664 int ignore;
2665 int sizeflag;
2666{
2667 oappend ("%st");
2668}
2669
2670/* ARGSUSED */
2671static void
2672OP_STi (ignore, sizeflag)
2673 int ignore;
2674 int sizeflag;
2675{
2676 sprintf (scratchbuf, "%%st(%d)", rm);
2677 oappend (scratchbuf);
2678}
2679
2680
2681/* capital letters in template are macros */
2682static void
2683putop (template, sizeflag)
2da11e11 2684 const char *template;
252b5132
RH
2685 int sizeflag;
2686{
2da11e11 2687 const char *p;
252b5132
RH
2688
2689 for (p = template; *p; p++)
2690 {
2691 switch (*p)
2692 {
2693 default:
2694 *obufp++ = *p;
2695 break;
2696 case 'A':
2697 if (intel_syntax)
2698 break;
2699 if (mod != 3
2700#ifdef SUFFIX_ALWAYS
2701 || (sizeflag & SUFFIX_ALWAYS)
2702#endif
2703 )
2704 *obufp++ = 'b';
2705 break;
2706 case 'B':
2707 if (intel_syntax)
2708 break;
2709#ifdef SUFFIX_ALWAYS
2710 if (sizeflag & SUFFIX_ALWAYS)
2711 *obufp++ = 'b';
2712#endif
2713 break;
2714 case 'E': /* For jcxz/jecxz */
2715 if (sizeflag & AFLAG)
2716 *obufp++ = 'e';
2717 break;
2718 case 'L':
2719 if (intel_syntax)
2720 break;
2721#ifdef SUFFIX_ALWAYS
2722 if (sizeflag & SUFFIX_ALWAYS)
2723 *obufp++ = 'l';
2724#endif
2725 break;
2726 case 'N':
2727 if ((prefixes & PREFIX_FWAIT) == 0)
2728 *obufp++ = 'n';
7d421014
ILT
2729 else
2730 used_prefixes |= PREFIX_FWAIT;
252b5132
RH
2731 break;
2732 case 'P':
2733 if (intel_syntax)
2734 break;
2735 if ((prefixes & PREFIX_DATA)
2736#ifdef SUFFIX_ALWAYS
2737 || (sizeflag & SUFFIX_ALWAYS)
2738#endif
2739 )
2740 {
2741 if (sizeflag & DFLAG)
2742 *obufp++ = 'l';
2743 else
2744 *obufp++ = 'w';
7d421014 2745 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
2746 }
2747 break;
2748 case 'Q':
2749 if (intel_syntax)
2750 break;
2751 if (mod != 3
2752#ifdef SUFFIX_ALWAYS
2753 || (sizeflag & SUFFIX_ALWAYS)
2754#endif
2755 )
2756 {
2757 if (sizeflag & DFLAG)
2758 *obufp++ = 'l';
2759 else
2760 *obufp++ = 'w';
7d421014 2761 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
2762 }
2763 break;
2764 case 'R':
2765 if (intel_syntax)
c608c12e
AM
2766 {
2767 if (sizeflag & DFLAG)
2768 {
2769 *obufp++ = 'd';
2770 *obufp++ = 'q';
2771 }
2772 else
2773 {
2774 *obufp++ = 'w';
2775 *obufp++ = 'd';
2776 }
2777 }
252b5132 2778 else
c608c12e
AM
2779 {
2780 if (sizeflag & DFLAG)
2781 *obufp++ = 'l';
2782 else
2783 *obufp++ = 'w';
2784 }
7d421014 2785 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
2786 break;
2787 case 'S':
2788 if (intel_syntax)
2789 break;
2790#ifdef SUFFIX_ALWAYS
2791 if (sizeflag & SUFFIX_ALWAYS)
2792 {
2793 if (sizeflag & DFLAG)
2794 *obufp++ = 'l';
2795 else
2796 *obufp++ = 'w';
7d421014 2797 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
2798 }
2799#endif
2800 break;
2801 case 'W':
252b5132
RH
2802 /* operand size flag for cwtl, cbtw */
2803 if (sizeflag & DFLAG)
2804 *obufp++ = 'w';
2805 else
2806 *obufp++ = 'b';
c608c12e
AM
2807 if (intel_syntax)
2808 {
2809 if (sizeflag & DFLAG)
2810 {
2811 *obufp++ = 'd';
2812 *obufp++ = 'e';
2813 }
2814 else
2815 {
2816 *obufp++ = 'w';
2817 }
2818 }
7d421014 2819 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
2820 break;
2821 }
2822 }
2823 *obufp = 0;
2824}
2825
2826static void
2827oappend (s)
2da11e11 2828 const char *s;
252b5132
RH
2829{
2830 strcpy (obufp, s);
2831 obufp += strlen (s);
2832}
2833
2834static void
2835append_seg ()
2836{
2837 if (prefixes & PREFIX_CS)
7d421014
ILT
2838 {
2839 oappend ("%cs:");
2840 used_prefixes |= PREFIX_CS;
2841 }
252b5132 2842 if (prefixes & PREFIX_DS)
7d421014
ILT
2843 {
2844 oappend ("%ds:");
2845 used_prefixes |= PREFIX_DS;
2846 }
252b5132 2847 if (prefixes & PREFIX_SS)
7d421014
ILT
2848 {
2849 oappend ("%ss:");
2850 used_prefixes |= PREFIX_SS;
2851 }
252b5132 2852 if (prefixes & PREFIX_ES)
7d421014
ILT
2853 {
2854 oappend ("%es:");
2855 used_prefixes |= PREFIX_ES;
2856 }
252b5132 2857 if (prefixes & PREFIX_FS)
7d421014
ILT
2858 {
2859 oappend ("%fs:");
2860 used_prefixes |= PREFIX_FS;
2861 }
252b5132 2862 if (prefixes & PREFIX_GS)
7d421014
ILT
2863 {
2864 oappend ("%gs:");
2865 used_prefixes |= PREFIX_GS;
2866 }
252b5132
RH
2867}
2868
2869static void
2870OP_indirE (bytemode, sizeflag)
2871 int bytemode;
2872 int sizeflag;
2873{
2874 if (!intel_syntax)
2875 oappend ("*");
2876 OP_E (bytemode, sizeflag);
2877}
2878
2879static void
2880OP_E (bytemode, sizeflag)
2881 int bytemode;
2882 int sizeflag;
2883{
2884 int disp;
2885
2886 /* skip mod/rm byte */
2887 codep++;
2888
2889 if (mod == 3)
2890 {
2891 switch (bytemode)
2892 {
2893 case b_mode:
2894 oappend (names8[rm]);
2895 break;
2896 case w_mode:
2897 oappend (names16[rm]);
2898 break;
2da11e11
AM
2899 case d_mode:
2900 oappend (names32[rm]);
2901 break;
252b5132
RH
2902 case v_mode:
2903 if (sizeflag & DFLAG)
2904 oappend (names32[rm]);
2905 else
2906 oappend (names16[rm]);
7d421014 2907 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132 2908 break;
2da11e11
AM
2909 case 0:
2910 if ( !(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */))
2911 BadOp(); /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */
c608c12e 2912 break;
252b5132 2913 default:
c608c12e 2914 oappend (INTERNAL_DISASSEMBLER_ERROR);
252b5132
RH
2915 break;
2916 }
2917 return;
2918 }
2919
2920 disp = 0;
2921 append_seg ();
2922
2923 if (sizeflag & AFLAG) /* 32 bit address mode */
2924 {
2925 int havesib;
2926 int havebase;
2927 int base;
2928 int index = 0;
2929 int scale = 0;
2930
2931 havesib = 0;
2932 havebase = 1;
2933 base = rm;
2934
2935 if (base == 4)
2936 {
2937 havesib = 1;
2938 FETCH_DATA (the_info, codep + 1);
2939 scale = (*codep >> 6) & 3;
2940 index = (*codep >> 3) & 7;
2941 base = *codep & 7;
2942 codep++;
2943 }
2944
2945 switch (mod)
2946 {
2947 case 0:
2948 if (base == 5)
2949 {
2950 havebase = 0;
2951 disp = get32 ();
2952 }
2953 break;
2954 case 1:
2955 FETCH_DATA (the_info, codep + 1);
2956 disp = *codep++;
2957 if ((disp & 0x80) != 0)
2958 disp -= 0x100;
2959 break;
2960 case 2:
2961 disp = get32 ();
2962 break;
2963 }
2964
2965 if (!intel_syntax)
2966 if (mod != 0 || base == 5)
2967 {
2968 sprintf (scratchbuf, "0x%x", disp);
2969 oappend (scratchbuf);
2970 }
2da11e11 2971
252b5132
RH
2972 if (havebase || (havesib && (index != 4 || scale != 0)))
2973 {
2974 if (intel_syntax)
2975 {
2976 switch (bytemode)
2977 {
2978 case b_mode:
2979 oappend("BYTE PTR ");
2980 break;
2981 case w_mode:
2982 oappend("WORD PTR ");
2983 break;
2984 case v_mode:
2985 oappend("DWORD PTR ");
2986 break;
2987 case d_mode:
2988 oappend("QWORD PTR ");
2989 break;
2990 case x_mode:
2991 oappend("XWORD PTR ");
2992 break;
2993 default:
2994 break;
2995 }
2996 }
2997 *obufp++ = open_char;
2998 *obufp = '\0';
2999 if (havebase)
3000 oappend (names32[base]);
3001 if (havesib)
3002 {
3003 if (index != 4)
3004 {
3005 if (intel_syntax)
3006 {
3007 if (havebase)
3008 {
3009 *obufp++ = separator_char;
3010 *obufp = '\0';
3011 }
3012 sprintf (scratchbuf, "%s", names32[index]);
3013 }
3014 else
3015 sprintf (scratchbuf, ",%s", names32[index]);
3016 oappend (scratchbuf);
3017 }
3018 if (!intel_syntax
2da11e11 3019 || (intel_syntax
252b5132
RH
3020 && bytemode != b_mode
3021 && bytemode != w_mode
3022 && bytemode != v_mode))
3023 {
3024 *obufp++ = scale_char;
3025 *obufp = '\0';
3026 sprintf (scratchbuf, "%d", 1 << scale);
3027 oappend (scratchbuf);
3028 }
3029 }
3030 if (intel_syntax)
3031 if (mod != 0 || base == 5)
3032 {
3033 /* Don't print zero displacements */
3034 if (disp > 0)
3035 {
3036 sprintf (scratchbuf, "+%d", disp);
3037 oappend (scratchbuf);
3038 }
3039 else if (disp < 0)
3040 {
3041 sprintf (scratchbuf, "%d", disp);
3042 oappend (scratchbuf);
3043 }
3044 }
3045
3046 *obufp++ = close_char;
3047 *obufp = '\0';
3048 }
3049 else if (intel_syntax)
3050 {
3051 if (mod != 0 || base == 5)
3052 {
3053 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3054 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
3055 ;
3056 else
3057 {
3058 oappend (names_seg[3]);
3059 oappend (":");
3060 }
3061 sprintf (scratchbuf, "0x%x", disp);
3062 oappend (scratchbuf);
3063 }
3064 }
3065 }
3066 else
3067 { /* 16 bit address mode */
3068 switch (mod)
3069 {
3070 case 0:
3071 if (rm == 6)
3072 {
3073 disp = get16 ();
3074 if ((disp & 0x8000) != 0)
3075 disp -= 0x10000;
3076 }
3077 break;
3078 case 1:
3079 FETCH_DATA (the_info, codep + 1);
3080 disp = *codep++;
3081 if ((disp & 0x80) != 0)
3082 disp -= 0x100;
3083 break;
3084 case 2:
3085 disp = get16 ();
3086 if ((disp & 0x8000) != 0)
3087 disp -= 0x10000;
3088 break;
3089 }
3090
3091 if (!intel_syntax)
3092 if (mod != 0 || rm == 6)
3093 {
3094 sprintf (scratchbuf, "%d", disp);
3095 oappend (scratchbuf);
3096 }
3097
3098 if (mod != 0 || rm != 6)
3099 {
3100 *obufp++ = open_char;
3101 *obufp = '\0';
3102 oappend (index16[rm]);
3103 *obufp++ = close_char;
3104 *obufp = '\0';
3105 }
3106 }
3107}
3108
252b5132
RH
3109static void
3110OP_G (bytemode, sizeflag)
3111 int bytemode;
3112 int sizeflag;
3113{
3114 switch (bytemode)
3115 {
3116 case b_mode:
3117 oappend (names8[reg]);
3118 break;
3119 case w_mode:
3120 oappend (names16[reg]);
3121 break;
3122 case d_mode:
3123 oappend (names32[reg]);
3124 break;
3125 case v_mode:
3126 if (sizeflag & DFLAG)
3127 oappend (names32[reg]);
3128 else
3129 oappend (names16[reg]);
7d421014 3130 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
3131 break;
3132 default:
3133 oappend (INTERNAL_DISASSEMBLER_ERROR);
3134 break;
3135 }
3136}
3137
3138static int
3139get32 ()
3140{
3141 int x = 0;
3142
3143 FETCH_DATA (the_info, codep + 4);
3144 x = *codep++ & 0xff;
3145 x |= (*codep++ & 0xff) << 8;
3146 x |= (*codep++ & 0xff) << 16;
3147 x |= (*codep++ & 0xff) << 24;
3148 return x;
3149}
3150
3151static int
3152get16 ()
3153{
3154 int x = 0;
3155
3156 FETCH_DATA (the_info, codep + 2);
3157 x = *codep++ & 0xff;
3158 x |= (*codep++ & 0xff) << 8;
3159 return x;
3160}
3161
3162static void
3163set_op (op)
3164 unsigned int op;
3165{
3166 op_index[op_ad] = op_ad;
3167 op_address[op_ad] = op;
3168}
3169
3170static void
3171OP_REG (code, sizeflag)
3172 int code;
3173 int sizeflag;
3174{
2da11e11 3175 const char *s;
252b5132
RH
3176
3177 switch (code)
3178 {
3179 case indir_dx_reg:
3180 s = "(%dx)";
3181 break;
3182 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3183 case sp_reg: case bp_reg: case si_reg: case di_reg:
3184 s = names16[code - ax_reg];
3185 break;
3186 case es_reg: case ss_reg: case cs_reg:
3187 case ds_reg: case fs_reg: case gs_reg:
3188 s = names_seg[code - es_reg];
3189 break;
3190 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3191 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3192 s = names8[code - al_reg];
3193 break;
3194 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3195 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3196 if (sizeflag & DFLAG)
3197 s = names32[code - eAX_reg];
3198 else
3199 s = names16[code - eAX_reg];
7d421014 3200 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
3201 break;
3202 default:
3203 s = INTERNAL_DISASSEMBLER_ERROR;
3204 break;
3205 }
3206 oappend (s);
3207}
3208
3209static void
3210OP_I (bytemode, sizeflag)
3211 int bytemode;
3212 int sizeflag;
3213{
3214 int op;
3215
3216 switch (bytemode)
3217 {
3218 case b_mode:
3219 FETCH_DATA (the_info, codep + 1);
3220 op = *codep++ & 0xff;
3221 break;
3222 case v_mode:
3223 if (sizeflag & DFLAG)
3224 op = get32 ();
3225 else
3226 op = get16 ();
7d421014 3227 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
3228 break;
3229 case w_mode:
3230 op = get16 ();
3231 break;
3232 default:
3233 oappend (INTERNAL_DISASSEMBLER_ERROR);
3234 return;
3235 }
3236
3237 if (intel_syntax)
3238 sprintf (scratchbuf, "0x%x", op);
3239 else
3240 sprintf (scratchbuf, "$0x%x", op);
3241 oappend (scratchbuf);
3242 scratchbuf[0] = '\0';
3243}
3244
3245static void
3246OP_sI (bytemode, sizeflag)
3247 int bytemode;
3248 int sizeflag;
3249{
3250 int op;
3251
3252 switch (bytemode)
3253 {
3254 case b_mode:
3255 FETCH_DATA (the_info, codep + 1);
3256 op = *codep++;
3257 if ((op & 0x80) != 0)
3258 op -= 0x100;
3259 break;
3260 case v_mode:
3261 if (sizeflag & DFLAG)
3262 op = get32 ();
3263 else
3264 {
3265 op = get16();
3266 if ((op & 0x8000) != 0)
3267 op -= 0x10000;
3268 }
7d421014 3269 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
3270 break;
3271 case w_mode:
3272 op = get16 ();
3273 if ((op & 0x8000) != 0)
3274 op -= 0x10000;
3275 break;
3276 default:
3277 oappend (INTERNAL_DISASSEMBLER_ERROR);
3278 return;
3279 }
3280 if (intel_syntax)
3281 sprintf (scratchbuf, "%d", op);
3282 else
3283 sprintf (scratchbuf, "$0x%x", op);
3284 oappend (scratchbuf);
3285}
3286
3287static void
3288OP_J (bytemode, sizeflag)
3289 int bytemode;
3290 int sizeflag;
3291{
3292 int disp;
3293 int mask = -1;
3294
3295 switch (bytemode)
3296 {
3297 case b_mode:
3298 FETCH_DATA (the_info, codep + 1);
3299 disp = *codep++;
3300 if ((disp & 0x80) != 0)
3301 disp -= 0x100;
3302 break;
3303 case v_mode:
3304 if (sizeflag & DFLAG)
3305 disp = get32 ();
3306 else
3307 {
3308 disp = get16 ();
3309 /* for some reason, a data16 prefix on a jump instruction
3310 means that the pc is masked to 16 bits after the
3311 displacement is added! */
3312 mask = 0xffff;
3313 }
7d421014 3314 used_prefixes |= (prefixes & PREFIX_DATA);
252b5132
RH
3315 break;
3316 default:
3317 oappend (INTERNAL_DISASSEMBLER_ERROR);
3318 return;
3319 }
3320 disp = (start_pc + codep - start_codep + disp) & mask;
3321 set_op (disp);
3322 sprintf (scratchbuf, "0x%x", disp);
3323 oappend (scratchbuf);
3324}
3325
3326/* ARGSUSED */
3327static void
3328OP_SEG (dummy, sizeflag)
3329 int dummy;
3330 int sizeflag;
3331{
3332 static char *sreg[] = {
3333 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
3334 };
3335
3336 oappend (sreg[reg]);
3337}
3338
c608c12e 3339/* ARGSUSED */
252b5132 3340static void
c608c12e
AM
3341OP_DIR (dummy, sizeflag)
3342 int dummy;
252b5132
RH
3343 int sizeflag;
3344{
3345 int seg, offset;
3346
c608c12e 3347 if (sizeflag & DFLAG)
252b5132 3348 {
c608c12e
AM
3349 offset = get32 ();
3350 seg = get16 ();
252b5132 3351 }
c608c12e
AM
3352 else
3353 {
3354 offset = get16 ();
3355 seg = get16 ();
3356 }
7d421014 3357 used_prefixes |= (prefixes & PREFIX_DATA);
c608c12e
AM
3358 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3359 oappend (scratchbuf);
252b5132
RH
3360}
3361
3362/* ARGSUSED */
3363static void
3364OP_OFF (ignore, sizeflag)
3365 int ignore;
3366 int sizeflag;
3367{
3368 int off;
3369
3370 append_seg ();
3371
3372 if (sizeflag & AFLAG)
3373 off = get32 ();
3374 else
3375 off = get16 ();
3376
3377 if (intel_syntax)
3378 {
3379 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3380 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3381 {
3382 oappend (names_seg[3]);
3383 oappend (":");
3384 }
3385 }
3386 sprintf (scratchbuf, "0x%x", off);
3387 oappend (scratchbuf);
3388}
3389
3390static void
3391ptr_reg (code, sizeflag)
3392 int code;
3393 int sizeflag;
3394{
2da11e11 3395 const char *s;
252b5132
RH
3396 oappend ("(");
3397 if (sizeflag & AFLAG)
3398 s = names32[code - eAX_reg];
3399 else
3400 s = names16[code - eAX_reg];
3401 oappend (s);
3402 oappend (")");
3403}
3404
3405static void
3406OP_ESreg (code, sizeflag)
3407 int code;
3408 int sizeflag;
3409{
3410 oappend ("%es:");
3411 ptr_reg (code, sizeflag);
3412}
3413
3414static void
3415OP_DSreg (code, sizeflag)
3416 int code;
3417 int sizeflag;
3418{
3419 if ((prefixes
3420 & (PREFIX_CS
3421 | PREFIX_DS
3422 | PREFIX_SS
3423 | PREFIX_ES
3424 | PREFIX_FS
3425 | PREFIX_GS)) == 0)
3426 prefixes |= PREFIX_DS;
3427 append_seg();
3428 ptr_reg (code, sizeflag);
3429}
3430
252b5132
RH
3431/* ARGSUSED */
3432static void
3433OP_C (dummy, sizeflag)
3434 int dummy;
3435 int sizeflag;
3436{
252b5132
RH
3437 sprintf (scratchbuf, "%%cr%d", reg);
3438 oappend (scratchbuf);
3439}
3440
3441/* ARGSUSED */
3442static void
3443OP_D (dummy, sizeflag)
3444 int dummy;
3445 int sizeflag;
3446{
252b5132
RH
3447 sprintf (scratchbuf, "%%db%d", reg);
3448 oappend (scratchbuf);
3449}
3450
3451/* ARGSUSED */
3452static void
3453OP_T (dummy, sizeflag)
3454 int dummy;
3455 int sizeflag;
3456{
252b5132
RH
3457 sprintf (scratchbuf, "%%tr%d", reg);
3458 oappend (scratchbuf);
3459}
3460
3461static void
2da11e11 3462OP_Rd (bytemode, sizeflag)
252b5132
RH
3463 int bytemode;
3464 int sizeflag;
3465{
2da11e11
AM
3466 if (mod == 3)
3467 OP_E (bytemode, sizeflag);
3468 else
3469 BadOp();
252b5132
RH
3470}
3471
3472static void
3473OP_MMX (ignore, sizeflag)
3474 int ignore;
3475 int sizeflag;
3476{
3477 sprintf (scratchbuf, "%%mm%d", reg);
3478 oappend (scratchbuf);
3479}
3480
c608c12e
AM
3481static void
3482OP_XMM (bytemode, sizeflag)
3483 int bytemode;
3484 int sizeflag;
3485{
3486 sprintf (scratchbuf, "%%xmm%d", reg);
3487 oappend (scratchbuf);
3488}
3489
252b5132
RH
3490static void
3491OP_EM (bytemode, sizeflag)
3492 int bytemode;
3493 int sizeflag;
3494{
3495 if (mod != 3)
3496 {
3497 OP_E (bytemode, sizeflag);
3498 return;
3499 }
3500
3501 codep++;
3502 sprintf (scratchbuf, "%%mm%d", rm);
3503 oappend (scratchbuf);
3504}
3505
c608c12e
AM
3506static void
3507OP_EX (bytemode, sizeflag)
3508 int bytemode;
3509 int sizeflag;
3510{
3511 if (mod != 3)
3512 {
3513 OP_E (bytemode, sizeflag);
3514 return;
3515 }
3516
3517 codep++;
3518 sprintf (scratchbuf, "%%xmm%d", rm);
3519 oappend (scratchbuf);
3520}
3521
252b5132 3522static void
2da11e11
AM
3523OP_MS (bytemode, sizeflag)
3524 int bytemode;
252b5132
RH
3525 int sizeflag;
3526{
2da11e11
AM
3527 if (mod == 3)
3528 OP_EM (bytemode, sizeflag);
3529 else
3530 BadOp();
252b5132
RH
3531}
3532
3533static const char *Suffix3DNow[] = {
3534/* 00 */ NULL, NULL, NULL, NULL,
3535/* 04 */ NULL, NULL, NULL, NULL,
3536/* 08 */ NULL, NULL, NULL, NULL,
3537/* 0C */ NULL, "pi2fd", NULL, NULL,
3538/* 10 */ NULL, NULL, NULL, NULL,
3539/* 14 */ NULL, NULL, NULL, NULL,
3540/* 18 */ NULL, NULL, NULL, NULL,
3541/* 1C */ NULL, "pf2id", NULL, NULL,
3542/* 20 */ NULL, NULL, NULL, NULL,
3543/* 24 */ NULL, NULL, NULL, NULL,
3544/* 28 */ NULL, NULL, NULL, NULL,
3545/* 2C */ NULL, NULL, NULL, NULL,
3546/* 30 */ NULL, NULL, NULL, NULL,
3547/* 34 */ NULL, NULL, NULL, NULL,
3548/* 38 */ NULL, NULL, NULL, NULL,
3549/* 3C */ NULL, NULL, NULL, NULL,
3550/* 40 */ NULL, NULL, NULL, NULL,
3551/* 44 */ NULL, NULL, NULL, NULL,
3552/* 48 */ NULL, NULL, NULL, NULL,
3553/* 4C */ NULL, NULL, NULL, NULL,
3554/* 50 */ NULL, NULL, NULL, NULL,
3555/* 54 */ NULL, NULL, NULL, NULL,
3556/* 58 */ NULL, NULL, NULL, NULL,
3557/* 5C */ NULL, NULL, NULL, NULL,
3558/* 60 */ NULL, NULL, NULL, NULL,
3559/* 64 */ NULL, NULL, NULL, NULL,
3560/* 68 */ NULL, NULL, NULL, NULL,
3561/* 6C */ NULL, NULL, NULL, NULL,
3562/* 70 */ NULL, NULL, NULL, NULL,
3563/* 74 */ NULL, NULL, NULL, NULL,
3564/* 78 */ NULL, NULL, NULL, NULL,
3565/* 7C */ NULL, NULL, NULL, NULL,
3566/* 80 */ NULL, NULL, NULL, NULL,
3567/* 84 */ NULL, NULL, NULL, NULL,
3568/* 88 */ NULL, NULL, NULL, NULL,
3569/* 8C */ NULL, NULL, NULL, NULL,
3570/* 90 */ "pfcmpge", NULL, NULL, NULL,
3571/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
3572/* 98 */ NULL, NULL, "pfsub", NULL,
3573/* 9C */ NULL, NULL, "pfadd", NULL,
3574/* A0 */ "pfcmpgt", NULL, NULL, NULL,
3575/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
3576/* A8 */ NULL, NULL, "pfsubr", NULL,
3577/* AC */ NULL, NULL, "pfacc", NULL,
3578/* B0 */ "pfcmpeq", NULL, NULL, NULL,
3579/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
3580/* B8 */ NULL, NULL, NULL, NULL,
3581/* BC */ NULL, NULL, NULL, "pavgusb",
3582/* C0 */ NULL, NULL, NULL, NULL,
3583/* C4 */ NULL, NULL, NULL, NULL,
3584/* C8 */ NULL, NULL, NULL, NULL,
3585/* CC */ NULL, NULL, NULL, NULL,
3586/* D0 */ NULL, NULL, NULL, NULL,
3587/* D4 */ NULL, NULL, NULL, NULL,
3588/* D8 */ NULL, NULL, NULL, NULL,
3589/* DC */ NULL, NULL, NULL, NULL,
3590/* E0 */ NULL, NULL, NULL, NULL,
3591/* E4 */ NULL, NULL, NULL, NULL,
3592/* E8 */ NULL, NULL, NULL, NULL,
3593/* EC */ NULL, NULL, NULL, NULL,
3594/* F0 */ NULL, NULL, NULL, NULL,
3595/* F4 */ NULL, NULL, NULL, NULL,
3596/* F8 */ NULL, NULL, NULL, NULL,
3597/* FC */ NULL, NULL, NULL, NULL,
3598};
3599
3600static void
3601OP_3DNowSuffix (bytemode, sizeflag)
3602 int bytemode;
3603 int sizeflag;
3604{
3605 const char *mnemonic;
3606
3607 FETCH_DATA (the_info, codep + 1);
3608 /* AMD 3DNow! instructions are specified by an opcode suffix in the
3609 place where an 8-bit immediate would normally go. ie. the last
3610 byte of the instruction. */
2da11e11 3611 obufp = obuf + strlen(obuf);
c608c12e 3612 mnemonic = Suffix3DNow[*codep++ & 0xff];
252b5132 3613 if (mnemonic)
2da11e11 3614 oappend (mnemonic);
252b5132
RH
3615 else
3616 {
3617 /* Since a variable sized modrm/sib chunk is between the start
3618 of the opcode (0x0f0f) and the opcode suffix, we need to do
3619 all the modrm processing first, and don't know until now that
3620 we have a bad opcode. This necessitates some cleaning up. */
2da11e11
AM
3621 op1out[0] = '\0';
3622 op2out[0] = '\0';
3623 BadOp();
252b5132
RH
3624 }
3625}
c608c12e
AM
3626
3627
3628static const char *simd_cmp_op [] = {
3629 "eq",
3630 "lt",
3631 "le",
3632 "unord",
3633 "neq",
3634 "nlt",
3635 "nle",
3636 "ord"
3637};
3638
3639static void
3640OP_SIMD_Suffix (bytemode, sizeflag)
3641 int bytemode;
3642 int sizeflag;
3643{
3644 unsigned int cmp_type;
3645
3646 FETCH_DATA (the_info, codep + 1);
2da11e11 3647 obufp = obuf + strlen(obuf);
c608c12e
AM
3648 cmp_type = *codep++ & 0xff;
3649 if (cmp_type < 8)
3650 {
3651 sprintf (scratchbuf, "cmp%s%cs",
3652 simd_cmp_op[cmp_type],
3653 prefixes & PREFIX_REPZ ? 's' : 'p');
7d421014 3654 used_prefixes |= (prefixes & PREFIX_REPZ);
2da11e11 3655 oappend (scratchbuf);
c608c12e
AM
3656 }
3657 else
3658 {
3659 /* We have a bad extension byte. Clean up. */
2da11e11
AM
3660 op1out[0] = '\0';
3661 op2out[0] = '\0';
3662 BadOp();
c608c12e
AM
3663 }
3664}
3665
3666static void
3667SIMD_Fixup (extrachar, sizeflag)
3668 int extrachar;
3669 int sizeflag;
3670{
3671 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
3672 forms of these instructions. */
3673 if (mod == 3)
3674 {
3675 char *p = obuf + strlen(obuf);
3676 *(p+1) = '\0';
3677 *p = *(p-1);
3678 *(p-1) = *(p-2);
3679 *(p-2) = *(p-3);
3680 *(p-3) = extrachar;
3681 }
3682}
2da11e11
AM
3683
3684static void BadOp (void)
3685{
3686 codep = insn_codep + 1; /* throw away prefixes and 1st. opcode byte */
3687 oappend ("(bad)");
3688}
This page took 0.173094 seconds and 4 git commands to generate.