9d36eeb8e0dd56e9345963ea55800b84af6fc2da
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
1 /* Print i386 instructions for GDB, the GNU debugger.
2 Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 98, 1999
3 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21 /*
22 * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
23 * July 1988
24 * modified by John Hassey (hassey@dg-rtp.dg.com)
25 */
26
27 /*
28 * The main tables describing the instructions is essentially a copy
29 * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
30 * Programmers Manual. Usually, there is a capital letter, followed
31 * by a small letter. The capital letter tell the addressing mode,
32 * and the small letter tells about the operand size. Refer to
33 * the Intel manual for details.
34 */
35
36 #include "dis-asm.h"
37 #include "sysdep.h"
38 #include "opintl.h"
39
40 #define MAXLEN 20
41
42 #include <setjmp.h>
43
44 #ifndef UNIXWARE_COMPAT
45 /* Set non-zero for broken, compatible instructions. Set to zero for
46 non-broken opcodes. */
47 #define UNIXWARE_COMPAT 1
48 #endif
49
50
51 static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
52
53 struct dis_private
54 {
55 /* Points to first byte not fetched. */
56 bfd_byte *max_fetched;
57 bfd_byte the_buffer[MAXLEN];
58 bfd_vma insn_start;
59 jmp_buf bailout;
60 };
61
62 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
63 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
64 on error. */
65 #define FETCH_DATA(info, addr) \
66 ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
67 ? 1 : fetch_data ((info), (addr)))
68
69 static int
70 fetch_data (info, addr)
71 struct disassemble_info *info;
72 bfd_byte *addr;
73 {
74 int status;
75 struct dis_private *priv = (struct dis_private *)info->private_data;
76 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
77
78 status = (*info->read_memory_func) (start,
79 priv->max_fetched,
80 addr - priv->max_fetched,
81 info);
82 if (status != 0)
83 {
84 (*info->memory_error_func) (status, start, info);
85 longjmp (priv->bailout, 1);
86 }
87 else
88 priv->max_fetched = addr;
89 return 1;
90 }
91
92 #define Eb OP_E, b_mode
93 #define indirEb OP_indirE, b_mode
94 #define Gb OP_G, b_mode
95 #define Ev OP_E, v_mode
96 #define indirEv OP_indirE, v_mode
97 #define Ew OP_E, w_mode
98 #define Ma OP_E, v_mode
99 #define M OP_E, 0
100 #define Mp OP_E, 0 /* ? */
101 #define Gv OP_G, v_mode
102 #define Gw OP_G, w_mode
103 #define Rw OP_rm, w_mode
104 #define Rd OP_rm, d_mode
105 #define Ib OP_I, b_mode
106 #define sIb OP_sI, b_mode /* sign extened byte */
107 #define Iv OP_I, v_mode
108 #define Iw OP_I, w_mode
109 #define Jb OP_J, b_mode
110 #define Jv OP_J, v_mode
111 #if 0
112 #define ONE OP_ONE, 0
113 #endif
114 #define Cd OP_C, d_mode
115 #define Dd OP_D, d_mode
116 #define Td OP_T, d_mode
117
118 #define eAX OP_REG, eAX_reg
119 #define eBX OP_REG, eBX_reg
120 #define eCX OP_REG, eCX_reg
121 #define eDX OP_REG, eDX_reg
122 #define eSP OP_REG, eSP_reg
123 #define eBP OP_REG, eBP_reg
124 #define eSI OP_REG, eSI_reg
125 #define eDI OP_REG, eDI_reg
126 #define AL OP_REG, al_reg
127 #define CL OP_REG, cl_reg
128 #define DL OP_REG, dl_reg
129 #define BL OP_REG, bl_reg
130 #define AH OP_REG, ah_reg
131 #define CH OP_REG, ch_reg
132 #define DH OP_REG, dh_reg
133 #define BH OP_REG, bh_reg
134 #define AX OP_REG, ax_reg
135 #define DX OP_REG, dx_reg
136 #define indirDX OP_REG, indir_dx_reg
137
138 #define Sw OP_SEG, w_mode
139 #define Ap OP_DIR, 0
140 #define Ob OP_OFF, b_mode
141 #define Ov OP_OFF, v_mode
142 #define Xb OP_DSreg, eSI_reg
143 #define Xv OP_DSreg, eSI_reg
144 #define Yb OP_ESreg, eDI_reg
145 #define Yv OP_ESreg, eDI_reg
146 #define DSBX OP_DSreg, eBX_reg
147
148 #define es OP_REG, es_reg
149 #define ss OP_REG, ss_reg
150 #define cs OP_REG, cs_reg
151 #define ds OP_REG, ds_reg
152 #define fs OP_REG, fs_reg
153 #define gs OP_REG, gs_reg
154
155 #define MX OP_MMX, 0
156 #define XM OP_XMM, 0
157 #define EM OP_EM, v_mode
158 #define EX OP_EX, v_mode
159 #define MS OP_MS, b_mode
160 #define None OP_E, 0
161 #define OPSUF OP_3DNowSuffix, 0
162 #define OPSIMD OP_SIMD_Suffix, 0
163
164 /* bits in sizeflag */
165 #if 0 /* leave undefined until someone adds the extra flag to objdump */
166 #define SUFFIX_ALWAYS 4
167 #endif
168 #define AFLAG 2
169 #define DFLAG 1
170
171 typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag ));
172
173 static void OP_E PARAMS ((int, int));
174 static void OP_G PARAMS ((int, int));
175 static void OP_I PARAMS ((int, int));
176 static void OP_indirE PARAMS ((int, int));
177 static void OP_sI PARAMS ((int, int));
178 static void OP_REG PARAMS ((int, int));
179 static void OP_J PARAMS ((int, int));
180 static void OP_DIR PARAMS ((int, int));
181 static void OP_OFF PARAMS ((int, int));
182 static void OP_ESreg PARAMS ((int, int));
183 static void OP_DSreg PARAMS ((int, int));
184 static void OP_SEG PARAMS ((int, int));
185 static void OP_C PARAMS ((int, int));
186 static void OP_D PARAMS ((int, int));
187 static void OP_T PARAMS ((int, int));
188 static void OP_rm PARAMS ((int, int));
189 static void OP_ST PARAMS ((int, int));
190 static void OP_STi PARAMS ((int, int));
191 #if 0
192 static void OP_ONE PARAMS ((int, int));
193 #endif
194 static void OP_MMX PARAMS ((int, int));
195 static void OP_XMM PARAMS ((int, int));
196 static void OP_EM PARAMS ((int, int));
197 static void OP_EX PARAMS ((int, int));
198 static void OP_MS PARAMS ((int, int));
199 static void OP_3DNowSuffix PARAMS ((int, int));
200 static void OP_SIMD_Suffix PARAMS ((int, int));
201 static void SIMD_Fixup PARAMS ((int, int));
202
203 static void append_seg PARAMS ((void));
204 static void set_op PARAMS ((unsigned int op));
205 static void putop PARAMS ((char *template, int sizeflag));
206 static void dofloat PARAMS ((int sizeflag));
207 static int get16 PARAMS ((void));
208 static int get32 PARAMS ((void));
209 static void ckprefix PARAMS ((void));
210 static void ptr_reg PARAMS ((int, int));
211
212 #define b_mode 1
213 #define v_mode 2
214 #define w_mode 3
215 #define d_mode 4
216 #define x_mode 5
217
218 #define es_reg 100
219 #define cs_reg 101
220 #define ss_reg 102
221 #define ds_reg 103
222 #define fs_reg 104
223 #define gs_reg 105
224
225 #define eAX_reg 108
226 #define eCX_reg 109
227 #define eDX_reg 110
228 #define eBX_reg 111
229 #define eSP_reg 112
230 #define eBP_reg 113
231 #define eSI_reg 114
232 #define eDI_reg 115
233
234 #define al_reg 116
235 #define cl_reg 117
236 #define dl_reg 118
237 #define bl_reg 119
238 #define ah_reg 120
239 #define ch_reg 121
240 #define dh_reg 122
241 #define bh_reg 123
242
243 #define ax_reg 124
244 #define cx_reg 125
245 #define dx_reg 126
246 #define bx_reg 127
247 #define sp_reg 128
248 #define bp_reg 129
249 #define si_reg 130
250 #define di_reg 131
251
252 #define indir_dx_reg 150
253
254 #define USE_GROUPS 1
255 #define USE_PREFIX_USER_TABLE 2
256
257 #define GRP1b NULL, NULL, 0, NULL, USE_GROUPS
258 #define GRP1S NULL, NULL, 1, NULL, USE_GROUPS
259 #define GRP1Ss NULL, NULL, 2, NULL, USE_GROUPS
260 #define GRP2b NULL, NULL, 3, NULL, USE_GROUPS
261 #define GRP2S NULL, NULL, 4, NULL, USE_GROUPS
262 #define GRP2b_one NULL, NULL, 5, NULL, USE_GROUPS
263 #define GRP2S_one NULL, NULL, 6, NULL, USE_GROUPS
264 #define GRP2b_cl NULL, NULL, 7, NULL, USE_GROUPS
265 #define GRP2S_cl NULL, NULL, 8, NULL, USE_GROUPS
266 #define GRP3b NULL, NULL, 9, NULL, USE_GROUPS
267 #define GRP3S NULL, NULL, 10, NULL, USE_GROUPS
268 #define GRP4 NULL, NULL, 11, NULL, USE_GROUPS
269 #define GRP5 NULL, NULL, 12, NULL, USE_GROUPS
270 #define GRP6 NULL, NULL, 13, NULL, USE_GROUPS
271 #define GRP7 NULL, NULL, 14, NULL, USE_GROUPS
272 #define GRP8 NULL, NULL, 15, NULL, USE_GROUPS
273 #define GRP9 NULL, NULL, 16, NULL, USE_GROUPS
274 #define GRP10 NULL, NULL, 17, NULL, USE_GROUPS
275 #define GRP11 NULL, NULL, 18, NULL, USE_GROUPS
276 #define GRP12 NULL, NULL, 19, NULL, USE_GROUPS
277 #define GRP13 NULL, NULL, 20, NULL, USE_GROUPS
278 #define GRP14 NULL, NULL, 21, NULL, USE_GROUPS
279 #define GRPAMD NULL, NULL, 22, NULL, USE_GROUPS
280
281 #define PREGRP0 NULL, NULL, 0, NULL, USE_PREFIX_USER_TABLE
282 #define PREGRP1 NULL, NULL, 1, NULL, USE_PREFIX_USER_TABLE
283 #define PREGRP2 NULL, NULL, 2, NULL, USE_PREFIX_USER_TABLE
284 #define PREGRP3 NULL, NULL, 3, NULL, USE_PREFIX_USER_TABLE
285 #define PREGRP4 NULL, NULL, 4, NULL, USE_PREFIX_USER_TABLE
286 #define PREGRP5 NULL, NULL, 5, NULL, USE_PREFIX_USER_TABLE
287 #define PREGRP6 NULL, NULL, 6, NULL, USE_PREFIX_USER_TABLE
288 #define PREGRP7 NULL, NULL, 7, NULL, USE_PREFIX_USER_TABLE
289 #define PREGRP8 NULL, NULL, 8, NULL, USE_PREFIX_USER_TABLE
290 #define PREGRP9 NULL, NULL, 9, NULL, USE_PREFIX_USER_TABLE
291 #define PREGRP10 NULL, NULL, 10, NULL, USE_PREFIX_USER_TABLE
292 #define PREGRP11 NULL, NULL, 11, NULL, USE_PREFIX_USER_TABLE
293 #define PREGRP12 NULL, NULL, 12, NULL, USE_PREFIX_USER_TABLE
294 #define PREGRP13 NULL, NULL, 13, NULL, USE_PREFIX_USER_TABLE
295 #define PREGRP14 NULL, NULL, 14, NULL, USE_PREFIX_USER_TABLE
296
297 #define FLOATCODE 50
298 #define FLOAT NULL, NULL, FLOATCODE
299
300 struct dis386 {
301 char *name;
302 op_rtn op1;
303 int bytemode1;
304 op_rtn op2;
305 int bytemode2;
306 op_rtn op3;
307 int bytemode3;
308 };
309
310 /* Upper case letters in the instruction names here are macros.
311 'A' => print 'b' if no register operands or suffix_always is true
312 'B' => print 'b' if suffix_always is true
313 'E' => print 'e' if 32-bit form of jcxz
314 'L' => print 'l' if suffix_always is true
315 'N' => print 'n' if instruction has no wait "prefix"
316 'P' => print 'w' or 'l' if instruction has an operand size prefix,
317 or suffix_always is true
318 'Q' => print 'w' or 'l' if no register operands or suffix_always is true
319 'R' => print 'w' or 'l'
320 'S' => print 'w' or 'l' if suffix_always is true
321 'W' => print 'b' or 'w'
322 */
323
324 static struct dis386 dis386_att[] = {
325 /* 00 */
326 { "addB", Eb, Gb },
327 { "addS", Ev, Gv },
328 { "addB", Gb, Eb },
329 { "addS", Gv, Ev },
330 { "addB", AL, Ib },
331 { "addS", eAX, Iv },
332 { "pushP", es },
333 { "popP", es },
334 /* 08 */
335 { "orB", Eb, Gb },
336 { "orS", Ev, Gv },
337 { "orB", Gb, Eb },
338 { "orS", Gv, Ev },
339 { "orB", AL, Ib },
340 { "orS", eAX, Iv },
341 { "pushP", cs },
342 { "(bad)" }, /* 0x0f extended opcode escape */
343 /* 10 */
344 { "adcB", Eb, Gb },
345 { "adcS", Ev, Gv },
346 { "adcB", Gb, Eb },
347 { "adcS", Gv, Ev },
348 { "adcB", AL, Ib },
349 { "adcS", eAX, Iv },
350 { "pushP", ss },
351 { "popP", ss },
352 /* 18 */
353 { "sbbB", Eb, Gb },
354 { "sbbS", Ev, Gv },
355 { "sbbB", Gb, Eb },
356 { "sbbS", Gv, Ev },
357 { "sbbB", AL, Ib },
358 { "sbbS", eAX, Iv },
359 { "pushP", ds },
360 { "popP", ds },
361 /* 20 */
362 { "andB", Eb, Gb },
363 { "andS", Ev, Gv },
364 { "andB", Gb, Eb },
365 { "andS", Gv, Ev },
366 { "andB", AL, Ib },
367 { "andS", eAX, Iv },
368 { "(bad)" }, /* SEG ES prefix */
369 { "daa" },
370 /* 28 */
371 { "subB", Eb, Gb },
372 { "subS", Ev, Gv },
373 { "subB", Gb, Eb },
374 { "subS", Gv, Ev },
375 { "subB", AL, Ib },
376 { "subS", eAX, Iv },
377 { "(bad)" }, /* SEG CS prefix */
378 { "das" },
379 /* 30 */
380 { "xorB", Eb, Gb },
381 { "xorS", Ev, Gv },
382 { "xorB", Gb, Eb },
383 { "xorS", Gv, Ev },
384 { "xorB", AL, Ib },
385 { "xorS", eAX, Iv },
386 { "(bad)" }, /* SEG SS prefix */
387 { "aaa" },
388 /* 38 */
389 { "cmpB", Eb, Gb },
390 { "cmpS", Ev, Gv },
391 { "cmpB", Gb, Eb },
392 { "cmpS", Gv, Ev },
393 { "cmpB", AL, Ib },
394 { "cmpS", eAX, Iv },
395 { "(bad)" }, /* SEG DS prefix */
396 { "aas" },
397 /* 40 */
398 { "incS", eAX },
399 { "incS", eCX },
400 { "incS", eDX },
401 { "incS", eBX },
402 { "incS", eSP },
403 { "incS", eBP },
404 { "incS", eSI },
405 { "incS", eDI },
406 /* 48 */
407 { "decS", eAX },
408 { "decS", eCX },
409 { "decS", eDX },
410 { "decS", eBX },
411 { "decS", eSP },
412 { "decS", eBP },
413 { "decS", eSI },
414 { "decS", eDI },
415 /* 50 */
416 { "pushS", eAX },
417 { "pushS", eCX },
418 { "pushS", eDX },
419 { "pushS", eBX },
420 { "pushS", eSP },
421 { "pushS", eBP },
422 { "pushS", eSI },
423 { "pushS", eDI },
424 /* 58 */
425 { "popS", eAX },
426 { "popS", eCX },
427 { "popS", eDX },
428 { "popS", eBX },
429 { "popS", eSP },
430 { "popS", eBP },
431 { "popS", eSI },
432 { "popS", eDI },
433 /* 60 */
434 { "pushaP" },
435 { "popaP" },
436 { "boundS", Gv, Ma },
437 { "arpl", Ew, Gw },
438 { "(bad)" }, /* seg fs */
439 { "(bad)" }, /* seg gs */
440 { "(bad)" }, /* op size prefix */
441 { "(bad)" }, /* adr size prefix */
442 /* 68 */
443 { "pushP", Iv }, /* 386 book wrong */
444 { "imulS", Gv, Ev, Iv },
445 { "pushP", sIb }, /* push of byte really pushes 2 or 4 bytes */
446 { "imulS", Gv, Ev, sIb },
447 { "insb", Yb, indirDX },
448 { "insR", Yv, indirDX },
449 { "outsb", indirDX, Xb },
450 { "outsR", indirDX, Xv },
451 /* 70 */
452 { "jo", Jb },
453 { "jno", Jb },
454 { "jb", Jb },
455 { "jae", Jb },
456 { "je", Jb },
457 { "jne", Jb },
458 { "jbe", Jb },
459 { "ja", Jb },
460 /* 78 */
461 { "js", Jb },
462 { "jns", Jb },
463 { "jp", Jb },
464 { "jnp", Jb },
465 { "jl", Jb },
466 { "jge", Jb },
467 { "jle", Jb },
468 { "jg", Jb },
469 /* 80 */
470 { GRP1b },
471 { GRP1S },
472 { "(bad)" },
473 { GRP1Ss },
474 { "testB", Eb, Gb },
475 { "testS", Ev, Gv },
476 { "xchgB", Eb, Gb },
477 { "xchgS", Ev, Gv },
478 /* 88 */
479 { "movB", Eb, Gb },
480 { "movS", Ev, Gv },
481 { "movB", Gb, Eb },
482 { "movS", Gv, Ev },
483 { "movQ", Ev, Sw },
484 { "leaS", Gv, M },
485 { "movQ", Sw, Ev },
486 { "popQ", Ev },
487 /* 90 */
488 { "nop" },
489 { "xchgS", eCX, eAX },
490 { "xchgS", eDX, eAX },
491 { "xchgS", eBX, eAX },
492 { "xchgS", eSP, eAX },
493 { "xchgS", eBP, eAX },
494 { "xchgS", eSI, eAX },
495 { "xchgS", eDI, eAX },
496 /* 98 */
497 { "cWtR" },
498 { "cRtd" },
499 { "lcallP", Ap },
500 { "(bad)" }, /* fwait */
501 { "pushfP" },
502 { "popfP" },
503 { "sahf" },
504 { "lahf" },
505 /* a0 */
506 { "movB", AL, Ob },
507 { "movS", eAX, Ov },
508 { "movB", Ob, AL },
509 { "movS", Ov, eAX },
510 { "movsb", Yb, Xb },
511 { "movsR", Yv, Xv },
512 { "cmpsb", Xb, Yb },
513 { "cmpsR", Xv, Yv },
514 /* a8 */
515 { "testB", AL, Ib },
516 { "testS", eAX, Iv },
517 { "stosB", Yb, AL },
518 { "stosS", Yv, eAX },
519 { "lodsB", AL, Xb },
520 { "lodsS", eAX, Xv },
521 { "scasB", AL, Yb },
522 { "scasS", eAX, Yv },
523 /* b0 */
524 { "movB", AL, Ib },
525 { "movB", CL, Ib },
526 { "movB", DL, Ib },
527 { "movB", BL, Ib },
528 { "movB", AH, Ib },
529 { "movB", CH, Ib },
530 { "movB", DH, Ib },
531 { "movB", BH, Ib },
532 /* b8 */
533 { "movS", eAX, Iv },
534 { "movS", eCX, Iv },
535 { "movS", eDX, Iv },
536 { "movS", eBX, Iv },
537 { "movS", eSP, Iv },
538 { "movS", eBP, Iv },
539 { "movS", eSI, Iv },
540 { "movS", eDI, Iv },
541 /* c0 */
542 { GRP2b },
543 { GRP2S },
544 { "retP", Iw },
545 { "retP" },
546 { "lesS", Gv, Mp },
547 { "ldsS", Gv, Mp },
548 { "movA", Eb, Ib },
549 { "movQ", Ev, Iv },
550 /* c8 */
551 { "enterP", Iw, Ib },
552 { "leaveP" },
553 { "lretP", Iw },
554 { "lretP" },
555 { "int3" },
556 { "int", Ib },
557 { "into" },
558 { "iretP" },
559 /* d0 */
560 { GRP2b_one },
561 { GRP2S_one },
562 { GRP2b_cl },
563 { GRP2S_cl },
564 { "aam", sIb },
565 { "aad", sIb },
566 { "(bad)" },
567 { "xlat", DSBX },
568 /* d8 */
569 { FLOAT },
570 { FLOAT },
571 { FLOAT },
572 { FLOAT },
573 { FLOAT },
574 { FLOAT },
575 { FLOAT },
576 { FLOAT },
577 /* e0 */
578 { "loopne", Jb },
579 { "loope", Jb },
580 { "loop", Jb },
581 { "jEcxz", Jb },
582 { "inB", AL, Ib },
583 { "inS", eAX, Ib },
584 { "outB", Ib, AL },
585 { "outS", Ib, eAX },
586 /* e8 */
587 { "callP", Jv },
588 { "jmpP", Jv },
589 { "ljmpP", Ap },
590 { "jmp", Jb },
591 { "inB", AL, indirDX },
592 { "inS", eAX, indirDX },
593 { "outB", indirDX, AL },
594 { "outS", indirDX, eAX },
595 /* f0 */
596 { "(bad)" }, /* lock prefix */
597 { "(bad)" },
598 { "(bad)" }, /* repne */
599 { "(bad)" }, /* repz */
600 { "hlt" },
601 { "cmc" },
602 { GRP3b },
603 { GRP3S },
604 /* f8 */
605 { "clc" },
606 { "stc" },
607 { "cli" },
608 { "sti" },
609 { "cld" },
610 { "std" },
611 { GRP4 },
612 { GRP5 },
613 };
614
615 static struct dis386 dis386_intel[] = {
616 /* 00 */
617 { "add", Eb, Gb },
618 { "add", Ev, Gv },
619 { "add", Gb, Eb },
620 { "add", Gv, Ev },
621 { "add", AL, Ib },
622 { "add", eAX, Iv },
623 { "push", es },
624 { "pop", es },
625 /* 08 */
626 { "or", Eb, Gb },
627 { "or", Ev, Gv },
628 { "or", Gb, Eb },
629 { "or", Gv, Ev },
630 { "or", AL, Ib },
631 { "or", eAX, Iv },
632 { "push", cs },
633 { "(bad)" }, /* 0x0f extended opcode escape */
634 /* 10 */
635 { "adc", Eb, Gb },
636 { "adc", Ev, Gv },
637 { "adc", Gb, Eb },
638 { "adc", Gv, Ev },
639 { "adc", AL, Ib },
640 { "adc", eAX, Iv },
641 { "push", ss },
642 { "pop", ss },
643 /* 18 */
644 { "sbb", Eb, Gb },
645 { "sbb", Ev, Gv },
646 { "sbb", Gb, Eb },
647 { "sbb", Gv, Ev },
648 { "sbb", AL, Ib },
649 { "sbb", eAX, Iv },
650 { "push", ds },
651 { "pop", ds },
652 /* 20 */
653 { "and", Eb, Gb },
654 { "and", Ev, Gv },
655 { "and", Gb, Eb },
656 { "and", Gv, Ev },
657 { "and", AL, Ib },
658 { "and", eAX, Iv },
659 { "(bad)" }, /* SEG ES prefix */
660 { "daa" },
661 /* 28 */
662 { "sub", Eb, Gb },
663 { "sub", Ev, Gv },
664 { "sub", Gb, Eb },
665 { "sub", Gv, Ev },
666 { "sub", AL, Ib },
667 { "sub", eAX, Iv },
668 { "(bad)" }, /* SEG CS prefix */
669 { "das" },
670 /* 30 */
671 { "xor", Eb, Gb },
672 { "xor", Ev, Gv },
673 { "xor", Gb, Eb },
674 { "xor", Gv, Ev },
675 { "xor", AL, Ib },
676 { "xor", eAX, Iv },
677 { "(bad)" }, /* SEG SS prefix */
678 { "aaa" },
679 /* 38 */
680 { "cmp", Eb, Gb },
681 { "cmp", Ev, Gv },
682 { "cmp", Gb, Eb },
683 { "cmp", Gv, Ev },
684 { "cmp", AL, Ib },
685 { "cmp", eAX, Iv },
686 { "(bad)" }, /* SEG DS prefix */
687 { "aas" },
688 /* 40 */
689 { "inc", eAX },
690 { "inc", eCX },
691 { "inc", eDX },
692 { "inc", eBX },
693 { "inc", eSP },
694 { "inc", eBP },
695 { "inc", eSI },
696 { "inc", eDI },
697 /* 48 */
698 { "dec", eAX },
699 { "dec", eCX },
700 { "dec", eDX },
701 { "dec", eBX },
702 { "dec", eSP },
703 { "dec", eBP },
704 { "dec", eSI },
705 { "dec", eDI },
706 /* 50 */
707 { "push", eAX },
708 { "push", eCX },
709 { "push", eDX },
710 { "push", eBX },
711 { "push", eSP },
712 { "push", eBP },
713 { "push", eSI },
714 { "push", eDI },
715 /* 58 */
716 { "pop", eAX },
717 { "pop", eCX },
718 { "pop", eDX },
719 { "pop", eBX },
720 { "pop", eSP },
721 { "pop", eBP },
722 { "pop", eSI },
723 { "pop", eDI },
724 /* 60 */
725 { "pusha" },
726 { "popa" },
727 { "bound", Gv, Ma },
728 { "arpl", Ew, Gw },
729 { "(bad)" }, /* seg fs */
730 { "(bad)" }, /* seg gs */
731 { "(bad)" }, /* op size prefix */
732 { "(bad)" }, /* adr size prefix */
733 /* 68 */
734 { "push", Iv }, /* 386 book wrong */
735 { "imul", Gv, Ev, Iv },
736 { "push", sIb }, /* push of byte really pushes 2 or 4 bytes */
737 { "imul", Gv, Ev, sIb },
738 { "ins", Yb, indirDX },
739 { "ins", Yv, indirDX },
740 { "outs", indirDX, Xb },
741 { "outs", indirDX, Xv },
742 /* 70 */
743 { "jo", Jb },
744 { "jno", Jb },
745 { "jb", Jb },
746 { "jae", Jb },
747 { "je", Jb },
748 { "jne", Jb },
749 { "jbe", Jb },
750 { "ja", Jb },
751 /* 78 */
752 { "js", Jb },
753 { "jns", Jb },
754 { "jp", Jb },
755 { "jnp", Jb },
756 { "jl", Jb },
757 { "jge", Jb },
758 { "jle", Jb },
759 { "jg", Jb },
760 /* 80 */
761 { GRP1b },
762 { GRP1S },
763 { "(bad)" },
764 { GRP1Ss },
765 { "test", Eb, Gb },
766 { "test", Ev, Gv },
767 { "xchg", Eb, Gb },
768 { "xchg", Ev, Gv },
769 /* 88 */
770 { "mov", Eb, Gb },
771 { "mov", Ev, Gv },
772 { "mov", Gb, Eb },
773 { "mov", Gv, Ev },
774 { "mov", Ev, Sw },
775 { "lea", Gv, M },
776 { "mov", Sw, Ev },
777 { "pop", Ev },
778 /* 90 */
779 { "nop" },
780 { "xchg", eCX, eAX },
781 { "xchg", eDX, eAX },
782 { "xchg", eBX, eAX },
783 { "xchg", eSP, eAX },
784 { "xchg", eBP, eAX },
785 { "xchg", eSI, eAX },
786 { "xchg", eDI, eAX },
787 /* 98 */
788 { "cW" }, /* cwde and cbw */
789 { "cR" }, /* cdq and cwd */
790 { "lcall", Ap },
791 { "(bad)" }, /* fwait */
792 { "pushf" },
793 { "popf" },
794 { "sahf" },
795 { "lahf" },
796 /* a0 */
797 { "mov", AL, Ob },
798 { "mov", eAX, Ov },
799 { "mov", Ob, AL },
800 { "mov", Ov, eAX },
801 { "movs", Yb, Xb },
802 { "movs", Yv, Xv },
803 { "cmps", Xb, Yb },
804 { "cmps", Xv, Yv },
805 /* a8 */
806 { "test", AL, Ib },
807 { "test", eAX, Iv },
808 { "stos", Yb, AL },
809 { "stos", Yv, eAX },
810 { "lods", AL, Xb },
811 { "lods", eAX, Xv },
812 { "scas", AL, Yb },
813 { "scas", eAX, Yv },
814 /* b0 */
815 { "mov", AL, Ib },
816 { "mov", CL, Ib },
817 { "mov", DL, Ib },
818 { "mov", BL, Ib },
819 { "mov", AH, Ib },
820 { "mov", CH, Ib },
821 { "mov", DH, Ib },
822 { "mov", BH, Ib },
823 /* b8 */
824 { "mov", eAX, Iv },
825 { "mov", eCX, Iv },
826 { "mov", eDX, Iv },
827 { "mov", eBX, Iv },
828 { "mov", eSP, Iv },
829 { "mov", eBP, Iv },
830 { "mov", eSI, Iv },
831 { "mov", eDI, Iv },
832 /* c0 */
833 { GRP2b },
834 { GRP2S },
835 { "ret", Iw },
836 { "ret" },
837 { "les", Gv, Mp },
838 { "lds", Gv, Mp },
839 { "mov", Eb, Ib },
840 { "mov", Ev, Iv },
841 /* c8 */
842 { "enter", Iw, Ib },
843 { "leave" },
844 { "lret", Iw },
845 { "lret" },
846 { "int3" },
847 { "int", Ib },
848 { "into" },
849 { "iret" },
850 /* d0 */
851 { GRP2b_one },
852 { GRP2S_one },
853 { GRP2b_cl },
854 { GRP2S_cl },
855 { "aam", sIb },
856 { "aad", sIb },
857 { "(bad)" },
858 { "xlat", DSBX },
859 /* d8 */
860 { FLOAT },
861 { FLOAT },
862 { FLOAT },
863 { FLOAT },
864 { FLOAT },
865 { FLOAT },
866 { FLOAT },
867 { FLOAT },
868 /* e0 */
869 { "loopne", Jb },
870 { "loope", Jb },
871 { "loop", Jb },
872 { "jEcxz", Jb },
873 { "in", AL, Ib },
874 { "in", eAX, Ib },
875 { "out", Ib, AL },
876 { "out", Ib, eAX },
877 /* e8 */
878 { "call", Jv },
879 { "jmp", Jv },
880 { "ljmp", Ap },
881 { "jmp", Jb },
882 { "in", AL, indirDX },
883 { "in", eAX, indirDX },
884 { "out", indirDX, AL },
885 { "out", indirDX, eAX },
886 /* f0 */
887 { "(bad)" }, /* lock prefix */
888 { "(bad)" },
889 { "(bad)" }, /* repne */
890 { "(bad)" }, /* repz */
891 { "hlt" },
892 { "cmc" },
893 { GRP3b },
894 { GRP3S },
895 /* f8 */
896 { "clc" },
897 { "stc" },
898 { "cli" },
899 { "sti" },
900 { "cld" },
901 { "std" },
902 { GRP4 },
903 { GRP5 },
904 };
905
906 static struct dis386 dis386_twobyte_att[] = {
907 /* 00 */
908 { GRP6 },
909 { GRP7 },
910 { "larS", Gv, Ew },
911 { "lslS", Gv, Ew },
912 { "(bad)" },
913 { "(bad)" },
914 { "clts" },
915 { "(bad)" },
916 /* 08 */
917 { "invd" },
918 { "wbinvd" },
919 { "(bad)" },
920 { "ud2a" },
921 { "(bad)" },
922 { GRPAMD },
923 { "femms" },
924 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
925 /* 10 */
926 { PREGRP8 },
927 { PREGRP9 },
928 { "movlps", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
929 { "movlps", EX, XM, SIMD_Fixup, 'h' },
930 { "unpcklps", XM, EX },
931 { "unpckhps", XM, EX },
932 { "movhps", XM, EX, SIMD_Fixup, 'l' },
933 { "movhps", EX, XM, SIMD_Fixup, 'l' },
934 /* 18 */
935 { GRP14 },
936 { "(bad)" }, { "(bad)" }, { "(bad)" },
937 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
938 /* 20 */
939 /* these are all backward in appendix A of the intel book */
940 { "movL", Rd, Cd },
941 { "movL", Rd, Dd },
942 { "movL", Cd, Rd },
943 { "movL", Dd, Rd },
944 { "movL", Rd, Td },
945 { "(bad)" },
946 { "movL", Td, Rd },
947 { "(bad)" },
948 /* 28 */
949 { "movaps", XM, EX },
950 { "movaps", EX, XM },
951 { PREGRP2 },
952 { "movntps", Ev, XM },
953 { PREGRP4 },
954 { PREGRP3 },
955 { "ucomiss", XM, EX },
956 { "comiss", XM, EX },
957 /* 30 */
958 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
959 { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
960 /* 38 */
961 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
962 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
963 /* 40 */
964 { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
965 { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
966 /* 48 */
967 { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
968 { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
969 /* 50 */
970 { "movmskps", Gv, EX },
971 { PREGRP13 },
972 { PREGRP12 },
973 { PREGRP11 },
974 { "andps", XM, EX },
975 { "andnps", XM, EX },
976 { "orps", XM, EX },
977 { "xorps", XM, EX },
978 /* 58 */
979 { PREGRP0 },
980 { PREGRP10 },
981 { "(bad)" },
982 { "(bad)" },
983 { PREGRP14 },
984 { PREGRP7 },
985 { PREGRP5 },
986 { PREGRP6 },
987 /* 60 */
988 { "punpcklbw", MX, EM },
989 { "punpcklwd", MX, EM },
990 { "punpckldq", MX, EM },
991 { "packsswb", MX, EM },
992 { "pcmpgtb", MX, EM },
993 { "pcmpgtw", MX, EM },
994 { "pcmpgtd", MX, EM },
995 { "packuswb", MX, EM },
996 /* 68 */
997 { "punpckhbw", MX, EM },
998 { "punpckhwd", MX, EM },
999 { "punpckhdq", MX, EM },
1000 { "packssdw", MX, EM },
1001 { "(bad)" }, { "(bad)" },
1002 { "movd", MX, Ev },
1003 { "movq", MX, EM },
1004 /* 70 */
1005 { "pshufw", MX, EM, Ib },
1006 { GRP10 },
1007 { GRP11 },
1008 { GRP12 },
1009 { "pcmpeqb", MX, EM },
1010 { "pcmpeqw", MX, EM },
1011 { "pcmpeqd", MX, EM },
1012 { "emms" },
1013 /* 78 */
1014 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1015 { "(bad)" }, { "(bad)" },
1016 { "movd", Ev, MX },
1017 { "movq", EM, MX },
1018 /* 80 */
1019 { "jo", Jv },
1020 { "jno", Jv },
1021 { "jb", Jv },
1022 { "jae", Jv },
1023 { "je", Jv },
1024 { "jne", Jv },
1025 { "jbe", Jv },
1026 { "ja", Jv },
1027 /* 88 */
1028 { "js", Jv },
1029 { "jns", Jv },
1030 { "jp", Jv },
1031 { "jnp", Jv },
1032 { "jl", Jv },
1033 { "jge", Jv },
1034 { "jle", Jv },
1035 { "jg", Jv },
1036 /* 90 */
1037 { "seto", Eb },
1038 { "setno", Eb },
1039 { "setb", Eb },
1040 { "setae", Eb },
1041 { "sete", Eb },
1042 { "setne", Eb },
1043 { "setbe", Eb },
1044 { "seta", Eb },
1045 /* 98 */
1046 { "sets", Eb },
1047 { "setns", Eb },
1048 { "setp", Eb },
1049 { "setnp", Eb },
1050 { "setl", Eb },
1051 { "setge", Eb },
1052 { "setle", Eb },
1053 { "setg", Eb },
1054 /* a0 */
1055 { "pushP", fs },
1056 { "popP", fs },
1057 { "cpuid" },
1058 { "btS", Ev, Gv },
1059 { "shldS", Ev, Gv, Ib },
1060 { "shldS", Ev, Gv, CL },
1061 { "(bad)" },
1062 { "(bad)" },
1063 /* a8 */
1064 { "pushP", gs },
1065 { "popP", gs },
1066 { "rsm" },
1067 { "btsS", Ev, Gv },
1068 { "shrdS", Ev, Gv, Ib },
1069 { "shrdS", Ev, Gv, CL },
1070 { GRP13 },
1071 { "imulS", Gv, Ev },
1072 /* b0 */
1073 { "cmpxchgB", Eb, Gb },
1074 { "cmpxchgS", Ev, Gv },
1075 { "lssS", Gv, Mp }, /* 386 lists only Mp */
1076 { "btrS", Ev, Gv },
1077 { "lfsS", Gv, Mp }, /* 386 lists only Mp */
1078 { "lgsS", Gv, Mp }, /* 386 lists only Mp */
1079 { "movzbR", Gv, Eb },
1080 { "movzwR", Gv, Ew }, /* yes, there really is movzww ! */
1081 /* b8 */
1082 { "(bad)" },
1083 { "ud2b" },
1084 { GRP8 },
1085 { "btcS", Ev, Gv },
1086 { "bsfS", Gv, Ev },
1087 { "bsrS", Gv, Ev },
1088 { "movsbR", Gv, Eb },
1089 { "movswR", Gv, Ew }, /* yes, there really is movsww ! */
1090 /* c0 */
1091 { "xaddB", Eb, Gb },
1092 { "xaddS", Ev, Gv },
1093 { PREGRP1 },
1094 { "(bad)" },
1095 { "pinsrw", MX, Ev, Ib },
1096 { "pextrw", Ev, MX, Ib },
1097 { "shufps", XM, EX, Ib },
1098 { GRP9 },
1099 /* c8 */
1100 { "bswap", eAX }, /* bswap doesn't support 16 bit regs */
1101 { "bswap", eCX },
1102 { "bswap", eDX },
1103 { "bswap", eBX },
1104 { "bswap", eSP },
1105 { "bswap", eBP },
1106 { "bswap", eSI },
1107 { "bswap", eDI },
1108 /* d0 */
1109 { "(bad)" },
1110 { "psrlw", MX, EM },
1111 { "psrld", MX, EM },
1112 { "psrlq", MX, EM },
1113 { "(bad)" },
1114 { "pmullw", MX, EM },
1115 { "(bad)" },
1116 { "pmovmskb", Ev, MX },
1117 /* d8 */
1118 { "psubusb", MX, EM },
1119 { "psubusw", MX, EM },
1120 { "pminub", MX, EM },
1121 { "pand", MX, EM },
1122 { "paddusb", MX, EM },
1123 { "paddusw", MX, EM },
1124 { "pmaxub", MX, EM },
1125 { "pandn", MX, EM },
1126 /* e0 */
1127 { "pavgb", MX, EM },
1128 { "psraw", MX, EM },
1129 { "psrad", MX, EM },
1130 { "pavgw", MX, EM },
1131 { "pmulhuw", MX, EM },
1132 { "pmulhw", MX, EM },
1133 { "(bad)" },
1134 { "movntq", Ev, MX },
1135 /* e8 */
1136 { "psubsb", MX, EM },
1137 { "psubsw", MX, EM },
1138 { "pminsw", MX, EM },
1139 { "por", MX, EM },
1140 { "paddsb", MX, EM },
1141 { "paddsw", MX, EM },
1142 { "pmaxsw", MX, EM },
1143 { "pxor", MX, EM },
1144 /* f0 */
1145 { "(bad)" },
1146 { "psllw", MX, EM },
1147 { "pslld", MX, EM },
1148 { "psllq", MX, EM },
1149 { "(bad)" },
1150 { "pmaddwd", MX, EM },
1151 { "psadbw", MX, EM },
1152 { "maskmovq", MX, EM },
1153 /* f8 */
1154 { "psubb", MX, EM },
1155 { "psubw", MX, EM },
1156 { "psubd", MX, EM },
1157 { "(bad)" },
1158 { "paddb", MX, EM },
1159 { "paddw", MX, EM },
1160 { "paddd", MX, EM },
1161 { "(bad)" }
1162 };
1163
1164 static struct dis386 dis386_twobyte_intel[] = {
1165 /* 00 */
1166 { GRP6 },
1167 { GRP7 },
1168 { "lar", Gv, Ew },
1169 { "lsl", Gv, Ew },
1170 { "(bad)" },
1171 { "(bad)" },
1172 { "clts" },
1173 { "(bad)" },
1174 /* 08 */
1175 { "invd" },
1176 { "wbinvd" },
1177 { "(bad)" },
1178 { "ud2a" },
1179 { "(bad)" },
1180 { GRPAMD },
1181 { "femms" },
1182 { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix */
1183 /* 10 */
1184 { PREGRP8 },
1185 { PREGRP9 },
1186 { "movlps", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
1187 { "movlps", EX, XM, SIMD_Fixup, 'h' },
1188 { "unpcklps", XM, EX },
1189 { "unpckhps", XM, EX },
1190 { "movhps", XM, EX, SIMD_Fixup, 'l' },
1191 { "movhps", EX, XM, SIMD_Fixup, 'l' },
1192 /* 18 */
1193 { GRP14 },
1194 { "(bad)" }, { "(bad)" }, { "(bad)" },
1195 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1196 /* 20 */
1197 /* these are all backward in appendix A of the intel book */
1198 { "mov", Rd, Cd },
1199 { "mov", Rd, Dd },
1200 { "mov", Cd, Rd },
1201 { "mov", Dd, Rd },
1202 { "mov", Rd, Td },
1203 { "(bad)" },
1204 { "mov", Td, Rd },
1205 { "(bad)" },
1206 /* 28 */
1207 { "movaps", XM, EX },
1208 { "movaps", EX, XM },
1209 { PREGRP2 },
1210 { "movntps", Ev, XM },
1211 { PREGRP4 },
1212 { PREGRP3 },
1213 { "ucomiss", XM, EX },
1214 { "comiss", XM, EX },
1215 /* 30 */
1216 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
1217 { "sysenter" }, { "sysexit" }, { "(bad)" }, { "(bad)" },
1218 /* 38 */
1219 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1220 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1221 /* 40 */
1222 { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
1223 { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
1224 /* 48 */
1225 { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
1226 { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
1227 /* 50 */
1228 { "movmskps", Gv, EX },
1229 { PREGRP13 },
1230 { PREGRP12 },
1231 { PREGRP11 },
1232 { "andps", XM, EX },
1233 { "andnps", XM, EX },
1234 { "orps", XM, EX },
1235 { "xorps", XM, EX },
1236 /* 58 */
1237 { PREGRP0 },
1238 { PREGRP10 },
1239 { "(bad)" },
1240 { "(bad)" },
1241 { PREGRP14 },
1242 { PREGRP7 },
1243 { PREGRP5 },
1244 { PREGRP6 },
1245 /* 60 */
1246 { "punpcklbw", MX, EM },
1247 { "punpcklwd", MX, EM },
1248 { "punpckldq", MX, EM },
1249 { "packsswb", MX, EM },
1250 { "pcmpgtb", MX, EM },
1251 { "pcmpgtw", MX, EM },
1252 { "pcmpgtd", MX, EM },
1253 { "packuswb", MX, EM },
1254 /* 68 */
1255 { "punpckhbw", MX, EM },
1256 { "punpckhwd", MX, EM },
1257 { "punpckhdq", MX, EM },
1258 { "packssdw", MX, EM },
1259 { "(bad)" }, { "(bad)" },
1260 { "movd", MX, Ev },
1261 { "movq", MX, EM },
1262 /* 70 */
1263 { "pshufw", MX, EM, Ib },
1264 { GRP10 },
1265 { GRP11 },
1266 { GRP12 },
1267 { "pcmpeqb", MX, EM },
1268 { "pcmpeqw", MX, EM },
1269 { "pcmpeqd", MX, EM },
1270 { "emms" },
1271 /* 78 */
1272 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
1273 { "(bad)" }, { "(bad)" },
1274 { "movd", Ev, MX },
1275 { "movq", EM, MX },
1276 /* 80 */
1277 { "jo", Jv },
1278 { "jno", Jv },
1279 { "jb", Jv },
1280 { "jae", Jv },
1281 { "je", Jv },
1282 { "jne", Jv },
1283 { "jbe", Jv },
1284 { "ja", Jv },
1285 /* 88 */
1286 { "js", Jv },
1287 { "jns", Jv },
1288 { "jp", Jv },
1289 { "jnp", Jv },
1290 { "jl", Jv },
1291 { "jge", Jv },
1292 { "jle", Jv },
1293 { "jg", Jv },
1294 /* 90 */
1295 { "seto", Eb },
1296 { "setno", Eb },
1297 { "setb", Eb },
1298 { "setae", Eb },
1299 { "sete", Eb },
1300 { "setne", Eb },
1301 { "setbe", Eb },
1302 { "seta", Eb },
1303 /* 98 */
1304 { "sets", Eb },
1305 { "setns", Eb },
1306 { "setp", Eb },
1307 { "setnp", Eb },
1308 { "setl", Eb },
1309 { "setge", Eb },
1310 { "setle", Eb },
1311 { "setg", Eb },
1312 /* a0 */
1313 { "push", fs },
1314 { "pop", fs },
1315 { "cpuid" },
1316 { "bt", Ev, Gv },
1317 { "shld", Ev, Gv, Ib },
1318 { "shld", Ev, Gv, CL },
1319 { "(bad)" },
1320 { "(bad)" },
1321 /* a8 */
1322 { "push", gs },
1323 { "pop", gs },
1324 { "rsm" },
1325 { "bts", Ev, Gv },
1326 { "shrd", Ev, Gv, Ib },
1327 { "shrd", Ev, Gv, CL },
1328 { GRP13 },
1329 { "imul", Gv, Ev },
1330 /* b0 */
1331 { "cmpxchg", Eb, Gb },
1332 { "cmpxchg", Ev, Gv },
1333 { "lss", Gv, Mp }, /* 386 lists only Mp */
1334 { "btr", Ev, Gv },
1335 { "lfs", Gv, Mp }, /* 386 lists only Mp */
1336 { "lgs", Gv, Mp }, /* 386 lists only Mp */
1337 { "movzx", Gv, Eb },
1338 { "movzx", Gv, Ew },
1339 /* b8 */
1340 { "(bad)" },
1341 { "ud2b" },
1342 { GRP8 },
1343 { "btc", Ev, Gv },
1344 { "bsf", Gv, Ev },
1345 { "bsr", Gv, Ev },
1346 { "movsx", Gv, Eb },
1347 { "movsx", Gv, Ew },
1348 /* c0 */
1349 { "xadd", Eb, Gb },
1350 { "xadd", Ev, Gv },
1351 { PREGRP1 },
1352 { "(bad)" },
1353 { "pinsrw", MX, Ev, Ib },
1354 { "pextrw", Ev, MX, Ib },
1355 { "shufps", XM, EX, Ib },
1356 { GRP9 },
1357 /* c8 */
1358 { "bswap", eAX }, /* bswap doesn't support 16 bit regs */
1359 { "bswap", eCX },
1360 { "bswap", eDX },
1361 { "bswap", eBX },
1362 { "bswap", eSP },
1363 { "bswap", eBP },
1364 { "bswap", eSI },
1365 { "bswap", eDI },
1366 /* d0 */
1367 { "(bad)" },
1368 { "psrlw", MX, EM },
1369 { "psrld", MX, EM },
1370 { "psrlq", MX, EM },
1371 { "(bad)" },
1372 { "pmullw", MX, EM },
1373 { "(bad)" },
1374 { "pmovmskb", Ev, MX },
1375 /* d8 */
1376 { "psubusb", MX, EM },
1377 { "psubusw", MX, EM },
1378 { "pminub", MX, EM },
1379 { "pand", MX, EM },
1380 { "paddusb", MX, EM },
1381 { "paddusw", MX, EM },
1382 { "pmaxub", MX, EM },
1383 { "pandn", MX, EM },
1384 /* e0 */
1385 { "pavgb", MX, EM },
1386 { "psraw", MX, EM },
1387 { "psrad", MX, EM },
1388 { "pavgw", MX, EM },
1389 { "pmulhuw", MX, EM },
1390 { "pmulhw", MX, EM },
1391 { "(bad)" },
1392 { "movntq", Ev, MX },
1393 /* e8 */
1394 { "psubsb", MX, EM },
1395 { "psubsw", MX, EM },
1396 { "pminsw", MX, EM },
1397 { "por", MX, EM },
1398 { "paddsb", MX, EM },
1399 { "paddsw", MX, EM },
1400 { "pmaxsw", MX, EM },
1401 { "pxor", MX, EM },
1402 /* f0 */
1403 { "(bad)" },
1404 { "psllw", MX, EM },
1405 { "pslld", MX, EM },
1406 { "psllq", MX, EM },
1407 { "(bad)" },
1408 { "pmaddwd", MX, EM },
1409 { "psadbw", MX, EM },
1410 { "maskmovq", MX, EM },
1411 /* f8 */
1412 { "psubb", MX, EM },
1413 { "psubw", MX, EM },
1414 { "psubd", MX, EM },
1415 { "(bad)" },
1416 { "paddb", MX, EM },
1417 { "paddw", MX, EM },
1418 { "paddd", MX, EM },
1419 { "(bad)" }
1420 };
1421
1422 static const unsigned char onebyte_has_modrm[256] = {
1423 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1424 /* ------------------------------- */
1425 /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
1426 /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
1427 /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
1428 /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
1429 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
1430 /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
1431 /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
1432 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
1433 /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
1434 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
1435 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
1436 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
1437 /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
1438 /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
1439 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
1440 /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
1441 /* ------------------------------- */
1442 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1443 };
1444
1445 static const unsigned char twobyte_has_modrm[256] = {
1446 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1447 /* ------------------------------- */
1448 /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
1449 /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
1450 /* 20 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 2f */
1451 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1452 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
1453 /* 50 */ 1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1, /* 5f */
1454 /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
1455 /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
1456 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1457 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
1458 /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
1459 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
1460 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
1461 /* d0 */ 0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1, /* df */
1462 /* e0 */ 1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1, /* ef */
1463 /* f0 */ 0,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0 /* ff */
1464 /* ------------------------------- */
1465 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1466 };
1467
1468 static const unsigned char twobyte_uses_f3_prefix[256] = {
1469 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1470 /* ------------------------------- */
1471 /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
1472 /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
1473 /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
1474 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
1475 /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
1476 /* 50 */ 0,1,1,1,0,0,0,0,1,1,0,0,1,1,1,1, /* 5f */
1477 /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 6f */
1478 /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 7f */
1479 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
1480 /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
1481 /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
1482 /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
1483 /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
1484 /* d0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* df */
1485 /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* ef */
1486 /* f0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* ff */
1487 /* ------------------------------- */
1488 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
1489 };
1490
1491 static char obuf[100];
1492 static char *obufp;
1493 static char scratchbuf[100];
1494 static unsigned char *start_codep;
1495 static unsigned char *insn_codep;
1496 static unsigned char *codep;
1497 static disassemble_info *the_info;
1498 static int mod;
1499 static int rm;
1500 static int reg;
1501 static void oappend PARAMS ((char *s));
1502
1503 static char *names32[]={
1504 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
1505 };
1506 static char *names16[] = {
1507 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
1508 };
1509 static char *names8[] = {
1510 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
1511 };
1512 static char *names_seg[] = {
1513 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1514 };
1515 static char *index16[] = {
1516 "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx"
1517 };
1518
1519 static struct dis386 grps[][8] = {
1520 /* GRP1b */
1521 {
1522 { "addA", Eb, Ib },
1523 { "orA", Eb, Ib },
1524 { "adcA", Eb, Ib },
1525 { "sbbA", Eb, Ib },
1526 { "andA", Eb, Ib },
1527 { "subA", Eb, Ib },
1528 { "xorA", Eb, Ib },
1529 { "cmpA", Eb, Ib }
1530 },
1531 /* GRP1S */
1532 {
1533 { "addQ", Ev, Iv },
1534 { "orQ", Ev, Iv },
1535 { "adcQ", Ev, Iv },
1536 { "sbbQ", Ev, Iv },
1537 { "andQ", Ev, Iv },
1538 { "subQ", Ev, Iv },
1539 { "xorQ", Ev, Iv },
1540 { "cmpQ", Ev, Iv }
1541 },
1542 /* GRP1Ss */
1543 {
1544 { "addQ", Ev, sIb },
1545 { "orQ", Ev, sIb },
1546 { "adcQ", Ev, sIb },
1547 { "sbbQ", Ev, sIb },
1548 { "andQ", Ev, sIb },
1549 { "subQ", Ev, sIb },
1550 { "xorQ", Ev, sIb },
1551 { "cmpQ", Ev, sIb }
1552 },
1553 /* GRP2b */
1554 {
1555 { "rolA", Eb, Ib },
1556 { "rorA", Eb, Ib },
1557 { "rclA", Eb, Ib },
1558 { "rcrA", Eb, Ib },
1559 { "shlA", Eb, Ib },
1560 { "shrA", Eb, Ib },
1561 { "(bad)" },
1562 { "sarA", Eb, Ib },
1563 },
1564 /* GRP2S */
1565 {
1566 { "rolQ", Ev, Ib },
1567 { "rorQ", Ev, Ib },
1568 { "rclQ", Ev, Ib },
1569 { "rcrQ", Ev, Ib },
1570 { "shlQ", Ev, Ib },
1571 { "shrQ", Ev, Ib },
1572 { "(bad)" },
1573 { "sarQ", Ev, Ib },
1574 },
1575 /* GRP2b_one */
1576 {
1577 { "rolA", Eb },
1578 { "rorA", Eb },
1579 { "rclA", Eb },
1580 { "rcrA", Eb },
1581 { "shlA", Eb },
1582 { "shrA", Eb },
1583 { "(bad)" },
1584 { "sarA", Eb },
1585 },
1586 /* GRP2S_one */
1587 {
1588 { "rolQ", Ev },
1589 { "rorQ", Ev },
1590 { "rclQ", Ev },
1591 { "rcrQ", Ev },
1592 { "shlQ", Ev },
1593 { "shrQ", Ev },
1594 { "(bad)" },
1595 { "sarQ", Ev },
1596 },
1597 /* GRP2b_cl */
1598 {
1599 { "rolA", Eb, CL },
1600 { "rorA", Eb, CL },
1601 { "rclA", Eb, CL },
1602 { "rcrA", Eb, CL },
1603 { "shlA", Eb, CL },
1604 { "shrA", Eb, CL },
1605 { "(bad)" },
1606 { "sarA", Eb, CL },
1607 },
1608 /* GRP2S_cl */
1609 {
1610 { "rolQ", Ev, CL },
1611 { "rorQ", Ev, CL },
1612 { "rclQ", Ev, CL },
1613 { "rcrQ", Ev, CL },
1614 { "shlQ", Ev, CL },
1615 { "shrQ", Ev, CL },
1616 { "(bad)" },
1617 { "sarQ", Ev, CL }
1618 },
1619 /* GRP3b */
1620 {
1621 { "testA", Eb, Ib },
1622 { "(bad)", Eb },
1623 { "notA", Eb },
1624 { "negA", Eb },
1625 { "mulB", AL, Eb },
1626 { "imulB", AL, Eb },
1627 { "divB", AL, Eb },
1628 { "idivB", AL, Eb }
1629 },
1630 /* GRP3S */
1631 {
1632 { "testQ", Ev, Iv },
1633 { "(bad)" },
1634 { "notQ", Ev },
1635 { "negQ", Ev },
1636 { "mulS", eAX, Ev },
1637 { "imulS", eAX, Ev },
1638 { "divS", eAX, Ev },
1639 { "idivS", eAX, Ev },
1640 },
1641 /* GRP4 */
1642 {
1643 { "incA", Eb },
1644 { "decA", Eb },
1645 { "(bad)" },
1646 { "(bad)" },
1647 { "(bad)" },
1648 { "(bad)" },
1649 { "(bad)" },
1650 { "(bad)" },
1651 },
1652 /* GRP5 */
1653 {
1654 { "incQ", Ev },
1655 { "decQ", Ev },
1656 { "callP", indirEv },
1657 { "callP", indirEv },
1658 { "jmpP", indirEv },
1659 { "ljmpP", indirEv },
1660 { "pushQ", Ev },
1661 { "(bad)" },
1662 },
1663 /* GRP6 */
1664 {
1665 { "sldt", Ew },
1666 { "str", Ew },
1667 { "lldt", Ew },
1668 { "ltr", Ew },
1669 { "verr", Ew },
1670 { "verw", Ew },
1671 { "(bad)" },
1672 { "(bad)" }
1673 },
1674 /* GRP7 */
1675 {
1676 { "sgdt", Ew },
1677 { "sidt", Ew },
1678 { "lgdt", Ew },
1679 { "lidt", Ew },
1680 { "smsw", Ew },
1681 { "(bad)" },
1682 { "lmsw", Ew },
1683 { "invlpg", Ew },
1684 },
1685 /* GRP8 */
1686 {
1687 { "(bad)" },
1688 { "(bad)" },
1689 { "(bad)" },
1690 { "(bad)" },
1691 { "btQ", Ev, Ib },
1692 { "btsQ", Ev, Ib },
1693 { "btrQ", Ev, Ib },
1694 { "btcQ", Ev, Ib },
1695 },
1696 /* GRP9 */
1697 {
1698 { "(bad)" },
1699 { "cmpxchg8b", Ev },
1700 { "(bad)" },
1701 { "(bad)" },
1702 { "(bad)" },
1703 { "(bad)" },
1704 { "(bad)" },
1705 { "(bad)" },
1706 },
1707 /* GRP10 */
1708 {
1709 { "(bad)" },
1710 { "(bad)" },
1711 { "psrlw", MS, Ib },
1712 { "(bad)" },
1713 { "psraw", MS, Ib },
1714 { "(bad)" },
1715 { "psllw", MS, Ib },
1716 { "(bad)" },
1717 },
1718 /* GRP11 */
1719 {
1720 { "(bad)" },
1721 { "(bad)" },
1722 { "psrld", MS, Ib },
1723 { "(bad)" },
1724 { "psrad", MS, Ib },
1725 { "(bad)" },
1726 { "pslld", MS, Ib },
1727 { "(bad)" },
1728 },
1729 /* GRP12 */
1730 {
1731 { "(bad)" },
1732 { "(bad)" },
1733 { "psrlq", MS, Ib },
1734 { "(bad)" },
1735 { "(bad)" },
1736 { "(bad)" },
1737 { "psllq", MS, Ib },
1738 { "(bad)" },
1739 },
1740 /* GRP13 */
1741 {
1742 { "fxsave", Ev },
1743 { "fxrstor", Ev },
1744 { "ldmxcsr", Ev },
1745 { "stmxcsr", Ev },
1746 { "(bad)" },
1747 { "(bad)" },
1748 { "(bad)" },
1749 { "sfence", None },
1750 },
1751 /* GRP14 */
1752 {
1753 { "prefetchnta", Ev },
1754 { "prefetcht0", Ev },
1755 { "prefetcht1", Ev },
1756 { "prefetcht2", Ev },
1757 { "(bad)" },
1758 { "(bad)" },
1759 { "(bad)" },
1760 { "(bad)" },
1761 },
1762 /* GRPAMD */
1763 {
1764 { "prefetch", Eb },
1765 { "prefetchw", Eb },
1766 { "(bad)" },
1767 { "(bad)" },
1768 { "(bad)" },
1769 { "(bad)" },
1770 { "(bad)" },
1771 { "(bad)" },
1772 }
1773
1774 };
1775
1776 static struct dis386 prefix_user_table[][2] = {
1777 /* PREGRP0 */
1778 {
1779 { "addps", XM, EX },
1780 { "addss", XM, EX },
1781 },
1782 /* PREGRP1 */
1783 {
1784 { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX */
1785 { "", XM, EX, OPSIMD },
1786 },
1787 /* PREGRP2 */
1788 {
1789 { "cvtpi2ps", XM, EM },
1790 { "cvtsi2ss", XM, Ev },
1791 },
1792 /* PREGRP3 */
1793 {
1794 { "cvtps2pi", MX, EX },
1795 { "cvtss2si", Gv, EX },
1796 },
1797 /* PREGRP4 */
1798 {
1799 { "cvttps2pi", MX, EX },
1800 { "cvttss2si", Gv, EX },
1801 },
1802 /* PREGRP5 */
1803 {
1804 { "divps", XM, EX },
1805 { "divss", XM, EX },
1806 },
1807 /* PREGRP6 */
1808 {
1809 { "maxps", XM, EX },
1810 { "maxss", XM, EX },
1811 },
1812 /* PREGRP7 */
1813 {
1814 { "minps", XM, EX },
1815 { "minss", XM, EX },
1816 },
1817 /* PREGRP8 */
1818 {
1819 { "movups", XM, EX },
1820 { "movss", XM, EX },
1821 },
1822 /* PREGRP9 */
1823 {
1824 { "movups", EX, XM },
1825 { "movss", EX, XM },
1826 },
1827 /* PREGRP10 */
1828 {
1829 { "mulps", XM, EX },
1830 { "mulss", XM, EX },
1831 },
1832 /* PREGRP11 */
1833 {
1834 { "rcpps", XM, EX },
1835 { "rcpss", XM, EX },
1836 },
1837 /* PREGRP12 */
1838 {
1839 { "rsqrtps", XM, EX },
1840 { "rsqrtss", XM, EX },
1841 },
1842 /* PREGRP13 */
1843 {
1844 { "sqrtps", XM, EX },
1845 { "sqrtss", XM, EX },
1846 },
1847 /* PREGRP14 */
1848 {
1849 { "subps", XM, EX },
1850 { "subss", XM, EX },
1851 }
1852 };
1853
1854 #define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1855
1856 #define PREFIX_REPZ 1
1857 #define PREFIX_REPNZ 2
1858 #define PREFIX_LOCK 4
1859 #define PREFIX_CS 8
1860 #define PREFIX_SS 0x10
1861 #define PREFIX_DS 0x20
1862 #define PREFIX_ES 0x40
1863 #define PREFIX_FS 0x80
1864 #define PREFIX_GS 0x100
1865 #define PREFIX_DATA 0x200
1866 #define PREFIX_ADDR 0x400
1867 #define PREFIX_FWAIT 0x800
1868
1869 static int prefixes;
1870
1871 static void
1872 ckprefix ()
1873 {
1874 prefixes = 0;
1875 while (1)
1876 {
1877 FETCH_DATA (the_info, codep + 1);
1878 switch (*codep)
1879 {
1880 case 0xf3:
1881 prefixes |= PREFIX_REPZ;
1882 break;
1883 case 0xf2:
1884 prefixes |= PREFIX_REPNZ;
1885 break;
1886 case 0xf0:
1887 prefixes |= PREFIX_LOCK;
1888 break;
1889 case 0x2e:
1890 prefixes |= PREFIX_CS;
1891 break;
1892 case 0x36:
1893 prefixes |= PREFIX_SS;
1894 break;
1895 case 0x3e:
1896 prefixes |= PREFIX_DS;
1897 break;
1898 case 0x26:
1899 prefixes |= PREFIX_ES;
1900 break;
1901 case 0x64:
1902 prefixes |= PREFIX_FS;
1903 break;
1904 case 0x65:
1905 prefixes |= PREFIX_GS;
1906 break;
1907 case 0x66:
1908 prefixes |= PREFIX_DATA;
1909 break;
1910 case 0x67:
1911 prefixes |= PREFIX_ADDR;
1912 break;
1913 case 0x9b:
1914 /* fwait is really an instruction. If there are prefixes
1915 before the fwait, they belong to the fwait, *not* to the
1916 following instruction. */
1917 if (prefixes)
1918 {
1919 prefixes |= PREFIX_FWAIT;
1920 codep++;
1921 return;
1922 }
1923 prefixes = PREFIX_FWAIT;
1924 break;
1925 default:
1926 return;
1927 }
1928 codep++;
1929 }
1930 }
1931
1932 static char op1out[100], op2out[100], op3out[100];
1933 static int op_ad, op_index[3];
1934 static unsigned int op_address[3];
1935 static unsigned int start_pc;
1936
1937 \f
1938 /*
1939 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1940 * (see topic "Redundant prefixes" in the "Differences from 8086"
1941 * section of the "Virtual 8086 Mode" chapter.)
1942 * 'pc' should be the address of this instruction, it will
1943 * be used to print the target address if this is a relative jump or call
1944 * The function returns the length of this instruction in bytes.
1945 */
1946
1947 static int print_insn_x86
1948 PARAMS ((bfd_vma pc, disassemble_info *info, int sizeflag));
1949 static int print_insn_i386
1950 PARAMS ((bfd_vma pc, disassemble_info *info));
1951
1952 static char intel_syntax;
1953 static char open_char;
1954 static char close_char;
1955 static char separator_char;
1956 static char scale_char;
1957
1958 int
1959 print_insn_i386_att (pc, info)
1960 bfd_vma pc;
1961 disassemble_info *info;
1962 {
1963 intel_syntax = 0;
1964 open_char = '(';
1965 close_char = ')';
1966 separator_char = ',';
1967 scale_char = ',';
1968
1969 return print_insn_i386 (pc, info);
1970 }
1971
1972 int
1973 print_insn_i386_intel (pc, info)
1974 bfd_vma pc;
1975 disassemble_info *info;
1976 {
1977 intel_syntax = 1;
1978 open_char = '[';
1979 close_char = ']';
1980 separator_char = '+';
1981 scale_char = '*';
1982
1983 return print_insn_i386 (pc, info);
1984 }
1985
1986 static int
1987 print_insn_i386 (pc, info)
1988 bfd_vma pc;
1989 disassemble_info *info;
1990 {
1991 int flags;
1992 if (info->mach == bfd_mach_i386_i386
1993 || info->mach == bfd_mach_i386_i386_intel_syntax)
1994 flags = AFLAG|DFLAG;
1995 else if (info->mach == bfd_mach_i386_i8086)
1996 flags = 0;
1997 else
1998 abort ();
1999 return print_insn_x86 (pc, info, flags);
2000 }
2001
2002 static int
2003 print_insn_x86 (pc, info, sizeflag)
2004 bfd_vma pc;
2005 disassemble_info *info;
2006 int sizeflag;
2007 {
2008 struct dis386 *dp;
2009 int i;
2010 int two_source_ops;
2011 char *first, *second, *third;
2012 int needcomma;
2013 unsigned char need_modrm;
2014 unsigned char uses_f3_prefix;
2015
2016 struct dis_private priv;
2017 bfd_byte *inbuf = priv.the_buffer;
2018
2019 /* The output looks better if we put 6 bytes on a line, since that
2020 puts most long word instructions on a single line. */
2021 info->bytes_per_line = 6;
2022
2023 info->private_data = (PTR) &priv;
2024 priv.max_fetched = priv.the_buffer;
2025 priv.insn_start = pc;
2026 if (setjmp (priv.bailout) != 0)
2027 /* Error return. */
2028 return -1;
2029
2030 obuf[0] = 0;
2031 op1out[0] = 0;
2032 op2out[0] = 0;
2033 op3out[0] = 0;
2034
2035 op_index[0] = op_index[1] = op_index[2] = -1;
2036
2037 the_info = info;
2038 start_pc = pc;
2039 start_codep = inbuf;
2040 codep = inbuf;
2041
2042 ckprefix ();
2043
2044 insn_codep = codep;
2045
2046 FETCH_DATA (info, codep + 1);
2047 two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
2048
2049 obufp = obuf;
2050
2051 if ((prefixes & PREFIX_FWAIT)
2052 && ((*codep < 0xd8) || (*codep > 0xdf)))
2053 {
2054 /* fwait not followed by floating point instruction. */
2055 (*info->fprintf_func) (info->stream, "fwait");
2056 /* There may be other prefixes. Skip any before the fwait. */
2057 return codep - inbuf;
2058 }
2059
2060 if (*codep == 0x0f)
2061 {
2062 FETCH_DATA (info, codep + 2);
2063 if (intel_syntax)
2064 dp = &dis386_twobyte_intel[*++codep];
2065 else
2066 dp = &dis386_twobyte_att[*++codep];
2067 need_modrm = twobyte_has_modrm[*codep];
2068 uses_f3_prefix = twobyte_uses_f3_prefix[*codep];
2069 }
2070 else
2071 {
2072 if (intel_syntax)
2073 dp = &dis386_intel[*codep];
2074 else
2075 dp = &dis386_att[*codep];
2076 need_modrm = onebyte_has_modrm[*codep];
2077 uses_f3_prefix = 0;
2078 }
2079 codep++;
2080
2081 if (!uses_f3_prefix && (prefixes & PREFIX_REPZ))
2082 oappend ("repz ");
2083 if (prefixes & PREFIX_REPNZ)
2084 oappend ("repnz ");
2085 if (prefixes & PREFIX_LOCK)
2086 oappend ("lock ");
2087
2088 if (prefixes & PREFIX_DATA)
2089 sizeflag ^= DFLAG;
2090
2091 if (prefixes & PREFIX_ADDR)
2092 {
2093 sizeflag ^= AFLAG;
2094 if (sizeflag & AFLAG)
2095 oappend ("addr32 ");
2096 else
2097 oappend ("addr16 ");
2098 }
2099
2100 if (need_modrm)
2101 {
2102 FETCH_DATA (info, codep + 1);
2103 mod = (*codep >> 6) & 3;
2104 reg = (*codep >> 3) & 7;
2105 rm = *codep & 7;
2106 }
2107
2108 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
2109 {
2110 dofloat (sizeflag);
2111 }
2112 else
2113 {
2114 if (dp->name == NULL)
2115 {
2116 switch(dp->bytemode2)
2117 {
2118 case USE_GROUPS:
2119 dp = &grps[dp->bytemode1][reg];
2120 break;
2121 case USE_PREFIX_USER_TABLE:
2122 dp = &prefix_user_table[dp->bytemode1][prefixes & PREFIX_REPZ ? 1 : 0];
2123 break;
2124 default:
2125 oappend (INTERNAL_DISASSEMBLER_ERROR);
2126 break;
2127 }
2128 }
2129
2130 putop (dp->name, sizeflag);
2131
2132 obufp = op1out;
2133 op_ad = 2;
2134 if (dp->op1)
2135 (*dp->op1)(dp->bytemode1, sizeflag);
2136
2137 obufp = op2out;
2138 op_ad = 1;
2139 if (dp->op2)
2140 (*dp->op2)(dp->bytemode2, sizeflag);
2141
2142 obufp = op3out;
2143 op_ad = 0;
2144 if (dp->op3)
2145 (*dp->op3)(dp->bytemode3, sizeflag);
2146 }
2147
2148 obufp = obuf + strlen (obuf);
2149 for (i = strlen (obuf); i < 6; i++)
2150 oappend (" ");
2151 oappend (" ");
2152 (*info->fprintf_func) (info->stream, "%s", obuf);
2153
2154 /* The enter and bound instructions are printed with operands in the same
2155 order as the intel book; everything else is printed in reverse order. */
2156 if (intel_syntax || two_source_ops)
2157 {
2158 first = op1out;
2159 second = op2out;
2160 third = op3out;
2161 op_ad = op_index[0];
2162 op_index[0] = op_index[2];
2163 op_index[2] = op_ad;
2164 }
2165 else
2166 {
2167 first = op3out;
2168 second = op2out;
2169 third = op1out;
2170 }
2171 needcomma = 0;
2172 if (*first)
2173 {
2174 if (op_index[0] != -1)
2175 (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
2176 else
2177 (*info->fprintf_func) (info->stream, "%s", first);
2178 needcomma = 1;
2179 }
2180 if (*second)
2181 {
2182 if (needcomma)
2183 (*info->fprintf_func) (info->stream, ",");
2184 if (op_index[1] != -1)
2185 (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
2186 else
2187 (*info->fprintf_func) (info->stream, "%s", second);
2188 needcomma = 1;
2189 }
2190 if (*third)
2191 {
2192 if (needcomma)
2193 (*info->fprintf_func) (info->stream, ",");
2194 if (op_index[2] != -1)
2195 (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
2196 else
2197 (*info->fprintf_func) (info->stream, "%s", third);
2198 }
2199 return codep - inbuf;
2200 }
2201
2202 static char *float_mem_att[] = {
2203 /* d8 */
2204 "fadds",
2205 "fmuls",
2206 "fcoms",
2207 "fcomps",
2208 "fsubs",
2209 "fsubrs",
2210 "fdivs",
2211 "fdivrs",
2212 /* d9 */
2213 "flds",
2214 "(bad)",
2215 "fsts",
2216 "fstps",
2217 "fldenv",
2218 "fldcw",
2219 "fNstenv",
2220 "fNstcw",
2221 /* da */
2222 "fiaddl",
2223 "fimull",
2224 "ficoml",
2225 "ficompl",
2226 "fisubl",
2227 "fisubrl",
2228 "fidivl",
2229 "fidivrl",
2230 /* db */
2231 "fildl",
2232 "(bad)",
2233 "fistl",
2234 "fistpl",
2235 "(bad)",
2236 "fldt",
2237 "(bad)",
2238 "fstpt",
2239 /* dc */
2240 "faddl",
2241 "fmull",
2242 "fcoml",
2243 "fcompl",
2244 "fsubl",
2245 "fsubrl",
2246 "fdivl",
2247 "fdivrl",
2248 /* dd */
2249 "fldl",
2250 "(bad)",
2251 "fstl",
2252 "fstpl",
2253 "frstor",
2254 "(bad)",
2255 "fNsave",
2256 "fNstsw",
2257 /* de */
2258 "fiadd",
2259 "fimul",
2260 "ficom",
2261 "ficomp",
2262 "fisub",
2263 "fisubr",
2264 "fidiv",
2265 "fidivr",
2266 /* df */
2267 "fild",
2268 "(bad)",
2269 "fist",
2270 "fistp",
2271 "fbld",
2272 "fildll",
2273 "fbstp",
2274 "fistpll",
2275 };
2276
2277 static char *float_mem_intel[] = {
2278 /* d8 */
2279 "fadd",
2280 "fmul",
2281 "fcom",
2282 "fcomp",
2283 "fsub",
2284 "fsubr",
2285 "fdiv",
2286 "fdivr",
2287 /* d9 */
2288 "fld",
2289 "(bad)",
2290 "fst",
2291 "fstp",
2292 "fldenv",
2293 "fldcw",
2294 "fNstenv",
2295 "fNstcw",
2296 /* da */
2297 "fiadd",
2298 "fimul",
2299 "ficom",
2300 "ficomp",
2301 "fisub",
2302 "fisubr",
2303 "fidiv",
2304 "fidivr",
2305 /* db */
2306 "fild",
2307 "(bad)",
2308 "fist",
2309 "fistp",
2310 "(bad)",
2311 "fld",
2312 "(bad)",
2313 "fstp",
2314 /* dc */
2315 "fadd",
2316 "fmul",
2317 "fcom",
2318 "fcomp",
2319 "fsub",
2320 "fsubr",
2321 "fdiv",
2322 "fdivr",
2323 /* dd */
2324 "fld",
2325 "(bad)",
2326 "fst",
2327 "fstp",
2328 "frstor",
2329 "(bad)",
2330 "fNsave",
2331 "fNstsw",
2332 /* de */
2333 "fiadd",
2334 "fimul",
2335 "ficom",
2336 "ficomp",
2337 "fisub",
2338 "fisubr",
2339 "fidiv",
2340 "fidivr",
2341 /* df */
2342 "fild",
2343 "(bad)",
2344 "fist",
2345 "fistp",
2346 "fbld",
2347 "fild",
2348 "fbstp",
2349 "fistpll",
2350 };
2351
2352 #define ST OP_ST, 0
2353 #define STi OP_STi, 0
2354
2355 #define FGRPd9_2 NULL, NULL, 0
2356 #define FGRPd9_4 NULL, NULL, 1
2357 #define FGRPd9_5 NULL, NULL, 2
2358 #define FGRPd9_6 NULL, NULL, 3
2359 #define FGRPd9_7 NULL, NULL, 4
2360 #define FGRPda_5 NULL, NULL, 5
2361 #define FGRPdb_4 NULL, NULL, 6
2362 #define FGRPde_3 NULL, NULL, 7
2363 #define FGRPdf_4 NULL, NULL, 8
2364
2365 static struct dis386 float_reg[][8] = {
2366 /* d8 */
2367 {
2368 { "fadd", ST, STi },
2369 { "fmul", ST, STi },
2370 { "fcom", STi },
2371 { "fcomp", STi },
2372 { "fsub", ST, STi },
2373 { "fsubr", ST, STi },
2374 { "fdiv", ST, STi },
2375 { "fdivr", ST, STi },
2376 },
2377 /* d9 */
2378 {
2379 { "fld", STi },
2380 { "fxch", STi },
2381 { FGRPd9_2 },
2382 { "(bad)" },
2383 { FGRPd9_4 },
2384 { FGRPd9_5 },
2385 { FGRPd9_6 },
2386 { FGRPd9_7 },
2387 },
2388 /* da */
2389 {
2390 { "fcmovb", ST, STi },
2391 { "fcmove", ST, STi },
2392 { "fcmovbe",ST, STi },
2393 { "fcmovu", ST, STi },
2394 { "(bad)" },
2395 { FGRPda_5 },
2396 { "(bad)" },
2397 { "(bad)" },
2398 },
2399 /* db */
2400 {
2401 { "fcmovnb",ST, STi },
2402 { "fcmovne",ST, STi },
2403 { "fcmovnbe",ST, STi },
2404 { "fcmovnu",ST, STi },
2405 { FGRPdb_4 },
2406 { "fucomi", ST, STi },
2407 { "fcomi", ST, STi },
2408 { "(bad)" },
2409 },
2410 /* dc */
2411 {
2412 { "fadd", STi, ST },
2413 { "fmul", STi, ST },
2414 { "(bad)" },
2415 { "(bad)" },
2416 #if UNIXWARE_COMPAT
2417 { "fsub", STi, ST },
2418 { "fsubr", STi, ST },
2419 { "fdiv", STi, ST },
2420 { "fdivr", STi, ST },
2421 #else
2422 { "fsubr", STi, ST },
2423 { "fsub", STi, ST },
2424 { "fdivr", STi, ST },
2425 { "fdiv", STi, ST },
2426 #endif
2427 },
2428 /* dd */
2429 {
2430 { "ffree", STi },
2431 { "(bad)" },
2432 { "fst", STi },
2433 { "fstp", STi },
2434 { "fucom", STi },
2435 { "fucomp", STi },
2436 { "(bad)" },
2437 { "(bad)" },
2438 },
2439 /* de */
2440 {
2441 { "faddp", STi, ST },
2442 { "fmulp", STi, ST },
2443 { "(bad)" },
2444 { FGRPde_3 },
2445 #if UNIXWARE_COMPAT
2446 { "fsubp", STi, ST },
2447 { "fsubrp", STi, ST },
2448 { "fdivp", STi, ST },
2449 { "fdivrp", STi, ST },
2450 #else
2451 { "fsubrp", STi, ST },
2452 { "fsubp", STi, ST },
2453 { "fdivrp", STi, ST },
2454 { "fdivp", STi, ST },
2455 #endif
2456 },
2457 /* df */
2458 {
2459 { "(bad)" },
2460 { "(bad)" },
2461 { "(bad)" },
2462 { "(bad)" },
2463 { FGRPdf_4 },
2464 { "fucomip",ST, STi },
2465 { "fcomip", ST, STi },
2466 { "(bad)" },
2467 },
2468 };
2469
2470
2471 static char *fgrps[][8] = {
2472 /* d9_2 0 */
2473 {
2474 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2475 },
2476
2477 /* d9_4 1 */
2478 {
2479 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
2480 },
2481
2482 /* d9_5 2 */
2483 {
2484 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
2485 },
2486
2487 /* d9_6 3 */
2488 {
2489 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
2490 },
2491
2492 /* d9_7 4 */
2493 {
2494 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
2495 },
2496
2497 /* da_5 5 */
2498 {
2499 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2500 },
2501
2502 /* db_4 6 */
2503 {
2504 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
2505 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
2506 },
2507
2508 /* de_3 7 */
2509 {
2510 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2511 },
2512
2513 /* df_4 8 */
2514 {
2515 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
2516 },
2517 };
2518
2519 static void
2520 dofloat (sizeflag)
2521 int sizeflag;
2522 {
2523 struct dis386 *dp;
2524 unsigned char floatop;
2525
2526 floatop = codep[-1];
2527
2528 if (mod != 3)
2529 {
2530 if (intel_syntax)
2531 putop (float_mem_intel[(floatop - 0xd8 ) * 8 + reg], sizeflag);
2532 else
2533 putop (float_mem_att[(floatop - 0xd8 ) * 8 + reg], sizeflag);
2534 obufp = op1out;
2535 if (floatop == 0xdb)
2536 OP_E (x_mode, sizeflag);
2537 else if (floatop == 0xdd)
2538 OP_E (d_mode, sizeflag);
2539 else
2540 OP_E (v_mode, sizeflag);
2541 return;
2542 }
2543 codep++;
2544
2545 dp = &float_reg[floatop - 0xd8][reg];
2546 if (dp->name == NULL)
2547 {
2548 putop (fgrps[dp->bytemode1][rm], sizeflag);
2549
2550 /* instruction fnstsw is only one with strange arg */
2551 if (floatop == 0xdf && codep[-1] == 0xe0)
2552 strcpy (op1out, names16[0]);
2553 }
2554 else
2555 {
2556 putop (dp->name, sizeflag);
2557
2558 obufp = op1out;
2559 if (dp->op1)
2560 (*dp->op1)(dp->bytemode1, sizeflag);
2561 obufp = op2out;
2562 if (dp->op2)
2563 (*dp->op2)(dp->bytemode2, sizeflag);
2564 }
2565 }
2566
2567 /* ARGSUSED */
2568 static void
2569 OP_ST (ignore, sizeflag)
2570 int ignore;
2571 int sizeflag;
2572 {
2573 oappend ("%st");
2574 }
2575
2576 /* ARGSUSED */
2577 static void
2578 OP_STi (ignore, sizeflag)
2579 int ignore;
2580 int sizeflag;
2581 {
2582 sprintf (scratchbuf, "%%st(%d)", rm);
2583 oappend (scratchbuf);
2584 }
2585
2586
2587 /* capital letters in template are macros */
2588 static void
2589 putop (template, sizeflag)
2590 char *template;
2591 int sizeflag;
2592 {
2593 char *p;
2594
2595 for (p = template; *p; p++)
2596 {
2597 switch (*p)
2598 {
2599 default:
2600 *obufp++ = *p;
2601 break;
2602 case 'A':
2603 if (intel_syntax)
2604 break;
2605 if (mod != 3
2606 #ifdef SUFFIX_ALWAYS
2607 || (sizeflag & SUFFIX_ALWAYS)
2608 #endif
2609 )
2610 *obufp++ = 'b';
2611 break;
2612 case 'B':
2613 if (intel_syntax)
2614 break;
2615 #ifdef SUFFIX_ALWAYS
2616 if (sizeflag & SUFFIX_ALWAYS)
2617 *obufp++ = 'b';
2618 #endif
2619 break;
2620 case 'E': /* For jcxz/jecxz */
2621 if (sizeflag & AFLAG)
2622 *obufp++ = 'e';
2623 break;
2624 case 'L':
2625 if (intel_syntax)
2626 break;
2627 #ifdef SUFFIX_ALWAYS
2628 if (sizeflag & SUFFIX_ALWAYS)
2629 *obufp++ = 'l';
2630 #endif
2631 break;
2632 case 'N':
2633 if ((prefixes & PREFIX_FWAIT) == 0)
2634 *obufp++ = 'n';
2635 break;
2636 case 'P':
2637 if (intel_syntax)
2638 break;
2639 if ((prefixes & PREFIX_DATA)
2640 #ifdef SUFFIX_ALWAYS
2641 || (sizeflag & SUFFIX_ALWAYS)
2642 #endif
2643 )
2644 {
2645 if (sizeflag & DFLAG)
2646 *obufp++ = 'l';
2647 else
2648 *obufp++ = 'w';
2649 }
2650 break;
2651 case 'Q':
2652 if (intel_syntax)
2653 break;
2654 if (mod != 3
2655 #ifdef SUFFIX_ALWAYS
2656 || (sizeflag & SUFFIX_ALWAYS)
2657 #endif
2658 )
2659 {
2660 if (sizeflag & DFLAG)
2661 *obufp++ = 'l';
2662 else
2663 *obufp++ = 'w';
2664 }
2665 break;
2666 case 'R':
2667 if (intel_syntax)
2668 {
2669 if (sizeflag & DFLAG)
2670 {
2671 *obufp++ = 'd';
2672 *obufp++ = 'q';
2673 }
2674 else
2675 {
2676 *obufp++ = 'w';
2677 *obufp++ = 'd';
2678 }
2679 }
2680 else
2681 {
2682 if (sizeflag & DFLAG)
2683 *obufp++ = 'l';
2684 else
2685 *obufp++ = 'w';
2686 }
2687 break;
2688 case 'S':
2689 if (intel_syntax)
2690 break;
2691 #ifdef SUFFIX_ALWAYS
2692 if (sizeflag & SUFFIX_ALWAYS)
2693 {
2694 if (sizeflag & DFLAG)
2695 *obufp++ = 'l';
2696 else
2697 *obufp++ = 'w';
2698 }
2699 #endif
2700 break;
2701 case 'W':
2702 /* operand size flag for cwtl, cbtw */
2703 if (sizeflag & DFLAG)
2704 *obufp++ = 'w';
2705 else
2706 *obufp++ = 'b';
2707 if (intel_syntax)
2708 {
2709 if (sizeflag & DFLAG)
2710 {
2711 *obufp++ = 'd';
2712 *obufp++ = 'e';
2713 }
2714 else
2715 {
2716 *obufp++ = 'w';
2717 }
2718 }
2719 break;
2720 }
2721 }
2722 *obufp = 0;
2723 }
2724
2725 static void
2726 oappend (s)
2727 char *s;
2728 {
2729 strcpy (obufp, s);
2730 obufp += strlen (s);
2731 }
2732
2733 static void
2734 append_seg ()
2735 {
2736 if (prefixes & PREFIX_CS)
2737 oappend ("%cs:");
2738 if (prefixes & PREFIX_DS)
2739 oappend ("%ds:");
2740 if (prefixes & PREFIX_SS)
2741 oappend ("%ss:");
2742 if (prefixes & PREFIX_ES)
2743 oappend ("%es:");
2744 if (prefixes & PREFIX_FS)
2745 oappend ("%fs:");
2746 if (prefixes & PREFIX_GS)
2747 oappend ("%gs:");
2748 }
2749
2750 static void
2751 OP_indirE (bytemode, sizeflag)
2752 int bytemode;
2753 int sizeflag;
2754 {
2755 if (!intel_syntax)
2756 oappend ("*");
2757 OP_E (bytemode, sizeflag);
2758 }
2759
2760 static void
2761 OP_E (bytemode, sizeflag)
2762 int bytemode;
2763 int sizeflag;
2764 {
2765 int disp;
2766
2767 /* skip mod/rm byte */
2768 codep++;
2769
2770 if (mod == 3)
2771 {
2772 switch (bytemode)
2773 {
2774 case b_mode:
2775 oappend (names8[rm]);
2776 break;
2777 case w_mode:
2778 oappend (names16[rm]);
2779 break;
2780 case v_mode:
2781 if (sizeflag & DFLAG)
2782 oappend (names32[rm]);
2783 else
2784 oappend (names16[rm]);
2785 break;
2786 case 0: /* sfence */
2787 break;
2788 default:
2789 oappend (INTERNAL_DISASSEMBLER_ERROR);
2790 break;
2791 }
2792 return;
2793 }
2794
2795 disp = 0;
2796 append_seg ();
2797
2798 if (sizeflag & AFLAG) /* 32 bit address mode */
2799 {
2800 int havesib;
2801 int havebase;
2802 int base;
2803 int index = 0;
2804 int scale = 0;
2805
2806 havesib = 0;
2807 havebase = 1;
2808 base = rm;
2809
2810 if (base == 4)
2811 {
2812 havesib = 1;
2813 FETCH_DATA (the_info, codep + 1);
2814 scale = (*codep >> 6) & 3;
2815 index = (*codep >> 3) & 7;
2816 base = *codep & 7;
2817 codep++;
2818 }
2819
2820 switch (mod)
2821 {
2822 case 0:
2823 if (base == 5)
2824 {
2825 havebase = 0;
2826 disp = get32 ();
2827 }
2828 break;
2829 case 1:
2830 FETCH_DATA (the_info, codep + 1);
2831 disp = *codep++;
2832 if ((disp & 0x80) != 0)
2833 disp -= 0x100;
2834 break;
2835 case 2:
2836 disp = get32 ();
2837 break;
2838 }
2839
2840 if (!intel_syntax)
2841 if (mod != 0 || base == 5)
2842 {
2843 sprintf (scratchbuf, "0x%x", disp);
2844 oappend (scratchbuf);
2845 }
2846
2847 if (havebase || (havesib && (index != 4 || scale != 0)))
2848 {
2849 if (intel_syntax)
2850 {
2851 switch (bytemode)
2852 {
2853 case b_mode:
2854 oappend("BYTE PTR ");
2855 break;
2856 case w_mode:
2857 oappend("WORD PTR ");
2858 break;
2859 case v_mode:
2860 oappend("DWORD PTR ");
2861 break;
2862 case d_mode:
2863 oappend("QWORD PTR ");
2864 break;
2865 case x_mode:
2866 oappend("XWORD PTR ");
2867 break;
2868 default:
2869 break;
2870 }
2871 }
2872 *obufp++ = open_char;
2873 *obufp = '\0';
2874 if (havebase)
2875 oappend (names32[base]);
2876 if (havesib)
2877 {
2878 if (index != 4)
2879 {
2880 if (intel_syntax)
2881 {
2882 if (havebase)
2883 {
2884 *obufp++ = separator_char;
2885 *obufp = '\0';
2886 }
2887 sprintf (scratchbuf, "%s", names32[index]);
2888 }
2889 else
2890 sprintf (scratchbuf, ",%s", names32[index]);
2891 oappend (scratchbuf);
2892 }
2893 if (!intel_syntax
2894 || (intel_syntax
2895 && bytemode != b_mode
2896 && bytemode != w_mode
2897 && bytemode != v_mode))
2898 {
2899 *obufp++ = scale_char;
2900 *obufp = '\0';
2901 sprintf (scratchbuf, "%d", 1 << scale);
2902 oappend (scratchbuf);
2903 }
2904 }
2905 if (intel_syntax)
2906 if (mod != 0 || base == 5)
2907 {
2908 /* Don't print zero displacements */
2909 if (disp > 0)
2910 {
2911 sprintf (scratchbuf, "+%d", disp);
2912 oappend (scratchbuf);
2913 }
2914 else if (disp < 0)
2915 {
2916 sprintf (scratchbuf, "%d", disp);
2917 oappend (scratchbuf);
2918 }
2919 }
2920
2921 *obufp++ = close_char;
2922 *obufp = '\0';
2923 }
2924 else if (intel_syntax)
2925 {
2926 if (mod != 0 || base == 5)
2927 {
2928 if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
2929 | PREFIX_ES | PREFIX_FS | PREFIX_GS))
2930 ;
2931 else
2932 {
2933 oappend (names_seg[3]);
2934 oappend (":");
2935 }
2936 sprintf (scratchbuf, "0x%x", disp);
2937 oappend (scratchbuf);
2938 }
2939 }
2940 }
2941 else
2942 { /* 16 bit address mode */
2943 switch (mod)
2944 {
2945 case 0:
2946 if (rm == 6)
2947 {
2948 disp = get16 ();
2949 if ((disp & 0x8000) != 0)
2950 disp -= 0x10000;
2951 }
2952 break;
2953 case 1:
2954 FETCH_DATA (the_info, codep + 1);
2955 disp = *codep++;
2956 if ((disp & 0x80) != 0)
2957 disp -= 0x100;
2958 break;
2959 case 2:
2960 disp = get16 ();
2961 if ((disp & 0x8000) != 0)
2962 disp -= 0x10000;
2963 break;
2964 }
2965
2966 if (!intel_syntax)
2967 if (mod != 0 || rm == 6)
2968 {
2969 sprintf (scratchbuf, "%d", disp);
2970 oappend (scratchbuf);
2971 }
2972
2973 if (mod != 0 || rm != 6)
2974 {
2975 *obufp++ = open_char;
2976 *obufp = '\0';
2977 oappend (index16[rm]);
2978 *obufp++ = close_char;
2979 *obufp = '\0';
2980 }
2981 }
2982 }
2983
2984 static void
2985 OP_G (bytemode, sizeflag)
2986 int bytemode;
2987 int sizeflag;
2988 {
2989 switch (bytemode)
2990 {
2991 case b_mode:
2992 oappend (names8[reg]);
2993 break;
2994 case w_mode:
2995 oappend (names16[reg]);
2996 break;
2997 case d_mode:
2998 oappend (names32[reg]);
2999 break;
3000 case v_mode:
3001 if (sizeflag & DFLAG)
3002 oappend (names32[reg]);
3003 else
3004 oappend (names16[reg]);
3005 break;
3006 default:
3007 oappend (INTERNAL_DISASSEMBLER_ERROR);
3008 break;
3009 }
3010 }
3011
3012 static int
3013 get32 ()
3014 {
3015 int x = 0;
3016
3017 FETCH_DATA (the_info, codep + 4);
3018 x = *codep++ & 0xff;
3019 x |= (*codep++ & 0xff) << 8;
3020 x |= (*codep++ & 0xff) << 16;
3021 x |= (*codep++ & 0xff) << 24;
3022 return x;
3023 }
3024
3025 static int
3026 get16 ()
3027 {
3028 int x = 0;
3029
3030 FETCH_DATA (the_info, codep + 2);
3031 x = *codep++ & 0xff;
3032 x |= (*codep++ & 0xff) << 8;
3033 return x;
3034 }
3035
3036 static void
3037 set_op (op)
3038 unsigned int op;
3039 {
3040 op_index[op_ad] = op_ad;
3041 op_address[op_ad] = op;
3042 }
3043
3044 static void
3045 OP_REG (code, sizeflag)
3046 int code;
3047 int sizeflag;
3048 {
3049 char *s;
3050
3051 switch (code)
3052 {
3053 case indir_dx_reg:
3054 s = "(%dx)";
3055 break;
3056 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
3057 case sp_reg: case bp_reg: case si_reg: case di_reg:
3058 s = names16[code - ax_reg];
3059 break;
3060 case es_reg: case ss_reg: case cs_reg:
3061 case ds_reg: case fs_reg: case gs_reg:
3062 s = names_seg[code - es_reg];
3063 break;
3064 case al_reg: case ah_reg: case cl_reg: case ch_reg:
3065 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
3066 s = names8[code - al_reg];
3067 break;
3068 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
3069 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
3070 if (sizeflag & DFLAG)
3071 s = names32[code - eAX_reg];
3072 else
3073 s = names16[code - eAX_reg];
3074 break;
3075 default:
3076 s = INTERNAL_DISASSEMBLER_ERROR;
3077 break;
3078 }
3079 oappend (s);
3080 }
3081
3082 static void
3083 OP_I (bytemode, sizeflag)
3084 int bytemode;
3085 int sizeflag;
3086 {
3087 int op;
3088
3089 switch (bytemode)
3090 {
3091 case b_mode:
3092 FETCH_DATA (the_info, codep + 1);
3093 op = *codep++ & 0xff;
3094 break;
3095 case v_mode:
3096 if (sizeflag & DFLAG)
3097 op = get32 ();
3098 else
3099 op = get16 ();
3100 break;
3101 case w_mode:
3102 op = get16 ();
3103 break;
3104 default:
3105 oappend (INTERNAL_DISASSEMBLER_ERROR);
3106 return;
3107 }
3108
3109 if (intel_syntax)
3110 sprintf (scratchbuf, "0x%x", op);
3111 else
3112 sprintf (scratchbuf, "$0x%x", op);
3113 oappend (scratchbuf);
3114 scratchbuf[0] = '\0';
3115 }
3116
3117 static void
3118 OP_sI (bytemode, sizeflag)
3119 int bytemode;
3120 int sizeflag;
3121 {
3122 int op;
3123
3124 switch (bytemode)
3125 {
3126 case b_mode:
3127 FETCH_DATA (the_info, codep + 1);
3128 op = *codep++;
3129 if ((op & 0x80) != 0)
3130 op -= 0x100;
3131 break;
3132 case v_mode:
3133 if (sizeflag & DFLAG)
3134 op = get32 ();
3135 else
3136 {
3137 op = get16();
3138 if ((op & 0x8000) != 0)
3139 op -= 0x10000;
3140 }
3141 break;
3142 case w_mode:
3143 op = get16 ();
3144 if ((op & 0x8000) != 0)
3145 op -= 0x10000;
3146 break;
3147 default:
3148 oappend (INTERNAL_DISASSEMBLER_ERROR);
3149 return;
3150 }
3151 if (intel_syntax)
3152 sprintf (scratchbuf, "%d", op);
3153 else
3154 sprintf (scratchbuf, "$0x%x", op);
3155 oappend (scratchbuf);
3156 }
3157
3158 static void
3159 OP_J (bytemode, sizeflag)
3160 int bytemode;
3161 int sizeflag;
3162 {
3163 int disp;
3164 int mask = -1;
3165
3166 switch (bytemode)
3167 {
3168 case b_mode:
3169 FETCH_DATA (the_info, codep + 1);
3170 disp = *codep++;
3171 if ((disp & 0x80) != 0)
3172 disp -= 0x100;
3173 break;
3174 case v_mode:
3175 if (sizeflag & DFLAG)
3176 disp = get32 ();
3177 else
3178 {
3179 disp = get16 ();
3180 /* for some reason, a data16 prefix on a jump instruction
3181 means that the pc is masked to 16 bits after the
3182 displacement is added! */
3183 mask = 0xffff;
3184 }
3185 break;
3186 default:
3187 oappend (INTERNAL_DISASSEMBLER_ERROR);
3188 return;
3189 }
3190 disp = (start_pc + codep - start_codep + disp) & mask;
3191 set_op (disp);
3192 sprintf (scratchbuf, "0x%x", disp);
3193 oappend (scratchbuf);
3194 }
3195
3196 /* ARGSUSED */
3197 static void
3198 OP_SEG (dummy, sizeflag)
3199 int dummy;
3200 int sizeflag;
3201 {
3202 static char *sreg[] = {
3203 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
3204 };
3205
3206 oappend (sreg[reg]);
3207 }
3208
3209 /* ARGSUSED */
3210 static void
3211 OP_DIR (dummy, sizeflag)
3212 int dummy;
3213 int sizeflag;
3214 {
3215 int seg, offset;
3216
3217 if (sizeflag & DFLAG)
3218 {
3219 offset = get32 ();
3220 seg = get16 ();
3221 }
3222 else
3223 {
3224 offset = get16 ();
3225 seg = get16 ();
3226 }
3227 sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
3228 oappend (scratchbuf);
3229 }
3230
3231 /* ARGSUSED */
3232 static void
3233 OP_OFF (ignore, sizeflag)
3234 int ignore;
3235 int sizeflag;
3236 {
3237 int off;
3238
3239 append_seg ();
3240
3241 if (sizeflag & AFLAG)
3242 off = get32 ();
3243 else
3244 off = get16 ();
3245
3246 if (intel_syntax)
3247 {
3248 if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
3249 | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
3250 {
3251 oappend (names_seg[3]);
3252 oappend (":");
3253 }
3254 }
3255 sprintf (scratchbuf, "0x%x", off);
3256 oappend (scratchbuf);
3257 }
3258
3259 static void
3260 ptr_reg (code, sizeflag)
3261 int code;
3262 int sizeflag;
3263 {
3264 char *s;
3265 oappend ("(");
3266 if (sizeflag & AFLAG)
3267 s = names32[code - eAX_reg];
3268 else
3269 s = names16[code - eAX_reg];
3270 oappend (s);
3271 oappend (")");
3272 }
3273
3274 static void
3275 OP_ESreg (code, sizeflag)
3276 int code;
3277 int sizeflag;
3278 {
3279 oappend ("%es:");
3280 ptr_reg (code, sizeflag);
3281 }
3282
3283 static void
3284 OP_DSreg (code, sizeflag)
3285 int code;
3286 int sizeflag;
3287 {
3288 if ((prefixes
3289 & (PREFIX_CS
3290 | PREFIX_DS
3291 | PREFIX_SS
3292 | PREFIX_ES
3293 | PREFIX_FS
3294 | PREFIX_GS)) == 0)
3295 prefixes |= PREFIX_DS;
3296 append_seg();
3297 ptr_reg (code, sizeflag);
3298 }
3299
3300 #if 0
3301 /* Not used. */
3302
3303 /* ARGSUSED */
3304 static void
3305 OP_ONE (dummy, sizeflag)
3306 int dummy;
3307 int sizeflag;
3308 {
3309 oappend ("1");
3310 }
3311
3312 #endif
3313
3314 /* ARGSUSED */
3315 static void
3316 OP_C (dummy, sizeflag)
3317 int dummy;
3318 int sizeflag;
3319 {
3320 codep++; /* skip mod/rm */
3321 sprintf (scratchbuf, "%%cr%d", reg);
3322 oappend (scratchbuf);
3323 }
3324
3325 /* ARGSUSED */
3326 static void
3327 OP_D (dummy, sizeflag)
3328 int dummy;
3329 int sizeflag;
3330 {
3331 codep++; /* skip mod/rm */
3332 sprintf (scratchbuf, "%%db%d", reg);
3333 oappend (scratchbuf);
3334 }
3335
3336 /* ARGSUSED */
3337 static void
3338 OP_T (dummy, sizeflag)
3339 int dummy;
3340 int sizeflag;
3341 {
3342 codep++; /* skip mod/rm */
3343 sprintf (scratchbuf, "%%tr%d", reg);
3344 oappend (scratchbuf);
3345 }
3346
3347 static void
3348 OP_rm (bytemode, sizeflag)
3349 int bytemode;
3350 int sizeflag;
3351 {
3352 switch (bytemode)
3353 {
3354 case d_mode:
3355 oappend (names32[rm]);
3356 break;
3357 case w_mode:
3358 oappend (names16[rm]);
3359 break;
3360 }
3361 }
3362
3363 static void
3364 OP_MMX (ignore, sizeflag)
3365 int ignore;
3366 int sizeflag;
3367 {
3368 sprintf (scratchbuf, "%%mm%d", reg);
3369 oappend (scratchbuf);
3370 }
3371
3372 static void
3373 OP_XMM (bytemode, sizeflag)
3374 int bytemode;
3375 int sizeflag;
3376 {
3377 sprintf (scratchbuf, "%%xmm%d", reg);
3378 oappend (scratchbuf);
3379 }
3380
3381 static void
3382 OP_EM (bytemode, sizeflag)
3383 int bytemode;
3384 int sizeflag;
3385 {
3386 if (mod != 3)
3387 {
3388 OP_E (bytemode, sizeflag);
3389 return;
3390 }
3391
3392 codep++;
3393 sprintf (scratchbuf, "%%mm%d", rm);
3394 oappend (scratchbuf);
3395 }
3396
3397 static void
3398 OP_EX (bytemode, sizeflag)
3399 int bytemode;
3400 int sizeflag;
3401 {
3402 if (mod != 3)
3403 {
3404 OP_E (bytemode, sizeflag);
3405 return;
3406 }
3407
3408 codep++;
3409 sprintf (scratchbuf, "%%xmm%d", rm);
3410 oappend (scratchbuf);
3411 }
3412
3413 static void
3414 OP_MS (ignore, sizeflag)
3415 int ignore;
3416 int sizeflag;
3417 {
3418 ++codep;
3419 sprintf (scratchbuf, "%%mm%d", rm);
3420 oappend (scratchbuf);
3421 }
3422
3423 static const char *Suffix3DNow[] = {
3424 /* 00 */ NULL, NULL, NULL, NULL,
3425 /* 04 */ NULL, NULL, NULL, NULL,
3426 /* 08 */ NULL, NULL, NULL, NULL,
3427 /* 0C */ NULL, "pi2fd", NULL, NULL,
3428 /* 10 */ NULL, NULL, NULL, NULL,
3429 /* 14 */ NULL, NULL, NULL, NULL,
3430 /* 18 */ NULL, NULL, NULL, NULL,
3431 /* 1C */ NULL, "pf2id", NULL, NULL,
3432 /* 20 */ NULL, NULL, NULL, NULL,
3433 /* 24 */ NULL, NULL, NULL, NULL,
3434 /* 28 */ NULL, NULL, NULL, NULL,
3435 /* 2C */ NULL, NULL, NULL, NULL,
3436 /* 30 */ NULL, NULL, NULL, NULL,
3437 /* 34 */ NULL, NULL, NULL, NULL,
3438 /* 38 */ NULL, NULL, NULL, NULL,
3439 /* 3C */ NULL, NULL, NULL, NULL,
3440 /* 40 */ NULL, NULL, NULL, NULL,
3441 /* 44 */ NULL, NULL, NULL, NULL,
3442 /* 48 */ NULL, NULL, NULL, NULL,
3443 /* 4C */ NULL, NULL, NULL, NULL,
3444 /* 50 */ NULL, NULL, NULL, NULL,
3445 /* 54 */ NULL, NULL, NULL, NULL,
3446 /* 58 */ NULL, NULL, NULL, NULL,
3447 /* 5C */ NULL, NULL, NULL, NULL,
3448 /* 60 */ NULL, NULL, NULL, NULL,
3449 /* 64 */ NULL, NULL, NULL, NULL,
3450 /* 68 */ NULL, NULL, NULL, NULL,
3451 /* 6C */ NULL, NULL, NULL, NULL,
3452 /* 70 */ NULL, NULL, NULL, NULL,
3453 /* 74 */ NULL, NULL, NULL, NULL,
3454 /* 78 */ NULL, NULL, NULL, NULL,
3455 /* 7C */ NULL, NULL, NULL, NULL,
3456 /* 80 */ NULL, NULL, NULL, NULL,
3457 /* 84 */ NULL, NULL, NULL, NULL,
3458 /* 88 */ NULL, NULL, NULL, NULL,
3459 /* 8C */ NULL, NULL, NULL, NULL,
3460 /* 90 */ "pfcmpge", NULL, NULL, NULL,
3461 /* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
3462 /* 98 */ NULL, NULL, "pfsub", NULL,
3463 /* 9C */ NULL, NULL, "pfadd", NULL,
3464 /* A0 */ "pfcmpgt", NULL, NULL, NULL,
3465 /* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
3466 /* A8 */ NULL, NULL, "pfsubr", NULL,
3467 /* AC */ NULL, NULL, "pfacc", NULL,
3468 /* B0 */ "pfcmpeq", NULL, NULL, NULL,
3469 /* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
3470 /* B8 */ NULL, NULL, NULL, NULL,
3471 /* BC */ NULL, NULL, NULL, "pavgusb",
3472 /* C0 */ NULL, NULL, NULL, NULL,
3473 /* C4 */ NULL, NULL, NULL, NULL,
3474 /* C8 */ NULL, NULL, NULL, NULL,
3475 /* CC */ NULL, NULL, NULL, NULL,
3476 /* D0 */ NULL, NULL, NULL, NULL,
3477 /* D4 */ NULL, NULL, NULL, NULL,
3478 /* D8 */ NULL, NULL, NULL, NULL,
3479 /* DC */ NULL, NULL, NULL, NULL,
3480 /* E0 */ NULL, NULL, NULL, NULL,
3481 /* E4 */ NULL, NULL, NULL, NULL,
3482 /* E8 */ NULL, NULL, NULL, NULL,
3483 /* EC */ NULL, NULL, NULL, NULL,
3484 /* F0 */ NULL, NULL, NULL, NULL,
3485 /* F4 */ NULL, NULL, NULL, NULL,
3486 /* F8 */ NULL, NULL, NULL, NULL,
3487 /* FC */ NULL, NULL, NULL, NULL,
3488 };
3489
3490 static void
3491 OP_3DNowSuffix (bytemode, sizeflag)
3492 int bytemode;
3493 int sizeflag;
3494 {
3495 const char *mnemonic;
3496
3497 FETCH_DATA (the_info, codep + 1);
3498 /* AMD 3DNow! instructions are specified by an opcode suffix in the
3499 place where an 8-bit immediate would normally go. ie. the last
3500 byte of the instruction. */
3501 mnemonic = Suffix3DNow[*codep++ & 0xff];
3502 if (mnemonic)
3503 strcat (obuf, mnemonic);
3504 else
3505 {
3506 /* Since a variable sized modrm/sib chunk is between the start
3507 of the opcode (0x0f0f) and the opcode suffix, we need to do
3508 all the modrm processing first, and don't know until now that
3509 we have a bad opcode. This necessitates some cleaning up. */
3510 op1out[0] = 0;
3511 op2out[0] = 0;
3512 codep = insn_codep + 1;
3513 strcat (obuf, "(bad)");
3514 }
3515 }
3516
3517
3518 static const char *simd_cmp_op [] = {
3519 "eq",
3520 "lt",
3521 "le",
3522 "unord",
3523 "neq",
3524 "nlt",
3525 "nle",
3526 "ord"
3527 };
3528
3529 static void
3530 OP_SIMD_Suffix (bytemode, sizeflag)
3531 int bytemode;
3532 int sizeflag;
3533 {
3534 unsigned int cmp_type;
3535
3536 FETCH_DATA (the_info, codep + 1);
3537 cmp_type = *codep++ & 0xff;
3538 if (cmp_type < 8)
3539 {
3540 sprintf (scratchbuf, "cmp%s%cs",
3541 simd_cmp_op[cmp_type],
3542 prefixes & PREFIX_REPZ ? 's' : 'p');
3543 strcat (obuf, scratchbuf);
3544 }
3545 else
3546 {
3547 /* We have a bad extension byte. Clean up. */
3548 op1out[0] = 0;
3549 op2out[0] = 0;
3550 codep = insn_codep + 1;
3551 strcat (obuf, "(bad)");
3552 }
3553 }
3554
3555 static void
3556 SIMD_Fixup (extrachar, sizeflag)
3557 int extrachar;
3558 int sizeflag;
3559 {
3560 /* Change movlps/movhps to movhlps/movlhps for 2 register operand
3561 forms of these instructions. */
3562 if (mod == 3)
3563 {
3564 char *p = obuf + strlen(obuf);
3565 *(p+1) = '\0';
3566 *p = *(p-1);
3567 *(p-1) = *(p-2);
3568 *(p-2) = *(p-3);
3569 *(p-3) = extrachar;
3570 }
3571 }
This page took 0.106344 seconds and 4 git commands to generate.