~vcs-imports/qemu/git

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