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