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