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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [opcodes/] [i386-dis.c] - Blame information for rev 1778

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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