Mercurial > repos > blastem
changeset 2615:cbd54de385d3
Fix some issues with constant folding in CPU DSL
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 17 Feb 2025 23:40:36 -0800 |
parents | c5314c0779c2 |
children | cbf5a01e429e |
files | cpu_dsl.py |
diffstat | 1 files changed, 56 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/cpu_dsl.py Mon Feb 17 23:40:14 2025 -0800 +++ b/cpu_dsl.py Mon Feb 17 23:40:36 2025 -0800 @@ -1297,18 +1297,53 @@ procParams = [] allParamsConst = flagUpdates is None and not prog.conditional opDef = _opMap.get(self.op) - for param in self.params: - isDst = (not opDef is None) and len(procParams) in opDef.outOp - allowConst = (self.op in prog.subroutines or not isDst) and param in parent.regValues - if isDst and self.op == 'xchg': - #xchg uses its regs as both source and destination - #we need to resolve as both so that disperse/coalesce flag stuff gets done - prog.resolveParam(param, parent, fieldVals, allowConst, False) - param = prog.resolveParam(param, parent, fieldVals, allowConst, isDst) - - if (not type(param) is int) and len(procParams) != len(self.params) - 1: + if self.op == 'xchg': + #xchg uses its regs as both source and destination + #we need to resolve as both so that disperse/coalesce flag stuff gets done + #it also interacts weirdly with constant folding + a = prog.resolveParam(self.params[0], parent, fieldVals, True, False) + b = prog.resolveParam(self.params[1], parent, fieldVals, True, False) + dsta = prog.resolveParam(self.params[0], parent, fieldVals, False, True) + dstb = prog.resolveParam(self.params[1], parent, fieldVals, False, True) + dsta_nocontext = dsta[len("context->"):] if dsta.startswith('context->') else dsta + dstb_nocontext = dstb[len("context->"):] if dstb.startswith('context->') else dstb + if type(a) is int: + if type(b) is int: + #both params are constant, fold + parent.regValues[dsta_nocontext] = b + parent.regValues[dstb_nocontext] = a + if prog.isReg(dsta_nocontext): + output.append(_opMap['mov'].generate(otype, prog, (b, dsta), (self.params[1], self.params[0]), None)) + if prog.isReg(dstb_nocontext): + output.append(_opMap['mov'].generate(otype, prog, (a, dstb), (self.params[0], self.params[1]), None)) + else: + parent.regValues[dstb_nocontext] = a + del parent.regValues[dsta_nocontext] + output.append(_opMap['mov'].generate(otype, prog, (b, dsta), (self.params[1], self.params[0]), None)) + if prog.isReg(dstb_nocontext): + output.append(_opMap['mov'].generate(otype, prog, (a, dstb), (self.params[0], self.params[1]), None)) + prog.lastOp = self + return + elif type(b) is int: + parent.regValues[dsta_nocontext] = b + del parent.regValues[dstb_nocontext] + output.append(_opMap['mov'].generate(otype, prog, (a, dstb), (self.params[0], self.params[1]), None)) + if prog.isReg(dsta_nocontext): + output.append(_opMap['mov'].generate(otype, prog, (b, dsta), (self.params[1], self.params[0]), None)) + prog.lastOp = self + return + else: + procParams = [dsta, dstb] allParamsConst = False - procParams.append(param) + else: + for param in self.params: + isDst = (not opDef is None) and len(procParams) in opDef.outOp + allowConst = (self.op in prog.subroutines or not isDst) and param in parent.regValues + param = prog.resolveParam(param, parent, fieldVals, allowConst, isDst) + + if (not type(param) is int) and len(procParams) != len(self.params) - 1: + allParamsConst = False + procParams.append(param) if prog.needFlagCoalesce: output.append(prog.flags.coalesceFlags(prog, otype)) prog.needFlagCoalesce = False @@ -1355,7 +1390,14 @@ dst = prog.meta[dst] if dst in parent.regValues: del parent.regValues[dst] - + if self.op in ('ocall', 'ccall', 'pcall'): + #we called in to arbitrary C code, assume any reg could have changed + to_clear = [] + for name in parent.regValues: + if prog.isReg(name): + to_clear.append(name) + for name in to_clear: + del parent.regValues[name] elif self.op in prog.subroutines: procParams = [] for param in self.params: @@ -2138,6 +2180,8 @@ if isdst: self.lastDst = param self.lastSize = None + if allowConstant and maybeLocal in parent.regValues: + return parent.regValues[maybeLocal] return maybeLocal if param in fieldVals: param = fieldVals[param]