7 static void fatalerror(char *format, ...) {
10 vfprintf(stderr,format,ap); // JFF: fixed. Was using fprintf and arguments were wrong
15 #define FPCC_N 0x08000000
16 #define FPCC_Z 0x04000000
17 #define FPCC_I 0x02000000
18 #define FPCC_NAN 0x01000000
20 #define FPES_OE 0x00002000
21 #define FPAE_IOP 0x00000080
23 #define DOUBLE_INFINITY (unsigned long long)(0x7ff0000000000000)
24 #define DOUBLE_EXPONENT (unsigned long long)(0x7ff0000000000000)
25 #define DOUBLE_MANTISSA (unsigned long long)(0x000fffffffffffff)
27 extern flag floatx80_is_nan( floatx80 a );
29 // masks for packed dwords, positive k-factor
30 static uint32 pkmask2[18] =
32 0xffffffff, 0, 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
33 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
34 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
35 0xffffffff, 0xffffffff, 0xffffffff
38 static uint32 pkmask3[18] =
40 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
42 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
45 static inline double fx80_to_double(floatx80 fx)
52 d = floatx80_to_float64(fx);
57 static inline floatx80 double_to_fx80(double in)
63 return float64_to_floatx80(*d);
66 static inline floatx80 load_extended_float80(uint32 ea)
72 d3 = m68ki_read_16(ea);
73 d1 = m68ki_read_32(ea+4);
74 d2 = m68ki_read_32(ea+8);
77 fp.low = ((uint64)d1<<32) | (d2 & 0xffffffff);
82 static inline void store_extended_float80(uint32 ea, floatx80 fpr)
84 m68ki_write_16(ea+0, fpr.high);
85 m68ki_write_16(ea+2, 0);
86 m68ki_write_32(ea+4, (fpr.low>>32)&0xffffffff);
87 m68ki_write_32(ea+8, fpr.low&0xffffffff);
90 static inline floatx80 load_pack_float80(uint32 ea)
97 dw1 = m68ki_read_32(ea);
98 dw2 = m68ki_read_32(ea+4);
99 dw3 = m68ki_read_32(ea+8);
102 if (dw1 & 0x80000000) // mantissa sign
106 *ch++ = (char)((dw1 & 0xf) + '0');
108 *ch++ = (char)(((dw2 >> 28) & 0xf) + '0');
109 *ch++ = (char)(((dw2 >> 24) & 0xf) + '0');
110 *ch++ = (char)(((dw2 >> 20) & 0xf) + '0');
111 *ch++ = (char)(((dw2 >> 16) & 0xf) + '0');
112 *ch++ = (char)(((dw2 >> 12) & 0xf) + '0');
113 *ch++ = (char)(((dw2 >> 8) & 0xf) + '0');
114 *ch++ = (char)(((dw2 >> 4) & 0xf) + '0');
115 *ch++ = (char)(((dw2 >> 0) & 0xf) + '0');
116 *ch++ = (char)(((dw3 >> 28) & 0xf) + '0');
117 *ch++ = (char)(((dw3 >> 24) & 0xf) + '0');
118 *ch++ = (char)(((dw3 >> 20) & 0xf) + '0');
119 *ch++ = (char)(((dw3 >> 16) & 0xf) + '0');
120 *ch++ = (char)(((dw3 >> 12) & 0xf) + '0');
121 *ch++ = (char)(((dw3 >> 8) & 0xf) + '0');
122 *ch++ = (char)(((dw3 >> 4) & 0xf) + '0');
123 *ch++ = (char)(((dw3 >> 0) & 0xf) + '0');
125 if (dw1 & 0x40000000) // exponent sign
129 *ch++ = (char)(((dw1 >> 24) & 0xf) + '0');
130 *ch++ = (char)(((dw1 >> 20) & 0xf) + '0');
131 *ch++ = (char)(((dw1 >> 16) & 0xf) + '0');
134 sscanf(str, "%le", &tmp);
136 result = double_to_fx80(tmp);
141 static inline void store_pack_float80(uint32 ea, int k, floatx80 fpr)
143 uint32 dw1, dw2, dw3;
150 sprintf(str, "%.16e", fx80_to_double(fpr));
163 dw1 |= (*ch++ - '0');
170 // handle negative k-factor here
171 if ((k <= 0) && (k >= -13))
174 for (i = 0; i < 3; i++)
176 if (ch[18+i] >= '0' && ch[18+i] <= '9')
178 exp = (exp << 4) | (ch[18+i] - '0');
188 // last digit is (k + exponent - 1)
191 // round up the last significant mantissa digit
197 // zero out the rest of the mantissa digits
198 for (j = (k+1); j < 16; j++)
203 // now zero out K to avoid tripping the positive K detection below
207 // crack 8 digits of the mantissa
208 for (i = 0; i < 8; i++)
211 if (*ch >= '0' && *ch <= '9')
217 // next 8 digits of the mantissa
218 for (i = 0; i < 8; i++)
221 if (*ch >= '0' && *ch <= '9')
225 // handle masking if k is positive
237 // m68ki_cpu.fpcr |= (need to set OPERR bit)
241 // finally, crack the exponent
242 if (*ch == 'e' || *ch == 'E')
257 for (i = 0; i < 3; i++)
259 if (*ch >= '0' && *ch <= '9')
261 j = (j << 4) | (*ch++ - '0');
268 m68ki_write_32(ea, dw1);
269 m68ki_write_32(ea+4, dw2);
270 m68ki_write_32(ea+8, dw3);
273 static inline void SET_CONDITION_CODES(floatx80 reg)
277 // regi = (u64 *)®
279 REG_FPSR &= ~(FPCC_N|FPCC_Z|FPCC_I|FPCC_NAN);
282 if (reg.high & 0x8000)
288 if (((reg.high & 0x7fff) == 0) && ((reg.low<<1) == 0))
294 if (((reg.high & 0x7fff) == 0x7fff) && ((reg.low<<1) == 0))
300 if (floatx80_is_nan(reg))
302 REG_FPSR |= FPCC_NAN;
306 static inline int TEST_CONDITION(int condition)
308 int n = (REG_FPSR & FPCC_N) != 0;
309 int z = (REG_FPSR & FPCC_Z) != 0;
310 int nan = (REG_FPSR & FPCC_NAN) != 0;
315 case 0x00: return 0; // False
318 case 0x01: return (z); // Equal
321 case 0x02: return (!(nan || z || n)); // Greater Than
324 case 0x03: return (z || !(nan || n)); // Greater or Equal
327 case 0x04: return (n && !(nan || z)); // Less Than
330 case 0x05: return (z || (n && !nan)); // Less Than or Equal
333 case 0x06: return !nan && !z;
336 case 0x07: return !nan;
339 case 0x08: return nan;
342 case 0x09: return nan || z;
345 case 0x0a: return (nan || !(n || z)); // Not Less Than or Equal
348 case 0x0b: return (nan || z || !n); // Not Less Than
351 case 0x0c: return (nan || (n && !z)); // Not Greater or Equal Than
354 case 0x0d: return (nan || z || n); // Not Greater Than
357 case 0x0e: return (!z); // Not Equal
360 case 0x0f: return 1; // True
362 default: fatalerror("M68kFPU: test_condition: unhandled condition %02X\n", condition);
368 static uint8 READ_EA_8(int ea)
370 int mode = (ea >> 3) & 0x7;
371 int reg = (ea & 0x7);
381 uint32 ea = REG_A[reg];
382 return m68ki_read_8(ea);
386 uint32 ea = EA_AY_PI_8();
387 return m68ki_read_8(ea);
391 uint32 ea = EA_AY_PD_8();
392 return m68ki_read_8(ea);
396 uint32 ea = EA_AY_DI_8();
397 return m68ki_read_8(ea);
399 case 6: // (An) + (Xn) + d8
401 uint32 ea = EA_AY_IX_8();
402 return m68ki_read_8(ea);
410 uint32 ea = (uint32)OPER_I_16();
411 return m68ki_read_8(ea);
415 uint32 d1 = OPER_I_16();
416 uint32 d2 = OPER_I_16();
417 uint32 ea = (d1 << 16) | d2;
418 return m68ki_read_8(ea);
422 uint32 ea = EA_PCDI_8();
423 return m68ki_read_8(ea);
425 case 3: // (PC) + (Xn) + d8
427 uint32 ea = EA_PCIX_8();
428 return m68ki_read_8(ea);
434 default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
438 default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
444 static uint16 READ_EA_16(int ea)
446 int mode = (ea >> 3) & 0x7;
447 int reg = (ea & 0x7);
453 return (uint16)(REG_D[reg]);
457 uint32 ea = REG_A[reg];
458 return m68ki_read_16(ea);
462 uint32 ea = EA_AY_PI_16();
463 return m68ki_read_16(ea);
467 uint32 ea = EA_AY_PD_16();
468 return m68ki_read_16(ea);
472 uint32 ea = EA_AY_DI_16();
473 return m68ki_read_16(ea);
475 case 6: // (An) + (Xn) + d8
477 uint32 ea = EA_AY_IX_16();
478 return m68ki_read_16(ea);
486 uint32 ea = (uint32)OPER_I_16();
487 return m68ki_read_16(ea);
491 uint32 d1 = OPER_I_16();
492 uint32 d2 = OPER_I_16();
493 uint32 ea = (d1 << 16) | d2;
494 return m68ki_read_16(ea);
498 uint32 ea = EA_PCDI_16();
499 return m68ki_read_16(ea);
501 case 3: // (PC) + (Xn) + d8
503 uint32 ea = EA_PCIX_16();
504 return m68ki_read_16(ea);
511 default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
515 default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
521 static uint32 READ_EA_32(int ea)
523 int mode = (ea >> 3) & 0x7;
524 int reg = (ea & 0x7);
534 uint32 ea = REG_A[reg];
535 return m68ki_read_32(ea);
539 uint32 ea = EA_AY_PI_32();
540 return m68ki_read_32(ea);
544 uint32 ea = EA_AY_PD_32();
545 return m68ki_read_32(ea);
549 uint32 ea = EA_AY_DI_32();
550 return m68ki_read_32(ea);
552 case 6: // (An) + (Xn) + d8
554 uint32 ea = EA_AY_IX_32();
555 return m68ki_read_32(ea);
563 uint32 ea = (uint32)OPER_I_16();
564 return m68ki_read_32(ea);
568 uint32 d1 = OPER_I_16();
569 uint32 d2 = OPER_I_16();
570 uint32 ea = (d1 << 16) | d2;
571 return m68ki_read_32(ea);
575 uint32 ea = EA_PCDI_32();
576 return m68ki_read_32(ea);
578 case 3: // (PC) + (Xn) + d8
580 uint32 ea = EA_PCIX_32();
581 return m68ki_read_32(ea);
587 default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
591 default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
596 static uint64 READ_EA_64(int ea)
598 int mode = (ea >> 3) & 0x7;
599 int reg = (ea & 0x7);
606 uint32 ea = REG_A[reg];
607 h1 = m68ki_read_32(ea+0);
608 h2 = m68ki_read_32(ea+4);
609 return (uint64)(h1) << 32 | (uint64)(h2);
613 uint32 ea = REG_A[reg];
615 h1 = m68ki_read_32(ea+0);
616 h2 = m68ki_read_32(ea+4);
617 return (uint64)(h1) << 32 | (uint64)(h2);
621 uint32 ea = REG_A[reg]-8;
623 h1 = m68ki_read_32(ea+0);
624 h2 = m68ki_read_32(ea+4);
625 return (uint64)(h1) << 32 | (uint64)(h2);
629 uint32 ea = EA_AY_DI_32();
630 h1 = m68ki_read_32(ea+0);
631 h2 = m68ki_read_32(ea+4);
632 return (uint64)(h1) << 32 | (uint64)(h2);
634 case 6: // (An) + (Xn) + d8
636 uint32 ea = EA_AY_IX_32();
637 h1 = m68ki_read_32(ea+0);
638 h2 = m68ki_read_32(ea+4);
639 return (uint64)(h1) << 32 | (uint64)(h2);
647 uint32 d1 = OPER_I_16();
648 uint32 d2 = OPER_I_16();
649 uint32 ea = (d1 << 16) | d2;
650 return (uint64)(m68ki_read_32(ea)) << 32 | (uint64)(m68ki_read_32(ea+4));
652 case 3: // (PC) + (Xn) + d8
654 uint32 ea = EA_PCIX_32();
655 h1 = m68ki_read_32(ea+0);
656 h2 = m68ki_read_32(ea+4);
657 return (uint64)(h1) << 32 | (uint64)(h2);
663 return (uint64)(h1) << 32 | (uint64)(h2);
667 uint32 ea = EA_PCDI_32();
668 h1 = m68ki_read_32(ea+0);
669 h2 = m68ki_read_32(ea+4);
670 return (uint64)(h1) << 32 | (uint64)(h2);
672 default: fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
676 default: fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
683 static floatx80 READ_EA_FPE(uint32 ea)
686 int mode = (ea >> 3) & 0x7;
687 int reg = (ea & 0x7);
693 uint32 ea = REG_A[reg];
694 fpr = load_extended_float80(ea);
700 uint32 ea = REG_A[reg];
702 fpr = load_extended_float80(ea);
707 uint32 ea = REG_A[reg]-12;
709 fpr = load_extended_float80(ea);
714 // FIXME: will fail for fmovem
715 uint32 ea = EA_AY_DI_32();
716 fpr = load_extended_float80(ea);
719 case 6: // (An) + (Xn) + d8
721 // FIXME: will fail for fmovem
722 uint32 ea = EA_AY_IX_32();
723 fpr = load_extended_float80(ea);
727 case 7: // extended modes
733 uint32 d1 = OPER_I_16();
734 uint32 d2 = OPER_I_16();
735 uint32 ea = (d1 << 16) | d2;
736 fpr = load_extended_float80(ea);
742 uint32 ea = EA_PCDI_32();
743 fpr = load_extended_float80(ea);
747 case 3: // (d16,PC,Dx.w)
749 uint32 ea = EA_PCIX_32();
750 fpr = load_extended_float80(ea);
754 case 4: // immediate (JFF)
757 fpr = load_extended_float80(ea);
763 fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
769 default: fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break;
775 static floatx80 READ_EA_PACK(int ea)
778 int mode = (ea >> 3) & 0x7;
779 int reg = (ea & 0x7);
785 uint32 ea = REG_A[reg];
786 fpr = load_pack_float80(ea);
792 uint32 ea = REG_A[reg];
794 fpr = load_pack_float80(ea);
798 case 7: // extended modes
802 case 3: // (d16,PC,Dx.w)
804 uint32 ea = EA_PCIX_32();
805 fpr = load_pack_float80(ea);
810 fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
816 default: fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break;
822 static void WRITE_EA_8(int ea, uint8 data)
824 int mode = (ea >> 3) & 0x7;
825 int reg = (ea & 0x7);
836 uint32 ea = REG_A[reg];
837 m68ki_write_8(ea, data);
842 uint32 ea = EA_AY_PI_8();
843 m68ki_write_8(ea, data);
848 uint32 ea = EA_AY_PD_8();
849 m68ki_write_8(ea, data);
854 uint32 ea = EA_AY_DI_8();
855 m68ki_write_8(ea, data);
858 case 6: // (An) + (Xn) + d8
860 uint32 ea = EA_AY_IX_8();
861 m68ki_write_8(ea, data);
870 uint32 d1 = OPER_I_16();
871 uint32 d2 = OPER_I_16();
872 uint32 ea = (d1 << 16) | d2;
873 m68ki_write_8(ea, data);
878 uint32 ea = EA_PCDI_16();
879 m68ki_write_8(ea, data);
882 default: fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
886 default: fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
890 static void WRITE_EA_16(int ea, uint16 data)
892 int mode = (ea >> 3) & 0x7;
893 int reg = (ea & 0x7);
904 uint32 ea = REG_A[reg];
905 m68ki_write_16(ea, data);
910 uint32 ea = EA_AY_PI_16();
911 m68ki_write_16(ea, data);
916 uint32 ea = EA_AY_PD_16();
917 m68ki_write_16(ea, data);
922 uint32 ea = EA_AY_DI_16();
923 m68ki_write_16(ea, data);
926 case 6: // (An) + (Xn) + d8
928 uint32 ea = EA_AY_IX_16();
929 m68ki_write_16(ea, data);
938 uint32 d1 = OPER_I_16();
939 uint32 d2 = OPER_I_16();
940 uint32 ea = (d1 << 16) | d2;
941 m68ki_write_16(ea, data);
946 uint32 ea = EA_PCDI_16();
947 m68ki_write_16(ea, data);
950 default: fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
954 default: fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
958 static void WRITE_EA_32(int ea, uint32 data)
960 int mode = (ea >> 3) & 0x7;
961 int reg = (ea & 0x7);
977 uint32 ea = REG_A[reg];
978 m68ki_write_32(ea, data);
983 uint32 ea = EA_AY_PI_32();
984 m68ki_write_32(ea, data);
989 uint32 ea = EA_AY_PD_32();
990 m68ki_write_32(ea, data);
995 uint32 ea = EA_AY_DI_32();
996 m68ki_write_32(ea, data);
999 case 6: // (An) + (Xn) + d8
1001 uint32 ea = EA_AY_IX_32();
1002 m68ki_write_32(ea, data);
1011 uint32 ea = OPER_I_16();
1012 m68ki_write_32(ea, data);
1017 uint32 d1 = OPER_I_16();
1018 uint32 d2 = OPER_I_16();
1019 uint32 ea = (d1 << 16) | d2;
1020 m68ki_write_32(ea, data);
1023 case 2: // (d16, PC)
1025 uint32 ea = EA_PCDI_32();
1026 m68ki_write_32(ea, data);
1029 default: fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
1033 default: fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
1037 static void WRITE_EA_64(int ea, uint64 data)
1039 int mode = (ea >> 3) & 0x7;
1040 int reg = (ea & 0x7);
1046 uint32 ea = REG_A[reg];
1047 m68ki_write_32(ea, (uint32)(data >> 32));
1048 m68ki_write_32(ea+4, (uint32)(data));
1053 uint32 ea = REG_A[reg];
1055 m68ki_write_32(ea+0, (uint32)(data >> 32));
1056 m68ki_write_32(ea+4, (uint32)(data));
1064 m68ki_write_32(ea+0, (uint32)(data >> 32));
1065 m68ki_write_32(ea+4, (uint32)(data));
1068 case 5: // (d16, An)
1070 uint32 ea = EA_AY_DI_32();
1071 m68ki_write_32(ea+0, (uint32)(data >> 32));
1072 m68ki_write_32(ea+4, (uint32)(data));
1075 case 6: // (An) + (Xn) + d8
1077 uint32 ea = EA_AY_IX_32();
1078 m68ki_write_32(ea+0, (uint32)(data >> 32));
1079 m68ki_write_32(ea+4, (uint32)(data));
1088 uint32 d1 = OPER_I_16();
1089 uint32 d2 = OPER_I_16();
1090 uint32 ea = (d1 << 16) | d2;
1091 m68ki_write_32(ea+0, (uint32)(data >> 32));
1092 m68ki_write_32(ea+4, (uint32)(data));
1095 case 2: // (d16, PC)
1097 uint32 ea = EA_PCDI_32();
1098 m68ki_write_32(ea+0, (uint32)(data >> 32));
1099 m68ki_write_32(ea+4, (uint32)(data));
1102 default: fatalerror("M68kFPU: WRITE_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
1106 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);
1110 static void WRITE_EA_FPE(uint32 ea, floatx80 fpr)
1112 int mode = (ea >> 3) & 0x7;
1113 int reg = (ea & 0x7);
1121 store_extended_float80(ea, fpr);
1129 store_extended_float80(ea, fpr);
1139 store_extended_float80(ea, fpr);
1142 case 5: // (d16, An)
1144 uint32 ea = EA_AY_DI_32();
1145 store_extended_float80(ea, fpr);
1153 default: fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1157 default: fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1161 static void WRITE_EA_PACK(int ea, int k, floatx80 fpr)
1163 int mode = (ea >> 3) & 0x7;
1164 int reg = (ea & 0x7);
1172 store_pack_float80(ea, k, fpr);
1180 store_pack_float80(ea, k, fpr);
1190 store_pack_float80(ea, k, fpr);
1198 default: fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1202 default: fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1207 static void fpgen_rm_reg(uint16 w2)
1209 int ea = REG_IR & 0x3f;
1210 int rm = (w2 >> 14) & 0x1;
1211 int src = (w2 >> 10) & 0x7;
1212 int dst = (w2 >> 7) & 0x7;
1213 int opmode = w2 & 0x7f;
1216 // fmovecr #$f, fp0 f200 5c0f
1222 case 0: // Long-Word Integer
1224 sint32 d = READ_EA_32(ea);
1225 source = int32_to_floatx80(d);
1228 case 1: // Single-precision Real
1230 uint32 d = READ_EA_32(ea);
1231 source = float32_to_floatx80(d);
1234 case 2: // Extended-precision Real
1236 source = READ_EA_FPE(ea);
1239 case 3: // Packed-decimal Real
1241 source = READ_EA_PACK(ea);
1244 case 4: // Word Integer
1246 sint16 d = READ_EA_16(ea);
1247 source = int32_to_floatx80((sint32)d);
1250 case 5: // Double-precision Real
1252 uint64 d = READ_EA_64(ea);
1254 source = float64_to_floatx80(d);
1257 case 6: // Byte Integer
1259 sint8 d = READ_EA_8(ea);
1260 source = int32_to_floatx80((sint32)d);
1263 case 7: // FMOVECR load from constant ROM
1268 source.high = 0x4000;
1269 source.low = U64(0xc90fdaa22168c235);
1272 case 0xb: // log10(2)
1273 source.high = 0x3ffd;
1274 source.low = U64(0x9a209a84fbcff798);
1278 source.high = 0x4000;
1279 source.low = U64(0xadf85458a2bb4a9b);
1282 case 0xd: // log2(e)
1283 source.high = 0x3fff;
1284 source.low = U64(0xb8aa3b295c17f0bc);
1287 case 0xe: // log10(e)
1288 source.high = 0x3ffd;
1289 source.low = U64(0xde5bd8a937287195);
1293 source = int32_to_floatx80((sint32)0);
1297 source.high = 0x3ffe;
1298 source.low = U64(0xb17217f7d1cf79ac);
1301 case 0x31: // ln(10)
1302 source.high = 0x4000;
1303 source.low = U64(0x935d8dddaaa8ac17);
1306 case 0x32: // 1 (or 100? manuals are unclear, but 1 would make more sense)
1307 source = int32_to_floatx80((sint32)1);
1311 source = int32_to_floatx80((sint32)10);
1315 source = int32_to_floatx80((sint32)10*10);
1318 source = int32_to_floatx80((sint32)1000*10);
1322 source = int32_to_floatx80((sint32)10000000*10);
1325 case 0x37: // 1.0e16 - can't get the right precision from s32 so go "direct" with constants from h/w
1326 source.high = 0x4034;
1327 source.low = U64(0x8e1bc9bf04000000);
1330 case 0x38: // 1.0e32
1331 source.high = 0x4069;
1332 source.low = U64(0x9dc5ada82b70b59e);
1335 case 0x39: // 1.0e64
1336 source.high = 0x40d3;
1337 source.low = U64(0xc2781f49ffcfa6d5);
1340 case 0x3a: // 1.0e128
1341 source.high = 0x41a8;
1342 source.low = U64(0x93ba47c980e98ce0);
1345 case 0x3b: // 1.0e256
1346 source.high = 0x4351;
1347 source.low = U64(0xaa7eebfb9df9de8e);
1350 case 0x3c: // 1.0e512
1351 source.high = 0x46a3;
1352 source.low = U64(0xe319a0aea60e91c7);
1355 case 0x3d: // 1.0e1024
1356 source.high = 0x4d48;
1357 source.low = U64(0xc976758681750c17);
1360 case 0x3e: // 1.0e2048
1361 source.high = 0x5a92;
1362 source.low = U64(0x9e8b3b5dc53d5de5);
1365 case 0x3f: // 1.0e4096
1366 source.high = 0x7525;
1367 source.low = U64(0xc46052028a20979b);
1372 fatalerror("fmove_rm_reg: unknown constant ROM offset %x at %08x\n", w2&0x7f, REG_PC-4);
1376 // handle it right here, the usual opmode bits aren't valid in the FMOVECR case
1377 REG_FP[dst] = source;
1378 //FIXME mame doesn't use SET_CONDITION_CODES here
1379 SET_CONDITION_CODES(REG_FP[dst]); // JFF when destination is a register, we HAVE to update FPCR
1383 default: fatalerror("fmove_rm_reg: invalid source specifier %x at %08X\n", src, REG_PC-4);
1388 source = REG_FP[src];
1397 REG_FP[dst] = source;
1398 SET_CONDITION_CODES(REG_FP[dst]);
1405 temp = floatx80_to_int32(source);
1406 REG_FP[dst] = int32_to_floatx80(temp);
1407 //FIXME mame doesn't use SET_CONDITION_CODES here
1408 SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes
1411 case 0x03: // FINTRZ
1414 temp = floatx80_to_int32_round_to_zero(source);
1415 REG_FP[dst] = int32_to_floatx80(temp);
1416 //FIXME mame doesn't use SET_CONDITION_CODES here
1417 SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes
1422 REG_FP[dst] = floatx80_sqrt(source);
1423 SET_CONDITION_CODES(REG_FP[dst]);
1427 case 0x06: // FLOGNP1
1429 REG_FP[dst] = floatx80_flognp1 (source);
1430 SET_CONDITION_CODES(REG_FP[dst]);
1431 USE_CYCLES(594); // for MC68881
1436 REG_FP[dst] = source;
1437 floatx80_fsin(®_FP[dst]);
1438 SET_CONDITION_CODES(REG_FP[dst]);
1444 REG_FP[dst] = source;
1445 floatx80_ftan(®_FP[dst]);
1446 SET_CONDITION_CODES(REG_FP[dst]);
1452 REG_FP[dst] = floatx80_flogn (source);
1453 SET_CONDITION_CODES(REG_FP[dst]);
1454 USE_CYCLES(548); // for MC68881
1457 case 0x15: // FLOG10
1459 REG_FP[dst] = floatx80_flog10 (source);
1460 SET_CONDITION_CODES(REG_FP[dst]);
1461 USE_CYCLES(604); // for MC68881
1466 REG_FP[dst] = floatx80_flog2 (source);
1467 SET_CONDITION_CODES(REG_FP[dst]);
1468 USE_CYCLES(604); // for MC68881
1473 REG_FP[dst] = source;
1474 REG_FP[dst].high &= 0x7fff;
1475 SET_CONDITION_CODES(REG_FP[dst]);
1481 REG_FP[dst] = source;
1482 REG_FP[dst].high ^= 0x8000;
1483 SET_CONDITION_CODES(REG_FP[dst]);
1489 REG_FP[dst] = source;
1490 floatx80_fcos(®_FP[dst]);
1491 SET_CONDITION_CODES(REG_FP[dst]);
1495 case 0x1e: // FGETEXP
1499 temp2 = source.high; // get the exponent
1500 temp2 -= 0x3fff; // take off the bias
1501 REG_FP[dst] = double_to_fx80((double)temp2);
1502 SET_CONDITION_CODES(REG_FP[dst]);
1506 case 0x60: // FSDIVS (JFF) (source has already been converted to floatx80)
1509 REG_FP[dst] = floatx80_div(REG_FP[dst], source);
1510 //FIXME mame doesn't use SET_CONDITION_CODES here
1511 SET_CONDITION_CODES(REG_FP[dst]); // JFF
1517 sint8 const mode = float_rounding_mode;
1518 float_rounding_mode = float_round_to_zero;
1519 REG_FP[dst] = floatx80_rem(REG_FP[dst], source);
1520 SET_CONDITION_CODES(REG_FP[dst]);
1521 float_rounding_mode = mode;
1522 USE_CYCLES(43); // guess
1527 REG_FP[dst] = floatx80_add(REG_FP[dst], source);
1528 SET_CONDITION_CODES(REG_FP[dst]);
1532 case 0x63: // FSMULS (JFF) (source has already been converted to floatx80)
1535 REG_FP[dst] = floatx80_mul(REG_FP[dst], source);
1536 SET_CONDITION_CODES(REG_FP[dst]);
1540 case 0x24: // FSGLDIV
1542 float32 a = floatx80_to_float32( REG_FP[dst] );
1543 float32 b = floatx80_to_float32( source );
1544 REG_FP[dst] = float32_to_floatx80( float32_div(a, b) );
1545 USE_CYCLES(43); // // ? (value is from FDIV)
1550 sint8 const mode = float_rounding_mode;
1551 float_rounding_mode = float_round_nearest_even;
1552 REG_FP[dst] = floatx80_rem(REG_FP[dst], source);
1553 SET_CONDITION_CODES(REG_FP[dst]);
1554 float_rounding_mode = mode;
1555 USE_CYCLES(43); // guess
1558 case 0x26: // FSCALE
1560 REG_FP[dst] = floatx80_scale(REG_FP[dst], source);
1561 SET_CONDITION_CODES(REG_FP[dst]);
1562 USE_CYCLES(46); // (better?) guess
1565 case 0x27: // FSGLMUL
1567 float32 a = floatx80_to_float32( REG_FP[dst] );
1568 float32 b = floatx80_to_float32( source );
1569 REG_FP[dst] = float32_to_floatx80( float32_mul(a, b) );
1570 SET_CONDITION_CODES(REG_FP[dst]);
1571 USE_CYCLES(11); // ? (value is from FMUL)
1576 REG_FP[dst] = floatx80_sub(REG_FP[dst], source);
1577 SET_CONDITION_CODES(REG_FP[dst]);
1584 res = floatx80_sub(REG_FP[dst], source);
1585 SET_CONDITION_CODES(res);
1593 SET_CONDITION_CODES(res);
1598 default: fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PC-4);
1602 static void fmove_reg_mem(uint16 w2)
1604 int ea = REG_IR & 0x3f;
1605 int src = (w2 >> 7) & 0x7;
1606 int dst = (w2 >> 10) & 0x7;
1607 int k = (w2 & 0x7f);
1611 case 0: // Long-Word Integer
1613 sint32 d = (sint32)floatx80_to_int32(REG_FP[src]);
1617 case 1: // Single-precision Real
1619 uint32 d = floatx80_to_float32(REG_FP[src]);
1623 case 2: // Extended-precision Real
1625 WRITE_EA_FPE(ea, REG_FP[src]);
1628 case 3: // Packed-decimal Real with Static K-factor
1631 k = (k & 0x40) ? (k | 0xffffff80) : (k & 0x7f);
1632 WRITE_EA_PACK(ea, k, REG_FP[src]);
1635 case 4: // Word Integer
1637 sint32 value = floatx80_to_int32(REG_FP[src]);
1638 if (value > 0x7fff || value < -0x8000 )
1640 REG_FPSR |= FPES_OE | FPAE_IOP;
1642 WRITE_EA_16(ea, (sint16)value);
1645 case 5: // Double-precision Real
1649 d = floatx80_to_float64(REG_FP[src]);
1654 case 6: // Byte Integer
1656 sint32 value = floatx80_to_int32(REG_FP[src]);
1657 if (value > 127 || value < -128)
1659 REG_FPSR |= FPES_OE | FPAE_IOP;
1661 WRITE_EA_8(ea, (sint8)value);
1664 case 7: // Packed-decimal Real with Dynamic K-factor
1666 WRITE_EA_PACK(ea, REG_D[k>>4], REG_FP[src]);
1674 static void fmove_fpcr(uint16 w2)
1676 int ea = REG_IR & 0x3f;
1677 int dir = (w2 >> 13) & 0x1;
1678 int regsel = (w2 >> 10) & 0x7;
1679 int mode = (ea >> 3) & 0x7;
1681 if ((mode == 5) || (mode == 6))
1683 uint32 address = 0xffffffff; // force a bus error if this doesn't get assigned
1687 address = EA_AY_DI_32();
1691 address = EA_AY_IX_32();
1694 if (dir) // From system control reg to <ea>
1696 if (regsel & 4) { m68ki_write_32(address, REG_FPCR); address += 4; }
1697 if (regsel & 2) { m68ki_write_32(address, REG_FPSR); address += 4; }
1698 if (regsel & 1) { m68ki_write_32(address, REG_FPIAR); address += 4; }
1700 else // From <ea> to system control reg
1702 if (regsel & 4) { REG_FPCR = m68ki_read_32(address); address += 4; }
1703 if (regsel & 2) { REG_FPSR = m68ki_read_32(address); address += 4; }
1704 if (regsel & 1) { REG_FPIAR = m68ki_read_32(address); address += 4; }
1709 if (dir) // From system control reg to <ea>
1711 if (regsel & 4) WRITE_EA_32(ea, REG_FPCR);
1712 if (regsel & 2) WRITE_EA_32(ea, REG_FPSR);
1713 if (regsel & 1) WRITE_EA_32(ea, REG_FPIAR);
1715 else // From <ea> to system control reg
1717 if (regsel & 4) REG_FPCR = READ_EA_32(ea);
1718 if (regsel & 2) REG_FPSR = READ_EA_32(ea);
1719 if (regsel & 1) REG_FPIAR = READ_EA_32(ea);
1723 // FIXME: (2011-12-18 ost)
1724 // rounding_mode and rounding_precision of softfloat.c should be set according to current fpcr
1725 // but: with this code on Apollo the following programs in /systest/fptest will fail:
1726 // 1. Single Precision Whetstone will return wrong results never the less
1727 // 2. Vector Test will fault with 00040004: reference to illegal address
1729 if ((regsel & 4) && dir == 0)
1731 int rnd = (REG_FPCR >> 4) & 3;
1732 int prec = (REG_FPCR >> 6) & 3;
1734 // logerror("m68k_fpsp:fmove_fpcr fpcr=%04x prec=%d rnd=%d\n", m_fpcr, prec, rnd);
1739 case 0: // Extend (X)
1740 floatx80_rounding_precision = 80;
1742 case 1: // Single (S)
1743 floatx80_rounding_precision = 32;
1745 case 2: // Double (D)
1746 floatx80_rounding_precision = 64;
1748 case 3: // Undefined
1749 floatx80_rounding_precision = 80;
1756 case 0: // To Nearest (RN)
1757 float_rounding_mode = float_round_nearest_even;
1759 case 1: // To Zero (RZ)
1760 float_rounding_mode = float_round_to_zero;
1762 case 2: // To Minus Infinitiy (RM)
1763 float_rounding_mode = float_round_down;
1765 case 3: // To Plus Infinitiy (RP)
1766 float_rounding_mode = float_round_up;
1774 static void fmovem(uint16 w2)
1777 int ea = REG_IR & 0x3f;
1778 int dir = (w2 >> 13) & 0x1;
1779 int mode = (w2 >> 11) & 0x3;
1780 int reglist = w2 & 0xff;
1782 uint32 mem_addr = 0;
1785 case 5: // (d16, An)
1786 mem_addr= EA_AY_DI_32();
1788 case 6: // (An) + (Xn) + d8
1789 mem_addr= EA_AY_IX_32();
1793 if (dir) // From FP regs to mem
1797 case 1: // Dynamic register list, postincrement or control addressing mode.
1798 // FIXME: not really tested, but seems to work
1799 reglist = REG_D[(reglist >> 4) & 7];
1802 case 0: // Static register list, predecrement or control addressing mode
1804 for (i=0; i < 8; i++)
1806 if (reglist & (1 << i))
1810 case 5: // (d16, An)
1811 case 6: // (An) + (Xn) + d8
1812 store_extended_float80(mem_addr, REG_FP[i]);
1816 WRITE_EA_FPE(ea, REG_FP[i]);
1826 case 2: // Static register list, postdecrement or control addressing mode.
1828 for (i=0; i < 8; i++)
1830 if (reglist & (1 << i))
1834 case 5: // (d16, An)
1835 case 6: // (An) + (Xn) + d8
1836 store_extended_float80(mem_addr, REG_FP[7-i]);
1840 WRITE_EA_FPE(ea, REG_FP[7-i]);
1850 default: fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
1853 else // From mem to FP regs
1857 case 3: // Dynamic register list, predecrement addressing mode.
1858 // FIXME: not really tested, but seems to work
1859 reglist = REG_D[(reglist >> 4) & 7];
1862 case 2: // Static register list, postincrement or control addressing mode
1864 for (i=0; i < 8; i++)
1866 if (reglist & (1 << i))
1870 case 5: // (d16, An)
1871 case 6: // (An) + (Xn) + d8
1872 REG_FP[7-i] = load_extended_float80(mem_addr);
1876 REG_FP[7-i] = READ_EA_FPE(ea);
1885 default: fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
1892 int ea = REG_IR & 0x3f;
1893 int condition = (sint16)(OPER_I_16());
1895 WRITE_EA_8(ea, TEST_CONDITION(condition) ? 0xff : 0);
1896 USE_CYCLES(7); // ???
1898 static void fbcc16(void)
1901 int condition = REG_IR & 0x3f;
1903 offset = (sint16)(OPER_I_16());
1905 // TODO: condition and jump!!!
1906 if (TEST_CONDITION(condition))
1908 m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */
1909 m68ki_branch_16(offset-2);
1915 static void fbcc32(void)
1918 int condition = REG_IR & 0x3f;
1920 offset = OPER_I_32();
1922 // TODO: condition and jump!!!
1923 if (TEST_CONDITION(condition))
1925 m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */
1926 m68ki_branch_32(offset-4);
1933 void m68040_fpu_op0()
1935 m68ki_cpu.fpu_just_reset = 0;
1937 switch ((REG_IR >> 6) & 0x3)
1941 uint16 w2 = OPER_I_16();
1942 switch ((w2 >> 13) & 0x7)
1944 case 0x0: // FPU ALU FP, FP
1945 case 0x2: // FPU ALU ea, FP
1951 case 0x3: // FMOVE FP, ea
1957 case 0x4: // FMOVEM ea, FPCR
1958 case 0x5: // FMOVEM FPCR, ea
1964 case 0x6: // FMOVEM ea, list
1965 case 0x7: // FMOVEM list, ea
1971 default: fatalerror("M68kFPU: unimplemented subop %d at %08X\n", (w2 >> 13) & 0x7, REG_PC-4);
1976 case 1: // FBcc disp16
1978 switch ((REG_IR >> 3) & 0x7) {
1981 printf("M68kFPU: unimplemented FDBcc main op %d with mode %d at %08X\n", (REG_IR >> 6) & 0x3, (REG_IR >> 3) & 0x7, REG_PC-4);
1983 default: // FScc (?)
1987 fatalerror("M68kFPU: unimplemented main op %d with mode %d at %08X\n", (REG_IR >> 6) & 0x3, (REG_IR >> 3) & 0x7, REG_PC-4);
1990 case 2: // FBcc disp16
1995 case 3: // FBcc disp32
2001 default: fatalerror("M68kFPU: unimplemented main op %d\n", (REG_IR >> 6) & 0x3);
2005 static int perform_fsave(uint32 addr, int inc)
2007 if(m68ki_cpu.cpu_type & CPU_TYPE_040)
2011 m68ki_write_32(addr, 0x41000000);
2016 m68ki_write_32(addr, 0x41000000);
2023 // 68881 IDLE, version 0x1f
2024 m68ki_write_32(addr, 0x1f180000);
2025 m68ki_write_32(addr+4, 0);
2026 m68ki_write_32(addr+8, 0);
2027 m68ki_write_32(addr+12, 0);
2028 m68ki_write_32(addr+16, 0);
2029 m68ki_write_32(addr+20, 0);
2030 m68ki_write_32(addr+24, 0x70000000);
2035 m68ki_write_32(addr+4-4, 0x70000000);
2036 m68ki_write_32(addr+4-8, 0);
2037 m68ki_write_32(addr+4-12, 0);
2038 m68ki_write_32(addr+4-16, 0);
2039 m68ki_write_32(addr+4-20, 0);
2040 m68ki_write_32(addr+4-24, 0);
2041 m68ki_write_32(addr+4-28, 0x1f180000);
2046 // FRESTORE on a NULL frame reboots the FPU - all registers to NaN, the 3 status regs to 0
2047 static void do_frestore_null(void)
2054 for (i = 0; i < 8; i++)
2056 REG_FP[i].high = 0x7fff;
2057 REG_FP[i].low = U64(0xffffffffffffffff);
2060 // Mac IIci at 408458e6 wants an FSAVE of a just-restored NULL frame to also be NULL
2061 // The PRM says it's possible to generate a NULL frame, but not how/when/why. (need the 68881/68882 manual!)
2062 m68ki_cpu.fpu_just_reset = 1;
2065 void m68040_do_fsave(uint32 addr, int reg, int inc)
2067 if (m68ki_cpu.fpu_just_reset)
2069 m68ki_write_32(addr, 0);
2073 // we normally generate an IDLE frame
2074 int delta = perform_fsave(addr, inc);
2076 REG_A[reg] += delta;
2080 void m68040_do_frestore(uint32 addr, int reg)
2082 uint32 temp = m68ki_read_32(addr);
2083 // check for nullptr frame
2084 if (temp & 0xff000000)
2086 // we don't handle non-nullptr frames
2087 m68ki_cpu.fpu_just_reset = 0;
2091 uint8 m40 = !!(m68ki_cpu.cpu_type & CPU_TYPE_040);
2092 // how about an IDLE frame?
2093 if (!m40 && ((temp & 0x00ff0000) == 0x00180000))
2095 REG_A[reg] += 7*4-4;
2097 else if (m40 && ((temp & 0xffff0000) == 0x41000000))
2101 else if ((temp & 0x00ff0000) == 0x00380000)
2105 else if ((temp & 0x00ff0000) == 0x00b40000)
2117 void m68040_fpu_op1()
2119 int ea = REG_IR & 0x3f;
2120 int mode = (ea >> 3) & 0x7;
2121 int reg = (ea & 0x7);
2124 switch ((REG_IR >> 6) & 0x3)
2126 case 0: // FSAVE <ea>
2132 m68040_do_fsave(addr, -1, 1);
2136 addr = EA_AY_PI_32();
2137 printf("FSAVE mode %d, reg A%d=0x%08x\n",mode,reg,REG_A[reg]);
2138 m68040_do_fsave(addr, -1, 1); // FIXME: -1 was reg
2142 addr = EA_AY_PD_32();
2143 m68040_do_fsave(addr, reg, 0); // FIXME: -1 was reg
2145 case 5: // (D16, An)
2146 addr = EA_AY_DI_16();
2147 m68040_do_fsave(addr, -1, 1);
2150 case 6: // (An) + (Xn) + d8
2151 addr = EA_AY_IX_16();
2152 m68040_do_fsave(addr, -1, 1);
2162 m68040_do_fsave(addr, -1, 1);
2165 case 2: // (d16, PC)
2167 addr = EA_PCDI_16();
2168 m68040_do_fsave(addr, -1, 1);
2172 fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2178 fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2183 case 1: // FRESTORE <ea>
2189 m68040_do_frestore(addr, -1);
2193 addr = EA_AY_PI_32();
2194 m68040_do_frestore(addr, reg);
2197 case 5: // (D16, An)
2198 addr = EA_AY_DI_16();
2199 m68040_do_frestore(addr, -1);
2202 case 6: // (An) + (Xn) + d8
2203 addr = EA_AY_IX_16();
2204 m68040_do_frestore(addr, -1);
2214 m68040_do_frestore(addr, -1);
2217 case 2: // (d16, PC)
2219 addr = EA_PCDI_16();
2220 m68040_do_frestore(addr, -1);
2224 fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2230 fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2235 default: fatalerror("m68040_fpu_op1: unimplemented op %d at %08X\n", (REG_IR >> 6) & 0x3, REG_PC-2);
2241 uint16 w2 = OPER_I_16();
2243 // now check the condition
2244 if (TEST_CONDITION(w2 & 0x3f))
2247 m68ki_exception_trap(EXCEPTION_TRAPV);
2249 else // fall through, requires eating the operand
2251 switch (REG_IR & 0x7)
2253 case 2: // word operand
2257 case 3: // long word operand
2261 case 4: // no operand