1 // SPDX-License-Identifier: MIT
6 #include "softfloat/softfloat.h"
11 static void fatalerror(char *format, ...) {
14 vfprintf(stderr,format,ap); // JFF: fixed. Was using fprintf and arguments were wrong
19 #define FPCC_N 0x08000000
20 #define FPCC_Z 0x04000000
21 #define FPCC_I 0x02000000
22 #define FPCC_NAN 0x01000000
24 #define FPES_OE 0x00002000
25 #define FPAE_IOP 0x00000080
27 #define DOUBLE_INFINITY (unsigned long long)(0x7ff0000000000000)
28 #define DOUBLE_EXPONENT (unsigned long long)(0x7ff0000000000000)
29 #define DOUBLE_MANTISSA (unsigned long long)(0x000fffffffffffff)
31 /*----------------------------------------------------------------------------
32 | Returns 1 if the extended double-precision floating-point value `a' is a
33 | NaN; otherwise returns 0.
34 *----------------------------------------------------------------------------*/
36 flag floatx80_is_nan( floatx80 a )
39 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (uint64_t) ( a.low<<1 );
44 // masks for packed dwords, positive k-factor
45 static uint32 pkmask2[18] =
47 0xffffffff, 0, 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
48 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
49 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
50 0xffffffff, 0xffffffff, 0xffffffff
53 static uint32 pkmask3[18] =
55 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0,
56 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
57 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
60 static inline double fx80_to_double(floatx80 fx)
67 d = floatx80_to_float64(fx, &status);
72 static inline floatx80 double_to_fx80(double in)
78 return float64_to_floatx80(*d, &status);
81 static inline floatx80 load_extended_float80(uint32 ea)
87 d3 = m68ki_read_16(ea);
88 d1 = m68ki_read_32(ea+4);
89 d2 = m68ki_read_32(ea+8);
92 fp.low = ((uint64)d1<<32) | (d2 & 0xffffffff);
97 static inline void store_extended_float80(uint32 ea, floatx80 fpr)
99 m68ki_write_16(ea+0, fpr.high);
100 m68ki_write_16(ea+2, 0);
101 m68ki_write_32(ea+4, (fpr.low>>32)&0xffffffff);
102 m68ki_write_32(ea+8, fpr.low&0xffffffff);
105 static inline floatx80 load_pack_float80(uint32 ea)
107 uint32 dw1, dw2, dw3;
112 dw1 = m68ki_read_32(ea);
113 dw2 = m68ki_read_32(ea+4);
114 dw3 = m68ki_read_32(ea+8);
117 if (dw1 & 0x80000000) // mantissa sign
121 *ch++ = (char)((dw1 & 0xf) + '0');
123 *ch++ = (char)(((dw2 >> 28) & 0xf) + '0');
124 *ch++ = (char)(((dw2 >> 24) & 0xf) + '0');
125 *ch++ = (char)(((dw2 >> 20) & 0xf) + '0');
126 *ch++ = (char)(((dw2 >> 16) & 0xf) + '0');
127 *ch++ = (char)(((dw2 >> 12) & 0xf) + '0');
128 *ch++ = (char)(((dw2 >> 8) & 0xf) + '0');
129 *ch++ = (char)(((dw2 >> 4) & 0xf) + '0');
130 *ch++ = (char)(((dw2 >> 0) & 0xf) + '0');
131 *ch++ = (char)(((dw3 >> 28) & 0xf) + '0');
132 *ch++ = (char)(((dw3 >> 24) & 0xf) + '0');
133 *ch++ = (char)(((dw3 >> 20) & 0xf) + '0');
134 *ch++ = (char)(((dw3 >> 16) & 0xf) + '0');
135 *ch++ = (char)(((dw3 >> 12) & 0xf) + '0');
136 *ch++ = (char)(((dw3 >> 8) & 0xf) + '0');
137 *ch++ = (char)(((dw3 >> 4) & 0xf) + '0');
138 *ch++ = (char)(((dw3 >> 0) & 0xf) + '0');
140 if (dw1 & 0x40000000) // exponent sign
144 *ch++ = (char)(((dw1 >> 24) & 0xf) + '0');
145 *ch++ = (char)(((dw1 >> 20) & 0xf) + '0');
146 *ch++ = (char)(((dw1 >> 16) & 0xf) + '0');
149 sscanf(str, "%le", &tmp);
151 result = double_to_fx80(tmp);
156 static inline void store_pack_float80(uint32 ea, int k, floatx80 fpr)
158 uint32 dw1, dw2, dw3;
165 sprintf(str, "%.16e", fx80_to_double(fpr));
178 dw1 |= (*ch++ - '0');
185 // handle negative k-factor here
186 if ((k <= 0) && (k >= -13))
189 for (i = 0; i < 3; i++)
191 if (ch[18+i] >= '0' && ch[18+i] <= '9')
193 exp = (exp << 4) | (ch[18+i] - '0');
203 // last digit is (k + exponent - 1)
206 // round up the last significant mantissa digit
212 // zero out the rest of the mantissa digits
213 for (j = (k+1); j < 16; j++)
218 // now zero out K to avoid tripping the positive K detection below
222 // crack 8 digits of the mantissa
223 for (i = 0; i < 8; i++)
226 if (*ch >= '0' && *ch <= '9')
232 // next 8 digits of the mantissa
233 for (i = 0; i < 8; i++)
236 if (*ch >= '0' && *ch <= '9')
240 // handle masking if k is positive
252 // m68ki_cpu.fpcr |= (need to set OPERR bit)
256 // finally, crack the exponent
257 if (*ch == 'e' || *ch == 'E')
272 for (i = 0; i < 3; i++)
274 if (*ch >= '0' && *ch <= '9')
276 j = (j << 4) | (*ch++ - '0');
283 m68ki_write_32(ea, dw1);
284 m68ki_write_32(ea+4, dw2);
285 m68ki_write_32(ea+8, dw3);
288 static inline void SET_CONDITION_CODES(floatx80 reg)
292 // regi = (u64 *)®
294 REG_FPSR &= ~(FPCC_N|FPCC_Z|FPCC_I|FPCC_NAN);
297 if (reg.high & 0x8000)
303 if (((reg.high & 0x7fff) == 0) && ((reg.low<<1) == 0))
309 if (((reg.high & 0x7fff) == 0x7fff) && ((reg.low<<1) == 0))
315 if (floatx80_is_nan(reg))
317 REG_FPSR |= FPCC_NAN;
321 static inline int TEST_CONDITION(int condition)
323 int n = (REG_FPSR & FPCC_N) != 0;
324 int z = (REG_FPSR & FPCC_Z) != 0;
325 int nan = (REG_FPSR & FPCC_NAN) != 0;
330 case 0x00: return 0; // False
333 case 0x01: return (z); // Equal
336 case 0x02: return (!(nan || z || n)); // Greater Than
339 case 0x03: return (z || !(nan || n)); // Greater or Equal
342 case 0x04: return (n && !(nan || z)); // Less Than
345 case 0x05: return (z || (n && !nan)); // Less Than or Equal
348 case 0x06: return !nan && !z;
351 case 0x07: return !nan;
354 case 0x08: return nan;
357 case 0x09: return nan || z;
360 case 0x0a: return (nan || !(n || z)); // Not Less Than or Equal
363 case 0x0b: return (nan || z || !n); // Not Less Than
366 case 0x0c: return (nan || (n && !z)); // Not Greater or Equal Than
369 case 0x0d: return (nan || z || n); // Not Greater Than
372 case 0x0e: return (!z); // Not Equal
375 case 0x0f: return 1; // True
377 default: fatalerror("M68kFPU: test_condition: unhandled condition %02X\n", condition);
383 static uint8 READ_EA_8(int ea)
385 int mode = (ea >> 3) & 0x7;
386 int reg = (ea & 0x7);
396 uint32 ea = REG_A[reg];
397 return m68ki_read_8(ea);
401 uint32 ea = EA_AY_PI_8();
402 return m68ki_read_8(ea);
406 uint32 ea = EA_AY_PD_8();
407 return m68ki_read_8(ea);
411 uint32 ea = EA_AY_DI_8();
412 return m68ki_read_8(ea);
414 case 6: // (An) + (Xn) + d8
416 uint32 ea = EA_AY_IX_8();
417 return m68ki_read_8(ea);
425 uint32 ea = (uint32)OPER_I_16();
426 return m68ki_read_8(ea);
430 uint32 d1 = OPER_I_16();
431 uint32 d2 = OPER_I_16();
432 uint32 ea = (d1 << 16) | d2;
433 return m68ki_read_8(ea);
437 uint32 ea = EA_PCDI_8();
438 return m68ki_read_8(ea);
440 case 3: // (PC) + (Xn) + d8
442 uint32 ea = EA_PCIX_8();
443 return m68ki_read_8(ea);
449 default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
453 default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
459 static uint16 READ_EA_16(int ea)
461 int mode = (ea >> 3) & 0x7;
462 int reg = (ea & 0x7);
468 return (uint16)(REG_D[reg]);
472 uint32 ea = REG_A[reg];
473 return m68ki_read_16(ea);
477 uint32 ea = EA_AY_PI_16();
478 return m68ki_read_16(ea);
482 uint32 ea = EA_AY_PD_16();
483 return m68ki_read_16(ea);
487 uint32 ea = EA_AY_DI_16();
488 return m68ki_read_16(ea);
490 case 6: // (An) + (Xn) + d8
492 uint32 ea = EA_AY_IX_16();
493 return m68ki_read_16(ea);
501 uint32 ea = (uint32)OPER_I_16();
502 return m68ki_read_16(ea);
506 uint32 d1 = OPER_I_16();
507 uint32 d2 = OPER_I_16();
508 uint32 ea = (d1 << 16) | d2;
509 return m68ki_read_16(ea);
513 uint32 ea = EA_PCDI_16();
514 return m68ki_read_16(ea);
516 case 3: // (PC) + (Xn) + d8
518 uint32 ea = EA_PCIX_16();
519 return m68ki_read_16(ea);
526 default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
530 default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
536 static uint32 READ_EA_32(int ea)
538 int mode = (ea >> 3) & 0x7;
539 int reg = (ea & 0x7);
549 uint32 ea = REG_A[reg];
550 return m68ki_read_32(ea);
554 uint32 ea = EA_AY_PI_32();
555 return m68ki_read_32(ea);
559 uint32 ea = EA_AY_PD_32();
560 return m68ki_read_32(ea);
564 uint32 ea = EA_AY_DI_32();
565 return m68ki_read_32(ea);
567 case 6: // (An) + (Xn) + d8
569 uint32 ea = EA_AY_IX_32();
570 return m68ki_read_32(ea);
578 uint32 ea = (uint32)OPER_I_16();
579 return m68ki_read_32(ea);
583 uint32 d1 = OPER_I_16();
584 uint32 d2 = OPER_I_16();
585 uint32 ea = (d1 << 16) | d2;
586 return m68ki_read_32(ea);
590 uint32 ea = EA_PCDI_32();
591 return m68ki_read_32(ea);
593 case 3: // (PC) + (Xn) + d8
595 uint32 ea = EA_PCIX_32();
596 return m68ki_read_32(ea);
602 default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
606 default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
611 static uint64 READ_EA_64(int ea)
613 int mode = (ea >> 3) & 0x7;
614 int reg = (ea & 0x7);
621 uint32 ea = REG_A[reg];
622 h1 = m68ki_read_32(ea+0);
623 h2 = m68ki_read_32(ea+4);
624 return (uint64)(h1) << 32 | (uint64)(h2);
628 uint32 ea = REG_A[reg];
630 h1 = m68ki_read_32(ea+0);
631 h2 = m68ki_read_32(ea+4);
632 return (uint64)(h1) << 32 | (uint64)(h2);
636 uint32 ea = REG_A[reg]-8;
638 h1 = m68ki_read_32(ea+0);
639 h2 = m68ki_read_32(ea+4);
640 return (uint64)(h1) << 32 | (uint64)(h2);
644 uint32 ea = EA_AY_DI_32();
645 h1 = m68ki_read_32(ea+0);
646 h2 = m68ki_read_32(ea+4);
647 return (uint64)(h1) << 32 | (uint64)(h2);
649 case 6: // (An) + (Xn) + d8
651 uint32 ea = EA_AY_IX_32();
652 h1 = m68ki_read_32(ea+0);
653 h2 = m68ki_read_32(ea+4);
654 return (uint64)(h1) << 32 | (uint64)(h2);
662 uint32 d1 = OPER_I_16();
663 uint32 d2 = OPER_I_16();
664 uint32 ea = (d1 << 16) | d2;
665 return (uint64)(m68ki_read_32(ea)) << 32 | (uint64)(m68ki_read_32(ea+4));
667 case 3: // (PC) + (Xn) + d8
669 uint32 ea = EA_PCIX_32();
670 h1 = m68ki_read_32(ea+0);
671 h2 = m68ki_read_32(ea+4);
672 return (uint64)(h1) << 32 | (uint64)(h2);
678 return (uint64)(h1) << 32 | (uint64)(h2);
682 uint32 ea = EA_PCDI_32();
683 h1 = m68ki_read_32(ea+0);
684 h2 = m68ki_read_32(ea+4);
685 return (uint64)(h1) << 32 | (uint64)(h2);
687 default: fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
691 default: fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
698 static floatx80 READ_EA_FPE(uint32 ea)
701 int mode = (ea >> 3) & 0x7;
702 int reg = (ea & 0x7);
708 uint32 ea = REG_A[reg];
709 fpr = load_extended_float80(ea);
715 uint32 ea = REG_A[reg];
717 fpr = load_extended_float80(ea);
722 uint32 ea = REG_A[reg]-12;
724 fpr = load_extended_float80(ea);
729 // FIXME: will fail for fmovem
730 uint32 ea = EA_AY_DI_32();
731 fpr = load_extended_float80(ea);
734 case 6: // (An) + (Xn) + d8
736 // FIXME: will fail for fmovem
737 uint32 ea = EA_AY_IX_32();
738 fpr = load_extended_float80(ea);
742 case 7: // extended modes
748 uint32 d1 = OPER_I_16();
749 uint32 d2 = OPER_I_16();
750 uint32 ea = (d1 << 16) | d2;
751 fpr = load_extended_float80(ea);
757 uint32 ea = EA_PCDI_32();
758 fpr = load_extended_float80(ea);
762 case 3: // (d16,PC,Dx.w)
764 uint32 ea = EA_PCIX_32();
765 fpr = load_extended_float80(ea);
769 case 4: // immediate (JFF)
772 fpr = load_extended_float80(ea);
778 fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
784 default: fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break;
790 static floatx80 READ_EA_PACK(int ea)
793 int mode = (ea >> 3) & 0x7;
794 int reg = (ea & 0x7);
800 uint32 ea = REG_A[reg];
801 fpr = load_pack_float80(ea);
807 uint32 ea = REG_A[reg];
809 fpr = load_pack_float80(ea);
813 case 7: // extended modes
817 case 3: // (d16,PC,Dx.w)
819 uint32 ea = EA_PCIX_32();
820 fpr = load_pack_float80(ea);
825 fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
831 default: fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break;
837 static void WRITE_EA_8(int ea, uint8 data)
839 int mode = (ea >> 3) & 0x7;
840 int reg = (ea & 0x7);
851 uint32 ea = REG_A[reg];
852 m68ki_write_8(ea, data);
857 uint32 ea = EA_AY_PI_8();
858 m68ki_write_8(ea, data);
863 uint32 ea = EA_AY_PD_8();
864 m68ki_write_8(ea, data);
869 uint32 ea = EA_AY_DI_8();
870 m68ki_write_8(ea, data);
873 case 6: // (An) + (Xn) + d8
875 uint32 ea = EA_AY_IX_8();
876 m68ki_write_8(ea, data);
885 uint32 d1 = OPER_I_16();
886 uint32 d2 = OPER_I_16();
887 uint32 ea = (d1 << 16) | d2;
888 m68ki_write_8(ea, data);
893 uint32 ea = EA_PCDI_16();
894 m68ki_write_8(ea, data);
897 default: fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
901 default: fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
905 static void WRITE_EA_16(int ea, uint16 data)
907 int mode = (ea >> 3) & 0x7;
908 int reg = (ea & 0x7);
919 uint32 ea = REG_A[reg];
920 m68ki_write_16(ea, data);
925 uint32 ea = EA_AY_PI_16();
926 m68ki_write_16(ea, data);
931 uint32 ea = EA_AY_PD_16();
932 m68ki_write_16(ea, data);
937 uint32 ea = EA_AY_DI_16();
938 m68ki_write_16(ea, data);
941 case 6: // (An) + (Xn) + d8
943 uint32 ea = EA_AY_IX_16();
944 m68ki_write_16(ea, data);
953 uint32 d1 = OPER_I_16();
954 uint32 d2 = OPER_I_16();
955 uint32 ea = (d1 << 16) | d2;
956 m68ki_write_16(ea, data);
961 uint32 ea = EA_PCDI_16();
962 m68ki_write_16(ea, data);
965 default: fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
969 default: fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
973 static void WRITE_EA_32(int ea, uint32 data)
975 int mode = (ea >> 3) & 0x7;
976 int reg = (ea & 0x7);
992 uint32 ea = REG_A[reg];
993 m68ki_write_32(ea, data);
998 uint32 ea = EA_AY_PI_32();
999 m68ki_write_32(ea, data);
1004 uint32 ea = EA_AY_PD_32();
1005 m68ki_write_32(ea, data);
1008 case 5: // (d16, An)
1010 uint32 ea = EA_AY_DI_32();
1011 m68ki_write_32(ea, data);
1014 case 6: // (An) + (Xn) + d8
1016 uint32 ea = EA_AY_IX_32();
1017 m68ki_write_32(ea, data);
1026 uint32 ea = OPER_I_16();
1027 m68ki_write_32(ea, data);
1032 uint32 d1 = OPER_I_16();
1033 uint32 d2 = OPER_I_16();
1034 uint32 ea = (d1 << 16) | d2;
1035 m68ki_write_32(ea, data);
1038 case 2: // (d16, PC)
1040 uint32 ea = EA_PCDI_32();
1041 m68ki_write_32(ea, data);
1044 default: fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
1048 default: fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
1052 static void WRITE_EA_64(int ea, uint64 data)
1054 int mode = (ea >> 3) & 0x7;
1055 int reg = (ea & 0x7);
1061 uint32 ea = REG_A[reg];
1062 m68ki_write_32(ea, (uint32)(data >> 32));
1063 m68ki_write_32(ea+4, (uint32)(data));
1068 uint32 ea = REG_A[reg];
1070 m68ki_write_32(ea+0, (uint32)(data >> 32));
1071 m68ki_write_32(ea+4, (uint32)(data));
1079 m68ki_write_32(ea+0, (uint32)(data >> 32));
1080 m68ki_write_32(ea+4, (uint32)(data));
1083 case 5: // (d16, An)
1085 uint32 ea = EA_AY_DI_32();
1086 m68ki_write_32(ea+0, (uint32)(data >> 32));
1087 m68ki_write_32(ea+4, (uint32)(data));
1090 case 6: // (An) + (Xn) + d8
1092 uint32 ea = EA_AY_IX_32();
1093 m68ki_write_32(ea+0, (uint32)(data >> 32));
1094 m68ki_write_32(ea+4, (uint32)(data));
1103 uint32 d1 = OPER_I_16();
1104 uint32 d2 = OPER_I_16();
1105 uint32 ea = (d1 << 16) | d2;
1106 m68ki_write_32(ea+0, (uint32)(data >> 32));
1107 m68ki_write_32(ea+4, (uint32)(data));
1110 case 2: // (d16, PC)
1112 uint32 ea = EA_PCDI_32();
1113 m68ki_write_32(ea+0, (uint32)(data >> 32));
1114 m68ki_write_32(ea+4, (uint32)(data));
1117 default: fatalerror("M68kFPU: WRITE_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
1121 default: fatalerror("M68kFPU: WRITE_EA_64: unhandled mode %d, reg %d, data %08X%08X at %08X\n", mode, reg, (uint32)(data >> 32), (uint32)(data), REG_PC);
1125 static void WRITE_EA_FPE(uint32 ea, floatx80 fpr)
1127 int mode = (ea >> 3) & 0x7;
1128 int reg = (ea & 0x7);
1136 store_extended_float80(ea, fpr);
1144 store_extended_float80(ea, fpr);
1154 store_extended_float80(ea, fpr);
1157 case 5: // (d16, An)
1159 uint32 ea = EA_AY_DI_32();
1160 store_extended_float80(ea, fpr);
1168 default: fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1172 default: fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1176 static void WRITE_EA_PACK(int ea, int k, floatx80 fpr)
1178 int mode = (ea >> 3) & 0x7;
1179 int reg = (ea & 0x7);
1187 store_pack_float80(ea, k, fpr);
1195 store_pack_float80(ea, k, fpr);
1205 store_pack_float80(ea, k, fpr);
1213 default: fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1217 default: fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1222 static void fpgen_rm_reg(uint16 w2)
1224 int ea = REG_IR & 0x3f;
1225 int rm = (w2 >> 14) & 0x1;
1226 int src = (w2 >> 10) & 0x7;
1227 int dst = (w2 >> 7) & 0x7;
1228 int opmode = w2 & 0x7f;
1231 // fmovecr #$f, fp0 f200 5c0f
1237 case 0: // Long-Word Integer
1239 sint32 d = READ_EA_32(ea);
1240 source = int32_to_floatx80(d);
1243 case 1: // Single-precision Real
1245 uint32 d = READ_EA_32(ea);
1246 source = float32_to_floatx80(d, &status);
1249 case 2: // Extended-precision Real
1251 source = READ_EA_FPE(ea);
1254 case 3: // Packed-decimal Real
1256 source = READ_EA_PACK(ea);
1259 case 4: // Word Integer
1261 sint16 d = READ_EA_16(ea);
1262 source = int32_to_floatx80((sint32)d);
1265 case 5: // Double-precision Real
1267 uint64 d = READ_EA_64(ea);
1269 source = float64_to_floatx80(d, &status);
1272 case 6: // Byte Integer
1274 sint8 d = READ_EA_8(ea);
1275 source = int32_to_floatx80((sint32)d);
1278 case 7: // FMOVECR load from constant ROM
1283 source.high = 0x4000;
1284 source.low = U64(0xc90fdaa22168c235);
1287 case 0xb: // log10(2)
1288 source.high = 0x3ffd;
1289 source.low = U64(0x9a209a84fbcff798);
1293 source.high = 0x4000;
1294 source.low = U64(0xadf85458a2bb4a9b);
1297 case 0xd: // log2(e)
1298 source.high = 0x3fff;
1299 source.low = U64(0xb8aa3b295c17f0bc);
1302 case 0xe: // log10(e)
1303 source.high = 0x3ffd;
1304 source.low = U64(0xde5bd8a937287195);
1308 source = int32_to_floatx80((sint32)0);
1312 source.high = 0x3ffe;
1313 source.low = U64(0xb17217f7d1cf79ac);
1316 case 0x31: // ln(10)
1317 source.high = 0x4000;
1318 source.low = U64(0x935d8dddaaa8ac17);
1321 case 0x32: // 1 (or 100? manuals are unclear, but 1 would make more sense)
1322 source = int32_to_floatx80((sint32)1);
1326 source = int32_to_floatx80((sint32)10);
1330 source = int32_to_floatx80((sint32)10*10);
1333 source = int32_to_floatx80((sint32)1000*10);
1337 source = int32_to_floatx80((sint32)10000000*10);
1340 case 0x37: // 1.0e16 - can't get the right precision from s32 so go "direct" with constants from h/w
1341 source.high = 0x4034;
1342 source.low = U64(0x8e1bc9bf04000000);
1345 case 0x38: // 1.0e32
1346 source.high = 0x4069;
1347 source.low = U64(0x9dc5ada82b70b59e);
1350 case 0x39: // 1.0e64
1351 source.high = 0x40d3;
1352 source.low = U64(0xc2781f49ffcfa6d5);
1355 case 0x3a: // 1.0e128
1356 source.high = 0x41a8;
1357 source.low = U64(0x93ba47c980e98ce0);
1360 case 0x3b: // 1.0e256
1361 source.high = 0x4351;
1362 source.low = U64(0xaa7eebfb9df9de8e);
1365 case 0x3c: // 1.0e512
1366 source.high = 0x46a3;
1367 source.low = U64(0xe319a0aea60e91c7);
1370 case 0x3d: // 1.0e1024
1371 source.high = 0x4d48;
1372 source.low = U64(0xc976758681750c17);
1375 case 0x3e: // 1.0e2048
1376 source.high = 0x5a92;
1377 source.low = U64(0x9e8b3b5dc53d5de5);
1380 case 0x3f: // 1.0e4096
1381 source.high = 0x7525;
1382 source.low = U64(0xc46052028a20979b);
1387 fatalerror("fmove_rm_reg: unknown constant ROM offset %x at %08x\n", w2&0x7f, REG_PC-4);
1391 // handle it right here, the usual opmode bits aren't valid in the FMOVECR case
1392 REG_FP[dst] = source;
1393 //FIXME mame doesn't use SET_CONDITION_CODES here
1394 SET_CONDITION_CODES(REG_FP[dst]); // JFF when destination is a register, we HAVE to update FPCR
1398 default: fatalerror("fmove_rm_reg: invalid source specifier %x at %08X\n", src, REG_PC-4);
1403 source = REG_FP[src];
1406 // For FD* and FS* prefixes we already converted the source to floatx80
1407 // so we can treat these as their parent op.
1411 case 0x44: // FDMOVE
1412 case 0x40: // FSMOVE
1415 REG_FP[dst] = source;
1416 SET_CONDITION_CODES(REG_FP[dst]);
1423 temp = floatx80_to_int32(source, &status);
1424 REG_FP[dst] = int32_to_floatx80(temp);
1425 //FIXME mame doesn't use SET_CONDITION_CODES here
1426 SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes
1432 REG_FP[dst] = floatx80_sinh(source, &status);
1433 SET_CONDITION_CODES(REG_FP[dst]);
1437 case 0x03: // FINTRZ
1440 temp = floatx80_to_int32_round_to_zero(source, &status);
1441 REG_FP[dst] = int32_to_floatx80(temp);
1442 //FIXME mame doesn't use SET_CONDITION_CODES here
1443 SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes
1446 case 0x45: // FDSQRT
1447 case 0x41: // FSSQRT
1450 REG_FP[dst] = floatx80_sqrt(source, &status);
1451 SET_CONDITION_CODES(REG_FP[dst]);
1455 case 0x06: // FLOGNP1
1457 REG_FP[dst] = floatx80_lognp1 (source, &status);
1458 SET_CONDITION_CODES(REG_FP[dst]);
1459 USE_CYCLES(594); // for MC68881
1462 case 0x08: // FETOXM1
1464 REG_FP[dst] = floatx80_etoxm1(source, &status);
1465 SET_CONDITION_CODES(REG_FP[dst]);
1471 REG_FP[dst] = floatx80_tanh(source, &status);
1472 SET_CONDITION_CODES(REG_FP[dst]);
1478 REG_FP[dst] = floatx80_atan(source, &status);
1479 SET_CONDITION_CODES(REG_FP[dst]);
1485 REG_FP[dst] = floatx80_asin(source, &status);
1486 SET_CONDITION_CODES(REG_FP[dst]);
1490 case 0x0d: // FATANH
1492 REG_FP[dst] = floatx80_atanh(source, &status);
1493 SET_CONDITION_CODES(REG_FP[dst]);
1499 REG_FP[dst] = floatx80_sin(source, &status);
1500 SET_CONDITION_CODES(REG_FP[dst]);
1506 REG_FP[dst] = floatx80_tan(source, &status);
1507 SET_CONDITION_CODES(REG_FP[dst]);
1513 REG_FP[dst] = floatx80_etox(source, &status);
1514 SET_CONDITION_CODES(REG_FP[dst]);
1518 case 0x11: // FTWOTOX
1520 REG_FP[dst] = floatx80_twotox(source, &status);
1521 SET_CONDITION_CODES(REG_FP[dst]);
1525 case 0x12: // FTENTOX
1527 REG_FP[dst] = floatx80_tentox(source, &status);
1528 SET_CONDITION_CODES(REG_FP[dst]);
1534 REG_FP[dst] = floatx80_logn(source, &status);
1535 SET_CONDITION_CODES(REG_FP[dst]);
1536 USE_CYCLES(548); // for MC68881
1539 case 0x15: // FLOG10
1541 REG_FP[dst] = floatx80_log10(source, &status);
1542 SET_CONDITION_CODES(REG_FP[dst]);
1543 USE_CYCLES(604); // for MC68881
1548 REG_FP[dst] = floatx80_log2(source, &status);
1549 SET_CONDITION_CODES(REG_FP[dst]);
1550 USE_CYCLES(604); // for MC68881
1557 REG_FP[dst] = source;
1558 REG_FP[dst].high &= 0x7fff;
1559 SET_CONDITION_CODES(REG_FP[dst]);
1565 REG_FP[dst] = floatx80_cosh(source, &status);
1566 SET_CONDITION_CODES(REG_FP[dst]);
1574 REG_FP[dst] = source;
1575 REG_FP[dst].high ^= 0x8000;
1576 SET_CONDITION_CODES(REG_FP[dst]);
1582 REG_FP[dst] = floatx80_acos(source, &status);
1583 SET_CONDITION_CODES(REG_FP[dst]);
1584 USE_CYCLES(604); // for MC68881
1590 REG_FP[dst] = floatx80_cos(source, &status);
1591 SET_CONDITION_CODES(REG_FP[dst]);
1595 case 0x1e: // FGETEXP
1597 REG_FP[dst] = floatx80_getexp(source, &status);
1598 SET_CONDITION_CODES(REG_FP[dst]);
1602 case 0x1f: // FGETMAN
1604 REG_FP[dst] = floatx80_getman(source, &status);
1605 SET_CONDITION_CODES(REG_FP[dst]);
1613 REG_FP[dst] = floatx80_div(REG_FP[dst], source, &status);
1614 //FIXME mame doesn't use SET_CONDITION_CODES here
1615 SET_CONDITION_CODES(REG_FP[dst]); // JFF
1621 sint8 const mode = status.float_rounding_mode;
1622 status.float_rounding_mode = float_round_to_zero;
1625 REG_FP[dst] = floatx80_rem(REG_FP[dst], source, &q, &s, &status);
1626 SET_CONDITION_CODES(REG_FP[dst]);
1627 status.float_rounding_mode = mode;
1628 USE_CYCLES(43); // guess
1635 REG_FP[dst] = floatx80_add(REG_FP[dst], source, &status);
1636 SET_CONDITION_CODES(REG_FP[dst]);
1644 REG_FP[dst] = floatx80_mul(REG_FP[dst], source, &status);
1645 SET_CONDITION_CODES(REG_FP[dst]);
1649 case 0x24: // FSGLDIV
1651 REG_FP[dst] = floatx80_sgldiv(REG_FP[dst], source, &status);
1652 USE_CYCLES(43); // // ? (value is from FDIV)
1657 sint8 const mode = status.float_rounding_mode;
1658 status.float_rounding_mode = float_round_nearest_even;
1661 REG_FP[dst] = floatx80_rem(REG_FP[dst], source, &q, &s, &status);
1662 SET_CONDITION_CODES(REG_FP[dst]);
1663 status.float_rounding_mode = mode;
1664 USE_CYCLES(43); // guess
1667 case 0x26: // FSCALE
1669 REG_FP[dst] = floatx80_scale(REG_FP[dst], source, &status);
1670 SET_CONDITION_CODES(REG_FP[dst]);
1671 USE_CYCLES(46); // (better?) guess
1674 case 0x27: // FSGLMUL
1676 REG_FP[dst] = floatx80_sglmul(REG_FP[dst], source, &status);
1677 SET_CONDITION_CODES(REG_FP[dst]);
1678 USE_CYCLES(11); // ? (value is from FMUL)
1685 REG_FP[dst] = floatx80_sub(REG_FP[dst], source, &status);
1686 SET_CONDITION_CODES(REG_FP[dst]);
1690 case 0x30: // FSINCOS
1691 case 0x31: // FSINCOS
1692 case 0x32: // FSINCOS
1693 case 0x33: // FSINCOS
1694 case 0x34: // FSINCOS
1695 case 0x35: // FSINCOS
1696 case 0x36: // FSINCOS
1697 case 0x37: // FSINCOS
1699 REG_FP[dst] = floatx80_cos(source, &status);
1700 REG_FP[w2&7] = floatx80_sin(source, &status);
1701 SET_CONDITION_CODES(REG_FP[dst]);
1709 res = floatx80_sub(REG_FP[dst], source, &status);
1710 SET_CONDITION_CODES(res);
1718 SET_CONDITION_CODES(res);
1723 default: fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PC-4);
1727 static void fmove_reg_mem(uint16 w2)
1729 int ea = REG_IR & 0x3f;
1730 int src = (w2 >> 7) & 0x7;
1731 int dst = (w2 >> 10) & 0x7;
1732 int k = (w2 & 0x7f);
1736 case 0: // Long-Word Integer
1738 sint32 d = (sint32)floatx80_to_int32(REG_FP[src], &status);
1742 case 1: // Single-precision Real
1744 uint32 d = floatx80_to_float32(REG_FP[src], &status);
1748 case 2: // Extended-precision Real
1750 WRITE_EA_FPE(ea, REG_FP[src]);
1753 case 3: // Packed-decimal Real with Static K-factor
1756 k = (k & 0x40) ? (k | 0xffffff80) : (k & 0x7f);
1757 WRITE_EA_PACK(ea, k, REG_FP[src]);
1760 case 4: // Word Integer
1762 sint32 value = floatx80_to_int32(REG_FP[src], &status);
1763 if (value > 0x7fff || value < -0x8000 )
1765 REG_FPSR |= FPES_OE | FPAE_IOP;
1767 WRITE_EA_16(ea, (sint16)value);
1770 case 5: // Double-precision Real
1774 d = floatx80_to_float64(REG_FP[src], &status);
1779 case 6: // Byte Integer
1781 sint32 value = floatx80_to_int32(REG_FP[src], &status);
1782 if (value > 127 || value < -128)
1784 REG_FPSR |= FPES_OE | FPAE_IOP;
1786 WRITE_EA_8(ea, (sint8)value);
1789 case 7: // Packed-decimal Real with Dynamic K-factor
1791 WRITE_EA_PACK(ea, REG_D[k>>4], REG_FP[src]);
1799 static void fmove_fpcr(uint16 w2)
1801 int ea = REG_IR & 0x3f;
1802 int dir = (w2 >> 13) & 0x1;
1803 int regsel = (w2 >> 10) & 0x7;
1804 int mode = (ea >> 3) & 0x7;
1806 if ((mode == 5) || (mode == 6))
1808 uint32 address = 0xffffffff; // force a bus error if this doesn't get assigned
1812 address = EA_AY_DI_32();
1816 address = EA_AY_IX_32();
1819 if (dir) // From system control reg to <ea>
1821 if (regsel & 4) { m68ki_write_32(address, REG_FPCR); address += 4; }
1822 if (regsel & 2) { m68ki_write_32(address, REG_FPSR); address += 4; }
1823 if (regsel & 1) { m68ki_write_32(address, REG_FPIAR); address += 4; }
1825 else // From <ea> to system control reg
1827 if (regsel & 4) { REG_FPCR = m68ki_read_32(address); address += 4; }
1828 if (regsel & 2) { REG_FPSR = m68ki_read_32(address); address += 4; }
1829 if (regsel & 1) { REG_FPIAR = m68ki_read_32(address); address += 4; }
1834 if (dir) // From system control reg to <ea>
1836 if (regsel & 4) WRITE_EA_32(ea, REG_FPCR);
1837 if (regsel & 2) WRITE_EA_32(ea, REG_FPSR);
1838 if (regsel & 1) WRITE_EA_32(ea, REG_FPIAR);
1840 else // From <ea> to system control reg
1842 if (regsel & 4) REG_FPCR = READ_EA_32(ea);
1843 if (regsel & 2) REG_FPSR = READ_EA_32(ea);
1844 if (regsel & 1) REG_FPIAR = READ_EA_32(ea);
1848 // FIXME: (2011-12-18 ost)
1849 // rounding_mode and rounding_precision of softfloat.c should be set according to current fpcr
1850 // but: with this code on Apollo the following programs in /systest/fptest will fail:
1851 // 1. Single Precision Whetstone will return wrong results never the less
1852 // 2. Vector Test will fault with 00040004: reference to illegal address
1854 if ((regsel & 4) && dir == 0)
1856 int rnd = (REG_FPCR >> 4) & 3;
1857 int prec = (REG_FPCR >> 6) & 3;
1859 // logerror("m68k_fpsp:fmove_fpcr fpcr=%04x prec=%d rnd=%d\n", m_fpcr, prec, rnd);
1864 case 0: // Extend (X)
1865 status.floatx80_rounding_precision = 80;
1867 case 1: // Single (S)
1868 status.floatx80_rounding_precision = 32;
1870 case 2: // Double (D)
1871 status.floatx80_rounding_precision = 64;
1873 case 3: // Undefined
1874 status.floatx80_rounding_precision = 80;
1881 case 0: // To Nearest (RN)
1882 status.float_rounding_mode = float_round_nearest_even;
1884 case 1: // To Zero (RZ)
1885 status.float_rounding_mode = float_round_to_zero;
1887 case 2: // To Minus Infinitiy (RM)
1888 status.float_rounding_mode = float_round_down;
1890 case 3: // To Plus Infinitiy (RP)
1891 status.float_rounding_mode = float_round_up;
1899 static void fmovem(uint16 w2)
1902 int ea = REG_IR & 0x3f;
1903 int dir = (w2 >> 13) & 0x1;
1904 int mode = (w2 >> 11) & 0x3;
1905 int reglist = w2 & 0xff;
1907 uint32 mem_addr = 0;
1910 case 5: // (d16, An)
1911 mem_addr= EA_AY_DI_32();
1913 case 6: // (An) + (Xn) + d8
1914 mem_addr= EA_AY_IX_32();
1918 if (dir) // From FP regs to mem
1922 case 1: // Dynamic register list, postincrement or control addressing mode.
1923 // FIXME: not really tested, but seems to work
1924 reglist = REG_D[(reglist >> 4) & 7];
1927 case 0: // Static register list, predecrement or control addressing mode
1929 for (i=0; i < 8; i++)
1931 if (reglist & (1 << i))
1935 case 5: // (d16, An)
1936 case 6: // (An) + (Xn) + d8
1937 store_extended_float80(mem_addr, REG_FP[i]);
1941 WRITE_EA_FPE(ea, REG_FP[i]);
1951 case 2: // Static register list, postdecrement or control addressing mode.
1953 for (i=0; i < 8; i++)
1955 if (reglist & (1 << i))
1959 case 5: // (d16, An)
1960 case 6: // (An) + (Xn) + d8
1961 store_extended_float80(mem_addr, REG_FP[7-i]);
1965 WRITE_EA_FPE(ea, REG_FP[7-i]);
1975 default: fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
1978 else // From mem to FP regs
1982 case 3: // Dynamic register list, predecrement addressing mode.
1983 // FIXME: not really tested, but seems to work
1984 reglist = REG_D[(reglist >> 4) & 7];
1987 case 2: // Static register list, postincrement or control addressing mode
1989 for (i=0; i < 8; i++)
1991 if (reglist & (1 << i))
1995 case 5: // (d16, An)
1996 case 6: // (An) + (Xn) + d8
1997 REG_FP[7-i] = load_extended_float80(mem_addr);
2001 REG_FP[7-i] = READ_EA_FPE(ea);
2010 default: fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
2017 int ea = REG_IR & 0x3f;
2018 int condition = (sint16)(OPER_I_16());
2020 WRITE_EA_8(ea, TEST_CONDITION(condition) ? 0xff : 0);
2021 USE_CYCLES(7); // ???
2023 static void fbcc16(void)
2026 int condition = REG_IR & 0x3f;
2028 offset = (sint16)(OPER_I_16());
2030 // TODO: condition and jump!!!
2031 if (TEST_CONDITION(condition))
2033 m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */
2034 m68ki_branch_16(offset-2);
2040 static void fbcc32(void)
2043 int condition = REG_IR & 0x3f;
2045 offset = OPER_I_32();
2047 // TODO: condition and jump!!!
2048 if (TEST_CONDITION(condition))
2050 m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */
2051 m68ki_branch_32(offset-4);
2058 void m68040_fpu_op0()
2060 m68ki_cpu.fpu_just_reset = 0;
2062 switch ((REG_IR >> 6) & 0x3)
2066 uint16 w2 = OPER_I_16();
2067 switch ((w2 >> 13) & 0x7)
2069 case 0x0: // FPU ALU FP, FP
2070 case 0x2: // FPU ALU ea, FP
2076 case 0x3: // FMOVE FP, ea
2082 case 0x4: // FMOVEM ea, FPCR
2083 case 0x5: // FMOVEM FPCR, ea
2089 case 0x6: // FMOVEM ea, list
2090 case 0x7: // FMOVEM list, ea
2096 default: fatalerror("M68kFPU: unimplemented subop %d at %08X\n", (w2 >> 13) & 0x7, REG_PC-4);
2101 case 1: // FBcc disp16
2103 switch ((REG_IR >> 3) & 0x7) {
2106 printf("M68kFPU: unimplemented FDBcc main op %d with mode %d at %08X\n", (REG_IR >> 6) & 0x3, (REG_IR >> 3) & 0x7, REG_PC-4);
2108 default: // FScc (?)
2112 fatalerror("M68kFPU: unimplemented main op %d with mode %d at %08X\n", (REG_IR >> 6) & 0x3, (REG_IR >> 3) & 0x7, REG_PC-4);
2115 case 2: // FBcc disp16
2120 case 3: // FBcc disp32
2126 default: fatalerror("M68kFPU: unimplemented main op %d\n", (REG_IR >> 6) & 0x3);
2130 static int perform_fsave(uint32 addr, int inc)
2132 if(m68ki_cpu.cpu_type & CPU_TYPE_040)
2136 m68ki_write_32(addr, 0x41000000);
2141 m68ki_write_32(addr, 0x41000000);
2148 // 68881 IDLE, version 0x1f
2149 m68ki_write_32(addr, 0x1f180000);
2150 m68ki_write_32(addr+4, 0);
2151 m68ki_write_32(addr+8, 0);
2152 m68ki_write_32(addr+12, 0);
2153 m68ki_write_32(addr+16, 0);
2154 m68ki_write_32(addr+20, 0);
2155 m68ki_write_32(addr+24, 0x70000000);
2160 m68ki_write_32(addr+4-4, 0x70000000);
2161 m68ki_write_32(addr+4-8, 0);
2162 m68ki_write_32(addr+4-12, 0);
2163 m68ki_write_32(addr+4-16, 0);
2164 m68ki_write_32(addr+4-20, 0);
2165 m68ki_write_32(addr+4-24, 0);
2166 m68ki_write_32(addr+4-28, 0x1f180000);
2171 // FRESTORE on a NULL frame reboots the FPU - all registers to NaN, the 3 status regs to 0
2172 static void do_frestore_null(void)
2179 for (i = 0; i < 8; i++)
2181 REG_FP[i].high = 0x7fff;
2182 REG_FP[i].low = U64(0xffffffffffffffff);
2185 // Mac IIci at 408458e6 wants an FSAVE of a just-restored NULL frame to also be NULL
2186 // The PRM says it's possible to generate a NULL frame, but not how/when/why. (need the 68881/68882 manual!)
2187 m68ki_cpu.fpu_just_reset = 1;
2190 void m68040_do_fsave(uint32 addr, int reg, int inc)
2192 if (m68ki_cpu.fpu_just_reset)
2194 m68ki_write_32(addr, 0);
2198 // we normally generate an IDLE frame
2199 int delta = perform_fsave(addr, inc);
2201 REG_A[reg] += delta;
2205 void m68040_do_frestore(uint32 addr, int reg)
2207 uint32 temp = m68ki_read_32(addr);
2208 // check for nullptr frame
2209 if (temp & 0xff000000)
2211 // we don't handle non-nullptr frames
2212 m68ki_cpu.fpu_just_reset = 0;
2216 uint8 m40 = !!(m68ki_cpu.cpu_type & CPU_TYPE_040);
2217 // how about an IDLE frame?
2218 if (!m40 && ((temp & 0x00ff0000) == 0x00180000))
2220 REG_A[reg] += 7*4-4;
2222 else if (m40 && ((temp & 0xffff0000) == 0x41000000))
2226 else if ((temp & 0x00ff0000) == 0x00380000)
2230 else if ((temp & 0x00ff0000) == 0x00b40000)
2242 void m68040_fpu_op1()
2244 int ea = REG_IR & 0x3f;
2245 int mode = (ea >> 3) & 0x7;
2246 int reg = (ea & 0x7);
2249 switch ((REG_IR >> 6) & 0x3)
2251 case 0: // FSAVE <ea>
2257 m68040_do_fsave(addr, -1, 1);
2261 addr = EA_AY_PI_32();
2262 printf("FSAVE mode %d, reg A%d=0x%08x\n",mode,reg,REG_A[reg]);
2263 m68040_do_fsave(addr, -1, 1); // FIXME: -1 was reg
2267 addr = EA_AY_PD_32();
2268 m68040_do_fsave(addr, reg, 0); // FIXME: -1 was reg
2270 case 5: // (D16, An)
2271 addr = EA_AY_DI_16();
2272 m68040_do_fsave(addr, -1, 1);
2275 case 6: // (An) + (Xn) + d8
2276 addr = EA_AY_IX_16();
2277 m68040_do_fsave(addr, -1, 1);
2287 m68040_do_fsave(addr, -1, 1);
2290 case 2: // (d16, PC)
2292 addr = EA_PCDI_16();
2293 m68040_do_fsave(addr, -1, 1);
2297 fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2303 fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2308 case 1: // FRESTORE <ea>
2314 m68040_do_frestore(addr, -1);
2318 addr = EA_AY_PI_32();
2319 m68040_do_frestore(addr, reg);
2322 case 5: // (D16, An)
2323 addr = EA_AY_DI_16();
2324 m68040_do_frestore(addr, -1);
2327 case 6: // (An) + (Xn) + d8
2328 addr = EA_AY_IX_16();
2329 m68040_do_frestore(addr, -1);
2339 m68040_do_frestore(addr, -1);
2342 case 2: // (d16, PC)
2344 addr = EA_PCDI_16();
2345 m68040_do_frestore(addr, -1);
2349 fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2355 fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2360 default: fatalerror("m68040_fpu_op1: unimplemented op %d at %08X\n", (REG_IR >> 6) & 0x3, REG_PC-2);
2366 uint16 w2 = OPER_I_16();
2368 // now check the condition
2369 if (TEST_CONDITION(w2 & 0x3f))
2372 m68ki_exception_trap(EXCEPTION_TRAPV);
2374 else // fall through, requires eating the operand
2376 switch (REG_IR & 0x7)
2378 case 2: // word operand
2382 case 3: // long word operand
2386 case 4: // no operand