comparison cpu_dsl.py @ 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 9bd90cd94000
children 1579b840a1af
comparison
equal deleted inserted replaced
2614:c5314c0779c2 2615:cbd54de385d3
1295 1295
1296 def generate(self, prog, parent, fieldVals, output, otype, flagUpdates): 1296 def generate(self, prog, parent, fieldVals, output, otype, flagUpdates):
1297 procParams = [] 1297 procParams = []
1298 allParamsConst = flagUpdates is None and not prog.conditional 1298 allParamsConst = flagUpdates is None and not prog.conditional
1299 opDef = _opMap.get(self.op) 1299 opDef = _opMap.get(self.op)
1300 for param in self.params: 1300 if self.op == 'xchg':
1301 isDst = (not opDef is None) and len(procParams) in opDef.outOp 1301 #xchg uses its regs as both source and destination
1302 allowConst = (self.op in prog.subroutines or not isDst) and param in parent.regValues 1302 #we need to resolve as both so that disperse/coalesce flag stuff gets done
1303 if isDst and self.op == 'xchg': 1303 #it also interacts weirdly with constant folding
1304 #xchg uses its regs as both source and destination 1304 a = prog.resolveParam(self.params[0], parent, fieldVals, True, False)
1305 #we need to resolve as both so that disperse/coalesce flag stuff gets done 1305 b = prog.resolveParam(self.params[1], parent, fieldVals, True, False)
1306 prog.resolveParam(param, parent, fieldVals, allowConst, False) 1306 dsta = prog.resolveParam(self.params[0], parent, fieldVals, False, True)
1307 param = prog.resolveParam(param, parent, fieldVals, allowConst, isDst) 1307 dstb = prog.resolveParam(self.params[1], parent, fieldVals, False, True)
1308 1308 dsta_nocontext = dsta[len("context->"):] if dsta.startswith('context->') else dsta
1309 if (not type(param) is int) and len(procParams) != len(self.params) - 1: 1309 dstb_nocontext = dstb[len("context->"):] if dstb.startswith('context->') else dstb
1310 if type(a) is int:
1311 if type(b) is int:
1312 #both params are constant, fold
1313 parent.regValues[dsta_nocontext] = b
1314 parent.regValues[dstb_nocontext] = a
1315 if prog.isReg(dsta_nocontext):
1316 output.append(_opMap['mov'].generate(otype, prog, (b, dsta), (self.params[1], self.params[0]), None))
1317 if prog.isReg(dstb_nocontext):
1318 output.append(_opMap['mov'].generate(otype, prog, (a, dstb), (self.params[0], self.params[1]), None))
1319 else:
1320 parent.regValues[dstb_nocontext] = a
1321 del parent.regValues[dsta_nocontext]
1322 output.append(_opMap['mov'].generate(otype, prog, (b, dsta), (self.params[1], self.params[0]), None))
1323 if prog.isReg(dstb_nocontext):
1324 output.append(_opMap['mov'].generate(otype, prog, (a, dstb), (self.params[0], self.params[1]), None))
1325 prog.lastOp = self
1326 return
1327 elif type(b) is int:
1328 parent.regValues[dsta_nocontext] = b
1329 del parent.regValues[dstb_nocontext]
1330 output.append(_opMap['mov'].generate(otype, prog, (a, dstb), (self.params[0], self.params[1]), None))
1331 if prog.isReg(dsta_nocontext):
1332 output.append(_opMap['mov'].generate(otype, prog, (b, dsta), (self.params[1], self.params[0]), None))
1333 prog.lastOp = self
1334 return
1335 else:
1336 procParams = [dsta, dstb]
1310 allParamsConst = False 1337 allParamsConst = False
1311 procParams.append(param) 1338 else:
1339 for param in self.params:
1340 isDst = (not opDef is None) and len(procParams) in opDef.outOp
1341 allowConst = (self.op in prog.subroutines or not isDst) and param in parent.regValues
1342 param = prog.resolveParam(param, parent, fieldVals, allowConst, isDst)
1343
1344 if (not type(param) is int) and len(procParams) != len(self.params) - 1:
1345 allParamsConst = False
1346 procParams.append(param)
1312 if prog.needFlagCoalesce: 1347 if prog.needFlagCoalesce:
1313 output.append(prog.flags.coalesceFlags(prog, otype)) 1348 output.append(prog.flags.coalesceFlags(prog, otype))
1314 prog.needFlagCoalesce = False 1349 prog.needFlagCoalesce = False
1315 1350
1316 if self.op == 'meta': 1351 if self.op == 'meta':
1353 dst = self.params[dstIdx] 1388 dst = self.params[dstIdx]
1354 while dst in prog.meta: 1389 while dst in prog.meta:
1355 dst = prog.meta[dst] 1390 dst = prog.meta[dst]
1356 if dst in parent.regValues: 1391 if dst in parent.regValues:
1357 del parent.regValues[dst] 1392 del parent.regValues[dst]
1358 1393 if self.op in ('ocall', 'ccall', 'pcall'):
1394 #we called in to arbitrary C code, assume any reg could have changed
1395 to_clear = []
1396 for name in parent.regValues:
1397 if prog.isReg(name):
1398 to_clear.append(name)
1399 for name in to_clear:
1400 del parent.regValues[name]
1359 elif self.op in prog.subroutines: 1401 elif self.op in prog.subroutines:
1360 procParams = [] 1402 procParams = []
1361 for param in self.params: 1403 for param in self.params:
1362 begin,sep,end = param.partition('.') 1404 begin,sep,end = param.partition('.')
1363 if sep: 1405 if sep:
2136 maybeLocal = parent.resolveLocal(param) 2178 maybeLocal = parent.resolveLocal(param)
2137 if maybeLocal: 2179 if maybeLocal:
2138 if isdst: 2180 if isdst:
2139 self.lastDst = param 2181 self.lastDst = param
2140 self.lastSize = None 2182 self.lastSize = None
2183 if allowConstant and maybeLocal in parent.regValues:
2184 return parent.regValues[maybeLocal]
2141 return maybeLocal 2185 return maybeLocal
2142 if param in fieldVals: 2186 if param in fieldVals:
2143 param = fieldVals[param] 2187 param = fieldVals[param]
2144 fieldVals = {} 2188 fieldVals = {}
2145 keepGoing = True 2189 keepGoing = True