comparison cpu_dsl.py @ 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 a8f04b0ab744
children 48a43dff4dc0
comparison
equal deleted inserted replaced
1746:cd6f4cea97b6 1747:89ddf41a50bb
331 331
332 def _updateFlagsCImpl(prog, params, rawParams): 332 def _updateFlagsCImpl(prog, params, rawParams):
333 autoUpdate, explicit = prog.flags.parseFlagUpdate(params[0]) 333 autoUpdate, explicit = prog.flags.parseFlagUpdate(params[0])
334 output = [] 334 output = []
335 parity = None 335 parity = None
336 directFlags = {}
336 for flag in autoUpdate: 337 for flag in autoUpdate:
337 calc = prog.flags.flagCalc[flag] 338 calc = prog.flags.flagCalc[flag]
338 calc,_,resultBit = calc.partition('-') 339 calc,_,resultBit = calc.partition('-')
339 if prog.carryFlowDst: 340 if prog.carryFlowDst:
340 lastDst = prog.carryFlowDst 341 lastDst = prog.carryFlowDst
363 #Note: offsetting this by the operation size - 8 makes sense for the Z80 364 #Note: offsetting this by the operation size - 8 makes sense for the Z80
364 #but might not for other CPUs with this kind of fixed bit flag behavior 365 #but might not for other CPUs with this kind of fixed bit flag behavior
365 resultBit = int(resultBit) + prog.paramSize(prog.lastDst) - 8 366 resultBit = int(resultBit) + prog.paramSize(prog.lastDst) - 8
366 if type(storage) is tuple: 367 if type(storage) is tuple:
367 reg,storageBit = storage 368 reg,storageBit = storage
368 reg = prog.resolveParam(reg, None, {})
369 if storageBit == resultBit: 369 if storageBit == resultBit:
370 #TODO: optimize this case 370 directFlags.setdefault((reg, myRes), []).append(resultBit)
371 output.append('\n\t{reg} = ({reg} & ~{mask}U) | ({res} & {mask}U);'.format(
372 reg = reg, mask = 1 << resultBit, res = myRes
373 ))
374 else: 371 else:
372 reg = prog.resolveParam(reg, None, {})
375 if resultBit > storageBit: 373 if resultBit > storageBit:
376 op = '>>' 374 op = '>>'
377 shift = resultBit - storageBit 375 shift = resultBit - storageBit
378 else: 376 else:
379 op = '<<' 377 op = '<<'
414 decl,name = prog.getTemp(paritySize) 412 decl,name = prog.getTemp(paritySize)
415 output.append(decl) 413 output.append(decl)
416 parityDst = name 414 parityDst = name
417 else: 415 else:
418 raise Exception('Unknown flag calc type: ' + calc) 416 raise Exception('Unknown flag calc type: ' + calc)
417 for reg, myRes in directFlags:
418 bits = directFlags[(reg, myRes)]
419 resolved = prog.resolveParam(reg, None, {})
420 if len(bits) == len(prog.flags.storageToFlags[reg]):
421 output.append('\n\t{reg} = {res};'.format(reg = resolved, res = myRes))
422 else:
423 mask = 0
424 for bit in bits:
425 mask |= 1 << bit
426 output.append('\n\t{reg} = ({reg} & ~{mask}U) | ({res} & {mask}U);'.format(
427 reg = resolved, mask = mask, res = myRes
428 ))
419 if prog.carryFlowDst: 429 if prog.carryFlowDst:
420 if prog.lastOp.op != 'cmp': 430 if prog.lastOp.op != 'cmp':
421 output.append('\n\t{dst} = {tmpdst};'.format(dst = prog.resolveParam(prog.lastDst, prog.currentScope, {}), tmpdst = prog.carryFlowDst)) 431 output.append('\n\t{dst} = {tmpdst};'.format(dst = prog.resolveParam(prog.lastDst, prog.currentScope, {}), tmpdst = prog.carryFlowDst))
422 prog.carryFlowDst = None 432 prog.carryFlowDst = None
423 if parity: 433 if parity:
1088 def __init__(self): 1098 def __init__(self):
1089 self.flagBits = {} 1099 self.flagBits = {}
1090 self.flagCalc = {} 1100 self.flagCalc = {}
1091 self.flagStorage = {} 1101 self.flagStorage = {}
1092 self.flagReg = None 1102 self.flagReg = None
1103 self.storageToFlags = {}
1093 self.maxBit = -1 1104 self.maxBit = -1
1094 1105
1095 def processLine(self, parts): 1106 def processLine(self, parts):
1096 if parts[0] == 'register': 1107 if parts[0] == 'register':
1097 self.flagReg = parts[1] 1108 self.flagReg = parts[1]
1108 if bit > self.maxBit: 1119 if bit > self.maxBit:
1109 self.maxBit = bit 1120 self.maxBit = bit
1110 self.flagBits[flag] = bit 1121 self.flagBits[flag] = bit
1111 self.flagCalc[flag] = calc 1122 self.flagCalc[flag] = calc
1112 self.flagStorage[flag] = storage 1123 self.flagStorage[flag] = storage
1124 storage,_,storebit = storage.partition('.')
1125 self.storageToFlags.setdefault(storage, []).append((storebit, flag))
1113 return self 1126 return self
1114 1127
1115 def getStorage(self, flag): 1128 def getStorage(self, flag):
1116 if not flag in self.flagStorage: 1129 if not flag in self.flagStorage:
1117 raise Exception('Undefined flag ' + flag) 1130 raise Exception('Undefined flag ' + flag)