From ff1f3992d68e0016dffc9b4dd6974dba4813dea1 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 8 Oct 2025 22:47:49 +0200 Subject: [PATCH] gcc parameter "naked" added --- inspect.sh | 5 ++- src/copapy/generate_stencils.py | 30 ++++++++---------- tests/test_compile.py | 32 +++++++++---------- tests/test_compile_div.py | 54 +++++++++++++++++++++++++++++++++ tests/test_coparun_module.py | 17 ++++------- 5 files changed, 91 insertions(+), 47 deletions(-) create mode 100644 tests/test_compile_div.py diff --git a/inspect.sh b/inspect.sh index 212a0ce..72e7fb5 100644 --- a/inspect.sh +++ b/inspect.sh @@ -1,3 +1,6 @@ #!/bin/bash -objdump -D -b binary -m i386:x86-64 --adjust-vma=0x1000 bin/test_code.bin \ No newline at end of file +source build.sh +python tests/test_compile_div.py +python tools/extract_code.py +objdump -D -b binary -m i386:x86-64 --adjust-vma=0x1000 bin/test_code.bin > bin/test_code.bin.txt diff --git a/src/copapy/generate_stencils.py b/src/copapy/generate_stencils.py index 7a9e239..7fe354e 100644 --- a/src/copapy/generate_stencils.py +++ b/src/copapy/generate_stencils.py @@ -5,11 +5,12 @@ import argparse op_signs = {'add': '+', 'sub': '-', 'mul': '*', 'div': '/', 'gt': '>', 'eq': '==', 'mod': '%'} -func_prefix = '' # __attribute__((ms_abi)) +entry_func_prefix = '' +stencil_func_prefix = '__attribute__((naked)) ' # Remove collee prolog def get_function_start() -> str: return f""" - {func_prefix}int function_start(){{ + {entry_func_prefix}int function_start(){{ result_int(0); // dummy call instruction before marker gets striped asm volatile (".long 0xE2401F0F"); return 1; @@ -19,7 +20,7 @@ def get_function_start() -> str: def get_function_end() -> str: return f""" - {func_prefix}int function_end(){{ + {entry_func_prefix}int function_end(){{ result_int(0); asm volatile (".long 0xE1401F0F"); return 1; @@ -29,8 +30,7 @@ def get_function_end() -> str: def get_op_code(op: str, type1: str, type2: str, type_out: str) -> str: return f""" - void {op}_{type1}_{type2}({type1} arg1, {type2} arg2) {{ - asm volatile (".long 0xE1401F0F"); + {stencil_func_prefix}void {op}_{type1}_{type2}({type1} arg1, {type2} arg2) {{ result_{type_out}_{type2}(arg1 {op_signs[op]} arg2, arg2); asm volatile (".long 0xE2401F0F"); }} @@ -39,8 +39,7 @@ def get_op_code(op: str, type1: str, type2: str, type_out: str) -> str: def get_conv_code(type1: str, type2: str, type_out: str) -> str: return f""" - void conv_{type1}_{type2}({type1} arg1, {type2} arg2) {{ - asm volatile (".long 0xE1401F0F"); + {stencil_func_prefix}void conv_{type1}_{type2}({type1} arg1, {type2} arg2) {{ result_{type_out}_{type2}(({type_out})arg1, arg2); asm volatile (".long 0xE2401F0F"); }} @@ -49,8 +48,7 @@ def get_conv_code(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 0xE1401F0F"); + {stencil_func_prefix}void {op}_{type1}_{type2}({type1} arg1, {type2} arg2) {{ result_float_{type2}((float)arg1 {op_signs[op]} (float)arg2, arg2); asm volatile (".long 0xE2401F0F"); }} @@ -59,8 +57,7 @@ def get_op_code_float(op: str, type1: str, type2: str) -> str: 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 0xE1401F0F"); + {stencil_func_prefix}void {op}_{type1}_{type2}({type1} arg1, {type2} arg2) {{ result_int_{type2}((int)(arg1 {op_signs[op]} arg2), arg2); asm volatile (".long 0xE2401F0F"); }} @@ -81,8 +78,7 @@ def get_result_stubs2(type1: str, type2: str) -> str: def get_read_reg0_code(type1: str, type2: str, type_out: str) -> str: return f""" - void read_{type_out}_reg0_{type1}_{type2}({type1} arg1, {type2} arg2) {{ - asm volatile (".long 0xE1401F0F"); + {stencil_func_prefix}void read_{type_out}_reg0_{type1}_{type2}({type1} arg1, {type2} arg2) {{ result_{type_out}_{type2}(dummy_{type_out}, arg2); asm volatile (".long 0xE2401F0F"); }} @@ -91,8 +87,7 @@ def get_read_reg0_code(type1: str, type2: str, type_out: str) -> str: def get_read_reg1_code(type1: str, type2: str, type_out: str) -> str: return f""" - void read_{type_out}_reg1_{type1}_{type2}({type1} arg1, {type2} arg2) {{ - asm volatile (".long 0xE1401F0F"); + {stencil_func_prefix}void read_{type_out}_reg1_{type1}_{type2}({type1} arg1, {type2} arg2) {{ result_{type1}_{type_out}(arg1, dummy_{type_out}); asm volatile (".long 0xE2401F0F"); }} @@ -101,8 +96,7 @@ def get_read_reg1_code(type1: str, type2: str, type_out: str) -> str: def get_write_code(type1: str) -> str: return f""" - void write_{type1}({type1} arg1) {{ - asm volatile (".long 0xE1401F0F"); + {stencil_func_prefix}void write_{type1}({type1} arg1) {{ dummy_{type1} = arg1; result_{type1}(arg1); asm volatile (".long 0xE2401F0F"); @@ -127,7 +121,7 @@ if __name__ == "__main__": args = parser.parse_args() if args.abi: - func_prefix = f"__attribute__(({args.abi}_abi)) " + entry_func_prefix = f"__attribute__(({args.abi}_abi)) " types = ['int', 'float'] ops = ['add', 'sub', 'mul', 'div', 'gt', 'eq'] diff --git a/tests/test_compile.py b/tests/test_compile.py index 51b9113..f845b14 100644 --- a/tests/test_compile.py +++ b/tests/test_compile.py @@ -33,27 +33,25 @@ def test_example(): #example r2 41 88 00 00 + +def function(c1, c2): + i1 = c1 * 3.3 + 5 + i2 = c2 * 5 + c1 + #r1 = i1 + i2 * 55 / 4 + r1 = i1 + i2 * 55 / 4 + r2 = 4 * i2 + 5 + + return i1, i2, r1, r2 + + def test_compile(): - #c1 = const(1.11) - #c2 = const(2.22) - - #i1 = c1 * 2 - #i2 = i1 + 3 - - #r1 = i1 + i2 - #r2 = c2 + 4 + c1 - - #out = [Write(r1), Write(r2)] - c1 = const(4) c2 = const(2) - #i1 = c1 * 2 - #r1 = i1 + 7 + (c2 + 7 * 9) - #r2 = i1 + 9 - #out = [Write(r1), Write(r2)] - r1 = c1 * 5 + 8 + c2 * 3 - out = [Write(r1)] + + ret = function(c1, c2) + + out = [Write(r) for r in ret] il, _ = copapy.compile_to_instruction_list(out, copapy.generic_sdb) diff --git a/tests/test_compile_div.py b/tests/test_compile_div.py new file mode 100644 index 0000000..decc97c --- /dev/null +++ b/tests/test_compile_div.py @@ -0,0 +1,54 @@ +from copapy import Write, const +import copapy +import subprocess +import struct +from copapy import binwrite + + +def run_command(command: list[str], encoding: str = 'utf8') -> str: + process = subprocess.Popen(command, stdout=subprocess.PIPE) + output, error = process.communicate() + + assert error is None, f"Error occurred: {error.decode(encoding)}" + return output.decode(encoding) + +def function(c1): + r1 = c1 / 2 + + return [r1] + +def test_compile(): + + c1 = const(16) + + ret = function(c1) + + out = [Write(r) for r in ret] + + il, _ = copapy.compile_to_instruction_list(out, copapy.generic_sdb) + + # run program command + il.write_com(binwrite.Command.RUN_PROG) + il.write_int(0) + + il.write_com(binwrite.Command.READ_DATA) + il.write_int(0) + il.write_int(36) + + il.write_com(binwrite.Command.END_PROG) + + print('* Data to runner:') + il.print() + + il.to_file('bin/test.copapy') + + result = run_command(['bin/coparun', 'bin/test.copapy']) + print('* Output from runner:') + print(result) + + assert 'Return value: 1' in result + + +if __name__ == "__main__": + #test_example() + test_compile() diff --git a/tests/test_coparun_module.py b/tests/test_coparun_module.py index 11502df..a22dbe2 100644 --- a/tests/test_coparun_module.py +++ b/tests/test_coparun_module.py @@ -2,22 +2,17 @@ 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 - r1 = i1 + i2 * 55 / 4 - r2 = 4 * i2 + 5 +def function(c1): + r1 = c1 / 2 - return i1, i2, r1, r2 + return [r1] def test_compile(): - c1 = const(4) - c2 = const(2) + c1 = const(16) - ret = function(c1, c2) + ret = function(c1) tg = Target() print('* compile and copy ...') @@ -27,7 +22,7 @@ def test_compile(): tg.run() #print('* finished') - ret_ref = function(4, 2) + ret_ref = function(16) for test, ref, name in zip(ret, ret_ref, ['i1', 'i2', 'r1', 'r2']): val = tg.read_value(test)