]> git.ipfire.org Git - people/ms/u-boot.git/blob - board/MAI/bios_emulator/scitech/src/x86emu/fpu.c
* Code cleanup:
[people/ms/u-boot.git] / board / MAI / bios_emulator / scitech / src / x86emu / fpu.c
1 /****************************************************************************
2 *
3 * Realmode X86 Emulator Library
4 *
5 * Copyright (C) 1996-1999 SciTech Software, Inc.
6 * Copyright (C) David Mosberger-Tang
7 * Copyright (C) 1999 Egbert Eich
8 *
9 * ========================================================================
10 *
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.
20 *
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.
28 *
29 * ========================================================================
30 *
31 * Language: ANSI C
32 * Environment: Any
33 * Developer: Kendall Bennett
34 *
35 * Description: This file contains the code to implement the decoding and
36 * emulation of the FPU instructions.
37 *
38 ****************************************************************************/
39
40 #include "x86emu/x86emui.h"
41
42 /*----------------------------- Implementation ----------------------------*/
43
44 /* opcode=0xd8 */
45 void x86emuOp_esc_coprocess_d8(u8 X86EMU_UNUSED(op1))
46 {
47 START_OF_INSTR();
48 DECODE_PRINTF("ESC D8\n");
49 DECODE_CLEAR_SEGOVR();
50 END_OF_INSTR_NO_TRACE();
51 }
52
53 #ifdef DEBUG
54
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",
58
59 "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
60 "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
61
62 "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
63 "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
64 };
65
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",
69
70 "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
71 "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
72
73 "FNOP", "ESC_D9", "ESC_D9", "ESC_D9",
74 "ESC_D9", "ESC_D9", "ESC_D9", "ESC_D9",
75
76 "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
77 "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
78
79 "FCHS", "FABS", "ESC_D9", "ESC_D9",
80 "FTST", "FXAM", "ESC_D9", "ESC_D9",
81
82 "FLD1", "FLDL2T", "FLDL2E", "FLDPI",
83 "FLDLG2", "FLDLN2", "FLDZ", "ESC_D9",
84
85 "F2XM1", "FYL2X", "FPTAN", "FPATAN",
86 "FXTRACT", "ESC_D9", "FDECSTP", "FINCSTP",
87
88 "FPREM", "FYL2XP1", "FSQRT", "ESC_D9",
89 "FRNDINT", "FSCALE", "ESC_D9", "ESC_D9",
90 };
91
92 #endif /* DEBUG */
93
94 /* opcode=0xd9 */
95 void x86emuOp_esc_coprocess_d9(u8 X86EMU_UNUSED(op1))
96 {
97 int mod, rl, rh;
98 uint destoffset;
99 u8 stkelem;
100
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]);
108 }
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");
129 }
130 break;
131 }
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;
151 }
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;
173 }
174 break;
175
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;
203 }
204 break;
205
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;
232 }
233 break;
234
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;
260 }
261 break;
262
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;
289 }
290 }
291 }
292 #endif /* X86EMU_FPU_PRESENT */
293 DECODE_CLEAR_SEGOVR();
294 END_OF_INSTR_NO_TRACE();
295 }
296
297 #ifdef DEBUG
298
299 char *x86emu_fpu_op_da_tab[] = {
300 "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
301 "FICOMP\tDWORD PTR ",
302 "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
303 "FIDIVR\tDWORD PTR ",
304
305 "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
306 "FICOMP\tDWORD PTR ",
307 "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
308 "FIDIVR\tDWORD PTR ",
309
310 "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
311 "FICOMP\tDWORD PTR ",
312 "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
313 "FIDIVR\tDWORD PTR ",
314
315 "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
316 "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
317 };
318
319 #endif /* DEBUG */
320
321 /* opcode=0xda */
322 void x86emuOp_esc_coprocess_da(u8 X86EMU_UNUSED(op1))
323 {
324 int mod, rl, rh;
325 uint destoffset;
326 u8 stkelem;
327
328 START_OF_INSTR();
329 FETCH_DECODE_MODRM(mod, rh, rl);
330 DECODE_PRINTINSTR32(x86emu_fpu_op_da_tab, mod, rh, rl);
331 switch (mod) {
332 case 0:
333 destoffset = decode_rm00_address(rl);
334 DECODE_PRINTF("\n");
335 break;
336 case 1:
337 destoffset = decode_rm01_address(rl);
338 DECODE_PRINTF("\n");
339 break;
340 case 2:
341 destoffset = decode_rm10_address(rl);
342 DECODE_PRINTF("\n");
343 break;
344 case 3: /* register to register */
345 stkelem = (u8)rl;
346 DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
347 break;
348 }
349 #ifdef X86EMU_FPU_PRESENT
350 switch (mod) {
351 case 3:
352 x86emu_fpu_illegal();
353 break;
354 default:
355 switch (rh) {
356 case 0:
357 x86emu_fpu_M_iadd(X86EMU_FPU_SHORT, destoffset);
358 break;
359 case 1:
360 x86emu_fpu_M_imul(X86EMU_FPU_SHORT, destoffset);
361 break;
362 case 2:
363 x86emu_fpu_M_icom(X86EMU_FPU_SHORT, destoffset);
364 break;
365 case 3:
366 x86emu_fpu_M_icomp(X86EMU_FPU_SHORT, destoffset);
367 break;
368 case 4:
369 x86emu_fpu_M_isub(X86EMU_FPU_SHORT, destoffset);
370 break;
371 case 5:
372 x86emu_fpu_M_isubr(X86EMU_FPU_SHORT, destoffset);
373 break;
374 case 6:
375 x86emu_fpu_M_idiv(X86EMU_FPU_SHORT, destoffset);
376 break;
377 case 7:
378 x86emu_fpu_M_idivr(X86EMU_FPU_SHORT, destoffset);
379 break;
380 }
381 }
382 #endif
383 DECODE_CLEAR_SEGOVR();
384 END_OF_INSTR_NO_TRACE();
385 }
386
387 #ifdef DEBUG
388
389 char *x86emu_fpu_op_db_tab[] = {
390 "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
391 "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
392
393 "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
394 "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
395
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 ",
398 };
399
400 #endif /* DEBUG */
401
402 /* opcode=0xdb */
403 void x86emuOp_esc_coprocess_db(u8 X86EMU_UNUSED(op1))
404 {
405 int mod, rl, rh;
406 uint destoffset;
407
408 START_OF_INSTR();
409 FETCH_DECODE_MODRM(mod, rh, rl);
410 #ifdef DEBUG
411 if (mod != 3) {
412 DECODE_PRINTINSTR32(x86emu_fpu_op_db_tab, mod, rh, rl);
413 } else if (rh == 4) { /* === 11 10 0 nnn */
414 switch (rl) {
415 case 0:
416 DECODE_PRINTF("FENI\n");
417 break;
418 case 1:
419 DECODE_PRINTF("FDISI\n");
420 break;
421 case 2:
422 DECODE_PRINTF("FCLEX\n");
423 break;
424 case 3:
425 DECODE_PRINTF("FINIT\n");
426 break;
427 }
428 } else {
429 DECODE_PRINTF2("ESC_DB %0x\n", (mod << 6) + (rh << 3) + (rl));
430 }
431 #endif /* DEBUG */
432 switch (mod) {
433 case 0:
434 destoffset = decode_rm00_address(rl);
435 break;
436 case 1:
437 destoffset = decode_rm01_address(rl);
438 break;
439 case 2:
440 destoffset = decode_rm10_address(rl);
441 break;
442 case 3: /* register to register */
443 break;
444 }
445 #ifdef X86EMU_FPU_PRESENT
446 /* execute */
447 switch (mod) {
448 case 3:
449 switch (rh) {
450 case 4:
451 switch (rl) {
452 case 0:
453 x86emu_fpu_R_feni();
454 break;
455 case 1:
456 x86emu_fpu_R_fdisi();
457 break;
458 case 2:
459 x86emu_fpu_R_fclex();
460 break;
461 case 3:
462 x86emu_fpu_R_finit();
463 break;
464 default:
465 x86emu_fpu_illegal();
466 break;
467 }
468 break;
469 default:
470 x86emu_fpu_illegal();
471 break;
472 }
473 break;
474 default:
475 switch (rh) {
476 case 0:
477 x86emu_fpu_M_fild(X86EMU_FPU_SHORT, destoffset);
478 break;
479 case 1:
480 x86emu_fpu_illegal();
481 break;
482 case 2:
483 x86emu_fpu_M_fist(X86EMU_FPU_SHORT, destoffset);
484 break;
485 case 3:
486 x86emu_fpu_M_fistp(X86EMU_FPU_SHORT, destoffset);
487 break;
488 case 4:
489 x86emu_fpu_illegal();
490 break;
491 case 5:
492 x86emu_fpu_M_fld(X86EMU_FPU_LDBL, destoffset);
493 break;
494 case 6:
495 x86emu_fpu_illegal();
496 break;
497 case 7:
498 x86emu_fpu_M_fstp(X86EMU_FPU_LDBL, destoffset);
499 break;
500 }
501 }
502 #endif
503 DECODE_CLEAR_SEGOVR();
504 END_OF_INSTR_NO_TRACE();
505 }
506
507 #ifdef DEBUG
508 char *x86emu_fpu_op_dc_tab[] = {
509 "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
510 "FCOMP\tQWORD PTR ",
511 "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
512 "FDIVR\tQWORD PTR ",
513
514 "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
515 "FCOMP\tQWORD PTR ",
516 "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
517 "FDIVR\tQWORD PTR ",
518
519 "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
520 "FCOMP\tQWORD PTR ",
521 "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
522 "FDIVR\tQWORD PTR ",
523
524 "FADD\t", "FMUL\t", "FCOM\t", "FCOMP\t",
525 "FSUBR\t", "FSUB\t", "FDIVR\t", "FDIV\t",
526 };
527 #endif /* DEBUG */
528
529 /* opcode=0xdc */
530 void x86emuOp_esc_coprocess_dc(u8 X86EMU_UNUSED(op1))
531 {
532 int mod, rl, rh;
533 uint destoffset;
534 u8 stkelem;
535
536 START_OF_INSTR();
537 FETCH_DECODE_MODRM(mod, rh, rl);
538 DECODE_PRINTINSTR32(x86emu_fpu_op_dc_tab, mod, rh, rl);
539 switch (mod) {
540 case 0:
541 destoffset = decode_rm00_address(rl);
542 DECODE_PRINTF("\n");
543 break;
544 case 1:
545 destoffset = decode_rm01_address(rl);
546 DECODE_PRINTF("\n");
547 break;
548 case 2:
549 destoffset = decode_rm10_address(rl);
550 DECODE_PRINTF("\n");
551 break;
552 case 3: /* register to register */
553 stkelem = (u8)rl;
554 DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
555 break;
556 }
557 #ifdef X86EMU_FPU_PRESENT
558 /* execute */
559 switch (mod) {
560 case 3:
561 switch (rh) {
562 case 0:
563 x86emu_fpu_R_fadd(stkelem, X86EMU_FPU_STKTOP);
564 break;
565 case 1:
566 x86emu_fpu_R_fmul(stkelem, X86EMU_FPU_STKTOP);
567 break;
568 case 2:
569 x86emu_fpu_R_fcom(stkelem, X86EMU_FPU_STKTOP);
570 break;
571 case 3:
572 x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
573 break;
574 case 4:
575 x86emu_fpu_R_fsubr(stkelem, X86EMU_FPU_STKTOP);
576 break;
577 case 5:
578 x86emu_fpu_R_fsub(stkelem, X86EMU_FPU_STKTOP);
579 break;
580 case 6:
581 x86emu_fpu_R_fdivr(stkelem, X86EMU_FPU_STKTOP);
582 break;
583 case 7:
584 x86emu_fpu_R_fdiv(stkelem, X86EMU_FPU_STKTOP);
585 break;
586 }
587 break;
588 default:
589 switch (rh) {
590 case 0:
591 x86emu_fpu_M_fadd(X86EMU_FPU_DOUBLE, destoffset);
592 break;
593 case 1:
594 x86emu_fpu_M_fmul(X86EMU_FPU_DOUBLE, destoffset);
595 break;
596 case 2:
597 x86emu_fpu_M_fcom(X86EMU_FPU_DOUBLE, destoffset);
598 break;
599 case 3:
600 x86emu_fpu_M_fcomp(X86EMU_FPU_DOUBLE, destoffset);
601 break;
602 case 4:
603 x86emu_fpu_M_fsub(X86EMU_FPU_DOUBLE, destoffset);
604 break;
605 case 5:
606 x86emu_fpu_M_fsubr(X86EMU_FPU_DOUBLE, destoffset);
607 break;
608 case 6:
609 x86emu_fpu_M_fdiv(X86EMU_FPU_DOUBLE, destoffset);
610 break;
611 case 7:
612 x86emu_fpu_M_fdivr(X86EMU_FPU_DOUBLE, destoffset);
613 break;
614 }
615 }
616 #endif
617 DECODE_CLEAR_SEGOVR();
618 END_OF_INSTR_NO_TRACE();
619 }
620
621 #ifdef DEBUG
622
623 static char *x86emu_fpu_op_dd_tab[] = {
624 "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
625 "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
626
627 "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
628 "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
629
630 "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
631 "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
632
633 "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
634 "ESC_DD\t2C,", "ESC_DD\t2D,", "ESC_DD\t2E,", "ESC_DD\t2F,",
635 };
636
637 #endif /* DEBUG */
638
639 /* opcode=0xdd */
640 void x86emuOp_esc_coprocess_dd(u8 X86EMU_UNUSED(op1))
641 {
642 int mod, rl, rh;
643 uint destoffset;
644 u8 stkelem;
645
646 START_OF_INSTR();
647 FETCH_DECODE_MODRM(mod, rh, rl);
648 DECODE_PRINTINSTR32(x86emu_fpu_op_dd_tab, mod, rh, rl);
649 switch (mod) {
650 case 0:
651 destoffset = decode_rm00_address(rl);
652 DECODE_PRINTF("\n");
653 break;
654 case 1:
655 destoffset = decode_rm01_address(rl);
656 DECODE_PRINTF("\n");
657 break;
658 case 2:
659 destoffset = decode_rm10_address(rl);
660 DECODE_PRINTF("\n");
661 break;
662 case 3: /* register to register */
663 stkelem = (u8)rl;
664 DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
665 break;
666 }
667 #ifdef X86EMU_FPU_PRESENT
668 switch (mod) {
669 case 3:
670 switch (rh) {
671 case 0:
672 x86emu_fpu_R_ffree(stkelem);
673 break;
674 case 1:
675 x86emu_fpu_R_fxch(stkelem);
676 break;
677 case 2:
678 x86emu_fpu_R_fst(stkelem); /* register version */
679 break;
680 case 3:
681 x86emu_fpu_R_fstp(stkelem); /* register version */
682 break;
683 default:
684 x86emu_fpu_illegal();
685 break;
686 }
687 break;
688 default:
689 switch (rh) {
690 case 0:
691 x86emu_fpu_M_fld(X86EMU_FPU_DOUBLE, destoffset);
692 break;
693 case 1:
694 x86emu_fpu_illegal();
695 break;
696 case 2:
697 x86emu_fpu_M_fst(X86EMU_FPU_DOUBLE, destoffset);
698 break;
699 case 3:
700 x86emu_fpu_M_fstp(X86EMU_FPU_DOUBLE, destoffset);
701 break;
702 case 4:
703 x86emu_fpu_M_frstor(X86EMU_FPU_WORD, destoffset);
704 break;
705 case 5:
706 x86emu_fpu_illegal();
707 break;
708 case 6:
709 x86emu_fpu_M_fsave(X86EMU_FPU_WORD, destoffset);
710 break;
711 case 7:
712 x86emu_fpu_M_fstsw(X86EMU_FPU_WORD, destoffset);
713 break;
714 }
715 }
716 #endif
717 DECODE_CLEAR_SEGOVR();
718 END_OF_INSTR_NO_TRACE();
719 }
720
721 #ifdef DEBUG
722
723 static char *x86emu_fpu_op_de_tab[] =
724 {
725 "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
726 "FICOMP\tWORD PTR ",
727 "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
728 "FIDIVR\tWORD PTR ",
729
730 "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
731 "FICOMP\tWORD PTR ",
732 "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
733 "FIDIVR\tWORD PTR ",
734
735 "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
736 "FICOMP\tWORD PTR ",
737 "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
738 "FIDIVR\tWORD PTR ",
739
740 "FADDP\t", "FMULP\t", "FCOMP\t", "FCOMPP\t",
741 "FSUBRP\t", "FSUBP\t", "FDIVRP\t", "FDIVP\t",
742 };
743
744 #endif /* DEBUG */
745
746 /* opcode=0xde */
747 void x86emuOp_esc_coprocess_de(u8 X86EMU_UNUSED(op1))
748 {
749 int mod, rl, rh;
750 uint destoffset;
751 u8 stkelem;
752
753 START_OF_INSTR();
754 FETCH_DECODE_MODRM(mod, rh, rl);
755 DECODE_PRINTINSTR32(x86emu_fpu_op_de_tab, mod, rh, rl);
756 switch (mod) {
757 case 0:
758 destoffset = decode_rm00_address(rl);
759 DECODE_PRINTF("\n");
760 break;
761 case 1:
762 destoffset = decode_rm01_address(rl);
763 DECODE_PRINTF("\n");
764 break;
765 case 2:
766 destoffset = decode_rm10_address(rl);
767 DECODE_PRINTF("\n");
768 break;
769 case 3: /* register to register */
770 stkelem = (u8)rl;
771 DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
772 break;
773 }
774 #ifdef X86EMU_FPU_PRESENT
775 switch (mod) {
776 case 3:
777 switch (rh) {
778 case 0:
779 x86emu_fpu_R_faddp(stkelem, X86EMU_FPU_STKTOP);
780 break;
781 case 1:
782 x86emu_fpu_R_fmulp(stkelem, X86EMU_FPU_STKTOP);
783 break;
784 case 2:
785 x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
786 break;
787 case 3:
788 if (stkelem == 1)
789 x86emu_fpu_R_fcompp(stkelem, X86EMU_FPU_STKTOP);
790 else
791 x86emu_fpu_illegal();
792 break;
793 case 4:
794 x86emu_fpu_R_fsubrp(stkelem, X86EMU_FPU_STKTOP);
795 break;
796 case 5:
797 x86emu_fpu_R_fsubp(stkelem, X86EMU_FPU_STKTOP);
798 break;
799 case 6:
800 x86emu_fpu_R_fdivrp(stkelem, X86EMU_FPU_STKTOP);
801 break;
802 case 7:
803 x86emu_fpu_R_fdivp(stkelem, X86EMU_FPU_STKTOP);
804 break;
805 }
806 break;
807 default:
808 switch (rh) {
809 case 0:
810 x86emu_fpu_M_fiadd(X86EMU_FPU_WORD, destoffset);
811 break;
812 case 1:
813 x86emu_fpu_M_fimul(X86EMU_FPU_WORD, destoffset);
814 break;
815 case 2:
816 x86emu_fpu_M_ficom(X86EMU_FPU_WORD, destoffset);
817 break;
818 case 3:
819 x86emu_fpu_M_ficomp(X86EMU_FPU_WORD, destoffset);
820 break;
821 case 4:
822 x86emu_fpu_M_fisub(X86EMU_FPU_WORD, destoffset);
823 break;
824 case 5:
825 x86emu_fpu_M_fisubr(X86EMU_FPU_WORD, destoffset);
826 break;
827 case 6:
828 x86emu_fpu_M_fidiv(X86EMU_FPU_WORD, destoffset);
829 break;
830 case 7:
831 x86emu_fpu_M_fidivr(X86EMU_FPU_WORD, destoffset);
832 break;
833 }
834 }
835 #endif
836 DECODE_CLEAR_SEGOVR();
837 END_OF_INSTR_NO_TRACE();
838 }
839
840 #ifdef DEBUG
841
842 static char *x86emu_fpu_op_df_tab[] = {
843 /* mod == 00 */
844 "FILD\tWORD PTR ", "ESC_DF\t39\n", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
845 "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
846 "FISTP\tQWORD PTR ",
847
848 /* mod == 01 */
849 "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
850 "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
851 "FISTP\tQWORD PTR ",
852
853 /* mod == 10 */
854 "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
855 "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
856 "FISTP\tQWORD PTR ",
857
858 /* mod == 11 */
859 "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
860 "ESC_DF\t3C,", "ESC_DF\t3D,", "ESC_DF\t3E,", "ESC_DF\t3F,"
861 };
862
863 #endif /* DEBUG */
864
865 /* opcode=0xdf */
866 void x86emuOp_esc_coprocess_df(u8 X86EMU_UNUSED(op1))
867 {
868 int mod, rl, rh;
869 uint destoffset;
870 u8 stkelem;
871
872 START_OF_INSTR();
873 FETCH_DECODE_MODRM(mod, rh, rl);
874 DECODE_PRINTINSTR32(x86emu_fpu_op_df_tab, mod, rh, rl);
875 switch (mod) {
876 case 0:
877 destoffset = decode_rm00_address(rl);
878 DECODE_PRINTF("\n");
879 break;
880 case 1:
881 destoffset = decode_rm01_address(rl);
882 DECODE_PRINTF("\n");
883 break;
884 case 2:
885 destoffset = decode_rm10_address(rl);
886 DECODE_PRINTF("\n");
887 break;
888 case 3: /* register to register */
889 stkelem = (u8)rl;
890 DECODE_PRINTF2("\tST(%d)\n", stkelem);
891 break;
892 }
893 #ifdef X86EMU_FPU_PRESENT
894 switch (mod) {
895 case 3:
896 switch (rh) {
897 case 0:
898 x86emu_fpu_R_ffree(stkelem);
899 break;
900 case 1:
901 x86emu_fpu_R_fxch(stkelem);
902 break;
903 case 2:
904 x86emu_fpu_R_fst(stkelem); /* register version */
905 break;
906 case 3:
907 x86emu_fpu_R_fstp(stkelem); /* register version */
908 break;
909 default:
910 x86emu_fpu_illegal();
911 break;
912 }
913 break;
914 default:
915 switch (rh) {
916 case 0:
917 x86emu_fpu_M_fild(X86EMU_FPU_WORD, destoffset);
918 break;
919 case 1:
920 x86emu_fpu_illegal();
921 break;
922 case 2:
923 x86emu_fpu_M_fist(X86EMU_FPU_WORD, destoffset);
924 break;
925 case 3:
926 x86emu_fpu_M_fistp(X86EMU_FPU_WORD, destoffset);
927 break;
928 case 4:
929 x86emu_fpu_M_fbld(X86EMU_FPU_BSD, destoffset);
930 break;
931 case 5:
932 x86emu_fpu_M_fild(X86EMU_FPU_LONG, destoffset);
933 break;
934 case 6:
935 x86emu_fpu_M_fbstp(X86EMU_FPU_BSD, destoffset);
936 break;
937 case 7:
938 x86emu_fpu_M_fistp(X86EMU_FPU_LONG, destoffset);
939 break;
940 }
941 }
942 #endif
943 DECODE_CLEAR_SEGOVR();
944 END_OF_INSTR_NO_TRACE();
945 }