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: