comparison cpu_dsl.py @ 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 6bca3c28e2ad
children 8ef8b2e99f4f
comparison
equal deleted inserted replaced
2590:e602dbf776d8 2591:563d05355a12
86 if i + 1 < len(oplist) and oplist[i+1].op == 'update_flags': 86 if i + 1 < len(oplist) and oplist[i+1].op == 'update_flags':
87 flagUpdates, _ = prog.flags.parseFlagUpdate(oplist[i+1].params[0]) 87 flagUpdates, _ = prog.flags.parseFlagUpdate(oplist[i+1].params[0])
88 else: 88 else:
89 flagUpdates = None 89 flagUpdates = None
90 oplist[i].generate(prog, self, fieldVals, output, otype, flagUpdates) 90 oplist[i].generate(prog, self, fieldVals, output, otype, flagUpdates)
91
92 def processDispatch(self, prog):
93 for op in self.implementation:
94 op.processDispatch(prog)
91 95
92 def resolveLocal(self, name): 96 def resolveLocal(self, name):
93 return None 97 return None
94 98
95 class ChildBlock(Block): 99 class ChildBlock(Block):
109 self.regValues = {} 113 self.regValues = {}
110 self.varyingBits = 0 114 self.varyingBits = 0
111 self.invalidFieldValues = {} 115 self.invalidFieldValues = {}
112 self.invalidCombos = [] 116 self.invalidCombos = []
113 self.newLocals = [] 117 self.newLocals = []
118 self.noSpecialize = set()
114 for field in fields: 119 for field in fields:
115 self.varyingBits += fields[field][1] 120 self.varyingBits += fields[field][1]
116 121
117 def addOp(self, op): 122 def addOp(self, op):
118 if op.op == 'local': 123 if op.op == 'local':
129 for i in range(0, len(op.params), 2): 134 for i in range(0, len(op.params), 2):
130 name = op.params[i] 135 name = op.params[i]
131 value = int(op.params[i+1]) 136 value = int(op.params[i+1])
132 vmap[name] = value 137 vmap[name] = value
133 self.invalidCombos.append(vmap) 138 self.invalidCombos.append(vmap)
139 elif op.op == 'nospecialize':
140 for name in op.params:
141 self.noSpecialize.add(name)
134 else: 142 else:
135 self.implementation.append(op) 143 self.implementation.append(op)
136 144
137 def resolveLocal(self, name): 145 def resolveLocal(self, name):
138 if name in self.locals: 146 if name in self.locals:
198 fieldBits[field] = bits 206 fieldBits[field] = bits
199 return (fieldVals, fieldBits) 207 return (fieldVals, fieldBits)
200 208
201 def generateName(self, value): 209 def generateName(self, value):
202 fieldVals,fieldBits = self.getFieldVals(value) 210 fieldVals,fieldBits = self.getFieldVals(value)
211 for name in self.noSpecialize:
212 del fieldVals[name]
203 names = list(fieldVals.keys()) 213 names = list(fieldVals.keys())
204 names.sort() 214 names.sort()
205 funName = self.name 215 funName = self.name
206 for name in names: 216 for name in names:
207 funName += '_{0}_{1:0>{2}}'.format(name, bin(fieldVals[name])[2:], fieldBits[name]) 217 funName += '_{0}_{1:0>{2}}'.format(name, bin(fieldVals[name])[2:], fieldBits[name])
214 self.regValues = {} 224 self.regValues = {}
215 for var in self.locals: 225 for var in self.locals:
216 output.append('\n\tuint{sz}_t {name};'.format(sz=self.locals[var], name=var)) 226 output.append('\n\tuint{sz}_t {name};'.format(sz=self.locals[var], name=var))
217 self.newLocals = [] 227 self.newLocals = []
218 fieldVals,_ = self.getFieldVals(value) 228 fieldVals,_ = self.getFieldVals(value)
229 for name in self.noSpecialize:
230 del fieldVals[name]
231 self.locals[name] = prog.opsize
232 if len(prog.mainDispatch) != 1:
233 raise Exception('nospecialize requires exactly 1 field used for main table dispatch')
234 shift,bits = self.fields[name]
235 mask = (1 << bits) - 1
236 opfield = list(prog.mainDispatch)[0]
237 if shift:
238 output.append(f'\n\tuint{prog.opsize}_t {name} = context->{opfield} >> {shift} & {mask};')
239 else:
240 output.append(f'\n\tuint{prog.opsize}_t {name} = context->{opfield} & {mask};')
219 self.processOps(prog, fieldVals, output, otype, self.implementation) 241 self.processOps(prog, fieldVals, output, otype, self.implementation)
242 for name in self.noSpecialize:
243 del self.locals[name]
220 244
221 if prog.dispatch == 'call': 245 if prog.dispatch == 'call':
222 begin = '\nvoid ' + self.generateName(value) + '(' + prog.context_type + ' *context, uint32_t target_cycle)\n{' 246 begin = '\nvoid ' + self.generateName(value) + '(' + prog.context_type + ' *context, uint32_t target_cycle)\n{'
223 elif prog.dispatch == 'goto': 247 elif prog.dispatch == 'goto':
224 begin = '\n' + self.generateName(value) + ': {' 248 begin = '\n' + self.generateName(value) + ': {'
1307 prog.subroutines[self.op].inline(prog, procParams, output, otype, parent) 1331 prog.subroutines[self.op].inline(prog, procParams, output, otype, parent)
1308 else: 1332 else:
1309 output.append('\n\t' + self.op + '(' + ', '.join([str(p) for p in procParams]) + ');') 1333 output.append('\n\t' + self.op + '(' + ', '.join([str(p) for p in procParams]) + ');')
1310 prog.lastOp = self 1334 prog.lastOp = self
1311 1335
1336 def processDispatch(self, prog):
1337 if self.op == 'dispatch' and (len(self.params) == 1 or self.params[1] == 'main'):
1338 prog.mainDispatch.add(self.params[0])
1339
1312 def __str__(self): 1340 def __str__(self):
1313 return '\n\t' + self.op + ' ' + ' '.join(self.params) 1341 return '\n\t' + self.op + ' ' + ' '.join(self.params)
1314 1342
1315 #represents a DSL switch construct 1343 #represents a DSL switch construct
1316 class Switch(ChildBlock): 1344 class Switch(ChildBlock):
1407 #prog.temp = temp 1435 #prog.temp = temp
1408 output.append('\n\t}') 1436 output.append('\n\t}')
1409 prog.conditional = oldCond 1437 prog.conditional = oldCond
1410 prog.popScope() 1438 prog.popScope()
1411 1439
1440 def processDispatch(self, prog):
1441 for case in self.cases:
1442 for op in self.cases[case]:
1443 op.processDispatch(prog)
1444 if self.default:
1445 for op in self.default:
1446 op.processDispatch(prog)
1447
1412 def __str__(self): 1448 def __str__(self):
1413 keys = self.cases.keys() 1449 keys = self.cases.keys()
1414 keys.sort() 1450 keys.sort()
1415 lines = ['\n\tswitch'] 1451 lines = ['\n\tswitch']
1416 for case in keys: 1452 for case in keys:
1551 self._genFalseBody(prog, fieldVals, output, otype) 1587 self._genFalseBody(prog, fieldVals, output, otype)
1552 #prog.temp = temp 1588 #prog.temp = temp
1553 output.append('\n\t}') 1589 output.append('\n\t}')
1554 prog.conditional = oldCond 1590 prog.conditional = oldCond
1555 1591
1592
1593 def processDispatch(self, prog):
1594 for op in self.body:
1595 op.processDispatch(prog)
1596 for op in self.elseBody:
1597 op.processDispatch(prog)
1556 1598
1557 def __str__(self): 1599 def __str__(self):
1558 lines = ['\n\tif'] 1600 lines = ['\n\tif']
1559 for op in self.body: 1601 for op in self.body:
1560 lines.append(str(op)) 1602 lines.append(str(op))
1901 self.meta = {} 1943 self.meta = {}
1902 self.temp = {} 1944 self.temp = {}
1903 self.needFlagCoalesce = False 1945 self.needFlagCoalesce = False
1904 self.needFlagDisperse = False 1946 self.needFlagDisperse = False
1905 self.lastOp = None 1947 self.lastOp = None
1906 opmap[val] = inst.generateName(val) 1948 name = inst.generateName(val)
1907 bodymap[val] = inst.generateBody(val, self, otype) 1949 opmap[val] = name
1908 1950 if not name in bodymap:
1951 bodymap[name] = inst.generateBody(val, self, otype)
1952
1953 alreadyAppended = set()
1909 if self.dispatch == 'call': 1954 if self.dispatch == 'call':
1910 lateBody.append('\nstatic impl_fun impl_{name}[{sz}] = {{'.format(name = table, sz=len(opmap))) 1955 lateBody.append('\nstatic impl_fun impl_{name}[{sz}] = {{'.format(name = table, sz=len(opmap)))
1911 for inst in range(0, len(opmap)): 1956 for inst in range(0, len(opmap)):
1912 op = opmap[inst] 1957 op = opmap[inst]
1913 if op is None: 1958 if op is None:
1914 lateBody.append('\n\tunimplemented,') 1959 lateBody.append('\n\tunimplemented,')
1915 else: 1960 else:
1916 lateBody.append('\n\t' + op + ',') 1961 lateBody.append('\n\t' + op + ',')
1917 body.append(bodymap[inst]) 1962 if not op in alreadyAppended:
1963 body.append(bodymap[op])
1964 alreadyAppended.add(op)
1918 lateBody.append('\n};') 1965 lateBody.append('\n};')
1919 elif self.dispatch == 'goto': 1966 elif self.dispatch == 'goto':
1920 body.append('\n\tstatic void *impl_{name}[{sz}] = {{'.format(name = table, sz=len(opmap))) 1967 body.append('\n\tstatic void *impl_{name}[{sz}] = {{'.format(name = table, sz=len(opmap)))
1921 for inst in range(0, len(opmap)): 1968 for inst in range(0, len(opmap)):
1922 op = opmap[inst] 1969 op = opmap[inst]
1923 if op is None: 1970 if op is None:
1924 body.append('\n\t\t&&unimplemented,') 1971 body.append('\n\t\t&&unimplemented,')
1925 else: 1972 else:
1926 body.append('\n\t\t&&' + op + ',') 1973 body.append('\n\t\t&&' + op + ',')
1927 lateBody.append(bodymap[inst]) 1974 if not op in alreadyAppended:
1975 lateBody.append(bodymap[op])
1928 body.append('\n\t};') 1976 body.append('\n\t};')
1929 else: 1977 else:
1930 raise Exception("unimplmeneted dispatch type " + self.dispatch) 1978 raise Exception("unimplmeneted dispatch type " + self.dispatch)
1931 body.extend(pieces) 1979 body.extend(pieces)
1932 1980
1958 body.append('\nstatic impl_fun impl_{name}[{sz}];'.format(name = table, sz=(1 << self.opsize))) 2006 body.append('\nstatic impl_fun impl_{name}[{sz}];'.format(name = table, sz=(1 << self.opsize)))
1959 body.append('\nstatic impl_fun impl_main[{sz}];'.format(sz=(1 << self.opsize))) 2007 body.append('\nstatic impl_fun impl_main[{sz}];'.format(sz=(1 << self.opsize)))
1960 elif self.dispatch == 'goto': 2008 elif self.dispatch == 'goto':
1961 body.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type)) 2009 body.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type))
1962 body.append('\n{') 2010 body.append('\n{')
2011
2012 for table in self.instructions:
2013 for inst in self.instructions[table]:
2014 inst.processDispatch(self)
2015 for sub in self.subroutines:
2016 self.subroutines[sub].processDispatch(self)
1963 2017
1964 for table in self.extra_tables: 2018 for table in self.extra_tables:
1965 self._buildTable(otype, table, body, pieces) 2019 self._buildTable(otype, table, body, pieces)
1966 self._buildTable(otype, 'main', body, pieces) 2020 self._buildTable(otype, 'main', body, pieces)
1967 if self.dispatch == 'call': 2021 if self.dispatch == 'call':