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