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