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