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