Mercurial > repos > blastem
comparison cpu_dsl.py @ 1737:2207cd2bae14
Fixed some issues involving conditional execution and temporaries/constant folding
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 04 Feb 2019 21:43:43 -0800 |
parents | ca2336469397 |
children | 28ab56ff8cea |
comparison
equal
deleted
inserted
replaced
1736:06c2438c7641 | 1737:2207cd2bae14 |
---|---|
696 self.op = parts[0] | 696 self.op = parts[0] |
697 self.params = parts[1:] | 697 self.params = parts[1:] |
698 | 698 |
699 def generate(self, prog, parent, fieldVals, output, otype, flagUpdates): | 699 def generate(self, prog, parent, fieldVals, output, otype, flagUpdates): |
700 procParams = [] | 700 procParams = [] |
701 allParamsConst = flagUpdates is None | 701 allParamsConst = flagUpdates is None and not prog.conditional |
702 opDef = _opMap.get(self.op) | 702 opDef = _opMap.get(self.op) |
703 for param in self.params: | 703 for param in self.params: |
704 allowConst = (self.op in prog.subroutines or len(procParams) != len(self.params) - 1) and param in parent.regValues | 704 allowConst = (self.op in prog.subroutines or len(procParams) != len(self.params) - 1) and param in parent.regValues |
705 isDst = (not opDef is None) and len(procParams) in opDef.outOp | 705 isDst = (not opDef is None) and len(procParams) in opDef.outOp |
706 param = prog.resolveParam(param, parent, fieldVals, allowConst, isDst) | 706 param = prog.resolveParam(param, parent, fieldVals, allowConst, isDst) |
833 for local in self.default_locals: | 833 for local in self.default_locals: |
834 output.append('\n\tuint{0}_t {1};'.format(self.default[local], local)) | 834 output.append('\n\tuint{0}_t {1};'.format(self.default[local], local)) |
835 self.processOps(prog, fieldVals, output, otype, self.default) | 835 self.processOps(prog, fieldVals, output, otype, self.default) |
836 output.append('\n\t}') | 836 output.append('\n\t}') |
837 else: | 837 else: |
838 oldCond = prog.conditional | |
839 prog.conditional = True | |
838 output.append('\n\tswitch(' + param + ')') | 840 output.append('\n\tswitch(' + param + ')') |
839 output.append('\n\t{') | 841 output.append('\n\t{') |
840 for case in self.cases: | 842 for case in self.cases: |
843 temp = prog.temp.copy() | |
841 self.current_locals = self.case_locals[case] | 844 self.current_locals = self.case_locals[case] |
842 self.regValues = dict(self.parent.regValues) | 845 self.regValues = dict(self.parent.regValues) |
843 output.append('\n\tcase {0}U: '.format(case) + '{') | 846 output.append('\n\tcase {0}U: '.format(case) + '{') |
844 for local in self.case_locals[case]: | 847 for local in self.case_locals[case]: |
845 output.append('\n\tuint{0}_t {1};'.format(self.case_locals[case][local], local)) | 848 output.append('\n\tuint{0}_t {1};'.format(self.case_locals[case][local], local)) |
846 self.processOps(prog, fieldVals, output, otype, self.cases[case]) | 849 self.processOps(prog, fieldVals, output, otype, self.cases[case]) |
847 output.append('\n\tbreak;') | 850 output.append('\n\tbreak;') |
848 output.append('\n\t}') | 851 output.append('\n\t}') |
852 prog.temp = temp | |
849 if self.default: | 853 if self.default: |
854 temp = prog.temp.copy() | |
850 self.current_locals = self.default_locals | 855 self.current_locals = self.default_locals |
851 self.regValues = dict(self.parent.regValues) | 856 self.regValues = dict(self.parent.regValues) |
852 output.append('\n\tdefault: {') | 857 output.append('\n\tdefault: {') |
853 for local in self.default_locals: | 858 for local in self.default_locals: |
854 output.append('\n\tuint{0}_t {1};'.format(self.default_locals[local], local)) | 859 output.append('\n\tuint{0}_t {1};'.format(self.default_locals[local], local)) |
855 self.processOps(prog, fieldVals, output, otype, self.default) | 860 self.processOps(prog, fieldVals, output, otype, self.default) |
861 prog.temp = temp | |
856 output.append('\n\t}') | 862 output.append('\n\t}') |
863 prog.conditional = oldCond | |
857 prog.popScope() | 864 prog.popScope() |
858 | 865 |
859 def __str__(self): | 866 def __str__(self): |
860 keys = self.cases.keys() | 867 keys = self.cases.keys() |
861 keys.sort() | 868 keys.sort() |
906 if op.op in ('case', 'arg'): | 913 if op.op in ('case', 'arg'): |
907 raise Exception(self.op + ' is not allows inside an if block') | 914 raise Exception(self.op + ' is not allows inside an if block') |
908 if op.op == 'local': | 915 if op.op == 'local': |
909 name = op.params[0] | 916 name = op.params[0] |
910 size = op.params[1] | 917 size = op.params[1] |
911 self.locals[name] = size | 918 self.curLocals[name] = size |
912 elif op.op == 'else': | 919 elif op.op == 'else': |
913 self.curLocals = self.elseLocals | 920 self.curLocals = self.elseLocals |
914 self.curBody = self.elseBody | 921 self.curBody = self.elseBody |
915 else: | 922 else: |
916 self.curBody.append(op) | 923 self.curBody.append(op) |
917 | 924 |
918 def localSize(self, name): | 925 def localSize(self, name): |
919 return self.curLocals.get(name) | 926 return self.curLocals.get(name) |
920 | 927 |
921 def resolveLocal(self, name): | 928 def resolveLocal(self, name): |
922 if name in self.locals: | 929 if name in self.curLocals: |
923 return name | 930 return name |
924 return self.parent.resolveLocal(name) | 931 return self.parent.resolveLocal(name) |
925 | 932 |
926 def _genTrueBody(self, prog, fieldVals, output, otype): | 933 def _genTrueBody(self, prog, fieldVals, output, otype): |
927 self.curLocals = self.locals | 934 self.curLocals = self.locals |
935 subOut = [] | |
936 self.processOps(prog, fieldVals, subOut, otype, self.body) | |
928 for local in self.locals: | 937 for local in self.locals: |
929 output.append('\n\tuint{sz}_t {nm};'.format(sz=self.locals[local], nm=local)) | 938 output.append('\n\tuint{sz}_t {nm};'.format(sz=self.locals[local], nm=local)) |
930 self.processOps(prog, fieldVals, output, otype, self.body) | 939 output += subOut |
931 | 940 |
932 def _genFalseBody(self, prog, fieldVals, output, otype): | 941 def _genFalseBody(self, prog, fieldVals, output, otype): |
933 self.curLocals = self.elseLocals | 942 self.curLocals = self.elseLocals |
943 subOut = [] | |
944 self.processOps(prog, fieldVals, subOut, otype, self.elseBody) | |
934 for local in self.elseLocals: | 945 for local in self.elseLocals: |
935 output.append('\n\tuint{sz}_t {nm};'.format(sz=self.elseLocals[local], nm=local)) | 946 output.append('\n\tuint{sz}_t {nm};'.format(sz=self.elseLocals[local], nm=local)) |
936 self.processOps(prog, fieldVals, output, otype, self.elsebody) | 947 output += subOut |
937 | 948 |
938 def _genConstParam(self, param, prog, fieldVals, output, otype): | 949 def _genConstParam(self, param, prog, fieldVals, output, otype): |
939 if param: | 950 if param: |
940 self._genTrueBody(prog, fieldVals, output, otype) | 951 self._genTrueBody(prog, fieldVals, output, otype) |
941 else: | 952 else: |
945 self.regValues = parent.regValues | 956 self.regValues = parent.regValues |
946 try: | 957 try: |
947 self._genConstParam(prog.checkBool(self.cond), prog, fieldVals, output, otype) | 958 self._genConstParam(prog.checkBool(self.cond), prog, fieldVals, output, otype) |
948 except Exception: | 959 except Exception: |
949 if self.cond in _ifCmpImpl[otype]: | 960 if self.cond in _ifCmpImpl[otype]: |
961 oldCond = prog.conditional | |
962 prog.conditional = True | |
963 temp = prog.temp.copy() | |
950 output.append(_ifCmpImpl[otype][self.cond](prog, parent, fieldVals, output)) | 964 output.append(_ifCmpImpl[otype][self.cond](prog, parent, fieldVals, output)) |
951 self._genTrueBody(prog, fieldVals, output, otype) | 965 self._genTrueBody(prog, fieldVals, output, otype) |
966 prog.temp = temp | |
952 if self.elseBody: | 967 if self.elseBody: |
968 temp = prog.temp.copy() | |
953 output.append('\n\t} else {') | 969 output.append('\n\t} else {') |
954 self._genFalseBody(prog, fieldVals, output, otype) | 970 self._genFalseBody(prog, fieldVals, output, otype) |
971 prog.temp = temp | |
955 output.append('\n\t}') | 972 output.append('\n\t}') |
973 prog.conditional = oldCond | |
956 else: | 974 else: |
957 cond = prog.resolveParam(self.cond, parent, fieldVals) | 975 cond = prog.resolveParam(self.cond, parent, fieldVals) |
958 if type(cond) is int: | 976 if type(cond) is int: |
959 self._genConstParam(cond, prog, fieldVals, output, otype) | 977 self._genConstParam(cond, prog, fieldVals, output, otype) |
960 else: | 978 else: |
979 temp = prog.temp.copy() | |
961 output.append('\n\tif ({cond}) '.format(cond=cond) + '{') | 980 output.append('\n\tif ({cond}) '.format(cond=cond) + '{') |
981 oldCond = prog.conditional | |
982 prog.conditional = True | |
962 self._genTrueBody(prog, fieldVals, output, otype) | 983 self._genTrueBody(prog, fieldVals, output, otype) |
984 prog.temp = temp | |
963 if self.elseBody: | 985 if self.elseBody: |
986 temp = prog.temp.copy() | |
964 output.append('\n\t} else {') | 987 output.append('\n\t} else {') |
965 self._genFalseBody(prog, fieldVals, output, otype) | 988 self._genFalseBody(prog, fieldVals, output, otype) |
989 prog.temp = temp | |
966 output.append('\n\t}') | 990 output.append('\n\t}') |
991 prog.conditional = oldCond | |
967 | 992 |
968 | 993 |
969 def __str__(self): | 994 def __str__(self): |
970 lines = ['\n\tif'] | 995 lines = ['\n\tif'] |
971 for op in self.body: | 996 for op in self.body: |
1239 self.lastOp = None | 1264 self.lastOp = None |
1240 self.carryFlowDst = None | 1265 self.carryFlowDst = None |
1241 self.lastA = None | 1266 self.lastA = None |
1242 self.lastB = None | 1267 self.lastB = None |
1243 self.lastBFlow = None | 1268 self.lastBFlow = None |
1269 self.conditional = False | |
1244 | 1270 |
1245 def __str__(self): | 1271 def __str__(self): |
1246 pieces = [] | 1272 pieces = [] |
1247 for reg in self.regs: | 1273 for reg in self.regs: |
1248 pieces.append(str(self.regs[reg])) | 1274 pieces.append(str(self.regs[reg])) |