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