diff --git a/src/copapy/__init__.py b/src/copapy/__init__.py index d8712be..dbb7ce2 100644 --- a/src/copapy/__init__.py +++ b/src/copapy/__init__.py @@ -73,6 +73,12 @@ class Net: def __rtruediv__(self, other: Any) -> 'Net': return _add_op('div', [other, self]) + def __floordiv__(self, other: Any) -> 'Net': + return _add_op('floordiv', [self, other]) + + def __rfloordiv__(self, other: Any) -> 'Net': + return _add_op('floordiv', [other, self]) + def __neg__(self) -> 'Net': return _add_op('sub', [const(0), self]) diff --git a/src/copapy/generate_stencils.py b/src/copapy/generate_stencils.py index ccd7aa9..d14ecaf 100644 --- a/src/copapy/generate_stencils.py +++ b/src/copapy/generate_stencils.py @@ -35,6 +35,26 @@ def get_op_code(op: str, type1: str, type2: str, type_out: str) -> str: """ +def get_op_code_float(op: str, type1: str, type2: str) -> str: + return f""" + void {op}_{type1}_{type2}({type1} arg1, {type2} arg2) {{ + asm volatile (".long 0xF17ECAFE"); + result_float_{type2}((float)arg1 {op_signs[op]} arg2, arg2); + asm volatile (".long 0xF27ECAFE"); + }} + """ + + +def get_op_code_int(op: str, type1: str, type2: str) -> str: + return f""" + void {op}_{type1}_{type2}({type1} arg1, {type2} arg2) {{ + asm volatile (".long 0xF17ECAFE"); + result_int_{type2}((int)(arg1 {op_signs[op]} arg2), arg2); + asm volatile (".long 0xF27ECAFE"); + }} + """ + + def get_result_stubs1(type1: str) -> str: return f""" void result_{type1}({type1} arg1); @@ -108,7 +128,12 @@ if __name__ == "__main__": for op, t1, t2 in permutate(ops, types, types): t_out = t1 if t1 == t2 else 'float' - code += get_op_code(op, t1, t2, t_out) + if op == 'floordiv': + code += get_op_code_int('div', t1, t2) + elif op == 'div' and t1 == 'int': + code += get_op_code_float(op, t1, t2) + else: + code += get_op_code(op, t1, t2, t_out) code += get_op_code('mod', 'int', 'int', 'int') diff --git a/src/copapy/stencils.c b/src/copapy/stencils.c index c214630..fac8ca3 100644 --- a/src/copapy/stencils.c +++ b/src/copapy/stencils.c @@ -91,13 +91,13 @@ void div_int_int(int arg1, int arg2) { asm volatile (".long 0xF17ECAFE"); - result_int_int(arg1 / arg2, arg2); + result_float_int((float)arg1 / arg2, arg2); asm volatile (".long 0xF27ECAFE"); } void div_int_float(int arg1, float arg2) { asm volatile (".long 0xF17ECAFE"); - result_float_float(arg1 / arg2, arg2); + result_float_float((float)arg1 / arg2, arg2); asm volatile (".long 0xF27ECAFE"); } diff --git a/tests/test_coparun_module.py b/tests/test_coparun_module.py index 5fc81de..58142e0 100644 --- a/tests/test_coparun_module.py +++ b/tests/test_coparun_module.py @@ -1,22 +1,33 @@ from copapy import const, Target +from pytest import approx + + +def function(c1, c2): + i1 = c1 * 3.3 + 5 + i2 = c2 * 5 + c1 + r1 = i1 + i2 * 55 / 4 + r2 = 4 * i2 + 5 + + return i1, i2, r1, r2 def test_compile(): c1 = const(4) - c2 = const(2) * 4 - - i1 = c2 * 2 - r1 = i1 + 7 + (c1 + 7 * 9) - r2 = i1 + 9 + c2 = const(2) + + ret = function(c1, c2) tg = Target() - tg.compile(r1, r2, c2) + tg.compile(ret) tg.run() - print(tg.read_value(r1)) - print(tg.read_value(r2)) - print(tg.read_value(c2)) + ret_ref = function(4, 2) + + print() + + for test, ref, name in zip(ret, ret_ref, ['i1', 'i2', 'r1', 'r2']): + assert tg.read_value(test) == approx(ref, 1e-5), name if __name__ == "__main__":