comparison cpu_dsl.py @ 1715:4fd84c3efc72

Implement 16-bit addition in new Z80 core along with necessary CPU DSL fixes to make them work right
author Michael Pavone <pavone@retrodev.com>
date Tue, 29 Jan 2019 23:56:48 -0800
parents 0264d8b288e2
children 04cafe626118
comparison
equal deleted inserted replaced
1714:e170a0f75c4f 1715:4fd84c3efc72
53 self.varyingBits += fields[field][1] 53 self.varyingBits += fields[field][1]
54 54
55 def addOp(self, op): 55 def addOp(self, op):
56 if op.op == 'local': 56 if op.op == 'local':
57 name = op.params[0] 57 name = op.params[0]
58 size = op.params[1] 58 size = int(op.params[1])
59 self.locals[name] = size 59 self.locals[name] = size
60 elif op.op == 'invalid': 60 elif op.op == 'invalid':
61 name = op.params[0] 61 name = op.params[0]
62 value = int(op.params[1]) 62 value = int(op.params[1])
63 self.invalidFieldValues.setdefault(name, set()).add(value) 63 self.invalidFieldValues.setdefault(name, set()).add(value)
310 if calc == 'sign': 310 if calc == 'sign':
311 resultBit = prog.paramSize(prog.lastDst) - 1 311 resultBit = prog.paramSize(prog.lastDst) - 1
312 elif calc == 'carry': 312 elif calc == 'carry':
313 resultBit = prog.paramSize(prog.lastDst) 313 resultBit = prog.paramSize(prog.lastDst)
314 elif calc == 'half': 314 elif calc == 'half':
315 resultBit = 4 315 resultBit = prog.paramSize(prog.lastDst) - 4
316 myRes = '({a} ^ {b} ^ {res})'.format(a = prog.lastA, b = prog.lastB, res = lastDst) 316 myRes = '({a} ^ {b} ^ {res})'.format(a = prog.lastA, b = prog.lastB, res = lastDst)
317 elif calc == 'overflow': 317 elif calc == 'overflow':
318 resultBit = prog.paramSize(prog.lastDst) - 1 318 resultBit = prog.paramSize(prog.lastDst) - 1
319 myRes = '((({a} ^ {b})) & ({a} ^ {res}))'.format(a = prog.lastA, b = prog.lastBFlow, res = lastDst) 319 myRes = '((({a} ^ {b})) & ({a} ^ {res}))'.format(a = prog.lastA, b = prog.lastBFlow, res = lastDst)
320 else: 320 else:
321 resultBit = int(resultBit) 321 #Note: offsetting this by the operation size - 8 makes sense for the Z80
322 #but might not for other CPUs with this kind of fixed bit flag behavior
323 resultBit = int(resultBit) + prog.paramSize(prog.lastDst) - 8
322 if type(storage) is tuple: 324 if type(storage) is tuple:
323 reg,storageBit = storage 325 reg,storageBit = storage
324 reg = prog.resolveParam(reg, None, {}) 326 reg = prog.resolveParam(reg, None, {})
325 if storageBit == resultBit: 327 if storageBit == resultBit:
326 #TODO: optimize this case 328 #TODO: optimize this case
337 output.append('\n\t{reg} = ({reg} & ~{mask}U) | ({res} {op} {shift}U & {mask}U);'.format( 339 output.append('\n\t{reg} = ({reg} & ~{mask}U) | ({res} {op} {shift}U & {mask}U);'.format(
338 reg = reg, mask = 1 << storageBit, res = myRes, op = op, shift = shift 340 reg = reg, mask = 1 << storageBit, res = myRes, op = op, shift = shift
339 )) 341 ))
340 else: 342 else:
341 reg = prog.resolveParam(storage, None, {}) 343 reg = prog.resolveParam(storage, None, {})
342 output.append('\n\t{reg} = {res} & {mask}U;'.format(reg=reg, res=myRes, mask = 1 << resultBit)) 344 maxBit = prog.paramSize(storage) - 1
345 if resultBit > maxBit:
346 output.append('\n\t{reg} = {res} >> {shift} & {mask}U;'.format(reg=reg, res=myRes, shift = resultBit - maxBit, mask = 1 << maxBit))
347 else:
348 output.append('\n\t{reg} = {res} & {mask}U;'.format(reg=reg, res=myRes, mask = 1 << resultBit))
343 elif calc == 'zero': 349 elif calc == 'zero':
344 if type(storage) is tuple: 350 if type(storage) is tuple:
345 reg,storageBit = storage 351 reg,storageBit = storage
346 reg = prog.resolveParam(reg, None, {}) 352 reg = prog.resolveParam(reg, None, {})
347 output.append('\n\t{reg} = {res} ? ({reg} & {mask}U) : ({reg} | {bit}U);'.format( 353 output.append('\n\t{reg} = {res} ? ({reg} & {mask}U) : ({reg} | {bit}U);'.format(
1174 if parent: 1180 if parent:
1175 if param in parent.regValues and allowConstant: 1181 if param in parent.regValues and allowConstant:
1176 return parent.regValues[param] 1182 return parent.regValues[param]
1177 maybeLocal = parent.resolveLocal(param) 1183 maybeLocal = parent.resolveLocal(param)
1178 if maybeLocal: 1184 if maybeLocal:
1185 if isdst:
1186 self.lastDst = param
1179 return maybeLocal 1187 return maybeLocal
1180 if param in fieldVals: 1188 if param in fieldVals:
1181 param = fieldVals[param] 1189 param = fieldVals[param]
1182 elif param in self.meta: 1190 elif param in self.meta:
1183 param = self.meta[param] 1191 param = self.meta[param]
1184 keepGoing = True 1192 keepGoing = True
1185 elif self.isReg(param): 1193 elif self.isReg(param):
1186 param = self.resolveReg(param, parent, fieldVals, isdst) 1194 return self.resolveReg(param, parent, fieldVals, isdst)
1195 if isdst:
1196 self.lastDst = param
1187 return param 1197 return param
1188 1198
1189 def isReg(self, name): 1199 def isReg(self, name):
1190 if not type(name) is str: 1200 if not type(name) is str:
1191 return False 1201 return False
1231 return ret 1241 return ret
1232 1242
1233 1243
1234 1244
1235 def paramSize(self, name): 1245 def paramSize(self, name):
1236 size = self.currentScope.localSize(name) 1246 if name in self.meta:
1237 if size: 1247 return self.paramSize(self.meta[name])
1238 return size 1248 for i in range(len(self.scopes) -1, -1, -1):
1249 size = self.scopes[i].localSize(name)
1250 if size:
1251 return size
1239 begin,sep,_ = name.partition('.') 1252 begin,sep,_ = name.partition('.')
1240 if sep and self.regs.isRegArray(begin): 1253 if sep and self.regs.isRegArray(begin):
1241 return self.regs.regArrays[begin][0] 1254 return self.regs.regArrays[begin][0]
1242 if self.regs.isReg(name): 1255 if self.regs.isReg(name):
1243 return self.regs.regs[name] 1256 return self.regs.regs[name]