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 DOUBLE_INFINITY (unsigned long long)(0x7ff0000000000000)
21 #define DOUBLE_EXPONENT (unsigned long long)(0x7ff0000000000000)
22 #define DOUBLE_MANTISSA (unsigned long long)(0x000fffffffffffff)
24 extern flag floatx80_is_nan( floatx80 a );
26 // masks for packed dwords, positive k-factor
27 static uint32 pkmask2[18] =
29 0xffffffff, 0, 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
30 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
31 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
32 0xffffffff, 0xffffffff, 0xffffffff
35 static uint32 pkmask3[18] =
37 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0,
38 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
39 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
42 static inline double fx80_to_double(floatx80 fx)
49 d = floatx80_to_float64(fx);
54 static inline floatx80 double_to_fx80(double in)
60 return float64_to_floatx80(*d);
63 static inline floatx80 load_extended_float80(uint32 ea)
69 d3 = m68ki_read_16(ea);
70 d1 = m68ki_read_32(ea+4);
71 d2 = m68ki_read_32(ea+8);
74 fp.low = ((uint64)d1<<32) | (d2 & 0xffffffff);
79 static inline void store_extended_float80(uint32 ea, floatx80 fpr)
81 m68ki_write_16(ea+0, fpr.high);
82 m68ki_write_16(ea+2, 0);
83 m68ki_write_32(ea+4, (fpr.low>>32)&0xffffffff);
84 m68ki_write_32(ea+8, fpr.low&0xffffffff);
87 static inline floatx80 load_pack_float80(uint32 ea)
94 dw1 = m68ki_read_32(ea);
95 dw2 = m68ki_read_32(ea+4);
96 dw3 = m68ki_read_32(ea+8);
99 if (dw1 & 0x80000000) // mantissa sign
103 *ch++ = (char)((dw1 & 0xf) + '0');
105 *ch++ = (char)(((dw2 >> 28) & 0xf) + '0');
106 *ch++ = (char)(((dw2 >> 24) & 0xf) + '0');
107 *ch++ = (char)(((dw2 >> 20) & 0xf) + '0');
108 *ch++ = (char)(((dw2 >> 16) & 0xf) + '0');
109 *ch++ = (char)(((dw2 >> 12) & 0xf) + '0');
110 *ch++ = (char)(((dw2 >> 8) & 0xf) + '0');
111 *ch++ = (char)(((dw2 >> 4) & 0xf) + '0');
112 *ch++ = (char)(((dw2 >> 0) & 0xf) + '0');
113 *ch++ = (char)(((dw3 >> 28) & 0xf) + '0');
114 *ch++ = (char)(((dw3 >> 24) & 0xf) + '0');
115 *ch++ = (char)(((dw3 >> 20) & 0xf) + '0');
116 *ch++ = (char)(((dw3 >> 16) & 0xf) + '0');
117 *ch++ = (char)(((dw3 >> 12) & 0xf) + '0');
118 *ch++ = (char)(((dw3 >> 8) & 0xf) + '0');
119 *ch++ = (char)(((dw3 >> 4) & 0xf) + '0');
120 *ch++ = (char)(((dw3 >> 0) & 0xf) + '0');
122 if (dw1 & 0x40000000) // exponent sign
126 *ch++ = (char)(((dw1 >> 24) & 0xf) + '0');
127 *ch++ = (char)(((dw1 >> 20) & 0xf) + '0');
128 *ch++ = (char)(((dw1 >> 16) & 0xf) + '0');
131 sscanf(str, "%le", &tmp);
133 result = double_to_fx80(tmp);
138 static inline void store_pack_float80(uint32 ea, int k, floatx80 fpr)
140 uint32 dw1, dw2, dw3;
147 sprintf(str, "%.16e", fx80_to_double(fpr));
160 dw1 |= (*ch++ - '0');
167 // handle negative k-factor here
168 if ((k <= 0) && (k >= -13))
171 for (i = 0; i < 3; i++)
173 if (ch[18+i] >= '0' && ch[18+i] <= '9')
175 exp = (exp << 4) | (ch[18+i] - '0');
185 // last digit is (k + exponent - 1)
188 // round up the last significant mantissa digit
194 // zero out the rest of the mantissa digits
195 for (j = (k+1); j < 16; j++)
200 // now zero out K to avoid tripping the positive K detection below
204 // crack 8 digits of the mantissa
205 for (i = 0; i < 8; i++)
208 if (*ch >= '0' && *ch <= '9')
214 // next 8 digits of the mantissa
215 for (i = 0; i < 8; i++)
218 if (*ch >= '0' && *ch <= '9')
222 // handle masking if k is positive
234 // m68ki_cpu.fpcr |= (need to set OPERR bit)
238 // finally, crack the exponent
239 if (*ch == 'e' || *ch == 'E')
254 for (i = 0; i < 3; i++)
256 if (*ch >= '0' && *ch <= '9')
258 j = (j << 4) | (*ch++ - '0');
265 m68ki_write_32(ea, dw1);
266 m68ki_write_32(ea+4, dw2);
267 m68ki_write_32(ea+8, dw3);
270 static inline void SET_CONDITION_CODES(floatx80 reg)
272 REG_FPSR &= ~(FPCC_N|FPCC_Z|FPCC_I|FPCC_NAN);
275 if (reg.high & 0x8000)
281 if (((reg.high & 0x7fff) == 0) && ((reg.low<<1) == 0))
287 if (((reg.high & 0x7fff) == 0x7fff) && ((reg.low<<1) == 0))
293 if (floatx80_is_nan(reg))
295 REG_FPSR |= FPCC_NAN;
299 static inline int TEST_CONDITION(int condition)
301 int n = (REG_FPSR & FPCC_N) != 0;
302 int z = (REG_FPSR & FPCC_Z) != 0;
303 int nan = (REG_FPSR & FPCC_NAN) != 0;
308 case 0x00: return 0; // False
311 case 0x01: return (z); // Equal
314 case 0x02: return (!(nan || z || n)); // Greater Than
317 case 0x03: return (z || !(nan || n)); // Greater or Equal
320 case 0x04: return (n && !(nan || z)); // Less Than
323 case 0x05: return (z || (n && !nan)); // Less Than or Equal
326 case 0x06: return !nan && !z;
329 case 0x07: return !nan;
332 case 0x08: return nan;
335 case 0x09: return nan || z;
338 case 0x0a: return (nan || !(n || z)); // Not Less Than or Equal
341 case 0x0b: return (nan || z || !n); // Not Less Than
344 case 0x0c: return (nan || (n && !z)); // Not Greater or Equal Than
347 case 0x0d: return (nan || z || n); // Not Greater Than
350 case 0x0e: return (!z); // Not Equal
353 case 0x0f: return 1; // True
355 default: fatalerror("M68kFPU: test_condition: unhandled condition %02X\n", condition);
361 static uint8 READ_EA_8(int ea)
363 int mode = (ea >> 3) & 0x7;
364 int reg = (ea & 0x7);
374 uint32 ea = REG_A[reg];
375 return m68ki_read_8(ea);
379 uint32 ea = EA_AY_DI_8();
380 return m68ki_read_8(ea);
382 case 6: // (An) + (Xn) + d8
384 uint32 ea = EA_AY_IX_8();
385 return m68ki_read_8(ea);
393 uint32 ea = (uint32)OPER_I_16();
394 return m68ki_read_8(ea);
398 uint32 d1 = OPER_I_16();
399 uint32 d2 = OPER_I_16();
400 uint32 ea = (d1 << 16) | d2;
401 return m68ki_read_8(ea);
407 default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
411 default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
417 static uint16 READ_EA_16(int ea)
419 int mode = (ea >> 3) & 0x7;
420 int reg = (ea & 0x7);
426 return (uint16)(REG_D[reg]);
430 uint32 ea = REG_A[reg];
431 return m68ki_read_16(ea);
435 uint32 ea = EA_AY_DI_16();
436 return m68ki_read_16(ea);
438 case 6: // (An) + (Xn) + d8
440 uint32 ea = EA_AY_IX_16();
441 return m68ki_read_16(ea);
449 uint32 ea = (uint32)OPER_I_16();
450 return m68ki_read_16(ea);
454 uint32 d1 = OPER_I_16();
455 uint32 d2 = OPER_I_16();
456 uint32 ea = (d1 << 16) | d2;
457 return m68ki_read_16(ea);
464 default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
468 default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
474 static uint32 READ_EA_32(int ea)
476 int mode = (ea >> 3) & 0x7;
477 int reg = (ea & 0x7);
487 uint32 ea = REG_A[reg];
488 return m68ki_read_32(ea);
492 uint32 ea = EA_AY_PI_32();
493 return m68ki_read_32(ea);
497 uint32 ea = EA_AY_DI_32();
498 return m68ki_read_32(ea);
500 case 6: // (An) + (Xn) + d8
502 uint32 ea = EA_AY_IX_32();
503 return m68ki_read_32(ea);
511 uint32 ea = (uint32)OPER_I_16();
512 return m68ki_read_32(ea);
516 uint32 d1 = OPER_I_16();
517 uint32 d2 = OPER_I_16();
518 uint32 ea = (d1 << 16) | d2;
519 return m68ki_read_32(ea);
523 uint32 ea = EA_PCDI_32();
524 return m68ki_read_32(ea);
530 default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
534 default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
539 static uint64 READ_EA_64(int ea)
541 int mode = (ea >> 3) & 0x7;
542 int reg = (ea & 0x7);
549 uint32 ea = REG_A[reg];
550 h1 = m68ki_read_32(ea+0);
551 h2 = m68ki_read_32(ea+4);
552 return (uint64)(h1) << 32 | (uint64)(h2);
556 uint32 ea = REG_A[reg];
558 h1 = m68ki_read_32(ea+0);
559 h2 = m68ki_read_32(ea+4);
560 return (uint64)(h1) << 32 | (uint64)(h2);
564 uint32 ea = EA_AY_DI_32();
565 h1 = m68ki_read_32(ea+0);
566 h2 = m68ki_read_32(ea+4);
567 return (uint64)(h1) << 32 | (uint64)(h2);
577 return (uint64)(h1) << 32 | (uint64)(h2);
581 uint32 ea = EA_PCDI_32();
582 h1 = m68ki_read_32(ea+0);
583 h2 = m68ki_read_32(ea+4);
584 return (uint64)(h1) << 32 | (uint64)(h2);
586 default: fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
590 default: fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
597 static floatx80 READ_EA_FPE(int mode, int reg, uint32 di_mode_ea)
605 uint32 ea = REG_A[reg];
606 fpr = load_extended_float80(ea);
612 uint32 ea = REG_A[reg];
614 fpr = load_extended_float80(ea);
617 case 5: // (d16, An) (added by JFF)
619 fpr = load_extended_float80(di_mode_ea);
623 case 7: // extended modes
629 uint32 ea = EA_PCDI_32();
630 fpr = load_extended_float80(ea);
634 case 3: // (d16,PC,Dx.w)
636 uint32 ea = EA_PCIX_32();
637 fpr = load_extended_float80(ea);
640 case 4: // immediate (JFF)
643 fpr = load_extended_float80(ea);
648 fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
654 default: fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break;
660 static floatx80 READ_EA_PACK(int ea)
663 int mode = (ea >> 3) & 0x7;
664 int reg = (ea & 0x7);
670 uint32 ea = REG_A[reg];
671 fpr = load_pack_float80(ea);
677 uint32 ea = REG_A[reg];
679 fpr = load_pack_float80(ea);
683 case 7: // extended modes
687 case 3: // (d16,PC,Dx.w)
689 uint32 ea = EA_PCIX_32();
690 fpr = load_pack_float80(ea);
695 fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
701 default: fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break;
707 static void WRITE_EA_8(int ea, uint8 data)
709 int mode = (ea >> 3) & 0x7;
710 int reg = (ea & 0x7);
721 uint32 ea = REG_A[reg];
722 m68ki_write_8(ea, data);
727 uint32 ea = EA_AY_PI_8();
728 m68ki_write_8(ea, data);
733 uint32 ea = EA_AY_PD_8();
734 m68ki_write_8(ea, data);
739 uint32 ea = EA_AY_DI_8();
740 m68ki_write_8(ea, data);
743 case 6: // (An) + (Xn) + d8
745 uint32 ea = EA_AY_IX_8();
746 m68ki_write_8(ea, data);
755 uint32 d1 = OPER_I_16();
756 uint32 d2 = OPER_I_16();
757 uint32 ea = (d1 << 16) | d2;
758 m68ki_write_8(ea, data);
763 uint32 ea = EA_PCDI_16();
764 m68ki_write_8(ea, data);
767 default: fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
771 default: fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
775 static void WRITE_EA_16(int ea, uint16 data)
777 int mode = (ea >> 3) & 0x7;
778 int reg = (ea & 0x7);
789 uint32 ea = REG_A[reg];
790 m68ki_write_16(ea, data);
795 uint32 ea = EA_AY_PI_16();
796 m68ki_write_16(ea, data);
801 uint32 ea = EA_AY_PD_16();
802 m68ki_write_16(ea, data);
807 uint32 ea = EA_AY_DI_16();
808 m68ki_write_16(ea, data);
811 case 6: // (An) + (Xn) + d8
813 uint32 ea = EA_AY_IX_16();
814 m68ki_write_16(ea, data);
823 uint32 d1 = OPER_I_16();
824 uint32 d2 = OPER_I_16();
825 uint32 ea = (d1 << 16) | d2;
826 m68ki_write_16(ea, data);
831 uint32 ea = EA_PCDI_16();
832 m68ki_write_16(ea, data);
835 default: fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
839 default: fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
843 static void WRITE_EA_32(int ea, uint32 data)
845 int mode = (ea >> 3) & 0x7;
846 int reg = (ea & 0x7);
862 uint32 ea = REG_A[reg];
863 m68ki_write_32(ea, data);
868 uint32 ea = EA_AY_PI_32();
869 m68ki_write_32(ea, data);
874 uint32 ea = EA_AY_PD_32();
875 m68ki_write_32(ea, data);
880 uint32 ea = EA_AY_DI_32();
881 m68ki_write_32(ea, data);
884 case 6: // (An) + (Xn) + d8
886 uint32 ea = EA_AY_IX_32();
887 m68ki_write_32(ea, data);
896 uint32 d1 = OPER_I_16();
897 uint32 d2 = OPER_I_16();
898 uint32 ea = (d1 << 16) | d2;
899 m68ki_write_32(ea, data);
904 uint32 ea = EA_PCDI_32();
905 m68ki_write_32(ea, data);
908 default: fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
912 default: fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
916 static void WRITE_EA_64(int ea, uint64 data)
918 int mode = (ea >> 3) & 0x7;
919 int reg = (ea & 0x7);
925 uint32 ea = REG_A[reg];
926 m68ki_write_32(ea, (uint32)(data >> 32));
927 m68ki_write_32(ea+4, (uint32)(data));
935 m68ki_write_32(ea+0, (uint32)(data >> 32));
936 m68ki_write_32(ea+4, (uint32)(data));
941 uint32 ea = EA_AY_DI_32();
942 m68ki_write_32(ea+0, (uint32)(data >> 32));
943 m68ki_write_32(ea+4, (uint32)(data));
946 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);
950 static void WRITE_EA_FPE(int mode, int reg, floatx80 fpr, uint32 di_mode_ea)
960 store_extended_float80(ea, fpr);
968 store_extended_float80(ea, fpr);
978 store_extended_float80(ea, fpr);
981 case 5: // (d16, An) (added by JFF)
983 // EA_AY_DI_32() should not be done here because fmovem would increase
984 // PC each time, reading incorrect displacement & advancing PC too much
985 // uint32 ea = EA_AY_DI_32();
986 store_extended_float80(di_mode_ea, fpr);
994 default: fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
998 default: fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1002 static void WRITE_EA_PACK(int ea, int k, floatx80 fpr)
1004 int mode = (ea >> 3) & 0x7;
1005 int reg = (ea & 0x7);
1013 store_pack_float80(ea, k, fpr);
1021 store_pack_float80(ea, k, fpr);
1031 store_pack_float80(ea, k, fpr);
1039 default: fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1043 default: fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1048 static void fpgen_rm_reg(uint16 w2)
1050 int ea = REG_IR & 0x3f;
1051 int rm = (w2 >> 14) & 0x1;
1052 int src = (w2 >> 10) & 0x7;
1053 int dst = (w2 >> 7) & 0x7;
1054 int opmode = w2 & 0x7f;
1057 // fmovecr #$f, fp0 f200 5c0f
1063 case 0: // Long-Word Integer
1065 sint32 d = READ_EA_32(ea);
1066 source = int32_to_floatx80(d);
1069 case 1: // Single-precision Real
1071 uint32 d = READ_EA_32(ea);
1072 source = float32_to_floatx80(d);
1075 case 2: // Extended-precision Real
1077 int imode = (ea >> 3) & 0x7;
1078 int reg = (ea & 0x7);
1079 uint32 di_mode_ea = imode == 5 ? (REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16())) : 0;
1080 source = READ_EA_FPE(imode,reg,di_mode_ea);
1083 case 3: // Packed-decimal Real
1085 source = READ_EA_PACK(ea);
1088 case 4: // Word Integer
1090 sint16 d = READ_EA_16(ea);
1091 source = int32_to_floatx80((sint32)d);
1094 case 5: // Double-precision Real
1096 uint64 d = READ_EA_64(ea);
1098 source = float64_to_floatx80(d);
1101 case 6: // Byte Integer
1103 sint8 d = READ_EA_8(ea);
1104 source = int32_to_floatx80((sint32)d);
1107 case 7: // FMOVECR load from constant ROM
1112 source.high = 0x4000;
1113 source.low = U64(0xc90fdaa22168c235);
1116 case 0xb: // log10(2)
1117 source.high = 0x3ffd;
1118 source.low = U64(0x9a209a84fbcff798);
1122 source.high = 0x4000;
1123 source.low = U64(0xadf85458a2bb4a9b);
1126 case 0xd: // log2(e)
1127 source.high = 0x3fff;
1128 source.low = U64(0xb8aa3b295c17f0bc);
1131 case 0xe: // log10(e)
1132 source.high = 0x3ffd;
1133 source.low = U64(0xde5bd8a937287195);
1137 source = int32_to_floatx80((sint32)0);
1141 source.high = 0x3ffe;
1142 source.low = U64(0xb17217f7d1cf79ac);
1145 case 0x31: // ln(10)
1146 source.high = 0x4000;
1147 source.low = U64(0x935d8dddaaa8ac17);
1150 case 0x32: // 1 (or 100? manuals are unclear, but 1 would make more sense)
1151 source = int32_to_floatx80((sint32)1);
1155 source = int32_to_floatx80((sint32)10);
1159 source = int32_to_floatx80((sint32)10*10);
1163 fatalerror("fmove_rm_reg: unknown constant ROM offset %x at %08x\n", w2&0x7f, REG_PC-4);
1167 // handle it right here, the usual opmode bits aren't valid in the FMOVECR case
1168 REG_FP[dst] = source;
1169 SET_CONDITION_CODES(REG_FP[dst]); // JFF when destination is a register, we HAVE to update FPCR
1173 default: fatalerror("fmove_rm_reg: invalid source specifier %x at %08X\n", src, REG_PC-4);
1178 source = REG_FP[src];
1187 REG_FP[dst] = source;
1188 SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes
1195 temp = floatx80_to_int32(source);
1196 REG_FP[dst] = int32_to_floatx80(temp);
1197 SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes
1200 case 0x03: // FsintRZ
1203 temp = floatx80_to_int32_round_to_zero(source);
1204 REG_FP[dst] = int32_to_floatx80(temp);
1205 SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes
1210 REG_FP[dst] = floatx80_sqrt(source);
1211 SET_CONDITION_CODES(REG_FP[dst]);
1217 REG_FP[dst] = source;
1218 REG_FP[dst].high &= 0x7fff;
1219 SET_CONDITION_CODES(REG_FP[dst]);
1225 REG_FP[dst] = source;
1226 REG_FP[dst].high ^= 0x8000;
1227 SET_CONDITION_CODES(REG_FP[dst]);
1231 case 0x1e: // FGETEXP
1234 temp = source.high; // get the exponent
1235 temp -= 0x3fff; // take off the bias
1236 REG_FP[dst] = double_to_fx80((double)temp);
1237 SET_CONDITION_CODES(REG_FP[dst]);
1241 case 0x60: // FSDIVS (JFF) (source has already been converted to floatx80)
1244 REG_FP[dst] = floatx80_div(REG_FP[dst], source);
1245 SET_CONDITION_CODES(REG_FP[dst]); // JFF
1251 REG_FP[dst] = floatx80_add(REG_FP[dst], source);
1252 SET_CONDITION_CODES(REG_FP[dst]);
1256 case 0x63: // FSMULS (JFF) (source has already been converted to floatx80)
1259 REG_FP[dst] = floatx80_mul(REG_FP[dst], source);
1260 SET_CONDITION_CODES(REG_FP[dst]);
1266 REG_FP[dst] = floatx80_rem(REG_FP[dst], source);
1267 SET_CONDITION_CODES(REG_FP[dst]);
1268 USE_CYCLES(43); // guess
1273 REG_FP[dst] = floatx80_sub(REG_FP[dst], source);
1274 SET_CONDITION_CODES(REG_FP[dst]);
1281 res = floatx80_sub(REG_FP[dst], source);
1282 SET_CONDITION_CODES(res);
1290 SET_CONDITION_CODES(res);
1295 default: fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PC-4);
1299 static void fmove_reg_mem(uint16 w2)
1301 int ea = REG_IR & 0x3f;
1302 int src = (w2 >> 7) & 0x7;
1303 int dst = (w2 >> 10) & 0x7;
1304 int k = (w2 & 0x7f);
1308 case 0: // Long-Word Integer
1310 sint32 d = (sint32)floatx80_to_int32(REG_FP[src]);
1314 case 1: // Single-precision Real
1316 uint32 d = floatx80_to_float32(REG_FP[src]);
1320 case 2: // Extended-precision Real
1322 int mode = (ea >> 3) & 0x7;
1323 int reg = (ea & 0x7);
1324 uint32 di_mode_ea = mode == 5 ? (REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16())) : 0;
1325 WRITE_EA_FPE(mode, reg, REG_FP[src], di_mode_ea);
1328 case 3: // Packed-decimal Real with Static K-factor
1331 k = (k & 0x40) ? (k | 0xffffff80) : (k & 0x7f);
1332 WRITE_EA_PACK(ea, k, REG_FP[src]);
1335 case 4: // Word Integer
1337 WRITE_EA_16(ea, (sint16)floatx80_to_int32(REG_FP[src]));
1340 case 5: // Double-precision Real
1344 d = floatx80_to_float64(REG_FP[src]);
1349 case 6: // Byte Integer
1351 WRITE_EA_8(ea, (sint8)floatx80_to_int32(REG_FP[src]));
1354 case 7: // Packed-decimal Real with Dynamic K-factor
1356 WRITE_EA_PACK(ea, REG_D[k>>4], REG_FP[src]);
1364 static void fmove_fpcr(uint16 w2)
1366 int ea = REG_IR & 0x3f;
1367 int dir = (w2 >> 13) & 0x1;
1368 int reg = (w2 >> 10) & 0x7;
1370 if (dir) // From system control reg to <ea>
1372 if (reg & 4) WRITE_EA_32(ea, REG_FPCR);
1373 if (reg & 2) WRITE_EA_32(ea, REG_FPSR);
1374 if (reg & 1) WRITE_EA_32(ea, REG_FPIAR);
1376 else // From <ea> to system control reg
1380 REG_FPCR = READ_EA_32(ea);
1381 // JFF: need to update rounding mode from softfloat module
1382 float_rounding_mode = (REG_FPCR >> 4) & 0x3;
1384 if (reg & 2) REG_FPSR = READ_EA_32(ea);
1385 if (reg & 1) REG_FPIAR = READ_EA_32(ea);
1391 static void fmovem(uint16 w2)
1394 int ea = REG_IR & 0x3f;
1395 int dir = (w2 >> 13) & 0x1;
1396 int mode = (w2 >> 11) & 0x3;
1397 int reglist = w2 & 0xff;
1399 if (dir) // From FP regs to mem
1403 case 2: // (JFF): Static register list, postincrement or control addressing mode.
1405 int imode = (ea >> 3) & 0x7;
1406 int reg = (ea & 0x7);
1407 int di_mode = imode == 5;
1408 uint32 di_mode_ea = di_mode ? (REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16())) : 0;
1409 for (i=0; i < 8; i++)
1411 if (reglist & (1 << i))
1413 WRITE_EA_FPE(imode,reg, REG_FP[7-i],di_mode_ea);
1423 case 0: // Static register list, predecrement addressing mode
1425 int imode = (ea >> 3) & 0x7;
1426 int reg = (ea & 0x7);
1427 // the "di_mode_ea" parameter kludge is required here else WRITE_EA_FPE would have
1428 // to call EA_AY_DI_32() (that advances PC & reads displacement) each time
1429 // when the proper behaviour is 1) read once, 2) increment ea for each matching register
1430 // this forces to pre-read the mode (named "imode") so we can decide to read displacement, only once
1431 int di_mode = imode == 5;
1432 uint32 di_mode_ea = di_mode ? (REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16())) : 0;
1433 for (i=0; i < 8; i++)
1435 if (reglist & (1 << i))
1437 WRITE_EA_FPE(imode,reg, REG_FP[i],di_mode_ea);
1448 default: fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
1451 else // From mem to FP regs
1455 case 2: // Static register list, postincrement addressing mode
1457 int imode = (ea >> 3) & 0x7;
1458 int reg = (ea & 0x7);
1459 int di_mode = imode == 5;
1460 uint32 di_mode_ea = di_mode ? (REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16())) : 0;
1461 for (i=0; i < 8; i++)
1463 if (reglist & (1 << i))
1465 REG_FP[7-i] = READ_EA_FPE(imode,reg,di_mode_ea);
1476 default: fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
1483 // added by JFF, this seems to work properly now
1484 int condition = OPER_I_16() & 0x3f;
1486 int cc = TEST_CONDITION(condition);
1487 int mode = (REG_IR & 0x38) >> 3;
1488 int v = (cc ? 0xff : 0x00);
1494 // If the specified floating-point condition is true, sets the byte integer operand at
1495 // the destination to TRUE (all ones); otherwise, sets the byte to FALSE (all zeros).
1497 REG_D[REG_IR & 7] = (REG_D[REG_IR & 7] & 0xFFFFFF00) | v;
1500 case 5: // (disp,Ax)
1502 int reg = REG_IR & 7;
1503 uint32 ea = REG_A[reg]+MAKE_INT_16(m68ki_read_imm_16());
1504 m68ki_write_8(ea,v);
1510 // unimplemented see fpu_uae.cpp around line 1300
1511 fatalerror("040fpu0: fscc: mode %d not implemented at %08X\n", mode, REG_PC-4);
1514 USE_CYCLES(7); // JFF unsure of the number of cycles!!
1516 static void fbcc16(void)
1519 int condition = REG_IR & 0x3f;
1521 offset = (sint16)(OPER_I_16());
1523 // TODO: condition and jump!!!
1524 if (TEST_CONDITION(condition))
1526 m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */
1527 m68ki_branch_16(offset-2);
1533 static void fbcc32(void)
1536 int condition = REG_IR & 0x3f;
1538 offset = OPER_I_32();
1540 // TODO: condition and jump!!!
1541 if (TEST_CONDITION(condition))
1543 m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */
1544 m68ki_branch_32(offset-4);
1551 void m68040_fpu_op0()
1553 m68ki_cpu.fpu_just_reset = 0;
1555 switch ((REG_IR >> 6) & 0x3)
1559 uint16 w2 = OPER_I_16();
1560 switch ((w2 >> 13) & 0x7)
1562 case 0x0: // FPU ALU FP, FP
1563 case 0x2: // FPU ALU ea, FP
1569 case 0x3: // FMOVE FP, ea
1575 case 0x4: // FMOVEM ea, FPCR
1576 case 0x5: // FMOVEM FPCR, ea
1582 case 0x6: // FMOVEM ea, list
1583 case 0x7: // FMOVEM list, ea
1589 default: fatalerror("M68kFPU: unimplemented subop %d at %08X\n", (w2 >> 13) & 0x7, REG_PC-4);
1594 case 1: // FScc (JFF)
1599 case 2: // FBcc disp16
1604 case 3: // FBcc disp32
1610 default: fatalerror("M68kFPU: unimplemented main op %d at %08X\n", (m68ki_cpu.ir >> 6) & 0x3, REG_PC-4);
1614 static void perform_fsave(uint32 addr, int inc)
1618 // 68881 IDLE, version 0x1f
1619 m68ki_write_32(addr, 0x1f180000);
1620 m68ki_write_32(addr+4, 0);
1621 m68ki_write_32(addr+8, 0);
1622 m68ki_write_32(addr+12, 0);
1623 m68ki_write_32(addr+16, 0);
1624 m68ki_write_32(addr+20, 0);
1625 m68ki_write_32(addr+24, 0x70000000);
1629 m68ki_write_32(addr, 0x70000000);
1630 m68ki_write_32(addr-4, 0);
1631 m68ki_write_32(addr-8, 0);
1632 m68ki_write_32(addr-12, 0);
1633 m68ki_write_32(addr-16, 0);
1634 m68ki_write_32(addr-20, 0);
1635 m68ki_write_32(addr-24, 0x1f180000);
1639 // FRESTORE on a NULL frame reboots the FPU - all registers to NaN, the 3 status regs to 0
1640 static void do_frestore_null()
1647 for (i = 0; i < 8; i++)
1649 REG_FP[i].high = 0x7fff;
1650 REG_FP[i].low = U64(0xffffffffffffffff);
1653 // Mac IIci at 408458e6 wants an FSAVE of a just-restored NULL frame to also be NULL
1654 // The PRM says it's possible to generate a NULL frame, but not how/when/why. (need the 68881/68882 manual!)
1655 m68ki_cpu.fpu_just_reset = 1;
1658 void m68040_fpu_op1()
1660 int ea = REG_IR & 0x3f;
1661 int mode = (ea >> 3) & 0x7;
1662 int reg = (ea & 0x7);
1665 switch ((REG_IR >> 6) & 0x3)
1667 case 0: // FSAVE <ea>
1672 addr = EA_AY_PI_32();
1674 if (m68ki_cpu.fpu_just_reset)
1676 m68ki_write_32(addr, 0);
1680 // we normally generate an IDLE frame
1682 perform_fsave(addr, 1);
1687 addr = EA_AY_PD_32();
1689 if (m68ki_cpu.fpu_just_reset)
1691 m68ki_write_32(addr, 0);
1695 // we normally generate an IDLE frame
1697 perform_fsave(addr, 0);
1702 fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
1708 case 1: // FRESTORE <ea>
1714 temp = m68ki_read_32(addr);
1716 // check for NULL frame
1717 if (temp & 0xff000000)
1719 // we don't handle non-NULL frames and there's no pre/post inc/dec to do here
1720 m68ki_cpu.fpu_just_reset = 0;
1729 addr = EA_AY_PI_32();
1730 temp = m68ki_read_32(addr);
1732 // check for NULL frame
1733 if (temp & 0xff000000)
1735 m68ki_cpu.fpu_just_reset = 0;
1737 // how about an IDLE frame?
1738 if ((temp & 0x00ff0000) == 0x00180000)
1742 else if ((temp & 0x00ff0000) == 0x00380000)
1746 else if ((temp & 0x00ff0000) == 0x00b40000)
1758 fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
1764 default: fatalerror("m68040_fpu_op1: unimplemented op %d at %08X\n", (REG_IR >> 6) & 0x3, REG_PC-2);