Mercurial > repos > blastem
changeset 2591:563d05355a12
Cut down on code bloat in 68K core a little
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 09 Feb 2025 14:15:22 -0800 |
parents | e602dbf776d8 |
children | 8ef8b2e99f4f |
files | cpu_dsl.py m68k.cpu |
diffstat | 2 files changed, 61 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/cpu_dsl.py Sun Feb 09 02:57:37 2025 -0800 +++ b/cpu_dsl.py Sun Feb 09 14:15:22 2025 -0800 @@ -88,6 +88,10 @@ else: flagUpdates = None oplist[i].generate(prog, self, fieldVals, output, otype, flagUpdates) + + def processDispatch(self, prog): + for op in self.implementation: + op.processDispatch(prog) def resolveLocal(self, name): return None @@ -111,6 +115,7 @@ self.invalidFieldValues = {} self.invalidCombos = [] self.newLocals = [] + self.noSpecialize = set() for field in fields: self.varyingBits += fields[field][1] @@ -131,6 +136,9 @@ value = int(op.params[i+1]) vmap[name] = value self.invalidCombos.append(vmap) + elif op.op == 'nospecialize': + for name in op.params: + self.noSpecialize.add(name) else: self.implementation.append(op) @@ -200,6 +208,8 @@ def generateName(self, value): fieldVals,fieldBits = self.getFieldVals(value) + for name in self.noSpecialize: + del fieldVals[name] names = list(fieldVals.keys()) names.sort() funName = self.name @@ -216,7 +226,21 @@ output.append('\n\tuint{sz}_t {name};'.format(sz=self.locals[var], name=var)) self.newLocals = [] fieldVals,_ = self.getFieldVals(value) + for name in self.noSpecialize: + del fieldVals[name] + self.locals[name] = prog.opsize + if len(prog.mainDispatch) != 1: + raise Exception('nospecialize requires exactly 1 field used for main table dispatch') + shift,bits = self.fields[name] + mask = (1 << bits) - 1 + opfield = list(prog.mainDispatch)[0] + if shift: + output.append(f'\n\tuint{prog.opsize}_t {name} = context->{opfield} >> {shift} & {mask};') + else: + output.append(f'\n\tuint{prog.opsize}_t {name} = context->{opfield} & {mask};') self.processOps(prog, fieldVals, output, otype, self.implementation) + for name in self.noSpecialize: + del self.locals[name] if prog.dispatch == 'call': begin = '\nvoid ' + self.generateName(value) + '(' + prog.context_type + ' *context, uint32_t target_cycle)\n{' @@ -1309,6 +1333,10 @@ output.append('\n\t' + self.op + '(' + ', '.join([str(p) for p in procParams]) + ');') prog.lastOp = self + def processDispatch(self, prog): + if self.op == 'dispatch' and (len(self.params) == 1 or self.params[1] == 'main'): + prog.mainDispatch.add(self.params[0]) + def __str__(self): return '\n\t' + self.op + ' ' + ' '.join(self.params) @@ -1409,6 +1437,14 @@ prog.conditional = oldCond prog.popScope() + def processDispatch(self, prog): + for case in self.cases: + for op in self.cases[case]: + op.processDispatch(prog) + if self.default: + for op in self.default: + op.processDispatch(prog) + def __str__(self): keys = self.cases.keys() keys.sort() @@ -1554,6 +1590,12 @@ prog.conditional = oldCond + def processDispatch(self, prog): + for op in self.body: + op.processDispatch(prog) + for op in self.elseBody: + op.processDispatch(prog) + def __str__(self): lines = ['\n\tif'] for op in self.body: @@ -1903,9 +1945,12 @@ self.needFlagCoalesce = False self.needFlagDisperse = False self.lastOp = None - opmap[val] = inst.generateName(val) - bodymap[val] = inst.generateBody(val, self, otype) + name = inst.generateName(val) + opmap[val] = name + if not name in bodymap: + bodymap[name] = inst.generateBody(val, self, otype) + alreadyAppended = set() if self.dispatch == 'call': lateBody.append('\nstatic impl_fun impl_{name}[{sz}] = {{'.format(name = table, sz=len(opmap))) for inst in range(0, len(opmap)): @@ -1914,7 +1959,9 @@ lateBody.append('\n\tunimplemented,') else: lateBody.append('\n\t' + op + ',') - body.append(bodymap[inst]) + if not op in alreadyAppended: + body.append(bodymap[op]) + alreadyAppended.add(op) lateBody.append('\n};') elif self.dispatch == 'goto': body.append('\n\tstatic void *impl_{name}[{sz}] = {{'.format(name = table, sz=len(opmap))) @@ -1924,7 +1971,8 @@ body.append('\n\t\t&&unimplemented,') else: body.append('\n\t\t&&' + op + ',') - lateBody.append(bodymap[inst]) + if not op in alreadyAppended: + lateBody.append(bodymap[op]) body.append('\n\t};') else: raise Exception("unimplmeneted dispatch type " + self.dispatch) @@ -1960,6 +2008,12 @@ elif self.dispatch == 'goto': body.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type)) body.append('\n{') + + for table in self.instructions: + for inst in self.instructions[table]: + inst.processDispatch(self) + for sub in self.subroutines: + self.subroutines[sub].processDispatch(self) for table in self.extra_tables: self._buildTable(otype, table, body, pieces)
--- a/m68k.cpu Sun Feb 09 02:57:37 2025 -0800 +++ b/m68k.cpu Sun Feb 09 14:15:22 2025 -0800 @@ -2777,6 +2777,7 @@ m68k_prefetch 0111RRR0IIIIIIII moveq + nospecialize I local tmp 32 sext 16 I tmp sext 32 tmp dregs.R @@ -2803,6 +2804,7 @@ 01100001DDDDDDDD bsr + nospecialize D #mid-instruction timing isn't quite right #becuase I'm only emulating a 1-word prefetch buffer instead of 2 local offset 32 @@ -2926,6 +2928,7 @@ m68k_prefetch 0110CCCCDDDDDDDD bcc + nospecialize D #mid-instruction timing isn't quite right #becuase I'm only emulating a 1-word prefetch buffer instead of 2 local offset 32