Mercurial > repos > blastem
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: |