*** empty log message ***
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2001
4 Free Software Foundation, Inc.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22 /*
23 * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
24 * July 1988
25 * modified by John Hassey (hassey@dg-rtp.dg.com)
26 * x86-64 support added by Jan Hubicka (jh@suse.cz)
27 */
28
29 /*
30 * The main tables describing the instructions is essentially a copy
31 * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
32 * Programmers Manual. Usually, there is a capital letter, followed
33 * by a small letter. The capital letter tell the addressing mode,
34 * and the small letter tells about the operand size. Refer to
35 * the Intel manual for details.
36 */
37
38 #include "dis-asm.h"
39 #include "sysdep.h"
40 #include "opintl.h"
41
42 #define MAXLEN 20
43
44 #include <setjmp.h>
45
46 #ifndef UNIXWARE_COMPAT
47 /* Set non-zero for broken, compatible instructions. Set to zero for
48 non-broken opcodes. */
49 #define UNIXWARE_COMPAT 1
50 #endif
51
52 static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
53 static void ckprefix PARAMS ((void));
54 static const char *prefix_name PARAMS ((int, int));
55 static int print_insn_i386 PARAMS ((bfd_vma, disassemble_info *));
56 static void dofloat PARAMS ((int));
57 static void OP_ST PARAMS ((int, int));
58 static void OP_STi PARAMS ((int, int));
59 static int putop PARAMS ((const char *, int));
60 static void oappend PARAMS ((const char *));
61 static void append_seg PARAMS ((void));
62 static void OP_indirE PARAMS ((int, int));
63 static void print_operand_value PARAMS ((char *, int, bfd_vma));
64 static void OP_E PARAMS ((int, int));
65 static void OP_G PARAMS ((int, int));
66 static bfd_vma get64 PARAMS ((void));
67 static bfd_signed_vma get32 PARAMS ((void));
68 static bfd_signed_vma get32s PARAMS ((void));
69 static int get16 PARAMS ((void));
70 static void set_op PARAMS ((bfd_vma, int));
71 static void OP_REG PARAMS ((int, int));
72 static void OP_IMREG PARAMS ((int, int));
73 static void OP_I PARAMS ((int, int));
74 static void OP_I64 PARAMS ((int, int));
75 static void OP_sI PARAMS ((int, int));
76 static void OP_J PARAMS ((int, int));
77 static void OP_SEG PARAMS ((int, int));
78 static void OP_DIR PARAMS ((int, int));
79 static void OP_OFF PARAMS ((int, int));
80 static void OP_OFF64 PARAMS ((int, int));
81 static void ptr_reg PARAMS ((int, int));
82 static void OP_ESreg PARAMS ((int, int));
83 static void OP_DSreg PARAMS ((int, int));
84 static void OP_C PARAMS ((int, int));
85 static void OP_D PARAMS ((int, int));
86 static void OP_T PARAMS ((int, int));
87 static void OP_Rd PARAMS ((int, int));
88 static void OP_MMX PARAMS ((int, int));
89 static void OP_XMM PARAMS ((int, int));
90 static void OP_EM PARAMS ((int, int));
91 static void OP_EX PARAMS ((int, int));
92 static void OP_MS PARAMS ((int, int));
93 static void OP_XS PARAMS ((int, int));
94 static void OP_3DNowSuffix PARAMS ((int, int));
95 static void OP_SIMD_Suffix PARAMS ((int, int));
96 static void SIMD_Fixup PARAMS ((int, int));
97 static void BadOp PARAMS ((void));
98
99 struct dis_private
100 {
101 /* Points to first byte not fetched. */
102 bfd_byte *max_fetched;
103 bfd_byte the_buffer[MAXLEN];
104 bfd_vma insn_start;
105 jmp_buf bailout;
106 };
107
108 /* The opcode for the fwait instruction, which we treat as a prefix
109 when we can. */
110 #define FWAIT_OPCODE (0x9b)
111
112 /* Set to 1 for 64bit mode disassembly. */
113 static int mode_64bit;
114
115 /* Flags for the prefixes for the current instruction. See below. */
116 static int prefixes;
117
118 /* REX prefix the current instruction. See below. */
119 static int rex;
120 /* Bits of REX we've already used. */
121 static int rex_used;
122 #define REX_MODE64 8
123 #define REX_EXTX 4
124 #define REX_EXTY 2
125 #define REX_EXTZ 1
126 /* Mark parts used in the REX prefix. When we are testing for
127 empty prefix (for 8bit register REX extension), just mask it
128 out. Otherwise test for REX bit is excuse for existence of REX
129 only in case value is nonzero. */
130 #define USED_REX(value) \
131 { \
132 if (value) \
133 rex_used |= (rex & value) ? (value) | 0x40 : 0; \
134 else \
135 rex_used |= 0x40; \
136 }
137
138 /* Flags for prefixes which we somehow handled when printing the
139 current instruction. */
140 static int used_prefixes;
141
142 /* Flags stored in PREFIXES. */
143 #define PREFIX_REPZ 1
144 #define PREFIX_REPNZ 2
145 #define PREFIX_LOCK 4
146 #define PREFIX_CS 8
147 #define PREFIX_SS 0x10
148 #define PREFIX_DS 0x20
149 #define PREFIX_ES 0x40
150 #define PREFIX_FS 0x80
151 #define PREFIX_GS 0x100
152 #define PREFIX_DATA 0x200
153 #define PREFIX_ADDR 0x400
154 #define PREFIX_FWAIT 0x800
155
156 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
157 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
158 on error. */
159 #define FETCH_DATA(info, addr) \
160 ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
161 ? 1 : fetch_data ((info), (addr)))
162
163 static int
164 fetch_data (info, addr)
165 struct disassemble_info *info;
166 bfd_byte *addr;
167 {
168 int status;
169 struct dis_private *priv = (struct dis_private *)info->private_data;
170 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
171
172 status = (*info->read_memory_func) (start,
173 priv->max_fetched,
174 addr - priv->max_fetched,
175 info);
176 if (status != 0)
177 {
178 /* If we did manage to read at least one byte, then
179 print_insn_i386 will do something sensible. Otherwise, print
180 an error. We do that here because this is where we know
181 STATUS. */
182 if (priv->max_fetched == priv->the_buffer)
183 (*info->memory_error_func) (status, start, info);
184 longjmp (priv->bailout, 1);
185 }
186 else
187 priv->max_fetched = addr;
188 return 1;
189 }
190
191 #define XX NULL, 0
192
193 #define Eb OP_E, b_mode
194 #define Ev OP_E, v_mode
195 #define Ed OP_E, d_mode
196 #define indirEb OP_indirE, b_mode
197 #define indirEv OP_indirE, v_mode
198 #define Ew OP_E, w_mode
199 #define Ma OP_E, v_mode
200 #define M OP_E, 0 /* lea, lgdt, etc. */
201 #define Mp OP_E, 0 /* 32 or 48 bit memory operand for LDS, LES etc */
202 #define Gb OP_G, b_mode
203 #define Gv OP_G, v_mode
204 #define Gd OP_G, d_mode
205 #define Gw OP_G, w_mode
206 #define Rd OP_Rd, d_mode
207 #define Rm OP_Rd, m_mode
208 #define Ib OP_I, b_mode
209 #define sIb OP_sI, b_mode /* sign extened byte */
210 #define Iv OP_I, v_mode
211 #define Iq OP_I, q_mode
212 #define Iv64 OP_I64, v_mode
213 #define Iw OP_I, w_mode
214 #define Jb OP_J, b_mode
215 #define Jv OP_J, v_mode
216 #define Cm OP_C, m_mode
217 #define Dm OP_D, m_mode
218 #define Td OP_T, d_mode
219
220 #define RMeAX OP_REG, eAX_reg
221 #define RMeBX OP_REG, eBX_reg
222 #define RMeCX OP_REG, eCX_reg
223 #define RMeDX OP_REG, eDX_reg
224 #define RMeSP OP_REG, eSP_reg
225 #define RMeBP OP_REG, eBP_reg
226 #define RMeSI OP_REG, eSI_reg
227 #define RMeDI OP_REG, eDI_reg
228 #define RMrAX OP_REG, rAX_reg
229 #define RMrBX OP_REG, rBX_reg
230 #define RMrCX OP_REG, rCX_reg
231 #define RMrDX OP_REG, rDX_reg
232 #define RMrSP OP_REG, rSP_reg
233 #define RMrBP OP_REG, rBP_reg
234 #define RMrSI OP_REG, rSI_reg
235 #define RMrDI OP_REG, rDI_reg
236 #define RMAL OP_REG, al_reg
237 #define RMAL OP_REG, al_reg
238 #define RMCL OP_REG, cl_reg
239 #define RMDL OP_REG, dl_reg
240 #define RMBL OP_REG, bl_reg
241 #define RMAH OP_REG, ah_reg
242 #define RMCH OP_REG, ch_reg
243 #define RMDH OP_REG, dh_reg
244 #define RMBH OP_REG, bh_reg
245 #define RMAX OP_REG, ax_reg
246 #define RMDX OP_REG, dx_reg
247
248 #define eAX OP_IMREG, eAX_reg
249 #define eBX OP_IMREG, eBX_reg
250 #define eCX OP_IMREG, eCX_reg
251 #define eDX OP_IMREG, eDX_reg
252 #define eSP OP_IMREG, eSP_reg
253 #define eBP OP_IMREG, eBP_reg
254 #define eSI OP_IMREG, eSI_reg
255 #define eDI OP_IMREG, eDI_reg
256 #define AL OP_IMREG, al_reg
257 #define AL OP_IMREG, al_reg
258 #define CL OP_IMREG, cl_reg
259 #define DL OP_IMREG, dl_reg
260 #define BL OP_IMREG, bl_reg
261 #define AH OP_IMREG, ah_reg
262 #define CH OP_IMREG, ch_reg
263 #define DH OP_IMREG, dh_reg
264 #define BH OP_IMREG, bh_reg
265 #define AX OP_IMREG, ax_reg
266 #define DX OP_IMREG, dx_reg
267 #define indirDX OP_IMREG, indir_dx_reg
268
269 #define Sw OP_SEG, w_mode
270 #define Ap OP_DIR, 0
271 #define Ob OP_OFF, b_mode
272 #define Ob64 OP_OFF64, b_mode
273 #define Ov OP_OFF, v_mode
274 #define Ov64 OP_OFF64, v_mode
275 #define Xb OP_DSreg, eSI_reg
276 #define Xv OP_DSreg, eSI_reg
277 #define Yb OP_ESreg, eDI_reg
278 #define Yv OP_ESreg, eDI_reg
279 #define DSBX OP_DSreg, eBX_reg
280
281 #define es OP_REG, es_reg
282 #define ss OP_REG, ss_reg
283 #define cs OP_REG, cs_reg
284 #define ds OP_REG, ds_reg
285 #define fs OP_REG, fs_reg
286 #define gs OP_REG, gs_reg
287
288 #define MX OP_MMX, 0
289 #define XM OP_XMM, 0
290 #define EM OP_EM, v_mode
291 #define EX OP_EX, v_mode
292 #define MS OP_MS, v_mode
293 #define XS OP_XS, v_mode
294 #define None OP_E, 0
295 #define OPSUF OP_3DNowSuffix, 0
296 #define OPSIMD OP_SIMD_Suffix, 0
297
298 #define cond_jump_flag NULL, cond_jump_mode
299 #define loop_jcxz_flag NULL, loop_jcxz_mode
300
301 /* bits in sizeflag */
302 #if 0 /* leave undefined until someone adds the extra flag to objdump */
303 #define SUFFIX_ALWAYS 4
304 #endif
305 #define AFLAG 2
306 #define DFLAG 1
307
308 #define b_mode 1 /* byte operand */
309 #define v_mode 2 /* operand size depends on prefixes */
310 #define w_mode 3 /* word operand */
311 #define d_mode 4 /* double word operand */
312 #define q_mode 5 /* quad word operand */
313 #define x_mode 6
314 #define m_mode 7 /* d_mode in 32bit, q_mode in 64bit mode. */
315 #define cond_jump_mode 8
316 #define loop_jcxz_mode 9
317
318 #define es_reg 100
319 #define cs_reg 101
320 #define ss_reg 102
321 #define ds_reg 103
322 #define fs_reg 104
323 #define gs_reg 105
324
325 #define eAX_reg 108
326 #define eCX_reg 109
327 #define eDX_reg 110
328 #define eBX_reg 111
329 #define eSP_reg 112
330 #define eBP_reg 113
331 #define eSI_reg 114
332 #define eDI_reg 115
333
334 #define al_reg 116
335 #define cl_reg 117
336 #define dl_reg 118
337 #define bl_reg 119
338 #define ah_reg 120
339 #define ch_reg 121
340 #define dh_reg 122
341 #define bh_reg 123
342
343 #define ax_reg 124
344 #define cx_reg 125
345 #define dx_reg 126
346 #define bx_reg 127
347 #define sp_reg 128
348 #define bp_reg 129
349 #define si_reg 130
350 #define di_reg 131
351
352 #define rAX_reg 132
353 #define rCX_reg 133
354 #define rDX_reg 134
355 #define rBX_reg 135
356 #define rSP_reg 136
357 #define rBP_reg 137
358 #define rSI_reg 138
359 #define rDI_reg 139
360
361 #define indir_dx_reg 150
362
363 #define FLOATCODE 1
364 #define USE_GROUPS 2
365 #define USE_PREFIX_USER_TABLE 3
366 #define X86_64_SPECIAL 4
367
368 #define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
369
370 #define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
371 #define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
372 #define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
373 #define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
374 #define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
375 #define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
376 #define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
377 #define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
378 #define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
379 #define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
380 #define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
381 #define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
382 #define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
383 #define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
384 #define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
385 #define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
386 #define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
387 #define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
388 #define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
389 #define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
390 #define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
391 #define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
392 #define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
393
394 #define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
395 #define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
396 #define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
397 #define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
398 #define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
399 #define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
400 #define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
401 #define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
402 #define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
403 #define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
404 #define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
405 #define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
406 #define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
407 #define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
408 #define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
409 #define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
410 #define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
411 #define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
412 #define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
413 #define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
414 #define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
415 #define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
416 #define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
417 #define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
418 #define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
419 #define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
420 #define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
421
422 #define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
423
424 typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag));
425
426 struct dis386 {
427 const char *name;
428 op_rtn op1;
429 int bytemode1;
430 op_rtn op2;
431 int bytemode2;
432 op_rtn op3;
433 int bytemode3;
434 };
435
436 /* Upper case letters in the instruction names here are macros.
437 'A' => print 'b' if no register operands or suffix_always is true
438 'B' => print 'b' if suffix_always is true
439 'E' => print 'e' if 32-bit form of jcxz
440 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
441 'H' => print ",pt" or ",pn" branch hint
442 'L' => print 'l' if suffix_always is true
443 'N' => print 'n' if instruction has no wait "prefix"
444 'O' => print 'd', or 'o'
445 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
446 or suffix_always is true
447 print 'q' if rex prefix is present.
448 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always is true
449 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
450 'S' => print 'w', 'l' or 'q' if suffix_always is true
451 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
452 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
453 'X' => print 's', 'd' depending on data16 prefix (for XMM)
454 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
455 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
456
457 Many of the above letters print nothing in Intel mode. See "putop"
458 for the details.
459
460 Braces '{' and '}', and vertical bars '|', indicate alternative
461 mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
462 modes. In cases where there are only two alternatives, the X86_64
463 instruction is reserved, and "(bad)" is printed.
464 */
465
466 static const struct dis386 dis386[] = {
467 /* 00 */
468 { "addB", Eb, Gb, XX },
469 { "addS", Ev, Gv, XX },
470 { "addB", Gb, Eb, XX },
471 { "addS", Gv, Ev, XX },
472 { "addB", AL, Ib, XX },
473 { "addS", eAX, Iv, XX },
474 { "push{T|}", es, XX, XX },
475 { "pop{T|}", es, XX, XX },
476 /* 08 */
477 { "orB", Eb, Gb, XX },
478 { "orS", Ev, Gv, XX },
479 { "orB", Gb, Eb, XX },
480 { "orS", Gv, Ev, XX },
481 { "orB", AL, Ib, XX },
482 { "orS", eAX, Iv, XX },
483 { "push{T|}", cs, XX, XX },
484 { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */
485 /* 10 */
486 { "adcB", Eb, Gb, XX },
487 { "adcS", Ev, Gv, XX },
488 { "adcB", Gb, Eb, XX },
489 { "adcS", Gv, Ev, XX },
490 { "adcB", AL, Ib, XX },
491 { "adcS", eAX, Iv, XX },
492 { "push{T|}", ss, XX, XX },
493 { "popT|}", ss, XX, XX },
494 /* 18 */
495 { "sbbB", Eb, Gb, XX },
496 { "sbbS", Ev, Gv, XX },
497 { "sbbB", Gb, Eb, XX },
498 { "sbbS", Gv, Ev, XX },
499 { "sbbB", AL, Ib, XX },
500 { "sbbS", eAX, Iv, XX },
501 { "push{T|}", ds, XX, XX },
502 { "pop{T|}", ds, XX, XX },
503 /* 20 */
504 { "andB", Eb, Gb, XX },
505 { "andS", Ev, Gv, XX },
506 { "andB", Gb, Eb, XX },
507 { "andS", Gv, Ev, XX },
508 { "andB", AL, Ib, XX },
509 { "andS", eAX, Iv, XX },
510 { "(bad)", XX, XX, XX }, /* SEG ES prefix */
511 { "daa{|}", XX, XX, XX },
512 /* 28 */
513 { "subB", Eb, Gb, XX },
514 { "subS", Ev, Gv, XX },
515 { "subB", Gb, Eb, XX },
516 { "subS", Gv, Ev, XX },
517 { "subB", AL, Ib, XX },
518 { "subS", eAX, Iv, XX },
519 { "(bad)", XX, XX, XX }, /* SEG CS prefix */
520 { "das{|}", XX, XX, XX },
521 /* 30 */
522 { "xorB", Eb, Gb, XX },
523 { "xorS", Ev, Gv, XX },
524 { "xorB", Gb, Eb, XX },
525 { "xorS", Gv, Ev, XX },
526 { "xorB", AL, Ib, XX },
527 { "xorS", eAX, Iv, XX },
528 { "(bad)", XX, XX, XX }, /* SEG SS prefix */
529 { "aaa{|}", XX, XX, XX },
530 /* 38 */
531 { "cmpB", Eb, Gb, XX },
532 { "cmpS", Ev, Gv, XX },
533 { "cmpB", Gb, Eb, XX },
534 { "cmpS", Gv, Ev, XX },
535 { "cmpB", AL, Ib, XX },
536 { "cmpS", eAX, Iv, XX },
537 { "(bad)", XX, XX, XX }, /* SEG DS prefix */
538 { "aas{|}", XX, XX, XX },
539 /* 40 */
540 { "inc{S|}", RMeAX, XX, XX },
541 { "inc{S|}", RMeCX, XX, XX },
542 { "inc{S|}", RMeDX, XX, XX },
543 { "inc{S|}", RMeBX, XX, XX },
544 { "inc{S|}", RMeSP, XX, XX },
545 { "inc{S|}", RMeBP, XX, XX },
546 { "inc{S|}", RMeSI, XX, XX },
547 { "inc{S|}", RMeDI, XX, XX },
548 /* 48 */
549 { "dec{S|}", RMeAX, XX, XX },
550 { "dec{S|}", RMeCX, XX, XX },
551 { "dec{S|}", RMeDX, XX, XX },
552 { "dec{S|}", RMeBX, XX, XX },
553 { "dec{S|}", RMeSP, XX, XX },
554 { "dec{S|}", RMeBP, XX, XX },
555 { "dec{S|}", RMeSI, XX, XX },
556 { "dec{S|}", RMeDI, XX, XX },
557 /* 50 */
558 { "pushS", RMrAX, XX, XX },
559 { "pushS", RMrCX, XX, XX },
560 { "pushS", RMrDX, XX, XX },
561 { "pushS", RMrBX, XX, XX },
562 { "pushS", RMrSP, XX, XX },
563 { "pushS", RMrBP, XX, XX },
564 { "pushS", RMrSI, XX, XX },
565 { "pushS", RMrDI, XX, XX },
566 /* 58 */
567 { "popS", RMrAX, XX, XX },
568 { "popS", RMrCX, XX, XX },
569 { "popS", RMrDX, XX, XX },
570 { "popS", RMrBX, XX, XX },
571 { "popS", RMrSP, XX, XX },
572 { "popS", RMrBP, XX, XX },
573 { "popS", RMrSI, XX, XX },
574 { "popS", RMrDI, XX, XX },
575 /* 60 */
576 { "pusha{P|}", XX, XX, XX },
577 { "popa{P|}", XX, XX, XX },
578 { "bound{S|}", Gv, Ma, XX },
579 { X86_64_0 },
580 { "(bad)", XX, XX, XX }, /* seg fs */
581 { "(bad)", XX, XX, XX }, /* seg gs */
582 { "(bad)", XX, XX, XX }, /* op size prefix */
583 { "(bad)", XX, XX, XX }, /* adr size prefix */
584 /* 68 */
585 { "pushT", Iq, XX, XX },
586 { "imulS", Gv, Ev, Iv },
587 { "pushT", sIb, XX, XX },
588 { "imulS", Gv, Ev, sIb },
589 { "ins{b||b|}", Yb, indirDX, XX },
590 { "ins{R||R|}", Yv, indirDX, XX },
591 { "outs{b||b|}", indirDX, Xb, XX },
592 { "outs{R||R|}", indirDX, Xv, XX },
593 /* 70 */
594 { "joH", Jb, XX, cond_jump_flag },
595 { "jnoH", Jb, XX, cond_jump_flag },
596 { "jbH", Jb, XX, cond_jump_flag },
597 { "jaeH", Jb, XX, cond_jump_flag },
598 { "jeH", Jb, XX, cond_jump_flag },
599 { "jneH", Jb, XX, cond_jump_flag },
600 { "jbeH", Jb, XX, cond_jump_flag },
601 { "jaH", Jb, XX, cond_jump_flag },
602 /* 78 */
603 { "jsH", Jb, XX, cond_jump_flag },
604 { "jnsH", Jb, XX, cond_jump_flag },
605 { "jpH", Jb, XX, cond_jump_flag },
606 { "jnpH", Jb, XX, cond_jump_flag },
607 { "jlH", Jb, XX, cond_jump_flag },
608 { "jgeH", Jb, XX, cond_jump_flag },
609 { "jleH", Jb, XX, cond_jump_flag },
610 { "jgH", Jb, XX, cond_jump_flag },
611 /* 80 */
612 { GRP1b },
613 { GRP1S },
614 { "(bad)", XX, XX, XX },
615 { GRP1Ss },
616 { "testB", Eb, Gb, XX },
617 { "testS", Ev, Gv, XX },
618 { "xchgB", Eb, Gb, XX },
619 { "xchgS", Ev, Gv, XX },
620 /* 88 */
621 { "movB", Eb, Gb, XX },
622 { "movS", Ev, Gv, XX },
623 { "movB", Gb, Eb, XX },
624 { "movS", Gv, Ev, XX },
625 { "movQ", Ev, Sw, XX },
626 { "leaS", Gv, M, XX },
627 { "movQ", Sw, Ev, XX },
628 { "popU", Ev, XX, XX },
629 /* 90 */
630 { "nop", XX, XX, XX },
631 /* FIXME: NOP with REPz prefix is called PAUSE. */
632 { "xchgS", RMeCX, eAX, XX },
633 { "xchgS", RMeDX, eAX, XX },
634 { "xchgS", RMeBX, eAX, XX },
635 { "xchgS", RMeSP, eAX, XX },
636 { "xchgS", RMeBP, eAX, XX },
637 { "xchgS", RMeSI, eAX, XX },
638 { "xchgS", RMeDI, eAX, XX },
639 /* 98 */
640 { "cW{tR||tR|}", XX, XX, XX },
641 { "cR{tO||tO|}", XX, XX, XX },
642 { "lcall{T|}", Ap, XX, XX },
643 { "(bad)", XX, XX, XX }, /* fwait */
644 { "pushfT", XX, XX, XX },
645 { "popfT", XX, XX, XX },
646 { "sahf{|}", XX, XX, XX },
647 { "lahf{|}", XX, XX, XX },
648 /* a0 */
649 { "movB", AL, Ob64, XX },
650 { "movS", eAX, Ov64, XX },
651 { "movB", Ob64, AL, XX },
652 { "movS", Ov64, eAX, XX },
653 { "movs{b||b|}", Yb, Xb, XX },
654 { "movs{R||R|}", Yv, Xv, XX },
655 { "cmps{b||b|}", Xb, Yb, XX },
656 { "cmps{R||R|}", Xv, Yv, XX },
657 /* a8 */
658 { "testB", AL, Ib, XX },
659 { "testS", eAX, Iv, XX },
660 { "stosB", Yb, AL, XX },
661 { "stosS", Yv, eAX, XX },
662 { "lodsB", AL, Xb, XX },
663 { "lodsS", eAX, Xv, XX },
664 { "scasB", AL, Yb, XX },
665 { "scasS", eAX, Yv, XX },
666 /* b0 */
667 { "movB", RMAL, Ib, XX },
668 { "movB", RMCL, Ib, XX },
669 { "movB", RMDL, Ib, XX },
670 { "movB", RMBL, Ib, XX },
671 { "movB", RMAH, Ib, XX },
672 { "movB", RMCH, Ib, XX },
673 { "movB", RMDH, Ib, XX },
674 { "movB", RMBH, Ib, XX },
675 /* b8 */
676 { "movS", RMeAX, Iv64, XX },
677 { "movS", RMeCX, Iv64, XX },
678 { "movS", RMeDX, Iv64, XX },
679 { "movS", RMeBX, Iv64, XX },
680 { "movS", RMeSP, Iv64, XX },
681 { "movS", RMeBP, Iv64, XX },
682 { "movS", RMeSI, Iv64, XX },
683 { "movS", RMeDI, Iv64, XX },
684 /* c0 */
685 { GRP2b },
686 { GRP2S },
687 { "retT", Iw, XX, XX },
688 { "retT", XX, XX, XX },
689 { "les{S|}", Gv, Mp, XX },
690 { "ldsS", Gv, Mp, XX },
691 { "movA", Eb, Ib, XX },
692 { "movQ", Ev, Iv, XX },
693 /* c8 */
694 { "enterT", Iw, Ib, XX },
695 { "leaveT", XX, XX, XX },
696 { "lretP", Iw, XX, XX },
697 { "lretP", XX, XX, XX },
698 { "int3", XX, XX, XX },
699 { "int", Ib, XX, XX },
700 { "into{|}", XX, XX, XX },
701 { "iretP", XX, XX, XX },
702 /* d0 */
703 { GRP2b_one },
704 { GRP2S_one },
705 { GRP2b_cl },
706 { GRP2S_cl },
707 { "aam{|}", sIb, XX, XX },
708 { "aad{|}", sIb, XX, XX },
709 { "(bad)", XX, XX, XX },
710 { "xlat", DSBX, XX, XX },
711 /* d8 */
712 { FLOAT },
713 { FLOAT },
714 { FLOAT },
715 { FLOAT },
716 { FLOAT },
717 { FLOAT },
718 { FLOAT },
719 { FLOAT },
720 /* e0 */
721 { "loopneFH", Jb, XX, loop_jcxz_flag },
722 { "loopeFH", Jb, XX, loop_jcxz_flag },
723 { "loopFH", Jb, XX, loop_jcxz_flag },
724 { "jEcxzH", Jb, XX, loop_jcxz_flag },
725 { "inB", AL, Ib, XX },
726 { "inS", eAX, Ib, XX },
727 { "outB", Ib, AL, XX },
728 { "outS", Ib, eAX, XX },
729 /* e8 */
730 { "callT", Jv, XX, XX },
731 { "jmpT", Jv, XX, XX },
732 { "ljmp{T|}", Ap, XX, XX },
733 { "jmp", Jb, XX, XX },
734 { "inB", AL, indirDX, XX },
735 { "inS", eAX, indirDX, XX },
736 { "outB", indirDX, AL, XX },
737 { "outS", indirDX, eAX, XX },
738 /* f0 */
739 { "(bad)", XX, XX, XX }, /* lock prefix */
740 { "(bad)", XX, XX, XX },
741 { "(bad)", XX, XX, XX }, /* repne */
742 { "(bad)", XX, XX, XX }, /* repz */
743 { "hlt", XX, XX, XX },
744 { "cmc", XX, XX, XX },
745 { GRP3b },
746 { GRP3S },
747 /* f8 */
748 { "clc", XX, XX, XX },
749 { "stc", XX, XX, XX },
750 { "cli", XX, XX, XX },
751 { "sti", XX, XX, XX },
752 { "cld", XX, XX, XX },
753 { "std", XX, XX, XX },
754 { GRP4 },
755 { GRP5 },
756 };
757
758 static const struct dis386 dis386_twobyte[] = {
759 /* 00 */
760 { GRP6 },
761 { GRP7 },
762 { "larS", Gv, Ew, XX },
763 { "lslS", Gv, Ew, XX },
764 { "(bad)", XX, XX, XX },
765 { "syscall", XX, XX, XX },
766 { "clts", XX, XX, XX },
767 { "sysretP", XX, XX, XX },
768 /* 08 */
769 { "invd", XX, XX, XX },
770 { "wbinvd", XX, XX, XX },
771 { "(bad)", XX, XX, XX },
772 { "ud2a", XX, XX, XX },
773 { "(bad)", XX, XX, XX },
774 { GRPAMD },
775 { "femms", XX, XX, XX },
776 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
777 /* 10 */
778 { PREGRP8 },
779 { PREGRP9 },
780 { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
781 { "movlpX", EX, XM, SIMD_Fixup, 'h' },
782 { "unpcklpX", XM, EX, XX },
783 { "unpckhpX", XM, EX, XX },
784 { "movhpX", XM, EX, SIMD_Fixup, 'l' },
785 { "movhpX", EX, XM, SIMD_Fixup, 'l' },
786 /* 18 */
787 { GRP14 },
788 { "(bad)", XX, XX, XX },
789 { "(bad)", XX, XX, XX },
790 { "(bad)", XX, XX, XX },
791 { "(bad)", XX, XX, XX },
792 { "(bad)", XX, XX, XX },
793 { "(bad)", XX, XX, XX },
794 { "(bad)", XX, XX, XX },
795 /* 20 */
796 { "movL", Rm, Cm, XX },
797 { "movL", Rm, Dm, XX },
798 { "movL", Cm, Rm, XX },
799 { "movL", Dm, Rm, XX },
800 { "movL", Rd, Td, XX },
801 { "(bad)", XX, XX, XX },
802 { "movL", Td, Rd, XX },
803 { "(bad)", XX, XX, XX },
804 /* 28 */
805 { "movapX", XM, EX, XX },
806 { "movapX", EX, XM, XX },
807 { PREGRP2 },
808 { "movntpX", Ev, XM, XX },
809 { PREGRP4 },
810 { PREGRP3 },
811 { "ucomisX", XM,EX, XX },
812 { "comisX", XM,EX, XX },
813 /* 30 */
814 { "wrmsr", XX, XX, XX },
815 { "rdtsc", XX, XX, XX },
816 { "rdmsr", XX, XX, XX },
817 { "rdpmc", XX, XX, XX },
818 { "sysenter", XX, XX, XX },
819 { "sysexit", XX, XX, XX },
820 { "(bad)", XX, XX, XX },
821 { "(bad)", XX, XX, XX },
822 /* 38 */
823 { "(bad)", XX, XX, XX },
824 { "(bad)", XX, XX, XX },
825 { "(bad)", XX, XX, XX },
826 { "(bad)", XX, XX, XX },
827 { "(bad)", XX, XX, XX },
828 { "(bad)", XX, XX, XX },
829 { "(bad)", XX, XX, XX },
830 { "(bad)", XX, XX, XX },
831 /* 40 */
832 { "cmovo", Gv, Ev, XX },
833 { "cmovno", Gv, Ev, XX },
834 { "cmovb", Gv, Ev, XX },
835 { "cmovae", Gv, Ev, XX },
836 { "cmove", Gv, Ev, XX },
837 { "cmovne", Gv, Ev, XX },
838 { "cmovbe", Gv, Ev, XX },
839 { "cmova", Gv, Ev, XX },
840 /* 48 */
841 { "cmovs", Gv, Ev, XX },
842 { "cmovns", Gv, Ev, XX },
843 { "cmovp", Gv, Ev, XX },
844 { "cmovnp", Gv, Ev, XX },
845 { "cmovl", Gv, Ev, XX },
846 { "cmovge", Gv, Ev, XX },
847 { "cmovle", Gv, Ev, XX },
848 { "cmovg", Gv, Ev, XX },
849 /* 50 */
850 { "movmskpX", Gd, XS, XX },
851 { PREGRP13 },
852 { PREGRP12 },
853 { PREGRP11 },
854 { "andpX", XM, EX, XX },
855 { "andnpX", XM, EX, XX },
856 { "orpX", XM, EX, XX },
857 { "xorpX", XM, EX, XX },
858 /* 58 */
859 { PREGRP0 },
860 { PREGRP10 },
861 { PREGRP17 },
862 { PREGRP16 },
863 { PREGRP14 },
864 { PREGRP7 },
865 { PREGRP5 },
866 { PREGRP6 },
867 /* 60 */
868 { "punpcklbw", MX, EM, XX },
869 { "punpcklwd", MX, EM, XX },
870 { "punpckldq", MX, EM, XX },
871 { "packsswb", MX, EM, XX },
872 { "pcmpgtb", MX, EM, XX },
873 { "pcmpgtw", MX, EM, XX },
874 { "pcmpgtd", MX, EM, XX },
875 { "packuswb", MX, EM, XX },
876 /* 68 */
877 { "punpckhbw", MX, EM, XX },
878 { "punpckhwd", MX, EM, XX },
879 { "punpckhdq", MX, EM, XX },
880 { "packssdw", MX, EM, XX },
881 { PREGRP26 },
882 { PREGRP24 },
883 { "movd", MX, Ed, XX },
884 { PREGRP19 },
885 /* 70 */
886 { PREGRP22 },
887 { GRP10 },
888 { GRP11 },
889 { GRP12 },
890 { "pcmpeqb", MX, EM, XX },
891 { "pcmpeqw", MX, EM, XX },
892 { "pcmpeqd", MX, EM, XX },
893 { "emms", XX, XX, XX },
894 /* 78 */
895 { "(bad)", XX, XX, XX },
896 { "(bad)", XX, XX, XX },
897 { "(bad)", XX, XX, XX },
898 { "(bad)", XX, XX, XX },
899 { "(bad)", XX, XX, XX },
900 { "(bad)", XX, XX, XX },
901 { PREGRP23 },
902 { PREGRP20 },
903 /* 80 */
904 { "joH", Jv, XX, cond_jump_flag },
905 { "jnoH", Jv, XX, cond_jump_flag },
906 { "jbH", Jv, XX, cond_jump_flag },
907 { "jaeH", Jv, XX, cond_jump_flag },
908 { "jeH", Jv, XX, cond_jump_flag },
909 { "jneH", Jv, XX, cond_jump_flag },
910 { "jbeH", Jv, XX, cond_jump_flag },
911 { "jaH", Jv, XX, cond_jump_flag },
912 /* 88 */
913 { "jsH", Jv, XX, cond_jump_flag },
914 { "jnsH", Jv, XX, cond_jump_flag },
915 { "jpH", Jv, XX, cond_jump_flag },
916 { "jnpH", Jv, XX, cond_jump_flag },
917 { "jlH", Jv, XX, cond_jump_flag },
918 { "jgeH", Jv, XX, cond_jump_flag },
919 { "jleH", Jv, XX, cond_jump_flag },
920 { "jgH", Jv, XX, cond_jump_flag },
921 /* 90 */
922 { "seto", Eb, XX, XX },
923 { "setno", Eb, XX, XX },
924 { "setb", Eb, XX, XX },
925 { "setae", Eb, XX, XX },
926 { "sete", Eb, XX, XX },
927 { "setne", Eb, XX, XX },
928 { "setbe", Eb, XX, XX },
929 { "seta", Eb, XX, XX },
930 /* 98 */
931 { "sets", Eb, XX, XX },
932 { "setns", Eb, XX, XX },
933 { "setp", Eb, XX, XX },
934 { "setnp", Eb, XX, XX },
935 { "setl", Eb, XX, XX },
936 { "setge", Eb, XX, XX },
937 { "setle", Eb, XX, XX },
938 { "setg", Eb, XX, XX },
939 /* a0 */
940 { "pushT", fs, XX, XX },
941 { "popT", fs, XX, XX },
942 { "cpuid", XX, XX, XX },
943 { "btS", Ev, Gv, XX },
944 { "shldS", Ev, Gv, Ib },
945 { "shldS", Ev, Gv, CL },
946 { "(bad)", XX, XX, XX },
947 { "(bad)", XX, XX, XX },
948 /* a8 */
949 { "pushT", gs, XX, XX },
950 { "popT", gs, XX, XX },
951 { "rsm", XX, XX, XX },
952 { "btsS", Ev, Gv, XX },
953 { "shrdS", Ev, Gv, Ib },
954 { "shrdS", Ev, Gv, CL },
955 { GRP13 },
956 { "imulS", Gv, Ev, XX },
957 /* b0 */
958 { "cmpxchgB", Eb, Gb, XX },
959 { "cmpxchgS", Ev, Gv, XX },
960 { "lssS", Gv, Mp, XX },
961 { "btrS", Ev, Gv, XX },
962 { "lfsS", Gv, Mp, XX },
963 { "lgsS", Gv, Mp, XX },
964 { "movz{bR|x|bR|x}", Gv, Eb, XX },
965 { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */
966 /* b8 */
967 { "(bad)", XX, XX, XX },
968 { "ud2b", XX, XX, XX },
969 { GRP8 },
970 { "btcS", Ev, Gv, XX },
971 { "bsfS", Gv, Ev, XX },
972 { "bsrS", Gv, Ev, XX },
973 { "movs{bR|x|bR|x}", Gv, Eb, XX },
974 { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */
975 /* c0 */
976 { "xaddB", Eb, Gb, XX },
977 { "xaddS", Ev, Gv, XX },
978 { PREGRP1 },
979 { "movntiS", Ev, Gv, XX },
980 { "pinsrw", MX, Ed, Ib },
981 { "pextrw", Gd, MS, Ib },
982 { "shufpX", XM, EX, Ib },
983 { GRP9 },
984 /* c8 */
985 { "bswap", RMeAX, XX, XX },
986 { "bswap", RMeCX, XX, XX },
987 { "bswap", RMeDX, XX, XX },
988 { "bswap", RMeBX, XX, XX },
989 { "bswap", RMeSP, XX, XX },
990 { "bswap", RMeBP, XX, XX },
991 { "bswap", RMeSI, XX, XX },
992 { "bswap", RMeDI, XX, XX },
993 /* d0 */
994 { "(bad)", XX, XX, XX },
995 { "psrlw", MX, EM, XX },
996 { "psrld", MX, EM, XX },
997 { "psrlq", MX, EM, XX },
998 { "paddq", MX, EM, XX },
999 { "pmullw", MX, EM, XX },
1000 { PREGRP21 },
1001 { "pmovmskb", Gd, MS, XX },
1002 /* d8 */
1003 { "psubusb", MX, EM, XX },
1004 { "psubusw", MX, EM, XX },
1005 { "pminub", MX, EM, XX },
1006 { "pand", MX, EM, XX },
1007 { "paddusb", MX, EM, XX },
1008 { "paddusw", MX, EM, XX },
1009 { "pmaxub", MX, EM, XX },
1010 { "pandn", MX, EM, XX },
1011 /* e0 */
1012 { "pavgb", MX, EM, XX },
1013 { "psraw", MX, EM, XX },
1014 { "psrad", MX, EM, XX },
1015 { "pavgw", MX, EM, XX },
1016 { "pmulhuw", MX, EM, XX },
1017 { "pmulhw", MX, EM, XX },
1018 { PREGRP15 },
1019 { PREGRP25 },
1020 /* e8 */
1021 { "psubsb", MX, EM, XX },
1022 { "psubsw", MX, EM, XX },
1023 { "pminsw", MX, EM, XX },
1024 { "por", MX, EM, XX },
1025 { "paddsb", MX, EM, XX },
1026 { "paddsw", MX, EM, XX },
1027 { "pmaxsw", MX, EM, XX },
1028 { "pxor", MX, EM, XX },
1029 /* f0 */
1030 { "(bad)", XX, XX, XX },
1031 { "psllw", MX, EM, XX },
1032 { "pslld", MX, EM, XX },
1033 { "psllq", MX, EM, XX },
1034 { "pmuludq", MX, EM, XX },
1035 { "pmaddwd", MX, EM, XX },
1036 { "psadbw", MX, EM, XX },
1037 { PREGRP18 },
1038 /* f8 */
1039 { "psubb", MX, EM, XX },
1040 { "psubw", MX, EM, XX },
1041 { "psubd", MX, EM, XX },
1042 { "psubq", MX, EM, XX },
1043 { "paddb", MX, EM, XX },
1044 { "paddw", MX, EM, XX },
1045 { "paddd", MX, EM, XX },
1046 { "(bad)", XX, XX, XX }
1047 };
1048
1049 static const unsigned char onebyte_has_modrm[256] = {
1050 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1051 /* ------------------------------- */
1052 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1053 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1054 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1055 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1056 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1057 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1058 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1059 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1060 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1061 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1062 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1063 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1064 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1065 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1066 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1067 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1068 /* ------------------------------- */
1069 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1070 };
1071
1072 static const unsigned char twobyte_has_modrm[256] = {
1073 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1074 /* ------------------------------- */
1075 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1076 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1077 /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
1078 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1079 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1080 /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
1081 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
1082 /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
1083 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1084 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1085 /* a0 */ 0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1, /* af */
1086 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1087 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1088 /* d0 */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
1089 /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
1090 /* f0 */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
1091 /* ------------------------------- */
1092 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1093 };
1094
1095 static const unsigned char twobyte_uses_SSE_prefix[256] = {
1096 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1097 /* ------------------------------- */
1098 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1099 /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1100 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1101 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1102 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1103 /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
1104 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
1105 /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
1106 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1107 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1108 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1109 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1110 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1111 /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
1112 /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
1113 /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
1114 /* ------------------------------- */
1115 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1116 };
1117
1118 static char obuf[100];
1119 static char *obufp;
1120 static char scratchbuf[100];
1121 static unsigned char *start_codep;
1122 static unsigned char *insn_codep;
1123 static unsigned char *codep;
1124 static disassemble_info *the_info;
1125 static int mod;
1126 static int rm;
1127 static int reg;
1128 static unsigned char need_modrm;
1129
1130 /* If we are accessing mod/rm/reg without need_modrm set, then the
1131 values are stale. Hitting this abort likely indicates that you
1132 need to update onebyte_has_modrm or twobyte_has_modrm. */
1133 #define MODRM_CHECK if (!need_modrm) abort ()
1134
1135 static const char *names64[] = {
1136 "%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 { "sgdtQ", M, XX, XX },
1319 { "sidtQ", M, XX, XX },
1320 { "lgdtQ", M, XX, XX },
1321 { "lidtQ", M, 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 bfd_vma op_address[3];
1790 static bfd_vma 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 bfd_vma op;
3242 int riprel;
3243 {
3244 op_index[op_ad] = op_ad;
3245 if (mode_64bit)
3246 {
3247 op_address[op_ad] = op;
3248 op_riprel[op_ad] = riprel;
3249 }
3250 else
3251 {
3252 /* Mask to get a 32-bit address. */
3253 op_address[op_ad] = op & 0xffffffff;
3254 op_riprel[op_ad] = riprel & 0xffffffff;
3255 }
3256 }
3257
3258 static void
3259 OP_REG (code, sizeflag)
3260 int code;
3261 int sizeflag;
3262 {
3263 const char *s;
3264 int add = 0;
3265 USED_REX (REX_EXTZ);
3266 if (rex & REX_EXTZ)
3267 add = 8;
3268
3269 switch (code)
3270 {
3271 case indir_dx_reg:
3272 s = "(%dx)";
3273 break;
3274 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3275 case sp_reg: case bp_reg: case si_reg: case di_reg:
3276 s = names16[code - ax_reg + add];
3277 break;
3278 case es_reg: case ss_reg: case cs_reg:
3279 case ds_reg: case fs_reg: case gs_reg:
3280 s = names_seg[code - es_reg + add];
3281 break;
3282 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3283 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3284 USED_REX (0);
3285 if (rex)
3286 s = names8rex[code - al_reg + add];
3287 else
3288 s = names8[code - al_reg];
3289 break;
3290 case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
3291 case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
3292 if (mode_64bit)
3293 {
3294 s = names64[code - rAX_reg + add];
3295 break;
3296 }
3297 code += eAX_reg - rAX_reg;
3298 /* Fall through */
3299 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3300 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3301 USED_REX (REX_MODE64);
3302 if (rex & REX_MODE64)
3303 s = names64[code - eAX_reg + add];
3304 else if (sizeflag & DFLAG)
3305 s = names32[code - eAX_reg + add];
3306 else
3307 s = names16[code - eAX_reg + add];
3308 used_prefixes |= (prefixes & PREFIX_DATA);
3309 break;
3310 default:
3311 s = INTERNAL_DISASSEMBLER_ERROR;
3312 break;
3313 }
3314 oappend (s);
3315 }
3316
3317 static void
3318 OP_IMREG (code, sizeflag)
3319 int code;
3320 int sizeflag;
3321 {
3322 const char *s;
3323
3324 switch (code)
3325 {
3326 case indir_dx_reg:
3327 s = "(%dx)";
3328 break;
3329 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3330 case sp_reg: case bp_reg: case si_reg: case di_reg:
3331 s = names16[code - ax_reg];
3332 break;
3333 case es_reg: case ss_reg: case cs_reg:
3334 case ds_reg: case fs_reg: case gs_reg:
3335 s = names_seg[code - es_reg];
3336 break;
3337 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3338 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3339 USED_REX (0);
3340 if (rex)
3341 s = names8rex[code - al_reg];
3342 else
3343 s = names8[code - al_reg];
3344 break;
3345 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3346 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3347 USED_REX (REX_MODE64);
3348 if (rex & REX_MODE64)
3349 s = names64[code - eAX_reg];
3350 else if (sizeflag & DFLAG)
3351 s = names32[code - eAX_reg];
3352 else
3353 s = names16[code - eAX_reg];
3354 used_prefixes |= (prefixes & PREFIX_DATA);
3355 break;
3356 default:
3357 s = INTERNAL_DISASSEMBLER_ERROR;
3358 break;
3359 }
3360 oappend (s);
3361 }
3362
3363 static void
3364 OP_I (bytemode, sizeflag)
3365 int bytemode;
3366 int sizeflag;
3367 {
3368 bfd_signed_vma op;
3369 bfd_signed_vma mask = -1;
3370
3371 switch (bytemode)
3372 {
3373 case b_mode:
3374 FETCH_DATA (the_info, codep + 1);
3375 op = *codep++;
3376 mask = 0xff;
3377 break;
3378 case q_mode:
3379 if (mode_64bit)
3380 {
3381 op = get32s ();
3382 break;
3383 }
3384 /* Fall through */
3385 case v_mode:
3386 USED_REX (REX_MODE64);
3387 if (rex & REX_MODE64)
3388 op = get32s ();
3389 else if (sizeflag & DFLAG)
3390 {
3391 op = get32 ();
3392 mask = 0xffffffff;
3393 }
3394 else
3395 {
3396 op = get16 ();
3397 mask = 0xfffff;
3398 }
3399 used_prefixes |= (prefixes & PREFIX_DATA);
3400 break;
3401 case w_mode:
3402 mask = 0xfffff;
3403 op = get16 ();
3404 break;
3405 default:
3406 oappend (INTERNAL_DISASSEMBLER_ERROR);
3407 return;
3408 }
3409
3410 op &= mask;
3411 scratchbuf[0] = '$';
3412 print_operand_value (scratchbuf + !intel_syntax, 1, op);
3413 oappend (scratchbuf);
3414 scratchbuf[0] = '\0';
3415 }
3416
3417 static void
3418 OP_I64 (bytemode, sizeflag)
3419 int bytemode;
3420 int sizeflag;
3421 {
3422 bfd_signed_vma op;
3423 bfd_signed_vma mask = -1;
3424
3425 if (!mode_64bit)
3426 {
3427 OP_I (bytemode, sizeflag);
3428 return;
3429 }
3430
3431 switch (bytemode)
3432 {
3433 case b_mode:
3434 FETCH_DATA (the_info, codep + 1);
3435 op = *codep++;
3436 mask = 0xff;
3437 break;
3438 case v_mode:
3439 USED_REX (REX_MODE64);
3440 if (rex & REX_MODE64)
3441 op = get64 ();
3442 else if (sizeflag & DFLAG)
3443 {
3444 op = get32 ();
3445 mask = 0xffffffff;
3446 }
3447 else
3448 {
3449 op = get16 ();
3450 mask = 0xfffff;
3451 }
3452 used_prefixes |= (prefixes & PREFIX_DATA);
3453 break;
3454 case w_mode:
3455 mask = 0xfffff;
3456 op = get16 ();
3457 break;
3458 default:
3459 oappend (INTERNAL_DISASSEMBLER_ERROR);
3460 return;
3461 }
3462
3463 op &= mask;
3464 scratchbuf[0] = '$';
3465 print_operand_value (scratchbuf + !intel_syntax, 1, op);
3466 oappend (scratchbuf);
3467 scratchbuf[0] = '\0';
3468 }
3469
3470 static void
3471 OP_sI (bytemode, sizeflag)
3472 int bytemode;
3473 int sizeflag;
3474 {
3475 bfd_signed_vma op;
3476 bfd_signed_vma mask = -1;
3477
3478 switch (bytemode)
3479 {
3480 case b_mode:
3481 FETCH_DATA (the_info, codep + 1);
3482 op = *codep++;
3483 if ((op & 0x80) != 0)
3484 op -= 0x100;
3485 mask = 0xffffffff;
3486 break;
3487 case v_mode:
3488 USED_REX (REX_MODE64);
3489 if (rex & REX_MODE64)
3490 op = get32s ();
3491 else if (sizeflag & DFLAG)
3492 {
3493 op = get32s ();
3494 mask = 0xffffffff;
3495 }
3496 else
3497 {
3498 mask = 0xffffffff;
3499 op = get16();
3500 if ((op & 0x8000) != 0)
3501 op -= 0x10000;
3502 }
3503 used_prefixes |= (prefixes & PREFIX_DATA);
3504 break;
3505 case w_mode:
3506 op = get16 ();
3507 mask = 0xffffffff;
3508 if ((op & 0x8000) != 0)
3509 op -= 0x10000;
3510 break;
3511 default:
3512 oappend (INTERNAL_DISASSEMBLER_ERROR);
3513 return;
3514 }
3515
3516 scratchbuf[0] = '$';
3517 print_operand_value (scratchbuf + 1, 1, op);
3518 oappend (scratchbuf);
3519 }
3520
3521 static void
3522 OP_J (bytemode, sizeflag)
3523 int bytemode;
3524 int sizeflag;
3525 {
3526 bfd_vma disp;
3527 bfd_vma mask = -1;
3528
3529 switch (bytemode)
3530 {
3531 case b_mode:
3532 FETCH_DATA (the_info, codep + 1);
3533 disp = *codep++;
3534 if ((disp & 0x80) != 0)
3535 disp -= 0x100;
3536 break;
3537 case v_mode:
3538 if (sizeflag & DFLAG)
3539 disp = get32s ();
3540 else
3541 {
3542 disp = get16 ();
3543 /* for some reason, a data16 prefix on a jump instruction
3544 means that the pc is masked to 16 bits after the
3545 displacement is added! */
3546 mask = 0xffff;
3547 }
3548 break;
3549 default:
3550 oappend (INTERNAL_DISASSEMBLER_ERROR);
3551 return;
3552 }
3553 disp = (start_pc + codep - start_codep + disp) & mask;
3554 set_op (disp, 0);
3555 print_operand_value (scratchbuf, 1, disp);
3556 oappend (scratchbuf);
3557 }
3558
3559 static void
3560 OP_SEG (dummy, sizeflag)
3561 int dummy ATTRIBUTE_UNUSED;
3562 int sizeflag ATTRIBUTE_UNUSED;
3563 {
3564 static char *sreg[] = {
3565 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
3566 };
3567
3568 oappend (sreg[reg]);
3569 }
3570
3571 static void
3572 OP_DIR (dummy, sizeflag)
3573 int dummy ATTRIBUTE_UNUSED;
3574 int sizeflag;
3575 {
3576 int seg, offset;
3577
3578 if (sizeflag & DFLAG)
3579 {
3580 offset = get32 ();
3581 seg = get16 ();
3582 }
3583 else
3584 {
3585 offset = get16 ();
3586 seg = get16 ();
3587 }
3588 used_prefixes |= (prefixes & PREFIX_DATA);
3589 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3590 oappend (scratchbuf);
3591 }
3592
3593 static void
3594 OP_OFF (bytemode, sizeflag)
3595 int bytemode ATTRIBUTE_UNUSED;
3596 int sizeflag;
3597 {
3598 bfd_vma off;
3599
3600 append_seg ();
3601
3602 if (sizeflag & AFLAG)
3603 off = get32 ();
3604 else
3605 off = get16 ();
3606
3607 if (intel_syntax)
3608 {
3609 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3610 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3611 {
3612 oappend (names_seg[3]);
3613 oappend (":");
3614 }
3615 }
3616 print_operand_value (scratchbuf, 1, off);
3617 oappend (scratchbuf);
3618 }
3619
3620 static void
3621 OP_OFF64 (bytemode, sizeflag)
3622 int bytemode ATTRIBUTE_UNUSED;
3623 int sizeflag ATTRIBUTE_UNUSED;
3624 {
3625 bfd_vma off;
3626
3627 if (!mode_64bit)
3628 {
3629 OP_OFF (bytemode, sizeflag);
3630 return;
3631 }
3632
3633 append_seg ();
3634
3635 off = get64();
3636
3637 if (intel_syntax)
3638 {
3639 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3640 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3641 {
3642 oappend (names_seg[3]);
3643 oappend (":");
3644 }
3645 }
3646 print_operand_value (scratchbuf, 1, off);
3647 oappend (scratchbuf);
3648 }
3649
3650 static void
3651 ptr_reg (code, sizeflag)
3652 int code;
3653 int sizeflag;
3654 {
3655 const char *s;
3656 oappend ("(");
3657 USED_REX (REX_MODE64);
3658 if (rex & REX_MODE64)
3659 s = names64[code - eAX_reg];
3660 else if (sizeflag & AFLAG)
3661 s = names32[code - eAX_reg];
3662 else
3663 s = names16[code - eAX_reg];
3664 oappend (s);
3665 oappend (")");
3666 }
3667
3668 static void
3669 OP_ESreg (code, sizeflag)
3670 int code;
3671 int sizeflag;
3672 {
3673 oappend ("%es:");
3674 ptr_reg (code, sizeflag);
3675 }
3676
3677 static void
3678 OP_DSreg (code, sizeflag)
3679 int code;
3680 int sizeflag;
3681 {
3682 if ((prefixes
3683 & (PREFIX_CS
3684 | PREFIX_DS
3685 | PREFIX_SS
3686 | PREFIX_ES
3687 | PREFIX_FS
3688 | PREFIX_GS)) == 0)
3689 prefixes |= PREFIX_DS;
3690 append_seg();
3691 ptr_reg (code, sizeflag);
3692 }
3693
3694 static void
3695 OP_C (dummy, sizeflag)
3696 int dummy ATTRIBUTE_UNUSED;
3697 int sizeflag ATTRIBUTE_UNUSED;
3698 {
3699 int add = 0;
3700 USED_REX (REX_EXTX);
3701 if (rex & REX_EXTX)
3702 add = 8;
3703 sprintf (scratchbuf, "%%cr%d", reg+add);
3704 oappend (scratchbuf);
3705 }
3706
3707 static void
3708 OP_D (dummy, sizeflag)
3709 int dummy ATTRIBUTE_UNUSED;
3710 int sizeflag ATTRIBUTE_UNUSED;
3711 {
3712 int add = 0;
3713 USED_REX (REX_EXTX);
3714 if (rex & REX_EXTX)
3715 add = 8;
3716 sprintf (scratchbuf, "%%db%d", reg+add);
3717 oappend (scratchbuf);
3718 }
3719
3720 static void
3721 OP_T (dummy, sizeflag)
3722 int dummy ATTRIBUTE_UNUSED;
3723 int sizeflag ATTRIBUTE_UNUSED;
3724 {
3725 sprintf (scratchbuf, "%%tr%d", reg);
3726 oappend (scratchbuf);
3727 }
3728
3729 static void
3730 OP_Rd (bytemode, sizeflag)
3731 int bytemode;
3732 int sizeflag;
3733 {
3734 if (mod == 3)
3735 OP_E (bytemode, sizeflag);
3736 else
3737 BadOp();
3738 }
3739
3740 static void
3741 OP_MMX (bytemode, sizeflag)
3742 int bytemode ATTRIBUTE_UNUSED;
3743 int sizeflag ATTRIBUTE_UNUSED;
3744 {
3745 int add = 0;
3746 USED_REX (REX_EXTX);
3747 if (rex & REX_EXTX)
3748 add = 8;
3749 used_prefixes |= (prefixes & PREFIX_DATA);
3750 if (prefixes & PREFIX_DATA)
3751 sprintf (scratchbuf, "%%xmm%d", reg + add);
3752 else
3753 sprintf (scratchbuf, "%%mm%d", reg + add);
3754 oappend (scratchbuf);
3755 }
3756
3757 static void
3758 OP_XMM (bytemode, sizeflag)
3759 int bytemode ATTRIBUTE_UNUSED;
3760 int sizeflag ATTRIBUTE_UNUSED;
3761 {
3762 int add = 0;
3763 USED_REX (REX_EXTX);
3764 if (rex & REX_EXTX)
3765 add = 8;
3766 sprintf (scratchbuf, "%%xmm%d", reg + add);
3767 oappend (scratchbuf);
3768 }
3769
3770 static void
3771 OP_EM (bytemode, sizeflag)
3772 int bytemode;
3773 int sizeflag;
3774 {
3775 int add = 0;
3776 if (mod != 3)
3777 {
3778 OP_E (bytemode, sizeflag);
3779 return;
3780 }
3781 USED_REX (REX_EXTZ);
3782 if (rex & REX_EXTZ)
3783 add = 8;
3784
3785 /* skip mod/rm byte */
3786 MODRM_CHECK;
3787 codep++;
3788 used_prefixes |= (prefixes & PREFIX_DATA);
3789 if (prefixes & PREFIX_DATA)
3790 sprintf (scratchbuf, "%%xmm%d", rm + add);
3791 else
3792 sprintf (scratchbuf, "%%mm%d", rm + add);
3793 oappend (scratchbuf);
3794 }
3795
3796 static void
3797 OP_EX (bytemode, sizeflag)
3798 int bytemode;
3799 int sizeflag;
3800 {
3801 int add = 0;
3802 if (mod != 3)
3803 {
3804 OP_E (bytemode, sizeflag);
3805 return;
3806 }
3807 USED_REX (REX_EXTZ);
3808 if (rex & REX_EXTZ)
3809 add = 8;
3810
3811 /* skip mod/rm byte */
3812 MODRM_CHECK;
3813 codep++;
3814 sprintf (scratchbuf, "%%xmm%d", rm + add);
3815 oappend (scratchbuf);
3816 }
3817
3818 static void
3819 OP_MS (bytemode, sizeflag)
3820 int bytemode;
3821 int sizeflag;
3822 {
3823 if (mod == 3)
3824 OP_EM (bytemode, sizeflag);
3825 else
3826 BadOp();
3827 }
3828
3829 static void
3830 OP_XS (bytemode, sizeflag)
3831 int bytemode;
3832 int sizeflag;
3833 {
3834 if (mod == 3)
3835 OP_EX (bytemode, sizeflag);
3836 else
3837 BadOp();
3838 }
3839
3840 static const char *Suffix3DNow[] = {
3841 /* 00 */ NULL, NULL, NULL, NULL,
3842 /* 04 */ NULL, NULL, NULL, NULL,
3843 /* 08 */ NULL, NULL, NULL, NULL,
3844 /* 0C */ "pi2fw", "pi2fd", NULL, NULL,
3845 /* 10 */ NULL, NULL, NULL, NULL,
3846 /* 14 */ NULL, NULL, NULL, NULL,
3847 /* 18 */ NULL, NULL, NULL, NULL,
3848 /* 1C */ "pf2iw", "pf2id", NULL, NULL,
3849 /* 20 */ NULL, NULL, NULL, NULL,
3850 /* 24 */ NULL, NULL, NULL, NULL,
3851 /* 28 */ NULL, NULL, NULL, NULL,
3852 /* 2C */ NULL, NULL, NULL, NULL,
3853 /* 30 */ NULL, NULL, NULL, NULL,
3854 /* 34 */ NULL, NULL, NULL, NULL,
3855 /* 38 */ NULL, NULL, NULL, NULL,
3856 /* 3C */ NULL, NULL, NULL, NULL,
3857 /* 40 */ NULL, NULL, NULL, NULL,
3858 /* 44 */ NULL, NULL, NULL, NULL,
3859 /* 48 */ NULL, NULL, NULL, NULL,
3860 /* 4C */ NULL, NULL, NULL, NULL,
3861 /* 50 */ NULL, NULL, NULL, NULL,
3862 /* 54 */ NULL, NULL, NULL, NULL,
3863 /* 58 */ NULL, NULL, NULL, NULL,
3864 /* 5C */ NULL, NULL, NULL, NULL,
3865 /* 60 */ NULL, NULL, NULL, NULL,
3866 /* 64 */ NULL, NULL, NULL, NULL,
3867 /* 68 */ NULL, NULL, NULL, NULL,
3868 /* 6C */ NULL, NULL, NULL, NULL,
3869 /* 70 */ NULL, NULL, NULL, NULL,
3870 /* 74 */ NULL, NULL, NULL, NULL,
3871 /* 78 */ NULL, NULL, NULL, NULL,
3872 /* 7C */ NULL, NULL, NULL, NULL,
3873 /* 80 */ NULL, NULL, NULL, NULL,
3874 /* 84 */ NULL, NULL, NULL, NULL,
3875 /* 88 */ NULL, NULL, "pfnacc", NULL,
3876 /* 8C */ NULL, NULL, "pfpnacc", NULL,
3877 /* 90 */ "pfcmpge", NULL, NULL, NULL,
3878 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
3879 /* 98 */ NULL, NULL, "pfsub", NULL,
3880 /* 9C */ NULL, NULL, "pfadd", NULL,
3881 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
3882 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
3883 /* A8 */ NULL, NULL, "pfsubr", NULL,
3884 /* AC */ NULL, NULL, "pfacc", NULL,
3885 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
3886 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
3887 /* B8 */ NULL, NULL, NULL, "pswapd",
3888 /* BC */ NULL, NULL, NULL, "pavgusb",
3889 /* C0 */ NULL, NULL, NULL, NULL,
3890 /* C4 */ NULL, NULL, NULL, NULL,
3891 /* C8 */ NULL, NULL, NULL, NULL,
3892 /* CC */ NULL, NULL, NULL, NULL,
3893 /* D0 */ NULL, NULL, NULL, NULL,
3894 /* D4 */ NULL, NULL, NULL, NULL,
3895 /* D8 */ NULL, NULL, NULL, NULL,
3896 /* DC */ NULL, NULL, NULL, NULL,
3897 /* E0 */ NULL, NULL, NULL, NULL,
3898 /* E4 */ NULL, NULL, NULL, NULL,
3899 /* E8 */ NULL, NULL, NULL, NULL,
3900 /* EC */ NULL, NULL, NULL, NULL,
3901 /* F0 */ NULL, NULL, NULL, NULL,
3902 /* F4 */ NULL, NULL, NULL, NULL,
3903 /* F8 */ NULL, NULL, NULL, NULL,
3904 /* FC */ NULL, NULL, NULL, NULL,
3905 };
3906
3907 static void
3908 OP_3DNowSuffix (bytemode, sizeflag)
3909 int bytemode ATTRIBUTE_UNUSED;
3910 int sizeflag ATTRIBUTE_UNUSED;
3911 {
3912 const char *mnemonic;
3913
3914 FETCH_DATA (the_info, codep + 1);
3915 /* AMD 3DNow! instructions are specified by an opcode suffix in the
3916 place where an 8-bit immediate would normally go. ie. the last
3917 byte of the instruction. */
3918 obufp = obuf + strlen(obuf);
3919 mnemonic = Suffix3DNow[*codep++ & 0xff];
3920 if (mnemonic)
3921 oappend (mnemonic);
3922 else
3923 {
3924 /* Since a variable sized modrm/sib chunk is between the start
3925 of the opcode (0x0f0f) and the opcode suffix, we need to do
3926 all the modrm processing first, and don't know until now that
3927 we have a bad opcode. This necessitates some cleaning up. */
3928 op1out[0] = '\0';
3929 op2out[0] = '\0';
3930 BadOp();
3931 }
3932 }
3933
3934
3935 static const char *simd_cmp_op [] = {
3936 "eq",
3937 "lt",
3938 "le",
3939 "unord",
3940 "neq",
3941 "nlt",
3942 "nle",
3943 "ord"
3944 };
3945
3946 static void
3947 OP_SIMD_Suffix (bytemode, sizeflag)
3948 int bytemode ATTRIBUTE_UNUSED;
3949 int sizeflag ATTRIBUTE_UNUSED;
3950 {
3951 unsigned int cmp_type;
3952
3953 FETCH_DATA (the_info, codep + 1);
3954 obufp = obuf + strlen(obuf);
3955 cmp_type = *codep++ & 0xff;
3956 if (cmp_type < 8)
3957 {
3958 char suffix1 = 'p', suffix2 = 's';
3959 used_prefixes |= (prefixes & PREFIX_REPZ);
3960 if (prefixes & PREFIX_REPZ)
3961 suffix1 = 's';
3962 else
3963 {
3964 used_prefixes |= (prefixes & PREFIX_DATA);
3965 if (prefixes & PREFIX_DATA)
3966 suffix2 = 'd';
3967 else
3968 {
3969 used_prefixes |= (prefixes & PREFIX_REPNZ);
3970 if (prefixes & PREFIX_REPNZ)
3971 suffix1 = 's', suffix2 = 'd';
3972 }
3973 }
3974 sprintf (scratchbuf, "cmp%s%c%c",
3975 simd_cmp_op[cmp_type], suffix1, suffix2);
3976 used_prefixes |= (prefixes & PREFIX_REPZ);
3977 oappend (scratchbuf);
3978 }
3979 else
3980 {
3981 /* We have a bad extension byte. Clean up. */
3982 op1out[0] = '\0';
3983 op2out[0] = '\0';
3984 BadOp();
3985 }
3986 }
3987
3988 static void
3989 SIMD_Fixup (extrachar, sizeflag)
3990 int extrachar;
3991 int sizeflag ATTRIBUTE_UNUSED;
3992 {
3993 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
3994 forms of these instructions. */
3995 if (mod == 3)
3996 {
3997 char *p = obuf + strlen(obuf);
3998 *(p+1) = '\0';
3999 *p = *(p-1);
4000 *(p-1) = *(p-2);
4001 *(p-2) = *(p-3);
4002 *(p-3) = extrachar;
4003 }
4004 }
4005
4006 static void BadOp (void)
4007 {
4008 codep = insn_codep + 1; /* throw away prefixes and 1st. opcode byte */
4009 oappend ("(bad)");
4010 }
This page took 0.115149 seconds and 5 git commands to generate.