Print phys_base_ptr in testvbe.
[v86d.git] / libs / x86emu / fpu.c
blobb72de1ee5e3de411bd0297c6a8c477069992ab98
1 /****************************************************************************
3 * Realmode X86 Emulator Library
5 * Copyright (C) 1996-1999 SciTech Software, Inc.
6 * Copyright (C) David Mosberger-Tang
7 * Copyright (C) 1999 Egbert Eich
9 * ========================================================================
11 * Permission to use, copy, modify, distribute, and sell this software and
12 * its documentation for any purpose is hereby granted without fee,
13 * provided that the above copyright notice appear in all copies and that
14 * both that copyright notice and this permission notice appear in
15 * supporting documentation, and that the name of the authors not be used
16 * in advertising or publicity pertaining to distribution of the software
17 * without specific, written prior permission. The authors makes no
18 * representations about the suitability of this software for any purpose.
19 * It is provided "as is" without express or implied warranty.
21 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27 * PERFORMANCE OF THIS SOFTWARE.
29 * ========================================================================
31 * Language: ANSI C
32 * Environment: Any
33 * Developer: Kendall Bennett
35 * Description: This file contains the code to implement the decoding and
36 * emulation of the FPU instructions.
38 ****************************************************************************/
40 #include "x86emu/x86emui.h"
42 /*----------------------------- Implementation ----------------------------*/
44 /* opcode=0xd8 */
45 void x86emuOp_esc_coprocess_d8(u8 X86EMU_UNUSED(op1))
47 START_OF_INSTR();
48 DECODE_PRINTF("ESC D8\n");
49 DECODE_CLEAR_SEGOVR();
50 END_OF_INSTR_NO_TRACE();
53 #ifdef DEBUG
55 static char *x86emu_fpu_op_d9_tab[] = {
56 "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
57 "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
59 "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
60 "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
62 "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
63 "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
66 static char *x86emu_fpu_op_d9_tab1[] = {
67 "FLD\t", "FLD\t", "FLD\t", "FLD\t",
68 "FLD\t", "FLD\t", "FLD\t", "FLD\t",
70 "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
71 "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
73 "FNOP", "ESC_D9", "ESC_D9", "ESC_D9",
74 "ESC_D9", "ESC_D9", "ESC_D9", "ESC_D9",
76 "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
77 "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
79 "FCHS", "FABS", "ESC_D9", "ESC_D9",
80 "FTST", "FXAM", "ESC_D9", "ESC_D9",
82 "FLD1", "FLDL2T", "FLDL2E", "FLDPI",
83 "FLDLG2", "FLDLN2", "FLDZ", "ESC_D9",
85 "F2XM1", "FYL2X", "FPTAN", "FPATAN",
86 "FXTRACT", "ESC_D9", "FDECSTP", "FINCSTP",
88 "FPREM", "FYL2XP1", "FSQRT", "ESC_D9",
89 "FRNDINT", "FSCALE", "ESC_D9", "ESC_D9",
92 #endif /* DEBUG */
94 /* opcode=0xd9 */
95 void x86emuOp_esc_coprocess_d9(u8 X86EMU_UNUSED(op1))
97 int mod, rl, rh;
98 uint destoffset = 0;
99 u8 stkelem = 0;
101 START_OF_INSTR();
102 FETCH_DECODE_MODRM(mod, rh, rl);
103 #ifdef DEBUG
104 if (mod != 3) {
105 DECODE_PRINTINSTR32(x86emu_fpu_op_d9_tab, mod, rh, rl);
106 } else {
107 DECODE_PRINTF(x86emu_fpu_op_d9_tab1[(rh << 3) + rl]);
109 #endif
110 switch (mod) {
111 case 0:
112 destoffset = decode_rm00_address(rl);
113 DECODE_PRINTF("\n");
114 break;
115 case 1:
116 destoffset = decode_rm01_address(rl);
117 DECODE_PRINTF("\n");
118 break;
119 case 2:
120 destoffset = decode_rm10_address(rl);
121 DECODE_PRINTF("\n");
122 break;
123 case 3: /* register to register */
124 stkelem = (u8)rl;
125 if (rh < 4) {
126 DECODE_PRINTF2("ST(%d)\n", stkelem);
127 } else {
128 DECODE_PRINTF("\n");
130 break;
132 #ifdef X86EMU_FPU_PRESENT
133 /* execute */
134 switch (mod) {
135 case 3:
136 switch (rh) {
137 case 0:
138 x86emu_fpu_R_fld(X86EMU_FPU_STKTOP, stkelem);
139 break;
140 case 1:
141 x86emu_fpu_R_fxch(X86EMU_FPU_STKTOP, stkelem);
142 break;
143 case 2:
144 switch (rl) {
145 case 0:
146 x86emu_fpu_R_nop();
147 break;
148 default:
149 x86emu_fpu_illegal();
150 break;
152 case 3:
153 x86emu_fpu_R_fstp(X86EMU_FPU_STKTOP, stkelem);
154 break;
155 case 4:
156 switch (rl) {
157 case 0:
158 x86emu_fpu_R_fchs(X86EMU_FPU_STKTOP);
159 break;
160 case 1:
161 x86emu_fpu_R_fabs(X86EMU_FPU_STKTOP);
162 break;
163 case 4:
164 x86emu_fpu_R_ftst(X86EMU_FPU_STKTOP);
165 break;
166 case 5:
167 x86emu_fpu_R_fxam(X86EMU_FPU_STKTOP);
168 break;
169 default:
170 /* 2,3,6,7 */
171 x86emu_fpu_illegal();
172 break;
174 break;
176 case 5:
177 switch (rl) {
178 case 0:
179 x86emu_fpu_R_fld1(X86EMU_FPU_STKTOP);
180 break;
181 case 1:
182 x86emu_fpu_R_fldl2t(X86EMU_FPU_STKTOP);
183 break;
184 case 2:
185 x86emu_fpu_R_fldl2e(X86EMU_FPU_STKTOP);
186 break;
187 case 3:
188 x86emu_fpu_R_fldpi(X86EMU_FPU_STKTOP);
189 break;
190 case 4:
191 x86emu_fpu_R_fldlg2(X86EMU_FPU_STKTOP);
192 break;
193 case 5:
194 x86emu_fpu_R_fldln2(X86EMU_FPU_STKTOP);
195 break;
196 case 6:
197 x86emu_fpu_R_fldz(X86EMU_FPU_STKTOP);
198 break;
199 default:
200 /* 7 */
201 x86emu_fpu_illegal();
202 break;
204 break;
206 case 6:
207 switch (rl) {
208 case 0:
209 x86emu_fpu_R_f2xm1(X86EMU_FPU_STKTOP);
210 break;
211 case 1:
212 x86emu_fpu_R_fyl2x(X86EMU_FPU_STKTOP);
213 break;
214 case 2:
215 x86emu_fpu_R_fptan(X86EMU_FPU_STKTOP);
216 break;
217 case 3:
218 x86emu_fpu_R_fpatan(X86EMU_FPU_STKTOP);
219 break;
220 case 4:
221 x86emu_fpu_R_fxtract(X86EMU_FPU_STKTOP);
222 break;
223 case 5:
224 x86emu_fpu_illegal();
225 break;
226 case 6:
227 x86emu_fpu_R_decstp();
228 break;
229 case 7:
230 x86emu_fpu_R_incstp();
231 break;
233 break;
235 case 7:
236 switch (rl) {
237 case 0:
238 x86emu_fpu_R_fprem(X86EMU_FPU_STKTOP);
239 break;
240 case 1:
241 x86emu_fpu_R_fyl2xp1(X86EMU_FPU_STKTOP);
242 break;
243 case 2:
244 x86emu_fpu_R_fsqrt(X86EMU_FPU_STKTOP);
245 break;
246 case 3:
247 x86emu_fpu_illegal();
248 break;
249 case 4:
250 x86emu_fpu_R_frndint(X86EMU_FPU_STKTOP);
251 break;
252 case 5:
253 x86emu_fpu_R_fscale(X86EMU_FPU_STKTOP);
254 break;
255 case 6:
256 case 7:
257 default:
258 x86emu_fpu_illegal();
259 break;
261 break;
263 default:
264 switch (rh) {
265 case 0:
266 x86emu_fpu_M_fld(X86EMU_FPU_FLOAT, destoffset);
267 break;
268 case 1:
269 x86emu_fpu_illegal();
270 break;
271 case 2:
272 x86emu_fpu_M_fst(X86EMU_FPU_FLOAT, destoffset);
273 break;
274 case 3:
275 x86emu_fpu_M_fstp(X86EMU_FPU_FLOAT, destoffset);
276 break;
277 case 4:
278 x86emu_fpu_M_fldenv(X86EMU_FPU_WORD, destoffset);
279 break;
280 case 5:
281 x86emu_fpu_M_fldcw(X86EMU_FPU_WORD, destoffset);
282 break;
283 case 6:
284 x86emu_fpu_M_fstenv(X86EMU_FPU_WORD, destoffset);
285 break;
286 case 7:
287 x86emu_fpu_M_fstcw(X86EMU_FPU_WORD, destoffset);
288 break;
292 #else
293 (void)destoffset;
294 (void)stkelem;
295 #endif /* X86EMU_FPU_PRESENT */
296 DECODE_CLEAR_SEGOVR();
297 END_OF_INSTR_NO_TRACE();
300 #ifdef DEBUG
302 char *x86emu_fpu_op_da_tab[] = {
303 "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
304 "FICOMP\tDWORD PTR ",
305 "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
306 "FIDIVR\tDWORD PTR ",
308 "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
309 "FICOMP\tDWORD PTR ",
310 "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
311 "FIDIVR\tDWORD PTR ",
313 "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
314 "FICOMP\tDWORD PTR ",
315 "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
316 "FIDIVR\tDWORD PTR ",
318 "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
319 "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
322 #endif /* DEBUG */
324 /* opcode=0xda */
325 void x86emuOp_esc_coprocess_da(u8 X86EMU_UNUSED(op1))
327 int mod, rl, rh;
328 uint destoffset = 0;
329 u8 stkelem = 0;
331 START_OF_INSTR();
332 FETCH_DECODE_MODRM(mod, rh, rl);
333 DECODE_PRINTINSTR32(x86emu_fpu_op_da_tab, mod, rh, rl);
334 switch (mod) {
335 case 0:
336 destoffset = decode_rm00_address(rl);
337 DECODE_PRINTF("\n");
338 break;
339 case 1:
340 destoffset = decode_rm01_address(rl);
341 DECODE_PRINTF("\n");
342 break;
343 case 2:
344 destoffset = decode_rm10_address(rl);
345 DECODE_PRINTF("\n");
346 break;
347 case 3: /* register to register */
348 stkelem = (u8)rl;
349 DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
350 break;
352 #ifdef X86EMU_FPU_PRESENT
353 switch (mod) {
354 case 3:
355 x86emu_fpu_illegal();
356 break;
357 default:
358 switch (rh) {
359 case 0:
360 x86emu_fpu_M_iadd(X86EMU_FPU_SHORT, destoffset);
361 break;
362 case 1:
363 x86emu_fpu_M_imul(X86EMU_FPU_SHORT, destoffset);
364 break;
365 case 2:
366 x86emu_fpu_M_icom(X86EMU_FPU_SHORT, destoffset);
367 break;
368 case 3:
369 x86emu_fpu_M_icomp(X86EMU_FPU_SHORT, destoffset);
370 break;
371 case 4:
372 x86emu_fpu_M_isub(X86EMU_FPU_SHORT, destoffset);
373 break;
374 case 5:
375 x86emu_fpu_M_isubr(X86EMU_FPU_SHORT, destoffset);
376 break;
377 case 6:
378 x86emu_fpu_M_idiv(X86EMU_FPU_SHORT, destoffset);
379 break;
380 case 7:
381 x86emu_fpu_M_idivr(X86EMU_FPU_SHORT, destoffset);
382 break;
385 #else
386 (void)destoffset;
387 (void)stkelem;
388 #endif
389 DECODE_CLEAR_SEGOVR();
390 END_OF_INSTR_NO_TRACE();
393 #ifdef DEBUG
395 char *x86emu_fpu_op_db_tab[] = {
396 "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
397 "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
399 "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
400 "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
402 "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
403 "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
406 #endif /* DEBUG */
408 /* opcode=0xdb */
409 void x86emuOp_esc_coprocess_db(u8 X86EMU_UNUSED(op1))
411 int mod, rl, rh;
412 uint destoffset = 0;
414 START_OF_INSTR();
415 FETCH_DECODE_MODRM(mod, rh, rl);
416 #ifdef DEBUG
417 if (mod != 3) {
418 DECODE_PRINTINSTR32(x86emu_fpu_op_db_tab, mod, rh, rl);
419 } else if (rh == 4) { /* === 11 10 0 nnn */
420 switch (rl) {
421 case 0:
422 DECODE_PRINTF("FENI\n");
423 break;
424 case 1:
425 DECODE_PRINTF("FDISI\n");
426 break;
427 case 2:
428 DECODE_PRINTF("FCLEX\n");
429 break;
430 case 3:
431 DECODE_PRINTF("FINIT\n");
432 break;
434 } else {
435 DECODE_PRINTF2("ESC_DB %0x\n", (mod << 6) + (rh << 3) + (rl));
437 #endif /* DEBUG */
438 switch (mod) {
439 case 0:
440 destoffset = decode_rm00_address(rl);
441 break;
442 case 1:
443 destoffset = decode_rm01_address(rl);
444 break;
445 case 2:
446 destoffset = decode_rm10_address(rl);
447 break;
448 case 3: /* register to register */
449 break;
451 #ifdef X86EMU_FPU_PRESENT
452 /* execute */
453 switch (mod) {
454 case 3:
455 switch (rh) {
456 case 4:
457 switch (rl) {
458 case 0:
459 x86emu_fpu_R_feni();
460 break;
461 case 1:
462 x86emu_fpu_R_fdisi();
463 break;
464 case 2:
465 x86emu_fpu_R_fclex();
466 break;
467 case 3:
468 x86emu_fpu_R_finit();
469 break;
470 default:
471 x86emu_fpu_illegal();
472 break;
474 break;
475 default:
476 x86emu_fpu_illegal();
477 break;
479 break;
480 default:
481 switch (rh) {
482 case 0:
483 x86emu_fpu_M_fild(X86EMU_FPU_SHORT, destoffset);
484 break;
485 case 1:
486 x86emu_fpu_illegal();
487 break;
488 case 2:
489 x86emu_fpu_M_fist(X86EMU_FPU_SHORT, destoffset);
490 break;
491 case 3:
492 x86emu_fpu_M_fistp(X86EMU_FPU_SHORT, destoffset);
493 break;
494 case 4:
495 x86emu_fpu_illegal();
496 break;
497 case 5:
498 x86emu_fpu_M_fld(X86EMU_FPU_LDBL, destoffset);
499 break;
500 case 6:
501 x86emu_fpu_illegal();
502 break;
503 case 7:
504 x86emu_fpu_M_fstp(X86EMU_FPU_LDBL, destoffset);
505 break;
508 #else
509 (void)destoffset;
510 #endif
511 DECODE_CLEAR_SEGOVR();
512 END_OF_INSTR_NO_TRACE();
515 #ifdef DEBUG
516 char *x86emu_fpu_op_dc_tab[] = {
517 "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
518 "FCOMP\tQWORD PTR ",
519 "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
520 "FDIVR\tQWORD PTR ",
522 "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
523 "FCOMP\tQWORD PTR ",
524 "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
525 "FDIVR\tQWORD PTR ",
527 "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
528 "FCOMP\tQWORD PTR ",
529 "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
530 "FDIVR\tQWORD PTR ",
532 "FADD\t", "FMUL\t", "FCOM\t", "FCOMP\t",
533 "FSUBR\t", "FSUB\t", "FDIVR\t", "FDIV\t",
535 #endif /* DEBUG */
537 /* opcode=0xdc */
538 void x86emuOp_esc_coprocess_dc(u8 X86EMU_UNUSED(op1))
540 int mod, rl, rh;
541 uint destoffset = 0;
542 u8 stkelem = 0;
544 START_OF_INSTR();
545 FETCH_DECODE_MODRM(mod, rh, rl);
546 DECODE_PRINTINSTR32(x86emu_fpu_op_dc_tab, mod, rh, rl);
547 switch (mod) {
548 case 0:
549 destoffset = decode_rm00_address(rl);
550 DECODE_PRINTF("\n");
551 break;
552 case 1:
553 destoffset = decode_rm01_address(rl);
554 DECODE_PRINTF("\n");
555 break;
556 case 2:
557 destoffset = decode_rm10_address(rl);
558 DECODE_PRINTF("\n");
559 break;
560 case 3: /* register to register */
561 stkelem = (u8)rl;
562 DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
563 break;
565 #ifdef X86EMU_FPU_PRESENT
566 /* execute */
567 switch (mod) {
568 case 3:
569 switch (rh) {
570 case 0:
571 x86emu_fpu_R_fadd(stkelem, X86EMU_FPU_STKTOP);
572 break;
573 case 1:
574 x86emu_fpu_R_fmul(stkelem, X86EMU_FPU_STKTOP);
575 break;
576 case 2:
577 x86emu_fpu_R_fcom(stkelem, X86EMU_FPU_STKTOP);
578 break;
579 case 3:
580 x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
581 break;
582 case 4:
583 x86emu_fpu_R_fsubr(stkelem, X86EMU_FPU_STKTOP);
584 break;
585 case 5:
586 x86emu_fpu_R_fsub(stkelem, X86EMU_FPU_STKTOP);
587 break;
588 case 6:
589 x86emu_fpu_R_fdivr(stkelem, X86EMU_FPU_STKTOP);
590 break;
591 case 7:
592 x86emu_fpu_R_fdiv(stkelem, X86EMU_FPU_STKTOP);
593 break;
595 break;
596 default:
597 switch (rh) {
598 case 0:
599 x86emu_fpu_M_fadd(X86EMU_FPU_DOUBLE, destoffset);
600 break;
601 case 1:
602 x86emu_fpu_M_fmul(X86EMU_FPU_DOUBLE, destoffset);
603 break;
604 case 2:
605 x86emu_fpu_M_fcom(X86EMU_FPU_DOUBLE, destoffset);
606 break;
607 case 3:
608 x86emu_fpu_M_fcomp(X86EMU_FPU_DOUBLE, destoffset);
609 break;
610 case 4:
611 x86emu_fpu_M_fsub(X86EMU_FPU_DOUBLE, destoffset);
612 break;
613 case 5:
614 x86emu_fpu_M_fsubr(X86EMU_FPU_DOUBLE, destoffset);
615 break;
616 case 6:
617 x86emu_fpu_M_fdiv(X86EMU_FPU_DOUBLE, destoffset);
618 break;
619 case 7:
620 x86emu_fpu_M_fdivr(X86EMU_FPU_DOUBLE, destoffset);
621 break;
624 #else
625 (void)destoffset;
626 (void)stkelem;
627 #endif
628 DECODE_CLEAR_SEGOVR();
629 END_OF_INSTR_NO_TRACE();
632 #ifdef DEBUG
634 static char *x86emu_fpu_op_dd_tab[] = {
635 "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
636 "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
638 "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
639 "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
641 "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
642 "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
644 "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
645 "ESC_DD\t2C,", "ESC_DD\t2D,", "ESC_DD\t2E,", "ESC_DD\t2F,",
648 #endif /* DEBUG */
650 /* opcode=0xdd */
651 void x86emuOp_esc_coprocess_dd(u8 X86EMU_UNUSED(op1))
653 int mod, rl, rh;
654 uint destoffset = 0;
655 u8 stkelem = 0;
657 START_OF_INSTR();
658 FETCH_DECODE_MODRM(mod, rh, rl);
659 DECODE_PRINTINSTR32(x86emu_fpu_op_dd_tab, mod, rh, rl);
660 switch (mod) {
661 case 0:
662 destoffset = decode_rm00_address(rl);
663 DECODE_PRINTF("\n");
664 break;
665 case 1:
666 destoffset = decode_rm01_address(rl);
667 DECODE_PRINTF("\n");
668 break;
669 case 2:
670 destoffset = decode_rm10_address(rl);
671 DECODE_PRINTF("\n");
672 break;
673 case 3: /* register to register */
674 stkelem = (u8)rl;
675 DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
676 break;
678 #ifdef X86EMU_FPU_PRESENT
679 switch (mod) {
680 case 3:
681 switch (rh) {
682 case 0:
683 x86emu_fpu_R_ffree(stkelem);
684 break;
685 case 1:
686 x86emu_fpu_R_fxch(stkelem);
687 break;
688 case 2:
689 x86emu_fpu_R_fst(stkelem); /* register version */
690 break;
691 case 3:
692 x86emu_fpu_R_fstp(stkelem); /* register version */
693 break;
694 default:
695 x86emu_fpu_illegal();
696 break;
698 break;
699 default:
700 switch (rh) {
701 case 0:
702 x86emu_fpu_M_fld(X86EMU_FPU_DOUBLE, destoffset);
703 break;
704 case 1:
705 x86emu_fpu_illegal();
706 break;
707 case 2:
708 x86emu_fpu_M_fst(X86EMU_FPU_DOUBLE, destoffset);
709 break;
710 case 3:
711 x86emu_fpu_M_fstp(X86EMU_FPU_DOUBLE, destoffset);
712 break;
713 case 4:
714 x86emu_fpu_M_frstor(X86EMU_FPU_WORD, destoffset);
715 break;
716 case 5:
717 x86emu_fpu_illegal();
718 break;
719 case 6:
720 x86emu_fpu_M_fsave(X86EMU_FPU_WORD, destoffset);
721 break;
722 case 7:
723 x86emu_fpu_M_fstsw(X86EMU_FPU_WORD, destoffset);
724 break;
727 #else
728 (void)destoffset;
729 (void)stkelem;
730 #endif
731 DECODE_CLEAR_SEGOVR();
732 END_OF_INSTR_NO_TRACE();
735 #ifdef DEBUG
737 static char *x86emu_fpu_op_de_tab[] =
739 "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
740 "FICOMP\tWORD PTR ",
741 "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
742 "FIDIVR\tWORD PTR ",
744 "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
745 "FICOMP\tWORD PTR ",
746 "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
747 "FIDIVR\tWORD PTR ",
749 "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
750 "FICOMP\tWORD PTR ",
751 "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
752 "FIDIVR\tWORD PTR ",
754 "FADDP\t", "FMULP\t", "FCOMP\t", "FCOMPP\t",
755 "FSUBRP\t", "FSUBP\t", "FDIVRP\t", "FDIVP\t",
758 #endif /* DEBUG */
760 /* opcode=0xde */
761 void x86emuOp_esc_coprocess_de(u8 X86EMU_UNUSED(op1))
763 int mod, rl, rh;
764 uint destoffset = 0;
765 u8 stkelem = 0;
767 START_OF_INSTR();
768 FETCH_DECODE_MODRM(mod, rh, rl);
769 DECODE_PRINTINSTR32(x86emu_fpu_op_de_tab, mod, rh, rl);
770 switch (mod) {
771 case 0:
772 destoffset = decode_rm00_address(rl);
773 DECODE_PRINTF("\n");
774 break;
775 case 1:
776 destoffset = decode_rm01_address(rl);
777 DECODE_PRINTF("\n");
778 break;
779 case 2:
780 destoffset = decode_rm10_address(rl);
781 DECODE_PRINTF("\n");
782 break;
783 case 3: /* register to register */
784 stkelem = (u8)rl;
785 DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
786 break;
788 #ifdef X86EMU_FPU_PRESENT
789 switch (mod) {
790 case 3:
791 switch (rh) {
792 case 0:
793 x86emu_fpu_R_faddp(stkelem, X86EMU_FPU_STKTOP);
794 break;
795 case 1:
796 x86emu_fpu_R_fmulp(stkelem, X86EMU_FPU_STKTOP);
797 break;
798 case 2:
799 x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
800 break;
801 case 3:
802 if (stkelem == 1)
803 x86emu_fpu_R_fcompp(stkelem, X86EMU_FPU_STKTOP);
804 else
805 x86emu_fpu_illegal();
806 break;
807 case 4:
808 x86emu_fpu_R_fsubrp(stkelem, X86EMU_FPU_STKTOP);
809 break;
810 case 5:
811 x86emu_fpu_R_fsubp(stkelem, X86EMU_FPU_STKTOP);
812 break;
813 case 6:
814 x86emu_fpu_R_fdivrp(stkelem, X86EMU_FPU_STKTOP);
815 break;
816 case 7:
817 x86emu_fpu_R_fdivp(stkelem, X86EMU_FPU_STKTOP);
818 break;
820 break;
821 default:
822 switch (rh) {
823 case 0:
824 x86emu_fpu_M_fiadd(X86EMU_FPU_WORD, destoffset);
825 break;
826 case 1:
827 x86emu_fpu_M_fimul(X86EMU_FPU_WORD, destoffset);
828 break;
829 case 2:
830 x86emu_fpu_M_ficom(X86EMU_FPU_WORD, destoffset);
831 break;
832 case 3:
833 x86emu_fpu_M_ficomp(X86EMU_FPU_WORD, destoffset);
834 break;
835 case 4:
836 x86emu_fpu_M_fisub(X86EMU_FPU_WORD, destoffset);
837 break;
838 case 5:
839 x86emu_fpu_M_fisubr(X86EMU_FPU_WORD, destoffset);
840 break;
841 case 6:
842 x86emu_fpu_M_fidiv(X86EMU_FPU_WORD, destoffset);
843 break;
844 case 7:
845 x86emu_fpu_M_fidivr(X86EMU_FPU_WORD, destoffset);
846 break;
849 #else
850 (void)destoffset;
851 (void)stkelem;
852 #endif
853 DECODE_CLEAR_SEGOVR();
854 END_OF_INSTR_NO_TRACE();
857 #ifdef DEBUG
859 static char *x86emu_fpu_op_df_tab[] = {
860 /* mod == 00 */
861 "FILD\tWORD PTR ", "ESC_DF\t39\n", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
862 "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
863 "FISTP\tQWORD PTR ",
865 /* mod == 01 */
866 "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
867 "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
868 "FISTP\tQWORD PTR ",
870 /* mod == 10 */
871 "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
872 "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
873 "FISTP\tQWORD PTR ",
875 /* mod == 11 */
876 "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
877 "ESC_DF\t3C,", "ESC_DF\t3D,", "ESC_DF\t3E,", "ESC_DF\t3F,"
880 #endif /* DEBUG */
882 /* opcode=0xdf */
883 void x86emuOp_esc_coprocess_df(u8 X86EMU_UNUSED(op1))
885 int mod, rl, rh;
886 uint destoffset = 0;
887 u8 stkelem = 0;
889 START_OF_INSTR();
890 FETCH_DECODE_MODRM(mod, rh, rl);
891 DECODE_PRINTINSTR32(x86emu_fpu_op_df_tab, mod, rh, rl);
892 switch (mod) {
893 case 0:
894 destoffset = decode_rm00_address(rl);
895 DECODE_PRINTF("\n");
896 break;
897 case 1:
898 destoffset = decode_rm01_address(rl);
899 DECODE_PRINTF("\n");
900 break;
901 case 2:
902 destoffset = decode_rm10_address(rl);
903 DECODE_PRINTF("\n");
904 break;
905 case 3: /* register to register */
906 stkelem = (u8)rl;
907 DECODE_PRINTF2("\tST(%d)\n", stkelem);
908 break;
910 #ifdef X86EMU_FPU_PRESENT
911 switch (mod) {
912 case 3:
913 switch (rh) {
914 case 0:
915 x86emu_fpu_R_ffree(stkelem);
916 break;
917 case 1:
918 x86emu_fpu_R_fxch(stkelem);
919 break;
920 case 2:
921 x86emu_fpu_R_fst(stkelem); /* register version */
922 break;
923 case 3:
924 x86emu_fpu_R_fstp(stkelem); /* register version */
925 break;
926 default:
927 x86emu_fpu_illegal();
928 break;
930 break;
931 default:
932 switch (rh) {
933 case 0:
934 x86emu_fpu_M_fild(X86EMU_FPU_WORD, destoffset);
935 break;
936 case 1:
937 x86emu_fpu_illegal();
938 break;
939 case 2:
940 x86emu_fpu_M_fist(X86EMU_FPU_WORD, destoffset);
941 break;
942 case 3:
943 x86emu_fpu_M_fistp(X86EMU_FPU_WORD, destoffset);
944 break;
945 case 4:
946 x86emu_fpu_M_fbld(X86EMU_FPU_BSD, destoffset);
947 break;
948 case 5:
949 x86emu_fpu_M_fild(X86EMU_FPU_LONG, destoffset);
950 break;
951 case 6:
952 x86emu_fpu_M_fbstp(X86EMU_FPU_BSD, destoffset);
953 break;
954 case 7:
955 x86emu_fpu_M_fistp(X86EMU_FPU_LONG, destoffset);
956 break;
959 #else
960 (void)destoffset;
961 (void)stkelem;
962 #endif
963 DECODE_CLEAR_SEGOVR();
964 END_OF_INSTR_NO_TRACE();