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