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