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