Franck Pommereau

added / and % operations for x86

......@@ -272,10 +272,10 @@ class x86Registers:
if type == None:
type = self.default_type
self.type_stack.append(type)
if valid_regs == None:
valid_regs = self._get_type_valid_regs(type)
reg = self._get_free_reg(valid_regs, preferred_reg)
self.type_stack.append(type)
self.stack.append(reg)
return reg
......@@ -313,7 +313,8 @@ class x86Registers:
reg = self._pop(valid_regs)
return self._coerce_type(reg, prev_type, type)
else:
return self._pop(self.all_regs)
reg = self._pop(self.all_regs)
return reg
def _pop(self, valid_regs):
"""Pops the top element of the stack into a free register
......@@ -437,8 +438,8 @@ class CodeGenVisitor(Visitor):
'+' : 'add',
'-' : 'sub',
'*' : 'imul',
'=' : 'mov'
}
'=' : 'mov',
}
# Windows' C linkage prepends a '_' before symbol
# names, whereas Unix doesn't. This is particularly
......@@ -1048,6 +1049,49 @@ class CodeGenVisitor(Visitor):
if new_reg != left_reg:
raise Exception("PANIC! Binop push() isn't same as last pop()!")
def _binop_divmod(self, node):
"""Performs a division/modulo operation on the given Binop node."""
if node.op == "/" :
result_reg = self.stack.push(node.type, preferred_reg="%eax")
else :
result_reg = self.stack.push(node.type, preferred_reg="%edx")
node.left.accept(self)
right_reg = self._accept_and_pop(node.right)
left_reg = self.stack.pop(node.left.coerce_to_type)
type_str = node.type.get_outer_string()
if type_str == 'char':
divisor_reg = self.stack.lo(right_reg)
dividend_reg = self.stack.lo("%eax")
remainder_reg = self.stack.lo("%edx")
self.o(" mov $0, %s" % result_reg, "Reset result reg")
result_reg = self.stack.lo(result_reg)
else:
divisor_reg = right_reg
dividend_reg = "%eax"
remainder_reg = "%edx"
if result_reg != "%eax" :
self.o(" pushl %eax", "Save %eax used as dividend")
if result_reg != "%edx" :
self.o(" pushl %edx", "Save %edx used as remainder")
if left_reg != dividend_reg :
self.o(" mov %s, %s" % (left_reg, dividend_reg), "Copy dividend to %eax")
self.o(" mov $0, %edx", "Reset remainder reg %edx")
self.o(" div %s" % divisor_reg, "Perform '%s'" % node.op)
if node.op == "/" and result_reg != dividend_reg :
self.o(" mov %s, %s" % (dividend_reg, result_reg), "Copy result")
elif node.op == "%" and result_reg != remainder_reg :
self.o(" mov %s, %s" % (remainder_reg, result_reg), "Copy result")
if result_reg != "%edx" :
self.o(" popl %edx", "Restore %edx")
if result_reg != "%eax" :
self.o(" popl %eax", "Restore %eax")
self.stack.done()
def _binop_compare(self, node):
"""Performs a comparison operation (>, ==, etc) on the given
Binop node."""
......@@ -1078,8 +1122,12 @@ class CodeGenVisitor(Visitor):
self._binop_assign(node)
elif node.op in ['+','-','*']:
self._binop_arith(node)
elif node.op in ['/','%']:
self._binop_divmod(node)
elif node.op in ['==', '!=', '<', '>', '<=', '>=']:
self._binop_compare(node)
else :
raise Exception("unsupported operator %r" % node.op)
def vNegative(self, node):
self._loc(node)
......
......@@ -116,6 +116,7 @@ def main (args=None) :
print("Compiling preprocessed %r" % src)
else :
code = "\n".join(l.rstrip() for l in open(src).readlines())
lmap = {}
print("Compiling %r" % src)
ret = Compiler(ARCH[args.arch], src, lmap, args.test).compile(code, ast_file)
if ast_file is not None :
......