OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [final_interface/] [gdb-5.0/] [opcodes/] [i386-dis.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/* Print i386 instructions for GDB, the GNU debugger.
2
   Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 98, 1999
3
   Free Software Foundation, Inc.
4
 
5
This file is part of GDB.
6
 
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
 
21
/*
22
 * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
23
 * July 1988
24
 *  modified by John Hassey (hassey@dg-rtp.dg.com)
25
 */
26
 
27
/*
28
 * The main tables describing the instructions is essentially a copy
29
 * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
30
 * Programmers Manual.  Usually, there is a capital letter, followed
31
 * by a small letter.  The capital letter tell the addressing mode,
32
 * and the small letter tells about the operand size.  Refer to
33
 * the Intel manual for details.
34
 */
35
 
36
#include "dis-asm.h"
37
#include "sysdep.h"
38
#include "opintl.h"
39
 
40
#define MAXLEN 20
41
 
42
#include <setjmp.h>
43
 
44
#ifndef UNIXWARE_COMPAT
45
/* Set non-zero for broken, compatible instructions.  Set to zero for
46
   non-broken opcodes.  */
47
#define UNIXWARE_COMPAT 1
48
#endif
49
 
50
static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
51
 
52
struct dis_private
53
{
54
  /* Points to first byte not fetched.  */
55
  bfd_byte *max_fetched;
56
  bfd_byte the_buffer[MAXLEN];
57
  bfd_vma insn_start;
58
  jmp_buf bailout;
59
};
60
 
61
/* The opcode for the fwait instruction, which we treat as a prefix
62
   when we can.  */
63
#define FWAIT_OPCODE (0x9b)
64
 
65
/* Flags for the prefixes for the current instruction.  See below.  */
66
static int prefixes;
67
 
68
/* Flags for prefixes which we somehow handled when printing the
69
   current instruction.  */
70
static int used_prefixes;
71
 
72
/* Flags stored in PREFIXES.  */
73
#define PREFIX_REPZ 1
74
#define PREFIX_REPNZ 2
75
#define PREFIX_LOCK 4
76
#define PREFIX_CS 8
77
#define PREFIX_SS 0x10
78
#define PREFIX_DS 0x20
79
#define PREFIX_ES 0x40
80
#define PREFIX_FS 0x80
81
#define PREFIX_GS 0x100
82
#define PREFIX_DATA 0x200
83
#define PREFIX_ADDR 0x400
84
#define PREFIX_FWAIT 0x800
85
 
86
/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
87
   to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
88
   on error.  */
89
#define FETCH_DATA(info, addr) \
90
  ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
91
   ? 1 : fetch_data ((info), (addr)))
92
 
93
static int
94
fetch_data (info, addr)
95
     struct disassemble_info *info;
96
     bfd_byte *addr;
97
{
98
  int status;
99
  struct dis_private *priv = (struct dis_private *)info->private_data;
100
  bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
101
 
102
  status = (*info->read_memory_func) (start,
103
                                      priv->max_fetched,
104
                                      addr - priv->max_fetched,
105
                                      info);
106
  if (status != 0)
107
    {
108
      /* If we did manage to read at least one byte, then
109
         print_insn_i386 will do something sensible.  Otherwise, print
110
         an error.  We do that here because this is where we know
111
         STATUS.  */
112
      if (priv->max_fetched == priv->the_buffer)
113
        (*info->memory_error_func) (status, start, info);
114
      longjmp (priv->bailout, 1);
115
    }
116
  else
117
    priv->max_fetched = addr;
118
  return 1;
119
}
120
 
121
#define XX NULL, 0
122
 
123
#define Eb OP_E, b_mode
124
#define indirEb OP_indirE, b_mode
125
#define Gb OP_G, b_mode
126
#define Ev OP_E, v_mode
127
#define Ed OP_E, d_mode
128
#define indirEv OP_indirE, v_mode
129
#define Ew OP_E, w_mode
130
#define Ma OP_E, v_mode
131
#define M OP_E, 0               /* lea */
132
#define Mp OP_E, 0              /* 32 or 48 bit memory operand for LDS, LES etc */
133
#define Gv OP_G, v_mode
134
#define Gw OP_G, w_mode
135
#define Rd OP_Rd, d_mode
136
#define Ib OP_I, b_mode
137
#define sIb OP_sI, b_mode       /* sign extened byte */
138
#define Iv OP_I, v_mode
139
#define Iw OP_I, w_mode
140
#define Jb OP_J, b_mode
141
#define Jv OP_J, v_mode
142
#define Cd OP_C, d_mode
143
#define Dd OP_D, d_mode
144
#define Td OP_T, d_mode
145
 
146
#define eAX OP_REG, eAX_reg
147
#define eBX OP_REG, eBX_reg
148
#define eCX OP_REG, eCX_reg
149
#define eDX OP_REG, eDX_reg
150
#define eSP OP_REG, eSP_reg
151
#define eBP OP_REG, eBP_reg
152
#define eSI OP_REG, eSI_reg
153
#define eDI OP_REG, eDI_reg
154
#define AL OP_REG, al_reg
155
#define CL OP_REG, cl_reg
156
#define DL OP_REG, dl_reg
157
#define BL OP_REG, bl_reg
158
#define AH OP_REG, ah_reg
159
#define CH OP_REG, ch_reg
160
#define DH OP_REG, dh_reg
161
#define BH OP_REG, bh_reg
162
#define AX OP_REG, ax_reg
163
#define DX OP_REG, dx_reg
164
#define indirDX OP_REG, indir_dx_reg
165
 
166
#define Sw OP_SEG, w_mode
167
#define Ap OP_DIR, 0
168
#define Ob OP_OFF, b_mode
169
#define Ov OP_OFF, v_mode
170
#define Xb OP_DSreg, eSI_reg
171
#define Xv OP_DSreg, eSI_reg
172
#define Yb OP_ESreg, eDI_reg
173
#define Yv OP_ESreg, eDI_reg
174
#define DSBX OP_DSreg, eBX_reg
175
 
176
#define es OP_REG, es_reg
177
#define ss OP_REG, ss_reg
178
#define cs OP_REG, cs_reg
179
#define ds OP_REG, ds_reg
180
#define fs OP_REG, fs_reg
181
#define gs OP_REG, gs_reg
182
 
183
#define MX OP_MMX, 0
184
#define XM OP_XMM, 0
185
#define EM OP_EM, v_mode
186
#define EX OP_EX, v_mode
187
#define MS OP_MS, v_mode
188
#define None OP_E, 0
189
#define OPSUF OP_3DNowSuffix, 0
190
#define OPSIMD OP_SIMD_Suffix, 0
191
 
192
/* bits in sizeflag */
193
#if 0 /* leave undefined until someone adds the extra flag to objdump */
194
#define SUFFIX_ALWAYS 4
195
#endif
196
#define AFLAG 2
197
#define DFLAG 1
198
 
199
typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag));
200
 
201
static void OP_E PARAMS ((int, int));
202
static void OP_G PARAMS ((int, int));
203
static void OP_I PARAMS ((int, int));
204
static void OP_indirE PARAMS ((int, int));
205
static void OP_sI PARAMS ((int, int));
206
static void OP_REG PARAMS ((int, int));
207
static void OP_J PARAMS ((int, int));
208
static void OP_DIR PARAMS ((int, int));
209
static void OP_OFF PARAMS ((int, int));
210
static void OP_ESreg PARAMS ((int, int));
211
static void OP_DSreg PARAMS ((int, int));
212
static void OP_SEG PARAMS ((int, int));
213
static void OP_C PARAMS ((int, int));
214
static void OP_D PARAMS ((int, int));
215
static void OP_T PARAMS ((int, int));
216
static void OP_Rd PARAMS ((int, int));
217
static void OP_ST PARAMS ((int, int));
218
static void OP_STi  PARAMS ((int, int));
219
static void OP_MMX PARAMS ((int, int));
220
static void OP_XMM PARAMS ((int, int));
221
static void OP_EM PARAMS ((int, int));
222
static void OP_EX PARAMS ((int, int));
223
static void OP_MS PARAMS ((int, int));
224
static void OP_3DNowSuffix PARAMS ((int, int));
225
static void OP_SIMD_Suffix PARAMS ((int, int));
226
static void SIMD_Fixup PARAMS ((int, int));
227
 
228
static void append_seg PARAMS ((void));
229
static void set_op PARAMS ((unsigned int op));
230
static void putop PARAMS ((const char *template, int sizeflag));
231
static void dofloat PARAMS ((int sizeflag));
232
static int get16 PARAMS ((void));
233
static int get32 PARAMS ((void));
234
static void ckprefix PARAMS ((void));
235
static const char *prefix_name PARAMS ((int, int));
236
static void ptr_reg PARAMS ((int, int));
237
static void BadOp PARAMS ((void));
238
 
239
#define b_mode 1
240
#define v_mode 2
241
#define w_mode 3
242
#define d_mode 4
243
#define x_mode 5
244
 
245
#define es_reg 100
246
#define cs_reg 101
247
#define ss_reg 102
248
#define ds_reg 103
249
#define fs_reg 104
250
#define gs_reg 105
251
 
252
#define eAX_reg 108
253
#define eCX_reg 109
254
#define eDX_reg 110
255
#define eBX_reg 111
256
#define eSP_reg 112
257
#define eBP_reg 113
258
#define eSI_reg 114
259
#define eDI_reg 115
260
 
261
#define al_reg 116
262
#define cl_reg 117
263
#define dl_reg 118
264
#define bl_reg 119
265
#define ah_reg 120
266
#define ch_reg 121
267
#define dh_reg 122
268
#define bh_reg 123
269
 
270
#define ax_reg 124
271
#define cx_reg 125
272
#define dx_reg 126
273
#define bx_reg 127
274
#define sp_reg 128
275
#define bp_reg 129
276
#define si_reg 130
277
#define di_reg 131
278
 
279
#define indir_dx_reg 150
280
 
281
#define USE_GROUPS 1
282
#define USE_PREFIX_USER_TABLE 2
283
 
284
#define GRP1b NULL, NULL, 0, NULL, USE_GROUPS, NULL, 0
285
#define GRP1S NULL, NULL, 1, NULL, USE_GROUPS, NULL, 0
286
#define GRP1Ss NULL, NULL, 2, NULL, USE_GROUPS, NULL, 0
287
#define GRP2b NULL, NULL, 3, NULL, USE_GROUPS, NULL, 0
288
#define GRP2S NULL, NULL, 4, NULL, USE_GROUPS, NULL, 0
289
#define GRP2b_one NULL, NULL, 5, NULL, USE_GROUPS, NULL, 0
290
#define GRP2S_one NULL, NULL, 6, NULL, USE_GROUPS, NULL, 0
291
#define GRP2b_cl NULL, NULL, 7, NULL, USE_GROUPS, NULL, 0
292
#define GRP2S_cl NULL, NULL, 8, NULL, USE_GROUPS, NULL, 0
293
#define GRP3b NULL, NULL, 9, NULL, USE_GROUPS, NULL, 0
294
#define GRP3S NULL, NULL, 10, NULL, USE_GROUPS, NULL, 0
295
#define GRP4  NULL, NULL, 11, NULL, USE_GROUPS, NULL, 0
296
#define GRP5  NULL, NULL, 12, NULL, USE_GROUPS, NULL, 0
297
#define GRP6  NULL, NULL, 13, NULL, USE_GROUPS, NULL, 0
298
#define GRP7 NULL, NULL, 14, NULL, USE_GROUPS, NULL, 0
299
#define GRP8 NULL, NULL, 15, NULL, USE_GROUPS, NULL, 0
300
#define GRP9 NULL, NULL, 16, NULL, USE_GROUPS, NULL, 0
301
#define GRP10 NULL, NULL, 17, NULL, USE_GROUPS, NULL, 0
302
#define GRP11 NULL, NULL, 18, NULL, USE_GROUPS, NULL, 0
303
#define GRP12 NULL, NULL, 19, NULL, USE_GROUPS, NULL, 0
304
#define GRP13 NULL, NULL, 20, NULL, USE_GROUPS, NULL, 0
305
#define GRP14 NULL, NULL, 21, NULL, USE_GROUPS, NULL, 0
306
#define GRPAMD NULL, NULL, 22, NULL, USE_GROUPS, NULL, 0
307
 
308
#define PREGRP0 NULL, NULL, 0, NULL, USE_PREFIX_USER_TABLE, NULL, 0
309
#define PREGRP1 NULL, NULL, 1, NULL, USE_PREFIX_USER_TABLE, NULL, 0
310
#define PREGRP2 NULL, NULL, 2, NULL, USE_PREFIX_USER_TABLE, NULL, 0
311
#define PREGRP3 NULL, NULL, 3, NULL, USE_PREFIX_USER_TABLE, NULL, 0
312
#define PREGRP4 NULL, NULL, 4, NULL, USE_PREFIX_USER_TABLE, NULL, 0
313
#define PREGRP5 NULL, NULL, 5, NULL, USE_PREFIX_USER_TABLE, NULL, 0
314
#define PREGRP6 NULL, NULL, 6, NULL, USE_PREFIX_USER_TABLE, NULL, 0
315
#define PREGRP7 NULL, NULL, 7, NULL, USE_PREFIX_USER_TABLE, NULL, 0
316
#define PREGRP8 NULL, NULL, 8, NULL, USE_PREFIX_USER_TABLE, NULL, 0
317
#define PREGRP9 NULL, NULL, 9, NULL, USE_PREFIX_USER_TABLE, NULL, 0
318
#define PREGRP10 NULL, NULL, 10, NULL, USE_PREFIX_USER_TABLE, NULL, 0
319
#define PREGRP11 NULL, NULL, 11, NULL, USE_PREFIX_USER_TABLE, NULL, 0
320
#define PREGRP12 NULL, NULL, 12, NULL, USE_PREFIX_USER_TABLE, NULL, 0
321
#define PREGRP13 NULL, NULL, 13, NULL, USE_PREFIX_USER_TABLE, NULL, 0
322
#define PREGRP14 NULL, NULL, 14, NULL, USE_PREFIX_USER_TABLE, NULL, 0
323
 
324
#define FLOATCODE 50
325
#define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
326
 
327
struct dis386 {
328
  const char *name;
329
  op_rtn op1;
330
  int bytemode1;
331
  op_rtn op2;
332
  int bytemode2;
333
  op_rtn op3;
334
  int bytemode3;
335
};
336
 
337
/* Upper case letters in the instruction names here are macros.
338
   'A' => print 'b' if no register operands or suffix_always is true
339
   'B' => print 'b' if suffix_always is true
340
   'E' => print 'e' if 32-bit form of jcxz
341
   'L' => print 'l' if suffix_always is true
342
   'N' => print 'n' if instruction has no wait "prefix"
343
   'P' => print 'w' or 'l' if instruction has an operand size prefix,
344
                              or suffix_always is true
345
   'Q' => print 'w' or 'l' if no register operands or suffix_always is true
346
   'R' => print 'w' or 'l' ("wd" or "dq" in intel mode)
347
   'S' => print 'w' or 'l' if suffix_always is true
348
   'W' => print 'b' or 'w' ("w" or "de" in intel mode)
349
*/
350
 
351
static const struct dis386 dis386_att[] = {
352
  /* 00 */
353
  { "addB",     Eb, Gb, XX },
354
  { "addS",     Ev, Gv, XX },
355
  { "addB",     Gb, Eb, XX },
356
  { "addS",     Gv, Ev, XX },
357
  { "addB",     AL, Ib, XX },
358
  { "addS",     eAX, Iv, XX },
359
  { "pushP",    es, XX, XX },
360
  { "popP",     es, XX, XX },
361
  /* 08 */
362
  { "orB",      Eb, Gb, XX },
363
  { "orS",      Ev, Gv, XX },
364
  { "orB",      Gb, Eb, XX },
365
  { "orS",      Gv, Ev, XX },
366
  { "orB",      AL, Ib, XX },
367
  { "orS",      eAX, Iv, XX },
368
  { "pushP",    cs, XX, XX },
369
  { "(bad)",    XX, XX, XX },   /* 0x0f extended opcode escape */
370
  /* 10 */
371
  { "adcB",     Eb, Gb, XX },
372
  { "adcS",     Ev, Gv, XX },
373
  { "adcB",     Gb, Eb, XX },
374
  { "adcS",     Gv, Ev, XX },
375
  { "adcB",     AL, Ib, XX },
376
  { "adcS",     eAX, Iv, XX },
377
  { "pushP",    ss, XX, XX },
378
  { "popP",     ss, XX, XX },
379
  /* 18 */
380
  { "sbbB",     Eb, Gb, XX },
381
  { "sbbS",     Ev, Gv, XX },
382
  { "sbbB",     Gb, Eb, XX },
383
  { "sbbS",     Gv, Ev, XX },
384
  { "sbbB",     AL, Ib, XX },
385
  { "sbbS",     eAX, Iv, XX },
386
  { "pushP",    ds, XX, XX },
387
  { "popP",     ds, XX, XX },
388
  /* 20 */
389
  { "andB",     Eb, Gb, XX },
390
  { "andS",     Ev, Gv, XX },
391
  { "andB",     Gb, Eb, XX },
392
  { "andS",     Gv, Ev, XX },
393
  { "andB",     AL, Ib, XX },
394
  { "andS",     eAX, Iv, XX },
395
  { "(bad)",    XX, XX, XX },                   /* SEG ES prefix */
396
  { "daa",      XX, XX, XX },
397
  /* 28 */
398
  { "subB",     Eb, Gb, XX },
399
  { "subS",     Ev, Gv, XX },
400
  { "subB",     Gb, Eb, XX },
401
  { "subS",     Gv, Ev, XX },
402
  { "subB",     AL, Ib, XX },
403
  { "subS",     eAX, Iv, XX },
404
  { "(bad)",    XX, XX, XX },                   /* SEG CS prefix */
405
  { "das",      XX, XX, XX },
406
  /* 30 */
407
  { "xorB",     Eb, Gb, XX },
408
  { "xorS",     Ev, Gv, XX },
409
  { "xorB",     Gb, Eb, XX },
410
  { "xorS",     Gv, Ev, XX },
411
  { "xorB",     AL, Ib, XX },
412
  { "xorS",     eAX, Iv, XX },
413
  { "(bad)",    XX, XX, XX },                   /* SEG SS prefix */
414
  { "aaa",      XX, XX, XX },
415
  /* 38 */
416
  { "cmpB",     Eb, Gb, XX },
417
  { "cmpS",     Ev, Gv, XX },
418
  { "cmpB",     Gb, Eb, XX },
419
  { "cmpS",     Gv, Ev, XX },
420
  { "cmpB",     AL, Ib, XX },
421
  { "cmpS",     eAX, Iv, XX },
422
  { "(bad)",    XX, XX, XX },                   /* SEG DS prefix */
423
  { "aas",      XX, XX, XX },
424
  /* 40 */
425
  { "incS",     eAX, XX, XX },
426
  { "incS",     eCX, XX, XX },
427
  { "incS",     eDX, XX, XX },
428
  { "incS",     eBX, XX, XX },
429
  { "incS",     eSP, XX, XX },
430
  { "incS",     eBP, XX, XX },
431
  { "incS",     eSI, XX, XX },
432
  { "incS",     eDI, XX, XX },
433
  /* 48 */
434
  { "decS",     eAX, XX, XX },
435
  { "decS",     eCX, XX, XX },
436
  { "decS",     eDX, XX, XX },
437
  { "decS",     eBX, XX, XX },
438
  { "decS",     eSP, XX, XX },
439
  { "decS",     eBP, XX, XX },
440
  { "decS",     eSI, XX, XX },
441
  { "decS",     eDI, XX, XX },
442
  /* 50 */
443
  { "pushS",    eAX, XX, XX },
444
  { "pushS",    eCX, XX, XX },
445
  { "pushS",    eDX, XX, XX },
446
  { "pushS",    eBX, XX, XX },
447
  { "pushS",    eSP, XX, XX },
448
  { "pushS",    eBP, XX, XX },
449
  { "pushS",    eSI, XX, XX },
450
  { "pushS",    eDI, XX, XX },
451
  /* 58 */
452
  { "popS",     eAX, XX, XX },
453
  { "popS",     eCX, XX, XX },
454
  { "popS",     eDX, XX, XX },
455
  { "popS",     eBX, XX, XX },
456
  { "popS",     eSP, XX, XX },
457
  { "popS",     eBP, XX, XX },
458
  { "popS",     eSI, XX, XX },
459
  { "popS",     eDI, XX, XX },
460
  /* 60 */
461
  { "pushaP",   XX, XX, XX },
462
  { "popaP",    XX, XX, XX },
463
  { "boundS",   Gv, Ma, XX },
464
  { "arpl",     Ew, Gw, XX },
465
  { "(bad)",    XX, XX, XX },                   /* seg fs */
466
  { "(bad)",    XX, XX, XX },                   /* seg gs */
467
  { "(bad)",    XX, XX, XX },                   /* op size prefix */
468
  { "(bad)",    XX, XX, XX },                   /* adr size prefix */
469
  /* 68 */
470
  { "pushP",    Iv, XX, XX },           /* 386 book wrong */
471
  { "imulS",    Gv, Ev, Iv },
472
  { "pushP",    sIb, XX, XX },  /* push of byte really pushes 2 or 4 bytes */
473
  { "imulS",    Gv, Ev, sIb },
474
  { "insb",     Yb, indirDX, XX },
475
  { "insR",     Yv, indirDX, XX },
476
  { "outsb",    indirDX, Xb, XX },
477
  { "outsR",    indirDX, Xv, XX },
478
  /* 70 */
479
  { "jo",       Jb, XX, XX },
480
  { "jno",      Jb, XX, XX },
481
  { "jb",       Jb, XX, XX },
482
  { "jae",      Jb, XX, XX },
483
  { "je",       Jb, XX, XX },
484
  { "jne",      Jb, XX, XX },
485
  { "jbe",      Jb, XX, XX },
486
  { "ja",       Jb, XX, XX },
487
  /* 78 */
488
  { "js",       Jb, XX, XX },
489
  { "jns",      Jb, XX, XX },
490
  { "jp",       Jb, XX, XX },
491
  { "jnp",      Jb, XX, XX },
492
  { "jl",       Jb, XX, XX },
493
  { "jge",      Jb, XX, XX },
494
  { "jle",      Jb, XX, XX },
495
  { "jg",       Jb, XX, XX },
496
  /* 80 */
497
  { GRP1b },
498
  { GRP1S },
499
  { "(bad)",    XX, XX, XX },
500
  { GRP1Ss },
501
  { "testB",    Eb, Gb, XX },
502
  { "testS",    Ev, Gv, XX },
503
  { "xchgB",    Eb, Gb, XX },
504
  { "xchgS",    Ev, Gv, XX },
505
  /* 88 */
506
  { "movB",     Eb, Gb, XX },
507
  { "movS",     Ev, Gv, XX },
508
  { "movB",     Gb, Eb, XX },
509
  { "movS",     Gv, Ev, XX },
510
  { "movQ",     Ev, Sw, XX },
511
  { "leaS",     Gv, M, XX },
512
  { "movQ",     Sw, Ev, XX },
513
  { "popQ",     Ev, XX, XX },
514
  /* 90 */
515
  { "nop",      XX, XX, XX },
516
  { "xchgS",    eCX, eAX, XX },
517
  { "xchgS",    eDX, eAX, XX },
518
  { "xchgS",    eBX, eAX, XX },
519
  { "xchgS",    eSP, eAX, XX },
520
  { "xchgS",    eBP, eAX, XX },
521
  { "xchgS",    eSI, eAX, XX },
522
  { "xchgS",    eDI, eAX, XX },
523
  /* 98 */
524
  { "cWtR",     XX, XX, XX },
525
  { "cRtd",     XX, XX, XX },
526
  { "lcallP",   Ap, XX, XX },
527
  { "(bad)",    XX, XX, XX },           /* fwait */
528
  { "pushfP",   XX, XX, XX },
529
  { "popfP",    XX, XX, XX },
530
  { "sahf",     XX, XX, XX },
531
  { "lahf",     XX, XX, XX },
532
  /* a0 */
533
  { "movB",     AL, Ob, XX },
534
  { "movS",     eAX, Ov, XX },
535
  { "movB",     Ob, AL, XX },
536
  { "movS",     Ov, eAX, XX },
537
  { "movsb",    Yb, Xb, XX },
538
  { "movsR",    Yv, Xv, XX },
539
  { "cmpsb",    Xb, Yb, XX },
540
  { "cmpsR",    Xv, Yv, XX },
541
  /* a8 */
542
  { "testB",    AL, Ib, XX },
543
  { "testS",    eAX, Iv, XX },
544
  { "stosB",    Yb, AL, XX },
545
  { "stosS",    Yv, eAX, XX },
546
  { "lodsB",    AL, Xb, XX },
547
  { "lodsS",    eAX, Xv, XX },
548
  { "scasB",    AL, Yb, XX },
549
  { "scasS",    eAX, Yv, XX },
550
  /* b0 */
551
  { "movB",     AL, Ib, XX },
552
  { "movB",     CL, Ib, XX },
553
  { "movB",     DL, Ib, XX },
554
  { "movB",     BL, Ib, XX },
555
  { "movB",     AH, Ib, XX },
556
  { "movB",     CH, Ib, XX },
557
  { "movB",     DH, Ib, XX },
558
  { "movB",     BH, Ib, XX },
559
  /* b8 */
560
  { "movS",     eAX, Iv, XX },
561
  { "movS",     eCX, Iv, XX },
562
  { "movS",     eDX, Iv, XX },
563
  { "movS",     eBX, Iv, XX },
564
  { "movS",     eSP, Iv, XX },
565
  { "movS",     eBP, Iv, XX },
566
  { "movS",     eSI, Iv, XX },
567
  { "movS",     eDI, Iv, XX },
568
  /* c0 */
569
  { GRP2b },
570
  { GRP2S },
571
  { "retP",     Iw, XX, XX },
572
  { "retP",     XX, XX, XX },
573
  { "lesS",     Gv, Mp, XX },
574
  { "ldsS",     Gv, Mp, XX },
575
  { "movA",     Eb, Ib, XX },
576
  { "movQ",     Ev, Iv, XX },
577
  /* c8 */
578
  { "enterP",   Iw, Ib, XX },
579
  { "leaveP",   XX, XX, XX },
580
  { "lretP",    Iw, XX, XX },
581
  { "lretP",    XX, XX, XX },
582
  { "int3",     XX, XX, XX },
583
  { "int",      Ib, XX, XX },
584
  { "into",     XX, XX, XX},
585
  { "iretP",    XX, XX, XX },
586
  /* d0 */
587
  { GRP2b_one },
588
  { GRP2S_one },
589
  { GRP2b_cl },
590
  { GRP2S_cl },
591
  { "aam",      sIb, XX, XX },
592
  { "aad",      sIb, XX, XX },
593
  { "(bad)",    XX, XX, XX },
594
  { "xlat",     DSBX, XX, XX },
595
  /* d8 */
596
  { FLOAT },
597
  { FLOAT },
598
  { FLOAT },
599
  { FLOAT },
600
  { FLOAT },
601
  { FLOAT },
602
  { FLOAT },
603
  { FLOAT },
604
  /* e0 */
605
  { "loopne",   Jb, XX, XX },
606
  { "loope",    Jb, XX, XX },
607
  { "loop",     Jb, XX, XX },
608
  { "jEcxz",    Jb, XX, XX },
609
  { "inB",      AL, Ib, XX },
610
  { "inS",      eAX, Ib, XX },
611
  { "outB",     Ib, AL, XX },
612
  { "outS",     Ib, eAX, XX },
613
  /* e8 */
614
  { "callP",    Jv, XX, XX },
615
  { "jmpP",     Jv, XX, XX },
616
  { "ljmpP",    Ap, XX, XX },
617
  { "jmp",      Jb, XX, XX },
618
  { "inB",      AL, indirDX, XX },
619
  { "inS",      eAX, indirDX, XX },
620
  { "outB",     indirDX, AL, XX },
621
  { "outS",     indirDX, eAX, XX },
622
  /* f0 */
623
  { "(bad)",    XX, XX, XX },                   /* lock prefix */
624
  { "(bad)",    XX, XX, XX },
625
  { "(bad)",    XX, XX, XX },                   /* repne */
626
  { "(bad)",    XX, XX, XX },                   /* repz */
627
  { "hlt",      XX, XX, XX },
628
  { "cmc",      XX, XX, XX },
629
  { GRP3b },
630
  { GRP3S },
631
  /* f8 */
632
  { "clc",      XX, XX, XX },
633
  { "stc",      XX, XX, XX },
634
  { "cli",      XX, XX, XX },
635
  { "sti",      XX, XX, XX },
636
  { "cld",      XX, XX, XX },
637
  { "std",      XX, XX, XX },
638
  { GRP4 },
639
  { GRP5 },
640
};
641
 
642
static const struct dis386 dis386_intel[] = {
643
  /* 00 */
644
  { "add",      Eb, Gb, XX },
645
  { "add",      Ev, Gv, XX },
646
  { "add",      Gb, Eb, XX },
647
  { "add",      Gv, Ev, XX },
648
  { "add",      AL, Ib, XX },
649
  { "add",      eAX, Iv, XX },
650
  { "push",     es, XX, XX },
651
  { "pop",      es, XX, XX },
652
  /* 08 */
653
  { "or",       Eb, Gb, XX },
654
  { "or",       Ev, Gv, XX },
655
  { "or",       Gb, Eb, XX },
656
  { "or",       Gv, Ev, XX },
657
  { "or",       AL, Ib, XX },
658
  { "or",       eAX, Iv, XX },
659
  { "push",     cs, XX, XX },
660
  { "(bad)",    XX, XX, XX },   /* 0x0f extended opcode escape */
661
  /* 10 */
662
  { "adc",      Eb, Gb, XX },
663
  { "adc",      Ev, Gv, XX },
664
  { "adc",      Gb, Eb, XX },
665
  { "adc",      Gv, Ev, XX },
666
  { "adc",      AL, Ib, XX },
667
  { "adc",      eAX, Iv, XX },
668
  { "push",     ss, XX, XX },
669
  { "pop",      ss, XX, XX },
670
  /* 18 */
671
  { "sbb",      Eb, Gb, XX },
672
  { "sbb",      Ev, Gv, XX },
673
  { "sbb",      Gb, Eb, XX },
674
  { "sbb",      Gv, Ev, XX },
675
  { "sbb",      AL, Ib, XX },
676
  { "sbb",      eAX, Iv, XX },
677
  { "push",     ds, XX, XX },
678
  { "pop",      ds, XX, XX },
679
  /* 20 */
680
  { "and",      Eb, Gb, XX },
681
  { "and",      Ev, Gv, XX },
682
  { "and",      Gb, Eb, XX },
683
  { "and",      Gv, Ev, XX },
684
  { "and",      AL, Ib, XX },
685
  { "and",      eAX, Iv, XX },
686
  { "(bad)",    XX, XX, XX },                   /* SEG ES prefix */
687
  { "daa",      XX, XX, XX },
688
  /* 28 */
689
  { "sub",      Eb, Gb, XX },
690
  { "sub",      Ev, Gv, XX },
691
  { "sub",      Gb, Eb, XX },
692
  { "sub",      Gv, Ev, XX },
693
  { "sub",      AL, Ib, XX },
694
  { "sub",      eAX, Iv, XX },
695
  { "(bad)",    XX, XX, XX },                   /* SEG CS prefix */
696
  { "das",      XX, XX, XX },
697
  /* 30 */
698
  { "xor",      Eb, Gb, XX },
699
  { "xor",      Ev, Gv, XX },
700
  { "xor",      Gb, Eb, XX },
701
  { "xor",      Gv, Ev, XX },
702
  { "xor",      AL, Ib, XX },
703
  { "xor",      eAX, Iv, XX },
704
  { "(bad)",    XX, XX, XX },                   /* SEG SS prefix */
705
  { "aaa",      XX, XX, XX },
706
  /* 38 */
707
  { "cmp",      Eb, Gb, XX },
708
  { "cmp",      Ev, Gv, XX },
709
  { "cmp",      Gb, Eb, XX },
710
  { "cmp",      Gv, Ev, XX },
711
  { "cmp",      AL, Ib, XX },
712
  { "cmp",      eAX, Iv, XX },
713
  { "(bad)",    XX, XX, XX },                   /* SEG DS prefix */
714
  { "aas",      XX, XX, XX },
715
  /* 40 */
716
  { "inc",      eAX, XX, XX },
717
  { "inc",      eCX, XX, XX },
718
  { "inc",      eDX, XX, XX },
719
  { "inc",      eBX, XX, XX },
720
  { "inc",      eSP, XX, XX },
721
  { "inc",      eBP, XX, XX },
722
  { "inc",      eSI, XX, XX },
723
  { "inc",      eDI, XX, XX },
724
  /* 48 */
725
  { "dec",      eAX, XX, XX },
726
  { "dec",      eCX, XX, XX },
727
  { "dec",      eDX, XX, XX },
728
  { "dec",      eBX, XX, XX },
729
  { "dec",      eSP, XX, XX },
730
  { "dec",      eBP, XX, XX },
731
  { "dec",      eSI, XX, XX },
732
  { "dec",      eDI, XX, XX },
733
  /* 50 */
734
  { "push",     eAX, XX, XX },
735
  { "push",     eCX, XX, XX },
736
  { "push",     eDX, XX, XX },
737
  { "push",     eBX, XX, XX },
738
  { "push",     eSP, XX, XX },
739
  { "push",     eBP, XX, XX },
740
  { "push",     eSI, XX, XX },
741
  { "push",     eDI, XX, XX },
742
  /* 58 */
743
  { "pop",      eAX, XX, XX },
744
  { "pop",      eCX, XX, XX },
745
  { "pop",      eDX, XX, XX },
746
  { "pop",      eBX, XX, XX },
747
  { "pop",      eSP, XX, XX },
748
  { "pop",      eBP, XX, XX },
749
  { "pop",      eSI, XX, XX },
750
  { "pop",      eDI, XX, XX },
751
  /* 60 */
752
  { "pusha",    XX, XX, XX },
753
  { "popa",     XX, XX, XX },
754
  { "bound",    Gv, Ma, XX },
755
  { "arpl",     Ew, Gw, XX },
756
  { "(bad)",    XX, XX, XX },                   /* seg fs */
757
  { "(bad)",    XX, XX, XX },                   /* seg gs */
758
  { "(bad)",    XX, XX, XX },                   /* op size prefix */
759
  { "(bad)",    XX, XX, XX },                   /* adr size prefix */
760
  /* 68 */
761
  { "push",     Iv, XX, XX },           /* 386 book wrong */
762
  { "imul",     Gv, Ev, Iv },
763
  { "push",     sIb, XX, XX },  /* push of byte really pushes 2 or 4 bytes */
764
  { "imul",     Gv, Ev, sIb },
765
  { "ins",      Yb, indirDX, XX },
766
  { "ins",      Yv, indirDX, XX },
767
  { "outs",     indirDX, Xb, XX },
768
  { "outs",     indirDX, Xv, XX },
769
  /* 70 */
770
  { "jo",       Jb, XX, XX },
771
  { "jno",      Jb, XX, XX },
772
  { "jb",       Jb, XX, XX },
773
  { "jae",      Jb, XX, XX },
774
  { "je",       Jb, XX, XX },
775
  { "jne",      Jb, XX, XX },
776
  { "jbe",      Jb, XX, XX },
777
  { "ja",       Jb, XX, XX },
778
  /* 78 */
779
  { "js",       Jb, XX, XX },
780
  { "jns",      Jb, XX, XX },
781
  { "jp",       Jb, XX, XX },
782
  { "jnp",      Jb, XX, XX },
783
  { "jl",       Jb, XX, XX },
784
  { "jge",      Jb, XX, XX },
785
  { "jle",      Jb, XX, XX },
786
  { "jg",       Jb, XX, XX },
787
  /* 80 */
788
  { GRP1b },
789
  { GRP1S },
790
  { "(bad)",    XX, XX, XX },
791
  { GRP1Ss },
792
  { "test",     Eb, Gb, XX },
793
  { "test",     Ev, Gv, XX },
794
  { "xchg",     Eb, Gb, XX },
795
  { "xchg",     Ev, Gv, XX },
796
  /* 88 */
797
  { "mov",      Eb, Gb, XX },
798
  { "mov",      Ev, Gv, XX },
799
  { "mov",      Gb, Eb, XX },
800
  { "mov",      Gv, Ev, XX },
801
  { "mov",      Ev, Sw, XX },
802
  { "lea",      Gv, M, XX },
803
  { "mov",      Sw, Ev, XX },
804
  { "pop",      Ev, XX, XX },
805
  /* 90 */
806
  { "nop",      XX, XX, XX },
807
  { "xchg",     eCX, eAX, XX },
808
  { "xchg",     eDX, eAX, XX },
809
  { "xchg",     eBX, eAX, XX },
810
  { "xchg",     eSP, eAX, XX },
811
  { "xchg",     eBP, eAX, XX },
812
  { "xchg",     eSI, eAX, XX },
813
  { "xchg",     eDI, eAX, XX },
814
  /* 98 */
815
  { "cW",       XX, XX, XX },           /* cwde and cbw */
816
  { "cR",       XX, XX, XX },           /* cdq and cwd */
817
  { "lcall",    Ap, XX, XX },
818
  { "(bad)",    XX, XX, XX },           /* fwait */
819
  { "pushf",    XX, XX, XX },
820
  { "popf",     XX, XX, XX },
821
  { "sahf",     XX, XX, XX },
822
  { "lahf",     XX, XX, XX },
823
  /* a0 */
824
  { "mov",      AL, Ob, XX },
825
  { "mov",      eAX, Ov, XX },
826
  { "mov",      Ob, AL, XX },
827
  { "mov",      Ov, eAX, XX },
828
  { "movs",     Yb, Xb, XX },
829
  { "movs",     Yv, Xv, XX },
830
  { "cmps",     Xb, Yb, XX },
831
  { "cmps",     Xv, Yv, XX },
832
  /* a8 */
833
  { "test",     AL, Ib, XX },
834
  { "test",     eAX, Iv, XX },
835
  { "stos",     Yb, AL, XX },
836
  { "stos",     Yv, eAX, XX },
837
  { "lods",     AL, Xb, XX },
838
  { "lods",     eAX, Xv, XX },
839
  { "scas",     AL, Yb, XX },
840
  { "scas",     eAX, Yv, XX },
841
  /* b0 */
842
  { "mov",      AL, Ib, XX },
843
  { "mov",      CL, Ib, XX },
844
  { "mov",      DL, Ib, XX },
845
  { "mov",      BL, Ib, XX },
846
  { "mov",      AH, Ib, XX },
847
  { "mov",      CH, Ib, XX },
848
  { "mov",      DH, Ib, XX },
849
  { "mov",      BH, Ib, XX },
850
  /* b8 */
851
  { "mov",      eAX, Iv, XX },
852
  { "mov",      eCX, Iv, XX },
853
  { "mov",      eDX, Iv, XX },
854
  { "mov",      eBX, Iv, XX },
855
  { "mov",      eSP, Iv, XX },
856
  { "mov",      eBP, Iv, XX },
857
  { "mov",      eSI, Iv, XX },
858
  { "mov",      eDI, Iv, XX },
859
  /* c0 */
860
  { GRP2b },
861
  { GRP2S },
862
  { "ret",      Iw, XX, XX },
863
  { "ret",      XX, XX, XX },
864
  { "les",      Gv, Mp, XX },
865
  { "lds",      Gv, Mp, XX },
866
  { "mov",      Eb, Ib, XX },
867
  { "mov",      Ev, Iv, XX },
868
  /* c8 */
869
  { "enter",    Iw, Ib, XX },
870
  { "leave",    XX, XX, XX },
871
  { "lret",     Iw, XX, XX },
872
  { "lret",     XX, XX, XX },
873
  { "int3",     XX, XX, XX },
874
  { "int",      Ib, XX, XX },
875
  { "into",     XX, XX, XX },
876
  { "iret",     XX, XX, XX },
877
  /* d0 */
878
  { GRP2b_one },
879
  { GRP2S_one },
880
  { GRP2b_cl },
881
  { GRP2S_cl },
882
  { "aam",      sIb, XX, XX },
883
  { "aad",      sIb, XX, XX },
884
  { "(bad)",    XX, XX, XX },
885
  { "xlat",     DSBX, XX, XX },
886
  /* d8 */
887
  { FLOAT },
888
  { FLOAT },
889
  { FLOAT },
890
  { FLOAT },
891
  { FLOAT },
892
  { FLOAT },
893
  { FLOAT },
894
  { FLOAT },
895
  /* e0 */
896
  { "loopne",   Jb, XX, XX },
897
  { "loope",    Jb, XX, XX },
898
  { "loop",     Jb, XX, XX },
899
  { "jEcxz",    Jb, XX, XX },
900
  { "in",       AL, Ib, XX },
901
  { "in",       eAX, Ib, XX },
902
  { "out",      Ib, AL, XX },
903
  { "out",      Ib, eAX, XX },
904
  /* e8 */
905
  { "call",     Jv, XX, XX },
906
  { "jmp",      Jv, XX, XX },
907
  { "ljmp",     Ap, XX, XX },
908
  { "jmp",      Jb, XX, XX },
909
  { "in",       AL, indirDX, XX },
910
  { "in",       eAX, indirDX, XX },
911
  { "out",      indirDX, AL, XX },
912
  { "out",      indirDX, eAX, XX },
913
  /* f0 */
914
  { "(bad)",    XX, XX, XX },                   /* lock prefix */
915
  { "(bad)",    XX, XX, XX },
916
  { "(bad)",    XX, XX, XX },                   /* repne */
917
  { "(bad)",    XX, XX, XX },                   /* repz */
918
  { "hlt",      XX, XX, XX },
919
  { "cmc",      XX, XX, XX },
920
  { GRP3b },
921
  { GRP3S },
922
  /* f8 */
923
  { "clc",      XX, XX, XX },
924
  { "stc",      XX, XX, XX },
925
  { "cli",      XX, XX, XX },
926
  { "sti",      XX, XX, XX },
927
  { "cld",      XX, XX, XX },
928
  { "std",      XX, XX, XX },
929
  { GRP4 },
930
  { GRP5 },
931
};
932
 
933
static const struct dis386 dis386_twobyte_att[] = {
934
  /* 00 */
935
  { GRP6 },
936
  { GRP7 },
937
  { "larS", Gv, Ew, XX },
938
  { "lslS", Gv, Ew, XX },
939
  { "(bad)", XX, XX, XX },
940
  { "(bad)", XX, XX, XX },
941
  { "clts", XX, XX, XX },
942
  { "(bad)", XX, XX, XX },
943
  /* 08 */
944
  { "invd", XX, XX, XX },
945
  { "wbinvd", XX, XX, XX },
946
  { "(bad)", XX, XX, XX },
947
  { "ud2a", XX, XX, XX },
948
  { "(bad)", XX, XX, XX },
949
  { GRPAMD },
950
  { "femms", XX, XX, XX },
951
  { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
952
  /* 10 */
953
  { PREGRP8 },
954
  { PREGRP9 },
955
  { "movlps", XM, EX, SIMD_Fixup, 'h' },  /* really only 2 operands */
956
  { "movlps", EX, XM, SIMD_Fixup, 'h' },
957
  { "unpcklps", XM, EX, XX },
958
  { "unpckhps", XM, EX, XX },
959
  { "movhps", XM, EX, SIMD_Fixup, 'l' },
960
  { "movhps", EX, XM, SIMD_Fixup, 'l' },
961
  /* 18 */
962
  { GRP14 },
963
  { "(bad)", XX, XX, XX },
964
  { "(bad)", XX, XX, XX },
965
  { "(bad)", XX, XX, XX },
966
  { "(bad)", XX, XX, XX },
967
  { "(bad)", XX, XX, XX },
968
  { "(bad)", XX, XX, XX },
969
  { "(bad)", XX, XX, XX },
970
  /* 20 */
971
  /* these are all backward in appendix A of the intel book */
972
  { "movL", Rd, Cd, XX },
973
  { "movL", Rd, Dd, XX },
974
  { "movL", Cd, Rd, XX },
975
  { "movL", Dd, Rd, XX },
976
  { "movL", Rd, Td, XX },
977
  { "(bad)", XX, XX, XX },
978
  { "movL", Td, Rd, XX },
979
  { "(bad)", XX, XX, XX },
980
  /* 28 */
981
  { "movaps", XM, EX, XX },
982
  { "movaps", EX, XM, XX },
983
  { PREGRP2 },
984
  { "movntps", Ev, XM, XX },
985
  { PREGRP4 },
986
  { PREGRP3 },
987
  { "ucomiss", XM, EX, XX },
988
  { "comiss", XM, EX, XX },
989
  /* 30 */
990
  { "wrmsr", XX, XX, XX },
991
  { "rdtsc", XX, XX, XX },
992
  { "rdmsr", XX, XX, XX },
993
  { "rdpmc", XX, XX, XX },
994
  { "sysenter", XX, XX, XX },
995
  { "sysexit", XX, XX, XX },
996
  { "(bad)", XX, XX, XX },
997
  { "(bad)", XX, XX, XX },
998
  /* 38 */
999
  { "(bad)", XX, XX, XX },
1000
  { "(bad)", XX, XX, XX },
1001
  { "(bad)", XX, XX, XX },
1002
  { "(bad)", XX, XX, XX },
1003
  { "(bad)", XX, XX, XX },
1004
  { "(bad)", XX, XX, XX },
1005
  { "(bad)", XX, XX, XX },
1006
  { "(bad)", XX, XX, XX },
1007
  /* 40 */
1008
  { "cmovo", Gv, Ev, XX },
1009
  { "cmovno", Gv, Ev, XX },
1010
  { "cmovb", Gv, Ev, XX },
1011
  { "cmovae", Gv, Ev, XX },
1012
  { "cmove", Gv, Ev, XX },
1013
  { "cmovne", Gv, Ev, XX },
1014
  { "cmovbe", Gv, Ev, XX },
1015
  { "cmova", Gv, Ev, XX },
1016
  /* 48 */
1017
  { "cmovs", Gv, Ev, XX },
1018
  { "cmovns", Gv, Ev, XX },
1019
  { "cmovp", Gv, Ev, XX },
1020
  { "cmovnp", Gv, Ev, XX },
1021
  { "cmovl", Gv, Ev, XX },
1022
  { "cmovge", Gv, Ev, XX },
1023
  { "cmovle", Gv, Ev, XX },
1024
  { "cmovg", Gv, Ev, XX },
1025
  /* 50 */
1026
  { "movmskps", Gv, EX, XX },
1027
  { PREGRP13 },
1028
  { PREGRP12 },
1029
  { PREGRP11 },
1030
  { "andps", XM, EX, XX },
1031
  { "andnps", XM, EX, XX },
1032
  { "orps", XM, EX, XX },
1033
  { "xorps", XM, EX, XX },
1034
  /* 58 */
1035
  { PREGRP0 },
1036
  { PREGRP10 },
1037
  { "(bad)", XX, XX, XX },
1038
  { "(bad)", XX, XX, XX },
1039
  { PREGRP14 },
1040
  { PREGRP7 },
1041
  { PREGRP5 },
1042
  { PREGRP6 },
1043
  /* 60 */
1044
  { "punpcklbw", MX, EM, XX },
1045
  { "punpcklwd", MX, EM, XX },
1046
  { "punpckldq", MX, EM, XX },
1047
  { "packsswb", MX, EM, XX },
1048
  { "pcmpgtb", MX, EM, XX },
1049
  { "pcmpgtw", MX, EM, XX },
1050
  { "pcmpgtd", MX, EM, XX },
1051
  { "packuswb", MX, EM, XX },
1052
  /* 68 */
1053
  { "punpckhbw", MX, EM, XX },
1054
  { "punpckhwd", MX, EM, XX },
1055
  { "punpckhdq", MX, EM, XX },
1056
  { "packssdw", MX, EM, XX },
1057
  { "(bad)", XX, XX, XX },
1058
  { "(bad)", XX, XX, XX },
1059
  { "movd", MX, Ed, XX },
1060
  { "movq", MX, EM, XX },
1061
  /* 70 */
1062
  { "pshufw", MX, EM, Ib },
1063
  { GRP10 },
1064
  { GRP11 },
1065
  { GRP12 },
1066
  { "pcmpeqb", MX, EM, XX },
1067
  { "pcmpeqw", MX, EM, XX },
1068
  { "pcmpeqd", MX, EM, XX },
1069
  { "emms", XX, XX, XX },
1070
  /* 78 */
1071
  { "(bad)", XX, XX, XX },
1072
  { "(bad)", XX, XX, XX },
1073
  { "(bad)", XX, XX, XX },
1074
  { "(bad)", XX, XX, XX },
1075
  { "(bad)", XX, XX, XX },
1076
  { "(bad)", XX, XX, XX },
1077
  { "movd", Ed, MX, XX },
1078
  { "movq", EM, MX, XX },
1079
  /* 80 */
1080
  { "jo", Jv, XX, XX },
1081
  { "jno", Jv, XX, XX },
1082
  { "jb", Jv, XX, XX },
1083
  { "jae", Jv, XX, XX },
1084
  { "je", Jv, XX, XX },
1085
  { "jne", Jv, XX, XX },
1086
  { "jbe", Jv, XX, XX },
1087
  { "ja", Jv, XX, XX },
1088
  /* 88 */
1089
  { "js", Jv, XX, XX },
1090
  { "jns", Jv, XX, XX },
1091
  { "jp", Jv, XX, XX },
1092
  { "jnp", Jv, XX, XX },
1093
  { "jl", Jv, XX, XX },
1094
  { "jge", Jv, XX, XX },
1095
  { "jle", Jv, XX, XX },
1096
  { "jg", Jv, XX, XX },
1097
  /* 90 */
1098
  { "seto", Eb, XX, XX },
1099
  { "setno", Eb, XX, XX },
1100
  { "setb", Eb, XX, XX },
1101
  { "setae", Eb, XX, XX },
1102
  { "sete", Eb, XX, XX },
1103
  { "setne", Eb, XX, XX },
1104
  { "setbe", Eb, XX, XX },
1105
  { "seta", Eb, XX, XX },
1106
  /* 98 */
1107
  { "sets", Eb, XX, XX },
1108
  { "setns", Eb, XX, XX },
1109
  { "setp", Eb, XX, XX },
1110
  { "setnp", Eb, XX, XX },
1111
  { "setl", Eb, XX, XX },
1112
  { "setge", Eb, XX, XX },
1113
  { "setle", Eb, XX, XX },
1114
  { "setg", Eb, XX, XX },
1115
  /* a0 */
1116
  { "pushP", fs, XX, XX },
1117
  { "popP", fs, XX, XX },
1118
  { "cpuid", XX, XX, XX },
1119
  { "btS", Ev, Gv, XX },
1120
  { "shldS", Ev, Gv, Ib },
1121
  { "shldS", Ev, Gv, CL },
1122
  { "(bad)", XX, XX, XX },
1123
  { "(bad)", XX, XX, XX },
1124
  /* a8 */
1125
  { "pushP", gs, XX, XX },
1126
  { "popP", gs, XX, XX },
1127
  { "rsm", XX, XX, XX },
1128
  { "btsS", Ev, Gv, XX },
1129
  { "shrdS", Ev, Gv, Ib },
1130
  { "shrdS", Ev, Gv, CL },
1131
  { GRP13 },
1132
  { "imulS", Gv, Ev, XX },
1133
  /* b0 */
1134
  { "cmpxchgB", Eb, Gb, XX },
1135
  { "cmpxchgS", Ev, Gv, XX },
1136
  { "lssS", Gv, Mp, XX },
1137
  { "btrS", Ev, Gv, XX },
1138
  { "lfsS", Gv, Mp, XX },
1139
  { "lgsS", Gv, Mp, XX },
1140
  { "movzbR", Gv, Eb, XX },
1141
  { "movzwR", Gv, Ew, XX }, /* yes, there really is movzww ! */
1142
  /* b8 */
1143
  { "(bad)", XX, XX, XX },
1144
  { "ud2b", XX, XX, XX },
1145
  { GRP8 },
1146
  { "btcS", Ev, Gv, XX },
1147
  { "bsfS", Gv, Ev, XX },
1148
  { "bsrS", Gv, Ev, XX },
1149
  { "movsbR", Gv, Eb, XX },
1150
  { "movswR", Gv, Ew, XX }, /* yes, there really is movsww ! */
1151
  /* c0 */
1152
  { "xaddB", Eb, Gb, XX },
1153
  { "xaddS", Ev, Gv, XX },
1154
  { PREGRP1 },
1155
  { "(bad)", XX, XX, XX },
1156
  { "pinsrw", MX, Ev, Ib },
1157
  { "pextrw", Ev, MX, Ib },
1158
  { "shufps", XM, EX, Ib },
1159
  { GRP9 },
1160
  /* c8 */
1161
  { "bswap", eAX, XX, XX },     /* bswap doesn't support 16 bit regs */
1162
  { "bswap", eCX, XX, XX },
1163
  { "bswap", eDX, XX, XX },
1164
  { "bswap", eBX, XX, XX },
1165
  { "bswap", eSP, XX, XX },
1166
  { "bswap", eBP, XX, XX },
1167
  { "bswap", eSI, XX, XX },
1168
  { "bswap", eDI, XX, XX },
1169
  /* d0 */
1170
  { "(bad)", XX, XX, XX },
1171
  { "psrlw", MX, EM, XX },
1172
  { "psrld", MX, EM, XX },
1173
  { "psrlq", MX, EM, XX },
1174
  { "(bad)", XX, XX, XX },
1175
  { "pmullw", MX, EM, XX },
1176
  { "(bad)", XX, XX, XX },
1177
  { "pmovmskb", Ev, MX, XX },
1178
  /* d8 */
1179
  { "psubusb", MX, EM, XX },
1180
  { "psubusw", MX, EM, XX },
1181
  { "pminub", MX, EM, XX },
1182
  { "pand", MX, EM, XX },
1183
  { "paddusb", MX, EM, XX },
1184
  { "paddusw", MX, EM, XX },
1185
  { "pmaxub", MX, EM, XX },
1186
  { "pandn", MX, EM, XX },
1187
  /* e0 */
1188
  { "pavgb", MX, EM, XX },
1189
  { "psraw", MX, EM, XX },
1190
  { "psrad", MX, EM, XX },
1191
  { "pavgw", MX, EM, XX },
1192
  { "pmulhuw", MX, EM, XX },
1193
  { "pmulhw", MX, EM, XX },
1194
  { "(bad)", XX, XX, XX },
1195
  { "movntq", Ev, MX, XX },
1196
  /* e8 */
1197
  { "psubsb", MX, EM, XX },
1198
  { "psubsw", MX, EM, XX },
1199
  { "pminsw", MX, EM, XX },
1200
  { "por", MX, EM, XX },
1201
  { "paddsb", MX, EM, XX },
1202
  { "paddsw", MX, EM, XX },
1203
  { "pmaxsw", MX, EM, XX },
1204
  { "pxor", MX, EM, XX },
1205
  /* f0 */
1206
  { "(bad)", XX, XX, XX },
1207
  { "psllw", MX, EM, XX },
1208
  { "pslld", MX, EM, XX },
1209
  { "psllq", MX, EM, XX },
1210
  { "(bad)", XX, XX, XX },
1211
  { "pmaddwd", MX, EM, XX },
1212
  { "psadbw", MX, EM, XX },
1213
  { "maskmovq", MX, EM, XX },
1214
  /* f8 */
1215
  { "psubb", MX, EM, XX },
1216
  { "psubw", MX, EM, XX },
1217
  { "psubd", MX, EM, XX },
1218
  { "(bad)", XX, XX, XX },
1219
  { "paddb", MX, EM, XX },
1220
  { "paddw", MX, EM, XX },
1221
  { "paddd", MX, EM, XX },
1222
  { "(bad)", XX, XX, XX }
1223
};
1224
 
1225
static const struct dis386 dis386_twobyte_intel[] = {
1226
  /* 00 */
1227
  { GRP6 },
1228
  { GRP7 },
1229
  { "lar", Gv, Ew, XX },
1230
  { "lsl", Gv, Ew, XX },
1231
  { "(bad)", XX, XX, XX },
1232
  { "(bad)", XX, XX, XX },
1233
  { "clts", XX, XX, XX },
1234
  { "(bad)", XX, XX, XX },
1235
  /* 08 */
1236
  { "invd", XX, XX, XX },
1237
  { "wbinvd", XX, XX, XX },
1238
  { "(bad)", XX, XX, XX },
1239
  { "ud2a", XX, XX, XX },
1240
  { "(bad)", XX, XX, XX },
1241
  { GRPAMD },
1242
  { "femms" , XX, XX, XX},
1243
  { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
1244
  /* 10 */
1245
  { PREGRP8 },
1246
  { PREGRP9 },
1247
  { "movlps", XM, EX, SIMD_Fixup, 'h' },  /* really only 2 operands */
1248
  { "movlps", EX, XM, SIMD_Fixup, 'h' },
1249
  { "unpcklps", XM, EX, XX },
1250
  { "unpckhps", XM, EX, XX },
1251
  { "movhps", XM, EX, SIMD_Fixup, 'l' },
1252
  { "movhps", EX, XM, SIMD_Fixup, 'l' },
1253
  /* 18 */
1254
  { GRP14 },
1255
  { "(bad)", XX, XX, XX },
1256
  { "(bad)", XX, XX, XX },
1257
  { "(bad)", XX, XX, XX },
1258
  { "(bad)", XX, XX, XX },
1259
  { "(bad)", XX, XX, XX },
1260
  { "(bad)", XX, XX, XX },
1261
  { "(bad)", XX, XX, XX },
1262
  /* 20 */
1263
  /* these are all backward in appendix A of the intel book */
1264
  { "mov", Rd, Cd, XX },
1265
  { "mov", Rd, Dd, XX },
1266
  { "mov", Cd, Rd, XX },
1267
  { "mov", Dd, Rd, XX },
1268
  { "mov", Rd, Td, XX },
1269
  { "(bad)", XX, XX, XX },
1270
  { "mov", Td, Rd, XX },
1271
  { "(bad)", XX, XX, XX },
1272
  /* 28 */
1273
  { "movaps", XM, EX, XX },
1274
  { "movaps", EX, XM, XX },
1275
  { PREGRP2 },
1276
  { "movntps", Ev, XM, XX },
1277
  { PREGRP4 },
1278
  { PREGRP3 },
1279
  { "ucomiss", XM, EX, XX },
1280
  { "comiss", XM, EX, XX },
1281
  /* 30 */
1282
  { "wrmsr", XX, XX, XX },
1283
  { "rdtsc", XX, XX, XX },
1284
  { "rdmsr", XX, XX, XX },
1285
  { "rdpmc", XX, XX, XX },
1286
  { "sysenter", XX, XX, XX },
1287
  { "sysexit", XX, XX, XX },
1288
  { "(bad)", XX, XX, XX },
1289
  { "(bad)", XX, XX, XX },
1290
  /* 38 */
1291
  { "(bad)", XX, XX, XX },
1292
  { "(bad)", XX, XX, XX },
1293
  { "(bad)", XX, XX, XX },
1294
  { "(bad)", XX, XX, XX },
1295
  { "(bad)", XX, XX, XX },
1296
  { "(bad)", XX, XX, XX },
1297
  { "(bad)", XX, XX, XX },
1298
  { "(bad)", XX, XX, XX },
1299
  /* 40 */
1300
  { "cmovo", Gv, Ev, XX },
1301
  { "cmovno", Gv, Ev, XX },
1302
  { "cmovb", Gv, Ev, XX },
1303
  { "cmovae", Gv, Ev, XX },
1304
  { "cmove", Gv, Ev, XX },
1305
  { "cmovne", Gv, Ev, XX },
1306
  { "cmovbe", Gv, Ev, XX },
1307
  { "cmova", Gv, Ev, XX },
1308
  /* 48 */
1309
  { "cmovs", Gv, Ev, XX },
1310
  { "cmovns", Gv, Ev, XX },
1311
  { "cmovp", Gv, Ev, XX },
1312
  { "cmovnp", Gv, Ev, XX },
1313
  { "cmovl", Gv, Ev, XX },
1314
  { "cmovge", Gv, Ev, XX },
1315
  { "cmovle", Gv, Ev, XX },
1316
  { "cmovg", Gv, Ev, XX },
1317
  /* 50 */
1318
  { "movmskps", Gv, EX, XX },
1319
  { PREGRP13 },
1320
  { PREGRP12 },
1321
  { PREGRP11 },
1322
  { "andps", XM, EX, XX },
1323
  { "andnps", XM, EX, XX },
1324
  { "orps", XM, EX, XX },
1325
  { "xorps", XM, EX, XX },
1326
  /* 58 */
1327
  { PREGRP0 },
1328
  { PREGRP10 },
1329
  { "(bad)", XX, XX, XX },
1330
  { "(bad)", XX, XX, XX },
1331
  { PREGRP14 },
1332
  { PREGRP7 },
1333
  { PREGRP5 },
1334
  { PREGRP6 },
1335
  /* 60 */
1336
  { "punpcklbw", MX, EM, XX },
1337
  { "punpcklwd", MX, EM, XX },
1338
  { "punpckldq", MX, EM, XX },
1339
  { "packsswb", MX, EM, XX },
1340
  { "pcmpgtb", MX, EM, XX },
1341
  { "pcmpgtw", MX, EM, XX },
1342
  { "pcmpgtd", MX, EM, XX },
1343
  { "packuswb", MX, EM, XX },
1344
  /* 68 */
1345
  { "punpckhbw", MX, EM, XX },
1346
  { "punpckhwd", MX, EM, XX },
1347
  { "punpckhdq", MX, EM, XX },
1348
  { "packssdw", MX, EM, XX },
1349
  { "(bad)", XX, XX, XX },
1350
  { "(bad)", XX, XX, XX },
1351
  { "movd", MX, Ed, XX },
1352
  { "movq", MX, EM, XX },
1353
  /* 70 */
1354
  { "pshufw", MX, EM, Ib },
1355
  { GRP10 },
1356
  { GRP11 },
1357
  { GRP12 },
1358
  { "pcmpeqb", MX, EM, XX },
1359
  { "pcmpeqw", MX, EM, XX },
1360
  { "pcmpeqd", MX, EM, XX },
1361
  { "emms", XX, XX, XX },
1362
  /* 78 */
1363
  { "(bad)", XX, XX, XX },
1364
  { "(bad)", XX, XX, XX },
1365
  { "(bad)", XX, XX, XX },
1366
  { "(bad)", XX, XX, XX },
1367
  { "(bad)", XX, XX, XX },
1368
  { "(bad)", XX, XX, XX },
1369
  { "movd", Ed, MX, XX },
1370
  { "movq", EM, MX, XX },
1371
  /* 80 */
1372
  { "jo", Jv, XX, XX },
1373
  { "jno", Jv, XX, XX },
1374
  { "jb", Jv, XX, XX },
1375
  { "jae", Jv, XX, XX },
1376
  { "je", Jv, XX, XX },
1377
  { "jne", Jv, XX, XX },
1378
  { "jbe", Jv, XX, XX },
1379
  { "ja", Jv, XX, XX },
1380
  /* 88 */
1381
  { "js", Jv, XX, XX },
1382
  { "jns", Jv, XX, XX },
1383
  { "jp", Jv, XX, XX },
1384
  { "jnp", Jv, XX, XX },
1385
  { "jl", Jv, XX, XX },
1386
  { "jge", Jv, XX, XX },
1387
  { "jle", Jv, XX, XX },
1388
  { "jg", Jv, XX, XX },
1389
  /* 90 */
1390
  { "seto", Eb, XX, XX },
1391
  { "setno", Eb, XX, XX },
1392
  { "setb", Eb, XX, XX },
1393
  { "setae", Eb, XX, XX },
1394
  { "sete", Eb, XX, XX },
1395
  { "setne", Eb, XX, XX },
1396
  { "setbe", Eb, XX, XX },
1397
  { "seta", Eb, XX, XX },
1398
  /* 98 */
1399
  { "sets", Eb, XX, XX },
1400
  { "setns", Eb, XX, XX },
1401
  { "setp", Eb, XX, XX },
1402
  { "setnp", Eb, XX, XX },
1403
  { "setl", Eb, XX, XX },
1404
  { "setge", Eb, XX, XX },
1405
  { "setle", Eb, XX, XX },
1406
  { "setg", Eb, XX, XX },
1407
  /* a0 */
1408
  { "push", fs, XX, XX },
1409
  { "pop", fs, XX, XX },
1410
  { "cpuid", XX, XX, XX },
1411
  { "bt", Ev, Gv, XX },
1412
  { "shld", Ev, Gv, Ib },
1413
  { "shld", Ev, Gv, CL },
1414
  { "(bad)", XX, XX, XX },
1415
  { "(bad)", XX, XX, XX },
1416
  /* a8 */
1417
  { "push", gs, XX, XX },
1418
  { "pop", gs, XX, XX },
1419
  { "rsm" , XX, XX, XX},
1420
  { "bts", Ev, Gv, XX },
1421
  { "shrd", Ev, Gv, Ib },
1422
  { "shrd", Ev, Gv, CL },
1423
  { GRP13 },
1424
  { "imul", Gv, Ev, XX },
1425
  /* b0 */
1426
  { "cmpxchg", Eb, Gb, XX },
1427
  { "cmpxchg", Ev, Gv, XX },
1428
  { "lss", Gv, Mp, XX },
1429
  { "btr", Ev, Gv, XX },
1430
  { "lfs", Gv, Mp, XX },
1431
  { "lgs", Gv, Mp, XX },
1432
  { "movzx", Gv, Eb, XX },
1433
  { "movzx", Gv, Ew, XX },
1434
  /* b8 */
1435
  { "(bad)", XX, XX, XX },
1436
  { "ud2b", XX, XX, XX },
1437
  { GRP8 },
1438
  { "btc", Ev, Gv, XX },
1439
  { "bsf", Gv, Ev, XX },
1440
  { "bsr", Gv, Ev, XX },
1441
  { "movsx", Gv, Eb, XX },
1442
  { "movsx", Gv, Ew, XX },
1443
  /* c0 */
1444
  { "xadd", Eb, Gb, XX },
1445
  { "xadd", Ev, Gv, XX },
1446
  { PREGRP1 },
1447
  { "(bad)", XX, XX, XX },
1448
  { "pinsrw", MX, Ev, Ib },
1449
  { "pextrw", Ev, MX, Ib },
1450
  { "shufps", XM, EX, Ib },
1451
  { GRP9 },
1452
  /* c8 */
1453
  { "bswap", eAX, XX, XX },     /* bswap doesn't support 16 bit regs */
1454
  { "bswap", eCX, XX, XX },
1455
  { "bswap", eDX, XX, XX },
1456
  { "bswap", eBX, XX, XX },
1457
  { "bswap", eSP, XX, XX },
1458
  { "bswap", eBP, XX, XX },
1459
  { "bswap", eSI, XX, XX },
1460
  { "bswap", eDI, XX, XX },
1461
  /* d0 */
1462
  { "(bad)", XX, XX, XX },
1463
  { "psrlw", MX, EM, XX },
1464
  { "psrld", MX, EM, XX },
1465
  { "psrlq", MX, EM, XX },
1466
  { "(bad)", XX, XX, XX },
1467
  { "pmullw", MX, EM, XX },
1468
  { "(bad)", XX, XX, XX },
1469
  { "pmovmskb", Ev, MX, XX },
1470
  /* d8 */
1471
  { "psubusb", MX, EM, XX },
1472
  { "psubusw", MX, EM, XX },
1473
  { "pminub", MX, EM, XX },
1474
  { "pand", MX, EM, XX },
1475
  { "paddusb", MX, EM, XX },
1476
  { "paddusw", MX, EM, XX },
1477
  { "pmaxub", MX, EM, XX },
1478
  { "pandn", MX, EM, XX },
1479
  /* e0 */
1480
  { "pavgb", MX, EM, XX },
1481
  { "psraw", MX, EM, XX },
1482
  { "psrad", MX, EM, XX },
1483
  { "pavgw", MX, EM, XX },
1484
  { "pmulhuw", MX, EM, XX },
1485
  { "pmulhw", MX, EM, XX },
1486
  { "(bad)", XX, XX, XX },
1487
  { "movntq", Ev, MX, XX },
1488
  /* e8 */
1489
  { "psubsb", MX, EM, XX },
1490
  { "psubsw", MX, EM, XX },
1491
  { "pminsw", MX, EM, XX },
1492
  { "por", MX, EM, XX },
1493
  { "paddsb", MX, EM, XX },
1494
  { "paddsw", MX, EM, XX },
1495
  { "pmaxsw", MX, EM, XX },
1496
  { "pxor", MX, EM, XX },
1497
  /* f0 */
1498
  { "(bad)", XX, XX, XX },
1499
  { "psllw", MX, EM, XX },
1500
  { "pslld", MX, EM, XX },
1501
  { "psllq", MX, EM, XX },
1502
  { "(bad)", XX, XX, XX },
1503
  { "pmaddwd", MX, EM, XX },
1504
  { "psadbw", MX, EM, XX },
1505
  { "maskmovq", MX, EM, XX },
1506
  /* f8 */
1507
  { "psubb", MX, EM, XX },
1508
  { "psubw", MX, EM, XX },
1509
  { "psubd", MX, EM, XX },
1510
  { "(bad)", XX, XX, XX },
1511
  { "paddb", MX, EM, XX },
1512
  { "paddw", MX, EM, XX },
1513
  { "paddd", MX, EM, XX },
1514
  { "(bad)", XX, XX, XX }
1515
};
1516
 
1517
static const unsigned char onebyte_has_modrm[256] = {
1518
  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1519
  /*       -------------------------------        */
1520
  /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1521
  /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1522
  /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1523
  /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1524
  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1525
  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1526
  /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1527
  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1528
  /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1529
  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1530
  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1531
  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1532
  /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1533
  /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1534
  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1535
  /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1  /* f0 */
1536
  /*       -------------------------------        */
1537
  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1538
};
1539
 
1540
static const unsigned char twobyte_has_modrm[256] = {
1541
  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1542
  /*       -------------------------------        */
1543
  /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1544
  /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1545
  /* 20 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 2f */
1546
  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1547
  /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1548
  /* 50 */ 1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1, /* 5f */
1549
  /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
1550
  /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
1551
  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1552
  /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1553
  /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1554
  /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1555
  /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1556
  /* d0 */ 0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, /* df */
1557
  /* e0 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* ef */
1558
  /* f0 */ 0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0  /* ff */
1559
  /*       -------------------------------        */
1560
  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1561
};
1562
 
1563
static const unsigned char twobyte_uses_f3_prefix[256] = {
1564
  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1565
  /*       -------------------------------        */
1566
  /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1567
  /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1568
  /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1569
  /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1570
  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1571
  /* 50 */ 0,1,1,1,0,0,0,0,1,1,0,0,1,1,1,1, /* 5f */
1572
  /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1573
  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1574
  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1575
  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1576
  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1577
  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1578
  /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1579
  /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1580
  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1581
  /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  /* ff */
1582
  /*       -------------------------------        */
1583
  /*       0 1 2 3 4 5 6 7 8 9 a b c d e f        */
1584
};
1585
 
1586
static char obuf[100];
1587
static char *obufp;
1588
static char scratchbuf[100];
1589
static unsigned char *start_codep;
1590
static unsigned char *insn_codep;
1591
static unsigned char *codep;
1592
static disassemble_info *the_info;
1593
static int mod;
1594
static int rm;
1595
static int reg;
1596
static void oappend PARAMS ((const char *s));
1597
 
1598
static const char *names32[]={
1599
  "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
1600
};
1601
static const char *names16[] = {
1602
  "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
1603
};
1604
static const char *names8[] = {
1605
  "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
1606
};
1607
static const char *names_seg[] = {
1608
  "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1609
};
1610
static const char *index16[] = {
1611
  "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx"
1612
};
1613
 
1614
static const struct dis386 grps[][8] = {
1615
  /* GRP1b */
1616
  {
1617
    { "addA",   Eb, Ib, XX },
1618
    { "orA",    Eb, Ib, XX },
1619
    { "adcA",   Eb, Ib, XX },
1620
    { "sbbA",   Eb, Ib, XX },
1621
    { "andA",   Eb, Ib, XX },
1622
    { "subA",   Eb, Ib, XX },
1623
    { "xorA",   Eb, Ib, XX },
1624
    { "cmpA",   Eb, Ib, XX }
1625
  },
1626
  /* GRP1S */
1627
  {
1628
    { "addQ",   Ev, Iv, XX },
1629
    { "orQ",    Ev, Iv, XX },
1630
    { "adcQ",   Ev, Iv, XX },
1631
    { "sbbQ",   Ev, Iv, XX },
1632
    { "andQ",   Ev, Iv, XX },
1633
    { "subQ",   Ev, Iv, XX },
1634
    { "xorQ",   Ev, Iv, XX },
1635
    { "cmpQ",   Ev, Iv, XX }
1636
  },
1637
  /* GRP1Ss */
1638
  {
1639
    { "addQ",   Ev, sIb, XX },
1640
    { "orQ",    Ev, sIb, XX },
1641
    { "adcQ",   Ev, sIb, XX },
1642
    { "sbbQ",   Ev, sIb, XX },
1643
    { "andQ",   Ev, sIb, XX },
1644
    { "subQ",   Ev, sIb, XX },
1645
    { "xorQ",   Ev, sIb, XX },
1646
    { "cmpQ",   Ev, sIb, XX }
1647
  },
1648
  /* GRP2b */
1649
  {
1650
    { "rolA",   Eb, Ib, XX },
1651
    { "rorA",   Eb, Ib, XX },
1652
    { "rclA",   Eb, Ib, XX },
1653
    { "rcrA",   Eb, Ib, XX },
1654
    { "shlA",   Eb, Ib, XX },
1655
    { "shrA",   Eb, Ib, XX },
1656
    { "(bad)",  XX, XX, XX },
1657
    { "sarA",   Eb, Ib, XX },
1658
  },
1659
  /* GRP2S */
1660
  {
1661
    { "rolQ",   Ev, Ib, XX },
1662
    { "rorQ",   Ev, Ib, XX },
1663
    { "rclQ",   Ev, Ib, XX },
1664
    { "rcrQ",   Ev, Ib, XX },
1665
    { "shlQ",   Ev, Ib, XX },
1666
    { "shrQ",   Ev, Ib, XX },
1667
    { "(bad)",  XX, XX, XX },
1668
    { "sarQ",   Ev, Ib, XX },
1669
  },
1670
  /* GRP2b_one */
1671
  {
1672
    { "rolA",   Eb, XX, XX },
1673
    { "rorA",   Eb, XX, XX },
1674
    { "rclA",   Eb, XX, XX },
1675
    { "rcrA",   Eb, XX, XX },
1676
    { "shlA",   Eb, XX, XX },
1677
    { "shrA",   Eb, XX, XX },
1678
    { "(bad)",  XX, XX, XX },
1679
    { "sarA",   Eb, XX, XX },
1680
  },
1681
  /* GRP2S_one */
1682
  {
1683
    { "rolQ",   Ev, XX, XX },
1684
    { "rorQ",   Ev, XX, XX },
1685
    { "rclQ",   Ev, XX, XX },
1686
    { "rcrQ",   Ev, XX, XX },
1687
    { "shlQ",   Ev, XX, XX },
1688
    { "shrQ",   Ev, XX, XX },
1689
    { "(bad)",  XX, XX, XX},
1690
    { "sarQ",   Ev, XX, XX },
1691
  },
1692
  /* GRP2b_cl */
1693
  {
1694
    { "rolA",   Eb, CL, XX },
1695
    { "rorA",   Eb, CL, XX },
1696
    { "rclA",   Eb, CL, XX },
1697
    { "rcrA",   Eb, CL, XX },
1698
    { "shlA",   Eb, CL, XX },
1699
    { "shrA",   Eb, CL, XX },
1700
    { "(bad)",  XX, XX, XX },
1701
    { "sarA",   Eb, CL, XX },
1702
  },
1703
  /* GRP2S_cl */
1704
  {
1705
    { "rolQ",   Ev, CL, XX },
1706
    { "rorQ",   Ev, CL, XX },
1707
    { "rclQ",   Ev, CL, XX },
1708
    { "rcrQ",   Ev, CL, XX },
1709
    { "shlQ",   Ev, CL, XX },
1710
    { "shrQ",   Ev, CL, XX },
1711
    { "(bad)",  XX, XX, XX },
1712
    { "sarQ",   Ev, CL, XX }
1713
  },
1714
  /* GRP3b */
1715
  {
1716
    { "testA",  Eb, Ib, XX },
1717
    { "(bad)",  Eb, XX, XX },
1718
    { "notA",   Eb, XX, XX },
1719
    { "negA",   Eb, XX, XX },
1720
    { "mulB",   AL, Eb, XX },
1721
    { "imulB",  AL, Eb, XX },
1722
    { "divB",   AL, Eb, XX },
1723
    { "idivB",  AL, Eb, XX }
1724
  },
1725
  /* GRP3S */
1726
  {
1727
    { "testQ",  Ev, Iv, XX },
1728
    { "(bad)",  XX, XX, XX },
1729
    { "notQ",   Ev, XX, XX },
1730
    { "negQ",   Ev, XX, XX },
1731
    { "mulS",   eAX, Ev, XX },
1732
    { "imulS",  eAX, Ev, XX },
1733
    { "divS",   eAX, Ev, XX },
1734
    { "idivS",  eAX, Ev, XX },
1735
  },
1736
  /* GRP4 */
1737
  {
1738
    { "incA",   Eb, XX, XX },
1739
    { "decA",   Eb, XX, XX },
1740
    { "(bad)",  XX, XX, XX },
1741
    { "(bad)",  XX, XX, XX },
1742
    { "(bad)",  XX, XX, XX },
1743
    { "(bad)",  XX, XX, XX },
1744
    { "(bad)",  XX, XX, XX },
1745
    { "(bad)",  XX, XX, XX },
1746
  },
1747
  /* GRP5 */
1748
  {
1749
    { "incQ",   Ev, XX, XX },
1750
    { "decQ",   Ev, XX, XX },
1751
    { "callP",  indirEv, XX, XX },
1752
    { "lcallP", indirEv, XX, XX },
1753
    { "jmpP",   indirEv, XX, XX },
1754
    { "ljmpP",  indirEv, XX, XX },
1755
    { "pushQ",  Ev, XX, XX },
1756
    { "(bad)",  XX, XX, XX },
1757
  },
1758
  /* GRP6 */
1759
  {
1760
    { "sldt",   Ew, XX, XX },
1761
    { "str",    Ew, XX, XX },
1762
    { "lldt",   Ew, XX, XX },
1763
    { "ltr",    Ew, XX, XX },
1764
    { "verr",   Ew, XX, XX },
1765
    { "verw",   Ew, XX, XX },
1766
    { "(bad)",  XX, XX, XX },
1767
    { "(bad)",  XX, XX, XX }
1768
  },
1769
  /* GRP7 */
1770
  {
1771
    { "sgdt", Ew, XX, XX },
1772
    { "sidt", Ew, XX, XX },
1773
    { "lgdt", Ew, XX, XX },
1774
    { "lidt", Ew, XX, XX },
1775
    { "smsw", Ew, XX, XX },
1776
    { "(bad)", XX, XX, XX },
1777
    { "lmsw", Ew, XX, XX },
1778
    { "invlpg", Ew, XX, XX },
1779
  },
1780
  /* GRP8 */
1781
  {
1782
    { "(bad)",  XX, XX, XX },
1783
    { "(bad)",  XX, XX, XX },
1784
    { "(bad)",  XX, XX, XX },
1785
    { "(bad)",  XX, XX, XX },
1786
    { "btQ",    Ev, Ib, XX },
1787
    { "btsQ",   Ev, Ib, XX },
1788
    { "btrQ",   Ev, Ib, XX },
1789
    { "btcQ",   Ev, Ib, XX },
1790
  },
1791
  /* GRP9 */
1792
  {
1793
    { "(bad)",  XX, XX, XX },
1794
    { "cmpxchg8b", Ev, XX, XX },
1795
    { "(bad)",  XX, XX, XX },
1796
    { "(bad)",  XX, XX, XX },
1797
    { "(bad)",  XX, XX, XX },
1798
    { "(bad)",  XX, XX, XX },
1799
    { "(bad)",  XX, XX, XX },
1800
    { "(bad)",  XX, XX, XX },
1801
  },
1802
  /* GRP10 */
1803
  {
1804
    { "(bad)",  XX, XX, XX },
1805
    { "(bad)",  XX, XX, XX },
1806
    { "psrlw",  MS, Ib, XX },
1807
    { "(bad)",  XX, XX, XX },
1808
    { "psraw",  MS, Ib, XX },
1809
    { "(bad)",  XX, XX, XX },
1810
    { "psllw",  MS, Ib, XX },
1811
    { "(bad)",  XX, XX, XX },
1812
  },
1813
  /* GRP11 */
1814
  {
1815
    { "(bad)",  XX, XX, XX },
1816
    { "(bad)",  XX, XX, XX },
1817
    { "psrld",  MS, Ib, XX },
1818
    { "(bad)",  XX, XX, XX },
1819
    { "psrad",  MS, Ib, XX },
1820
    { "(bad)",  XX, XX, XX },
1821
    { "pslld",  MS, Ib, XX },
1822
    { "(bad)",  XX, XX, XX },
1823
  },
1824
  /* GRP12 */
1825
  {
1826
    { "(bad)",  XX, XX, XX },
1827
    { "(bad)",  XX, XX, XX },
1828
    { "psrlq",  MS, Ib, XX },
1829
    { "(bad)",  XX, XX, XX },
1830
    { "(bad)",  XX, XX, XX },
1831
    { "(bad)",  XX, XX, XX },
1832
    { "psllq",  MS, Ib, XX },
1833
    { "(bad)",  XX, XX, XX },
1834
  },
1835
  /* GRP13 */
1836
  {
1837
    { "fxsave", Ev, XX, XX },
1838
    { "fxrstor", Ev, XX, XX },
1839
    { "ldmxcsr", Ev, XX, XX },
1840
    { "stmxcsr", Ev, XX, XX },
1841
    { "(bad)",  XX, XX, XX },
1842
    { "(bad)",  XX, XX, XX },
1843
    { "(bad)",  XX, XX, XX },
1844
    { "sfence", None, XX, XX },
1845
  },
1846
  /* GRP14 */
1847
  {
1848
    { "prefetchnta", Ev, XX, XX },
1849
    { "prefetcht0", Ev, XX, XX },
1850
    { "prefetcht1", Ev, XX, XX },
1851
    { "prefetcht2", Ev, XX, XX },
1852
    { "(bad)",  XX, XX, XX },
1853
    { "(bad)",  XX, XX, XX },
1854
    { "(bad)",  XX, XX, XX },
1855
    { "(bad)",  XX, XX, XX },
1856
  },
1857
  /* GRPAMD */
1858
  {
1859
    { "prefetch", Eb, XX, XX },
1860
    { "prefetchw", Eb, XX, XX },
1861
    { "(bad)",  XX, XX, XX },
1862
    { "(bad)",  XX, XX, XX },
1863
    { "(bad)",  XX, XX, XX },
1864
    { "(bad)",  XX, XX, XX },
1865
    { "(bad)",  XX, XX, XX },
1866
    { "(bad)",  XX, XX, XX },
1867
  }
1868
 
1869
};
1870
 
1871
static const struct dis386 prefix_user_table[][2] = {
1872
  /* PREGRP0 */
1873
  {
1874
    { "addps", XM, EX, XX },
1875
    { "addss", XM, EX, XX },
1876
  },
1877
  /* PREGRP1 */
1878
  {
1879
    { "", XM, EX, OPSIMD },     /* See OP_SIMD_SUFFIX */
1880
    { "", XM, EX, OPSIMD },
1881
  },
1882
  /* PREGRP2 */
1883
  {
1884
    { "cvtpi2ps", XM, EM, XX },
1885
    { "cvtsi2ss", XM, Ev, XX },
1886
  },
1887
  /* PREGRP3 */
1888
  {
1889
    { "cvtps2pi", MX, EX, XX },
1890
    { "cvtss2si", Gv, EX, XX },
1891
  },
1892
  /* PREGRP4 */
1893
  {
1894
    { "cvttps2pi", MX, EX, XX },
1895
    { "cvttss2si", Gv, EX, XX },
1896
  },
1897
  /* PREGRP5 */
1898
  {
1899
    { "divps", XM, EX, XX },
1900
    { "divss", XM, EX, XX },
1901
  },
1902
  /* PREGRP6 */
1903
  {
1904
    { "maxps", XM, EX, XX },
1905
    { "maxss", XM, EX, XX },
1906
  },
1907
  /* PREGRP7 */
1908
  {
1909
    { "minps", XM, EX, XX },
1910
    { "minss", XM, EX, XX },
1911
  },
1912
  /* PREGRP8 */
1913
  {
1914
    { "movups", XM, EX, XX },
1915
    { "movss", XM, EX, XX },
1916
  },
1917
  /* PREGRP9 */
1918
  {
1919
    { "movups", EX, XM, XX },
1920
    { "movss", EX, XM, XX },
1921
  },
1922
  /* PREGRP10 */
1923
  {
1924
    { "mulps", XM, EX, XX },
1925
    { "mulss", XM, EX, XX },
1926
  },
1927
  /* PREGRP11 */
1928
  {
1929
    { "rcpps", XM, EX, XX },
1930
    { "rcpss", XM, EX, XX },
1931
  },
1932
  /* PREGRP12 */
1933
  {
1934
    { "rsqrtps", XM, EX, XX },
1935
    { "rsqrtss", XM, EX, XX },
1936
  },
1937
  /* PREGRP13 */
1938
  {
1939
    { "sqrtps", XM, EX, XX },
1940
    { "sqrtss", XM, EX, XX },
1941
  },
1942
  /* PREGRP14 */
1943
  {
1944
    { "subps", XM, EX, XX },
1945
    { "subss", XM, EX, XX },
1946
  }
1947
};
1948
 
1949
#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1950
 
1951
static void
1952
ckprefix ()
1953
{
1954
  prefixes = 0;
1955
  used_prefixes = 0;
1956
  while (1)
1957
    {
1958
      FETCH_DATA (the_info, codep + 1);
1959
      switch (*codep)
1960
        {
1961
        case 0xf3:
1962
          prefixes |= PREFIX_REPZ;
1963
          break;
1964
        case 0xf2:
1965
          prefixes |= PREFIX_REPNZ;
1966
          break;
1967
        case 0xf0:
1968
          prefixes |= PREFIX_LOCK;
1969
          break;
1970
        case 0x2e:
1971
          prefixes |= PREFIX_CS;
1972
          break;
1973
        case 0x36:
1974
          prefixes |= PREFIX_SS;
1975
          break;
1976
        case 0x3e:
1977
          prefixes |= PREFIX_DS;
1978
          break;
1979
        case 0x26:
1980
          prefixes |= PREFIX_ES;
1981
          break;
1982
        case 0x64:
1983
          prefixes |= PREFIX_FS;
1984
          break;
1985
        case 0x65:
1986
          prefixes |= PREFIX_GS;
1987
          break;
1988
        case 0x66:
1989
          prefixes |= PREFIX_DATA;
1990
          break;
1991
        case 0x67:
1992
          prefixes |= PREFIX_ADDR;
1993
          break;
1994
        case FWAIT_OPCODE:
1995
          /* fwait is really an instruction.  If there are prefixes
1996
             before the fwait, they belong to the fwait, *not* to the
1997
             following instruction.  */
1998
          if (prefixes)
1999
            {
2000
              prefixes |= PREFIX_FWAIT;
2001
              codep++;
2002
              return;
2003
            }
2004
          prefixes = PREFIX_FWAIT;
2005
          break;
2006
        default:
2007
          return;
2008
        }
2009
      codep++;
2010
    }
2011
}
2012
 
2013
/* Return the name of the prefix byte PREF, or NULL if PREF is not a
2014
   prefix byte.  */
2015
 
2016
static const char *
2017
prefix_name (pref, sizeflag)
2018
     int pref;
2019
     int sizeflag;
2020
{
2021
  switch (pref)
2022
    {
2023
    case 0xf3:
2024
      return "repz";
2025
    case 0xf2:
2026
      return "repnz";
2027
    case 0xf0:
2028
      return "lock";
2029
    case 0x2e:
2030
      return "cs";
2031
    case 0x36:
2032
      return "ss";
2033
    case 0x3e:
2034
      return "ds";
2035
    case 0x26:
2036
      return "es";
2037
    case 0x64:
2038
      return "fs";
2039
    case 0x65:
2040
      return "gs";
2041
    case 0x66:
2042
      return (sizeflag & DFLAG) ? "data16" : "data32";
2043
    case 0x67:
2044
      return (sizeflag & AFLAG) ? "addr16" : "addr32";
2045
    case FWAIT_OPCODE:
2046
      return "fwait";
2047
    default:
2048
      return NULL;
2049
    }
2050
}
2051
 
2052
static char op1out[100], op2out[100], op3out[100];
2053
static int op_ad, op_index[3];
2054
static unsigned int op_address[3];
2055
static unsigned int start_pc;
2056
 
2057
 
2058
/*
2059
 *   On the 386's of 1988, the maximum length of an instruction is 15 bytes.
2060
 *   (see topic "Redundant prefixes" in the "Differences from 8086"
2061
 *   section of the "Virtual 8086 Mode" chapter.)
2062
 * 'pc' should be the address of this instruction, it will
2063
 *   be used to print the target address if this is a relative jump or call
2064
 * The function returns the length of this instruction in bytes.
2065
 */
2066
 
2067
static int print_insn_i386
2068
  PARAMS ((bfd_vma pc, disassemble_info *info));
2069
 
2070
static char intel_syntax;
2071
static char open_char;
2072
static char close_char;
2073
static char separator_char;
2074
static char scale_char;
2075
 
2076
int
2077
print_insn_i386_att (pc, info)
2078
     bfd_vma pc;
2079
     disassemble_info *info;
2080
{
2081
  intel_syntax = 0;
2082
  open_char = '(';
2083
  close_char =  ')';
2084
  separator_char = ',';
2085
  scale_char = ',';
2086
 
2087
  return print_insn_i386 (pc, info);
2088
}
2089
 
2090
int
2091
print_insn_i386_intel (pc, info)
2092
     bfd_vma pc;
2093
     disassemble_info *info;
2094
{
2095
  intel_syntax = 1;
2096
  open_char = '[';
2097
  close_char = ']';
2098
  separator_char = '+';
2099
  scale_char = '*';
2100
 
2101
  return print_insn_i386 (pc, info);
2102
}
2103
 
2104
static int
2105
print_insn_i386 (pc, info)
2106
     bfd_vma pc;
2107
     disassemble_info *info;
2108
{
2109
  const struct dis386 *dp;
2110
  int i;
2111
  int two_source_ops;
2112
  char *first, *second, *third;
2113
  int needcomma;
2114
  unsigned char need_modrm;
2115
  unsigned char uses_f3_prefix;
2116
  VOLATILE int sizeflag;
2117
  VOLATILE int orig_sizeflag;
2118
 
2119
  struct dis_private priv;
2120
  bfd_byte *inbuf = priv.the_buffer;
2121
 
2122
  if (info->mach == bfd_mach_i386_i386
2123
      || info->mach == bfd_mach_i386_i386_intel_syntax)
2124
    sizeflag = AFLAG|DFLAG;
2125
  else if (info->mach == bfd_mach_i386_i8086)
2126
    sizeflag = 0;
2127
  else
2128
    abort ();
2129
  orig_sizeflag = sizeflag;
2130
 
2131
  /* The output looks better if we put 7 bytes on a line, since that
2132
     puts most long word instructions on a single line.  */
2133
  info->bytes_per_line = 7;
2134
 
2135
  info->private_data = (PTR) &priv;
2136
  priv.max_fetched = priv.the_buffer;
2137
  priv.insn_start = pc;
2138
 
2139
  obuf[0] = 0;
2140
  op1out[0] = 0;
2141
  op2out[0] = 0;
2142
  op3out[0] = 0;
2143
 
2144
  op_index[0] = op_index[1] = op_index[2] = -1;
2145
 
2146
  the_info = info;
2147
  start_pc = pc;
2148
  start_codep = inbuf;
2149
  codep = inbuf;
2150
 
2151
  if (setjmp (priv.bailout) != 0)
2152
    {
2153
      const char *name;
2154
 
2155
      /* Getting here means we tried for data but didn't get it.  That
2156
         means we have an incomplete instruction of some sort.  Just
2157
         print the first byte as a prefix or a .byte pseudo-op.  */
2158
      if (codep > inbuf)
2159
        {
2160
          name = prefix_name (inbuf[0], orig_sizeflag);
2161
          if (name != NULL)
2162
            (*info->fprintf_func) (info->stream, "%s", name);
2163
          else
2164
            {
2165
              /* Just print the first byte as a .byte instruction.  */
2166
              (*info->fprintf_func) (info->stream, ".byte 0x%x",
2167
                                     (unsigned int) inbuf[0]);
2168
            }
2169
 
2170
          return 1;
2171
        }
2172
 
2173
      return -1;
2174
    }
2175
 
2176
  ckprefix ();
2177
 
2178
  insn_codep = codep;
2179
 
2180
  FETCH_DATA (info, codep + 1);
2181
  two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
2182
 
2183
  obufp = obuf;
2184
 
2185
  if ((prefixes & PREFIX_FWAIT)
2186
      && ((*codep < 0xd8) || (*codep > 0xdf)))
2187
    {
2188
      const char *name;
2189
 
2190
      /* fwait not followed by floating point instruction.  Print the
2191
         first prefix, which is probably fwait itself.  */
2192
      name = prefix_name (inbuf[0], orig_sizeflag);
2193
      if (name == NULL)
2194
        name = INTERNAL_DISASSEMBLER_ERROR;
2195
      (*info->fprintf_func) (info->stream, "%s", name);
2196
      return 1;
2197
    }
2198
 
2199
  if (*codep == 0x0f)
2200
    {
2201
      FETCH_DATA (info, codep + 2);
2202
      if (intel_syntax)
2203
        dp = &dis386_twobyte_intel[*++codep];
2204
      else
2205
        dp = &dis386_twobyte_att[*++codep];
2206
      need_modrm = twobyte_has_modrm[*codep];
2207
      uses_f3_prefix = twobyte_uses_f3_prefix[*codep];
2208
    }
2209
  else
2210
    {
2211
      if (intel_syntax)
2212
        dp = &dis386_intel[*codep];
2213
      else
2214
        dp = &dis386_att[*codep];
2215
      need_modrm = onebyte_has_modrm[*codep];
2216
      uses_f3_prefix = 0;
2217
    }
2218
  codep++;
2219
 
2220
  if (!uses_f3_prefix && (prefixes & PREFIX_REPZ))
2221
    {
2222
      oappend ("repz ");
2223
      used_prefixes |= PREFIX_REPZ;
2224
    }
2225
  if (prefixes & PREFIX_REPNZ)
2226
    {
2227
      oappend ("repnz ");
2228
      used_prefixes |= PREFIX_REPNZ;
2229
    }
2230
  if (prefixes & PREFIX_LOCK)
2231
    {
2232
      oappend ("lock ");
2233
      used_prefixes |= PREFIX_LOCK;
2234
    }
2235
 
2236
  if (prefixes & PREFIX_DATA)
2237
    sizeflag ^= DFLAG;
2238
 
2239
  if (prefixes & PREFIX_ADDR)
2240
    {
2241
      sizeflag ^= AFLAG;
2242
      if (sizeflag & AFLAG)
2243
        oappend ("addr32 ");
2244
      else
2245
        oappend ("addr16 ");
2246
      used_prefixes |= PREFIX_ADDR;
2247
    }
2248
 
2249
  if (need_modrm)
2250
    {
2251
      FETCH_DATA (info, codep + 1);
2252
      mod = (*codep >> 6) & 3;
2253
      reg = (*codep >> 3) & 7;
2254
      rm = *codep & 7;
2255
    }
2256
 
2257
  if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2258
    {
2259
      dofloat (sizeflag);
2260
    }
2261
  else
2262
    {
2263
      if (dp->name == NULL)
2264
        {
2265
          switch(dp->bytemode2)
2266
            {
2267
              case USE_GROUPS:
2268
                dp = &grps[dp->bytemode1][reg];
2269
                break;
2270
              case USE_PREFIX_USER_TABLE:
2271
                dp = &prefix_user_table[dp->bytemode1][prefixes & PREFIX_REPZ ? 1 : 0];
2272
                used_prefixes |= (prefixes & PREFIX_REPZ);
2273
                break;
2274
              default:
2275
                oappend (INTERNAL_DISASSEMBLER_ERROR);
2276
                break;
2277
            }
2278
        }
2279
 
2280
      putop (dp->name, sizeflag);
2281
 
2282
      obufp = op1out;
2283
      op_ad = 2;
2284
      if (dp->op1)
2285
        (*dp->op1)(dp->bytemode1, sizeflag);
2286
 
2287
      obufp = op2out;
2288
      op_ad = 1;
2289
      if (dp->op2)
2290
        (*dp->op2)(dp->bytemode2, sizeflag);
2291
 
2292
      obufp = op3out;
2293
      op_ad = 0;
2294
      if (dp->op3)
2295
        (*dp->op3)(dp->bytemode3, sizeflag);
2296
    }
2297
 
2298
  /* See if any prefixes were not used.  If so, print the first one
2299
     separately.  If we don't do this, we'll wind up printing an
2300
     instruction stream which does not precisely correspond to the
2301
     bytes we are disassembling.  */
2302
  if ((prefixes & ~used_prefixes) != 0)
2303
    {
2304
      const char *name;
2305
 
2306
      name = prefix_name (inbuf[0], orig_sizeflag);
2307
      if (name == NULL)
2308
        name = INTERNAL_DISASSEMBLER_ERROR;
2309
      (*info->fprintf_func) (info->stream, "%s", name);
2310
      return 1;
2311
    }
2312
 
2313
  obufp = obuf + strlen (obuf);
2314
  for (i = strlen (obuf); i < 6; i++)
2315
    oappend (" ");
2316
  oappend (" ");
2317
  (*info->fprintf_func) (info->stream, "%s", obuf);
2318
 
2319
  /* The enter and bound instructions are printed with operands in the same
2320
     order as the intel book; everything else is printed in reverse order.  */
2321
  if (intel_syntax || two_source_ops)
2322
    {
2323
      first = op1out;
2324
      second = op2out;
2325
      third = op3out;
2326
      op_ad = op_index[0];
2327
      op_index[0] = op_index[2];
2328
      op_index[2] = op_ad;
2329
    }
2330
  else
2331
    {
2332
      first = op3out;
2333
      second = op2out;
2334
      third = op1out;
2335
    }
2336
  needcomma = 0;
2337
  if (*first)
2338
    {
2339
      if (op_index[0] != -1)
2340
        (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
2341
      else
2342
        (*info->fprintf_func) (info->stream, "%s", first);
2343
      needcomma = 1;
2344
    }
2345
  if (*second)
2346
    {
2347
      if (needcomma)
2348
        (*info->fprintf_func) (info->stream, ",");
2349
      if (op_index[1] != -1)
2350
        (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
2351
      else
2352
        (*info->fprintf_func) (info->stream, "%s", second);
2353
      needcomma = 1;
2354
    }
2355
  if (*third)
2356
    {
2357
      if (needcomma)
2358
        (*info->fprintf_func) (info->stream, ",");
2359
      if (op_index[2] != -1)
2360
        (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
2361
      else
2362
        (*info->fprintf_func) (info->stream, "%s", third);
2363
    }
2364
  return codep - inbuf;
2365
}
2366
 
2367
static const char *float_mem_att[] = {
2368
  /* d8 */
2369
  "fadds",
2370
  "fmuls",
2371
  "fcoms",
2372
  "fcomps",
2373
  "fsubs",
2374
  "fsubrs",
2375
  "fdivs",
2376
  "fdivrs",
2377
  /*  d9 */
2378
  "flds",
2379
  "(bad)",
2380
  "fsts",
2381
  "fstps",
2382
  "fldenv",
2383
  "fldcw",
2384
  "fNstenv",
2385
  "fNstcw",
2386
  /* da */
2387
  "fiaddl",
2388
  "fimull",
2389
  "ficoml",
2390
  "ficompl",
2391
  "fisubl",
2392
  "fisubrl",
2393
  "fidivl",
2394
  "fidivrl",
2395
  /* db */
2396
  "fildl",
2397
  "(bad)",
2398
  "fistl",
2399
  "fistpl",
2400
  "(bad)",
2401
  "fldt",
2402
  "(bad)",
2403
  "fstpt",
2404
  /* dc */
2405
  "faddl",
2406
  "fmull",
2407
  "fcoml",
2408
  "fcompl",
2409
  "fsubl",
2410
  "fsubrl",
2411
  "fdivl",
2412
  "fdivrl",
2413
  /* dd */
2414
  "fldl",
2415
  "(bad)",
2416
  "fstl",
2417
  "fstpl",
2418
  "frstor",
2419
  "(bad)",
2420
  "fNsave",
2421
  "fNstsw",
2422
  /* de */
2423
  "fiadd",
2424
  "fimul",
2425
  "ficom",
2426
  "ficomp",
2427
  "fisub",
2428
  "fisubr",
2429
  "fidiv",
2430
  "fidivr",
2431
  /* df */
2432
  "fild",
2433
  "(bad)",
2434
  "fist",
2435
  "fistp",
2436
  "fbld",
2437
  "fildll",
2438
  "fbstp",
2439
  "fistpll",
2440
};
2441
 
2442
static const char *float_mem_intel[] = {
2443
  /* d8 */
2444
  "fadd",
2445
  "fmul",
2446
  "fcom",
2447
  "fcomp",
2448
  "fsub",
2449
  "fsubr",
2450
  "fdiv",
2451
  "fdivr",
2452
  /*  d9 */
2453
  "fld",
2454
  "(bad)",
2455
  "fst",
2456
  "fstp",
2457
  "fldenv",
2458
  "fldcw",
2459
  "fNstenv",
2460
  "fNstcw",
2461
  /* da */
2462
  "fiadd",
2463
  "fimul",
2464
  "ficom",
2465
  "ficomp",
2466
  "fisub",
2467
  "fisubr",
2468
  "fidiv",
2469
  "fidivr",
2470
  /* db */
2471
  "fild",
2472
  "(bad)",
2473
  "fist",
2474
  "fistp",
2475
  "(bad)",
2476
  "fld",
2477
  "(bad)",
2478
  "fstp",
2479
  /* dc */
2480
  "fadd",
2481
  "fmul",
2482
  "fcom",
2483
  "fcomp",
2484
  "fsub",
2485
  "fsubr",
2486
  "fdiv",
2487
  "fdivr",
2488
  /* dd */
2489
  "fld",
2490
  "(bad)",
2491
  "fst",
2492
  "fstp",
2493
  "frstor",
2494
  "(bad)",
2495
  "fNsave",
2496
  "fNstsw",
2497
  /* de */
2498
  "fiadd",
2499
  "fimul",
2500
  "ficom",
2501
  "ficomp",
2502
  "fisub",
2503
  "fisubr",
2504
  "fidiv",
2505
  "fidivr",
2506
  /* df */
2507
  "fild",
2508
  "(bad)",
2509
  "fist",
2510
  "fistp",
2511
  "fbld",
2512
  "fild",
2513
  "fbstp",
2514
  "fistpll",
2515
};
2516
 
2517
#define ST OP_ST, 0
2518
#define STi OP_STi, 0
2519
 
2520
#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
2521
#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
2522
#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
2523
#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
2524
#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
2525
#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
2526
#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
2527
#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
2528
#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
2529
 
2530
static const struct dis386 float_reg[][8] = {
2531
  /* d8 */
2532
  {
2533
    { "fadd",   ST, STi, XX },
2534
    { "fmul",   ST, STi, XX },
2535
    { "fcom",   STi, XX, XX },
2536
    { "fcomp",  STi, XX, XX },
2537
    { "fsub",   ST, STi, XX },
2538
    { "fsubr",  ST, STi, XX },
2539
    { "fdiv",   ST, STi, XX },
2540
    { "fdivr",  ST, STi, XX },
2541
  },
2542
  /* d9 */
2543
  {
2544
    { "fld",    STi, XX, XX },
2545
    { "fxch",   STi, XX, XX },
2546
    { FGRPd9_2 },
2547
    { "(bad)",  XX, XX, XX },
2548
    { FGRPd9_4 },
2549
    { FGRPd9_5 },
2550
    { FGRPd9_6 },
2551
    { FGRPd9_7 },
2552
  },
2553
  /* da */
2554
  {
2555
    { "fcmovb", ST, STi, XX },
2556
    { "fcmove", ST, STi, XX },
2557
    { "fcmovbe",ST, STi, XX },
2558
    { "fcmovu", ST, STi, XX },
2559
    { "(bad)",  XX, XX, XX },
2560
    { FGRPda_5 },
2561
    { "(bad)",  XX, XX, XX },
2562
    { "(bad)",  XX, XX, XX },
2563
  },
2564
  /* db */
2565
  {
2566
    { "fcmovnb",ST, STi, XX },
2567
    { "fcmovne",ST, STi, XX },
2568
    { "fcmovnbe",ST, STi, XX },
2569
    { "fcmovnu",ST, STi, XX },
2570
    { FGRPdb_4 },
2571
    { "fucomi", ST, STi, XX },
2572
    { "fcomi",  ST, STi, XX },
2573
    { "(bad)",  XX, XX, XX },
2574
  },
2575
  /* dc */
2576
  {
2577
    { "fadd",   STi, ST, XX },
2578
    { "fmul",   STi, ST, XX },
2579
    { "(bad)",  XX, XX, XX },
2580
    { "(bad)",  XX, XX, XX },
2581
#if UNIXWARE_COMPAT
2582
    { "fsub",   STi, ST, XX },
2583
    { "fsubr",  STi, ST, XX },
2584
    { "fdiv",   STi, ST, XX },
2585
    { "fdivr",  STi, ST, XX },
2586
#else
2587
    { "fsubr",  STi, ST, XX },
2588
    { "fsub",   STi, ST, XX },
2589
    { "fdivr",  STi, ST, XX },
2590
    { "fdiv",   STi, ST, XX },
2591
#endif
2592
  },
2593
  /* dd */
2594
  {
2595
    { "ffree",  STi, XX, XX },
2596
    { "(bad)",  XX, XX, XX },
2597
    { "fst",    STi, XX, XX },
2598
    { "fstp",   STi, XX, XX },
2599
    { "fucom",  STi, XX, XX },
2600
    { "fucomp", STi, XX, XX },
2601
    { "(bad)",  XX, XX, XX },
2602
    { "(bad)",  XX, XX, XX },
2603
  },
2604
  /* de */
2605
  {
2606
    { "faddp",  STi, ST, XX },
2607
    { "fmulp",  STi, ST, XX },
2608
    { "(bad)",  XX, XX, XX },
2609
    { FGRPde_3 },
2610
#if UNIXWARE_COMPAT
2611
    { "fsubp",  STi, ST, XX },
2612
    { "fsubrp", STi, ST, XX },
2613
    { "fdivp",  STi, ST, XX },
2614
    { "fdivrp", STi, ST, XX },
2615
#else
2616
    { "fsubrp", STi, ST, XX },
2617
    { "fsubp",  STi, ST, XX },
2618
    { "fdivrp", STi, ST, XX },
2619
    { "fdivp",  STi, ST, XX },
2620
#endif
2621
  },
2622
  /* df */
2623
  {
2624
    { "(bad)",  XX, XX, XX },
2625
    { "(bad)",  XX, XX, XX },
2626
    { "(bad)",  XX, XX, XX },
2627
    { "(bad)",  XX, XX, XX },
2628
    { FGRPdf_4 },
2629
    { "fucomip",ST, STi, XX },
2630
    { "fcomip", ST, STi, XX },
2631
    { "(bad)",  XX, XX, XX },
2632
  },
2633
};
2634
 
2635
 
2636
static char *fgrps[][8] = {
2637
  /* d9_2  0 */
2638
  {
2639
    "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2640
  },
2641
 
2642
  /* d9_4  1 */
2643
  {
2644
    "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2645
  },
2646
 
2647
  /* d9_5  2 */
2648
  {
2649
    "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2650
  },
2651
 
2652
  /* d9_6  3 */
2653
  {
2654
    "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2655
  },
2656
 
2657
  /* d9_7  4 */
2658
  {
2659
    "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2660
  },
2661
 
2662
  /* da_5  5 */
2663
  {
2664
    "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2665
  },
2666
 
2667
  /* db_4  6 */
2668
  {
2669
    "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2670
    "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2671
  },
2672
 
2673
  /* de_3  7 */
2674
  {
2675
    "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2676
  },
2677
 
2678
  /* df_4  8 */
2679
  {
2680
    "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2681
  },
2682
};
2683
 
2684
static void
2685
dofloat (sizeflag)
2686
     int sizeflag;
2687
{
2688
  const struct dis386 *dp;
2689
  unsigned char floatop;
2690
 
2691
  floatop = codep[-1];
2692
 
2693
  if (mod != 3)
2694
    {
2695
      if (intel_syntax)
2696
        putop (float_mem_intel[(floatop - 0xd8 ) * 8 + reg], sizeflag);
2697
      else
2698
        putop (float_mem_att[(floatop - 0xd8 ) * 8 + reg], sizeflag);
2699
      obufp = op1out;
2700
      if (floatop == 0xdb)
2701
        OP_E (x_mode, sizeflag);
2702
      else if (floatop == 0xdd)
2703
        OP_E (d_mode, sizeflag);
2704
      else
2705
        OP_E (v_mode, sizeflag);
2706
      return;
2707
    }
2708
  codep++;
2709
 
2710
  dp = &float_reg[floatop - 0xd8][reg];
2711
  if (dp->name == NULL)
2712
    {
2713
      putop (fgrps[dp->bytemode1][rm], sizeflag);
2714
 
2715
      /* instruction fnstsw is only one with strange arg */
2716
      if (floatop == 0xdf && codep[-1] == 0xe0)
2717
        strcpy (op1out, names16[0]);
2718
    }
2719
  else
2720
    {
2721
      putop (dp->name, sizeflag);
2722
 
2723
      obufp = op1out;
2724
      if (dp->op1)
2725
        (*dp->op1)(dp->bytemode1, sizeflag);
2726
      obufp = op2out;
2727
      if (dp->op2)
2728
        (*dp->op2)(dp->bytemode2, sizeflag);
2729
    }
2730
}
2731
 
2732
/* ARGSUSED */
2733
static void
2734
OP_ST (ignore, sizeflag)
2735
     int ignore ATTRIBUTE_UNUSED;
2736
     int sizeflag ATTRIBUTE_UNUSED;
2737
{
2738
  oappend ("%st");
2739
}
2740
 
2741
/* ARGSUSED */
2742
static void
2743
OP_STi (ignore, sizeflag)
2744
     int ignore ATTRIBUTE_UNUSED;
2745
     int sizeflag ATTRIBUTE_UNUSED;
2746
{
2747
  sprintf (scratchbuf, "%%st(%d)", rm);
2748
  oappend (scratchbuf);
2749
}
2750
 
2751
 
2752
/* capital letters in template are macros */
2753
static void
2754
putop (template, sizeflag)
2755
     const char *template;
2756
     int sizeflag;
2757
{
2758
  const char *p;
2759
 
2760
  for (p = template; *p; p++)
2761
    {
2762
      switch (*p)
2763
        {
2764
        default:
2765
          *obufp++ = *p;
2766
          break;
2767
        case 'A':
2768
          if (intel_syntax)
2769
            break;
2770
          if (mod != 3
2771
#ifdef SUFFIX_ALWAYS
2772
              || (sizeflag & SUFFIX_ALWAYS)
2773
#endif
2774
              )
2775
            *obufp++ = 'b';
2776
          break;
2777
        case 'B':
2778
          if (intel_syntax)
2779
            break;
2780
#ifdef SUFFIX_ALWAYS
2781
          if (sizeflag & SUFFIX_ALWAYS)
2782
            *obufp++ = 'b';
2783
#endif
2784
          break;
2785
        case 'E':               /* For jcxz/jecxz */
2786
          if (sizeflag & AFLAG)
2787
            *obufp++ = 'e';
2788
          break;
2789
        case 'L':
2790
          if (intel_syntax)
2791
            break;
2792
#ifdef SUFFIX_ALWAYS
2793
          if (sizeflag & SUFFIX_ALWAYS)
2794
            *obufp++ = 'l';
2795
#endif
2796
          break;
2797
        case 'N':
2798
          if ((prefixes & PREFIX_FWAIT) == 0)
2799
            *obufp++ = 'n';
2800
          else
2801
            used_prefixes |= PREFIX_FWAIT;
2802
          break;
2803
        case 'P':
2804
          if (intel_syntax)
2805
            break;
2806
          if ((prefixes & PREFIX_DATA)
2807
#ifdef SUFFIX_ALWAYS
2808
              || (sizeflag & SUFFIX_ALWAYS)
2809
#endif
2810
              )
2811
            {
2812
              if (sizeflag & DFLAG)
2813
                *obufp++ = 'l';
2814
              else
2815
                *obufp++ = 'w';
2816
              used_prefixes |= (prefixes & PREFIX_DATA);
2817
            }
2818
          break;
2819
        case 'Q':
2820
          if (intel_syntax)
2821
            break;
2822
          if (mod != 3
2823
#ifdef SUFFIX_ALWAYS
2824
              || (sizeflag & SUFFIX_ALWAYS)
2825
#endif
2826
              )
2827
            {
2828
              if (sizeflag & DFLAG)
2829
                *obufp++ = 'l';
2830
              else
2831
                *obufp++ = 'w';
2832
              used_prefixes |= (prefixes & PREFIX_DATA);
2833
            }
2834
          break;
2835
        case 'R':
2836
          if (intel_syntax)
2837
            {
2838
              if (sizeflag & DFLAG)
2839
                {
2840
                  *obufp++ = 'd';
2841
                  *obufp++ = 'q';
2842
                }
2843
              else
2844
                {
2845
                  *obufp++ = 'w';
2846
                  *obufp++ = 'd';
2847
                }
2848
            }
2849
          else
2850
            {
2851
              if (sizeflag & DFLAG)
2852
                *obufp++ = 'l';
2853
              else
2854
                *obufp++ = 'w';
2855
            }
2856
          used_prefixes |= (prefixes & PREFIX_DATA);
2857
          break;
2858
        case 'S':
2859
          if (intel_syntax)
2860
            break;
2861
#ifdef SUFFIX_ALWAYS
2862
          if (sizeflag & SUFFIX_ALWAYS)
2863
            {
2864
              if (sizeflag & DFLAG)
2865
                *obufp++ = 'l';
2866
              else
2867
                *obufp++ = 'w';
2868
              used_prefixes |= (prefixes & PREFIX_DATA);
2869
            }
2870
#endif
2871
          break;
2872
        case 'W':
2873
          /* operand size flag for cwtl, cbtw */
2874
          if (sizeflag & DFLAG)
2875
            *obufp++ = 'w';
2876
          else
2877
            *obufp++ = 'b';
2878
          if (intel_syntax)
2879
            {
2880
              if (sizeflag & DFLAG)
2881
                {
2882
                  *obufp++ = 'd';
2883
                  *obufp++ = 'e';
2884
                }
2885
              else
2886
                {
2887
                  *obufp++ = 'w';
2888
                }
2889
            }
2890
          used_prefixes |= (prefixes & PREFIX_DATA);
2891
          break;
2892
        }
2893
    }
2894
  *obufp = 0;
2895
}
2896
 
2897
static void
2898
oappend (s)
2899
     const char *s;
2900
{
2901
  strcpy (obufp, s);
2902
  obufp += strlen (s);
2903
}
2904
 
2905
static void
2906
append_seg ()
2907
{
2908
  if (prefixes & PREFIX_CS)
2909
    {
2910
      oappend ("%cs:");
2911
      used_prefixes |= PREFIX_CS;
2912
    }
2913
  if (prefixes & PREFIX_DS)
2914
    {
2915
      oappend ("%ds:");
2916
      used_prefixes |= PREFIX_DS;
2917
    }
2918
  if (prefixes & PREFIX_SS)
2919
    {
2920
      oappend ("%ss:");
2921
      used_prefixes |= PREFIX_SS;
2922
    }
2923
  if (prefixes & PREFIX_ES)
2924
    {
2925
      oappend ("%es:");
2926
      used_prefixes |= PREFIX_ES;
2927
    }
2928
  if (prefixes & PREFIX_FS)
2929
    {
2930
      oappend ("%fs:");
2931
      used_prefixes |= PREFIX_FS;
2932
    }
2933
  if (prefixes & PREFIX_GS)
2934
    {
2935
      oappend ("%gs:");
2936
      used_prefixes |= PREFIX_GS;
2937
    }
2938
}
2939
 
2940
static void
2941
OP_indirE (bytemode, sizeflag)
2942
     int bytemode;
2943
     int sizeflag;
2944
{
2945
  if (!intel_syntax)
2946
    oappend ("*");
2947
  OP_E (bytemode, sizeflag);
2948
}
2949
 
2950
static void
2951
OP_E (bytemode, sizeflag)
2952
     int bytemode;
2953
     int sizeflag;
2954
{
2955
  int disp;
2956
 
2957
  /* skip mod/rm byte */
2958
  codep++;
2959
 
2960
  if (mod == 3)
2961
    {
2962
      switch (bytemode)
2963
        {
2964
        case b_mode:
2965
          oappend (names8[rm]);
2966
          break;
2967
        case w_mode:
2968
          oappend (names16[rm]);
2969
          break;
2970
        case d_mode:
2971
          oappend (names32[rm]);
2972
          break;
2973
        case v_mode:
2974
          if (sizeflag & DFLAG)
2975
            oappend (names32[rm]);
2976
          else
2977
            oappend (names16[rm]);
2978
          used_prefixes |= (prefixes & PREFIX_DATA);
2979
          break;
2980
        case 0:
2981
          if ( !(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */))
2982
            BadOp();    /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */
2983
          break;
2984
        default:
2985
          oappend (INTERNAL_DISASSEMBLER_ERROR);
2986
          break;
2987
        }
2988
      return;
2989
    }
2990
 
2991
  disp = 0;
2992
  append_seg ();
2993
 
2994
  if (sizeflag & AFLAG) /* 32 bit address mode */
2995
    {
2996
      int havesib;
2997
      int havebase;
2998
      int base;
2999
      int index = 0;
3000
      int scale = 0;
3001
 
3002
      havesib = 0;
3003
      havebase = 1;
3004
      base = rm;
3005
 
3006
      if (base == 4)
3007
        {
3008
          havesib = 1;
3009
          FETCH_DATA (the_info, codep + 1);
3010
          scale = (*codep >> 6) & 3;
3011
          index = (*codep >> 3) & 7;
3012
          base = *codep & 7;
3013
          codep++;
3014
        }
3015
 
3016
      switch (mod)
3017
        {
3018
        case 0:
3019
          if (base == 5)
3020
            {
3021
              havebase = 0;
3022
              disp = get32 ();
3023
            }
3024
          break;
3025
        case 1:
3026
          FETCH_DATA (the_info, codep + 1);
3027
          disp = *codep++;
3028
          if ((disp & 0x80) != 0)
3029
            disp -= 0x100;
3030
          break;
3031
        case 2:
3032
          disp = get32 ();
3033
          break;
3034
        }
3035
 
3036
      if (!intel_syntax)
3037
        if (mod != 0 || base == 5)
3038
          {
3039
            sprintf (scratchbuf, "0x%x", disp);
3040
            oappend (scratchbuf);
3041
          }
3042
 
3043
      if (havebase || (havesib && (index != 4 || scale != 0)))
3044
        {
3045
          if (intel_syntax)
3046
            {
3047
              switch (bytemode)
3048
                {
3049
                case b_mode:
3050
                  oappend("BYTE PTR ");
3051
                  break;
3052
                case w_mode:
3053
                  oappend("WORD PTR ");
3054
                  break;
3055
                case v_mode:
3056
                  oappend("DWORD PTR ");
3057
                  break;
3058
                case d_mode:
3059
                  oappend("QWORD PTR ");
3060
                  break;
3061
                case x_mode:
3062
                  oappend("XWORD PTR ");
3063
                  break;
3064
                default:
3065
                  break;
3066
                }
3067
             }
3068
          *obufp++ = open_char;
3069
          *obufp = '\0';
3070
          if (havebase)
3071
            oappend (names32[base]);
3072
          if (havesib)
3073
            {
3074
              if (index != 4)
3075
                {
3076
                  if (intel_syntax)
3077
                    {
3078
                      if (havebase)
3079
                        {
3080
                          *obufp++ = separator_char;
3081
                          *obufp = '\0';
3082
                        }
3083
                      sprintf (scratchbuf, "%s", names32[index]);
3084
                    }
3085
                  else
3086
                    sprintf (scratchbuf, ",%s", names32[index]);
3087
                  oappend (scratchbuf);
3088
                }
3089
              if (!intel_syntax
3090
                  || (intel_syntax
3091
                      && bytemode != b_mode
3092
                      && bytemode != w_mode
3093
                      && bytemode != v_mode))
3094
                {
3095
                  *obufp++ = scale_char;
3096
                  *obufp = '\0';
3097
                  sprintf (scratchbuf, "%d", 1 << scale);
3098
                  oappend (scratchbuf);
3099
                }
3100
            }
3101
          if (intel_syntax)
3102
            if (mod != 0 || base == 5)
3103
              {
3104
                /* Don't print zero displacements */
3105
                if (disp > 0)
3106
                  {
3107
                    sprintf (scratchbuf, "+%d", disp);
3108
                    oappend (scratchbuf);
3109
                  }
3110
                else if (disp < 0)
3111
                  {
3112
                    sprintf (scratchbuf, "%d", disp);
3113
                    oappend (scratchbuf);
3114
                  }
3115
              }
3116
 
3117
          *obufp++ = close_char;
3118
          *obufp = '\0';
3119
        }
3120
      else if (intel_syntax)
3121
        {
3122
          if (mod != 0 || base == 5)
3123
            {
3124
              if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3125
                              | PREFIX_ES | PREFIX_FS | PREFIX_GS))
3126
                ;
3127
              else
3128
                {
3129
                  oappend (names_seg[3]);
3130
                  oappend (":");
3131
                }
3132
              sprintf (scratchbuf, "0x%x", disp);
3133
              oappend (scratchbuf);
3134
            }
3135
        }
3136
    }
3137
  else
3138
    { /* 16 bit address mode */
3139
      switch (mod)
3140
        {
3141
        case 0:
3142
          if (rm == 6)
3143
            {
3144
              disp = get16 ();
3145
              if ((disp & 0x8000) != 0)
3146
                disp -= 0x10000;
3147
            }
3148
          break;
3149
        case 1:
3150
          FETCH_DATA (the_info, codep + 1);
3151
          disp = *codep++;
3152
          if ((disp & 0x80) != 0)
3153
            disp -= 0x100;
3154
          break;
3155
        case 2:
3156
          disp = get16 ();
3157
          if ((disp & 0x8000) != 0)
3158
            disp -= 0x10000;
3159
          break;
3160
        }
3161
 
3162
      if (!intel_syntax)
3163
        if (mod != 0 || rm == 6)
3164
          {
3165
            sprintf (scratchbuf, "%d", disp);
3166
            oappend (scratchbuf);
3167
          }
3168
 
3169
      if (mod != 0 || rm != 6)
3170
        {
3171
          *obufp++ = open_char;
3172
          *obufp = '\0';
3173
          oappend (index16[rm]);
3174
          *obufp++ = close_char;
3175
          *obufp = '\0';
3176
        }
3177
    }
3178
}
3179
 
3180
static void
3181
OP_G (bytemode, sizeflag)
3182
     int bytemode;
3183
     int sizeflag;
3184
{
3185
  switch (bytemode)
3186
    {
3187
    case b_mode:
3188
      oappend (names8[reg]);
3189
      break;
3190
    case w_mode:
3191
      oappend (names16[reg]);
3192
      break;
3193
    case d_mode:
3194
      oappend (names32[reg]);
3195
      break;
3196
    case v_mode:
3197
      if (sizeflag & DFLAG)
3198
        oappend (names32[reg]);
3199
      else
3200
        oappend (names16[reg]);
3201
      used_prefixes |= (prefixes & PREFIX_DATA);
3202
      break;
3203
    default:
3204
      oappend (INTERNAL_DISASSEMBLER_ERROR);
3205
      break;
3206
    }
3207
}
3208
 
3209
static int
3210
get32 ()
3211
{
3212
  int x = 0;
3213
 
3214
  FETCH_DATA (the_info, codep + 4);
3215
  x = *codep++ & 0xff;
3216
  x |= (*codep++ & 0xff) << 8;
3217
  x |= (*codep++ & 0xff) << 16;
3218
  x |= (*codep++ & 0xff) << 24;
3219
  return x;
3220
}
3221
 
3222
static int
3223
get16 ()
3224
{
3225
  int x = 0;
3226
 
3227
  FETCH_DATA (the_info, codep + 2);
3228
  x = *codep++ & 0xff;
3229
  x |= (*codep++ & 0xff) << 8;
3230
  return x;
3231
}
3232
 
3233
static void
3234
set_op (op)
3235
     unsigned int op;
3236
{
3237
  op_index[op_ad] = op_ad;
3238
  op_address[op_ad] = op;
3239
}
3240
 
3241
static void
3242
OP_REG (code, sizeflag)
3243
     int code;
3244
     int sizeflag;
3245
{
3246
  const char *s;
3247
 
3248
  switch (code)
3249
    {
3250
    case indir_dx_reg:
3251
      s = "(%dx)";
3252
      break;
3253
    case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3254
    case sp_reg: case bp_reg: case si_reg: case di_reg:
3255
      s = names16[code - ax_reg];
3256
      break;
3257
    case es_reg: case ss_reg: case cs_reg:
3258
    case ds_reg: case fs_reg: case gs_reg:
3259
      s = names_seg[code - es_reg];
3260
      break;
3261
    case al_reg: case ah_reg: case cl_reg: case ch_reg:
3262
    case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3263
      s = names8[code - al_reg];
3264
      break;
3265
    case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3266
    case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3267
      if (sizeflag & DFLAG)
3268
        s = names32[code - eAX_reg];
3269
      else
3270
        s = names16[code - eAX_reg];
3271
      used_prefixes |= (prefixes & PREFIX_DATA);
3272
      break;
3273
    default:
3274
      s = INTERNAL_DISASSEMBLER_ERROR;
3275
      break;
3276
    }
3277
  oappend (s);
3278
}
3279
 
3280
static void
3281
OP_I (bytemode, sizeflag)
3282
     int bytemode;
3283
     int sizeflag;
3284
{
3285
  int op;
3286
 
3287
  switch (bytemode)
3288
    {
3289
    case b_mode:
3290
      FETCH_DATA (the_info, codep + 1);
3291
      op = *codep++ & 0xff;
3292
      break;
3293
    case v_mode:
3294
      if (sizeflag & DFLAG)
3295
        op = get32 ();
3296
      else
3297
        op = get16 ();
3298
      used_prefixes |= (prefixes & PREFIX_DATA);
3299
      break;
3300
    case w_mode:
3301
      op = get16 ();
3302
      break;
3303
    default:
3304
      oappend (INTERNAL_DISASSEMBLER_ERROR);
3305
      return;
3306
    }
3307
 
3308
  if (intel_syntax)
3309
    sprintf (scratchbuf, "0x%x", op);
3310
  else
3311
    sprintf (scratchbuf, "$0x%x", op);
3312
  oappend (scratchbuf);
3313
  scratchbuf[0] = '\0';
3314
}
3315
 
3316
static void
3317
OP_sI (bytemode, sizeflag)
3318
     int bytemode;
3319
     int sizeflag;
3320
{
3321
  int op;
3322
 
3323
  switch (bytemode)
3324
    {
3325
    case b_mode:
3326
      FETCH_DATA (the_info, codep + 1);
3327
      op = *codep++;
3328
      if ((op & 0x80) != 0)
3329
        op -= 0x100;
3330
      break;
3331
    case v_mode:
3332
      if (sizeflag & DFLAG)
3333
        op = get32 ();
3334
      else
3335
        {
3336
          op = get16();
3337
          if ((op & 0x8000) != 0)
3338
            op -= 0x10000;
3339
        }
3340
      used_prefixes |= (prefixes & PREFIX_DATA);
3341
      break;
3342
    case w_mode:
3343
      op = get16 ();
3344
      if ((op & 0x8000) != 0)
3345
        op -= 0x10000;
3346
      break;
3347
    default:
3348
      oappend (INTERNAL_DISASSEMBLER_ERROR);
3349
      return;
3350
    }
3351
  if (intel_syntax)
3352
    sprintf (scratchbuf, "%d", op);
3353
  else
3354
    sprintf (scratchbuf, "$0x%x", op);
3355
  oappend (scratchbuf);
3356
}
3357
 
3358
static void
3359
OP_J (bytemode, sizeflag)
3360
     int bytemode;
3361
     int sizeflag;
3362
{
3363
  int disp;
3364
  int mask = -1;
3365
 
3366
  switch (bytemode)
3367
    {
3368
    case b_mode:
3369
      FETCH_DATA (the_info, codep + 1);
3370
      disp = *codep++;
3371
      if ((disp & 0x80) != 0)
3372
        disp -= 0x100;
3373
      break;
3374
    case v_mode:
3375
      if (sizeflag & DFLAG)
3376
        disp = get32 ();
3377
      else
3378
        {
3379
          disp = get16 ();
3380
          /* for some reason, a data16 prefix on a jump instruction
3381
             means that the pc is masked to 16 bits after the
3382
             displacement is added!  */
3383
          mask = 0xffff;
3384
        }
3385
      used_prefixes |= (prefixes & PREFIX_DATA);
3386
      break;
3387
    default:
3388
      oappend (INTERNAL_DISASSEMBLER_ERROR);
3389
      return;
3390
    }
3391
  disp = (start_pc + codep - start_codep + disp) & mask;
3392
  set_op (disp);
3393
  sprintf (scratchbuf, "0x%x", disp);
3394
  oappend (scratchbuf);
3395
}
3396
 
3397
/* ARGSUSED */
3398
static void
3399
OP_SEG (dummy, sizeflag)
3400
     int dummy ATTRIBUTE_UNUSED;
3401
     int sizeflag ATTRIBUTE_UNUSED;
3402
{
3403
  static char *sreg[] = {
3404
    "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
3405
  };
3406
 
3407
  oappend (sreg[reg]);
3408
}
3409
 
3410
/* ARGSUSED */
3411
static void
3412
OP_DIR (dummy, sizeflag)
3413
     int dummy ATTRIBUTE_UNUSED;
3414
     int sizeflag;
3415
{
3416
  int seg, offset;
3417
 
3418
  if (sizeflag & DFLAG)
3419
    {
3420
      offset = get32 ();
3421
      seg = get16 ();
3422
    }
3423
  else
3424
    {
3425
      offset = get16 ();
3426
      seg = get16 ();
3427
    }
3428
  used_prefixes |= (prefixes & PREFIX_DATA);
3429
  sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3430
  oappend (scratchbuf);
3431
}
3432
 
3433
/* ARGSUSED */
3434
static void
3435
OP_OFF (ignore, sizeflag)
3436
     int ignore ATTRIBUTE_UNUSED;
3437
     int sizeflag;
3438
{
3439
  int off;
3440
 
3441
  append_seg ();
3442
 
3443
  if (sizeflag & AFLAG)
3444
    off = get32 ();
3445
  else
3446
    off = get16 ();
3447
 
3448
  if (intel_syntax)
3449
    {
3450
      if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3451
                        | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3452
        {
3453
          oappend (names_seg[3]);
3454
          oappend (":");
3455
        }
3456
    }
3457
  sprintf (scratchbuf, "0x%x", off);
3458
  oappend (scratchbuf);
3459
}
3460
 
3461
static void
3462
ptr_reg (code, sizeflag)
3463
     int code;
3464
     int sizeflag;
3465
{
3466
  const char *s;
3467
  oappend ("(");
3468
  if (sizeflag & AFLAG)
3469
    s = names32[code - eAX_reg];
3470
  else
3471
    s = names16[code - eAX_reg];
3472
  oappend (s);
3473
  oappend (")");
3474
}
3475
 
3476
static void
3477
OP_ESreg (code, sizeflag)
3478
     int code;
3479
     int sizeflag;
3480
{
3481
  oappend ("%es:");
3482
  ptr_reg (code, sizeflag);
3483
}
3484
 
3485
static void
3486
OP_DSreg (code, sizeflag)
3487
     int code;
3488
     int sizeflag;
3489
{
3490
  if ((prefixes
3491
       & (PREFIX_CS
3492
          | PREFIX_DS
3493
          | PREFIX_SS
3494
          | PREFIX_ES
3495
          | PREFIX_FS
3496
          | PREFIX_GS)) == 0)
3497
    prefixes |= PREFIX_DS;
3498
  append_seg();
3499
  ptr_reg (code, sizeflag);
3500
}
3501
 
3502
/* ARGSUSED */
3503
static void
3504
OP_C (dummy, sizeflag)
3505
     int dummy ATTRIBUTE_UNUSED;
3506
     int sizeflag ATTRIBUTE_UNUSED;
3507
{
3508
  sprintf (scratchbuf, "%%cr%d", reg);
3509
  oappend (scratchbuf);
3510
}
3511
 
3512
/* ARGSUSED */
3513
static void
3514
OP_D (dummy, sizeflag)
3515
     int dummy ATTRIBUTE_UNUSED;
3516
     int sizeflag ATTRIBUTE_UNUSED;
3517
{
3518
  sprintf (scratchbuf, "%%db%d", reg);
3519
  oappend (scratchbuf);
3520
}
3521
 
3522
/* ARGSUSED */
3523
static void
3524
OP_T (dummy, sizeflag)
3525
     int dummy ATTRIBUTE_UNUSED;
3526
     int sizeflag ATTRIBUTE_UNUSED;
3527
{
3528
  sprintf (scratchbuf, "%%tr%d", reg);
3529
  oappend (scratchbuf);
3530
}
3531
 
3532
static void
3533
OP_Rd (bytemode, sizeflag)
3534
     int bytemode;
3535
     int sizeflag;
3536
{
3537
  if (mod == 3)
3538
    OP_E (bytemode, sizeflag);
3539
  else
3540
    BadOp();
3541
}
3542
 
3543
static void
3544
OP_MMX (ignore, sizeflag)
3545
     int ignore ATTRIBUTE_UNUSED;
3546
     int sizeflag ATTRIBUTE_UNUSED;
3547
{
3548
  sprintf (scratchbuf, "%%mm%d", reg);
3549
  oappend (scratchbuf);
3550
}
3551
 
3552
static void
3553
OP_XMM (bytemode, sizeflag)
3554
     int bytemode ATTRIBUTE_UNUSED;
3555
     int sizeflag ATTRIBUTE_UNUSED;
3556
{
3557
  sprintf (scratchbuf, "%%xmm%d", reg);
3558
  oappend (scratchbuf);
3559
}
3560
 
3561
static void
3562
OP_EM (bytemode, sizeflag)
3563
     int bytemode;
3564
     int sizeflag;
3565
{
3566
  if (mod != 3)
3567
    {
3568
      OP_E (bytemode, sizeflag);
3569
      return;
3570
    }
3571
 
3572
  codep++;
3573
  sprintf (scratchbuf, "%%mm%d", rm);
3574
  oappend (scratchbuf);
3575
}
3576
 
3577
static void
3578
OP_EX (bytemode, sizeflag)
3579
     int bytemode;
3580
     int sizeflag;
3581
{
3582
  if (mod != 3)
3583
    {
3584
      OP_E (bytemode, sizeflag);
3585
      return;
3586
    }
3587
 
3588
  codep++;
3589
  sprintf (scratchbuf, "%%xmm%d", rm);
3590
  oappend (scratchbuf);
3591
}
3592
 
3593
static void
3594
OP_MS (bytemode, sizeflag)
3595
     int bytemode;
3596
     int sizeflag;
3597
{
3598
  if (mod == 3)
3599
    OP_EM (bytemode, sizeflag);
3600
  else
3601
    BadOp();
3602
}
3603
 
3604
static const char *Suffix3DNow[] = {
3605
/* 00 */        NULL,           NULL,           NULL,           NULL,
3606
/* 04 */        NULL,           NULL,           NULL,           NULL,
3607
/* 08 */        NULL,           NULL,           NULL,           NULL,
3608
/* 0C */        "pi2fw",        "pi2fd",        NULL,           NULL,
3609
/* 10 */        NULL,           NULL,           NULL,           NULL,
3610
/* 14 */        NULL,           NULL,           NULL,           NULL,
3611
/* 18 */        NULL,           NULL,           NULL,           NULL,
3612
/* 1C */        "pf2iw",        "pf2id",        NULL,           NULL,
3613
/* 20 */        NULL,           NULL,           NULL,           NULL,
3614
/* 24 */        NULL,           NULL,           NULL,           NULL,
3615
/* 28 */        NULL,           NULL,           NULL,           NULL,
3616
/* 2C */        NULL,           NULL,           NULL,           NULL,
3617
/* 30 */        NULL,           NULL,           NULL,           NULL,
3618
/* 34 */        NULL,           NULL,           NULL,           NULL,
3619
/* 38 */        NULL,           NULL,           NULL,           NULL,
3620
/* 3C */        NULL,           NULL,           NULL,           NULL,
3621
/* 40 */        NULL,           NULL,           NULL,           NULL,
3622
/* 44 */        NULL,           NULL,           NULL,           NULL,
3623
/* 48 */        NULL,           NULL,           NULL,           NULL,
3624
/* 4C */        NULL,           NULL,           NULL,           NULL,
3625
/* 50 */        NULL,           NULL,           NULL,           NULL,
3626
/* 54 */        NULL,           NULL,           NULL,           NULL,
3627
/* 58 */        NULL,           NULL,           NULL,           NULL,
3628
/* 5C */        NULL,           NULL,           NULL,           NULL,
3629
/* 60 */        NULL,           NULL,           NULL,           NULL,
3630
/* 64 */        NULL,           NULL,           NULL,           NULL,
3631
/* 68 */        NULL,           NULL,           NULL,           NULL,
3632
/* 6C */        NULL,           NULL,           NULL,           NULL,
3633
/* 70 */        NULL,           NULL,           NULL,           NULL,
3634
/* 74 */        NULL,           NULL,           NULL,           NULL,
3635
/* 78 */        NULL,           NULL,           NULL,           NULL,
3636
/* 7C */        NULL,           NULL,           NULL,           NULL,
3637
/* 80 */        NULL,           NULL,           NULL,           NULL,
3638
/* 84 */        NULL,           NULL,           NULL,           NULL,
3639
/* 88 */        NULL,           NULL,           "pfnacc",       NULL,
3640
/* 8C */        NULL,           NULL,           "pfpnacc",      NULL,
3641
/* 90 */        "pfcmpge",      NULL,           NULL,           NULL,
3642
/* 94 */        "pfmin",        NULL,           "pfrcp",        "pfrsqrt",
3643
/* 98 */        NULL,           NULL,           "pfsub",        NULL,
3644
/* 9C */        NULL,           NULL,           "pfadd",        NULL,
3645
/* A0 */        "pfcmpgt",      NULL,           NULL,           NULL,
3646
/* A4 */        "pfmax",        NULL,           "pfrcpit1",     "pfrsqit1",
3647
/* A8 */        NULL,           NULL,           "pfsubr",       NULL,
3648
/* AC */        NULL,           NULL,           "pfacc",        NULL,
3649
/* B0 */        "pfcmpeq",      NULL,           NULL,           NULL,
3650
/* B4 */        "pfmul",        NULL,           "pfrcpit2",     "pfmulhrw",
3651
/* B8 */        NULL,           NULL,           NULL,           "pswapd",
3652
/* BC */        NULL,           NULL,           NULL,           "pavgusb",
3653
/* C0 */        NULL,           NULL,           NULL,           NULL,
3654
/* C4 */        NULL,           NULL,           NULL,           NULL,
3655
/* C8 */        NULL,           NULL,           NULL,           NULL,
3656
/* CC */        NULL,           NULL,           NULL,           NULL,
3657
/* D0 */        NULL,           NULL,           NULL,           NULL,
3658
/* D4 */        NULL,           NULL,           NULL,           NULL,
3659
/* D8 */        NULL,           NULL,           NULL,           NULL,
3660
/* DC */        NULL,           NULL,           NULL,           NULL,
3661
/* E0 */        NULL,           NULL,           NULL,           NULL,
3662
/* E4 */        NULL,           NULL,           NULL,           NULL,
3663
/* E8 */        NULL,           NULL,           NULL,           NULL,
3664
/* EC */        NULL,           NULL,           NULL,           NULL,
3665
/* F0 */        NULL,           NULL,           NULL,           NULL,
3666
/* F4 */        NULL,           NULL,           NULL,           NULL,
3667
/* F8 */        NULL,           NULL,           NULL,           NULL,
3668
/* FC */        NULL,           NULL,           NULL,           NULL,
3669
};
3670
 
3671
static void
3672
OP_3DNowSuffix (bytemode, sizeflag)
3673
     int bytemode ATTRIBUTE_UNUSED;
3674
     int sizeflag ATTRIBUTE_UNUSED;
3675
{
3676
  const char *mnemonic;
3677
 
3678
  FETCH_DATA (the_info, codep + 1);
3679
  /* AMD 3DNow! instructions are specified by an opcode suffix in the
3680
     place where an 8-bit immediate would normally go.  ie. the last
3681
     byte of the instruction.  */
3682
  obufp = obuf + strlen(obuf);
3683
  mnemonic = Suffix3DNow[*codep++ & 0xff];
3684
  if (mnemonic)
3685
    oappend (mnemonic);
3686
  else
3687
    {
3688
      /* Since a variable sized modrm/sib chunk is between the start
3689
         of the opcode (0x0f0f) and the opcode suffix, we need to do
3690
         all the modrm processing first, and don't know until now that
3691
         we have a bad opcode.  This necessitates some cleaning up.  */
3692
      op1out[0] = '\0';
3693
      op2out[0] = '\0';
3694
      BadOp();
3695
    }
3696
}
3697
 
3698
 
3699
static const char *simd_cmp_op [] = {
3700
  "eq",
3701
  "lt",
3702
  "le",
3703
  "unord",
3704
  "neq",
3705
  "nlt",
3706
  "nle",
3707
  "ord"
3708
};
3709
 
3710
static void
3711
OP_SIMD_Suffix (bytemode, sizeflag)
3712
     int bytemode ATTRIBUTE_UNUSED;
3713
     int sizeflag ATTRIBUTE_UNUSED;
3714
{
3715
  unsigned int cmp_type;
3716
 
3717
  FETCH_DATA (the_info, codep + 1);
3718
  obufp = obuf + strlen(obuf);
3719
  cmp_type = *codep++ & 0xff;
3720
  if (cmp_type < 8)
3721
    {
3722
      sprintf (scratchbuf, "cmp%s%cs",
3723
               simd_cmp_op[cmp_type],
3724
               prefixes & PREFIX_REPZ ? 's' : 'p');
3725
      used_prefixes |= (prefixes & PREFIX_REPZ);
3726
      oappend (scratchbuf);
3727
    }
3728
  else
3729
    {
3730
      /* We have a bad extension byte.  Clean up.  */
3731
      op1out[0] = '\0';
3732
      op2out[0] = '\0';
3733
      BadOp();
3734
    }
3735
}
3736
 
3737
static void
3738
SIMD_Fixup (extrachar, sizeflag)
3739
     int extrachar;
3740
     int sizeflag ATTRIBUTE_UNUSED;
3741
{
3742
  /* Change movlps/movhps to movhlps/movlhps for 2 register operand
3743
     forms of these instructions.  */
3744
  if (mod == 3)
3745
    {
3746
      char *p = obuf + strlen(obuf);
3747
      *(p+1) = '\0';
3748
      *p     = *(p-1);
3749
      *(p-1) = *(p-2);
3750
      *(p-2) = *(p-3);
3751
      *(p-3) = extrachar;
3752
    }
3753
}
3754
 
3755
static void BadOp (void)
3756
{
3757
  codep = insn_codep + 1;       /* throw away prefixes and 1st. opcode byte */
3758
  oappend ("(bad)");
3759
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.