Showing
2 changed files
with
53 additions
and
4 deletions
... | @@ -272,10 +272,10 @@ class x86Registers: | ... | @@ -272,10 +272,10 @@ class x86Registers: |
272 | 272 | ||
273 | if type == None: | 273 | if type == None: |
274 | type = self.default_type | 274 | type = self.default_type |
275 | - self.type_stack.append(type) | ||
276 | if valid_regs == None: | 275 | if valid_regs == None: |
277 | valid_regs = self._get_type_valid_regs(type) | 276 | valid_regs = self._get_type_valid_regs(type) |
278 | reg = self._get_free_reg(valid_regs, preferred_reg) | 277 | reg = self._get_free_reg(valid_regs, preferred_reg) |
278 | + self.type_stack.append(type) | ||
279 | self.stack.append(reg) | 279 | self.stack.append(reg) |
280 | return reg | 280 | return reg |
281 | 281 | ||
... | @@ -313,7 +313,8 @@ class x86Registers: | ... | @@ -313,7 +313,8 @@ class x86Registers: |
313 | reg = self._pop(valid_regs) | 313 | reg = self._pop(valid_regs) |
314 | return self._coerce_type(reg, prev_type, type) | 314 | return self._coerce_type(reg, prev_type, type) |
315 | else: | 315 | else: |
316 | - return self._pop(self.all_regs) | 316 | + reg = self._pop(self.all_regs) |
317 | + return reg | ||
317 | 318 | ||
318 | def _pop(self, valid_regs): | 319 | def _pop(self, valid_regs): |
319 | """Pops the top element of the stack into a free register | 320 | """Pops the top element of the stack into a free register |
... | @@ -437,8 +438,8 @@ class CodeGenVisitor(Visitor): | ... | @@ -437,8 +438,8 @@ class CodeGenVisitor(Visitor): |
437 | '+' : 'add', | 438 | '+' : 'add', |
438 | '-' : 'sub', | 439 | '-' : 'sub', |
439 | '*' : 'imul', | 440 | '*' : 'imul', |
440 | - '=' : 'mov' | 441 | + '=' : 'mov', |
441 | - } | 442 | + } |
442 | 443 | ||
443 | # Windows' C linkage prepends a '_' before symbol | 444 | # Windows' C linkage prepends a '_' before symbol |
444 | # names, whereas Unix doesn't. This is particularly | 445 | # names, whereas Unix doesn't. This is particularly |
... | @@ -1048,6 +1049,49 @@ class CodeGenVisitor(Visitor): | ... | @@ -1048,6 +1049,49 @@ class CodeGenVisitor(Visitor): |
1048 | if new_reg != left_reg: | 1049 | if new_reg != left_reg: |
1049 | raise Exception("PANIC! Binop push() isn't same as last pop()!") | 1050 | raise Exception("PANIC! Binop push() isn't same as last pop()!") |
1050 | 1051 | ||
1052 | + def _binop_divmod(self, node): | ||
1053 | + """Performs a division/modulo operation on the given Binop node.""" | ||
1054 | + | ||
1055 | + if node.op == "/" : | ||
1056 | + result_reg = self.stack.push(node.type, preferred_reg="%eax") | ||
1057 | + else : | ||
1058 | + result_reg = self.stack.push(node.type, preferred_reg="%edx") | ||
1059 | + | ||
1060 | + node.left.accept(self) | ||
1061 | + right_reg = self._accept_and_pop(node.right) | ||
1062 | + left_reg = self.stack.pop(node.left.coerce_to_type) | ||
1063 | + | ||
1064 | + type_str = node.type.get_outer_string() | ||
1065 | + | ||
1066 | + if type_str == 'char': | ||
1067 | + divisor_reg = self.stack.lo(right_reg) | ||
1068 | + dividend_reg = self.stack.lo("%eax") | ||
1069 | + remainder_reg = self.stack.lo("%edx") | ||
1070 | + self.o(" mov $0, %s" % result_reg, "Reset result reg") | ||
1071 | + result_reg = self.stack.lo(result_reg) | ||
1072 | + else: | ||
1073 | + divisor_reg = right_reg | ||
1074 | + dividend_reg = "%eax" | ||
1075 | + remainder_reg = "%edx" | ||
1076 | + | ||
1077 | + if result_reg != "%eax" : | ||
1078 | + self.o(" pushl %eax", "Save %eax used as dividend") | ||
1079 | + if result_reg != "%edx" : | ||
1080 | + self.o(" pushl %edx", "Save %edx used as remainder") | ||
1081 | + if left_reg != dividend_reg : | ||
1082 | + self.o(" mov %s, %s" % (left_reg, dividend_reg), "Copy dividend to %eax") | ||
1083 | + self.o(" mov $0, %edx", "Reset remainder reg %edx") | ||
1084 | + self.o(" div %s" % divisor_reg, "Perform '%s'" % node.op) | ||
1085 | + if node.op == "/" and result_reg != dividend_reg : | ||
1086 | + self.o(" mov %s, %s" % (dividend_reg, result_reg), "Copy result") | ||
1087 | + elif node.op == "%" and result_reg != remainder_reg : | ||
1088 | + self.o(" mov %s, %s" % (remainder_reg, result_reg), "Copy result") | ||
1089 | + if result_reg != "%edx" : | ||
1090 | + self.o(" popl %edx", "Restore %edx") | ||
1091 | + if result_reg != "%eax" : | ||
1092 | + self.o(" popl %eax", "Restore %eax") | ||
1093 | + self.stack.done() | ||
1094 | + | ||
1051 | def _binop_compare(self, node): | 1095 | def _binop_compare(self, node): |
1052 | """Performs a comparison operation (>, ==, etc) on the given | 1096 | """Performs a comparison operation (>, ==, etc) on the given |
1053 | Binop node.""" | 1097 | Binop node.""" |
... | @@ -1078,8 +1122,12 @@ class CodeGenVisitor(Visitor): | ... | @@ -1078,8 +1122,12 @@ class CodeGenVisitor(Visitor): |
1078 | self._binop_assign(node) | 1122 | self._binop_assign(node) |
1079 | elif node.op in ['+','-','*']: | 1123 | elif node.op in ['+','-','*']: |
1080 | self._binop_arith(node) | 1124 | self._binop_arith(node) |
1125 | + elif node.op in ['/','%']: | ||
1126 | + self._binop_divmod(node) | ||
1081 | elif node.op in ['==', '!=', '<', '>', '<=', '>=']: | 1127 | elif node.op in ['==', '!=', '<', '>', '<=', '>=']: |
1082 | self._binop_compare(node) | 1128 | self._binop_compare(node) |
1129 | + else : | ||
1130 | + raise Exception("unsupported operator %r" % node.op) | ||
1083 | 1131 | ||
1084 | def vNegative(self, node): | 1132 | def vNegative(self, node): |
1085 | self._loc(node) | 1133 | self._loc(node) | ... | ... |
... | @@ -116,6 +116,7 @@ def main (args=None) : | ... | @@ -116,6 +116,7 @@ def main (args=None) : |
116 | print("Compiling preprocessed %r" % src) | 116 | print("Compiling preprocessed %r" % src) |
117 | else : | 117 | else : |
118 | code = "\n".join(l.rstrip() for l in open(src).readlines()) | 118 | code = "\n".join(l.rstrip() for l in open(src).readlines()) |
119 | + lmap = {} | ||
119 | print("Compiling %r" % src) | 120 | print("Compiling %r" % src) |
120 | ret = Compiler(ARCH[args.arch], src, lmap, args.test).compile(code, ast_file) | 121 | ret = Compiler(ARCH[args.arch], src, lmap, args.test).compile(code, ast_file) |
121 | if ast_file is not None : | 122 | if ast_file is not None : | ... | ... |
-
Please register or login to post a comment