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