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