1 // SPDX-License-Identifier: MIT
8 static void fatalerror(char *format, ...) {
11 vfprintf(stderr,format,ap); // JFF: fixed. Was using fprintf and arguments were wrong
16 #define FPCC_N 0x08000000
17 #define FPCC_Z 0x04000000
18 #define FPCC_I 0x02000000
19 #define FPCC_NAN 0x01000000
21 #define FPES_OE 0x00002000
22 #define FPAE_IOP 0x00000080
24 #define DOUBLE_INFINITY (unsigned long long)(0x7ff0000000000000)
25 #define DOUBLE_EXPONENT (unsigned long long)(0x7ff0000000000000)
26 #define DOUBLE_MANTISSA (unsigned long long)(0x000fffffffffffff)
28 extern flag floatx80_is_nan( floatx80 a );
30 // masks for packed dwords, positive k-factor
31 static uint32 pkmask2[18] =
33 0xffffffff, 0, 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
34 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
35 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
36 0xffffffff, 0xffffffff, 0xffffffff
39 static uint32 pkmask3[18] =
41 0xffffffff, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42 0xf0000000, 0xff000000, 0xfff00000, 0xffff0000,
43 0xfffff000, 0xffffff00, 0xfffffff0, 0xffffffff,
46 static inline double fx80_to_double(floatx80 fx)
53 d = floatx80_to_float64(fx);
58 static inline floatx80 double_to_fx80(double in)
64 return float64_to_floatx80(*d);
67 static inline floatx80 load_extended_float80(uint32 ea)
73 d3 = m68ki_read_16(ea);
74 d1 = m68ki_read_32(ea+4);
75 d2 = m68ki_read_32(ea+8);
78 fp.low = ((uint64)d1<<32) | (d2 & 0xffffffff);
83 static inline void store_extended_float80(uint32 ea, floatx80 fpr)
85 m68ki_write_16(ea+0, fpr.high);
86 m68ki_write_16(ea+2, 0);
87 m68ki_write_32(ea+4, (fpr.low>>32)&0xffffffff);
88 m68ki_write_32(ea+8, fpr.low&0xffffffff);
91 static inline floatx80 load_pack_float80(uint32 ea)
98 dw1 = m68ki_read_32(ea);
99 dw2 = m68ki_read_32(ea+4);
100 dw3 = m68ki_read_32(ea+8);
103 if (dw1 & 0x80000000) // mantissa sign
107 *ch++ = (char)((dw1 & 0xf) + '0');
109 *ch++ = (char)(((dw2 >> 28) & 0xf) + '0');
110 *ch++ = (char)(((dw2 >> 24) & 0xf) + '0');
111 *ch++ = (char)(((dw2 >> 20) & 0xf) + '0');
112 *ch++ = (char)(((dw2 >> 16) & 0xf) + '0');
113 *ch++ = (char)(((dw2 >> 12) & 0xf) + '0');
114 *ch++ = (char)(((dw2 >> 8) & 0xf) + '0');
115 *ch++ = (char)(((dw2 >> 4) & 0xf) + '0');
116 *ch++ = (char)(((dw2 >> 0) & 0xf) + '0');
117 *ch++ = (char)(((dw3 >> 28) & 0xf) + '0');
118 *ch++ = (char)(((dw3 >> 24) & 0xf) + '0');
119 *ch++ = (char)(((dw3 >> 20) & 0xf) + '0');
120 *ch++ = (char)(((dw3 >> 16) & 0xf) + '0');
121 *ch++ = (char)(((dw3 >> 12) & 0xf) + '0');
122 *ch++ = (char)(((dw3 >> 8) & 0xf) + '0');
123 *ch++ = (char)(((dw3 >> 4) & 0xf) + '0');
124 *ch++ = (char)(((dw3 >> 0) & 0xf) + '0');
126 if (dw1 & 0x40000000) // exponent sign
130 *ch++ = (char)(((dw1 >> 24) & 0xf) + '0');
131 *ch++ = (char)(((dw1 >> 20) & 0xf) + '0');
132 *ch++ = (char)(((dw1 >> 16) & 0xf) + '0');
135 sscanf(str, "%le", &tmp);
137 result = double_to_fx80(tmp);
142 static inline void store_pack_float80(uint32 ea, int k, floatx80 fpr)
144 uint32 dw1, dw2, dw3;
151 sprintf(str, "%.16e", fx80_to_double(fpr));
164 dw1 |= (*ch++ - '0');
171 // handle negative k-factor here
172 if ((k <= 0) && (k >= -13))
175 for (i = 0; i < 3; i++)
177 if (ch[18+i] >= '0' && ch[18+i] <= '9')
179 exp = (exp << 4) | (ch[18+i] - '0');
189 // last digit is (k + exponent - 1)
192 // round up the last significant mantissa digit
198 // zero out the rest of the mantissa digits
199 for (j = (k+1); j < 16; j++)
204 // now zero out K to avoid tripping the positive K detection below
208 // crack 8 digits of the mantissa
209 for (i = 0; i < 8; i++)
212 if (*ch >= '0' && *ch <= '9')
218 // next 8 digits of the mantissa
219 for (i = 0; i < 8; i++)
222 if (*ch >= '0' && *ch <= '9')
226 // handle masking if k is positive
238 // m68ki_cpu.fpcr |= (need to set OPERR bit)
242 // finally, crack the exponent
243 if (*ch == 'e' || *ch == 'E')
258 for (i = 0; i < 3; i++)
260 if (*ch >= '0' && *ch <= '9')
262 j = (j << 4) | (*ch++ - '0');
269 m68ki_write_32(ea, dw1);
270 m68ki_write_32(ea+4, dw2);
271 m68ki_write_32(ea+8, dw3);
274 static inline void SET_CONDITION_CODES(floatx80 reg)
278 // regi = (u64 *)®
280 REG_FPSR &= ~(FPCC_N|FPCC_Z|FPCC_I|FPCC_NAN);
283 if (reg.high & 0x8000)
289 if (((reg.high & 0x7fff) == 0) && ((reg.low<<1) == 0))
295 if (((reg.high & 0x7fff) == 0x7fff) && ((reg.low<<1) == 0))
301 if (floatx80_is_nan(reg))
303 REG_FPSR |= FPCC_NAN;
307 static inline int TEST_CONDITION(int condition)
309 int n = (REG_FPSR & FPCC_N) != 0;
310 int z = (REG_FPSR & FPCC_Z) != 0;
311 int nan = (REG_FPSR & FPCC_NAN) != 0;
316 case 0x00: return 0; // False
319 case 0x01: return (z); // Equal
322 case 0x02: return (!(nan || z || n)); // Greater Than
325 case 0x03: return (z || !(nan || n)); // Greater or Equal
328 case 0x04: return (n && !(nan || z)); // Less Than
331 case 0x05: return (z || (n && !nan)); // Less Than or Equal
334 case 0x06: return !nan && !z;
337 case 0x07: return !nan;
340 case 0x08: return nan;
343 case 0x09: return nan || z;
346 case 0x0a: return (nan || !(n || z)); // Not Less Than or Equal
349 case 0x0b: return (nan || z || !n); // Not Less Than
352 case 0x0c: return (nan || (n && !z)); // Not Greater or Equal Than
355 case 0x0d: return (nan || z || n); // Not Greater Than
358 case 0x0e: return (!z); // Not Equal
361 case 0x0f: return 1; // True
363 default: fatalerror("M68kFPU: test_condition: unhandled condition %02X\n", condition);
369 static uint8 READ_EA_8(int ea)
371 int mode = (ea >> 3) & 0x7;
372 int reg = (ea & 0x7);
382 uint32 ea = REG_A[reg];
383 return m68ki_read_8(ea);
387 uint32 ea = EA_AY_PI_8();
388 return m68ki_read_8(ea);
392 uint32 ea = EA_AY_PD_8();
393 return m68ki_read_8(ea);
397 uint32 ea = EA_AY_DI_8();
398 return m68ki_read_8(ea);
400 case 6: // (An) + (Xn) + d8
402 uint32 ea = EA_AY_IX_8();
403 return m68ki_read_8(ea);
411 uint32 ea = (uint32)OPER_I_16();
412 return m68ki_read_8(ea);
416 uint32 d1 = OPER_I_16();
417 uint32 d2 = OPER_I_16();
418 uint32 ea = (d1 << 16) | d2;
419 return m68ki_read_8(ea);
423 uint32 ea = EA_PCDI_8();
424 return m68ki_read_8(ea);
426 case 3: // (PC) + (Xn) + d8
428 uint32 ea = EA_PCIX_8();
429 return m68ki_read_8(ea);
435 default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
439 default: fatalerror("M68kFPU: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
445 static uint16 READ_EA_16(int ea)
447 int mode = (ea >> 3) & 0x7;
448 int reg = (ea & 0x7);
454 return (uint16)(REG_D[reg]);
458 uint32 ea = REG_A[reg];
459 return m68ki_read_16(ea);
463 uint32 ea = EA_AY_PI_16();
464 return m68ki_read_16(ea);
468 uint32 ea = EA_AY_PD_16();
469 return m68ki_read_16(ea);
473 uint32 ea = EA_AY_DI_16();
474 return m68ki_read_16(ea);
476 case 6: // (An) + (Xn) + d8
478 uint32 ea = EA_AY_IX_16();
479 return m68ki_read_16(ea);
487 uint32 ea = (uint32)OPER_I_16();
488 return m68ki_read_16(ea);
492 uint32 d1 = OPER_I_16();
493 uint32 d2 = OPER_I_16();
494 uint32 ea = (d1 << 16) | d2;
495 return m68ki_read_16(ea);
499 uint32 ea = EA_PCDI_16();
500 return m68ki_read_16(ea);
502 case 3: // (PC) + (Xn) + d8
504 uint32 ea = EA_PCIX_16();
505 return m68ki_read_16(ea);
512 default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
516 default: fatalerror("M68kFPU: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
522 static uint32 READ_EA_32(int ea)
524 int mode = (ea >> 3) & 0x7;
525 int reg = (ea & 0x7);
535 uint32 ea = REG_A[reg];
536 return m68ki_read_32(ea);
540 uint32 ea = EA_AY_PI_32();
541 return m68ki_read_32(ea);
545 uint32 ea = EA_AY_PD_32();
546 return m68ki_read_32(ea);
550 uint32 ea = EA_AY_DI_32();
551 return m68ki_read_32(ea);
553 case 6: // (An) + (Xn) + d8
555 uint32 ea = EA_AY_IX_32();
556 return m68ki_read_32(ea);
564 uint32 ea = (uint32)OPER_I_16();
565 return m68ki_read_32(ea);
569 uint32 d1 = OPER_I_16();
570 uint32 d2 = OPER_I_16();
571 uint32 ea = (d1 << 16) | d2;
572 return m68ki_read_32(ea);
576 uint32 ea = EA_PCDI_32();
577 return m68ki_read_32(ea);
579 case 3: // (PC) + (Xn) + d8
581 uint32 ea = EA_PCIX_32();
582 return m68ki_read_32(ea);
588 default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
592 default: fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
597 static uint64 READ_EA_64(int ea)
599 int mode = (ea >> 3) & 0x7;
600 int reg = (ea & 0x7);
607 uint32 ea = REG_A[reg];
608 h1 = m68ki_read_32(ea+0);
609 h2 = m68ki_read_32(ea+4);
610 return (uint64)(h1) << 32 | (uint64)(h2);
614 uint32 ea = REG_A[reg];
616 h1 = m68ki_read_32(ea+0);
617 h2 = m68ki_read_32(ea+4);
618 return (uint64)(h1) << 32 | (uint64)(h2);
622 uint32 ea = REG_A[reg]-8;
624 h1 = m68ki_read_32(ea+0);
625 h2 = m68ki_read_32(ea+4);
626 return (uint64)(h1) << 32 | (uint64)(h2);
630 uint32 ea = EA_AY_DI_32();
631 h1 = m68ki_read_32(ea+0);
632 h2 = m68ki_read_32(ea+4);
633 return (uint64)(h1) << 32 | (uint64)(h2);
635 case 6: // (An) + (Xn) + d8
637 uint32 ea = EA_AY_IX_32();
638 h1 = m68ki_read_32(ea+0);
639 h2 = m68ki_read_32(ea+4);
640 return (uint64)(h1) << 32 | (uint64)(h2);
648 uint32 d1 = OPER_I_16();
649 uint32 d2 = OPER_I_16();
650 uint32 ea = (d1 << 16) | d2;
651 return (uint64)(m68ki_read_32(ea)) << 32 | (uint64)(m68ki_read_32(ea+4));
653 case 3: // (PC) + (Xn) + d8
655 uint32 ea = EA_PCIX_32();
656 h1 = m68ki_read_32(ea+0);
657 h2 = m68ki_read_32(ea+4);
658 return (uint64)(h1) << 32 | (uint64)(h2);
664 return (uint64)(h1) << 32 | (uint64)(h2);
668 uint32 ea = EA_PCDI_32();
669 h1 = m68ki_read_32(ea+0);
670 h2 = m68ki_read_32(ea+4);
671 return (uint64)(h1) << 32 | (uint64)(h2);
673 default: fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
677 default: fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
684 static floatx80 READ_EA_FPE(uint32 ea)
687 int mode = (ea >> 3) & 0x7;
688 int reg = (ea & 0x7);
694 uint32 ea = REG_A[reg];
695 fpr = load_extended_float80(ea);
701 uint32 ea = REG_A[reg];
703 fpr = load_extended_float80(ea);
708 uint32 ea = REG_A[reg]-12;
710 fpr = load_extended_float80(ea);
715 // FIXME: will fail for fmovem
716 uint32 ea = EA_AY_DI_32();
717 fpr = load_extended_float80(ea);
720 case 6: // (An) + (Xn) + d8
722 // FIXME: will fail for fmovem
723 uint32 ea = EA_AY_IX_32();
724 fpr = load_extended_float80(ea);
728 case 7: // extended modes
734 uint32 d1 = OPER_I_16();
735 uint32 d2 = OPER_I_16();
736 uint32 ea = (d1 << 16) | d2;
737 fpr = load_extended_float80(ea);
743 uint32 ea = EA_PCDI_32();
744 fpr = load_extended_float80(ea);
748 case 3: // (d16,PC,Dx.w)
750 uint32 ea = EA_PCIX_32();
751 fpr = load_extended_float80(ea);
755 case 4: // immediate (JFF)
758 fpr = load_extended_float80(ea);
764 fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
770 default: fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break;
776 static floatx80 READ_EA_PACK(int ea)
779 int mode = (ea >> 3) & 0x7;
780 int reg = (ea & 0x7);
786 uint32 ea = REG_A[reg];
787 fpr = load_pack_float80(ea);
793 uint32 ea = REG_A[reg];
795 fpr = load_pack_float80(ea);
799 case 7: // extended modes
803 case 3: // (d16,PC,Dx.w)
805 uint32 ea = EA_PCIX_32();
806 fpr = load_pack_float80(ea);
811 fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
817 default: fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC); break;
823 static void WRITE_EA_8(int ea, uint8 data)
825 int mode = (ea >> 3) & 0x7;
826 int reg = (ea & 0x7);
837 uint32 ea = REG_A[reg];
838 m68ki_write_8(ea, data);
843 uint32 ea = EA_AY_PI_8();
844 m68ki_write_8(ea, data);
849 uint32 ea = EA_AY_PD_8();
850 m68ki_write_8(ea, data);
855 uint32 ea = EA_AY_DI_8();
856 m68ki_write_8(ea, data);
859 case 6: // (An) + (Xn) + d8
861 uint32 ea = EA_AY_IX_8();
862 m68ki_write_8(ea, data);
871 uint32 d1 = OPER_I_16();
872 uint32 d2 = OPER_I_16();
873 uint32 ea = (d1 << 16) | d2;
874 m68ki_write_8(ea, data);
879 uint32 ea = EA_PCDI_16();
880 m68ki_write_8(ea, data);
883 default: fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
887 default: fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
891 static void WRITE_EA_16(int ea, uint16 data)
893 int mode = (ea >> 3) & 0x7;
894 int reg = (ea & 0x7);
905 uint32 ea = REG_A[reg];
906 m68ki_write_16(ea, data);
911 uint32 ea = EA_AY_PI_16();
912 m68ki_write_16(ea, data);
917 uint32 ea = EA_AY_PD_16();
918 m68ki_write_16(ea, data);
923 uint32 ea = EA_AY_DI_16();
924 m68ki_write_16(ea, data);
927 case 6: // (An) + (Xn) + d8
929 uint32 ea = EA_AY_IX_16();
930 m68ki_write_16(ea, data);
939 uint32 d1 = OPER_I_16();
940 uint32 d2 = OPER_I_16();
941 uint32 ea = (d1 << 16) | d2;
942 m68ki_write_16(ea, data);
947 uint32 ea = EA_PCDI_16();
948 m68ki_write_16(ea, data);
951 default: fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
955 default: fatalerror("M68kFPU: WRITE_EA_16: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
959 static void WRITE_EA_32(int ea, uint32 data)
961 int mode = (ea >> 3) & 0x7;
962 int reg = (ea & 0x7);
978 uint32 ea = REG_A[reg];
979 m68ki_write_32(ea, data);
984 uint32 ea = EA_AY_PI_32();
985 m68ki_write_32(ea, data);
990 uint32 ea = EA_AY_PD_32();
991 m68ki_write_32(ea, data);
996 uint32 ea = EA_AY_DI_32();
997 m68ki_write_32(ea, data);
1000 case 6: // (An) + (Xn) + d8
1002 uint32 ea = EA_AY_IX_32();
1003 m68ki_write_32(ea, data);
1012 uint32 ea = OPER_I_16();
1013 m68ki_write_32(ea, data);
1018 uint32 d1 = OPER_I_16();
1019 uint32 d2 = OPER_I_16();
1020 uint32 ea = (d1 << 16) | d2;
1021 m68ki_write_32(ea, data);
1024 case 2: // (d16, PC)
1026 uint32 ea = EA_PCDI_32();
1027 m68ki_write_32(ea, data);
1030 default: fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
1034 default: fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
1038 static void WRITE_EA_64(int ea, uint64 data)
1040 int mode = (ea >> 3) & 0x7;
1041 int reg = (ea & 0x7);
1047 uint32 ea = REG_A[reg];
1048 m68ki_write_32(ea, (uint32)(data >> 32));
1049 m68ki_write_32(ea+4, (uint32)(data));
1054 uint32 ea = REG_A[reg];
1056 m68ki_write_32(ea+0, (uint32)(data >> 32));
1057 m68ki_write_32(ea+4, (uint32)(data));
1065 m68ki_write_32(ea+0, (uint32)(data >> 32));
1066 m68ki_write_32(ea+4, (uint32)(data));
1069 case 5: // (d16, An)
1071 uint32 ea = EA_AY_DI_32();
1072 m68ki_write_32(ea+0, (uint32)(data >> 32));
1073 m68ki_write_32(ea+4, (uint32)(data));
1076 case 6: // (An) + (Xn) + d8
1078 uint32 ea = EA_AY_IX_32();
1079 m68ki_write_32(ea+0, (uint32)(data >> 32));
1080 m68ki_write_32(ea+4, (uint32)(data));
1089 uint32 d1 = OPER_I_16();
1090 uint32 d2 = OPER_I_16();
1091 uint32 ea = (d1 << 16) | d2;
1092 m68ki_write_32(ea+0, (uint32)(data >> 32));
1093 m68ki_write_32(ea+4, (uint32)(data));
1096 case 2: // (d16, PC)
1098 uint32 ea = EA_PCDI_32();
1099 m68ki_write_32(ea+0, (uint32)(data >> 32));
1100 m68ki_write_32(ea+4, (uint32)(data));
1103 default: fatalerror("M68kFPU: WRITE_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
1107 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);
1111 static void WRITE_EA_FPE(uint32 ea, floatx80 fpr)
1113 int mode = (ea >> 3) & 0x7;
1114 int reg = (ea & 0x7);
1122 store_extended_float80(ea, fpr);
1130 store_extended_float80(ea, fpr);
1140 store_extended_float80(ea, fpr);
1143 case 5: // (d16, An)
1145 uint32 ea = EA_AY_DI_32();
1146 store_extended_float80(ea, fpr);
1154 default: fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1158 default: fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1162 static void WRITE_EA_PACK(int ea, int k, floatx80 fpr)
1164 int mode = (ea >> 3) & 0x7;
1165 int reg = (ea & 0x7);
1173 store_pack_float80(ea, k, fpr);
1181 store_pack_float80(ea, k, fpr);
1191 store_pack_float80(ea, k, fpr);
1199 default: fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1203 default: fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
1208 static void fpgen_rm_reg(uint16 w2)
1210 int ea = REG_IR & 0x3f;
1211 int rm = (w2 >> 14) & 0x1;
1212 int src = (w2 >> 10) & 0x7;
1213 int dst = (w2 >> 7) & 0x7;
1214 int opmode = w2 & 0x7f;
1217 // fmovecr #$f, fp0 f200 5c0f
1223 case 0: // Long-Word Integer
1225 sint32 d = READ_EA_32(ea);
1226 source = int32_to_floatx80(d);
1229 case 1: // Single-precision Real
1231 uint32 d = READ_EA_32(ea);
1232 source = float32_to_floatx80(d);
1235 case 2: // Extended-precision Real
1237 source = READ_EA_FPE(ea);
1240 case 3: // Packed-decimal Real
1242 source = READ_EA_PACK(ea);
1245 case 4: // Word Integer
1247 sint16 d = READ_EA_16(ea);
1248 source = int32_to_floatx80((sint32)d);
1251 case 5: // Double-precision Real
1253 uint64 d = READ_EA_64(ea);
1255 source = float64_to_floatx80(d);
1258 case 6: // Byte Integer
1260 sint8 d = READ_EA_8(ea);
1261 source = int32_to_floatx80((sint32)d);
1264 case 7: // FMOVECR load from constant ROM
1269 source.high = 0x4000;
1270 source.low = U64(0xc90fdaa22168c235);
1273 case 0xb: // log10(2)
1274 source.high = 0x3ffd;
1275 source.low = U64(0x9a209a84fbcff798);
1279 source.high = 0x4000;
1280 source.low = U64(0xadf85458a2bb4a9b);
1283 case 0xd: // log2(e)
1284 source.high = 0x3fff;
1285 source.low = U64(0xb8aa3b295c17f0bc);
1288 case 0xe: // log10(e)
1289 source.high = 0x3ffd;
1290 source.low = U64(0xde5bd8a937287195);
1294 source = int32_to_floatx80((sint32)0);
1298 source.high = 0x3ffe;
1299 source.low = U64(0xb17217f7d1cf79ac);
1302 case 0x31: // ln(10)
1303 source.high = 0x4000;
1304 source.low = U64(0x935d8dddaaa8ac17);
1307 case 0x32: // 1 (or 100? manuals are unclear, but 1 would make more sense)
1308 source = int32_to_floatx80((sint32)1);
1312 source = int32_to_floatx80((sint32)10);
1316 source = int32_to_floatx80((sint32)10*10);
1319 source = int32_to_floatx80((sint32)1000*10);
1323 source = int32_to_floatx80((sint32)10000000*10);
1326 case 0x37: // 1.0e16 - can't get the right precision from s32 so go "direct" with constants from h/w
1327 source.high = 0x4034;
1328 source.low = U64(0x8e1bc9bf04000000);
1331 case 0x38: // 1.0e32
1332 source.high = 0x4069;
1333 source.low = U64(0x9dc5ada82b70b59e);
1336 case 0x39: // 1.0e64
1337 source.high = 0x40d3;
1338 source.low = U64(0xc2781f49ffcfa6d5);
1341 case 0x3a: // 1.0e128
1342 source.high = 0x41a8;
1343 source.low = U64(0x93ba47c980e98ce0);
1346 case 0x3b: // 1.0e256
1347 source.high = 0x4351;
1348 source.low = U64(0xaa7eebfb9df9de8e);
1351 case 0x3c: // 1.0e512
1352 source.high = 0x46a3;
1353 source.low = U64(0xe319a0aea60e91c7);
1356 case 0x3d: // 1.0e1024
1357 source.high = 0x4d48;
1358 source.low = U64(0xc976758681750c17);
1361 case 0x3e: // 1.0e2048
1362 source.high = 0x5a92;
1363 source.low = U64(0x9e8b3b5dc53d5de5);
1366 case 0x3f: // 1.0e4096
1367 source.high = 0x7525;
1368 source.low = U64(0xc46052028a20979b);
1373 fatalerror("fmove_rm_reg: unknown constant ROM offset %x at %08x\n", w2&0x7f, REG_PC-4);
1377 // handle it right here, the usual opmode bits aren't valid in the FMOVECR case
1378 REG_FP[dst] = source;
1379 //FIXME mame doesn't use SET_CONDITION_CODES here
1380 SET_CONDITION_CODES(REG_FP[dst]); // JFF when destination is a register, we HAVE to update FPCR
1384 default: fatalerror("fmove_rm_reg: invalid source specifier %x at %08X\n", src, REG_PC-4);
1389 source = REG_FP[src];
1398 REG_FP[dst] = source;
1399 SET_CONDITION_CODES(REG_FP[dst]);
1406 temp = floatx80_to_int32(source);
1407 REG_FP[dst] = int32_to_floatx80(temp);
1408 //FIXME mame doesn't use SET_CONDITION_CODES here
1409 SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes
1412 case 0x03: // FINTRZ
1415 temp = floatx80_to_int32_round_to_zero(source);
1416 REG_FP[dst] = int32_to_floatx80(temp);
1417 //FIXME mame doesn't use SET_CONDITION_CODES here
1418 SET_CONDITION_CODES(REG_FP[dst]); // JFF needs update condition codes
1423 REG_FP[dst] = floatx80_sqrt(source);
1424 SET_CONDITION_CODES(REG_FP[dst]);
1428 case 0x06: // FLOGNP1
1430 REG_FP[dst] = floatx80_flognp1 (source);
1431 SET_CONDITION_CODES(REG_FP[dst]);
1432 USE_CYCLES(594); // for MC68881
1437 REG_FP[dst] = source;
1438 floatx80_fsin(®_FP[dst]);
1439 SET_CONDITION_CODES(REG_FP[dst]);
1445 REG_FP[dst] = source;
1446 floatx80_ftan(®_FP[dst]);
1447 SET_CONDITION_CODES(REG_FP[dst]);
1453 REG_FP[dst] = floatx80_flogn (source);
1454 SET_CONDITION_CODES(REG_FP[dst]);
1455 USE_CYCLES(548); // for MC68881
1458 case 0x15: // FLOG10
1460 REG_FP[dst] = floatx80_flog10 (source);
1461 SET_CONDITION_CODES(REG_FP[dst]);
1462 USE_CYCLES(604); // for MC68881
1467 REG_FP[dst] = floatx80_flog2 (source);
1468 SET_CONDITION_CODES(REG_FP[dst]);
1469 USE_CYCLES(604); // for MC68881
1474 REG_FP[dst] = source;
1475 REG_FP[dst].high &= 0x7fff;
1476 SET_CONDITION_CODES(REG_FP[dst]);
1482 REG_FP[dst] = source;
1483 REG_FP[dst].high ^= 0x8000;
1484 SET_CONDITION_CODES(REG_FP[dst]);
1490 REG_FP[dst] = source;
1491 floatx80_fcos(®_FP[dst]);
1492 SET_CONDITION_CODES(REG_FP[dst]);
1496 case 0x1e: // FGETEXP
1500 temp2 = source.high; // get the exponent
1501 temp2 -= 0x3fff; // take off the bias
1502 REG_FP[dst] = double_to_fx80((double)temp2);
1503 SET_CONDITION_CODES(REG_FP[dst]);
1507 case 0x60: // FSDIVS (JFF) (source has already been converted to floatx80)
1510 REG_FP[dst] = floatx80_div(REG_FP[dst], source);
1511 //FIXME mame doesn't use SET_CONDITION_CODES here
1512 SET_CONDITION_CODES(REG_FP[dst]); // JFF
1518 sint8 const mode = float_rounding_mode;
1519 float_rounding_mode = float_round_to_zero;
1520 REG_FP[dst] = floatx80_rem(REG_FP[dst], source);
1521 SET_CONDITION_CODES(REG_FP[dst]);
1522 float_rounding_mode = mode;
1523 USE_CYCLES(43); // guess
1528 REG_FP[dst] = floatx80_add(REG_FP[dst], source);
1529 SET_CONDITION_CODES(REG_FP[dst]);
1533 case 0x63: // FSMULS (JFF) (source has already been converted to floatx80)
1536 REG_FP[dst] = floatx80_mul(REG_FP[dst], source);
1537 SET_CONDITION_CODES(REG_FP[dst]);
1541 case 0x24: // FSGLDIV
1543 float32 a = floatx80_to_float32( REG_FP[dst] );
1544 float32 b = floatx80_to_float32( source );
1545 REG_FP[dst] = float32_to_floatx80( float32_div(a, b) );
1546 USE_CYCLES(43); // // ? (value is from FDIV)
1551 sint8 const mode = float_rounding_mode;
1552 float_rounding_mode = float_round_nearest_even;
1553 REG_FP[dst] = floatx80_rem(REG_FP[dst], source);
1554 SET_CONDITION_CODES(REG_FP[dst]);
1555 float_rounding_mode = mode;
1556 USE_CYCLES(43); // guess
1559 case 0x26: // FSCALE
1561 REG_FP[dst] = floatx80_scale(REG_FP[dst], source);
1562 SET_CONDITION_CODES(REG_FP[dst]);
1563 USE_CYCLES(46); // (better?) guess
1566 case 0x27: // FSGLMUL
1568 float32 a = floatx80_to_float32( REG_FP[dst] );
1569 float32 b = floatx80_to_float32( source );
1570 REG_FP[dst] = float32_to_floatx80( float32_mul(a, b) );
1571 SET_CONDITION_CODES(REG_FP[dst]);
1572 USE_CYCLES(11); // ? (value is from FMUL)
1577 REG_FP[dst] = floatx80_sub(REG_FP[dst], source);
1578 SET_CONDITION_CODES(REG_FP[dst]);
1585 res = floatx80_sub(REG_FP[dst], source);
1586 SET_CONDITION_CODES(res);
1594 SET_CONDITION_CODES(res);
1599 default: fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PC-4);
1603 static void fmove_reg_mem(uint16 w2)
1605 int ea = REG_IR & 0x3f;
1606 int src = (w2 >> 7) & 0x7;
1607 int dst = (w2 >> 10) & 0x7;
1608 int k = (w2 & 0x7f);
1612 case 0: // Long-Word Integer
1614 sint32 d = (sint32)floatx80_to_int32(REG_FP[src]);
1618 case 1: // Single-precision Real
1620 uint32 d = floatx80_to_float32(REG_FP[src]);
1624 case 2: // Extended-precision Real
1626 WRITE_EA_FPE(ea, REG_FP[src]);
1629 case 3: // Packed-decimal Real with Static K-factor
1632 k = (k & 0x40) ? (k | 0xffffff80) : (k & 0x7f);
1633 WRITE_EA_PACK(ea, k, REG_FP[src]);
1636 case 4: // Word Integer
1638 sint32 value = floatx80_to_int32(REG_FP[src]);
1639 if (value > 0x7fff || value < -0x8000 )
1641 REG_FPSR |= FPES_OE | FPAE_IOP;
1643 WRITE_EA_16(ea, (sint16)value);
1646 case 5: // Double-precision Real
1650 d = floatx80_to_float64(REG_FP[src]);
1655 case 6: // Byte Integer
1657 sint32 value = floatx80_to_int32(REG_FP[src]);
1658 if (value > 127 || value < -128)
1660 REG_FPSR |= FPES_OE | FPAE_IOP;
1662 WRITE_EA_8(ea, (sint8)value);
1665 case 7: // Packed-decimal Real with Dynamic K-factor
1667 WRITE_EA_PACK(ea, REG_D[k>>4], REG_FP[src]);
1675 static void fmove_fpcr(uint16 w2)
1677 int ea = REG_IR & 0x3f;
1678 int dir = (w2 >> 13) & 0x1;
1679 int regsel = (w2 >> 10) & 0x7;
1680 int mode = (ea >> 3) & 0x7;
1682 if ((mode == 5) || (mode == 6))
1684 uint32 address = 0xffffffff; // force a bus error if this doesn't get assigned
1688 address = EA_AY_DI_32();
1692 address = EA_AY_IX_32();
1695 if (dir) // From system control reg to <ea>
1697 if (regsel & 4) { m68ki_write_32(address, REG_FPCR); address += 4; }
1698 if (regsel & 2) { m68ki_write_32(address, REG_FPSR); address += 4; }
1699 if (regsel & 1) { m68ki_write_32(address, REG_FPIAR); address += 4; }
1701 else // From <ea> to system control reg
1703 if (regsel & 4) { REG_FPCR = m68ki_read_32(address); address += 4; }
1704 if (regsel & 2) { REG_FPSR = m68ki_read_32(address); address += 4; }
1705 if (regsel & 1) { REG_FPIAR = m68ki_read_32(address); address += 4; }
1710 if (dir) // From system control reg to <ea>
1712 if (regsel & 4) WRITE_EA_32(ea, REG_FPCR);
1713 if (regsel & 2) WRITE_EA_32(ea, REG_FPSR);
1714 if (regsel & 1) WRITE_EA_32(ea, REG_FPIAR);
1716 else // From <ea> to system control reg
1718 if (regsel & 4) REG_FPCR = READ_EA_32(ea);
1719 if (regsel & 2) REG_FPSR = READ_EA_32(ea);
1720 if (regsel & 1) REG_FPIAR = READ_EA_32(ea);
1724 // FIXME: (2011-12-18 ost)
1725 // rounding_mode and rounding_precision of softfloat.c should be set according to current fpcr
1726 // but: with this code on Apollo the following programs in /systest/fptest will fail:
1727 // 1. Single Precision Whetstone will return wrong results never the less
1728 // 2. Vector Test will fault with 00040004: reference to illegal address
1730 if ((regsel & 4) && dir == 0)
1732 int rnd = (REG_FPCR >> 4) & 3;
1733 int prec = (REG_FPCR >> 6) & 3;
1735 // logerror("m68k_fpsp:fmove_fpcr fpcr=%04x prec=%d rnd=%d\n", m_fpcr, prec, rnd);
1740 case 0: // Extend (X)
1741 floatx80_rounding_precision = 80;
1743 case 1: // Single (S)
1744 floatx80_rounding_precision = 32;
1746 case 2: // Double (D)
1747 floatx80_rounding_precision = 64;
1749 case 3: // Undefined
1750 floatx80_rounding_precision = 80;
1757 case 0: // To Nearest (RN)
1758 float_rounding_mode = float_round_nearest_even;
1760 case 1: // To Zero (RZ)
1761 float_rounding_mode = float_round_to_zero;
1763 case 2: // To Minus Infinitiy (RM)
1764 float_rounding_mode = float_round_down;
1766 case 3: // To Plus Infinitiy (RP)
1767 float_rounding_mode = float_round_up;
1775 static void fmovem(uint16 w2)
1778 int ea = REG_IR & 0x3f;
1779 int dir = (w2 >> 13) & 0x1;
1780 int mode = (w2 >> 11) & 0x3;
1781 int reglist = w2 & 0xff;
1783 uint32 mem_addr = 0;
1786 case 5: // (d16, An)
1787 mem_addr= EA_AY_DI_32();
1789 case 6: // (An) + (Xn) + d8
1790 mem_addr= EA_AY_IX_32();
1794 if (dir) // From FP regs to mem
1798 case 1: // Dynamic register list, postincrement or control addressing mode.
1799 // FIXME: not really tested, but seems to work
1800 reglist = REG_D[(reglist >> 4) & 7];
1803 case 0: // Static register list, predecrement or control addressing mode
1805 for (i=0; i < 8; i++)
1807 if (reglist & (1 << i))
1811 case 5: // (d16, An)
1812 case 6: // (An) + (Xn) + d8
1813 store_extended_float80(mem_addr, REG_FP[i]);
1817 WRITE_EA_FPE(ea, REG_FP[i]);
1827 case 2: // Static register list, postdecrement or control addressing mode.
1829 for (i=0; i < 8; i++)
1831 if (reglist & (1 << i))
1835 case 5: // (d16, An)
1836 case 6: // (An) + (Xn) + d8
1837 store_extended_float80(mem_addr, REG_FP[7-i]);
1841 WRITE_EA_FPE(ea, REG_FP[7-i]);
1851 default: fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
1854 else // From mem to FP regs
1858 case 3: // Dynamic register list, predecrement addressing mode.
1859 // FIXME: not really tested, but seems to work
1860 reglist = REG_D[(reglist >> 4) & 7];
1863 case 2: // Static register list, postincrement or control addressing mode
1865 for (i=0; i < 8; i++)
1867 if (reglist & (1 << i))
1871 case 5: // (d16, An)
1872 case 6: // (An) + (Xn) + d8
1873 REG_FP[7-i] = load_extended_float80(mem_addr);
1877 REG_FP[7-i] = READ_EA_FPE(ea);
1886 default: fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
1893 int ea = REG_IR & 0x3f;
1894 int condition = (sint16)(OPER_I_16());
1896 WRITE_EA_8(ea, TEST_CONDITION(condition) ? 0xff : 0);
1897 USE_CYCLES(7); // ???
1899 static void fbcc16(void)
1902 int condition = REG_IR & 0x3f;
1904 offset = (sint16)(OPER_I_16());
1906 // TODO: condition and jump!!!
1907 if (TEST_CONDITION(condition))
1909 m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */
1910 m68ki_branch_16(offset-2);
1916 static void fbcc32(void)
1919 int condition = REG_IR & 0x3f;
1921 offset = OPER_I_32();
1923 // TODO: condition and jump!!!
1924 if (TEST_CONDITION(condition))
1926 m68ki_trace_t0(); /* auto-disable (see m68kcpu.h) */
1927 m68ki_branch_32(offset-4);
1934 void m68040_fpu_op0()
1936 m68ki_cpu.fpu_just_reset = 0;
1938 switch ((REG_IR >> 6) & 0x3)
1942 uint16 w2 = OPER_I_16();
1943 switch ((w2 >> 13) & 0x7)
1945 case 0x0: // FPU ALU FP, FP
1946 case 0x2: // FPU ALU ea, FP
1952 case 0x3: // FMOVE FP, ea
1958 case 0x4: // FMOVEM ea, FPCR
1959 case 0x5: // FMOVEM FPCR, ea
1965 case 0x6: // FMOVEM ea, list
1966 case 0x7: // FMOVEM list, ea
1972 default: fatalerror("M68kFPU: unimplemented subop %d at %08X\n", (w2 >> 13) & 0x7, REG_PC-4);
1977 case 1: // FBcc disp16
1979 switch ((REG_IR >> 3) & 0x7) {
1982 printf("M68kFPU: unimplemented FDBcc main op %d with mode %d at %08X\n", (REG_IR >> 6) & 0x3, (REG_IR >> 3) & 0x7, REG_PC-4);
1984 default: // FScc (?)
1988 fatalerror("M68kFPU: unimplemented main op %d with mode %d at %08X\n", (REG_IR >> 6) & 0x3, (REG_IR >> 3) & 0x7, REG_PC-4);
1991 case 2: // FBcc disp16
1996 case 3: // FBcc disp32
2002 default: fatalerror("M68kFPU: unimplemented main op %d\n", (REG_IR >> 6) & 0x3);
2006 static int perform_fsave(uint32 addr, int inc)
2008 if(m68ki_cpu.cpu_type & CPU_TYPE_040)
2012 m68ki_write_32(addr, 0x41000000);
2017 m68ki_write_32(addr, 0x41000000);
2024 // 68881 IDLE, version 0x1f
2025 m68ki_write_32(addr, 0x1f180000);
2026 m68ki_write_32(addr+4, 0);
2027 m68ki_write_32(addr+8, 0);
2028 m68ki_write_32(addr+12, 0);
2029 m68ki_write_32(addr+16, 0);
2030 m68ki_write_32(addr+20, 0);
2031 m68ki_write_32(addr+24, 0x70000000);
2036 m68ki_write_32(addr+4-4, 0x70000000);
2037 m68ki_write_32(addr+4-8, 0);
2038 m68ki_write_32(addr+4-12, 0);
2039 m68ki_write_32(addr+4-16, 0);
2040 m68ki_write_32(addr+4-20, 0);
2041 m68ki_write_32(addr+4-24, 0);
2042 m68ki_write_32(addr+4-28, 0x1f180000);
2047 // FRESTORE on a NULL frame reboots the FPU - all registers to NaN, the 3 status regs to 0
2048 static void do_frestore_null(void)
2055 for (i = 0; i < 8; i++)
2057 REG_FP[i].high = 0x7fff;
2058 REG_FP[i].low = U64(0xffffffffffffffff);
2061 // Mac IIci at 408458e6 wants an FSAVE of a just-restored NULL frame to also be NULL
2062 // The PRM says it's possible to generate a NULL frame, but not how/when/why. (need the 68881/68882 manual!)
2063 m68ki_cpu.fpu_just_reset = 1;
2066 void m68040_do_fsave(uint32 addr, int reg, int inc)
2068 if (m68ki_cpu.fpu_just_reset)
2070 m68ki_write_32(addr, 0);
2074 // we normally generate an IDLE frame
2075 int delta = perform_fsave(addr, inc);
2077 REG_A[reg] += delta;
2081 void m68040_do_frestore(uint32 addr, int reg)
2083 uint32 temp = m68ki_read_32(addr);
2084 // check for nullptr frame
2085 if (temp & 0xff000000)
2087 // we don't handle non-nullptr frames
2088 m68ki_cpu.fpu_just_reset = 0;
2092 uint8 m40 = !!(m68ki_cpu.cpu_type & CPU_TYPE_040);
2093 // how about an IDLE frame?
2094 if (!m40 && ((temp & 0x00ff0000) == 0x00180000))
2096 REG_A[reg] += 7*4-4;
2098 else if (m40 && ((temp & 0xffff0000) == 0x41000000))
2102 else if ((temp & 0x00ff0000) == 0x00380000)
2106 else if ((temp & 0x00ff0000) == 0x00b40000)
2118 void m68040_fpu_op1()
2120 int ea = REG_IR & 0x3f;
2121 int mode = (ea >> 3) & 0x7;
2122 int reg = (ea & 0x7);
2125 switch ((REG_IR >> 6) & 0x3)
2127 case 0: // FSAVE <ea>
2133 m68040_do_fsave(addr, -1, 1);
2137 addr = EA_AY_PI_32();
2138 printf("FSAVE mode %d, reg A%d=0x%08x\n",mode,reg,REG_A[reg]);
2139 m68040_do_fsave(addr, -1, 1); // FIXME: -1 was reg
2143 addr = EA_AY_PD_32();
2144 m68040_do_fsave(addr, reg, 0); // FIXME: -1 was reg
2146 case 5: // (D16, An)
2147 addr = EA_AY_DI_16();
2148 m68040_do_fsave(addr, -1, 1);
2151 case 6: // (An) + (Xn) + d8
2152 addr = EA_AY_IX_16();
2153 m68040_do_fsave(addr, -1, 1);
2163 m68040_do_fsave(addr, -1, 1);
2166 case 2: // (d16, PC)
2168 addr = EA_PCDI_16();
2169 m68040_do_fsave(addr, -1, 1);
2173 fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2179 fatalerror("M68kFPU: FSAVE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2184 case 1: // FRESTORE <ea>
2190 m68040_do_frestore(addr, -1);
2194 addr = EA_AY_PI_32();
2195 m68040_do_frestore(addr, reg);
2198 case 5: // (D16, An)
2199 addr = EA_AY_DI_16();
2200 m68040_do_frestore(addr, -1);
2203 case 6: // (An) + (Xn) + d8
2204 addr = EA_AY_IX_16();
2205 m68040_do_frestore(addr, -1);
2215 m68040_do_frestore(addr, -1);
2218 case 2: // (d16, PC)
2220 addr = EA_PCDI_16();
2221 m68040_do_frestore(addr, -1);
2225 fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2231 fatalerror("M68kFPU: FRESTORE unhandled mode %d reg %d at %x\n", mode, reg, REG_PC);
2236 default: fatalerror("m68040_fpu_op1: unimplemented op %d at %08X\n", (REG_IR >> 6) & 0x3, REG_PC-2);
2242 uint16 w2 = OPER_I_16();
2244 // now check the condition
2245 if (TEST_CONDITION(w2 & 0x3f))
2248 m68ki_exception_trap(EXCEPTION_TRAPV);
2250 else // fall through, requires eating the operand
2252 switch (REG_IR & 0x7)
2254 case 2: // word operand
2258 case 3: // long word operand
2262 case 4: // no operand