Mercurial > repos > blastem
changeset 2581:9e10149c9e10
Better unimplemented instruction error message in CPU DSL
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 08 Feb 2025 12:51:35 -0800 |
parents | 939b818df589 |
children | 6c475ddefd6f |
files | cpu_dsl.py |
diffstat | 1 files changed, 41 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/cpu_dsl.py Sat Feb 08 11:40:42 2025 -0800 +++ b/cpu_dsl.py Sat Feb 08 12:51:35 2025 -0800 @@ -475,6 +475,8 @@ table = 'main' else: table = params[1] + if table == 'main': + prog.mainDispatch.add(params[0]) if prog.dispatch == 'call': return '\n\timpl_{tbl}[{op}](context, target_cycle);'.format(tbl = table, op = params[0]) elif prog.dispatch == 'goto': @@ -1841,6 +1843,7 @@ self.conditional = False self.declares = [] self.lastSize = None + self.mainDispatch = set() def __str__(self): pieces = [] @@ -1898,15 +1901,15 @@ bodymap[val] = inst.generateBody(val, self, otype) if self.dispatch == 'call': - pieces.append('\nstatic impl_fun impl_{name}[{sz}] = {{'.format(name = table, sz=len(opmap))) + lateBody.append('\nstatic impl_fun impl_{name}[{sz}] = {{'.format(name = table, sz=len(opmap))) for inst in range(0, len(opmap)): op = opmap[inst] if op is None: - pieces.append('\n\tunimplemented,') + lateBody.append('\n\tunimplemented,') else: - pieces.append('\n\t' + op + ',') + lateBody.append('\n\t' + op + ',') body.append(bodymap[inst]) - pieces.append('\n};') + lateBody.append('\n};') elif self.dispatch == 'goto': body.append('\n\tstatic void *impl_{name}[{sz}] = {{'.format(name = table, sz=len(opmap))) for inst in range(0, len(opmap)): @@ -1944,10 +1947,6 @@ for include in self.includes: body.append('#include "{0}"\n'.format(include)) if self.dispatch == 'call': - body.append('\nstatic void unimplemented({pre}context *context, uint32_t target_cycle)'.format(pre = self.prefix)) - body.append('\n{') - body.append('\n\tfatal_error("Unimplemented instruction\\n");') - body.append('\n}\n') body.append('\ntypedef void (*impl_fun)({pre}context *context, uint32_t target_cycle);'.format(pre=self.prefix)) for table in self.extra_tables: body.append('\nstatic impl_fun impl_{name}[{sz}];'.format(name = table, sz=(1 << self.opsize))) @@ -1959,33 +1958,46 @@ for table in self.extra_tables: self._buildTable(otype, table, body, pieces) self._buildTable(otype, 'main', body, pieces) - if self.dispatch == 'call' and self.body in self.subroutines: - pieces.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type)) - pieces.append('\n{') - pieces.append('\n\t{sync}(context, target_cycle);'.format(sync=self.sync_cycle)) - pieces.append('\n\twhile (context->cycles < target_cycle)') - pieces.append('\n\t{') - if self.interrupt in self.subroutines: - pieces.append('\n\t\tif (context->cycles >= context->sync_cycle) {') - pieces.append(f'\n\t\t\t{self.sync_cycle}(context, target_cycle);') - pieces.append('\n\t\t}') + if self.dispatch == 'call': + if self.body in self.subroutines: + pieces.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type)) + pieces.append('\n{') + pieces.append('\n\t{sync}(context, target_cycle);'.format(sync=self.sync_cycle)) + pieces.append('\n\twhile (context->cycles < target_cycle)') + pieces.append('\n\t{') + if self.interrupt in self.subroutines: + pieces.append('\n\t\tif (context->cycles >= context->sync_cycle) {') + pieces.append(f'\n\t\t\t{self.sync_cycle}(context, target_cycle);') + pieces.append('\n\t\t}') + self.meta = {} + self.temp = {} + intpieces = [] + self.subroutines[self.interrupt].inline(self, [], intpieces, otype, None) + for size in self.temp: + pieces.append('\n\tuint{sz}_t gen_tmp{sz}__;'.format(sz=size)) + pieces += intpieces self.meta = {} self.temp = {} - intpieces = [] - self.subroutines[self.interrupt].inline(self, [], intpieces, otype, None) - for size in self.temp: - pieces.append('\n\tuint{sz}_t gen_tmp{sz}__;'.format(sz=size)) - pieces += intpieces - self.meta = {} - self.temp = {} - self.subroutines[self.body].inline(self, [], pieces, otype, None) - pieces.append('\n\t}') - pieces.append('\n}') + self.subroutines[self.body].inline(self, [], pieces, otype, None) + pieces.append('\n\t}') + pieces.append('\n}') + body.append('\nstatic void unimplemented({pre}context *context, uint32_t target_cycle)'.format(pre = self.prefix)) + body.append('\n{') + if len(self.mainDispatch) == 1: + dispatch = list(self.mainDispatch)[0] + body.append(f'\n\tfatal_error("Unimplemented instruction: %X\\n", {dispatch});') + else: + body.append('\n\tfatal_error("Unimplemented instruction\\n");') + body.append('\n}\n') elif self.dispatch == 'goto': body.append('\n\t{sync}(context, target_cycle);'.format(sync=self.sync_cycle)) body += self.nextInstruction(otype) pieces.append('\nunimplemented:') - pieces.append('\n\tfatal_error("Unimplemented instruction\\n");') + if len(self.mainDispatch) == 1: + dispatch = list(self.mainDispatch)[0] + body.append(f'\n\tfatal_error("Unimplemented instruction: %X\\n", {dispatch});') + else: + body.append('\n\tfatal_error("Unimplemented instruction\\n");') pieces.append('\n}') return ''.join(body) + ''.join(pieces)