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