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