Re: [hatari-devel] Basic cpu testsuite

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


On 8.6.2018 22.00, Toni Wilen wrote:
>> Good catch. It also lacks check if multiple control register bits are
>> set at the same time (or none) which works strangely on 68060.. I'll
>> attach patch later today.
> 
> Patch attached.
> 
> - FMOVE control register<>Dn/An missing validation added.
> - FMOVEM fpp<>ea missing -(an)/(an)+ validation added. (Oddly enough
> control register FMOVEM do not have same addressing mode restrictions)

Some more changes: PC relative addressing modes was incorrectly allowed
when writing to memory. Added some comments.
diff --git "a/C:\\Users\\TONI~1.WIL\\AppData\\Local\\Temp\\TortoiseGit\\fpp-fc4d3c3.003.cpp" "b/C:\\projects\\winuae\\src\\fpp.cpp"
index 2150a5e4..c9502763 100644
--- "a/C:\\Users\\TONI~1.WIL\\AppData\\Local\\Temp\\TortoiseGit\\fpp-fc4d3c3.003.cpp"
+++ "b/C:\\projects\\winuae\\src\\fpp.cpp"
@@ -1326,7 +1326,7 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old
 	size = (extra >> 10) & 7;
 
 	switch (mode) {
-		case 0:
+		case 0: // Dn
 			if ((size == 0 || size == 1 ||size == 4 || size == 6) && fault_if_no_fpu (opcode, extra, 0, oldpc))
 				return -1;
 			switch (size)
@@ -1348,12 +1348,12 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old
 					return 0;
 			}
 			return 1;
-		case 1:
+		case 1: // An
 			return 0;
-		case 2:
+		case 2: // (An)
 			ad = m68k_areg (regs, reg);
 			break;
-		case 3:
+		case 3: // (An)+
 			// Also needed by fault_if_no_fpu 
 			mmufixup[0].reg = reg;
 			mmufixup[0].value = m68k_areg (regs, reg);
@@ -1361,7 +1361,7 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old
 			ad = m68k_areg (regs, reg);
 			m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size];
 			break;
-		case 4:
+		case 4: // -(An)
 			// Also needed by fault_if_no_fpu 
 			mmufixup[0].reg = reg;
 			mmufixup[0].value = m68k_areg (regs, reg);
@@ -1372,10 +1372,10 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old
 			if (currprefs.cpu_model == 68060 && if_no_fpu() && sz1[size] == 12)
 				ad += 8;
 			break;
-		case 5:
+		case 5: // (d16,An)
 			ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) x_cp_next_iword ();
 			break;
-		case 6:
+		case 6: // (d8,An,Xn)+
 			ad = x_cp_get_disp_ea_020 (m68k_areg (regs, reg), 0);
 			break;
 		case 7:
@@ -1444,14 +1444,14 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old
 
 	switch (size)
 	{
-		case 0:
+		case 0: // L
 			fpset(src, (uae_s32) (doext ? exts[0] : x_cp_get_long (ad)));
 			break;
-		case 1:
+		case 1: // S
 			fpp_to_single (src, (doext ? exts[0] : x_cp_get_long (ad)));
 			normalize_or_fault_if_no_denormal_support(opcode, extra, adold, oldpc, src);
 			break;
-		case 2:
+		case 2: // X
 			{
 				uae_u32 wrd1, wrd2, wrd3;
 				wrd1 = (doext ? exts[0] : x_cp_get_long (ad));
@@ -1463,7 +1463,7 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old
 				normalize_or_fault_if_no_denormal_support(opcode, extra, adold, oldpc, src);
 			}
 			break;
-		case 3:
+		case 3: // P
 			{
 				uae_u32 wrd[3];
 				if (currprefs.cpu_model == 68060) {
@@ -1482,10 +1482,10 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old
 				return 1;
 			}
 			break;
-		case 4:
+		case 4: // W
 			fpset(src, (uae_s16) (doext ? exts[0] : x_cp_get_word (ad)));
 			break;
-		case 5:
+		case 5: // D
 			{
 				uae_u32 wrd1, wrd2;
 				wrd1 = (doext ? exts[0] : x_cp_get_long (ad));
@@ -1495,7 +1495,7 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old
 				normalize_or_fault_if_no_denormal_support(opcode, extra, adold, oldpc, src);
 			}
 			break;
-		case 6:
+		case 6: // B
 			fpset(src, (uae_s8) (doext ? exts[0] : x_cp_get_byte (ad)));
 			break;
 		default:
@@ -1528,13 +1528,13 @@ static int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, uaecptr o
 	size = (extra >> 10) & 7;
 	switch (mode)
 	{
-		case 0:
+		case 0: // Dn
 
 			if ((size == 0 || size == 1 ||size == 4 || size == 6) && fault_if_no_fpu (opcode, extra, 0, oldpc))
 				return -1;
 			switch (size)
 			{
-				case 6:
+				case 6: // B
 					if (normalize_or_fault_if_no_denormal_support(opcode, extra, 0, oldpc, value))
 						return 1;
 					m68k_dreg (regs, reg) = (uae_u32)(((fpp_to_int (value, 0) & 0xff)
@@ -1542,7 +1542,7 @@ static int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, uaecptr o
 					if (fault_if_68040_integer_nonmaskable(opcode, extra, ad, oldpc, value))
 						return -1;
 					break;
-				case 4:
+				case 4: // W
 					if (normalize_or_fault_if_no_denormal_support(opcode, extra, 0, oldpc, value))
 						return 1;
 					m68k_dreg (regs, reg) = (uae_u32)(((fpp_to_int (value, 1) & 0xffff)
@@ -1550,14 +1550,14 @@ static int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, uaecptr o
 					if (fault_if_68040_integer_nonmaskable(opcode, extra, ad, oldpc, value))
 						return -1;
 					break;
-				case 0:
+				case 0: // L
 					if (normalize_or_fault_if_no_denormal_support(opcode, extra, 0, oldpc, value))
 						return 1;
 					m68k_dreg (regs, reg) = (uae_u32)fpp_to_int (value, 2);
 					if (fault_if_68040_integer_nonmaskable(opcode, extra, ad, oldpc, value))
 						return -1;
 					break;
-				case 1:
+				case 1: // S
 					if (normalize_or_fault_if_no_denormal_support(opcode, extra, 0, oldpc, value))
 						return 1;
 					m68k_dreg (regs, reg) = fpp_from_single (value);
@@ -1566,12 +1566,12 @@ static int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, uaecptr o
 					return 0;
 			}
 			return 1;
-		case 1:
+		case 1: // An
 			return 0;
-		case 2:
+		case 2: // (An)
 			ad = m68k_areg (regs, reg);
 			break;
-		case 3:
+		case 3: // (An)+
 			// Also needed by fault_if_no_fpu 
 			mmufixup[0].reg = reg;
 			mmufixup[0].value = m68k_areg (regs, reg);
@@ -1579,7 +1579,7 @@ static int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, uaecptr o
 			ad = m68k_areg (regs, reg);
 			m68k_areg (regs, reg) += reg == 7 ? sz2[size] : sz1[size];
 			break;
-		case 4:
+		case 4: // -(An)
 			// Also needed by fault_if_no_fpu 
 			mmufixup[0].reg = reg;
 			mmufixup[0].value = m68k_areg (regs, reg);
@@ -1590,28 +1590,22 @@ static int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, uaecptr o
 			if (currprefs.cpu_model == 68060 && if_no_fpu() && sz1[size] == 12)
 				ad += 8;
 			break;
-		case 5:
+		case 5: // (d16,An)
 			ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) x_cp_next_iword ();
 			break;
-		case 6:
+		case 6: // (d8,An,Xn)+
 			ad = x_cp_get_disp_ea_020 (m68k_areg (regs, reg), 0);
 			break;
 		case 7:
 			switch (reg)
 			{
-				case 0:
+				case 0: // (xxx).W
 					ad = (uae_s32) (uae_s16) x_cp_next_iword ();
 					break;
-				case 1:
+				case 1: // (xxx).L
 					ad = x_cp_next_ilong ();
 					break;
-				case 2:
-					ad = m68k_getpc ();
-					ad += (uae_s32) (uae_s16) x_cp_next_iword ();
-					break;
-				case 3:
-					ad = x_cp_get_disp_ea_020 (m68k_getpc (), 0);
-					break;
+				// Immediate and PC-relative modes are not supported
 				default:
 					return 0;
 			}
@@ -1624,19 +1618,19 @@ static int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, uaecptr o
 
 	switch (size)
 	{
-		case 0:
+		case 0: // L
 			if (normalize_or_fault_if_no_denormal_support(opcode, extra, ad, oldpc, value))
 				return 1;
 			x_cp_put_long(ad, (uae_u32)fpp_to_int(value, 2));
 			if (fault_if_68040_integer_nonmaskable(opcode, extra, ad, oldpc, value))
 				return -1;
 			break;
-		case 1:
+		case 1: // S
 			if (normalize_or_fault_if_no_denormal_support(opcode, extra, ad, oldpc, value))
 				return 1;
 			x_cp_put_long(ad, fpp_from_single(value));
 			break;
-		case 2:
+		case 2: // X
 			{
 				if (normalize_or_fault_if_no_denormal_support(opcode, extra, ad, oldpc, value))
 					return 1;
@@ -1669,14 +1663,14 @@ static int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, uaecptr o
 				x_cp_put_long (ad, wrd[2]);
 			}
 			break;
-		case 4:
+		case 4: // W
 			if (normalize_or_fault_if_no_denormal_support(opcode, extra, ad, oldpc, value))
 				return 1;
 			x_cp_put_word(ad, (uae_s16)fpp_to_int(value, 1));
 			if (fault_if_68040_integer_nonmaskable(opcode, extra, ad, oldpc, value))
 				return -1;
 			break;
-		case 5:
+		case 5: // D
 			{
 				if (normalize_or_fault_if_no_denormal_support(opcode, extra, ad, oldpc, value))
 					return 1;
@@ -1687,7 +1681,7 @@ static int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, uaecptr o
 				x_cp_put_long (ad, wrd2);
 			}
 			break;
-		case 6:
+		case 6: // B
 			if (normalize_or_fault_if_no_denormal_support(opcode, extra, ad, oldpc, value))
 				return 1;
 			x_cp_put_byte(ad, (uae_s8)fpp_to_int(value, 0));
@@ -1709,38 +1703,38 @@ static int get_fp_ad (uae_u32 opcode, uae_u32 * ad)
 	reg = opcode & 7;
 	switch (mode)
 	{
-		case 0:
-		case 1:
+		case 0: // Dn
+		case 1: // An
 			return 0;
-		case 2:
+		case 2: // (An)
 			*ad = m68k_areg (regs, reg);
 			break;
-		case 3:
+		case 3: // (An)+
 			*ad = m68k_areg (regs, reg);
 			break;
-		case 4:
+		case 4: // -(An)
 			*ad = m68k_areg (regs, reg);
 			break;
-		case 5:
+		case 5: // (d16,An)
 			*ad = m68k_areg (regs, reg) + (uae_s32) (uae_s16) x_cp_next_iword ();
 			break;
-		case 6:
+		case 6: // (d8,An,Xn)+
 			*ad = x_cp_get_disp_ea_020 (m68k_areg (regs, reg), 0);
 			break;
 		case 7:
 			switch (reg)
 			{
-				case 0:
+				case 0: // (xxx).W
 					*ad = (uae_s32) (uae_s16) x_cp_next_iword ();
 					break;
-				case 1:
+				case 1: // (xxx).L
 					*ad = x_cp_next_ilong ();
 					break;
-				case 2:
+				case 2: // (d16,PC)
 					*ad = m68k_getpc ();
 					*ad += (uae_s32) (uae_s16) x_cp_next_iword ();
 					break;
-				case 3:
+				case 3: // (d8,PC,Xn)+
 					*ad = x_cp_get_disp_ea_020 (m68k_getpc (), 0);
 					break;
 				default:
@@ -2806,6 +2800,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
 	switch ((extra >> 13) & 0x7)
 	{
 		case 3:
+			// FMOVE FPP->EA
 			if (fp_exception_pending(true))
 				return;
 
@@ -2825,41 +2820,52 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
 
 		case 4:
 		case 5:
+			// FMOVE Control Register <> Data or Address register
 			if ((opcode & 0x38) == 0) {
+				// Dn
 				if (fault_if_no_fpu (opcode, extra, 0, pc))
 					return;
+				// Only single selected control register is allowed
+				// All control register bits unset = FPIAR
+				uae_u16 bits = extra & (0x1000 | 0x0800 | 0x0400);
+				if (bits && bits != 0x1000 && bits != 0x0800 && bits != 0x400) {
+					// 68060 does not generate f-line if multiple bits are set
+					// but it also works unexpectedly, just do nothing for now.
+					if (currprefs.fpu_model != 68060)
+						fpu_noinst(opcode, pc);
+					return;
+				}
 				if (extra & 0x2000) {
 					if (extra & 0x1000)
 						m68k_dreg (regs, opcode & 7) = fpp_get_fpcr();
 					if (extra & 0x0800)
 						m68k_dreg (regs, opcode & 7) = fpp_get_fpsr();
-					if (extra & 0x0400)
+					if ((extra & 0x0400) || !bits)
 						m68k_dreg (regs, opcode & 7) = regs.fpiar;
 				} else {
 					if (extra & 0x1000)
 						fpp_set_fpcr(m68k_dreg (regs, opcode & 7));
 					if (extra & 0x0800)
 						fpp_set_fpsr(m68k_dreg (regs, opcode & 7));
-					if (extra & 0x0400)
+					if ((extra & 0x0400) || !bits)
 						regs.fpiar = m68k_dreg (regs, opcode & 7);
 				}
 			} else if ((opcode & 0x38) == 0x08) {
+				// An
 				if (fault_if_no_fpu (opcode, extra, 0, pc))
 					return;
+				// Only FPIAR can be moved to/from address register
+				// All bits unset = FPIAR
+				uae_u16 bits = extra & (0x1000 | 0x0800 | 0x0400);
+				// 68060, An and all bits unset: f-line
+				if ((bits && bits != 0x0400) || (!bits && currprefs.fpu_model == 68060)) {
+					fpu_noinst(opcode, pc);
+					return;
+				}
 				if (extra & 0x2000) {
-					if (extra & 0x1000)
-						m68k_areg (regs, opcode & 7) = fpp_get_fpcr();
-					if (extra & 0x0800)
-						m68k_areg (regs, opcode & 7) = fpp_get_fpsr();
-					if (extra & 0x0400)
-						m68k_areg (regs, opcode & 7) = regs.fpiar;
+					m68k_areg (regs, opcode & 7) = regs.fpiar;
 				} else {
-					if (extra & 0x1000)
-						fpp_set_fpcr(m68k_areg (regs, opcode & 7));
-					if (extra & 0x0800)
-						fpp_set_fpsr(m68k_areg (regs, opcode & 7));
-					if (extra & 0x0400)
-						regs.fpiar = m68k_areg (regs, opcode & 7);
+					regs.fpiar = m68k_areg (regs, opcode & 7);
 				}
 			} else if ((opcode & 0x3f) == 0x3c) {
 				if ((extra & 0x2000) == 0) {
@@ -2892,7 +2898,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
 					return;
 				}
 			} else if (extra & 0x2000) {
-				/* FMOVEM FPP->memory */
+				/* FMOVEM Control Register->Memory */
 				uae_u32 ad;
 				int incr = 0;
 
@@ -2902,6 +2908,11 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
 				}
 				if (fault_if_no_fpu (opcode, extra, ad, pc))
 					return;
+				if ((opcode & 0x3f) >= 0x3a) {
+					// PC relative modes not supported
+					fpu_noinst(opcode, pc);
+					return;
+				}
 
 				if ((opcode & 0x38) == 0x20) {
 					if (extra & 0x1000)
@@ -2930,7 +2941,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
 				if ((opcode & 0x38) == 0x20)
 					m68k_areg (regs, opcode & 7) = ad;
 			} else {
-				/* FMOVEM memory->FPP */
+				/* FMOVEM Memory->Control Register */
 				uae_u32 ad;
 				int incr = 0;
 
@@ -2972,6 +2983,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
 		case 6:
 		case 7:
 			{
+				// FMOVEM FPP<>Memory
 				uae_u32 ad, list = 0;
 				int incr = 1;
 				int regdir = 1;
@@ -2981,6 +2993,18 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
 				}
 				if (fault_if_no_fpu (opcode, extra, ad, pc))
 					return;
+
+				if ((extra & 0x2000) && ((opcode & 0x38) == 0x18 || (opcode & 0x3f) >= 0x3a)) {
+					// FMOVEM FPP->Memory: (An)+ and PC relative modes not supported
+					fpu_noinst(opcode, pc);
+					return;
+				}
+				if (!(extra & 0x2000) && (opcode & 0x38) == 0x20) {
+					// FMOVEM Memory->FPP: -(An) not supported
+					fpu_noinst(opcode, pc);
+					return;
+				}
+
 				switch ((extra >> 11) & 3)
 				{
 					case 0:	/* static pred */
@@ -3005,10 +3029,10 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
 					}
 				}
 				if (extra & 0x2000) {
-					/* FMOVEM FPP->memory */
+					/* FMOVEM FPP->Memory */
 					ad = fmovem2mem (ad, list, incr, regdir);
 				} else {
-					/* FMOVEM memory->FPP */
+					/* FMOVEM Memory->FPP */
 					ad = fmovem2fpp (ad, list, incr, regdir);
 				}
 				if ((opcode & 0x38) == 0x18 || (opcode & 0x38) == 0x20) // (an)+ or -(an)


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/