changeset 1747:89ddf41a50bb

Optimization of flag calculation for flags that just copy a bit from the result in CPU DSL
author Michael Pavone <pavone@retrodev.com>
date Wed, 06 Feb 2019 09:13:24 -0800
parents cd6f4cea97b6
children 48a43dff4dc0
files cpu_dsl.py
diffstat 1 files changed, 18 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/cpu_dsl.py	Wed Feb 06 08:54:56 2019 -0800
+++ b/cpu_dsl.py	Wed Feb 06 09:13:24 2019 -0800
@@ -333,6 +333,7 @@
 	autoUpdate, explicit = prog.flags.parseFlagUpdate(params[0])
 	output = []
 	parity = None
+	directFlags = {}
 	for flag in autoUpdate:
 		calc = prog.flags.flagCalc[flag]
 		calc,_,resultBit = calc.partition('-')
@@ -365,13 +366,10 @@
 				resultBit = int(resultBit) + prog.paramSize(prog.lastDst) - 8
 			if type(storage) is tuple:
 				reg,storageBit = storage
-				reg = prog.resolveParam(reg, None, {})
 				if storageBit == resultBit:
-					#TODO: optimize this case
-					output.append('\n\t{reg} = ({reg} & ~{mask}U) | ({res} & {mask}U);'.format(
-						reg = reg, mask = 1 << resultBit, res = myRes
-					))
+					directFlags.setdefault((reg, myRes), []).append(resultBit)
 				else:
+					reg = prog.resolveParam(reg, None, {})
 					if resultBit > storageBit:
 						op = '>>'
 						shift = resultBit - storageBit
@@ -416,6 +414,18 @@
 				parityDst = name
 		else:
 			raise Exception('Unknown flag calc type: ' + calc)
+	for reg, myRes in directFlags:
+		bits = directFlags[(reg, myRes)]
+		resolved = prog.resolveParam(reg, None, {})
+		if len(bits) == len(prog.flags.storageToFlags[reg]):
+			output.append('\n\t{reg} = {res};'.format(reg = resolved, res = myRes))
+		else:
+			mask = 0
+			for bit in bits:
+				mask |= 1 << bit
+			output.append('\n\t{reg} = ({reg} & ~{mask}U) | ({res} & {mask}U);'.format(
+				reg = resolved, mask = mask, res = myRes
+			))
 	if prog.carryFlowDst:
 		if prog.lastOp.op != 'cmp':
 			output.append('\n\t{dst} = {tmpdst};'.format(dst = prog.resolveParam(prog.lastDst, prog.currentScope, {}), tmpdst = prog.carryFlowDst))
@@ -1090,6 +1100,7 @@
 		self.flagCalc = {}
 		self.flagStorage = {}
 		self.flagReg = None
+		self.storageToFlags = {}
 		self.maxBit = -1
 	
 	def processLine(self, parts):
@@ -1110,6 +1121,8 @@
 				self.flagBits[flag] = bit
 			self.flagCalc[flag] = calc
 			self.flagStorage[flag] = storage
+			storage,_,storebit = storage.partition('.')
+			self.storageToFlags.setdefault(storage, []).append((storebit, flag))
 		return self
 	
 	def getStorage(self, flag):