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