comparison cpu_dsl.py @ 2704:c5dce4284e69

Fix a couple of bugs in CPU DSL found while working on uPD78K/II core
author Michael Pavone <pavone@retrodev.com>
date Sun, 06 Jul 2025 15:18:02 -0700
parents e3394457427e
children 2fb2e989186f
comparison
equal deleted inserted replaced
2703:829205a9647a 2704:c5dce4284e69
317 if len(params) != len(self.args): 317 if len(params) != len(self.args):
318 raise Exception('{0} expects {1} arguments, but was called with {2}'.format(self.name, len(self.args), len(params))) 318 raise Exception('{0} expects {1} arguments, but was called with {2}'.format(self.name, len(self.args), len(params)))
319 argValues = {} 319 argValues = {}
320 if parent: 320 if parent:
321 self.regValues = parent.regValues 321 self.regValues = parent.regValues
322 output.append('\n\t{')
322 prog.pushScope(self) 323 prog.pushScope(self)
323 i = 0 324 i = 0
324 for name,size in self.args: 325 for name,size in self.args:
325 argValues[name] = params[i] 326 argValues[name] = params[i]
326 i += 1 327 i += 1
328 size = self.locals[name] 329 size = self.locals[name]
329 output.append('\n\tuint{size}_t {sub}_{local};'.format(size=size, sub=self.name, local=name)) 330 output.append('\n\tuint{size}_t {sub}_{local};'.format(size=size, sub=self.name, local=name))
330 self.argValues = argValues 331 self.argValues = argValues
331 self.processOps(prog, argValues, output, otype, self.implementation) 332 self.processOps(prog, argValues, output, otype, self.implementation)
332 prog.popScope() 333 prog.popScope()
334 output.append('\n\t}')
333 335
334 def __str__(self): 336 def __str__(self):
335 pieces = [self.name] 337 pieces = [self.name]
336 for name,size in self.args: 338 for name,size in self.args:
337 pieces.append('\n\targ {0} {1}'.format(name, size)) 339 pieces.append('\n\targ {0} {1}'.format(name, size))
1418 else: 1420 else:
1419 if param in fieldVals: 1421 if param in fieldVals:
1420 param = fieldVals[param] 1422 param = fieldVals[param]
1421 else: 1423 else:
1422 maybeLocal = parent.resolveLocal(param) 1424 maybeLocal = parent.resolveLocal(param)
1423 if maybeLocal and maybeLocal in parent.regValues: 1425 if maybeLocal:
1424 param = parent.regValues[maybeLocal] 1426 if maybeLocal in parent.regValues:
1427 param = parent.regValues[maybeLocal]
1428 else:
1429 param = maybeLocal
1425 procParams.append(param) 1430 procParams.append(param)
1426 prog.subroutines[self.op].inline(prog, procParams, output, otype, parent) 1431 prog.subroutines[self.op].inline(prog, procParams, output, otype, parent)
1427 else: 1432 else:
1428 output.append('\n\t' + self.op + '(' + ', '.join([str(p) for p in procParams]) + ');') 1433 output.append('\n\t' + self.op + '(' + ', '.join([str(p) for p in procParams]) + ');')
1429 prog.lastOp = self 1434 prog.lastOp = self
1539 if self.default: 1544 if self.default:
1540 for op in self.default: 1545 for op in self.default:
1541 op.processDispatch(prog) 1546 op.processDispatch(prog)
1542 1547
1543 def __str__(self): 1548 def __str__(self):
1544 keys = self.cases.keys() 1549 keys = list(self.cases.keys())
1545 keys.sort() 1550 keys.sort()
1546 lines = ['\n\tswitch'] 1551 lines = ['\n\tswitch']
1547 for case in keys: 1552 for case in keys:
1548 lines.append('\n\tcase {0}'.format(case)) 1553 lines.append('\n\tcase {0}'.format(case))
1549 lines.append(''.join([str(op) for op in self.cases[case]])) 1554 lines.append(''.join([str(op) for op in self.cases[case]]))
1566 return '\n\tif ({a} == {b}) '.format(a=params[1], b = params[0]) + '{' 1571 return '\n\tif ({a} == {b}) '.format(a=params[1], b = params[0]) + '{'
1567 else: 1572 else:
1568 return '\n\tif (!{a}) {{'.format(a=prog.resolveParam(prog.lastDst, None, {})) 1573 return '\n\tif (!{a}) {{'.format(a=prog.resolveParam(prog.lastDst, None, {}))
1569 1574
1570 def _neqCImpl(prog, parent, fieldVals, output): 1575 def _neqCImpl(prog, parent, fieldVals, output):
1571 return '\n\tif ({a}) {{'.format(a=prog.resolveParam(prog.lastDst, None, {})) 1576 if prog.lastOp.op == 'cmp':
1577 output.pop()
1578 params = [prog.resolveParam(p, parent, fieldVals) for p in prog.lastOp.params]
1579 return '\n\tif ({a} != {b}) '.format(a=params[1], b = params[0]) + '{'
1580 else:
1581 return '\n\tif ({a}) {{'.format(a=prog.resolveParam(prog.lastDst, None, {}))
1572 1582
1573 _ifCmpImpl = { 1583 _ifCmpImpl = {
1574 'c': { 1584 'c': {
1575 '>=U': _geuCImpl, 1585 '>=U': _geuCImpl,
1576 '=': _eqCImpl, 1586 '=': _eqCImpl,
2204 self._buildTable(otype, 'main', body, pieces) 2214 self._buildTable(otype, 'main', body, pieces)
2205 if self.dispatch == 'call': 2215 if self.dispatch == 'call':
2206 if self.body in self.subroutines: 2216 if self.body in self.subroutines:
2207 pieces.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type)) 2217 pieces.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type))
2208 pieces.append('\n{') 2218 pieces.append('\n{')
2209 pieces.append('\n\t{sync}(context, target_cycle);'.format(sync=self.sync_cycle)) 2219 if self.sync_cycle:
2220 pieces.append('\n\t{sync}(context, target_cycle);'.format(sync=self.sync_cycle))
2210 if self.pc_reg: 2221 if self.pc_reg:
2211 pieces.append('\n\tif (context->breakpoints) {') 2222 pieces.append('\n\tif (context->breakpoints) {')
2212 pieces.append('\n\t\twhile (context->cycles < target_cycle)') 2223 pieces.append('\n\t\twhile (context->cycles < target_cycle)')
2213 pieces.append('\n\t\t{') 2224 pieces.append('\n\t\t{')
2214 if self.interrupt in self.subroutines: 2225 if self.interrupt in self.subroutines: