ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/disass/i386-dis.c
Revision: 1.1
Committed: 2000-09-25T12:44:37Z (23 years, 10 months ago) by cebix
Content type: text/plain
Branch: MAIN
Log Message:
- replaced 680x0 and 80x86 disassemblers with the ones from GNU binutils
- 680x0 disassembler shows symbolic MacOS low memory globals

File Contents

# User Rev Content
1 cebix 1.1 /* Print i386 instructions for GDB, the GNU debugger.
2     Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 1998
3     Free Software Foundation, Inc.
4    
5     This file is part of GDB.
6    
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11    
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20    
21     /*
22     * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
23     * July 1988
24     * modified by John Hassey (hassey@dg-rtp.dg.com)
25     */
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    
38     #define MAXLEN 20
39    
40     #include <setjmp.h>
41    
42     static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
43    
44     struct dis_private
45     {
46     /* Points to first byte not fetched. */
47     bfd_byte *max_fetched;
48     bfd_byte the_buffer[MAXLEN];
49     bfd_vma insn_start;
50     jmp_buf bailout;
51     };
52    
53     /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
54     to ADDR (exclusive) are valid. Returns 1 for success, longjmps
55     on error. */
56     #define FETCH_DATA(info, addr) \
57     ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
58     ? 1 : fetch_data ((info), (addr)))
59    
60     static int
61     fetch_data (info, addr)
62     struct disassemble_info *info;
63     bfd_byte *addr;
64     {
65     int status;
66     struct dis_private *priv = (struct dis_private *)info->private_data;
67     bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
68    
69     status = (*info->read_memory_func) (start,
70     priv->max_fetched,
71     addr - priv->max_fetched,
72     info);
73     if (status != 0)
74     {
75     (*info->memory_error_func) (status, start, info);
76     longjmp (priv->bailout, 1);
77     }
78     else
79     priv->max_fetched = addr;
80     return 1;
81     }
82    
83     #define Eb OP_E, b_mode
84     #define indirEb OP_indirE, b_mode
85     #define Gb OP_G, b_mode
86     #define Ev OP_E, v_mode
87     #define indirEv OP_indirE, v_mode
88     #define Ew OP_E, w_mode
89     #define Ma OP_E, v_mode
90     #define M OP_E, 0
91     #define Mp OP_E, 0 /* ? */
92     #define Gv OP_G, v_mode
93     #define Gw OP_G, w_mode
94     #define Rw OP_rm, w_mode
95     #define Rd OP_rm, d_mode
96     #define Ib OP_I, b_mode
97     #define sIb OP_sI, b_mode /* sign extened byte */
98     #define Iv OP_I, v_mode
99     #define Iw OP_I, w_mode
100     #define Jb OP_J, b_mode
101     #define Jv OP_J, v_mode
102     #if 0
103     #define ONE OP_ONE, 0
104     #endif
105     #define Cd OP_C, d_mode
106     #define Dd OP_D, d_mode
107     #define Td OP_T, d_mode
108    
109     #define eAX OP_REG, eAX_reg
110     #define eBX OP_REG, eBX_reg
111     #define eCX OP_REG, eCX_reg
112     #define eDX OP_REG, eDX_reg
113     #define eSP OP_REG, eSP_reg
114     #define eBP OP_REG, eBP_reg
115     #define eSI OP_REG, eSI_reg
116     #define eDI OP_REG, eDI_reg
117     #define AL OP_REG, al_reg
118     #define CL OP_REG, cl_reg
119     #define DL OP_REG, dl_reg
120     #define BL OP_REG, bl_reg
121     #define AH OP_REG, ah_reg
122     #define CH OP_REG, ch_reg
123     #define DH OP_REG, dh_reg
124     #define BH OP_REG, bh_reg
125     #define AX OP_REG, ax_reg
126     #define DX OP_REG, dx_reg
127     #define indirDX OP_REG, indir_dx_reg
128    
129     #define Sw OP_SEG, w_mode
130     #define Ap OP_DIR, lptr
131     #define Av OP_DIR, v_mode
132     #define Ob OP_OFF, b_mode
133     #define Ov OP_OFF, v_mode
134     #define Xb OP_DSSI, b_mode
135     #define Xv OP_DSSI, v_mode
136     #define Yb OP_ESDI, b_mode
137     #define Yv OP_ESDI, v_mode
138    
139     #define es OP_REG, es_reg
140     #define ss OP_REG, ss_reg
141     #define cs OP_REG, cs_reg
142     #define ds OP_REG, ds_reg
143     #define fs OP_REG, fs_reg
144     #define gs OP_REG, gs_reg
145    
146     #define MX OP_MMX, 0
147     #define EM OP_EM, v_mode
148     #define MS OP_MS, b_mode
149    
150     typedef int (*op_rtn) PARAMS ((int bytemode, int aflag, int dflag));
151    
152     static int OP_E PARAMS ((int, int, int));
153     static int OP_G PARAMS ((int, int, int));
154     static int OP_I PARAMS ((int, int, int));
155     static int OP_indirE PARAMS ((int, int, int));
156     static int OP_sI PARAMS ((int, int, int));
157     static int OP_REG PARAMS ((int, int, int));
158     static int OP_J PARAMS ((int, int, int));
159     static int OP_DIR PARAMS ((int, int, int));
160     static int OP_OFF PARAMS ((int, int, int));
161     static int OP_ESDI PARAMS ((int, int, int));
162     static int OP_DSSI PARAMS ((int, int, int));
163     static int OP_SEG PARAMS ((int, int, int));
164     static int OP_C PARAMS ((int, int, int));
165     static int OP_D PARAMS ((int, int, int));
166     static int OP_T PARAMS ((int, int, int));
167     static int OP_rm PARAMS ((int, int, int));
168     static int OP_ST PARAMS ((int, int, int));
169     static int OP_STi PARAMS ((int, int, int));
170     #if 0
171     static int OP_ONE PARAMS ((int, int, int));
172     #endif
173     static int OP_MMX PARAMS ((int, int, int));
174     static int OP_EM PARAMS ((int, int, int));
175     static int OP_MS PARAMS ((int, int, int));
176    
177     static void append_prefix PARAMS ((void));
178     static void set_op PARAMS ((int op));
179     static void putop PARAMS ((char *template, int aflag, int dflag));
180     static void dofloat PARAMS ((int aflag, int dflag));
181     static int get16 PARAMS ((void));
182     static int get32 PARAMS ((void));
183     static void ckprefix PARAMS ((void));
184    
185     #define b_mode 1
186     #define v_mode 2
187     #define w_mode 3
188     #define d_mode 4
189    
190     #define es_reg 100
191     #define cs_reg 101
192     #define ss_reg 102
193     #define ds_reg 103
194     #define fs_reg 104
195     #define gs_reg 105
196     #define eAX_reg 107
197     #define eCX_reg 108
198     #define eDX_reg 109
199     #define eBX_reg 110
200     #define eSP_reg 111
201     #define eBP_reg 112
202     #define eSI_reg 113
203     #define eDI_reg 114
204    
205     #define lptr 115
206    
207     #define al_reg 116
208     #define cl_reg 117
209     #define dl_reg 118
210     #define bl_reg 119
211     #define ah_reg 120
212     #define ch_reg 121
213     #define dh_reg 122
214     #define bh_reg 123
215    
216     #define ax_reg 124
217     #define cx_reg 125
218     #define dx_reg 126
219     #define bx_reg 127
220     #define sp_reg 128
221     #define bp_reg 129
222     #define si_reg 130
223     #define di_reg 131
224    
225     #define indir_dx_reg 150
226    
227     #define GRP1b NULL, NULL, 0
228     #define GRP1S NULL, NULL, 1
229     #define GRP1Ss NULL, NULL, 2
230     #define GRP2b NULL, NULL, 3
231     #define GRP2S NULL, NULL, 4
232     #define GRP2b_one NULL, NULL, 5
233     #define GRP2S_one NULL, NULL, 6
234     #define GRP2b_cl NULL, NULL, 7
235     #define GRP2S_cl NULL, NULL, 8
236     #define GRP3b NULL, NULL, 9
237     #define GRP3S NULL, NULL, 10
238     #define GRP4 NULL, NULL, 11
239     #define GRP5 NULL, NULL, 12
240     #define GRP6 NULL, NULL, 13
241     #define GRP7 NULL, NULL, 14
242     #define GRP8 NULL, NULL, 15
243     #define GRP9 NULL, NULL, 16
244     #define GRP10 NULL, NULL, 17
245     #define GRP11 NULL, NULL, 18
246     #define GRP12 NULL, NULL, 19
247    
248     #define FLOATCODE 50
249     #define FLOAT NULL, NULL, FLOATCODE
250    
251     struct dis386 {
252     char *name;
253     op_rtn op1;
254     int bytemode1;
255     op_rtn op2;
256     int bytemode2;
257     op_rtn op3;
258     int bytemode3;
259     };
260    
261     static struct dis386 dis386[] = {
262     /* 00 */
263     { "addb", Eb, Gb },
264     { "addS", Ev, Gv },
265     { "addb", Gb, Eb },
266     { "addS", Gv, Ev },
267     { "addb", AL, Ib },
268     { "addS", eAX, Iv },
269     { "pushS", es },
270     { "popS", es },
271     /* 08 */
272     { "orb", Eb, Gb },
273     { "orS", Ev, Gv },
274     { "orb", Gb, Eb },
275     { "orS", Gv, Ev },
276     { "orb", AL, Ib },
277     { "orS", eAX, Iv },
278     { "pushS", cs },
279     { "(bad)" }, /* 0x0f extended opcode escape */
280     /* 10 */
281     { "adcb", Eb, Gb },
282     { "adcS", Ev, Gv },
283     { "adcb", Gb, Eb },
284     { "adcS", Gv, Ev },
285     { "adcb", AL, Ib },
286     { "adcS", eAX, Iv },
287     { "pushS", ss },
288     { "popS", ss },
289     /* 18 */
290     { "sbbb", Eb, Gb },
291     { "sbbS", Ev, Gv },
292     { "sbbb", Gb, Eb },
293     { "sbbS", Gv, Ev },
294     { "sbbb", AL, Ib },
295     { "sbbS", eAX, Iv },
296     { "pushS", ds },
297     { "popS", ds },
298     /* 20 */
299     { "andb", Eb, Gb },
300     { "andS", Ev, Gv },
301     { "andb", Gb, Eb },
302     { "andS", Gv, Ev },
303     { "andb", AL, Ib },
304     { "andS", eAX, Iv },
305     { "(bad)" }, /* SEG ES prefix */
306     { "daa" },
307     /* 28 */
308     { "subb", Eb, Gb },
309     { "subS", Ev, Gv },
310     { "subb", Gb, Eb },
311     { "subS", Gv, Ev },
312     { "subb", AL, Ib },
313     { "subS", eAX, Iv },
314     { "(bad)" }, /* SEG CS prefix */
315     { "das" },
316     /* 30 */
317     { "xorb", Eb, Gb },
318     { "xorS", Ev, Gv },
319     { "xorb", Gb, Eb },
320     { "xorS", Gv, Ev },
321     { "xorb", AL, Ib },
322     { "xorS", eAX, Iv },
323     { "(bad)" }, /* SEG SS prefix */
324     { "aaa" },
325     /* 38 */
326     { "cmpb", Eb, Gb },
327     { "cmpS", Ev, Gv },
328     { "cmpb", Gb, Eb },
329     { "cmpS", Gv, Ev },
330     { "cmpb", AL, Ib },
331     { "cmpS", eAX, Iv },
332     { "(bad)" }, /* SEG DS prefix */
333     { "aas" },
334     /* 40 */
335     { "incS", eAX },
336     { "incS", eCX },
337     { "incS", eDX },
338     { "incS", eBX },
339     { "incS", eSP },
340     { "incS", eBP },
341     { "incS", eSI },
342     { "incS", eDI },
343     /* 48 */
344     { "decS", eAX },
345     { "decS", eCX },
346     { "decS", eDX },
347     { "decS", eBX },
348     { "decS", eSP },
349     { "decS", eBP },
350     { "decS", eSI },
351     { "decS", eDI },
352     /* 50 */
353     { "pushS", eAX },
354     { "pushS", eCX },
355     { "pushS", eDX },
356     { "pushS", eBX },
357     { "pushS", eSP },
358     { "pushS", eBP },
359     { "pushS", eSI },
360     { "pushS", eDI },
361     /* 58 */
362     { "popS", eAX },
363     { "popS", eCX },
364     { "popS", eDX },
365     { "popS", eBX },
366     { "popS", eSP },
367     { "popS", eBP },
368     { "popS", eSI },
369     { "popS", eDI },
370     /* 60 */
371     { "pusha" },
372     { "popa" },
373     { "boundS", Gv, Ma },
374     { "arpl", Ew, Gw },
375     { "(bad)" }, /* seg fs */
376     { "(bad)" }, /* seg gs */
377     { "(bad)" }, /* op size prefix */
378     { "(bad)" }, /* adr size prefix */
379     /* 68 */
380     { "pushS", Iv }, /* 386 book wrong */
381     { "imulS", Gv, Ev, Iv },
382     { "pushS", sIb }, /* push of byte really pushes 2 or 4 bytes */
383     { "imulS", Gv, Ev, Ib },
384     { "insb", Yb, indirDX },
385     { "insS", Yv, indirDX },
386     { "outsb", indirDX, Xb },
387     { "outsS", indirDX, Xv },
388     /* 70 */
389     { "jo", Jb },
390     { "jno", Jb },
391     { "jb", Jb },
392     { "jae", Jb },
393     { "je", Jb },
394     { "jne", Jb },
395     { "jbe", Jb },
396     { "ja", Jb },
397     /* 78 */
398     { "js", Jb },
399     { "jns", Jb },
400     { "jp", Jb },
401     { "jnp", Jb },
402     { "jl", Jb },
403     { "jnl", Jb },
404     { "jle", Jb },
405     { "jg", Jb },
406     /* 80 */
407     { GRP1b },
408     { GRP1S },
409     { "(bad)" },
410     { GRP1Ss },
411     { "testb", Eb, Gb },
412     { "testS", Ev, Gv },
413     { "xchgb", Eb, Gb },
414     { "xchgS", Ev, Gv },
415     /* 88 */
416     { "movb", Eb, Gb },
417     { "movS", Ev, Gv },
418     { "movb", Gb, Eb },
419     { "movS", Gv, Ev },
420     { "movS", Ev, Sw },
421     { "leaS", Gv, M },
422     { "movS", Sw, Ev },
423     { "popS", Ev },
424     /* 90 */
425     { "nop" },
426     { "xchgS", eCX, eAX },
427     { "xchgS", eDX, eAX },
428     { "xchgS", eBX, eAX },
429     { "xchgS", eSP, eAX },
430     { "xchgS", eBP, eAX },
431     { "xchgS", eSI, eAX },
432     { "xchgS", eDI, eAX },
433     /* 98 */
434     { "cWtS" },
435     { "cStd" },
436     { "lcall", Ap },
437     { "(bad)" }, /* fwait */
438     { "pushf" },
439     { "popf" },
440     { "sahf" },
441     { "lahf" },
442     /* a0 */
443     { "movb", AL, Ob },
444     { "movS", eAX, Ov },
445     { "movb", Ob, AL },
446     { "movS", Ov, eAX },
447     { "movsb", Yb, Xb },
448     { "movsS", Yv, Xv },
449     { "cmpsb", Yb, Xb },
450     { "cmpsS", Yv, Xv },
451     /* a8 */
452     { "testb", AL, Ib },
453     { "testS", eAX, Iv },
454     { "stosb", Yb, AL },
455     { "stosS", Yv, eAX },
456     { "lodsb", AL, Xb },
457     { "lodsS", eAX, Xv },
458     { "scasb", AL, Yb },
459     { "scasS", eAX, Yv },
460     /* b0 */
461     { "movb", AL, Ib },
462     { "movb", CL, Ib },
463     { "movb", DL, Ib },
464     { "movb", BL, Ib },
465     { "movb", AH, Ib },
466     { "movb", CH, Ib },
467     { "movb", DH, Ib },
468     { "movb", BH, Ib },
469     /* b8 */
470     { "movS", eAX, Iv },
471     { "movS", eCX, Iv },
472     { "movS", eDX, Iv },
473     { "movS", eBX, Iv },
474     { "movS", eSP, Iv },
475     { "movS", eBP, Iv },
476     { "movS", eSI, Iv },
477     { "movS", eDI, Iv },
478     /* c0 */
479     { GRP2b },
480     { GRP2S },
481     { "ret", Iw },
482     { "ret" },
483     { "lesS", Gv, Mp },
484     { "ldsS", Gv, Mp },
485     { "movb", Eb, Ib },
486     { "movS", Ev, Iv },
487     /* c8 */
488     { "enter", Iw, Ib },
489     { "leave" },
490     { "lret", Iw },
491     { "lret" },
492     { "int3" },
493     { "int", Ib },
494     { "into" },
495     { "iret" },
496     /* d0 */
497     { GRP2b_one },
498     { GRP2S_one },
499     { GRP2b_cl },
500     { GRP2S_cl },
501     { "aam", Ib },
502     { "aad", Ib },
503     { "(bad)" },
504     { "xlat" },
505     /* d8 */
506     { FLOAT },
507     { FLOAT },
508     { FLOAT },
509     { FLOAT },
510     { FLOAT },
511     { FLOAT },
512     { FLOAT },
513     { FLOAT },
514     /* e0 */
515     { "loopne", Jb },
516     { "loope", Jb },
517     { "loop", Jb },
518     { "jCcxz", Jb },
519     { "inb", AL, Ib },
520     { "inS", eAX, Ib },
521     { "outb", Ib, AL },
522     { "outS", Ib, eAX },
523     /* e8 */
524     { "call", Av },
525     { "jmp", Jv },
526     { "ljmp", Ap },
527     { "jmp", Jb },
528     { "inb", AL, indirDX },
529     { "inS", eAX, indirDX },
530     { "outb", indirDX, AL },
531     { "outS", indirDX, eAX },
532     /* f0 */
533     { "(bad)" }, /* lock prefix */
534     { "(bad)" },
535     { "(bad)" }, /* repne */
536     { "(bad)" }, /* repz */
537     { "hlt" },
538     { "cmc" },
539     { GRP3b },
540     { GRP3S },
541     /* f8 */
542     { "clc" },
543     { "stc" },
544     { "cli" },
545     { "sti" },
546     { "cld" },
547     { "std" },
548     { GRP4 },
549     { GRP5 },
550     };
551    
552     static struct dis386 dis386_twobyte[] = {
553     /* 00 */
554     { GRP6 },
555     { GRP7 },
556     { "larS", Gv, Ew },
557     { "lslS", Gv, Ew },
558     { "(bad)" },
559     { "(bad)" },
560     { "clts" },
561     { "(bad)" },
562     /* 08 */
563     { "invd" },
564     { "wbinvd" },
565     { "(bad)" }, { "ud2a" },
566     { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
567     /* 10 */
568     { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
569     { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
570     /* 18 */
571     { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
572     { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
573     /* 20 */
574     /* these are all backward in appendix A of the intel book */
575     { "movl", Rd, Cd },
576     { "movl", Rd, Dd },
577     { "movl", Cd, Rd },
578     { "movl", Dd, Rd },
579     { "movl", Rd, Td },
580     { "(bad)" },
581     { "movl", Td, Rd },
582     { "(bad)" },
583     /* 28 */
584     { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
585     { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
586     /* 30 */
587     { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
588     { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
589     /* 38 */
590     { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
591     { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
592     /* 40 */
593     { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
594     { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
595     /* 48 */
596     { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
597     { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
598     /* 50 */
599     { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
600     { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
601     /* 58 */
602     { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
603     { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
604     /* 60 */
605     { "punpcklbw", MX, EM },
606     { "punpcklwd", MX, EM },
607     { "punpckldq", MX, EM },
608     { "packsswb", MX, EM },
609     { "pcmpgtb", MX, EM },
610     { "pcmpgtw", MX, EM },
611     { "pcmpgtd", MX, EM },
612     { "packuswb", MX, EM },
613     /* 68 */
614     { "punpckhbw", MX, EM },
615     { "punpckhwd", MX, EM },
616     { "punpckhdq", MX, EM },
617     { "packssdw", MX, EM },
618     { "(bad)" }, { "(bad)" },
619     { "movd", MX, Ev },
620     { "movq", MX, EM },
621     /* 70 */
622     { "(bad)" },
623     { GRP10 },
624     { GRP11 },
625     { GRP12 },
626     { "pcmpeqb", MX, EM },
627     { "pcmpeqw", MX, EM },
628     { "pcmpeqd", MX, EM },
629     { "emms" },
630     /* 78 */
631     { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
632     { "(bad)" }, { "(bad)" },
633     { "movd", Ev, MX },
634     { "movq", EM, MX },
635     /* 80 */
636     { "jo", Jv },
637     { "jno", Jv },
638     { "jb", Jv },
639     { "jae", Jv },
640     { "je", Jv },
641     { "jne", Jv },
642     { "jbe", Jv },
643     { "ja", Jv },
644     /* 88 */
645     { "js", Jv },
646     { "jns", Jv },
647     { "jp", Jv },
648     { "jnp", Jv },
649     { "jl", Jv },
650     { "jge", Jv },
651     { "jle", Jv },
652     { "jg", Jv },
653     /* 90 */
654     { "seto", Eb },
655     { "setno", Eb },
656     { "setb", Eb },
657     { "setae", Eb },
658     { "sete", Eb },
659     { "setne", Eb },
660     { "setbe", Eb },
661     { "seta", Eb },
662     /* 98 */
663     { "sets", Eb },
664     { "setns", Eb },
665     { "setp", Eb },
666     { "setnp", Eb },
667     { "setl", Eb },
668     { "setge", Eb },
669     { "setle", Eb },
670     { "setg", Eb },
671     /* a0 */
672     { "pushS", fs },
673     { "popS", fs },
674     { "cpuid" },
675     { "btS", Ev, Gv },
676     { "shldS", Ev, Gv, Ib },
677     { "shldS", Ev, Gv, CL },
678     { "(bad)" },
679     { "(bad)" },
680     /* a8 */
681     { "pushS", gs },
682     { "popS", gs },
683     { "rsm" },
684     { "btsS", Ev, Gv },
685     { "shrdS", Ev, Gv, Ib },
686     { "shrdS", Ev, Gv, CL },
687     { "(bad)" },
688     { "imulS", Gv, Ev },
689     /* b0 */
690     { "cmpxchgb", Eb, Gb },
691     { "cmpxchgS", Ev, Gv },
692     { "lssS", Gv, Mp }, /* 386 lists only Mp */
693     { "btrS", Ev, Gv },
694     { "lfsS", Gv, Mp }, /* 386 lists only Mp */
695     { "lgsS", Gv, Mp }, /* 386 lists only Mp */
696     { "movzbS", Gv, Eb },
697     { "movzwS", Gv, Ew },
698     /* b8 */
699     { "ud2b" },
700     { "(bad)" },
701     { GRP8 },
702     { "btcS", Ev, Gv },
703     { "bsfS", Gv, Ev },
704     { "bsrS", Gv, Ev },
705     { "movsbS", Gv, Eb },
706     { "movswS", Gv, Ew },
707     /* c0 */
708     { "xaddb", Eb, Gb },
709     { "xaddS", Ev, Gv },
710     { "(bad)" },
711     { "(bad)" },
712     { "(bad)" },
713     { "(bad)" },
714     { "(bad)" },
715     { GRP9 },
716     /* c8 */
717     { "bswap", eAX },
718     { "bswap", eCX },
719     { "bswap", eDX },
720     { "bswap", eBX },
721     { "bswap", eSP },
722     { "bswap", eBP },
723     { "bswap", eSI },
724     { "bswap", eDI },
725     /* d0 */
726     { "(bad)" },
727     { "psrlw", MX, EM },
728     { "psrld", MX, EM },
729     { "psrlq", MX, EM },
730     { "(bad)" },
731     { "pmullw", MX, EM },
732     { "(bad)" }, { "(bad)" },
733     /* d8 */
734     { "psubusb", MX, EM },
735     { "psubusw", MX, EM },
736     { "(bad)" },
737     { "pand", MX, EM },
738     { "paddusb", MX, EM },
739     { "paddusw", MX, EM },
740     { "(bad)" },
741     { "pandn", MX, EM },
742     /* e0 */
743     { "(bad)" },
744     { "psraw", MX, EM },
745     { "psrad", MX, EM },
746     { "(bad)" },
747     { "(bad)" },
748     { "pmulhw", MX, EM },
749     { "(bad)" }, { "(bad)" },
750     /* e8 */
751     { "psubsb", MX, EM },
752     { "psubsw", MX, EM },
753     { "(bad)" },
754     { "por", MX, EM },
755     { "paddsb", MX, EM },
756     { "paddsw", MX, EM },
757     { "(bad)" },
758     { "pxor", MX, EM },
759     /* f0 */
760     { "(bad)" },
761     { "psllw", MX, EM },
762     { "pslld", MX, EM },
763     { "psllq", MX, EM },
764     { "(bad)" },
765     { "pmaddwd", MX, EM },
766     { "(bad)" }, { "(bad)" },
767     /* f8 */
768     { "psubb", MX, EM },
769     { "psubw", MX, EM },
770     { "psubd", MX, EM },
771     { "(bad)" },
772     { "paddb", MX, EM },
773     { "paddw", MX, EM },
774     { "paddd", MX, EM },
775     { "(bad)" }
776     };
777    
778     static const unsigned char onebyte_has_modrm[256] = {
779     1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
780     1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
781     1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
782     1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
783     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
784     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
785     0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
786     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
787     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
788     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
789     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
790     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
791     1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
792     1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
793     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
794     0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
795     };
796    
797     static const unsigned char twobyte_has_modrm[256] = {
798     /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
799     /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
800     /* 20 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 2f */
801     /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
802     /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
803     /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
804     /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
805     /* 70 */ 0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
806     /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
807     /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
808     /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
809     /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
810     /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
811     /* d0 */ 0,1,1,1,0,1,0,0,1,1,0,1,1,1,0,1, /* df */
812     /* e0 */ 0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,1, /* ef */
813     /* f0 */ 0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0 /* ff */
814     };
815    
816     static char obuf[100];
817     static char *obufp;
818     static char scratchbuf[100];
819     static unsigned char *start_codep;
820     static unsigned char *codep;
821     static disassemble_info *the_info;
822     static int mod;
823     static int rm;
824     static int reg;
825     static void oappend PARAMS ((char *s));
826    
827     static char *names32[]={
828     "eax","ecx","edx","ebx", "esp","ebp","esi","edi",
829     };
830     static char *names16[] = {
831     "ax","cx","dx","bx","sp","bp","si","di",
832     };
833     static char *names8[] = {
834     "al","cl","dl","bl","ah","ch","dh","bh",
835     };
836     static char *names_seg[] = {
837     "es","cs","ss","ds","fs","gs","?","?",
838     };
839     static char *index16[] = {
840     "bx+si","bx+di","bp+si","bp+di","si","di","bp","bx"
841     };
842    
843     static struct dis386 grps[][8] = {
844     /* GRP1b */
845     {
846     { "addb", Eb, Ib },
847     { "orb", Eb, Ib },
848     { "adcb", Eb, Ib },
849     { "sbbb", Eb, Ib },
850     { "andb", Eb, Ib },
851     { "subb", Eb, Ib },
852     { "xorb", Eb, Ib },
853     { "cmpb", Eb, Ib }
854     },
855     /* GRP1S */
856     {
857     { "addS", Ev, Iv },
858     { "orS", Ev, Iv },
859     { "adcS", Ev, Iv },
860     { "sbbS", Ev, Iv },
861     { "andS", Ev, Iv },
862     { "subS", Ev, Iv },
863     { "xorS", Ev, Iv },
864     { "cmpS", Ev, Iv }
865     },
866     /* GRP1Ss */
867     {
868     { "addS", Ev, sIb },
869     { "orS", Ev, sIb },
870     { "adcS", Ev, sIb },
871     { "sbbS", Ev, sIb },
872     { "andS", Ev, sIb },
873     { "subS", Ev, sIb },
874     { "xorS", Ev, sIb },
875     { "cmpS", Ev, sIb }
876     },
877     /* GRP2b */
878     {
879     { "rolb", Eb, Ib },
880     { "rorb", Eb, Ib },
881     { "rclb", Eb, Ib },
882     { "rcrb", Eb, Ib },
883     { "shlb", Eb, Ib },
884     { "shrb", Eb, Ib },
885     { "(bad)" },
886     { "sarb", Eb, Ib },
887     },
888     /* GRP2S */
889     {
890     { "rolS", Ev, Ib },
891     { "rorS", Ev, Ib },
892     { "rclS", Ev, Ib },
893     { "rcrS", Ev, Ib },
894     { "shlS", Ev, Ib },
895     { "shrS", Ev, Ib },
896     { "(bad)" },
897     { "sarS", Ev, Ib },
898     },
899     /* GRP2b_one */
900     {
901     { "rolb", Eb },
902     { "rorb", Eb },
903     { "rclb", Eb },
904     { "rcrb", Eb },
905     { "shlb", Eb },
906     { "shrb", Eb },
907     { "(bad)" },
908     { "sarb", Eb },
909     },
910     /* GRP2S_one */
911     {
912     { "rolS", Ev },
913     { "rorS", Ev },
914     { "rclS", Ev },
915     { "rcrS", Ev },
916     { "shlS", Ev },
917     { "shrS", Ev },
918     { "(bad)" },
919     { "sarS", Ev },
920     },
921     /* GRP2b_cl */
922     {
923     { "rolb", Eb, CL },
924     { "rorb", Eb, CL },
925     { "rclb", Eb, CL },
926     { "rcrb", Eb, CL },
927     { "shlb", Eb, CL },
928     { "shrb", Eb, CL },
929     { "(bad)" },
930     { "sarb", Eb, CL },
931     },
932     /* GRP2S_cl */
933     {
934     { "rolS", Ev, CL },
935     { "rorS", Ev, CL },
936     { "rclS", Ev, CL },
937     { "rcrS", Ev, CL },
938     { "shlS", Ev, CL },
939     { "shrS", Ev, CL },
940     { "(bad)" },
941     { "sarS", Ev, CL }
942     },
943     /* GRP3b */
944     {
945     { "testb", Eb, Ib },
946     { "(bad)", Eb },
947     { "notb", Eb },
948     { "negb", Eb },
949     { "mulb", AL, Eb },
950     { "imulb", AL, Eb },
951     { "divb", AL, Eb },
952     { "idivb", AL, Eb }
953     },
954     /* GRP3S */
955     {
956     { "testS", Ev, Iv },
957     { "(bad)" },
958     { "notS", Ev },
959     { "negS", Ev },
960     { "mulS", eAX, Ev },
961     { "imulS", eAX, Ev },
962     { "divS", eAX, Ev },
963     { "idivS", eAX, Ev },
964     },
965     /* GRP4 */
966     {
967     { "incb", Eb },
968     { "decb", Eb },
969     { "(bad)" },
970     { "(bad)" },
971     { "(bad)" },
972     { "(bad)" },
973     { "(bad)" },
974     { "(bad)" },
975     },
976     /* GRP5 */
977     {
978     { "incS", Ev },
979     { "decS", Ev },
980     { "call", indirEv },
981     { "lcall", indirEv },
982     { "jmp", indirEv },
983     { "ljmp", indirEv },
984     { "pushS", Ev },
985     { "(bad)" },
986     },
987     /* GRP6 */
988     {
989     { "sldt", Ew },
990     { "str", Ew },
991     { "lldt", Ew },
992     { "ltr", Ew },
993     { "verr", Ew },
994     { "verw", Ew },
995     { "(bad)" },
996     { "(bad)" }
997     },
998     /* GRP7 */
999     {
1000     { "sgdt", Ew },
1001     { "sidt", Ew },
1002     { "lgdt", Ew },
1003     { "lidt", Ew },
1004     { "smsw", Ew },
1005     { "(bad)" },
1006     { "lmsw", Ew },
1007     { "invlpg", Ew },
1008     },
1009     /* GRP8 */
1010     {
1011     { "(bad)" },
1012     { "(bad)" },
1013     { "(bad)" },
1014     { "(bad)" },
1015     { "btS", Ev, Ib },
1016     { "btsS", Ev, Ib },
1017     { "btrS", Ev, Ib },
1018     { "btcS", Ev, Ib },
1019     },
1020     /* GRP9 */
1021     {
1022     { "(bad)" },
1023     { "cmpxchg8b", Ev },
1024     { "(bad)" },
1025     { "(bad)" },
1026     { "(bad)" },
1027     { "(bad)" },
1028     { "(bad)" },
1029     { "(bad)" },
1030     },
1031     /* GRP10 */
1032     {
1033     { "(bad)" },
1034     { "(bad)" },
1035     { "psrlw", MS, Ib },
1036     { "(bad)" },
1037     { "psraw", MS, Ib },
1038     { "(bad)" },
1039     { "psllw", MS, Ib },
1040     { "(bad)" },
1041     },
1042     /* GRP11 */
1043     {
1044     { "(bad)" },
1045     { "(bad)" },
1046     { "psrld", MS, Ib },
1047     { "(bad)" },
1048     { "psrad", MS, Ib },
1049     { "(bad)" },
1050     { "pslld", MS, Ib },
1051     { "(bad)" },
1052     },
1053     /* GRP12 */
1054     {
1055     { "(bad)" },
1056     { "(bad)" },
1057     { "psrlq", MS, Ib },
1058     { "(bad)" },
1059     { "(bad)" },
1060     { "(bad)" },
1061     { "psllq", MS, Ib },
1062     { "(bad)" },
1063     }
1064     };
1065    
1066     #define PREFIX_REPZ 1
1067     #define PREFIX_REPNZ 2
1068     #define PREFIX_LOCK 4
1069     #define PREFIX_CS 8
1070     #define PREFIX_SS 0x10
1071     #define PREFIX_DS 0x20
1072     #define PREFIX_ES 0x40
1073     #define PREFIX_FS 0x80
1074     #define PREFIX_GS 0x100
1075     #define PREFIX_DATA 0x200
1076     #define PREFIX_ADR 0x400
1077     #define PREFIX_FWAIT 0x800
1078    
1079     static int prefixes;
1080    
1081     static void
1082     ckprefix ()
1083     {
1084     prefixes = 0;
1085     while (1)
1086     {
1087     FETCH_DATA (the_info, codep + 1);
1088     switch (*codep)
1089     {
1090     case 0xf3:
1091     prefixes |= PREFIX_REPZ;
1092     break;
1093     case 0xf2:
1094     prefixes |= PREFIX_REPNZ;
1095     break;
1096     case 0xf0:
1097     prefixes |= PREFIX_LOCK;
1098     break;
1099     case 0x2e:
1100     prefixes |= PREFIX_CS;
1101     break;
1102     case 0x36:
1103     prefixes |= PREFIX_SS;
1104     break;
1105     case 0x3e:
1106     prefixes |= PREFIX_DS;
1107     break;
1108     case 0x26:
1109     prefixes |= PREFIX_ES;
1110     break;
1111     case 0x64:
1112     prefixes |= PREFIX_FS;
1113     break;
1114     case 0x65:
1115     prefixes |= PREFIX_GS;
1116     break;
1117     case 0x66:
1118     prefixes |= PREFIX_DATA;
1119     break;
1120     case 0x67:
1121     prefixes |= PREFIX_ADR;
1122     break;
1123     case 0x9b:
1124     prefixes |= PREFIX_FWAIT;
1125     break;
1126     default:
1127     return;
1128     }
1129     codep++;
1130     }
1131     }
1132    
1133     static char op1out[100], op2out[100], op3out[100];
1134     static int op_address[3], op_ad, op_index[3];
1135     static int start_pc;
1136    
1137    
1138     /*
1139     * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1140     * (see topic "Redundant prefixes" in the "Differences from 8086"
1141     * section of the "Virtual 8086 Mode" chapter.)
1142     * 'pc' should be the address of this instruction, it will
1143     * be used to print the target address if this is a relative jump or call
1144     * The function returns the length of this instruction in bytes.
1145     */
1146    
1147     int print_insn_x86 PARAMS ((bfd_vma pc, disassemble_info *info, int aflag,
1148     int dflag));
1149     int
1150     print_insn_i386 (pc, info)
1151     bfd_vma pc;
1152     disassemble_info *info;
1153     {
1154     if (info->mach == bfd_mach_i386_i386)
1155     return print_insn_x86 (pc, info, 1, 1);
1156     else if (info->mach == bfd_mach_i386_i8086)
1157     return print_insn_x86 (pc, info, 0, 0);
1158     else
1159     abort ();
1160     }
1161    
1162     int
1163     print_insn_x86 (pc, info, aflag, dflag)
1164     bfd_vma pc;
1165     disassemble_info *info;
1166     int aflag;
1167     int dflag;
1168     {
1169     struct dis386 *dp;
1170     int i;
1171     int enter_instruction;
1172     char *first, *second, *third;
1173     int needcomma;
1174     unsigned char need_modrm;
1175    
1176     struct dis_private priv;
1177     bfd_byte *inbuf = priv.the_buffer;
1178    
1179     /* The output looks better if we put 5 bytes on a line, since that
1180     puts long word instructions on a single line. */
1181     info->bytes_per_line = 5;
1182    
1183     info->private_data = (PTR) &priv;
1184     priv.max_fetched = priv.the_buffer;
1185     priv.insn_start = pc;
1186     if (setjmp (priv.bailout) != 0)
1187     /* Error return. */
1188     return -1;
1189    
1190     obuf[0] = 0;
1191     op1out[0] = 0;
1192     op2out[0] = 0;
1193     op3out[0] = 0;
1194    
1195     op_index[0] = op_index[1] = op_index[2] = -1;
1196    
1197     the_info = info;
1198     start_pc = pc;
1199     start_codep = inbuf;
1200     codep = inbuf;
1201    
1202     ckprefix ();
1203    
1204     FETCH_DATA (info, codep + 1);
1205     if (*codep == 0xc8)
1206     enter_instruction = 1;
1207     else
1208     enter_instruction = 0;
1209    
1210     obufp = obuf;
1211    
1212     if (prefixes & PREFIX_REPZ)
1213     oappend ("repz ");
1214     if (prefixes & PREFIX_REPNZ)
1215     oappend ("repnz ");
1216     if (prefixes & PREFIX_LOCK)
1217     oappend ("lock ");
1218    
1219     if ((prefixes & PREFIX_FWAIT)
1220     && ((*codep < 0xd8) || (*codep > 0xdf)))
1221     {
1222     /* fwait not followed by floating point instruction */
1223     (*info->fprintf_func) (info->stream, "fwait");
1224     return (1);
1225     }
1226    
1227     if (prefixes & PREFIX_DATA)
1228     dflag ^= 1;
1229    
1230     if (prefixes & PREFIX_ADR)
1231     {
1232     aflag ^= 1;
1233     if (aflag)
1234     oappend ("addr32 ");
1235     else
1236     oappend ("addr16 ");
1237     }
1238    
1239     if (*codep == 0x0f)
1240     {
1241     FETCH_DATA (info, codep + 2);
1242     dp = &dis386_twobyte[*++codep];
1243     need_modrm = twobyte_has_modrm[*codep];
1244     }
1245     else
1246     {
1247     dp = &dis386[*codep];
1248     need_modrm = onebyte_has_modrm[*codep];
1249     }
1250     codep++;
1251    
1252     if (need_modrm)
1253     {
1254     FETCH_DATA (info, codep + 1);
1255     mod = (*codep >> 6) & 3;
1256     reg = (*codep >> 3) & 7;
1257     rm = *codep & 7;
1258     }
1259    
1260     if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
1261     {
1262     dofloat (aflag, dflag);
1263     }
1264     else
1265     {
1266     if (dp->name == NULL)
1267     dp = &grps[dp->bytemode1][reg];
1268    
1269     putop (dp->name, aflag, dflag);
1270    
1271     obufp = op1out;
1272     op_ad = 2;
1273     if (dp->op1)
1274     (*dp->op1)(dp->bytemode1, aflag, dflag);
1275    
1276     obufp = op2out;
1277     op_ad = 1;
1278     if (dp->op2)
1279     (*dp->op2)(dp->bytemode2, aflag, dflag);
1280    
1281     obufp = op3out;
1282     op_ad = 0;
1283     if (dp->op3)
1284     (*dp->op3)(dp->bytemode3, aflag, dflag);
1285     }
1286    
1287     obufp = obuf + strlen (obuf);
1288     for (i = strlen (obuf); i < 6; i++)
1289     oappend (" ");
1290     oappend (" ");
1291     (*info->fprintf_func) (info->stream, "%s", obuf);
1292    
1293     /* enter instruction is printed with operands in the
1294     * same order as the intel book; everything else
1295     * is printed in reverse order
1296     */
1297     if (enter_instruction)
1298     {
1299     first = op1out;
1300     second = op2out;
1301     third = op3out;
1302     op_ad = op_index[0];
1303     op_index[0] = op_index[2];
1304     op_index[2] = op_ad;
1305     }
1306     else
1307     {
1308     first = op3out;
1309     second = op2out;
1310     third = op1out;
1311     }
1312     needcomma = 0;
1313     if (*first)
1314     {
1315     if (op_index[0] != -1)
1316     (*info->print_address_func) (op_address[op_index[0]], info);
1317     else
1318     (*info->fprintf_func) (info->stream, "%s", first);
1319     needcomma = 1;
1320     }
1321     if (*second)
1322     {
1323     if (needcomma)
1324     (*info->fprintf_func) (info->stream, ",");
1325     if (op_index[1] != -1)
1326     (*info->print_address_func) (op_address[op_index[1]], info);
1327     else
1328     (*info->fprintf_func) (info->stream, "%s", second);
1329     needcomma = 1;
1330     }
1331     if (*third)
1332     {
1333     if (needcomma)
1334     (*info->fprintf_func) (info->stream, ",");
1335     if (op_index[2] != -1)
1336     (*info->print_address_func) (op_address[op_index[2]], info);
1337     else
1338     (*info->fprintf_func) (info->stream, "%s", third);
1339     }
1340     return (codep - inbuf);
1341     }
1342    
1343     static char *float_mem[] = {
1344     /* d8 */
1345     "fadds",
1346     "fmuls",
1347     "fcoms",
1348     "fcomps",
1349     "fsubs",
1350     "fsubrs",
1351     "fdivs",
1352     "fdivrs",
1353     /* d9 */
1354     "flds",
1355     "(bad)",
1356     "fsts",
1357     "fstps",
1358     "fldenv",
1359     "fldcw",
1360     "fNstenv",
1361     "fNstcw",
1362     /* da */
1363     "fiaddl",
1364     "fimull",
1365     "ficoml",
1366     "ficompl",
1367     "fisubl",
1368     "fisubrl",
1369     "fidivl",
1370     "fidivrl",
1371     /* db */
1372     "fildl",
1373     "(bad)",
1374     "fistl",
1375     "fistpl",
1376     "(bad)",
1377     "fldt",
1378     "(bad)",
1379     "fstpt",
1380     /* dc */
1381     "faddl",
1382     "fmull",
1383     "fcoml",
1384     "fcompl",
1385     "fsubl",
1386     "fsubrl",
1387     "fdivl",
1388     "fdivrl",
1389     /* dd */
1390     "fldl",
1391     "(bad)",
1392     "fstl",
1393     "fstpl",
1394     "frstor",
1395     "(bad)",
1396     "fNsave",
1397     "fNstsw",
1398     /* de */
1399     "fiadd",
1400     "fimul",
1401     "ficom",
1402     "ficomp",
1403     "fisub",
1404     "fisubr",
1405     "fidiv",
1406     "fidivr",
1407     /* df */
1408     "fild",
1409     "(bad)",
1410     "fist",
1411     "fistp",
1412     "fbld",
1413     "fildll",
1414     "fbstp",
1415     "fistpll",
1416     };
1417    
1418     #define ST OP_ST, 0
1419     #define STi OP_STi, 0
1420    
1421     #define FGRPd9_2 NULL, NULL, 0
1422     #define FGRPd9_4 NULL, NULL, 1
1423     #define FGRPd9_5 NULL, NULL, 2
1424     #define FGRPd9_6 NULL, NULL, 3
1425     #define FGRPd9_7 NULL, NULL, 4
1426     #define FGRPda_5 NULL, NULL, 5
1427     #define FGRPdb_4 NULL, NULL, 6
1428     #define FGRPde_3 NULL, NULL, 7
1429     #define FGRPdf_4 NULL, NULL, 8
1430    
1431     static struct dis386 float_reg[][8] = {
1432     /* d8 */
1433     {
1434     { "fadd", ST, STi },
1435     { "fmul", ST, STi },
1436     { "fcom", STi },
1437     { "fcomp", STi },
1438     { "fsub", ST, STi },
1439     { "fsubr", ST, STi },
1440     { "fdiv", ST, STi },
1441     { "fdivr", ST, STi },
1442     },
1443     /* d9 */
1444     {
1445     { "fld", STi },
1446     { "fxch", STi },
1447     { FGRPd9_2 },
1448     { "(bad)" },
1449     { FGRPd9_4 },
1450     { FGRPd9_5 },
1451     { FGRPd9_6 },
1452     { FGRPd9_7 },
1453     },
1454     /* da */
1455     {
1456     { "fcmovb", ST, STi },
1457     { "fcmove", ST, STi },
1458     { "fcmovbe",ST, STi },
1459     { "fcmovu", ST, STi },
1460     { "(bad)" },
1461     { FGRPda_5 },
1462     { "(bad)" },
1463     { "(bad)" },
1464     },
1465     /* db */
1466     {
1467     { "fcmovnb",ST, STi },
1468     { "fcmovne",ST, STi },
1469     { "fcmovnbe",ST, STi },
1470     { "fcmovnu",ST, STi },
1471     { FGRPdb_4 },
1472     { "fucomi", ST, STi },
1473     { "fcomi", ST, STi },
1474     { "(bad)" },
1475     },
1476     /* dc */
1477     {
1478     { "fadd", STi, ST },
1479     { "fmul", STi, ST },
1480     { "(bad)" },
1481     { "(bad)" },
1482     { "fsub", STi, ST },
1483     { "fsubr", STi, ST },
1484     { "fdiv", STi, ST },
1485     { "fdivr", STi, ST },
1486     },
1487     /* dd */
1488     {
1489     { "ffree", STi },
1490     { "(bad)" },
1491     { "fst", STi },
1492     { "fstp", STi },
1493     { "fucom", STi },
1494     { "fucomp", STi },
1495     { "(bad)" },
1496     { "(bad)" },
1497     },
1498     /* de */
1499     {
1500     { "faddp", STi, ST },
1501     { "fmulp", STi, ST },
1502     { "(bad)" },
1503     { FGRPde_3 },
1504     { "fsubp", STi, ST },
1505     { "fsubrp", STi, ST },
1506     { "fdivp", STi, ST },
1507     { "fdivrp", STi, ST },
1508     },
1509     /* df */
1510     {
1511     { "(bad)" },
1512     { "(bad)" },
1513     { "(bad)" },
1514     { "(bad)" },
1515     { FGRPdf_4 },
1516     { "fucomip",ST, STi },
1517     { "fcomip", ST, STi },
1518     { "(bad)" },
1519     },
1520     };
1521    
1522    
1523     static char *fgrps[][8] = {
1524     /* d9_2 0 */
1525     {
1526     "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1527     },
1528    
1529     /* d9_4 1 */
1530     {
1531     "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
1532     },
1533    
1534     /* d9_5 2 */
1535     {
1536     "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
1537     },
1538    
1539     /* d9_6 3 */
1540     {
1541     "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
1542     },
1543    
1544     /* d9_7 4 */
1545     {
1546     "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
1547     },
1548    
1549     /* da_5 5 */
1550     {
1551     "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1552     },
1553    
1554     /* db_4 6 */
1555     {
1556     "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
1557     "fNsetpm(287 only)","(bad)","(bad)","(bad)",
1558     },
1559    
1560     /* de_3 7 */
1561     {
1562     "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1563     },
1564    
1565     /* df_4 8 */
1566     {
1567     "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1568     },
1569     };
1570    
1571     static void
1572     dofloat (aflag, dflag)
1573     int aflag;
1574     int dflag;
1575     {
1576     struct dis386 *dp;
1577     unsigned char floatop;
1578    
1579     floatop = codep[-1];
1580    
1581     if (mod != 3)
1582     {
1583     putop (float_mem[(floatop - 0xd8) * 8 + reg], aflag, dflag);
1584     obufp = op1out;
1585     OP_E (v_mode, aflag, dflag);
1586     return;
1587     }
1588     codep++;
1589    
1590     dp = &float_reg[floatop - 0xd8][reg];
1591     if (dp->name == NULL)
1592     {
1593     putop (fgrps[dp->bytemode1][rm], aflag, dflag);
1594     /* instruction fnstsw is only one with strange arg */
1595     if (floatop == 0xdf
1596     && FETCH_DATA (the_info, codep + 1)
1597     && *codep == 0xe0)
1598     strcpy (op1out, "eax");
1599     }
1600     else
1601     {
1602     putop (dp->name, aflag, dflag);
1603     obufp = op1out;
1604     if (dp->op1)
1605     (*dp->op1)(dp->bytemode1, aflag, dflag);
1606     obufp = op2out;
1607     if (dp->op2)
1608     (*dp->op2)(dp->bytemode2, aflag, dflag);
1609     }
1610     }
1611    
1612     /* ARGSUSED */
1613     static int
1614     OP_ST (ignore, aflag, dflag)
1615     int ignore;
1616     int aflag;
1617     int dflag;
1618     {
1619     oappend ("st");
1620     return (0);
1621     }
1622    
1623     /* ARGSUSED */
1624     static int
1625     OP_STi (ignore, aflag, dflag)
1626     int ignore;
1627     int aflag;
1628     int dflag;
1629     {
1630     sprintf (scratchbuf, "st(%d)", rm);
1631     oappend (scratchbuf);
1632     return (0);
1633     }
1634    
1635    
1636     /* capital letters in template are macros */
1637     static void
1638     putop (template, aflag, dflag)
1639     char *template;
1640     int aflag;
1641     int dflag;
1642     {
1643     char *p;
1644    
1645     for (p = template; *p; p++)
1646     {
1647     switch (*p)
1648     {
1649     default:
1650     *obufp++ = *p;
1651     break;
1652     case 'C': /* For jcxz/jecxz */
1653     if (aflag)
1654     *obufp++ = 'e';
1655     break;
1656     case 'N':
1657     if ((prefixes & PREFIX_FWAIT) == 0)
1658     *obufp++ = 'n';
1659     break;
1660     case 'S':
1661     /* operand size flag */
1662     if (dflag)
1663     *obufp++ = 'l';
1664     else
1665     *obufp++ = 'w';
1666     break;
1667     case 'W':
1668     /* operand size flag for cwtl, cbtw */
1669     if (dflag)
1670     *obufp++ = 'w';
1671     else
1672     *obufp++ = 'b';
1673     break;
1674     }
1675     }
1676     *obufp = 0;
1677     }
1678    
1679     static void
1680     oappend (s)
1681     char *s;
1682     {
1683     strcpy (obufp, s);
1684     obufp += strlen (s);
1685     *obufp = 0;
1686     }
1687    
1688     static void
1689     append_prefix ()
1690     {
1691     if (prefixes & PREFIX_CS)
1692     oappend ("cs:");
1693     if (prefixes & PREFIX_DS)
1694     oappend ("ds:");
1695     if (prefixes & PREFIX_SS)
1696     oappend ("ss:");
1697     if (prefixes & PREFIX_ES)
1698     oappend ("es:");
1699     if (prefixes & PREFIX_FS)
1700     oappend ("fs:");
1701     if (prefixes & PREFIX_GS)
1702     oappend ("gs:");
1703     }
1704    
1705     static int
1706     OP_indirE (bytemode, aflag, dflag)
1707     int bytemode;
1708     int aflag;
1709     int dflag;
1710     {
1711     oappend ("*");
1712     return OP_E (bytemode, aflag, dflag);
1713     }
1714    
1715     static int
1716     OP_E (bytemode, aflag, dflag)
1717     int bytemode;
1718     int aflag;
1719     int dflag;
1720     {
1721     int disp;
1722    
1723     /* skip mod/rm byte */
1724     codep++;
1725    
1726     if (mod == 3)
1727     {
1728     switch (bytemode)
1729     {
1730     case b_mode:
1731     oappend (names8[rm]);
1732     break;
1733     case w_mode:
1734     oappend (names16[rm]);
1735     break;
1736     case v_mode:
1737     if (dflag)
1738     oappend (names32[rm]);
1739     else
1740     oappend (names16[rm]);
1741     break;
1742     default:
1743     oappend ("<bad dis table>");
1744     break;
1745     }
1746     return 0;
1747     }
1748    
1749     disp = 0;
1750     append_prefix ();
1751    
1752     if (aflag) /* 32 bit address mode */
1753     {
1754     int havesib;
1755     int havebase;
1756     int base;
1757     int index = 0;
1758     int scale = 0;
1759    
1760     havesib = 0;
1761     havebase = 1;
1762     base = rm;
1763    
1764     if (base == 4)
1765     {
1766     havesib = 1;
1767     FETCH_DATA (the_info, codep + 1);
1768     scale = (*codep >> 6) & 3;
1769     index = (*codep >> 3) & 7;
1770     base = *codep & 7;
1771     codep++;
1772     }
1773    
1774     switch (mod)
1775     {
1776     case 0:
1777     if (base == 5)
1778     {
1779     havebase = 0;
1780     disp = get32 ();
1781     }
1782     break;
1783     case 1:
1784     FETCH_DATA (the_info, codep + 1);
1785     disp = *codep++;
1786     if ((disp & 0x80) != 0)
1787     disp -= 0x100;
1788     break;
1789     case 2:
1790     disp = get32 ();
1791     break;
1792     }
1793    
1794     if (mod != 0 || base == 5)
1795     {
1796     sprintf (scratchbuf, "$%08x", disp);
1797     oappend (scratchbuf);
1798     }
1799    
1800     if (havebase || (havesib && (index != 4 || scale != 0)))
1801     {
1802     oappend ("(");
1803     if (havebase)
1804     oappend (names32[base]);
1805     if (havesib)
1806     {
1807     if (index != 4)
1808     {
1809     sprintf (scratchbuf, ",%s", names32[index]);
1810     oappend (scratchbuf);
1811     }
1812     sprintf (scratchbuf, "*%d", 1 << scale);
1813     oappend (scratchbuf);
1814     }
1815     oappend (")");
1816     }
1817     }
1818     else
1819     { /* 16 bit address mode */
1820     switch (mod)
1821     {
1822     case 0:
1823     if (rm == 6)
1824     {
1825     disp = get16 ();
1826     if ((disp & 0x8000) != 0)
1827     disp -= 0x10000;
1828     }
1829     break;
1830     case 1:
1831     FETCH_DATA (the_info, codep + 1);
1832     disp = *codep++;
1833     if ((disp & 0x80) != 0)
1834     disp -= 0x100;
1835     break;
1836     case 2:
1837     disp = get16 ();
1838     if ((disp & 0x8000) != 0)
1839     disp -= 0x10000;
1840     break;
1841     }
1842    
1843     if (mod != 0 || rm == 6)
1844     {
1845     sprintf (scratchbuf, "$%04x", disp);
1846     oappend (scratchbuf);
1847     }
1848    
1849     if (mod != 0 || rm != 6)
1850     {
1851     oappend ("(");
1852     oappend (index16[rm]);
1853     oappend (")");
1854     }
1855     }
1856     return 0;
1857     }
1858    
1859     static int
1860     OP_G (bytemode, aflag, dflag)
1861     int bytemode;
1862     int aflag;
1863     int dflag;
1864     {
1865     switch (bytemode)
1866     {
1867     case b_mode:
1868     oappend (names8[reg]);
1869     break;
1870     case w_mode:
1871     oappend (names16[reg]);
1872     break;
1873     case d_mode:
1874     oappend (names32[reg]);
1875     break;
1876     case v_mode:
1877     if (dflag)
1878     oappend (names32[reg]);
1879     else
1880     oappend (names16[reg]);
1881     break;
1882     default:
1883     oappend ("<internal disassembler error>");
1884     break;
1885     }
1886     return (0);
1887     }
1888    
1889     static int
1890     get32 ()
1891     {
1892     int x = 0;
1893    
1894     FETCH_DATA (the_info, codep + 4);
1895     x = *codep++ & 0xff;
1896     x |= (*codep++ & 0xff) << 8;
1897     x |= (*codep++ & 0xff) << 16;
1898     x |= (*codep++ & 0xff) << 24;
1899     return (x);
1900     }
1901    
1902     static int
1903     get16 ()
1904     {
1905     int x = 0;
1906    
1907     FETCH_DATA (the_info, codep + 2);
1908     x = *codep++ & 0xff;
1909     x |= (*codep++ & 0xff) << 8;
1910     return (x);
1911     }
1912    
1913     static void
1914     set_op (op)
1915     int op;
1916     {
1917     op_index[op_ad] = op_ad;
1918     op_address[op_ad] = op;
1919     }
1920    
1921     static int
1922     OP_REG (code, aflag, dflag)
1923     int code;
1924     int aflag;
1925     int dflag;
1926     {
1927     char *s;
1928    
1929     switch (code)
1930     {
1931     case indir_dx_reg: s = "(dx)"; break;
1932     case ax_reg: case cx_reg: case dx_reg: case bx_reg:
1933     case sp_reg: case bp_reg: case si_reg: case di_reg:
1934     s = names16[code - ax_reg];
1935     break;
1936     case es_reg: case ss_reg: case cs_reg:
1937     case ds_reg: case fs_reg: case gs_reg:
1938     s = names_seg[code - es_reg];
1939     break;
1940     case al_reg: case ah_reg: case cl_reg: case ch_reg:
1941     case dl_reg: case dh_reg: case bl_reg: case bh_reg:
1942     s = names8[code - al_reg];
1943     break;
1944     case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
1945     case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
1946     if (dflag)
1947     s = names32[code - eAX_reg];
1948     else
1949     s = names16[code - eAX_reg];
1950     break;
1951     default:
1952     s = "<internal disassembler error>";
1953     break;
1954     }
1955     oappend (s);
1956     return (0);
1957     }
1958    
1959     static int
1960     OP_I (bytemode, aflag, dflag)
1961     int bytemode;
1962     int aflag;
1963     int dflag;
1964     {
1965     int op;
1966    
1967     switch (bytemode)
1968     {
1969     case b_mode:
1970     FETCH_DATA (the_info, codep + 1);
1971     op = *codep++ & 0xff;
1972     break;
1973     case v_mode:
1974     if (dflag)
1975     op = get32 ();
1976     else
1977     op = get16 ();
1978     break;
1979     case w_mode:
1980     op = get16 ();
1981     break;
1982     default:
1983     oappend ("<internal disassembler error>");
1984     return (0);
1985     }
1986     sprintf (scratchbuf, "#$%08x", op);
1987     oappend (scratchbuf);
1988     return (0);
1989     }
1990    
1991     static int
1992     OP_sI (bytemode, aflag, dflag)
1993     int bytemode;
1994     int aflag;
1995     int dflag;
1996     {
1997     int op;
1998    
1999     switch (bytemode)
2000     {
2001     case b_mode:
2002     FETCH_DATA (the_info, codep + 1);
2003     op = *codep++;
2004     if ((op & 0x80) != 0)
2005     op -= 0x100;
2006     break;
2007     case v_mode:
2008     if (dflag)
2009     op = get32 ();
2010     else
2011     {
2012     op = get16();
2013     if ((op & 0x8000) != 0)
2014     op -= 0x10000;
2015     }
2016     break;
2017     case w_mode:
2018     op = get16 ();
2019     if ((op & 0x8000) != 0)
2020     op -= 0x10000;
2021     break;
2022     default:
2023     oappend ("<internal disassembler error>");
2024     return (0);
2025     }
2026     sprintf (scratchbuf, "#$%08x", op);
2027     oappend (scratchbuf);
2028     return (0);
2029     }
2030    
2031     static int
2032     OP_J (bytemode, aflag, dflag)
2033     int bytemode;
2034     int aflag;
2035     int dflag;
2036     {
2037     int disp;
2038     int mask = -1;
2039    
2040     switch (bytemode)
2041     {
2042     case b_mode:
2043     FETCH_DATA (the_info, codep + 1);
2044     disp = *codep++;
2045     if ((disp & 0x80) != 0)
2046     disp -= 0x100;
2047     break;
2048     case v_mode:
2049     if (dflag)
2050     disp = get32 ();
2051     else
2052     {
2053     disp = get16 ();
2054     if ((disp & 0x8000) != 0)
2055     disp -= 0x10000;
2056     /* for some reason, a data16 prefix on a jump instruction
2057     means that the pc is masked to 16 bits after the
2058     displacement is added! */
2059     mask = 0xffff;
2060     }
2061     break;
2062     default:
2063     oappend ("<internal disassembler error>");
2064     return (0);
2065     }
2066     disp = (start_pc + codep - start_codep + disp) & mask;
2067     set_op (disp);
2068     sprintf (scratchbuf, "$%08x", disp);
2069     oappend (scratchbuf);
2070     return (0);
2071     }
2072    
2073     /* ARGSUSED */
2074     static int
2075     OP_SEG (dummy, aflag, dflag)
2076     int dummy;
2077     int aflag;
2078     int dflag;
2079     {
2080     static char *sreg[] = {
2081     "es","cs","ss","ds","fs","gs","?","?",
2082     };
2083    
2084     oappend (sreg[reg]);
2085     return (0);
2086     }
2087    
2088     static int
2089     OP_DIR (size, aflag, dflag)
2090     int size;
2091     int aflag;
2092     int dflag;
2093     {
2094     int seg, offset;
2095    
2096     switch (size)
2097     {
2098     case lptr:
2099     if (aflag)
2100     {
2101     offset = get32 ();
2102     seg = get16 ();
2103     }
2104     else
2105     {
2106     offset = get16 ();
2107     seg = get16 ();
2108     }
2109     sprintf (scratchbuf, "$%04x,$%08x", seg, offset);
2110     oappend (scratchbuf);
2111     break;
2112     case v_mode:
2113     if (aflag)
2114     offset = get32 ();
2115     else
2116     {
2117     offset = get16 ();
2118     if ((offset & 0x8000) != 0)
2119     offset -= 0x10000;
2120     }
2121    
2122     offset = start_pc + codep - start_codep + offset;
2123     set_op (offset);
2124     sprintf (scratchbuf, "$%08x", offset);
2125     oappend (scratchbuf);
2126     break;
2127     default:
2128     oappend ("<internal disassembler error>");
2129     break;
2130     }
2131     return (0);
2132     }
2133    
2134     /* ARGSUSED */
2135     static int
2136     OP_OFF (bytemode, aflag, dflag)
2137     int bytemode;
2138     int aflag;
2139     int dflag;
2140     {
2141     int off;
2142    
2143     append_prefix ();
2144    
2145     if (aflag)
2146     off = get32 ();
2147     else
2148     off = get16 ();
2149    
2150     sprintf (scratchbuf, "$%08x", off);
2151     oappend (scratchbuf);
2152     return (0);
2153     }
2154    
2155     /* ARGSUSED */
2156     static int
2157     OP_ESDI (dummy, aflag, dflag)
2158     int dummy;
2159     int aflag;
2160     int dflag;
2161     {
2162     oappend ("es:(");
2163     oappend (aflag ? "edi" : "di");
2164     oappend (")");
2165     return (0);
2166     }
2167    
2168     /* ARGSUSED */
2169     static int
2170     OP_DSSI (dummy, aflag, dflag)
2171     int dummy;
2172     int aflag;
2173     int dflag;
2174     {
2175     if ((prefixes
2176     & (PREFIX_CS
2177     | PREFIX_DS
2178     | PREFIX_SS
2179     | PREFIX_ES
2180     | PREFIX_FS
2181     | PREFIX_GS)) == 0)
2182     prefixes |= PREFIX_DS;
2183     append_prefix ();
2184     oappend ("(");
2185     oappend (aflag ? "esi" : "si");
2186     oappend (")");
2187     return (0);
2188     }
2189    
2190     #if 0
2191     /* Not used. */
2192    
2193     /* ARGSUSED */
2194     static int
2195     OP_ONE (dummy, aflag, dflag)
2196     int dummy;
2197     int aflag;
2198     int dflag;
2199     {
2200     oappend ("1");
2201     return (0);
2202     }
2203    
2204     #endif
2205    
2206     /* ARGSUSED */
2207     static int
2208     OP_C (dummy, aflag, dflag)
2209     int dummy;
2210     int aflag;
2211     int dflag;
2212     {
2213     codep++; /* skip mod/rm */
2214     sprintf (scratchbuf, "cr%d", reg);
2215     oappend (scratchbuf);
2216     return (0);
2217     }
2218    
2219     /* ARGSUSED */
2220     static int
2221     OP_D (dummy, aflag, dflag)
2222     int dummy;
2223     int aflag;
2224     int dflag;
2225     {
2226     codep++; /* skip mod/rm */
2227     sprintf (scratchbuf, "dr%d", reg);
2228     oappend (scratchbuf);
2229     return (0);
2230     }
2231    
2232     /* ARGSUSED */
2233     static int
2234     OP_T (dummy, aflag, dflag)
2235     int dummy;
2236     int aflag;
2237     int dflag;
2238     {
2239     codep++; /* skip mod/rm */
2240     sprintf (scratchbuf, "tr%d", reg);
2241     oappend (scratchbuf);
2242     return (0);
2243     }
2244    
2245     static int
2246     OP_rm (bytemode, aflag, dflag)
2247     int bytemode;
2248     int aflag;
2249     int dflag;
2250     {
2251     switch (bytemode)
2252     {
2253     case d_mode:
2254     oappend (names32[rm]);
2255     break;
2256     case w_mode:
2257     oappend (names16[rm]);
2258     break;
2259     }
2260     return (0);
2261     }
2262    
2263     static int
2264     OP_MMX (bytemode, aflag, dflag)
2265     int bytemode;
2266     int aflag;
2267     int dflag;
2268     {
2269     sprintf (scratchbuf, "mm%d", reg);
2270     oappend (scratchbuf);
2271     return 0;
2272     }
2273    
2274     static int
2275     OP_EM (bytemode, aflag, dflag)
2276     int bytemode;
2277     int aflag;
2278     int dflag;
2279     {
2280     if (mod != 3)
2281     return OP_E (bytemode, aflag, dflag);
2282    
2283     codep++;
2284     sprintf (scratchbuf, "mm%d", rm);
2285     oappend (scratchbuf);
2286     return 0;
2287     }
2288    
2289     static int
2290     OP_MS (bytemode, aflag, dflag)
2291     int bytemode;
2292     int aflag;
2293     int dflag;
2294     {
2295     ++codep;
2296     sprintf (scratchbuf, "mm%d", rm);
2297     oappend (scratchbuf);
2298     return 0;
2299     }