gas/
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
20
21 /* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
22 July 1988
23 modified by John Hassey (hassey@dg-rtp.dg.com)
24 x86-64 support added by Jan Hubicka (jh@suse.cz)
25 VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */
26
27 /* The main tables describing the instructions is essentially a copy
28 of the "Opcode Map" chapter (Appendix A) of the Intel 80386
29 Programmers Manual. Usually, there is a capital letter, followed
30 by a small letter. The capital letter tell the addressing mode,
31 and the small letter tells about the operand size. Refer to
32 the Intel manual for details. */
33
34 #include "dis-asm.h"
35 #include "sysdep.h"
36 #include "opintl.h"
37 #include "opcode/i386.h"
38
39 #include <setjmp.h>
40
41 static int fetch_data (struct disassemble_info *, bfd_byte *);
42 static void ckprefix (void);
43 static const char *prefix_name (int, int);
44 static int print_insn (bfd_vma, disassemble_info *);
45 static void dofloat (int);
46 static void OP_ST (int, int);
47 static void OP_STi (int, int);
48 static int putop (const char *, int);
49 static void oappend (const char *);
50 static void append_seg (void);
51 static void OP_indirE (int, int);
52 static void print_operand_value (char *, int, bfd_vma);
53 static void OP_E (int, int);
54 static void OP_G (int, int);
55 static bfd_vma get64 (void);
56 static bfd_signed_vma get32 (void);
57 static bfd_signed_vma get32s (void);
58 static int get16 (void);
59 static void set_op (bfd_vma, int);
60 static void OP_REG (int, int);
61 static void OP_IMREG (int, int);
62 static void OP_I (int, int);
63 static void OP_I64 (int, int);
64 static void OP_sI (int, int);
65 static void OP_J (int, int);
66 static void OP_SEG (int, int);
67 static void OP_DIR (int, int);
68 static void OP_OFF (int, int);
69 static void OP_OFF64 (int, int);
70 static void ptr_reg (int, int);
71 static void OP_ESreg (int, int);
72 static void OP_DSreg (int, int);
73 static void OP_C (int, int);
74 static void OP_D (int, int);
75 static void OP_T (int, int);
76 static void OP_R (int, int);
77 static void OP_MMX (int, int);
78 static void OP_XMM (int, int);
79 static void OP_EM (int, int);
80 static void OP_EX (int, int);
81 static void OP_EMC (int,int);
82 static void OP_MXC (int,int);
83 static void OP_MS (int, int);
84 static void OP_XS (int, int);
85 static void OP_M (int, int);
86 static void OP_VMX (int, int);
87 static void OP_0fae (int, int);
88 static void OP_0f07 (int, int);
89 static void NOP_Fixup1 (int, int);
90 static void NOP_Fixup2 (int, int);
91 static void OP_3DNowSuffix (int, int);
92 static void OP_SIMD_Suffix (int, int);
93 static void SIMD_Fixup (int, int);
94 static void PNI_Fixup (int, int);
95 static void SVME_Fixup (int, int);
96 static void INVLPG_Fixup (int, int);
97 static void BadOp (void);
98 static void VMX_Fixup (int, int);
99 static void REP_Fixup (int, int);
100 static void CMPXCHG8B_Fixup (int, int);
101
102 struct dis_private {
103 /* Points to first byte not fetched. */
104 bfd_byte *max_fetched;
105 bfd_byte the_buffer[MAX_MNEM_SIZE];
106 bfd_vma insn_start;
107 int orig_sizeflag;
108 jmp_buf bailout;
109 };
110
111 enum address_mode
112 {
113 mode_16bit,
114 mode_32bit,
115 mode_64bit
116 };
117
118 enum address_mode address_mode;
119
120 /* Flags for the prefixes for the current instruction. See below. */
121 static int prefixes;
122
123 /* REX prefix the current instruction. See below. */
124 static int rex;
125 /* Bits of REX we've already used. */
126 static int rex_used;
127 #define REX_MODE64 8
128 #define REX_EXTX 4
129 #define REX_EXTY 2
130 #define REX_EXTZ 1
131 /* Mark parts used in the REX prefix. When we are testing for
132 empty prefix (for 8bit register REX extension), just mask it
133 out. Otherwise test for REX bit is excuse for existence of REX
134 only in case value is nonzero. */
135 #define USED_REX(value) \
136 { \
137 if (value) \
138 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
139 else \
140 rex_used |= 0x40; \
141 }
142
143 /* Flags for prefixes which we somehow handled when printing the
144 current instruction. */
145 static int used_prefixes;
146
147 /* Flags stored in PREFIXES. */
148 #define PREFIX_REPZ 1
149 #define PREFIX_REPNZ 2
150 #define PREFIX_LOCK 4
151 #define PREFIX_CS 8
152 #define PREFIX_SS 0x10
153 #define PREFIX_DS 0x20
154 #define PREFIX_ES 0x40
155 #define PREFIX_FS 0x80
156 #define PREFIX_GS 0x100
157 #define PREFIX_DATA 0x200
158 #define PREFIX_ADDR 0x400
159 #define PREFIX_FWAIT 0x800
160
161 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
162 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
163 on error. */
164 #define FETCH_DATA(info, addr) \
165 ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
166 ? 1 : fetch_data ((info), (addr)))
167
168 static int
169 fetch_data (struct disassemble_info *info, bfd_byte *addr)
170 {
171 int status;
172 struct dis_private *priv = (struct dis_private *) info->private_data;
173 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
174
175 if (addr <= priv->the_buffer + MAX_MNEM_SIZE)
176 status = (*info->read_memory_func) (start,
177 priv->max_fetched,
178 addr - priv->max_fetched,
179 info);
180 else
181 status = -1;
182 if (status != 0)
183 {
184 /* If we did manage to read at least one byte, then
185 print_insn_i386 will do something sensible. Otherwise, print
186 an error. We do that here because this is where we know
187 STATUS. */
188 if (priv->max_fetched == priv->the_buffer)
189 (*info->memory_error_func) (status, start, info);
190 longjmp (priv->bailout, 1);
191 }
192 else
193 priv->max_fetched = addr;
194 return 1;
195 }
196
197 #define XX { NULL, 0 }
198
199 #define Eb { OP_E, b_mode }
200 #define Ev { OP_E, v_mode }
201 #define Ed { OP_E, d_mode }
202 #define Edq { OP_E, dq_mode }
203 #define Edqw { OP_E, dqw_mode }
204 #define indirEv { OP_indirE, stack_v_mode }
205 #define indirEp { OP_indirE, f_mode }
206 #define stackEv { OP_E, stack_v_mode }
207 #define Em { OP_E, m_mode }
208 #define Ew { OP_E, w_mode }
209 #define M { OP_M, 0 } /* lea, lgdt, etc. */
210 #define Ma { OP_M, v_mode }
211 #define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */
212 #define Mq { OP_M, q_mode }
213 #define Gb { OP_G, b_mode }
214 #define Gv { OP_G, v_mode }
215 #define Gd { OP_G, d_mode }
216 #define Gdq { OP_G, dq_mode }
217 #define Gm { OP_G, m_mode }
218 #define Gw { OP_G, w_mode }
219 #define Rd { OP_R, d_mode }
220 #define Rm { OP_R, m_mode }
221 #define Ib { OP_I, b_mode }
222 #define sIb { OP_sI, b_mode } /* sign extened byte */
223 #define Iv { OP_I, v_mode }
224 #define Iq { OP_I, q_mode }
225 #define Iv64 { OP_I64, v_mode }
226 #define Iw { OP_I, w_mode }
227 #define I1 { OP_I, const_1_mode }
228 #define Jb { OP_J, b_mode }
229 #define Jv { OP_J, v_mode }
230 #define Cm { OP_C, m_mode }
231 #define Dm { OP_D, m_mode }
232 #define Td { OP_T, d_mode }
233
234 #define RMeAX { OP_REG, eAX_reg }
235 #define RMeBX { OP_REG, eBX_reg }
236 #define RMeCX { OP_REG, eCX_reg }
237 #define RMeDX { OP_REG, eDX_reg }
238 #define RMeSP { OP_REG, eSP_reg }
239 #define RMeBP { OP_REG, eBP_reg }
240 #define RMeSI { OP_REG, eSI_reg }
241 #define RMeDI { OP_REG, eDI_reg }
242 #define RMrAX { OP_REG, rAX_reg }
243 #define RMrBX { OP_REG, rBX_reg }
244 #define RMrCX { OP_REG, rCX_reg }
245 #define RMrDX { OP_REG, rDX_reg }
246 #define RMrSP { OP_REG, rSP_reg }
247 #define RMrBP { OP_REG, rBP_reg }
248 #define RMrSI { OP_REG, rSI_reg }
249 #define RMrDI { OP_REG, rDI_reg }
250 #define RMAL { OP_REG, al_reg }
251 #define RMAL { OP_REG, al_reg }
252 #define RMCL { OP_REG, cl_reg }
253 #define RMDL { OP_REG, dl_reg }
254 #define RMBL { OP_REG, bl_reg }
255 #define RMAH { OP_REG, ah_reg }
256 #define RMCH { OP_REG, ch_reg }
257 #define RMDH { OP_REG, dh_reg }
258 #define RMBH { OP_REG, bh_reg }
259 #define RMAX { OP_REG, ax_reg }
260 #define RMDX { OP_REG, dx_reg }
261
262 #define eAX { OP_IMREG, eAX_reg }
263 #define eBX { OP_IMREG, eBX_reg }
264 #define eCX { OP_IMREG, eCX_reg }
265 #define eDX { OP_IMREG, eDX_reg }
266 #define eSP { OP_IMREG, eSP_reg }
267 #define eBP { OP_IMREG, eBP_reg }
268 #define eSI { OP_IMREG, eSI_reg }
269 #define eDI { OP_IMREG, eDI_reg }
270 #define AL { OP_IMREG, al_reg }
271 #define CL { OP_IMREG, cl_reg }
272 #define DL { OP_IMREG, dl_reg }
273 #define BL { OP_IMREG, bl_reg }
274 #define AH { OP_IMREG, ah_reg }
275 #define CH { OP_IMREG, ch_reg }
276 #define DH { OP_IMREG, dh_reg }
277 #define BH { OP_IMREG, bh_reg }
278 #define AX { OP_IMREG, ax_reg }
279 #define DX { OP_IMREG, dx_reg }
280 #define zAX { OP_IMREG, z_mode_ax_reg }
281 #define indirDX { OP_IMREG, indir_dx_reg }
282
283 #define Sw { OP_SEG, w_mode }
284 #define Sv { OP_SEG, v_mode }
285 #define Ap { OP_DIR, 0 }
286 #define Ob { OP_OFF64, b_mode }
287 #define Ov { OP_OFF64, v_mode }
288 #define Xb { OP_DSreg, eSI_reg }
289 #define Xv { OP_DSreg, eSI_reg }
290 #define Xz { OP_DSreg, eSI_reg }
291 #define Yb { OP_ESreg, eDI_reg }
292 #define Yv { OP_ESreg, eDI_reg }
293 #define DSBX { OP_DSreg, eBX_reg }
294
295 #define es { OP_REG, es_reg }
296 #define ss { OP_REG, ss_reg }
297 #define cs { OP_REG, cs_reg }
298 #define ds { OP_REG, ds_reg }
299 #define fs { OP_REG, fs_reg }
300 #define gs { OP_REG, gs_reg }
301
302 #define MX { OP_MMX, 0 }
303 #define XM { OP_XMM, 0 }
304 #define EM { OP_EM, v_mode }
305 #define EX { OP_EX, v_mode }
306 #define MS { OP_MS, v_mode }
307 #define XS { OP_XS, v_mode }
308 #define EMC { OP_EMC, v_mode }
309 #define MXC { OP_MXC, 0 }
310 #define VM { OP_VMX, q_mode }
311 #define OPSUF { OP_3DNowSuffix, 0 }
312 #define OPSIMD { OP_SIMD_Suffix, 0 }
313
314 /* Used handle "rep" prefix for string instructions. */
315 #define Xbr { REP_Fixup, eSI_reg }
316 #define Xvr { REP_Fixup, eSI_reg }
317 #define Ybr { REP_Fixup, eDI_reg }
318 #define Yvr { REP_Fixup, eDI_reg }
319 #define Yzr { REP_Fixup, eDI_reg }
320 #define indirDXr { REP_Fixup, indir_dx_reg }
321 #define ALr { REP_Fixup, al_reg }
322 #define eAXr { REP_Fixup, eAX_reg }
323
324 #define cond_jump_flag { NULL, cond_jump_mode }
325 #define loop_jcxz_flag { NULL, loop_jcxz_mode }
326
327 /* bits in sizeflag */
328 #define SUFFIX_ALWAYS 4
329 #define AFLAG 2
330 #define DFLAG 1
331
332 #define b_mode 1 /* byte operand */
333 #define v_mode 2 /* operand size depends on prefixes */
334 #define w_mode 3 /* word operand */
335 #define d_mode 4 /* double word operand */
336 #define q_mode 5 /* quad word operand */
337 #define t_mode 6 /* ten-byte operand */
338 #define x_mode 7 /* 16-byte XMM operand */
339 #define m_mode 8 /* d_mode in 32bit, q_mode in 64bit mode. */
340 #define cond_jump_mode 9
341 #define loop_jcxz_mode 10
342 #define dq_mode 11 /* operand size depends on REX prefixes. */
343 #define dqw_mode 12 /* registers like dq_mode, memory like w_mode. */
344 #define f_mode 13 /* 4- or 6-byte pointer operand */
345 #define const_1_mode 14
346 #define stack_v_mode 15 /* v_mode for stack-related opcodes. */
347 #define z_mode 16 /* non-quad operand size depends on prefixes */
348 #define o_mode 17 /* 16-byte operand */
349
350 #define es_reg 100
351 #define cs_reg 101
352 #define ss_reg 102
353 #define ds_reg 103
354 #define fs_reg 104
355 #define gs_reg 105
356
357 #define eAX_reg 108
358 #define eCX_reg 109
359 #define eDX_reg 110
360 #define eBX_reg 111
361 #define eSP_reg 112
362 #define eBP_reg 113
363 #define eSI_reg 114
364 #define eDI_reg 115
365
366 #define al_reg 116
367 #define cl_reg 117
368 #define dl_reg 118
369 #define bl_reg 119
370 #define ah_reg 120
371 #define ch_reg 121
372 #define dh_reg 122
373 #define bh_reg 123
374
375 #define ax_reg 124
376 #define cx_reg 125
377 #define dx_reg 126
378 #define bx_reg 127
379 #define sp_reg 128
380 #define bp_reg 129
381 #define si_reg 130
382 #define di_reg 131
383
384 #define rAX_reg 132
385 #define rCX_reg 133
386 #define rDX_reg 134
387 #define rBX_reg 135
388 #define rSP_reg 136
389 #define rBP_reg 137
390 #define rSI_reg 138
391 #define rDI_reg 139
392
393 #define z_mode_ax_reg 149
394 #define indir_dx_reg 150
395
396 #define FLOATCODE 1
397 #define USE_GROUPS 2
398 #define USE_PREFIX_USER_TABLE 3
399 #define X86_64_SPECIAL 4
400 #define IS_3BYTE_OPCODE 5
401
402 #define FLOAT NULL, { { NULL, FLOATCODE } }
403
404 #define GRP1b NULL, { { NULL, USE_GROUPS }, { NULL, 0 } }
405 #define GRP1S NULL, { { NULL, USE_GROUPS }, { NULL, 1 } }
406 #define GRP1Ss NULL, { { NULL, USE_GROUPS }, { NULL, 2 } }
407 #define GRP2b NULL, { { NULL, USE_GROUPS }, { NULL, 3 } }
408 #define GRP2S NULL, { { NULL, USE_GROUPS }, { NULL, 4 } }
409 #define GRP2b_one NULL, { { NULL, USE_GROUPS }, { NULL, 5 } }
410 #define GRP2S_one NULL, { { NULL, USE_GROUPS }, { NULL, 6 } }
411 #define GRP2b_cl NULL, { { NULL, USE_GROUPS }, { NULL, 7 } }
412 #define GRP2S_cl NULL, { { NULL, USE_GROUPS }, { NULL, 8 } }
413 #define GRP3b NULL, { { NULL, USE_GROUPS }, { NULL, 9 } }
414 #define GRP3S NULL, { { NULL, USE_GROUPS }, { NULL, 10 } }
415 #define GRP4 NULL, { { NULL, USE_GROUPS }, { NULL, 11 } }
416 #define GRP5 NULL, { { NULL, USE_GROUPS }, { NULL, 12 } }
417 #define GRP6 NULL, { { NULL, USE_GROUPS }, { NULL, 13 } }
418 #define GRP7 NULL, { { NULL, USE_GROUPS }, { NULL, 14 } }
419 #define GRP8 NULL, { { NULL, USE_GROUPS }, { NULL, 15 } }
420 #define GRP9 NULL, { { NULL, USE_GROUPS }, { NULL, 16 } }
421 #define GRP11_C6 NULL, { { NULL, USE_GROUPS }, { NULL, 17 } }
422 #define GRP11_C7 NULL, { { NULL, USE_GROUPS }, { NULL, 18 } }
423 #define GRP12 NULL, { { NULL, USE_GROUPS }, { NULL, 19 } }
424 #define GRP13 NULL, { { NULL, USE_GROUPS }, { NULL, 20 } }
425 #define GRP14 NULL, { { NULL, USE_GROUPS }, { NULL, 21 } }
426 #define GRP15 NULL, { { NULL, USE_GROUPS }, { NULL, 22 } }
427 #define GRP16 NULL, { { NULL, USE_GROUPS }, { NULL, 23 } }
428 #define GRPAMD NULL, { { NULL, USE_GROUPS }, { NULL, 24 } }
429 #define GRPPADLCK1 NULL, { { NULL, USE_GROUPS }, { NULL, 25 } }
430 #define GRPPADLCK2 NULL, { { NULL, USE_GROUPS }, { NULL, 26 } }
431
432 #define PREGRP0 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 0 } }
433 #define PREGRP1 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 1 } }
434 #define PREGRP2 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 2 } }
435 #define PREGRP3 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 3 } }
436 #define PREGRP4 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 4 } }
437 #define PREGRP5 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 5 } }
438 #define PREGRP6 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 6 } }
439 #define PREGRP7 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 7 } }
440 #define PREGRP8 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 8 } }
441 #define PREGRP9 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 9 } }
442 #define PREGRP10 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 10 } }
443 #define PREGRP11 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 11 } }
444 #define PREGRP12 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 12 } }
445 #define PREGRP13 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 13 } }
446 #define PREGRP14 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 14 } }
447 #define PREGRP15 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 15 } }
448 #define PREGRP16 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 16 } }
449 #define PREGRP17 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 17 } }
450 #define PREGRP18 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 18 } }
451 #define PREGRP19 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 19 } }
452 #define PREGRP20 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 20 } }
453 #define PREGRP21 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 21 } }
454 #define PREGRP22 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 22 } }
455 #define PREGRP23 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 23 } }
456 #define PREGRP24 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 24 } }
457 #define PREGRP25 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 25 } }
458 #define PREGRP26 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 26 } }
459 #define PREGRP27 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 27 } }
460 #define PREGRP28 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 28 } }
461 #define PREGRP29 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 29 } }
462 #define PREGRP30 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 30 } }
463 #define PREGRP31 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 31 } }
464 #define PREGRP32 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 32 } }
465 #define PREGRP33 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 33 } }
466 #define PREGRP34 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 34 } }
467 #define PREGRP35 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 35 } }
468 #define PREGRP36 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 36 } }
469 #define PREGRP37 NULL, { { NULL, USE_PREFIX_USER_TABLE }, { NULL, 37 } }
470
471
472 #define X86_64_0 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 0 } }
473 #define X86_64_1 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 1 } }
474 #define X86_64_2 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 2 } }
475 #define X86_64_3 NULL, { { NULL, X86_64_SPECIAL }, { NULL, 3 } }
476
477 #define THREE_BYTE_0 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 0 } }
478 #define THREE_BYTE_1 NULL, { { NULL, IS_3BYTE_OPCODE }, { NULL, 1 } }
479
480 typedef void (*op_rtn) (int bytemode, int sizeflag);
481
482 struct dis386 {
483 const char *name;
484 struct
485 {
486 op_rtn rtn;
487 int bytemode;
488 } op[MAX_OPERANDS];
489 };
490
491 /* Upper case letters in the instruction names here are macros.
492 'A' => print 'b' if no register operands or suffix_always is true
493 'B' => print 'b' if suffix_always is true
494 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand
495 . size prefix
496 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if
497 . suffix_always is true
498 'E' => print 'e' if 32-bit form of jcxz
499 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
500 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
501 'H' => print ",pt" or ",pn" branch hint
502 'I' => honor following macro letter even in Intel mode (implemented only
503 . for some of the macro letters)
504 'J' => print 'l'
505 'L' => print 'l' if suffix_always is true
506 'N' => print 'n' if instruction has no wait "prefix"
507 'O' => print 'd' or 'o' (or 'q' in Intel mode)
508 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
509 . or suffix_always is true. print 'q' if rex prefix is present.
510 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
511 . is true
512 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
513 'S' => print 'w', 'l' or 'q' if suffix_always is true
514 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
515 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
516 'V' => print 'q' in 64bit mode and behave as 'S' otherwise
517 'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
518 'X' => print 's', 'd' depending on data16 prefix (for XMM)
519 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
520 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise
521
522 Many of the above letters print nothing in Intel mode. See "putop"
523 for the details.
524
525 Braces '{' and '}', and vertical bars '|', indicate alternative
526 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
527 modes. In cases where there are only two alternatives, the X86_64
528 instruction is reserved, and "(bad)" is printed.
529 */
530
531 static const struct dis386 dis386[] = {
532 /* 00 */
533 { "addB", { Eb, Gb } },
534 { "addS", { Ev, Gv } },
535 { "addB", { Gb, Eb } },
536 { "addS", { Gv, Ev } },
537 { "addB", { AL, Ib } },
538 { "addS", { eAX, Iv } },
539 { "push{T|}", { es } },
540 { "pop{T|}", { es } },
541 /* 08 */
542 { "orB", { Eb, Gb } },
543 { "orS", { Ev, Gv } },
544 { "orB", { Gb, Eb } },
545 { "orS", { Gv, Ev } },
546 { "orB", { AL, Ib } },
547 { "orS", { eAX, Iv } },
548 { "push{T|}", { cs } },
549 { "(bad)", { XX } }, /* 0x0f extended opcode escape */
550 /* 10 */
551 { "adcB", { Eb, Gb } },
552 { "adcS", { Ev, Gv } },
553 { "adcB", { Gb, Eb } },
554 { "adcS", { Gv, Ev } },
555 { "adcB", { AL, Ib } },
556 { "adcS", { eAX, Iv } },
557 { "push{T|}", { ss } },
558 { "pop{T|}", { ss } },
559 /* 18 */
560 { "sbbB", { Eb, Gb } },
561 { "sbbS", { Ev, Gv } },
562 { "sbbB", { Gb, Eb } },
563 { "sbbS", { Gv, Ev } },
564 { "sbbB", { AL, Ib } },
565 { "sbbS", { eAX, Iv } },
566 { "push{T|}", { ds } },
567 { "pop{T|}", { ds } },
568 /* 20 */
569 { "andB", { Eb, Gb } },
570 { "andS", { Ev, Gv } },
571 { "andB", { Gb, Eb } },
572 { "andS", { Gv, Ev } },
573 { "andB", { AL, Ib } },
574 { "andS", { eAX, Iv } },
575 { "(bad)", { XX } }, /* SEG ES prefix */
576 { "daa{|}", { XX } },
577 /* 28 */
578 { "subB", { Eb, Gb } },
579 { "subS", { Ev, Gv } },
580 { "subB", { Gb, Eb } },
581 { "subS", { Gv, Ev } },
582 { "subB", { AL, Ib } },
583 { "subS", { eAX, Iv } },
584 { "(bad)", { XX } }, /* SEG CS prefix */
585 { "das{|}", { XX } },
586 /* 30 */
587 { "xorB", { Eb, Gb } },
588 { "xorS", { Ev, Gv } },
589 { "xorB", { Gb, Eb } },
590 { "xorS", { Gv, Ev } },
591 { "xorB", { AL, Ib } },
592 { "xorS", { eAX, Iv } },
593 { "(bad)", { XX } }, /* SEG SS prefix */
594 { "aaa{|}", { XX } },
595 /* 38 */
596 { "cmpB", { Eb, Gb } },
597 { "cmpS", { Ev, Gv } },
598 { "cmpB", { Gb, Eb } },
599 { "cmpS", { Gv, Ev } },
600 { "cmpB", { AL, Ib } },
601 { "cmpS", { eAX, Iv } },
602 { "(bad)", { XX } }, /* SEG DS prefix */
603 { "aas{|}", { XX } },
604 /* 40 */
605 { "inc{S|}", { RMeAX } },
606 { "inc{S|}", { RMeCX } },
607 { "inc{S|}", { RMeDX } },
608 { "inc{S|}", { RMeBX } },
609 { "inc{S|}", { RMeSP } },
610 { "inc{S|}", { RMeBP } },
611 { "inc{S|}", { RMeSI } },
612 { "inc{S|}", { RMeDI } },
613 /* 48 */
614 { "dec{S|}", { RMeAX } },
615 { "dec{S|}", { RMeCX } },
616 { "dec{S|}", { RMeDX } },
617 { "dec{S|}", { RMeBX } },
618 { "dec{S|}", { RMeSP } },
619 { "dec{S|}", { RMeBP } },
620 { "dec{S|}", { RMeSI } },
621 { "dec{S|}", { RMeDI } },
622 /* 50 */
623 { "pushV", { RMrAX } },
624 { "pushV", { RMrCX } },
625 { "pushV", { RMrDX } },
626 { "pushV", { RMrBX } },
627 { "pushV", { RMrSP } },
628 { "pushV", { RMrBP } },
629 { "pushV", { RMrSI } },
630 { "pushV", { RMrDI } },
631 /* 58 */
632 { "popV", { RMrAX } },
633 { "popV", { RMrCX } },
634 { "popV", { RMrDX } },
635 { "popV", { RMrBX } },
636 { "popV", { RMrSP } },
637 { "popV", { RMrBP } },
638 { "popV", { RMrSI } },
639 { "popV", { RMrDI } },
640 /* 60 */
641 { X86_64_0 },
642 { X86_64_1 },
643 { X86_64_2 },
644 { X86_64_3 },
645 { "(bad)", { XX } }, /* seg fs */
646 { "(bad)", { XX } }, /* seg gs */
647 { "(bad)", { XX } }, /* op size prefix */
648 { "(bad)", { XX } }, /* adr size prefix */
649 /* 68 */
650 { "pushT", { Iq } },
651 { "imulS", { Gv, Ev, Iv } },
652 { "pushT", { sIb } },
653 { "imulS", { Gv, Ev, sIb } },
654 { "ins{b||b|}", { Ybr, indirDX } },
655 { "ins{R||G|}", { Yzr, indirDX } },
656 { "outs{b||b|}", { indirDXr, Xb } },
657 { "outs{R||G|}", { indirDXr, Xz } },
658 /* 70 */
659 { "joH", { Jb, XX, cond_jump_flag } },
660 { "jnoH", { Jb, XX, cond_jump_flag } },
661 { "jbH", { Jb, XX, cond_jump_flag } },
662 { "jaeH", { Jb, XX, cond_jump_flag } },
663 { "jeH", { Jb, XX, cond_jump_flag } },
664 { "jneH", { Jb, XX, cond_jump_flag } },
665 { "jbeH", { Jb, XX, cond_jump_flag } },
666 { "jaH", { Jb, XX, cond_jump_flag } },
667 /* 78 */
668 { "jsH", { Jb, XX, cond_jump_flag } },
669 { "jnsH", { Jb, XX, cond_jump_flag } },
670 { "jpH", { Jb, XX, cond_jump_flag } },
671 { "jnpH", { Jb, XX, cond_jump_flag } },
672 { "jlH", { Jb, XX, cond_jump_flag } },
673 { "jgeH", { Jb, XX, cond_jump_flag } },
674 { "jleH", { Jb, XX, cond_jump_flag } },
675 { "jgH", { Jb, XX, cond_jump_flag } },
676 /* 80 */
677 { GRP1b },
678 { GRP1S },
679 { "(bad)", { XX } },
680 { GRP1Ss },
681 { "testB", { Eb, Gb } },
682 { "testS", { Ev, Gv } },
683 { "xchgB", { Eb, Gb } },
684 { "xchgS", { Ev, Gv } },
685 /* 88 */
686 { "movB", { Eb, Gb } },
687 { "movS", { Ev, Gv } },
688 { "movB", { Gb, Eb } },
689 { "movS", { Gv, Ev } },
690 { "movD", { Sv, Sw } },
691 { "leaS", { Gv, M } },
692 { "movD", { Sw, Sv } },
693 { "popU", { stackEv } },
694 /* 90 */
695 { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } },
696 { "xchgS", { RMeCX, eAX } },
697 { "xchgS", { RMeDX, eAX } },
698 { "xchgS", { RMeBX, eAX } },
699 { "xchgS", { RMeSP, eAX } },
700 { "xchgS", { RMeBP, eAX } },
701 { "xchgS", { RMeSI, eAX } },
702 { "xchgS", { RMeDI, eAX } },
703 /* 98 */
704 { "cW{t||t|}R", { XX } },
705 { "cR{t||t|}O", { XX } },
706 { "Jcall{T|}", { Ap } },
707 { "(bad)", { XX } }, /* fwait */
708 { "pushfT", { XX } },
709 { "popfT", { XX } },
710 { "sahf{|}", { XX } },
711 { "lahf{|}", { XX } },
712 /* a0 */
713 { "movB", { AL, Ob } },
714 { "movS", { eAX, Ov } },
715 { "movB", { Ob, AL } },
716 { "movS", { Ov, eAX } },
717 { "movs{b||b|}", { Ybr, Xb } },
718 { "movs{R||R|}", { Yvr, Xv } },
719 { "cmps{b||b|}", { Xb, Yb } },
720 { "cmps{R||R|}", { Xv, Yv } },
721 /* a8 */
722 { "testB", { AL, Ib } },
723 { "testS", { eAX, Iv } },
724 { "stosB", { Ybr, AL } },
725 { "stosS", { Yvr, eAX } },
726 { "lodsB", { ALr, Xb } },
727 { "lodsS", { eAXr, Xv } },
728 { "scasB", { AL, Yb } },
729 { "scasS", { eAX, Yv } },
730 /* b0 */
731 { "movB", { RMAL, Ib } },
732 { "movB", { RMCL, Ib } },
733 { "movB", { RMDL, Ib } },
734 { "movB", { RMBL, Ib } },
735 { "movB", { RMAH, Ib } },
736 { "movB", { RMCH, Ib } },
737 { "movB", { RMDH, Ib } },
738 { "movB", { RMBH, Ib } },
739 /* b8 */
740 { "movS", { RMeAX, Iv64 } },
741 { "movS", { RMeCX, Iv64 } },
742 { "movS", { RMeDX, Iv64 } },
743 { "movS", { RMeBX, Iv64 } },
744 { "movS", { RMeSP, Iv64 } },
745 { "movS", { RMeBP, Iv64 } },
746 { "movS", { RMeSI, Iv64 } },
747 { "movS", { RMeDI, Iv64 } },
748 /* c0 */
749 { GRP2b },
750 { GRP2S },
751 { "retT", { Iw } },
752 { "retT", { XX } },
753 { "les{S|}", { Gv, Mp } },
754 { "ldsS", { Gv, Mp } },
755 { GRP11_C6 },
756 { GRP11_C7 },
757 /* c8 */
758 { "enterT", { Iw, Ib } },
759 { "leaveT", { XX } },
760 { "lretP", { Iw } },
761 { "lretP", { XX } },
762 { "int3", { XX } },
763 { "int", { Ib } },
764 { "into{|}", { XX } },
765 { "iretP", { XX } },
766 /* d0 */
767 { GRP2b_one },
768 { GRP2S_one },
769 { GRP2b_cl },
770 { GRP2S_cl },
771 { "aam{|}", { sIb } },
772 { "aad{|}", { sIb } },
773 { "(bad)", { XX } },
774 { "xlat", { DSBX } },
775 /* d8 */
776 { FLOAT },
777 { FLOAT },
778 { FLOAT },
779 { FLOAT },
780 { FLOAT },
781 { FLOAT },
782 { FLOAT },
783 { FLOAT },
784 /* e0 */
785 { "loopneFH", { Jb, XX, loop_jcxz_flag } },
786 { "loopeFH", { Jb, XX, loop_jcxz_flag } },
787 { "loopFH", { Jb, XX, loop_jcxz_flag } },
788 { "jEcxzH", { Jb, XX, loop_jcxz_flag } },
789 { "inB", { AL, Ib } },
790 { "inG", { zAX, Ib } },
791 { "outB", { Ib, AL } },
792 { "outG", { Ib, zAX } },
793 /* e8 */
794 { "callT", { Jv } },
795 { "jmpT", { Jv } },
796 { "Jjmp{T|}", { Ap } },
797 { "jmp", { Jb } },
798 { "inB", { AL, indirDX } },
799 { "inG", { zAX, indirDX } },
800 { "outB", { indirDX, AL } },
801 { "outG", { indirDX, zAX } },
802 /* f0 */
803 { "(bad)", { XX } }, /* lock prefix */
804 { "icebp", { XX } },
805 { "(bad)", { XX } }, /* repne */
806 { "(bad)", { XX } }, /* repz */
807 { "hlt", { XX } },
808 { "cmc", { XX } },
809 { GRP3b },
810 { GRP3S },
811 /* f8 */
812 { "clc", { XX } },
813 { "stc", { XX } },
814 { "cli", { XX } },
815 { "sti", { XX } },
816 { "cld", { XX } },
817 { "std", { XX } },
818 { GRP4 },
819 { GRP5 },
820 };
821
822 static const struct dis386 dis386_twobyte[] = {
823 /* 00 */
824 { GRP6 },
825 { GRP7 },
826 { "larS", { Gv, Ew } },
827 { "lslS", { Gv, Ew } },
828 { "(bad)", { XX } },
829 { "syscall", { XX } },
830 { "clts", { XX } },
831 { "sysretP", { XX } },
832 /* 08 */
833 { "invd", { XX } },
834 { "wbinvd", { XX } },
835 { "(bad)", { XX } },
836 { "ud2a", { XX } },
837 { "(bad)", { XX } },
838 { GRPAMD },
839 { "femms", { XX } },
840 { "", { MX, EM, OPSUF } }, /* See OP_3DNowSuffix. */
841 /* 10 */
842 { PREGRP8 },
843 { PREGRP9 },
844 { PREGRP30 },
845 { "movlpX", { EX, XM, { SIMD_Fixup, 'h' } } },
846 { "unpcklpX", { XM, EX } },
847 { "unpckhpX", { XM, EX } },
848 { PREGRP31 },
849 { "movhpX", { EX, XM, { SIMD_Fixup, 'l' } } },
850 /* 18 */
851 { GRP16 },
852 { "(bad)", { XX } },
853 { "(bad)", { XX } },
854 { "(bad)", { XX } },
855 { "(bad)", { XX } },
856 { "(bad)", { XX } },
857 { "(bad)", { XX } },
858 { "nopQ", { Ev } },
859 /* 20 */
860 { "movZ", { Rm, Cm } },
861 { "movZ", { Rm, Dm } },
862 { "movZ", { Cm, Rm } },
863 { "movZ", { Dm, Rm } },
864 { "movL", { Rd, Td } },
865 { "(bad)", { XX } },
866 { "movL", { Td, Rd } },
867 { "(bad)", { XX } },
868 /* 28 */
869 { "movapX", { XM, EX } },
870 { "movapX", { EX, XM } },
871 { PREGRP2 },
872 { PREGRP33 },
873 { PREGRP4 },
874 { PREGRP3 },
875 { "ucomisX", { XM,EX } },
876 { "comisX", { XM,EX } },
877 /* 30 */
878 { "wrmsr", { XX } },
879 { "rdtsc", { XX } },
880 { "rdmsr", { XX } },
881 { "rdpmc", { XX } },
882 { "sysenter", { XX } },
883 { "sysexit", { XX } },
884 { "(bad)", { XX } },
885 { "(bad)", { XX } },
886 /* 38 */
887 { THREE_BYTE_0 },
888 { "(bad)", { XX } },
889 { THREE_BYTE_1 },
890 { "(bad)", { XX } },
891 { "(bad)", { XX } },
892 { "(bad)", { XX } },
893 { "(bad)", { XX } },
894 { "(bad)", { XX } },
895 /* 40 */
896 { "cmovo", { Gv, Ev } },
897 { "cmovno", { Gv, Ev } },
898 { "cmovb", { Gv, Ev } },
899 { "cmovae", { Gv, Ev } },
900 { "cmove", { Gv, Ev } },
901 { "cmovne", { Gv, Ev } },
902 { "cmovbe", { Gv, Ev } },
903 { "cmova", { Gv, Ev } },
904 /* 48 */
905 { "cmovs", { Gv, Ev } },
906 { "cmovns", { Gv, Ev } },
907 { "cmovp", { Gv, Ev } },
908 { "cmovnp", { Gv, Ev } },
909 { "cmovl", { Gv, Ev } },
910 { "cmovge", { Gv, Ev } },
911 { "cmovle", { Gv, Ev } },
912 { "cmovg", { Gv, Ev } },
913 /* 50 */
914 { "movmskpX", { Gdq, XS } },
915 { PREGRP13 },
916 { PREGRP12 },
917 { PREGRP11 },
918 { "andpX", { XM, EX } },
919 { "andnpX", { XM, EX } },
920 { "orpX", { XM, EX } },
921 { "xorpX", { XM, EX } },
922 /* 58 */
923 { PREGRP0 },
924 { PREGRP10 },
925 { PREGRP17 },
926 { PREGRP16 },
927 { PREGRP14 },
928 { PREGRP7 },
929 { PREGRP5 },
930 { PREGRP6 },
931 /* 60 */
932 { "punpcklbw", { MX, EM } },
933 { "punpcklwd", { MX, EM } },
934 { "punpckldq", { MX, EM } },
935 { "packsswb", { MX, EM } },
936 { "pcmpgtb", { MX, EM } },
937 { "pcmpgtw", { MX, EM } },
938 { "pcmpgtd", { MX, EM } },
939 { "packuswb", { MX, EM } },
940 /* 68 */
941 { "punpckhbw", { MX, EM } },
942 { "punpckhwd", { MX, EM } },
943 { "punpckhdq", { MX, EM } },
944 { "packssdw", { MX, EM } },
945 { PREGRP26 },
946 { PREGRP24 },
947 { "movd", { MX, Edq } },
948 { PREGRP19 },
949 /* 70 */
950 { PREGRP22 },
951 { GRP12 },
952 { GRP13 },
953 { GRP14 },
954 { "pcmpeqb", { MX, EM } },
955 { "pcmpeqw", { MX, EM } },
956 { "pcmpeqd", { MX, EM } },
957 { "emms", { XX } },
958 /* 78 */
959 { PREGRP34 },
960 { PREGRP35 },
961 { "(bad)", { XX } },
962 { "(bad)", { XX } },
963 { PREGRP28 },
964 { PREGRP29 },
965 { PREGRP23 },
966 { PREGRP20 },
967 /* 80 */
968 { "joH", { Jv, XX, cond_jump_flag } },
969 { "jnoH", { Jv, XX, cond_jump_flag } },
970 { "jbH", { Jv, XX, cond_jump_flag } },
971 { "jaeH", { Jv, XX, cond_jump_flag } },
972 { "jeH", { Jv, XX, cond_jump_flag } },
973 { "jneH", { Jv, XX, cond_jump_flag } },
974 { "jbeH", { Jv, XX, cond_jump_flag } },
975 { "jaH", { Jv, XX, cond_jump_flag } },
976 /* 88 */
977 { "jsH", { Jv, XX, cond_jump_flag } },
978 { "jnsH", { Jv, XX, cond_jump_flag } },
979 { "jpH", { Jv, XX, cond_jump_flag } },
980 { "jnpH", { Jv, XX, cond_jump_flag } },
981 { "jlH", { Jv, XX, cond_jump_flag } },
982 { "jgeH", { Jv, XX, cond_jump_flag } },
983 { "jleH", { Jv, XX, cond_jump_flag } },
984 { "jgH", { Jv, XX, cond_jump_flag } },
985 /* 90 */
986 { "seto", { Eb } },
987 { "setno", { Eb } },
988 { "setb", { Eb } },
989 { "setae", { Eb } },
990 { "sete", { Eb } },
991 { "setne", { Eb } },
992 { "setbe", { Eb } },
993 { "seta", { Eb } },
994 /* 98 */
995 { "sets", { Eb } },
996 { "setns", { Eb } },
997 { "setp", { Eb } },
998 { "setnp", { Eb } },
999 { "setl", { Eb } },
1000 { "setge", { Eb } },
1001 { "setle", { Eb } },
1002 { "setg", { Eb } },
1003 /* a0 */
1004 { "pushT", { fs } },
1005 { "popT", { fs } },
1006 { "cpuid", { XX } },
1007 { "btS", { Ev, Gv } },
1008 { "shldS", { Ev, Gv, Ib } },
1009 { "shldS", { Ev, Gv, CL } },
1010 { GRPPADLCK2 },
1011 { GRPPADLCK1 },
1012 /* a8 */
1013 { "pushT", { gs } },
1014 { "popT", { gs } },
1015 { "rsm", { XX } },
1016 { "btsS", { Ev, Gv } },
1017 { "shrdS", { Ev, Gv, Ib } },
1018 { "shrdS", { Ev, Gv, CL } },
1019 { GRP15 },
1020 { "imulS", { Gv, Ev } },
1021 /* b0 */
1022 { "cmpxchgB", { Eb, Gb } },
1023 { "cmpxchgS", { Ev, Gv } },
1024 { "lssS", { Gv, Mp } },
1025 { "btrS", { Ev, Gv } },
1026 { "lfsS", { Gv, Mp } },
1027 { "lgsS", { Gv, Mp } },
1028 { "movz{bR|x|bR|x}", { Gv, Eb } },
1029 { "movz{wR|x|wR|x}", { Gv, Ew } }, /* yes, there really is movzww ! */
1030 /* b8 */
1031 { PREGRP37 },
1032 { "ud2b", { XX } },
1033 { GRP8 },
1034 { "btcS", { Ev, Gv } },
1035 { "bsfS", { Gv, Ev } },
1036 { PREGRP36 },
1037 { "movs{bR|x|bR|x}", { Gv, Eb } },
1038 { "movs{wR|x|wR|x}", { Gv, Ew } }, /* yes, there really is movsww ! */
1039 /* c0 */
1040 { "xaddB", { Eb, Gb } },
1041 { "xaddS", { Ev, Gv } },
1042 { PREGRP1 },
1043 { "movntiS", { Ev, Gv } },
1044 { "pinsrw", { MX, Edqw, Ib } },
1045 { "pextrw", { Gdq, MS, Ib } },
1046 { "shufpX", { XM, EX, Ib } },
1047 { GRP9 },
1048 /* c8 */
1049 { "bswap", { RMeAX } },
1050 { "bswap", { RMeCX } },
1051 { "bswap", { RMeDX } },
1052 { "bswap", { RMeBX } },
1053 { "bswap", { RMeSP } },
1054 { "bswap", { RMeBP } },
1055 { "bswap", { RMeSI } },
1056 { "bswap", { RMeDI } },
1057 /* d0 */
1058 { PREGRP27 },
1059 { "psrlw", { MX, EM } },
1060 { "psrld", { MX, EM } },
1061 { "psrlq", { MX, EM } },
1062 { "paddq", { MX, EM } },
1063 { "pmullw", { MX, EM } },
1064 { PREGRP21 },
1065 { "pmovmskb", { Gdq, MS } },
1066 /* d8 */
1067 { "psubusb", { MX, EM } },
1068 { "psubusw", { MX, EM } },
1069 { "pminub", { MX, EM } },
1070 { "pand", { MX, EM } },
1071 { "paddusb", { MX, EM } },
1072 { "paddusw", { MX, EM } },
1073 { "pmaxub", { MX, EM } },
1074 { "pandn", { MX, EM } },
1075 /* e0 */
1076 { "pavgb", { MX, EM } },
1077 { "psraw", { MX, EM } },
1078 { "psrad", { MX, EM } },
1079 { "pavgw", { MX, EM } },
1080 { "pmulhuw", { MX, EM } },
1081 { "pmulhw", { MX, EM } },
1082 { PREGRP15 },
1083 { PREGRP25 },
1084 /* e8 */
1085 { "psubsb", { MX, EM } },
1086 { "psubsw", { MX, EM } },
1087 { "pminsw", { MX, EM } },
1088 { "por", { MX, EM } },
1089 { "paddsb", { MX, EM } },
1090 { "paddsw", { MX, EM } },
1091 { "pmaxsw", { MX, EM } },
1092 { "pxor", { MX, EM } },
1093 /* f0 */
1094 { PREGRP32 },
1095 { "psllw", { MX, EM } },
1096 { "pslld", { MX, EM } },
1097 { "psllq", { MX, EM } },
1098 { "pmuludq", { MX, EM } },
1099 { "pmaddwd", { MX, EM } },
1100 { "psadbw", { MX, EM } },
1101 { PREGRP18 },
1102 /* f8 */
1103 { "psubb", { MX, EM } },
1104 { "psubw", { MX, EM } },
1105 { "psubd", { MX, EM } },
1106 { "psubq", { MX, EM } },
1107 { "paddb", { MX, EM } },
1108 { "paddw", { MX, EM } },
1109 { "paddd", { MX, EM } },
1110 { "(bad)", { XX } },
1111 };
1112
1113 static const unsigned char onebyte_has_modrm[256] = {
1114 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1115 /* ------------------------------- */
1116 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1117 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1118 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1119 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1120 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1121 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1122 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1123 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1124 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1125 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1126 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1127 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1128 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1129 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1130 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1131 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1132 /* ------------------------------- */
1133 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1134 };
1135
1136 static const unsigned char twobyte_has_modrm[256] = {
1137 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1138 /* ------------------------------- */
1139 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1140 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1, /* 1f */
1141 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1142 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1143 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1144 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1145 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1146 /* 70 */ 1,1,1,1,1,1,1,0,1,1,0,0,1,1,1,1, /* 7f */
1147 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1148 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1149 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1150 /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
1151 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1152 /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1153 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1154 /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1155 /* ------------------------------- */
1156 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1157 };
1158
1159 static const unsigned char twobyte_uses_DATA_prefix[256] = {
1160 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1161 /* ------------------------------- */
1162 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1163 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1164 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1165 /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
1166 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1167 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1168 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1169 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1, /* 7f */
1170 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1171 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1172 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1173 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1174 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1175 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1176 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1177 /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1178 /* ------------------------------- */
1179 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1180 };
1181
1182 static const unsigned char twobyte_uses_REPNZ_prefix[256] = {
1183 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1184 /* ------------------------------- */
1185 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1186 /* 10 */ 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1187 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1188 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1189 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1190 /* 50 */ 0,1,0,0,0,0,0,0,1,1,1,0,1,1,1,1, /* 5f */
1191 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1192 /* 70 */ 1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0, /* 7f */
1193 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1194 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1195 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1196 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1197 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1198 /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1199 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1200 /* f0 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1201 /* ------------------------------- */
1202 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1203 };
1204
1205 static const unsigned char twobyte_uses_REPZ_prefix[256] = {
1206 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1207 /* ------------------------------- */
1208 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1209 /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */
1210 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0, /* 2f */
1211 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1212 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1213 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1214 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 6f */
1215 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1216 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1217 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1218 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1219 /* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
1220 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1221 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1222 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1223 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1224 /* ------------------------------- */
1225 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1226 };
1227
1228 /* This is used to determine if opcode 0f 38 XX uses DATA prefix. */
1229 static const unsigned char threebyte_0x38_uses_DATA_prefix[256] = {
1230 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1231 /* ------------------------------- */
1232 /* 00 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0, /* 0f */
1233 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0, /* 1f */
1234 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1235 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1236 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1237 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1238 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1239 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1240 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1241 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1242 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1243 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1244 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1245 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1246 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1247 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1248 /* ------------------------------- */
1249 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1250 };
1251
1252 /* This is used to determine if opcode 0f 38 XX uses REPNZ prefix. */
1253 static const unsigned char threebyte_0x38_uses_REPNZ_prefix[256] = {
1254 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1255 /* ------------------------------- */
1256 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1257 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1258 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1259 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1260 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1261 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1262 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1263 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1264 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1265 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1266 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1267 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1268 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1269 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1270 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1271 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1272 /* ------------------------------- */
1273 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1274 };
1275
1276 /* This is used to determine if opcode 0f 38 XX uses REPZ prefix. */
1277 static const unsigned char threebyte_0x38_uses_REPZ_prefix[256] = {
1278 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1279 /* ------------------------------- */
1280 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1281 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1282 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1283 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1284 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1285 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1286 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1287 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1288 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1289 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1290 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1291 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1292 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1293 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1294 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1295 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1296 /* ------------------------------- */
1297 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1298 };
1299
1300 /* This is used to determine if opcode 0f 3a XX uses DATA prefix. */
1301 static const unsigned char threebyte_0x3a_uses_DATA_prefix[256] = {
1302 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1303 /* ------------------------------- */
1304 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, /* 0f */
1305 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1306 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1307 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1308 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1309 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1310 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1311 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1312 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1313 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1314 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1315 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1316 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1317 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1318 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1319 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1320 /* ------------------------------- */
1321 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1322 };
1323
1324 /* This is used to determine if opcode 0f 3a XX uses REPNZ prefix. */
1325 static const unsigned char threebyte_0x3a_uses_REPNZ_prefix[256] = {
1326 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1327 /* ------------------------------- */
1328 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1329 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1330 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1331 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1332 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1333 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1334 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1335 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1336 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1337 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1338 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1339 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1340 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1341 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1342 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1343 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1344 /* ------------------------------- */
1345 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1346 };
1347
1348 /* This is used to determine if opcode 0f 3a XX uses REPZ prefix. */
1349 static const unsigned char threebyte_0x3a_uses_REPZ_prefix[256] = {
1350 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1351 /* ------------------------------- */
1352 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1353 /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1354 /* 20 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 2f */
1355 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1356 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1357 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
1358 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1359 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1360 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1361 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1362 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1363 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1364 /* c0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1365 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1366 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1367 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ff */
1368 /* ------------------------------- */
1369 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1370 };
1371
1372 static char obuf[100];
1373 static char *obufp;
1374 static char scratchbuf[100];
1375 static unsigned char *start_codep;
1376 static unsigned char *insn_codep;
1377 static unsigned char *codep;
1378 static disassemble_info *the_info;
1379 static int mod;
1380 static int rm;
1381 static int reg;
1382 static unsigned char need_modrm;
1383
1384 /* If we are accessing mod/rm/reg without need_modrm set, then the
1385 values are stale. Hitting this abort likely indicates that you
1386 need to update onebyte_has_modrm or twobyte_has_modrm. */
1387 #define MODRM_CHECK if (!need_modrm) abort ()
1388
1389 static const char **names64;
1390 static const char **names32;
1391 static const char **names16;
1392 static const char **names8;
1393 static const char **names8rex;
1394 static const char **names_seg;
1395 static const char **index16;
1396
1397 static const char *intel_names64[] = {
1398 "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
1399 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
1400 };
1401 static const char *intel_names32[] = {
1402 "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
1403 "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
1404 };
1405 static const char *intel_names16[] = {
1406 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
1407 "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
1408 };
1409 static const char *intel_names8[] = {
1410 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
1411 };
1412 static const char *intel_names8rex[] = {
1413 "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
1414 "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
1415 };
1416 static const char *intel_names_seg[] = {
1417 "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
1418 };
1419 static const char *intel_index16[] = {
1420 "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
1421 };
1422
1423 static const char *att_names64[] = {
1424 "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
1425 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1426 };
1427 static const char *att_names32[] = {
1428 "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
1429 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1430 };
1431 static const char *att_names16[] = {
1432 "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
1433 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1434 };
1435 static const char *att_names8[] = {
1436 "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
1437 };
1438 static const char *att_names8rex[] = {
1439 "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
1440 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1441 };
1442 static const char *att_names_seg[] = {
1443 "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
1444 };
1445 static const char *att_index16[] = {
1446 "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
1447 };
1448
1449 static const struct dis386 grps[][8] = {
1450 /* GRP1b */
1451 {
1452 { "addA", { Eb, Ib } },
1453 { "orA", { Eb, Ib } },
1454 { "adcA", { Eb, Ib } },
1455 { "sbbA", { Eb, Ib } },
1456 { "andA", { Eb, Ib } },
1457 { "subA", { Eb, Ib } },
1458 { "xorA", { Eb, Ib } },
1459 { "cmpA", { Eb, Ib } },
1460 },
1461 /* GRP1S */
1462 {
1463 { "addQ", { Ev, Iv } },
1464 { "orQ", { Ev, Iv } },
1465 { "adcQ", { Ev, Iv } },
1466 { "sbbQ", { Ev, Iv } },
1467 { "andQ", { Ev, Iv } },
1468 { "subQ", { Ev, Iv } },
1469 { "xorQ", { Ev, Iv } },
1470 { "cmpQ", { Ev, Iv } },
1471 },
1472 /* GRP1Ss */
1473 {
1474 { "addQ", { Ev, sIb } },
1475 { "orQ", { Ev, sIb } },
1476 { "adcQ", { Ev, sIb } },
1477 { "sbbQ", { Ev, sIb } },
1478 { "andQ", { Ev, sIb } },
1479 { "subQ", { Ev, sIb } },
1480 { "xorQ", { Ev, sIb } },
1481 { "cmpQ", { Ev, sIb } },
1482 },
1483 /* GRP2b */
1484 {
1485 { "rolA", { Eb, Ib } },
1486 { "rorA", { Eb, Ib } },
1487 { "rclA", { Eb, Ib } },
1488 { "rcrA", { Eb, Ib } },
1489 { "shlA", { Eb, Ib } },
1490 { "shrA", { Eb, Ib } },
1491 { "(bad)", { XX } },
1492 { "sarA", { Eb, Ib } },
1493 },
1494 /* GRP2S */
1495 {
1496 { "rolQ", { Ev, Ib } },
1497 { "rorQ", { Ev, Ib } },
1498 { "rclQ", { Ev, Ib } },
1499 { "rcrQ", { Ev, Ib } },
1500 { "shlQ", { Ev, Ib } },
1501 { "shrQ", { Ev, Ib } },
1502 { "(bad)", { XX } },
1503 { "sarQ", { Ev, Ib } },
1504 },
1505 /* GRP2b_one */
1506 {
1507 { "rolA", { Eb, I1 } },
1508 { "rorA", { Eb, I1 } },
1509 { "rclA", { Eb, I1 } },
1510 { "rcrA", { Eb, I1 } },
1511 { "shlA", { Eb, I1 } },
1512 { "shrA", { Eb, I1 } },
1513 { "(bad)", { XX } },
1514 { "sarA", { Eb, I1 } },
1515 },
1516 /* GRP2S_one */
1517 {
1518 { "rolQ", { Ev, I1 } },
1519 { "rorQ", { Ev, I1 } },
1520 { "rclQ", { Ev, I1 } },
1521 { "rcrQ", { Ev, I1 } },
1522 { "shlQ", { Ev, I1 } },
1523 { "shrQ", { Ev, I1 } },
1524 { "(bad)", { XX } },
1525 { "sarQ", { Ev, I1 } },
1526 },
1527 /* GRP2b_cl */
1528 {
1529 { "rolA", { Eb, CL } },
1530 { "rorA", { Eb, CL } },
1531 { "rclA", { Eb, CL } },
1532 { "rcrA", { Eb, CL } },
1533 { "shlA", { Eb, CL } },
1534 { "shrA", { Eb, CL } },
1535 { "(bad)", { XX } },
1536 { "sarA", { Eb, CL } },
1537 },
1538 /* GRP2S_cl */
1539 {
1540 { "rolQ", { Ev, CL } },
1541 { "rorQ", { Ev, CL } },
1542 { "rclQ", { Ev, CL } },
1543 { "rcrQ", { Ev, CL } },
1544 { "shlQ", { Ev, CL } },
1545 { "shrQ", { Ev, CL } },
1546 { "(bad)", { XX } },
1547 { "sarQ", { Ev, CL } },
1548 },
1549 /* GRP3b */
1550 {
1551 { "testA", { Eb, Ib } },
1552 { "(bad)", { Eb } },
1553 { "notA", { Eb } },
1554 { "negA", { Eb } },
1555 { "mulA", { Eb } }, /* Don't print the implicit %al register, */
1556 { "imulA", { Eb } }, /* to distinguish these opcodes from other */
1557 { "divA", { Eb } }, /* mul/imul opcodes. Do the same for div */
1558 { "idivA", { Eb } }, /* and idiv for consistency. */
1559 },
1560 /* GRP3S */
1561 {
1562 { "testQ", { Ev, Iv } },
1563 { "(bad)", { XX } },
1564 { "notQ", { Ev } },
1565 { "negQ", { Ev } },
1566 { "mulQ", { Ev } }, /* Don't print the implicit register. */
1567 { "imulQ", { Ev } },
1568 { "divQ", { Ev } },
1569 { "idivQ", { Ev } },
1570 },
1571 /* GRP4 */
1572 {
1573 { "incA", { Eb } },
1574 { "decA", { Eb } },
1575 { "(bad)", { XX } },
1576 { "(bad)", { XX } },
1577 { "(bad)", { XX } },
1578 { "(bad)", { XX } },
1579 { "(bad)", { XX } },
1580 { "(bad)", { XX } },
1581 },
1582 /* GRP5 */
1583 {
1584 { "incQ", { Ev } },
1585 { "decQ", { Ev } },
1586 { "callT", { indirEv } },
1587 { "JcallT", { indirEp } },
1588 { "jmpT", { indirEv } },
1589 { "JjmpT", { indirEp } },
1590 { "pushU", { stackEv } },
1591 { "(bad)", { XX } },
1592 },
1593 /* GRP6 */
1594 {
1595 { "sldtD", { Sv } },
1596 { "strD", { Sv } },
1597 { "lldt", { Ew } },
1598 { "ltr", { Ew } },
1599 { "verr", { Ew } },
1600 { "verw", { Ew } },
1601 { "(bad)", { XX } },
1602 { "(bad)", { XX } },
1603 },
1604 /* GRP7 */
1605 {
1606 { "sgdt{Q|IQ||}", { { VMX_Fixup, 0 } } },
1607 { "sidt{Q|IQ||}", { { PNI_Fixup, 0 } } },
1608 { "lgdt{Q|Q||}", { M } },
1609 { "lidt{Q|Q||}", { { SVME_Fixup, 0 } } },
1610 { "smswD", { Sv } },
1611 { "(bad)", { XX } },
1612 { "lmsw", { Ew } },
1613 { "invlpg", { { INVLPG_Fixup, w_mode } } },
1614 },
1615 /* GRP8 */
1616 {
1617 { "(bad)", { XX } },
1618 { "(bad)", { XX } },
1619 { "(bad)", { XX } },
1620 { "(bad)", { XX } },
1621 { "btQ", { Ev, Ib } },
1622 { "btsQ", { Ev, Ib } },
1623 { "btrQ", { Ev, Ib } },
1624 { "btcQ", { Ev, Ib } },
1625 },
1626 /* GRP9 */
1627 {
1628 { "(bad)", { XX } },
1629 { "cmpxchg8b", { { CMPXCHG8B_Fixup, q_mode } } },
1630 { "(bad)", { XX } },
1631 { "(bad)", { XX } },
1632 { "(bad)", { XX } },
1633 { "(bad)", { XX } },
1634 { "", { VM } }, /* See OP_VMX. */
1635 { "vmptrst", { Mq } },
1636 },
1637 /* GRP11_C6 */
1638 {
1639 { "movA", { Eb, Ib } },
1640 { "(bad)", { XX } },
1641 { "(bad)", { XX } },
1642 { "(bad)", { XX } },
1643 { "(bad)", { XX } },
1644 { "(bad)", { XX } },
1645 { "(bad)", { XX } },
1646 { "(bad)", { XX } },
1647 },
1648 /* GRP11_C7 */
1649 {
1650 { "movQ", { Ev, Iv } },
1651 { "(bad)", { XX } },
1652 { "(bad)", { XX } },
1653 { "(bad)", { XX } },
1654 { "(bad)", { XX } },
1655 { "(bad)", { XX } },
1656 { "(bad)", { XX } },
1657 { "(bad)", { XX } },
1658 },
1659 /* GRP12 */
1660 {
1661 { "(bad)", { XX } },
1662 { "(bad)", { XX } },
1663 { "psrlw", { MS, Ib } },
1664 { "(bad)", { XX } },
1665 { "psraw", { MS, Ib } },
1666 { "(bad)", { XX } },
1667 { "psllw", { MS, Ib } },
1668 { "(bad)", { XX } },
1669 },
1670 /* GRP13 */
1671 {
1672 { "(bad)", { XX } },
1673 { "(bad)", { XX } },
1674 { "psrld", { MS, Ib } },
1675 { "(bad)", { XX } },
1676 { "psrad", { MS, Ib } },
1677 { "(bad)", { XX } },
1678 { "pslld", { MS, Ib } },
1679 { "(bad)", { XX } },
1680 },
1681 /* GRP14 */
1682 {
1683 { "(bad)", { XX } },
1684 { "(bad)", { XX } },
1685 { "psrlq", { MS, Ib } },
1686 { "psrldq", { MS, Ib } },
1687 { "(bad)", { XX } },
1688 { "(bad)", { XX } },
1689 { "psllq", { MS, Ib } },
1690 { "pslldq", { MS, Ib } },
1691 },
1692 /* GRP15 */
1693 {
1694 { "fxsave", { Ev } },
1695 { "fxrstor", { Ev } },
1696 { "ldmxcsr", { Ev } },
1697 { "stmxcsr", { Ev } },
1698 { "(bad)", { XX } },
1699 { "lfence", { { OP_0fae, 0 } } },
1700 { "mfence", { { OP_0fae, 0 } } },
1701 { "clflush", { { OP_0fae, 0 } } },
1702 },
1703 /* GRP16 */
1704 {
1705 { "prefetchnta", { Ev } },
1706 { "prefetcht0", { Ev } },
1707 { "prefetcht1", { Ev } },
1708 { "prefetcht2", { Ev } },
1709 { "(bad)", { XX } },
1710 { "(bad)", { XX } },
1711 { "(bad)", { XX } },
1712 { "(bad)", { XX } },
1713 },
1714 /* GRPAMD */
1715 {
1716 { "prefetch", { Eb } },
1717 { "prefetchw", { Eb } },
1718 { "(bad)", { XX } },
1719 { "(bad)", { XX } },
1720 { "(bad)", { XX } },
1721 { "(bad)", { XX } },
1722 { "(bad)", { XX } },
1723 { "(bad)", { XX } },
1724 },
1725 /* GRPPADLCK1 */
1726 {
1727 { "xstore-rng", { { OP_0f07, 0 } } },
1728 { "xcrypt-ecb", { { OP_0f07, 0 } } },
1729 { "xcrypt-cbc", { { OP_0f07, 0 } } },
1730 { "xcrypt-ctr", { { OP_0f07, 0 } } },
1731 { "xcrypt-cfb", { { OP_0f07, 0 } } },
1732 { "xcrypt-ofb", { { OP_0f07, 0 } } },
1733 { "(bad)", { { OP_0f07, 0 } } },
1734 { "(bad)", { { OP_0f07, 0 } } },
1735 },
1736 /* GRPPADLCK2 */
1737 {
1738 { "montmul", { { OP_0f07, 0 } } },
1739 { "xsha1", { { OP_0f07, 0 } } },
1740 { "xsha256", { { OP_0f07, 0 } } },
1741 { "(bad)", { { OP_0f07, 0 } } },
1742 { "(bad)", { { OP_0f07, 0 } } },
1743 { "(bad)", { { OP_0f07, 0 } } },
1744 { "(bad)", { { OP_0f07, 0 } } },
1745 { "(bad)", { { OP_0f07, 0 } } },
1746 }
1747 };
1748
1749 static const struct dis386 prefix_user_table[][4] = {
1750 /* PREGRP0 */
1751 {
1752 { "addps", { XM, EX } },
1753 { "addss", { XM, EX } },
1754 { "addpd", { XM, EX } },
1755 { "addsd", { XM, EX } },
1756 },
1757 /* PREGRP1 */
1758 {
1759 { "", { XM, EX, OPSIMD } }, /* See OP_SIMD_SUFFIX. */
1760 { "", { XM, EX, OPSIMD } },
1761 { "", { XM, EX, OPSIMD } },
1762 { "", { XM, EX, OPSIMD } },
1763 },
1764 /* PREGRP2 */
1765 {
1766 { "cvtpi2ps", { XM, EMC } },
1767 { "cvtsi2ssY", { XM, Ev } },
1768 { "cvtpi2pd", { XM, EMC } },
1769 { "cvtsi2sdY", { XM, Ev } },
1770 },
1771 /* PREGRP3 */
1772 {
1773 { "cvtps2pi", { MXC, EX } },
1774 { "cvtss2siY", { Gv, EX } },
1775 { "cvtpd2pi", { MXC, EX } },
1776 { "cvtsd2siY", { Gv, EX } },
1777 },
1778 /* PREGRP4 */
1779 {
1780 { "cvttps2pi", { MXC, EX } },
1781 { "cvttss2siY", { Gv, EX } },
1782 { "cvttpd2pi", { MXC, EX } },
1783 { "cvttsd2siY", { Gv, EX } },
1784 },
1785 /* PREGRP5 */
1786 {
1787 { "divps", { XM, EX } },
1788 { "divss", { XM, EX } },
1789 { "divpd", { XM, EX } },
1790 { "divsd", { XM, EX } },
1791 },
1792 /* PREGRP6 */
1793 {
1794 { "maxps", { XM, EX } },
1795 { "maxss", { XM, EX } },
1796 { "maxpd", { XM, EX } },
1797 { "maxsd", { XM, EX } },
1798 },
1799 /* PREGRP7 */
1800 {
1801 { "minps", { XM, EX } },
1802 { "minss", { XM, EX } },
1803 { "minpd", { XM, EX } },
1804 { "minsd", { XM, EX } },
1805 },
1806 /* PREGRP8 */
1807 {
1808 { "movups", { XM, EX } },
1809 { "movss", { XM, EX } },
1810 { "movupd", { XM, EX } },
1811 { "movsd", { XM, EX } },
1812 },
1813 /* PREGRP9 */
1814 {
1815 { "movups", { EX, XM } },
1816 { "movss", { EX, XM } },
1817 { "movupd", { EX, XM } },
1818 { "movsd", { EX, XM } },
1819 },
1820 /* PREGRP10 */
1821 {
1822 { "mulps", { XM, EX } },
1823 { "mulss", { XM, EX } },
1824 { "mulpd", { XM, EX } },
1825 { "mulsd", { XM, EX } },
1826 },
1827 /* PREGRP11 */
1828 {
1829 { "rcpps", { XM, EX } },
1830 { "rcpss", { XM, EX } },
1831 { "(bad)", { XM, EX } },
1832 { "(bad)", { XM, EX } },
1833 },
1834 /* PREGRP12 */
1835 {
1836 { "rsqrtps",{ XM, EX } },
1837 { "rsqrtss",{ XM, EX } },
1838 { "(bad)", { XM, EX } },
1839 { "(bad)", { XM, EX } },
1840 },
1841 /* PREGRP13 */
1842 {
1843 { "sqrtps", { XM, EX } },
1844 { "sqrtss", { XM, EX } },
1845 { "sqrtpd", { XM, EX } },
1846 { "sqrtsd", { XM, EX } },
1847 },
1848 /* PREGRP14 */
1849 {
1850 { "subps", { XM, EX } },
1851 { "subss", { XM, EX } },
1852 { "subpd", { XM, EX } },
1853 { "subsd", { XM, EX } },
1854 },
1855 /* PREGRP15 */
1856 {
1857 { "(bad)", { XM, EX } },
1858 { "cvtdq2pd", { XM, EX } },
1859 { "cvttpd2dq", { XM, EX } },
1860 { "cvtpd2dq", { XM, EX } },
1861 },
1862 /* PREGRP16 */
1863 {
1864 { "cvtdq2ps", { XM, EX } },
1865 { "cvttps2dq", { XM, EX } },
1866 { "cvtps2dq", { XM, EX } },
1867 { "(bad)", { XM, EX } },
1868 },
1869 /* PREGRP17 */
1870 {
1871 { "cvtps2pd", { XM, EX } },
1872 { "cvtss2sd", { XM, EX } },
1873 { "cvtpd2ps", { XM, EX } },
1874 { "cvtsd2ss", { XM, EX } },
1875 },
1876 /* PREGRP18 */
1877 {
1878 { "maskmovq", { MX, MS } },
1879 { "(bad)", { XM, EX } },
1880 { "maskmovdqu", { XM, XS } },
1881 { "(bad)", { XM, EX } },
1882 },
1883 /* PREGRP19 */
1884 {
1885 { "movq", { MX, EM } },
1886 { "movdqu", { XM, EX } },
1887 { "movdqa", { XM, EX } },
1888 { "(bad)", { XM, EX } },
1889 },
1890 /* PREGRP20 */
1891 {
1892 { "movq", { EM, MX } },
1893 { "movdqu", { EX, XM } },
1894 { "movdqa", { EX, XM } },
1895 { "(bad)", { EX, XM } },
1896 },
1897 /* PREGRP21 */
1898 {
1899 { "(bad)", { EX, XM } },
1900 { "movq2dq",{ XM, MS } },
1901 { "movq", { EX, XM } },
1902 { "movdq2q",{ MX, XS } },
1903 },
1904 /* PREGRP22 */
1905 {
1906 { "pshufw", { MX, EM, Ib } },
1907 { "pshufhw",{ XM, EX, Ib } },
1908 { "pshufd", { XM, EX, Ib } },
1909 { "pshuflw",{ XM, EX, Ib } },
1910 },
1911 /* PREGRP23 */
1912 {
1913 { "movd", { Edq, MX } },
1914 { "movq", { XM, EX } },
1915 { "movd", { Edq, XM } },
1916 { "(bad)", { Ed, XM } },
1917 },
1918 /* PREGRP24 */
1919 {
1920 { "(bad)", { MX, EX } },
1921 { "(bad)", { XM, EX } },
1922 { "punpckhqdq", { XM, EX } },
1923 { "(bad)", { XM, EX } },
1924 },
1925 /* PREGRP25 */
1926 {
1927 { "movntq", { EM, MX } },
1928 { "(bad)", { EM, XM } },
1929 { "movntdq",{ EM, XM } },
1930 { "(bad)", { EM, XM } },
1931 },
1932 /* PREGRP26 */
1933 {
1934 { "(bad)", { MX, EX } },
1935 { "(bad)", { XM, EX } },
1936 { "punpcklqdq", { XM, EX } },
1937 { "(bad)", { XM, EX } },
1938 },
1939 /* PREGRP27 */
1940 {
1941 { "(bad)", { MX, EX } },
1942 { "(bad)", { XM, EX } },
1943 { "addsubpd", { XM, EX } },
1944 { "addsubps", { XM, EX } },
1945 },
1946 /* PREGRP28 */
1947 {
1948 { "(bad)", { MX, EX } },
1949 { "(bad)", { XM, EX } },
1950 { "haddpd", { XM, EX } },
1951 { "haddps", { XM, EX } },
1952 },
1953 /* PREGRP29 */
1954 {
1955 { "(bad)", { MX, EX } },
1956 { "(bad)", { XM, EX } },
1957 { "hsubpd", { XM, EX } },
1958 { "hsubps", { XM, EX } },
1959 },
1960 /* PREGRP30 */
1961 {
1962 { "movlpX", { XM, EX, { SIMD_Fixup, 'h' } } }, /* really only 2 operands */
1963 { "movsldup", { XM, EX } },
1964 { "movlpd", { XM, EX } },
1965 { "movddup", { XM, EX } },
1966 },
1967 /* PREGRP31 */
1968 {
1969 { "movhpX", { XM, EX, { SIMD_Fixup, 'l' } } },
1970 { "movshdup", { XM, EX } },
1971 { "movhpd", { XM, EX } },
1972 { "(bad)", { XM, EX } },
1973 },
1974 /* PREGRP32 */
1975 {
1976 { "(bad)", { XM, EX } },
1977 { "(bad)", { XM, EX } },
1978 { "(bad)", { XM, EX } },
1979 { "lddqu", { XM, M } },
1980 },
1981 /* PREGRP33 */
1982 {
1983 {"movntps", { Ev, XM } },
1984 {"movntss", { Ev, XM } },
1985 {"movntpd", { Ev, XM } },
1986 {"movntsd", { Ev, XM } },
1987 },
1988
1989 /* PREGRP34 */
1990 {
1991 {"vmread", { Em, Gm } },
1992 {"(bad)", { XX } },
1993 {"extrq", { XS, Ib, Ib } },
1994 {"insertq", { XM, XS, Ib, Ib } },
1995 },
1996
1997 /* PREGRP35 */
1998 {
1999 {"vmwrite", { Gm, Em } },
2000 {"(bad)", { XX } },
2001 {"extrq", { XM, XS } },
2002 {"insertq", { XM, XS } },
2003 },
2004
2005 /* PREGRP36 */
2006 {
2007 { "bsrS", { Gv, Ev } },
2008 { "lzcntS", { Gv, Ev } },
2009 { "bsrS", { Gv, Ev } },
2010 { "(bad)", { XX } },
2011 },
2012
2013 /* PREGRP37 */
2014 {
2015 { "(bad)", { XX } },
2016 { "popcntS", { Gv, Ev } },
2017 { "(bad)", { XX } },
2018 { "(bad)", { XX } },
2019 },
2020 };
2021
2022 static const struct dis386 x86_64_table[][2] = {
2023 {
2024 { "pusha{P|}", { XX } },
2025 { "(bad)", { XX } },
2026 },
2027 {
2028 { "popa{P|}", { XX } },
2029 { "(bad)", { XX } },
2030 },
2031 {
2032 { "bound{S|}", { Gv, Ma } },
2033 { "(bad)", { XX } },
2034 },
2035 {
2036 { "arpl", { Ew, Gw } },
2037 { "movs{||lq|xd}", { Gv, Ed } },
2038 },
2039 };
2040
2041 static const struct dis386 three_byte_table[][256] = {
2042 /* THREE_BYTE_0 */
2043 {
2044 /* 00 */
2045 { "pshufb", { MX, EM } },
2046 { "phaddw", { MX, EM } },
2047 { "phaddd", { MX, EM } },
2048 { "phaddsw", { MX, EM } },
2049 { "pmaddubsw", { MX, EM } },
2050 { "phsubw", { MX, EM } },
2051 { "phsubd", { MX, EM } },
2052 { "phsubsw", { MX, EM } },
2053 /* 08 */
2054 { "psignb", { MX, EM } },
2055 { "psignw", { MX, EM } },
2056 { "psignd", { MX, EM } },
2057 { "pmulhrsw", { MX, EM } },
2058 { "(bad)", { XX } },
2059 { "(bad)", { XX } },
2060 { "(bad)", { XX } },
2061 { "(bad)", { XX } },
2062 /* 10 */
2063 { "(bad)", { XX } },
2064 { "(bad)", { XX } },
2065 { "(bad)", { XX } },
2066 { "(bad)", { XX } },
2067 { "(bad)", { XX } },
2068 { "(bad)", { XX } },
2069 { "(bad)", { XX } },
2070 { "(bad)", { XX } },
2071 /* 18 */
2072 { "(bad)", { XX } },
2073 { "(bad)", { XX } },
2074 { "(bad)", { XX } },
2075 { "(bad)", { XX } },
2076 { "pabsb", { MX, EM } },
2077 { "pabsw", { MX, EM } },
2078 { "pabsd", { MX, EM } },
2079 { "(bad)", { XX } },
2080 /* 20 */
2081 { "(bad)", { XX } },
2082 { "(bad)", { XX } },
2083 { "(bad)", { XX } },
2084 { "(bad)", { XX } },
2085 { "(bad)", { XX } },
2086 { "(bad)", { XX } },
2087 { "(bad)", { XX } },
2088 { "(bad)", { XX } },
2089 /* 28 */
2090 { "(bad)", { XX } },
2091 { "(bad)", { XX } },
2092 { "(bad)", { XX } },
2093 { "(bad)", { XX } },
2094 { "(bad)", { XX } },
2095 { "(bad)", { XX } },
2096 { "(bad)", { XX } },
2097 { "(bad)", { XX } },
2098 /* 30 */
2099 { "(bad)", { XX } },
2100 { "(bad)", { XX } },
2101 { "(bad)", { XX } },
2102 { "(bad)", { XX } },
2103 { "(bad)", { XX } },
2104 { "(bad)", { XX } },
2105 { "(bad)", { XX } },
2106 { "(bad)", { XX } },
2107 /* 38 */
2108 { "(bad)", { XX } },
2109 { "(bad)", { XX } },
2110 { "(bad)", { XX } },
2111 { "(bad)", { XX } },
2112 { "(bad)", { XX } },
2113 { "(bad)", { XX } },
2114 { "(bad)", { XX } },
2115 { "(bad)", { XX } },
2116 /* 40 */
2117 { "(bad)", { XX } },
2118 { "(bad)", { XX } },
2119 { "(bad)", { XX } },
2120 { "(bad)", { XX } },
2121 { "(bad)", { XX } },
2122 { "(bad)", { XX } },
2123 { "(bad)", { XX } },
2124 { "(bad)", { XX } },
2125 /* 48 */
2126 { "(bad)", { XX } },
2127 { "(bad)", { XX } },
2128 { "(bad)", { XX } },
2129 { "(bad)", { XX } },
2130 { "(bad)", { XX } },
2131 { "(bad)", { XX } },
2132 { "(bad)", { XX } },
2133 { "(bad)", { XX } },
2134 /* 50 */
2135 { "(bad)", { XX } },
2136 { "(bad)", { XX } },
2137 { "(bad)", { XX } },
2138 { "(bad)", { XX } },
2139 { "(bad)", { XX } },
2140 { "(bad)", { XX } },
2141 { "(bad)", { XX } },
2142 { "(bad)", { XX } },
2143 /* 58 */
2144 { "(bad)", { XX } },
2145 { "(bad)", { XX } },
2146 { "(bad)", { XX } },
2147 { "(bad)", { XX } },
2148 { "(bad)", { XX } },
2149 { "(bad)", { XX } },
2150 { "(bad)", { XX } },
2151 { "(bad)", { XX } },
2152 /* 60 */
2153 { "(bad)", { XX } },
2154 { "(bad)", { XX } },
2155 { "(bad)", { XX } },
2156 { "(bad)", { XX } },
2157 { "(bad)", { XX } },
2158 { "(bad)", { XX } },
2159 { "(bad)", { XX } },
2160 { "(bad)", { XX } },
2161 /* 68 */
2162 { "(bad)", { XX } },
2163 { "(bad)", { XX } },
2164 { "(bad)", { XX } },
2165 { "(bad)", { XX } },
2166 { "(bad)", { XX } },
2167 { "(bad)", { XX } },
2168 { "(bad)", { XX } },
2169 { "(bad)", { XX } },
2170 /* 70 */
2171 { "(bad)", { XX } },
2172 { "(bad)", { XX } },
2173 { "(bad)", { XX } },
2174 { "(bad)", { XX } },
2175 { "(bad)", { XX } },
2176 { "(bad)", { XX } },
2177 { "(bad)", { XX } },
2178 { "(bad)", { XX } },
2179 /* 78 */
2180 { "(bad)", { XX } },
2181 { "(bad)", { XX } },
2182 { "(bad)", { XX } },
2183 { "(bad)", { XX } },
2184 { "(bad)", { XX } },
2185 { "(bad)", { XX } },
2186 { "(bad)", { XX } },
2187 { "(bad)", { XX } },
2188 /* 80 */
2189 { "(bad)", { XX } },
2190 { "(bad)", { XX } },
2191 { "(bad)", { XX } },
2192 { "(bad)", { XX } },
2193 { "(bad)", { XX } },
2194 { "(bad)", { XX } },
2195 { "(bad)", { XX } },
2196 { "(bad)", { XX } },
2197 /* 88 */
2198 { "(bad)", { XX } },
2199 { "(bad)", { XX } },
2200 { "(bad)", { XX } },
2201 { "(bad)", { XX } },
2202 { "(bad)", { XX } },
2203 { "(bad)", { XX } },
2204 { "(bad)", { XX } },
2205 { "(bad)", { XX } },
2206 /* 90 */
2207 { "(bad)", { XX } },
2208 { "(bad)", { XX } },
2209 { "(bad)", { XX } },
2210 { "(bad)", { XX } },
2211 { "(bad)", { XX } },
2212 { "(bad)", { XX } },
2213 { "(bad)", { XX } },
2214 { "(bad)", { XX } },
2215 /* 98 */
2216 { "(bad)", { XX } },
2217 { "(bad)", { XX } },
2218 { "(bad)", { XX } },
2219 { "(bad)", { XX } },
2220 { "(bad)", { XX } },
2221 { "(bad)", { XX } },
2222 { "(bad)", { XX } },
2223 { "(bad)", { XX } },
2224 /* a0 */
2225 { "(bad)", { XX } },
2226 { "(bad)", { XX } },
2227 { "(bad)", { XX } },
2228 { "(bad)", { XX } },
2229 { "(bad)", { XX } },
2230 { "(bad)", { XX } },
2231 { "(bad)", { XX } },
2232 { "(bad)", { XX } },
2233 /* a8 */
2234 { "(bad)", { XX } },
2235 { "(bad)", { XX } },
2236 { "(bad)", { XX } },
2237 { "(bad)", { XX } },
2238 { "(bad)", { XX } },
2239 { "(bad)", { XX } },
2240 { "(bad)", { XX } },
2241 { "(bad)", { XX } },
2242 /* b0 */
2243 { "(bad)", { XX } },
2244 { "(bad)", { XX } },
2245 { "(bad)", { XX } },
2246 { "(bad)", { XX } },
2247 { "(bad)", { XX } },
2248 { "(bad)", { XX } },
2249 { "(bad)", { XX } },
2250 { "(bad)", { XX } },
2251 /* b8 */
2252 { "(bad)", { XX } },
2253 { "(bad)", { XX } },
2254 { "(bad)", { XX } },
2255 { "(bad)", { XX } },
2256 { "(bad)", { XX } },
2257 { "(bad)", { XX } },
2258 { "(bad)", { XX } },
2259 { "(bad)", { XX } },
2260 /* c0 */
2261 { "(bad)", { XX } },
2262 { "(bad)", { XX } },
2263 { "(bad)", { XX } },
2264 { "(bad)", { XX } },
2265 { "(bad)", { XX } },
2266 { "(bad)", { XX } },
2267 { "(bad)", { XX } },
2268 { "(bad)", { XX } },
2269 /* c8 */
2270 { "(bad)", { XX } },
2271 { "(bad)", { XX } },
2272 { "(bad)", { XX } },
2273 { "(bad)", { XX } },
2274 { "(bad)", { XX } },
2275 { "(bad)", { XX } },
2276 { "(bad)", { XX } },
2277 { "(bad)", { XX } },
2278 /* d0 */
2279 { "(bad)", { XX } },
2280 { "(bad)", { XX } },
2281 { "(bad)", { XX } },
2282 { "(bad)", { XX } },
2283 { "(bad)", { XX } },
2284 { "(bad)", { XX } },
2285 { "(bad)", { XX } },
2286 { "(bad)", { XX } },
2287 /* d8 */
2288 { "(bad)", { XX } },
2289 { "(bad)", { XX } },
2290 { "(bad)", { XX } },
2291 { "(bad)", { XX } },
2292 { "(bad)", { XX } },
2293 { "(bad)", { XX } },
2294 { "(bad)", { XX } },
2295 { "(bad)", { XX } },
2296 /* e0 */
2297 { "(bad)", { XX } },
2298 { "(bad)", { XX } },
2299 { "(bad)", { XX } },
2300 { "(bad)", { XX } },
2301 { "(bad)", { XX } },
2302 { "(bad)", { XX } },
2303 { "(bad)", { XX } },
2304 { "(bad)", { XX } },
2305 /* e8 */
2306 { "(bad)", { XX } },
2307 { "(bad)", { XX } },
2308 { "(bad)", { XX } },
2309 { "(bad)", { XX } },
2310 { "(bad)", { XX } },
2311 { "(bad)", { XX } },
2312 { "(bad)", { XX } },
2313 { "(bad)", { XX } },
2314 /* f0 */
2315 { "(bad)", { XX } },
2316 { "(bad)", { XX } },
2317 { "(bad)", { XX } },
2318 { "(bad)", { XX } },
2319 { "(bad)", { XX } },
2320 { "(bad)", { XX } },
2321 { "(bad)", { XX } },
2322 { "(bad)", { XX } },
2323 /* f8 */
2324 { "(bad)", { XX } },
2325 { "(bad)", { XX } },
2326 { "(bad)", { XX } },
2327 { "(bad)", { XX } },
2328 { "(bad)", { XX } },
2329 { "(bad)", { XX } },
2330 { "(bad)", { XX } },
2331 { "(bad)", { XX } },
2332 },
2333 /* THREE_BYTE_1 */
2334 {
2335 /* 00 */
2336 { "(bad)", { XX } },
2337 { "(bad)", { XX } },
2338 { "(bad)", { XX } },
2339 { "(bad)", { XX } },
2340 { "(bad)", { XX } },
2341 { "(bad)", { XX } },
2342 { "(bad)", { XX } },
2343 { "(bad)", { XX } },
2344 /* 08 */
2345 { "(bad)", { XX } },
2346 { "(bad)", { XX } },
2347 { "(bad)", { XX } },
2348 { "(bad)", { XX } },
2349 { "(bad)", { XX } },
2350 { "(bad)", { XX } },
2351 { "(bad)", { XX } },
2352 { "palignr", { MX, EM, Ib } },
2353 /* 10 */
2354 { "(bad)", { XX } },
2355 { "(bad)", { XX } },
2356 { "(bad)", { XX } },
2357 { "(bad)", { XX } },
2358 { "(bad)", { XX } },
2359 { "(bad)", { XX } },
2360 { "(bad)", { XX } },
2361 { "(bad)", { XX } },
2362 /* 18 */
2363 { "(bad)", { XX } },
2364 { "(bad)", { XX } },
2365 { "(bad)", { XX } },
2366 { "(bad)", { XX } },
2367 { "(bad)", { XX } },
2368 { "(bad)", { XX } },
2369 { "(bad)", { XX } },
2370 { "(bad)", { XX } },
2371 /* 20 */
2372 { "(bad)", { XX } },
2373 { "(bad)", { XX } },
2374 { "(bad)", { XX } },
2375 { "(bad)", { XX } },
2376 { "(bad)", { XX } },
2377 { "(bad)", { XX } },
2378 { "(bad)", { XX } },
2379 { "(bad)", { XX } },
2380 /* 28 */
2381 { "(bad)", { XX } },
2382 { "(bad)", { XX } },
2383 { "(bad)", { XX } },
2384 { "(bad)", { XX } },
2385 { "(bad)", { XX } },
2386 { "(bad)", { XX } },
2387 { "(bad)", { XX } },
2388 { "(bad)", { XX } },
2389 /* 30 */
2390 { "(bad)", { XX } },
2391 { "(bad)", { XX } },
2392 { "(bad)", { XX } },
2393 { "(bad)", { XX } },
2394 { "(bad)", { XX } },
2395 { "(bad)", { XX } },
2396 { "(bad)", { XX } },
2397 { "(bad)", { XX } },
2398 /* 38 */
2399 { "(bad)", { XX } },
2400 { "(bad)", { XX } },
2401 { "(bad)", { XX } },
2402 { "(bad)", { XX } },
2403 { "(bad)", { XX } },
2404 { "(bad)", { XX } },
2405 { "(bad)", { XX } },
2406 { "(bad)", { XX } },
2407 /* 40 */
2408 { "(bad)", { XX } },
2409 { "(bad)", { XX } },
2410 { "(bad)", { XX } },
2411 { "(bad)", { XX } },
2412 { "(bad)", { XX } },
2413 { "(bad)", { XX } },
2414 { "(bad)", { XX } },
2415 { "(bad)", { XX } },
2416 /* 48 */
2417 { "(bad)", { XX } },
2418 { "(bad)", { XX } },
2419 { "(bad)", { XX } },
2420 { "(bad)", { XX } },
2421 { "(bad)", { XX } },
2422 { "(bad)", { XX } },
2423 { "(bad)", { XX } },
2424 { "(bad)", { XX } },
2425 /* 50 */
2426 { "(bad)", { XX } },
2427 { "(bad)", { XX } },
2428 { "(bad)", { XX } },
2429 { "(bad)", { XX } },
2430 { "(bad)", { XX } },
2431 { "(bad)", { XX } },
2432 { "(bad)", { XX } },
2433 { "(bad)", { XX } },
2434 /* 58 */
2435 { "(bad)", { XX } },
2436 { "(bad)", { XX } },
2437 { "(bad)", { XX } },
2438 { "(bad)", { XX } },
2439 { "(bad)", { XX } },
2440 { "(bad)", { XX } },
2441 { "(bad)", { XX } },
2442 { "(bad)", { XX } },
2443 /* 60 */
2444 { "(bad)", { XX } },
2445 { "(bad)", { XX } },
2446 { "(bad)", { XX } },
2447 { "(bad)", { XX } },
2448 { "(bad)", { XX } },
2449 { "(bad)", { XX } },
2450 { "(bad)", { XX } },
2451 { "(bad)", { XX } },
2452 /* 68 */
2453 { "(bad)", { XX } },
2454 { "(bad)", { XX } },
2455 { "(bad)", { XX } },
2456 { "(bad)", { XX } },
2457 { "(bad)", { XX } },
2458 { "(bad)", { XX } },
2459 { "(bad)", { XX } },
2460 { "(bad)", { XX } },
2461 /* 70 */
2462 { "(bad)", { XX } },
2463 { "(bad)", { XX } },
2464 { "(bad)", { XX } },
2465 { "(bad)", { XX } },
2466 { "(bad)", { XX } },
2467 { "(bad)", { XX } },
2468 { "(bad)", { XX } },
2469 { "(bad)", { XX } },
2470 /* 78 */
2471 { "(bad)", { XX } },
2472 { "(bad)", { XX } },
2473 { "(bad)", { XX } },
2474 { "(bad)", { XX } },
2475 { "(bad)", { XX } },
2476 { "(bad)", { XX } },
2477 { "(bad)", { XX } },
2478 { "(bad)", { XX } },
2479 /* 80 */
2480 { "(bad)", { XX } },
2481 { "(bad)", { XX } },
2482 { "(bad)", { XX } },
2483 { "(bad)", { XX } },
2484 { "(bad)", { XX } },
2485 { "(bad)", { XX } },
2486 { "(bad)", { XX } },
2487 { "(bad)", { XX } },
2488 /* 88 */
2489 { "(bad)", { XX } },
2490 { "(bad)", { XX } },
2491 { "(bad)", { XX } },
2492 { "(bad)", { XX } },
2493 { "(bad)", { XX } },
2494 { "(bad)", { XX } },
2495 { "(bad)", { XX } },
2496 { "(bad)", { XX } },
2497 /* 90 */
2498 { "(bad)", { XX } },
2499 { "(bad)", { XX } },
2500 { "(bad)", { XX } },
2501 { "(bad)", { XX } },
2502 { "(bad)", { XX } },
2503 { "(bad)", { XX } },
2504 { "(bad)", { XX } },
2505 { "(bad)", { XX } },
2506 /* 98 */
2507 { "(bad)", { XX } },
2508 { "(bad)", { XX } },
2509 { "(bad)", { XX } },
2510 { "(bad)", { XX } },
2511 { "(bad)", { XX } },
2512 { "(bad)", { XX } },
2513 { "(bad)", { XX } },
2514 { "(bad)", { XX } },
2515 /* a0 */
2516 { "(bad)", { XX } },
2517 { "(bad)", { XX } },
2518 { "(bad)", { XX } },
2519 { "(bad)", { XX } },
2520 { "(bad)", { XX } },
2521 { "(bad)", { XX } },
2522 { "(bad)", { XX } },
2523 { "(bad)", { XX } },
2524 /* a8 */
2525 { "(bad)", { XX } },
2526 { "(bad)", { XX } },
2527 { "(bad)", { XX } },
2528 { "(bad)", { XX } },
2529 { "(bad)", { XX } },
2530 { "(bad)", { XX } },
2531 { "(bad)", { XX } },
2532 { "(bad)", { XX } },
2533 /* b0 */
2534 { "(bad)", { XX } },
2535 { "(bad)", { XX } },
2536 { "(bad)", { XX } },
2537 { "(bad)", { XX } },
2538 { "(bad)", { XX } },
2539 { "(bad)", { XX } },
2540 { "(bad)", { XX } },
2541 { "(bad)", { XX } },
2542 /* b8 */
2543 { "(bad)", { XX } },
2544 { "(bad)", { XX } },
2545 { "(bad)", { XX } },
2546 { "(bad)", { XX } },
2547 { "(bad)", { XX } },
2548 { "(bad)", { XX } },
2549 { "(bad)", { XX } },
2550 { "(bad)", { XX } },
2551 /* c0 */
2552 { "(bad)", { XX } },
2553 { "(bad)", { XX } },
2554 { "(bad)", { XX } },
2555 { "(bad)", { XX } },
2556 { "(bad)", { XX } },
2557 { "(bad)", { XX } },
2558 { "(bad)", { XX } },
2559 { "(bad)", { XX } },
2560 /* c8 */
2561 { "(bad)", { XX } },
2562 { "(bad)", { XX } },
2563 { "(bad)", { XX } },
2564 { "(bad)", { XX } },
2565 { "(bad)", { XX } },
2566 { "(bad)", { XX } },
2567 { "(bad)", { XX } },
2568 { "(bad)", { XX } },
2569 /* d0 */
2570 { "(bad)", { XX } },
2571 { "(bad)", { XX } },
2572 { "(bad)", { XX } },
2573 { "(bad)", { XX } },
2574 { "(bad)", { XX } },
2575 { "(bad)", { XX } },
2576 { "(bad)", { XX } },
2577 { "(bad)", { XX } },
2578 /* d8 */
2579 { "(bad)", { XX } },
2580 { "(bad)", { XX } },
2581 { "(bad)", { XX } },
2582 { "(bad)", { XX } },
2583 { "(bad)", { XX } },
2584 { "(bad)", { XX } },
2585 { "(bad)", { XX } },
2586 { "(bad)", { XX } },
2587 /* e0 */
2588 { "(bad)", { XX } },
2589 { "(bad)", { XX } },
2590 { "(bad)", { XX } },
2591 { "(bad)", { XX } },
2592 { "(bad)", { XX } },
2593 { "(bad)", { XX } },
2594 { "(bad)", { XX } },
2595 { "(bad)", { XX } },
2596 /* e8 */
2597 { "(bad)", { XX } },
2598 { "(bad)", { XX } },
2599 { "(bad)", { XX } },
2600 { "(bad)", { XX } },
2601 { "(bad)", { XX } },
2602 { "(bad)", { XX } },
2603 { "(bad)", { XX } },
2604 { "(bad)", { XX } },
2605 /* f0 */
2606 { "(bad)", { XX } },
2607 { "(bad)", { XX } },
2608 { "(bad)", { XX } },
2609 { "(bad)", { XX } },
2610 { "(bad)", { XX } },
2611 { "(bad)", { XX } },
2612 { "(bad)", { XX } },
2613 { "(bad)", { XX } },
2614 /* f8 */
2615 { "(bad)", { XX } },
2616 { "(bad)", { XX } },
2617 { "(bad)", { XX } },
2618 { "(bad)", { XX } },
2619 { "(bad)", { XX } },
2620 { "(bad)", { XX } },
2621 { "(bad)", { XX } },
2622 { "(bad)", { XX } },
2623 }
2624 };
2625
2626 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
2627
2628 static void
2629 ckprefix (void)
2630 {
2631 int newrex;
2632 rex = 0;
2633 prefixes = 0;
2634 used_prefixes = 0;
2635 rex_used = 0;
2636 while (1)
2637 {
2638 FETCH_DATA (the_info, codep + 1);
2639 newrex = 0;
2640 switch (*codep)
2641 {
2642 /* REX prefixes family. */
2643 case 0x40:
2644 case 0x41:
2645 case 0x42:
2646 case 0x43:
2647 case 0x44:
2648 case 0x45:
2649 case 0x46:
2650 case 0x47:
2651 case 0x48:
2652 case 0x49:
2653 case 0x4a:
2654 case 0x4b:
2655 case 0x4c:
2656 case 0x4d:
2657 case 0x4e:
2658 case 0x4f:
2659 if (address_mode == mode_64bit)
2660 newrex = *codep;
2661 else
2662 return;
2663 break;
2664 case 0xf3:
2665 prefixes |= PREFIX_REPZ;
2666 break;
2667 case 0xf2:
2668 prefixes |= PREFIX_REPNZ;
2669 break;
2670 case 0xf0:
2671 prefixes |= PREFIX_LOCK;
2672 break;
2673 case 0x2e:
2674 prefixes |= PREFIX_CS;
2675 break;
2676 case 0x36:
2677 prefixes |= PREFIX_SS;
2678 break;
2679 case 0x3e:
2680 prefixes |= PREFIX_DS;
2681 break;
2682 case 0x26:
2683 prefixes |= PREFIX_ES;
2684 break;
2685 case 0x64:
2686 prefixes |= PREFIX_FS;
2687 break;
2688 case 0x65:
2689 prefixes |= PREFIX_GS;
2690 break;
2691 case 0x66:
2692 prefixes |= PREFIX_DATA;
2693 break;
2694 case 0x67:
2695 prefixes |= PREFIX_ADDR;
2696 break;
2697 case FWAIT_OPCODE:
2698 /* fwait is really an instruction. If there are prefixes
2699 before the fwait, they belong to the fwait, *not* to the
2700 following instruction. */
2701 if (prefixes || rex)
2702 {
2703 prefixes |= PREFIX_FWAIT;
2704 codep++;
2705 return;
2706 }
2707 prefixes = PREFIX_FWAIT;
2708 break;
2709 default:
2710 return;
2711 }
2712 /* Rex is ignored when followed by another prefix. */
2713 if (rex)
2714 {
2715 rex_used = rex;
2716 return;
2717 }
2718 rex = newrex;
2719 codep++;
2720 }
2721 }
2722
2723 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
2724 prefix byte. */
2725
2726 static const char *
2727 prefix_name (int pref, int sizeflag)
2728 {
2729 switch (pref)
2730 {
2731 /* REX prefixes family. */
2732 case 0x40:
2733 return "rex";
2734 case 0x41:
2735 return "rexZ";
2736 case 0x42:
2737 return "rexY";
2738 case 0x43:
2739 return "rexYZ";
2740 case 0x44:
2741 return "rexX";
2742 case 0x45:
2743 return "rexXZ";
2744 case 0x46:
2745 return "rexXY";
2746 case 0x47:
2747 return "rexXYZ";
2748 case 0x48:
2749 return "rex64";
2750 case 0x49:
2751 return "rex64Z";
2752 case 0x4a:
2753 return "rex64Y";
2754 case 0x4b:
2755 return "rex64YZ";
2756 case 0x4c:
2757 return "rex64X";
2758 case 0x4d:
2759 return "rex64XZ";
2760 case 0x4e:
2761 return "rex64XY";
2762 case 0x4f:
2763 return "rex64XYZ";
2764 case 0xf3:
2765 return "repz";
2766 case 0xf2:
2767 return "repnz";
2768 case 0xf0:
2769 return "lock";
2770 case 0x2e:
2771 return "cs";
2772 case 0x36:
2773 return "ss";
2774 case 0x3e:
2775 return "ds";
2776 case 0x26:
2777 return "es";
2778 case 0x64:
2779 return "fs";
2780 case 0x65:
2781 return "gs";
2782 case 0x66:
2783 return (sizeflag & DFLAG) ? "data16" : "data32";
2784 case 0x67:
2785 if (address_mode == mode_64bit)
2786 return (sizeflag & AFLAG) ? "addr32" : "addr64";
2787 else
2788 return (sizeflag & AFLAG) ? "addr16" : "addr32";
2789 case FWAIT_OPCODE:
2790 return "fwait";
2791 default:
2792 return NULL;
2793 }
2794 }
2795
2796 static char op_out[MAX_OPERANDS][100];
2797 static int op_ad, op_index[MAX_OPERANDS];
2798 static int two_source_ops;
2799 static bfd_vma op_address[MAX_OPERANDS];
2800 static bfd_vma op_riprel[MAX_OPERANDS];
2801 static bfd_vma start_pc;
2802
2803 /*
2804 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
2805 * (see topic "Redundant prefixes" in the "Differences from 8086"
2806 * section of the "Virtual 8086 Mode" chapter.)
2807 * 'pc' should be the address of this instruction, it will
2808 * be used to print the target address if this is a relative jump or call
2809 * The function returns the length of this instruction in bytes.
2810 */
2811
2812 static char intel_syntax;
2813 static char open_char;
2814 static char close_char;
2815 static char separator_char;
2816 static char scale_char;
2817
2818 /* Here for backwards compatibility. When gdb stops using
2819 print_insn_i386_att and print_insn_i386_intel these functions can
2820 disappear, and print_insn_i386 be merged into print_insn. */
2821 int
2822 print_insn_i386_att (bfd_vma pc, disassemble_info *info)
2823 {
2824 intel_syntax = 0;
2825
2826 return print_insn (pc, info);
2827 }
2828
2829 int
2830 print_insn_i386_intel (bfd_vma pc, disassemble_info *info)
2831 {
2832 intel_syntax = 1;
2833
2834 return print_insn (pc, info);
2835 }
2836
2837 int
2838 print_insn_i386 (bfd_vma pc, disassemble_info *info)
2839 {
2840 intel_syntax = -1;
2841
2842 return print_insn (pc, info);
2843 }
2844
2845 void
2846 print_i386_disassembler_options (FILE *stream)
2847 {
2848 fprintf (stream, _("\n\
2849 The following i386/x86-64 specific disassembler options are supported for use\n\
2850 with the -M switch (multiple options should be separated by commas):\n"));
2851
2852 fprintf (stream, _(" x86-64 Disassemble in 64bit mode\n"));
2853 fprintf (stream, _(" i386 Disassemble in 32bit mode\n"));
2854 fprintf (stream, _(" i8086 Disassemble in 16bit mode\n"));
2855 fprintf (stream, _(" att Display instruction in AT&T syntax\n"));
2856 fprintf (stream, _(" intel Display instruction in Intel syntax\n"));
2857 fprintf (stream, _(" addr64 Assume 64bit address size\n"));
2858 fprintf (stream, _(" addr32 Assume 32bit address size\n"));
2859 fprintf (stream, _(" addr16 Assume 16bit address size\n"));
2860 fprintf (stream, _(" data32 Assume 32bit data size\n"));
2861 fprintf (stream, _(" data16 Assume 16bit data size\n"));
2862 fprintf (stream, _(" suffix Always display instruction suffix in AT&T syntax\n"));
2863 }
2864
2865 static int
2866 print_insn (bfd_vma pc, disassemble_info *info)
2867 {
2868 const struct dis386 *dp;
2869 int i;
2870 char *op_txt[MAX_OPERANDS];
2871 int needcomma;
2872 unsigned char uses_DATA_prefix, uses_LOCK_prefix;
2873 unsigned char uses_REPNZ_prefix, uses_REPZ_prefix;
2874 int sizeflag;
2875 const char *p;
2876 struct dis_private priv;
2877 unsigned char op;
2878
2879 if (info->mach == bfd_mach_x86_64_intel_syntax
2880 || info->mach == bfd_mach_x86_64)
2881 address_mode = mode_64bit;
2882 else
2883 address_mode = mode_32bit;
2884
2885 if (intel_syntax == (char) -1)
2886 intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
2887 || info->mach == bfd_mach_x86_64_intel_syntax);
2888
2889 if (info->mach == bfd_mach_i386_i386
2890 || info->mach == bfd_mach_x86_64
2891 || info->mach == bfd_mach_i386_i386_intel_syntax
2892 || info->mach == bfd_mach_x86_64_intel_syntax)
2893 priv.orig_sizeflag = AFLAG | DFLAG;
2894 else if (info->mach == bfd_mach_i386_i8086)
2895 priv.orig_sizeflag = 0;
2896 else
2897 abort ();
2898
2899 for (p = info->disassembler_options; p != NULL; )
2900 {
2901 if (CONST_STRNEQ (p, "x86-64"))
2902 {
2903 address_mode = mode_64bit;
2904 priv.orig_sizeflag = AFLAG | DFLAG;
2905 }
2906 else if (CONST_STRNEQ (p, "i386"))
2907 {
2908 address_mode = mode_32bit;
2909 priv.orig_sizeflag = AFLAG | DFLAG;
2910 }
2911 else if (CONST_STRNEQ (p, "i8086"))
2912 {
2913 address_mode = mode_16bit;
2914 priv.orig_sizeflag = 0;
2915 }
2916 else if (CONST_STRNEQ (p, "intel"))
2917 {
2918 intel_syntax = 1;
2919 }
2920 else if (CONST_STRNEQ (p, "att"))
2921 {
2922 intel_syntax = 0;
2923 }
2924 else if (CONST_STRNEQ (p, "addr"))
2925 {
2926 if (address_mode == mode_64bit)
2927 {
2928 if (p[4] == '3' && p[5] == '2')
2929 priv.orig_sizeflag &= ~AFLAG;
2930 else if (p[4] == '6' && p[5] == '4')
2931 priv.orig_sizeflag |= AFLAG;
2932 }
2933 else
2934 {
2935 if (p[4] == '1' && p[5] == '6')
2936 priv.orig_sizeflag &= ~AFLAG;
2937 else if (p[4] == '3' && p[5] == '2')
2938 priv.orig_sizeflag |= AFLAG;
2939 }
2940 }
2941 else if (CONST_STRNEQ (p, "data"))
2942 {
2943 if (p[4] == '1' && p[5] == '6')
2944 priv.orig_sizeflag &= ~DFLAG;
2945 else if (p[4] == '3' && p[5] == '2')
2946 priv.orig_sizeflag |= DFLAG;
2947 }
2948 else if (CONST_STRNEQ (p, "suffix"))
2949 priv.orig_sizeflag |= SUFFIX_ALWAYS;
2950
2951 p = strchr (p, ',');
2952 if (p != NULL)
2953 p++;
2954 }
2955
2956 if (intel_syntax)
2957 {
2958 names64 = intel_names64;
2959 names32 = intel_names32;
2960 names16 = intel_names16;
2961 names8 = intel_names8;
2962 names8rex = intel_names8rex;
2963 names_seg = intel_names_seg;
2964 index16 = intel_index16;
2965 open_char = '[';
2966 close_char = ']';
2967 separator_char = '+';
2968 scale_char = '*';
2969 }
2970 else
2971 {
2972 names64 = att_names64;
2973 names32 = att_names32;
2974 names16 = att_names16;
2975 names8 = att_names8;
2976 names8rex = att_names8rex;
2977 names_seg = att_names_seg;
2978 index16 = att_index16;
2979 open_char = '(';
2980 close_char = ')';
2981 separator_char = ',';
2982 scale_char = ',';
2983 }
2984
2985 /* The output looks better if we put 7 bytes on a line, since that
2986 puts most long word instructions on a single line. */
2987 info->bytes_per_line = 7;
2988
2989 info->private_data = &priv;
2990 priv.max_fetched = priv.the_buffer;
2991 priv.insn_start = pc;
2992
2993 obuf[0] = 0;
2994 for (i = 0; i < MAX_OPERANDS; ++i)
2995 {
2996 op_out[i][0] = 0;
2997 op_index[i] = -1;
2998 }
2999
3000 the_info = info;
3001 start_pc = pc;
3002 start_codep = priv.the_buffer;
3003 codep = priv.the_buffer;
3004
3005 if (setjmp (priv.bailout) != 0)
3006 {
3007 const char *name;
3008
3009 /* Getting here means we tried for data but didn't get it. That
3010 means we have an incomplete instruction of some sort. Just
3011 print the first byte as a prefix or a .byte pseudo-op. */
3012 if (codep > priv.the_buffer)
3013 {
3014 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3015 if (name != NULL)
3016 (*info->fprintf_func) (info->stream, "%s", name);
3017 else
3018 {
3019 /* Just print the first byte as a .byte instruction. */
3020 (*info->fprintf_func) (info->stream, ".byte 0x%x",
3021 (unsigned int) priv.the_buffer[0]);
3022 }
3023
3024 return 1;
3025 }
3026
3027 return -1;
3028 }
3029
3030 obufp = obuf;
3031 ckprefix ();
3032
3033 insn_codep = codep;
3034 sizeflag = priv.orig_sizeflag;
3035
3036 FETCH_DATA (info, codep + 1);
3037 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
3038
3039 if (((prefixes & PREFIX_FWAIT)
3040 && ((*codep < 0xd8) || (*codep > 0xdf)))
3041 || (rex && rex_used))
3042 {
3043 const char *name;
3044
3045 /* fwait not followed by floating point instruction, or rex followed
3046 by other prefixes. Print the first prefix. */
3047 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3048 if (name == NULL)
3049 name = INTERNAL_DISASSEMBLER_ERROR;
3050 (*info->fprintf_func) (info->stream, "%s", name);
3051 return 1;
3052 }
3053
3054 op = 0;
3055 if (*codep == 0x0f)
3056 {
3057 unsigned char threebyte;
3058 FETCH_DATA (info, codep + 2);
3059 threebyte = *++codep;
3060 dp = &dis386_twobyte[threebyte];
3061 need_modrm = twobyte_has_modrm[*codep];
3062 uses_DATA_prefix = twobyte_uses_DATA_prefix[*codep];
3063 uses_REPNZ_prefix = twobyte_uses_REPNZ_prefix[*codep];
3064 uses_REPZ_prefix = twobyte_uses_REPZ_prefix[*codep];
3065 uses_LOCK_prefix = (*codep & ~0x02) == 0x20;
3066 codep++;
3067 if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
3068 {
3069 FETCH_DATA (info, codep + 2);
3070 op = *codep++;
3071 switch (threebyte)
3072 {
3073 case 0x38:
3074 uses_DATA_prefix = threebyte_0x38_uses_DATA_prefix[op];
3075 uses_REPNZ_prefix = threebyte_0x38_uses_REPNZ_prefix[op];
3076 uses_REPZ_prefix = threebyte_0x38_uses_REPZ_prefix[op];
3077 break;
3078 case 0x3a:
3079 uses_DATA_prefix = threebyte_0x3a_uses_DATA_prefix[op];
3080 uses_REPNZ_prefix = threebyte_0x3a_uses_REPNZ_prefix[op];
3081 uses_REPZ_prefix = threebyte_0x3a_uses_REPZ_prefix[op];
3082 break;
3083 default:
3084 break;
3085 }
3086 }
3087 }
3088 else
3089 {
3090 dp = &dis386[*codep];
3091 need_modrm = onebyte_has_modrm[*codep];
3092 uses_DATA_prefix = 0;
3093 uses_REPNZ_prefix = 0;
3094 uses_REPZ_prefix = 0;
3095 uses_LOCK_prefix = 0;
3096 codep++;
3097 }
3098
3099 if (!uses_REPZ_prefix && (prefixes & PREFIX_REPZ))
3100 {
3101 oappend ("repz ");
3102 used_prefixes |= PREFIX_REPZ;
3103 }
3104 if (!uses_REPNZ_prefix && (prefixes & PREFIX_REPNZ))
3105 {
3106 oappend ("repnz ");
3107 used_prefixes |= PREFIX_REPNZ;
3108 }
3109
3110 if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK))
3111 {
3112 oappend ("lock ");
3113 used_prefixes |= PREFIX_LOCK;
3114 }
3115
3116 if (prefixes & PREFIX_ADDR)
3117 {
3118 sizeflag ^= AFLAG;
3119 if (dp->op[2].bytemode != loop_jcxz_mode || intel_syntax)
3120 {
3121 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
3122 oappend ("addr32 ");
3123 else
3124 oappend ("addr16 ");
3125 used_prefixes |= PREFIX_ADDR;
3126 }
3127 }
3128
3129 if (!uses_DATA_prefix && (prefixes & PREFIX_DATA))
3130 {
3131 sizeflag ^= DFLAG;
3132 if (dp->op[2].bytemode == cond_jump_mode
3133 && dp->op[0].bytemode == v_mode
3134 && !intel_syntax)
3135 {
3136 if (sizeflag & DFLAG)
3137 oappend ("data32 ");
3138 else
3139 oappend ("data16 ");
3140 used_prefixes |= PREFIX_DATA;
3141 }
3142 }
3143
3144 if (dp->name == NULL && dp->op[0].bytemode == IS_3BYTE_OPCODE)
3145 {
3146 dp = &three_byte_table[dp->op[1].bytemode][op];
3147 mod = (*codep >> 6) & 3;
3148 reg = (*codep >> 3) & 7;
3149 rm = *codep & 7;
3150 }
3151 else if (need_modrm)
3152 {
3153 FETCH_DATA (info, codep + 1);
3154 mod = (*codep >> 6) & 3;
3155 reg = (*codep >> 3) & 7;
3156 rm = *codep & 7;
3157 }
3158
3159 if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE)
3160 {
3161 dofloat (sizeflag);
3162 }
3163 else
3164 {
3165 int index;
3166 if (dp->name == NULL)
3167 {
3168 switch (dp->op[0].bytemode)
3169 {
3170 case USE_GROUPS:
3171 dp = &grps[dp->op[1].bytemode][reg];
3172 break;
3173
3174 case USE_PREFIX_USER_TABLE:
3175 index = 0;
3176 used_prefixes |= (prefixes & PREFIX_REPZ);
3177 if (prefixes & PREFIX_REPZ)
3178 index = 1;
3179 else
3180 {
3181 /* We should check PREFIX_REPNZ and PREFIX_REPZ
3182 before PREFIX_DATA. */
3183 used_prefixes |= (prefixes & PREFIX_REPNZ);
3184 if (prefixes & PREFIX_REPNZ)
3185 index = 3;
3186 else
3187 {
3188 used_prefixes |= (prefixes & PREFIX_DATA);
3189 if (prefixes & PREFIX_DATA)
3190 index = 2;
3191 }
3192 }
3193 dp = &prefix_user_table[dp->op[1].bytemode][index];
3194 break;
3195
3196 case X86_64_SPECIAL:
3197 index = address_mode == mode_64bit ? 1 : 0;
3198 dp = &x86_64_table[dp->op[1].bytemode][index];
3199 break;
3200
3201 default:
3202 oappend (INTERNAL_DISASSEMBLER_ERROR);
3203 break;
3204 }
3205 }
3206
3207 if (putop (dp->name, sizeflag) == 0)
3208 {
3209 for (i = 0; i < MAX_OPERANDS; ++i)
3210 {
3211 obufp = op_out[i];
3212 op_ad = MAX_OPERANDS - 1 - i;
3213 if (dp->op[i].rtn)
3214 (*dp->op[i].rtn) (dp->op[i].bytemode, sizeflag);
3215 }
3216 }
3217 }
3218
3219 /* See if any prefixes were not used. If so, print the first one
3220 separately. If we don't do this, we'll wind up printing an
3221 instruction stream which does not precisely correspond to the
3222 bytes we are disassembling. */
3223 if ((prefixes & ~used_prefixes) != 0)
3224 {
3225 const char *name;
3226
3227 name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
3228 if (name == NULL)
3229 name = INTERNAL_DISASSEMBLER_ERROR;
3230 (*info->fprintf_func) (info->stream, "%s", name);
3231 return 1;
3232 }
3233 if (rex & ~rex_used)
3234 {
3235 const char *name;
3236 name = prefix_name (rex | 0x40, priv.orig_sizeflag);
3237 if (name == NULL)
3238 name = INTERNAL_DISASSEMBLER_ERROR;
3239 (*info->fprintf_func) (info->stream, "%s ", name);
3240 }
3241
3242 obufp = obuf + strlen (obuf);
3243 for (i = strlen (obuf); i < 6; i++)
3244 oappend (" ");
3245 oappend (" ");
3246 (*info->fprintf_func) (info->stream, "%s", obuf);
3247
3248 /* The enter and bound instructions are printed with operands in the same
3249 order as the intel book; everything else is printed in reverse order. */
3250 if (intel_syntax || two_source_ops)
3251 {
3252 for (i = 0; i < MAX_OPERANDS; ++i)
3253 op_txt[i] = op_out[i];
3254
3255 for (i = 0; i < (MAX_OPERANDS >> 1); ++i)
3256 {
3257 op_ad = op_index[i];
3258 op_index[i] = op_index[MAX_OPERANDS - 1 - i];
3259 op_index[MAX_OPERANDS - 1 - i] = op_ad;
3260 }
3261 }
3262 else
3263 {
3264 for (i = 0; i < MAX_OPERANDS; ++i)
3265 op_txt[MAX_OPERANDS - 1 - i] = op_out[i];
3266 }
3267
3268 needcomma = 0;
3269 for (i = 0; i < MAX_OPERANDS; ++i)
3270 if (*op_txt[i])
3271 {
3272 if (needcomma)
3273 (*info->fprintf_func) (info->stream, ",");
3274 if (op_index[i] != -1 && !op_riprel[i])
3275 (*info->print_address_func) ((bfd_vma) op_address[op_index[i]], info);
3276 else
3277 (*info->fprintf_func) (info->stream, "%s", op_txt[i]);
3278 needcomma = 1;
3279 }
3280
3281 for (i = 0; i < MAX_OPERANDS; i++)
3282 if (op_index[i] != -1 && op_riprel[i])
3283 {
3284 (*info->fprintf_func) (info->stream, " # ");
3285 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
3286 + op_address[op_index[i]]), info);
3287 }
3288 return codep - priv.the_buffer;
3289 }
3290
3291 static const char *float_mem[] = {
3292 /* d8 */
3293 "fadd{s||s|}",
3294 "fmul{s||s|}",
3295 "fcom{s||s|}",
3296 "fcomp{s||s|}",
3297 "fsub{s||s|}",
3298 "fsubr{s||s|}",
3299 "fdiv{s||s|}",
3300 "fdivr{s||s|}",
3301 /* d9 */
3302 "fld{s||s|}",
3303 "(bad)",
3304 "fst{s||s|}",
3305 "fstp{s||s|}",
3306 "fldenvIC",
3307 "fldcw",
3308 "fNstenvIC",
3309 "fNstcw",
3310 /* da */
3311 "fiadd{l||l|}",
3312 "fimul{l||l|}",
3313 "ficom{l||l|}",
3314 "ficomp{l||l|}",
3315 "fisub{l||l|}",
3316 "fisubr{l||l|}",
3317 "fidiv{l||l|}",
3318 "fidivr{l||l|}",
3319 /* db */
3320 "fild{l||l|}",
3321 "fisttp{l||l|}",
3322 "fist{l||l|}",
3323 "fistp{l||l|}",
3324 "(bad)",
3325 "fld{t||t|}",
3326 "(bad)",
3327 "fstp{t||t|}",
3328 /* dc */
3329 "fadd{l||l|}",
3330 "fmul{l||l|}",
3331 "fcom{l||l|}",
3332 "fcomp{l||l|}",
3333 "fsub{l||l|}",
3334 "fsubr{l||l|}",
3335 "fdiv{l||l|}",
3336 "fdivr{l||l|}",
3337 /* dd */
3338 "fld{l||l|}",
3339 "fisttp{ll||ll|}",
3340 "fst{l||l|}",
3341 "fstp{l||l|}",
3342 "frstorIC",
3343 "(bad)",
3344 "fNsaveIC",
3345 "fNstsw",
3346 /* de */
3347 "fiadd",
3348 "fimul",
3349 "ficom",
3350 "ficomp",
3351 "fisub",
3352 "fisubr",
3353 "fidiv",
3354 "fidivr",
3355 /* df */
3356 "fild",
3357 "fisttp",
3358 "fist",
3359 "fistp",
3360 "fbld",
3361 "fild{ll||ll|}",
3362 "fbstp",
3363 "fistp{ll||ll|}",
3364 };
3365
3366 static const unsigned char float_mem_mode[] = {
3367 /* d8 */
3368 d_mode,
3369 d_mode,
3370 d_mode,
3371 d_mode,
3372 d_mode,
3373 d_mode,
3374 d_mode,
3375 d_mode,
3376 /* d9 */
3377 d_mode,
3378 0,
3379 d_mode,
3380 d_mode,
3381 0,
3382 w_mode,
3383 0,
3384 w_mode,
3385 /* da */
3386 d_mode,
3387 d_mode,
3388 d_mode,
3389 d_mode,
3390 d_mode,
3391 d_mode,
3392 d_mode,
3393 d_mode,
3394 /* db */
3395 d_mode,
3396 d_mode,
3397 d_mode,
3398 d_mode,
3399 0,
3400 t_mode,
3401 0,
3402 t_mode,
3403 /* dc */
3404 q_mode,
3405 q_mode,
3406 q_mode,
3407 q_mode,
3408 q_mode,
3409 q_mode,
3410 q_mode,
3411 q_mode,
3412 /* dd */
3413 q_mode,
3414 q_mode,
3415 q_mode,
3416 q_mode,
3417 0,
3418 0,
3419 0,
3420 w_mode,
3421 /* de */
3422 w_mode,
3423 w_mode,
3424 w_mode,
3425 w_mode,
3426 w_mode,
3427 w_mode,
3428 w_mode,
3429 w_mode,
3430 /* df */
3431 w_mode,
3432 w_mode,
3433 w_mode,
3434 w_mode,
3435 t_mode,
3436 q_mode,
3437 t_mode,
3438 q_mode
3439 };
3440
3441 #define ST { OP_ST, 0 }
3442 #define STi { OP_STi, 0 }
3443
3444 #define FGRPd9_2 NULL, { { NULL, 0 } }
3445 #define FGRPd9_4 NULL, { { NULL, 1 } }
3446 #define FGRPd9_5 NULL, { { NULL, 2 } }
3447 #define FGRPd9_6 NULL, { { NULL, 3 } }
3448 #define FGRPd9_7 NULL, { { NULL, 4 } }
3449 #define FGRPda_5 NULL, { { NULL, 5 } }
3450 #define FGRPdb_4 NULL, { { NULL, 6 } }
3451 #define FGRPde_3 NULL, { { NULL, 7 } }
3452 #define FGRPdf_4 NULL, { { NULL, 8 } }
3453
3454 static const struct dis386 float_reg[][8] = {
3455 /* d8 */
3456 {
3457 { "fadd", { ST, STi } },
3458 { "fmul", { ST, STi } },
3459 { "fcom", { STi } },
3460 { "fcomp", { STi } },
3461 { "fsub", { ST, STi } },
3462 { "fsubr", { ST, STi } },
3463 { "fdiv", { ST, STi } },
3464 { "fdivr", { ST, STi } },
3465 },
3466 /* d9 */
3467 {
3468 { "fld", { STi } },
3469 { "fxch", { STi } },
3470 { FGRPd9_2 },
3471 { "(bad)", { XX } },
3472 { FGRPd9_4 },
3473 { FGRPd9_5 },
3474 { FGRPd9_6 },
3475 { FGRPd9_7 },
3476 },
3477 /* da */
3478 {
3479 { "fcmovb", { ST, STi } },
3480 { "fcmove", { ST, STi } },
3481 { "fcmovbe",{ ST, STi } },
3482 { "fcmovu", { ST, STi } },
3483 { "(bad)", { XX } },
3484 { FGRPda_5 },
3485 { "(bad)", { XX } },
3486 { "(bad)", { XX } },
3487 },
3488 /* db */
3489 {
3490 { "fcmovnb",{ ST, STi } },
3491 { "fcmovne",{ ST, STi } },
3492 { "fcmovnbe",{ ST, STi } },
3493 { "fcmovnu",{ ST, STi } },
3494 { FGRPdb_4 },
3495 { "fucomi", { ST, STi } },
3496 { "fcomi", { ST, STi } },
3497 { "(bad)", { XX } },
3498 },
3499 /* dc */
3500 {
3501 { "fadd", { STi, ST } },
3502 { "fmul", { STi, ST } },
3503 { "(bad)", { XX } },
3504 { "(bad)", { XX } },
3505 #if SYSV386_COMPAT
3506 { "fsub", { STi, ST } },
3507 { "fsubr", { STi, ST } },
3508 { "fdiv", { STi, ST } },
3509 { "fdivr", { STi, ST } },
3510 #else
3511 { "fsubr", { STi, ST } },
3512 { "fsub", { STi, ST } },
3513 { "fdivr", { STi, ST } },
3514 { "fdiv", { STi, ST } },
3515 #endif
3516 },
3517 /* dd */
3518 {
3519 { "ffree", { STi } },
3520 { "(bad)", { XX } },
3521 { "fst", { STi } },
3522 { "fstp", { STi } },
3523 { "fucom", { STi } },
3524 { "fucomp", { STi } },
3525 { "(bad)", { XX } },
3526 { "(bad)", { XX } },
3527 },
3528 /* de */
3529 {
3530 { "faddp", { STi, ST } },
3531 { "fmulp", { STi, ST } },
3532 { "(bad)", { XX } },
3533 { FGRPde_3 },
3534 #if SYSV386_COMPAT
3535 { "fsubp", { STi, ST } },
3536 { "fsubrp", { STi, ST } },
3537 { "fdivp", { STi, ST } },
3538 { "fdivrp", { STi, ST } },
3539 #else
3540 { "fsubrp", { STi, ST } },
3541 { "fsubp", { STi, ST } },
3542 { "fdivrp", { STi, ST } },
3543 { "fdivp", { STi, ST } },
3544 #endif
3545 },
3546 /* df */
3547 {
3548 { "ffreep", { STi } },
3549 { "(bad)", { XX } },
3550 { "(bad)", { XX } },
3551 { "(bad)", { XX } },
3552 { FGRPdf_4 },
3553 { "fucomip", { ST, STi } },
3554 { "fcomip", { ST, STi } },
3555 { "(bad)", { XX } },
3556 },
3557 };
3558
3559 static char *fgrps[][8] = {
3560 /* d9_2 0 */
3561 {
3562 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3563 },
3564
3565 /* d9_4 1 */
3566 {
3567 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
3568 },
3569
3570 /* d9_5 2 */
3571 {
3572 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
3573 },
3574
3575 /* d9_6 3 */
3576 {
3577 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
3578 },
3579
3580 /* d9_7 4 */
3581 {
3582 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
3583 },
3584
3585 /* da_5 5 */
3586 {
3587 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3588 },
3589
3590 /* db_4 6 */
3591 {
3592 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
3593 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
3594 },
3595
3596 /* de_3 7 */
3597 {
3598 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3599 },
3600
3601 /* df_4 8 */
3602 {
3603 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
3604 },
3605 };
3606
3607 static void
3608 dofloat (int sizeflag)
3609 {
3610 const struct dis386 *dp;
3611 unsigned char floatop;
3612
3613 floatop = codep[-1];
3614
3615 if (mod != 3)
3616 {
3617 int fp_indx = (floatop - 0xd8) * 8 + reg;
3618
3619 putop (float_mem[fp_indx], sizeflag);
3620 obufp = op_out[0];
3621 op_ad = 2;
3622 OP_E (float_mem_mode[fp_indx], sizeflag);
3623 return;
3624 }
3625 /* Skip mod/rm byte. */
3626 MODRM_CHECK;
3627 codep++;
3628
3629 dp = &float_reg[floatop - 0xd8][reg];
3630 if (dp->name == NULL)
3631 {
3632 putop (fgrps[dp->op[0].bytemode][rm], sizeflag);
3633
3634 /* Instruction fnstsw is only one with strange arg. */
3635 if (floatop == 0xdf && codep[-1] == 0xe0)
3636 strcpy (op_out[0], names16[0]);
3637 }
3638 else
3639 {
3640 putop (dp->name, sizeflag);
3641
3642 obufp = op_out[0];
3643 op_ad = 2;
3644 if (dp->op[0].rtn)
3645 (*dp->op[0].rtn) (dp->op[0].bytemode, sizeflag);
3646
3647 obufp = op_out[1];
3648 op_ad = 1;
3649 if (dp->op[1].rtn)
3650 (*dp->op[1].rtn) (dp->op[1].bytemode, sizeflag);
3651 }
3652 }
3653
3654 static void
3655 OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3656 {
3657 oappend ("%st" + intel_syntax);
3658 }
3659
3660 static void
3661 OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
3662 {
3663 sprintf (scratchbuf, "%%st(%d)", rm);
3664 oappend (scratchbuf + intel_syntax);
3665 }
3666
3667 /* Capital letters in template are macros. */
3668 static int
3669 putop (const char *template, int sizeflag)
3670 {
3671 const char *p;
3672 int alt = 0;
3673
3674 for (p = template; *p; p++)
3675 {
3676 switch (*p)
3677 {
3678 default:
3679 *obufp++ = *p;
3680 break;
3681 case '{':
3682 alt = 0;
3683 if (intel_syntax)
3684 alt += 1;
3685 if (address_mode == mode_64bit)
3686 alt += 2;
3687 while (alt != 0)
3688 {
3689 while (*++p != '|')
3690 {
3691 if (*p == '}')
3692 {
3693 /* Alternative not valid. */
3694 strcpy (obuf, "(bad)");
3695 obufp = obuf + 5;
3696 return 1;
3697 }
3698 else if (*p == '\0')
3699 abort ();
3700 }
3701 alt--;
3702 }
3703 /* Fall through. */
3704 case 'I':
3705 alt = 1;
3706 continue;
3707 case '|':
3708 while (*++p != '}')
3709 {
3710 if (*p == '\0')
3711 abort ();
3712 }
3713 break;
3714 case '}':
3715 break;
3716 case 'A':
3717 if (intel_syntax)
3718 break;
3719 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
3720 *obufp++ = 'b';
3721 break;
3722 case 'B':
3723 if (intel_syntax)
3724 break;
3725 if (sizeflag & SUFFIX_ALWAYS)
3726 *obufp++ = 'b';
3727 break;
3728 case 'C':
3729 if (intel_syntax && !alt)
3730 break;
3731 if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS))
3732 {
3733 if (sizeflag & DFLAG)
3734 *obufp++ = intel_syntax ? 'd' : 'l';
3735 else
3736 *obufp++ = intel_syntax ? 'w' : 's';
3737 used_prefixes |= (prefixes & PREFIX_DATA);
3738 }
3739 break;
3740 case 'D':
3741 if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS))
3742 break;
3743 USED_REX (REX_MODE64);
3744 if (mod == 3)
3745 {
3746 if (rex & REX_MODE64)
3747 *obufp++ = 'q';
3748 else if (sizeflag & DFLAG)
3749 *obufp++ = intel_syntax ? 'd' : 'l';
3750 else
3751 *obufp++ = 'w';
3752 used_prefixes |= (prefixes & PREFIX_DATA);
3753 }
3754 else
3755 *obufp++ = 'w';
3756 break;
3757 case 'E': /* For jcxz/jecxz */
3758 if (address_mode == mode_64bit)
3759 {
3760 if (sizeflag & AFLAG)
3761 *obufp++ = 'r';
3762 else
3763 *obufp++ = 'e';
3764 }
3765 else
3766 if (sizeflag & AFLAG)
3767 *obufp++ = 'e';
3768 used_prefixes |= (prefixes & PREFIX_ADDR);
3769 break;
3770 case 'F':
3771 if (intel_syntax)
3772 break;
3773 if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
3774 {
3775 if (sizeflag & AFLAG)
3776 *obufp++ = address_mode == mode_64bit ? 'q' : 'l';
3777 else
3778 *obufp++ = address_mode == mode_64bit ? 'l' : 'w';
3779 used_prefixes |= (prefixes & PREFIX_ADDR);
3780 }
3781 break;
3782 case 'G':
3783 if (intel_syntax || (obufp[-1] != 's' && !(sizeflag & SUFFIX_ALWAYS)))
3784 break;
3785 if ((rex & REX_MODE64) || (sizeflag & DFLAG))
3786 *obufp++ = 'l';
3787 else
3788 *obufp++ = 'w';
3789 if (!(rex & REX_MODE64))
3790 used_prefixes |= (prefixes & PREFIX_DATA);
3791 break;
3792 case 'H':
3793 if (intel_syntax)
3794 break;
3795 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
3796 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
3797 {
3798 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
3799 *obufp++ = ',';
3800 *obufp++ = 'p';
3801 if (prefixes & PREFIX_DS)
3802 *obufp++ = 't';
3803 else
3804 *obufp++ = 'n';
3805 }
3806 break;
3807 case 'J':
3808 if (intel_syntax)
3809 break;
3810 *obufp++ = 'l';
3811 break;
3812 case 'Z':
3813 if (intel_syntax)
3814 break;
3815 if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS))
3816 {
3817 *obufp++ = 'q';
3818 break;
3819 }
3820 /* Fall through. */
3821 case 'L':
3822 if (intel_syntax)
3823 break;
3824 if (sizeflag & SUFFIX_ALWAYS)
3825 *obufp++ = 'l';
3826 break;
3827 case 'N':
3828 if ((prefixes & PREFIX_FWAIT) == 0)
3829 *obufp++ = 'n';
3830 else
3831 used_prefixes |= PREFIX_FWAIT;
3832 break;
3833 case 'O':
3834 USED_REX (REX_MODE64);
3835 if (rex & REX_MODE64)
3836 *obufp++ = 'o';
3837 else if (intel_syntax && (sizeflag & DFLAG))
3838 *obufp++ = 'q';
3839 else
3840 *obufp++ = 'd';
3841 if (!(rex & REX_MODE64))
3842 used_prefixes |= (prefixes & PREFIX_DATA);
3843 break;
3844 case 'T':
3845 if (intel_syntax)
3846 break;
3847 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3848 {
3849 *obufp++ = 'q';
3850 break;
3851 }
3852 /* Fall through. */
3853 case 'P':
3854 if (intel_syntax)
3855 break;
3856 if ((prefixes & PREFIX_DATA)
3857 || (rex & REX_MODE64)
3858 || (sizeflag & SUFFIX_ALWAYS))
3859 {
3860 USED_REX (REX_MODE64);
3861 if (rex & REX_MODE64)
3862 *obufp++ = 'q';
3863 else
3864 {
3865 if (sizeflag & DFLAG)
3866 *obufp++ = 'l';
3867 else
3868 *obufp++ = 'w';
3869 }
3870 used_prefixes |= (prefixes & PREFIX_DATA);
3871 }
3872 break;
3873 case 'U':
3874 if (intel_syntax)
3875 break;
3876 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3877 {
3878 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
3879 *obufp++ = 'q';
3880 break;
3881 }
3882 /* Fall through. */
3883 case 'Q':
3884 if (intel_syntax && !alt)
3885 break;
3886 USED_REX (REX_MODE64);
3887 if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
3888 {
3889 if (rex & REX_MODE64)
3890 *obufp++ = 'q';
3891 else
3892 {
3893 if (sizeflag & DFLAG)
3894 *obufp++ = intel_syntax ? 'd' : 'l';
3895 else
3896 *obufp++ = 'w';
3897 }
3898 used_prefixes |= (prefixes & PREFIX_DATA);
3899 }
3900 break;
3901 case 'R':
3902 USED_REX (REX_MODE64);
3903 if (rex & REX_MODE64)
3904 *obufp++ = 'q';
3905 else if (sizeflag & DFLAG)
3906 {
3907 if (intel_syntax)
3908 *obufp++ = 'd';
3909 else
3910 *obufp++ = 'l';
3911 }
3912 else
3913 *obufp++ = 'w';
3914 if (intel_syntax && !p[1]
3915 && ((rex & REX_MODE64) || (sizeflag & DFLAG)))
3916 *obufp++ = 'e';
3917 if (!(rex & REX_MODE64))
3918 used_prefixes |= (prefixes & PREFIX_DATA);
3919 break;
3920 case 'V':
3921 if (intel_syntax)
3922 break;
3923 if (address_mode == mode_64bit && (sizeflag & DFLAG))
3924 {
3925 if (sizeflag & SUFFIX_ALWAYS)
3926 *obufp++ = 'q';
3927 break;
3928 }
3929 /* Fall through. */
3930 case 'S':
3931 if (intel_syntax)
3932 break;
3933 if (sizeflag & SUFFIX_ALWAYS)
3934 {
3935 if (rex & REX_MODE64)
3936 *obufp++ = 'q';
3937 else
3938 {
3939 if (sizeflag & DFLAG)
3940 *obufp++ = 'l';
3941 else
3942 *obufp++ = 'w';
3943 used_prefixes |= (prefixes & PREFIX_DATA);
3944 }
3945 }
3946 break;
3947 case 'X':
3948 if (prefixes & PREFIX_DATA)
3949 *obufp++ = 'd';
3950 else
3951 *obufp++ = 's';
3952 used_prefixes |= (prefixes & PREFIX_DATA);
3953 break;
3954 case 'Y':
3955 if (intel_syntax)
3956 break;
3957 if (rex & REX_MODE64)
3958 {
3959 USED_REX (REX_MODE64);
3960 *obufp++ = 'q';
3961 }
3962 break;
3963 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
3964 case 'W':
3965 /* operand size flag for cwtl, cbtw */
3966 USED_REX (REX_MODE64);
3967 if (rex & REX_MODE64)
3968 {
3969 if (intel_syntax)
3970 *obufp++ = 'd';
3971 else
3972 *obufp++ = 'l';
3973 }
3974 else if (sizeflag & DFLAG)
3975 *obufp++ = 'w';
3976 else
3977 *obufp++ = 'b';
3978 if (!(rex & REX_MODE64))
3979 used_prefixes |= (prefixes & PREFIX_DATA);
3980 break;
3981 }
3982 alt = 0;
3983 }
3984 *obufp = 0;
3985 return 0;
3986 }
3987
3988 static void
3989 oappend (const char *s)
3990 {
3991 strcpy (obufp, s);
3992 obufp += strlen (s);
3993 }
3994
3995 static void
3996 append_seg (void)
3997 {
3998 if (prefixes & PREFIX_CS)
3999 {
4000 used_prefixes |= PREFIX_CS;
4001 oappend ("%cs:" + intel_syntax);
4002 }
4003 if (prefixes & PREFIX_DS)
4004 {
4005 used_prefixes |= PREFIX_DS;
4006 oappend ("%ds:" + intel_syntax);
4007 }
4008 if (prefixes & PREFIX_SS)
4009 {
4010 used_prefixes |= PREFIX_SS;
4011 oappend ("%ss:" + intel_syntax);
4012 }
4013 if (prefixes & PREFIX_ES)
4014 {
4015 used_prefixes |= PREFIX_ES;
4016 oappend ("%es:" + intel_syntax);
4017 }
4018 if (prefixes & PREFIX_FS)
4019 {
4020 used_prefixes |= PREFIX_FS;
4021 oappend ("%fs:" + intel_syntax);
4022 }
4023 if (prefixes & PREFIX_GS)
4024 {
4025 used_prefixes |= PREFIX_GS;
4026 oappend ("%gs:" + intel_syntax);
4027 }
4028 }
4029
4030 static void
4031 OP_indirE (int bytemode, int sizeflag)
4032 {
4033 if (!intel_syntax)
4034 oappend ("*");
4035 OP_E (bytemode, sizeflag);
4036 }
4037
4038 static void
4039 print_operand_value (char *buf, int hex, bfd_vma disp)
4040 {
4041 if (address_mode == mode_64bit)
4042 {
4043 if (hex)
4044 {
4045 char tmp[30];
4046 int i;
4047 buf[0] = '0';
4048 buf[1] = 'x';
4049 sprintf_vma (tmp, disp);
4050 for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
4051 strcpy (buf + 2, tmp + i);
4052 }
4053 else
4054 {
4055 bfd_signed_vma v = disp;
4056 char tmp[30];
4057 int i;
4058 if (v < 0)
4059 {
4060 *(buf++) = '-';
4061 v = -disp;
4062 /* Check for possible overflow on 0x8000000000000000. */
4063 if (v < 0)
4064 {
4065 strcpy (buf, "9223372036854775808");
4066 return;
4067 }
4068 }
4069 if (!v)
4070 {
4071 strcpy (buf, "0");
4072 return;
4073 }
4074
4075 i = 0;
4076 tmp[29] = 0;
4077 while (v)
4078 {
4079 tmp[28 - i] = (v % 10) + '0';
4080 v /= 10;
4081 i++;
4082 }
4083 strcpy (buf, tmp + 29 - i);
4084 }
4085 }
4086 else
4087 {
4088 if (hex)
4089 sprintf (buf, "0x%x", (unsigned int) disp);
4090 else
4091 sprintf (buf, "%d", (int) disp);
4092 }
4093 }
4094
4095 static void
4096 intel_operand_size (int bytemode, int sizeflag)
4097 {
4098 switch (bytemode)
4099 {
4100 case b_mode:
4101 oappend ("BYTE PTR ");
4102 break;
4103 case w_mode:
4104 case dqw_mode:
4105 oappend ("WORD PTR ");
4106 break;
4107 case stack_v_mode:
4108 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4109 {
4110 oappend ("QWORD PTR ");
4111 used_prefixes |= (prefixes & PREFIX_DATA);
4112 break;
4113 }
4114 /* FALLTHRU */
4115 case v_mode:
4116 case dq_mode:
4117 USED_REX (REX_MODE64);
4118 if (rex & REX_MODE64)
4119 oappend ("QWORD PTR ");
4120 else if ((sizeflag & DFLAG) || bytemode == dq_mode)
4121 oappend ("DWORD PTR ");
4122 else
4123 oappend ("WORD PTR ");
4124 used_prefixes |= (prefixes & PREFIX_DATA);
4125 break;
4126 case z_mode:
4127 if ((rex & REX_MODE64) || (sizeflag & DFLAG))
4128 *obufp++ = 'D';
4129 oappend ("WORD PTR ");
4130 if (!(rex & REX_MODE64))
4131 used_prefixes |= (prefixes & PREFIX_DATA);
4132 break;
4133 case d_mode:
4134 oappend ("DWORD PTR ");
4135 break;
4136 case q_mode:
4137 oappend ("QWORD PTR ");
4138 break;
4139 case m_mode:
4140 if (address_mode == mode_64bit)
4141 oappend ("QWORD PTR ");
4142 else
4143 oappend ("DWORD PTR ");
4144 break;
4145 case f_mode:
4146 if (sizeflag & DFLAG)
4147 oappend ("FWORD PTR ");
4148 else
4149 oappend ("DWORD PTR ");
4150 used_prefixes |= (prefixes & PREFIX_DATA);
4151 break;
4152 case t_mode:
4153 oappend ("TBYTE PTR ");
4154 break;
4155 case x_mode:
4156 oappend ("XMMWORD PTR ");
4157 break;
4158 case o_mode:
4159 oappend ("OWORD PTR ");
4160 break;
4161 default:
4162 break;
4163 }
4164 }
4165
4166 static void
4167 OP_E (int bytemode, int sizeflag)
4168 {
4169 bfd_vma disp;
4170 int add = 0;
4171 int riprel = 0;
4172 USED_REX (REX_EXTZ);
4173 if (rex & REX_EXTZ)
4174 add += 8;
4175
4176 /* Skip mod/rm byte. */
4177 MODRM_CHECK;
4178 codep++;
4179
4180 if (mod == 3)
4181 {
4182 switch (bytemode)
4183 {
4184 case b_mode:
4185 USED_REX (0);
4186 if (rex)
4187 oappend (names8rex[rm + add]);
4188 else
4189 oappend (names8[rm + add]);
4190 break;
4191 case w_mode:
4192 oappend (names16[rm + add]);
4193 break;
4194 case d_mode:
4195 oappend (names32[rm + add]);
4196 break;
4197 case q_mode:
4198 oappend (names64[rm + add]);
4199 break;
4200 case m_mode:
4201 if (address_mode == mode_64bit)
4202 oappend (names64[rm + add]);
4203 else
4204 oappend (names32[rm + add]);
4205 break;
4206 case stack_v_mode:
4207 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4208 {
4209 oappend (names64[rm + add]);
4210 used_prefixes |= (prefixes & PREFIX_DATA);
4211 break;
4212 }
4213 bytemode = v_mode;
4214 /* FALLTHRU */
4215 case v_mode:
4216 case dq_mode:
4217 case dqw_mode:
4218 USED_REX (REX_MODE64);
4219 if (rex & REX_MODE64)
4220 oappend (names64[rm + add]);
4221 else if ((sizeflag & DFLAG) || bytemode != v_mode)
4222 oappend (names32[rm + add]);
4223 else
4224 oappend (names16[rm + add]);
4225 used_prefixes |= (prefixes & PREFIX_DATA);
4226 break;
4227 case 0:
4228 break;
4229 default:
4230 oappend (INTERNAL_DISASSEMBLER_ERROR);
4231 break;
4232 }
4233 return;
4234 }
4235
4236 disp = 0;
4237 if (intel_syntax)
4238 intel_operand_size (bytemode, sizeflag);
4239 append_seg ();
4240
4241 if ((sizeflag & AFLAG) || address_mode == mode_64bit) /* 32 bit address mode */
4242 {
4243 int havesib;
4244 int havebase;
4245 int base;
4246 int index = 0;
4247 int scale = 0;
4248
4249 havesib = 0;
4250 havebase = 1;
4251 base = rm;
4252
4253 if (base == 4)
4254 {
4255 havesib = 1;
4256 FETCH_DATA (the_info, codep + 1);
4257 index = (*codep >> 3) & 7;
4258 if (address_mode == mode_64bit || index != 0x4)
4259 /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */
4260 scale = (*codep >> 6) & 3;
4261 base = *codep & 7;
4262 USED_REX (REX_EXTY);
4263 if (rex & REX_EXTY)
4264 index += 8;
4265 codep++;
4266 }
4267 base += add;
4268
4269 switch (mod)
4270 {
4271 case 0:
4272 if ((base & 7) == 5)
4273 {
4274 havebase = 0;
4275 if (address_mode == mode_64bit && !havesib)
4276 riprel = 1;
4277 disp = get32s ();
4278 }
4279 break;
4280 case 1:
4281 FETCH_DATA (the_info, codep + 1);
4282 disp = *codep++;
4283 if ((disp & 0x80) != 0)
4284 disp -= 0x100;
4285 break;
4286 case 2:
4287 disp = get32s ();
4288 break;
4289 }
4290
4291 if (!intel_syntax)
4292 if (mod != 0 || (base & 7) == 5)
4293 {
4294 print_operand_value (scratchbuf, !riprel, disp);
4295 oappend (scratchbuf);
4296 if (riprel)
4297 {
4298 set_op (disp, 1);
4299 oappend ("(%rip)");
4300 }
4301 }
4302
4303 if (havebase || (havesib && (index != 4 || scale != 0)))
4304 {
4305 *obufp++ = open_char;
4306 if (intel_syntax && riprel)
4307 oappend ("rip + ");
4308 *obufp = '\0';
4309 if (havebase)
4310 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
4311 ? names64[base] : names32[base]);
4312 if (havesib)
4313 {
4314 if (index != 4)
4315 {
4316 if (!intel_syntax || havebase)
4317 {
4318 *obufp++ = separator_char;
4319 *obufp = '\0';
4320 }
4321 oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
4322 ? names64[index] : names32[index]);
4323 }
4324 if (scale != 0 || (!intel_syntax && index != 4))
4325 {
4326 *obufp++ = scale_char;
4327 *obufp = '\0';
4328 sprintf (scratchbuf, "%d", 1 << scale);
4329 oappend (scratchbuf);
4330 }
4331 }
4332 if (intel_syntax && disp)
4333 {
4334 if ((bfd_signed_vma) disp > 0)
4335 {
4336 *obufp++ = '+';
4337 *obufp = '\0';
4338 }
4339 else if (mod != 1)
4340 {
4341 *obufp++ = '-';
4342 *obufp = '\0';
4343 disp = - (bfd_signed_vma) disp;
4344 }
4345
4346 print_operand_value (scratchbuf, mod != 1, disp);
4347 oappend (scratchbuf);
4348 }
4349
4350 *obufp++ = close_char;
4351 *obufp = '\0';
4352 }
4353 else if (intel_syntax)
4354 {
4355 if (mod != 0 || (base & 7) == 5)
4356 {
4357 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4358 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
4359 ;
4360 else
4361 {
4362 oappend (names_seg[ds_reg - es_reg]);
4363 oappend (":");
4364 }
4365 print_operand_value (scratchbuf, 1, disp);
4366 oappend (scratchbuf);
4367 }
4368 }
4369 }
4370 else
4371 { /* 16 bit address mode */
4372 switch (mod)
4373 {
4374 case 0:
4375 if (rm == 6)
4376 {
4377 disp = get16 ();
4378 if ((disp & 0x8000) != 0)
4379 disp -= 0x10000;
4380 }
4381 break;
4382 case 1:
4383 FETCH_DATA (the_info, codep + 1);
4384 disp = *codep++;
4385 if ((disp & 0x80) != 0)
4386 disp -= 0x100;
4387 break;
4388 case 2:
4389 disp = get16 ();
4390 if ((disp & 0x8000) != 0)
4391 disp -= 0x10000;
4392 break;
4393 }
4394
4395 if (!intel_syntax)
4396 if (mod != 0 || rm == 6)
4397 {
4398 print_operand_value (scratchbuf, 0, disp);
4399 oappend (scratchbuf);
4400 }
4401
4402 if (mod != 0 || rm != 6)
4403 {
4404 *obufp++ = open_char;
4405 *obufp = '\0';
4406 oappend (index16[rm]);
4407 if (intel_syntax && disp)
4408 {
4409 if ((bfd_signed_vma) disp > 0)
4410 {
4411 *obufp++ = '+';
4412 *obufp = '\0';
4413 }
4414 else if (mod != 1)
4415 {
4416 *obufp++ = '-';
4417 *obufp = '\0';
4418 disp = - (bfd_signed_vma) disp;
4419 }
4420
4421 print_operand_value (scratchbuf, mod != 1, disp);
4422 oappend (scratchbuf);
4423 }
4424
4425 *obufp++ = close_char;
4426 *obufp = '\0';
4427 }
4428 else if (intel_syntax)
4429 {
4430 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4431 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
4432 ;
4433 else
4434 {
4435 oappend (names_seg[ds_reg - es_reg]);
4436 oappend (":");
4437 }
4438 print_operand_value (scratchbuf, 1, disp & 0xffff);
4439 oappend (scratchbuf);
4440 }
4441 }
4442 }
4443
4444 static void
4445 OP_G (int bytemode, int sizeflag)
4446 {
4447 int add = 0;
4448 USED_REX (REX_EXTX);
4449 if (rex & REX_EXTX)
4450 add += 8;
4451 switch (bytemode)
4452 {
4453 case b_mode:
4454 USED_REX (0);
4455 if (rex)
4456 oappend (names8rex[reg + add]);
4457 else
4458 oappend (names8[reg + add]);
4459 break;
4460 case w_mode:
4461 oappend (names16[reg + add]);
4462 break;
4463 case d_mode:
4464 oappend (names32[reg + add]);
4465 break;
4466 case q_mode:
4467 oappend (names64[reg + add]);
4468 break;
4469 case v_mode:
4470 case dq_mode:
4471 case dqw_mode:
4472 USED_REX (REX_MODE64);
4473 if (rex & REX_MODE64)
4474 oappend (names64[reg + add]);
4475 else if ((sizeflag & DFLAG) || bytemode != v_mode)
4476 oappend (names32[reg + add]);
4477 else
4478 oappend (names16[reg + add]);
4479 used_prefixes |= (prefixes & PREFIX_DATA);
4480 break;
4481 case m_mode:
4482 if (address_mode == mode_64bit)
4483 oappend (names64[reg + add]);
4484 else
4485 oappend (names32[reg + add]);
4486 break;
4487 default:
4488 oappend (INTERNAL_DISASSEMBLER_ERROR);
4489 break;
4490 }
4491 }
4492
4493 static bfd_vma
4494 get64 (void)
4495 {
4496 bfd_vma x;
4497 #ifdef BFD64
4498 unsigned int a;
4499 unsigned int b;
4500
4501 FETCH_DATA (the_info, codep + 8);
4502 a = *codep++ & 0xff;
4503 a |= (*codep++ & 0xff) << 8;
4504 a |= (*codep++ & 0xff) << 16;
4505 a |= (*codep++ & 0xff) << 24;
4506 b = *codep++ & 0xff;
4507 b |= (*codep++ & 0xff) << 8;
4508 b |= (*codep++ & 0xff) << 16;
4509 b |= (*codep++ & 0xff) << 24;
4510 x = a + ((bfd_vma) b << 32);
4511 #else
4512 abort ();
4513 x = 0;
4514 #endif
4515 return x;
4516 }
4517
4518 static bfd_signed_vma
4519 get32 (void)
4520 {
4521 bfd_signed_vma x = 0;
4522
4523 FETCH_DATA (the_info, codep + 4);
4524 x = *codep++ & (bfd_signed_vma) 0xff;
4525 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
4526 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
4527 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
4528 return x;
4529 }
4530
4531 static bfd_signed_vma
4532 get32s (void)
4533 {
4534 bfd_signed_vma x = 0;
4535
4536 FETCH_DATA (the_info, codep + 4);
4537 x = *codep++ & (bfd_signed_vma) 0xff;
4538 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
4539 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
4540 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
4541
4542 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
4543
4544 return x;
4545 }
4546
4547 static int
4548 get16 (void)
4549 {
4550 int x = 0;
4551
4552 FETCH_DATA (the_info, codep + 2);
4553 x = *codep++ & 0xff;
4554 x |= (*codep++ & 0xff) << 8;
4555 return x;
4556 }
4557
4558 static void
4559 set_op (bfd_vma op, int riprel)
4560 {
4561 op_index[op_ad] = op_ad;
4562 if (address_mode == mode_64bit)
4563 {
4564 op_address[op_ad] = op;
4565 op_riprel[op_ad] = riprel;
4566 }
4567 else
4568 {
4569 /* Mask to get a 32-bit address. */
4570 op_address[op_ad] = op & 0xffffffff;
4571 op_riprel[op_ad] = riprel & 0xffffffff;
4572 }
4573 }
4574
4575 static void
4576 OP_REG (int code, int sizeflag)
4577 {
4578 const char *s;
4579 int add = 0;
4580 USED_REX (REX_EXTZ);
4581 if (rex & REX_EXTZ)
4582 add = 8;
4583
4584 switch (code)
4585 {
4586 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
4587 case sp_reg: case bp_reg: case si_reg: case di_reg:
4588 s = names16[code - ax_reg + add];
4589 break;
4590 case es_reg: case ss_reg: case cs_reg:
4591 case ds_reg: case fs_reg: case gs_reg:
4592 s = names_seg[code - es_reg + add];
4593 break;
4594 case al_reg: case ah_reg: case cl_reg: case ch_reg:
4595 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
4596 USED_REX (0);
4597 if (rex)
4598 s = names8rex[code - al_reg + add];
4599 else
4600 s = names8[code - al_reg];
4601 break;
4602 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
4603 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
4604 if (address_mode == mode_64bit && (sizeflag & DFLAG))
4605 {
4606 s = names64[code - rAX_reg + add];
4607 break;
4608 }
4609 code += eAX_reg - rAX_reg;
4610 /* Fall through. */
4611 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
4612 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
4613 USED_REX (REX_MODE64);
4614 if (rex & REX_MODE64)
4615 s = names64[code - eAX_reg + add];
4616 else if (sizeflag & DFLAG)
4617 s = names32[code - eAX_reg + add];
4618 else
4619 s = names16[code - eAX_reg + add];
4620 used_prefixes |= (prefixes & PREFIX_DATA);
4621 break;
4622 default:
4623 s = INTERNAL_DISASSEMBLER_ERROR;
4624 break;
4625 }
4626 oappend (s);
4627 }
4628
4629 static void
4630 OP_IMREG (int code, int sizeflag)
4631 {
4632 const char *s;
4633
4634 switch (code)
4635 {
4636 case indir_dx_reg:
4637 if (intel_syntax)
4638 s = "dx";
4639 else
4640 s = "(%dx)";
4641 break;
4642 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
4643 case sp_reg: case bp_reg: case si_reg: case di_reg:
4644 s = names16[code - ax_reg];
4645 break;
4646 case es_reg: case ss_reg: case cs_reg:
4647 case ds_reg: case fs_reg: case gs_reg:
4648 s = names_seg[code - es_reg];
4649 break;
4650 case al_reg: case ah_reg: case cl_reg: case ch_reg:
4651 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
4652 USED_REX (0);
4653 if (rex)
4654 s = names8rex[code - al_reg];
4655 else
4656 s = names8[code - al_reg];
4657 break;
4658 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
4659 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
4660 USED_REX (REX_MODE64);
4661 if (rex & REX_MODE64)
4662 s = names64[code - eAX_reg];
4663 else if (sizeflag & DFLAG)
4664 s = names32[code - eAX_reg];
4665 else
4666 s = names16[code - eAX_reg];
4667 used_prefixes |= (prefixes & PREFIX_DATA);
4668 break;
4669 case z_mode_ax_reg:
4670 if ((rex & REX_MODE64) || (sizeflag & DFLAG))
4671 s = *names32;
4672 else
4673 s = *names16;
4674 if (!(rex & REX_MODE64))
4675 used_prefixes |= (prefixes & PREFIX_DATA);
4676 break;
4677 default:
4678 s = INTERNAL_DISASSEMBLER_ERROR;
4679 break;
4680 }
4681 oappend (s);
4682 }
4683
4684 static void
4685 OP_I (int bytemode, int sizeflag)
4686 {
4687 bfd_signed_vma op;
4688 bfd_signed_vma mask = -1;
4689
4690 switch (bytemode)
4691 {
4692 case b_mode:
4693 FETCH_DATA (the_info, codep + 1);
4694 op = *codep++;
4695 mask = 0xff;
4696 break;
4697 case q_mode:
4698 if (address_mode == mode_64bit)
4699 {
4700 op = get32s ();
4701 break;
4702 }
4703 /* Fall through. */
4704 case v_mode:
4705 USED_REX (REX_MODE64);
4706 if (rex & REX_MODE64)
4707 op = get32s ();
4708 else if (sizeflag & DFLAG)
4709 {
4710 op = get32 ();
4711 mask = 0xffffffff;
4712 }
4713 else
4714 {
4715 op = get16 ();
4716 mask = 0xfffff;
4717 }
4718 used_prefixes |= (prefixes & PREFIX_DATA);
4719 break;
4720 case w_mode:
4721 mask = 0xfffff;
4722 op = get16 ();
4723 break;
4724 case const_1_mode:
4725 if (intel_syntax)
4726 oappend ("1");
4727 return;
4728 default:
4729 oappend (INTERNAL_DISASSEMBLER_ERROR);
4730 return;
4731 }
4732
4733 op &= mask;
4734 scratchbuf[0] = '$';
4735 print_operand_value (scratchbuf + 1, 1, op);
4736 oappend (scratchbuf + intel_syntax);
4737 scratchbuf[0] = '\0';
4738 }
4739
4740 static void
4741 OP_I64 (int bytemode, int sizeflag)
4742 {
4743 bfd_signed_vma op;
4744 bfd_signed_vma mask = -1;
4745
4746 if (address_mode != mode_64bit)
4747 {
4748 OP_I (bytemode, sizeflag);
4749 return;
4750 }
4751
4752 switch (bytemode)
4753 {
4754 case b_mode:
4755 FETCH_DATA (the_info, codep + 1);
4756 op = *codep++;
4757 mask = 0xff;
4758 break;
4759 case v_mode:
4760 USED_REX (REX_MODE64);
4761 if (rex & REX_MODE64)
4762 op = get64 ();
4763 else if (sizeflag & DFLAG)
4764 {
4765 op = get32 ();
4766 mask = 0xffffffff;
4767 }
4768 else
4769 {
4770 op = get16 ();
4771 mask = 0xfffff;
4772 }
4773 used_prefixes |= (prefixes & PREFIX_DATA);
4774 break;
4775 case w_mode:
4776 mask = 0xfffff;
4777 op = get16 ();
4778 break;
4779 default:
4780 oappend (INTERNAL_DISASSEMBLER_ERROR);
4781 return;
4782 }
4783
4784 op &= mask;
4785 scratchbuf[0] = '$';
4786 print_operand_value (scratchbuf + 1, 1, op);
4787 oappend (scratchbuf + intel_syntax);
4788 scratchbuf[0] = '\0';
4789 }
4790
4791 static void
4792 OP_sI (int bytemode, int sizeflag)
4793 {
4794 bfd_signed_vma op;
4795 bfd_signed_vma mask = -1;
4796
4797 switch (bytemode)
4798 {
4799 case b_mode:
4800 FETCH_DATA (the_info, codep + 1);
4801 op = *codep++;
4802 if ((op & 0x80) != 0)
4803 op -= 0x100;
4804 mask = 0xffffffff;
4805 break;
4806 case v_mode:
4807 USED_REX (REX_MODE64);
4808 if (rex & REX_MODE64)
4809 op = get32s ();
4810 else if (sizeflag & DFLAG)
4811 {
4812 op = get32s ();
4813 mask = 0xffffffff;
4814 }
4815 else
4816 {
4817 mask = 0xffffffff;
4818 op = get16 ();
4819 if ((op & 0x8000) != 0)
4820 op -= 0x10000;
4821 }
4822 used_prefixes |= (prefixes & PREFIX_DATA);
4823 break;
4824 case w_mode:
4825 op = get16 ();
4826 mask = 0xffffffff;
4827 if ((op & 0x8000) != 0)
4828 op -= 0x10000;
4829 break;
4830 default:
4831 oappend (INTERNAL_DISASSEMBLER_ERROR);
4832 return;
4833 }
4834
4835 scratchbuf[0] = '$';
4836 print_operand_value (scratchbuf + 1, 1, op);
4837 oappend (scratchbuf + intel_syntax);
4838 }
4839
4840 static void
4841 OP_J (int bytemode, int sizeflag)
4842 {
4843 bfd_vma disp;
4844 bfd_vma mask = -1;
4845 bfd_vma segment = 0;
4846
4847 switch (bytemode)
4848 {
4849 case b_mode:
4850 FETCH_DATA (the_info, codep + 1);
4851 disp = *codep++;
4852 if ((disp & 0x80) != 0)
4853 disp -= 0x100;
4854 break;
4855 case v_mode:
4856 if ((sizeflag & DFLAG) || (rex & REX_MODE64))
4857 disp = get32s ();
4858 else
4859 {
4860 disp = get16 ();
4861 if ((disp & 0x8000) != 0)
4862 disp -= 0x10000;
4863 /* In 16bit mode, address is wrapped around at 64k within
4864 the same segment. Otherwise, a data16 prefix on a jump
4865 instruction means that the pc is masked to 16 bits after
4866 the displacement is added! */
4867 mask = 0xffff;
4868 if ((prefixes & PREFIX_DATA) == 0)
4869 segment = ((start_pc + codep - start_codep)
4870 & ~((bfd_vma) 0xffff));
4871 }
4872 used_prefixes |= (prefixes & PREFIX_DATA);
4873 break;
4874 default:
4875 oappend (INTERNAL_DISASSEMBLER_ERROR);
4876 return;
4877 }
4878 disp = ((start_pc + codep - start_codep + disp) & mask) | segment;
4879 set_op (disp, 0);
4880 print_operand_value (scratchbuf, 1, disp);
4881 oappend (scratchbuf);
4882 }
4883
4884 static void
4885 OP_SEG (int bytemode, int sizeflag)
4886 {
4887 if (bytemode == w_mode)
4888 oappend (names_seg[reg]);
4889 else
4890 OP_E (mod == 3 ? bytemode : w_mode, sizeflag);
4891 }
4892
4893 static void
4894 OP_DIR (int dummy ATTRIBUTE_UNUSED, int sizeflag)
4895 {
4896 int seg, offset;
4897
4898 if (sizeflag & DFLAG)
4899 {
4900 offset = get32 ();
4901 seg = get16 ();
4902 }
4903 else
4904 {
4905 offset = get16 ();
4906 seg = get16 ();
4907 }
4908 used_prefixes |= (prefixes & PREFIX_DATA);
4909 if (intel_syntax)
4910 sprintf (scratchbuf, "0x%x:0x%x", seg, offset);
4911 else
4912 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
4913 oappend (scratchbuf);
4914 }
4915
4916 static void
4917 OP_OFF (int bytemode, int sizeflag)
4918 {
4919 bfd_vma off;
4920
4921 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
4922 intel_operand_size (bytemode, sizeflag);
4923 append_seg ();
4924
4925 if ((sizeflag & AFLAG) || address_mode == mode_64bit)
4926 off = get32 ();
4927 else
4928 off = get16 ();
4929
4930 if (intel_syntax)
4931 {
4932 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4933 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
4934 {
4935 oappend (names_seg[ds_reg - es_reg]);
4936 oappend (":");
4937 }
4938 }
4939 print_operand_value (scratchbuf, 1, off);
4940 oappend (scratchbuf);
4941 }
4942
4943 static void
4944 OP_OFF64 (int bytemode, int sizeflag)
4945 {
4946 bfd_vma off;
4947
4948 if (address_mode != mode_64bit
4949 || (prefixes & PREFIX_ADDR))
4950 {
4951 OP_OFF (bytemode, sizeflag);
4952 return;
4953 }
4954
4955 if (intel_syntax && (sizeflag & SUFFIX_ALWAYS))
4956 intel_operand_size (bytemode, sizeflag);
4957 append_seg ();
4958
4959 off = get64 ();
4960
4961 if (intel_syntax)
4962 {
4963 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
4964 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
4965 {
4966 oappend (names_seg[ds_reg - es_reg]);
4967 oappend (":");
4968 }
4969 }
4970 print_operand_value (scratchbuf, 1, off);
4971 oappend (scratchbuf);
4972 }
4973
4974 static void
4975 ptr_reg (int code, int sizeflag)
4976 {
4977 const char *s;
4978
4979 *obufp++ = open_char;
4980 used_prefixes |= (prefixes & PREFIX_ADDR);
4981 if (address_mode == mode_64bit)
4982 {
4983 if (!(sizeflag & AFLAG))
4984 s = names32[code - eAX_reg];
4985 else
4986 s = names64[code - eAX_reg];
4987 }
4988 else if (sizeflag & AFLAG)
4989 s = names32[code - eAX_reg];
4990 else
4991 s = names16[code - eAX_reg];
4992 oappend (s);
4993 *obufp++ = close_char;
4994 *obufp = 0;
4995 }
4996
4997 static void
4998 OP_ESreg (int code, int sizeflag)
4999 {
5000 if (intel_syntax)
5001 {
5002 switch (codep[-1])
5003 {
5004 case 0x6d: /* insw/insl */
5005 intel_operand_size (z_mode, sizeflag);
5006 break;
5007 case 0xa5: /* movsw/movsl/movsq */
5008 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5009 case 0xab: /* stosw/stosl */
5010 case 0xaf: /* scasw/scasl */
5011 intel_operand_size (v_mode, sizeflag);
5012 break;
5013 default:
5014 intel_operand_size (b_mode, sizeflag);
5015 }
5016 }
5017 oappend ("%es:" + intel_syntax);
5018 ptr_reg (code, sizeflag);
5019 }
5020
5021 static void
5022 OP_DSreg (int code, int sizeflag)
5023 {
5024 if (intel_syntax)
5025 {
5026 switch (codep[-1])
5027 {
5028 case 0x6f: /* outsw/outsl */
5029 intel_operand_size (z_mode, sizeflag);
5030 break;
5031 case 0xa5: /* movsw/movsl/movsq */
5032 case 0xa7: /* cmpsw/cmpsl/cmpsq */
5033 case 0xad: /* lodsw/lodsl/lodsq */
5034 intel_operand_size (v_mode, sizeflag);
5035 break;
5036 default:
5037 intel_operand_size (b_mode, sizeflag);
5038 }
5039 }
5040 if ((prefixes
5041 & (PREFIX_CS
5042 | PREFIX_DS
5043 | PREFIX_SS
5044 | PREFIX_ES
5045 | PREFIX_FS
5046 | PREFIX_GS)) == 0)
5047 prefixes |= PREFIX_DS;
5048 append_seg ();
5049 ptr_reg (code, sizeflag);
5050 }
5051
5052 static void
5053 OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5054 {
5055 int add = 0;
5056 if (rex & REX_EXTX)
5057 {
5058 USED_REX (REX_EXTX);
5059 add = 8;
5060 }
5061 else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK))
5062 {
5063 used_prefixes |= PREFIX_LOCK;
5064 add = 8;
5065 }
5066 sprintf (scratchbuf, "%%cr%d", reg + add);
5067 oappend (scratchbuf + intel_syntax);
5068 }
5069
5070 static void
5071 OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5072 {
5073 int add = 0;
5074 USED_REX (REX_EXTX);
5075 if (rex & REX_EXTX)
5076 add = 8;
5077 if (intel_syntax)
5078 sprintf (scratchbuf, "db%d", reg + add);
5079 else
5080 sprintf (scratchbuf, "%%db%d", reg + add);
5081 oappend (scratchbuf);
5082 }
5083
5084 static void
5085 OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5086 {
5087 sprintf (scratchbuf, "%%tr%d", reg);
5088 oappend (scratchbuf + intel_syntax);
5089 }
5090
5091 static void
5092 OP_R (int bytemode, int sizeflag)
5093 {
5094 if (mod == 3)
5095 OP_E (bytemode, sizeflag);
5096 else
5097 BadOp ();
5098 }
5099
5100 static void
5101 OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5102 {
5103 used_prefixes |= (prefixes & PREFIX_DATA);
5104 if (prefixes & PREFIX_DATA)
5105 {
5106 int add = 0;
5107 USED_REX (REX_EXTX);
5108 if (rex & REX_EXTX)
5109 add = 8;
5110 sprintf (scratchbuf, "%%xmm%d", reg + add);
5111 }
5112 else
5113 sprintf (scratchbuf, "%%mm%d", reg);
5114 oappend (scratchbuf + intel_syntax);
5115 }
5116
5117 static void
5118 OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5119 {
5120 int add = 0;
5121 USED_REX (REX_EXTX);
5122 if (rex & REX_EXTX)
5123 add = 8;
5124 sprintf (scratchbuf, "%%xmm%d", reg + add);
5125 oappend (scratchbuf + intel_syntax);
5126 }
5127
5128 static void
5129 OP_EM (int bytemode, int sizeflag)
5130 {
5131 if (mod != 3)
5132 {
5133 if (intel_syntax && bytemode == v_mode)
5134 {
5135 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
5136 used_prefixes |= (prefixes & PREFIX_DATA);
5137 }
5138 OP_E (bytemode, sizeflag);
5139 return;
5140 }
5141
5142 /* Skip mod/rm byte. */
5143 MODRM_CHECK;
5144 codep++;
5145 used_prefixes |= (prefixes & PREFIX_DATA);
5146 if (prefixes & PREFIX_DATA)
5147 {
5148 int add = 0;
5149
5150 USED_REX (REX_EXTZ);
5151 if (rex & REX_EXTZ)
5152 add = 8;
5153 sprintf (scratchbuf, "%%xmm%d", rm + add);
5154 }
5155 else
5156 sprintf (scratchbuf, "%%mm%d", rm);
5157 oappend (scratchbuf + intel_syntax);
5158 }
5159
5160 /* cvt* are the only instructions in sse2 which have
5161 both SSE and MMX operands and also have 0x66 prefix
5162 in their opcode. 0x66 was originally used to differentiate
5163 between SSE and MMX instruction(operands). So we have to handle the
5164 cvt* separately using OP_EMC and OP_MXC */
5165 static void
5166 OP_EMC (int bytemode, int sizeflag)
5167 {
5168 if (mod != 3)
5169 {
5170 if (intel_syntax && bytemode == v_mode)
5171 {
5172 bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode;
5173 used_prefixes |= (prefixes & PREFIX_DATA);
5174 }
5175 OP_E (bytemode, sizeflag);
5176 return;
5177 }
5178
5179 /* Skip mod/rm byte. */
5180 MODRM_CHECK;
5181 codep++;
5182 used_prefixes |= (prefixes & PREFIX_DATA);
5183 sprintf (scratchbuf, "%%mm%d", rm);
5184 oappend (scratchbuf + intel_syntax);
5185 }
5186
5187 static void
5188 OP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5189 {
5190 used_prefixes |= (prefixes & PREFIX_DATA);
5191 sprintf (scratchbuf, "%%mm%d", reg);
5192 oappend (scratchbuf + intel_syntax);
5193 }
5194
5195 static void
5196 OP_EX (int bytemode, int sizeflag)
5197 {
5198 int add = 0;
5199 if (mod != 3)
5200 {
5201 if (intel_syntax && bytemode == v_mode)
5202 {
5203 switch (prefixes & (PREFIX_DATA|PREFIX_REPZ|PREFIX_REPNZ))
5204 {
5205 case 0: bytemode = x_mode; break;
5206 case PREFIX_REPZ: bytemode = d_mode; used_prefixes |= PREFIX_REPZ; break;
5207 case PREFIX_DATA: bytemode = x_mode; used_prefixes |= PREFIX_DATA; break;
5208 case PREFIX_REPNZ: bytemode = q_mode; used_prefixes |= PREFIX_REPNZ; break;
5209 default: bytemode = 0; break;
5210 }
5211 }
5212 OP_E (bytemode, sizeflag);
5213 return;
5214 }
5215 USED_REX (REX_EXTZ);
5216 if (rex & REX_EXTZ)
5217 add = 8;
5218
5219 /* Skip mod/rm byte. */
5220 MODRM_CHECK;
5221 codep++;
5222 sprintf (scratchbuf, "%%xmm%d", rm + add);
5223 oappend (scratchbuf + intel_syntax);
5224 }
5225
5226 static void
5227 OP_MS (int bytemode, int sizeflag)
5228 {
5229 if (mod == 3)
5230 OP_EM (bytemode, sizeflag);
5231 else
5232 BadOp ();
5233 }
5234
5235 static void
5236 OP_XS (int bytemode, int sizeflag)
5237 {
5238 if (mod == 3)
5239 OP_EX (bytemode, sizeflag);
5240 else
5241 BadOp ();
5242 }
5243
5244 static void
5245 OP_M (int bytemode, int sizeflag)
5246 {
5247 if (mod == 3)
5248 /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */
5249 BadOp ();
5250 else
5251 OP_E (bytemode, sizeflag);
5252 }
5253
5254 static void
5255 OP_0f07 (int bytemode, int sizeflag)
5256 {
5257 if (mod != 3 || rm != 0)
5258 BadOp ();
5259 else
5260 OP_E (bytemode, sizeflag);
5261 }
5262
5263 static void
5264 OP_0fae (int bytemode, int sizeflag)
5265 {
5266 if (mod == 3)
5267 {
5268 if (reg == 7)
5269 strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
5270
5271 if (reg < 5 || rm != 0)
5272 {
5273 BadOp (); /* bad sfence, mfence, or lfence */
5274 return;
5275 }
5276 }
5277 else if (reg != 7)
5278 {
5279 BadOp (); /* bad clflush */
5280 return;
5281 }
5282
5283 OP_E (bytemode, sizeflag);
5284 }
5285
5286 /* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in
5287 32bit mode and "xchg %rax,%rax" in 64bit mode. NOP with REPZ prefix
5288 is called PAUSE. We display "xchg %ax,%ax" instead of "data16 nop".
5289 */
5290
5291 static void
5292 NOP_Fixup1 (int bytemode, int sizeflag)
5293 {
5294 if (prefixes == PREFIX_REPZ)
5295 strcpy (obuf, "pause");
5296 else if (prefixes == PREFIX_DATA
5297 || ((rex & REX_MODE64) && rex != 0x48))
5298 OP_REG (bytemode, sizeflag);
5299 else
5300 strcpy (obuf, "nop");
5301 }
5302
5303 static void
5304 NOP_Fixup2 (int bytemode, int sizeflag)
5305 {
5306 if (prefixes == PREFIX_DATA
5307 || ((rex & REX_MODE64) && rex != 0x48))
5308 OP_IMREG (bytemode, sizeflag);
5309 }
5310
5311 static const char *const Suffix3DNow[] = {
5312 /* 00 */ NULL, NULL, NULL, NULL,
5313 /* 04 */ NULL, NULL, NULL, NULL,
5314 /* 08 */ NULL, NULL, NULL, NULL,
5315 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
5316 /* 10 */ NULL, NULL, NULL, NULL,
5317 /* 14 */ NULL, NULL, NULL, NULL,
5318 /* 18 */ NULL, NULL, NULL, NULL,
5319 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
5320 /* 20 */ NULL, NULL, NULL, NULL,
5321 /* 24 */ NULL, NULL, NULL, NULL,
5322 /* 28 */ NULL, NULL, NULL, NULL,
5323 /* 2C */ NULL, NULL, NULL, NULL,
5324 /* 30 */ NULL, NULL, NULL, NULL,
5325 /* 34 */ NULL, NULL, NULL, NULL,
5326 /* 38 */ NULL, NULL, NULL, NULL,
5327 /* 3C */ NULL, NULL, NULL, NULL,
5328 /* 40 */ NULL, NULL, NULL, NULL,
5329 /* 44 */ NULL, NULL, NULL, NULL,
5330 /* 48 */ NULL, NULL, NULL, NULL,
5331 /* 4C */ NULL, NULL, NULL, NULL,
5332 /* 50 */ NULL, NULL, NULL, NULL,
5333 /* 54 */ NULL, NULL, NULL, NULL,
5334 /* 58 */ NULL, NULL, NULL, NULL,
5335 /* 5C */ NULL, NULL, NULL, NULL,
5336 /* 60 */ NULL, NULL, NULL, NULL,
5337 /* 64 */ NULL, NULL, NULL, NULL,
5338 /* 68 */ NULL, NULL, NULL, NULL,
5339 /* 6C */ NULL, NULL, NULL, NULL,
5340 /* 70 */ NULL, NULL, NULL, NULL,
5341 /* 74 */ NULL, NULL, NULL, NULL,
5342 /* 78 */ NULL, NULL, NULL, NULL,
5343 /* 7C */ NULL, NULL, NULL, NULL,
5344 /* 80 */ NULL, NULL, NULL, NULL,
5345 /* 84 */ NULL, NULL, NULL, NULL,
5346 /* 88 */ NULL, NULL, "pfnacc", NULL,
5347 /* 8C */ NULL, NULL, "pfpnacc", NULL,
5348 /* 90 */ "pfcmpge", NULL, NULL, NULL,
5349 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
5350 /* 98 */ NULL, NULL, "pfsub", NULL,
5351 /* 9C */ NULL, NULL, "pfadd", NULL,
5352 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
5353 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
5354 /* A8 */ NULL, NULL, "pfsubr", NULL,
5355 /* AC */ NULL, NULL, "pfacc", NULL,
5356 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
5357 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
5358 /* B8 */ NULL, NULL, NULL, "pswapd",
5359 /* BC */ NULL, NULL, NULL, "pavgusb",
5360 /* C0 */ NULL, NULL, NULL, NULL,
5361 /* C4 */ NULL, NULL, NULL, NULL,
5362 /* C8 */ NULL, NULL, NULL, NULL,
5363 /* CC */ NULL, NULL, NULL, NULL,
5364 /* D0 */ NULL, NULL, NULL, NULL,
5365 /* D4 */ NULL, NULL, NULL, NULL,
5366 /* D8 */ NULL, NULL, NULL, NULL,
5367 /* DC */ NULL, NULL, NULL, NULL,
5368 /* E0 */ NULL, NULL, NULL, NULL,
5369 /* E4 */ NULL, NULL, NULL, NULL,
5370 /* E8 */ NULL, NULL, NULL, NULL,
5371 /* EC */ NULL, NULL, NULL, NULL,
5372 /* F0 */ NULL, NULL, NULL, NULL,
5373 /* F4 */ NULL, NULL, NULL, NULL,
5374 /* F8 */ NULL, NULL, NULL, NULL,
5375 /* FC */ NULL, NULL, NULL, NULL,
5376 };
5377
5378 static void
5379 OP_3DNowSuffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5380 {
5381 const char *mnemonic;
5382
5383 FETCH_DATA (the_info, codep + 1);
5384 /* AMD 3DNow! instructions are specified by an opcode suffix in the
5385 place where an 8-bit immediate would normally go. ie. the last
5386 byte of the instruction. */
5387 obufp = obuf + strlen (obuf);
5388 mnemonic = Suffix3DNow[*codep++ & 0xff];
5389 if (mnemonic)
5390 oappend (mnemonic);
5391 else
5392 {
5393 /* Since a variable sized modrm/sib chunk is between the start
5394 of the opcode (0x0f0f) and the opcode suffix, we need to do
5395 all the modrm processing first, and don't know until now that
5396 we have a bad opcode. This necessitates some cleaning up. */
5397 op_out[0][0] = '\0';
5398 op_out[1][0] = '\0';
5399 BadOp ();
5400 }
5401 }
5402
5403 static const char *simd_cmp_op[] = {
5404 "eq",
5405 "lt",
5406 "le",
5407 "unord",
5408 "neq",
5409 "nlt",
5410 "nle",
5411 "ord"
5412 };
5413
5414 static void
5415 OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED)
5416 {
5417 unsigned int cmp_type;
5418
5419 FETCH_DATA (the_info, codep + 1);
5420 obufp = obuf + strlen (obuf);
5421 cmp_type = *codep++ & 0xff;
5422 if (cmp_type < 8)
5423 {
5424 char suffix1 = 'p', suffix2 = 's';
5425 used_prefixes |= (prefixes & PREFIX_REPZ);
5426 if (prefixes & PREFIX_REPZ)
5427 suffix1 = 's';
5428 else
5429 {
5430 used_prefixes |= (prefixes & PREFIX_DATA);
5431 if (prefixes & PREFIX_DATA)
5432 suffix2 = 'd';
5433 else
5434 {
5435 used_prefixes |= (prefixes & PREFIX_REPNZ);
5436 if (prefixes & PREFIX_REPNZ)
5437 suffix1 = 's', suffix2 = 'd';
5438 }
5439 }
5440 sprintf (scratchbuf, "cmp%s%c%c",
5441 simd_cmp_op[cmp_type], suffix1, suffix2);
5442 used_prefixes |= (prefixes & PREFIX_REPZ);
5443 oappend (scratchbuf);
5444 }
5445 else
5446 {
5447 /* We have a bad extension byte. Clean up. */
5448 op_out[0][0] = '\0';
5449 op_out[1][0] = '\0';
5450 BadOp ();
5451 }
5452 }
5453
5454 static void
5455 SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED)
5456 {
5457 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
5458 forms of these instructions. */
5459 if (mod == 3)
5460 {
5461 char *p = obuf + strlen (obuf);
5462 *(p + 1) = '\0';
5463 *p = *(p - 1);
5464 *(p - 1) = *(p - 2);
5465 *(p - 2) = *(p - 3);
5466 *(p - 3) = extrachar;
5467 }
5468 }
5469
5470 static void
5471 PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
5472 {
5473 if (mod == 3 && reg == 1 && rm <= 1)
5474 {
5475 /* Override "sidt". */
5476 size_t olen = strlen (obuf);
5477 char *p = obuf + olen - 4;
5478 const char **names = (address_mode == mode_64bit
5479 ? names64 : names32);
5480
5481 /* We might have a suffix when disassembling with -Msuffix. */
5482 if (*p == 'i')
5483 --p;
5484
5485 /* Remove "addr16/addr32" if we aren't in Intel mode. */
5486 if (!intel_syntax
5487 && (prefixes & PREFIX_ADDR)
5488 && olen >= (4 + 7)
5489 && *(p - 1) == ' '
5490 && CONST_STRNEQ (p - 7, "addr")
5491 && (CONST_STRNEQ (p - 3, "16")
5492 || CONST_STRNEQ (p - 3, "32")))
5493 p -= 7;
5494
5495 if (rm)
5496 {
5497 /* mwait %eax,%ecx */
5498 strcpy (p, "mwait");
5499 if (!intel_syntax)
5500 strcpy (op_out[0], names[0]);
5501 }
5502 else
5503 {
5504 /* monitor %eax,%ecx,%edx" */
5505 strcpy (p, "monitor");
5506 if (!intel_syntax)
5507 {
5508 const char **op1_names;
5509 if (!(prefixes & PREFIX_ADDR))
5510 op1_names = (address_mode == mode_16bit
5511 ? names16 : names);
5512 else
5513 {
5514 op1_names = (address_mode != mode_32bit
5515 ? names32 : names16);
5516 used_prefixes |= PREFIX_ADDR;
5517 }
5518 strcpy (op_out[0], op1_names[0]);
5519 strcpy (op_out[2], names[2]);
5520 }
5521 }
5522 if (!intel_syntax)
5523 {
5524 strcpy (op_out[1], names[1]);
5525 two_source_ops = 1;
5526 }
5527
5528 codep++;
5529 }
5530 else
5531 OP_M (0, sizeflag);
5532 }
5533
5534 static void
5535 SVME_Fixup (int bytemode, int sizeflag)
5536 {
5537 const char *alt;
5538 char *p;
5539
5540 switch (*codep)
5541 {
5542 case 0xd8:
5543 alt = "vmrun";
5544 break;
5545 case 0xd9:
5546 alt = "vmmcall";
5547 break;
5548 case 0xda:
5549 alt = "vmload";
5550 break;
5551 case 0xdb:
5552 alt = "vmsave";
5553 break;
5554 case 0xdc:
5555 alt = "stgi";
5556 break;
5557 case 0xdd:
5558 alt = "clgi";
5559 break;
5560 case 0xde:
5561 alt = "skinit";
5562 break;
5563 case 0xdf:
5564 alt = "invlpga";
5565 break;
5566 default:
5567 OP_M (bytemode, sizeflag);
5568 return;
5569 }
5570 /* Override "lidt". */
5571 p = obuf + strlen (obuf) - 4;
5572 /* We might have a suffix. */
5573 if (*p == 'i')
5574 --p;
5575 strcpy (p, alt);
5576 if (!(prefixes & PREFIX_ADDR))
5577 {
5578 ++codep;
5579 return;
5580 }
5581 used_prefixes |= PREFIX_ADDR;
5582 switch (*codep++)
5583 {
5584 case 0xdf:
5585 strcpy (op_out[1], names32[1]);
5586 two_source_ops = 1;
5587 /* Fall through. */
5588 case 0xd8:
5589 case 0xda:
5590 case 0xdb:
5591 *obufp++ = open_char;
5592 if (address_mode == mode_64bit || (sizeflag & AFLAG))
5593 alt = names32[0];
5594 else
5595 alt = names16[0];
5596 strcpy (obufp, alt);
5597 obufp += strlen (alt);
5598 *obufp++ = close_char;
5599 *obufp = '\0';
5600 break;
5601 }
5602 }
5603
5604 static void
5605 INVLPG_Fixup (int bytemode, int sizeflag)
5606 {
5607 const char *alt;
5608
5609 switch (*codep)
5610 {
5611 case 0xf8:
5612 alt = "swapgs";
5613 break;
5614 case 0xf9:
5615 alt = "rdtscp";
5616 break;
5617 default:
5618 OP_M (bytemode, sizeflag);
5619 return;
5620 }
5621 /* Override "invlpg". */
5622 strcpy (obuf + strlen (obuf) - 6, alt);
5623 codep++;
5624 }
5625
5626 static void
5627 BadOp (void)
5628 {
5629 /* Throw away prefixes and 1st. opcode byte. */
5630 codep = insn_codep + 1;
5631 oappend ("(bad)");
5632 }
5633
5634 static void
5635 VMX_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag)
5636 {
5637 if (mod == 3 && reg == 0 && rm >=1 && rm <= 4)
5638 {
5639 /* Override "sgdt". */
5640 char *p = obuf + strlen (obuf) - 4;
5641
5642 /* We might have a suffix when disassembling with -Msuffix. */
5643 if (*p == 'g')
5644 --p;
5645
5646 switch (rm)
5647 {
5648 case 1:
5649 strcpy (p, "vmcall");
5650 break;
5651 case 2:
5652 strcpy (p, "vmlaunch");
5653 break;
5654 case 3:
5655 strcpy (p, "vmresume");
5656 break;
5657 case 4:
5658 strcpy (p, "vmxoff");
5659 break;
5660 }
5661
5662 codep++;
5663 }
5664 else
5665 OP_E (0, sizeflag);
5666 }
5667
5668 static void
5669 OP_VMX (int bytemode, int sizeflag)
5670 {
5671 used_prefixes |= (prefixes & (PREFIX_DATA | PREFIX_REPZ));
5672 if (prefixes & PREFIX_DATA)
5673 strcpy (obuf, "vmclear");
5674 else if (prefixes & PREFIX_REPZ)
5675 strcpy (obuf, "vmxon");
5676 else
5677 strcpy (obuf, "vmptrld");
5678 OP_E (bytemode, sizeflag);
5679 }
5680
5681 static void
5682 REP_Fixup (int bytemode, int sizeflag)
5683 {
5684 /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs,
5685 lods and stos. */
5686 size_t ilen = 0;
5687
5688 if (prefixes & PREFIX_REPZ)
5689 switch (*insn_codep)
5690 {
5691 case 0x6e: /* outsb */
5692 case 0x6f: /* outsw/outsl */
5693 case 0xa4: /* movsb */
5694 case 0xa5: /* movsw/movsl/movsq */
5695 if (!intel_syntax)
5696 ilen = 5;
5697 else
5698 ilen = 4;
5699 break;
5700 case 0xaa: /* stosb */
5701 case 0xab: /* stosw/stosl/stosq */
5702 case 0xac: /* lodsb */
5703 case 0xad: /* lodsw/lodsl/lodsq */
5704 if (!intel_syntax && (sizeflag & SUFFIX_ALWAYS))
5705 ilen = 5;
5706 else
5707 ilen = 4;
5708 break;
5709 case 0x6c: /* insb */
5710 case 0x6d: /* insl/insw */
5711 if (!intel_syntax)
5712 ilen = 4;
5713 else
5714 ilen = 3;
5715 break;
5716 default:
5717 abort ();
5718 break;
5719 }
5720
5721 if (ilen != 0)
5722 {
5723 size_t olen;
5724 char *p;
5725
5726 olen = strlen (obuf);
5727 p = obuf + olen - ilen - 1 - 4;
5728 /* Handle "repz [addr16|addr32]". */
5729 if ((prefixes & PREFIX_ADDR))
5730 p -= 1 + 6;
5731
5732 memmove (p + 3, p + 4, olen - (p + 3 - obuf));
5733 }
5734
5735 switch (bytemode)
5736 {
5737 case al_reg:
5738 case eAX_reg:
5739 case indir_dx_reg:
5740 OP_IMREG (bytemode, sizeflag);
5741 break;
5742 case eDI_reg:
5743 OP_ESreg (bytemode, sizeflag);
5744 break;
5745 case eSI_reg:
5746 OP_DSreg (bytemode, sizeflag);
5747 break;
5748 default:
5749 abort ();
5750 break;
5751 }
5752 }
5753
5754 static void
5755 CMPXCHG8B_Fixup (int bytemode, int sizeflag)
5756 {
5757 USED_REX (REX_MODE64);
5758 if (rex & REX_MODE64)
5759 {
5760 /* Change cmpxchg8b to cmpxchg16b. */
5761 char *p = obuf + strlen (obuf) - 2;
5762 strcpy (p, "16b");
5763 bytemode = o_mode;
5764 }
5765 OP_M (bytemode, sizeflag);
5766 }
This page took 0.177475 seconds and 4 git commands to generate.