2001-07-05 H.J. Lu <hjl@gnu.org>
[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 ((unsigned int, 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 */
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 "%rax","%rcx","%rdx","%rbx", "%rsp","%rbp","%rsi","%rdi",
1137 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
1138 };
1139 static const char *names32[] = {
1140 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
1141 "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
1142 };
1143 static const char *names16[] = {
1144 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
1145 "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
1146 };
1147 static const char *names8[] = {
1148 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
1149 };
1150 static const char *names8rex[] = {
1151 "%al","%cl","%dl","%bl","%spl", "%bpl", "%sil", "%dil",
1152 "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
1153 };
1154 static const char *names_seg[] = {
1155 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1156 };
1157 static const char *index16[] = {
1158 "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx"
1159 };
1160
1161 static const struct dis386 grps[][8] = {
1162 /* GRP1b */
1163 {
1164 { "addA", Eb, Ib, XX },
1165 { "orA", Eb, Ib, XX },
1166 { "adcA", Eb, Ib, XX },
1167 { "sbbA", Eb, Ib, XX },
1168 { "andA", Eb, Ib, XX },
1169 { "subA", Eb, Ib, XX },
1170 { "xorA", Eb, Ib, XX },
1171 { "cmpA", Eb, Ib, XX }
1172 },
1173 /* GRP1S */
1174 {
1175 { "addQ", Ev, Iv, XX },
1176 { "orQ", Ev, Iv, XX },
1177 { "adcQ", Ev, Iv, XX },
1178 { "sbbQ", Ev, Iv, XX },
1179 { "andQ", Ev, Iv, XX },
1180 { "subQ", Ev, Iv, XX },
1181 { "xorQ", Ev, Iv, XX },
1182 { "cmpQ", Ev, Iv, XX }
1183 },
1184 /* GRP1Ss */
1185 {
1186 { "addQ", Ev, sIb, XX },
1187 { "orQ", Ev, sIb, XX },
1188 { "adcQ", Ev, sIb, XX },
1189 { "sbbQ", Ev, sIb, XX },
1190 { "andQ", Ev, sIb, XX },
1191 { "subQ", Ev, sIb, XX },
1192 { "xorQ", Ev, sIb, XX },
1193 { "cmpQ", Ev, sIb, XX }
1194 },
1195 /* GRP2b */
1196 {
1197 { "rolA", Eb, Ib, XX },
1198 { "rorA", Eb, Ib, XX },
1199 { "rclA", Eb, Ib, XX },
1200 { "rcrA", Eb, Ib, XX },
1201 { "shlA", Eb, Ib, XX },
1202 { "shrA", Eb, Ib, XX },
1203 { "(bad)", XX, XX, XX },
1204 { "sarA", Eb, Ib, XX },
1205 },
1206 /* GRP2S */
1207 {
1208 { "rolQ", Ev, Ib, XX },
1209 { "rorQ", Ev, Ib, XX },
1210 { "rclQ", Ev, Ib, XX },
1211 { "rcrQ", Ev, Ib, XX },
1212 { "shlQ", Ev, Ib, XX },
1213 { "shrQ", Ev, Ib, XX },
1214 { "(bad)", XX, XX, XX },
1215 { "sarQ", Ev, Ib, XX },
1216 },
1217 /* GRP2b_one */
1218 {
1219 { "rolA", Eb, XX, XX },
1220 { "rorA", Eb, XX, XX },
1221 { "rclA", Eb, XX, XX },
1222 { "rcrA", Eb, XX, XX },
1223 { "shlA", Eb, XX, XX },
1224 { "shrA", Eb, XX, XX },
1225 { "(bad)", XX, XX, XX },
1226 { "sarA", Eb, XX, XX },
1227 },
1228 /* GRP2S_one */
1229 {
1230 { "rolQ", Ev, XX, XX },
1231 { "rorQ", Ev, XX, XX },
1232 { "rclQ", Ev, XX, XX },
1233 { "rcrQ", Ev, XX, XX },
1234 { "shlQ", Ev, XX, XX },
1235 { "shrQ", Ev, XX, XX },
1236 { "(bad)", XX, XX, XX},
1237 { "sarQ", Ev, XX, XX },
1238 },
1239 /* GRP2b_cl */
1240 {
1241 { "rolA", Eb, CL, XX },
1242 { "rorA", Eb, CL, XX },
1243 { "rclA", Eb, CL, XX },
1244 { "rcrA", Eb, CL, XX },
1245 { "shlA", Eb, CL, XX },
1246 { "shrA", Eb, CL, XX },
1247 { "(bad)", XX, XX, XX },
1248 { "sarA", Eb, CL, XX },
1249 },
1250 /* GRP2S_cl */
1251 {
1252 { "rolQ", Ev, CL, XX },
1253 { "rorQ", Ev, CL, XX },
1254 { "rclQ", Ev, CL, XX },
1255 { "rcrQ", Ev, CL, XX },
1256 { "shlQ", Ev, CL, XX },
1257 { "shrQ", Ev, CL, XX },
1258 { "(bad)", XX, XX, XX },
1259 { "sarQ", Ev, CL, XX }
1260 },
1261 /* GRP3b */
1262 {
1263 { "testA", Eb, Ib, XX },
1264 { "(bad)", Eb, XX, XX },
1265 { "notA", Eb, XX, XX },
1266 { "negA", Eb, XX, XX },
1267 { "mulB", AL, Eb, XX },
1268 { "imulB", AL, Eb, XX },
1269 { "divB", AL, Eb, XX },
1270 { "idivB", AL, Eb, XX }
1271 },
1272 /* GRP3S */
1273 {
1274 { "testQ", Ev, Iv, XX },
1275 { "(bad)", XX, XX, XX },
1276 { "notQ", Ev, XX, XX },
1277 { "negQ", Ev, XX, XX },
1278 { "mulS", eAX, Ev, XX },
1279 { "imulS", eAX, Ev, XX },
1280 { "divS", eAX, Ev, XX },
1281 { "idivS", eAX, Ev, XX },
1282 },
1283 /* GRP4 */
1284 {
1285 { "incA", Eb, XX, XX },
1286 { "decA", Eb, XX, XX },
1287 { "(bad)", XX, XX, XX },
1288 { "(bad)", XX, XX, XX },
1289 { "(bad)", XX, XX, XX },
1290 { "(bad)", XX, XX, XX },
1291 { "(bad)", XX, XX, XX },
1292 { "(bad)", XX, XX, XX },
1293 },
1294 /* GRP5 */
1295 {
1296 { "incQ", Ev, XX, XX },
1297 { "decQ", Ev, XX, XX },
1298 { "callT", indirEv, XX, XX },
1299 { "lcallT", indirEv, XX, XX },
1300 { "jmpT", indirEv, XX, XX },
1301 { "ljmpT", indirEv, XX, XX },
1302 { "pushU", Ev, XX, XX },
1303 { "(bad)", XX, XX, XX },
1304 },
1305 /* GRP6 */
1306 {
1307 { "sldt", Ew, XX, XX },
1308 { "str", Ew, XX, XX },
1309 { "lldt", Ew, XX, XX },
1310 { "ltr", Ew, XX, XX },
1311 { "verr", Ew, XX, XX },
1312 { "verw", Ew, XX, XX },
1313 { "(bad)", XX, XX, XX },
1314 { "(bad)", XX, XX, XX }
1315 },
1316 /* GRP7 */
1317 {
1318 { "sgdt", Ew, XX, XX },
1319 { "sidt", Ew, XX, XX },
1320 { "lgdt", Ew, XX, XX },
1321 { "lidt", Ew, XX, XX },
1322 { "smsw", Ew, XX, XX },
1323 { "(bad)", XX, XX, XX },
1324 { "lmsw", Ew, XX, XX },
1325 { "invlpg", Ew, XX, XX },
1326 },
1327 /* GRP8 */
1328 {
1329 { "(bad)", XX, XX, XX },
1330 { "(bad)", XX, XX, XX },
1331 { "(bad)", XX, XX, XX },
1332 { "(bad)", XX, XX, XX },
1333 { "btQ", Ev, Ib, XX },
1334 { "btsQ", Ev, Ib, XX },
1335 { "btrQ", Ev, Ib, XX },
1336 { "btcQ", Ev, Ib, XX },
1337 },
1338 /* GRP9 */
1339 {
1340 { "(bad)", XX, XX, XX },
1341 { "cmpxchg8b", Ev, XX, XX },
1342 { "(bad)", XX, XX, XX },
1343 { "(bad)", XX, XX, XX },
1344 { "(bad)", XX, XX, XX },
1345 { "(bad)", XX, XX, XX },
1346 { "(bad)", XX, XX, XX },
1347 { "(bad)", XX, XX, XX },
1348 },
1349 /* GRP10 */
1350 {
1351 { "(bad)", XX, XX, XX },
1352 { "(bad)", XX, XX, XX },
1353 { "psrlw", MS, Ib, XX },
1354 { "(bad)", XX, XX, XX },
1355 { "psraw", MS, Ib, XX },
1356 { "(bad)", XX, XX, XX },
1357 { "psllw", MS, Ib, XX },
1358 { "(bad)", XX, XX, XX },
1359 },
1360 /* GRP11 */
1361 {
1362 { "(bad)", XX, XX, XX },
1363 { "(bad)", XX, XX, XX },
1364 { "psrld", MS, Ib, XX },
1365 { "(bad)", XX, XX, XX },
1366 { "psrad", MS, Ib, XX },
1367 { "(bad)", XX, XX, XX },
1368 { "pslld", MS, Ib, XX },
1369 { "(bad)", XX, XX, XX },
1370 },
1371 /* GRP12 */
1372 {
1373 { "(bad)", XX, XX, XX },
1374 { "(bad)", XX, XX, XX },
1375 { "psrlq", MS, Ib, XX },
1376 { "psrldq", MS, Ib, XX },
1377 { "(bad)", XX, XX, XX },
1378 { "(bad)", XX, XX, XX },
1379 { "psllq", MS, Ib, XX },
1380 { "pslldq", MS, Ib, XX },
1381 },
1382 /* GRP13 */
1383 {
1384 { "fxsave", Ev, XX, XX },
1385 { "fxrstor", Ev, XX, XX },
1386 { "ldmxcsr", Ev, XX, XX },
1387 { "stmxcsr", Ev, XX, XX },
1388 { "(bad)", XX, XX, XX },
1389 { "lfence", None, XX, XX },
1390 { "mfence", None, XX, XX },
1391 { "sfence", None, XX, XX },
1392 /* FIXME: the sfence with memory operand is clflush! */
1393 },
1394 /* GRP14 */
1395 {
1396 { "prefetchnta", Ev, XX, XX },
1397 { "prefetcht0", Ev, XX, XX },
1398 { "prefetcht1", Ev, XX, XX },
1399 { "prefetcht2", Ev, XX, XX },
1400 { "(bad)", XX, XX, XX },
1401 { "(bad)", XX, XX, XX },
1402 { "(bad)", XX, XX, XX },
1403 { "(bad)", XX, XX, XX },
1404 },
1405 /* GRPAMD */
1406 {
1407 { "prefetch", Eb, XX, XX },
1408 { "prefetchw", Eb, XX, XX },
1409 { "(bad)", XX, XX, XX },
1410 { "(bad)", XX, XX, XX },
1411 { "(bad)", XX, XX, XX },
1412 { "(bad)", XX, XX, XX },
1413 { "(bad)", XX, XX, XX },
1414 { "(bad)", XX, XX, XX },
1415 }
1416
1417 };
1418
1419 static const struct dis386 prefix_user_table[][4] = {
1420 /* PREGRP0 */
1421 {
1422 { "addps", XM, EX, XX },
1423 { "addss", XM, EX, XX },
1424 { "addpd", XM, EX, XX },
1425 { "addsd", XM, EX, XX },
1426 },
1427 /* PREGRP1 */
1428 {
1429 { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX */
1430 { "", XM, EX, OPSIMD },
1431 { "", XM, EX, OPSIMD },
1432 { "", XM, EX, OPSIMD },
1433 },
1434 /* PREGRP2 */
1435 {
1436 { "cvtpi2ps", XM, EM, XX },
1437 { "cvtsi2ssY", XM, Ev, XX },
1438 { "cvtpi2pd", XM, EM, XX },
1439 { "cvtsi2sdY", XM, Ev, XX },
1440 },
1441 /* PREGRP3 */
1442 {
1443 { "cvtps2pi", MX, EX, XX },
1444 { "cvtss2siY", Gv, EX, XX },
1445 { "cvtpd2pi", MX, EX, XX },
1446 { "cvtsd2siY", Gv, EX, XX },
1447 },
1448 /* PREGRP4 */
1449 {
1450 { "cvttps2pi", MX, EX, XX },
1451 { "cvttss2siY", Gv, EX, XX },
1452 { "cvttpd2pi", MX, EX, XX },
1453 { "cvttsd2siY", Gv, EX, XX },
1454 },
1455 /* PREGRP5 */
1456 {
1457 { "divps", XM, EX, XX },
1458 { "divss", XM, EX, XX },
1459 { "divpd", XM, EX, XX },
1460 { "divsd", XM, EX, XX },
1461 },
1462 /* PREGRP6 */
1463 {
1464 { "maxps", XM, EX, XX },
1465 { "maxss", XM, EX, XX },
1466 { "maxpd", XM, EX, XX },
1467 { "maxsd", XM, EX, XX },
1468 },
1469 /* PREGRP7 */
1470 {
1471 { "minps", XM, EX, XX },
1472 { "minss", XM, EX, XX },
1473 { "minpd", XM, EX, XX },
1474 { "minsd", XM, EX, XX },
1475 },
1476 /* PREGRP8 */
1477 {
1478 { "movups", XM, EX, XX },
1479 { "movss", XM, EX, XX },
1480 { "movupd", XM, EX, XX },
1481 { "movsd", XM, EX, XX },
1482 },
1483 /* PREGRP9 */
1484 {
1485 { "movups", EX, XM, XX },
1486 { "movss", EX, XM, XX },
1487 { "movupd", EX, XM, XX },
1488 { "movsd", EX, XM, XX },
1489 },
1490 /* PREGRP10 */
1491 {
1492 { "mulps", XM, EX, XX },
1493 { "mulss", XM, EX, XX },
1494 { "mulpd", XM, EX, XX },
1495 { "mulsd", XM, EX, XX },
1496 },
1497 /* PREGRP11 */
1498 {
1499 { "rcpps", XM, EX, XX },
1500 { "rcpss", XM, EX, XX },
1501 { "(bad)", XM, EX, XX },
1502 { "(bad)", XM, EX, XX },
1503 },
1504 /* PREGRP12 */
1505 {
1506 { "rsqrtps", XM, EX, XX },
1507 { "rsqrtss", XM, EX, XX },
1508 { "(bad)", XM, EX, XX },
1509 { "(bad)", XM, EX, XX },
1510 },
1511 /* PREGRP13 */
1512 {
1513 { "sqrtps", XM, EX, XX },
1514 { "sqrtss", XM, EX, XX },
1515 { "sqrtpd", XM, EX, XX },
1516 { "sqrtsd", XM, EX, XX },
1517 },
1518 /* PREGRP14 */
1519 {
1520 { "subps", XM, EX, XX },
1521 { "subss", XM, EX, XX },
1522 { "subpd", XM, EX, XX },
1523 { "subsd", XM, EX, XX },
1524 },
1525 /* PREGRP15 */
1526 {
1527 { "(bad)", XM, EX, XX },
1528 { "cvtdq2pd", XM, EX, XX },
1529 { "cvttpd2dq", XM, EX, XX },
1530 { "cvtpd2dq", XM, EX, XX },
1531 },
1532 /* PREGRP16 */
1533 {
1534 { "cvtdq2ps", XM, EX, XX },
1535 { "cvttps2dq",XM, EX, XX },
1536 { "cvtps2dq",XM, EX, XX },
1537 { "(bad)", XM, EX, XX },
1538 },
1539 /* PREGRP17 */
1540 {
1541 { "cvtps2pd", XM, EX, XX },
1542 { "cvtss2sd", XM, EX, XX },
1543 { "cvtpd2ps", XM, EX, XX },
1544 { "cvtsd2ss", XM, EX, XX },
1545 },
1546 /* PREGRP18 */
1547 {
1548 { "maskmovq", MX, MS, XX },
1549 { "(bad)", XM, EX, XX },
1550 { "maskmovdqu", XM, EX, XX },
1551 { "(bad)", XM, EX, XX },
1552 },
1553 /* PREGRP19 */
1554 {
1555 { "movq", MX, EM, XX },
1556 { "movdqu", XM, EX, XX },
1557 { "movdqa", XM, EX, XX },
1558 { "(bad)", XM, EX, XX },
1559 },
1560 /* PREGRP20 */
1561 {
1562 { "movq", EM, MX, XX },
1563 { "movdqu", EX, XM, XX },
1564 { "movdqa", EX, XM, XX },
1565 { "(bad)", EX, XM, XX },
1566 },
1567 /* PREGRP21 */
1568 {
1569 { "(bad)", EX, XM, XX },
1570 { "movq2dq", XM, MS, XX },
1571 { "movq", EX, XM, XX },
1572 { "movdq2q", MX, XS, XX },
1573 },
1574 /* PREGRP22 */
1575 {
1576 { "pshufw", MX, EM, Ib },
1577 { "pshufhw", XM, EX, Ib },
1578 { "pshufd", XM, EX, Ib },
1579 { "pshuflw", XM, EX, Ib },
1580 },
1581 /* PREGRP23 */
1582 {
1583 { "movd", Ed, MX, XX },
1584 { "movq", XM, EX, XX },
1585 { "movd", Ed, XM, XX },
1586 { "(bad)", Ed, XM, XX },
1587 },
1588 /* PREGRP24 */
1589 {
1590 { "(bad)", MX, EX, XX },
1591 { "(bad)", XM, EX, XX },
1592 { "punpckhqdq", XM, EX, XX },
1593 { "(bad)", XM, EX, XX },
1594 },
1595 /* PREGRP25 */
1596 {
1597 { "movntq", Ev, MX, XX },
1598 { "(bad)", Ev, XM, XX },
1599 { "movntdq", Ev, XM, XX },
1600 { "(bad)", Ev, XM, XX },
1601 },
1602 /* PREGRP26 */
1603 {
1604 { "(bad)", MX, EX, XX },
1605 { "(bad)", XM, EX, XX },
1606 { "punpcklqdq", XM, EX, XX },
1607 { "(bad)", XM, EX, XX },
1608 },
1609 };
1610
1611 static const struct dis386 x86_64_table[][2] = {
1612 {
1613 { "arpl", Ew, Gw, XX },
1614 { "movs{||lq|xd}", Gv, Ed, XX },
1615 },
1616 };
1617
1618 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1619
1620 static void
1621 ckprefix ()
1622 {
1623 int newrex;
1624 rex = 0;
1625 prefixes = 0;
1626 used_prefixes = 0;
1627 rex_used = 0;
1628 while (1)
1629 {
1630 FETCH_DATA (the_info, codep + 1);
1631 newrex = 0;
1632 switch (*codep)
1633 {
1634 /* REX prefixes family. */
1635 case 0x40:
1636 case 0x41:
1637 case 0x42:
1638 case 0x43:
1639 case 0x44:
1640 case 0x45:
1641 case 0x46:
1642 case 0x47:
1643 case 0x48:
1644 case 0x49:
1645 case 0x4a:
1646 case 0x4b:
1647 case 0x4c:
1648 case 0x4d:
1649 case 0x4e:
1650 case 0x4f:
1651 if (mode_64bit)
1652 newrex = *codep;
1653 else
1654 return;
1655 break;
1656 case 0xf3:
1657 prefixes |= PREFIX_REPZ;
1658 break;
1659 case 0xf2:
1660 prefixes |= PREFIX_REPNZ;
1661 break;
1662 case 0xf0:
1663 prefixes |= PREFIX_LOCK;
1664 break;
1665 case 0x2e:
1666 prefixes |= PREFIX_CS;
1667 break;
1668 case 0x36:
1669 prefixes |= PREFIX_SS;
1670 break;
1671 case 0x3e:
1672 prefixes |= PREFIX_DS;
1673 break;
1674 case 0x26:
1675 prefixes |= PREFIX_ES;
1676 break;
1677 case 0x64:
1678 prefixes |= PREFIX_FS;
1679 break;
1680 case 0x65:
1681 prefixes |= PREFIX_GS;
1682 break;
1683 case 0x66:
1684 prefixes |= PREFIX_DATA;
1685 break;
1686 case 0x67:
1687 prefixes |= PREFIX_ADDR;
1688 break;
1689 case FWAIT_OPCODE:
1690 /* fwait is really an instruction. If there are prefixes
1691 before the fwait, they belong to the fwait, *not* to the
1692 following instruction. */
1693 if (prefixes)
1694 {
1695 prefixes |= PREFIX_FWAIT;
1696 codep++;
1697 return;
1698 }
1699 prefixes = PREFIX_FWAIT;
1700 break;
1701 default:
1702 return;
1703 }
1704 /* Rex is ignored when followed by another prefix. */
1705 if (rex)
1706 {
1707 oappend (prefix_name (rex, 0));
1708 oappend (" ");
1709 }
1710 rex = newrex;
1711 codep++;
1712 }
1713 }
1714
1715 /* Return the name of the prefix byte PREF, or NULL if PREF is not a
1716 prefix byte. */
1717
1718 static const char *
1719 prefix_name (pref, sizeflag)
1720 int pref;
1721 int sizeflag;
1722 {
1723 switch (pref)
1724 {
1725 /* REX prefixes family. */
1726 case 0x40:
1727 return "rex";
1728 case 0x41:
1729 return "rexZ";
1730 case 0x42:
1731 return "rexY";
1732 case 0x43:
1733 return "rexYZ";
1734 case 0x44:
1735 return "rexX";
1736 case 0x45:
1737 return "rexXZ";
1738 case 0x46:
1739 return "rexXY";
1740 case 0x47:
1741 return "rexXYZ";
1742 case 0x48:
1743 return "rex64";
1744 case 0x49:
1745 return "rex64Z";
1746 case 0x4a:
1747 return "rex64Y";
1748 case 0x4b:
1749 return "rex64YZ";
1750 case 0x4c:
1751 return "rex64X";
1752 case 0x4d:
1753 return "rex64XZ";
1754 case 0x4e:
1755 return "rex64XY";
1756 case 0x4f:
1757 return "rex64XYZ";
1758 case 0xf3:
1759 return "repz";
1760 case 0xf2:
1761 return "repnz";
1762 case 0xf0:
1763 return "lock";
1764 case 0x2e:
1765 return "cs";
1766 case 0x36:
1767 return "ss";
1768 case 0x3e:
1769 return "ds";
1770 case 0x26:
1771 return "es";
1772 case 0x64:
1773 return "fs";
1774 case 0x65:
1775 return "gs";
1776 case 0x66:
1777 return (sizeflag & DFLAG) ? "data16" : "data32";
1778 case 0x67:
1779 return (sizeflag & AFLAG) ? "addr16" : "addr32";
1780 case FWAIT_OPCODE:
1781 return "fwait";
1782 default:
1783 return NULL;
1784 }
1785 }
1786
1787 static char op1out[100], op2out[100], op3out[100];
1788 static int op_ad, op_index[3];
1789 static unsigned int op_address[3];
1790 static unsigned int op_riprel[3];
1791 static bfd_vma start_pc;
1792
1793 \f
1794 /*
1795 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1796 * (see topic "Redundant prefixes" in the "Differences from 8086"
1797 * section of the "Virtual 8086 Mode" chapter.)
1798 * 'pc' should be the address of this instruction, it will
1799 * be used to print the target address if this is a relative jump or call
1800 * The function returns the length of this instruction in bytes.
1801 */
1802
1803 static char intel_syntax;
1804 static char open_char;
1805 static char close_char;
1806 static char separator_char;
1807 static char scale_char;
1808
1809 int
1810 print_insn_i386_att (pc, info)
1811 bfd_vma pc;
1812 disassemble_info *info;
1813 {
1814 intel_syntax = 0;
1815 open_char = '(';
1816 close_char = ')';
1817 separator_char = ',';
1818 scale_char = ',';
1819
1820 return print_insn_i386 (pc, info);
1821 }
1822
1823 int
1824 print_insn_i386_intel (pc, info)
1825 bfd_vma pc;
1826 disassemble_info *info;
1827 {
1828 intel_syntax = 1;
1829 open_char = '[';
1830 close_char = ']';
1831 separator_char = '+';
1832 scale_char = '*';
1833
1834 return print_insn_i386 (pc, info);
1835 }
1836
1837 static int
1838 print_insn_i386 (pc, info)
1839 bfd_vma pc;
1840 disassemble_info *info;
1841 {
1842 const struct dis386 *dp;
1843 int i;
1844 int two_source_ops;
1845 char *first, *second, *third;
1846 int needcomma;
1847 unsigned char uses_SSE_prefix;
1848 VOLATILE int sizeflag;
1849 VOLATILE int orig_sizeflag;
1850
1851 struct dis_private priv;
1852 bfd_byte *inbuf = priv.the_buffer;
1853
1854 mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
1855 || info->mach == bfd_mach_x86_64);
1856
1857 if (info->mach == bfd_mach_i386_i386
1858 || info->mach == bfd_mach_x86_64
1859 || info->mach == bfd_mach_i386_i386_intel_syntax
1860 || info->mach == bfd_mach_x86_64_intel_syntax)
1861 sizeflag = AFLAG|DFLAG;
1862 else if (info->mach == bfd_mach_i386_i8086)
1863 sizeflag = 0;
1864 else
1865 abort ();
1866 orig_sizeflag = sizeflag;
1867
1868 /* The output looks better if we put 7 bytes on a line, since that
1869 puts most long word instructions on a single line. */
1870 info->bytes_per_line = 7;
1871
1872 info->private_data = (PTR) &priv;
1873 priv.max_fetched = priv.the_buffer;
1874 priv.insn_start = pc;
1875
1876 obuf[0] = 0;
1877 op1out[0] = 0;
1878 op2out[0] = 0;
1879 op3out[0] = 0;
1880
1881 op_index[0] = op_index[1] = op_index[2] = -1;
1882
1883 the_info = info;
1884 start_pc = pc;
1885 start_codep = inbuf;
1886 codep = inbuf;
1887
1888 if (setjmp (priv.bailout) != 0)
1889 {
1890 const char *name;
1891
1892 /* Getting here means we tried for data but didn't get it. That
1893 means we have an incomplete instruction of some sort. Just
1894 print the first byte as a prefix or a .byte pseudo-op. */
1895 if (codep > inbuf)
1896 {
1897 name = prefix_name (inbuf[0], orig_sizeflag);
1898 if (name != NULL)
1899 (*info->fprintf_func) (info->stream, "%s", name);
1900 else
1901 {
1902 /* Just print the first byte as a .byte instruction. */
1903 (*info->fprintf_func) (info->stream, ".byte 0x%x",
1904 (unsigned int) inbuf[0]);
1905 }
1906
1907 return 1;
1908 }
1909
1910 return -1;
1911 }
1912
1913 obufp = obuf;
1914 ckprefix ();
1915
1916 insn_codep = codep;
1917
1918 FETCH_DATA (info, codep + 1);
1919 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
1920
1921 if ((prefixes & PREFIX_FWAIT)
1922 && ((*codep < 0xd8) || (*codep > 0xdf)))
1923 {
1924 const char *name;
1925
1926 /* fwait not followed by floating point instruction. Print the
1927 first prefix, which is probably fwait itself. */
1928 name = prefix_name (inbuf[0], orig_sizeflag);
1929 if (name == NULL)
1930 name = INTERNAL_DISASSEMBLER_ERROR;
1931 (*info->fprintf_func) (info->stream, "%s", name);
1932 return 1;
1933 }
1934
1935 if (*codep == 0x0f)
1936 {
1937 FETCH_DATA (info, codep + 2);
1938 dp = &dis386_twobyte[*++codep];
1939 need_modrm = twobyte_has_modrm[*codep];
1940 uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
1941 }
1942 else
1943 {
1944 dp = &dis386[*codep];
1945 need_modrm = onebyte_has_modrm[*codep];
1946 uses_SSE_prefix = 0;
1947 }
1948 codep++;
1949
1950 if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
1951 {
1952 oappend ("repz ");
1953 used_prefixes |= PREFIX_REPZ;
1954 }
1955 if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
1956 {
1957 oappend ("repnz ");
1958 used_prefixes |= PREFIX_REPNZ;
1959 }
1960 if (prefixes & PREFIX_LOCK)
1961 {
1962 oappend ("lock ");
1963 used_prefixes |= PREFIX_LOCK;
1964 }
1965
1966 if (prefixes & PREFIX_ADDR)
1967 {
1968 sizeflag ^= AFLAG;
1969 if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
1970 {
1971 if (sizeflag & AFLAG)
1972 oappend ("addr32 ");
1973 else
1974 oappend ("addr16 ");
1975 used_prefixes |= PREFIX_ADDR;
1976 }
1977 }
1978
1979 if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
1980 {
1981 sizeflag ^= DFLAG;
1982 if (dp->bytemode3 == cond_jump_mode
1983 && dp->bytemode1 == v_mode
1984 && !intel_syntax)
1985 {
1986 if (sizeflag & DFLAG)
1987 oappend ("data32 ");
1988 else
1989 oappend ("data16 ");
1990 used_prefixes |= PREFIX_DATA;
1991 }
1992 }
1993
1994 if (need_modrm)
1995 {
1996 FETCH_DATA (info, codep + 1);
1997 mod = (*codep >> 6) & 3;
1998 reg = (*codep >> 3) & 7;
1999 rm = *codep & 7;
2000 }
2001
2002 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2003 {
2004 dofloat (sizeflag);
2005 }
2006 else
2007 {
2008 int index;
2009 if (dp->name == NULL)
2010 {
2011 switch (dp->bytemode1)
2012 {
2013 case USE_GROUPS:
2014 dp = &grps[dp->bytemode2][reg];
2015 break;
2016
2017 case USE_PREFIX_USER_TABLE:
2018 index = 0;
2019 used_prefixes |= (prefixes & PREFIX_REPZ);
2020 if (prefixes & PREFIX_REPZ)
2021 index = 1;
2022 else
2023 {
2024 used_prefixes |= (prefixes & PREFIX_DATA);
2025 if (prefixes & PREFIX_DATA)
2026 index = 2;
2027 else
2028 {
2029 used_prefixes |= (prefixes & PREFIX_REPNZ);
2030 if (prefixes & PREFIX_REPNZ)
2031 index = 3;
2032 }
2033 }
2034 dp = &prefix_user_table[dp->bytemode2][index];
2035 break;
2036
2037 case X86_64_SPECIAL:
2038 dp = &x86_64_table[dp->bytemode2][mode_64bit];
2039 break;
2040
2041 default:
2042 oappend (INTERNAL_DISASSEMBLER_ERROR);
2043 break;
2044 }
2045 }
2046
2047 if (putop (dp->name, sizeflag) == 0)
2048 {
2049 obufp = op1out;
2050 op_ad = 2;
2051 if (dp->op1)
2052 (*dp->op1)(dp->bytemode1, sizeflag);
2053
2054 obufp = op2out;
2055 op_ad = 1;
2056 if (dp->op2)
2057 (*dp->op2)(dp->bytemode2, sizeflag);
2058
2059 obufp = op3out;
2060 op_ad = 0;
2061 if (dp->op3)
2062 (*dp->op3)(dp->bytemode3, sizeflag);
2063 }
2064 }
2065
2066 /* See if any prefixes were not used. If so, print the first one
2067 separately. If we don't do this, we'll wind up printing an
2068 instruction stream which does not precisely correspond to the
2069 bytes we are disassembling. */
2070 if ((prefixes & ~used_prefixes) != 0)
2071 {
2072 const char *name;
2073
2074 name = prefix_name (inbuf[0], orig_sizeflag);
2075 if (name == NULL)
2076 name = INTERNAL_DISASSEMBLER_ERROR;
2077 (*info->fprintf_func) (info->stream, "%s", name);
2078 return 1;
2079 }
2080 if (rex & ~rex_used)
2081 {
2082 const char *name;
2083 name = prefix_name (rex | 0x40, orig_sizeflag);
2084 if (name == NULL)
2085 name = INTERNAL_DISASSEMBLER_ERROR;
2086 (*info->fprintf_func) (info->stream, "%s ", name);
2087 }
2088
2089 obufp = obuf + strlen (obuf);
2090 for (i = strlen (obuf); i < 6; i++)
2091 oappend (" ");
2092 oappend (" ");
2093 (*info->fprintf_func) (info->stream, "%s", obuf);
2094
2095 /* The enter and bound instructions are printed with operands in the same
2096 order as the intel book; everything else is printed in reverse order. */
2097 if (intel_syntax || two_source_ops)
2098 {
2099 first = op1out;
2100 second = op2out;
2101 third = op3out;
2102 op_ad = op_index[0];
2103 op_index[0] = op_index[2];
2104 op_index[2] = op_ad;
2105 }
2106 else
2107 {
2108 first = op3out;
2109 second = op2out;
2110 third = op1out;
2111 }
2112 needcomma = 0;
2113 if (*first)
2114 {
2115 if (op_index[0] != -1 && !op_riprel[0])
2116 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
2117 else
2118 (*info->fprintf_func) (info->stream, "%s", first);
2119 needcomma = 1;
2120 }
2121 if (*second)
2122 {
2123 if (needcomma)
2124 (*info->fprintf_func) (info->stream, ",");
2125 if (op_index[1] != -1 && !op_riprel[1])
2126 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
2127 else
2128 (*info->fprintf_func) (info->stream, "%s", second);
2129 needcomma = 1;
2130 }
2131 if (*third)
2132 {
2133 if (needcomma)
2134 (*info->fprintf_func) (info->stream, ",");
2135 if (op_index[2] != -1 && !op_riprel[2])
2136 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
2137 else
2138 (*info->fprintf_func) (info->stream, "%s", third);
2139 }
2140 for (i = 0; i < 3; i++)
2141 if (op_index[i] != -1 && op_riprel[i])
2142 {
2143 (*info->fprintf_func) (info->stream, " # ");
2144 (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
2145 + op_address[op_index[i]]), info);
2146 }
2147 return codep - inbuf;
2148 }
2149
2150 static const char *float_mem[] = {
2151 /* d8 */
2152 "fadd{s||s|}",
2153 "fmul{s||s|}",
2154 "fcom{s||s|}",
2155 "fcomp{s||s|}",
2156 "fsub{s||s|}",
2157 "fsubr{s||s|}",
2158 "fdiv{s||s|}",
2159 "fdivr{s||s|}",
2160 /* d9 */
2161 "fld{s||s|}",
2162 "(bad)",
2163 "fst{s||s|}",
2164 "fstp{s||s|}",
2165 "fldenv",
2166 "fldcw",
2167 "fNstenv",
2168 "fNstcw",
2169 /* da */
2170 "fiadd{l||l|}",
2171 "fimul{l||l|}",
2172 "ficom{l||l|}",
2173 "ficomp{l||l|}",
2174 "fisub{l||l|}",
2175 "fisubr{l||l|}",
2176 "fidiv{l||l|}",
2177 "fidivr{l||l|}",
2178 /* db */
2179 "fild{l||l|}",
2180 "(bad)",
2181 "fist{l||l|}",
2182 "fistp{l||l|}",
2183 "(bad)",
2184 "fld{t||t|}",
2185 "(bad)",
2186 "fstp{t||t|}",
2187 /* dc */
2188 "fadd{l||l|}",
2189 "fmul{l||l|}",
2190 "fcom{l||l|}",
2191 "fcomp{l||l|}",
2192 "fsub{l||l|}",
2193 "fsubr{l||l|}",
2194 "fdiv{l||l|}",
2195 "fdivr{l||l|}",
2196 /* dd */
2197 "fld{l||l|}",
2198 "(bad)",
2199 "fst{l||l|}",
2200 "fstp{l||l|}",
2201 "frstor",
2202 "(bad)",
2203 "fNsave",
2204 "fNstsw",
2205 /* de */
2206 "fiadd",
2207 "fimul",
2208 "ficom",
2209 "ficomp",
2210 "fisub",
2211 "fisubr",
2212 "fidiv",
2213 "fidivr",
2214 /* df */
2215 "fild",
2216 "(bad)",
2217 "fist",
2218 "fistp",
2219 "fbld",
2220 "fild{ll||ll|}",
2221 "fbstp",
2222 "fistpll",
2223 };
2224
2225 #define ST OP_ST, 0
2226 #define STi OP_STi, 0
2227
2228 #define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
2229 #define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
2230 #define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
2231 #define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
2232 #define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
2233 #define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
2234 #define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
2235 #define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
2236 #define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
2237
2238 static const struct dis386 float_reg[][8] = {
2239 /* d8 */
2240 {
2241 { "fadd", ST, STi, XX },
2242 { "fmul", ST, STi, XX },
2243 { "fcom", STi, XX, XX },
2244 { "fcomp", STi, XX, XX },
2245 { "fsub", ST, STi, XX },
2246 { "fsubr", ST, STi, XX },
2247 { "fdiv", ST, STi, XX },
2248 { "fdivr", ST, STi, XX },
2249 },
2250 /* d9 */
2251 {
2252 { "fld", STi, XX, XX },
2253 { "fxch", STi, XX, XX },
2254 { FGRPd9_2 },
2255 { "(bad)", XX, XX, XX },
2256 { FGRPd9_4 },
2257 { FGRPd9_5 },
2258 { FGRPd9_6 },
2259 { FGRPd9_7 },
2260 },
2261 /* da */
2262 {
2263 { "fcmovb", ST, STi, XX },
2264 { "fcmove", ST, STi, XX },
2265 { "fcmovbe",ST, STi, XX },
2266 { "fcmovu", ST, STi, XX },
2267 { "(bad)", XX, XX, XX },
2268 { FGRPda_5 },
2269 { "(bad)", XX, XX, XX },
2270 { "(bad)", XX, XX, XX },
2271 },
2272 /* db */
2273 {
2274 { "fcmovnb",ST, STi, XX },
2275 { "fcmovne",ST, STi, XX },
2276 { "fcmovnbe",ST, STi, XX },
2277 { "fcmovnu",ST, STi, XX },
2278 { FGRPdb_4 },
2279 { "fucomi", ST, STi, XX },
2280 { "fcomi", ST, STi, XX },
2281 { "(bad)", XX, XX, XX },
2282 },
2283 /* dc */
2284 {
2285 { "fadd", STi, ST, XX },
2286 { "fmul", STi, ST, XX },
2287 { "(bad)", XX, XX, XX },
2288 { "(bad)", XX, XX, XX },
2289 #if UNIXWARE_COMPAT
2290 { "fsub", STi, ST, XX },
2291 { "fsubr", STi, ST, XX },
2292 { "fdiv", STi, ST, XX },
2293 { "fdivr", STi, ST, XX },
2294 #else
2295 { "fsubr", STi, ST, XX },
2296 { "fsub", STi, ST, XX },
2297 { "fdivr", STi, ST, XX },
2298 { "fdiv", STi, ST, XX },
2299 #endif
2300 },
2301 /* dd */
2302 {
2303 { "ffree", STi, XX, XX },
2304 { "(bad)", XX, XX, XX },
2305 { "fst", STi, XX, XX },
2306 { "fstp", STi, XX, XX },
2307 { "fucom", STi, XX, XX },
2308 { "fucomp", STi, XX, XX },
2309 { "(bad)", XX, XX, XX },
2310 { "(bad)", XX, XX, XX },
2311 },
2312 /* de */
2313 {
2314 { "faddp", STi, ST, XX },
2315 { "fmulp", STi, ST, XX },
2316 { "(bad)", XX, XX, XX },
2317 { FGRPde_3 },
2318 #if UNIXWARE_COMPAT
2319 { "fsubp", STi, ST, XX },
2320 { "fsubrp", STi, ST, XX },
2321 { "fdivp", STi, ST, XX },
2322 { "fdivrp", STi, ST, XX },
2323 #else
2324 { "fsubrp", STi, ST, XX },
2325 { "fsubp", STi, ST, XX },
2326 { "fdivrp", STi, ST, XX },
2327 { "fdivp", STi, ST, XX },
2328 #endif
2329 },
2330 /* df */
2331 {
2332 { "ffreep", STi, XX, XX },
2333 { "(bad)", XX, XX, XX },
2334 { "(bad)", XX, XX, XX },
2335 { "(bad)", XX, XX, XX },
2336 { FGRPdf_4 },
2337 { "fucomip",ST, STi, XX },
2338 { "fcomip", ST, STi, XX },
2339 { "(bad)", XX, XX, XX },
2340 },
2341 };
2342
2343
2344 static char *fgrps[][8] = {
2345 /* d9_2 0 */
2346 {
2347 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2348 },
2349
2350 /* d9_4 1 */
2351 {
2352 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2353 },
2354
2355 /* d9_5 2 */
2356 {
2357 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2358 },
2359
2360 /* d9_6 3 */
2361 {
2362 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2363 },
2364
2365 /* d9_7 4 */
2366 {
2367 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2368 },
2369
2370 /* da_5 5 */
2371 {
2372 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2373 },
2374
2375 /* db_4 6 */
2376 {
2377 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2378 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2379 },
2380
2381 /* de_3 7 */
2382 {
2383 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2384 },
2385
2386 /* df_4 8 */
2387 {
2388 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2389 },
2390 };
2391
2392 static void
2393 dofloat (sizeflag)
2394 int sizeflag;
2395 {
2396 const struct dis386 *dp;
2397 unsigned char floatop;
2398
2399 floatop = codep[-1];
2400
2401 if (mod != 3)
2402 {
2403 putop (float_mem[(floatop - 0xd8 ) * 8 + reg], sizeflag);
2404 obufp = op1out;
2405 if (floatop == 0xdb)
2406 OP_E (x_mode, sizeflag);
2407 else if (floatop == 0xdd)
2408 OP_E (d_mode, sizeflag);
2409 else
2410 OP_E (v_mode, sizeflag);
2411 return;
2412 }
2413 /* skip mod/rm byte */
2414 MODRM_CHECK;
2415 codep++;
2416
2417 dp = &float_reg[floatop - 0xd8][reg];
2418 if (dp->name == NULL)
2419 {
2420 putop (fgrps[dp->bytemode1][rm], sizeflag);
2421
2422 /* instruction fnstsw is only one with strange arg */
2423 if (floatop == 0xdf && codep[-1] == 0xe0)
2424 strcpy (op1out, names16[0]);
2425 }
2426 else
2427 {
2428 putop (dp->name, sizeflag);
2429
2430 obufp = op1out;
2431 if (dp->op1)
2432 (*dp->op1)(dp->bytemode1, sizeflag);
2433 obufp = op2out;
2434 if (dp->op2)
2435 (*dp->op2)(dp->bytemode2, sizeflag);
2436 }
2437 }
2438
2439 static void
2440 OP_ST (bytemode, sizeflag)
2441 int bytemode ATTRIBUTE_UNUSED;
2442 int sizeflag ATTRIBUTE_UNUSED;
2443 {
2444 oappend ("%st");
2445 }
2446
2447 static void
2448 OP_STi (bytemode, sizeflag)
2449 int bytemode ATTRIBUTE_UNUSED;
2450 int sizeflag ATTRIBUTE_UNUSED;
2451 {
2452 sprintf (scratchbuf, "%%st(%d)", rm);
2453 oappend (scratchbuf);
2454 }
2455
2456 /* capital letters in template are macros */
2457 static int
2458 putop (template, sizeflag)
2459 const char *template;
2460 int sizeflag;
2461 {
2462 const char *p;
2463 int alt;
2464
2465 for (p = template; *p; p++)
2466 {
2467 switch (*p)
2468 {
2469 default:
2470 *obufp++ = *p;
2471 break;
2472 case '{':
2473 alt = 0;
2474 if (intel_syntax)
2475 alt += 1;
2476 if (mode_64bit)
2477 alt += 2;
2478 while (alt != 0)
2479 {
2480 while (*++p != '|')
2481 {
2482 if (*p == '}')
2483 {
2484 /* Alternative not valid. */
2485 strcpy (obuf, "(bad)");
2486 obufp = obuf + 5;
2487 return 1;
2488 }
2489 else if (*p == '\0')
2490 abort ();
2491 }
2492 alt--;
2493 }
2494 break;
2495 case '|':
2496 while (*++p != '}')
2497 {
2498 if (*p == '\0')
2499 abort ();
2500 }
2501 break;
2502 case '}':
2503 break;
2504 case 'A':
2505 if (intel_syntax)
2506 break;
2507 if (mod != 3
2508 #ifdef SUFFIX_ALWAYS
2509 || (sizeflag & SUFFIX_ALWAYS)
2510 #endif
2511 )
2512 *obufp++ = 'b';
2513 break;
2514 case 'B':
2515 if (intel_syntax)
2516 break;
2517 #ifdef SUFFIX_ALWAYS
2518 if (sizeflag & SUFFIX_ALWAYS)
2519 *obufp++ = 'b';
2520 #endif
2521 break;
2522 case 'E': /* For jcxz/jecxz */
2523 if (sizeflag & AFLAG)
2524 *obufp++ = 'e';
2525 used_prefixes |= (prefixes & PREFIX_ADDR);
2526 break;
2527 case 'F':
2528 if (intel_syntax)
2529 break;
2530 if ((prefixes & PREFIX_ADDR)
2531 #ifdef SUFFIX_ALWAYS
2532 || (sizeflag & SUFFIX_ALWAYS)
2533 #endif
2534 )
2535 {
2536 if (sizeflag & AFLAG)
2537 *obufp++ = 'l';
2538 else
2539 *obufp++ = 'w';
2540 used_prefixes |= (prefixes & PREFIX_ADDR);
2541 }
2542 break;
2543 case 'H':
2544 if (intel_syntax)
2545 break;
2546 if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
2547 || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
2548 {
2549 used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
2550 *obufp++ = ',';
2551 *obufp++ = 'p';
2552 if (prefixes & PREFIX_DS)
2553 *obufp++ = 't';
2554 else
2555 *obufp++ = 'n';
2556 }
2557 break;
2558 case 'L':
2559 if (intel_syntax)
2560 break;
2561 #ifdef SUFFIX_ALWAYS
2562 if (sizeflag & SUFFIX_ALWAYS)
2563 *obufp++ = 'l';
2564 #endif
2565 break;
2566 case 'N':
2567 if ((prefixes & PREFIX_FWAIT) == 0)
2568 *obufp++ = 'n';
2569 else
2570 used_prefixes |= PREFIX_FWAIT;
2571 break;
2572 case 'O':
2573 USED_REX (REX_MODE64);
2574 if (rex & REX_MODE64)
2575 *obufp++ = 'o';
2576 else
2577 *obufp++ = 'd';
2578 break;
2579 case 'T':
2580 if (intel_syntax)
2581 break;
2582 if (mode_64bit)
2583 {
2584 *obufp++ = 'q';
2585 break;
2586 }
2587 /* Fall through */
2588 case 'P':
2589 if (intel_syntax)
2590 break;
2591 if ((prefixes & PREFIX_DATA)
2592 || (rex & REX_MODE64)
2593 #ifdef SUFFIX_ALWAYS
2594 || (sizeflag & SUFFIX_ALWAYS)
2595 #endif
2596 )
2597 {
2598 USED_REX (REX_MODE64);
2599 if (rex & REX_MODE64)
2600 *obufp++ = 'q';
2601 else
2602 {
2603 if (sizeflag & DFLAG)
2604 *obufp++ = 'l';
2605 else
2606 *obufp++ = 'w';
2607 used_prefixes |= (prefixes & PREFIX_DATA);
2608 }
2609 }
2610 break;
2611 case 'U':
2612 if (intel_syntax)
2613 break;
2614 if (mode_64bit)
2615 {
2616 *obufp++ = 'q';
2617 break;
2618 }
2619 /* Fall through */
2620 case 'Q':
2621 if (intel_syntax)
2622 break;
2623 USED_REX (REX_MODE64);
2624 if (mod != 3
2625 #ifdef SUFFIX_ALWAYS
2626 || (sizeflag & SUFFIX_ALWAYS)
2627 #endif
2628 )
2629 {
2630 if (rex & REX_MODE64)
2631 *obufp++ = 'q';
2632 else
2633 {
2634 if (sizeflag & DFLAG)
2635 *obufp++ = 'l';
2636 else
2637 *obufp++ = 'w';
2638 used_prefixes |= (prefixes & PREFIX_DATA);
2639 }
2640 }
2641 break;
2642 case 'R':
2643 USED_REX (REX_MODE64);
2644 if (intel_syntax)
2645 {
2646 if (rex & REX_MODE64)
2647 {
2648 *obufp++ = 'q';
2649 *obufp++ = 't';
2650 }
2651 else if (sizeflag & DFLAG)
2652 {
2653 *obufp++ = 'd';
2654 *obufp++ = 'q';
2655 }
2656 else
2657 {
2658 *obufp++ = 'w';
2659 *obufp++ = 'd';
2660 }
2661 }
2662 else
2663 {
2664 if (rex & REX_MODE64)
2665 *obufp++ = 'q';
2666 else if (sizeflag & DFLAG)
2667 *obufp++ = 'l';
2668 else
2669 *obufp++ = 'w';
2670 }
2671 if (!(rex & REX_MODE64))
2672 used_prefixes |= (prefixes & PREFIX_DATA);
2673 break;
2674 case 'S':
2675 if (intel_syntax)
2676 break;
2677 #ifdef SUFFIX_ALWAYS
2678 if (sizeflag & SUFFIX_ALWAYS)
2679 {
2680 if (rex & REX_MODE64)
2681 *obufp++ = 'q';
2682 else
2683 {
2684 if (sizeflag & DFLAG)
2685 *obufp++ = 'l';
2686 else
2687 *obufp++ = 'w';
2688 used_prefixes |= (prefixes & PREFIX_DATA);
2689 }
2690 }
2691 #endif
2692 break;
2693 case 'X':
2694 if (prefixes & PREFIX_DATA)
2695 *obufp++ = 'd';
2696 else
2697 *obufp++ = 's';
2698 used_prefixes |= (prefixes & PREFIX_DATA);
2699 break;
2700 case 'Y':
2701 if (intel_syntax)
2702 break;
2703 if (rex & REX_MODE64)
2704 {
2705 USED_REX (REX_MODE64);
2706 *obufp++ = 'q';
2707 }
2708 break;
2709 /* implicit operand size 'l' for i386 or 'q' for x86-64 */
2710 case 'W':
2711 /* operand size flag for cwtl, cbtw */
2712 USED_REX (0);
2713 if (rex)
2714 *obufp++ = 'l';
2715 else if (sizeflag & DFLAG)
2716 *obufp++ = 'w';
2717 else
2718 *obufp++ = 'b';
2719 if (intel_syntax)
2720 {
2721 if (rex)
2722 {
2723 *obufp++ = 'q';
2724 *obufp++ = 'e';
2725 }
2726 if (sizeflag & DFLAG)
2727 {
2728 *obufp++ = 'd';
2729 *obufp++ = 'e';
2730 }
2731 else
2732 {
2733 *obufp++ = 'w';
2734 }
2735 }
2736 if (!rex)
2737 used_prefixes |= (prefixes & PREFIX_DATA);
2738 break;
2739 }
2740 }
2741 *obufp = 0;
2742 return 0;
2743 }
2744
2745 static void
2746 oappend (s)
2747 const char *s;
2748 {
2749 strcpy (obufp, s);
2750 obufp += strlen (s);
2751 }
2752
2753 static void
2754 append_seg ()
2755 {
2756 if (prefixes & PREFIX_CS)
2757 {
2758 oappend ("%cs:");
2759 used_prefixes |= PREFIX_CS;
2760 }
2761 if (prefixes & PREFIX_DS)
2762 {
2763 oappend ("%ds:");
2764 used_prefixes |= PREFIX_DS;
2765 }
2766 if (prefixes & PREFIX_SS)
2767 {
2768 oappend ("%ss:");
2769 used_prefixes |= PREFIX_SS;
2770 }
2771 if (prefixes & PREFIX_ES)
2772 {
2773 oappend ("%es:");
2774 used_prefixes |= PREFIX_ES;
2775 }
2776 if (prefixes & PREFIX_FS)
2777 {
2778 oappend ("%fs:");
2779 used_prefixes |= PREFIX_FS;
2780 }
2781 if (prefixes & PREFIX_GS)
2782 {
2783 oappend ("%gs:");
2784 used_prefixes |= PREFIX_GS;
2785 }
2786 }
2787
2788 static void
2789 OP_indirE (bytemode, sizeflag)
2790 int bytemode;
2791 int sizeflag;
2792 {
2793 if (!intel_syntax)
2794 oappend ("*");
2795 OP_E (bytemode, sizeflag);
2796 }
2797
2798 static void
2799 print_operand_value (buf, hex, disp)
2800 char *buf;
2801 int hex;
2802 bfd_vma disp;
2803 {
2804 if (mode_64bit)
2805 {
2806 if (hex)
2807 {
2808 char tmp[30];
2809 int i;
2810 buf[0] = '0';
2811 buf[1] = 'x';
2812 sprintf_vma (tmp, disp);
2813 for (i = 0; tmp[i] == '0' && tmp[i+1]; i++);
2814 strcpy (buf + 2, tmp + i);
2815 }
2816 else
2817 {
2818 bfd_signed_vma v = disp;
2819 char tmp[30];
2820 int i;
2821 if (v < 0)
2822 {
2823 *(buf++) = '-';
2824 v = -disp;
2825 /* Check for possible overflow on 0x8000000000000000 */
2826 if (v < 0)
2827 {
2828 strcpy (buf, "9223372036854775808");
2829 return;
2830 }
2831 }
2832 if (!v)
2833 {
2834 strcpy (buf, "0");
2835 return;
2836 }
2837
2838 i = 0;
2839 tmp[29] = 0;
2840 while (v)
2841 {
2842 tmp[28-i] = (v % 10) + '0';
2843 v /= 10;
2844 i++;
2845 }
2846 strcpy (buf, tmp + 29 - i);
2847 }
2848 }
2849 else
2850 {
2851 if (hex)
2852 sprintf (buf, "0x%x", (unsigned int) disp);
2853 else
2854 sprintf (buf, "%d", (int) disp);
2855 }
2856 }
2857
2858 static void
2859 OP_E (bytemode, sizeflag)
2860 int bytemode;
2861 int sizeflag;
2862 {
2863 bfd_vma disp;
2864 int add = 0;
2865 int riprel = 0;
2866 USED_REX (REX_EXTZ);
2867 if (rex & REX_EXTZ)
2868 add += 8;
2869
2870 /* skip mod/rm byte */
2871 MODRM_CHECK;
2872 codep++;
2873
2874 if (mod == 3)
2875 {
2876 switch (bytemode)
2877 {
2878 case b_mode:
2879 USED_REX (0);
2880 if (rex)
2881 oappend (names8rex[rm + add]);
2882 else
2883 oappend (names8[rm + add]);
2884 break;
2885 case w_mode:
2886 oappend (names16[rm + add]);
2887 break;
2888 case d_mode:
2889 oappend (names32[rm + add]);
2890 break;
2891 case q_mode:
2892 oappend (names64[rm + add]);
2893 break;
2894 case m_mode:
2895 if (mode_64bit)
2896 oappend (names64[rm + add]);
2897 else
2898 oappend (names32[rm + add]);
2899 break;
2900 case v_mode:
2901 USED_REX (REX_MODE64);
2902 if (rex & REX_MODE64)
2903 oappend (names64[rm + add]);
2904 else if (sizeflag & DFLAG)
2905 oappend (names32[rm + add]);
2906 else
2907 oappend (names16[rm + add]);
2908 used_prefixes |= (prefixes & PREFIX_DATA);
2909 break;
2910 case 0:
2911 if ( !(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */)
2912 && !(codep[-2] == 0xAE && codep[-1] == 0xF0 /* mfence */)
2913 && !(codep[-2] == 0xAE && codep[-1] == 0xe8 /* lfence */))
2914 BadOp(); /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */
2915 break;
2916 default:
2917 oappend (INTERNAL_DISASSEMBLER_ERROR);
2918 break;
2919 }
2920 return;
2921 }
2922
2923 disp = 0;
2924 append_seg ();
2925
2926 if (sizeflag & AFLAG) /* 32 bit address mode */
2927 {
2928 int havesib;
2929 int havebase;
2930 int base;
2931 int index = 0;
2932 int scale = 0;
2933
2934 havesib = 0;
2935 havebase = 1;
2936 base = rm;
2937
2938 if (base == 4)
2939 {
2940 havesib = 1;
2941 FETCH_DATA (the_info, codep + 1);
2942 scale = (*codep >> 6) & 3;
2943 index = (*codep >> 3) & 7;
2944 base = *codep & 7;
2945 USED_REX (REX_EXTY);
2946 USED_REX (REX_EXTZ);
2947 if (rex & REX_EXTY)
2948 index += 8;
2949 if (rex & REX_EXTZ)
2950 base += 8;
2951 codep++;
2952 }
2953
2954 switch (mod)
2955 {
2956 case 0:
2957 if ((base & 7) == 5)
2958 {
2959 havebase = 0;
2960 if (mode_64bit && !havesib)
2961 riprel = 1;
2962 disp = get32s ();
2963 }
2964 break;
2965 case 1:
2966 FETCH_DATA (the_info, codep + 1);
2967 disp = *codep++;
2968 if ((disp & 0x80) != 0)
2969 disp -= 0x100;
2970 break;
2971 case 2:
2972 disp = get32s ();
2973 break;
2974 }
2975
2976 if (!intel_syntax)
2977 if (mod != 0 || (base & 7) == 5)
2978 {
2979 print_operand_value (scratchbuf, !riprel, disp);
2980 oappend (scratchbuf);
2981 if (riprel)
2982 {
2983 set_op (disp, 1);
2984 oappend ("(%rip)");
2985 }
2986 }
2987
2988 if (havebase || (havesib && (index != 4 || scale != 0)))
2989 {
2990 if (intel_syntax)
2991 {
2992 switch (bytemode)
2993 {
2994 case b_mode:
2995 oappend ("BYTE PTR ");
2996 break;
2997 case w_mode:
2998 oappend ("WORD PTR ");
2999 break;
3000 case v_mode:
3001 oappend ("DWORD PTR ");
3002 break;
3003 case d_mode:
3004 oappend ("QWORD PTR ");
3005 break;
3006 case m_mode:
3007 if (mode_64bit)
3008 oappend ("DWORD PTR ");
3009 else
3010 oappend ("QWORD PTR ");
3011 break;
3012 case x_mode:
3013 oappend ("XWORD PTR ");
3014 break;
3015 default:
3016 break;
3017 }
3018 }
3019 *obufp++ = open_char;
3020 if (intel_syntax && riprel)
3021 oappend ("rip + ");
3022 *obufp = '\0';
3023 USED_REX (REX_EXTZ);
3024 if (!havesib && (rex & REX_EXTZ))
3025 base += 8;
3026 if (havebase)
3027 oappend (mode_64bit ? names64[base] : names32[base]);
3028 if (havesib)
3029 {
3030 if (index != 4)
3031 {
3032 if (intel_syntax)
3033 {
3034 if (havebase)
3035 {
3036 *obufp++ = separator_char;
3037 *obufp = '\0';
3038 }
3039 sprintf (scratchbuf, "%s", mode_64bit ? names64[index] : names32[index]);
3040 }
3041 else
3042 sprintf (scratchbuf, ",%s", mode_64bit ? names64[index] : names32[index]);
3043 oappend (scratchbuf);
3044 }
3045 if (!intel_syntax
3046 || (intel_syntax
3047 && bytemode != b_mode
3048 && bytemode != w_mode
3049 && bytemode != v_mode))
3050 {
3051 *obufp++ = scale_char;
3052 *obufp = '\0';
3053 sprintf (scratchbuf, "%d", 1 << scale);
3054 oappend (scratchbuf);
3055 }
3056 }
3057 if (intel_syntax)
3058 if (mod != 0 || (base & 7) == 5)
3059 {
3060 /* Don't print zero displacements */
3061 if (disp != 0)
3062 {
3063 print_operand_value (scratchbuf, 0, disp);
3064 oappend (scratchbuf);
3065 }
3066 }
3067
3068 *obufp++ = close_char;
3069 *obufp = '\0';
3070 }
3071 else if (intel_syntax)
3072 {
3073 if (mod != 0 || (base & 7) == 5)
3074 {
3075 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3076 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
3077 ;
3078 else
3079 {
3080 oappend (names_seg[3]);
3081 oappend (":");
3082 }
3083 print_operand_value (scratchbuf, 1, disp);
3084 oappend (scratchbuf);
3085 }
3086 }
3087 }
3088 else
3089 { /* 16 bit address mode */
3090 switch (mod)
3091 {
3092 case 0:
3093 if ((rm & 7) == 6)
3094 {
3095 disp = get16 ();
3096 if ((disp & 0x8000) != 0)
3097 disp -= 0x10000;
3098 }
3099 break;
3100 case 1:
3101 FETCH_DATA (the_info, codep + 1);
3102 disp = *codep++;
3103 if ((disp & 0x80) != 0)
3104 disp -= 0x100;
3105 break;
3106 case 2:
3107 disp = get16 ();
3108 if ((disp & 0x8000) != 0)
3109 disp -= 0x10000;
3110 break;
3111 }
3112
3113 if (!intel_syntax)
3114 if (mod != 0 || (rm & 7) == 6)
3115 {
3116 print_operand_value (scratchbuf, 0, disp);
3117 oappend (scratchbuf);
3118 }
3119
3120 if (mod != 0 || (rm & 7) != 6)
3121 {
3122 *obufp++ = open_char;
3123 *obufp = '\0';
3124 oappend (index16[rm + add]);
3125 *obufp++ = close_char;
3126 *obufp = '\0';
3127 }
3128 }
3129 }
3130
3131 static void
3132 OP_G (bytemode, sizeflag)
3133 int bytemode;
3134 int sizeflag;
3135 {
3136 int add = 0;
3137 USED_REX (REX_EXTX);
3138 if (rex & REX_EXTX)
3139 add += 8;
3140 switch (bytemode)
3141 {
3142 case b_mode:
3143 USED_REX (0);
3144 if (rex)
3145 oappend (names8rex[reg + add]);
3146 else
3147 oappend (names8[reg + add]);
3148 break;
3149 case w_mode:
3150 oappend (names16[reg + add]);
3151 break;
3152 case d_mode:
3153 oappend (names32[reg + add]);
3154 break;
3155 case q_mode:
3156 oappend (names64[reg + add]);
3157 break;
3158 case v_mode:
3159 USED_REX (REX_MODE64);
3160 if (rex & REX_MODE64)
3161 oappend (names64[reg + add]);
3162 else if (sizeflag & DFLAG)
3163 oappend (names32[reg + add]);
3164 else
3165 oappend (names16[reg + add]);
3166 used_prefixes |= (prefixes & PREFIX_DATA);
3167 break;
3168 default:
3169 oappend (INTERNAL_DISASSEMBLER_ERROR);
3170 break;
3171 }
3172 }
3173
3174 static bfd_vma
3175 get64 ()
3176 {
3177 bfd_vma x;
3178 #ifdef BFD64
3179 unsigned int a;
3180 unsigned int b;
3181
3182 FETCH_DATA (the_info, codep + 8);
3183 a = *codep++ & 0xff;
3184 a |= (*codep++ & 0xff) << 8;
3185 a |= (*codep++ & 0xff) << 16;
3186 a |= (*codep++ & 0xff) << 24;
3187 b = *codep++ & 0xff;
3188 b |= (*codep++ & 0xff) << 8;
3189 b |= (*codep++ & 0xff) << 16;
3190 b |= (*codep++ & 0xff) << 24;
3191 x = a + ((bfd_vma) b << 32);
3192 #else
3193 abort();
3194 x = 0;
3195 #endif
3196 return x;
3197 }
3198
3199 static bfd_signed_vma
3200 get32 ()
3201 {
3202 bfd_signed_vma x = 0;
3203
3204 FETCH_DATA (the_info, codep + 4);
3205 x = *codep++ & (bfd_signed_vma) 0xff;
3206 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3207 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3208 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3209 return x;
3210 }
3211
3212 static bfd_signed_vma
3213 get32s ()
3214 {
3215 bfd_signed_vma x = 0;
3216
3217 FETCH_DATA (the_info, codep + 4);
3218 x = *codep++ & (bfd_signed_vma) 0xff;
3219 x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
3220 x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
3221 x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
3222
3223 x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
3224
3225 return x;
3226 }
3227
3228 static int
3229 get16 ()
3230 {
3231 int x = 0;
3232
3233 FETCH_DATA (the_info, codep + 2);
3234 x = *codep++ & 0xff;
3235 x |= (*codep++ & 0xff) << 8;
3236 return x;
3237 }
3238
3239 static void
3240 set_op (op, riprel)
3241 unsigned int op;
3242 int riprel;
3243 {
3244 op_index[op_ad] = op_ad;
3245 op_address[op_ad] = op;
3246 op_riprel[op_ad] = riprel;
3247 }
3248
3249 static void
3250 OP_REG (code, sizeflag)
3251 int code;
3252 int sizeflag;
3253 {
3254 const char *s;
3255 int add = 0;
3256 USED_REX (REX_EXTZ);
3257 if (rex & REX_EXTZ)
3258 add = 8;
3259
3260 switch (code)
3261 {
3262 case indir_dx_reg:
3263 s = "(%dx)";
3264 break;
3265 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3266 case sp_reg: case bp_reg: case si_reg: case di_reg:
3267 s = names16[code - ax_reg + add];
3268 break;
3269 case es_reg: case ss_reg: case cs_reg:
3270 case ds_reg: case fs_reg: case gs_reg:
3271 s = names_seg[code - es_reg + add];
3272 break;
3273 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3274 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3275 USED_REX (0);
3276 if (rex)
3277 s = names8rex[code - al_reg + add];
3278 else
3279 s = names8[code - al_reg];
3280 break;
3281 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
3282 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
3283 if (mode_64bit)
3284 {
3285 s = names64[code - rAX_reg + add];
3286 break;
3287 }
3288 code += eAX_reg - rAX_reg;
3289 /* Fall through */
3290 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3291 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3292 USED_REX (REX_MODE64);
3293 if (rex & REX_MODE64)
3294 s = names64[code - eAX_reg + add];
3295 else if (sizeflag & DFLAG)
3296 s = names32[code - eAX_reg + add];
3297 else
3298 s = names16[code - eAX_reg + add];
3299 used_prefixes |= (prefixes & PREFIX_DATA);
3300 break;
3301 default:
3302 s = INTERNAL_DISASSEMBLER_ERROR;
3303 break;
3304 }
3305 oappend (s);
3306 }
3307
3308 static void
3309 OP_IMREG (code, sizeflag)
3310 int code;
3311 int sizeflag;
3312 {
3313 const char *s;
3314
3315 switch (code)
3316 {
3317 case indir_dx_reg:
3318 s = "(%dx)";
3319 break;
3320 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3321 case sp_reg: case bp_reg: case si_reg: case di_reg:
3322 s = names16[code - ax_reg];
3323 break;
3324 case es_reg: case ss_reg: case cs_reg:
3325 case ds_reg: case fs_reg: case gs_reg:
3326 s = names_seg[code - es_reg];
3327 break;
3328 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3329 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3330 USED_REX (0);
3331 if (rex)
3332 s = names8rex[code - al_reg];
3333 else
3334 s = names8[code - al_reg];
3335 break;
3336 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3337 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3338 USED_REX (REX_MODE64);
3339 if (rex & REX_MODE64)
3340 s = names64[code - eAX_reg];
3341 else if (sizeflag & DFLAG)
3342 s = names32[code - eAX_reg];
3343 else
3344 s = names16[code - eAX_reg];
3345 used_prefixes |= (prefixes & PREFIX_DATA);
3346 break;
3347 default:
3348 s = INTERNAL_DISASSEMBLER_ERROR;
3349 break;
3350 }
3351 oappend (s);
3352 }
3353
3354 static void
3355 OP_I (bytemode, sizeflag)
3356 int bytemode;
3357 int sizeflag;
3358 {
3359 bfd_signed_vma op;
3360 bfd_signed_vma mask = -1;
3361
3362 switch (bytemode)
3363 {
3364 case b_mode:
3365 FETCH_DATA (the_info, codep + 1);
3366 op = *codep++;
3367 mask = 0xff;
3368 break;
3369 case q_mode:
3370 if (mode_64bit)
3371 {
3372 op = get32s ();
3373 break;
3374 }
3375 /* Fall through */
3376 case v_mode:
3377 USED_REX (REX_MODE64);
3378 if (rex & REX_MODE64)
3379 op = get32s ();
3380 else if (sizeflag & DFLAG)
3381 {
3382 op = get32 ();
3383 mask = 0xffffffff;
3384 }
3385 else
3386 {
3387 op = get16 ();
3388 mask = 0xfffff;
3389 }
3390 used_prefixes |= (prefixes & PREFIX_DATA);
3391 break;
3392 case w_mode:
3393 mask = 0xfffff;
3394 op = get16 ();
3395 break;
3396 default:
3397 oappend (INTERNAL_DISASSEMBLER_ERROR);
3398 return;
3399 }
3400
3401 op &= mask;
3402 scratchbuf[0] = '$';
3403 print_operand_value (scratchbuf + !intel_syntax, 1, op);
3404 oappend (scratchbuf);
3405 scratchbuf[0] = '\0';
3406 }
3407
3408 static void
3409 OP_I64 (bytemode, sizeflag)
3410 int bytemode;
3411 int sizeflag;
3412 {
3413 bfd_signed_vma op;
3414 bfd_signed_vma mask = -1;
3415
3416 if (!mode_64bit)
3417 {
3418 OP_I (bytemode, sizeflag);
3419 return;
3420 }
3421
3422 switch (bytemode)
3423 {
3424 case b_mode:
3425 FETCH_DATA (the_info, codep + 1);
3426 op = *codep++;
3427 mask = 0xff;
3428 break;
3429 case v_mode:
3430 USED_REX (REX_MODE64);
3431 if (rex & REX_MODE64)
3432 op = get64 ();
3433 else if (sizeflag & DFLAG)
3434 {
3435 op = get32 ();
3436 mask = 0xffffffff;
3437 }
3438 else
3439 {
3440 op = get16 ();
3441 mask = 0xfffff;
3442 }
3443 used_prefixes |= (prefixes & PREFIX_DATA);
3444 break;
3445 case w_mode:
3446 mask = 0xfffff;
3447 op = get16 ();
3448 break;
3449 default:
3450 oappend (INTERNAL_DISASSEMBLER_ERROR);
3451 return;
3452 }
3453
3454 op &= mask;
3455 scratchbuf[0] = '$';
3456 print_operand_value (scratchbuf + !intel_syntax, 1, op);
3457 oappend (scratchbuf);
3458 scratchbuf[0] = '\0';
3459 }
3460
3461 static void
3462 OP_sI (bytemode, sizeflag)
3463 int bytemode;
3464 int sizeflag;
3465 {
3466 bfd_signed_vma op;
3467 bfd_signed_vma mask = -1;
3468
3469 switch (bytemode)
3470 {
3471 case b_mode:
3472 FETCH_DATA (the_info, codep + 1);
3473 op = *codep++;
3474 if ((op & 0x80) != 0)
3475 op -= 0x100;
3476 mask = 0xffffffff;
3477 break;
3478 case v_mode:
3479 USED_REX (REX_MODE64);
3480 if (rex & REX_MODE64)
3481 op = get32s ();
3482 else if (sizeflag & DFLAG)
3483 {
3484 op = get32s ();
3485 mask = 0xffffffff;
3486 }
3487 else
3488 {
3489 mask = 0xffffffff;
3490 op = get16();
3491 if ((op & 0x8000) != 0)
3492 op -= 0x10000;
3493 }
3494 used_prefixes |= (prefixes & PREFIX_DATA);
3495 break;
3496 case w_mode:
3497 op = get16 ();
3498 mask = 0xffffffff;
3499 if ((op & 0x8000) != 0)
3500 op -= 0x10000;
3501 break;
3502 default:
3503 oappend (INTERNAL_DISASSEMBLER_ERROR);
3504 return;
3505 }
3506
3507 scratchbuf[0] = '$';
3508 print_operand_value (scratchbuf + 1, 1, op);
3509 oappend (scratchbuf);
3510 }
3511
3512 static void
3513 OP_J (bytemode, sizeflag)
3514 int bytemode;
3515 int sizeflag;
3516 {
3517 bfd_vma disp;
3518 int mask = -1;
3519
3520 switch (bytemode)
3521 {
3522 case b_mode:
3523 FETCH_DATA (the_info, codep + 1);
3524 disp = *codep++;
3525 if ((disp & 0x80) != 0)
3526 disp -= 0x100;
3527 break;
3528 case v_mode:
3529 if (sizeflag & DFLAG)
3530 disp = get32s ();
3531 else
3532 {
3533 disp = get16 ();
3534 /* for some reason, a data16 prefix on a jump instruction
3535 means that the pc is masked to 16 bits after the
3536 displacement is added! */
3537 mask = 0xffff;
3538 }
3539 break;
3540 default:
3541 oappend (INTERNAL_DISASSEMBLER_ERROR);
3542 return;
3543 }
3544 disp = (start_pc + codep - start_codep + disp) & mask;
3545 set_op (disp, 0);
3546 print_operand_value (scratchbuf, 1, disp);
3547 oappend (scratchbuf);
3548 }
3549
3550 static void
3551 OP_SEG (dummy, sizeflag)
3552 int dummy ATTRIBUTE_UNUSED;
3553 int sizeflag ATTRIBUTE_UNUSED;
3554 {
3555 static char *sreg[] = {
3556 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
3557 };
3558
3559 oappend (sreg[reg]);
3560 }
3561
3562 static void
3563 OP_DIR (dummy, sizeflag)
3564 int dummy ATTRIBUTE_UNUSED;
3565 int sizeflag;
3566 {
3567 int seg, offset;
3568
3569 if (sizeflag & DFLAG)
3570 {
3571 offset = get32 ();
3572 seg = get16 ();
3573 }
3574 else
3575 {
3576 offset = get16 ();
3577 seg = get16 ();
3578 }
3579 used_prefixes |= (prefixes & PREFIX_DATA);
3580 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3581 oappend (scratchbuf);
3582 }
3583
3584 static void
3585 OP_OFF (bytemode, sizeflag)
3586 int bytemode ATTRIBUTE_UNUSED;
3587 int sizeflag;
3588 {
3589 bfd_vma off;
3590
3591 append_seg ();
3592
3593 if (sizeflag & AFLAG)
3594 off = get32 ();
3595 else
3596 off = get16 ();
3597
3598 if (intel_syntax)
3599 {
3600 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3601 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3602 {
3603 oappend (names_seg[3]);
3604 oappend (":");
3605 }
3606 }
3607 print_operand_value (scratchbuf, 1, off);
3608 oappend (scratchbuf);
3609 }
3610
3611 static void
3612 OP_OFF64 (bytemode, sizeflag)
3613 int bytemode ATTRIBUTE_UNUSED;
3614 int sizeflag ATTRIBUTE_UNUSED;
3615 {
3616 bfd_vma off;
3617
3618 if (!mode_64bit)
3619 {
3620 OP_OFF (bytemode, sizeflag);
3621 return;
3622 }
3623
3624 append_seg ();
3625
3626 off = get64();
3627
3628 if (intel_syntax)
3629 {
3630 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3631 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3632 {
3633 oappend (names_seg[3]);
3634 oappend (":");
3635 }
3636 }
3637 print_operand_value (scratchbuf, 1, off);
3638 oappend (scratchbuf);
3639 }
3640
3641 static void
3642 ptr_reg (code, sizeflag)
3643 int code;
3644 int sizeflag;
3645 {
3646 const char *s;
3647 oappend ("(");
3648 USED_REX (REX_MODE64);
3649 if (rex & REX_MODE64)
3650 s = names64[code - eAX_reg];
3651 else if (sizeflag & AFLAG)
3652 s = names32[code - eAX_reg];
3653 else
3654 s = names16[code - eAX_reg];
3655 oappend (s);
3656 oappend (")");
3657 }
3658
3659 static void
3660 OP_ESreg (code, sizeflag)
3661 int code;
3662 int sizeflag;
3663 {
3664 oappend ("%es:");
3665 ptr_reg (code, sizeflag);
3666 }
3667
3668 static void
3669 OP_DSreg (code, sizeflag)
3670 int code;
3671 int sizeflag;
3672 {
3673 if ((prefixes
3674 & (PREFIX_CS
3675 | PREFIX_DS
3676 | PREFIX_SS
3677 | PREFIX_ES
3678 | PREFIX_FS
3679 | PREFIX_GS)) == 0)
3680 prefixes |= PREFIX_DS;
3681 append_seg();
3682 ptr_reg (code, sizeflag);
3683 }
3684
3685 static void
3686 OP_C (dummy, sizeflag)
3687 int dummy ATTRIBUTE_UNUSED;
3688 int sizeflag ATTRIBUTE_UNUSED;
3689 {
3690 int add = 0;
3691 USED_REX (REX_EXTX);
3692 if (rex & REX_EXTX)
3693 add = 8;
3694 sprintf (scratchbuf, "%%cr%d", reg+add);
3695 oappend (scratchbuf);
3696 }
3697
3698 static void
3699 OP_D (dummy, sizeflag)
3700 int dummy ATTRIBUTE_UNUSED;
3701 int sizeflag ATTRIBUTE_UNUSED;
3702 {
3703 int add = 0;
3704 USED_REX (REX_EXTX);
3705 if (rex & REX_EXTX)
3706 add = 8;
3707 sprintf (scratchbuf, "%%db%d", reg+add);
3708 oappend (scratchbuf);
3709 }
3710
3711 static void
3712 OP_T (dummy, sizeflag)
3713 int dummy ATTRIBUTE_UNUSED;
3714 int sizeflag ATTRIBUTE_UNUSED;
3715 {
3716 sprintf (scratchbuf, "%%tr%d", reg);
3717 oappend (scratchbuf);
3718 }
3719
3720 static void
3721 OP_Rd (bytemode, sizeflag)
3722 int bytemode;
3723 int sizeflag;
3724 {
3725 if (mod == 3)
3726 OP_E (bytemode, sizeflag);
3727 else
3728 BadOp();
3729 }
3730
3731 static void
3732 OP_MMX (bytemode, sizeflag)
3733 int bytemode ATTRIBUTE_UNUSED;
3734 int sizeflag ATTRIBUTE_UNUSED;
3735 {
3736 int add = 0;
3737 USED_REX (REX_EXTX);
3738 if (rex & REX_EXTX)
3739 add = 8;
3740 used_prefixes |= (prefixes & PREFIX_DATA);
3741 if (prefixes & PREFIX_DATA)
3742 sprintf (scratchbuf, "%%xmm%d", reg + add);
3743 else
3744 sprintf (scratchbuf, "%%mm%d", reg + add);
3745 oappend (scratchbuf);
3746 }
3747
3748 static void
3749 OP_XMM (bytemode, sizeflag)
3750 int bytemode ATTRIBUTE_UNUSED;
3751 int sizeflag ATTRIBUTE_UNUSED;
3752 {
3753 int add = 0;
3754 USED_REX (REX_EXTX);
3755 if (rex & REX_EXTX)
3756 add = 8;
3757 sprintf (scratchbuf, "%%xmm%d", reg + add);
3758 oappend (scratchbuf);
3759 }
3760
3761 static void
3762 OP_EM (bytemode, sizeflag)
3763 int bytemode;
3764 int sizeflag;
3765 {
3766 int add = 0;
3767 if (mod != 3)
3768 {
3769 OP_E (bytemode, sizeflag);
3770 return;
3771 }
3772 USED_REX (REX_EXTZ);
3773 if (rex & REX_EXTZ)
3774 add = 8;
3775
3776 /* skip mod/rm byte */
3777 MODRM_CHECK;
3778 codep++;
3779 used_prefixes |= (prefixes & PREFIX_DATA);
3780 if (prefixes & PREFIX_DATA)
3781 sprintf (scratchbuf, "%%xmm%d", rm + add);
3782 else
3783 sprintf (scratchbuf, "%%mm%d", rm + add);
3784 oappend (scratchbuf);
3785 }
3786
3787 static void
3788 OP_EX (bytemode, sizeflag)
3789 int bytemode;
3790 int sizeflag;
3791 {
3792 int add = 0;
3793 if (mod != 3)
3794 {
3795 OP_E (bytemode, sizeflag);
3796 return;
3797 }
3798 USED_REX (REX_EXTZ);
3799 if (rex & REX_EXTZ)
3800 add = 8;
3801
3802 /* skip mod/rm byte */
3803 MODRM_CHECK;
3804 codep++;
3805 sprintf (scratchbuf, "%%xmm%d", rm + add);
3806 oappend (scratchbuf);
3807 }
3808
3809 static void
3810 OP_MS (bytemode, sizeflag)
3811 int bytemode;
3812 int sizeflag;
3813 {
3814 if (mod == 3)
3815 OP_EM (bytemode, sizeflag);
3816 else
3817 BadOp();
3818 }
3819
3820 static void
3821 OP_XS (bytemode, sizeflag)
3822 int bytemode;
3823 int sizeflag;
3824 {
3825 if (mod == 3)
3826 OP_EX (bytemode, sizeflag);
3827 else
3828 BadOp();
3829 }
3830
3831 static const char *Suffix3DNow[] = {
3832 /* 00 */ NULL, NULL, NULL, NULL,
3833 /* 04 */ NULL, NULL, NULL, NULL,
3834 /* 08 */ NULL, NULL, NULL, NULL,
3835 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
3836 /* 10 */ NULL, NULL, NULL, NULL,
3837 /* 14 */ NULL, NULL, NULL, NULL,
3838 /* 18 */ NULL, NULL, NULL, NULL,
3839 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
3840 /* 20 */ NULL, NULL, NULL, NULL,
3841 /* 24 */ NULL, NULL, NULL, NULL,
3842 /* 28 */ NULL, NULL, NULL, NULL,
3843 /* 2C */ NULL, NULL, NULL, NULL,
3844 /* 30 */ NULL, NULL, NULL, NULL,
3845 /* 34 */ NULL, NULL, NULL, NULL,
3846 /* 38 */ NULL, NULL, NULL, NULL,
3847 /* 3C */ NULL, NULL, NULL, NULL,
3848 /* 40 */ NULL, NULL, NULL, NULL,
3849 /* 44 */ NULL, NULL, NULL, NULL,
3850 /* 48 */ NULL, NULL, NULL, NULL,
3851 /* 4C */ NULL, NULL, NULL, NULL,
3852 /* 50 */ NULL, NULL, NULL, NULL,
3853 /* 54 */ NULL, NULL, NULL, NULL,
3854 /* 58 */ NULL, NULL, NULL, NULL,
3855 /* 5C */ NULL, NULL, NULL, NULL,
3856 /* 60 */ NULL, NULL, NULL, NULL,
3857 /* 64 */ NULL, NULL, NULL, NULL,
3858 /* 68 */ NULL, NULL, NULL, NULL,
3859 /* 6C */ NULL, NULL, NULL, NULL,
3860 /* 70 */ NULL, NULL, NULL, NULL,
3861 /* 74 */ NULL, NULL, NULL, NULL,
3862 /* 78 */ NULL, NULL, NULL, NULL,
3863 /* 7C */ NULL, NULL, NULL, NULL,
3864 /* 80 */ NULL, NULL, NULL, NULL,
3865 /* 84 */ NULL, NULL, NULL, NULL,
3866 /* 88 */ NULL, NULL, "pfnacc", NULL,
3867 /* 8C */ NULL, NULL, "pfpnacc", NULL,
3868 /* 90 */ "pfcmpge", NULL, NULL, NULL,
3869 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
3870 /* 98 */ NULL, NULL, "pfsub", NULL,
3871 /* 9C */ NULL, NULL, "pfadd", NULL,
3872 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
3873 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
3874 /* A8 */ NULL, NULL, "pfsubr", NULL,
3875 /* AC */ NULL, NULL, "pfacc", NULL,
3876 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
3877 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
3878 /* B8 */ NULL, NULL, NULL, "pswapd",
3879 /* BC */ NULL, NULL, NULL, "pavgusb",
3880 /* C0 */ NULL, NULL, NULL, NULL,
3881 /* C4 */ NULL, NULL, NULL, NULL,
3882 /* C8 */ NULL, NULL, NULL, NULL,
3883 /* CC */ NULL, NULL, NULL, NULL,
3884 /* D0 */ NULL, NULL, NULL, NULL,
3885 /* D4 */ NULL, NULL, NULL, NULL,
3886 /* D8 */ NULL, NULL, NULL, NULL,
3887 /* DC */ NULL, NULL, NULL, NULL,
3888 /* E0 */ NULL, NULL, NULL, NULL,
3889 /* E4 */ NULL, NULL, NULL, NULL,
3890 /* E8 */ NULL, NULL, NULL, NULL,
3891 /* EC */ NULL, NULL, NULL, NULL,
3892 /* F0 */ NULL, NULL, NULL, NULL,
3893 /* F4 */ NULL, NULL, NULL, NULL,
3894 /* F8 */ NULL, NULL, NULL, NULL,
3895 /* FC */ NULL, NULL, NULL, NULL,
3896 };
3897
3898 static void
3899 OP_3DNowSuffix (bytemode, sizeflag)
3900 int bytemode ATTRIBUTE_UNUSED;
3901 int sizeflag ATTRIBUTE_UNUSED;
3902 {
3903 const char *mnemonic;
3904
3905 FETCH_DATA (the_info, codep + 1);
3906 /* AMD 3DNow! instructions are specified by an opcode suffix in the
3907 place where an 8-bit immediate would normally go. ie. the last
3908 byte of the instruction. */
3909 obufp = obuf + strlen(obuf);
3910 mnemonic = Suffix3DNow[*codep++ & 0xff];
3911 if (mnemonic)
3912 oappend (mnemonic);
3913 else
3914 {
3915 /* Since a variable sized modrm/sib chunk is between the start
3916 of the opcode (0x0f0f) and the opcode suffix, we need to do
3917 all the modrm processing first, and don't know until now that
3918 we have a bad opcode. This necessitates some cleaning up. */
3919 op1out[0] = '\0';
3920 op2out[0] = '\0';
3921 BadOp();
3922 }
3923 }
3924
3925
3926 static const char *simd_cmp_op [] = {
3927 "eq",
3928 "lt",
3929 "le",
3930 "unord",
3931 "neq",
3932 "nlt",
3933 "nle",
3934 "ord"
3935 };
3936
3937 static void
3938 OP_SIMD_Suffix (bytemode, sizeflag)
3939 int bytemode ATTRIBUTE_UNUSED;
3940 int sizeflag ATTRIBUTE_UNUSED;
3941 {
3942 unsigned int cmp_type;
3943
3944 FETCH_DATA (the_info, codep + 1);
3945 obufp = obuf + strlen(obuf);
3946 cmp_type = *codep++ & 0xff;
3947 if (cmp_type < 8)
3948 {
3949 char suffix1 = 'p', suffix2 = 's';
3950 used_prefixes |= (prefixes & PREFIX_REPZ);
3951 if (prefixes & PREFIX_REPZ)
3952 suffix1 = 's';
3953 else
3954 {
3955 used_prefixes |= (prefixes & PREFIX_DATA);
3956 if (prefixes & PREFIX_DATA)
3957 suffix2 = 'd';
3958 else
3959 {
3960 used_prefixes |= (prefixes & PREFIX_REPNZ);
3961 if (prefixes & PREFIX_REPNZ)
3962 suffix1 = 's', suffix2 = 'd';
3963 }
3964 }
3965 sprintf (scratchbuf, "cmp%s%c%c",
3966 simd_cmp_op[cmp_type], suffix1, suffix2);
3967 used_prefixes |= (prefixes & PREFIX_REPZ);
3968 oappend (scratchbuf);
3969 }
3970 else
3971 {
3972 /* We have a bad extension byte. Clean up. */
3973 op1out[0] = '\0';
3974 op2out[0] = '\0';
3975 BadOp();
3976 }
3977 }
3978
3979 static void
3980 SIMD_Fixup (extrachar, sizeflag)
3981 int extrachar;
3982 int sizeflag ATTRIBUTE_UNUSED;
3983 {
3984 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
3985 forms of these instructions. */
3986 if (mod == 3)
3987 {
3988 char *p = obuf + strlen(obuf);
3989 *(p+1) = '\0';
3990 *p = *(p-1);
3991 *(p-1) = *(p-2);
3992 *(p-2) = *(p-3);
3993 *(p-3) = extrachar;
3994 }
3995 }
3996
3997 static void BadOp (void)
3998 {
3999 codep = insn_codep + 1; /* throw away prefixes and 1st. opcode byte */
4000 oappend ("(bad)");
4001 }
This page took 0.158578 seconds and 4 git commands to generate.