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