OSDN Git Service

[VM][DEVICE] Use __FASTCALL with interfaces, read_*() ,write_*(), fetch_op() and...
[csp-qt/common_source_project-fm7.git] / source / src / vm / mame / emu / cpu / i386 / x87ops.c
1 // license:BSD-3-Clause
2 // copyright-holders:Philip Bennett
3 /***************************************************************************
4
5     x87 FPU emulation
6
7     TODO:
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
17      - Exceptions
18
19    Corrections and Additions [8-December-2017 Andrey Merkulov)
20      FXAM, FPREM - fixed
21      FINCSTP, FDECSTP - tags and exceptions corrected
22      FENI, FDISI opcodes added
23
24 ***************************************************************************/
25
26 #include <math.h>
27
28
29 /*************************************
30  *
31  * Defines
32  *
33  *************************************/
34
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
50
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
69
70 #define X87_TW_MASK             3
71 #define X87_TW_VALID            0
72 #define X87_TW_ZERO             1
73 #define X87_TW_SPECIAL          2
74 #define X87_TW_EMPTY            3
75
76
77 /*************************************
78  *
79  * Macros
80  *
81  *************************************/
82
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
90
91 #define UNIMPLEMENTED           fatalerror("Unimplemented x87 op: %s (PC:%x)\n", __FUNCTION__, cpustate->pc)
92
93
94 /*************************************
95  *
96  * Constants
97  *
98  *************************************/
99
100 static const floatx80 fx80_zero =   { 0x0000, U64(0x0000000000000000) };
101 static const floatx80 fx80_one =    { 0x3fff, U64(0x8000000000000000) };
102
103 static const floatx80 fx80_ninf =   { 0xffff, U64(0x8000000000000000) };
104 static const floatx80 fx80_inan =   { 0xffff, U64(0xc000000000000000) };
105
106 /* Maps x87 round modes to SoftFloat round modes */
107 static const int x87_to_sf_rc[4] =
108 {
109         float_round_nearest_even,
110         float_round_down,
111         float_round_up,
112         float_round_to_zero,
113 };
114
115
116 /*************************************
117  *
118  * SoftFloat helpers
119  *
120  *************************************/
121
122 extern flag floatx80_is_nan( floatx80 a );
123
124 extern flag floatx80_is_signaling_nan(floatx80 a);
125
126 INLINE flag floatx80_is_quiet_nan(floatx80 a)
127 {
128         bits64 aLow;
129
130         aLow = a.low & ~LIT64(0x4000000000000000);
131         return
132                 ((a.high & 0x7FFF) == 0x7FFF)
133                 && (bits64)(aLow << 1)
134                 && (a.low != aLow);
135 }
136
137 INLINE int floatx80_is_zero(floatx80 fx)
138 {
139         return (((fx.high & 0x7fff) == 0) && ((fx.low << 1) == 0));
140 }
141
142 INLINE int floatx80_is_inf(floatx80 fx)
143 {
144         return (((fx.high & 0x7fff) == 0x7fff) && ((fx.low << 1) == 0));
145 }
146
147 INLINE int floatx80_is_denormal(floatx80 fx)
148 {
149         return (((fx.high & 0x7fff) == 0) &&
150                         ((fx.low & U64(0x8000000000000000)) == 0) &&
151                         ((fx.low << 1) != 0));
152 }
153
154 INLINE floatx80 floatx80_abs(floatx80 fx)
155 {
156         fx.high &= 0x7fff;
157         return fx;
158 }
159
160 INLINE double fx80_to_double(floatx80 fx)
161 {
162         UINT64 d = floatx80_to_float64(fx);
163         return *(double*)&d;
164 }
165
166 INLINE floatx80 double_to_fx80(double in)
167 {
168         return float64_to_floatx80(*(UINT64*)&in);
169 }
170
171 INLINE floatx80 READ80(i386_state *cpustate, UINT32 ea)
172 {
173         floatx80 t;
174
175         t.low = READ64(cpustate, ea);
176         t.high = READ16(cpustate, ea + 8);
177
178         return t;
179 }
180
181 INLINE void __FASTCALL WRITE80(i386_state *cpustate, UINT32 ea, floatx80 t)
182 {
183         WRITE64(cpustate, ea, t.low);
184         WRITE16(cpustate, ea + 8, t.high);
185 }
186
187
188 /*************************************
189  *
190  * x87 stack handling
191  *
192  *************************************/
193
194 INLINE void __FASTCALL x87_set_stack_top(i386_state *cpustate, int top)
195 {
196         cpustate->x87_sw &= ~(X87_SW_TOP_MASK << X87_SW_TOP_SHIFT);
197         cpustate->x87_sw |= (top << X87_SW_TOP_SHIFT);
198 }
199
200 INLINE void __FASTCALL x87_set_tag(i386_state *cpustate, int reg, int tag)
201 {
202         int shift = X87_TW_FIELD_SHIFT(reg);
203
204         cpustate->x87_tw &= ~(X87_TW_MASK << shift);
205         cpustate->x87_tw |= (tag << shift);
206 }
207
208 void __FASTCALL x87_write_stack(i386_state *cpustate, int i, floatx80 value, int update_tag)
209 {
210         ST(i) = value;
211
212         if (update_tag)
213         {
214                 int tag;
215
216                 if (floatx80_is_zero(value))
217                 {
218                         tag = X87_TW_ZERO;
219                 }
220                 else if (floatx80_is_inf(value) || floatx80_is_nan(value))
221                 {
222                         tag = X87_TW_SPECIAL;
223                 }
224                 else
225                 {
226                         tag = X87_TW_VALID;
227                 }
228
229                 x87_set_tag(cpustate, ST_TO_PHYS(i), tag);
230         }
231 }
232
233 INLINE void __FASTCALL x87_set_stack_underflow(i386_state *cpustate)
234 {
235         cpustate->x87_sw &= ~X87_SW_C1;
236         cpustate->x87_sw |= X87_SW_IE | X87_SW_SF;
237 }
238
239 INLINE void __FASTCALL x87_set_stack_overflow(i386_state *cpustate)
240 {
241         cpustate->x87_sw |= X87_SW_C1 | X87_SW_IE | X87_SW_SF;
242 }
243
244 int x87_inc_stack(i386_state *cpustate)
245 {
246         int ret = 1;
247
248         // Check for stack underflow
249         if (X87_IS_ST_EMPTY(0))
250         {
251                 ret = 0;
252                 x87_set_stack_underflow(cpustate);
253
254                 // Don't update the stack if the exception is unmasked
255                 if (~cpustate->x87_cw & X87_CW_IM)
256                         return ret;
257         }
258
259         x87_set_tag(cpustate, ST_TO_PHYS(0), X87_TW_EMPTY);
260         x87_set_stack_top(cpustate, ST_TO_PHYS(1));
261         return ret;
262 }
263
264 int x87_dec_stack(i386_state *cpustate)
265 {
266         int ret = 1;
267
268         // Check for stack overflow
269         if (!X87_IS_ST_EMPTY(7))
270         {
271                 ret = 0;
272                 x87_set_stack_overflow(cpustate);
273
274                 // Don't update the stack if the exception is unmasked
275                 if (~cpustate->x87_cw & X87_CW_IM)
276                         return ret;
277         }
278
279         x87_set_stack_top(cpustate, ST_TO_PHYS(7));
280         return ret;
281 }
282
283
284 /*************************************
285  *
286  * Exception handling
287  *
288  *************************************/
289
290 int x87_check_exceptions(i386_state *cpustate)
291 {
292         /* Update the exceptions from SoftFloat */
293         if (float_exception_flags & float_flag_invalid)
294         {
295                 cpustate->x87_sw |= X87_SW_IE;
296                 float_exception_flags &= ~float_flag_invalid;
297         }
298         if (float_exception_flags & float_flag_overflow)
299         {
300                 cpustate->x87_sw |= X87_SW_OE;
301                 float_exception_flags &= ~float_flag_overflow;
302         }
303         if (float_exception_flags & float_flag_underflow)
304         {
305                 cpustate->x87_sw |= X87_SW_UE;
306                 float_exception_flags &= ~float_flag_underflow;
307         }
308         if (float_exception_flags & float_flag_inexact)
309         {
310                 cpustate->x87_sw |= X87_SW_PE;
311                 float_exception_flags &= ~float_flag_inexact;
312         }
313
314         if ((cpustate->x87_sw & ~cpustate->x87_cw) & 0x3f)
315         {
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);
318                 // interrupt handler
319                 if (!(cpustate->x87_cw & X87_CW_IEM)) { cpustate->x87_sw |= X87_SW_ES; /*ferr_handler(cpustate, 1);*/ }
320
321                 if (cpustate->cr[0] & 0x20) // FIXME: 486 and up only
322                 {
323                         cpustate->ext = 1;
324                         i386_trap(cpustate, FAULT_MF, 0, 0);
325                 }
326                 return 0;
327         }
328
329         return 1;
330 }
331
332 INLINE void __FASTCALL x87_write_cw(i386_state *cpustate, UINT16 cw)
333 {
334         cpustate->x87_cw = cw;
335
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];
338 }
339
340 void __FASTCALL x87_reset(i386_state *cpustate)
341 {
342         x87_write_cw(cpustate, 0x0037f);
343
344         cpustate->x87_sw = 0;
345         cpustate->x87_tw = 0xffff;
346
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;
351
352 //      ferr_handler(cpustate, 0);
353 }
354
355
356 /*************************************
357  *
358  * Core arithmetic
359  *
360  *************************************/
361
362 static floatx80 x87_add(i386_state *cpustate, floatx80 a, floatx80 b)
363 {
364         floatx80 result = { 0 };
365
366         switch ((cpustate->x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
367         {
368                 case X87_CW_PC_SINGLE:
369                 {
370                         float32 a32 = floatx80_to_float32(a);
371                         float32 b32 = floatx80_to_float32(b);
372                         result = float32_to_floatx80(float32_add(a32, b32));
373                         break;
374                 }
375                 case X87_CW_PC_DOUBLE:
376                 {
377                         float64 a64 = floatx80_to_float64(a);
378                         float64 b64 = floatx80_to_float64(b);
379                         result = float64_to_floatx80(float64_add(a64, b64));
380                         break;
381                 }
382                 case X87_CW_PC_EXTEND:
383                 {
384                         result = floatx80_add(a, b);
385                         break;
386                 }
387         }
388
389         return result;
390 }
391
392 static floatx80 x87_sub(i386_state *cpustate, floatx80 a, floatx80 b)
393 {
394         floatx80 result = { 0 };
395
396         switch ((cpustate->x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
397         {
398                 case X87_CW_PC_SINGLE:
399                 {
400                         float32 a32 = floatx80_to_float32(a);
401                         float32 b32 = floatx80_to_float32(b);
402                         result = float32_to_floatx80(float32_sub(a32, b32));
403                         break;
404                 }
405                 case X87_CW_PC_DOUBLE:
406                 {
407                         float64 a64 = floatx80_to_float64(a);
408                         float64 b64 = floatx80_to_float64(b);
409                         result = float64_to_floatx80(float64_sub(a64, b64));
410                         break;
411                 }
412                 case X87_CW_PC_EXTEND:
413                 {
414                         result = floatx80_sub(a, b);
415                         break;
416                 }
417         }
418
419         return result;
420 }
421
422 static floatx80 x87_mul(i386_state *cpustate, floatx80 a, floatx80 b)
423 {
424         floatx80 val = { 0 };
425
426         switch ((cpustate->x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
427         {
428                 case X87_CW_PC_SINGLE:
429                 {
430                         float32 a32 = floatx80_to_float32(a);
431                         float32 b32 = floatx80_to_float32(b);
432                         val = float32_to_floatx80(float32_mul(a32, b32));
433                         break;
434                 }
435                 case X87_CW_PC_DOUBLE:
436                 {
437                         float64 a64 = floatx80_to_float64(a);
438                         float64 b64 = floatx80_to_float64(b);
439                         val = float64_to_floatx80(float64_mul(a64, b64));
440                         break;
441                 }
442                 case X87_CW_PC_EXTEND:
443                 {
444                         val = floatx80_mul(a, b);
445                         break;
446                 }
447         }
448
449         return val;
450 }
451
452
453 static floatx80 x87_div(i386_state *cpustate, floatx80 a, floatx80 b)
454 {
455         floatx80 val = { 0 };
456
457         switch ((cpustate->x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK)
458         {
459                 case X87_CW_PC_SINGLE:
460                 {
461                         float32 a32 = floatx80_to_float32(a);
462                         float32 b32 = floatx80_to_float32(b);
463                         val = float32_to_floatx80(float32_div(a32, b32));
464                         break;
465                 }
466                 case X87_CW_PC_DOUBLE:
467                 {
468                         float64 a64 = floatx80_to_float64(a);
469                         float64 b64 = floatx80_to_float64(b);
470                         val = float64_to_floatx80(float64_div(a64, b64));
471                         break;
472                 }
473                 case X87_CW_PC_EXTEND:
474                 {
475                         val = floatx80_div(a, b);
476                         break;
477                 }
478         }
479         return val;
480 }
481
482
483 /*************************************
484  *
485  * Instructions
486  *
487  *************************************/
488
489 /*************************************
490  *
491  * Add
492  *
493  *************************************/
494
495 void __FASTCALL x87_fadd_m32real(i386_state *cpustate, UINT8 modrm)
496 {
497         floatx80 result;
498
499         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
500         if (X87_IS_ST_EMPTY(0))
501         {
502                 x87_set_stack_underflow(cpustate);
503                 result = fx80_inan;
504         }
505         else
506         {
507                 UINT32 m32real = READ32(cpustate, ea);
508
509                 floatx80 a = ST(0);
510                 floatx80 b = float32_to_floatx80(m32real);
511
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)))
514                 {
515                         cpustate->x87_sw |= X87_SW_IE;
516                         result = fx80_inan;
517                 }
518                 else
519                 {
520                         result = x87_add(cpustate, a, b);
521                 }
522         }
523
524         if (x87_check_exceptions(cpustate))
525                 x87_write_stack(cpustate, 0, result, TRUE);
526
527         CYCLES(cpustate, 8);
528 }
529
530 void __FASTCALL x87_fadd_m64real(i386_state *cpustate, UINT8 modrm)
531 {
532         floatx80 result;
533
534         UINT32 ea = GetEA(cpustate, modrm, 0, 8);
535         if (X87_IS_ST_EMPTY(0))
536         {
537                 x87_set_stack_underflow(cpustate);
538                 result = fx80_inan;
539         }
540         else
541         {
542                 UINT64 m64real = READ64(cpustate, ea);
543
544                 floatx80 a = ST(0);
545                 floatx80 b = float64_to_floatx80(m64real);
546
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)))
549                 {
550                         cpustate->x87_sw |= X87_SW_IE;
551                         result = fx80_inan;
552                 }
553                 else
554                 {
555                         result = x87_add(cpustate, a, b);
556                 }
557         }
558
559         if (x87_check_exceptions(cpustate))
560                 x87_write_stack(cpustate, 0, result, TRUE);
561
562         CYCLES(cpustate, 8);
563 }
564
565 void __FASTCALL x87_fadd_st_sti(i386_state *cpustate, UINT8 modrm)
566 {
567         floatx80 result;
568         int i = modrm & 7;
569
570         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
571         {
572                 x87_set_stack_underflow(cpustate);
573                 result = fx80_inan;
574         }
575         else
576         {
577                 floatx80 a = ST(0);
578                 floatx80 b = ST(i);
579
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)))
582                 {
583                         cpustate->x87_sw |= X87_SW_IE;
584                         result = fx80_inan;
585                 }
586                 else
587                 {
588                         result = x87_add(cpustate, a, b);
589                 }
590         }
591
592         if (x87_check_exceptions(cpustate))
593                 x87_write_stack(cpustate, 0, result, TRUE);
594
595         CYCLES(cpustate, 8);
596 }
597
598 void __FASTCALL x87_fadd_sti_st(i386_state *cpustate, UINT8 modrm)
599 {
600         floatx80 result;
601         int i = modrm & 7;
602
603         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
604         {
605                 x87_set_stack_underflow(cpustate);
606                 result = fx80_inan;
607         }
608         else
609         {
610                 floatx80 a = ST(0);
611                 floatx80 b = ST(i);
612
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)))
615                 {
616                         cpustate->x87_sw |= X87_SW_IE;
617                         result = fx80_inan;
618                 }
619                 else
620                 {
621                         result = x87_add(cpustate, a, b);
622                 }
623         }
624
625         if (x87_check_exceptions(cpustate))
626                 x87_write_stack(cpustate, i, result, TRUE);
627
628         CYCLES(cpustate, 8);
629 }
630
631 void __FASTCALL x87_faddp(i386_state *cpustate, UINT8 modrm)
632 {
633         floatx80 result;
634         int i = modrm & 7;
635
636         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
637         {
638                 x87_set_stack_underflow(cpustate);
639                 result = fx80_inan;
640         }
641         else
642         {
643                 floatx80 a = ST(0);
644                 floatx80 b = ST(i);
645
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)))
648                 {
649                         cpustate->x87_sw |= X87_SW_IE;
650                         result = fx80_inan;
651                 }
652                 else
653                 {
654                         result = x87_add(cpustate, a, b);
655                 }
656         }
657
658         if (x87_check_exceptions(cpustate))
659         {
660                 x87_write_stack(cpustate, i, result, TRUE);
661                 x87_inc_stack(cpustate);
662         }
663
664         CYCLES(cpustate, 8);
665 }
666
667 void __FASTCALL x87_fiadd_m32int(i386_state *cpustate, UINT8 modrm)
668 {
669         floatx80 result;
670
671         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
672         if (X87_IS_ST_EMPTY(0))
673         {
674                 x87_set_stack_underflow(cpustate);
675                 result = fx80_inan;
676         }
677         else
678         {
679                 INT32 m32int = READ32(cpustate, ea);
680
681                 floatx80 a = ST(0);
682                 floatx80 b = int32_to_floatx80(m32int);
683
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)))
686                 {
687                         cpustate->x87_sw |= X87_SW_IE;
688                         result = fx80_inan;
689                 }
690                 else
691                 {
692                         result = x87_add(cpustate, a, b);
693                 }
694         }
695
696         if (x87_check_exceptions(cpustate))
697                 x87_write_stack(cpustate, 0, result, TRUE);
698
699         CYCLES(cpustate, 19);
700 }
701
702 void __FASTCALL x87_fiadd_m16int(i386_state *cpustate, UINT8 modrm)
703 {
704         floatx80 result;
705
706         UINT32 ea = GetEA(cpustate, modrm, 0, 2);
707         if (X87_IS_ST_EMPTY(0))
708         {
709                 x87_set_stack_underflow(cpustate);
710                 result = fx80_inan;
711         }
712         else
713         {
714                 INT16 m16int = READ16(cpustate, ea);
715
716                 floatx80 a = ST(0);
717                 floatx80 b = int32_to_floatx80(m16int);
718
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)))
721                 {
722                         cpustate->x87_sw |= X87_SW_IE;
723                         result = fx80_inan;
724                 }
725                 else
726                 {
727                         result = x87_add(cpustate, a, b);
728                 }
729         }
730
731         if (x87_check_exceptions(cpustate))
732                 x87_write_stack(cpustate, 0, result, TRUE);
733
734         CYCLES(cpustate, 20);
735 }
736
737
738 /*************************************
739  *
740  * Subtract
741  *
742  *************************************/
743
744 void __FASTCALL x87_fsub_m32real(i386_state *cpustate, UINT8 modrm)
745 {
746         floatx80 result;
747
748         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
749         if (X87_IS_ST_EMPTY(0))
750         {
751                 x87_set_stack_underflow(cpustate);
752                 result = fx80_inan;
753         }
754         else
755         {
756                 UINT32 m32real = READ32(cpustate, ea);
757
758                 floatx80 a = ST(0);
759                 floatx80 b = float32_to_floatx80(m32real);
760
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)))
763                 {
764                         cpustate->x87_sw |= X87_SW_IE;
765                         result = fx80_inan;
766                 }
767                 else
768                 {
769                         result = x87_sub(cpustate, a, b);
770                 }
771         }
772
773         if (x87_check_exceptions(cpustate))
774                 x87_write_stack(cpustate, 0, result, TRUE);
775
776         CYCLES(cpustate, 8);
777 }
778
779 void __FASTCALL x87_fsub_m64real(i386_state *cpustate, UINT8 modrm)
780 {
781         floatx80 result;
782
783         UINT32 ea = GetEA(cpustate, modrm, 0, 8);
784         if (X87_IS_ST_EMPTY(0))
785         {
786                 x87_set_stack_underflow(cpustate);
787                 result = fx80_inan;
788         }
789         else
790         {
791                 UINT64 m64real = READ64(cpustate, ea);
792
793                 floatx80 a = ST(0);
794                 floatx80 b = float64_to_floatx80(m64real);
795
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)))
798                 {
799                         cpustate->x87_sw |= X87_SW_IE;
800                         result = fx80_inan;
801                 }
802                 else
803                 {
804                         result = x87_sub(cpustate, a, b);
805                 }
806         }
807
808         if (x87_check_exceptions(cpustate))
809                 x87_write_stack(cpustate, 0, result, TRUE);
810
811         CYCLES(cpustate, 8);
812 }
813
814 void __FASTCALL x87_fsub_st_sti(i386_state *cpustate, UINT8 modrm)
815 {
816         floatx80 result;
817         int i = modrm & 7;
818
819         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
820         {
821                 x87_set_stack_underflow(cpustate);
822                 result = fx80_inan;
823         }
824         else
825         {
826                 floatx80 a = ST(0);
827                 floatx80 b = ST(i);
828
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)))
831                 {
832                         cpustate->x87_sw |= X87_SW_IE;
833                         result = fx80_inan;
834                 }
835                 else
836                 {
837                         result = x87_sub(cpustate, a, b);
838                 }
839         }
840
841         if (x87_check_exceptions(cpustate))
842                 x87_write_stack(cpustate, 0, result, TRUE);
843
844         CYCLES(cpustate, 8);
845 }
846
847 void __FASTCALL x87_fsub_sti_st(i386_state *cpustate, UINT8 modrm)
848 {
849         floatx80 result;
850         int i = modrm & 7;
851
852         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
853         {
854                 x87_set_stack_underflow(cpustate);
855                 result = fx80_inan;
856         }
857         else
858         {
859                 floatx80 a = ST(i);
860                 floatx80 b = ST(0);
861
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)))
864                 {
865                         cpustate->x87_sw |= X87_SW_IE;
866                         result = fx80_inan;
867                 }
868                 else
869                 {
870                         result = x87_sub(cpustate, a, b);
871                 }
872         }
873
874         if (x87_check_exceptions(cpustate))
875                 x87_write_stack(cpustate, i, result, TRUE);
876
877         CYCLES(cpustate, 8);
878 }
879
880 void __FASTCALL x87_fsubp(i386_state *cpustate, UINT8 modrm)
881 {
882         floatx80 result;
883         int i = modrm & 7;
884
885         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
886         {
887                 x87_set_stack_underflow(cpustate);
888                 result = fx80_inan;
889         }
890         else
891         {
892                 floatx80 a = ST(i);
893                 floatx80 b = ST(0);
894
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)))
897                 {
898                         cpustate->x87_sw |= X87_SW_IE;
899                         result = fx80_inan;
900                 }
901                 else
902                 {
903                         result = x87_sub(cpustate, a, b);
904                 }
905         }
906
907         if (x87_check_exceptions(cpustate))
908         {
909                 x87_write_stack(cpustate, i, result, TRUE);
910                 x87_inc_stack(cpustate);
911         }
912
913         CYCLES(cpustate, 8);
914 }
915
916 void __FASTCALL x87_fisub_m32int(i386_state *cpustate, UINT8 modrm)
917 {
918         floatx80 result;
919
920         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
921         if (X87_IS_ST_EMPTY(0))
922         {
923                 x87_set_stack_underflow(cpustate);
924                 result = fx80_inan;
925         }
926         else
927         {
928                 INT32 m32int = READ32(cpustate, ea);
929
930                 floatx80 a = ST(0);
931                 floatx80 b = int32_to_floatx80(m32int);
932
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)))
935                 {
936                         cpustate->x87_sw |= X87_SW_IE;
937                         result = fx80_inan;
938                 }
939                 else
940                 {
941                         result = x87_sub(cpustate, a, b);
942                 }
943         }
944
945         if (x87_check_exceptions(cpustate))
946                 x87_write_stack(cpustate, 0, result, TRUE);
947
948         CYCLES(cpustate, 19);
949 }
950
951 void __FASTCALL x87_fisub_m16int(i386_state *cpustate, UINT8 modrm)
952 {
953         floatx80 result;
954
955         UINT32 ea = GetEA(cpustate, modrm, 0, 2);
956         if (X87_IS_ST_EMPTY(0))
957         {
958                 x87_set_stack_underflow(cpustate);
959                 result = fx80_inan;
960         }
961         else
962         {
963                 INT16 m16int = READ16(cpustate, ea);
964
965                 floatx80 a = ST(0);
966                 floatx80 b = int32_to_floatx80(m16int);
967
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)))
970                 {
971                         cpustate->x87_sw |= X87_SW_IE;
972                         result = fx80_inan;
973                 }
974                 else
975                 {
976                         result = x87_sub(cpustate, a, b);
977                 }
978         }
979
980         if (x87_check_exceptions(cpustate))
981                 x87_write_stack(cpustate, 0, result, TRUE);
982
983         CYCLES(cpustate, 20);
984 }
985
986
987 /*************************************
988  *
989  * Reverse Subtract
990  *
991  *************************************/
992
993 void __FASTCALL x87_fsubr_m32real(i386_state *cpustate, UINT8 modrm)
994 {
995         floatx80 result;
996
997         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
998         if (X87_IS_ST_EMPTY(0))
999         {
1000                 x87_set_stack_underflow(cpustate);
1001                 result = fx80_inan;
1002         }
1003         else
1004         {
1005                 UINT32 m32real = READ32(cpustate, ea);
1006
1007                 floatx80 a = float32_to_floatx80(m32real);
1008                 floatx80 b = ST(0);
1009
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)))
1012                 {
1013                         cpustate->x87_sw |= X87_SW_IE;
1014                         result = fx80_inan;
1015                 }
1016                 else
1017                 {
1018                         result = x87_sub(cpustate, a, b);
1019                 }
1020         }
1021
1022         if (x87_check_exceptions(cpustate))
1023                 x87_write_stack(cpustate, 0, result, TRUE);
1024
1025         CYCLES(cpustate, 8);
1026 }
1027
1028 void __FASTCALL x87_fsubr_m64real(i386_state *cpustate, UINT8 modrm)
1029 {
1030         floatx80 result;
1031
1032         UINT32 ea = GetEA(cpustate, modrm, 0, 8);
1033         if (X87_IS_ST_EMPTY(0))
1034         {
1035                 x87_set_stack_underflow(cpustate);
1036                 result = fx80_inan;
1037         }
1038         else
1039         {
1040                 UINT64 m64real = READ64(cpustate, ea);
1041
1042                 floatx80 a = float64_to_floatx80(m64real);
1043                 floatx80 b = ST(0);
1044
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)))
1047                 {
1048                         cpustate->x87_sw |= X87_SW_IE;
1049                         result = fx80_inan;
1050                 }
1051                 else
1052                 {
1053                         result = x87_sub(cpustate, a, b);
1054                 }
1055         }
1056
1057         if (x87_check_exceptions(cpustate))
1058                 x87_write_stack(cpustate, 0, result, TRUE);
1059
1060         CYCLES(cpustate, 8);
1061 }
1062
1063 void __FASTCALL x87_fsubr_st_sti(i386_state *cpustate, UINT8 modrm)
1064 {
1065         floatx80 result;
1066         int i = modrm & 7;
1067
1068         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1069         {
1070                 x87_set_stack_underflow(cpustate);
1071                 result = fx80_inan;
1072         }
1073         else
1074         {
1075                 floatx80 a = ST(i);
1076                 floatx80 b = ST(0);
1077
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)))
1080                 {
1081                         cpustate->x87_sw |= X87_SW_IE;
1082                         result = fx80_inan;
1083                 }
1084                 else
1085                 {
1086                         result = x87_sub(cpustate, a, b);
1087                 }
1088         }
1089
1090         if (x87_check_exceptions(cpustate))
1091                 x87_write_stack(cpustate, 0, result, TRUE);
1092
1093         CYCLES(cpustate, 8);
1094 }
1095
1096 void __FASTCALL x87_fsubr_sti_st(i386_state *cpustate, UINT8 modrm)
1097 {
1098         floatx80 result;
1099         int i = modrm & 7;
1100
1101         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1102         {
1103                 x87_set_stack_underflow(cpustate);
1104                 result = fx80_inan;
1105         }
1106         else
1107         {
1108                 floatx80 a = ST(0);
1109                 floatx80 b = ST(i);
1110
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)))
1113                 {
1114                         cpustate->x87_sw |= X87_SW_IE;
1115                         result = fx80_inan;
1116                 }
1117                 else
1118                 {
1119                         result = x87_sub(cpustate, a, b);
1120                 }
1121         }
1122
1123         if (x87_check_exceptions(cpustate))
1124                 x87_write_stack(cpustate, i, result, TRUE);
1125
1126         CYCLES(cpustate, 8);
1127 }
1128
1129 void __FASTCALL x87_fsubrp(i386_state *cpustate, UINT8 modrm)
1130 {
1131         floatx80 result;
1132         int i = modrm & 7;
1133
1134         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1135         {
1136                 x87_set_stack_underflow(cpustate);
1137                 result = fx80_inan;
1138         }
1139         else
1140         {
1141                 floatx80 a = ST(0);
1142                 floatx80 b = ST(i);
1143
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)))
1146                 {
1147                         cpustate->x87_sw |= X87_SW_IE;
1148                         result = fx80_inan;
1149                 }
1150                 else
1151                 {
1152                         result = x87_sub(cpustate, a, b);
1153                 }
1154         }
1155
1156         if (x87_check_exceptions(cpustate))
1157         {
1158                 x87_write_stack(cpustate, i, result, TRUE);
1159                 x87_inc_stack(cpustate);
1160         }
1161
1162         CYCLES(cpustate, 8);
1163 }
1164
1165 void __FASTCALL x87_fisubr_m32int(i386_state *cpustate, UINT8 modrm)
1166 {
1167         floatx80 result;
1168
1169         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
1170         if (X87_IS_ST_EMPTY(0))
1171         {
1172                 x87_set_stack_underflow(cpustate);
1173                 result = fx80_inan;
1174         }
1175         else
1176         {
1177                 INT32 m32int = READ32(cpustate, ea);
1178
1179                 floatx80 a = int32_to_floatx80(m32int);
1180                 floatx80 b = ST(0);
1181
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)))
1184                 {
1185                         cpustate->x87_sw |= X87_SW_IE;
1186                         result = fx80_inan;
1187                 }
1188                 else
1189                 {
1190                         result = x87_sub(cpustate, a, b);
1191                 }
1192         }
1193
1194         if (x87_check_exceptions(cpustate))
1195                 x87_write_stack(cpustate, 0, result, TRUE);
1196
1197         CYCLES(cpustate, 19);
1198 }
1199
1200 void __FASTCALL x87_fisubr_m16int(i386_state *cpustate, UINT8 modrm)
1201 {
1202         floatx80 result;
1203
1204         UINT32 ea = GetEA(cpustate, modrm, 0, 2);
1205         if (X87_IS_ST_EMPTY(0))
1206         {
1207                 x87_set_stack_underflow(cpustate);
1208                 result = fx80_inan;
1209         }
1210         else
1211         {
1212                 INT16 m16int = READ16(cpustate, ea);
1213
1214                 floatx80 a = int32_to_floatx80(m16int);
1215                 floatx80 b = ST(0);
1216
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)))
1219                 {
1220                         cpustate->x87_sw |= X87_SW_IE;
1221                         result = fx80_inan;
1222                 }
1223                 else
1224                 {
1225                         result = x87_sub(cpustate, a, b);
1226                 }
1227         }
1228
1229         if (x87_check_exceptions(cpustate))
1230                 x87_write_stack(cpustate, 0, result, TRUE);
1231
1232         CYCLES(cpustate, 20);
1233 }
1234
1235
1236 /*************************************
1237  *
1238  * Divide
1239  *
1240  *************************************/
1241
1242 void __FASTCALL x87_fdiv_m32real(i386_state *cpustate, UINT8 modrm)
1243 {
1244         floatx80 result;
1245
1246         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
1247         if (X87_IS_ST_EMPTY(0))
1248         {
1249                 x87_set_stack_underflow(cpustate);
1250                 result = fx80_inan;
1251         }
1252         else
1253         {
1254                 UINT32 m32real = READ32(cpustate, ea);
1255
1256                 floatx80 a = ST(0);
1257                 floatx80 b = float32_to_floatx80(m32real);
1258
1259                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1260                 {
1261                         cpustate->x87_sw |= X87_SW_IE;
1262                         result = fx80_inan;
1263                 }
1264                 else
1265                 {
1266                         result = x87_div(cpustate, a, b);
1267                 }
1268         }
1269
1270         if (x87_check_exceptions(cpustate))
1271                 x87_write_stack(cpustate, 0, result, TRUE);
1272
1273         // 73, 62, 35
1274         CYCLES(cpustate, 73);
1275 }
1276
1277 void __FASTCALL x87_fdiv_m64real(i386_state *cpustate, UINT8 modrm)
1278 {
1279         floatx80 result;
1280
1281         UINT32 ea = GetEA(cpustate, modrm, 0, 8);
1282         if (X87_IS_ST_EMPTY(0))
1283         {
1284                 x87_set_stack_underflow(cpustate);
1285                 result = fx80_inan;
1286         }
1287         else
1288         {
1289                 UINT64 m64real = READ64(cpustate, ea);
1290
1291                 floatx80 a = ST(0);
1292                 floatx80 b = float64_to_floatx80(m64real);
1293
1294                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1295                 {
1296                         cpustate->x87_sw |= X87_SW_IE;
1297                         result = fx80_inan;
1298                 }
1299                 else
1300                 {
1301                         result = x87_div(cpustate, a, b);
1302                 }
1303         }
1304
1305         if (x87_check_exceptions(cpustate))
1306                 x87_write_stack(cpustate, 0, result, TRUE);
1307
1308         // 73, 62, 35
1309         CYCLES(cpustate, 73);
1310 }
1311
1312 void __FASTCALL x87_fdiv_st_sti(i386_state *cpustate, UINT8 modrm)
1313 {
1314         int i = modrm & 7;
1315         floatx80 result;
1316
1317         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1318         {
1319                 x87_set_stack_underflow(cpustate);
1320                 result = fx80_inan;
1321         }
1322         else
1323         {
1324                 floatx80 a = ST(0);
1325                 floatx80 b = ST(i);
1326
1327                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1328                 {
1329                         cpustate->x87_sw |= X87_SW_IE;
1330                         result = fx80_inan;
1331                 }
1332                 else
1333                 {
1334                         result = x87_div(cpustate, a, b);
1335                 }
1336         }
1337
1338         if (x87_check_exceptions(cpustate))
1339         {
1340                 x87_write_stack(cpustate, 0, result, TRUE);
1341         }
1342
1343         // 73, 62, 35
1344         CYCLES(cpustate, 73);
1345 }
1346
1347 void __FASTCALL x87_fdiv_sti_st(i386_state *cpustate, UINT8 modrm)
1348 {
1349         int i = modrm & 7;
1350         floatx80 result;
1351
1352         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1353         {
1354                 x87_set_stack_underflow(cpustate);
1355                 result = fx80_inan;
1356         }
1357         else
1358         {
1359                 floatx80 a = ST(i);
1360                 floatx80 b = ST(0);
1361
1362                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1363                 {
1364                         cpustate->x87_sw |= X87_SW_IE;
1365                         result = fx80_inan;
1366                 }
1367                 else
1368                 {
1369                         result = x87_div(cpustate, a, b);
1370                 }
1371         }
1372
1373         if (x87_check_exceptions(cpustate))
1374         {
1375                 x87_write_stack(cpustate, i, result, TRUE);
1376         }
1377
1378         // 73, 62, 35
1379         CYCLES(cpustate, 73);
1380 }
1381
1382 void __FASTCALL x87_fdivp(i386_state *cpustate, UINT8 modrm)
1383 {
1384         int i = modrm & 7;
1385         floatx80 result;
1386
1387         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1388         {
1389                 x87_set_stack_underflow(cpustate);
1390                 result = fx80_inan;
1391         }
1392         else
1393         {
1394                 floatx80 a = ST(i);
1395                 floatx80 b = ST(0);
1396
1397                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1398                 {
1399                         cpustate->x87_sw |= X87_SW_IE;
1400                         result = fx80_inan;
1401                 }
1402                 else
1403                 {
1404                         result = x87_div(cpustate, a, b);
1405                 }
1406         }
1407
1408         if (x87_check_exceptions(cpustate))
1409         {
1410                 x87_write_stack(cpustate, i, result, TRUE);
1411                 x87_inc_stack(cpustate);
1412         }
1413
1414         // 73, 62, 35
1415         CYCLES(cpustate, 73);
1416 }
1417
1418 void __FASTCALL x87_fidiv_m32int(i386_state *cpustate, UINT8 modrm)
1419 {
1420         floatx80 result;
1421
1422         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
1423         if (X87_IS_ST_EMPTY(0))
1424         {
1425                 x87_set_stack_underflow(cpustate);
1426                 result = fx80_inan;
1427         }
1428         else
1429         {
1430                 INT32 m32int = READ32(cpustate, ea);
1431
1432                 floatx80 a = ST(0);
1433                 floatx80 b = int32_to_floatx80(m32int);
1434
1435                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1436                 {
1437                         cpustate->x87_sw |= X87_SW_IE;
1438                         result = fx80_inan;
1439                 }
1440                 else
1441                 {
1442                         result = x87_div(cpustate, a, b);
1443                 }
1444         }
1445
1446         if (x87_check_exceptions(cpustate))
1447                 x87_write_stack(cpustate, 0, result, TRUE);
1448
1449         // 73, 62, 35
1450         CYCLES(cpustate, 73);
1451 }
1452
1453 void __FASTCALL x87_fidiv_m16int(i386_state *cpustate, UINT8 modrm)
1454 {
1455         floatx80 result;
1456
1457         UINT32 ea = GetEA(cpustate, modrm, 0, 2);
1458         if (X87_IS_ST_EMPTY(0))
1459         {
1460                 x87_set_stack_underflow(cpustate);
1461                 result = fx80_inan;
1462         }
1463         else
1464         {
1465                 INT16 m16int = READ16(cpustate, ea);
1466
1467                 floatx80 a = ST(0);
1468                 floatx80 b = int32_to_floatx80(m16int);
1469
1470                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1471                 {
1472                         cpustate->x87_sw |= X87_SW_IE;
1473                         result = fx80_inan;
1474                 }
1475                 else
1476                 {
1477                         result = x87_div(cpustate, a, b);
1478                 }
1479         }
1480
1481         if (x87_check_exceptions(cpustate))
1482                 x87_write_stack(cpustate, 0, result, TRUE);
1483
1484         // 73, 62, 35
1485         CYCLES(cpustate, 73);
1486 }
1487
1488
1489 /*************************************
1490  *
1491  * Reverse Divide
1492  *
1493  *************************************/
1494
1495 void __FASTCALL x87_fdivr_m32real(i386_state *cpustate, UINT8 modrm)
1496 {
1497         floatx80 result;
1498
1499         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
1500         if (X87_IS_ST_EMPTY(0))
1501         {
1502                 x87_set_stack_underflow(cpustate);
1503                 result = fx80_inan;
1504         }
1505         else
1506         {
1507                 UINT32 m32real = READ32(cpustate, ea);
1508
1509                 floatx80 a = float32_to_floatx80(m32real);
1510                 floatx80 b = ST(0);
1511
1512                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1513                 {
1514                         cpustate->x87_sw |= X87_SW_IE;
1515                         result = fx80_inan;
1516                 }
1517                 else
1518                 {
1519                         result = x87_div(cpustate, a, b);
1520                 }
1521         }
1522
1523         if (x87_check_exceptions(cpustate))
1524                 x87_write_stack(cpustate, 0, result, TRUE);
1525
1526         // 73, 62, 35
1527         CYCLES(cpustate, 73);
1528 }
1529
1530 void __FASTCALL x87_fdivr_m64real(i386_state *cpustate, UINT8 modrm)
1531 {
1532         floatx80 result;
1533
1534         UINT32 ea = GetEA(cpustate, modrm, 0, 8);
1535         if (X87_IS_ST_EMPTY(0))
1536         {
1537                 x87_set_stack_underflow(cpustate);
1538                 result = fx80_inan;
1539         }
1540         else
1541         {
1542                 UINT64 m64real = READ64(cpustate, ea);
1543
1544                 floatx80 a = float64_to_floatx80(m64real);
1545                 floatx80 b = ST(0);
1546
1547                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1548                 {
1549                         cpustate->x87_sw |= X87_SW_IE;
1550                         result = fx80_inan;
1551                 }
1552                 else
1553                 {
1554                         result = x87_div(cpustate, a, b);
1555                 }
1556         }
1557
1558         if (x87_check_exceptions(cpustate))
1559                 x87_write_stack(cpustate, 0, result, TRUE);
1560
1561         // 73, 62, 35
1562         CYCLES(cpustate, 73);
1563 }
1564
1565 void __FASTCALL x87_fdivr_st_sti(i386_state *cpustate, UINT8 modrm)
1566 {
1567         int i = modrm & 7;
1568         floatx80 result;
1569
1570         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1571         {
1572                 x87_set_stack_underflow(cpustate);
1573                 result = fx80_inan;
1574         }
1575         else
1576         {
1577                 floatx80 a = ST(i);
1578                 floatx80 b = ST(0);
1579
1580                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1581                 {
1582                         cpustate->x87_sw |= X87_SW_IE;
1583                         result = fx80_inan;
1584                 }
1585                 else
1586                 {
1587                         result = x87_div(cpustate, a, b);
1588                 }
1589         }
1590
1591         if (x87_check_exceptions(cpustate))
1592         {
1593                 x87_write_stack(cpustate, 0, result, TRUE);
1594         }
1595
1596         // 73, 62, 35
1597         CYCLES(cpustate, 73);
1598 }
1599
1600 void __FASTCALL x87_fdivr_sti_st(i386_state *cpustate, UINT8 modrm)
1601 {
1602         int i = modrm & 7;
1603         floatx80 result;
1604
1605         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1606         {
1607                 x87_set_stack_underflow(cpustate);
1608                 result = fx80_inan;
1609         }
1610         else
1611         {
1612                 floatx80 a = ST(0);
1613                 floatx80 b = ST(i);
1614
1615                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1616                 {
1617                         cpustate->x87_sw |= X87_SW_IE;
1618                         result = fx80_inan;
1619                 }
1620                 else
1621                 {
1622                         result = x87_div(cpustate, a, b);
1623                 }
1624         }
1625
1626         if (x87_check_exceptions(cpustate))
1627         {
1628                 x87_write_stack(cpustate, i, result, TRUE);
1629         }
1630
1631         // 73, 62, 35
1632         CYCLES(cpustate, 73);
1633 }
1634
1635 void __FASTCALL x87_fdivrp(i386_state *cpustate, UINT8 modrm)
1636 {
1637         int i = modrm & 7;
1638         floatx80 result;
1639
1640         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1641         {
1642                 x87_set_stack_underflow(cpustate);
1643                 result = fx80_inan;
1644         }
1645         else
1646         {
1647                 floatx80 a = ST(0);
1648                 floatx80 b = ST(i);
1649
1650                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1651                 {
1652                         cpustate->x87_sw |= X87_SW_IE;
1653                         result = fx80_inan;
1654                 }
1655                 else
1656                 {
1657                         result = x87_div(cpustate, a, b);
1658                 }
1659         }
1660
1661         if (x87_check_exceptions(cpustate))
1662         {
1663                 x87_write_stack(cpustate, i, result, TRUE);
1664                 x87_inc_stack(cpustate);
1665         }
1666
1667         // 73, 62, 35
1668         CYCLES(cpustate, 73);
1669 }
1670
1671
1672 void __FASTCALL x87_fidivr_m32int(i386_state *cpustate, UINT8 modrm)
1673 {
1674         floatx80 result;
1675
1676         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
1677         if (X87_IS_ST_EMPTY(0))
1678         {
1679                 x87_set_stack_underflow(cpustate);
1680                 result = fx80_inan;
1681         }
1682         else
1683         {
1684                 INT32 m32int = READ32(cpustate, ea);
1685
1686                 floatx80 a = int32_to_floatx80(m32int);
1687                 floatx80 b = ST(0);
1688
1689                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1690                 {
1691                         cpustate->x87_sw |= X87_SW_IE;
1692                         result = fx80_inan;
1693                 }
1694                 else
1695                 {
1696                         result = x87_div(cpustate, a, b);
1697                 }
1698         }
1699
1700         if (x87_check_exceptions(cpustate))
1701                 x87_write_stack(cpustate, 0, result, TRUE);
1702
1703         // 73, 62, 35
1704         CYCLES(cpustate, 73);
1705 }
1706
1707 void __FASTCALL x87_fidivr_m16int(i386_state *cpustate, UINT8 modrm)
1708 {
1709         floatx80 result;
1710
1711         UINT32 ea = GetEA(cpustate, modrm, 0, 2);
1712         if (X87_IS_ST_EMPTY(0))
1713         {
1714                 x87_set_stack_underflow(cpustate);
1715                 result = fx80_inan;
1716         }
1717         else
1718         {
1719                 INT16 m16int = READ16(cpustate, ea);
1720
1721                 floatx80 a = int32_to_floatx80(m16int);
1722                 floatx80 b = ST(0);
1723
1724                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1725                 {
1726                         cpustate->x87_sw |= X87_SW_IE;
1727                         result = fx80_inan;
1728                 }
1729                 else
1730                 {
1731                         result = x87_div(cpustate, a, b);
1732                 }
1733         }
1734
1735         if (x87_check_exceptions(cpustate))
1736                 x87_write_stack(cpustate, 0, result, TRUE);
1737
1738         // 73, 62, 35
1739         CYCLES(cpustate, 73);
1740 }
1741
1742
1743 /*************************************
1744  *
1745  * Multiply
1746  *
1747  *************************************/
1748
1749 void __FASTCALL x87_fmul_m32real(i386_state *cpustate, UINT8 modrm)
1750 {
1751         floatx80 result;
1752
1753         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
1754         if (X87_IS_ST_EMPTY(0))
1755         {
1756                 x87_set_stack_underflow(cpustate);
1757                 result = fx80_inan;
1758         }
1759         else
1760         {
1761                 UINT32 m32real = READ32(cpustate, ea);
1762
1763                 floatx80 a = ST(0);
1764                 floatx80 b = float32_to_floatx80(m32real);
1765
1766                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1767                 {
1768                         cpustate->x87_sw |= X87_SW_IE;
1769                         result = fx80_inan;
1770                 }
1771                 else
1772                 {
1773                         result = x87_mul(cpustate, a, b);
1774                 }
1775         }
1776
1777         if (x87_check_exceptions(cpustate))
1778                 x87_write_stack(cpustate, 0, result, TRUE);
1779
1780         CYCLES(cpustate, 11);
1781 }
1782
1783 void __FASTCALL x87_fmul_m64real(i386_state *cpustate, UINT8 modrm)
1784 {
1785         floatx80 result;
1786
1787         UINT32 ea = GetEA(cpustate, modrm, 0, 8);
1788         if (X87_IS_ST_EMPTY(0))
1789         {
1790                 x87_set_stack_underflow(cpustate);
1791                 result = fx80_inan;
1792         }
1793         else
1794         {
1795                 UINT64 m64real = READ64(cpustate, ea);
1796
1797                 floatx80 a = ST(0);
1798                 floatx80 b = float64_to_floatx80(m64real);
1799
1800                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1801                 {
1802                         cpustate->x87_sw |= X87_SW_IE;
1803                         result = fx80_inan;
1804                 }
1805                 else
1806                 {
1807                         result = x87_mul(cpustate, a, b);
1808                 }
1809         }
1810
1811         if (x87_check_exceptions(cpustate))
1812                 x87_write_stack(cpustate, 0, result, TRUE);
1813
1814         CYCLES(cpustate, 14);
1815 }
1816
1817 void __FASTCALL x87_fmul_st_sti(i386_state *cpustate, UINT8 modrm)
1818 {
1819         floatx80 result;
1820         int i = modrm & 7;
1821
1822         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1823         {
1824                 x87_set_stack_underflow(cpustate);
1825                 result = fx80_inan;
1826         }
1827         else
1828         {
1829                 floatx80 a = ST(0);
1830                 floatx80 b = ST(i);
1831
1832                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1833                 {
1834                         cpustate->x87_sw |= X87_SW_IE;
1835                         result = fx80_inan;
1836                 }
1837                 else
1838                 {
1839                         result = x87_mul(cpustate, a, b);
1840                 }
1841         }
1842
1843         if (x87_check_exceptions(cpustate))
1844                 x87_write_stack(cpustate, 0, result, TRUE);
1845
1846         CYCLES(cpustate, 16);
1847 }
1848
1849 void __FASTCALL x87_fmul_sti_st(i386_state *cpustate, UINT8 modrm)
1850 {
1851         floatx80 result;
1852         int i = modrm & 7;
1853
1854         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1855         {
1856                 x87_set_stack_underflow(cpustate);
1857                 result = fx80_inan;
1858         }
1859         else
1860         {
1861                 floatx80 a = ST(0);
1862                 floatx80 b = ST(i);
1863
1864                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1865                 {
1866                         cpustate->x87_sw |= X87_SW_IE;
1867                         result = fx80_inan;
1868                 }
1869                 else
1870                 {
1871                         result = x87_mul(cpustate, a, b);
1872                 }
1873         }
1874
1875         if (x87_check_exceptions(cpustate))
1876                 x87_write_stack(cpustate, i, result, TRUE);
1877
1878         CYCLES(cpustate, 16);
1879 }
1880
1881 void __FASTCALL x87_fmulp(i386_state *cpustate, UINT8 modrm)
1882 {
1883         floatx80 result;
1884         int i = modrm & 7;
1885
1886         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
1887         {
1888                 x87_set_stack_underflow(cpustate);
1889                 result = fx80_inan;
1890         }
1891         else
1892         {
1893                 floatx80 a = ST(0);
1894                 floatx80 b = ST(i);
1895
1896                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1897                 {
1898                         cpustate->x87_sw |= X87_SW_IE;
1899                         result = fx80_inan;
1900                 }
1901                 else
1902                 {
1903                         result = x87_mul(cpustate, a, b);
1904                 }
1905         }
1906
1907         if (x87_check_exceptions(cpustate))
1908         {
1909                 x87_write_stack(cpustate, i, result, TRUE);
1910                 x87_inc_stack(cpustate);
1911         }
1912
1913         CYCLES(cpustate, 16);
1914 }
1915
1916 void __FASTCALL x87_fimul_m32int(i386_state *cpustate, UINT8 modrm)
1917 {
1918         floatx80 result;
1919
1920         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
1921         if (X87_IS_ST_EMPTY(0))
1922         {
1923                 x87_set_stack_underflow(cpustate);
1924                 result = fx80_inan;
1925         }
1926         else
1927         {
1928                 INT32 m32int = READ32(cpustate, ea);
1929
1930                 floatx80 a = ST(0);
1931                 floatx80 b = int32_to_floatx80(m32int);
1932
1933                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1934                 {
1935                         cpustate->x87_sw |= X87_SW_IE;
1936                         result = fx80_inan;
1937                 }
1938                 else
1939                 {
1940                         result = x87_mul(cpustate, a, b);
1941                 }
1942         }
1943
1944         if (x87_check_exceptions(cpustate))
1945                 x87_write_stack(cpustate, 0, result, TRUE);
1946
1947         CYCLES(cpustate, 22);
1948 }
1949
1950 void __FASTCALL x87_fimul_m16int(i386_state *cpustate, UINT8 modrm)
1951 {
1952         floatx80 result;
1953
1954         UINT32 ea = GetEA(cpustate, modrm, 0, 2);
1955         if (X87_IS_ST_EMPTY(0))
1956         {
1957                 x87_set_stack_underflow(cpustate);
1958                 result = fx80_inan;
1959         }
1960         else
1961         {
1962                 INT16 m16int = READ16(cpustate, ea);
1963
1964                 floatx80 a = ST(0);
1965                 floatx80 b = int32_to_floatx80(m16int);
1966
1967                 if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
1968                 {
1969                         cpustate->x87_sw |= X87_SW_IE;
1970                         result = fx80_inan;
1971                 }
1972                 else
1973                 {
1974                         result = x87_mul(cpustate, a, b);
1975                 }
1976         }
1977
1978         if (x87_check_exceptions(cpustate))
1979                 x87_write_stack(cpustate, 0, result, TRUE);
1980
1981         CYCLES(cpustate, 22);
1982 }
1983
1984
1985 /*************************************
1986 *
1987 * Conditional Move
1988 *
1989 *************************************/
1990
1991 void __FASTCALL x87_fcmovb_sti(i386_state *cpustate, UINT8 modrm)
1992 {
1993         floatx80 result;
1994         int i = modrm & 7;
1995
1996         if (cpustate->CF == 1)
1997         {
1998                 if (X87_IS_ST_EMPTY(i))
1999                 {
2000                         x87_set_stack_underflow(cpustate);
2001                         result = fx80_inan;
2002                 }
2003                 else
2004                         result = ST(i);
2005
2006                 if (x87_check_exceptions(cpustate))
2007                 {
2008                         ST(0) = result;
2009                 }
2010         }
2011
2012         CYCLES(cpustate, 4);
2013 }
2014
2015 void __FASTCALL x87_fcmove_sti(i386_state *cpustate, UINT8 modrm)
2016 {
2017         floatx80 result;
2018         int i = modrm & 7;
2019
2020         if (cpustate->ZF == 1)
2021         {
2022                 if (X87_IS_ST_EMPTY(i))
2023                 {
2024                         x87_set_stack_underflow(cpustate);
2025                         result = fx80_inan;
2026                 }
2027                 else
2028                         result = ST(i);
2029
2030                 if (x87_check_exceptions(cpustate))
2031                 {
2032                         ST(0) = result;
2033                 }
2034         }
2035
2036         CYCLES(cpustate, 4);
2037 }
2038
2039 void __FASTCALL x87_fcmovbe_sti(i386_state *cpustate, UINT8 modrm)
2040 {
2041         floatx80 result;
2042         int i = modrm & 7;
2043
2044         if ((cpustate->CF | cpustate->ZF) == 1)
2045         {
2046                 if (X87_IS_ST_EMPTY(i))
2047                 {
2048                         x87_set_stack_underflow(cpustate);
2049                         result = fx80_inan;
2050                 }
2051                 else
2052                         result = ST(i);
2053
2054                 if (x87_check_exceptions(cpustate))
2055                 {
2056                         ST(0) = result;
2057                 }
2058         }
2059
2060         CYCLES(cpustate, 4);
2061 }
2062
2063 void __FASTCALL x87_fcmovu_sti(i386_state *cpustate, UINT8 modrm)
2064 {
2065         floatx80 result;
2066         int i = modrm & 7;
2067
2068         if (cpustate->PF == 1)
2069         {
2070                 if (X87_IS_ST_EMPTY(i))
2071                 {
2072                         x87_set_stack_underflow(cpustate);
2073                         result = fx80_inan;
2074                 }
2075                 else
2076                         result = ST(i);
2077
2078                 if (x87_check_exceptions(cpustate))
2079                 {
2080                         ST(0) = result;
2081                 }
2082         }
2083
2084         CYCLES(cpustate, 4);
2085 }
2086
2087 void __FASTCALL x87_fcmovnb_sti(i386_state *cpustate, UINT8 modrm)
2088 {
2089         floatx80 result;
2090         int i = modrm & 7;
2091
2092         if (cpustate->CF == 0)
2093         {
2094                 if (X87_IS_ST_EMPTY(i))
2095                 {
2096                         x87_set_stack_underflow(cpustate);
2097                         result = fx80_inan;
2098                 }
2099                 else
2100                         result = ST(i);
2101
2102                 if (x87_check_exceptions(cpustate))
2103                 {
2104                         ST(0) = result;
2105                 }
2106         }
2107
2108         CYCLES(cpustate, 4);
2109 }
2110
2111 void __FASTCALL x87_fcmovne_sti(i386_state *cpustate, UINT8 modrm)
2112 {
2113         floatx80 result;
2114         int i = modrm & 7;
2115
2116         if (cpustate->ZF == 0)
2117         {
2118                 if (X87_IS_ST_EMPTY(i))
2119                 {
2120                         x87_set_stack_underflow(cpustate);
2121                         result = fx80_inan;
2122                 }
2123                 else
2124                         result = ST(i);
2125
2126                 if (x87_check_exceptions(cpustate))
2127                 {
2128                         ST(0) = result;
2129                 }
2130         }
2131
2132         CYCLES(cpustate, 4);
2133 }
2134
2135 void __FASTCALL x87_fcmovnbe_sti(i386_state *cpustate, UINT8 modrm)
2136 {
2137         floatx80 result;
2138         int i = modrm & 7;
2139
2140         if ((cpustate->CF == 0) && (cpustate->ZF == 0))
2141         {
2142                 if (X87_IS_ST_EMPTY(i))
2143                 {
2144                         x87_set_stack_underflow(cpustate);
2145                         result = fx80_inan;
2146                 }
2147                 else
2148                         result = ST(i);
2149
2150                 if (x87_check_exceptions(cpustate))
2151                 {
2152                         ST(0) = result;
2153                 }
2154         }
2155
2156         CYCLES(cpustate, 4);
2157 }
2158
2159 void __FASTCALL x87_fcmovnu_sti(i386_state *cpustate, UINT8 modrm)
2160 {
2161         floatx80 result;
2162         int i = modrm & 7;
2163
2164         if (cpustate->PF == 0)
2165         {
2166                 if (X87_IS_ST_EMPTY(i))
2167                 {
2168                         x87_set_stack_underflow(cpustate);
2169                         result = fx80_inan;
2170                 }
2171                 else
2172                         result = ST(i);
2173
2174                 if (x87_check_exceptions(cpustate))
2175                 {
2176                         ST(0) = result;
2177                 }
2178         }
2179
2180         CYCLES(cpustate, 4);
2181 }
2182
2183 /*************************************
2184  *
2185  * Miscellaneous arithmetic
2186  *
2187  *************************************/
2188 /* D9 F8 */
2189 void __FASTCALL x87_fprem(i386_state *cpustate, UINT8 modrm)
2190 {
2191         floatx80 result;
2192
2193         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
2194         {
2195                 x87_set_stack_underflow(cpustate);
2196                 result = fx80_inan;
2197         }
2198         else
2199         {
2200                 floatx80 a0 = ST(0);   // dividend
2201                 floatx80 b1 = ST(1);   // divider
2202
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;
2206
2207                 //int d=extractFloatx80Exp(a0)-extractFloatx80Exp(b1);
2208                 int d = (a0.high & 0x7FFF) - (b1.high & 0x7FFF);
2209                 if (d < 64) {
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;
2216                         // C2 already 0
2217                         cpustate->x87_sw &= ~(X87_SW_C0|X87_SW_C3|X87_SW_C1);
2218                         if (q & 1)
2219                                 cpustate->x87_sw |= X87_SW_C1;
2220                         if (q & 2)
2221                                 cpustate->x87_sw |= X87_SW_C3;
2222                         if (q & 4)
2223                                 cpustate->x87_sw |= X87_SW_C0;
2224                 }
2225                 else {
2226                         cpustate->x87_sw |= X87_SW_C2;
2227                         int n = 63;
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);
2237                 }
2238         }
2239
2240         if (x87_check_exceptions(cpustate))
2241                 x87_write_stack(cpustate, 0, result, TRUE);
2242
2243         CYCLES(cpustate, 84);
2244 }
2245
2246 void __FASTCALL x87_fprem1(i386_state *cpustate, UINT8 modrm)
2247 {
2248         floatx80 result;
2249
2250         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
2251         {
2252                 x87_set_stack_underflow(cpustate);
2253                 result = fx80_inan;
2254         }
2255         else
2256         {
2257                 floatx80 a = ST(0);
2258                 floatx80 b = ST(1);
2259
2260                 cpustate->x87_sw &= ~X87_SW_C2;
2261
2262                 // TODO: Implement Cx bits
2263                 result = floatx80_rem(a, b);
2264         }
2265
2266         if (x87_check_exceptions(cpustate))
2267                 x87_write_stack(cpustate, 0, result, TRUE);
2268
2269         CYCLES(cpustate, 94);
2270 }
2271
2272 void __FASTCALL x87_fsqrt(i386_state *cpustate, UINT8 modrm)
2273 {
2274         floatx80 result;
2275
2276         if (X87_IS_ST_EMPTY(0))
2277         {
2278                 x87_set_stack_underflow(cpustate);
2279                 result = fx80_inan;
2280         }
2281         else
2282         {
2283                 floatx80 value = ST(0);
2284
2285                 if ((!floatx80_is_zero(value) && (value.high & 0x8000)) ||
2286                                 floatx80_is_denormal(value))
2287                 {
2288                         cpustate->x87_sw |= X87_SW_IE;
2289                         result = fx80_inan;
2290                 }
2291                 else
2292                 {
2293                         result = floatx80_sqrt(value);
2294                 }
2295         }
2296
2297         if (x87_check_exceptions(cpustate))
2298                 x87_write_stack(cpustate, 0, result, TRUE);
2299
2300         CYCLES(cpustate, 8);
2301 }
2302
2303 /*************************************
2304  *
2305  * Trigonometric
2306  *
2307  *************************************/
2308
2309 void __FASTCALL x87_f2xm1(i386_state *cpustate, UINT8 modrm)
2310 {
2311         floatx80 result;
2312
2313         if (X87_IS_ST_EMPTY(0))
2314         {
2315                 x87_set_stack_underflow(cpustate);
2316                 result = fx80_inan;
2317         }
2318         else
2319         {
2320                 // TODO: Inaccurate
2321                 double x = fx80_to_double(ST(0));
2322                 double res = pow(2.0, x) - 1;
2323                 result = double_to_fx80(res);
2324         }
2325
2326         if (x87_check_exceptions(cpustate))
2327         {
2328                 x87_write_stack(cpustate, 0, result, TRUE);
2329         }
2330
2331         CYCLES(cpustate, 242);
2332 }
2333
2334 void __FASTCALL x87_fyl2x(i386_state *cpustate, UINT8 modrm)
2335 {
2336         floatx80 result;
2337
2338         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
2339         {
2340                 x87_set_stack_underflow(cpustate);
2341                 result = fx80_inan;
2342         }
2343         else
2344         {
2345                 floatx80 x = ST(0);
2346                 floatx80 y = ST(1);
2347
2348                 if (x.high & 0x8000)
2349                 {
2350                         cpustate->x87_sw |= X87_SW_IE;
2351                         result = fx80_inan;
2352                 }
2353                 else
2354                 {
2355                         // TODO: Inaccurate
2356                         double d64 = fx80_to_double(x);
2357                         double l2x = log(d64)/log(2.0);
2358                         result = floatx80_mul(double_to_fx80(l2x), y);
2359                 }
2360         }
2361
2362         if (x87_check_exceptions(cpustate))
2363         {
2364                 x87_write_stack(cpustate, 1, result, TRUE);
2365                 x87_inc_stack(cpustate);
2366         }
2367
2368         CYCLES(cpustate, 250);
2369 }
2370
2371 void __FASTCALL x87_fyl2xp1(i386_state *cpustate, UINT8 modrm)
2372 {
2373         floatx80 result;
2374
2375         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
2376         {
2377                 x87_set_stack_underflow(cpustate);
2378                 result = fx80_inan;
2379         }
2380         else
2381         {
2382                 floatx80 x = ST(0);
2383                 floatx80 y = ST(1);
2384
2385                 // TODO: Inaccurate
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);
2389         }
2390
2391         if (x87_check_exceptions(cpustate))
2392         {
2393                 x87_write_stack(cpustate, 1, result, TRUE);
2394                 x87_inc_stack(cpustate);
2395         }
2396
2397         CYCLES(cpustate, 313);
2398 }
2399 /* D9 F2 if 8087   0 < angle < pi/4 */
2400 void __FASTCALL x87_fptan(i386_state *cpustate, UINT8 modrm)
2401 {
2402         floatx80 result1, result2;
2403
2404         if (X87_IS_ST_EMPTY(0))
2405         {
2406                 x87_set_stack_underflow(cpustate);
2407                 result1 = fx80_inan;
2408                 result2 = fx80_inan;
2409         }
2410         else if (!X87_IS_ST_EMPTY(7))
2411         {
2412                 x87_set_stack_overflow(cpustate);
2413                 result1 = fx80_inan;
2414                 result2 = fx80_inan;
2415         }
2416         else
2417         {
2418                 result1 = ST(0);
2419                 result2 = fx80_one;
2420
2421 #if 1 // TODO: Function produces bad values
2422                 if (floatx80_ftan(result1) != -1)
2423                         cpustate->x87_sw &= ~X87_SW_C2;
2424                 else
2425                         cpustate->x87_sw |= X87_SW_C2;
2426 #else
2427                 double x = fx80_to_double(result1);
2428                 x = tan(x);
2429                 result1 = double_to_fx80(x);
2430
2431                 cpustate->x87_sw &= ~X87_SW_C2;
2432 #endif
2433         }
2434
2435         if (x87_check_exceptions(cpustate))
2436         {
2437                 x87_write_stack(cpustate, 0, result1, TRUE);
2438                 x87_dec_stack(cpustate);
2439                 x87_write_stack(cpustate, 0, result2, TRUE);
2440         }
2441
2442         CYCLES(cpustate, 244);
2443 }
2444 /* D9 F3 */
2445 void __FASTCALL x87_fpatan(i386_state *cpustate, UINT8 modrm)
2446 {
2447         floatx80 result;
2448
2449         if (X87_IS_ST_EMPTY(0))
2450         {
2451                 x87_set_stack_underflow(cpustate);
2452                 result = fx80_inan;
2453         }
2454         else
2455         {
2456                 // TODO: Inaccurate
2457                 double val = atan2(fx80_to_double(ST(1)) , fx80_to_double(ST(0)));
2458                 result = double_to_fx80(val);
2459         }
2460
2461         if (x87_check_exceptions(cpustate))
2462         {
2463                 x87_write_stack(cpustate, 1, result, TRUE);
2464                 x87_inc_stack(cpustate);
2465         }
2466
2467         CYCLES(cpustate, 289);
2468 }
2469 /* D9 FE  387 only */
2470 void __FASTCALL x87_fsin(i386_state *cpustate, UINT8 modrm)
2471 {
2472         floatx80 result;
2473
2474         if (X87_IS_ST_EMPTY(0))
2475         {
2476                 x87_set_stack_underflow(cpustate);
2477                 result = fx80_inan;
2478         }
2479         else
2480         {
2481                 result = ST(0);
2482
2483 #if 1 // TODO: Function produces bad values    Result checked
2484                 if (floatx80_fsin(result) != -1)
2485                         cpustate->x87_sw &= ~X87_SW_C2;
2486                 else
2487                         cpustate->x87_sw |= X87_SW_C2;
2488 #else
2489                 double x = fx80_to_double(result);
2490                 x = sin(x);
2491                 result = double_to_fx80(x);
2492
2493                 cpustate->x87_sw &= ~X87_SW_C2;
2494 #endif
2495         }
2496
2497         if (x87_check_exceptions(cpustate))
2498                 x87_write_stack(cpustate, 0, result, TRUE);
2499
2500         CYCLES(cpustate, 241);
2501 }
2502 /* D9 FF 387 only */
2503 void __FASTCALL x87_fcos(i386_state *cpustate, UINT8 modrm)
2504 {
2505         floatx80 result;
2506
2507         if (X87_IS_ST_EMPTY(0))
2508         {
2509                 x87_set_stack_underflow(cpustate);
2510                 result = fx80_inan;
2511         }
2512         else
2513         {
2514                 result = ST(0);
2515
2516 #if 1 // TODO: Function produces bad values   to check!
2517                 if (floatx80_fcos(result) != -1)
2518                         cpustate->x87_sw &= ~X87_SW_C2;
2519                 else
2520                         cpustate->x87_sw |= X87_SW_C2;
2521 #else
2522                 double x = fx80_to_double(result);
2523                 x = cos(x);
2524                 result = double_to_fx80(x);
2525
2526                 cpustate->x87_sw &= ~X87_SW_C2;
2527 #endif
2528         }
2529
2530         if (x87_check_exceptions(cpustate))
2531                 x87_write_stack(cpustate, 0, result, TRUE);
2532
2533         CYCLES(cpustate, 241);
2534 }
2535 /* D9 FB  387 only */
2536 void __FASTCALL x87_fsincos(i386_state *cpustate, UINT8 modrm)
2537 {
2538         floatx80 s_result, c_result;
2539
2540         if (X87_IS_ST_EMPTY(0))
2541         {
2542                 x87_set_stack_underflow(cpustate);
2543                 s_result = c_result = fx80_inan;
2544         }
2545         else if (!X87_IS_ST_EMPTY(7))
2546         {
2547                 x87_set_stack_overflow(cpustate);
2548                 s_result = c_result = fx80_inan;
2549         }
2550         else
2551         {
2552                 extern int sf_fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a);
2553
2554                 s_result = c_result = ST(0);
2555
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;
2559                 else
2560                         cpustate->x87_sw |= X87_SW_C2;
2561 #else
2562                 double s = fx80_to_double(s_result);
2563                 double c = fx80_to_double(c_result);
2564                 s = sin(s);
2565                 c = cos(c);
2566
2567                 s_result = double_to_fx80(s);
2568                 c_result = double_to_fx80(c);
2569
2570                 cpustate->x87_sw &= ~X87_SW_C2;
2571 #endif
2572         }
2573
2574         if (x87_check_exceptions(cpustate))
2575         {
2576                 x87_write_stack(cpustate, 0, s_result, TRUE);
2577                 x87_dec_stack(cpustate);
2578                 x87_write_stack(cpustate, 0, c_result, TRUE);
2579         }
2580
2581         CYCLES(cpustate, 291);
2582 }
2583
2584
2585 /*************************************
2586  *
2587  * Load data
2588  *
2589  *************************************/
2590
2591 void __FASTCALL x87_fld_m32real(i386_state *cpustate, UINT8 modrm)
2592 {
2593         floatx80 value;
2594
2595         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
2596         if (x87_dec_stack(cpustate))
2597         {
2598                 UINT32 m32real = READ32(cpustate, ea);
2599
2600                 value = float32_to_floatx80(m32real);
2601
2602                 cpustate->x87_sw &= ~X87_SW_C1;
2603
2604                 if (floatx80_is_signaling_nan(value) || floatx80_is_denormal(value))
2605                 {
2606                         cpustate->x87_sw |= X87_SW_IE;
2607                         value = fx80_inan;
2608                 }
2609         }
2610         else
2611         {
2612                 value = fx80_inan;
2613         }
2614
2615         if (x87_check_exceptions(cpustate))
2616                 x87_write_stack(cpustate, 0, value, TRUE);
2617
2618         CYCLES(cpustate, 3);
2619 }
2620
2621 void __FASTCALL x87_fld_m64real(i386_state *cpustate, UINT8 modrm)
2622 {
2623         floatx80 value;
2624
2625         UINT32 ea = GetEA(cpustate, modrm, 0, 8);
2626         if (x87_dec_stack(cpustate))
2627         {
2628                 UINT64 m64real = READ64(cpustate, ea);
2629
2630                 value = float64_to_floatx80(m64real);
2631
2632                 cpustate->x87_sw &= ~X87_SW_C1;
2633
2634                 if (floatx80_is_signaling_nan(value) || floatx80_is_denormal(value))
2635                 {
2636                         cpustate->x87_sw |= X87_SW_IE;
2637                         value = fx80_inan;
2638                 }
2639         }
2640         else
2641         {
2642                 value = fx80_inan;
2643         }
2644
2645         if (x87_check_exceptions(cpustate))
2646                 x87_write_stack(cpustate, 0, value, TRUE);
2647
2648         CYCLES(cpustate, 3);
2649 }
2650
2651 void __FASTCALL x87_fld_m80real(i386_state *cpustate, UINT8 modrm)
2652 {
2653         floatx80 value;
2654
2655         UINT32 ea = GetEA(cpustate, modrm, 0, 10);
2656         if (x87_dec_stack(cpustate))
2657         {
2658                 cpustate->x87_sw &= ~X87_SW_C1;
2659                 value = READ80(cpustate, ea);
2660         }
2661         else
2662         {
2663                 value = fx80_inan;
2664         }
2665
2666         if (x87_check_exceptions(cpustate))
2667                 x87_write_stack(cpustate, 0, value, TRUE);
2668
2669         CYCLES(cpustate, 6);
2670 }
2671
2672 void __FASTCALL x87_fld_sti(i386_state *cpustate, UINT8 modrm)
2673 {
2674         floatx80 value;
2675
2676         if (x87_dec_stack(cpustate))
2677         {
2678                 cpustate->x87_sw &= ~X87_SW_C1;
2679                 value = ST((modrm + 1) & 7);
2680         }
2681         else
2682         {
2683                 value = fx80_inan;
2684         }
2685
2686         if (x87_check_exceptions(cpustate))
2687                 x87_write_stack(cpustate, 0, value, TRUE);
2688
2689         CYCLES(cpustate, 4);
2690 }
2691
2692 void __FASTCALL x87_fild_m16int(i386_state *cpustate, UINT8 modrm)
2693 {
2694         floatx80 value;
2695
2696         UINT32 ea = GetEA(cpustate, modrm, 0, 2);
2697         if (!x87_dec_stack(cpustate))
2698         {
2699                 value = fx80_inan;
2700         }
2701         else
2702         {
2703                 cpustate->x87_sw &= ~X87_SW_C1;
2704
2705                 INT16 m16int = READ16(cpustate, ea);
2706                 value = int32_to_floatx80(m16int);
2707         }
2708
2709         if (x87_check_exceptions(cpustate))
2710                 x87_write_stack(cpustate, 0, value, TRUE);
2711
2712         CYCLES(cpustate, 13);
2713 }
2714
2715 void __FASTCALL x87_fild_m32int(i386_state *cpustate, UINT8 modrm)
2716 {
2717         floatx80 value;
2718
2719         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
2720         if (!x87_dec_stack(cpustate))
2721         {
2722                 value = fx80_inan;
2723         }
2724         else
2725         {
2726                 cpustate->x87_sw &= ~X87_SW_C1;
2727
2728                 INT32 m32int = READ32(cpustate, ea);
2729                 value = int32_to_floatx80(m32int);
2730         }
2731
2732         if (x87_check_exceptions(cpustate))
2733                 x87_write_stack(cpustate, 0, value, TRUE);
2734
2735         CYCLES(cpustate, 9);
2736 }
2737
2738 void __FASTCALL x87_fild_m64int(i386_state *cpustate, UINT8 modrm)
2739 {
2740         floatx80 value;
2741
2742         UINT32 ea = GetEA(cpustate, modrm, 0, 8);
2743         if (!x87_dec_stack(cpustate))
2744         {
2745                 value = fx80_inan;
2746         }
2747         else
2748         {
2749                 cpustate->x87_sw &= ~X87_SW_C1;
2750
2751                 INT64 m64int = READ64(cpustate, ea);
2752                 value = int64_to_floatx80(m64int);
2753         }
2754
2755         if (x87_check_exceptions(cpustate))
2756                 x87_write_stack(cpustate, 0, value, TRUE);
2757
2758         CYCLES(cpustate, 10);
2759 }
2760
2761 void __FASTCALL x87_fbld(i386_state *cpustate, UINT8 modrm)
2762 {
2763         floatx80 value;
2764
2765         UINT32 ea = GetEA(cpustate, modrm, 0, 10);
2766         if (!x87_dec_stack(cpustate))
2767         {
2768                 value = fx80_inan;
2769         }
2770         else
2771         {
2772                 cpustate->x87_sw &= ~X87_SW_C1;
2773
2774                 UINT64 m64val = 0;
2775                 UINT16 sign;
2776
2777                 value = READ80(cpustate, ea);
2778
2779                 sign = value.high & 0x8000;
2780                 m64val += ((value.high >> 4) & 0xf) * 10;
2781                 m64val += ((value.high >> 0) & 0xf);
2782
2783                 for (int i = 60; i >= 0; i -= 4)
2784                 {
2785                         m64val *= 10;
2786                         m64val += (value.low >> i) & 0xf;
2787                 }
2788
2789                 value = int64_to_floatx80(m64val);
2790                 value.high |= sign;
2791         }
2792
2793         if (x87_check_exceptions(cpustate))
2794                 x87_write_stack(cpustate, 0, value, TRUE);
2795
2796         CYCLES(cpustate, 75);
2797 }
2798
2799
2800 /*************************************
2801  *
2802  * Store data
2803  *
2804  *************************************/
2805
2806 void __FASTCALL x87_fst_m32real(i386_state *cpustate, UINT8 modrm)
2807 {
2808         floatx80 value;
2809
2810         UINT32 ea = GetEA(cpustate, modrm, 1, 4);
2811         if (X87_IS_ST_EMPTY(0))
2812         {
2813                 x87_set_stack_underflow(cpustate);
2814                 value = fx80_inan;
2815         }
2816         else
2817         {
2818                 cpustate->x87_sw &= ~X87_SW_C1;
2819                 value = ST(0);
2820         }
2821
2822         if (x87_check_exceptions(cpustate))
2823         {
2824                 UINT32 m32real = floatx80_to_float32(value);
2825                 WRITE32(cpustate, ea, m32real);
2826         }
2827
2828         CYCLES(cpustate, 7);
2829 }
2830
2831 void __FASTCALL x87_fst_m64real(i386_state *cpustate, UINT8 modrm)
2832 {
2833         floatx80 value;
2834
2835         UINT32 ea = GetEA(cpustate, modrm, 1, 8);
2836         if (X87_IS_ST_EMPTY(0))
2837         {
2838                 x87_set_stack_underflow(cpustate);
2839                 value = fx80_inan;
2840         }
2841         else
2842         {
2843                 cpustate->x87_sw &= ~X87_SW_C1;
2844                 value = ST(0);
2845         }
2846
2847         if (x87_check_exceptions(cpustate))
2848         {
2849                 UINT64 m64real = floatx80_to_float64(value);
2850                 WRITE64(cpustate, ea, m64real);
2851         }
2852
2853         CYCLES(cpustate, 8);
2854 }
2855
2856 void __FASTCALL x87_fst_sti(i386_state *cpustate, UINT8 modrm)
2857 {
2858         int i = modrm & 7;
2859         floatx80 value;
2860
2861         if (X87_IS_ST_EMPTY(0))
2862         {
2863                 x87_set_stack_underflow(cpustate);
2864                 value = fx80_inan;
2865         }
2866         else
2867         {
2868                 cpustate->x87_sw &= ~X87_SW_C1;
2869                 value = ST(0);
2870         }
2871
2872         if (x87_check_exceptions(cpustate))
2873                 x87_write_stack(cpustate, i, value, TRUE);
2874
2875         CYCLES(cpustate, 3);
2876 }
2877
2878 void __FASTCALL x87_fstp_m32real(i386_state *cpustate, UINT8 modrm)
2879 {
2880         floatx80 value;
2881
2882         UINT32 ea = GetEA(cpustate, modrm, 1, 4);
2883         if (X87_IS_ST_EMPTY(0))
2884         {
2885                 x87_set_stack_underflow(cpustate);
2886                 value = fx80_inan;
2887         }
2888         else
2889         {
2890                 cpustate->x87_sw &= ~X87_SW_C1;
2891                 value = ST(0);
2892         }
2893
2894         if (x87_check_exceptions(cpustate))
2895         {
2896                 UINT32 m32real = floatx80_to_float32(value);
2897                 WRITE32(cpustate, ea, m32real);
2898                 x87_inc_stack(cpustate);
2899         }
2900
2901         CYCLES(cpustate, 7);
2902 }
2903
2904 void __FASTCALL x87_fstp_m64real(i386_state *cpustate, UINT8 modrm)
2905 {
2906         floatx80 value;
2907
2908         if (X87_IS_ST_EMPTY(0))
2909         {
2910                 x87_set_stack_underflow(cpustate);
2911                 value = fx80_inan;
2912         }
2913         else
2914         {
2915                 cpustate->x87_sw &= ~X87_SW_C1;
2916                 value = ST(0);
2917         }
2918
2919
2920         UINT32 ea = GetEA(cpustate, modrm, 1, 8);
2921         if (x87_check_exceptions(cpustate))
2922         {
2923                 UINT64 m64real = floatx80_to_float64(value);
2924                 WRITE64(cpustate, ea, m64real);
2925                 x87_inc_stack(cpustate);
2926         }
2927
2928         CYCLES(cpustate, 8);
2929 }
2930
2931 void __FASTCALL x87_fstp_m80real(i386_state *cpustate, UINT8 modrm)
2932 {
2933         floatx80 value;
2934
2935         if (X87_IS_ST_EMPTY(0))
2936         {
2937                 x87_set_stack_underflow(cpustate);
2938                 value = fx80_inan;
2939         }
2940         else
2941         {
2942                 cpustate->x87_sw &= ~X87_SW_C1;
2943                 value = ST(0);
2944         }
2945
2946         UINT32 ea = GetEA(cpustate, modrm, 1, 10);
2947         if (x87_check_exceptions(cpustate))
2948         {
2949                 WRITE80(cpustate, ea, value);
2950                 x87_inc_stack(cpustate);
2951         }
2952
2953         CYCLES(cpustate, 6);
2954 }
2955
2956 void __FASTCALL x87_fstp_sti(i386_state *cpustate, UINT8 modrm)
2957 {
2958         int i = modrm & 7;
2959         floatx80 value;
2960
2961         if (X87_IS_ST_EMPTY(0))
2962         {
2963                 x87_set_stack_underflow(cpustate);
2964                 value = fx80_inan;
2965         }
2966         else
2967         {
2968                 cpustate->x87_sw &= ~X87_SW_C1;
2969                 value = ST(0);
2970         }
2971
2972         if (x87_check_exceptions(cpustate))
2973         {
2974                 x87_write_stack(cpustate, i, value, TRUE);
2975                 x87_inc_stack(cpustate);
2976         }
2977
2978         CYCLES(cpustate, 3);
2979 }
2980
2981 void __FASTCALL x87_fist_m16int(i386_state *cpustate, UINT8 modrm)
2982 {
2983         INT16 m16int;
2984
2985         if (X87_IS_ST_EMPTY(0))
2986         {
2987                 x87_set_stack_underflow(cpustate);
2988                 m16int = -32768;
2989         }
2990         else
2991         {
2992                 floatx80 fx80 = floatx80_round_to_int(ST(0));
2993
2994                 floatx80 lowerLim = int32_to_floatx80(-32768);
2995                 floatx80 upperLim = int32_to_floatx80(32767);
2996
2997                 cpustate->x87_sw &= ~X87_SW_C1;
2998
2999                 if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
3000                         m16int = floatx80_to_int32(fx80);
3001                 else
3002                         m16int = -32768;
3003         }
3004
3005         UINT32 ea = GetEA(cpustate, modrm, 1, 2);
3006         if (x87_check_exceptions(cpustate))
3007         {
3008                 WRITE16(cpustate, ea, m16int);
3009         }
3010
3011         CYCLES(cpustate, 29);
3012 }
3013
3014 void __FASTCALL x87_fist_m32int(i386_state *cpustate, UINT8 modrm)
3015 {
3016         INT32 m32int;
3017
3018         if (X87_IS_ST_EMPTY(0))
3019         {
3020                 x87_set_stack_underflow(cpustate);
3021                 m32int = 0x80000000;
3022         }
3023         else
3024         {
3025                 floatx80 fx80 = floatx80_round_to_int(ST(0));
3026
3027                 floatx80 lowerLim = int32_to_floatx80(0x80000000);
3028                 floatx80 upperLim = int32_to_floatx80(0x7fffffff);
3029
3030                 cpustate->x87_sw &= ~X87_SW_C1;
3031
3032                 if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
3033                         m32int = floatx80_to_int32(fx80);
3034                 else
3035                         m32int = 0x80000000;
3036         }
3037
3038         UINT32 ea = GetEA(cpustate, modrm, 1, 4);
3039         if (x87_check_exceptions(cpustate))
3040         {
3041                 WRITE32(cpustate, ea, m32int);
3042         }
3043
3044         CYCLES(cpustate, 28);
3045 }
3046
3047 void __FASTCALL x87_fistp_m16int(i386_state *cpustate, UINT8 modrm)
3048 {
3049         INT16 m16int;
3050
3051         if (X87_IS_ST_EMPTY(0))
3052         {
3053                 x87_set_stack_underflow(cpustate);
3054                 m16int = (UINT16)0x8000;
3055         }
3056         else
3057         {
3058                 floatx80 fx80 = floatx80_round_to_int(ST(0));
3059
3060                 floatx80 lowerLim = int32_to_floatx80(-32768);
3061                 floatx80 upperLim = int32_to_floatx80(32767);
3062
3063                 cpustate->x87_sw &= ~X87_SW_C1;
3064
3065                 if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
3066                         m16int = floatx80_to_int32(fx80);
3067                 else
3068                         m16int = (UINT16)0x8000;
3069         }
3070
3071         UINT32 ea = GetEA(cpustate, modrm, 1, 2);
3072         if (x87_check_exceptions(cpustate))
3073         {
3074                 WRITE16(cpustate, ea, m16int);
3075                 x87_inc_stack(cpustate);
3076         }
3077
3078         CYCLES(cpustate, 29);
3079 }
3080
3081 void __FASTCALL x87_fistp_m32int(i386_state *cpustate, UINT8 modrm)
3082 {
3083         INT32 m32int;
3084
3085         if (X87_IS_ST_EMPTY(0))
3086         {
3087                 x87_set_stack_underflow(cpustate);
3088                 m32int = 0x80000000;
3089         }
3090         else
3091         {
3092                 floatx80 fx80 = floatx80_round_to_int(ST(0));
3093
3094                 floatx80 lowerLim = int32_to_floatx80(0x80000000);
3095                 floatx80 upperLim = int32_to_floatx80(0x7fffffff);
3096
3097                 cpustate->x87_sw &= ~X87_SW_C1;
3098
3099                 if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
3100                         m32int = floatx80_to_int32(fx80);
3101                 else
3102                         m32int = 0x80000000;
3103         }
3104
3105         UINT32 ea = GetEA(cpustate, modrm, 1, 4);
3106         if (x87_check_exceptions(cpustate))
3107         {
3108                 WRITE32(cpustate, ea, m32int);
3109                 x87_inc_stack(cpustate);
3110         }
3111
3112         CYCLES(cpustate, 29);
3113 }
3114
3115 void __FASTCALL x87_fistp_m64int(i386_state *cpustate, UINT8 modrm)
3116 {
3117         INT64 m64int;
3118
3119         if (X87_IS_ST_EMPTY(0))
3120         {
3121                 x87_set_stack_underflow(cpustate);
3122                 m64int = U64(0x8000000000000000);
3123         }
3124         else
3125         {
3126                 floatx80 fx80 = floatx80_round_to_int(ST(0));
3127
3128                 floatx80 lowerLim = int64_to_floatx80(U64(0x8000000000000000));
3129                 floatx80 upperLim = int64_to_floatx80(U64(0x7fffffffffffffff));
3130
3131                 cpustate->x87_sw &= ~X87_SW_C1;
3132
3133                 if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim))
3134                         m64int = floatx80_to_int64(fx80);
3135                 else
3136                         m64int = U64(0x8000000000000000);
3137         }
3138
3139         UINT32 ea = GetEA(cpustate, modrm, 1, 8);
3140         if (x87_check_exceptions(cpustate))
3141         {
3142                 WRITE64(cpustate, ea, m64int);
3143                 x87_inc_stack(cpustate);
3144         }
3145
3146         CYCLES(cpustate, 29);
3147 }
3148
3149 void __FASTCALL x87_fbstp(i386_state *cpustate, UINT8 modrm)
3150 {
3151         floatx80 result;
3152
3153         if (X87_IS_ST_EMPTY(0))
3154         {
3155                 x87_set_stack_underflow(cpustate);
3156                 result = fx80_inan;
3157         }
3158         else
3159         {
3160                 UINT64 u64 = floatx80_to_int64(floatx80_abs(ST(0)));
3161                 result.low = 0;
3162
3163                 for (int i = 0; i < 64; i += 4)
3164                 {
3165                         result.low += (u64 % 10) << i;
3166                         u64 /= 10;
3167                 }
3168
3169                 result.high = (u64 % 10);
3170                 result.high += ((u64 / 10) % 10) << 4;
3171                 result.high |= ST(0).high & 0x8000;
3172         }
3173
3174         UINT32 ea = GetEA(cpustate, modrm, 1, 10);
3175         if (x87_check_exceptions(cpustate))
3176         {
3177                 WRITE80(cpustate, ea, result);
3178                 x87_inc_stack(cpustate);
3179         }
3180
3181         CYCLES(cpustate, 175);
3182 }
3183
3184
3185 /*************************************
3186  *
3187  * Constant load
3188  *
3189  *************************************/
3190
3191 void __FASTCALL x87_fld1(i386_state *cpustate, UINT8 modrm)
3192 {
3193         floatx80 value;
3194         int tag;
3195
3196         if (x87_dec_stack(cpustate))
3197         {
3198                 cpustate->x87_sw &= ~X87_SW_C1;
3199                 value = fx80_one;
3200                 tag = X87_TW_VALID;
3201         }
3202         else
3203         {
3204                 value = fx80_inan;
3205                 tag = X87_TW_SPECIAL;
3206         }
3207
3208         if (x87_check_exceptions(cpustate))
3209         {
3210                 x87_set_tag(cpustate, ST_TO_PHYS(0), tag);
3211                 x87_write_stack(cpustate, 0, value, FALSE);
3212         }
3213
3214         CYCLES(cpustate, 4);
3215 }
3216
3217 void __FASTCALL x87_fldl2t(i386_state *cpustate, UINT8 modrm)
3218 {
3219         floatx80 value;
3220         int tag;
3221
3222         if (x87_dec_stack(cpustate))
3223         {
3224                 tag = X87_TW_VALID;
3225                 value.high = 0x4000;
3226
3227                 if (X87_RC == X87_CW_RC_UP)
3228                         value.low =  U64(0xd49a784bcd1b8aff);
3229                 else
3230                         value.low = U64(0xd49a784bcd1b8afe);
3231
3232                 cpustate->x87_sw &= ~X87_SW_C1;
3233         }
3234         else
3235         {
3236                 value = fx80_inan;
3237                 tag = X87_TW_SPECIAL;
3238         }
3239
3240         if (x87_check_exceptions(cpustate))
3241         {
3242                 x87_set_tag(cpustate, ST_TO_PHYS(0), tag);
3243                 x87_write_stack(cpustate, 0, value, FALSE);
3244         }
3245
3246         CYCLES(cpustate, 8);
3247 }
3248
3249 void __FASTCALL x87_fldl2e(i386_state *cpustate, UINT8 modrm)
3250 {
3251         floatx80 value;
3252         int tag;
3253
3254         if (x87_dec_stack(cpustate))
3255         {
3256                 int rc = X87_RC;
3257                 tag = X87_TW_VALID;
3258                 value.high = 0x3fff;
3259
3260                 if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
3261                         value.low = U64(0xb8aa3b295c17f0bc);
3262                 else
3263                         value.low = U64(0xb8aa3b295c17f0bb);
3264
3265                 cpustate->x87_sw &= ~X87_SW_C1;
3266         }
3267         else
3268         {
3269                 value = fx80_inan;
3270                 tag = X87_TW_SPECIAL;
3271         }
3272
3273         if (x87_check_exceptions(cpustate))
3274         {
3275                 x87_set_tag(cpustate, ST_TO_PHYS(0), tag);
3276                 x87_write_stack(cpustate, 0, value, FALSE);
3277         }
3278
3279         CYCLES(cpustate, 8);
3280 }
3281
3282 void __FASTCALL x87_fldpi(i386_state *cpustate, UINT8 modrm)
3283 {
3284         floatx80 value;
3285         int tag;
3286
3287         if (x87_dec_stack(cpustate))
3288         {
3289                 int rc = X87_RC;
3290                 tag = X87_TW_VALID;
3291                 value.high = 0x4000;
3292
3293                 if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
3294                         value.low = U64(0xc90fdaa22168c235);
3295                 else
3296                         value.low = U64(0xc90fdaa22168c234);
3297
3298                 cpustate->x87_sw &= ~X87_SW_C1;
3299         }
3300         else
3301         {
3302                 value = fx80_inan;
3303                 tag = X87_TW_SPECIAL;
3304         }
3305
3306         if (x87_check_exceptions(cpustate))
3307         {
3308                 x87_set_tag(cpustate, ST_TO_PHYS(0), tag);
3309                 x87_write_stack(cpustate, 0, value, FALSE);
3310         }
3311
3312         CYCLES(cpustate, 8);
3313 }
3314
3315 void __FASTCALL x87_fldlg2(i386_state *cpustate, UINT8 modrm)
3316 {
3317         floatx80 value;
3318         int tag;
3319
3320         if (x87_dec_stack(cpustate))
3321         {
3322                 int rc = X87_RC;
3323                 tag = X87_TW_VALID;
3324                 value.high = 0x3ffd;
3325
3326                 if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
3327                         value.low = U64(0x9a209a84fbcff799);
3328                 else
3329                         value.low = U64(0x9a209a84fbcff798);
3330
3331                 cpustate->x87_sw &= ~X87_SW_C1;
3332         }
3333         else
3334         {
3335                 value = fx80_inan;
3336                 tag = X87_TW_SPECIAL;
3337         }
3338
3339         if (x87_check_exceptions(cpustate))
3340         {
3341                 x87_set_tag(cpustate, ST_TO_PHYS(0), tag);
3342                 x87_write_stack(cpustate, 0, value, FALSE);
3343         }
3344
3345         CYCLES(cpustate, 8);
3346 }
3347
3348 void __FASTCALL x87_fldln2(i386_state *cpustate, UINT8 modrm)
3349 {
3350         floatx80 value;
3351         int tag;
3352
3353         if (x87_dec_stack(cpustate))
3354         {
3355                 int rc = X87_RC;
3356                 tag = X87_TW_VALID;
3357                 value.high = 0x3ffe;
3358
3359                 if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST)
3360                         value.low = U64(0xb17217f7d1cf79ac);
3361                 else
3362                         value.low = U64(0xb17217f7d1cf79ab);
3363
3364                 cpustate->x87_sw &= ~X87_SW_C1;
3365         }
3366         else
3367         {
3368                 value = fx80_inan;
3369                 tag = X87_TW_SPECIAL;
3370         }
3371
3372         if (x87_check_exceptions(cpustate))
3373         {
3374                 x87_set_tag(cpustate, ST_TO_PHYS(0), tag);
3375                 x87_write_stack(cpustate, 0, value, FALSE);
3376         }
3377
3378         CYCLES(cpustate, 8);
3379 }
3380
3381 void __FASTCALL x87_fldz(i386_state *cpustate, UINT8 modrm)
3382 {
3383         floatx80 value;
3384         int tag;
3385
3386         if (x87_dec_stack(cpustate))
3387         {
3388                 value = fx80_zero;
3389                 tag = X87_TW_ZERO;
3390                 cpustate->x87_sw &= ~X87_SW_C1;
3391         }
3392         else
3393         {
3394                 value = fx80_inan;
3395                 tag = X87_TW_SPECIAL;
3396         }
3397
3398         if (x87_check_exceptions(cpustate))
3399         {
3400                 x87_set_tag(cpustate, ST_TO_PHYS(0), tag);
3401                 x87_write_stack(cpustate, 0, value, FALSE);
3402         }
3403
3404         CYCLES(cpustate, 4);
3405 }
3406
3407
3408 /*************************************
3409  *
3410  * Miscellaneous
3411  *
3412  *************************************/
3413
3414 void __FASTCALL x87_fnop(i386_state *cpustate, UINT8 modrm)
3415 {
3416         CYCLES(cpustate, 3);
3417 }
3418
3419 void __FASTCALL x87_fchs(i386_state *cpustate, UINT8 modrm)
3420 {
3421         floatx80 value;
3422
3423         if (X87_IS_ST_EMPTY(0))
3424         {
3425                 x87_set_stack_underflow(cpustate);
3426                 value = fx80_inan;
3427         }
3428         else
3429         {
3430                 cpustate->x87_sw &= ~X87_SW_C1;
3431
3432                 value = ST(0);
3433                 value.high ^= 0x8000;
3434         }
3435
3436         if (x87_check_exceptions(cpustate))
3437                 x87_write_stack(cpustate, 0, value, FALSE);
3438
3439         CYCLES(cpustate, 6);
3440 }
3441
3442 void __FASTCALL x87_fabs(i386_state *cpustate, UINT8 modrm)
3443 {
3444         floatx80 value;
3445
3446         if (X87_IS_ST_EMPTY(0))
3447         {
3448                 x87_set_stack_underflow(cpustate);
3449                 value = fx80_inan;
3450         }
3451         else
3452         {
3453                 cpustate->x87_sw &= ~X87_SW_C1;
3454
3455                 value = ST(0);
3456                 value.high &= 0x7fff;
3457         }
3458
3459         if (x87_check_exceptions(cpustate))
3460                 x87_write_stack(cpustate, 0, value, FALSE);
3461
3462         CYCLES(cpustate, 6);
3463 }
3464
3465 void __FASTCALL x87_fscale(i386_state *cpustate, UINT8 modrm)
3466 {
3467         floatx80 value;
3468
3469         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
3470         {
3471                 x87_set_stack_underflow(cpustate);
3472                 value = fx80_inan;
3473         }
3474         else
3475         {
3476                 cpustate->x87_sw &= ~X87_SW_C1;
3477                 value = ST(0);
3478
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);
3483
3484                 // Interpret ST(1) as an integer
3485                 UINT32 st1 = floatx80_to_int32(floatx80_round_to_int(ST(1)));
3486
3487                 // Restore the rounding mode
3488                 x87_write_cw(cpustate, old_cw);
3489
3490                 // Get the unbiased exponent of ST(0)
3491                 INT16 exp = (ST(0).high & 0x7fff) - 0x3fff;
3492
3493                 // Calculate the new exponent
3494                 exp = (exp + st1 + 0x3fff) & 0x7fff;
3495
3496                 // Write it back
3497                 value.high = (value.high & ~0x7fff) + exp;
3498         }
3499
3500         if (x87_check_exceptions(cpustate))
3501                 x87_write_stack(cpustate, 0, value, FALSE);
3502
3503         CYCLES(cpustate, 31);
3504 }
3505
3506 void __FASTCALL x87_frndint(i386_state *cpustate, UINT8 modrm)
3507 {
3508         floatx80 value;
3509
3510         if (X87_IS_ST_EMPTY(0))
3511         {
3512                 x87_set_stack_underflow(cpustate);
3513                 value = fx80_inan;
3514         }
3515         else
3516         {
3517                 cpustate->x87_sw &= ~X87_SW_C1;
3518
3519                 value = floatx80_round_to_int(ST(0));
3520         }
3521
3522         if (x87_check_exceptions(cpustate))
3523                 x87_write_stack(cpustate, 0, value, TRUE);
3524
3525         CYCLES(cpustate, 21);
3526 }
3527
3528 void __FASTCALL x87_fxtract(i386_state *cpustate, UINT8 modrm)
3529 {
3530         floatx80 sig80, exp80;
3531
3532         if (X87_IS_ST_EMPTY(0))
3533         {
3534                 x87_set_stack_underflow(cpustate);
3535                 sig80 = exp80 = fx80_inan;
3536         }
3537         else if (!X87_IS_ST_EMPTY(7))
3538         {
3539                 x87_set_stack_overflow(cpustate);
3540                 sig80 = exp80 = fx80_inan;
3541         }
3542         else
3543         {
3544                 floatx80 value = ST(0);
3545
3546                 if (floatx80_eq(value, fx80_zero))
3547                 {
3548                         cpustate->x87_sw |= X87_SW_ZE;
3549
3550                         exp80 = fx80_ninf;
3551                         sig80 = fx80_zero;
3552                 }
3553                 else
3554                 {
3555                         // Extract the unbiased exponent
3556                         exp80 = int32_to_floatx80((value.high & 0x7fff) - 0x3fff);
3557
3558                         // For the significand, replicate the original value and set its true exponent to 0.
3559                         sig80 = value;
3560                         sig80.high &= ~0x7fff;
3561                         sig80.high |=  0x3fff;
3562                 }
3563         }
3564
3565         if (x87_check_exceptions(cpustate))
3566         {
3567                 x87_write_stack(cpustate, 0, exp80, TRUE);
3568                 x87_dec_stack(cpustate);
3569                 x87_write_stack(cpustate, 0, sig80, TRUE);
3570         }
3571
3572         CYCLES(cpustate, 21);
3573 }
3574
3575 /*************************************
3576  *
3577  * Comparison
3578  *
3579  *************************************/
3580
3581 void __FASTCALL x87_ftst(i386_state *cpustate, UINT8 modrm)
3582 {
3583         if (X87_IS_ST_EMPTY(0))
3584         {
3585                 x87_set_stack_underflow(cpustate);
3586                 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3587         }
3588         else
3589         {
3590                 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3591
3592                 if (floatx80_is_nan(ST(0)))
3593                 {
3594                         cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3595                         cpustate->x87_sw |= X87_SW_IE;
3596                 }
3597                 else
3598                 {
3599                         if (floatx80_eq(ST(0), fx80_zero))
3600                                 cpustate->x87_sw |= X87_SW_C3;
3601
3602                         if (floatx80_lt(ST(0), fx80_zero))
3603                                 cpustate->x87_sw |= X87_SW_C0;
3604                 }
3605         }
3606
3607         x87_check_exceptions(cpustate);
3608
3609         CYCLES(cpustate, 4);
3610 }
3611
3612 void __FASTCALL x87_fxam(i386_state *cpustate, UINT8 modrm)
3613 {
3614         floatx80 value = ST(0);
3615
3616         cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3617
3618         // TODO: Unsupported and denormal values
3619         if (X87_IS_ST_EMPTY(0))
3620         {
3621                 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C0;
3622         }
3623         else if (floatx80_is_zero(value))
3624         {
3625                 cpustate->x87_sw |= X87_SW_C3;
3626         }
3627         else if (floatx80_is_nan(value))
3628         {
3629                 cpustate->x87_sw |= X87_SW_C0;
3630         }
3631         else if (floatx80_is_inf(value))
3632         {
3633                 cpustate->x87_sw |= X87_SW_C2 | X87_SW_C0;
3634         }
3635         else
3636         {
3637                 cpustate->x87_sw |= X87_SW_C2;
3638         }
3639
3640         if (value.high & 0x8000)
3641                 cpustate->x87_sw |= X87_SW_C1;
3642
3643         CYCLES(cpustate, 8);
3644 }
3645
3646 void __FASTCALL x87_ficom_m16int(i386_state *cpustate, UINT8 modrm)
3647 {
3648         UINT32 ea = GetEA(cpustate, modrm, 0, 2);
3649         if (X87_IS_ST_EMPTY(0))
3650         {
3651                 x87_set_stack_underflow(cpustate);
3652                 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3653         }
3654         else
3655         {
3656                 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3657
3658                 INT16 m16int = READ16(cpustate, ea);
3659
3660                 floatx80 a = ST(0);
3661                 floatx80 b = int32_to_floatx80(m16int);
3662
3663                 if (floatx80_is_nan(a))
3664                 {
3665                         cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3666                         cpustate->x87_sw |= X87_SW_IE;
3667                 }
3668                 else
3669                 {
3670                         if (floatx80_eq(a, b))
3671                                 cpustate->x87_sw |= X87_SW_C3;
3672
3673                         if (floatx80_lt(a, b))
3674                                 cpustate->x87_sw |= X87_SW_C0;
3675                 }
3676         }
3677
3678         x87_check_exceptions(cpustate);
3679
3680         CYCLES(cpustate, 16);
3681 }
3682
3683 void __FASTCALL x87_ficom_m32int(i386_state *cpustate, UINT8 modrm)
3684 {
3685         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
3686         if (X87_IS_ST_EMPTY(0))
3687         {
3688                 x87_set_stack_underflow(cpustate);
3689                 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3690         }
3691         else
3692         {
3693                 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3694
3695                 INT32 m32int = READ32(cpustate, ea);
3696
3697                 floatx80 a = ST(0);
3698                 floatx80 b = int32_to_floatx80(m32int);
3699
3700                 if (floatx80_is_nan(a))
3701                 {
3702                         cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3703                         cpustate->x87_sw |= X87_SW_IE;
3704                 }
3705                 else
3706                 {
3707                         if (floatx80_eq(a, b))
3708                                 cpustate->x87_sw |= X87_SW_C3;
3709
3710                         if (floatx80_lt(a, b))
3711                                 cpustate->x87_sw |= X87_SW_C0;
3712                 }
3713         }
3714
3715         x87_check_exceptions(cpustate);
3716
3717         CYCLES(cpustate, 15);
3718 }
3719
3720 void __FASTCALL x87_ficomp_m16int(i386_state *cpustate, UINT8 modrm)
3721 {
3722         UINT32 ea = GetEA(cpustate, modrm, 0, 2);
3723         if (X87_IS_ST_EMPTY(0))
3724         {
3725                 x87_set_stack_underflow(cpustate);
3726                 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3727         }
3728         else
3729         {
3730                 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3731
3732                 INT16 m16int = READ16(cpustate, ea);
3733
3734                 floatx80 a = ST(0);
3735                 floatx80 b = int32_to_floatx80(m16int);
3736
3737                 if (floatx80_is_nan(a))
3738                 {
3739                         cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3740                         cpustate->x87_sw |= X87_SW_IE;
3741                 }
3742                 else
3743                 {
3744                         if (floatx80_eq(a, b))
3745                                 cpustate->x87_sw |= X87_SW_C3;
3746
3747                         if (floatx80_lt(a, b))
3748                                 cpustate->x87_sw |= X87_SW_C0;
3749                 }
3750         }
3751
3752         if (x87_check_exceptions(cpustate))
3753                 x87_inc_stack(cpustate);
3754
3755         CYCLES(cpustate, 16);
3756 }
3757
3758 void __FASTCALL x87_ficomp_m32int(i386_state *cpustate, UINT8 modrm)
3759 {
3760         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
3761         if (X87_IS_ST_EMPTY(0))
3762         {
3763                 x87_set_stack_underflow(cpustate);
3764                 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3765         }
3766         else
3767         {
3768                 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3769
3770                 INT32 m32int = READ32(cpustate, ea);
3771
3772                 floatx80 a = ST(0);
3773                 floatx80 b = int32_to_floatx80(m32int);
3774
3775                 if (floatx80_is_nan(a))
3776                 {
3777                         cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3778                         cpustate->x87_sw |= X87_SW_IE;
3779                 }
3780                 else
3781                 {
3782                         if (floatx80_eq(a, b))
3783                                 cpustate->x87_sw |= X87_SW_C3;
3784
3785                         if (floatx80_lt(a, b))
3786                                 cpustate->x87_sw |= X87_SW_C0;
3787                 }
3788         }
3789
3790         if (x87_check_exceptions(cpustate))
3791                 x87_inc_stack(cpustate);
3792
3793         CYCLES(cpustate, 15);
3794 }
3795
3796
3797 void __FASTCALL x87_fcom_m32real(i386_state *cpustate, UINT8 modrm)
3798 {
3799         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
3800         if (X87_IS_ST_EMPTY(0))
3801         {
3802                 x87_set_stack_underflow(cpustate);
3803                 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3804         }
3805         else
3806         {
3807                 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3808
3809                 UINT32 m32real = READ32(cpustate, ea);
3810
3811                 floatx80 a = ST(0);
3812                 floatx80 b = float32_to_floatx80(m32real);
3813
3814                 if (floatx80_is_nan(a) || floatx80_is_nan(b))
3815                 {
3816                         cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3817                         cpustate->x87_sw |= X87_SW_IE;
3818                 }
3819                 else
3820                 {
3821                         if (floatx80_eq(a, b))
3822                                 cpustate->x87_sw |= X87_SW_C3;
3823
3824                         if (floatx80_lt(a, b))
3825                                 cpustate->x87_sw |= X87_SW_C0;
3826                 }
3827         }
3828
3829         x87_check_exceptions(cpustate);
3830
3831         CYCLES(cpustate, 4);
3832 }
3833
3834 void __FASTCALL x87_fcom_m64real(i386_state *cpustate, UINT8 modrm)
3835 {
3836         UINT32 ea = GetEA(cpustate, modrm, 0, 8);
3837         if (X87_IS_ST_EMPTY(0))
3838         {
3839                 x87_set_stack_underflow(cpustate);
3840                 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3841         }
3842         else
3843         {
3844                 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3845
3846                 UINT64 m64real = READ64(cpustate, ea);
3847
3848                 floatx80 a = ST(0);
3849                 floatx80 b = float64_to_floatx80(m64real);
3850
3851                 if (floatx80_is_nan(a) || floatx80_is_nan(b))
3852                 {
3853                         cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3854                         cpustate->x87_sw |= X87_SW_IE;
3855                 }
3856                 else
3857                 {
3858                         if (floatx80_eq(a, b))
3859                                 cpustate->x87_sw |= X87_SW_C3;
3860
3861                         if (floatx80_lt(a, b))
3862                                 cpustate->x87_sw |= X87_SW_C0;
3863                 }
3864         }
3865
3866         x87_check_exceptions(cpustate);
3867
3868         CYCLES(cpustate, 4);
3869 }
3870
3871 void __FASTCALL x87_fcom_sti(i386_state *cpustate, UINT8 modrm)
3872 {
3873         int i = modrm & 7;
3874
3875         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
3876         {
3877                 x87_set_stack_underflow(cpustate);
3878                 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3879         }
3880         else
3881         {
3882                 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3883
3884                 floatx80 a = ST(0);
3885                 floatx80 b = ST(i);
3886
3887                 if (floatx80_is_nan(a) || floatx80_is_nan(b))
3888                 {
3889                         cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3890                         cpustate->x87_sw |= X87_SW_IE;
3891                 }
3892                 else
3893                 {
3894                         if (floatx80_eq(a, b))
3895                                 cpustate->x87_sw |= X87_SW_C3;
3896
3897                         if (floatx80_lt(a, b))
3898                                 cpustate->x87_sw |= X87_SW_C0;
3899                 }
3900         }
3901
3902         x87_check_exceptions(cpustate);
3903
3904         CYCLES(cpustate, 4);
3905 }
3906
3907 void __FASTCALL x87_fcomp_m32real(i386_state *cpustate, UINT8 modrm)
3908 {
3909         UINT32 ea = GetEA(cpustate, modrm, 0, 4);
3910         if (X87_IS_ST_EMPTY(0))
3911         {
3912                 x87_set_stack_underflow(cpustate);
3913                 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3914         }
3915         else
3916         {
3917                 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3918
3919                 UINT32 m32real = READ32(cpustate, ea);
3920
3921                 floatx80 a = ST(0);
3922                 floatx80 b = float32_to_floatx80(m32real);
3923
3924                 if (floatx80_is_nan(a) || floatx80_is_nan(b))
3925                 {
3926                         cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3927                         cpustate->x87_sw |= X87_SW_IE;
3928                 }
3929                 else
3930                 {
3931                         if (floatx80_eq(a, b))
3932                                 cpustate->x87_sw |= X87_SW_C3;
3933
3934                         if (floatx80_lt(a, b))
3935                                 cpustate->x87_sw |= X87_SW_C0;
3936                 }
3937         }
3938
3939         if (x87_check_exceptions(cpustate))
3940                 x87_inc_stack(cpustate);
3941
3942         CYCLES(cpustate, 4);
3943 }
3944
3945 void __FASTCALL x87_fcomp_m64real(i386_state *cpustate, UINT8 modrm)
3946 {
3947         UINT32 ea = GetEA(cpustate, modrm, 0, 8);
3948         if (X87_IS_ST_EMPTY(0))
3949         {
3950                 x87_set_stack_underflow(cpustate);
3951                 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3952         }
3953         else
3954         {
3955                 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3956
3957                 UINT64 m64real = READ64(cpustate, ea);
3958
3959                 floatx80 a = ST(0);
3960                 floatx80 b = float64_to_floatx80(m64real);
3961
3962                 if (floatx80_is_nan(a) || floatx80_is_nan(b))
3963                 {
3964                         cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
3965                         cpustate->x87_sw |= X87_SW_IE;
3966                 }
3967                 else
3968                 {
3969                         if (floatx80_eq(a, b))
3970                                 cpustate->x87_sw |= X87_SW_C3;
3971
3972                         if (floatx80_lt(a, b))
3973                                 cpustate->x87_sw |= X87_SW_C0;
3974                 }
3975         }
3976
3977         if (x87_check_exceptions(cpustate))
3978                 x87_inc_stack(cpustate);
3979
3980         CYCLES(cpustate, 4);
3981 }
3982
3983 void __FASTCALL x87_fcomp_sti(i386_state *cpustate, UINT8 modrm)
3984 {
3985         int i = modrm & 7;
3986
3987         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
3988         {
3989                 x87_set_stack_underflow(cpustate);
3990                 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
3991         }
3992         else
3993         {
3994                 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
3995
3996                 floatx80 a = ST(0);
3997                 floatx80 b = ST(i);
3998
3999                 if (floatx80_is_nan(a) || floatx80_is_nan(b))
4000                 {
4001                         cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
4002                         cpustate->x87_sw |= X87_SW_IE;
4003                 }
4004                 else
4005                 {
4006                         if (floatx80_eq(a, b))
4007                                 cpustate->x87_sw |= X87_SW_C3;
4008
4009                         if (floatx80_lt(a, b))
4010                                 cpustate->x87_sw |= X87_SW_C0;
4011                 }
4012         }
4013
4014         if (x87_check_exceptions(cpustate))
4015                 x87_inc_stack(cpustate);
4016
4017         CYCLES(cpustate, 4);
4018 }
4019
4020 void __FASTCALL x87_fcomi_sti(i386_state *cpustate, UINT8 modrm)
4021 {
4022         int i = modrm & 7;
4023
4024         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
4025         {
4026                 x87_set_stack_underflow(cpustate);
4027                 cpustate->ZF = 1;
4028                 cpustate->PF = 1;
4029                 cpustate->CF = 1;
4030         }
4031         else
4032         {
4033                 cpustate->x87_sw &= ~X87_SW_C1;
4034
4035                 floatx80 a = ST(0);
4036                 floatx80 b = ST(i);
4037
4038                 if (floatx80_is_nan(a) || floatx80_is_nan(b))
4039                 {
4040                         cpustate->ZF = 1;
4041                         cpustate->PF = 1;
4042                         cpustate->CF = 1;
4043                         cpustate->x87_sw |= X87_SW_IE;
4044                 }
4045                 else
4046                 {
4047                         cpustate->ZF = 0;
4048                         cpustate->PF = 0;
4049                         cpustate->CF = 0;
4050
4051                         if (floatx80_eq(a, b))
4052                                 cpustate->ZF = 1;
4053
4054                         if (floatx80_lt(a, b))
4055                                 cpustate->CF = 1;
4056                 }
4057         }
4058
4059         x87_check_exceptions(cpustate);
4060
4061         CYCLES(cpustate, 4); // TODO: correct cycle count
4062 }
4063
4064 void __FASTCALL x87_fcomip_sti(i386_state *cpustate, UINT8 modrm)
4065 {
4066         int i = modrm & 7;
4067
4068         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
4069         {
4070                 x87_set_stack_underflow(cpustate);
4071                 cpustate->ZF = 1;
4072                 cpustate->PF = 1;
4073                 cpustate->CF = 1;
4074         }
4075         else
4076         {
4077                 cpustate->x87_sw &= ~X87_SW_C1;
4078
4079                 floatx80 a = ST(0);
4080                 floatx80 b = ST(i);
4081
4082                 if (floatx80_is_nan(a) || floatx80_is_nan(b))
4083                 {
4084                         cpustate->ZF = 1;
4085                         cpustate->PF = 1;
4086                         cpustate->CF = 1;
4087                         cpustate->x87_sw |= X87_SW_IE;
4088                 }
4089                 else
4090                 {
4091                         cpustate->ZF = 0;
4092                         cpustate->PF = 0;
4093                         cpustate->CF = 0;
4094
4095                         if (floatx80_eq(a, b))
4096                                 cpustate->ZF = 1;
4097
4098                         if (floatx80_lt(a, b))
4099                                 cpustate->CF = 1;
4100                 }
4101         }
4102
4103         if (x87_check_exceptions(cpustate))
4104                 x87_inc_stack(cpustate);
4105
4106         CYCLES(cpustate, 4); // TODO: correct cycle count
4107 }
4108
4109 void __FASTCALL x87_fucomi_sti(i386_state *cpustate, UINT8 modrm)
4110 {
4111         int i = modrm & 7;
4112
4113         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
4114         {
4115                 x87_set_stack_underflow(cpustate);
4116                 cpustate->ZF = 1;
4117                 cpustate->PF = 1;
4118                 cpustate->CF = 1;
4119         }
4120         else
4121         {
4122                 cpustate->x87_sw &= ~X87_SW_C1;
4123
4124                 floatx80 a = ST(0);
4125                 floatx80 b = ST(i);
4126
4127                 if (floatx80_is_quiet_nan(a) || floatx80_is_quiet_nan(b))
4128                 {
4129                         cpustate->ZF = 1;
4130                         cpustate->PF = 1;
4131                         cpustate->CF = 1;
4132                 }
4133                 else if (floatx80_is_nan(a) || floatx80_is_nan(b))
4134                 {
4135                         cpustate->ZF = 1;
4136                         cpustate->PF = 1;
4137                         cpustate->CF = 1;
4138                         cpustate->x87_sw |= X87_SW_IE;
4139                 }
4140                 else
4141                 {
4142                         cpustate->ZF = 0;
4143                         cpustate->PF = 0;
4144                         cpustate->CF = 0;
4145
4146                         if (floatx80_eq(a, b))
4147                                 cpustate->ZF = 1;
4148
4149                         if (floatx80_lt(a, b))
4150                                 cpustate->CF = 1;
4151                 }
4152         }
4153
4154         x87_check_exceptions(cpustate);
4155
4156         CYCLES(cpustate, 4); // TODO: correct cycle count
4157 }
4158
4159 void __FASTCALL x87_fucomip_sti(i386_state *cpustate, UINT8 modrm)
4160 {
4161         int i = modrm & 7;
4162
4163         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
4164         {
4165                 x87_set_stack_underflow(cpustate);
4166                 cpustate->ZF = 1;
4167                 cpustate->PF = 1;
4168                 cpustate->CF = 1;
4169         }
4170         else
4171         {
4172                 cpustate->x87_sw &= ~X87_SW_C1;
4173
4174                 floatx80 a = ST(0);
4175                 floatx80 b = ST(i);
4176
4177                 if (floatx80_is_quiet_nan(a) || floatx80_is_quiet_nan(b))
4178                 {
4179                         cpustate->ZF = 1;
4180                         cpustate->PF = 1;
4181                         cpustate->CF = 1;
4182                 }
4183                 else if (floatx80_is_nan(a) || floatx80_is_nan(b))
4184                 {
4185                         cpustate->ZF = 1;
4186                         cpustate->PF = 1;
4187                         cpustate->CF = 1;
4188                         cpustate->x87_sw |= X87_SW_IE;
4189                 }
4190                 else
4191                 {
4192                         cpustate->ZF = 0;
4193                         cpustate->PF = 0;
4194                         cpustate->CF = 0;
4195
4196                         if (floatx80_eq(a, b))
4197                                 cpustate->ZF = 1;
4198
4199                         if (floatx80_lt(a, b))
4200                                 cpustate->CF = 1;
4201                 }
4202         }
4203
4204         if (x87_check_exceptions(cpustate))
4205                 x87_inc_stack(cpustate);
4206
4207         CYCLES(cpustate, 4); // TODO: correct cycle count
4208 }
4209
4210 void __FASTCALL x87_fcompp(i386_state *cpustate, UINT8 modrm)
4211 {
4212         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
4213         {
4214                 x87_set_stack_underflow(cpustate);
4215                 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
4216         }
4217         else
4218         {
4219                 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
4220
4221                 floatx80 a = ST(0);
4222                 floatx80 b = ST(1);
4223
4224                 if (floatx80_is_nan(a) || floatx80_is_nan(b))
4225                 {
4226                         cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
4227                         cpustate->x87_sw |= X87_SW_IE;
4228                 }
4229                 else
4230                 {
4231                         if (floatx80_eq(a, b))
4232                                 cpustate->x87_sw |= X87_SW_C3;
4233
4234                         if (floatx80_lt(a, b))
4235                                 cpustate->x87_sw |= X87_SW_C0;
4236                 }
4237         }
4238
4239         if (x87_check_exceptions(cpustate))
4240         {
4241                 x87_inc_stack(cpustate);
4242                 x87_inc_stack(cpustate);
4243         }
4244
4245         CYCLES(cpustate, 5);
4246 }
4247
4248
4249 /*************************************
4250  *
4251  * Unordererd comparison
4252  *
4253  *************************************/
4254
4255 void __FASTCALL x87_fucom_sti(i386_state *cpustate, UINT8 modrm)
4256 {
4257         int i = modrm & 7;
4258
4259         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
4260         {
4261                 x87_set_stack_underflow(cpustate);
4262                 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
4263         }
4264         else
4265         {
4266                 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
4267
4268                 floatx80 a = ST(0);
4269                 floatx80 b = ST(i);
4270
4271                 if (floatx80_is_nan(a) || floatx80_is_nan(b))
4272                 {
4273                         cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
4274
4275                         if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
4276                                 cpustate->x87_sw |= X87_SW_IE;
4277                 }
4278                 else
4279                 {
4280                         if (floatx80_eq(a, b))
4281                                 cpustate->x87_sw |= X87_SW_C3;
4282
4283                         if (floatx80_lt(a, b))
4284                                 cpustate->x87_sw |= X87_SW_C0;
4285                 }
4286         }
4287
4288         x87_check_exceptions(cpustate);
4289
4290         CYCLES(cpustate, 4);
4291 }
4292
4293 void __FASTCALL x87_fucomp_sti(i386_state *cpustate, UINT8 modrm)
4294 {
4295         int i = modrm & 7;
4296
4297         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i))
4298         {
4299                 x87_set_stack_underflow(cpustate);
4300                 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
4301         }
4302         else
4303         {
4304                 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
4305
4306                 floatx80 a = ST(0);
4307                 floatx80 b = ST(i);
4308
4309                 if (floatx80_is_nan(a) || floatx80_is_nan(b))
4310                 {
4311                         cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
4312
4313                         if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
4314                                 cpustate->x87_sw |= X87_SW_IE;
4315                 }
4316                 else
4317                 {
4318                         if (floatx80_eq(a, b))
4319                                 cpustate->x87_sw |= X87_SW_C3;
4320
4321                         if (floatx80_lt(a, b))
4322                                 cpustate->x87_sw |= X87_SW_C0;
4323                 }
4324         }
4325
4326         if (x87_check_exceptions(cpustate))
4327                 x87_inc_stack(cpustate);
4328
4329         CYCLES(cpustate, 4);
4330 }
4331
4332 void __FASTCALL x87_fucompp(i386_state *cpustate, UINT8 modrm)
4333 {
4334         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
4335         {
4336                 x87_set_stack_underflow(cpustate);
4337                 cpustate->x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0;
4338         }
4339         else
4340         {
4341                 cpustate->x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0);
4342
4343                 floatx80 a = ST(0);
4344                 floatx80 b = ST(1);
4345
4346                 if (floatx80_is_nan(a) || floatx80_is_nan(b))
4347                 {
4348                         cpustate->x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3;
4349
4350                         if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
4351                                 cpustate->x87_sw |= X87_SW_IE;
4352                 }
4353                 else
4354                 {
4355                         if (floatx80_eq(a, b))
4356                                 cpustate->x87_sw |= X87_SW_C3;
4357
4358                         if (floatx80_lt(a, b))
4359                                 cpustate->x87_sw |= X87_SW_C0;
4360                 }
4361         }
4362
4363         if (x87_check_exceptions(cpustate))
4364         {
4365                 x87_inc_stack(cpustate);
4366                 x87_inc_stack(cpustate);
4367         }
4368
4369         CYCLES(cpustate, 4);
4370 }
4371
4372
4373 /*************************************
4374  *
4375  * Control
4376  *
4377  *************************************/
4378
4379 void __FASTCALL x87_fdecstp(i386_state *cpustate, UINT8 modrm)
4380 {
4381         cpustate->x87_sw &= ~X87_SW_C1;
4382
4383         x87_set_stack_top(cpustate, ST_TO_PHYS(7));
4384
4385         CYCLES(cpustate, 3);
4386 }
4387
4388 void __FASTCALL x87_fincstp(i386_state *cpustate, UINT8 modrm)
4389 {
4390         cpustate->x87_sw &= ~X87_SW_C1;
4391
4392         x87_set_stack_top(cpustate, ST_TO_PHYS(1));
4393
4394         CYCLES(cpustate, 3);
4395 }
4396
4397 void __FASTCALL x87_fclex(i386_state *cpustate, UINT8 modrm)
4398 {
4399         cpustate->x87_sw &= ~0x80ff;
4400 //      ferr_handler(cpustate, 0);
4401         CYCLES(cpustate, 7);
4402 }
4403
4404 void __FASTCALL x87_feni(i386_state *cpustate, UINT8 modrm)
4405 {
4406         cpustate->x87_cw &= ~X87_CW_IEM;
4407         x87_check_exceptions(cpustate);
4408
4409         CYCLES(cpustate, 5);
4410 }
4411
4412 void __FASTCALL x87_fdisi(i386_state *cpustate, UINT8 modrm)
4413 {
4414         cpustate->x87_cw |= X87_CW_IEM;
4415
4416         CYCLES(cpustate, 5);
4417 }
4418
4419 void __FASTCALL x87_ffree(i386_state *cpustate, UINT8 modrm)
4420 {
4421         x87_set_tag(cpustate, ST_TO_PHYS(modrm & 7), X87_TW_EMPTY);
4422
4423         CYCLES(cpustate, 3);
4424 }
4425
4426 void __FASTCALL x87_finit(i386_state *cpustate, UINT8 modrm)
4427 {
4428         x87_reset(cpustate);
4429
4430         CYCLES(cpustate, 17);
4431 }
4432
4433 void __FASTCALL x87_fldcw(i386_state *cpustate, UINT8 modrm)
4434 {
4435         UINT32 ea = GetEA(cpustate, modrm, 0, 2);
4436         UINT16 cw = READ16(cpustate, ea);
4437
4438         x87_write_cw(cpustate, cw);
4439
4440         x87_check_exceptions(cpustate);
4441
4442         CYCLES(cpustate, 4);
4443 }
4444
4445 void __FASTCALL x87_fstcw(i386_state *cpustate, UINT8 modrm)
4446 {
4447         UINT32 ea = GetEA(cpustate, modrm, 1, 2);
4448         WRITE16(cpustate, ea, cpustate->x87_cw);
4449
4450         CYCLES(cpustate, 3);
4451 }
4452
4453 void __FASTCALL x87_fldenv(i386_state *cpustate, UINT8 modrm)
4454 {
4455         // TODO: Pointers and selectors
4456         if (cpustate->operand_size)
4457         {
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);
4463         }
4464         else
4465         {
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);
4471         }
4472
4473         x87_check_exceptions(cpustate);
4474
4475         CYCLES(cpustate,(cpustate->cr[0] & 1) ? 34 : 44);
4476 }
4477
4478 void __FASTCALL x87_fstenv(i386_state *cpustate, UINT8 modrm)
4479 {
4480         UINT32 ea;
4481
4482         // TODO: Pointers and selectors
4483         switch((cpustate->cr[0] & 1)|(cpustate->operand_size & 1)<<1)
4484         {
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);
4494                         break;
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);
4504                         break;
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);
4515                         break;
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);
4525                         break;
4526         }
4527         cpustate->x87_cw |= 0x3f;   // set all masks
4528
4529         CYCLES(cpustate,(cpustate->cr[0] & 1) ? 56 : 67);
4530 }
4531
4532 void __FASTCALL x87_fsave(i386_state *cpustate, UINT8 modrm)
4533 {
4534         UINT32 ea = GetEA(cpustate, modrm, 1, 80);
4535
4536         // TODO: Pointers and selectors
4537         switch((cpustate->cr[0] & 1)|(cpustate->operand_size & 1)<<1)
4538         {
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);
4547                         ea += 14;
4548                         break;
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);
4557                         ea += 14;
4558                         break;
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);
4568                         ea += 28;
4569                         break;
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);
4578                         ea += 28;
4579                         break;
4580         }
4581
4582         for (int i = 0; i < 8; ++i)
4583                 WRITE80(cpustate, ea + i*10, ST(i));
4584
4585         CYCLES(cpustate,(cpustate->cr[0] & 1) ? 56 : 67);
4586 }
4587
4588 void __FASTCALL x87_frstor(i386_state *cpustate, UINT8 modrm)
4589 {
4590         UINT32 ea = GetEA(cpustate, modrm, 0, 80);
4591
4592         // TODO: Pointers and selectors
4593         switch((cpustate->cr[0] & 1)|(cpustate->operand_size & 1)<<1)
4594         {
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);
4603                         ea += 14;
4604                         break;
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);
4613                         ea += 14;
4614                         break;
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);
4624                         ea += 28;
4625                         break;
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);
4634                         ea += 28;
4635                         break;
4636         }
4637
4638         for (int i = 0; i < 8; ++i)
4639                 x87_write_stack(cpustate, i, READ80(cpustate, ea + i*10), FALSE);
4640
4641         CYCLES(cpustate,(cpustate->cr[0] & 1) ? 34 : 44);
4642 }
4643
4644 void __FASTCALL x87_fxch(i386_state *cpustate, UINT8 modrm)
4645 {
4646         if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1))
4647                 x87_set_stack_underflow(cpustate);
4648
4649         if (x87_check_exceptions(cpustate))
4650         {
4651                 floatx80 tmp = ST(0);
4652                 ST(0) = ST(1);
4653                 ST(1) = tmp;
4654
4655                 // Swap the tags
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);
4659         }
4660
4661         CYCLES(cpustate, 4);
4662 }
4663
4664 void __FASTCALL x87_fxch_sti(i386_state *cpustate, UINT8 modrm)
4665 {
4666         int i = modrm & 7;
4667
4668         if (X87_IS_ST_EMPTY(0))
4669         {
4670                 ST(0) = fx80_inan;
4671                 x87_set_tag(cpustate, ST_TO_PHYS(0), X87_TW_SPECIAL);
4672                 x87_set_stack_underflow(cpustate);
4673         }
4674         if (X87_IS_ST_EMPTY(i))
4675         {
4676                 ST(i) = fx80_inan;
4677                 x87_set_tag(cpustate, ST_TO_PHYS(i), X87_TW_SPECIAL);
4678                 x87_set_stack_underflow(cpustate);
4679         }
4680
4681         if (x87_check_exceptions(cpustate))
4682         {
4683                 floatx80 tmp = ST(0);
4684                 ST(0) = ST(i);
4685                 ST(i) = tmp;
4686
4687                 // Swap the tags
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);
4691         }
4692
4693         CYCLES(cpustate, 4);
4694 }
4695
4696 void __FASTCALL x87_fstsw_ax(i386_state *cpustate, UINT8 modrm)
4697 {
4698         REG16(AX) = cpustate->x87_sw;
4699
4700         CYCLES(cpustate, 3);
4701 }
4702
4703 void __FASTCALL x87_fstsw_m2byte(i386_state *cpustate, UINT8 modrm)
4704 {
4705         UINT32 ea = GetEA(cpustate, modrm, 1, 2);
4706
4707         WRITE16(cpustate, ea, cpustate->x87_sw);
4708
4709         CYCLES(cpustate, 3);
4710 }
4711
4712 void __FASTCALL __FASTCALL x87_invalid(i386_state *cpustate, UINT8 modrm)
4713 {
4714         // TODO
4715         report_invalid_opcode(cpustate);
4716         i386_trap(cpustate, 6, 0, 0);
4717 }
4718
4719
4720
4721 /*************************************
4722  *
4723  * Instruction dispatch
4724  *
4725  *************************************/
4726
4727 static void __FASTCALL I386OP(x87_group_d8)(i386_state *cpustate)
4728 {
4729         UINT8 modrm = FETCH(cpustate);
4730         cpustate->opcode_table_x87_d8[modrm](cpustate, modrm);
4731 }
4732
4733 static void __FASTCALL I386OP(x87_group_d9)(i386_state *cpustate)
4734 {
4735         UINT8 modrm = FETCH(cpustate);
4736         cpustate->opcode_table_x87_d9[modrm](cpustate, modrm);
4737 }
4738
4739 static void __FASTCALL I386OP(x87_group_da)(i386_state *cpustate)
4740 {
4741         UINT8 modrm = FETCH(cpustate);
4742         cpustate->opcode_table_x87_da[modrm](cpustate, modrm);
4743 }
4744
4745 static void __FASTCALL I386OP(x87_group_db)(i386_state *cpustate)
4746 {
4747         UINT8 modrm = FETCH(cpustate);
4748         cpustate->opcode_table_x87_db[modrm](cpustate, modrm);
4749 }
4750
4751 static void __FASTCALL I386OP(x87_group_dc)(i386_state *cpustate)
4752 {
4753         UINT8 modrm = FETCH(cpustate);
4754         cpustate->opcode_table_x87_dc[modrm](cpustate, modrm);
4755 }
4756
4757 static void __FASTCALL I386OP(x87_group_dd)(i386_state *cpustate)
4758 {
4759         UINT8 modrm = FETCH(cpustate);
4760         cpustate->opcode_table_x87_dd[modrm](cpustate, modrm);
4761 }
4762
4763 static void __FASTCALL I386OP(x87_group_de)(i386_state *cpustate)
4764 {
4765         UINT8 modrm = FETCH(cpustate);
4766         cpustate->opcode_table_x87_de[modrm](cpustate, modrm);
4767 }
4768
4769 static void __FASTCALL I386OP(x87_group_df)(i386_state *cpustate)
4770 {
4771         UINT8 modrm = FETCH(cpustate);
4772         cpustate->opcode_table_x87_df[modrm](cpustate, modrm);
4773 }
4774
4775
4776 /*************************************
4777  *
4778  * Opcode table building
4779  *
4780  *************************************/
4781
4782 void build_x87_opcode_table_d8(i386_state *cpustate)
4783 {
4784         int modrm = 0;
4785
4786         for (modrm = 0; modrm < 0x100; ++modrm)
4787         {
4788                 void (__FASTCALL *ptr)(i386_state *cpustate, UINT8 modrm) = x87_invalid;
4789
4790                 if (modrm < 0xc0)
4791                 {
4792                         switch ((modrm >> 3) & 0x7)
4793                         {
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;
4802                         }
4803                 }
4804                 else
4805                 {
4806                         switch (modrm)
4807                         {
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;
4816                         }
4817                 }
4818
4819                 cpustate->opcode_table_x87_d8[modrm] = ptr;
4820         }
4821 }
4822
4823
4824 void build_x87_opcode_table_d9(i386_state *cpustate)
4825 {
4826         int modrm = 0;
4827
4828         for (modrm = 0; modrm < 0x100; ++modrm)
4829         {
4830                 void (__FASTCALL *ptr)(i386_state *cpustate, UINT8 modrm) = x87_invalid;
4831
4832                 if (modrm < 0xc0)
4833                 {
4834                         switch ((modrm >> 3) & 0x7)
4835                         {
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;
4843                         }
4844                 }
4845                 else
4846                 {
4847                         switch (modrm)
4848                         {
4849                                 case 0xc0:
4850                                 case 0xc1:
4851                                 case 0xc2:
4852                                 case 0xc3:
4853                                 case 0xc4:
4854                                 case 0xc5:
4855                                 case 0xc6:
4856                                 case 0xc7: ptr = x87_fld_sti;   break;
4857
4858                                 case 0xc8:
4859                                 case 0xc9:
4860                                 case 0xca:
4861                                 case 0xcb:
4862                                 case 0xcc:
4863                                 case 0xcd:
4864                                 case 0xce:
4865                                 case 0xcf: ptr = x87_fxch_sti;  break;
4866
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;
4895                         }
4896                 }
4897
4898                 cpustate->opcode_table_x87_d9[modrm] = ptr;
4899         }
4900 }
4901
4902 void build_x87_opcode_table_da(i386_state *cpustate)
4903 {
4904         int modrm = 0;
4905
4906         for (modrm = 0; modrm < 0x100; ++modrm)
4907         {
4908                 void (__FASTCALL *ptr)(i386_state *cpustate, UINT8 modrm) = x87_invalid;
4909
4910                 if (modrm < 0xc0)
4911                 {
4912                         switch ((modrm >> 3) & 0x7)
4913                         {
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;
4922                         }
4923                 }
4924                 else
4925                 {
4926                         switch (modrm)
4927                         {
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;
4933                         }
4934                 }
4935
4936                 cpustate->opcode_table_x87_da[modrm] = ptr;
4937         }
4938 }
4939
4940
4941 void build_x87_opcode_table_db(i386_state *cpustate)
4942 {
4943         int modrm = 0;
4944
4945         for (modrm = 0; modrm < 0x100; ++modrm)
4946         {
4947                 void (__FASTCALL *ptr)(i386_state *cpustate, UINT8 modrm) = x87_invalid;
4948
4949                 if (modrm < 0xc0)
4950                 {
4951                         switch ((modrm >> 3) & 0x7)
4952                         {
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;
4958                         }
4959                 }
4960                 else
4961                 {
4962                         switch (modrm)
4963                         {
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;
4975                         }
4976                 }
4977
4978                 cpustate->opcode_table_x87_db[modrm] = ptr;
4979         }
4980 }
4981
4982
4983 void build_x87_opcode_table_dc(i386_state *cpustate)
4984 {
4985         int modrm = 0;
4986
4987         for (modrm = 0; modrm < 0x100; ++modrm)
4988         {
4989                 void (__FASTCALL *ptr)(i386_state *cpustate, UINT8 modrm) = x87_invalid;
4990
4991                 if (modrm < 0xc0)
4992                 {
4993                         switch ((modrm >> 3) & 0x7)
4994                         {
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;
5003                         }
5004                 }
5005                 else
5006                 {
5007                         switch (modrm)
5008                         {
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;
5015                         }
5016                 }
5017
5018                 cpustate->opcode_table_x87_dc[modrm] = ptr;
5019         }
5020 }
5021
5022
5023 void build_x87_opcode_table_dd(i386_state *cpustate)
5024 {
5025         int modrm = 0;
5026
5027         for (modrm = 0; modrm < 0x100; ++modrm)
5028         {
5029                 void (__FASTCALL *ptr)(i386_state *cpustate, UINT8 modrm) = x87_invalid;
5030
5031                 if (modrm < 0xc0)
5032                 {
5033                         switch ((modrm >> 3) & 0x7)
5034                         {
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;
5041                         }
5042                 }
5043                 else
5044                 {
5045                         switch (modrm)
5046                         {
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;
5053                         }
5054                 }
5055
5056                 cpustate->opcode_table_x87_dd[modrm] = ptr;
5057         }
5058 }
5059
5060
5061 void build_x87_opcode_table_de(i386_state *cpustate)
5062 {
5063         int modrm = 0;
5064
5065         for (modrm = 0; modrm < 0x100; ++modrm)
5066         {
5067                 void (__FASTCALL *ptr)(i386_state *cpustate, UINT8 modrm) = x87_invalid;
5068
5069                 if (modrm < 0xc0)
5070                 {
5071                         switch ((modrm >> 3) & 0x7)
5072                         {
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;
5081                         }
5082                 }
5083                 else
5084                 {
5085                         switch (modrm)
5086                         {
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;
5094                         }
5095                 }
5096
5097                 cpustate->opcode_table_x87_de[modrm] = ptr;
5098         }
5099 }
5100
5101
5102 void build_x87_opcode_table_df(i386_state *cpustate)
5103 {
5104         int modrm = 0;
5105
5106         for (modrm = 0; modrm < 0x100; ++modrm)
5107         {
5108                 void (__FASTCALL *ptr)(i386_state *cpustate, UINT8 modrm) = x87_invalid;
5109
5110                 if (modrm < 0xc0)
5111                 {
5112                         switch ((modrm >> 3) & 0x7)
5113                         {
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;
5121                         }
5122                 }
5123                 else
5124                 {
5125                         switch (modrm)
5126                         {
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;
5130                         }
5131                 }
5132
5133                 cpustate->opcode_table_x87_df[modrm] = ptr;
5134         }
5135 }
5136
5137 void build_x87_opcode_table(i386_state *cpustate)
5138 {
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);
5147 }