* eval.c (evaluate_struct_tuple): Fix thinko.
[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 */
351 { "jo", Jb },
352 { "jno", Jb },
353 { "jb", Jb },
354 { "jae", Jb },
355 { "je", Jb },
356 { "jne", Jb },
357 { "jbe", Jb },
358 { "ja", Jb },
359 /* 78 */
360 { "js", Jb },
361 { "jns", Jb },
362 { "jp", Jb },
363 { "jnp", Jb },
364 { "jl", Jb },
365 { "jnl", Jb },
366 { "jle", Jb },
367 { "jg", Jb },
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" },
527 { "(bad)" }, { "(bad)" },
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 */
726257a8 549 { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "(bad)" },
5d0734a7
JK
550 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
551 /* 38 */
552 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
553 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
554 /* 40 */
555 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
556 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
557 /* 48 */
558 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
559 { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
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 */
642 { "(bad)" },
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
688static char obuf[100];
689static char *obufp;
690static char scratchbuf[100];
691static unsigned char *start_codep;
692static unsigned char *codep;
693static disassemble_info *the_info;
694static int mod;
695static int rm;
696static int reg;
697static void oappend ();
698
699static char *names32[]={
700 "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
701};
702static char *names16[] = {
703 "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
704};
705static char *names8[] = {
706 "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
707};
708static char *names_seg[] = {
709 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
710};
711
712struct dis386 grps[][8] = {
713 /* GRP1b */
714 {
715 { "addb", Eb, Ib },
716 { "orb", Eb, Ib },
717 { "adcb", Eb, Ib },
718 { "sbbb", Eb, Ib },
719 { "andb", Eb, Ib },
720 { "subb", Eb, Ib },
721 { "xorb", Eb, Ib },
722 { "cmpb", Eb, Ib }
723 },
724 /* GRP1S */
725 {
726 { "addS", Ev, Iv },
727 { "orS", Ev, Iv },
728 { "adcS", Ev, Iv },
729 { "sbbS", Ev, Iv },
730 { "andS", Ev, Iv },
731 { "subS", Ev, Iv },
732 { "xorS", Ev, Iv },
733 { "cmpS", Ev, Iv }
734 },
735 /* GRP1Ss */
736 {
737 { "addS", Ev, sIb },
738 { "orS", Ev, sIb },
739 { "adcS", Ev, sIb },
740 { "sbbS", Ev, sIb },
741 { "andS", Ev, sIb },
742 { "subS", Ev, sIb },
743 { "xorS", Ev, sIb },
744 { "cmpS", Ev, sIb }
745 },
746 /* GRP2b */
747 {
748 { "rolb", Eb, Ib },
749 { "rorb", Eb, Ib },
750 { "rclb", Eb, Ib },
751 { "rcrb", Eb, Ib },
752 { "shlb", Eb, Ib },
753 { "shrb", Eb, Ib },
754 { "(bad)" },
755 { "sarb", Eb, Ib },
756 },
757 /* GRP2S */
758 {
759 { "rolS", Ev, Ib },
760 { "rorS", Ev, Ib },
761 { "rclS", Ev, Ib },
762 { "rcrS", Ev, Ib },
763 { "shlS", Ev, Ib },
764 { "shrS", Ev, Ib },
765 { "(bad)" },
766 { "sarS", Ev, Ib },
767 },
768 /* GRP2b_one */
769 {
770 { "rolb", Eb },
771 { "rorb", Eb },
772 { "rclb", Eb },
773 { "rcrb", Eb },
774 { "shlb", Eb },
775 { "shrb", Eb },
776 { "(bad)" },
777 { "sarb", Eb },
778 },
779 /* GRP2S_one */
780 {
781 { "rolS", Ev },
782 { "rorS", Ev },
783 { "rclS", Ev },
784 { "rcrS", Ev },
785 { "shlS", Ev },
786 { "shrS", Ev },
787 { "(bad)" },
788 { "sarS", Ev },
789 },
790 /* GRP2b_cl */
791 {
792 { "rolb", Eb, CL },
793 { "rorb", Eb, CL },
794 { "rclb", Eb, CL },
795 { "rcrb", Eb, CL },
796 { "shlb", Eb, CL },
797 { "shrb", Eb, CL },
798 { "(bad)" },
799 { "sarb", Eb, CL },
800 },
801 /* GRP2S_cl */
802 {
803 { "rolS", Ev, CL },
804 { "rorS", Ev, CL },
805 { "rclS", Ev, CL },
806 { "rcrS", Ev, CL },
807 { "shlS", Ev, CL },
808 { "shrS", Ev, CL },
809 { "(bad)" },
810 { "sarS", Ev, CL }
811 },
812 /* GRP3b */
813 {
814 { "testb", Eb, Ib },
815 { "(bad)", Eb },
816 { "notb", Eb },
817 { "negb", Eb },
818 { "mulb", AL, Eb },
819 { "imulb", AL, Eb },
820 { "divb", AL, Eb },
821 { "idivb", AL, Eb }
822 },
823 /* GRP3S */
824 {
825 { "testS", Ev, Iv },
826 { "(bad)" },
827 { "notS", Ev },
828 { "negS", Ev },
829 { "mulS", eAX, Ev },
830 { "imulS", eAX, Ev },
831 { "divS", eAX, Ev },
832 { "idivS", eAX, Ev },
833 },
834 /* GRP4 */
835 {
836 { "incb", Eb },
837 { "decb", Eb },
838 { "(bad)" },
839 { "(bad)" },
840 { "(bad)" },
841 { "(bad)" },
842 { "(bad)" },
843 { "(bad)" },
844 },
845 /* GRP5 */
846 {
847 { "incS", Ev },
848 { "decS", Ev },
849 { "call", indirEv },
850 { "lcall", indirEv },
851 { "jmp", indirEv },
852 { "ljmp", indirEv },
853 { "pushS", Ev },
854 { "(bad)" },
855 },
856 /* GRP6 */
857 {
858 { "sldt", Ew },
859 { "str", Ew },
860 { "lldt", Ew },
861 { "ltr", Ew },
862 { "verr", Ew },
863 { "verw", Ew },
864 { "(bad)" },
865 { "(bad)" }
866 },
867 /* GRP7 */
868 {
869 { "sgdt", Ew },
870 { "sidt", Ew },
871 { "lgdt", Ew },
872 { "lidt", Ew },
873 { "smsw", Ew },
874 { "(bad)" },
875 { "lmsw", Ew },
876 { "invlpg", Ew },
877 },
878 /* GRP8 */
879 {
880 { "(bad)" },
881 { "(bad)" },
882 { "(bad)" },
883 { "(bad)" },
884 { "btS", Ev, Ib },
885 { "btsS", Ev, Ib },
886 { "btrS", Ev, Ib },
887 { "btcS", Ev, Ib },
726257a8
KR
888 },
889 /* GRP9 */
890 {
891 { "(bad)" },
892 { "cmpxch8b", Ev },
893 { "(bad)" },
894 { "(bad)" },
895 { "(bad)" },
896 { "(bad)" },
897 { "(bad)" },
898 { "(bad)" },
5d0734a7
JK
899 }
900};
901
902#define PREFIX_REPZ 1
903#define PREFIX_REPNZ 2
904#define PREFIX_LOCK 4
905#define PREFIX_CS 8
906#define PREFIX_SS 0x10
907#define PREFIX_DS 0x20
908#define PREFIX_ES 0x40
909#define PREFIX_FS 0x80
910#define PREFIX_GS 0x100
911#define PREFIX_DATA 0x200
912#define PREFIX_ADR 0x400
913#define PREFIX_FWAIT 0x800
914
915static int prefixes;
916
917static void
918ckprefix ()
919{
920 prefixes = 0;
921 while (1)
922 {
923 FETCH_DATA (the_info, codep + 1);
924 switch (*codep)
925 {
926 case 0xf3:
927 prefixes |= PREFIX_REPZ;
928 break;
929 case 0xf2:
930 prefixes |= PREFIX_REPNZ;
931 break;
932 case 0xf0:
933 prefixes |= PREFIX_LOCK;
934 break;
935 case 0x2e:
936 prefixes |= PREFIX_CS;
937 break;
938 case 0x36:
939 prefixes |= PREFIX_SS;
940 break;
941 case 0x3e:
942 prefixes |= PREFIX_DS;
943 break;
944 case 0x26:
945 prefixes |= PREFIX_ES;
946 break;
947 case 0x64:
948 prefixes |= PREFIX_FS;
949 break;
950 case 0x65:
951 prefixes |= PREFIX_GS;
952 break;
953 case 0x66:
954 prefixes |= PREFIX_DATA;
955 break;
956 case 0x67:
957 prefixes |= PREFIX_ADR;
958 break;
959 case 0x9b:
960 prefixes |= PREFIX_FWAIT;
961 break;
962 default:
963 return;
964 }
965 codep++;
966 }
967}
968
969static int dflag;
970static int aflag;
971
972static char op1out[100], op2out[100], op3out[100];
973static int op_address[3], op_ad, op_index[3];
974static int start_pc;
975
976\f
977/*
978 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
979 * (see topic "Redundant prefixes" in the "Differences from 8086"
980 * section of the "Virtual 8086 Mode" chapter.)
981 * 'pc' should be the address of this instruction, it will
982 * be used to print the target address if this is a relative jump or call
983 * The function returns the length of this instruction in bytes.
984 */
985
986int
987print_insn_i386 (pc, info)
988 bfd_vma pc;
989 disassemble_info *info;
990{
991 struct dis386 *dp;
992 int i;
993 int enter_instruction;
994 char *first, *second, *third;
995 int needcomma;
996
726257a8 997 struct dis_private priv;
5d0734a7
JK
998 bfd_byte *inbuf = priv.the_buffer;
999
1000 info->private_data = (PTR) &priv;
1001 priv.max_fetched = priv.the_buffer;
1002 priv.insn_start = pc;
1003 if (setjmp (priv.bailout) != 0)
1004 /* Error return. */
1005 return -1;
1006
1007 obuf[0] = 0;
1008 op1out[0] = 0;
1009 op2out[0] = 0;
1010 op3out[0] = 0;
1011
1012 op_index[0] = op_index[1] = op_index[2] = -1;
1013
1014 the_info = info;
1015 start_pc = pc;
1016 start_codep = inbuf;
1017 codep = inbuf;
1018
1019 ckprefix ();
1020
1021 FETCH_DATA (info, codep + 1);
1022 if (*codep == 0xc8)
1023 enter_instruction = 1;
1024 else
1025 enter_instruction = 0;
1026
1027 obufp = obuf;
1028
1029 if (prefixes & PREFIX_REPZ)
1030 oappend ("repz ");
1031 if (prefixes & PREFIX_REPNZ)
1032 oappend ("repnz ");
1033 if (prefixes & PREFIX_LOCK)
1034 oappend ("lock ");
1035
1036 if ((prefixes & PREFIX_FWAIT)
1037 && ((*codep < 0xd8) || (*codep > 0xdf)))
1038 {
1039 /* fwait not followed by floating point instruction */
1040 (*info->fprintf_func) (info->stream, "fwait");
1041 return (1);
1042 }
1043
1044 /* these would be initialized to 0 if disassembling for 8086 or 286 */
1045 dflag = 1;
1046 aflag = 1;
1047
1048 if (prefixes & PREFIX_DATA)
1049 dflag ^= 1;
1050
1051 if (prefixes & PREFIX_ADR)
1052 {
1053 aflag ^= 1;
1054 oappend ("addr16 ");
1055 }
1056
1057 if (*codep == 0x0f)
1058 {
1059 FETCH_DATA (info, codep + 2);
1060 dp = &dis386_twobyte[*++codep];
1061 }
1062 else
1063 dp = &dis386[*codep];
1064 codep++;
5c9b5f58
PS
1065
1066 /* Fetch the mod/reg/rm byte. FIXME: We should be only fetching
1067 this if we need it. As it is, this code loses if there is a
1068 one-byte instruction (without a mod/reg/rm byte) at the end of
1069 the address space. */
1070
5d0734a7
JK
1071 FETCH_DATA (info, codep + 1);
1072 mod = (*codep >> 6) & 3;
1073 reg = (*codep >> 3) & 7;
1074 rm = *codep & 7;
5c9b5f58 1075
5d0734a7
JK
1076 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
1077 {
1078 dofloat ();
1079 }
1080 else
1081 {
1082 if (dp->name == NULL)
1083 dp = &grps[dp->bytemode1][reg];
1084
1085 putop (dp->name);
1086
1087 obufp = op1out;
1088 op_ad = 2;
1089 if (dp->op1)
1090 (*dp->op1)(dp->bytemode1);
1091
1092 obufp = op2out;
1093 op_ad = 1;
1094 if (dp->op2)
1095 (*dp->op2)(dp->bytemode2);
1096
1097 obufp = op3out;
1098 op_ad = 0;
1099 if (dp->op3)
1100 (*dp->op3)(dp->bytemode3);
1101 }
1102
1103 obufp = obuf + strlen (obuf);
1104 for (i = strlen (obuf); i < 6; i++)
1105 oappend (" ");
1106 oappend (" ");
1107 (*info->fprintf_func) (info->stream, "%s", obuf);
1108
1109 /* enter instruction is printed with operands in the
1110 * same order as the intel book; everything else
1111 * is printed in reverse order
1112 */
1113 if (enter_instruction)
1114 {
1115 first = op1out;
1116 second = op2out;
1117 third = op3out;
1118 op_ad = op_index[0];
1119 op_index[0] = op_index[2];
1120 op_index[2] = op_ad;
1121 }
1122 else
1123 {
1124 first = op3out;
1125 second = op2out;
1126 third = op1out;
1127 }
1128 needcomma = 0;
1129 if (*first)
1130 {
1131 if (op_index[0] != -1)
a279b1f5 1132 (*info->print_address_func) (op_address[op_index[0]], info);
5d0734a7
JK
1133 else
1134 (*info->fprintf_func) (info->stream, "%s", first);
1135 needcomma = 1;
1136 }
1137 if (*second)
1138 {
1139 if (needcomma)
1140 (*info->fprintf_func) (info->stream, ",");
1141 if (op_index[1] != -1)
a279b1f5 1142 (*info->print_address_func) (op_address[op_index[1]], info);
5d0734a7
JK
1143 else
1144 (*info->fprintf_func) (info->stream, "%s", second);
1145 needcomma = 1;
1146 }
1147 if (*third)
1148 {
1149 if (needcomma)
1150 (*info->fprintf_func) (info->stream, ",");
1151 if (op_index[2] != -1)
a279b1f5 1152 (*info->print_address_func) (op_address[op_index[2]], info);
5d0734a7
JK
1153 else
1154 (*info->fprintf_func) (info->stream, "%s", third);
1155 }
1156 return (codep - inbuf);
1157}
1158
1159char *float_mem[] = {
1160 /* d8 */
1161 "fadds",
1162 "fmuls",
1163 "fcoms",
1164 "fcomps",
1165 "fsubs",
1166 "fsubrs",
1167 "fdivs",
1168 "fdivrs",
1169 /* d9 */
1170 "flds",
1171 "(bad)",
1172 "fsts",
1173 "fstps",
1174 "fldenv",
1175 "fldcw",
1176 "fNstenv",
1177 "fNstcw",
1178 /* da */
1179 "fiaddl",
1180 "fimull",
1181 "ficoml",
1182 "ficompl",
1183 "fisubl",
1184 "fisubrl",
1185 "fidivl",
1186 "fidivrl",
1187 /* db */
1188 "fildl",
1189 "(bad)",
1190 "fistl",
1191 "fistpl",
1192 "(bad)",
1193 "fldt",
1194 "(bad)",
1195 "fstpt",
1196 /* dc */
1197 "faddl",
1198 "fmull",
1199 "fcoml",
1200 "fcompl",
1201 "fsubl",
1202 "fsubrl",
1203 "fdivl",
1204 "fdivrl",
1205 /* dd */
1206 "fldl",
1207 "(bad)",
1208 "fstl",
1209 "fstpl",
1210 "frstor",
1211 "(bad)",
1212 "fNsave",
1213 "fNstsw",
1214 /* de */
1215 "fiadd",
1216 "fimul",
1217 "ficom",
1218 "ficomp",
1219 "fisub",
1220 "fisubr",
1221 "fidiv",
1222 "fidivr",
1223 /* df */
1224 "fild",
1225 "(bad)",
1226 "fist",
1227 "fistp",
1228 "fbld",
1229 "fildll",
1230 "fbstp",
1231 "fistpll",
1232};
1233
1234#define ST OP_ST, 0
1235#define STi OP_STi, 0
1236int OP_ST(), OP_STi();
1237
1238#define FGRPd9_2 NULL, NULL, 0
1239#define FGRPd9_4 NULL, NULL, 1
1240#define FGRPd9_5 NULL, NULL, 2
1241#define FGRPd9_6 NULL, NULL, 3
1242#define FGRPd9_7 NULL, NULL, 4
1243#define FGRPda_5 NULL, NULL, 5
1244#define FGRPdb_4 NULL, NULL, 6
1245#define FGRPde_3 NULL, NULL, 7
1246#define FGRPdf_4 NULL, NULL, 8
1247
1248struct dis386 float_reg[][8] = {
1249 /* d8 */
1250 {
1251 { "fadd", ST, STi },
1252 { "fmul", ST, STi },
1253 { "fcom", STi },
1254 { "fcomp", STi },
1255 { "fsub", ST, STi },
1256 { "fsubr", ST, STi },
1257 { "fdiv", ST, STi },
1258 { "fdivr", ST, STi },
1259 },
1260 /* d9 */
1261 {
1262 { "fld", STi },
1263 { "fxch", STi },
1264 { FGRPd9_2 },
1265 { "(bad)" },
1266 { FGRPd9_4 },
1267 { FGRPd9_5 },
1268 { FGRPd9_6 },
1269 { FGRPd9_7 },
1270 },
1271 /* da */
1272 {
1273 { "(bad)" },
1274 { "(bad)" },
1275 { "(bad)" },
1276 { "(bad)" },
1277 { "(bad)" },
1278 { FGRPda_5 },
1279 { "(bad)" },
1280 { "(bad)" },
1281 },
1282 /* db */
1283 {
1284 { "(bad)" },
1285 { "(bad)" },
1286 { "(bad)" },
1287 { "(bad)" },
1288 { FGRPdb_4 },
1289 { "(bad)" },
1290 { "(bad)" },
1291 { "(bad)" },
1292 },
1293 /* dc */
1294 {
1295 { "fadd", STi, ST },
1296 { "fmul", STi, ST },
1297 { "(bad)" },
1298 { "(bad)" },
1299 { "fsub", STi, ST },
1300 { "fsubr", STi, ST },
1301 { "fdiv", STi, ST },
1302 { "fdivr", STi, ST },
1303 },
1304 /* dd */
1305 {
1306 { "ffree", STi },
1307 { "(bad)" },
1308 { "fst", STi },
1309 { "fstp", STi },
1310 { "fucom", STi },
1311 { "fucomp", STi },
1312 { "(bad)" },
1313 { "(bad)" },
1314 },
1315 /* de */
1316 {
1317 { "faddp", STi, ST },
1318 { "fmulp", STi, ST },
1319 { "(bad)" },
1320 { FGRPde_3 },
1321 { "fsubp", STi, ST },
1322 { "fsubrp", STi, ST },
1323 { "fdivp", STi, ST },
1324 { "fdivrp", STi, ST },
1325 },
1326 /* df */
1327 {
1328 { "(bad)" },
1329 { "(bad)" },
1330 { "(bad)" },
1331 { "(bad)" },
1332 { FGRPdf_4 },
1333 { "(bad)" },
1334 { "(bad)" },
1335 { "(bad)" },
1336 },
1337};
1338
1339
1340char *fgrps[][8] = {
1341 /* d9_2 0 */
1342 {
1343 "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1344 },
1345
1346 /* d9_4 1 */
1347 {
1348 "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
1349 },
1350
1351 /* d9_5 2 */
1352 {
1353 "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
1354 },
1355
1356 /* d9_6 3 */
1357 {
1358 "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
1359 },
1360
1361 /* d9_7 4 */
1362 {
1363 "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
1364 },
1365
1366 /* da_5 5 */
1367 {
1368 "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1369 },
1370
1371 /* db_4 6 */
1372 {
1373 "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
1374 "fNsetpm(287 only)","(bad)","(bad)","(bad)",
1375 },
1376
1377 /* de_3 7 */
1378 {
1379 "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1380 },
1381
1382 /* df_4 8 */
1383 {
1384 "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
1385 },
1386};
1387
1388static void
1389dofloat ()
1390{
1391 struct dis386 *dp;
1392 unsigned char floatop;
1393
1394 floatop = codep[-1];
1395
1396 if (mod != 3)
1397 {
1398 putop (float_mem[(floatop - 0xd8) * 8 + reg]);
1399 obufp = op1out;
1400 OP_E (v_mode);
1401 return;
1402 }
1403 codep++;
1404
1405 dp = &float_reg[floatop - 0xd8][reg];
1406 if (dp->name == NULL)
1407 {
1408 putop (fgrps[dp->bytemode1][rm]);
1409 /* instruction fnstsw is only one with strange arg */
1410 if (floatop == 0xdf
1411 && FETCH_DATA (the_info, codep + 1)
1412 && *codep == 0xe0)
1413 strcpy (op1out, "%eax");
1414 }
1415 else
1416 {
1417 putop (dp->name);
1418 obufp = op1out;
1419 if (dp->op1)
1420 (*dp->op1)(dp->bytemode1);
1421 obufp = op2out;
1422 if (dp->op2)
1423 (*dp->op2)(dp->bytemode2);
1424 }
1425}
1426
1427/* ARGSUSED */
1428int
1429OP_ST (ignore)
1430 int ignore;
1431{
1432 oappend ("%st");
1433 return (0);
1434}
1435
1436/* ARGSUSED */
1437int
1438OP_STi (ignore)
1439 int ignore;
1440{
1441 sprintf (scratchbuf, "%%st(%d)", rm);
1442 oappend (scratchbuf);
1443 return (0);
1444}
1445
1446
1447/* capital letters in template are macros */
1448static void
1449putop (template)
1450 char *template;
1451{
1452 char *p;
1453
1454 for (p = template; *p; p++)
1455 {
1456 switch (*p)
1457 {
1458 default:
1459 *obufp++ = *p;
1460 break;
1461 case 'C': /* For jcxz/jecxz */
1462 if (aflag == 0)
1463 *obufp++ = 'e';
1464 break;
1465 case 'N':
1466 if ((prefixes & PREFIX_FWAIT) == 0)
1467 *obufp++ = 'n';
1468 break;
1469 case 'S':
1470 /* operand size flag */
1471 if (dflag)
1472 *obufp++ = 'l';
1473 else
1474 *obufp++ = 'w';
1475 break;
1476 }
1477 }
1478 *obufp = 0;
1479}
1480
1481static void
1482oappend (s)
1483 char *s;
1484{
1485 strcpy (obufp, s);
1486 obufp += strlen (s);
1487 *obufp = 0;
1488}
1489
1490static void
1491append_prefix ()
1492{
1493 if (prefixes & PREFIX_CS)
1494 oappend ("%cs:");
1495 if (prefixes & PREFIX_DS)
1496 oappend ("%ds:");
1497 if (prefixes & PREFIX_SS)
1498 oappend ("%ss:");
1499 if (prefixes & PREFIX_ES)
1500 oappend ("%es:");
1501 if (prefixes & PREFIX_FS)
1502 oappend ("%fs:");
1503 if (prefixes & PREFIX_GS)
1504 oappend ("%gs:");
1505}
1506
1507int
1508OP_indirE (bytemode)
1509 int bytemode;
1510{
1511 oappend ("*");
1512 OP_E (bytemode);
1513 return (0);
1514}
1515
1516int
1517OP_E (bytemode)
1518 int bytemode;
1519{
1520 int disp;
1521 int havesib;
1522 int base;
1523 int index;
1524 int scale;
1525 int havebase;
1526
1527 /* skip mod/rm byte */
1528 codep++;
1529
1530 havesib = 0;
1531 havebase = 0;
1532 disp = 0;
1533
1534 if (mod == 3)
1535 {
1536 switch (bytemode)
1537 {
1538 case b_mode:
1539 oappend (names8[rm]);
1540 break;
1541 case w_mode:
1542 oappend (names16[rm]);
1543 break;
1544 case v_mode:
1545 if (dflag)
1546 oappend (names32[rm]);
1547 else
1548 oappend (names16[rm]);
1549 break;
1550 default:
1551 oappend ("<bad dis table>");
1552 break;
1553 }
1554 return (0);
1555 }
1556
1557 append_prefix ();
1558 if (rm == 4)
1559 {
1560 havesib = 1;
1561 havebase = 1;
1562 FETCH_DATA (the_info, codep + 1);
1563 scale = (*codep >> 6) & 3;
1564 index = (*codep >> 3) & 7;
1565 base = *codep & 7;
1566 codep++;
1567 }
1568
1569 switch (mod)
1570 {
1571 case 0:
1572 switch (rm)
1573 {
1574 case 4:
1575 /* implies havesib and havebase */
1576 if (base == 5) {
1577 havebase = 0;
1578 disp = get32 ();
1579 }
1580 break;
1581 case 5:
1582 disp = get32 ();
1583 break;
1584 default:
1585 havebase = 1;
1586 base = rm;
1587 break;
1588 }
1589 break;
1590 case 1:
1591 FETCH_DATA (the_info, codep + 1);
1592 disp = *(char *)codep++;
1593 if (rm != 4)
1594 {
1595 havebase = 1;
1596 base = rm;
1597 }
1598 break;
1599 case 2:
1600 disp = get32 ();
1601 if (rm != 4)
1602 {
1603 havebase = 1;
1604 base = rm;
1605 }
1606 break;
1607 }
1608
1609 if (mod != 0 || rm == 5 || (havesib && base == 5))
1610 {
1611 sprintf (scratchbuf, "0x%x", disp);
1612 oappend (scratchbuf);
1613 }
1614
1615 if (havebase || havesib)
1616 {
1617 oappend ("(");
1618 if (havebase)
1619 oappend (names32[base]);
1620 if (havesib)
1621 {
1622 if (index != 4)
1623 {
1624 sprintf (scratchbuf, ",%s", names32[index]);
1625 oappend (scratchbuf);
1626 }
1627 sprintf (scratchbuf, ",%d", 1 << scale);
1628 oappend (scratchbuf);
1629 }
1630 oappend (")");
1631 }
1632 return (0);
1633}
1634
1635int
1636OP_G (bytemode)
1637 int bytemode;
1638{
1639 switch (bytemode)
1640 {
1641 case b_mode:
1642 oappend (names8[reg]);
1643 break;
1644 case w_mode:
1645 oappend (names16[reg]);
1646 break;
1647 case d_mode:
1648 oappend (names32[reg]);
1649 break;
1650 case v_mode:
1651 if (dflag)
1652 oappend (names32[reg]);
1653 else
1654 oappend (names16[reg]);
1655 break;
1656 default:
1657 oappend ("<internal disassembler error>");
1658 break;
1659 }
1660 return (0);
1661}
1662
1663static int
1664get32 ()
1665{
1666 int x = 0;
1667
1668 FETCH_DATA (the_info, codep + 4);
1669 x = *codep++ & 0xff;
1670 x |= (*codep++ & 0xff) << 8;
1671 x |= (*codep++ & 0xff) << 16;
1672 x |= (*codep++ & 0xff) << 24;
1673 return (x);
1674}
1675
1676static int
1677get16 ()
1678{
1679 int x = 0;
1680
1681 FETCH_DATA (the_info, codep + 2);
1682 x = *codep++ & 0xff;
1683 x |= (*codep++ & 0xff) << 8;
1684 return (x);
1685}
1686
1687static void
1688set_op (op)
1689 int op;
1690{
1691 op_index[op_ad] = op_ad;
1692 op_address[op_ad] = op;
1693}
1694
1695int
1696OP_REG (code)
1697 int code;
1698{
1699 char *s;
1700
1701 switch (code)
1702 {
1703 case indir_dx_reg: s = "(%dx)"; break;
1704 case ax_reg: case cx_reg: case dx_reg: case bx_reg:
1705 case sp_reg: case bp_reg: case si_reg: case di_reg:
1706 s = names16[code - ax_reg];
1707 break;
1708 case es_reg: case ss_reg: case cs_reg:
1709 case ds_reg: case fs_reg: case gs_reg:
1710 s = names_seg[code - es_reg];
1711 break;
1712 case al_reg: case ah_reg: case cl_reg: case ch_reg:
1713 case dl_reg: case dh_reg: case bl_reg: case bh_reg:
1714 s = names8[code - al_reg];
1715 break;
1716 case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
1717 case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
1718 if (dflag)
1719 s = names32[code - eAX_reg];
1720 else
1721 s = names16[code - eAX_reg];
1722 break;
1723 default:
1724 s = "<internal disassembler error>";
1725 break;
1726 }
1727 oappend (s);
1728 return (0);
1729}
1730
1731int
1732OP_I (bytemode)
1733 int bytemode;
1734{
1735 int op;
1736
1737 switch (bytemode)
1738 {
1739 case b_mode:
1740 FETCH_DATA (the_info, codep + 1);
1741 op = *codep++ & 0xff;
1742 break;
1743 case v_mode:
1744 if (dflag)
1745 op = get32 ();
1746 else
1747 op = get16 ();
1748 break;
1749 case w_mode:
1750 op = get16 ();
1751 break;
1752 default:
1753 oappend ("<internal disassembler error>");
1754 return (0);
1755 }
1756 sprintf (scratchbuf, "$0x%x", op);
1757 oappend (scratchbuf);
1758 return (0);
1759}
1760
1761int
1762OP_sI (bytemode)
1763 int bytemode;
1764{
1765 int op;
1766
1767 switch (bytemode)
1768 {
1769 case b_mode:
1770 FETCH_DATA (the_info, codep + 1);
1771 op = *(char *)codep++;
1772 break;
1773 case v_mode:
1774 if (dflag)
1775 op = get32 ();
1776 else
1777 op = (short)get16();
1778 break;
1779 case w_mode:
1780 op = (short)get16 ();
1781 break;
1782 default:
1783 oappend ("<internal disassembler error>");
1784 return (0);
1785 }
1786 sprintf (scratchbuf, "$0x%x", op);
1787 oappend (scratchbuf);
1788 return (0);
1789}
1790
1791int
1792OP_J (bytemode)
1793 int bytemode;
1794{
1795 int disp;
1796 int mask = -1;
1797
1798 switch (bytemode)
1799 {
1800 case b_mode:
1801 FETCH_DATA (the_info, codep + 1);
1802 disp = *(char *)codep++;
1803 break;
1804 case v_mode:
1805 if (dflag)
1806 disp = get32 ();
1807 else
1808 {
1809 disp = (short)get16 ();
1810 /* for some reason, a data16 prefix on a jump instruction
1811 means that the pc is masked to 16 bits after the
1812 displacement is added! */
1813 mask = 0xffff;
1814 }
1815 break;
1816 default:
1817 oappend ("<internal disassembler error>");
1818 return (0);
1819 }
1820 disp = (start_pc + codep - start_codep + disp) & mask;
1821 set_op (disp);
1822 sprintf (scratchbuf, "0x%x", disp);
1823 oappend (scratchbuf);
1824 return (0);
1825}
1826
1827/* ARGSUSED */
1828int
1829OP_SEG (dummy)
1830 int dummy;
1831{
1832 static char *sreg[] = {
1833 "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
1834 };
1835
1836 oappend (sreg[reg]);
1837 return (0);
1838}
1839
1840int
1841OP_DIR (size)
1842 int size;
1843{
1844 int seg, offset;
1845
1846 switch (size)
1847 {
1848 case lptr:
1849 if (aflag)
1850 {
1851 offset = get32 ();
1852 seg = get16 ();
1853 }
1854 else
1855 {
1856 offset = get16 ();
1857 seg = get16 ();
1858 }
1859 sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
1860 oappend (scratchbuf);
1861 break;
1862 case v_mode:
1863 if (aflag)
1864 offset = get32 ();
1865 else
1866 offset = (short)get16 ();
1867
1868 offset = start_pc + codep - start_codep + offset;
1869 set_op (offset);
1870 sprintf (scratchbuf, "0x%x", offset);
1871 oappend (scratchbuf);
1872 break;
1873 default:
1874 oappend ("<internal disassembler error>");
1875 break;
1876 }
1877 return (0);
1878}
1879
1880/* ARGSUSED */
1881int
1882OP_OFF (bytemode)
1883 int bytemode;
1884{
1885 int off;
1886
1887 if (aflag)
1888 off = get32 ();
1889 else
1890 off = get16 ();
1891
1892 sprintf (scratchbuf, "0x%x", off);
1893 oappend (scratchbuf);
1894 return (0);
1895}
1896
1897/* ARGSUSED */
1898int
1899OP_ESDI (dummy)
1900 int dummy;
1901{
1902 oappend ("%es:(");
1903 oappend (aflag ? "%edi" : "%di");
1904 oappend (")");
1905 return (0);
1906}
1907
1908/* ARGSUSED */
1909int
1910OP_DSSI (dummy)
1911 int dummy;
1912{
1913 oappend ("%ds:(");
1914 oappend (aflag ? "%esi" : "%si");
1915 oappend (")");
1916 return (0);
1917}
1918
1919/* ARGSUSED */
1920int
1921OP_ONE (dummy)
1922 int dummy;
1923{
1924 oappend ("1");
1925 return (0);
1926}
1927
1928/* ARGSUSED */
1929int
1930OP_C (dummy)
1931 int dummy;
1932{
1933 codep++; /* skip mod/rm */
1934 sprintf (scratchbuf, "%%cr%d", reg);
1935 oappend (scratchbuf);
1936 return (0);
1937}
1938
1939/* ARGSUSED */
1940int
1941OP_D (dummy)
1942 int dummy;
1943{
1944 codep++; /* skip mod/rm */
1945 sprintf (scratchbuf, "%%db%d", reg);
1946 oappend (scratchbuf);
1947 return (0);
1948}
1949
1950/* ARGSUSED */
1951int
1952OP_T (dummy)
1953 int dummy;
1954{
1955 codep++; /* skip mod/rm */
1956 sprintf (scratchbuf, "%%tr%d", reg);
1957 oappend (scratchbuf);
1958 return (0);
1959}
1960
1961int
1962OP_rm (bytemode)
1963 int bytemode;
1964{
1965 switch (bytemode)
1966 {
1967 case d_mode:
1968 oappend (names32[rm]);
1969 break;
1970 case w_mode:
1971 oappend (names16[rm]);
1972 break;
1973 }
1974 return (0);
1975}
This page took 0.178859 seconds and 4 git commands to generate.