changeset 2621:ce9386a7b21e

Fix V flag for asl in new CPU core
author Michael Pavone <pavone@retrodev.com>
date Sat, 22 Feb 2025 01:31:51 -0800
parents b58ca7af1e60
children adff015dc94f
files cpu_dsl.py m68k.cpu
diffstat 2 files changed, 61 insertions(+), 63 deletions(-) [+]
line wrap: on
line diff
--- a/cpu_dsl.py	Fri Feb 21 23:28:07 2025 -0800
+++ b/cpu_dsl.py	Sat Feb 22 01:31:51 2025 -0800
@@ -613,7 +613,10 @@
 				myRes = '({a} ^ {b} ^ {res})'.format(a = prog.lastA, b = prog.lastB, res = lastDst)
 			elif calc == 'overflow':
 				resultBit = prog.getLastSize() - 1
-				myRes = '((({a} ^ {b})) & ({a} ^ {res}))'.format(a = prog.lastA, b = prog.lastBFlow, res = lastDst)
+				if prog.lastOp.op == 'lsl':
+					myRes = f'({prog.lastA} ^ {lastDst})'
+				else:
+					myRes = '((({a} ^ {b})) & ({a} ^ {res}))'.format(a = prog.lastA, b = prog.lastBFlow, res = lastDst)
 			else:
 				#Note: offsetting this by the operation size - 8 makes sense for the Z80
 				#but might not for other CPUs with this kind of fixed bit flag behavior
@@ -1726,11 +1729,32 @@
 	
 	def generate(self, prog, parent, fieldVals, output, otype, flagUpdates):
 		self.regValues = parent.regValues
+		for op in self.body:
+			if op.op in _opMap:
+				opDef = _opMap[op.op]
+				if len(opDef.outOp):
+					for index in opDef.outOp:
+						dst = op.params[index]
+						while dst in prog.meta:
+							dst = prog.meta[dst]
+						if dst in self.regValues:
+							#value changes in loop body
+							#so we need to prevent constant folding
+							maybeLocal = self.resolveLocal(dst)
+							if maybeLocal:
+								#for locals, we also need to persist
+								#the current constant fold value to the actual variable
+								output.append(f'\n\t{maybeLocal} = {self.regValues[dst]};')
+							del self.regValues[dst]
+			else:
+				#TODO: handle block types here
+				pass
 		if self.count:
 			count = prog.resolveParam(self.count, self, fieldVals)
-			output.append('\n\tfor (uint32_t loop_counter__ = 0; loop_counter__ < {count}; loop_counter__++) {')
+			output.append(f'\n\tfor (uint32_t loop_counter__ = 0; loop_counter__ < {count}; loop_counter__++) {{')
 		else:
 			output.append('\n\tfor (;;) {')
+					
 		self.processOps(prog, fieldVals, output, otype, self.body)
 		output.append('\n\t}')
 	
--- a/m68k.cpu	Fri Feb 21 23:28:07 2025 -0800
+++ b/m68k.cpu	Sat Feb 22 01:31:51 2025 -0800
@@ -1732,14 +1732,25 @@
 
 1110CCC1ZZ000RRR asli
 	invalid Z 3
+	local vtmp 8
+	local shift 8
+	vtmp = 0
 	switch C
 	case 0
-		meta shift 8
+		shift = 8
 	default
-		meta shift C
+		shift = C
 	end
-	lsl dregs.R shift dregs.R Z
-	update_flags XNZV0C
+	shift -= 1
+	loop shift
+		lsl dregs.R 1 dregs.R Z
+		update_flags V
+		vtmp |= vflag
+	end
+	shift += 1
+	lsl dregs.R 1 dregs.R Z
+	update_flags XNZVC
+	vflag |= vtmp
 	local cyc 32
 	cyc = shift + shift
 	switch Z
@@ -1755,67 +1766,30 @@
 1110CCC1ZZ100RRR asl_dn
 	invalid Z 3
 	local shift 8
+	local vtmp 8
 	and dregs.C 63 shift
-	#TODO: implement loops and do this a bit at a time to implement V flag
+	vtmp = 0
+	if shift
+		shift -= 1
+		loop shift
+			lsl dregs.R 1 dregs.R Z
+			update_flags V
+			vtmp |= vflag
+		end
+		shift += 1
+		lsl dregs.R 1 dregs.R Z
+		update_flags XNZVC
+		vflag |= vtmp
+	else
+		cmp 0 dregs.R Z
+		update_flags NZV0C
+	end
+	shift += shift
 	switch Z
 	case 2
-		if shift >=U 32
-			if shift = 32
-				lsl dregs.R 31 dregs.R Z
-				lsl dregs.R 1 dregs.R Z
-				update_flags XNZ1V0C
-			else
-				dregs.R:Z = 0
-				update_flags X0N0Z1V0C0
-			end
-		else
-			lsl dregs.R shift dregs.R Z
-			update_flags NZV0C
-			if shift
-				xflag = cflag
-			end
-		end
-	case 1
-		if shift >=U 16
-			if shift = 16
-				lsl dregs.R 15 dregs.R Z
-				lsl dregs.R 1 dregs.R Z
-				update_flags XN0Z1V0C
-			else
-				dregs.R:Z = 0
-				update_flags X0N0Z1V0C0
-			end
-		else
-			lsl dregs.R shift dregs.R Z
-			update_flags NZV0C
-			if shift
-				xflag = cflag
-			end
-		end
-	case 0
-		if shift >=U 8
-			if shift = 8
-				lsl dregs.R 7 dregs.R Z
-				lsl dregs.R 1 dregs.R Z
-				update_flags XN0Z1V0C
-			else
-				dregs.R:Z = 0
-				update_flags X0N0Z1V0C0
-			end
-		else
-			lsl dregs.R shift dregs.R Z
-			update_flags NZV0C
-			if shift
-				xflag = cflag
-			end
-		end
-	end
-	add shift shift shift
-	switch Z
-	case 2
-		add 4 shift shift
+		shift += 4
 	default
-		add 2 shift shift
+		shift += 2
 	end
 	cycles shift
 	#TODO: should this happen before or after the majority of the shift?