Mercurial > repos > blastem
comparison cpu_dsl.py @ 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 | e04c7e753bf6 |
comparison
equal
deleted
inserted
replaced
2580:939b818df589 | 2581:9e10149c9e10 |
---|---|
473 def _dispatchCImpl(prog, params): | 473 def _dispatchCImpl(prog, params): |
474 if len(params) == 1: | 474 if len(params) == 1: |
475 table = 'main' | 475 table = 'main' |
476 else: | 476 else: |
477 table = params[1] | 477 table = params[1] |
478 if table == 'main': | |
479 prog.mainDispatch.add(params[0]) | |
478 if prog.dispatch == 'call': | 480 if prog.dispatch == 'call': |
479 return '\n\timpl_{tbl}[{op}](context, target_cycle);'.format(tbl = table, op = params[0]) | 481 return '\n\timpl_{tbl}[{op}](context, target_cycle);'.format(tbl = table, op = params[0]) |
480 elif prog.dispatch == 'goto': | 482 elif prog.dispatch == 'goto': |
481 return '\n\tgoto *impl_{tbl}[{op}];'.format(tbl = table, op = params[0]) | 483 return '\n\tgoto *impl_{tbl}[{op}];'.format(tbl = table, op = params[0]) |
482 else: | 484 else: |
1839 self.lastBFlow = None | 1841 self.lastBFlow = None |
1840 self.sizeAdjust = None | 1842 self.sizeAdjust = None |
1841 self.conditional = False | 1843 self.conditional = False |
1842 self.declares = [] | 1844 self.declares = [] |
1843 self.lastSize = None | 1845 self.lastSize = None |
1846 self.mainDispatch = set() | |
1844 | 1847 |
1845 def __str__(self): | 1848 def __str__(self): |
1846 pieces = [] | 1849 pieces = [] |
1847 for reg in self.regs: | 1850 for reg in self.regs: |
1848 pieces.append(str(self.regs[reg])) | 1851 pieces.append(str(self.regs[reg])) |
1896 self.lastOp = None | 1899 self.lastOp = None |
1897 opmap[val] = inst.generateName(val) | 1900 opmap[val] = inst.generateName(val) |
1898 bodymap[val] = inst.generateBody(val, self, otype) | 1901 bodymap[val] = inst.generateBody(val, self, otype) |
1899 | 1902 |
1900 if self.dispatch == 'call': | 1903 if self.dispatch == 'call': |
1901 pieces.append('\nstatic impl_fun impl_{name}[{sz}] = {{'.format(name = table, sz=len(opmap))) | 1904 lateBody.append('\nstatic impl_fun impl_{name}[{sz}] = {{'.format(name = table, sz=len(opmap))) |
1902 for inst in range(0, len(opmap)): | 1905 for inst in range(0, len(opmap)): |
1903 op = opmap[inst] | 1906 op = opmap[inst] |
1904 if op is None: | 1907 if op is None: |
1905 pieces.append('\n\tunimplemented,') | 1908 lateBody.append('\n\tunimplemented,') |
1906 else: | 1909 else: |
1907 pieces.append('\n\t' + op + ',') | 1910 lateBody.append('\n\t' + op + ',') |
1908 body.append(bodymap[inst]) | 1911 body.append(bodymap[inst]) |
1909 pieces.append('\n};') | 1912 lateBody.append('\n};') |
1910 elif self.dispatch == 'goto': | 1913 elif self.dispatch == 'goto': |
1911 body.append('\n\tstatic void *impl_{name}[{sz}] = {{'.format(name = table, sz=len(opmap))) | 1914 body.append('\n\tstatic void *impl_{name}[{sz}] = {{'.format(name = table, sz=len(opmap))) |
1912 for inst in range(0, len(opmap)): | 1915 for inst in range(0, len(opmap)): |
1913 op = opmap[inst] | 1916 op = opmap[inst] |
1914 if op is None: | 1917 if op is None: |
1942 body = [] | 1945 body = [] |
1943 pieces = [] | 1946 pieces = [] |
1944 for include in self.includes: | 1947 for include in self.includes: |
1945 body.append('#include "{0}"\n'.format(include)) | 1948 body.append('#include "{0}"\n'.format(include)) |
1946 if self.dispatch == 'call': | 1949 if self.dispatch == 'call': |
1947 body.append('\nstatic void unimplemented({pre}context *context, uint32_t target_cycle)'.format(pre = self.prefix)) | |
1948 body.append('\n{') | |
1949 body.append('\n\tfatal_error("Unimplemented instruction\\n");') | |
1950 body.append('\n}\n') | |
1951 body.append('\ntypedef void (*impl_fun)({pre}context *context, uint32_t target_cycle);'.format(pre=self.prefix)) | 1950 body.append('\ntypedef void (*impl_fun)({pre}context *context, uint32_t target_cycle);'.format(pre=self.prefix)) |
1952 for table in self.extra_tables: | 1951 for table in self.extra_tables: |
1953 body.append('\nstatic impl_fun impl_{name}[{sz}];'.format(name = table, sz=(1 << self.opsize))) | 1952 body.append('\nstatic impl_fun impl_{name}[{sz}];'.format(name = table, sz=(1 << self.opsize))) |
1954 body.append('\nstatic impl_fun impl_main[{sz}];'.format(sz=(1 << self.opsize))) | 1953 body.append('\nstatic impl_fun impl_main[{sz}];'.format(sz=(1 << self.opsize))) |
1955 elif self.dispatch == 'goto': | 1954 elif self.dispatch == 'goto': |
1957 body.append('\n{') | 1956 body.append('\n{') |
1958 | 1957 |
1959 for table in self.extra_tables: | 1958 for table in self.extra_tables: |
1960 self._buildTable(otype, table, body, pieces) | 1959 self._buildTable(otype, table, body, pieces) |
1961 self._buildTable(otype, 'main', body, pieces) | 1960 self._buildTable(otype, 'main', body, pieces) |
1962 if self.dispatch == 'call' and self.body in self.subroutines: | 1961 if self.dispatch == 'call': |
1963 pieces.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type)) | 1962 if self.body in self.subroutines: |
1964 pieces.append('\n{') | 1963 pieces.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type)) |
1965 pieces.append('\n\t{sync}(context, target_cycle);'.format(sync=self.sync_cycle)) | 1964 pieces.append('\n{') |
1966 pieces.append('\n\twhile (context->cycles < target_cycle)') | 1965 pieces.append('\n\t{sync}(context, target_cycle);'.format(sync=self.sync_cycle)) |
1967 pieces.append('\n\t{') | 1966 pieces.append('\n\twhile (context->cycles < target_cycle)') |
1968 if self.interrupt in self.subroutines: | 1967 pieces.append('\n\t{') |
1969 pieces.append('\n\t\tif (context->cycles >= context->sync_cycle) {') | 1968 if self.interrupt in self.subroutines: |
1970 pieces.append(f'\n\t\t\t{self.sync_cycle}(context, target_cycle);') | 1969 pieces.append('\n\t\tif (context->cycles >= context->sync_cycle) {') |
1971 pieces.append('\n\t\t}') | 1970 pieces.append(f'\n\t\t\t{self.sync_cycle}(context, target_cycle);') |
1971 pieces.append('\n\t\t}') | |
1972 self.meta = {} | |
1973 self.temp = {} | |
1974 intpieces = [] | |
1975 self.subroutines[self.interrupt].inline(self, [], intpieces, otype, None) | |
1976 for size in self.temp: | |
1977 pieces.append('\n\tuint{sz}_t gen_tmp{sz}__;'.format(sz=size)) | |
1978 pieces += intpieces | |
1972 self.meta = {} | 1979 self.meta = {} |
1973 self.temp = {} | 1980 self.temp = {} |
1974 intpieces = [] | 1981 self.subroutines[self.body].inline(self, [], pieces, otype, None) |
1975 self.subroutines[self.interrupt].inline(self, [], intpieces, otype, None) | 1982 pieces.append('\n\t}') |
1976 for size in self.temp: | 1983 pieces.append('\n}') |
1977 pieces.append('\n\tuint{sz}_t gen_tmp{sz}__;'.format(sz=size)) | 1984 body.append('\nstatic void unimplemented({pre}context *context, uint32_t target_cycle)'.format(pre = self.prefix)) |
1978 pieces += intpieces | 1985 body.append('\n{') |
1979 self.meta = {} | 1986 if len(self.mainDispatch) == 1: |
1980 self.temp = {} | 1987 dispatch = list(self.mainDispatch)[0] |
1981 self.subroutines[self.body].inline(self, [], pieces, otype, None) | 1988 body.append(f'\n\tfatal_error("Unimplemented instruction: %X\\n", {dispatch});') |
1982 pieces.append('\n\t}') | 1989 else: |
1983 pieces.append('\n}') | 1990 body.append('\n\tfatal_error("Unimplemented instruction\\n");') |
1991 body.append('\n}\n') | |
1984 elif self.dispatch == 'goto': | 1992 elif self.dispatch == 'goto': |
1985 body.append('\n\t{sync}(context, target_cycle);'.format(sync=self.sync_cycle)) | 1993 body.append('\n\t{sync}(context, target_cycle);'.format(sync=self.sync_cycle)) |
1986 body += self.nextInstruction(otype) | 1994 body += self.nextInstruction(otype) |
1987 pieces.append('\nunimplemented:') | 1995 pieces.append('\nunimplemented:') |
1988 pieces.append('\n\tfatal_error("Unimplemented instruction\\n");') | 1996 if len(self.mainDispatch) == 1: |
1997 dispatch = list(self.mainDispatch)[0] | |
1998 body.append(f'\n\tfatal_error("Unimplemented instruction: %X\\n", {dispatch});') | |
1999 else: | |
2000 body.append('\n\tfatal_error("Unimplemented instruction\\n");') | |
1989 pieces.append('\n}') | 2001 pieces.append('\n}') |
1990 return ''.join(body) + ''.join(pieces) | 2002 return ''.join(body) + ''.join(pieces) |
1991 | 2003 |
1992 def checkBool(self, name): | 2004 def checkBool(self, name): |
1993 if not name in self.booleans: | 2005 if not name in self.booleans: |