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