Statistics
| Branch: | Revision:

root / i386-dis.c @ a69d83b6

History | View | Annotate | Download (44.7 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 <stdlib.h>
37
#include <setjmp.h>
38

    
39
#include "dis-asm.h"
40

    
41
#define MAXLEN 20
42

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
206
#define lptr 115
207

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

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

    
226
#define indir_dx_reg 150
227

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

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

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

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

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

    
779
static const unsigned char onebyte_has_modrm[256] = {
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
  1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
784
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
785
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
786
  0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
787
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
788
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
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
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
792
  1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
793
  1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
794
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
795
  0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
796
};
797

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

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

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

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

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

    
1080
static int prefixes;
1081

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1523

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

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

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

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

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

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

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

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

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

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

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

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

    
1636

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

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

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

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

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

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

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

    
1750
  disp = 0;
1751
  append_prefix ();
1752

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
2144
  append_prefix ();
2145

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

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

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

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

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

2205
#endif
2206

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

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

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

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

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

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

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

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