Mercurial > repos > blastem
comparison cpu_dsl.py @ 1721:0e5df2bc0f9f
Implementation of some of the rotate instructions in new Z80 core
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 31 Jan 2019 22:41:37 -0800 |
parents | fb5ae8c20b85 |
children | ac809d044cab |
comparison
equal
deleted
inserted
replaced
1720:1648c685083a | 1721:0e5df2bc0f9f |
---|---|
155 self.implementation = [] | 155 self.implementation = [] |
156 self.args = [] | 156 self.args = [] |
157 self.arg_map = {} | 157 self.arg_map = {} |
158 self.locals = {} | 158 self.locals = {} |
159 self.regValues = {} | 159 self.regValues = {} |
160 self.argValues = {} | |
160 | 161 |
161 def addOp(self, op): | 162 def addOp(self, op): |
162 if op.op == 'arg': | 163 if op.op == 'arg': |
163 name = op.params[0] | 164 name = op.params[0] |
164 size = op.params[1] | 165 size = int(op.params[1]) |
165 self.arg_map[name] = len(self.args) | 166 self.arg_map[name] = len(self.args) |
166 self.args.append((name, size)) | 167 self.args.append((name, size)) |
167 elif op.op == 'local': | 168 elif op.op == 'local': |
168 name = op.params[0] | 169 name = op.params[0] |
169 size = op.params[1] | 170 size = op.params[1] |
178 | 179 |
179 def addLocal(self, name, size): | 180 def addLocal(self, name, size): |
180 self.locals[name] = size | 181 self.locals[name] = size |
181 | 182 |
182 def localSize(self, name): | 183 def localSize(self, name): |
183 return self.locals.get(name) | 184 if name in self.locals: |
185 return self.locals[name] | |
186 if name in self.arg_map: | |
187 argIndex = self.arg_map[name] | |
188 return self.args[argIndex][1] | |
189 return None | |
184 | 190 |
185 def inline(self, prog, params, output, otype, parent): | 191 def inline(self, prog, params, output, otype, parent): |
186 if len(params) != len(self.args): | 192 if len(params) != len(self.args): |
187 raise Exception('{0} expects {1} arguments, but was called with {2}'.format(self.name, len(self.args), len(params))) | 193 raise Exception('{0} expects {1} arguments, but was called with {2}'.format(self.name, len(self.args), len(params))) |
188 argValues = {} | 194 argValues = {} |
194 argValues[name] = params[i] | 200 argValues[name] = params[i] |
195 i += 1 | 201 i += 1 |
196 for name in self.locals: | 202 for name in self.locals: |
197 size = self.locals[name] | 203 size = self.locals[name] |
198 output.append('\n\tuint{size}_t {sub}_{local};'.format(size=size, sub=self.name, local=name)) | 204 output.append('\n\tuint{size}_t {sub}_{local};'.format(size=size, sub=self.name, local=name)) |
205 self.argValues = argValues | |
199 self.processOps(prog, argValues, output, otype, self.implementation) | 206 self.processOps(prog, argValues, output, otype, self.implementation) |
200 prog.popScope() | 207 prog.popScope() |
201 | 208 |
202 def __str__(self): | 209 def __str__(self): |
203 pieces = [self.name] | 210 pieces = [self.name] |
353 if resultBit > maxBit: | 360 if resultBit > maxBit: |
354 output.append('\n\t{reg} = {res} >> {shift} & {mask}U;'.format(reg=reg, res=myRes, shift = resultBit - maxBit, mask = 1 << maxBit)) | 361 output.append('\n\t{reg} = {res} >> {shift} & {mask}U;'.format(reg=reg, res=myRes, shift = resultBit - maxBit, mask = 1 << maxBit)) |
355 else: | 362 else: |
356 output.append('\n\t{reg} = {res} & {mask}U;'.format(reg=reg, res=myRes, mask = 1 << resultBit)) | 363 output.append('\n\t{reg} = {res} & {mask}U;'.format(reg=reg, res=myRes, mask = 1 << resultBit)) |
357 elif calc == 'zero': | 364 elif calc == 'zero': |
365 if prog.carryFlowDst: | |
366 realSize = prog.paramSize(prog.lastDst) | |
367 if realSize != prog.paramSize(prog.carryFlowDst): | |
368 lastDst = '({res} & {mask})'.format(res=lastDst, mask = (1 << realSize) - 1) | |
358 if type(storage) is tuple: | 369 if type(storage) is tuple: |
359 reg,storageBit = storage | 370 reg,storageBit = storage |
360 reg = prog.resolveParam(reg, None, {}) | 371 reg = prog.resolveParam(reg, None, {}) |
361 output.append('\n\t{reg} = {res} ? ({reg} & {mask}U) : ({reg} | {bit}U);'.format( | 372 output.append('\n\t{reg} = {res} ? ({reg} & {mask}U) : ({reg} | {bit}U);'.format( |
362 reg = reg, mask = ~(1 << storageBit), res = lastDst, bit = 1 << storageBit | 373 reg = reg, mask = ~(1 << storageBit), res = lastDst, bit = 1 << storageBit |
526 else: | 537 else: |
527 dst = params[2] | 538 dst = params[2] |
528 return decl + '\n\t{dst} = {b} - {a} - ({check} ? 1 : 0);'.format(dst = dst, | 539 return decl + '\n\t{dst} = {b} - {a} - ({check} ? 1 : 0);'.format(dst = dst, |
529 a = params[0], b = params[1], check=_getCarryCheck(prog) | 540 a = params[0], b = params[1], check=_getCarryCheck(prog) |
530 ) | 541 ) |
542 | |
543 def _rolCImpl(prog, params, rawParams, flagUpdates): | |
544 needsCarry = False | |
545 if flagUpdates: | |
546 for flag in flagUpdates: | |
547 calc = prog.flags.flagCalc[flag] | |
548 if calc == 'carry': | |
549 needsCarry = True | |
550 decl = '' | |
551 size = prog.paramSize(rawParams[2]) | |
552 if needsCarry: | |
553 decl,name = prog.getTemp(size * 2) | |
554 dst = prog.carryFlowDst = name | |
555 else: | |
556 dst = params[2] | |
557 return decl + '\n\t{dst} = {a} << {b} | {a} >> ({size} - {b});'.format(dst = dst, | |
558 a = params[0], b = params[1], size=size | |
559 ) | |
560 | |
561 def _rlcCImpl(prog, params, rawParams, flagUpdates): | |
562 needsCarry = False | |
563 if flagUpdates: | |
564 for flag in flagUpdates: | |
565 calc = prog.flags.flagCalc[flag] | |
566 if calc == 'carry': | |
567 needsCarry = True | |
568 decl = '' | |
569 carryCheck = _getCarryCheck(prog) | |
570 size = prog.paramSize(rawParams[2]) | |
571 if needsCarry: | |
572 decl,name = prog.getTemp(size * 2) | |
573 dst = prog.carryFlowDst = name | |
574 else: | |
575 dst = params[2] | |
576 return decl + '\n\t{dst} = {a} << {b} | {a} >> ({size} + 1 - {b}) | ({check} ? 1 : 0) << ({b} - 1);'.format(dst = dst, | |
577 a = params[0], b = params[1], size=size, check=carryCheck | |
578 ) | |
579 | |
580 def _rorCImpl(prog, params, rawParams, flagUpdates): | |
581 needsCarry = False | |
582 if flagUpdates: | |
583 for flag in flagUpdates: | |
584 calc = prog.flags.flagCalc[flag] | |
585 if calc == 'carry': | |
586 needsCarry = True | |
587 decl = '' | |
588 size = prog.paramSize(rawParams[2]) | |
589 if needsCarry: | |
590 decl,name = prog.getTemp(size) | |
591 dst = prog.carryFlowDst = name | |
592 else: | |
593 dst = params[2] | |
594 return decl + '\n\t{dst} = {a} >> {b} | {a} << ({size} - {b});'.format(dst = dst, | |
595 a = params[0], b = params[1], size=size | |
596 ) | |
597 | |
598 def _rrcCImpl(prog, params, rawParams, flagUpdates): | |
599 needsCarry = False | |
600 if flagUpdates: | |
601 for flag in flagUpdates: | |
602 calc = prog.flags.flagCalc[flag] | |
603 if calc == 'carry': | |
604 needsCarry = True | |
605 decl = '' | |
606 carryCheck = _getCarryCheck(prog) | |
607 size = prog.paramSize(rawParams[2]) | |
608 if needsCarry: | |
609 decl,name = prog.getTemp(size * 2) | |
610 dst = prog.carryFlowDst = name | |
611 else: | |
612 dst = params[2] | |
613 return decl + '\n\t{dst} = {a} >> {b} | {a} << ({size} + 1 - {b}) | ({check} ? 1 : 0) << ({size}-{b});'.format(dst = dst, | |
614 a = params[0], b = params[1], size=size, check=carryCheck | |
615 ) | |
531 | 616 |
532 _opMap = { | 617 _opMap = { |
533 'mov': Op(lambda val: val).cUnaryOperator(''), | 618 'mov': Op(lambda val: val).cUnaryOperator(''), |
534 'not': Op(lambda val: ~val).cUnaryOperator('~'), | 619 'not': Op(lambda val: ~val).cUnaryOperator('~'), |
535 'lnot': Op(lambda val: 0 if val else 1).cUnaryOperator('!'), | 620 'lnot': Op(lambda val: 0 if val else 1).cUnaryOperator('!'), |
539 'sub': Op(lambda a, b: b - a).cBinaryOperator('-'), | 624 'sub': Op(lambda a, b: b - a).cBinaryOperator('-'), |
540 'sbc': Op().addImplementation('c', 2, _sbcCImpl), | 625 'sbc': Op().addImplementation('c', 2, _sbcCImpl), |
541 'lsl': Op(lambda a, b: a << b).cBinaryOperator('<<'), | 626 'lsl': Op(lambda a, b: a << b).cBinaryOperator('<<'), |
542 'lsr': Op(lambda a, b: a >> b).cBinaryOperator('>>'), | 627 'lsr': Op(lambda a, b: a >> b).cBinaryOperator('>>'), |
543 'asr': Op(lambda a, b: a >> b).addImplementation('c', 2, _asrCImpl), | 628 'asr': Op(lambda a, b: a >> b).addImplementation('c', 2, _asrCImpl), |
629 'rol': Op().addImplementation('c', 2, _rolCImpl), | |
630 'rlc': Op().addImplementation('c', 2, _rlcCImpl), | |
631 'ror': Op().addImplementation('c', 2, _rorCImpl), | |
632 'rrc': Op().addImplementation('c', 2, _rrcCImpl), | |
544 'and': Op(lambda a, b: a & b).cBinaryOperator('&'), | 633 'and': Op(lambda a, b: a & b).cBinaryOperator('&'), |
545 'or': Op(lambda a, b: a | b).cBinaryOperator('|'), | 634 'or': Op(lambda a, b: a | b).cBinaryOperator('|'), |
546 'xor': Op(lambda a, b: a ^ b).cBinaryOperator('^'), | 635 'xor': Op(lambda a, b: a ^ b).cBinaryOperator('^'), |
547 'abs': Op(lambda val: abs(val)).addImplementation( | 636 'abs': Op(lambda val: abs(val)).addImplementation( |
548 'c', 1, lambda prog, params: '\n\t{dst} = abs({src});'.format(dst=params[1], src=params[0]) | 637 'c', 1, lambda prog, params: '\n\t{dst} = abs({src});'.format(dst=params[1], src=params[0]) |
626 shortParams = (self.params[0], self.params[-1]) | 715 shortParams = (self.params[0], self.params[-1]) |
627 output.append(_opMap['mov'].generate(otype, prog, shortProc, shortParams, None)) | 716 output.append(_opMap['mov'].generate(otype, prog, shortProc, shortParams, None)) |
628 else: | 717 else: |
629 output.append(opDef.generate(otype, prog, procParams, self.params, flagUpdates)) | 718 output.append(opDef.generate(otype, prog, procParams, self.params, flagUpdates)) |
630 elif self.op in prog.subroutines: | 719 elif self.op in prog.subroutines: |
720 procParams = [] | |
721 for param in self.params: | |
722 begin,sep,end = param.partition('.') | |
723 if sep: | |
724 if end in fieldVals: | |
725 param = begin + '.' + str(fieldVals[end]) | |
726 else: | |
727 if param in fieldVals: | |
728 param = fieldVals[param] | |
729 procParams.append(param) | |
631 prog.subroutines[self.op].inline(prog, procParams, output, otype, parent) | 730 prog.subroutines[self.op].inline(prog, procParams, output, otype, parent) |
632 else: | 731 else: |
633 output.append('\n\t' + self.op + '(' + ', '.join([str(p) for p in procParams]) + ');') | 732 output.append('\n\t' + self.op + '(' + ', '.join([str(p) for p in procParams]) + ');') |
634 prog.lastOp = self | 733 prog.lastOp = self |
635 | 734 |
1208 if isdst: | 1307 if isdst: |
1209 self.lastDst = param | 1308 self.lastDst = param |
1210 return maybeLocal | 1309 return maybeLocal |
1211 if param in fieldVals: | 1310 if param in fieldVals: |
1212 param = fieldVals[param] | 1311 param = fieldVals[param] |
1312 fieldVals = {} | |
1313 keepGoing = True | |
1213 elif param in self.meta: | 1314 elif param in self.meta: |
1214 param = self.meta[param] | 1315 param = self.meta[param] |
1215 keepGoing = True | 1316 keepGoing = True |
1216 elif self.isReg(param): | 1317 elif self.isReg(param): |
1217 return self.resolveReg(param, parent, fieldVals, isdst) | 1318 return self.resolveReg(param, parent, fieldVals, isdst) |