1 // license:BSD-3-Clause
2 // copyright-holders:Philip Bennett
3 /***************************************************************************
8 - 80-bit precision for F2XM1, FYL2X, FPATAN
9 - Figure out why SoftFloat trig extensions produce bad values
10 - Cycle counts for all processors (currently using 486 counts)
11 - Precision-dependent cycle counts for divide instructions
12 - Last instruction, operand pointers etc.
13 - Fix FLDENV, FSTENV, FSAVE, FRSTOR and FPREM
14 - Status word C2 updates to reflect round up/down
15 - Handling of invalid and denormal numbers
16 - Remove redundant operand checks
19 Corrections and Additions [8-December-2017 Andrey Merkulov)
21 FINCSTP, FDECSTP - tags and exceptions corrected
22 FENI, FDISI opcodes added
24 ***************************************************************************/
29 /*************************************
33 *************************************/
35 #define X87_SW_IE 0x0001
36 #define X87_SW_DE 0x0002
37 #define X87_SW_ZE 0x0004
38 #define X87_SW_OE 0x0008
39 #define X87_SW_UE 0x0010
40 #define X87_SW_PE 0x0020
41 #define X87_SW_SF 0x0040
42 #define X87_SW_ES 0x0080
43 #define X87_SW_C0 0x0100
44 #define X87_SW_C1 0x0200
45 #define X87_SW_C2 0x0400
46 #define X87_SW_TOP_SHIFT 11
47 #define X87_SW_TOP_MASK 7
48 #define X87_SW_C3 0x4000
49 #define X87_SW_BUSY 0x8000
51 #define X87_CW_IM 0x0001
52 #define X87_CW_DM 0x0002
53 #define X87_CW_ZM 0x0004
54 #define X87_CW_OM 0x0008
55 #define X87_CW_UM 0x0010
56 #define X87_CW_PM 0x0020
57 #define X87_CW_IEM 0x0080
58 #define X87_CW_PC_SHIFT 8
59 #define X87_CW_PC_MASK 3
60 #define X87_CW_PC_SINGLE 0
61 #define X87_CW_PC_DOUBLE 2
62 #define X87_CW_PC_EXTEND 3
63 #define X87_CW_RC_SHIFT 10
64 #define X87_CW_RC_MASK 3
65 #define X87_CW_RC_NEAREST 0
66 #define X87_CW_RC_DOWN 1
67 #define X87_CW_RC_UP 2
68 #define X87_CW_RC_ZERO 3
71 #define X87_TW_VALID 0
73 #define X87_TW_SPECIAL 2
74 #define X87_TW_EMPTY 3
77 /*************************************
81 *************************************/
83 #define ST_TO_PHYS(x) (((cpustate->x87_sw >> X87_SW_TOP_SHIFT) + (x)) & X87_SW_TOP_MASK)
84 #define ST(x) (cpustate->x87_reg[ST_TO_PHYS(x)])
85 #define X87_TW_FIELD_SHIFT(x) ((x) << 1)
86 #define X87_TAG(x) ((cpustate->x87_tw >> X87_TW_FIELD_SHIFT(x)) & X87_TW_MASK)
87 #define X87_RC ((cpustate->x87_cw >> X87_CW_RC_SHIFT) & X87_CW_RC_MASK)
88 #define X87_IS_ST_EMPTY(x) (X87_TAG(ST_TO_PHYS(x)) == X87_TW_EMPTY)
89 #define X87_SW_C3_0 X87_SW_C0
91 #define UNIMPLEMENTED fatalerror("Unimplemented x87 op: %s (PC:%x)\n", __FUNCTION__, cpustate->pc)
94 /*************************************
98 *************************************/
100 static const floatx80 fx80_zero = { 0x0000, U64(0x0000000000000000) };
101 static const floatx80 fx80_one = { 0x3fff, U64(0x8000000000000000) };
103 static const floatx80 fx80_ninf = { 0xffff, U64(0x8000000000000000) };
104 static const floatx80 fx80_inan = { 0xffff, U64(0xc000000000000000) };
106 /* Maps x87 round modes to SoftFloat round modes */
107 static const int x87_to_sf_rc[4] =
109 float_round_nearest_even,
116 /*************************************
120 *************************************/
122 extern flag floatx80_is_nan( floatx80 a );
124 extern flag floatx80_is_signaling_nan(floatx80 a);
126 INLINE flag floatx80_is_quiet_nan(floatx80 a)
130 aLow = a.low & ~LIT64(0x4000000000000000);
132 ((a.high & 0x7FFF) == 0x7FFF)
133 && (bits64)(aLow << 1)
137 INLINE int floatx80_is_zero(floatx80 fx)
139 return (((fx.high & 0x7fff) == 0) && ((fx.low << 1) == 0));
142 INLINE int floatx80_is_inf(floatx80 fx)
144 return (((fx.high & 0x7fff) == 0x7fff) && ((fx.low << 1) == 0));
147 INLINE int floatx80_is_denormal(floatx80 fx)
149 return (((fx.high & 0x7fff) == 0) &&
150 ((fx.low & U64(0x8000000000000000)) == 0) &&
151 ((fx.low << 1) != 0));
154 INLINE floatx80 floatx80_abs(floatx80 fx)
160 INLINE double fx80_to_double(floatx80 fx)
162 UINT64 d = floatx80_to_float64(fx);
166 INLINE floatx80 double_to_fx80(double in)
168 return float64_to_floatx80(*(UINT64*)&in);
171 INLINE floatx80 READ80(i386_state *cpustate, UINT32 ea)
175 t.low = READ64(cpustate, ea);
176 t.high = READ16(cpustate, ea + 8);
181 INLINE void __FASTCALL WRITE80(i386_state *cpustate, UINT32 ea, floatx80 t)
183 WRITE64(cpustate, ea, t.low);
184 WRITE16(cpustate, ea + 8, t.high);
188 /*************************************
192 *************************************/
194 INLINE void __FASTCALL x87_set_stack_top(i386_state *cpustate, int top)
196 cpustate->x87_sw &= ~(X87_SW_TOP_MASK << X87_SW_TOP_SHIFT);
197 cpustate->x87_sw |= (top << X87_SW_TOP_SHIFT);
200 INLINE void __FASTCALL x87_set_tag(i386_state *cpustate, int reg, int tag)
202 int shift = X87_TW_FIELD_SHIFT(reg);
204 cpustate->x87_tw &= ~(X87_TW_MASK << shift);
205 cpustate->x87_tw |= (tag << shift);
208 void __FASTCALL x87_write_stack(i386_state *cpustate, int i, floatx80 value, int update_tag)
216 if (floatx80_is_zero(value))
220 else if (floatx80_is_inf(value) || floatx80_is_nan(value))
222 tag = X87_TW_SPECIAL;
229 x87_set_tag(cpustate, ST_TO_PHYS(i), tag);
233 INLINE void __FASTCALL x87_set_stack_underflow(i386_state *cpustate)
235 cpustate->x87_sw &= ~X87_SW_C1;
236 cpustate->x87_sw |= X87_SW_IE | X87_SW_SF;
239 INLINE void __FASTCALL x87_set_stack_overflow(i386_state *cpustate)
241 cpustate->x87_sw |= X87_SW_C1 | X87_SW_IE | X87_SW_SF;
244 int x87_inc_stack(i386_state *cpustate)
248 // Check for stack underflow
249 if (X87_IS_ST_EMPTY(0))
252 x87_set_stack_underflow(cpustate);
254 // Don't update the stack if the exception is unmasked
255 if (~cpustate->x87_cw & X87_CW_IM)
259 x87_set_tag(cpustate, ST_TO_PHYS(0), X87_TW_EMPTY);
260 x87_set_stack_top(cpustate, ST_TO_PHYS(1));
264 int x87_dec_stack(i386_state *cpustate)
268 // Check for stack overflow
269 if (!X87_IS_ST_EMPTY(7))
272 x87_set_stack_overflow(cpustate);
274 // Don't update the stack if the exception is unmasked
275 if (~cpustate->x87_cw & X87_CW_IM)
279 x87_set_stack_top(cpustate, ST_TO_PHYS(7));
284 /*************************************
288 *************************************/
290 int x87_check_exceptions(i386_state *cpustate)
292 /* Update the exceptions from SoftFloat */
293 if (float_exception_flags & float_flag_invalid)
295 cpustate->x87_sw |= X87_SW_IE;
296 float_exception_flags &= ~float_flag_invalid;
298 if (float_exception_flags & float_flag_overflow)
300 cpustate->x87_sw |= X87_SW_OE;
301 float_exception_flags &= ~float_flag_overflow;
303 if (float_exception_flags & float_flag_underflow)
305 cpustate->x87_sw |= X87_SW_UE;
306 float_exception_flags &= ~float_flag_underflow;
308 if (float_exception_flags & float_flag_inexact)
310 cpustate->x87_sw |= X87_SW_PE;
311 float_exception_flags &= ~float_flag_inexact;
314 if ((cpustate->x87_sw & ~cpustate->x87_cw) & 0x3f)
316 // cpustate->device->execute().set_input_line(INPUT_LINE_FERR, RAISE_LINE);
317 logerror("Unmasked x87 exception (CW:%.4x, SW:%.4x)\n", cpustate->x87_cw, cpustate->x87_sw);
319 if (!(cpustate->x87_cw & X87_CW_IEM)) { cpustate->x87_sw |= X87_SW_ES; /*ferr_handler(cpustate, 1);*/ }
321 if (cpustate->cr[0] & 0x20) // FIXME: 486 and up only
324 i386_trap(cpustate, FAULT_MF, 0, 0);
332 INLINE void __FASTCALL x87_write_cw(i386_state *cpustate, UINT16 cw)
334 cpustate->x87_cw = cw;
336 /* Update the SoftFloat rounding mode */
337 float_rounding_mode = x87_to_sf_rc[(cpustate->x87_cw >> X87_CW_RC_SHIFT) & X87_CW_RC_MASK];
340 void __FASTCALL x87_reset(i386_state *cpustate)
342 x87_write_cw(cpustate, 0x0037f);
344 cpustate->x87_sw = 0;
345 cpustate->x87_tw = 0xffff;
347 // TODO: FEA=0, FDS=0, FIP=0 FOP=0 FCS=0
348 cpustate->x87_data_ptr = 0;
349 cpustate->x87_inst_ptr = 0;
350 cpustate->x87_opcode = 0;
352 // ferr_handler(cpustate, 0);
356 /*************************************
360 *************************************/
362 static floatx80 x87_add(i386_state *cpustate, floatx80 a, floatx80 b)
364 floatx80 result = { 0 };
366 switch ((cpustate->x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
368 case X87_CW_PC_SINGLE:
370 float32 a32 = floatx80_to_float32(a);
371 float32 b32 = floatx80_to_float32(b);
372 result = float32_to_floatx80(float32_add(a32, b32));
375 case X87_CW_PC_DOUBLE:
377 float64 a64 = floatx80_to_float64(a);
378 float64 b64 = floatx80_to_float64(b);
379 result = float64_to_floatx80(float64_add(a64, b64));
382 case X87_CW_PC_EXTEND:
384 result = floatx80_add(a, b);
392 static floatx80 x87_sub(i386_state *cpustate, floatx80 a, floatx80 b)
394 floatx80 result = { 0 };
396 switch ((cpustate->x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
398 case X87_CW_PC_SINGLE:
400 float32 a32 = floatx80_to_float32(a);
401 float32 b32 = floatx80_to_float32(b);
402 result = float32_to_floatx80(float32_sub(a32, b32));
405 case X87_CW_PC_DOUBLE:
407 float64 a64 = floatx80_to_float64(a);
408 float64 b64 = floatx80_to_float64(b);
409 result = float64_to_floatx80(float64_sub(a64, b64));
412 case X87_CW_PC_EXTEND:
414 result = floatx80_sub(a, b);
422 static floatx80 x87_mul(i386_state *cpustate, floatx80 a, floatx80 b)
424 floatx80 val = { 0 };
426 switch ((cpustate->x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
428 case X87_CW_PC_SINGLE:
430 float32 a32 = floatx80_to_float32(a);
431 float32 b32 = floatx80_to_float32(b);
432 val = float32_to_floatx80(float32_mul(a32, b32));
435 case X87_CW_PC_DOUBLE:
437 float64 a64 = floatx80_to_float64(a);
438 float64 b64 = floatx80_to_float64(b);
439 val = float64_to_floatx80(float64_mul(a64, b64));
442 case X87_CW_PC_EXTEND:
444 val = floatx80_mul(a, b);
453 static floatx80 x87_div(i386_state *cpustate, floatx80 a, floatx80 b)
455 floatx80 val = { 0 };
457 switch ((cpustate->x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
459 case X87_CW_PC_SINGLE:
461 float32 a32 = floatx80_to_float32(a);
462 float32 b32 = floatx80_to_float32(b);
463 val = float32_to_floatx80(float32_div(a32, b32));
466 case X87_CW_PC_DOUBLE:
468 float64 a64 = floatx80_to_float64(a);
469 float64 b64 = floatx80_to_float64(b);
470 val = float64_to_floatx80(float64_div(a64, b64));
473 case X87_CW_PC_EXTEND:
475 val = floatx80_div(a, b);
483 /*************************************
487 *************************************/
489 /*************************************
493 *************************************/
495 void __FASTCALL x87_fadd_m32real(i386_state *cpustate, UINT8 modrm)
499 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
500 if (X87_IS_ST_EMPTY(0))
502 x87_set_stack_underflow(cpustate);
507 UINT32 m32real = READ32(cpustate, ea);
510 floatx80 b = float32_to_floatx80(m32real);
512 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
513 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
515 cpustate->x87_sw |= X87_SW_IE;
520 result = x87_add(cpustate, a, b);
524 if (x87_check_exceptions(cpustate))
525 x87_write_stack(cpustate, 0, result, TRUE);
530 void __FASTCALL x87_fadd_m64real(i386_state *cpustate, UINT8 modrm)
534 UINT32 ea = GetEA(cpustate, modrm, 0, 8);
535 if (X87_IS_ST_EMPTY(0))
537 x87_set_stack_underflow(cpustate);
542 UINT64 m64real = READ64(cpustate, ea);
545 floatx80 b = float64_to_floatx80(m64real);
547 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
548 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
550 cpustate->x87_sw |= X87_SW_IE;
555 result = x87_add(cpustate, a, b);
559 if (x87_check_exceptions(cpustate))
560 x87_write_stack(cpustate, 0, result, TRUE);
565 void __FASTCALL x87_fadd_st_sti(i386_state *cpustate, UINT8 modrm)
570 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
572 x87_set_stack_underflow(cpustate);
580 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
581 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
583 cpustate->x87_sw |= X87_SW_IE;
588 result = x87_add(cpustate, a, b);
592 if (x87_check_exceptions(cpustate))
593 x87_write_stack(cpustate, 0, result, TRUE);
598 void __FASTCALL x87_fadd_sti_st(i386_state *cpustate, UINT8 modrm)
603 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
605 x87_set_stack_underflow(cpustate);
613 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
614 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
616 cpustate->x87_sw |= X87_SW_IE;
621 result = x87_add(cpustate, a, b);
625 if (x87_check_exceptions(cpustate))
626 x87_write_stack(cpustate, i, result, TRUE);
631 void __FASTCALL x87_faddp(i386_state *cpustate, UINT8 modrm)
636 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
638 x87_set_stack_underflow(cpustate);
646 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
647 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
649 cpustate->x87_sw |= X87_SW_IE;
654 result = x87_add(cpustate, a, b);
658 if (x87_check_exceptions(cpustate))
660 x87_write_stack(cpustate, i, result, TRUE);
661 x87_inc_stack(cpustate);
667 void __FASTCALL x87_fiadd_m32int(i386_state *cpustate, UINT8 modrm)
671 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
672 if (X87_IS_ST_EMPTY(0))
674 x87_set_stack_underflow(cpustate);
679 INT32 m32int = READ32(cpustate, ea);
682 floatx80 b = int32_to_floatx80(m32int);
684 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
685 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
687 cpustate->x87_sw |= X87_SW_IE;
692 result = x87_add(cpustate, a, b);
696 if (x87_check_exceptions(cpustate))
697 x87_write_stack(cpustate, 0, result, TRUE);
699 CYCLES(cpustate, 19);
702 void __FASTCALL x87_fiadd_m16int(i386_state *cpustate, UINT8 modrm)
706 UINT32 ea = GetEA(cpustate, modrm, 0, 2);
707 if (X87_IS_ST_EMPTY(0))
709 x87_set_stack_underflow(cpustate);
714 INT16 m16int = READ16(cpustate, ea);
717 floatx80 b = int32_to_floatx80(m16int);
719 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
720 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
722 cpustate->x87_sw |= X87_SW_IE;
727 result = x87_add(cpustate, a, b);
731 if (x87_check_exceptions(cpustate))
732 x87_write_stack(cpustate, 0, result, TRUE);
734 CYCLES(cpustate, 20);
738 /*************************************
742 *************************************/
744 void __FASTCALL x87_fsub_m32real(i386_state *cpustate, UINT8 modrm)
748 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
749 if (X87_IS_ST_EMPTY(0))
751 x87_set_stack_underflow(cpustate);
756 UINT32 m32real = READ32(cpustate, ea);
759 floatx80 b = float32_to_floatx80(m32real);
761 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
762 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
764 cpustate->x87_sw |= X87_SW_IE;
769 result = x87_sub(cpustate, a, b);
773 if (x87_check_exceptions(cpustate))
774 x87_write_stack(cpustate, 0, result, TRUE);
779 void __FASTCALL x87_fsub_m64real(i386_state *cpustate, UINT8 modrm)
783 UINT32 ea = GetEA(cpustate, modrm, 0, 8);
784 if (X87_IS_ST_EMPTY(0))
786 x87_set_stack_underflow(cpustate);
791 UINT64 m64real = READ64(cpustate, ea);
794 floatx80 b = float64_to_floatx80(m64real);
796 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
797 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
799 cpustate->x87_sw |= X87_SW_IE;
804 result = x87_sub(cpustate, a, b);
808 if (x87_check_exceptions(cpustate))
809 x87_write_stack(cpustate, 0, result, TRUE);
814 void __FASTCALL x87_fsub_st_sti(i386_state *cpustate, UINT8 modrm)
819 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
821 x87_set_stack_underflow(cpustate);
829 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
830 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
832 cpustate->x87_sw |= X87_SW_IE;
837 result = x87_sub(cpustate, a, b);
841 if (x87_check_exceptions(cpustate))
842 x87_write_stack(cpustate, 0, result, TRUE);
847 void __FASTCALL x87_fsub_sti_st(i386_state *cpustate, UINT8 modrm)
852 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
854 x87_set_stack_underflow(cpustate);
862 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
863 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
865 cpustate->x87_sw |= X87_SW_IE;
870 result = x87_sub(cpustate, a, b);
874 if (x87_check_exceptions(cpustate))
875 x87_write_stack(cpustate, i, result, TRUE);
880 void __FASTCALL x87_fsubp(i386_state *cpustate, UINT8 modrm)
885 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
887 x87_set_stack_underflow(cpustate);
895 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
896 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
898 cpustate->x87_sw |= X87_SW_IE;
903 result = x87_sub(cpustate, a, b);
907 if (x87_check_exceptions(cpustate))
909 x87_write_stack(cpustate, i, result, TRUE);
910 x87_inc_stack(cpustate);
916 void __FASTCALL x87_fisub_m32int(i386_state *cpustate, UINT8 modrm)
920 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
921 if (X87_IS_ST_EMPTY(0))
923 x87_set_stack_underflow(cpustate);
928 INT32 m32int = READ32(cpustate, ea);
931 floatx80 b = int32_to_floatx80(m32int);
933 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
934 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
936 cpustate->x87_sw |= X87_SW_IE;
941 result = x87_sub(cpustate, a, b);
945 if (x87_check_exceptions(cpustate))
946 x87_write_stack(cpustate, 0, result, TRUE);
948 CYCLES(cpustate, 19);
951 void __FASTCALL x87_fisub_m16int(i386_state *cpustate, UINT8 modrm)
955 UINT32 ea = GetEA(cpustate, modrm, 0, 2);
956 if (X87_IS_ST_EMPTY(0))
958 x87_set_stack_underflow(cpustate);
963 INT16 m16int = READ16(cpustate, ea);
966 floatx80 b = int32_to_floatx80(m16int);
968 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
969 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
971 cpustate->x87_sw |= X87_SW_IE;
976 result = x87_sub(cpustate, a, b);
980 if (x87_check_exceptions(cpustate))
981 x87_write_stack(cpustate, 0, result, TRUE);
983 CYCLES(cpustate, 20);
987 /*************************************
991 *************************************/
993 void __FASTCALL x87_fsubr_m32real(i386_state *cpustate, UINT8 modrm)
997 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
998 if (X87_IS_ST_EMPTY(0))
1000 x87_set_stack_underflow(cpustate);
1005 UINT32 m32real = READ32(cpustate, ea);
1007 floatx80 a = float32_to_floatx80(m32real);
1010 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1011 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1013 cpustate->x87_sw |= X87_SW_IE;
1018 result = x87_sub(cpustate, a, b);
1022 if (x87_check_exceptions(cpustate))
1023 x87_write_stack(cpustate, 0, result, TRUE);
1025 CYCLES(cpustate, 8);
1028 void __FASTCALL x87_fsubr_m64real(i386_state *cpustate, UINT8 modrm)
1032 UINT32 ea = GetEA(cpustate, modrm, 0, 8);
1033 if (X87_IS_ST_EMPTY(0))
1035 x87_set_stack_underflow(cpustate);
1040 UINT64 m64real = READ64(cpustate, ea);
1042 floatx80 a = float64_to_floatx80(m64real);
1045 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1046 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1048 cpustate->x87_sw |= X87_SW_IE;
1053 result = x87_sub(cpustate, a, b);
1057 if (x87_check_exceptions(cpustate))
1058 x87_write_stack(cpustate, 0, result, TRUE);
1060 CYCLES(cpustate, 8);
1063 void __FASTCALL x87_fsubr_st_sti(i386_state *cpustate, UINT8 modrm)
1068 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1070 x87_set_stack_underflow(cpustate);
1078 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1079 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1081 cpustate->x87_sw |= X87_SW_IE;
1086 result = x87_sub(cpustate, a, b);
1090 if (x87_check_exceptions(cpustate))
1091 x87_write_stack(cpustate, 0, result, TRUE);
1093 CYCLES(cpustate, 8);
1096 void __FASTCALL x87_fsubr_sti_st(i386_state *cpustate, UINT8 modrm)
1101 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1103 x87_set_stack_underflow(cpustate);
1111 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1112 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1114 cpustate->x87_sw |= X87_SW_IE;
1119 result = x87_sub(cpustate, a, b);
1123 if (x87_check_exceptions(cpustate))
1124 x87_write_stack(cpustate, i, result, TRUE);
1126 CYCLES(cpustate, 8);
1129 void __FASTCALL x87_fsubrp(i386_state *cpustate, UINT8 modrm)
1134 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1136 x87_set_stack_underflow(cpustate);
1144 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1145 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1147 cpustate->x87_sw |= X87_SW_IE;
1152 result = x87_sub(cpustate, a, b);
1156 if (x87_check_exceptions(cpustate))
1158 x87_write_stack(cpustate, i, result, TRUE);
1159 x87_inc_stack(cpustate);
1162 CYCLES(cpustate, 8);
1165 void __FASTCALL x87_fisubr_m32int(i386_state *cpustate, UINT8 modrm)
1169 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
1170 if (X87_IS_ST_EMPTY(0))
1172 x87_set_stack_underflow(cpustate);
1177 INT32 m32int = READ32(cpustate, ea);
1179 floatx80 a = int32_to_floatx80(m32int);
1182 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1183 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1185 cpustate->x87_sw |= X87_SW_IE;
1190 result = x87_sub(cpustate, a, b);
1194 if (x87_check_exceptions(cpustate))
1195 x87_write_stack(cpustate, 0, result, TRUE);
1197 CYCLES(cpustate, 19);
1200 void __FASTCALL x87_fisubr_m16int(i386_state *cpustate, UINT8 modrm)
1204 UINT32 ea = GetEA(cpustate, modrm, 0, 2);
1205 if (X87_IS_ST_EMPTY(0))
1207 x87_set_stack_underflow(cpustate);
1212 INT16 m16int = READ16(cpustate, ea);
1214 floatx80 a = int32_to_floatx80(m16int);
1217 if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1218 || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000)))
1220 cpustate->x87_sw |= X87_SW_IE;
1225 result = x87_sub(cpustate, a, b);
1229 if (x87_check_exceptions(cpustate))
1230 x87_write_stack(cpustate, 0, result, TRUE);
1232 CYCLES(cpustate, 20);
1236 /*************************************
1240 *************************************/
1242 void __FASTCALL x87_fdiv_m32real(i386_state *cpustate, UINT8 modrm)
1246 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
1247 if (X87_IS_ST_EMPTY(0))
1249 x87_set_stack_underflow(cpustate);
1254 UINT32 m32real = READ32(cpustate, ea);
1257 floatx80 b = float32_to_floatx80(m32real);
1259 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1261 cpustate->x87_sw |= X87_SW_IE;
1266 result = x87_div(cpustate, a, b);
1270 if (x87_check_exceptions(cpustate))
1271 x87_write_stack(cpustate, 0, result, TRUE);
1274 CYCLES(cpustate, 73);
1277 void __FASTCALL x87_fdiv_m64real(i386_state *cpustate, UINT8 modrm)
1281 UINT32 ea = GetEA(cpustate, modrm, 0, 8);
1282 if (X87_IS_ST_EMPTY(0))
1284 x87_set_stack_underflow(cpustate);
1289 UINT64 m64real = READ64(cpustate, ea);
1292 floatx80 b = float64_to_floatx80(m64real);
1294 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1296 cpustate->x87_sw |= X87_SW_IE;
1301 result = x87_div(cpustate, a, b);
1305 if (x87_check_exceptions(cpustate))
1306 x87_write_stack(cpustate, 0, result, TRUE);
1309 CYCLES(cpustate, 73);
1312 void __FASTCALL x87_fdiv_st_sti(i386_state *cpustate, UINT8 modrm)
1317 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1319 x87_set_stack_underflow(cpustate);
1327 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1329 cpustate->x87_sw |= X87_SW_IE;
1334 result = x87_div(cpustate, a, b);
1338 if (x87_check_exceptions(cpustate))
1340 x87_write_stack(cpustate, 0, result, TRUE);
1344 CYCLES(cpustate, 73);
1347 void __FASTCALL x87_fdiv_sti_st(i386_state *cpustate, UINT8 modrm)
1352 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1354 x87_set_stack_underflow(cpustate);
1362 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1364 cpustate->x87_sw |= X87_SW_IE;
1369 result = x87_div(cpustate, a, b);
1373 if (x87_check_exceptions(cpustate))
1375 x87_write_stack(cpustate, i, result, TRUE);
1379 CYCLES(cpustate, 73);
1382 void __FASTCALL x87_fdivp(i386_state *cpustate, UINT8 modrm)
1387 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1389 x87_set_stack_underflow(cpustate);
1397 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1399 cpustate->x87_sw |= X87_SW_IE;
1404 result = x87_div(cpustate, a, b);
1408 if (x87_check_exceptions(cpustate))
1410 x87_write_stack(cpustate, i, result, TRUE);
1411 x87_inc_stack(cpustate);
1415 CYCLES(cpustate, 73);
1418 void __FASTCALL x87_fidiv_m32int(i386_state *cpustate, UINT8 modrm)
1422 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
1423 if (X87_IS_ST_EMPTY(0))
1425 x87_set_stack_underflow(cpustate);
1430 INT32 m32int = READ32(cpustate, ea);
1433 floatx80 b = int32_to_floatx80(m32int);
1435 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1437 cpustate->x87_sw |= X87_SW_IE;
1442 result = x87_div(cpustate, a, b);
1446 if (x87_check_exceptions(cpustate))
1447 x87_write_stack(cpustate, 0, result, TRUE);
1450 CYCLES(cpustate, 73);
1453 void __FASTCALL x87_fidiv_m16int(i386_state *cpustate, UINT8 modrm)
1457 UINT32 ea = GetEA(cpustate, modrm, 0, 2);
1458 if (X87_IS_ST_EMPTY(0))
1460 x87_set_stack_underflow(cpustate);
1465 INT16 m16int = READ16(cpustate, ea);
1468 floatx80 b = int32_to_floatx80(m16int);
1470 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1472 cpustate->x87_sw |= X87_SW_IE;
1477 result = x87_div(cpustate, a, b);
1481 if (x87_check_exceptions(cpustate))
1482 x87_write_stack(cpustate, 0, result, TRUE);
1485 CYCLES(cpustate, 73);
1489 /*************************************
1493 *************************************/
1495 void __FASTCALL x87_fdivr_m32real(i386_state *cpustate, UINT8 modrm)
1499 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
1500 if (X87_IS_ST_EMPTY(0))
1502 x87_set_stack_underflow(cpustate);
1507 UINT32 m32real = READ32(cpustate, ea);
1509 floatx80 a = float32_to_floatx80(m32real);
1512 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1514 cpustate->x87_sw |= X87_SW_IE;
1519 result = x87_div(cpustate, a, b);
1523 if (x87_check_exceptions(cpustate))
1524 x87_write_stack(cpustate, 0, result, TRUE);
1527 CYCLES(cpustate, 73);
1530 void __FASTCALL x87_fdivr_m64real(i386_state *cpustate, UINT8 modrm)
1534 UINT32 ea = GetEA(cpustate, modrm, 0, 8);
1535 if (X87_IS_ST_EMPTY(0))
1537 x87_set_stack_underflow(cpustate);
1542 UINT64 m64real = READ64(cpustate, ea);
1544 floatx80 a = float64_to_floatx80(m64real);
1547 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1549 cpustate->x87_sw |= X87_SW_IE;
1554 result = x87_div(cpustate, a, b);
1558 if (x87_check_exceptions(cpustate))
1559 x87_write_stack(cpustate, 0, result, TRUE);
1562 CYCLES(cpustate, 73);
1565 void __FASTCALL x87_fdivr_st_sti(i386_state *cpustate, UINT8 modrm)
1570 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1572 x87_set_stack_underflow(cpustate);
1580 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1582 cpustate->x87_sw |= X87_SW_IE;
1587 result = x87_div(cpustate, a, b);
1591 if (x87_check_exceptions(cpustate))
1593 x87_write_stack(cpustate, 0, result, TRUE);
1597 CYCLES(cpustate, 73);
1600 void __FASTCALL x87_fdivr_sti_st(i386_state *cpustate, UINT8 modrm)
1605 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1607 x87_set_stack_underflow(cpustate);
1615 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1617 cpustate->x87_sw |= X87_SW_IE;
1622 result = x87_div(cpustate, a, b);
1626 if (x87_check_exceptions(cpustate))
1628 x87_write_stack(cpustate, i, result, TRUE);
1632 CYCLES(cpustate, 73);
1635 void __FASTCALL x87_fdivrp(i386_state *cpustate, UINT8 modrm)
1640 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1642 x87_set_stack_underflow(cpustate);
1650 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1652 cpustate->x87_sw |= X87_SW_IE;
1657 result = x87_div(cpustate, a, b);
1661 if (x87_check_exceptions(cpustate))
1663 x87_write_stack(cpustate, i, result, TRUE);
1664 x87_inc_stack(cpustate);
1668 CYCLES(cpustate, 73);
1672 void __FASTCALL x87_fidivr_m32int(i386_state *cpustate, UINT8 modrm)
1676 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
1677 if (X87_IS_ST_EMPTY(0))
1679 x87_set_stack_underflow(cpustate);
1684 INT32 m32int = READ32(cpustate, ea);
1686 floatx80 a = int32_to_floatx80(m32int);
1689 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1691 cpustate->x87_sw |= X87_SW_IE;
1696 result = x87_div(cpustate, a, b);
1700 if (x87_check_exceptions(cpustate))
1701 x87_write_stack(cpustate, 0, result, TRUE);
1704 CYCLES(cpustate, 73);
1707 void __FASTCALL x87_fidivr_m16int(i386_state *cpustate, UINT8 modrm)
1711 UINT32 ea = GetEA(cpustate, modrm, 0, 2);
1712 if (X87_IS_ST_EMPTY(0))
1714 x87_set_stack_underflow(cpustate);
1719 INT16 m16int = READ16(cpustate, ea);
1721 floatx80 a = int32_to_floatx80(m16int);
1724 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1726 cpustate->x87_sw |= X87_SW_IE;
1731 result = x87_div(cpustate, a, b);
1735 if (x87_check_exceptions(cpustate))
1736 x87_write_stack(cpustate, 0, result, TRUE);
1739 CYCLES(cpustate, 73);
1743 /*************************************
1747 *************************************/
1749 void __FASTCALL x87_fmul_m32real(i386_state *cpustate, UINT8 modrm)
1753 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
1754 if (X87_IS_ST_EMPTY(0))
1756 x87_set_stack_underflow(cpustate);
1761 UINT32 m32real = READ32(cpustate, ea);
1764 floatx80 b = float32_to_floatx80(m32real);
1766 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1768 cpustate->x87_sw |= X87_SW_IE;
1773 result = x87_mul(cpustate, a, b);
1777 if (x87_check_exceptions(cpustate))
1778 x87_write_stack(cpustate, 0, result, TRUE);
1780 CYCLES(cpustate, 11);
1783 void __FASTCALL x87_fmul_m64real(i386_state *cpustate, UINT8 modrm)
1787 UINT32 ea = GetEA(cpustate, modrm, 0, 8);
1788 if (X87_IS_ST_EMPTY(0))
1790 x87_set_stack_underflow(cpustate);
1795 UINT64 m64real = READ64(cpustate, ea);
1798 floatx80 b = float64_to_floatx80(m64real);
1800 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1802 cpustate->x87_sw |= X87_SW_IE;
1807 result = x87_mul(cpustate, a, b);
1811 if (x87_check_exceptions(cpustate))
1812 x87_write_stack(cpustate, 0, result, TRUE);
1814 CYCLES(cpustate, 14);
1817 void __FASTCALL x87_fmul_st_sti(i386_state *cpustate, UINT8 modrm)
1822 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1824 x87_set_stack_underflow(cpustate);
1832 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1834 cpustate->x87_sw |= X87_SW_IE;
1839 result = x87_mul(cpustate, a, b);
1843 if (x87_check_exceptions(cpustate))
1844 x87_write_stack(cpustate, 0, result, TRUE);
1846 CYCLES(cpustate, 16);
1849 void __FASTCALL x87_fmul_sti_st(i386_state *cpustate, UINT8 modrm)
1854 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1856 x87_set_stack_underflow(cpustate);
1864 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1866 cpustate->x87_sw |= X87_SW_IE;
1871 result = x87_mul(cpustate, a, b);
1875 if (x87_check_exceptions(cpustate))
1876 x87_write_stack(cpustate, i, result, TRUE);
1878 CYCLES(cpustate, 16);
1881 void __FASTCALL x87_fmulp(i386_state *cpustate, UINT8 modrm)
1886 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1888 x87_set_stack_underflow(cpustate);
1896 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1898 cpustate->x87_sw |= X87_SW_IE;
1903 result = x87_mul(cpustate, a, b);
1907 if (x87_check_exceptions(cpustate))
1909 x87_write_stack(cpustate, i, result, TRUE);
1910 x87_inc_stack(cpustate);
1913 CYCLES(cpustate, 16);
1916 void __FASTCALL x87_fimul_m32int(i386_state *cpustate, UINT8 modrm)
1920 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
1921 if (X87_IS_ST_EMPTY(0))
1923 x87_set_stack_underflow(cpustate);
1928 INT32 m32int = READ32(cpustate, ea);
1931 floatx80 b = int32_to_floatx80(m32int);
1933 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1935 cpustate->x87_sw |= X87_SW_IE;
1940 result = x87_mul(cpustate, a, b);
1944 if (x87_check_exceptions(cpustate))
1945 x87_write_stack(cpustate, 0, result, TRUE);
1947 CYCLES(cpustate, 22);
1950 void __FASTCALL x87_fimul_m16int(i386_state *cpustate, UINT8 modrm)
1954 UINT32 ea = GetEA(cpustate, modrm, 0, 2);
1955 if (X87_IS_ST_EMPTY(0))
1957 x87_set_stack_underflow(cpustate);
1962 INT16 m16int = READ16(cpustate, ea);
1965 floatx80 b = int32_to_floatx80(m16int);
1967 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1969 cpustate->x87_sw |= X87_SW_IE;
1974 result = x87_mul(cpustate, a, b);
1978 if (x87_check_exceptions(cpustate))
1979 x87_write_stack(cpustate, 0, result, TRUE);
1981 CYCLES(cpustate, 22);
1985 /*************************************
1989 *************************************/
1991 void __FASTCALL x87_fcmovb_sti(i386_state *cpustate, UINT8 modrm)
1996 if (cpustate->CF == 1)
1998 if (X87_IS_ST_EMPTY(i))
2000 x87_set_stack_underflow(cpustate);
2006 if (x87_check_exceptions(cpustate))
2012 CYCLES(cpustate, 4);
2015 void __FASTCALL x87_fcmove_sti(i386_state *cpustate, UINT8 modrm)
2020 if (cpustate->ZF == 1)
2022 if (X87_IS_ST_EMPTY(i))
2024 x87_set_stack_underflow(cpustate);
2030 if (x87_check_exceptions(cpustate))
2036 CYCLES(cpustate, 4);
2039 void __FASTCALL x87_fcmovbe_sti(i386_state *cpustate, UINT8 modrm)
2044 if ((cpustate->CF | cpustate->ZF) == 1)
2046 if (X87_IS_ST_EMPTY(i))
2048 x87_set_stack_underflow(cpustate);
2054 if (x87_check_exceptions(cpustate))
2060 CYCLES(cpustate, 4);
2063 void __FASTCALL x87_fcmovu_sti(i386_state *cpustate, UINT8 modrm)
2068 if (cpustate->PF == 1)
2070 if (X87_IS_ST_EMPTY(i))
2072 x87_set_stack_underflow(cpustate);
2078 if (x87_check_exceptions(cpustate))
2084 CYCLES(cpustate, 4);
2087 void __FASTCALL x87_fcmovnb_sti(i386_state *cpustate, UINT8 modrm)
2092 if (cpustate->CF == 0)
2094 if (X87_IS_ST_EMPTY(i))
2096 x87_set_stack_underflow(cpustate);
2102 if (x87_check_exceptions(cpustate))
2108 CYCLES(cpustate, 4);
2111 void __FASTCALL x87_fcmovne_sti(i386_state *cpustate, UINT8 modrm)
2116 if (cpustate->ZF == 0)
2118 if (X87_IS_ST_EMPTY(i))
2120 x87_set_stack_underflow(cpustate);
2126 if (x87_check_exceptions(cpustate))
2132 CYCLES(cpustate, 4);
2135 void __FASTCALL x87_fcmovnbe_sti(i386_state *cpustate, UINT8 modrm)
2140 if ((cpustate->CF == 0) && (cpustate->ZF == 0))
2142 if (X87_IS_ST_EMPTY(i))
2144 x87_set_stack_underflow(cpustate);
2150 if (x87_check_exceptions(cpustate))
2156 CYCLES(cpustate, 4);
2159 void __FASTCALL x87_fcmovnu_sti(i386_state *cpustate, UINT8 modrm)
2164 if (cpustate->PF == 0)
2166 if (X87_IS_ST_EMPTY(i))
2168 x87_set_stack_underflow(cpustate);
2174 if (x87_check_exceptions(cpustate))
2180 CYCLES(cpustate, 4);
2183 /*************************************
2185 * Miscellaneous arithmetic
2187 *************************************/
2189 void __FASTCALL x87_fprem(i386_state *cpustate, UINT8 modrm)
2193 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
2195 x87_set_stack_underflow(cpustate);
2200 floatx80 a0 = ST(0); // dividend
2201 floatx80 b1 = ST(1); // divider
2203 floatx80 a0_abs = packFloatx80(0, (a0.high & 0x7FFF), a0.low);
2204 floatx80 b1_abs = packFloatx80(0, (b1.high & 0x7FFF), b1.low);
2205 cpustate->x87_sw &= ~X87_SW_C2;
2207 //int d=extractFloatx80Exp(a0)-extractFloatx80Exp(b1);
2208 int d = (a0.high & 0x7FFF) - (b1.high & 0x7FFF);
2210 floatx80 t=floatx80_div(a0_abs, b1_abs);
2211 int64 q = floatx80_to_int64_round_to_zero(t);
2212 floatx80 qf = int64_to_floatx80(q);
2213 floatx80 tt = floatx80_mul(b1_abs, qf);
2214 result = floatx80_sub(a0_abs, tt);
2215 result.high |= a0.high & 0x8000;
2217 cpustate->x87_sw &= ~(X87_SW_C0|X87_SW_C3|X87_SW_C1);
2219 cpustate->x87_sw |= X87_SW_C1;
2221 cpustate->x87_sw |= X87_SW_C3;
2223 cpustate->x87_sw |= X87_SW_C0;
2226 cpustate->x87_sw |= X87_SW_C2;
2228 int e = 1 << (d - n);
2229 floatx80 ef = int32_to_floatx80(e);
2230 floatx80 t=floatx80_div(a0, b1);
2231 floatx80 td = floatx80_div(t, ef);
2232 int64 qq = floatx80_to_int64_round_to_zero(td);
2233 floatx80 qqf = int64_to_floatx80(qq);
2234 floatx80 tt = floatx80_mul(b1, qqf);
2235 floatx80 ttt = floatx80_mul(tt, ef);
2236 result = floatx80_sub(a0, ttt);
2240 if (x87_check_exceptions(cpustate))
2241 x87_write_stack(cpustate, 0, result, TRUE);
2243 CYCLES(cpustate, 84);
2246 void __FASTCALL x87_fprem1(i386_state *cpustate, UINT8 modrm)
2250 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
2252 x87_set_stack_underflow(cpustate);
2260 cpustate->x87_sw &= ~X87_SW_C2;
2262 // TODO: Implement Cx bits
2263 result = floatx80_rem(a, b);
2266 if (x87_check_exceptions(cpustate))
2267 x87_write_stack(cpustate, 0, result, TRUE);
2269 CYCLES(cpustate, 94);
2272 void __FASTCALL x87_fsqrt(i386_state *cpustate, UINT8 modrm)
2276 if (X87_IS_ST_EMPTY(0))
2278 x87_set_stack_underflow(cpustate);
2283 floatx80 value = ST(0);
2285 if ((!floatx80_is_zero(value) && (value.high & 0x8000)) ||
2286 floatx80_is_denormal(value))
2288 cpustate->x87_sw |= X87_SW_IE;
2293 result = floatx80_sqrt(value);
2297 if (x87_check_exceptions(cpustate))
2298 x87_write_stack(cpustate, 0, result, TRUE);
2300 CYCLES(cpustate, 8);
2303 /*************************************
2307 *************************************/
2309 void __FASTCALL x87_f2xm1(i386_state *cpustate, UINT8 modrm)
2313 if (X87_IS_ST_EMPTY(0))
2315 x87_set_stack_underflow(cpustate);
2321 double x = fx80_to_double(ST(0));
2322 double res = pow(2.0, x) - 1;
2323 result = double_to_fx80(res);
2326 if (x87_check_exceptions(cpustate))
2328 x87_write_stack(cpustate, 0, result, TRUE);
2331 CYCLES(cpustate, 242);
2334 void __FASTCALL x87_fyl2x(i386_state *cpustate, UINT8 modrm)
2338 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
2340 x87_set_stack_underflow(cpustate);
2348 if (x.high & 0x8000)
2350 cpustate->x87_sw |= X87_SW_IE;
2356 double d64 = fx80_to_double(x);
2357 double l2x = log(d64)/log(2.0);
2358 result = floatx80_mul(double_to_fx80(l2x), y);
2362 if (x87_check_exceptions(cpustate))
2364 x87_write_stack(cpustate, 1, result, TRUE);
2365 x87_inc_stack(cpustate);
2368 CYCLES(cpustate, 250);
2371 void __FASTCALL x87_fyl2xp1(i386_state *cpustate, UINT8 modrm)
2375 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
2377 x87_set_stack_underflow(cpustate);
2386 double d64 = fx80_to_double(x);
2387 double l2x1 = log(d64 + 1.0)/log(2.0);
2388 result = floatx80_mul(double_to_fx80(l2x1), y);
2391 if (x87_check_exceptions(cpustate))
2393 x87_write_stack(cpustate, 1, result, TRUE);
2394 x87_inc_stack(cpustate);
2397 CYCLES(cpustate, 313);
2399 /* D9 F2 if 8087 0 < angle < pi/4 */
2400 void __FASTCALL x87_fptan(i386_state *cpustate, UINT8 modrm)
2402 floatx80 result1, result2;
2404 if (X87_IS_ST_EMPTY(0))
2406 x87_set_stack_underflow(cpustate);
2407 result1 = fx80_inan;
2408 result2 = fx80_inan;
2410 else if (!X87_IS_ST_EMPTY(7))
2412 x87_set_stack_overflow(cpustate);
2413 result1 = fx80_inan;
2414 result2 = fx80_inan;
2421 #if 1 // TODO: Function produces bad values
2422 if (floatx80_ftan(result1) != -1)
2423 cpustate->x87_sw &= ~X87_SW_C2;
2425 cpustate->x87_sw |= X87_SW_C2;
2427 double x = fx80_to_double(result1);
2429 result1 = double_to_fx80(x);
2431 cpustate->x87_sw &= ~X87_SW_C2;
2435 if (x87_check_exceptions(cpustate))
2437 x87_write_stack(cpustate, 0, result1, TRUE);
2438 x87_dec_stack(cpustate);
2439 x87_write_stack(cpustate, 0, result2, TRUE);
2442 CYCLES(cpustate, 244);
2445 void __FASTCALL x87_fpatan(i386_state *cpustate, UINT8 modrm)
2449 if (X87_IS_ST_EMPTY(0))
2451 x87_set_stack_underflow(cpustate);
2457 double val = atan2(fx80_to_double(ST(1)) , fx80_to_double(ST(0)));
2458 result = double_to_fx80(val);
2461 if (x87_check_exceptions(cpustate))
2463 x87_write_stack(cpustate, 1, result, TRUE);
2464 x87_inc_stack(cpustate);
2467 CYCLES(cpustate, 289);
2469 /* D9 FE 387 only */
2470 void __FASTCALL x87_fsin(i386_state *cpustate, UINT8 modrm)
2474 if (X87_IS_ST_EMPTY(0))
2476 x87_set_stack_underflow(cpustate);
2483 #if 1 // TODO: Function produces bad values Result checked
2484 if (floatx80_fsin(result) != -1)
2485 cpustate->x87_sw &= ~X87_SW_C2;
2487 cpustate->x87_sw |= X87_SW_C2;
2489 double x = fx80_to_double(result);
2491 result = double_to_fx80(x);
2493 cpustate->x87_sw &= ~X87_SW_C2;
2497 if (x87_check_exceptions(cpustate))
2498 x87_write_stack(cpustate, 0, result, TRUE);
2500 CYCLES(cpustate, 241);
2502 /* D9 FF 387 only */
2503 void __FASTCALL x87_fcos(i386_state *cpustate, UINT8 modrm)
2507 if (X87_IS_ST_EMPTY(0))
2509 x87_set_stack_underflow(cpustate);
2516 #if 1 // TODO: Function produces bad values to check!
2517 if (floatx80_fcos(result) != -1)
2518 cpustate->x87_sw &= ~X87_SW_C2;
2520 cpustate->x87_sw |= X87_SW_C2;
2522 double x = fx80_to_double(result);
2524 result = double_to_fx80(x);
2526 cpustate->x87_sw &= ~X87_SW_C2;
2530 if (x87_check_exceptions(cpustate))
2531 x87_write_stack(cpustate, 0, result, TRUE);
2533 CYCLES(cpustate, 241);
2535 /* D9 FB 387 only */
2536 void __FASTCALL x87_fsincos(i386_state *cpustate, UINT8 modrm)
2538 floatx80 s_result, c_result;
2540 if (X87_IS_ST_EMPTY(0))
2542 x87_set_stack_underflow(cpustate);
2543 s_result = c_result = fx80_inan;
2545 else if (!X87_IS_ST_EMPTY(7))
2547 x87_set_stack_overflow(cpustate);
2548 s_result = c_result = fx80_inan;
2552 extern int sf_fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a);
2554 s_result = c_result = ST(0);
2556 #if 0 // TODO: Function produces bad values
2557 if (sf_fsincos(s_result, &s_result, &c_result) != -1)
2558 cpustate->x87_sw &= ~X87_SW_C2;
2560 cpustate->x87_sw |= X87_SW_C2;
2562 double s = fx80_to_double(s_result);
2563 double c = fx80_to_double(c_result);
2567 s_result = double_to_fx80(s);
2568 c_result = double_to_fx80(c);
2570 cpustate->x87_sw &= ~X87_SW_C2;
2574 if (x87_check_exceptions(cpustate))
2576 x87_write_stack(cpustate, 0, s_result, TRUE);
2577 x87_dec_stack(cpustate);
2578 x87_write_stack(cpustate, 0, c_result, TRUE);
2581 CYCLES(cpustate, 291);
2585 /*************************************
2589 *************************************/
2591 void __FASTCALL x87_fld_m32real(i386_state *cpustate, UINT8 modrm)
2595 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
2596 if (x87_dec_stack(cpustate))
2598 UINT32 m32real = READ32(cpustate, ea);
2600 value = float32_to_floatx80(m32real);
2602 cpustate->x87_sw &= ~X87_SW_C1;
2604 if (floatx80_is_signaling_nan(value) || floatx80_is_denormal(value))
2606 cpustate->x87_sw |= X87_SW_IE;
2615 if (x87_check_exceptions(cpustate))
2616 x87_write_stack(cpustate, 0, value, TRUE);
2618 CYCLES(cpustate, 3);
2621 void __FASTCALL x87_fld_m64real(i386_state *cpustate, UINT8 modrm)
2625 UINT32 ea = GetEA(cpustate, modrm, 0, 8);
2626 if (x87_dec_stack(cpustate))
2628 UINT64 m64real = READ64(cpustate, ea);
2630 value = float64_to_floatx80(m64real);
2632 cpustate->x87_sw &= ~X87_SW_C1;
2634 if (floatx80_is_signaling_nan(value) || floatx80_is_denormal(value))
2636 cpustate->x87_sw |= X87_SW_IE;
2645 if (x87_check_exceptions(cpustate))
2646 x87_write_stack(cpustate, 0, value, TRUE);
2648 CYCLES(cpustate, 3);
2651 void __FASTCALL x87_fld_m80real(i386_state *cpustate, UINT8 modrm)
2655 UINT32 ea = GetEA(cpustate, modrm, 0, 10);
2656 if (x87_dec_stack(cpustate))
2658 cpustate->x87_sw &= ~X87_SW_C1;
2659 value = READ80(cpustate, ea);
2666 if (x87_check_exceptions(cpustate))
2667 x87_write_stack(cpustate, 0, value, TRUE);
2669 CYCLES(cpustate, 6);
2672 void __FASTCALL x87_fld_sti(i386_state *cpustate, UINT8 modrm)
2676 if (x87_dec_stack(cpustate))
2678 cpustate->x87_sw &= ~X87_SW_C1;
2679 value = ST((modrm + 1) & 7);
2686 if (x87_check_exceptions(cpustate))
2687 x87_write_stack(cpustate, 0, value, TRUE);
2689 CYCLES(cpustate, 4);
2692 void __FASTCALL x87_fild_m16int(i386_state *cpustate, UINT8 modrm)
2696 UINT32 ea = GetEA(cpustate, modrm, 0, 2);
2697 if (!x87_dec_stack(cpustate))
2703 cpustate->x87_sw &= ~X87_SW_C1;
2705 INT16 m16int = READ16(cpustate, ea);
2706 value = int32_to_floatx80(m16int);
2709 if (x87_check_exceptions(cpustate))
2710 x87_write_stack(cpustate, 0, value, TRUE);
2712 CYCLES(cpustate, 13);
2715 void __FASTCALL x87_fild_m32int(i386_state *cpustate, UINT8 modrm)
2719 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
2720 if (!x87_dec_stack(cpustate))
2726 cpustate->x87_sw &= ~X87_SW_C1;
2728 INT32 m32int = READ32(cpustate, ea);
2729 value = int32_to_floatx80(m32int);
2732 if (x87_check_exceptions(cpustate))
2733 x87_write_stack(cpustate, 0, value, TRUE);
2735 CYCLES(cpustate, 9);
2738 void __FASTCALL x87_fild_m64int(i386_state *cpustate, UINT8 modrm)
2742 UINT32 ea = GetEA(cpustate, modrm, 0, 8);
2743 if (!x87_dec_stack(cpustate))
2749 cpustate->x87_sw &= ~X87_SW_C1;
2751 INT64 m64int = READ64(cpustate, ea);
2752 value = int64_to_floatx80(m64int);
2755 if (x87_check_exceptions(cpustate))
2756 x87_write_stack(cpustate, 0, value, TRUE);
2758 CYCLES(cpustate, 10);
2761 void __FASTCALL x87_fbld(i386_state *cpustate, UINT8 modrm)
2765 UINT32 ea = GetEA(cpustate, modrm, 0, 10);
2766 if (!x87_dec_stack(cpustate))
2772 cpustate->x87_sw &= ~X87_SW_C1;
2777 value = READ80(cpustate, ea);
2779 sign = value.high & 0x8000;
2780 m64val += ((value.high >> 4) & 0xf) * 10;
2781 m64val += ((value.high >> 0) & 0xf);
2783 for (int i = 60; i >= 0; i -= 4)
2786 m64val += (value.low >> i) & 0xf;
2789 value = int64_to_floatx80(m64val);
2793 if (x87_check_exceptions(cpustate))
2794 x87_write_stack(cpustate, 0, value, TRUE);
2796 CYCLES(cpustate, 75);
2800 /*************************************
2804 *************************************/
2806 void __FASTCALL x87_fst_m32real(i386_state *cpustate, UINT8 modrm)
2810 UINT32 ea = GetEA(cpustate, modrm, 1, 4);
2811 if (X87_IS_ST_EMPTY(0))
2813 x87_set_stack_underflow(cpustate);
2818 cpustate->x87_sw &= ~X87_SW_C1;
2822 if (x87_check_exceptions(cpustate))
2824 UINT32 m32real = floatx80_to_float32(value);
2825 WRITE32(cpustate, ea, m32real);
2828 CYCLES(cpustate, 7);
2831 void __FASTCALL x87_fst_m64real(i386_state *cpustate, UINT8 modrm)
2835 UINT32 ea = GetEA(cpustate, modrm, 1, 8);
2836 if (X87_IS_ST_EMPTY(0))
2838 x87_set_stack_underflow(cpustate);
2843 cpustate->x87_sw &= ~X87_SW_C1;
2847 if (x87_check_exceptions(cpustate))
2849 UINT64 m64real = floatx80_to_float64(value);
2850 WRITE64(cpustate, ea, m64real);
2853 CYCLES(cpustate, 8);
2856 void __FASTCALL x87_fst_sti(i386_state *cpustate, UINT8 modrm)
2861 if (X87_IS_ST_EMPTY(0))
2863 x87_set_stack_underflow(cpustate);
2868 cpustate->x87_sw &= ~X87_SW_C1;
2872 if (x87_check_exceptions(cpustate))
2873 x87_write_stack(cpustate, i, value, TRUE);
2875 CYCLES(cpustate, 3);
2878 void __FASTCALL x87_fstp_m32real(i386_state *cpustate, UINT8 modrm)
2882 UINT32 ea = GetEA(cpustate, modrm, 1, 4);
2883 if (X87_IS_ST_EMPTY(0))
2885 x87_set_stack_underflow(cpustate);
2890 cpustate->x87_sw &= ~X87_SW_C1;
2894 if (x87_check_exceptions(cpustate))
2896 UINT32 m32real = floatx80_to_float32(value);
2897 WRITE32(cpustate, ea, m32real);
2898 x87_inc_stack(cpustate);
2901 CYCLES(cpustate, 7);
2904 void __FASTCALL x87_fstp_m64real(i386_state *cpustate, UINT8 modrm)
2908 if (X87_IS_ST_EMPTY(0))
2910 x87_set_stack_underflow(cpustate);
2915 cpustate->x87_sw &= ~X87_SW_C1;
2920 UINT32 ea = GetEA(cpustate, modrm, 1, 8);
2921 if (x87_check_exceptions(cpustate))
2923 UINT64 m64real = floatx80_to_float64(value);
2924 WRITE64(cpustate, ea, m64real);
2925 x87_inc_stack(cpustate);
2928 CYCLES(cpustate, 8);
2931 void __FASTCALL x87_fstp_m80real(i386_state *cpustate, UINT8 modrm)
2935 if (X87_IS_ST_EMPTY(0))
2937 x87_set_stack_underflow(cpustate);
2942 cpustate->x87_sw &= ~X87_SW_C1;
2946 UINT32 ea = GetEA(cpustate, modrm, 1, 10);
2947 if (x87_check_exceptions(cpustate))
2949 WRITE80(cpustate, ea, value);
2950 x87_inc_stack(cpustate);
2953 CYCLES(cpustate, 6);
2956 void __FASTCALL x87_fstp_sti(i386_state *cpustate, UINT8 modrm)
2961 if (X87_IS_ST_EMPTY(0))
2963 x87_set_stack_underflow(cpustate);
2968 cpustate->x87_sw &= ~X87_SW_C1;
2972 if (x87_check_exceptions(cpustate))
2974 x87_write_stack(cpustate, i, value, TRUE);
2975 x87_inc_stack(cpustate);
2978 CYCLES(cpustate, 3);
2981 void __FASTCALL x87_fist_m16int(i386_state *cpustate, UINT8 modrm)
2985 if (X87_IS_ST_EMPTY(0))
2987 x87_set_stack_underflow(cpustate);
2992 floatx80 fx80 = floatx80_round_to_int(ST(0));
2994 floatx80 lowerLim = int32_to_floatx80(-32768);
2995 floatx80 upperLim = int32_to_floatx80(32767);
2997 cpustate->x87_sw &= ~X87_SW_C1;
2999 if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
3000 m16int = floatx80_to_int32(fx80);
3005 UINT32 ea = GetEA(cpustate, modrm, 1, 2);
3006 if (x87_check_exceptions(cpustate))
3008 WRITE16(cpustate, ea, m16int);
3011 CYCLES(cpustate, 29);
3014 void __FASTCALL x87_fist_m32int(i386_state *cpustate, UINT8 modrm)
3018 if (X87_IS_ST_EMPTY(0))
3020 x87_set_stack_underflow(cpustate);
3021 m32int = 0x80000000;
3025 floatx80 fx80 = floatx80_round_to_int(ST(0));
3027 floatx80 lowerLim = int32_to_floatx80(0x80000000);
3028 floatx80 upperLim = int32_to_floatx80(0x7fffffff);
3030 cpustate->x87_sw &= ~X87_SW_C1;
3032 if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
3033 m32int = floatx80_to_int32(fx80);
3035 m32int = 0x80000000;
3038 UINT32 ea = GetEA(cpustate, modrm, 1, 4);
3039 if (x87_check_exceptions(cpustate))
3041 WRITE32(cpustate, ea, m32int);
3044 CYCLES(cpustate, 28);
3047 void __FASTCALL x87_fistp_m16int(i386_state *cpustate, UINT8 modrm)
3051 if (X87_IS_ST_EMPTY(0))
3053 x87_set_stack_underflow(cpustate);
3054 m16int = (UINT16)0x8000;
3058 floatx80 fx80 = floatx80_round_to_int(ST(0));
3060 floatx80 lowerLim = int32_to_floatx80(-32768);
3061 floatx80 upperLim = int32_to_floatx80(32767);
3063 cpustate->x87_sw &= ~X87_SW_C1;
3065 if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
3066 m16int = floatx80_to_int32(fx80);
3068 m16int = (UINT16)0x8000;
3071 UINT32 ea = GetEA(cpustate, modrm, 1, 2);
3072 if (x87_check_exceptions(cpustate))
3074 WRITE16(cpustate, ea, m16int);
3075 x87_inc_stack(cpustate);
3078 CYCLES(cpustate, 29);
3081 void __FASTCALL x87_fistp_m32int(i386_state *cpustate, UINT8 modrm)
3085 if (X87_IS_ST_EMPTY(0))
3087 x87_set_stack_underflow(cpustate);
3088 m32int = 0x80000000;
3092 floatx80 fx80 = floatx80_round_to_int(ST(0));
3094 floatx80 lowerLim = int32_to_floatx80(0x80000000);
3095 floatx80 upperLim = int32_to_floatx80(0x7fffffff);
3097 cpustate->x87_sw &= ~X87_SW_C1;
3099 if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
3100 m32int = floatx80_to_int32(fx80);
3102 m32int = 0x80000000;
3105 UINT32 ea = GetEA(cpustate, modrm, 1, 4);
3106 if (x87_check_exceptions(cpustate))
3108 WRITE32(cpustate, ea, m32int);
3109 x87_inc_stack(cpustate);
3112 CYCLES(cpustate, 29);
3115 void __FASTCALL x87_fistp_m64int(i386_state *cpustate, UINT8 modrm)
3119 if (X87_IS_ST_EMPTY(0))
3121 x87_set_stack_underflow(cpustate);
3122 m64int = U64(0x8000000000000000);
3126 floatx80 fx80 = floatx80_round_to_int(ST(0));
3128 floatx80 lowerLim = int64_to_floatx80(U64(0x8000000000000000));
3129 floatx80 upperLim = int64_to_floatx80(U64(0x7fffffffffffffff));
3131 cpustate->x87_sw &= ~X87_SW_C1;
3133 if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
3134 m64int = floatx80_to_int64(fx80);
3136 m64int = U64(0x8000000000000000);
3139 UINT32 ea = GetEA(cpustate, modrm, 1, 8);
3140 if (x87_check_exceptions(cpustate))
3142 WRITE64(cpustate, ea, m64int);
3143 x87_inc_stack(cpustate);
3146 CYCLES(cpustate, 29);
3149 void __FASTCALL x87_fbstp(i386_state *cpustate, UINT8 modrm)
3153 if (X87_IS_ST_EMPTY(0))
3155 x87_set_stack_underflow(cpustate);
3160 UINT64 u64 = floatx80_to_int64(floatx80_abs(ST(0)));
3163 for (int i = 0; i < 64; i += 4)
3165 result.low += (u64 % 10) << i;
3169 result.high = (u64 % 10);
3170 result.high += ((u64 / 10) % 10) << 4;
3171 result.high |= ST(0).high & 0x8000;
3174 UINT32 ea = GetEA(cpustate, modrm, 1, 10);
3175 if (x87_check_exceptions(cpustate))
3177 WRITE80(cpustate, ea, result);
3178 x87_inc_stack(cpustate);
3181 CYCLES(cpustate, 175);
3185 /*************************************
3189 *************************************/
3191 void __FASTCALL x87_fld1(i386_state *cpustate, UINT8 modrm)
3196 if (x87_dec_stack(cpustate))
3198 cpustate->x87_sw &= ~X87_SW_C1;
3205 tag = X87_TW_SPECIAL;
3208 if (x87_check_exceptions(cpustate))
3210 x87_set_tag(cpustate, ST_TO_PHYS(0), tag);
3211 x87_write_stack(cpustate, 0, value, FALSE);
3214 CYCLES(cpustate, 4);
3217 void __FASTCALL x87_fldl2t(i386_state *cpustate, UINT8 modrm)
3222 if (x87_dec_stack(cpustate))
3225 value.high = 0x4000;
3227 if (X87_RC == X87_CW_RC_UP)
3228 value.low = U64(0xd49a784bcd1b8aff);
3230 value.low = U64(0xd49a784bcd1b8afe);
3232 cpustate->x87_sw &= ~X87_SW_C1;
3237 tag = X87_TW_SPECIAL;
3240 if (x87_check_exceptions(cpustate))
3242 x87_set_tag(cpustate, ST_TO_PHYS(0), tag);
3243 x87_write_stack(cpustate, 0, value, FALSE);
3246 CYCLES(cpustate, 8);
3249 void __FASTCALL x87_fldl2e(i386_state *cpustate, UINT8 modrm)
3254 if (x87_dec_stack(cpustate))
3258 value.high = 0x3fff;
3260 if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
3261 value.low = U64(0xb8aa3b295c17f0bc);
3263 value.low = U64(0xb8aa3b295c17f0bb);
3265 cpustate->x87_sw &= ~X87_SW_C1;
3270 tag = X87_TW_SPECIAL;
3273 if (x87_check_exceptions(cpustate))
3275 x87_set_tag(cpustate, ST_TO_PHYS(0), tag);
3276 x87_write_stack(cpustate, 0, value, FALSE);
3279 CYCLES(cpustate, 8);
3282 void __FASTCALL x87_fldpi(i386_state *cpustate, UINT8 modrm)
3287 if (x87_dec_stack(cpustate))
3291 value.high = 0x4000;
3293 if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
3294 value.low = U64(0xc90fdaa22168c235);
3296 value.low = U64(0xc90fdaa22168c234);
3298 cpustate->x87_sw &= ~X87_SW_C1;
3303 tag = X87_TW_SPECIAL;
3306 if (x87_check_exceptions(cpustate))
3308 x87_set_tag(cpustate, ST_TO_PHYS(0), tag);
3309 x87_write_stack(cpustate, 0, value, FALSE);
3312 CYCLES(cpustate, 8);
3315 void __FASTCALL x87_fldlg2(i386_state *cpustate, UINT8 modrm)
3320 if (x87_dec_stack(cpustate))
3324 value.high = 0x3ffd;
3326 if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
3327 value.low = U64(0x9a209a84fbcff799);
3329 value.low = U64(0x9a209a84fbcff798);
3331 cpustate->x87_sw &= ~X87_SW_C1;
3336 tag = X87_TW_SPECIAL;
3339 if (x87_check_exceptions(cpustate))
3341 x87_set_tag(cpustate, ST_TO_PHYS(0), tag);
3342 x87_write_stack(cpustate, 0, value, FALSE);
3345 CYCLES(cpustate, 8);
3348 void __FASTCALL x87_fldln2(i386_state *cpustate, UINT8 modrm)
3353 if (x87_dec_stack(cpustate))
3357 value.high = 0x3ffe;
3359 if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
3360 value.low = U64(0xb17217f7d1cf79ac);
3362 value.low = U64(0xb17217f7d1cf79ab);
3364 cpustate->x87_sw &= ~X87_SW_C1;
3369 tag = X87_TW_SPECIAL;
3372 if (x87_check_exceptions(cpustate))
3374 x87_set_tag(cpustate, ST_TO_PHYS(0), tag);
3375 x87_write_stack(cpustate, 0, value, FALSE);
3378 CYCLES(cpustate, 8);
3381 void __FASTCALL x87_fldz(i386_state *cpustate, UINT8 modrm)
3386 if (x87_dec_stack(cpustate))
3390 cpustate->x87_sw &= ~X87_SW_C1;
3395 tag = X87_TW_SPECIAL;
3398 if (x87_check_exceptions(cpustate))
3400 x87_set_tag(cpustate, ST_TO_PHYS(0), tag);
3401 x87_write_stack(cpustate, 0, value, FALSE);
3404 CYCLES(cpustate, 4);
3408 /*************************************
3412 *************************************/
3414 void __FASTCALL x87_fnop(i386_state *cpustate, UINT8 modrm)
3416 CYCLES(cpustate, 3);
3419 void __FASTCALL x87_fchs(i386_state *cpustate, UINT8 modrm)
3423 if (X87_IS_ST_EMPTY(0))
3425 x87_set_stack_underflow(cpustate);
3430 cpustate->x87_sw &= ~X87_SW_C1;
3433 value.high ^= 0x8000;
3436 if (x87_check_exceptions(cpustate))
3437 x87_write_stack(cpustate, 0, value, FALSE);
3439 CYCLES(cpustate, 6);
3442 void __FASTCALL x87_fabs(i386_state *cpustate, UINT8 modrm)
3446 if (X87_IS_ST_EMPTY(0))
3448 x87_set_stack_underflow(cpustate);
3453 cpustate->x87_sw &= ~X87_SW_C1;
3456 value.high &= 0x7fff;
3459 if (x87_check_exceptions(cpustate))
3460 x87_write_stack(cpustate, 0, value, FALSE);
3462 CYCLES(cpustate, 6);
3465 void __FASTCALL x87_fscale(i386_state *cpustate, UINT8 modrm)
3469 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
3471 x87_set_stack_underflow(cpustate);
3476 cpustate->x87_sw &= ~X87_SW_C1;
3479 // Set the rounding mode to truncate
3480 UINT16 old_cw = cpustate->x87_cw;
3481 UINT16 new_cw = (old_cw & ~(X87_CW_RC_MASK << X87_CW_RC_SHIFT)) | (X87_CW_RC_ZERO << X87_CW_RC_SHIFT);
3482 x87_write_cw(cpustate, new_cw);
3484 // Interpret ST(1) as an integer
3485 UINT32 st1 = floatx80_to_int32(floatx80_round_to_int(ST(1)));
3487 // Restore the rounding mode
3488 x87_write_cw(cpustate, old_cw);
3490 // Get the unbiased exponent of ST(0)
3491 INT16 exp = (ST(0).high & 0x7fff) - 0x3fff;
3493 // Calculate the new exponent
3494 exp = (exp + st1 + 0x3fff) & 0x7fff;
3497 value.high = (value.high & ~0x7fff) + exp;
3500 if (x87_check_exceptions(cpustate))
3501 x87_write_stack(cpustate, 0, value, FALSE);
3503 CYCLES(cpustate, 31);
3506 void __FASTCALL x87_frndint(i386_state *cpustate, UINT8 modrm)
3510 if (X87_IS_ST_EMPTY(0))
3512 x87_set_stack_underflow(cpustate);
3517 cpustate->x87_sw &= ~X87_SW_C1;
3519 value = floatx80_round_to_int(ST(0));
3522 if (x87_check_exceptions(cpustate))
3523 x87_write_stack(cpustate, 0, value, TRUE);
3525 CYCLES(cpustate, 21);
3528 void __FASTCALL x87_fxtract(i386_state *cpustate, UINT8 modrm)
3530 floatx80 sig80, exp80;
3532 if (X87_IS_ST_EMPTY(0))
3534 x87_set_stack_underflow(cpustate);
3535 sig80 = exp80 = fx80_inan;
3537 else if (!X87_IS_ST_EMPTY(7))
3539 x87_set_stack_overflow(cpustate);
3540 sig80 = exp80 = fx80_inan;
3544 floatx80 value = ST(0);
3546 if (floatx80_eq(value, fx80_zero))
3548 cpustate->x87_sw |= X87_SW_ZE;
3555 // Extract the unbiased exponent
3556 exp80 = int32_to_floatx80((value.high & 0x7fff) - 0x3fff);
3558 // For the significand, replicate the original value and set its true exponent to 0.
3560 sig80.high &= ~0x7fff;
3561 sig80.high |= 0x3fff;
3565 if (x87_check_exceptions(cpustate))
3567 x87_write_stack(cpustate, 0, exp80, TRUE);
3568 x87_dec_stack(cpustate);
3569 x87_write_stack(cpustate, 0, sig80, TRUE);
3572 CYCLES(cpustate, 21);
3575 /*************************************
3579 *************************************/
3581 void __FASTCALL x87_ftst(i386_state *cpustate, UINT8 modrm)
3583 if (X87_IS_ST_EMPTY(0))
3585 x87_set_stack_underflow(cpustate);
3586 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3590 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3592 if (floatx80_is_nan(ST(0)))
3594 cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3595 cpustate->x87_sw |= X87_SW_IE;
3599 if (floatx80_eq(ST(0), fx80_zero))
3600 cpustate->x87_sw |= X87_SW_C3;
3602 if (floatx80_lt(ST(0), fx80_zero))
3603 cpustate->x87_sw |= X87_SW_C0;
3607 x87_check_exceptions(cpustate);
3609 CYCLES(cpustate, 4);
3612 void __FASTCALL x87_fxam(i386_state *cpustate, UINT8 modrm)
3614 floatx80 value = ST(0);
3616 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3618 // TODO: Unsupported and denormal values
3619 if (X87_IS_ST_EMPTY(0))
3621 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C0;
3623 else if (floatx80_is_zero(value))
3625 cpustate->x87_sw |= X87_SW_C3;
3627 else if (floatx80_is_nan(value))
3629 cpustate->x87_sw |= X87_SW_C0;
3631 else if (floatx80_is_inf(value))
3633 cpustate->x87_sw |= X87_SW_C2 | X87_SW_C0;
3637 cpustate->x87_sw |= X87_SW_C2;
3640 if (value.high & 0x8000)
3641 cpustate->x87_sw |= X87_SW_C1;
3643 CYCLES(cpustate, 8);
3646 void __FASTCALL x87_ficom_m16int(i386_state *cpustate, UINT8 modrm)
3648 UINT32 ea = GetEA(cpustate, modrm, 0, 2);
3649 if (X87_IS_ST_EMPTY(0))
3651 x87_set_stack_underflow(cpustate);
3652 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3656 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3658 INT16 m16int = READ16(cpustate, ea);
3661 floatx80 b = int32_to_floatx80(m16int);
3663 if (floatx80_is_nan(a))
3665 cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3666 cpustate->x87_sw |= X87_SW_IE;
3670 if (floatx80_eq(a, b))
3671 cpustate->x87_sw |= X87_SW_C3;
3673 if (floatx80_lt(a, b))
3674 cpustate->x87_sw |= X87_SW_C0;
3678 x87_check_exceptions(cpustate);
3680 CYCLES(cpustate, 16);
3683 void __FASTCALL x87_ficom_m32int(i386_state *cpustate, UINT8 modrm)
3685 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
3686 if (X87_IS_ST_EMPTY(0))
3688 x87_set_stack_underflow(cpustate);
3689 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3693 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3695 INT32 m32int = READ32(cpustate, ea);
3698 floatx80 b = int32_to_floatx80(m32int);
3700 if (floatx80_is_nan(a))
3702 cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3703 cpustate->x87_sw |= X87_SW_IE;
3707 if (floatx80_eq(a, b))
3708 cpustate->x87_sw |= X87_SW_C3;
3710 if (floatx80_lt(a, b))
3711 cpustate->x87_sw |= X87_SW_C0;
3715 x87_check_exceptions(cpustate);
3717 CYCLES(cpustate, 15);
3720 void __FASTCALL x87_ficomp_m16int(i386_state *cpustate, UINT8 modrm)
3722 UINT32 ea = GetEA(cpustate, modrm, 0, 2);
3723 if (X87_IS_ST_EMPTY(0))
3725 x87_set_stack_underflow(cpustate);
3726 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3730 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3732 INT16 m16int = READ16(cpustate, ea);
3735 floatx80 b = int32_to_floatx80(m16int);
3737 if (floatx80_is_nan(a))
3739 cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3740 cpustate->x87_sw |= X87_SW_IE;
3744 if (floatx80_eq(a, b))
3745 cpustate->x87_sw |= X87_SW_C3;
3747 if (floatx80_lt(a, b))
3748 cpustate->x87_sw |= X87_SW_C0;
3752 if (x87_check_exceptions(cpustate))
3753 x87_inc_stack(cpustate);
3755 CYCLES(cpustate, 16);
3758 void __FASTCALL x87_ficomp_m32int(i386_state *cpustate, UINT8 modrm)
3760 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
3761 if (X87_IS_ST_EMPTY(0))
3763 x87_set_stack_underflow(cpustate);
3764 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3768 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3770 INT32 m32int = READ32(cpustate, ea);
3773 floatx80 b = int32_to_floatx80(m32int);
3775 if (floatx80_is_nan(a))
3777 cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3778 cpustate->x87_sw |= X87_SW_IE;
3782 if (floatx80_eq(a, b))
3783 cpustate->x87_sw |= X87_SW_C3;
3785 if (floatx80_lt(a, b))
3786 cpustate->x87_sw |= X87_SW_C0;
3790 if (x87_check_exceptions(cpustate))
3791 x87_inc_stack(cpustate);
3793 CYCLES(cpustate, 15);
3797 void __FASTCALL x87_fcom_m32real(i386_state *cpustate, UINT8 modrm)
3799 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
3800 if (X87_IS_ST_EMPTY(0))
3802 x87_set_stack_underflow(cpustate);
3803 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3807 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3809 UINT32 m32real = READ32(cpustate, ea);
3812 floatx80 b = float32_to_floatx80(m32real);
3814 if (floatx80_is_nan(a) || floatx80_is_nan(b))
3816 cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3817 cpustate->x87_sw |= X87_SW_IE;
3821 if (floatx80_eq(a, b))
3822 cpustate->x87_sw |= X87_SW_C3;
3824 if (floatx80_lt(a, b))
3825 cpustate->x87_sw |= X87_SW_C0;
3829 x87_check_exceptions(cpustate);
3831 CYCLES(cpustate, 4);
3834 void __FASTCALL x87_fcom_m64real(i386_state *cpustate, UINT8 modrm)
3836 UINT32 ea = GetEA(cpustate, modrm, 0, 8);
3837 if (X87_IS_ST_EMPTY(0))
3839 x87_set_stack_underflow(cpustate);
3840 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3844 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3846 UINT64 m64real = READ64(cpustate, ea);
3849 floatx80 b = float64_to_floatx80(m64real);
3851 if (floatx80_is_nan(a) || floatx80_is_nan(b))
3853 cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3854 cpustate->x87_sw |= X87_SW_IE;
3858 if (floatx80_eq(a, b))
3859 cpustate->x87_sw |= X87_SW_C3;
3861 if (floatx80_lt(a, b))
3862 cpustate->x87_sw |= X87_SW_C0;
3866 x87_check_exceptions(cpustate);
3868 CYCLES(cpustate, 4);
3871 void __FASTCALL x87_fcom_sti(i386_state *cpustate, UINT8 modrm)
3875 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
3877 x87_set_stack_underflow(cpustate);
3878 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3882 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3887 if (floatx80_is_nan(a) || floatx80_is_nan(b))
3889 cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3890 cpustate->x87_sw |= X87_SW_IE;
3894 if (floatx80_eq(a, b))
3895 cpustate->x87_sw |= X87_SW_C3;
3897 if (floatx80_lt(a, b))
3898 cpustate->x87_sw |= X87_SW_C0;
3902 x87_check_exceptions(cpustate);
3904 CYCLES(cpustate, 4);
3907 void __FASTCALL x87_fcomp_m32real(i386_state *cpustate, UINT8 modrm)
3909 UINT32 ea = GetEA(cpustate, modrm, 0, 4);
3910 if (X87_IS_ST_EMPTY(0))
3912 x87_set_stack_underflow(cpustate);
3913 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3917 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3919 UINT32 m32real = READ32(cpustate, ea);
3922 floatx80 b = float32_to_floatx80(m32real);
3924 if (floatx80_is_nan(a) || floatx80_is_nan(b))
3926 cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3927 cpustate->x87_sw |= X87_SW_IE;
3931 if (floatx80_eq(a, b))
3932 cpustate->x87_sw |= X87_SW_C3;
3934 if (floatx80_lt(a, b))
3935 cpustate->x87_sw |= X87_SW_C0;
3939 if (x87_check_exceptions(cpustate))
3940 x87_inc_stack(cpustate);
3942 CYCLES(cpustate, 4);
3945 void __FASTCALL x87_fcomp_m64real(i386_state *cpustate, UINT8 modrm)
3947 UINT32 ea = GetEA(cpustate, modrm, 0, 8);
3948 if (X87_IS_ST_EMPTY(0))
3950 x87_set_stack_underflow(cpustate);
3951 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3955 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3957 UINT64 m64real = READ64(cpustate, ea);
3960 floatx80 b = float64_to_floatx80(m64real);
3962 if (floatx80_is_nan(a) || floatx80_is_nan(b))
3964 cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3965 cpustate->x87_sw |= X87_SW_IE;
3969 if (floatx80_eq(a, b))
3970 cpustate->x87_sw |= X87_SW_C3;
3972 if (floatx80_lt(a, b))
3973 cpustate->x87_sw |= X87_SW_C0;
3977 if (x87_check_exceptions(cpustate))
3978 x87_inc_stack(cpustate);
3980 CYCLES(cpustate, 4);
3983 void __FASTCALL x87_fcomp_sti(i386_state *cpustate, UINT8 modrm)
3987 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
3989 x87_set_stack_underflow(cpustate);
3990 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3994 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3999 if (floatx80_is_nan(a) || floatx80_is_nan(b))
4001 cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
4002 cpustate->x87_sw |= X87_SW_IE;
4006 if (floatx80_eq(a, b))
4007 cpustate->x87_sw |= X87_SW_C3;
4009 if (floatx80_lt(a, b))
4010 cpustate->x87_sw |= X87_SW_C0;
4014 if (x87_check_exceptions(cpustate))
4015 x87_inc_stack(cpustate);
4017 CYCLES(cpustate, 4);
4020 void __FASTCALL x87_fcomi_sti(i386_state *cpustate, UINT8 modrm)
4024 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
4026 x87_set_stack_underflow(cpustate);
4033 cpustate->x87_sw &= ~X87_SW_C1;
4038 if (floatx80_is_nan(a) || floatx80_is_nan(b))
4043 cpustate->x87_sw |= X87_SW_IE;
4051 if (floatx80_eq(a, b))
4054 if (floatx80_lt(a, b))
4059 x87_check_exceptions(cpustate);
4061 CYCLES(cpustate, 4); // TODO: correct cycle count
4064 void __FASTCALL x87_fcomip_sti(i386_state *cpustate, UINT8 modrm)
4068 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
4070 x87_set_stack_underflow(cpustate);
4077 cpustate->x87_sw &= ~X87_SW_C1;
4082 if (floatx80_is_nan(a) || floatx80_is_nan(b))
4087 cpustate->x87_sw |= X87_SW_IE;
4095 if (floatx80_eq(a, b))
4098 if (floatx80_lt(a, b))
4103 if (x87_check_exceptions(cpustate))
4104 x87_inc_stack(cpustate);
4106 CYCLES(cpustate, 4); // TODO: correct cycle count
4109 void __FASTCALL x87_fucomi_sti(i386_state *cpustate, UINT8 modrm)
4113 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
4115 x87_set_stack_underflow(cpustate);
4122 cpustate->x87_sw &= ~X87_SW_C1;
4127 if (floatx80_is_quiet_nan(a) || floatx80_is_quiet_nan(b))
4133 else if (floatx80_is_nan(a) || floatx80_is_nan(b))
4138 cpustate->x87_sw |= X87_SW_IE;
4146 if (floatx80_eq(a, b))
4149 if (floatx80_lt(a, b))
4154 x87_check_exceptions(cpustate);
4156 CYCLES(cpustate, 4); // TODO: correct cycle count
4159 void __FASTCALL x87_fucomip_sti(i386_state *cpustate, UINT8 modrm)
4163 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
4165 x87_set_stack_underflow(cpustate);
4172 cpustate->x87_sw &= ~X87_SW_C1;
4177 if (floatx80_is_quiet_nan(a) || floatx80_is_quiet_nan(b))
4183 else if (floatx80_is_nan(a) || floatx80_is_nan(b))
4188 cpustate->x87_sw |= X87_SW_IE;
4196 if (floatx80_eq(a, b))
4199 if (floatx80_lt(a, b))
4204 if (x87_check_exceptions(cpustate))
4205 x87_inc_stack(cpustate);
4207 CYCLES(cpustate, 4); // TODO: correct cycle count
4210 void __FASTCALL x87_fcompp(i386_state *cpustate, UINT8 modrm)
4212 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
4214 x87_set_stack_underflow(cpustate);
4215 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
4219 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
4224 if (floatx80_is_nan(a) || floatx80_is_nan(b))
4226 cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
4227 cpustate->x87_sw |= X87_SW_IE;
4231 if (floatx80_eq(a, b))
4232 cpustate->x87_sw |= X87_SW_C3;
4234 if (floatx80_lt(a, b))
4235 cpustate->x87_sw |= X87_SW_C0;
4239 if (x87_check_exceptions(cpustate))
4241 x87_inc_stack(cpustate);
4242 x87_inc_stack(cpustate);
4245 CYCLES(cpustate, 5);
4249 /*************************************
4251 * Unordererd comparison
4253 *************************************/
4255 void __FASTCALL x87_fucom_sti(i386_state *cpustate, UINT8 modrm)
4259 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
4261 x87_set_stack_underflow(cpustate);
4262 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
4266 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
4271 if (floatx80_is_nan(a) || floatx80_is_nan(b))
4273 cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
4275 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
4276 cpustate->x87_sw |= X87_SW_IE;
4280 if (floatx80_eq(a, b))
4281 cpustate->x87_sw |= X87_SW_C3;
4283 if (floatx80_lt(a, b))
4284 cpustate->x87_sw |= X87_SW_C0;
4288 x87_check_exceptions(cpustate);
4290 CYCLES(cpustate, 4);
4293 void __FASTCALL x87_fucomp_sti(i386_state *cpustate, UINT8 modrm)
4297 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
4299 x87_set_stack_underflow(cpustate);
4300 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
4304 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
4309 if (floatx80_is_nan(a) || floatx80_is_nan(b))
4311 cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
4313 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
4314 cpustate->x87_sw |= X87_SW_IE;
4318 if (floatx80_eq(a, b))
4319 cpustate->x87_sw |= X87_SW_C3;
4321 if (floatx80_lt(a, b))
4322 cpustate->x87_sw |= X87_SW_C0;
4326 if (x87_check_exceptions(cpustate))
4327 x87_inc_stack(cpustate);
4329 CYCLES(cpustate, 4);
4332 void __FASTCALL x87_fucompp(i386_state *cpustate, UINT8 modrm)
4334 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
4336 x87_set_stack_underflow(cpustate);
4337 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
4341 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
4346 if (floatx80_is_nan(a) || floatx80_is_nan(b))
4348 cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
4350 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
4351 cpustate->x87_sw |= X87_SW_IE;
4355 if (floatx80_eq(a, b))
4356 cpustate->x87_sw |= X87_SW_C3;
4358 if (floatx80_lt(a, b))
4359 cpustate->x87_sw |= X87_SW_C0;
4363 if (x87_check_exceptions(cpustate))
4365 x87_inc_stack(cpustate);
4366 x87_inc_stack(cpustate);
4369 CYCLES(cpustate, 4);
4373 /*************************************
4377 *************************************/
4379 void __FASTCALL x87_fdecstp(i386_state *cpustate, UINT8 modrm)
4381 cpustate->x87_sw &= ~X87_SW_C1;
4383 x87_set_stack_top(cpustate, ST_TO_PHYS(7));
4385 CYCLES(cpustate, 3);
4388 void __FASTCALL x87_fincstp(i386_state *cpustate, UINT8 modrm)
4390 cpustate->x87_sw &= ~X87_SW_C1;
4392 x87_set_stack_top(cpustate, ST_TO_PHYS(1));
4394 CYCLES(cpustate, 3);
4397 void __FASTCALL x87_fclex(i386_state *cpustate, UINT8 modrm)
4399 cpustate->x87_sw &= ~0x80ff;
4400 // ferr_handler(cpustate, 0);
4401 CYCLES(cpustate, 7);
4404 void __FASTCALL x87_feni(i386_state *cpustate, UINT8 modrm)
4406 cpustate->x87_cw &= ~X87_CW_IEM;
4407 x87_check_exceptions(cpustate);
4409 CYCLES(cpustate, 5);
4412 void __FASTCALL x87_fdisi(i386_state *cpustate, UINT8 modrm)
4414 cpustate->x87_cw |= X87_CW_IEM;
4416 CYCLES(cpustate, 5);
4419 void __FASTCALL x87_ffree(i386_state *cpustate, UINT8 modrm)
4421 x87_set_tag(cpustate, ST_TO_PHYS(modrm & 7), X87_TW_EMPTY);
4423 CYCLES(cpustate, 3);
4426 void __FASTCALL x87_finit(i386_state *cpustate, UINT8 modrm)
4428 x87_reset(cpustate);
4430 CYCLES(cpustate, 17);
4433 void __FASTCALL x87_fldcw(i386_state *cpustate, UINT8 modrm)
4435 UINT32 ea = GetEA(cpustate, modrm, 0, 2);
4436 UINT16 cw = READ16(cpustate, ea);
4438 x87_write_cw(cpustate, cw);
4440 x87_check_exceptions(cpustate);
4442 CYCLES(cpustate, 4);
4445 void __FASTCALL x87_fstcw(i386_state *cpustate, UINT8 modrm)
4447 UINT32 ea = GetEA(cpustate, modrm, 1, 2);
4448 WRITE16(cpustate, ea, cpustate->x87_cw);
4450 CYCLES(cpustate, 3);
4453 void __FASTCALL x87_fldenv(i386_state *cpustate, UINT8 modrm)
4455 // TODO: Pointers and selectors
4456 if (cpustate->operand_size)
4458 // 32-bit real/protected mode
4459 UINT32 ea = GetEA(cpustate, modrm, 0, 10);
4460 x87_write_cw(cpustate, READ16(cpustate, ea));
4461 cpustate->x87_sw = READ16(cpustate, ea + 4);
4462 cpustate->x87_tw = READ16(cpustate, ea + 8);
4466 // 16-bit real/protected mode
4467 UINT32 ea = GetEA(cpustate, modrm, 0, 6);
4468 x87_write_cw(cpustate, READ16(cpustate, ea));
4469 cpustate->x87_sw = READ16(cpustate, ea + 2);
4470 cpustate->x87_tw = READ16(cpustate, ea + 4);
4473 x87_check_exceptions(cpustate);
4475 CYCLES(cpustate,(cpustate->cr[0] & 1) ? 34 : 44);
4478 void __FASTCALL x87_fstenv(i386_state *cpustate, UINT8 modrm)
4482 // TODO: Pointers and selectors
4483 switch((cpustate->cr[0] & 1)|(cpustate->operand_size & 1)<<1)
4485 case 0: // 16-bit real mode
4486 ea = GetEA(cpustate, modrm, 1, 6);
4487 WRITE16(cpustate, ea + 0, cpustate->x87_cw);
4488 WRITE16(cpustate, ea + 2, cpustate->x87_sw);
4489 WRITE16(cpustate, ea + 4, cpustate->x87_tw);
4490 // WRITE16(cpustate, ea + 6, cpustate->fpu_inst_ptr & 0xffff);
4491 // WRITE16(cpustate, ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
4492 // WRITE16(cpustate, ea + 10, cpustate->fpu_data_ptr & 0xffff);
4493 // WRITE16(cpustate, ea + 12, (cpustate->fpu_inst_ptr & 0x0f0000) >> 4);
4495 case 1: // 16-bit protected mode
4496 ea = GetEA(cpustate, modrm, 1, 6);
4497 WRITE16(cpustate, ea + 0, cpustate->x87_cw);
4498 WRITE16(cpustate,ea + 2, cpustate->x87_sw);
4499 WRITE16(cpustate,ea + 4, cpustate->x87_tw);
4500 // WRITE16(cpustate,ea + 6, cpustate->fpu_inst_ptr & 0xffff);
4501 // WRITE16(cpustate,ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
4502 // WRITE16(cpustate,ea + 10, cpustate->fpu_data_ptr & 0xffff);
4503 // WRITE16(cpustate,ea + 12, (cpustate->fpu_inst_ptr & 0x0f0000) >> 4);
4505 case 2: // 32-bit real mode
4506 ea = GetEA(cpustate, modrm, 1, 10);
4507 WRITE16(cpustate, ea + 0, cpustate->x87_cw);
4508 WRITE16(cpustate, ea + 4, cpustate->x87_sw);
4509 WRITE16(cpustate, ea + 8, cpustate->x87_tw);
4510 // WRITE16(cpustate, ea + 12, cpustate->fpu_inst_ptr & 0xffff);
4511 // WRITE16(cpustate, ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
4512 // WRITE16(cpustate, ea + 20, cpustate->fpu_data_ptr & 0xffff);
4513 // WRITE16(cpustate, ea + 12, ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
4514 // WRITE32(cpustate, ea + 24, (cpustate->fpu_data_ptr >> 16) << 12);
4516 case 3: // 32-bit protected mode
4517 ea = GetEA(cpustate, modrm, 1, 10);
4518 WRITE16(cpustate, ea + 0, cpustate->x87_cw);
4519 WRITE16(cpustate, ea + 4, cpustate->x87_sw);
4520 WRITE16(cpustate, ea + 8, cpustate->x87_tw);
4521 // WRITE32(cpustate, ea + 12, cpustate->fpu_inst_ptr);
4522 // WRITE32(cpustate, ea + 16, cpustate->fpu_opcode);
4523 // WRITE32(cpustate, ea + 20, cpustate->fpu_data_ptr);
4524 // WRITE32(cpustate, ea + 24, cpustate->fpu_inst_ptr);
4527 cpustate->x87_cw |= 0x3f; // set all masks
4529 CYCLES(cpustate,(cpustate->cr[0] & 1) ? 56 : 67);
4532 void __FASTCALL x87_fsave(i386_state *cpustate, UINT8 modrm)
4534 UINT32 ea = GetEA(cpustate, modrm, 1, 80);
4536 // TODO: Pointers and selectors
4537 switch((cpustate->cr[0] & 1)|(cpustate->operand_size & 1)<<1)
4539 case 0: // 16-bit real mode
4540 WRITE16(cpustate, ea + 0, cpustate->x87_cw);
4541 WRITE16(cpustate, ea + 2, cpustate->x87_sw);
4542 WRITE16(cpustate, ea + 4, cpustate->x87_tw);
4543 // WRITE16(cpustate, ea + 6, cpustate->fpu_inst_ptr & 0xffff);
4544 // WRITE16(cpustate, ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
4545 // WRITE16(cpustate, ea + 10, cpustate->fpu_data_ptr & 0xffff);
4546 // WRITE16(cpustate, ea + 12, (cpustate->fpu_inst_ptr & 0x0f0000) >> 4);
4549 case 1: // 16-bit protected mode
4550 WRITE16(cpustate,ea + 0, cpustate->x87_cw);
4551 WRITE16(cpustate,ea + 2, cpustate->x87_sw);
4552 WRITE16(cpustate,ea + 4, cpustate->x87_tw);
4553 // WRITE16(cpustate,ea + 6, cpustate->fpu_inst_ptr & 0xffff);
4554 // WRITE16(cpustate,ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
4555 // WRITE16(cpustate,ea + 10, cpustate->fpu_data_ptr & 0xffff);
4556 // WRITE16(cpustate,ea + 12, (cpustate->fpu_inst_ptr & 0x0f0000) >> 4);
4559 case 2: // 32-bit real mode
4560 WRITE16(cpustate, ea + 0, cpustate->x87_cw);
4561 WRITE16(cpustate, ea + 4, cpustate->x87_sw);
4562 WRITE16(cpustate, ea + 8, cpustate->x87_tw);
4563 // WRITE16(cpustate, ea + 12, cpustate->fpu_inst_ptr & 0xffff);
4564 // WRITE16(cpustate, ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
4565 // WRITE16(cpustate, ea + 20, cpustate->fpu_data_ptr & 0xffff);
4566 // WRITE16(cpustate, ea + 12, ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
4567 // WRITE32(cpustate, ea + 24, (cpustate->fpu_data_ptr >> 16) << 12);
4570 case 3: // 32-bit protected mode
4571 WRITE16(cpustate, ea + 0, cpustate->x87_cw);
4572 WRITE16(cpustate, ea + 4, cpustate->x87_sw);
4573 WRITE16(cpustate, ea + 8, cpustate->x87_tw);
4574 // WRITE32(cpustate, ea + 12, cpustate->fpu_inst_ptr);
4575 // WRITE32(cpustate, ea + 16, cpustate->fpu_opcode);
4576 // WRITE32(cpustate, ea + 20, cpustate->fpu_data_ptr);
4577 // WRITE32(cpustate, ea + 24, cpustate->fpu_inst_ptr);
4582 for (int i = 0; i < 8; ++i)
4583 WRITE80(cpustate, ea + i*10, ST(i));
4585 CYCLES(cpustate,(cpustate->cr[0] & 1) ? 56 : 67);
4588 void __FASTCALL x87_frstor(i386_state *cpustate, UINT8 modrm)
4590 UINT32 ea = GetEA(cpustate, modrm, 0, 80);
4592 // TODO: Pointers and selectors
4593 switch((cpustate->cr[0] & 1)|(cpustate->operand_size & 1)<<1)
4595 case 0: // 16-bit real mode
4596 x87_write_cw(cpustate, READ16(cpustate, ea));
4597 cpustate->x87_sw = READ16(cpustate, ea + 2);
4598 cpustate->x87_tw = READ16(cpustate, ea + 4);
4599 // WRITE16(cpustate, ea + 6, cpustate->fpu_inst_ptr & 0xffff);
4600 // WRITE16(cpustate, ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
4601 // WRITE16(cpustate, ea + 10, cpustate->fpu_data_ptr & 0xffff);
4602 // WRITE16(cpustate, ea + 12, (cpustate->fpu_inst_ptr & 0x0f0000) >> 4);
4605 case 1: // 16-bit protected mode
4606 x87_write_cw(cpustate, READ16(cpustate, ea));
4607 cpustate->x87_sw = READ16(cpustate, ea + 2);
4608 cpustate->x87_tw = READ16(cpustate, ea + 4);
4609 // WRITE16(cpustate,ea + 6, cpustate->fpu_inst_ptr & 0xffff);
4610 // WRITE16(cpustate,ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
4611 // WRITE16(cpustate,ea + 10, cpustate->fpu_data_ptr & 0xffff);
4612 // WRITE16(cpustate,ea + 12, (cpustate->fpu_inst_ptr & 0x0f0000) >> 4);
4615 case 2: // 32-bit real mode
4616 x87_write_cw(cpustate, READ16(cpustate, ea));
4617 cpustate->x87_sw = READ16(cpustate, ea + 4);
4618 cpustate->x87_tw = READ16(cpustate, ea + 8);
4619 // WRITE16(cpustate, ea + 12, cpustate->fpu_inst_ptr & 0xffff);
4620 // WRITE16(cpustate, ea + 8, (cpustate->fpu_opcode & 0x07ff) | ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
4621 // WRITE16(cpustate, ea + 20, cpustate->fpu_data_ptr & 0xffff);
4622 // WRITE16(cpustate, ea + 12, ((cpustate->fpu_inst_ptr & 0x0f0000) >> 4));
4623 // WRITE32(cpustate, ea + 24, (cpustate->fpu_data_ptr >> 16) << 12);
4626 case 3: // 32-bit protected mode
4627 x87_write_cw(cpustate, READ16(cpustate, ea));
4628 cpustate->x87_sw = READ16(cpustate, ea + 4);
4629 cpustate->x87_tw = READ16(cpustate, ea + 8);
4630 // WRITE32(cpustate, ea + 12, cpustate->fpu_inst_ptr);
4631 // WRITE32(cpustate, ea + 16, cpustate->fpu_opcode);
4632 // WRITE32(cpustate, ea + 20, cpustate->fpu_data_ptr);
4633 // WRITE32(cpustate, ea + 24, cpustate->fpu_inst_ptr);
4638 for (int i = 0; i < 8; ++i)
4639 x87_write_stack(cpustate, i, READ80(cpustate, ea + i*10), FALSE);
4641 CYCLES(cpustate,(cpustate->cr[0] & 1) ? 34 : 44);
4644 void __FASTCALL x87_fxch(i386_state *cpustate, UINT8 modrm)
4646 if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
4647 x87_set_stack_underflow(cpustate);
4649 if (x87_check_exceptions(cpustate))
4651 floatx80 tmp = ST(0);
4656 int tag0 = X87_TAG(ST_TO_PHYS(0));
4657 x87_set_tag(cpustate, ST_TO_PHYS(0), X87_TAG(ST_TO_PHYS(1)));
4658 x87_set_tag(cpustate, ST_TO_PHYS(1), tag0);
4661 CYCLES(cpustate, 4);
4664 void __FASTCALL x87_fxch_sti(i386_state *cpustate, UINT8 modrm)
4668 if (X87_IS_ST_EMPTY(0))
4671 x87_set_tag(cpustate, ST_TO_PHYS(0), X87_TW_SPECIAL);
4672 x87_set_stack_underflow(cpustate);
4674 if (X87_IS_ST_EMPTY(i))
4677 x87_set_tag(cpustate, ST_TO_PHYS(i), X87_TW_SPECIAL);
4678 x87_set_stack_underflow(cpustate);
4681 if (x87_check_exceptions(cpustate))
4683 floatx80 tmp = ST(0);
4688 int tag0 = X87_TAG(ST_TO_PHYS(0));
4689 x87_set_tag(cpustate, ST_TO_PHYS(0), X87_TAG(ST_TO_PHYS(i)));
4690 x87_set_tag(cpustate, ST_TO_PHYS(i), tag0);
4693 CYCLES(cpustate, 4);
4696 void __FASTCALL x87_fstsw_ax(i386_state *cpustate, UINT8 modrm)
4698 REG16(AX) = cpustate->x87_sw;
4700 CYCLES(cpustate, 3);
4703 void __FASTCALL x87_fstsw_m2byte(i386_state *cpustate, UINT8 modrm)
4705 UINT32 ea = GetEA(cpustate, modrm, 1, 2);
4707 WRITE16(cpustate, ea, cpustate->x87_sw);
4709 CYCLES(cpustate, 3);
4712 void __FASTCALL __FASTCALL x87_invalid(i386_state *cpustate, UINT8 modrm)
4715 report_invalid_opcode(cpustate);
4716 i386_trap(cpustate, 6, 0, 0);
4721 /*************************************
4723 * Instruction dispatch
4725 *************************************/
4727 static void __FASTCALL I386OP(x87_group_d8)(i386_state *cpustate)
4729 UINT8 modrm = FETCH(cpustate);
4730 cpustate->opcode_table_x87_d8[modrm](cpustate, modrm);
4733 static void __FASTCALL I386OP(x87_group_d9)(i386_state *cpustate)
4735 UINT8 modrm = FETCH(cpustate);
4736 cpustate->opcode_table_x87_d9[modrm](cpustate, modrm);
4739 static void __FASTCALL I386OP(x87_group_da)(i386_state *cpustate)
4741 UINT8 modrm = FETCH(cpustate);
4742 cpustate->opcode_table_x87_da[modrm](cpustate, modrm);
4745 static void __FASTCALL I386OP(x87_group_db)(i386_state *cpustate)
4747 UINT8 modrm = FETCH(cpustate);
4748 cpustate->opcode_table_x87_db[modrm](cpustate, modrm);
4751 static void __FASTCALL I386OP(x87_group_dc)(i386_state *cpustate)
4753 UINT8 modrm = FETCH(cpustate);
4754 cpustate->opcode_table_x87_dc[modrm](cpustate, modrm);
4757 static void __FASTCALL I386OP(x87_group_dd)(i386_state *cpustate)
4759 UINT8 modrm = FETCH(cpustate);
4760 cpustate->opcode_table_x87_dd[modrm](cpustate, modrm);
4763 static void __FASTCALL I386OP(x87_group_de)(i386_state *cpustate)
4765 UINT8 modrm = FETCH(cpustate);
4766 cpustate->opcode_table_x87_de[modrm](cpustate, modrm);
4769 static void __FASTCALL I386OP(x87_group_df)(i386_state *cpustate)
4771 UINT8 modrm = FETCH(cpustate);
4772 cpustate->opcode_table_x87_df[modrm](cpustate, modrm);
4776 /*************************************
4778 * Opcode table building
4780 *************************************/
4782 void build_x87_opcode_table_d8(i386_state *cpustate)
4786 for (modrm = 0; modrm < 0x100; ++modrm)
4788 void (__FASTCALL *ptr)(i386_state *cpustate, UINT8 modrm) = x87_invalid;
4792 switch ((modrm >> 3) & 0x7)
4794 case 0x00: ptr = x87_fadd_m32real; break;
4795 case 0x01: ptr = x87_fmul_m32real; break;
4796 case 0x02: ptr = x87_fcom_m32real; break;
4797 case 0x03: ptr = x87_fcomp_m32real; break;
4798 case 0x04: ptr = x87_fsub_m32real; break;
4799 case 0x05: ptr = x87_fsubr_m32real; break;
4800 case 0x06: ptr = x87_fdiv_m32real; break;
4801 case 0x07: ptr = x87_fdivr_m32real; break;
4808 case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = x87_fadd_st_sti; break;
4809 case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = x87_fmul_st_sti; break;
4810 case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = x87_fcom_sti; break;
4811 case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = x87_fcomp_sti; break;
4812 case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = x87_fsub_st_sti; break;
4813 case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = x87_fsubr_st_sti; break;
4814 case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = x87_fdiv_st_sti; break;
4815 case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: ptr = x87_fdivr_st_sti; break;
4819 cpustate->opcode_table_x87_d8[modrm] = ptr;
4824 void build_x87_opcode_table_d9(i386_state *cpustate)
4828 for (modrm = 0; modrm < 0x100; ++modrm)
4830 void (__FASTCALL *ptr)(i386_state *cpustate, UINT8 modrm) = x87_invalid;
4834 switch ((modrm >> 3) & 0x7)
4836 case 0x00: ptr = x87_fld_m32real; break;
4837 case 0x02: ptr = x87_fst_m32real; break;
4838 case 0x03: ptr = x87_fstp_m32real; break;
4839 case 0x04: ptr = x87_fldenv; break;
4840 case 0x05: ptr = x87_fldcw; break;
4841 case 0x06: ptr = x87_fstenv; break;
4842 case 0x07: ptr = x87_fstcw; break;
4856 case 0xc7: ptr = x87_fld_sti; break;
4865 case 0xcf: ptr = x87_fxch_sti; break;
4867 case 0xd0: ptr = x87_fnop; break;
4868 case 0xe0: ptr = x87_fchs; break;
4869 case 0xe1: ptr = x87_fabs; break;
4870 case 0xe4: ptr = x87_ftst; break;
4871 case 0xe5: ptr = x87_fxam; break;
4872 case 0xe8: ptr = x87_fld1; break;
4873 case 0xe9: ptr = x87_fldl2t; break;
4874 case 0xea: ptr = x87_fldl2e; break;
4875 case 0xeb: ptr = x87_fldpi; break;
4876 case 0xec: ptr = x87_fldlg2; break;
4877 case 0xed: ptr = x87_fldln2; break;
4878 case 0xee: ptr = x87_fldz; break;
4879 case 0xf0: ptr = x87_f2xm1; break;
4880 case 0xf1: ptr = x87_fyl2x; break;
4881 case 0xf2: ptr = x87_fptan; break;
4882 case 0xf3: ptr = x87_fpatan; break;
4883 case 0xf4: ptr = x87_fxtract; break;
4884 case 0xf5: ptr = x87_fprem1; break;
4885 case 0xf6: ptr = x87_fdecstp; break;
4886 case 0xf7: ptr = x87_fincstp; break;
4887 case 0xf8: ptr = x87_fprem; break;
4888 case 0xf9: ptr = x87_fyl2xp1; break;
4889 case 0xfa: ptr = x87_fsqrt; break;
4890 case 0xfb: ptr = x87_fsincos; break;
4891 case 0xfc: ptr = x87_frndint; break;
4892 case 0xfd: ptr = x87_fscale; break;
4893 case 0xfe: ptr = x87_fsin; break;
4894 case 0xff: ptr = x87_fcos; break;
4898 cpustate->opcode_table_x87_d9[modrm] = ptr;
4902 void build_x87_opcode_table_da(i386_state *cpustate)
4906 for (modrm = 0; modrm < 0x100; ++modrm)
4908 void (__FASTCALL *ptr)(i386_state *cpustate, UINT8 modrm) = x87_invalid;
4912 switch ((modrm >> 3) & 0x7)
4914 case 0x00: ptr = x87_fiadd_m32int; break;
4915 case 0x01: ptr = x87_fimul_m32int; break;
4916 case 0x02: ptr = x87_ficom_m32int; break;
4917 case 0x03: ptr = x87_ficomp_m32int; break;
4918 case 0x04: ptr = x87_fisub_m32int; break;
4919 case 0x05: ptr = x87_fisubr_m32int; break;
4920 case 0x06: ptr = x87_fidiv_m32int; break;
4921 case 0x07: ptr = x87_fidivr_m32int; break;
4928 case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = x87_fcmovb_sti; break;
4929 case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = x87_fcmove_sti; break;
4930 case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = x87_fcmovbe_sti; break;
4931 case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = x87_fcmovu_sti; break;
4932 case 0xe9: ptr = x87_fucompp; break;
4936 cpustate->opcode_table_x87_da[modrm] = ptr;
4941 void build_x87_opcode_table_db(i386_state *cpustate)
4945 for (modrm = 0; modrm < 0x100; ++modrm)
4947 void (__FASTCALL *ptr)(i386_state *cpustate, UINT8 modrm) = x87_invalid;
4951 switch ((modrm >> 3) & 0x7)
4953 case 0x00: ptr = x87_fild_m32int; break;
4954 case 0x02: ptr = x87_fist_m32int; break;
4955 case 0x03: ptr = x87_fistp_m32int; break;
4956 case 0x05: ptr = x87_fld_m80real; break;
4957 case 0x07: ptr = x87_fstp_m80real; break;
4964 case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = x87_fcmovnb_sti; break;
4965 case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = x87_fcmovne_sti; break;
4966 case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = x87_fcmovnbe_sti; break;
4967 case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = x87_fcmovnu_sti; break;
4968 case 0xe0: ptr = x87_feni; break; /* FENI */
4969 case 0xe1: ptr = x87_fdisi; break; /* FDISI */
4970 case 0xe2: ptr = x87_fclex; break;
4971 case 0xe3: ptr = x87_finit; break;
4972 case 0xe4: ptr = x87_fnop; break; /* FSETPM */
4973 case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = x87_fucomi_sti; break;
4974 case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = x87_fcomi_sti; break;
4978 cpustate->opcode_table_x87_db[modrm] = ptr;
4983 void build_x87_opcode_table_dc(i386_state *cpustate)
4987 for (modrm = 0; modrm < 0x100; ++modrm)
4989 void (__FASTCALL *ptr)(i386_state *cpustate, UINT8 modrm) = x87_invalid;
4993 switch ((modrm >> 3) & 0x7)
4995 case 0x00: ptr = x87_fadd_m64real; break;
4996 case 0x01: ptr = x87_fmul_m64real; break;
4997 case 0x02: ptr = x87_fcom_m64real; break;
4998 case 0x03: ptr = x87_fcomp_m64real; break;
4999 case 0x04: ptr = x87_fsub_m64real; break;
5000 case 0x05: ptr = x87_fsubr_m64real; break;
5001 case 0x06: ptr = x87_fdiv_m64real; break;
5002 case 0x07: ptr = x87_fdivr_m64real; break;
5009 case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = x87_fadd_sti_st; break;
5010 case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = x87_fmul_sti_st; break;
5011 case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = x87_fsubr_sti_st; break;
5012 case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = x87_fsub_sti_st; break;
5013 case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = x87_fdivr_sti_st; break;
5014 case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: ptr = x87_fdiv_sti_st; break;
5018 cpustate->opcode_table_x87_dc[modrm] = ptr;
5023 void build_x87_opcode_table_dd(i386_state *cpustate)
5027 for (modrm = 0; modrm < 0x100; ++modrm)
5029 void (__FASTCALL *ptr)(i386_state *cpustate, UINT8 modrm) = x87_invalid;
5033 switch ((modrm >> 3) & 0x7)
5035 case 0x00: ptr = x87_fld_m64real; break;
5036 case 0x02: ptr = x87_fst_m64real; break;
5037 case 0x03: ptr = x87_fstp_m64real; break;
5038 case 0x04: ptr = x87_frstor; break;
5039 case 0x06: ptr = x87_fsave; break;
5040 case 0x07: ptr = x87_fstsw_m2byte; break;
5047 case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = x87_ffree; break;
5048 case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = x87_fxch_sti; break;
5049 case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = x87_fst_sti; break;
5050 case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = x87_fstp_sti; break;
5051 case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = x87_fucom_sti; break;
5052 case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = x87_fucomp_sti; break;
5056 cpustate->opcode_table_x87_dd[modrm] = ptr;
5061 void build_x87_opcode_table_de(i386_state *cpustate)
5065 for (modrm = 0; modrm < 0x100; ++modrm)
5067 void (__FASTCALL *ptr)(i386_state *cpustate, UINT8 modrm) = x87_invalid;
5071 switch ((modrm >> 3) & 0x7)
5073 case 0x00: ptr = x87_fiadd_m16int; break;
5074 case 0x01: ptr = x87_fimul_m16int; break;
5075 case 0x02: ptr = x87_ficom_m16int; break;
5076 case 0x03: ptr = x87_ficomp_m16int; break;
5077 case 0x04: ptr = x87_fisub_m16int; break;
5078 case 0x05: ptr = x87_fisubr_m16int; break;
5079 case 0x06: ptr = x87_fidiv_m16int; break;
5080 case 0x07: ptr = x87_fidivr_m16int; break;
5087 case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = x87_faddp; break;
5088 case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = x87_fmulp; break;
5089 case 0xd9: ptr = x87_fcompp; break;
5090 case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = x87_fsubrp; break;
5091 case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = x87_fsubp; break;
5092 case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = x87_fdivrp; break;
5093 case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: ptr = x87_fdivp; break;
5097 cpustate->opcode_table_x87_de[modrm] = ptr;
5102 void build_x87_opcode_table_df(i386_state *cpustate)
5106 for (modrm = 0; modrm < 0x100; ++modrm)
5108 void (__FASTCALL *ptr)(i386_state *cpustate, UINT8 modrm) = x87_invalid;
5112 switch ((modrm >> 3) & 0x7)
5114 case 0x00: ptr = x87_fild_m16int; break;
5115 case 0x02: ptr = x87_fist_m16int; break;
5116 case 0x03: ptr = x87_fistp_m16int; break;
5117 case 0x04: ptr = x87_fbld; break;
5118 case 0x05: ptr = x87_fild_m64int; break;
5119 case 0x06: ptr = x87_fbstp; break;
5120 case 0x07: ptr = x87_fistp_m64int; break;
5127 case 0xe0: ptr = x87_fstsw_ax; break;
5128 case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = x87_fucomip_sti; break;
5129 case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = x87_fcomip_sti; break;
5133 cpustate->opcode_table_x87_df[modrm] = ptr;
5137 void build_x87_opcode_table(i386_state *cpustate)
5139 build_x87_opcode_table_d8(cpustate);
5140 build_x87_opcode_table_d9(cpustate);
5141 build_x87_opcode_table_da(cpustate);
5142 build_x87_opcode_table_db(cpustate);
5143 build_x87_opcode_table_dc(cpustate);
5144 build_x87_opcode_table_dd(cpustate);
5145 build_x87_opcode_table_de(cpustate);
5146 build_x87_opcode_table_df(cpustate);