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]))