Statistics
| Branch: | Revision:

root / i386-dis.c @ 3ef693a0

History | View | Annotate | Download (44.6 kB)

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

    
38
#define MAXLEN 20
39

    
40
#include <setjmp.h>
41

    
42
static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
43

    
44
struct dis_private
45
{
46
  /* Points to first byte not fetched.  */
47
  bfd_byte *max_fetched;
48
  bfd_byte the_buffer[MAXLEN];
49
  bfd_vma insn_start;
50
  jmp_buf bailout;
51
};
52

    
53
/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
54
   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
55
   on error.  */
56
#define FETCH_DATA(info, addr) \
57
  ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
58
   ? 1 : fetch_data ((info), (addr)))
59

    
60
static int
61
fetch_data (info, addr)
62
     struct disassemble_info *info;
63
     bfd_byte *addr;
64
{
65
  int status;
66
  struct dis_private *priv = (struct dis_private *)info->private_data;
67
  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
68

    
69
  status = (*info->read_memory_func) (start,
70
                                      priv->max_fetched,
71
                                      addr - priv->max_fetched,
72
                                      info);
73
  if (status != 0)
74
    {
75
      (*info->memory_error_func) (status, start, info);
76
      longjmp (priv->bailout, 1);
77
    }
78
  else
79
    priv->max_fetched = addr;
80
  return 1;
81
}
82

    
83
#define Eb OP_E, b_mode
84
#define indirEb OP_indirE, b_mode
85
#define Gb OP_G, b_mode
86
#define Ev OP_E, v_mode
87
#define indirEv OP_indirE, v_mode
88
#define Ew OP_E, w_mode
89
#define Ma OP_E, v_mode
90
#define M OP_E, 0
91
#define Mp OP_E, 0                /* ? */
92
#define Gv OP_G, v_mode
93
#define Gw OP_G, w_mode
94
#define Rw OP_rm, w_mode
95
#define Rd OP_rm, d_mode
96
#define Ib OP_I, b_mode
97
#define sIb OP_sI, b_mode        /* sign extened byte */
98
#define Iv OP_I, v_mode
99
#define Iw OP_I, w_mode
100
#define Jb OP_J, b_mode
101
#define Jv OP_J, v_mode
102
#if 0
103
#define ONE OP_ONE, 0
104
#endif
105
#define Cd OP_C, d_mode
106
#define Dd OP_D, d_mode
107
#define Td OP_T, d_mode
108

    
109
#define eAX OP_REG, eAX_reg
110
#define eBX OP_REG, eBX_reg
111
#define eCX OP_REG, eCX_reg
112
#define eDX OP_REG, eDX_reg
113
#define eSP OP_REG, eSP_reg
114
#define eBP OP_REG, eBP_reg
115
#define eSI OP_REG, eSI_reg
116
#define eDI OP_REG, eDI_reg
117
#define AL OP_REG, al_reg
118
#define CL OP_REG, cl_reg
119
#define DL OP_REG, dl_reg
120
#define BL OP_REG, bl_reg
121
#define AH OP_REG, ah_reg
122
#define CH OP_REG, ch_reg
123
#define DH OP_REG, dh_reg
124
#define BH OP_REG, bh_reg
125
#define AX OP_REG, ax_reg
126
#define DX OP_REG, dx_reg
127
#define indirDX OP_REG, indir_dx_reg
128

    
129
#define Sw OP_SEG, w_mode
130
#define Ap OP_DIR, lptr
131
#define Av OP_DIR, v_mode
132
#define Ob OP_OFF, b_mode
133
#define Ov OP_OFF, v_mode
134
#define Xb OP_DSSI, b_mode
135
#define Xv OP_DSSI, v_mode
136
#define Yb OP_ESDI, b_mode
137
#define Yv OP_ESDI, v_mode
138

    
139
#define es OP_REG, es_reg
140
#define ss OP_REG, ss_reg
141
#define cs OP_REG, cs_reg
142
#define ds OP_REG, ds_reg
143
#define fs OP_REG, fs_reg
144
#define gs OP_REG, gs_reg
145

    
146
#define MX OP_MMX, 0
147
#define EM OP_EM, v_mode
148
#define MS OP_MS, b_mode
149

    
150
typedef int (*op_rtn) PARAMS ((int bytemode, int aflag, int dflag));
151

    
152
static int OP_E PARAMS ((int, int, int));
153
static int OP_G PARAMS ((int, int, int));
154
static int OP_I PARAMS ((int, int, int));
155
static int OP_indirE PARAMS ((int, int, int));
156
static int OP_sI PARAMS ((int, int, int));
157
static int OP_REG PARAMS ((int, int, int));
158
static int OP_J PARAMS ((int, int, int));
159
static int OP_DIR PARAMS ((int, int, int));
160
static int OP_OFF PARAMS ((int, int, int));
161
static int OP_ESDI PARAMS ((int, int, int));
162
static int OP_DSSI PARAMS ((int, int, int));
163
static int OP_SEG PARAMS ((int, int, int));
164
static int OP_C PARAMS ((int, int, int));
165
static int OP_D PARAMS ((int, int, int));
166
static int OP_T PARAMS ((int, int, int));
167
static int OP_rm PARAMS ((int, int, int));
168
static int OP_ST PARAMS ((int, int, int));
169
static int OP_STi  PARAMS ((int, int, int));
170
#if 0
171
static int OP_ONE PARAMS ((int, int, int));
172
#endif
173
static int OP_MMX PARAMS ((int, int, int));
174
static int OP_EM PARAMS ((int, int, int));
175
static int OP_MS PARAMS ((int, int, int));
176

    
177
static void append_prefix PARAMS ((void));
178
static void set_op PARAMS ((int op));
179
static void putop PARAMS ((char *template, int aflag, int dflag));
180
static void dofloat PARAMS ((int aflag, int dflag));
181
static int get16 PARAMS ((void));
182
static int get32 PARAMS ((void));
183
static void ckprefix PARAMS ((void));
184

    
185
#define b_mode 1
186
#define v_mode 2
187
#define w_mode 3
188
#define d_mode 4
189

    
190
#define es_reg 100
191
#define cs_reg 101
192
#define ss_reg 102
193
#define ds_reg 103
194
#define fs_reg 104
195
#define gs_reg 105
196
#define eAX_reg 107
197
#define eCX_reg 108
198
#define eDX_reg 109
199
#define eBX_reg 110
200
#define eSP_reg 111
201
#define eBP_reg 112
202
#define eSI_reg 113
203
#define eDI_reg 114
204

    
205
#define lptr 115
206

    
207
#define al_reg 116
208
#define cl_reg 117
209
#define dl_reg 118
210
#define bl_reg 119
211
#define ah_reg 120
212
#define ch_reg 121
213
#define dh_reg 122
214
#define bh_reg 123
215

    
216
#define ax_reg 124
217
#define cx_reg 125
218
#define dx_reg 126
219
#define bx_reg 127
220
#define sp_reg 128
221
#define bp_reg 129
222
#define si_reg 130
223
#define di_reg 131
224

    
225
#define indir_dx_reg 150
226

    
227
#define GRP1b NULL, NULL, 0
228
#define GRP1S NULL, NULL, 1
229
#define GRP1Ss NULL, NULL, 2
230
#define GRP2b NULL, NULL, 3
231
#define GRP2S NULL, NULL, 4
232
#define GRP2b_one NULL, NULL, 5
233
#define GRP2S_one NULL, NULL, 6
234
#define GRP2b_cl NULL, NULL, 7
235
#define GRP2S_cl NULL, NULL, 8
236
#define GRP3b NULL, NULL, 9
237
#define GRP3S NULL, NULL, 10
238
#define GRP4  NULL, NULL, 11
239
#define GRP5  NULL, NULL, 12
240
#define GRP6  NULL, NULL, 13
241
#define GRP7 NULL, NULL, 14
242
#define GRP8 NULL, NULL, 15
243
#define GRP9 NULL, NULL, 16
244
#define GRP10 NULL, NULL, 17
245
#define GRP11 NULL, NULL, 18
246
#define GRP12 NULL, NULL, 19
247

    
248
#define FLOATCODE 50
249
#define FLOAT NULL, NULL, FLOATCODE
250

    
251
struct dis386 {
252
  char *name;
253
  op_rtn op1;
254
  int bytemode1;
255
  op_rtn op2;
256
  int bytemode2;
257
  op_rtn op3;
258
  int bytemode3;
259
};
260

    
261
static struct dis386 dis386[] = {
262
  /* 00 */
263
  { "addb",        Eb, Gb },
264
  { "addS",        Ev, Gv },
265
  { "addb",        Gb, Eb },
266
  { "addS",        Gv, Ev },
267
  { "addb",        AL, Ib },
268
  { "addS",        eAX, Iv },
269
  { "pushS",        es },
270
  { "popS",        es },
271
  /* 08 */
272
  { "orb",        Eb, Gb },
273
  { "orS",        Ev, Gv },
274
  { "orb",        Gb, Eb },
275
  { "orS",        Gv, Ev },
276
  { "orb",        AL, Ib },
277
  { "orS",        eAX, Iv },
278
  { "pushS",        cs },
279
  { "(bad)" },        /* 0x0f extended opcode escape */
280
  /* 10 */
281
  { "adcb",        Eb, Gb },
282
  { "adcS",        Ev, Gv },
283
  { "adcb",        Gb, Eb },
284
  { "adcS",        Gv, Ev },
285
  { "adcb",        AL, Ib },
286
  { "adcS",        eAX, Iv },
287
  { "pushS",        ss },
288
  { "popS",        ss },
289
  /* 18 */
290
  { "sbbb",        Eb, Gb },
291
  { "sbbS",        Ev, Gv },
292
  { "sbbb",        Gb, Eb },
293
  { "sbbS",        Gv, Ev },
294
  { "sbbb",        AL, Ib },
295
  { "sbbS",        eAX, Iv },
296
  { "pushS",        ds },
297
  { "popS",        ds },
298
  /* 20 */
299
  { "andb",        Eb, Gb },
300
  { "andS",        Ev, Gv },
301
  { "andb",        Gb, Eb },
302
  { "andS",        Gv, Ev },
303
  { "andb",        AL, Ib },
304
  { "andS",        eAX, Iv },
305
  { "(bad)" },                        /* SEG ES prefix */
306
  { "daa" },
307
  /* 28 */
308
  { "subb",        Eb, Gb },
309
  { "subS",        Ev, Gv },
310
  { "subb",        Gb, Eb },
311
  { "subS",        Gv, Ev },
312
  { "subb",        AL, Ib },
313
  { "subS",        eAX, Iv },
314
  { "(bad)" },                        /* SEG CS prefix */
315
  { "das" },
316
  /* 30 */
317
  { "xorb",        Eb, Gb },
318
  { "xorS",        Ev, Gv },
319
  { "xorb",        Gb, Eb },
320
  { "xorS",        Gv, Ev },
321
  { "xorb",        AL, Ib },
322
  { "xorS",        eAX, Iv },
323
  { "(bad)" },                        /* SEG SS prefix */
324
  { "aaa" },
325
  /* 38 */
326
  { "cmpb",        Eb, Gb },
327
  { "cmpS",        Ev, Gv },
328
  { "cmpb",        Gb, Eb },
329
  { "cmpS",        Gv, Ev },
330
  { "cmpb",        AL, Ib },
331
  { "cmpS",        eAX, Iv },
332
  { "(bad)" },                        /* SEG DS prefix */
333
  { "aas" },
334
  /* 40 */
335
  { "incS",        eAX },
336
  { "incS",        eCX },
337
  { "incS",        eDX },
338
  { "incS",        eBX },
339
  { "incS",        eSP },
340
  { "incS",        eBP },
341
  { "incS",        eSI },
342
  { "incS",        eDI },
343
  /* 48 */
344
  { "decS",        eAX },
345
  { "decS",        eCX },
346
  { "decS",        eDX },
347
  { "decS",        eBX },
348
  { "decS",        eSP },
349
  { "decS",        eBP },
350
  { "decS",        eSI },
351
  { "decS",        eDI },
352
  /* 50 */
353
  { "pushS",        eAX },
354
  { "pushS",        eCX },
355
  { "pushS",        eDX },
356
  { "pushS",        eBX },
357
  { "pushS",        eSP },
358
  { "pushS",        eBP },
359
  { "pushS",        eSI },
360
  { "pushS",        eDI },
361
  /* 58 */
362
  { "popS",        eAX },
363
  { "popS",        eCX },
364
  { "popS",        eDX },
365
  { "popS",        eBX },
366
  { "popS",        eSP },
367
  { "popS",        eBP },
368
  { "popS",        eSI },
369
  { "popS",        eDI },
370
  /* 60 */
371
  { "pusha" },
372
  { "popa" },
373
  { "boundS",        Gv, Ma },
374
  { "arpl",        Ew, Gw },
375
  { "(bad)" },                        /* seg fs */
376
  { "(bad)" },                        /* seg gs */
377
  { "(bad)" },                        /* op size prefix */
378
  { "(bad)" },                        /* adr size prefix */
379
  /* 68 */
380
  { "pushS",        Iv },                /* 386 book wrong */
381
  { "imulS",        Gv, Ev, Iv },
382
  { "pushS",        sIb },                /* push of byte really pushes 2 or 4 bytes */
383
  { "imulS",        Gv, Ev, Ib },
384
  { "insb",        Yb, indirDX },
385
  { "insS",        Yv, indirDX },
386
  { "outsb",        indirDX, Xb },
387
  { "outsS",        indirDX, Xv },
388
  /* 70 */
389
  { "jo",        Jb },
390
  { "jno",        Jb },
391
  { "jb",        Jb },
392
  { "jae",        Jb },
393
  { "je",        Jb },
394
  { "jne",        Jb },
395
  { "jbe",        Jb },
396
  { "ja",        Jb },
397
  /* 78 */
398
  { "js",        Jb },
399
  { "jns",        Jb },
400
  { "jp",        Jb },
401
  { "jnp",        Jb },
402
  { "jl",        Jb },
403
  { "jnl",        Jb },
404
  { "jle",        Jb },
405
  { "jg",        Jb },
406
  /* 80 */
407
  { GRP1b },
408
  { GRP1S },
409
  { "(bad)" },
410
  { GRP1Ss },
411
  { "testb",        Eb, Gb },
412
  { "testS",        Ev, Gv },
413
  { "xchgb",        Eb, Gb },
414
  { "xchgS",        Ev, Gv },
415
  /* 88 */
416
  { "movb",        Eb, Gb },
417
  { "movS",        Ev, Gv },
418
  { "movb",        Gb, Eb },
419
  { "movS",        Gv, Ev },
420
  { "movS",        Ev, Sw },
421
  { "leaS",        Gv, M },
422
  { "movS",        Sw, Ev },
423
  { "popS",        Ev },
424
  /* 90 */
425
  { "nop" },
426
  { "xchgS",        eCX, eAX },
427
  { "xchgS",        eDX, eAX },
428
  { "xchgS",        eBX, eAX },
429
  { "xchgS",        eSP, eAX },
430
  { "xchgS",        eBP, eAX },
431
  { "xchgS",        eSI, eAX },
432
  { "xchgS",        eDI, eAX },
433
  /* 98 */
434
  { "cWtS" },
435
  { "cStd" },
436
  { "lcall",        Ap },
437
  { "(bad)" },                /* fwait */
438
  { "pushf" },
439
  { "popf" },
440
  { "sahf" },
441
  { "lahf" },
442
  /* a0 */
443
  { "movb",        AL, Ob },
444
  { "movS",        eAX, Ov },
445
  { "movb",        Ob, AL },
446
  { "movS",        Ov, eAX },
447
  { "movsb",        Yb, Xb },
448
  { "movsS",        Yv, Xv },
449
  { "cmpsb",        Yb, Xb },
450
  { "cmpsS",        Yv, Xv },
451
  /* a8 */
452
  { "testb",        AL, Ib },
453
  { "testS",        eAX, Iv },
454
  { "stosb",        Yb, AL },
455
  { "stosS",        Yv, eAX },
456
  { "lodsb",        AL, Xb },
457
  { "lodsS",        eAX, Xv },
458
  { "scasb",        AL, Yb },
459
  { "scasS",        eAX, Yv },
460
  /* b0 */
461
  { "movb",        AL, Ib },
462
  { "movb",        CL, Ib },
463
  { "movb",        DL, Ib },
464
  { "movb",        BL, Ib },
465
  { "movb",        AH, Ib },
466
  { "movb",        CH, Ib },
467
  { "movb",        DH, Ib },
468
  { "movb",        BH, Ib },
469
  /* b8 */
470
  { "movS",        eAX, Iv },
471
  { "movS",        eCX, Iv },
472
  { "movS",        eDX, Iv },
473
  { "movS",        eBX, Iv },
474
  { "movS",        eSP, Iv },
475
  { "movS",        eBP, Iv },
476
  { "movS",        eSI, Iv },
477
  { "movS",        eDI, Iv },
478
  /* c0 */
479
  { GRP2b },
480
  { GRP2S },
481
  { "ret",        Iw },
482
  { "ret" },
483
  { "lesS",        Gv, Mp },
484
  { "ldsS",        Gv, Mp },
485
  { "movb",        Eb, Ib },
486
  { "movS",        Ev, Iv },
487
  /* c8 */
488
  { "enter",        Iw, Ib },
489
  { "leave" },
490
  { "lret",        Iw },
491
  { "lret" },
492
  { "int3" },
493
  { "int",        Ib },
494
  { "into" },
495
  { "iret" },
496
  /* d0 */
497
  { GRP2b_one },
498
  { GRP2S_one },
499
  { GRP2b_cl },
500
  { GRP2S_cl },
501
  { "aam",        Ib },
502
  { "aad",        Ib },
503
  { "(bad)" },
504
  { "xlat" },
505
  /* d8 */
506
  { FLOAT },
507
  { FLOAT },
508
  { FLOAT },
509
  { FLOAT },
510
  { FLOAT },
511
  { FLOAT },
512
  { FLOAT },
513
  { FLOAT },
514
  /* e0 */
515
  { "loopne",        Jb },
516
  { "loope",        Jb },
517
  { "loop",        Jb },
518
  { "jCcxz",        Jb },
519
  { "inb",        AL, Ib },
520
  { "inS",        eAX, Ib },
521
  { "outb",        Ib, AL },
522
  { "outS",        Ib, eAX },
523
  /* e8 */
524
  { "call",        Av },
525
  { "jmp",        Jv },
526
  { "ljmp",        Ap },
527
  { "jmp",        Jb },
528
  { "inb",        AL, indirDX },
529
  { "inS",        eAX, indirDX },
530
  { "outb",        indirDX, AL },
531
  { "outS",        indirDX, eAX },
532
  /* f0 */
533
  { "(bad)" },                        /* lock prefix */
534
  { "(bad)" },
535
  { "(bad)" },                        /* repne */
536
  { "(bad)" },                        /* repz */
537
  { "hlt" },
538
  { "cmc" },
539
  { GRP3b },
540
  { GRP3S },
541
  /* f8 */
542
  { "clc" },
543
  { "stc" },
544
  { "cli" },
545
  { "sti" },
546
  { "cld" },
547
  { "std" },
548
  { GRP4 },
549
  { GRP5 },
550
};
551

    
552
static struct dis386 dis386_twobyte[] = {
553
  /* 00 */
554
  { GRP6 },
555
  { GRP7 },
556
  { "larS", Gv, Ew },
557
  { "lslS", Gv, Ew },  
558
  { "(bad)" },
559
  { "(bad)" },
560
  { "clts" },
561
  { "(bad)" },  
562
  /* 08 */
563
  { "invd" },
564
  { "wbinvd" },
565
  { "(bad)" },  { "ud2a" },  
566
  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
567
  /* 10 */
568
  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
569
  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
570
  /* 18 */
571
  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
572
  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
573
  /* 20 */
574
  /* these are all backward in appendix A of the intel book */
575
  { "movl", Rd, Cd },
576
  { "movl", Rd, Dd },
577
  { "movl", Cd, Rd },
578
  { "movl", Dd, Rd },  
579
  { "movl", Rd, Td },
580
  { "(bad)" },
581
  { "movl", Td, Rd },
582
  { "(bad)" },  
583
  /* 28 */
584
  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
585
  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
586
  /* 30 */
587
  { "wrmsr" },  { "rdtsc" },  { "rdmsr" },  { "rdpmc" },  
588
  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
589
  /* 38 */
590
  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
591
  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
592
  /* 40 */
593
  { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
594
  { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
595
  /* 48 */
596
  { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
597
  { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },  
598
  /* 50 */
599
  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
600
  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
601
  /* 58 */
602
  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
603
  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
604
  /* 60 */
605
  { "punpcklbw", MX, EM },
606
  { "punpcklwd", MX, EM },
607
  { "punpckldq", MX, EM },
608
  { "packsswb", MX, EM },
609
  { "pcmpgtb", MX, EM },
610
  { "pcmpgtw", MX, EM },
611
  { "pcmpgtd", MX, EM },
612
  { "packuswb", MX, EM },
613
  /* 68 */
614
  { "punpckhbw", MX, EM },
615
  { "punpckhwd", MX, EM },
616
  { "punpckhdq", MX, EM },
617
  { "packssdw", MX, EM },
618
  { "(bad)" },  { "(bad)" },
619
  { "movd", MX, Ev },
620
  { "movq", MX, EM },
621
  /* 70 */
622
  { "(bad)" },
623
  { GRP10 },
624
  { GRP11 },
625
  { GRP12 },
626
  { "pcmpeqb", MX, EM },
627
  { "pcmpeqw", MX, EM },
628
  { "pcmpeqd", MX, EM },
629
  { "emms" },
630
  /* 78 */
631
  { "(bad)" },  { "(bad)" },  { "(bad)" },  { "(bad)" },  
632
  { "(bad)" },  { "(bad)" },
633
  { "movd", Ev, MX },
634
  { "movq", EM, MX },
635
  /* 80 */
636
  { "jo", Jv },
637
  { "jno", Jv },
638
  { "jb", Jv },
639
  { "jae", Jv },  
640
  { "je", Jv },
641
  { "jne", Jv },
642
  { "jbe", Jv },
643
  { "ja", Jv },  
644
  /* 88 */
645
  { "js", Jv },
646
  { "jns", Jv },
647
  { "jp", Jv },
648
  { "jnp", Jv },  
649
  { "jl", Jv },
650
  { "jge", Jv },
651
  { "jle", Jv },
652
  { "jg", Jv },  
653
  /* 90 */
654
  { "seto", Eb },
655
  { "setno", Eb },
656
  { "setb", Eb },
657
  { "setae", Eb },
658
  { "sete", Eb },
659
  { "setne", Eb },
660
  { "setbe", Eb },
661
  { "seta", Eb },
662
  /* 98 */
663
  { "sets", Eb },
664
  { "setns", Eb },
665
  { "setp", Eb },
666
  { "setnp", Eb },
667
  { "setl", Eb },
668
  { "setge", Eb },
669
  { "setle", Eb },
670
  { "setg", Eb },  
671
  /* a0 */
672
  { "pushS", fs },
673
  { "popS", fs },
674
  { "cpuid" },
675
  { "btS", Ev, Gv },  
676
  { "shldS", Ev, Gv, Ib },
677
  { "shldS", Ev, Gv, CL },
678
  { "(bad)" },
679
  { "(bad)" },  
680
  /* a8 */
681
  { "pushS", gs },
682
  { "popS", gs },
683
  { "rsm" },
684
  { "btsS", Ev, Gv },  
685
  { "shrdS", Ev, Gv, Ib },
686
  { "shrdS", Ev, Gv, CL },
687
  { "(bad)" },
688
  { "imulS", Gv, Ev },  
689
  /* b0 */
690
  { "cmpxchgb", Eb, Gb },
691
  { "cmpxchgS", Ev, Gv },
692
  { "lssS", Gv, Mp },        /* 386 lists only Mp */
693
  { "btrS", Ev, Gv },  
694
  { "lfsS", Gv, Mp },        /* 386 lists only Mp */
695
  { "lgsS", Gv, Mp },        /* 386 lists only Mp */
696
  { "movzbS", Gv, Eb },
697
  { "movzwS", Gv, Ew },  
698
  /* b8 */
699
  { "ud2b" },
700
  { "(bad)" },
701
  { GRP8 },
702
  { "btcS", Ev, Gv },  
703
  { "bsfS", Gv, Ev },
704
  { "bsrS", Gv, Ev },
705
  { "movsbS", Gv, Eb },
706
  { "movswS", Gv, Ew },  
707
  /* c0 */
708
  { "xaddb", Eb, Gb },
709
  { "xaddS", Ev, Gv },
710
  { "(bad)" },
711
  { "(bad)" },  
712
  { "(bad)" },
713
  { "(bad)" },
714
  { "(bad)" },
715
  { GRP9 },  
716
  /* c8 */
717
  { "bswap", eAX },
718
  { "bswap", eCX },
719
  { "bswap", eDX },
720
  { "bswap", eBX },
721
  { "bswap", eSP },
722
  { "bswap", eBP },
723
  { "bswap", eSI },
724
  { "bswap", eDI },
725
  /* d0 */
726
  { "(bad)" },
727
  { "psrlw", MX, EM },
728
  { "psrld", MX, EM },
729
  { "psrlq", MX, EM },
730
  { "(bad)" },
731
  { "pmullw", MX, EM },
732
  { "(bad)" },  { "(bad)" },  
733
  /* d8 */
734
  { "psubusb", MX, EM },
735
  { "psubusw", MX, EM },
736
  { "(bad)" },
737
  { "pand", MX, EM },
738
  { "paddusb", MX, EM },
739
  { "paddusw", MX, EM },
740
  { "(bad)" },
741
  { "pandn", MX, EM },
742
  /* e0 */
743
  { "(bad)" },
744
  { "psraw", MX, EM },
745
  { "psrad", MX, EM },
746
  { "(bad)" },
747
  { "(bad)" },
748
  { "pmulhw", MX, EM },
749
  { "(bad)" },  { "(bad)" },  
750
  /* e8 */
751
  { "psubsb", MX, EM },
752
  { "psubsw", MX, EM },
753
  { "(bad)" },
754
  { "por", MX, EM },
755
  { "paddsb", MX, EM },
756
  { "paddsw", MX, EM },
757
  { "(bad)" },
758
  { "pxor", MX, EM },
759
  /* f0 */
760
  { "(bad)" },
761
  { "psllw", MX, EM },
762
  { "pslld", MX, EM },
763
  { "psllq", MX, EM },
764
  { "(bad)" },
765
  { "pmaddwd", MX, EM },
766
  { "(bad)" },  { "(bad)" },  
767
  /* f8 */
768
  { "psubb", MX, EM },
769
  { "psubw", MX, EM },
770
  { "psubd", MX, EM },
771
  { "(bad)" },  
772
  { "paddb", MX, EM },
773
  { "paddw", MX, EM },
774
  { "paddd", MX, EM },
775
  { "(bad)" }
776
};
777

    
778
static const unsigned char onebyte_has_modrm[256] = {
779
  1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
780
  1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
781
  1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
782
  1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
783
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
784
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
785
  0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
786
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
787
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
788
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
789
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
790
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
791
  1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
792
  1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
793
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
794
  0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
795
};
796

    
797
static const unsigned char twobyte_has_modrm[256] = {
798
  /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
799
  /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
800
  /* 20 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 2f */
801
  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
802
  /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
803
  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
804
  /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
805
  /* 70 */ 0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
806
  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
807
  /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
808
  /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
809
  /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
810
  /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
811
  /* d0 */ 0,1,1,1,0,1,0,0,1,1,0,1,1,1,0,1, /* df */
812
  /* e0 */ 0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,1, /* ef */
813
  /* f0 */ 0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0  /* ff */
814
};
815

    
816
static char obuf[100];
817
static char *obufp;
818
static char scratchbuf[100];
819
static unsigned char *start_codep;
820
static unsigned char *codep;
821
static disassemble_info *the_info;
822
static int mod;
823
static int rm;
824
static int reg;
825
static void oappend PARAMS ((char *s));
826

    
827
static char *names32[]={
828
  "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
829
};
830
static char *names16[] = {
831
  "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
832
};
833
static char *names8[] = {
834
  "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
835
};
836
static char *names_seg[] = {
837
  "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
838
};
839
static char *index16[] = {
840
  "bx+si","bx+di","bp+si","bp+di","si","di","bp","bx"
841
};
842

    
843
static struct dis386 grps[][8] = {
844
  /* GRP1b */
845
  {
846
    { "addb",        Eb, Ib },
847
    { "orb",        Eb, Ib },
848
    { "adcb",        Eb, Ib },
849
    { "sbbb",        Eb, Ib },
850
    { "andb",        Eb, Ib },
851
    { "subb",        Eb, Ib },
852
    { "xorb",        Eb, Ib },
853
    { "cmpb",        Eb, Ib }
854
  },
855
  /* GRP1S */
856
  {
857
    { "addS",        Ev, Iv },
858
    { "orS",        Ev, Iv },
859
    { "adcS",        Ev, Iv },
860
    { "sbbS",        Ev, Iv },
861
    { "andS",        Ev, Iv },
862
    { "subS",        Ev, Iv },
863
    { "xorS",        Ev, Iv },
864
    { "cmpS",        Ev, Iv }
865
  },
866
  /* GRP1Ss */
867
  {
868
    { "addS",        Ev, sIb },
869
    { "orS",        Ev, sIb },
870
    { "adcS",        Ev, sIb },
871
    { "sbbS",        Ev, sIb },
872
    { "andS",        Ev, sIb },
873
    { "subS",        Ev, sIb },
874
    { "xorS",        Ev, sIb },
875
    { "cmpS",        Ev, sIb }
876
  },
877
  /* GRP2b */
878
  {
879
    { "rolb",        Eb, Ib },
880
    { "rorb",        Eb, Ib },
881
    { "rclb",        Eb, Ib },
882
    { "rcrb",        Eb, Ib },
883
    { "shlb",        Eb, Ib },
884
    { "shrb",        Eb, Ib },
885
    { "(bad)" },
886
    { "sarb",        Eb, Ib },
887
  },
888
  /* GRP2S */
889
  {
890
    { "rolS",        Ev, Ib },
891
    { "rorS",        Ev, Ib },
892
    { "rclS",        Ev, Ib },
893
    { "rcrS",        Ev, Ib },
894
    { "shlS",        Ev, Ib },
895
    { "shrS",        Ev, Ib },
896
    { "(bad)" },
897
    { "sarS",        Ev, Ib },
898
  },
899
  /* GRP2b_one */
900
  {
901
    { "rolb",        Eb },
902
    { "rorb",        Eb },
903
    { "rclb",        Eb },
904
    { "rcrb",        Eb },
905
    { "shlb",        Eb },
906
    { "shrb",        Eb },
907
    { "(bad)" },
908
    { "sarb",        Eb },
909
  },
910
  /* GRP2S_one */
911
  {
912
    { "rolS",        Ev },
913
    { "rorS",        Ev },
914
    { "rclS",        Ev },
915
    { "rcrS",        Ev },
916
    { "shlS",        Ev },
917
    { "shrS",        Ev },
918
    { "(bad)" },
919
    { "sarS",        Ev },
920
  },
921
  /* GRP2b_cl */
922
  {
923
    { "rolb",        Eb, CL },
924
    { "rorb",        Eb, CL },
925
    { "rclb",        Eb, CL },
926
    { "rcrb",        Eb, CL },
927
    { "shlb",        Eb, CL },
928
    { "shrb",        Eb, CL },
929
    { "(bad)" },
930
    { "sarb",        Eb, CL },
931
  },
932
  /* GRP2S_cl */
933
  {
934
    { "rolS",        Ev, CL },
935
    { "rorS",        Ev, CL },
936
    { "rclS",        Ev, CL },
937
    { "rcrS",        Ev, CL },
938
    { "shlS",        Ev, CL },
939
    { "shrS",        Ev, CL },
940
    { "(bad)" },
941
    { "sarS",        Ev, CL }
942
  },
943
  /* GRP3b */
944
  {
945
    { "testb",        Eb, Ib },
946
    { "(bad)",        Eb },
947
    { "notb",        Eb },
948
    { "negb",        Eb },
949
    { "mulb",        AL, Eb },
950
    { "imulb",        AL, Eb },
951
    { "divb",        AL, Eb },
952
    { "idivb",        AL, Eb }
953
  },
954
  /* GRP3S */
955
  {
956
    { "testS",        Ev, Iv },
957
    { "(bad)" },
958
    { "notS",        Ev },
959
    { "negS",        Ev },
960
    { "mulS",        eAX, Ev },
961
    { "imulS",        eAX, Ev },
962
    { "divS",        eAX, Ev },
963
    { "idivS",        eAX, Ev },
964
  },
965
  /* GRP4 */
966
  {
967
    { "incb", Eb },
968
    { "decb", Eb },
969
    { "(bad)" },
970
    { "(bad)" },
971
    { "(bad)" },
972
    { "(bad)" },
973
    { "(bad)" },
974
    { "(bad)" },
975
  },
976
  /* GRP5 */
977
  {
978
    { "incS",        Ev },
979
    { "decS",        Ev },
980
    { "call",        indirEv },
981
    { "lcall",        indirEv },
982
    { "jmp",        indirEv },
983
    { "ljmp",        indirEv },
984
    { "pushS",        Ev },
985
    { "(bad)" },
986
  },
987
  /* GRP6 */
988
  {
989
    { "sldt",        Ew },
990
    { "str",        Ew },
991
    { "lldt",        Ew },
992
    { "ltr",        Ew },
993
    { "verr",        Ew },
994
    { "verw",        Ew },
995
    { "(bad)" },
996
    { "(bad)" }
997
  },
998
  /* GRP7 */
999
  {
1000
    { "sgdt", Ew },
1001
    { "sidt", Ew },
1002
    { "lgdt", Ew },
1003
    { "lidt", Ew },
1004
    { "smsw", Ew },
1005
    { "(bad)" },
1006
    { "lmsw", Ew },
1007
    { "invlpg", Ew },
1008
  },
1009
  /* GRP8 */
1010
  {
1011
    { "(bad)" },
1012
    { "(bad)" },
1013
    { "(bad)" },
1014
    { "(bad)" },
1015
    { "btS",        Ev, Ib },
1016
    { "btsS",        Ev, Ib },
1017
    { "btrS",        Ev, Ib },
1018
    { "btcS",        Ev, Ib },
1019
  },
1020
  /* GRP9 */
1021
  {
1022
    { "(bad)" },
1023
    { "cmpxchg8b", Ev },
1024
    { "(bad)" },
1025
    { "(bad)" },
1026
    { "(bad)" },
1027
    { "(bad)" },
1028
    { "(bad)" },
1029
    { "(bad)" },
1030
  },
1031
  /* GRP10 */
1032
  {
1033
    { "(bad)" },
1034
    { "(bad)" },
1035
    { "psrlw", MS, Ib },
1036
    { "(bad)" },
1037
    { "psraw", MS, Ib },
1038
    { "(bad)" },
1039
    { "psllw", MS, Ib },
1040
    { "(bad)" },
1041
  },
1042
  /* GRP11 */
1043
  {
1044
    { "(bad)" },
1045
    { "(bad)" },
1046
    { "psrld", MS, Ib },
1047
    { "(bad)" },
1048
    { "psrad", MS, Ib },
1049
    { "(bad)" },
1050
    { "pslld", MS, Ib },
1051
    { "(bad)" },
1052
  },
1053
  /* GRP12 */
1054
  {
1055
    { "(bad)" },
1056
    { "(bad)" },
1057
    { "psrlq", MS, Ib },
1058
    { "(bad)" },
1059
    { "(bad)" },
1060
    { "(bad)" },
1061
    { "psllq", MS, Ib },
1062
    { "(bad)" },
1063
  }
1064
};
1065

    
1066
#define PREFIX_REPZ 1
1067
#define PREFIX_REPNZ 2
1068
#define PREFIX_LOCK 4
1069
#define PREFIX_CS 8
1070
#define PREFIX_SS 0x10
1071
#define PREFIX_DS 0x20
1072
#define PREFIX_ES 0x40
1073
#define PREFIX_FS 0x80
1074
#define PREFIX_GS 0x100
1075
#define PREFIX_DATA 0x200
1076
#define PREFIX_ADR 0x400
1077
#define PREFIX_FWAIT 0x800
1078

    
1079
static int prefixes;
1080

    
1081
static void
1082
ckprefix ()
1083
{
1084
  prefixes = 0;
1085
  while (1)
1086
    {
1087
      FETCH_DATA (the_info, codep + 1);
1088
      switch (*codep)
1089
        {
1090
        case 0xf3:
1091
          prefixes |= PREFIX_REPZ;
1092
          break;
1093
        case 0xf2:
1094
          prefixes |= PREFIX_REPNZ;
1095
          break;
1096
        case 0xf0:
1097
          prefixes |= PREFIX_LOCK;
1098
          break;
1099
        case 0x2e:
1100
          prefixes |= PREFIX_CS;
1101
          break;
1102
        case 0x36:
1103
          prefixes |= PREFIX_SS;
1104
          break;
1105
        case 0x3e:
1106
          prefixes |= PREFIX_DS;
1107
          break;
1108
        case 0x26:
1109
          prefixes |= PREFIX_ES;
1110
          break;
1111
        case 0x64:
1112
          prefixes |= PREFIX_FS;
1113
          break;
1114
        case 0x65:
1115
          prefixes |= PREFIX_GS;
1116
          break;
1117
        case 0x66:
1118
          prefixes |= PREFIX_DATA;
1119
          break;
1120
        case 0x67:
1121
          prefixes |= PREFIX_ADR;
1122
          break;
1123
        case 0x9b:
1124
          prefixes |= PREFIX_FWAIT;
1125
          break;
1126
        default:
1127
          return;
1128
        }
1129
      codep++;
1130
    }
1131
}
1132

    
1133
static char op1out[100], op2out[100], op3out[100];
1134
static int op_address[3], op_ad, op_index[3];
1135
static int start_pc;
1136

    
1137
 
1138
/*
1139
 *   On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1140
 *   (see topic "Redundant prefixes" in the "Differences from 8086"
1141
 *   section of the "Virtual 8086 Mode" chapter.)
1142
 * 'pc' should be the address of this instruction, it will
1143
 *   be used to print the target address if this is a relative jump or call
1144
 * The function returns the length of this instruction in bytes.
1145
 */
1146

    
1147
int print_insn_x86 PARAMS ((bfd_vma pc, disassemble_info *info, int aflag,
1148
                            int dflag));
1149
int
1150
print_insn_i386 (pc, info)
1151
     bfd_vma pc;
1152
     disassemble_info *info;
1153
{
1154
  if (info->mach == bfd_mach_i386_i386)
1155
    return print_insn_x86 (pc, info, 1, 1);
1156
  else if (info->mach == bfd_mach_i386_i8086)
1157
    return print_insn_x86 (pc, info, 0, 0);
1158
  else
1159
    abort ();
1160
}
1161

    
1162
int
1163
print_insn_x86 (pc, info, aflag, dflag)
1164
     bfd_vma pc;
1165
     disassemble_info *info;
1166
     int aflag;
1167
     int dflag;
1168
{
1169
  struct dis386 *dp;
1170
  int i;
1171
  int enter_instruction;
1172
  char *first, *second, *third;
1173
  int needcomma;
1174
  unsigned char need_modrm;
1175

    
1176
  struct dis_private priv;
1177
  bfd_byte *inbuf = priv.the_buffer;
1178

    
1179
  /* The output looks better if we put 5 bytes on a line, since that
1180
     puts long word instructions on a single line.  */
1181
  info->bytes_per_line = 5;
1182

    
1183
  info->private_data = (PTR) &priv;
1184
  priv.max_fetched = priv.the_buffer;
1185
  priv.insn_start = pc;
1186
  if (setjmp (priv.bailout) != 0)
1187
    /* Error return.  */
1188
    return -1;
1189

    
1190
  obuf[0] = 0;
1191
  op1out[0] = 0;
1192
  op2out[0] = 0;
1193
  op3out[0] = 0;
1194

    
1195
  op_index[0] = op_index[1] = op_index[2] = -1;
1196

    
1197
  the_info = info;
1198
  start_pc = pc;
1199
  start_codep = inbuf;
1200
  codep = inbuf;
1201
  
1202
  ckprefix ();
1203

    
1204
  FETCH_DATA (info, codep + 1);
1205
  if (*codep == 0xc8)
1206
    enter_instruction = 1;
1207
  else
1208
    enter_instruction = 0;
1209
  
1210
  obufp = obuf;
1211
  
1212
  if (prefixes & PREFIX_REPZ)
1213
    oappend ("repz ");
1214
  if (prefixes & PREFIX_REPNZ)
1215
    oappend ("repnz ");
1216
  if (prefixes & PREFIX_LOCK)
1217
    oappend ("lock ");
1218
  
1219
  if ((prefixes & PREFIX_FWAIT)
1220
      && ((*codep < 0xd8) || (*codep > 0xdf)))
1221
    {
1222
      /* fwait not followed by floating point instruction */
1223
      (*info->fprintf_func) (info->stream, "fwait");
1224
      return (1);
1225
    }
1226
  
1227
  if (prefixes & PREFIX_DATA)
1228
    dflag ^= 1;
1229
  
1230
  if (prefixes & PREFIX_ADR)
1231
    {
1232
      aflag ^= 1;
1233
      if (aflag)
1234
        oappend ("addr32 ");
1235
      else
1236
        oappend ("addr16 ");
1237
    }
1238
  
1239
  if (*codep == 0x0f)
1240
    {
1241
      FETCH_DATA (info, codep + 2);
1242
      dp = &dis386_twobyte[*++codep];
1243
      need_modrm = twobyte_has_modrm[*codep];
1244
    }
1245
  else
1246
    {
1247
      dp = &dis386[*codep];
1248
      need_modrm = onebyte_has_modrm[*codep];
1249
    }
1250
  codep++;
1251

    
1252
  if (need_modrm)
1253
    {
1254
      FETCH_DATA (info, codep + 1);
1255
      mod = (*codep >> 6) & 3;
1256
      reg = (*codep >> 3) & 7;
1257
      rm = *codep & 7;
1258
    }
1259

    
1260
  if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
1261
    {
1262
      dofloat (aflag, dflag);
1263
    }
1264
  else
1265
    {
1266
      if (dp->name == NULL)
1267
        dp = &grps[dp->bytemode1][reg];
1268
      
1269
      putop (dp->name, aflag, dflag);
1270
      
1271
      obufp = op1out;
1272
      op_ad = 2;
1273
      if (dp->op1)
1274
        (*dp->op1)(dp->bytemode1, aflag, dflag);
1275
      
1276
      obufp = op2out;
1277
      op_ad = 1;
1278
      if (dp->op2)
1279
        (*dp->op2)(dp->bytemode2, aflag, dflag);
1280
      
1281
      obufp = op3out;
1282
      op_ad = 0;
1283
      if (dp->op3)
1284
        (*dp->op3)(dp->bytemode3, aflag, dflag);
1285
    }
1286
  
1287
  obufp = obuf + strlen (obuf);
1288
  for (i = strlen (obuf); i < 6; i++)
1289
    oappend (" ");
1290
  oappend (" ");
1291
  (*info->fprintf_func) (info->stream, "%s", obuf);
1292
  
1293
  /* enter instruction is printed with operands in the
1294
   * same order as the intel book; everything else
1295
   * is printed in reverse order 
1296
   */
1297
  if (enter_instruction)
1298
    {
1299
      first = op1out;
1300
      second = op2out;
1301
      third = op3out;
1302
      op_ad = op_index[0];
1303
      op_index[0] = op_index[2];
1304
      op_index[2] = op_ad;
1305
    }
1306
  else
1307
    {
1308
      first = op3out;
1309
      second = op2out;
1310
      third = op1out;
1311
    }
1312
  needcomma = 0;
1313
  if (*first)
1314
    {
1315
      if (op_index[0] != -1)
1316
        (*info->print_address_func) (op_address[op_index[0]], info);
1317
      else
1318
        (*info->fprintf_func) (info->stream, "%s", first);
1319
      needcomma = 1;
1320
    }
1321
  if (*second)
1322
    {
1323
      if (needcomma)
1324
        (*info->fprintf_func) (info->stream, ",");
1325
      if (op_index[1] != -1)
1326
        (*info->print_address_func) (op_address[op_index[1]], info);
1327
      else
1328
        (*info->fprintf_func) (info->stream, "%s", second);
1329
      needcomma = 1;
1330
    }
1331
  if (*third)
1332
    {
1333
      if (needcomma)
1334
        (*info->fprintf_func) (info->stream, ",");
1335
      if (op_index[2] != -1)
1336
        (*info->print_address_func) (op_address[op_index[2]], info);
1337
      else
1338
        (*info->fprintf_func) (info->stream, "%s", third);
1339
    }
1340
  return (codep - inbuf);
1341
}
1342

    
1343
static char *float_mem[] = {
1344
  /* d8 */
1345
  "fadds",
1346
  "fmuls",
1347
  "fcoms",
1348
  "fcomps",
1349
  "fsubs",
1350
  "fsubrs",
1351
  "fdivs",
1352
  "fdivrs",
1353
  /*  d9 */
1354
  "flds",
1355
  "(bad)",
1356
  "fsts",
1357
  "fstps",
1358
  "fldenv",
1359
  "fldcw",
1360
  "fNstenv",
1361
  "fNstcw",
1362
  /* da */
1363
  "fiaddl",
1364
  "fimull",
1365
  "ficoml",
1366
  "ficompl",
1367
  "fisubl",
1368
  "fisubrl",
1369
  "fidivl",
1370
  "fidivrl",
1371
  /* db */
1372
  "fildl",
1373
  "(bad)",
1374
  "fistl",
1375
  "fistpl",
1376
  "(bad)",
1377
  "fldt",
1378
  "(bad)",
1379
  "fstpt",
1380
  /* dc */
1381
  "faddl",
1382
  "fmull",
1383
  "fcoml",
1384
  "fcompl",
1385
  "fsubl",
1386
  "fsubrl",
1387
  "fdivl",
1388
  "fdivrl",
1389
  /* dd */
1390
  "fldl",
1391
  "(bad)",
1392
  "fstl",
1393
  "fstpl",
1394
  "frstor",
1395
  "(bad)",
1396
  "fNsave",
1397
  "fNstsw",
1398
  /* de */
1399
  "fiadd",
1400
  "fimul",
1401
  "ficom",
1402
  "ficomp",
1403
  "fisub",
1404
  "fisubr",
1405
  "fidiv",
1406
  "fidivr",
1407
  /* df */
1408
  "fild",
1409
  "(bad)",
1410
  "fist",
1411
  "fistp",
1412
  "fbld",
1413
  "fildll",
1414
  "fbstp",
1415
  "fistpll",
1416
};
1417

    
1418
#define ST OP_ST, 0
1419
#define STi OP_STi, 0
1420

    
1421
#define FGRPd9_2 NULL, NULL, 0
1422
#define FGRPd9_4 NULL, NULL, 1
1423
#define FGRPd9_5 NULL, NULL, 2
1424
#define FGRPd9_6 NULL, NULL, 3
1425
#define FGRPd9_7 NULL, NULL, 4
1426
#define FGRPda_5 NULL, NULL, 5
1427
#define FGRPdb_4 NULL, NULL, 6
1428
#define FGRPde_3 NULL, NULL, 7
1429
#define FGRPdf_4 NULL, NULL, 8
1430

    
1431
static struct dis386 float_reg[][8] = {
1432
  /* d8 */
1433
  {
1434
    { "fadd",        ST, STi },
1435
    { "fmul",        ST, STi },
1436
    { "fcom",        STi },
1437
    { "fcomp",        STi },
1438
    { "fsub",        ST, STi },
1439
    { "fsubr",        ST, STi },
1440
    { "fdiv",        ST, STi },
1441
    { "fdivr",        ST, STi },
1442
  },
1443
  /* d9 */
1444
  {
1445
    { "fld",        STi },
1446
    { "fxch",        STi },
1447
    { FGRPd9_2 },
1448
    { "(bad)" },
1449
    { FGRPd9_4 },
1450
    { FGRPd9_5 },
1451
    { FGRPd9_6 },
1452
    { FGRPd9_7 },
1453
  },
1454
  /* da */
1455
  {
1456
    { "fcmovb",        ST, STi },
1457
    { "fcmove",        ST, STi },
1458
    { "fcmovbe",ST, STi },
1459
    { "fcmovu",        ST, STi },
1460
    { "(bad)" },
1461
    { FGRPda_5 },
1462
    { "(bad)" },
1463
    { "(bad)" },
1464
  },
1465
  /* db */
1466
  {
1467
    { "fcmovnb",ST, STi },
1468
    { "fcmovne",ST, STi },
1469
    { "fcmovnbe",ST, STi },
1470
    { "fcmovnu",ST, STi },
1471
    { FGRPdb_4 },
1472
    { "fucomi",        ST, STi },
1473
    { "fcomi",        ST, STi },
1474
    { "(bad)" },
1475
  },
1476
  /* dc */
1477
  {
1478
    { "fadd",        STi, ST },
1479
    { "fmul",        STi, ST },
1480
    { "(bad)" },
1481
    { "(bad)" },
1482
    { "fsub",        STi, ST },
1483
    { "fsubr",        STi, ST },
1484
    { "fdiv",        STi, ST },
1485
    { "fdivr",        STi, ST },
1486
  },
1487
  /* dd */
1488
  {
1489
    { "ffree",        STi },
1490
    { "(bad)" },
1491
    { "fst",        STi },
1492
    { "fstp",        STi },
1493
    { "fucom",        STi },
1494
    { "fucomp",        STi },
1495
    { "(bad)" },
1496
    { "(bad)" },
1497
  },
1498
  /* de */
1499
  {
1500
    { "faddp",        STi, ST },
1501
    { "fmulp",        STi, ST },
1502
    { "(bad)" },
1503
    { FGRPde_3 },
1504
    { "fsubp",        STi, ST },
1505
    { "fsubrp",        STi, ST },
1506
    { "fdivp",        STi, ST },
1507
    { "fdivrp",        STi, ST },
1508
  },
1509
  /* df */
1510
  {
1511
    { "(bad)" },
1512
    { "(bad)" },
1513
    { "(bad)" },
1514
    { "(bad)" },
1515
    { FGRPdf_4 },
1516
    { "fucomip",ST, STi },
1517
    { "fcomip", ST, STi },
1518
    { "(bad)" },
1519
  },
1520
};
1521

    
1522

    
1523
static char *fgrps[][8] = {
1524
  /* d9_2  0 */
1525
  {
1526
    "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1527
  },
1528

    
1529
  /* d9_4  1 */
1530
  {
1531
    "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
1532
  },
1533

    
1534
  /* d9_5  2 */
1535
  {
1536
    "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
1537
  },
1538

    
1539
  /* d9_6  3 */
1540
  {
1541
    "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
1542
  },
1543

    
1544
  /* d9_7  4 */
1545
  {
1546
    "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
1547
  },
1548

    
1549
  /* da_5  5 */
1550
  {
1551
    "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1552
  },
1553

    
1554
  /* db_4  6 */
1555
  {
1556
    "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
1557
    "fNsetpm(287 only)","(bad)","(bad)","(bad)",
1558
  },
1559

    
1560
  /* de_3  7 */
1561
  {
1562
    "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1563
  },
1564

    
1565
  /* df_4  8 */
1566
  {
1567
    "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1568
  },
1569
};
1570

    
1571
static void
1572
dofloat (aflag, dflag)
1573
     int aflag;
1574
     int dflag;
1575
{
1576
  struct dis386 *dp;
1577
  unsigned char floatop;
1578
  
1579
  floatop = codep[-1];
1580
  
1581
  if (mod != 3)
1582
    {
1583
      putop (float_mem[(floatop - 0xd8) * 8 + reg], aflag, dflag);
1584
      obufp = op1out;
1585
      OP_E (v_mode, aflag, dflag);
1586
      return;
1587
    }
1588
  codep++;
1589
  
1590
  dp = &float_reg[floatop - 0xd8][reg];
1591
  if (dp->name == NULL)
1592
    {
1593
      putop (fgrps[dp->bytemode1][rm], aflag, dflag);
1594
      /* instruction fnstsw is only one with strange arg */
1595
      if (floatop == 0xdf
1596
          && FETCH_DATA (the_info, codep + 1)
1597
          && *codep == 0xe0)
1598
        strcpy (op1out, "%eax");
1599
    }
1600
  else
1601
    {
1602
      putop (dp->name, aflag, dflag);
1603
      obufp = op1out;
1604
      if (dp->op1)
1605
        (*dp->op1)(dp->bytemode1, aflag, dflag);
1606
      obufp = op2out;
1607
      if (dp->op2)
1608
        (*dp->op2)(dp->bytemode2, aflag, dflag);
1609
    }
1610
}
1611

    
1612
/* ARGSUSED */
1613
static int
1614
OP_ST (ignore, aflag, dflag)
1615
     int ignore;
1616
     int aflag;
1617
     int dflag;
1618
{
1619
  oappend ("%st");
1620
  return (0);
1621
}
1622

    
1623
/* ARGSUSED */
1624
static int
1625
OP_STi (ignore, aflag, dflag)
1626
     int ignore;
1627
     int aflag;
1628
     int dflag;
1629
{
1630
  sprintf (scratchbuf, "%%st(%d)", rm);
1631
  oappend (scratchbuf);
1632
  return (0);
1633
}
1634

    
1635

    
1636
/* capital letters in template are macros */
1637
static void
1638
putop (template, aflag, dflag)
1639
     char *template;
1640
     int aflag;
1641
     int dflag;
1642
{
1643
  char *p;
1644
  
1645
  for (p = template; *p; p++)
1646
    {
1647
      switch (*p)
1648
        {
1649
        default:
1650
          *obufp++ = *p;
1651
          break;
1652
        case 'C':                /* For jcxz/jecxz */
1653
          if (aflag)
1654
            *obufp++ = 'e';
1655
          break;
1656
        case 'N':
1657
          if ((prefixes & PREFIX_FWAIT) == 0)
1658
            *obufp++ = 'n';
1659
          break;
1660
        case 'S':
1661
          /* operand size flag */
1662
          if (dflag)
1663
            *obufp++ = 'l';
1664
          else
1665
            *obufp++ = 'w';
1666
          break;
1667
        case 'W':
1668
          /* operand size flag for cwtl, cbtw */
1669
          if (dflag)
1670
            *obufp++ = 'w';
1671
          else
1672
            *obufp++ = 'b';
1673
          break;
1674
        }
1675
    }
1676
  *obufp = 0;
1677
}
1678

    
1679
static void
1680
oappend (s)
1681
     char *s;
1682
{
1683
  strcpy (obufp, s);
1684
  obufp += strlen (s);
1685
  *obufp = 0;
1686
}
1687

    
1688
static void
1689
append_prefix ()
1690
{
1691
  if (prefixes & PREFIX_CS)
1692
    oappend ("%cs:");
1693
  if (prefixes & PREFIX_DS)
1694
    oappend ("%ds:");
1695
  if (prefixes & PREFIX_SS)
1696
    oappend ("%ss:");
1697
  if (prefixes & PREFIX_ES)
1698
    oappend ("%es:");
1699
  if (prefixes & PREFIX_FS)
1700
    oappend ("%fs:");
1701
  if (prefixes & PREFIX_GS)
1702
    oappend ("%gs:");
1703
}
1704

    
1705
static int
1706
OP_indirE (bytemode, aflag, dflag)
1707
     int bytemode;
1708
     int aflag;
1709
     int dflag;
1710
{
1711
  oappend ("*");
1712
  return OP_E (bytemode, aflag, dflag);
1713
}
1714

    
1715
static int
1716
OP_E (bytemode, aflag, dflag)
1717
     int bytemode;
1718
     int aflag;
1719
     int dflag;
1720
{
1721
  int disp;
1722

    
1723
  /* skip mod/rm byte */
1724
  codep++;
1725

    
1726
  if (mod == 3)
1727
    {
1728
      switch (bytemode)
1729
        {
1730
        case b_mode:
1731
          oappend (names8[rm]);
1732
          break;
1733
        case w_mode:
1734
          oappend (names16[rm]);
1735
          break;
1736
        case v_mode:
1737
          if (dflag)
1738
            oappend (names32[rm]);
1739
          else
1740
            oappend (names16[rm]);
1741
          break;
1742
        default:
1743
          oappend ("<bad dis table>");
1744
          break;
1745
        }
1746
      return 0;
1747
    }
1748

    
1749
  disp = 0;
1750
  append_prefix ();
1751

    
1752
  if (aflag) /* 32 bit address mode */
1753
    {
1754
      int havesib;
1755
      int havebase;
1756
      int base;
1757
      int index = 0;
1758
      int scale = 0;
1759

    
1760
      havesib = 0;
1761
      havebase = 1;
1762
      base = rm;
1763

    
1764
      if (base == 4)
1765
        {
1766
          havesib = 1;
1767
          FETCH_DATA (the_info, codep + 1);
1768
          scale = (*codep >> 6) & 3;
1769
          index = (*codep >> 3) & 7;
1770
          base = *codep & 7;
1771
          codep++;
1772
        }
1773

    
1774
      switch (mod)
1775
        {
1776
        case 0:
1777
          if (base == 5)
1778
            {
1779
              havebase = 0;
1780
              disp = get32 ();
1781
            }
1782
          break;
1783
        case 1:
1784
          FETCH_DATA (the_info, codep + 1);
1785
          disp = *codep++;
1786
          if ((disp & 0x80) != 0)
1787
            disp -= 0x100;
1788
          break;
1789
        case 2:
1790
          disp = get32 ();
1791
          break;
1792
        }
1793

    
1794
      if (mod != 0 || base == 5)
1795
        {
1796
          sprintf (scratchbuf, "0x%x", disp);
1797
          oappend (scratchbuf);
1798
        }
1799

    
1800
      if (havebase || (havesib && (index != 4 || scale != 0)))
1801
        {
1802
          oappend ("(");
1803
          if (havebase)
1804
            oappend (names32[base]);
1805
          if (havesib)
1806
            {
1807
              if (index != 4)
1808
                {
1809
                  sprintf (scratchbuf, ",%s", names32[index]);
1810
                  oappend (scratchbuf);
1811
                }
1812
              sprintf (scratchbuf, ",%d", 1 << scale);
1813
              oappend (scratchbuf);
1814
            }
1815
          oappend (")");
1816
        }
1817
    }
1818
  else
1819
    { /* 16 bit address mode */
1820
      switch (mod)
1821
        {
1822
        case 0:
1823
          if (rm == 6)
1824
            {
1825
              disp = get16 ();
1826
              if ((disp & 0x8000) != 0)
1827
                disp -= 0x10000;
1828
            }
1829
          break;
1830
        case 1:
1831
          FETCH_DATA (the_info, codep + 1);
1832
          disp = *codep++;
1833
          if ((disp & 0x80) != 0)
1834
            disp -= 0x100;
1835
          break;
1836
        case 2:
1837
          disp = get16 ();
1838
          if ((disp & 0x8000) != 0)
1839
            disp -= 0x10000;
1840
          break;
1841
        }
1842

    
1843
      if (mod != 0 || rm == 6)
1844
        {
1845
          sprintf (scratchbuf, "0x%x", disp);
1846
          oappend (scratchbuf);
1847
        }
1848

    
1849
      if (mod != 0 || rm != 6)
1850
        {
1851
          oappend ("(");
1852
          oappend (index16[rm]);
1853
          oappend (")");
1854
        }
1855
    }
1856
  return 0;
1857
}
1858

    
1859
static int
1860
OP_G (bytemode, aflag, dflag)
1861
     int bytemode;
1862
     int aflag;
1863
     int dflag;
1864
{
1865
  switch (bytemode) 
1866
    {
1867
    case b_mode:
1868
      oappend (names8[reg]);
1869
      break;
1870
    case w_mode:
1871
      oappend (names16[reg]);
1872
      break;
1873
    case d_mode:
1874
      oappend (names32[reg]);
1875
      break;
1876
    case v_mode:
1877
      if (dflag)
1878
        oappend (names32[reg]);
1879
      else
1880
        oappend (names16[reg]);
1881
      break;
1882
    default:
1883
      oappend ("<internal disassembler error>");
1884
      break;
1885
    }
1886
  return (0);
1887
}
1888

    
1889
static int
1890
get32 ()
1891
{
1892
  int x = 0;
1893

    
1894
  FETCH_DATA (the_info, codep + 4);
1895
  x = *codep++ & 0xff;
1896
  x |= (*codep++ & 0xff) << 8;
1897
  x |= (*codep++ & 0xff) << 16;
1898
  x |= (*codep++ & 0xff) << 24;
1899
  return (x);
1900
}
1901

    
1902
static int
1903
get16 ()
1904
{
1905
  int x = 0;
1906

    
1907
  FETCH_DATA (the_info, codep + 2);
1908
  x = *codep++ & 0xff;
1909
  x |= (*codep++ & 0xff) << 8;
1910
  return (x);
1911
}
1912

    
1913
static void
1914
set_op (op)
1915
     int op;
1916
{
1917
  op_index[op_ad] = op_ad;
1918
  op_address[op_ad] = op;
1919
}
1920

    
1921
static int
1922
OP_REG (code, aflag, dflag)
1923
     int code;
1924
     int aflag;
1925
     int dflag;
1926
{
1927
  char *s;
1928
  
1929
  switch (code) 
1930
    {
1931
    case indir_dx_reg: s = "(%dx)"; break;
1932
        case ax_reg: case cx_reg: case dx_reg: case bx_reg:
1933
        case sp_reg: case bp_reg: case si_reg: case di_reg:
1934
                s = names16[code - ax_reg];
1935
                break;
1936
        case es_reg: case ss_reg: case cs_reg:
1937
        case ds_reg: case fs_reg: case gs_reg:
1938
                s = names_seg[code - es_reg];
1939
                break;
1940
        case al_reg: case ah_reg: case cl_reg: case ch_reg:
1941
        case dl_reg: case dh_reg: case bl_reg: case bh_reg:
1942
                s = names8[code - al_reg];
1943
                break;
1944
        case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
1945
        case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
1946
      if (dflag)
1947
        s = names32[code - eAX_reg];
1948
      else
1949
        s = names16[code - eAX_reg];
1950
      break;
1951
    default:
1952
      s = "<internal disassembler error>";
1953
      break;
1954
    }
1955
  oappend (s);
1956
  return (0);
1957
}
1958

    
1959
static int
1960
OP_I (bytemode, aflag, dflag)
1961
     int bytemode;
1962
     int aflag;
1963
     int dflag;
1964
{
1965
  int op;
1966
  
1967
  switch (bytemode) 
1968
    {
1969
    case b_mode:
1970
      FETCH_DATA (the_info, codep + 1);
1971
      op = *codep++ & 0xff;
1972
      break;
1973
    case v_mode:
1974
      if (dflag)
1975
        op = get32 ();
1976
      else
1977
        op = get16 ();
1978
      break;
1979
    case w_mode:
1980
      op = get16 ();
1981
      break;
1982
    default:
1983
      oappend ("<internal disassembler error>");
1984
      return (0);
1985
    }
1986
  sprintf (scratchbuf, "$0x%x", op);
1987
  oappend (scratchbuf);
1988
  return (0);
1989
}
1990

    
1991
static int
1992
OP_sI (bytemode, aflag, dflag)
1993
     int bytemode;
1994
     int aflag;
1995
     int dflag;
1996
{
1997
  int op;
1998
  
1999
  switch (bytemode) 
2000
    {
2001
    case b_mode:
2002
      FETCH_DATA (the_info, codep + 1);
2003
      op = *codep++;
2004
      if ((op & 0x80) != 0)
2005
        op -= 0x100;
2006
      break;
2007
    case v_mode:
2008
      if (dflag)
2009
        op = get32 ();
2010
      else
2011
        {
2012
          op = get16();
2013
          if ((op & 0x8000) != 0)
2014
            op -= 0x10000;
2015
        }
2016
      break;
2017
    case w_mode:
2018
      op = get16 ();
2019
      if ((op & 0x8000) != 0)
2020
        op -= 0x10000;
2021
      break;
2022
    default:
2023
      oappend ("<internal disassembler error>");
2024
      return (0);
2025
    }
2026
  sprintf (scratchbuf, "$0x%x", op);
2027
  oappend (scratchbuf);
2028
  return (0);
2029
}
2030

    
2031
static int
2032
OP_J (bytemode, aflag, dflag)
2033
     int bytemode;
2034
     int aflag;
2035
     int dflag;
2036
{
2037
  int disp;
2038
  int mask = -1;
2039
  
2040
  switch (bytemode) 
2041
    {
2042
    case b_mode:
2043
      FETCH_DATA (the_info, codep + 1);
2044
      disp = *codep++;
2045
      if ((disp & 0x80) != 0)
2046
        disp -= 0x100;
2047
      break;
2048
    case v_mode:
2049
      if (dflag)
2050
        disp = get32 ();
2051
      else
2052
        {
2053
          disp = get16 ();
2054
          if ((disp & 0x8000) != 0)
2055
            disp -= 0x10000;
2056
          /* for some reason, a data16 prefix on a jump instruction
2057
             means that the pc is masked to 16 bits after the
2058
             displacement is added!  */
2059
          mask = 0xffff;
2060
        }
2061
      break;
2062
    default:
2063
      oappend ("<internal disassembler error>");
2064
      return (0);
2065
    }
2066
  disp = (start_pc + codep - start_codep + disp) & mask;
2067
  set_op (disp);
2068
  sprintf (scratchbuf, "0x%x", disp);
2069
  oappend (scratchbuf);
2070
  return (0);
2071
}
2072

    
2073
/* ARGSUSED */
2074
static int
2075
OP_SEG (dummy, aflag, dflag)
2076
     int dummy;
2077
     int aflag;
2078
     int dflag;
2079
{
2080
  static char *sreg[] = {
2081
    "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
2082
  };
2083

    
2084
  oappend (sreg[reg]);
2085
  return (0);
2086
}
2087

    
2088
static int
2089
OP_DIR (size, aflag, dflag)
2090
     int size;
2091
     int aflag;
2092
     int dflag;
2093
{
2094
  int seg, offset;
2095
  
2096
  switch (size) 
2097
    {
2098
    case lptr:
2099
      if (aflag) 
2100
        {
2101
          offset = get32 ();
2102
          seg = get16 ();
2103
        } 
2104
      else 
2105
        {
2106
          offset = get16 ();
2107
          seg = get16 ();
2108
        }
2109
      sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
2110
      oappend (scratchbuf);
2111
      break;
2112
    case v_mode:
2113
      if (aflag)
2114
        offset = get32 ();
2115
      else
2116
        {
2117
          offset = get16 ();
2118
          if ((offset & 0x8000) != 0)
2119
            offset -= 0x10000;
2120
        }
2121
      
2122
      offset = start_pc + codep - start_codep + offset;
2123
      set_op (offset);
2124
      sprintf (scratchbuf, "0x%x", offset);
2125
      oappend (scratchbuf);
2126
      break;
2127
    default:
2128
      oappend ("<internal disassembler error>");
2129
      break;
2130
    }
2131
  return (0);
2132
}
2133

    
2134
/* ARGSUSED */
2135
static int
2136
OP_OFF (bytemode, aflag, dflag)
2137
     int bytemode;
2138
     int aflag;
2139
     int dflag;
2140
{
2141
  int off;
2142

    
2143
  append_prefix ();
2144

    
2145
  if (aflag)
2146
    off = get32 ();
2147
  else
2148
    off = get16 ();
2149
  
2150
  sprintf (scratchbuf, "0x%x", off);
2151
  oappend (scratchbuf);
2152
  return (0);
2153
}
2154

    
2155
/* ARGSUSED */
2156
static int
2157
OP_ESDI (dummy, aflag, dflag)
2158
     int dummy;
2159
     int aflag;
2160
     int dflag;
2161
{
2162
  oappend ("%es:(");
2163
  oappend (aflag ? "%edi" : "%di");
2164
  oappend (")");
2165
  return (0);
2166
}
2167

    
2168
/* ARGSUSED */
2169
static int
2170
OP_DSSI (dummy, aflag, dflag)
2171
     int dummy;
2172
     int aflag;
2173
     int dflag;
2174
{
2175
  if ((prefixes
2176
       & (PREFIX_CS
2177
          | PREFIX_DS
2178
          | PREFIX_SS
2179
          | PREFIX_ES
2180
          | PREFIX_FS
2181
          | PREFIX_GS)) == 0)
2182
    prefixes |= PREFIX_DS;
2183
  append_prefix ();
2184
  oappend ("(");
2185
  oappend (aflag ? "%esi" : "%si");
2186
  oappend (")");
2187
  return (0);
2188
}
2189

    
2190
#if 0
2191
/* Not used.  */
2192

2193
/* ARGSUSED */
2194
static int
2195
OP_ONE (dummy, aflag, dflag)
2196
     int dummy;
2197
     int aflag;
2198
     int dflag;
2199
{
2200
  oappend ("1");
2201
  return (0);
2202
}
2203

2204
#endif
2205

    
2206
/* ARGSUSED */
2207
static int
2208
OP_C (dummy, aflag, dflag)
2209
     int dummy;
2210
     int aflag;
2211
     int dflag;
2212
{
2213
  codep++; /* skip mod/rm */
2214
  sprintf (scratchbuf, "%%cr%d", reg);
2215
  oappend (scratchbuf);
2216
  return (0);
2217
}
2218

    
2219
/* ARGSUSED */
2220
static int
2221
OP_D (dummy, aflag, dflag)
2222
     int dummy;
2223
     int aflag;
2224
     int dflag;
2225
{
2226
  codep++; /* skip mod/rm */
2227
  sprintf (scratchbuf, "%%db%d", reg);
2228
  oappend (scratchbuf);
2229
  return (0);
2230
}
2231

    
2232
/* ARGSUSED */
2233
static int
2234
OP_T (dummy, aflag, dflag)
2235
     int dummy;
2236
     int aflag;
2237
     int dflag;
2238
{
2239
  codep++; /* skip mod/rm */
2240
  sprintf (scratchbuf, "%%tr%d", reg);
2241
  oappend (scratchbuf);
2242
  return (0);
2243
}
2244

    
2245
static int
2246
OP_rm (bytemode, aflag, dflag)
2247
     int bytemode;
2248
     int aflag;
2249
     int dflag;
2250
{
2251
  switch (bytemode) 
2252
    {
2253
    case d_mode:
2254
      oappend (names32[rm]);
2255
      break;
2256
    case w_mode:
2257
      oappend (names16[rm]);
2258
      break;
2259
    }
2260
  return (0);
2261
}
2262

    
2263
static int
2264
OP_MMX (bytemode, aflag, dflag)
2265
     int bytemode;
2266
     int aflag;
2267
     int dflag;
2268
{
2269
  sprintf (scratchbuf, "%%mm%d", reg);
2270
  oappend (scratchbuf);
2271
  return 0;
2272
}
2273

    
2274
static int
2275
OP_EM (bytemode, aflag, dflag)
2276
     int bytemode;
2277
     int aflag;
2278
     int dflag;
2279
{
2280
  if (mod != 3)
2281
    return OP_E (bytemode, aflag, dflag);
2282

    
2283
  codep++;
2284
  sprintf (scratchbuf, "%%mm%d", rm);
2285
  oappend (scratchbuf);
2286
  return 0;
2287
}
2288

    
2289
static int
2290
OP_MS (bytemode, aflag, dflag)
2291
     int bytemode;
2292
     int aflag;
2293
     int dflag;
2294
{
2295
  ++codep;
2296
  sprintf (scratchbuf, "%%mm%d", rm);
2297
  oappend (scratchbuf);
2298
  return 0;
2299
}