Franck Pommereau

added / and % operations for x86

...@@ -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 :
......