Set r environment variable that CC_FOR_TARGET needs in CONFIGURE_TARGET_MODULES
[deliverable/binutils-gdb.git] / opcodes / i386-dis.c
CommitLineData
5d0734a7 1/* Print i386 instructions for GDB, the GNU debugger.
726257a8 2 Copyright (C) 1988, 1989, 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
5d0734a7
JK
3
4This file is part of GDB.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
726257a8 18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
5d0734a7
JK
19
20/*
21 * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
22 * July 1988
23 * modified by John Hassey (hassey@dg-rtp.dg.com)
24 */
25
26/*
27 * The main tables describing the instructions is essentially a copy
28 * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
29 * Programmers Manual. Usually, there is a capital letter, followed
30 * by a small letter. The capital letter tell the addressing mode,
31 * and the small letter tells about the operand size. Refer to
32 * the Intel manual for details.
33 */
34
35#include "dis-asm.h"
726257a8 36#include "sysdep.h"
5d0734a7
JK
37
38#define MAXLEN 20
39
40#include <setjmp.h>
41
726257a8 42struct dis_private
5d0734a7
JK
43{
44 /* Points to first byte not fetched. */
45 bfd_byte *max_fetched;
46 bfd_byte the_buffer[MAXLEN];
47 bfd_vma insn_start;
48 jmp_buf bailout;
49};
50
51/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
52 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
53 on error. */
54#define FETCH_DATA(info, addr) \
726257a8 55 ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
5d0734a7
JK
56 ? 1 : fetch_data ((info), (addr)))
57
58static int
59fetch_data (info, addr)
60 struct disassemble_info *info;
61 bfd_byte *addr;
62{
63 int status;
726257a8 64 struct dis_private *priv = (struct dis_private *)info->private_data;
5d0734a7
JK
65 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
66
67 status = (*info->read_memory_func) (start,
68 priv->max_fetched,
69 addr - priv->max_fetched,
70 info);
71 if (status != 0)
72 {
73 (*info->memory_error_func) (status, start, info);
05545edc 74 longjmp (priv->bailout, 1);
5d0734a7
JK
75 }
76 else
77 priv->max_fetched = addr;
78 return 1;
79}
80
81#define Eb OP_E, b_mode
82#define indirEb OP_indirE, b_mode
83#define Gb OP_G, b_mode
84#define Ev OP_E, v_mode
85#define indirEv OP_indirE, v_mode
86#define Ew OP_E, w_mode
87#define Ma OP_E, v_mode
88#define M OP_E, 0
89#define Mp OP_E, 0 /* ? */
90#define Gv OP_G, v_mode
91#define Gw OP_G, w_mode
92#define Rw OP_rm, w_mode
93#define Rd OP_rm, d_mode
94#define Ib OP_I, b_mode
95#define sIb OP_sI, b_mode /* sign extened byte */
96#define Iv OP_I, v_mode
97#define Iw OP_I, w_mode
98#define Jb OP_J, b_mode
99#define Jv OP_J, v_mode
100#define ONE OP_ONE, 0
101#define Cd OP_C, d_mode
102#define Dd OP_D, d_mode
103#define Td OP_T, d_mode
104
105#define eAX OP_REG, eAX_reg
106#define eBX OP_REG, eBX_reg
107#define eCX OP_REG, eCX_reg
108#define eDX OP_REG, eDX_reg
109#define eSP OP_REG, eSP_reg
110#define eBP OP_REG, eBP_reg
111#define eSI OP_REG, eSI_reg
112#define eDI OP_REG, eDI_reg
113#define AL OP_REG, al_reg
114#define CL OP_REG, cl_reg
115#define DL OP_REG, dl_reg
116#define BL OP_REG, bl_reg
117#define AH OP_REG, ah_reg
118#define CH OP_REG, ch_reg
119#define DH OP_REG, dh_reg
120#define BH OP_REG, bh_reg
121#define AX OP_REG, ax_reg
122#define DX OP_REG, dx_reg
123#define indirDX OP_REG, indir_dx_reg
124
125#define Sw OP_SEG, w_mode
126#define Ap OP_DIR, lptr
127#define Av OP_DIR, v_mode
128#define Ob OP_OFF, b_mode
129#define Ov OP_OFF, v_mode
130#define Xb OP_DSSI, b_mode
131#define Xv OP_DSSI, v_mode
132#define Yb OP_ESDI, b_mode
133#define Yv OP_ESDI, v_mode
134
135#define es OP_REG, es_reg
136#define ss OP_REG, ss_reg
137#define cs OP_REG, cs_reg
138#define ds OP_REG, ds_reg
139#define fs OP_REG, fs_reg
140#define gs OP_REG, gs_reg
141
142int OP_E(), OP_indirE(), OP_G(), OP_I(), OP_sI(), OP_REG();
143int OP_J(), OP_SEG();
144int OP_DIR(), OP_OFF(), OP_DSSI(), OP_ESDI(), OP_ONE(), OP_C();
145int OP_D(), OP_T(), OP_rm();
146
147static void dofloat (), putop (), append_prefix (), set_op ();
148static int get16 (), get32 ();
149
150#define b_mode 1
151#define v_mode 2
152#define w_mode 3
153#define d_mode 4
154
155#define es_reg 100
156#define cs_reg 101
157#define ss_reg 102
158#define ds_reg 103
159#define fs_reg 104
160#define gs_reg 105
161#define eAX_reg 107
162#define eCX_reg 108
163#define eDX_reg 109
164#define eBX_reg 110
165#define eSP_reg 111
166#define eBP_reg 112
167#define eSI_reg 113
168#define eDI_reg 114
169
170#define lptr 115
171
172#define al_reg 116
173#define cl_reg 117
174#define dl_reg 118
175#define bl_reg 119
176#define ah_reg 120
177#define ch_reg 121
178#define dh_reg 122
179#define bh_reg 123
180
181#define ax_reg 124
182#define cx_reg 125
183#define dx_reg 126
184#define bx_reg 127
185#define sp_reg 128
186#define bp_reg 129
187#define si_reg 130
188#define di_reg 131
189
190#define indir_dx_reg 150
191
192#define GRP1b NULL, NULL, 0
193#define GRP1S NULL, NULL, 1
194#define GRP1Ss NULL, NULL, 2
195#define GRP2b NULL, NULL, 3
196#define GRP2S NULL, NULL, 4
197#define GRP2b_one NULL, NULL, 5
198#define GRP2S_one NULL, NULL, 6
199#define GRP2b_cl NULL, NULL, 7
200#define GRP2S_cl NULL, NULL, 8
201#define GRP3b NULL, NULL, 9
202#define GRP3S NULL, NULL, 10
203#define GRP4 NULL, NULL, 11
204#define GRP5 NULL, NULL, 12
205#define GRP6 NULL, NULL, 13
206#define GRP7 NULL, NULL, 14
207#define GRP8 NULL, NULL, 15
726257a8 208#define GRP9 NULL, NULL, 16
5d0734a7
JK
209
210#define FLOATCODE 50
211#define FLOAT NULL, NULL, FLOATCODE
212
213struct dis386 {
214 char *name;
215 int (*op1)();
216 int bytemode1;
217 int (*op2)();
218 int bytemode2;
219 int (*op3)();
220 int bytemode3;
221};
222
223struct dis386 dis386[] = {
224 /* 00 */
225 { "addb", Eb, Gb },
226 { "addS", Ev, Gv },
227 { "addb", Gb, Eb },
228 { "addS", Gv, Ev },
229 { "addb", AL, Ib },
230 { "addS", eAX, Iv },
231 { "pushl", es },
232 { "popl", es },
233 /* 08 */
234 { "orb", Eb, Gb },
235 { "orS", Ev, Gv },
236 { "orb", Gb, Eb },
237 { "orS", Gv, Ev },
238 { "orb", AL, Ib },
239 { "orS", eAX, Iv },
240 { "pushl", cs },
241 { "(bad)" }, /* 0x0f extended opcode escape */
242 /* 10 */
243 { "adcb", Eb, Gb },
244 { "adcS", Ev, Gv },
245 { "adcb", Gb, Eb },
246 { "adcS", Gv, Ev },
247 { "adcb", AL, Ib },
248 { "adcS", eAX, Iv },
249 { "pushl", ss },
250 { "popl", ss },
251 /* 18 */
252 { "sbbb", Eb, Gb },
253 { "sbbS", Ev, Gv },
254 { "sbbb", Gb, Eb },
255 { "sbbS", Gv, Ev },
256 { "sbbb", AL, Ib },
257 { "sbbS", eAX, Iv },
258 { "pushl", ds },
259 { "popl", ds },
260 /* 20 */
261 { "andb", Eb, Gb },
262 { "andS", Ev, Gv },
263 { "andb", Gb, Eb },
264 { "andS", Gv, Ev },
265 { "andb", AL, Ib },
266 { "andS", eAX, Iv },
267 { "(bad)" }, /* SEG ES prefix */
268 { "daa" },
269 /* 28 */
270 { "subb", Eb, Gb },
271 { "subS", Ev, Gv },
272 { "subb", Gb, Eb },
273 { "subS", Gv, Ev },
274 { "subb", AL, Ib },
275 { "subS", eAX, Iv },
276 { "(bad)" }, /* SEG CS prefix */
277 { "das" },
278 /* 30 */
279 { "xorb", Eb, Gb },
280 { "xorS", Ev, Gv },
281 { "xorb", Gb, Eb },
282 { "xorS", Gv, Ev },
283 { "xorb", AL, Ib },
284 { "xorS", eAX, Iv },
285 { "(bad)" }, /* SEG SS prefix */
286 { "aaa" },
287 /* 38 */
288 { "cmpb", Eb, Gb },
289 { "cmpS", Ev, Gv },
290 { "cmpb", Gb, Eb },
291 { "cmpS", Gv, Ev },
292 { "cmpb", AL, Ib },
293 { "cmpS", eAX, Iv },
294 { "(bad)" }, /* SEG DS prefix */
295 { "aas" },
296 /* 40 */
297 { "incS", eAX },
298 { "incS", eCX },
299 { "incS", eDX },
300 { "incS", eBX },
301 { "incS", eSP },
302 { "incS", eBP },
303 { "incS", eSI },
304 { "incS", eDI },
305 /* 48 */
306 { "decS", eAX },
307 { "decS", eCX },
308 { "decS", eDX },
309 { "decS", eBX },
310 { "decS", eSP },
311 { "decS", eBP },
312 { "decS", eSI },
313 { "decS", eDI },
314 /* 50 */
315 { "pushS", eAX },
316 { "pushS", eCX },
317 { "pushS", eDX },
318 { "pushS", eBX },
319 { "pushS", eSP },
320 { "pushS", eBP },
321 { "pushS", eSI },
322 { "pushS", eDI },
323 /* 58 */
324 { "popS", eAX },
325 { "popS", eCX },
326 { "popS", eDX },
327 { "popS", eBX },
328 { "popS", eSP },
329 { "popS", eBP },
330 { "popS", eSI },
331 { "popS", eDI },
332 /* 60 */
333 { "pusha" },
334 { "popa" },
335 { "boundS", Gv, Ma },
336 { "arpl", Ew, Gw },
337 { "(bad)" }, /* seg fs */
338 { "(bad)" }, /* seg gs */
339 { "(bad)" }, /* op size prefix */
340 { "(bad)" }, /* adr size prefix */
341 /* 68 */
342 { "pushS", Iv }, /* 386 book wrong */
343 { "imulS", Gv, Ev, Iv },
344 { "pushl", sIb }, /* push of byte really pushes 4 bytes */
345 { "imulS", Gv, Ev, Ib },
346 { "insb", Yb, indirDX },
347 { "insS", Yv, indirDX },
348 { "outsb", indirDX, Xb },
349 { "outsS", indirDX, Xv },
350 /* 70 */
03db5a93 351 { "jo", Jb },
5d0734a7 352 { "jno", Jb },
03db5a93 353 { "jb", Jb },
5d0734a7 354 { "jae", Jb },
03db5a93 355 { "je", Jb },
5d0734a7
JK
356 { "jne", Jb },
357 { "jbe", Jb },
03db5a93 358 { "ja", Jb },
5d0734a7 359 /* 78 */
03db5a93 360 { "js", Jb },
5d0734a7 361 { "jns", Jb },
03db5a93 362 { "jp", Jb },
5d0734a7 363 { "jnp", Jb },
03db5a93 364 { "jl", Jb },
5d0734a7
JK
365 { "jnl", Jb },
366 { "jle", Jb },
03db5a93 367 { "jg", Jb },
5d0734a7
JK
368 /* 80 */
369 { GRP1b },
370 { GRP1S },
371 { "(bad)" },
372 { GRP1Ss },
373 { "testb", Eb, Gb },
374 { "testS", Ev, Gv },
375 { "xchgb", Eb, Gb },
376 { "xchgS", Ev, Gv },
377 /* 88 */
378 { "movb", Eb, Gb },
379 { "movS", Ev, Gv },
380 { "movb", Gb, Eb },
381 { "movS", Gv, Ev },
382 { "movw", Ew, Sw },
383 { "leaS", Gv, M },
384 { "movw", Sw, Ew },
385 { "popS", Ev },
386 /* 90 */
387 { "nop" },
388 { "xchgS", eCX, eAX },
389 { "xchgS", eDX, eAX },
390 { "xchgS", eBX, eAX },
391 { "xchgS", eSP, eAX },
392 { "xchgS", eBP, eAX },
393 { "xchgS", eSI, eAX },
394 { "xchgS", eDI, eAX },
395 /* 98 */
396 { "cwtl" },
397 { "cltd" },
398 { "lcall", Ap },
399 { "(bad)" }, /* fwait */
400 { "pushf" },
401 { "popf" },
402 { "sahf" },
403 { "lahf" },
404 /* a0 */
405 { "movb", AL, Ob },
406 { "movS", eAX, Ov },
407 { "movb", Ob, AL },
408 { "movS", Ov, eAX },
409 { "movsb", Yb, Xb },
410 { "movsS", Yv, Xv },
411 { "cmpsb", Yb, Xb },
412 { "cmpsS", Yv, Xv },
413 /* a8 */
414 { "testb", AL, Ib },
415 { "testS", eAX, Iv },
416 { "stosb", Yb, AL },
417 { "stosS", Yv, eAX },
418 { "lodsb", AL, Xb },
419 { "lodsS", eAX, Xv },
a279b1f5
JK
420 { "scasb", AL, Yb },
421 { "scasS", eAX, Yv },
5d0734a7
JK
422 /* b0 */
423 { "movb", AL, Ib },
424 { "movb", CL, Ib },
425 { "movb", DL, Ib },
426 { "movb", BL, Ib },
427 { "movb", AH, Ib },
428 { "movb", CH, Ib },
429 { "movb", DH, Ib },
430 { "movb", BH, Ib },
431 /* b8 */
432 { "movS", eAX, Iv },
433 { "movS", eCX, Iv },
434 { "movS", eDX, Iv },
435 { "movS", eBX, Iv },
436 { "movS", eSP, Iv },
437 { "movS", eBP, Iv },
438 { "movS", eSI, Iv },
439 { "movS", eDI, Iv },
440 /* c0 */
441 { GRP2b },
442 { GRP2S },
443 { "ret", Iw },
444 { "ret" },
445 { "lesS", Gv, Mp },
446 { "ldsS", Gv, Mp },
447 { "movb", Eb, Ib },
448 { "movS", Ev, Iv },
449 /* c8 */
450 { "enter", Iw, Ib },
451 { "leave" },
452 { "lret", Iw },
453 { "lret" },
454 { "int3" },
455 { "int", Ib },
456 { "into" },
457 { "iret" },
458 /* d0 */
459 { GRP2b_one },
460 { GRP2S_one },
461 { GRP2b_cl },
462 { GRP2S_cl },
463 { "aam", Ib },
464 { "aad", Ib },
465 { "(bad)" },
466 { "xlat" },
467 /* d8 */
468 { FLOAT },
469 { FLOAT },
470 { FLOAT },
471 { FLOAT },
472 { FLOAT },
473 { FLOAT },
474 { FLOAT },
475 { FLOAT },
476 /* e0 */
477 { "loopne", Jb },
478 { "loope", Jb },
479 { "loop", Jb },
480 { "jCcxz", Jb },
481 { "inb", AL, Ib },
482 { "inS", eAX, Ib },
483 { "outb", Ib, AL },
484 { "outS", Ib, eAX },
485 /* e8 */
486 { "call", Av },
487 { "jmp", Jv },
488 { "ljmp", Ap },
489 { "jmp", Jb },
490 { "inb", AL, indirDX },
491 { "inS", eAX, indirDX },
492 { "outb", indirDX, AL },
493 { "outS", indirDX, eAX },
494 /* f0 */
495 { "(bad)" }, /* lock prefix */
496 { "(bad)" },
497 { "(bad)" }, /* repne */
498 { "(bad)" }, /* repz */
499 { "hlt" },
500 { "cmc" },
501 { GRP3b },
502 { GRP3S },
503 /* f8 */
504 { "clc" },
505 { "stc" },
506 { "cli" },
507 { "sti" },
508 { "cld" },
509 { "std" },
510 { GRP4 },
511 { GRP5 },
512};
513
514struct dis386 dis386_twobyte[] = {
515 /* 00 */
516 { GRP6 },
517 { GRP7 },
518 { "larS", Gv, Ew },
519 { "lslS", Gv, Ew },
520 { "(bad)" },
521 { "(bad)" },
522 { "clts" },
523 { "(bad)" },
524 /* 08 */
525 { "invd" },
526 { "wbinvd" },
1d935cf6 527 { "(bad)" }, { "ud2a" },
5d0734a7
JK
528 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
529 /* 10 */
530 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
531 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
532 /* 18 */
533 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
534 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
535 /* 20 */
536 /* these are all backward in appendix A of the intel book */
537 { "movl", Rd, Cd },
538 { "movl", Rd, Dd },
539 { "movl", Cd, Rd },
540 { "movl", Dd, Rd },
541 { "movl", Rd, Td },
542 { "(bad)" },
543 { "movl", Td, Rd },
544 { "(bad)" },
545 /* 28 */
546 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
547 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
548 /* 30 */
1d935cf6 549 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
5d0734a7
JK
550 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
551 /* 38 */
552 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
553 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
554 /* 40 */
1d935cf6
MM
555 { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
556 { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
5d0734a7 557 /* 48 */
1d935cf6
MM
558 { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
559 { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
5d0734a7
JK
560 /* 50 */
561 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
562 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
563 /* 58 */
564 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
565 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
566 /* 60 */
567 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
568 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
569 /* 68 */
570 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
571 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
572 /* 70 */
573 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
574 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
575 /* 78 */
576 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
577 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
578 /* 80 */
579 { "jo", Jv },
580 { "jno", Jv },
581 { "jb", Jv },
582 { "jae", Jv },
583 { "je", Jv },
584 { "jne", Jv },
585 { "jbe", Jv },
586 { "ja", Jv },
587 /* 88 */
588 { "js", Jv },
589 { "jns", Jv },
590 { "jp", Jv },
591 { "jnp", Jv },
592 { "jl", Jv },
593 { "jge", Jv },
594 { "jle", Jv },
595 { "jg", Jv },
596 /* 90 */
597 { "seto", Eb },
598 { "setno", Eb },
599 { "setb", Eb },
600 { "setae", Eb },
601 { "sete", Eb },
602 { "setne", Eb },
603 { "setbe", Eb },
604 { "seta", Eb },
605 /* 98 */
606 { "sets", Eb },
607 { "setns", Eb },
608 { "setp", Eb },
609 { "setnp", Eb },
610 { "setl", Eb },
611 { "setge", Eb },
612 { "setle", Eb },
613 { "setg", Eb },
614 /* a0 */
615 { "pushl", fs },
616 { "popl", fs },
726257a8 617 { "cpuid" },
5d0734a7
JK
618 { "btS", Ev, Gv },
619 { "shldS", Ev, Gv, Ib },
620 { "shldS", Ev, Gv, CL },
621 { "(bad)" },
622 { "(bad)" },
623 /* a8 */
624 { "pushl", gs },
625 { "popl", gs },
726257a8 626 { "rsm" },
5d0734a7
JK
627 { "btsS", Ev, Gv },
628 { "shrdS", Ev, Gv, Ib },
629 { "shrdS", Ev, Gv, CL },
630 { "(bad)" },
631 { "imulS", Gv, Ev },
632 /* b0 */
633 { "cmpxchgb", Eb, Gb },
634 { "cmpxchgS", Ev, Gv },
635 { "lssS", Gv, Mp }, /* 386 lists only Mp */
636 { "btrS", Ev, Gv },
637 { "lfsS", Gv, Mp }, /* 386 lists only Mp */
638 { "lgsS", Gv, Mp }, /* 386 lists only Mp */
639 { "movzbS", Gv, Eb },
640 { "movzwS", Gv, Ew },
641 /* b8 */
1d935cf6 642 { "ud2b" },
5d0734a7
JK
643 { "(bad)" },
644 { GRP8 },
645 { "btcS", Ev, Gv },
646 { "bsfS", Gv, Ev },
647 { "bsrS", Gv, Ev },
648 { "movsbS", Gv, Eb },
649 { "movswS", Gv, Ew },
650 /* c0 */
651 { "xaddb", Eb, Gb },
652 { "xaddS", Ev, Gv },
726257a8
KR
653 { "(bad)" },
654 { "(bad)" },
655 { "(bad)" },
656 { "(bad)" },
657 { "(bad)" },
658 { GRP9 },
5d0734a7
JK
659 /* c8 */
660 { "bswap", eAX },
661 { "bswap", eCX },
662 { "bswap", eDX },
663 { "bswap", eBX },
664 { "bswap", eSP },
665 { "bswap", eBP },
666 { "bswap", eSI },
667 { "bswap", eDI },
668 /* d0 */
669 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
670 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
671 /* d8 */
672 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
673 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
674 /* e0 */
675 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
676 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
677 /* e8 */
678 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
679 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
680 /* f0 */
681 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
682 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
683 /* f8 */
684 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
685 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
686};
687
03db5a93
ILT
688static const unsigned char onebyte_has_modrm[256] = {
689 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
690 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
691 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
692 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
693 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
694 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
695 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
696 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
697 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
698 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
699 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
700 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
701 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
702 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
703 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
704 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
705};
706
707static const unsigned char twobyte_has_modrm[256] = {
708 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
709 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
710 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
711 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
712 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
713 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
714 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
715 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
716 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
717 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
718 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1,
719 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,
720 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
721 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
722 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
723 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
724};
725
5d0734a7
JK
726static char obuf[100];
727static char *obufp;
728static char scratchbuf[100];
729static unsigned char *start_codep;
730static unsigned char *codep;
731static disassemble_info *the_info;
732static int mod;
733static int rm;
734static int reg;
735static void oappend ();
736
737static char *names32[]={
738 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
739};
740static char *names16[] = {
741 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
742};
743static char *names8[] = {
744 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
745};
746static char *names_seg[] = {
747 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
748};
749
750struct dis386 grps[][8] = {
751 /* GRP1b */
752 {
753 { "addb", Eb, Ib },
754 { "orb", Eb, Ib },
755 { "adcb", Eb, Ib },
756 { "sbbb", Eb, Ib },
757 { "andb", Eb, Ib },
758 { "subb", Eb, Ib },
759 { "xorb", Eb, Ib },
760 { "cmpb", Eb, Ib }
761 },
762 /* GRP1S */
763 {
764 { "addS", Ev, Iv },
765 { "orS", Ev, Iv },
766 { "adcS", Ev, Iv },
767 { "sbbS", Ev, Iv },
768 { "andS", Ev, Iv },
769 { "subS", Ev, Iv },
770 { "xorS", Ev, Iv },
771 { "cmpS", Ev, Iv }
772 },
773 /* GRP1Ss */
774 {
775 { "addS", Ev, sIb },
776 { "orS", Ev, sIb },
777 { "adcS", Ev, sIb },
778 { "sbbS", Ev, sIb },
779 { "andS", Ev, sIb },
780 { "subS", Ev, sIb },
781 { "xorS", Ev, sIb },
782 { "cmpS", Ev, sIb }
783 },
784 /* GRP2b */
785 {
786 { "rolb", Eb, Ib },
787 { "rorb", Eb, Ib },
788 { "rclb", Eb, Ib },
789 { "rcrb", Eb, Ib },
790 { "shlb", Eb, Ib },
791 { "shrb", Eb, Ib },
792 { "(bad)" },
793 { "sarb", Eb, Ib },
794 },
795 /* GRP2S */
796 {
797 { "rolS", Ev, Ib },
798 { "rorS", Ev, Ib },
799 { "rclS", Ev, Ib },
800 { "rcrS", Ev, Ib },
801 { "shlS", Ev, Ib },
802 { "shrS", Ev, Ib },
803 { "(bad)" },
804 { "sarS", Ev, Ib },
805 },
806 /* GRP2b_one */
807 {
808 { "rolb", Eb },
809 { "rorb", Eb },
810 { "rclb", Eb },
811 { "rcrb", Eb },
812 { "shlb", Eb },
813 { "shrb", Eb },
814 { "(bad)" },
815 { "sarb", Eb },
816 },
817 /* GRP2S_one */
818 {
819 { "rolS", Ev },
820 { "rorS", Ev },
821 { "rclS", Ev },
822 { "rcrS", Ev },
823 { "shlS", Ev },
824 { "shrS", Ev },
825 { "(bad)" },
826 { "sarS", Ev },
827 },
828 /* GRP2b_cl */
829 {
830 { "rolb", Eb, CL },
831 { "rorb", Eb, CL },
832 { "rclb", Eb, CL },
833 { "rcrb", Eb, CL },
834 { "shlb", Eb, CL },
835 { "shrb", Eb, CL },
836 { "(bad)" },
837 { "sarb", Eb, CL },
838 },
839 /* GRP2S_cl */
840 {
841 { "rolS", Ev, CL },
842 { "rorS", Ev, CL },
843 { "rclS", Ev, CL },
844 { "rcrS", Ev, CL },
845 { "shlS", Ev, CL },
846 { "shrS", Ev, CL },
847 { "(bad)" },
848 { "sarS", Ev, CL }
849 },
850 /* GRP3b */
851 {
852 { "testb", Eb, Ib },
853 { "(bad)", Eb },
854 { "notb", Eb },
855 { "negb", Eb },
856 { "mulb", AL, Eb },
857 { "imulb", AL, Eb },
858 { "divb", AL, Eb },
859 { "idivb", AL, Eb }
860 },
861 /* GRP3S */
862 {
863 { "testS", Ev, Iv },
864 { "(bad)" },
865 { "notS", Ev },
866 { "negS", Ev },
867 { "mulS", eAX, Ev },
868 { "imulS", eAX, Ev },
869 { "divS", eAX, Ev },
870 { "idivS", eAX, Ev },
871 },
872 /* GRP4 */
873 {
874 { "incb", Eb },
875 { "decb", Eb },
876 { "(bad)" },
877 { "(bad)" },
878 { "(bad)" },
879 { "(bad)" },
880 { "(bad)" },
881 { "(bad)" },
882 },
883 /* GRP5 */
884 {
885 { "incS", Ev },
886 { "decS", Ev },
887 { "call", indirEv },
888 { "lcall", indirEv },
889 { "jmp", indirEv },
890 { "ljmp", indirEv },
891 { "pushS", Ev },
892 { "(bad)" },
893 },
894 /* GRP6 */
895 {
896 { "sldt", Ew },
897 { "str", Ew },
898 { "lldt", Ew },
899 { "ltr", Ew },
900 { "verr", Ew },
901 { "verw", Ew },
902 { "(bad)" },
903 { "(bad)" }
904 },
905 /* GRP7 */
906 {
907 { "sgdt", Ew },
908 { "sidt", Ew },
909 { "lgdt", Ew },
910 { "lidt", Ew },
911 { "smsw", Ew },
912 { "(bad)" },
913 { "lmsw", Ew },
914 { "invlpg", Ew },
915 },
916 /* GRP8 */
917 {
918 { "(bad)" },
919 { "(bad)" },
920 { "(bad)" },
921 { "(bad)" },
922 { "btS", Ev, Ib },
923 { "btsS", Ev, Ib },
924 { "btrS", Ev, Ib },
925 { "btcS", Ev, Ib },
726257a8
KR
926 },
927 /* GRP9 */
928 {
929 { "(bad)" },
1d935cf6 930 { "cmpxchg8b", Ev },
726257a8
KR
931 { "(bad)" },
932 { "(bad)" },
933 { "(bad)" },
934 { "(bad)" },
935 { "(bad)" },
936 { "(bad)" },
5d0734a7
JK
937 }
938};
939
940#define PREFIX_REPZ 1
941#define PREFIX_REPNZ 2
942#define PREFIX_LOCK 4
943#define PREFIX_CS 8
944#define PREFIX_SS 0x10
945#define PREFIX_DS 0x20
946#define PREFIX_ES 0x40
947#define PREFIX_FS 0x80
948#define PREFIX_GS 0x100
949#define PREFIX_DATA 0x200
950#define PREFIX_ADR 0x400
951#define PREFIX_FWAIT 0x800
952
953static int prefixes;
954
955static void
956ckprefix ()
957{
958 prefixes = 0;
959 while (1)
960 {
961 FETCH_DATA (the_info, codep + 1);
962 switch (*codep)
963 {
964 case 0xf3:
965 prefixes |= PREFIX_REPZ;
966 break;
967 case 0xf2:
968 prefixes |= PREFIX_REPNZ;
969 break;
970 case 0xf0:
971 prefixes |= PREFIX_LOCK;
972 break;
973 case 0x2e:
974 prefixes |= PREFIX_CS;
975 break;
976 case 0x36:
977 prefixes |= PREFIX_SS;
978 break;
979 case 0x3e:
980 prefixes |= PREFIX_DS;
981 break;
982 case 0x26:
983 prefixes |= PREFIX_ES;
984 break;
985 case 0x64:
986 prefixes |= PREFIX_FS;
987 break;
988 case 0x65:
989 prefixes |= PREFIX_GS;
990 break;
991 case 0x66:
992 prefixes |= PREFIX_DATA;
993 break;
994 case 0x67:
995 prefixes |= PREFIX_ADR;
996 break;
997 case 0x9b:
998 prefixes |= PREFIX_FWAIT;
999 break;
1000 default:
1001 return;
1002 }
1003 codep++;
1004 }
1005}
1006
1007static int dflag;
1008static int aflag;
1009
1010static char op1out[100], op2out[100], op3out[100];
1011static int op_address[3], op_ad, op_index[3];
1012static int start_pc;
1013
1014\f
1015/*
1016 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
1017 * (see topic "Redundant prefixes" in the "Differences from 8086"
1018 * section of the "Virtual 8086 Mode" chapter.)
1019 * 'pc' should be the address of this instruction, it will
1020 * be used to print the target address if this is a relative jump or call
1021 * The function returns the length of this instruction in bytes.
1022 */
1023
1024int
1025print_insn_i386 (pc, info)
1026 bfd_vma pc;
1027 disassemble_info *info;
1028{
1029 struct dis386 *dp;
1030 int i;
1031 int enter_instruction;
1032 char *first, *second, *third;
1033 int needcomma;
03db5a93
ILT
1034 unsigned char need_modrm;
1035
726257a8 1036 struct dis_private priv;
5d0734a7
JK
1037 bfd_byte *inbuf = priv.the_buffer;
1038
1039 info->private_data = (PTR) &priv;
1040 priv.max_fetched = priv.the_buffer;
1041 priv.insn_start = pc;
1042 if (setjmp (priv.bailout) != 0)
1043 /* Error return. */
1044 return -1;
1045
1046 obuf[0] = 0;
1047 op1out[0] = 0;
1048 op2out[0] = 0;
1049 op3out[0] = 0;
1050
1051 op_index[0] = op_index[1] = op_index[2] = -1;
1052
1053 the_info = info;
1054 start_pc = pc;
1055 start_codep = inbuf;
1056 codep = inbuf;
1057
1058 ckprefix ();
1059
1060 FETCH_DATA (info, codep + 1);
1061 if (*codep == 0xc8)
1062 enter_instruction = 1;
1063 else
1064 enter_instruction = 0;
1065
1066 obufp = obuf;
1067
1068 if (prefixes & PREFIX_REPZ)
1069 oappend ("repz ");
1070 if (prefixes & PREFIX_REPNZ)
1071 oappend ("repnz ");
1072 if (prefixes & PREFIX_LOCK)
1073 oappend ("lock ");
1074
1075 if ((prefixes & PREFIX_FWAIT)
1076 && ((*codep < 0xd8) || (*codep > 0xdf)))
1077 {
1078 /* fwait not followed by floating point instruction */
1079 (*info->fprintf_func) (info->stream, "fwait");
1080 return (1);
1081 }
1082
1083 /* these would be initialized to 0 if disassembling for 8086 or 286 */
1084 dflag = 1;
1085 aflag = 1;
1086
1087 if (prefixes & PREFIX_DATA)
1088 dflag ^= 1;
1089
1090 if (prefixes & PREFIX_ADR)
1091 {
1092 aflag ^= 1;
1093 oappend ("addr16 ");
1094 }
1095
1096 if (*codep == 0x0f)
1097 {
1098 FETCH_DATA (info, codep + 2);
1099 dp = &dis386_twobyte[*++codep];
03db5a93 1100 need_modrm = twobyte_has_modrm[*codep];
5d0734a7
JK
1101 }
1102 else
03db5a93
ILT
1103 {
1104 dp = &dis386[*codep];
1105 need_modrm = onebyte_has_modrm[*codep];
1106 }
5d0734a7 1107 codep++;
5c9b5f58 1108
03db5a93
ILT
1109 if (need_modrm)
1110 {
1111 FETCH_DATA (info, codep + 1);
1112 mod = (*codep >> 6) & 3;
1113 reg = (*codep >> 3) & 7;
1114 rm = *codep & 7;
1115 }
5c9b5f58 1116
5d0734a7
JK
1117 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
1118 {
1119 dofloat ();
1120 }
1121 else
1122 {
1123 if (dp->name == NULL)
1124 dp = &grps[dp->bytemode1][reg];
1125
1126 putop (dp->name);
1127
1128 obufp = op1out;
1129 op_ad = 2;
1130 if (dp->op1)
1131 (*dp->op1)(dp->bytemode1);
1132
1133 obufp = op2out;
1134 op_ad = 1;
1135 if (dp->op2)
1136 (*dp->op2)(dp->bytemode2);
1137
1138 obufp = op3out;
1139 op_ad = 0;
1140 if (dp->op3)
1141 (*dp->op3)(dp->bytemode3);
1142 }
1143
1144 obufp = obuf + strlen (obuf);
1145 for (i = strlen (obuf); i < 6; i++)
1146 oappend (" ");
1147 oappend (" ");
1148 (*info->fprintf_func) (info->stream, "%s", obuf);
1149
1150 /* enter instruction is printed with operands in the
1151 * same order as the intel book; everything else
1152 * is printed in reverse order
1153 */
1154 if (enter_instruction)
1155 {
1156 first = op1out;
1157 second = op2out;
1158 third = op3out;
1159 op_ad = op_index[0];
1160 op_index[0] = op_index[2];
1161 op_index[2] = op_ad;
1162 }
1163 else
1164 {
1165 first = op3out;
1166 second = op2out;
1167 third = op1out;
1168 }
1169 needcomma = 0;
1170 if (*first)
1171 {
1172 if (op_index[0] != -1)
a279b1f5 1173 (*info->print_address_func) (op_address[op_index[0]], info);
5d0734a7
JK
1174 else
1175 (*info->fprintf_func) (info->stream, "%s", first);
1176 needcomma = 1;
1177 }
1178 if (*second)
1179 {
1180 if (needcomma)
1181 (*info->fprintf_func) (info->stream, ",");
1182 if (op_index[1] != -1)
a279b1f5 1183 (*info->print_address_func) (op_address[op_index[1]], info);
5d0734a7
JK
1184 else
1185 (*info->fprintf_func) (info->stream, "%s", second);
1186 needcomma = 1;
1187 }
1188 if (*third)
1189 {
1190 if (needcomma)
1191 (*info->fprintf_func) (info->stream, ",");
1192 if (op_index[2] != -1)
a279b1f5 1193 (*info->print_address_func) (op_address[op_index[2]], info);
5d0734a7
JK
1194 else
1195 (*info->fprintf_func) (info->stream, "%s", third);
1196 }
1197 return (codep - inbuf);
1198}
1199
1200char *float_mem[] = {
1201 /* d8 */
1202 "fadds",
1203 "fmuls",
1204 "fcoms",
1205 "fcomps",
1206 "fsubs",
1207 "fsubrs",
1208 "fdivs",
1209 "fdivrs",
1210 /* d9 */
1211 "flds",
1212 "(bad)",
1213 "fsts",
1214 "fstps",
1215 "fldenv",
1216 "fldcw",
1217 "fNstenv",
1218 "fNstcw",
1219 /* da */
1220 "fiaddl",
1221 "fimull",
1222 "ficoml",
1223 "ficompl",
1224 "fisubl",
1225 "fisubrl",
1226 "fidivl",
1227 "fidivrl",
1228 /* db */
1229 "fildl",
1230 "(bad)",
1231 "fistl",
1232 "fistpl",
1233 "(bad)",
1234 "fldt",
1235 "(bad)",
1236 "fstpt",
1237 /* dc */
1238 "faddl",
1239 "fmull",
1240 "fcoml",
1241 "fcompl",
1242 "fsubl",
1243 "fsubrl",
1244 "fdivl",
1245 "fdivrl",
1246 /* dd */
1247 "fldl",
1248 "(bad)",
1249 "fstl",
1250 "fstpl",
1251 "frstor",
1252 "(bad)",
1253 "fNsave",
1254 "fNstsw",
1255 /* de */
1256 "fiadd",
1257 "fimul",
1258 "ficom",
1259 "ficomp",
1260 "fisub",
1261 "fisubr",
1262 "fidiv",
1263 "fidivr",
1264 /* df */
1265 "fild",
1266 "(bad)",
1267 "fist",
1268 "fistp",
1269 "fbld",
1270 "fildll",
1271 "fbstp",
1272 "fistpll",
1273};
1274
1275#define ST OP_ST, 0
1276#define STi OP_STi, 0
1277int OP_ST(), OP_STi();
1278
1279#define FGRPd9_2 NULL, NULL, 0
1280#define FGRPd9_4 NULL, NULL, 1
1281#define FGRPd9_5 NULL, NULL, 2
1282#define FGRPd9_6 NULL, NULL, 3
1283#define FGRPd9_7 NULL, NULL, 4
1284#define FGRPda_5 NULL, NULL, 5
1285#define FGRPdb_4 NULL, NULL, 6
1286#define FGRPde_3 NULL, NULL, 7
1287#define FGRPdf_4 NULL, NULL, 8
1288
1289struct dis386 float_reg[][8] = {
1290 /* d8 */
1291 {
1292 { "fadd", ST, STi },
1293 { "fmul", ST, STi },
1294 { "fcom", STi },
1295 { "fcomp", STi },
1296 { "fsub", ST, STi },
1297 { "fsubr", ST, STi },
1298 { "fdiv", ST, STi },
1299 { "fdivr", ST, STi },
1300 },
1301 /* d9 */
1302 {
1303 { "fld", STi },
1304 { "fxch", STi },
1305 { FGRPd9_2 },
1306 { "(bad)" },
1307 { FGRPd9_4 },
1308 { FGRPd9_5 },
1309 { FGRPd9_6 },
1310 { FGRPd9_7 },
1311 },
1312 /* da */
1313 {
1d935cf6
MM
1314 { "fcmovb", ST, STi },
1315 { "fcmove", ST, STi },
1316 { "fcmovbe",ST, STi },
1317 { "fcmovu", ST, STi },
5d0734a7
JK
1318 { "(bad)" },
1319 { FGRPda_5 },
1320 { "(bad)" },
1321 { "(bad)" },
1322 },
1323 /* db */
1324 {
1d935cf6
MM
1325 { "fcmovnb",ST, STi },
1326 { "fcmovne",ST, STi },
1327 { "fcmovnbe",ST, STi },
1328 { "fcmovnu",ST, STi },
5d0734a7 1329 { FGRPdb_4 },
1d935cf6
MM
1330 { "fucomi", ST, STi },
1331 { "fcomi", ST, STi },
5d0734a7
JK
1332 { "(bad)" },
1333 },
1334 /* dc */
1335 {
1336 { "fadd", STi, ST },
1337 { "fmul", STi, ST },
1338 { "(bad)" },
1339 { "(bad)" },
1340 { "fsub", STi, ST },
1341 { "fsubr", STi, ST },
1342 { "fdiv", STi, ST },
1343 { "fdivr", STi, ST },
1344 },
1345 /* dd */
1346 {
1347 { "ffree", STi },
1348 { "(bad)" },
1349 { "fst", STi },
1350 { "fstp", STi },
1351 { "fucom", STi },
1352 { "fucomp", STi },
1353 { "(bad)" },
1354 { "(bad)" },
1355 },
1356 /* de */
1357 {
1358 { "faddp", STi, ST },
1359 { "fmulp", STi, ST },
1360 { "(bad)" },
1361 { FGRPde_3 },
1362 { "fsubp", STi, ST },
1363 { "fsubrp", STi, ST },
1364 { "fdivp", STi, ST },
1365 { "fdivrp", STi, ST },
1366 },
1367 /* df */
1368 {
1369 { "(bad)" },
1370 { "(bad)" },
1371 { "(bad)" },
1372 { "(bad)" },
1373 { FGRPdf_4 },
1d935cf6
MM
1374 { "fucomip",ST, STi },
1375 { "fcomip", ST, STi },
5d0734a7
JK
1376 { "(bad)" },
1377 },
1378};
1379
1380
1381char *fgrps[][8] = {
1382 /* d9_2 0 */
1383 {
1384 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1385 },
1386
1387 /* d9_4 1 */
1388 {
1389 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
1390 },
1391
1392 /* d9_5 2 */
1393 {
1394 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
1395 },
1396
1397 /* d9_6 3 */
1398 {
1399 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
1400 },
1401
1402 /* d9_7 4 */
1403 {
1404 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
1405 },
1406
1407 /* da_5 5 */
1408 {
1409 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1410 },
1411
1412 /* db_4 6 */
1413 {
1414 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
1415 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
1416 },
1417
1418 /* de_3 7 */
1419 {
1420 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1421 },
1422
1423 /* df_4 8 */
1424 {
1425 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1426 },
1427};
1428
1429static void
1430dofloat ()
1431{
1432 struct dis386 *dp;
1433 unsigned char floatop;
1434
1435 floatop = codep[-1];
1436
1437 if (mod != 3)
1438 {
1439 putop (float_mem[(floatop - 0xd8) * 8 + reg]);
1440 obufp = op1out;
1441 OP_E (v_mode);
1442 return;
1443 }
1444 codep++;
1445
1446 dp = &float_reg[floatop - 0xd8][reg];
1447 if (dp->name == NULL)
1448 {
1449 putop (fgrps[dp->bytemode1][rm]);
1450 /* instruction fnstsw is only one with strange arg */
1451 if (floatop == 0xdf
1452 && FETCH_DATA (the_info, codep + 1)
1453 && *codep == 0xe0)
1454 strcpy (op1out, "%eax");
1455 }
1456 else
1457 {
1458 putop (dp->name);
1459 obufp = op1out;
1460 if (dp->op1)
1461 (*dp->op1)(dp->bytemode1);
1462 obufp = op2out;
1463 if (dp->op2)
1464 (*dp->op2)(dp->bytemode2);
1465 }
1466}
1467
1468/* ARGSUSED */
1469int
1470OP_ST (ignore)
1471 int ignore;
1472{
1473 oappend ("%st");
1474 return (0);
1475}
1476
1477/* ARGSUSED */
1478int
1479OP_STi (ignore)
1480 int ignore;
1481{
1482 sprintf (scratchbuf, "%%st(%d)", rm);
1483 oappend (scratchbuf);
1484 return (0);
1485}
1486
1487
1488/* capital letters in template are macros */
1489static void
1490putop (template)
1491 char *template;
1492{
1493 char *p;
1494
1495 for (p = template; *p; p++)
1496 {
1497 switch (*p)
1498 {
1499 default:
1500 *obufp++ = *p;
1501 break;
1502 case 'C': /* For jcxz/jecxz */
1503 if (aflag == 0)
1504 *obufp++ = 'e';
1505 break;
1506 case 'N':
1507 if ((prefixes & PREFIX_FWAIT) == 0)
1508 *obufp++ = 'n';
1509 break;
1510 case 'S':
1511 /* operand size flag */
1512 if (dflag)
1513 *obufp++ = 'l';
1514 else
1515 *obufp++ = 'w';
1516 break;
1517 }
1518 }
1519 *obufp = 0;
1520}
1521
1522static void
1523oappend (s)
1524 char *s;
1525{
1526 strcpy (obufp, s);
1527 obufp += strlen (s);
1528 *obufp = 0;
1529}
1530
1531static void
1532append_prefix ()
1533{
1534 if (prefixes & PREFIX_CS)
1535 oappend ("%cs:");
1536 if (prefixes & PREFIX_DS)
1537 oappend ("%ds:");
1538 if (prefixes & PREFIX_SS)
1539 oappend ("%ss:");
1540 if (prefixes & PREFIX_ES)
1541 oappend ("%es:");
1542 if (prefixes & PREFIX_FS)
1543 oappend ("%fs:");
1544 if (prefixes & PREFIX_GS)
1545 oappend ("%gs:");
1546}
1547
1548int
1549OP_indirE (bytemode)
1550 int bytemode;
1551{
1552 oappend ("*");
1553 OP_E (bytemode);
1554 return (0);
1555}
1556
1557int
1558OP_E (bytemode)
1559 int bytemode;
1560{
1561 int disp;
1562 int havesib;
1563 int base;
1564 int index;
1565 int scale;
1566 int havebase;
1567
1568 /* skip mod/rm byte */
1569 codep++;
1570
1571 havesib = 0;
1572 havebase = 0;
1573 disp = 0;
1574
1575 if (mod == 3)
1576 {
1577 switch (bytemode)
1578 {
1579 case b_mode:
1580 oappend (names8[rm]);
1581 break;
1582 case w_mode:
1583 oappend (names16[rm]);
1584 break;
1585 case v_mode:
1586 if (dflag)
1587 oappend (names32[rm]);
1588 else
1589 oappend (names16[rm]);
1590 break;
1591 default:
1592 oappend ("<bad dis table>");
1593 break;
1594 }
1595 return (0);
1596 }
1597
1598 append_prefix ();
1599 if (rm == 4)
1600 {
1601 havesib = 1;
1602 havebase = 1;
1603 FETCH_DATA (the_info, codep + 1);
1604 scale = (*codep >> 6) & 3;
1605 index = (*codep >> 3) & 7;
1606 base = *codep & 7;
1607 codep++;
1608 }
1609
1610 switch (mod)
1611 {
1612 case 0:
1613 switch (rm)
1614 {
1615 case 4:
1616 /* implies havesib and havebase */
1617 if (base == 5) {
1618 havebase = 0;
1619 disp = get32 ();
1620 }
1621 break;
1622 case 5:
1623 disp = get32 ();
1624 break;
1625 default:
1626 havebase = 1;
1627 base = rm;
1628 break;
1629 }
1630 break;
1631 case 1:
1632 FETCH_DATA (the_info, codep + 1);
1633 disp = *(char *)codep++;
1634 if (rm != 4)
1635 {
1636 havebase = 1;
1637 base = rm;
1638 }
1639 break;
1640 case 2:
1641 disp = get32 ();
1642 if (rm != 4)
1643 {
1644 havebase = 1;
1645 base = rm;
1646 }
1647 break;
1648 }
1649
1650 if (mod != 0 || rm == 5 || (havesib && base == 5))
1651 {
1652 sprintf (scratchbuf, "0x%x", disp);
1653 oappend (scratchbuf);
1654 }
1655
1656 if (havebase || havesib)
1657 {
1658 oappend ("(");
1659 if (havebase)
1660 oappend (names32[base]);
1661 if (havesib)
1662 {
1663 if (index != 4)
1664 {
1665 sprintf (scratchbuf, ",%s", names32[index]);
1666 oappend (scratchbuf);
1667 }
1668 sprintf (scratchbuf, ",%d", 1 << scale);
1669 oappend (scratchbuf);
1670 }
1671 oappend (")");
1672 }
1673 return (0);
1674}
1675
1676int
1677OP_G (bytemode)
1678 int bytemode;
1679{
1680 switch (bytemode)
1681 {
1682 case b_mode:
1683 oappend (names8[reg]);
1684 break;
1685 case w_mode:
1686 oappend (names16[reg]);
1687 break;
1688 case d_mode:
1689 oappend (names32[reg]);
1690 break;
1691 case v_mode:
1692 if (dflag)
1693 oappend (names32[reg]);
1694 else
1695 oappend (names16[reg]);
1696 break;
1697 default:
1698 oappend ("<internal disassembler error>");
1699 break;
1700 }
1701 return (0);
1702}
1703
1704static int
1705get32 ()
1706{
1707 int x = 0;
1708
1709 FETCH_DATA (the_info, codep + 4);
1710 x = *codep++ & 0xff;
1711 x |= (*codep++ & 0xff) << 8;
1712 x |= (*codep++ & 0xff) << 16;
1713 x |= (*codep++ & 0xff) << 24;
1714 return (x);
1715}
1716
1717static int
1718get16 ()
1719{
1720 int x = 0;
1721
1722 FETCH_DATA (the_info, codep + 2);
1723 x = *codep++ & 0xff;
1724 x |= (*codep++ & 0xff) << 8;
1725 return (x);
1726}
1727
1728static void
1729set_op (op)
1730 int op;
1731{
1732 op_index[op_ad] = op_ad;
1733 op_address[op_ad] = op;
1734}
1735
1736int
1737OP_REG (code)
1738 int code;
1739{
1740 char *s;
1741
1742 switch (code)
1743 {
1744 case indir_dx_reg: s = "(%dx)"; break;
1745 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
1746 case sp_reg: case bp_reg: case si_reg: case di_reg:
1747 s = names16[code - ax_reg];
1748 break;
1749 case es_reg: case ss_reg: case cs_reg:
1750 case ds_reg: case fs_reg: case gs_reg:
1751 s = names_seg[code - es_reg];
1752 break;
1753 case al_reg: case ah_reg: case cl_reg: case ch_reg:
1754 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
1755 s = names8[code - al_reg];
1756 break;
1757 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
1758 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
1759 if (dflag)
1760 s = names32[code - eAX_reg];
1761 else
1762 s = names16[code - eAX_reg];
1763 break;
1764 default:
1765 s = "<internal disassembler error>";
1766 break;
1767 }
1768 oappend (s);
1769 return (0);
1770}
1771
1772int
1773OP_I (bytemode)
1774 int bytemode;
1775{
1776 int op;
1777
1778 switch (bytemode)
1779 {
1780 case b_mode:
1781 FETCH_DATA (the_info, codep + 1);
1782 op = *codep++ & 0xff;
1783 break;
1784 case v_mode:
1785 if (dflag)
1786 op = get32 ();
1787 else
1788 op = get16 ();
1789 break;
1790 case w_mode:
1791 op = get16 ();
1792 break;
1793 default:
1794 oappend ("<internal disassembler error>");
1795 return (0);
1796 }
1797 sprintf (scratchbuf, "$0x%x", op);
1798 oappend (scratchbuf);
1799 return (0);
1800}
1801
1802int
1803OP_sI (bytemode)
1804 int bytemode;
1805{
1806 int op;
1807
1808 switch (bytemode)
1809 {
1810 case b_mode:
1811 FETCH_DATA (the_info, codep + 1);
1812 op = *(char *)codep++;
1813 break;
1814 case v_mode:
1815 if (dflag)
1816 op = get32 ();
1817 else
1818 op = (short)get16();
1819 break;
1820 case w_mode:
1821 op = (short)get16 ();
1822 break;
1823 default:
1824 oappend ("<internal disassembler error>");
1825 return (0);
1826 }
1827 sprintf (scratchbuf, "$0x%x", op);
1828 oappend (scratchbuf);
1829 return (0);
1830}
1831
1832int
1833OP_J (bytemode)
1834 int bytemode;
1835{
1836 int disp;
1837 int mask = -1;
1838
1839 switch (bytemode)
1840 {
1841 case b_mode:
1842 FETCH_DATA (the_info, codep + 1);
1843 disp = *(char *)codep++;
1844 break;
1845 case v_mode:
1846 if (dflag)
1847 disp = get32 ();
1848 else
1849 {
1850 disp = (short)get16 ();
1851 /* for some reason, a data16 prefix on a jump instruction
1852 means that the pc is masked to 16 bits after the
1853 displacement is added! */
1854 mask = 0xffff;
1855 }
1856 break;
1857 default:
1858 oappend ("<internal disassembler error>");
1859 return (0);
1860 }
1861 disp = (start_pc + codep - start_codep + disp) & mask;
1862 set_op (disp);
1863 sprintf (scratchbuf, "0x%x", disp);
1864 oappend (scratchbuf);
1865 return (0);
1866}
1867
1868/* ARGSUSED */
1869int
1870OP_SEG (dummy)
1871 int dummy;
1872{
1873 static char *sreg[] = {
1874 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1875 };
1876
1877 oappend (sreg[reg]);
1878 return (0);
1879}
1880
1881int
1882OP_DIR (size)
1883 int size;
1884{
1885 int seg, offset;
1886
1887 switch (size)
1888 {
1889 case lptr:
1890 if (aflag)
1891 {
1892 offset = get32 ();
1893 seg = get16 ();
1894 }
1895 else
1896 {
1897 offset = get16 ();
1898 seg = get16 ();
1899 }
1900 sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
1901 oappend (scratchbuf);
1902 break;
1903 case v_mode:
1904 if (aflag)
1905 offset = get32 ();
1906 else
1907 offset = (short)get16 ();
1908
1909 offset = start_pc + codep - start_codep + offset;
1910 set_op (offset);
1911 sprintf (scratchbuf, "0x%x", offset);
1912 oappend (scratchbuf);
1913 break;
1914 default:
1915 oappend ("<internal disassembler error>");
1916 break;
1917 }
1918 return (0);
1919}
1920
1921/* ARGSUSED */
1922int
1923OP_OFF (bytemode)
1924 int bytemode;
1925{
1926 int off;
1927
1928 if (aflag)
1929 off = get32 ();
1930 else
1931 off = get16 ();
1932
1933 sprintf (scratchbuf, "0x%x", off);
1934 oappend (scratchbuf);
1935 return (0);
1936}
1937
1938/* ARGSUSED */
1939int
1940OP_ESDI (dummy)
1941 int dummy;
1942{
1943 oappend ("%es:(");
1944 oappend (aflag ? "%edi" : "%di");
1945 oappend (")");
1946 return (0);
1947}
1948
1949/* ARGSUSED */
1950int
1951OP_DSSI (dummy)
1952 int dummy;
1953{
1954 oappend ("%ds:(");
1955 oappend (aflag ? "%esi" : "%si");
1956 oappend (")");
1957 return (0);
1958}
1959
1960/* ARGSUSED */
1961int
1962OP_ONE (dummy)
1963 int dummy;
1964{
1965 oappend ("1");
1966 return (0);
1967}
1968
1969/* ARGSUSED */
1970int
1971OP_C (dummy)
1972 int dummy;
1973{
1974 codep++; /* skip mod/rm */
1975 sprintf (scratchbuf, "%%cr%d", reg);
1976 oappend (scratchbuf);
1977 return (0);
1978}
1979
1980/* ARGSUSED */
1981int
1982OP_D (dummy)
1983 int dummy;
1984{
1985 codep++; /* skip mod/rm */
1986 sprintf (scratchbuf, "%%db%d", reg);
1987 oappend (scratchbuf);
1988 return (0);
1989}
1990
1991/* ARGSUSED */
1992int
1993OP_T (dummy)
1994 int dummy;
1995{
1996 codep++; /* skip mod/rm */
1997 sprintf (scratchbuf, "%%tr%d", reg);
1998 oappend (scratchbuf);
1999 return (0);
2000}
2001
2002int
2003OP_rm (bytemode)
2004 int bytemode;
2005{
2006 switch (bytemode)
2007 {
2008 case d_mode:
2009 oappend (names32[rm]);
2010 break;
2011 case w_mode:
2012 oappend (names16[rm]);
2013 break;
2014 }
2015 return (0);
2016}
This page took 0.19964 seconds and 4 git commands to generate.