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