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