Mercurial > repos > blastem
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) |