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