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