]> Git Repo - binutils.git/blob - opcodes/i386-dis.c
* sparc-opc.c (asi_table): Add #ASI_N, #ASI_N_L, #ASI_NUCLEUS,
[binutils.git] / opcodes / i386-dis.c
1 /* Print i386 instructions for GDB, the GNU debugger.
2    Copyright (C) 1988, 1989, 1991, 1993, 1994, 1995 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 ([email protected])
22  * July 1988
23  *  modified by John Hassey ([email protected])
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
750 struct dis386 grps[][8] = {
751   /* GRP1b */
752   {
753     { "addb",   Eb, Ib },
754     { "orb",    Eb, Ib },
755     { "adcb",   Eb, Ib },
756     { "sbbb",   Eb, Ib },
757     { "andb",   Eb, Ib },
758     { "subb",   Eb, Ib },
759     { "xorb",   Eb, Ib },
760     { "cmpb",   Eb, Ib }
761   },
762   /* GRP1S */
763   {
764     { "addS",   Ev, Iv },
765     { "orS",    Ev, Iv },
766     { "adcS",   Ev, Iv },
767     { "sbbS",   Ev, Iv },
768     { "andS",   Ev, Iv },
769     { "subS",   Ev, Iv },
770     { "xorS",   Ev, Iv },
771     { "cmpS",   Ev, Iv }
772   },
773   /* GRP1Ss */
774   {
775     { "addS",   Ev, sIb },
776     { "orS",    Ev, sIb },
777     { "adcS",   Ev, sIb },
778     { "sbbS",   Ev, sIb },
779     { "andS",   Ev, sIb },
780     { "subS",   Ev, sIb },
781     { "xorS",   Ev, sIb },
782     { "cmpS",   Ev, sIb }
783   },
784   /* GRP2b */
785   {
786     { "rolb",   Eb, Ib },
787     { "rorb",   Eb, Ib },
788     { "rclb",   Eb, Ib },
789     { "rcrb",   Eb, Ib },
790     { "shlb",   Eb, Ib },
791     { "shrb",   Eb, Ib },
792     { "(bad)" },
793     { "sarb",   Eb, Ib },
794   },
795   /* GRP2S */
796   {
797     { "rolS",   Ev, Ib },
798     { "rorS",   Ev, Ib },
799     { "rclS",   Ev, Ib },
800     { "rcrS",   Ev, Ib },
801     { "shlS",   Ev, Ib },
802     { "shrS",   Ev, Ib },
803     { "(bad)" },
804     { "sarS",   Ev, Ib },
805   },
806   /* GRP2b_one */
807   {
808     { "rolb",   Eb },
809     { "rorb",   Eb },
810     { "rclb",   Eb },
811     { "rcrb",   Eb },
812     { "shlb",   Eb },
813     { "shrb",   Eb },
814     { "(bad)" },
815     { "sarb",   Eb },
816   },
817   /* GRP2S_one */
818   {
819     { "rolS",   Ev },
820     { "rorS",   Ev },
821     { "rclS",   Ev },
822     { "rcrS",   Ev },
823     { "shlS",   Ev },
824     { "shrS",   Ev },
825     { "(bad)" },
826     { "sarS",   Ev },
827   },
828   /* GRP2b_cl */
829   {
830     { "rolb",   Eb, CL },
831     { "rorb",   Eb, CL },
832     { "rclb",   Eb, CL },
833     { "rcrb",   Eb, CL },
834     { "shlb",   Eb, CL },
835     { "shrb",   Eb, CL },
836     { "(bad)" },
837     { "sarb",   Eb, CL },
838   },
839   /* GRP2S_cl */
840   {
841     { "rolS",   Ev, CL },
842     { "rorS",   Ev, CL },
843     { "rclS",   Ev, CL },
844     { "rcrS",   Ev, CL },
845     { "shlS",   Ev, CL },
846     { "shrS",   Ev, CL },
847     { "(bad)" },
848     { "sarS",   Ev, CL }
849   },
850   /* GRP3b */
851   {
852     { "testb",  Eb, Ib },
853     { "(bad)",  Eb },
854     { "notb",   Eb },
855     { "negb",   Eb },
856     { "mulb",   AL, Eb },
857     { "imulb",  AL, Eb },
858     { "divb",   AL, Eb },
859     { "idivb",  AL, Eb }
860   },
861   /* GRP3S */
862   {
863     { "testS",  Ev, Iv },
864     { "(bad)" },
865     { "notS",   Ev },
866     { "negS",   Ev },
867     { "mulS",   eAX, Ev },
868     { "imulS",  eAX, Ev },
869     { "divS",   eAX, Ev },
870     { "idivS",  eAX, Ev },
871   },
872   /* GRP4 */
873   {
874     { "incb", Eb },
875     { "decb", Eb },
876     { "(bad)" },
877     { "(bad)" },
878     { "(bad)" },
879     { "(bad)" },
880     { "(bad)" },
881     { "(bad)" },
882   },
883   /* GRP5 */
884   {
885     { "incS",   Ev },
886     { "decS",   Ev },
887     { "call",   indirEv },
888     { "lcall",  indirEv },
889     { "jmp",    indirEv },
890     { "ljmp",   indirEv },
891     { "pushS",  Ev },
892     { "(bad)" },
893   },
894   /* GRP6 */
895   {
896     { "sldt",   Ew },
897     { "str",    Ew },
898     { "lldt",   Ew },
899     { "ltr",    Ew },
900     { "verr",   Ew },
901     { "verw",   Ew },
902     { "(bad)" },
903     { "(bad)" }
904   },
905   /* GRP7 */
906   {
907     { "sgdt", Ew },
908     { "sidt", Ew },
909     { "lgdt", Ew },
910     { "lidt", Ew },
911     { "smsw", Ew },
912     { "(bad)" },
913     { "lmsw", Ew },
914     { "invlpg", Ew },
915   },
916   /* GRP8 */
917   {
918     { "(bad)" },
919     { "(bad)" },
920     { "(bad)" },
921     { "(bad)" },
922     { "btS",    Ev, Ib },
923     { "btsS",   Ev, Ib },
924     { "btrS",   Ev, Ib },
925     { "btcS",   Ev, Ib },
926   },
927   /* GRP9 */
928   {
929     { "(bad)" },
930     { "cmpxchg8b", Ev },
931     { "(bad)" },
932     { "(bad)" },
933     { "(bad)" },
934     { "(bad)" },
935     { "(bad)" },
936     { "(bad)" },
937   }
938 };
939
940 #define PREFIX_REPZ 1
941 #define PREFIX_REPNZ 2
942 #define PREFIX_LOCK 4
943 #define PREFIX_CS 8
944 #define PREFIX_SS 0x10
945 #define PREFIX_DS 0x20
946 #define PREFIX_ES 0x40
947 #define PREFIX_FS 0x80
948 #define PREFIX_GS 0x100
949 #define PREFIX_DATA 0x200
950 #define PREFIX_ADR 0x400
951 #define PREFIX_FWAIT 0x800
952
953 static int prefixes;
954
955 static void
956 ckprefix ()
957 {
958   prefixes = 0;
959   while (1)
960     {
961       FETCH_DATA (the_info, codep + 1);
962       switch (*codep)
963         {
964         case 0xf3:
965           prefixes |= PREFIX_REPZ;
966           break;
967         case 0xf2:
968           prefixes |= PREFIX_REPNZ;
969           break;
970         case 0xf0:
971           prefixes |= PREFIX_LOCK;
972           break;
973         case 0x2e:
974           prefixes |= PREFIX_CS;
975           break;
976         case 0x36:
977           prefixes |= PREFIX_SS;
978           break;
979         case 0x3e:
980           prefixes |= PREFIX_DS;
981           break;
982         case 0x26:
983           prefixes |= PREFIX_ES;
984           break;
985         case 0x64:
986           prefixes |= PREFIX_FS;
987           break;
988         case 0x65:
989           prefixes |= PREFIX_GS;
990           break;
991         case 0x66:
992           prefixes |= PREFIX_DATA;
993           break;
994         case 0x67:
995           prefixes |= PREFIX_ADR;
996           break;
997         case 0x9b:
998           prefixes |= PREFIX_FWAIT;
999           break;
1000         default:
1001           return;
1002         }
1003       codep++;
1004     }
1005 }
1006
1007 static int dflag;
1008 static int aflag;               
1009
1010 static char op1out[100], op2out[100], op3out[100];
1011 static int op_address[3], op_ad, op_index[3];
1012 static int start_pc;
1013
1014 \f
1015 /*
1016  *   On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1017  *   (see topic "Redundant prefixes" in the "Differences from 8086"
1018  *   section of the "Virtual 8086 Mode" chapter.)
1019  * 'pc' should be the address of this instruction, it will
1020  *   be used to print the target address if this is a relative jump or call
1021  * The function returns the length of this instruction in bytes.
1022  */
1023
1024 int
1025 print_insn_i386 (pc, info)
1026      bfd_vma pc;
1027      disassemble_info *info;
1028 {
1029   struct dis386 *dp;
1030   int i;
1031   int enter_instruction;
1032   char *first, *second, *third;
1033   int needcomma;
1034   unsigned char need_modrm;
1035
1036   struct dis_private priv;
1037   bfd_byte *inbuf = priv.the_buffer;
1038
1039   info->private_data = (PTR) &priv;
1040   priv.max_fetched = priv.the_buffer;
1041   priv.insn_start = pc;
1042   if (setjmp (priv.bailout) != 0)
1043     /* Error return.  */
1044     return -1;
1045
1046   obuf[0] = 0;
1047   op1out[0] = 0;
1048   op2out[0] = 0;
1049   op3out[0] = 0;
1050
1051   op_index[0] = op_index[1] = op_index[2] = -1;
1052
1053   the_info = info;
1054   start_pc = pc;
1055   start_codep = inbuf;
1056   codep = inbuf;
1057   
1058   ckprefix ();
1059
1060   FETCH_DATA (info, codep + 1);
1061   if (*codep == 0xc8)
1062     enter_instruction = 1;
1063   else
1064     enter_instruction = 0;
1065   
1066   obufp = obuf;
1067   
1068   if (prefixes & PREFIX_REPZ)
1069     oappend ("repz ");
1070   if (prefixes & PREFIX_REPNZ)
1071     oappend ("repnz ");
1072   if (prefixes & PREFIX_LOCK)
1073     oappend ("lock ");
1074   
1075   if ((prefixes & PREFIX_FWAIT)
1076       && ((*codep < 0xd8) || (*codep > 0xdf)))
1077     {
1078       /* fwait not followed by floating point instruction */
1079       (*info->fprintf_func) (info->stream, "fwait");
1080       return (1);
1081     }
1082   
1083   /* these would be initialized to 0 if disassembling for 8086 or 286 */
1084   dflag = 1;
1085   aflag = 1;
1086   
1087   if (prefixes & PREFIX_DATA)
1088     dflag ^= 1;
1089   
1090   if (prefixes & PREFIX_ADR)
1091     {
1092       aflag ^= 1;
1093       oappend ("addr16 ");
1094     }
1095   
1096   if (*codep == 0x0f)
1097     {
1098       FETCH_DATA (info, codep + 2);
1099       dp = &dis386_twobyte[*++codep];
1100       need_modrm = twobyte_has_modrm[*codep];
1101     }
1102   else
1103     {
1104       dp = &dis386[*codep];
1105       need_modrm = onebyte_has_modrm[*codep];
1106     }
1107   codep++;
1108
1109   if (need_modrm)
1110     {
1111       FETCH_DATA (info, codep + 1);
1112       mod = (*codep >> 6) & 3;
1113       reg = (*codep >> 3) & 7;
1114       rm = *codep & 7;
1115     }
1116
1117   if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
1118     {
1119       dofloat ();
1120     }
1121   else
1122     {
1123       if (dp->name == NULL)
1124         dp = &grps[dp->bytemode1][reg];
1125       
1126       putop (dp->name);
1127       
1128       obufp = op1out;
1129       op_ad = 2;
1130       if (dp->op1)
1131         (*dp->op1)(dp->bytemode1);
1132       
1133       obufp = op2out;
1134       op_ad = 1;
1135       if (dp->op2)
1136         (*dp->op2)(dp->bytemode2);
1137       
1138       obufp = op3out;
1139       op_ad = 0;
1140       if (dp->op3)
1141         (*dp->op3)(dp->bytemode3);
1142     }
1143   
1144   obufp = obuf + strlen (obuf);
1145   for (i = strlen (obuf); i < 6; i++)
1146     oappend (" ");
1147   oappend (" ");
1148   (*info->fprintf_func) (info->stream, "%s", obuf);
1149   
1150   /* enter instruction is printed with operands in the
1151    * same order as the intel book; everything else
1152    * is printed in reverse order 
1153    */
1154   if (enter_instruction)
1155     {
1156       first = op1out;
1157       second = op2out;
1158       third = op3out;
1159       op_ad = op_index[0];
1160       op_index[0] = op_index[2];
1161       op_index[2] = op_ad;
1162     }
1163   else
1164     {
1165       first = op3out;
1166       second = op2out;
1167       third = op1out;
1168     }
1169   needcomma = 0;
1170   if (*first)
1171     {
1172       if (op_index[0] != -1)
1173         (*info->print_address_func) (op_address[op_index[0]], info);
1174       else
1175         (*info->fprintf_func) (info->stream, "%s", first);
1176       needcomma = 1;
1177     }
1178   if (*second)
1179     {
1180       if (needcomma)
1181         (*info->fprintf_func) (info->stream, ",");
1182       if (op_index[1] != -1)
1183         (*info->print_address_func) (op_address[op_index[1]], info);
1184       else
1185         (*info->fprintf_func) (info->stream, "%s", second);
1186       needcomma = 1;
1187     }
1188   if (*third)
1189     {
1190       if (needcomma)
1191         (*info->fprintf_func) (info->stream, ",");
1192       if (op_index[2] != -1)
1193         (*info->print_address_func) (op_address[op_index[2]], info);
1194       else
1195         (*info->fprintf_func) (info->stream, "%s", third);
1196     }
1197   return (codep - inbuf);
1198 }
1199
1200 char *float_mem[] = {
1201   /* d8 */
1202   "fadds",
1203   "fmuls",
1204   "fcoms",
1205   "fcomps",
1206   "fsubs",
1207   "fsubrs",
1208   "fdivs",
1209   "fdivrs",
1210   /*  d9 */
1211   "flds",
1212   "(bad)",
1213   "fsts",
1214   "fstps",
1215   "fldenv",
1216   "fldcw",
1217   "fNstenv",
1218   "fNstcw",
1219   /* da */
1220   "fiaddl",
1221   "fimull",
1222   "ficoml",
1223   "ficompl",
1224   "fisubl",
1225   "fisubrl",
1226   "fidivl",
1227   "fidivrl",
1228   /* db */
1229   "fildl",
1230   "(bad)",
1231   "fistl",
1232   "fistpl",
1233   "(bad)",
1234   "fldt",
1235   "(bad)",
1236   "fstpt",
1237   /* dc */
1238   "faddl",
1239   "fmull",
1240   "fcoml",
1241   "fcompl",
1242   "fsubl",
1243   "fsubrl",
1244   "fdivl",
1245   "fdivrl",
1246   /* dd */
1247   "fldl",
1248   "(bad)",
1249   "fstl",
1250   "fstpl",
1251   "frstor",
1252   "(bad)",
1253   "fNsave",
1254   "fNstsw",
1255   /* de */
1256   "fiadd",
1257   "fimul",
1258   "ficom",
1259   "ficomp",
1260   "fisub",
1261   "fisubr",
1262   "fidiv",
1263   "fidivr",
1264   /* df */
1265   "fild",
1266   "(bad)",
1267   "fist",
1268   "fistp",
1269   "fbld",
1270   "fildll",
1271   "fbstp",
1272   "fistpll",
1273 };
1274
1275 #define ST OP_ST, 0
1276 #define STi OP_STi, 0
1277 int OP_ST(), OP_STi();
1278
1279 #define FGRPd9_2 NULL, NULL, 0
1280 #define FGRPd9_4 NULL, NULL, 1
1281 #define FGRPd9_5 NULL, NULL, 2
1282 #define FGRPd9_6 NULL, NULL, 3
1283 #define FGRPd9_7 NULL, NULL, 4
1284 #define FGRPda_5 NULL, NULL, 5
1285 #define FGRPdb_4 NULL, NULL, 6
1286 #define FGRPde_3 NULL, NULL, 7
1287 #define FGRPdf_4 NULL, NULL, 8
1288
1289 struct dis386 float_reg[][8] = {
1290   /* d8 */
1291   {
1292     { "fadd",   ST, STi },
1293     { "fmul",   ST, STi },
1294     { "fcom",   STi },
1295     { "fcomp",  STi },
1296     { "fsub",   ST, STi },
1297     { "fsubr",  ST, STi },
1298     { "fdiv",   ST, STi },
1299     { "fdivr",  ST, STi },
1300   },
1301   /* d9 */
1302   {
1303     { "fld",    STi },
1304     { "fxch",   STi },
1305     { FGRPd9_2 },
1306     { "(bad)" },
1307     { FGRPd9_4 },
1308     { FGRPd9_5 },
1309     { FGRPd9_6 },
1310     { FGRPd9_7 },
1311   },
1312   /* da */
1313   {
1314     { "fcmovb", ST, STi },
1315     { "fcmove", ST, STi },
1316     { "fcmovbe",ST, STi },
1317     { "fcmovu", ST, STi },
1318     { "(bad)" },
1319     { FGRPda_5 },
1320     { "(bad)" },
1321     { "(bad)" },
1322   },
1323   /* db */
1324   {
1325     { "fcmovnb",ST, STi },
1326     { "fcmovne",ST, STi },
1327     { "fcmovnbe",ST, STi },
1328     { "fcmovnu",ST, STi },
1329     { FGRPdb_4 },
1330     { "fucomi", ST, STi },
1331     { "fcomi",  ST, STi },
1332     { "(bad)" },
1333   },
1334   /* dc */
1335   {
1336     { "fadd",   STi, ST },
1337     { "fmul",   STi, ST },
1338     { "(bad)" },
1339     { "(bad)" },
1340     { "fsub",   STi, ST },
1341     { "fsubr",  STi, ST },
1342     { "fdiv",   STi, ST },
1343     { "fdivr",  STi, ST },
1344   },
1345   /* dd */
1346   {
1347     { "ffree",  STi },
1348     { "(bad)" },
1349     { "fst",    STi },
1350     { "fstp",   STi },
1351     { "fucom",  STi },
1352     { "fucomp", STi },
1353     { "(bad)" },
1354     { "(bad)" },
1355   },
1356   /* de */
1357   {
1358     { "faddp",  STi, ST },
1359     { "fmulp",  STi, ST },
1360     { "(bad)" },
1361     { FGRPde_3 },
1362     { "fsubp",  STi, ST },
1363     { "fsubrp", STi, ST },
1364     { "fdivp",  STi, ST },
1365     { "fdivrp", STi, ST },
1366   },
1367   /* df */
1368   {
1369     { "(bad)" },
1370     { "(bad)" },
1371     { "(bad)" },
1372     { "(bad)" },
1373     { FGRPdf_4 },
1374     { "fucomip",ST, STi },
1375     { "fcomip", ST, STi },
1376     { "(bad)" },
1377   },
1378 };
1379
1380
1381 char *fgrps[][8] = {
1382   /* d9_2  0 */
1383   {
1384     "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1385   },
1386
1387   /* d9_4  1 */
1388   {
1389     "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
1390   },
1391
1392   /* d9_5  2 */
1393   {
1394     "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
1395   },
1396
1397   /* d9_6  3 */
1398   {
1399     "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
1400   },
1401
1402   /* d9_7  4 */
1403   {
1404     "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
1405   },
1406
1407   /* da_5  5 */
1408   {
1409     "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1410   },
1411
1412   /* db_4  6 */
1413   {
1414     "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
1415     "fNsetpm(287 only)","(bad)","(bad)","(bad)",
1416   },
1417
1418   /* de_3  7 */
1419   {
1420     "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1421   },
1422
1423   /* df_4  8 */
1424   {
1425     "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1426   },
1427 };
1428
1429 static void
1430 dofloat ()
1431 {
1432   struct dis386 *dp;
1433   unsigned char floatop;
1434   
1435   floatop = codep[-1];
1436   
1437   if (mod != 3)
1438     {
1439       putop (float_mem[(floatop - 0xd8) * 8 + reg]);
1440       obufp = op1out;
1441       OP_E (v_mode);
1442       return;
1443     }
1444   codep++;
1445   
1446   dp = &float_reg[floatop - 0xd8][reg];
1447   if (dp->name == NULL)
1448     {
1449       putop (fgrps[dp->bytemode1][rm]);
1450       /* instruction fnstsw is only one with strange arg */
1451       if (floatop == 0xdf
1452           && FETCH_DATA (the_info, codep + 1)
1453           && *codep == 0xe0)
1454         strcpy (op1out, "%eax");
1455     }
1456   else
1457     {
1458       putop (dp->name);
1459       obufp = op1out;
1460       if (dp->op1)
1461         (*dp->op1)(dp->bytemode1);
1462       obufp = op2out;
1463       if (dp->op2)
1464         (*dp->op2)(dp->bytemode2);
1465     }
1466 }
1467
1468 /* ARGSUSED */
1469 int
1470 OP_ST (ignore)
1471      int ignore;
1472 {
1473   oappend ("%st");
1474   return (0);
1475 }
1476
1477 /* ARGSUSED */
1478 int
1479 OP_STi (ignore)
1480      int ignore;
1481 {
1482   sprintf (scratchbuf, "%%st(%d)", rm);
1483   oappend (scratchbuf);
1484   return (0);
1485 }
1486
1487
1488 /* capital letters in template are macros */
1489 static void
1490 putop (template)
1491      char *template;
1492 {
1493   char *p;
1494   
1495   for (p = template; *p; p++)
1496     {
1497       switch (*p)
1498         {
1499         default:
1500           *obufp++ = *p;
1501           break;
1502         case 'C':               /* For jcxz/jecxz */
1503           if (aflag == 0)
1504             *obufp++ = 'e';
1505           break;
1506         case 'N':
1507           if ((prefixes & PREFIX_FWAIT) == 0)
1508             *obufp++ = 'n';
1509           break;
1510         case 'S':
1511           /* operand size flag */
1512           if (dflag)
1513             *obufp++ = 'l';
1514           else
1515             *obufp++ = 'w';
1516           break;
1517         }
1518     }
1519   *obufp = 0;
1520 }
1521
1522 static void
1523 oappend (s)
1524      char *s;
1525 {
1526   strcpy (obufp, s);
1527   obufp += strlen (s);
1528   *obufp = 0;
1529 }
1530
1531 static void
1532 append_prefix ()
1533 {
1534   if (prefixes & PREFIX_CS)
1535     oappend ("%cs:");
1536   if (prefixes & PREFIX_DS)
1537     oappend ("%ds:");
1538   if (prefixes & PREFIX_SS)
1539     oappend ("%ss:");
1540   if (prefixes & PREFIX_ES)
1541     oappend ("%es:");
1542   if (prefixes & PREFIX_FS)
1543     oappend ("%fs:");
1544   if (prefixes & PREFIX_GS)
1545     oappend ("%gs:");
1546 }
1547
1548 int
1549 OP_indirE (bytemode)
1550      int bytemode;
1551 {
1552   oappend ("*");
1553   OP_E (bytemode);
1554   return (0);
1555 }
1556
1557 int
1558 OP_E (bytemode)
1559      int bytemode;
1560 {
1561   int disp;
1562   int havesib;
1563   int base;
1564   int index;
1565   int scale;
1566   int havebase;
1567   
1568   /* skip mod/rm byte */
1569   codep++;
1570   
1571   havesib = 0;
1572   havebase = 0;
1573   disp = 0;
1574   
1575   if (mod == 3)
1576     {
1577       switch (bytemode)
1578         {
1579         case b_mode:
1580           oappend (names8[rm]);
1581           break;
1582         case w_mode:
1583           oappend (names16[rm]);
1584           break;
1585         case v_mode:
1586           if (dflag)
1587             oappend (names32[rm]);
1588           else
1589             oappend (names16[rm]);
1590           break;
1591         default:
1592           oappend ("<bad dis table>");
1593           break;
1594         }
1595       return (0);
1596     }
1597   
1598   append_prefix ();
1599   if (rm == 4)
1600     {
1601       havesib = 1;
1602       havebase = 1;
1603       FETCH_DATA (the_info, codep + 1);
1604       scale = (*codep >> 6) & 3;
1605       index = (*codep >> 3) & 7;
1606       base = *codep & 7;
1607       codep++;
1608     }
1609   
1610   switch (mod)
1611     {
1612     case 0:
1613       switch (rm)
1614         {
1615         case 4:
1616           /* implies havesib and havebase */
1617           if (base == 5) {
1618             havebase = 0;
1619             disp = get32 ();
1620           }
1621           break;
1622         case 5:
1623           disp = get32 ();
1624           break;
1625         default:
1626           havebase = 1;
1627           base = rm;
1628           break;
1629         }
1630       break;
1631     case 1:
1632       FETCH_DATA (the_info, codep + 1);
1633       disp = *(char *)codep++;
1634       if (rm != 4)
1635         {
1636           havebase = 1;
1637           base = rm;
1638         }
1639       break;
1640     case 2:
1641       disp = get32 ();
1642       if (rm != 4)
1643         {
1644           havebase = 1;
1645           base = rm;
1646         }
1647       break;
1648     }
1649   
1650   if (mod != 0 || rm == 5 || (havesib && base == 5))
1651     {
1652       sprintf (scratchbuf, "0x%x", disp);
1653       oappend (scratchbuf);
1654     }
1655   
1656   if (havebase || havesib) 
1657     {
1658       oappend ("(");
1659       if (havebase)
1660         oappend (names32[base]);
1661       if (havesib) 
1662         {
1663           if (index != 4) 
1664             {
1665               sprintf (scratchbuf, ",%s", names32[index]);
1666               oappend (scratchbuf);
1667             }
1668           sprintf (scratchbuf, ",%d", 1 << scale);
1669           oappend (scratchbuf);
1670         }
1671       oappend (")");
1672     }
1673   return (0);
1674 }
1675
1676 int
1677 OP_G (bytemode)
1678      int bytemode;
1679 {
1680   switch (bytemode) 
1681     {
1682     case b_mode:
1683       oappend (names8[reg]);
1684       break;
1685     case w_mode:
1686       oappend (names16[reg]);
1687       break;
1688     case d_mode:
1689       oappend (names32[reg]);
1690       break;
1691     case v_mode:
1692       if (dflag)
1693         oappend (names32[reg]);
1694       else
1695         oappend (names16[reg]);
1696       break;
1697     default:
1698       oappend ("<internal disassembler error>");
1699       break;
1700     }
1701   return (0);
1702 }
1703
1704 static int
1705 get32 ()
1706 {
1707   int x = 0;
1708
1709   FETCH_DATA (the_info, codep + 4);
1710   x = *codep++ & 0xff;
1711   x |= (*codep++ & 0xff) << 8;
1712   x |= (*codep++ & 0xff) << 16;
1713   x |= (*codep++ & 0xff) << 24;
1714   return (x);
1715 }
1716
1717 static int
1718 get16 ()
1719 {
1720   int x = 0;
1721
1722   FETCH_DATA (the_info, codep + 2);
1723   x = *codep++ & 0xff;
1724   x |= (*codep++ & 0xff) << 8;
1725   return (x);
1726 }
1727
1728 static void
1729 set_op (op)
1730      int op;
1731 {
1732   op_index[op_ad] = op_ad;
1733   op_address[op_ad] = op;
1734 }
1735
1736 int
1737 OP_REG (code)
1738      int code;
1739 {
1740   char *s;
1741   
1742   switch (code) 
1743     {
1744     case indir_dx_reg: s = "(%dx)"; break;
1745         case ax_reg: case cx_reg: case dx_reg: case bx_reg:
1746         case sp_reg: case bp_reg: case si_reg: case di_reg:
1747                 s = names16[code - ax_reg];
1748                 break;
1749         case es_reg: case ss_reg: case cs_reg:
1750         case ds_reg: case fs_reg: case gs_reg:
1751                 s = names_seg[code - es_reg];
1752                 break;
1753         case al_reg: case ah_reg: case cl_reg: case ch_reg:
1754         case dl_reg: case dh_reg: case bl_reg: case bh_reg:
1755                 s = names8[code - al_reg];
1756                 break;
1757         case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
1758         case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
1759       if (dflag)
1760         s = names32[code - eAX_reg];
1761       else
1762         s = names16[code - eAX_reg];
1763       break;
1764     default:
1765       s = "<internal disassembler error>";
1766       break;
1767     }
1768   oappend (s);
1769   return (0);
1770 }
1771
1772 int
1773 OP_I (bytemode)
1774      int bytemode;
1775 {
1776   int op;
1777   
1778   switch (bytemode) 
1779     {
1780     case b_mode:
1781       FETCH_DATA (the_info, codep + 1);
1782       op = *codep++ & 0xff;
1783       break;
1784     case v_mode:
1785       if (dflag)
1786         op = get32 ();
1787       else
1788         op = get16 ();
1789       break;
1790     case w_mode:
1791       op = get16 ();
1792       break;
1793     default:
1794       oappend ("<internal disassembler error>");
1795       return (0);
1796     }
1797   sprintf (scratchbuf, "$0x%x", op);
1798   oappend (scratchbuf);
1799   return (0);
1800 }
1801
1802 int
1803 OP_sI (bytemode)
1804      int bytemode;
1805 {
1806   int op;
1807   
1808   switch (bytemode) 
1809     {
1810     case b_mode:
1811       FETCH_DATA (the_info, codep + 1);
1812       op = *(char *)codep++;
1813       break;
1814     case v_mode:
1815       if (dflag)
1816         op = get32 ();
1817       else
1818         op = (short)get16();
1819       break;
1820     case w_mode:
1821       op = (short)get16 ();
1822       break;
1823     default:
1824       oappend ("<internal disassembler error>");
1825       return (0);
1826     }
1827   sprintf (scratchbuf, "$0x%x", op);
1828   oappend (scratchbuf);
1829   return (0);
1830 }
1831
1832 int
1833 OP_J (bytemode)
1834      int bytemode;
1835 {
1836   int disp;
1837   int mask = -1;
1838   
1839   switch (bytemode) 
1840     {
1841     case b_mode:
1842       FETCH_DATA (the_info, codep + 1);
1843       disp = *(char *)codep++;
1844       break;
1845     case v_mode:
1846       if (dflag)
1847         disp = get32 ();
1848       else
1849         {
1850           disp = (short)get16 ();
1851           /* for some reason, a data16 prefix on a jump instruction
1852              means that the pc is masked to 16 bits after the
1853              displacement is added!  */
1854           mask = 0xffff;
1855         }
1856       break;
1857     default:
1858       oappend ("<internal disassembler error>");
1859       return (0);
1860     }
1861   disp = (start_pc + codep - start_codep + disp) & mask;
1862   set_op (disp);
1863   sprintf (scratchbuf, "0x%x", disp);
1864   oappend (scratchbuf);
1865   return (0);
1866 }
1867
1868 /* ARGSUSED */
1869 int
1870 OP_SEG (dummy)
1871      int dummy;
1872 {
1873   static char *sreg[] = {
1874     "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1875   };
1876
1877   oappend (sreg[reg]);
1878   return (0);
1879 }
1880
1881 int
1882 OP_DIR (size)
1883      int size;
1884 {
1885   int seg, offset;
1886   
1887   switch (size) 
1888     {
1889     case lptr:
1890       if (aflag) 
1891         {
1892           offset = get32 ();
1893           seg = get16 ();
1894         } 
1895       else 
1896         {
1897           offset = get16 ();
1898           seg = get16 ();
1899         }
1900       sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
1901       oappend (scratchbuf);
1902       break;
1903     case v_mode:
1904       if (aflag)
1905         offset = get32 ();
1906       else
1907         offset = (short)get16 ();
1908       
1909       offset = start_pc + codep - start_codep + offset;
1910       set_op (offset);
1911       sprintf (scratchbuf, "0x%x", offset);
1912       oappend (scratchbuf);
1913       break;
1914     default:
1915       oappend ("<internal disassembler error>");
1916       break;
1917     }
1918   return (0);
1919 }
1920
1921 /* ARGSUSED */
1922 int
1923 OP_OFF (bytemode)
1924      int bytemode;
1925 {
1926   int off;
1927   
1928   if (aflag)
1929     off = get32 ();
1930   else
1931     off = get16 ();
1932   
1933   sprintf (scratchbuf, "0x%x", off);
1934   oappend (scratchbuf);
1935   return (0);
1936 }
1937
1938 /* ARGSUSED */
1939 int
1940 OP_ESDI (dummy)
1941     int dummy;
1942 {
1943   oappend ("%es:(");
1944   oappend (aflag ? "%edi" : "%di");
1945   oappend (")");
1946   return (0);
1947 }
1948
1949 /* ARGSUSED */
1950 int
1951 OP_DSSI (dummy)
1952     int dummy;
1953 {
1954   oappend ("%ds:(");
1955   oappend (aflag ? "%esi" : "%si");
1956   oappend (")");
1957   return (0);
1958 }
1959
1960 /* ARGSUSED */
1961 int
1962 OP_ONE (dummy)
1963     int dummy;
1964 {
1965   oappend ("1");
1966   return (0);
1967 }
1968
1969 /* ARGSUSED */
1970 int
1971 OP_C (dummy)
1972     int dummy;
1973 {
1974   codep++; /* skip mod/rm */
1975   sprintf (scratchbuf, "%%cr%d", reg);
1976   oappend (scratchbuf);
1977   return (0);
1978 }
1979
1980 /* ARGSUSED */
1981 int
1982 OP_D (dummy)
1983     int dummy;
1984 {
1985   codep++; /* skip mod/rm */
1986   sprintf (scratchbuf, "%%db%d", reg);
1987   oappend (scratchbuf);
1988   return (0);
1989 }
1990
1991 /* ARGSUSED */
1992 int
1993 OP_T (dummy)
1994      int dummy;
1995 {
1996   codep++; /* skip mod/rm */
1997   sprintf (scratchbuf, "%%tr%d", reg);
1998   oappend (scratchbuf);
1999   return (0);
2000 }
2001
2002 int
2003 OP_rm (bytemode)
2004      int bytemode;
2005 {
2006   switch (bytemode) 
2007     {
2008     case d_mode:
2009       oappend (names32[rm]);
2010       break;
2011     case w_mode:
2012       oappend (names16[rm]);
2013       break;
2014     }
2015   return (0);
2016 }
This page took 0.136261 seconds and 4 git commands to generate.