comparison cpu_dsl.py @ 2577:5f725429d08f

WIP changes to new CPU core for rotate instructions and to get interrupts more functional
author Michael Pavone <pavone@retrodev.com>
date Fri, 07 Feb 2025 08:57:24 -0800
parents 595719fe69f2
children 9b01541cbd60
comparison
equal deleted inserted replaced
2576:c9bfed9156dc 2577:5f725429d08f
480 elif prog.dispatch == 'goto': 480 elif prog.dispatch == 'goto':
481 return '\n\tgoto *impl_{tbl}[{op}];'.format(tbl = table, op = params[0]) 481 return '\n\tgoto *impl_{tbl}[{op}];'.format(tbl = table, op = params[0])
482 else: 482 else:
483 raise Exception('Unsupported dispatch type ' + prog.dispatch) 483 raise Exception('Unsupported dispatch type ' + prog.dispatch)
484 484
485 def _addExplicitFlagSet(prog, output, flag, flagval):
486 location = prog.flags.getStorage(flag)
487 if type(location) is tuple:
488 reg,bit = location
489 reg = prog.resolveReg(reg, None, {})
490 value = str(1 << bit)
491 if flagval:
492 operator = '|='
493 else:
494 operator = '&='
495 value = '~' + value
496 output.append('\n\t{reg} {op} {val};'.format(reg=reg, op=operator, val=value))
497 else:
498 reg = prog.resolveReg(location, None, {})
499 output.append('\n\t{reg} = {val};'.format(reg=reg, val=flagval))
500
485 def _updateFlagsCImpl(prog, params, rawParams): 501 def _updateFlagsCImpl(prog, params, rawParams):
486 autoUpdate, explicit = prog.flags.parseFlagUpdate(params[0]) 502 autoUpdate, explicit = prog.flags.parseFlagUpdate(params[0])
487 output = [] 503 output = []
488 parity = None 504 parity = None
489 directFlags = {} 505 directFlags = {}
495 else: 511 else:
496 lastDst = prog.resolveParam(prog.lastDst, prog.currentScope, {}) 512 lastDst = prog.resolveParam(prog.lastDst, prog.currentScope, {})
497 storage = prog.flags.getStorage(flag) 513 storage = prog.flags.getStorage(flag)
498 if calc == 'bit' or calc == 'sign' or calc == 'carry' or calc == 'half' or calc == 'overflow': 514 if calc == 'bit' or calc == 'sign' or calc == 'carry' or calc == 'half' or calc == 'overflow':
499 myRes = lastDst 515 myRes = lastDst
516 after = ''
500 if calc == 'sign': 517 if calc == 'sign':
501 resultBit = prog.getLastSize() - 1 518 resultBit = prog.getLastSize() - 1
502 elif calc == 'carry': 519 elif calc == 'carry':
503 if prog.lastOp.op in ('asr', 'lsr'): 520 if prog.lastOp.op in ('asr', 'lsr', 'rrc'):
504 if type(prog.lastB) is int: 521 if type(prog.lastB) is int:
505 resultBit = prog.lastB - 1 522 if prog.lastB == 0:
523 explicit[flag] = 0
524 continue
525 else:
526 resultBit = prog.lastB - 1
506 else: 527 else:
528 output.append(f'\n\tif (!{prog.lastB}) {{')
529 _addExplicitFlagSet(prog, output, flag, 0)
530 output.append('\n\t} else {')
531 after = '\n\t}'
507 resultBit = f'({prog.lastB} - 1)' 532 resultBit = f'({prog.lastB} - 1)'
508 myRes = prog.lastA 533 myRes = prog.lastA
534 elif prog.lastOp.op == 'rlc':
535 if type(prog.lastB) is int:
536 if prog.lastB == 0:
537 explicit[flag] = 0
538 continue
539 else:
540 resultBit = prog.getLastSize() - prog.lastB
541 else:
542 output.append(f'\n\tif (!{prog.lastB}) {{')
543 _addExplicitFlagSet(prog, output, flag, 0)
544 output.append('\n\t} else {')
545 after = '\n\t}'
546 resultBit = f'({prog.getLastSize()} - {prog.lastB})'
547 myRes = prog.lastA
548 elif prog.lastOp.op == 'rol':
549 if type(prog.lastB) is int:
550 if prog.lastB == 0:
551 explicit[flag] = 0
552 continue
553 else:
554 output.append(f'\n\tif (!{prog.lastB}) {{')
555 _addExplicitFlagSet(prog, output, flag, 0)
556 output.append('\n\t} else {')
557 after = '\n\t}'
558 resultBit = 0
559 elif prog.lastOp.op == 'ror':
560 if type(prog.lastB) is int:
561 if prog.lastB == 0:
562 explicit[flag] = 0
563 continue
564 else:
565 output.append(f'\n\tif (!{prog.lastB}) {{')
566 _addExplicitFlagSet(prog, output, flag, 0)
567 output.append('\n\t} else {')
568 after = '\n\t}'
569 resultBit = prog.getLastSize() - 1
509 elif prog.lastOp.op == 'neg': 570 elif prog.lastOp.op == 'neg':
510 if prog.carryFlowDst: 571 if prog.carryFlowDst:
511 realSize = prog.getLastSize() 572 realSize = prog.getLastSize()
512 if realSize != prog.paramSize(prog.carryFlowDst): 573 if realSize != prog.paramSize(prog.carryFlowDst):
513 lastDst = '({res} & {mask})'.format(res=lastDst, mask = (1 << realSize) - 1) 574 lastDst = '({res} & {mask})'.format(res=lastDst, mask = (1 << realSize) - 1)
523 reg = reg, res = lastDst 584 reg = reg, res = lastDst
524 )) 585 ))
525 continue 586 continue
526 else: 587 else:
527 resultBit = prog.getLastSize() 588 resultBit = prog.getLastSize()
528 if prog.lastOp.op == 'ror':
529 resultBit -= 1
530 elif calc == 'half': 589 elif calc == 'half':
531 resultBit = prog.getLastSize() - 4 590 resultBit = prog.getLastSize() - 4
532 myRes = '({a} ^ {b} ^ {res})'.format(a = prog.lastA, b = prog.lastB, res = lastDst) 591 myRes = '({a} ^ {b} ^ {res})'.format(a = prog.lastA, b = prog.lastB, res = lastDst)
533 elif calc == 'overflow': 592 elif calc == 'overflow':
534 resultBit = prog.getLastSize() - 1 593 resultBit = prog.getLastSize() - 1
564 elif resultBit > maxBit: 623 elif resultBit > maxBit:
565 mask = f'{1 << maxBit}U' 624 mask = f'{1 << maxBit}U'
566 output.append('\n\t{reg} = {res} >> {shift} & {mask};'.format(reg=reg, res=myRes, shift = resultBit - maxBit, mask = mask)) 625 output.append('\n\t{reg} = {res} >> {shift} & {mask};'.format(reg=reg, res=myRes, shift = resultBit - maxBit, mask = mask))
567 else: 626 else:
568 output.append('\n\t{reg} = {res} & {mask};'.format(reg=reg, res=myRes, mask = mask)) 627 output.append('\n\t{reg} = {res} & {mask};'.format(reg=reg, res=myRes, mask = mask))
628 if after:
629 output.append(after)
569 elif calc == 'zero': 630 elif calc == 'zero':
570 if prog.carryFlowDst: 631 if prog.carryFlowDst:
571 realSize = prog.getLastSize() 632 realSize = prog.getLastSize()
572 if realSize != prog.paramSize(prog.carryFlowDst): 633 if realSize != prog.paramSize(prog.carryFlowDst):
573 lastDst = '({res} & {mask})'.format(res=lastDst, mask = (1 << realSize) - 1) 634 lastDst = '({res} & {mask})'.format(res=lastDst, mask = (1 << realSize) - 1)
634 reg = prog.resolveParam(parity, None, {}) 695 reg = prog.resolveParam(parity, None, {})
635 output.append('\n\t{flag} = 0x9669 >> {parity} & 1;'.format(flag=reg, parity=parityDst)) 696 output.append('\n\t{flag} = 0x9669 >> {parity} & 1;'.format(flag=reg, parity=parityDst))
636 697
637 #TODO: combine explicit flags targeting the same storage location 698 #TODO: combine explicit flags targeting the same storage location
638 for flag in explicit: 699 for flag in explicit:
639 location = prog.flags.getStorage(flag) 700 _addExplicitFlagSet(prog, output, flag, explicit[flag])
640 if type(location) is tuple:
641 reg,bit = location
642 reg = prog.resolveReg(reg, None, {})
643 value = str(1 << bit)
644 if explicit[flag]:
645 operator = '|='
646 else:
647 operator = '&='
648 value = '~' + value
649 output.append('\n\t{reg} {op} {val};'.format(reg=reg, op=operator, val=value))
650 else:
651 reg = prog.resolveReg(location, None, {})
652 output.append('\n\t{reg} = {val};'.format(reg=reg, val=explicit[flag]))
653 return ''.join(output) 701 return ''.join(output)
654 702
655 def _cmpCImpl(prog, params, rawParams, flagUpdates): 703 def _cmpCImpl(prog, params, rawParams, flagUpdates):
656 b_size = size = prog.paramSize(rawParams[1]) 704 b_size = size = prog.paramSize(rawParams[1])
657 needsCarry = False 705 needsCarry = False
927 for flag in flagUpdates: 975 for flag in flagUpdates:
928 calc = prog.flags.flagCalc[flag] 976 calc = prog.flags.flagCalc[flag]
929 if calc == 'carry': 977 if calc == 'carry':
930 needsCarry = True 978 needsCarry = True
931 decl = '' 979 decl = ''
932 size = prog.paramSize(rawParams[2]) 980 destSize = prog.paramSize(rawParams[2])
933 if needsCarry: 981 needsSizeAdjust = False
934 decl,name = prog.getTemp(size * 2) 982 if len(params) > 3:
983 size = params[3]
984 if size == 0:
985 size = 8
986 elif size == 1:
987 size = 16
988 else:
989 size = 32
990 prog.lastSize = size
991 if destSize > size:
992 needsSizeAdjust = True
993 if needsCarry:
994 prog.sizeAdjust = size
995 else:
996 size = destSize
997
998 prog.lastB = params[1]
999 if needsSizeAdjust:
1000 decl,name = prog.getTemp(size)
935 dst = prog.carryFlowDst = name 1001 dst = prog.carryFlowDst = name
936 else: 1002 else:
937 dst = params[2] 1003 dst = params[2]
938 return decl + '\n\t{dst} = {a} << {b} | {a} >> ({size} - {b});'.format(dst = dst, 1004 ret = decl + '\n\t{dst} = {a} << {b} | {a} >> ({size} - {b});'.format(dst = dst,
939 a = params[0], b = params[1], size=size 1005 a = params[0], b = params[1], size=size
940 ) 1006 )
1007 if needsSizeAdjust and not needsCarry:
1008 mask = (1 << size) - 1
1009 ret += f'\n\t{params[2]} = ({params[2]} & ~{mask}) | ({dst} & {mask});'
1010 return ret
941 1011
942 def _rlcCImpl(prog, params, rawParams, flagUpdates): 1012 def _rlcCImpl(prog, params, rawParams, flagUpdates):
943 needsCarry = False 1013 needsCarry = False
944 if flagUpdates: 1014 if flagUpdates:
945 for flag in flagUpdates: 1015 for flag in flagUpdates:
946 calc = prog.flags.flagCalc[flag] 1016 calc = prog.flags.flagCalc[flag]
947 if calc == 'carry': 1017 if calc == 'carry':
948 needsCarry = True 1018 needsCarry = True
949 decl = '' 1019 decl = ''
1020 destSize = prog.paramSize(rawParams[2])
1021 needsSizeAdjust = False
1022 if len(params) > 3:
1023 size = params[3]
1024 if size == 0:
1025 size = 8
1026 elif size == 1:
1027 size = 16
1028 else:
1029 size = 32
1030 prog.lastSize = size
1031 if destSize > size:
1032 needsSizeAdjust = True
1033 if needsCarry:
1034 prog.sizeAdjust = size
1035 else:
1036 size = destSize
950 carryCheck = _getCarryCheck(prog) 1037 carryCheck = _getCarryCheck(prog)
951 size = prog.paramSize(rawParams[2]) 1038 size = prog.paramSize(rawParams[2])
952 if needsCarry: 1039 if needsCarry or needsSizeAdjust:
953 decl,name = prog.getTemp(size * 2) 1040 decl,name = prog.getTemp(size)
954 dst = prog.carryFlowDst = name 1041 dst = prog.carryFlowDst = name
1042 prog.lastA = params[0]
1043 prog.lastB = params[1]
955 else: 1044 else:
956 dst = params[2] 1045 dst = params[2]
957 return decl + '\n\t{dst} = {a} << {b} | {a} >> ({size} + 1 - {b}) | ({check} ? 1 : 0) << ({b} - 1);'.format(dst = dst, 1046 if size == 32 and (not type(params[1]) is int) or params[1] <= 1:
958 a = params[0], b = params[1], size=size, check=carryCheck 1047 # we may need to shift by 32-bits which is too much for a normal int
1048 a = f'((uint64_t){params[0]})'
1049 else:
1050 a = params[0]
1051 ret = decl + '\n\t{dst} = {a} << {b} | {a} >> ({size} + 1 - {b}) | ({check} ? 1 : 0) << ({b} - 1);'.format(dst = dst,
1052 a = a, b = params[1], size=size, check=carryCheck
959 ) 1053 )
1054 if needsSizeAdjust and not needsCarry:
1055 mask = (1 << size) - 1
1056 ret += f'\n\t{params[2]} = ({params[2]} & ~{mask}) | ({dst} & {mask});'
1057 return ret
960 1058
961 def _rorCImpl(prog, params, rawParams, flagUpdates): 1059 def _rorCImpl(prog, params, rawParams, flagUpdates):
962 size = prog.paramSize(rawParams[2]) 1060 needsCarry = False
963 return '\n\t{dst} = {a} >> {b} | {a} << ({size} - {b});'.format(dst = params[2], 1061 if flagUpdates:
1062 for flag in flagUpdates:
1063 calc = prog.flags.flagCalc[flag]
1064 if calc == 'carry':
1065 needsCarry = True
1066 decl = ''
1067 destSize = prog.paramSize(rawParams[2])
1068 needsSizeAdjust = False
1069 if len(params) > 3:
1070 size = params[3]
1071 if size == 0:
1072 size = 8
1073 elif size == 1:
1074 size = 16
1075 else:
1076 size = 32
1077 prog.lastSize = size
1078 if destSize > size:
1079 needsSizeAdjust = True
1080 if needsCarry:
1081 prog.sizeAdjust = size
1082 else:
1083 size = destSize
1084 prog.lastB = params[1]
1085 if needsSizeAdjust:
1086 decl,name = prog.getTemp(size)
1087 dst = prog.carryFlowDst = name
1088 else:
1089 dst = params[2]
1090 ret = decl + '\n\t{dst} = {a} >> {b} | {a} << ({size} - {b});'.format(dst = dst,
964 a = params[0], b = params[1], size=size 1091 a = params[0], b = params[1], size=size
965 ) 1092 )
1093 if needsSizeAdjust and not needsCarry:
1094 mask = (1 << size) - 1
1095 ret += f'\n\t{params[2]} = ({params[2]} & ~{mask}) | ({dst} & {mask});'
1096 return ret
966 1097
967 def _rrcCImpl(prog, params, rawParams, flagUpdates): 1098 def _rrcCImpl(prog, params, rawParams, flagUpdates):
968 needsCarry = False 1099 needsCarry = False
969 if flagUpdates: 1100 if flagUpdates:
970 for flag in flagUpdates: 1101 for flag in flagUpdates:
971 calc = prog.flags.flagCalc[flag] 1102 calc = prog.flags.flagCalc[flag]
972 if calc == 'carry': 1103 if calc == 'carry':
973 needsCarry = True 1104 needsCarry = True
974 decl = '' 1105 decl = ''
1106 destSize = prog.paramSize(rawParams[2])
1107 needsSizeAdjust = False
1108 if len(params) > 3:
1109 size = params[3]
1110 if size == 0:
1111 size = 8
1112 elif size == 1:
1113 size = 16
1114 else:
1115 size = 32
1116 prog.lastSize = size
1117 if destSize > size:
1118 needsSizeAdjust = True
1119 if needsCarry:
1120 prog.sizeAdjust = size
1121 else:
1122 size = destSize
975 carryCheck = _getCarryCheck(prog) 1123 carryCheck = _getCarryCheck(prog)
976 size = prog.paramSize(rawParams[2]) 1124 size = prog.paramSize(rawParams[2])
977 if needsCarry: 1125 if needsCarry or needsSizeAdjust:
978 decl,name = prog.getTemp(size * 2) 1126 decl,name = prog.getTemp(size)
979 dst = prog.carryFlowDst = name 1127 dst = prog.carryFlowDst = name
1128 prog.lastA = params[0]
1129 prog.lastB = params[1]
980 else: 1130 else:
981 dst = params[2] 1131 dst = params[2]
982 return decl + '\n\t{dst} = {a} >> {b} | {a} << ({size} + 1 - {b}) | ({check} ? 1 : 0) << ({size}-{b});'.format(dst = dst, 1132 if size == 32 and (not type(params[1]) is int) or params[1] <= 1:
983 a = params[0], b = params[1], size=size, check=carryCheck 1133 # we may need to shift by 32-bits which is too much for a normal int
1134 a = f'((uint64_t){params[0]})'
1135 else:
1136 a = params[0]
1137 ret = decl + '\n\t{dst} = {a} >> {b} | {a} << ({size} + 1 - {b}) | ({check} ? 1 : 0) << ({size}-{b});'.format(dst = dst,
1138 a = a, b = params[1], size=size, check=carryCheck
984 ) 1139 )
1140 if needsSizeAdjust and not needsCarry:
1141 mask = (1 << size) - 1
1142 ret += f'\n\t{params[2]} = ({params[2]} & ~{mask}) | ({dst} & {mask});'
1143 return ret
985 1144
986 def _updateSyncCImpl(prog, params): 1145 def _updateSyncCImpl(prog, params):
987 return '\n\t{sync}(context, target_cycle);'.format(sync=prog.sync_cycle) 1146 return '\n\t{sync}(context, target_cycle);'.format(sync=prog.sync_cycle)
988 1147
989 _opMap = { 1148 _opMap = {
1681 macro = header.upper().replace('.', '_') 1840 macro = header.upper().replace('.', '_')
1682 hFile.write('#ifndef {0}_'.format(macro)) 1841 hFile.write('#ifndef {0}_'.format(macro))
1683 hFile.write('\n#define {0}_'.format(macro)) 1842 hFile.write('\n#define {0}_'.format(macro))
1684 hFile.write('\n#include <stdio.h>') 1843 hFile.write('\n#include <stdio.h>')
1685 hFile.write('\n#include "backend.h"') 1844 hFile.write('\n#include "backend.h"')
1686 hFile.write('\n\ntypedef struct {') 1845 hFile.write(f'\n\ntypedef struct {self.prefix}options {self.prefix}options;')
1687 hFile.write('\n\tcpu_options gen;') 1846 hFile.write(f'\n\ntypedef struct {self.prefix}context {self.prefix}context;')
1688 hFile.write('\n\tFILE* address_log;')
1689 hFile.write('\n}} {0}options;'.format(self.prefix))
1690 hFile.write('\n\ntypedef struct {')
1691 hFile.write('\n\t{0}options *opts;'.format(self.prefix))
1692 self.regs.writeHeader(otype, hFile)
1693 hFile.write('\n}} {0}context;'.format(self.prefix))
1694 hFile.write('\n')
1695 hFile.write('\nvoid {pre}execute({type} *context, uint32_t target_cycle);'.format(pre = self.prefix, type = self.context_type))
1696 for decl in self.declares: 1847 for decl in self.declares:
1697 if decl.startswith('define '): 1848 if decl.startswith('define '):
1698 decl = '#' + decl 1849 decl = '#' + decl
1699 hFile.write('\n' + decl) 1850 hFile.write('\n' + decl)
1851 hFile.write(f'\n\nstruct {self.prefix}options {{')
1852 hFile.write('\n\tcpu_options gen;')
1853 hFile.write('\n\tFILE* address_log;')
1854 hFile.write('\n};')
1855 hFile.write(f'\n\nstruct {self.prefix}context {{')
1856 hFile.write(f'\n\t{self.prefix}options *opts;')
1857 self.regs.writeHeader(otype, hFile)
1858 hFile.write('\n};')
1859 hFile.write('\n')
1860 hFile.write('\nvoid {pre}execute({type} *context, uint32_t target_cycle);'.format(pre = self.prefix, type = self.context_type))
1700 hFile.write('\n#endif //{0}_'.format(macro)) 1861 hFile.write('\n#endif //{0}_'.format(macro))
1701 hFile.write('\n') 1862 hFile.write('\n')
1702 hFile.close() 1863 hFile.close()
1703 1864
1704 def _buildTable(self, otype, table, body, lateBody): 1865 def _buildTable(self, otype, table, body, lateBody):