#ifndef AMAL_EXECUTOR_H #define AMAL_EXECUTOR_H #include "../include/std/misc.h" #include "../include/std/types.h" #include "../include/std/buffer_view.h" #include "../include/bytecode/bytecode.h" /*doc(Execution backend) Amalgam supports multiple execution backend and they can be implemented with minimal effort. The only requirement is implementation of all the functions in executor/executor.h and adding the source file with the implementation to the build script. See executor/interpreter/executor.c as an example.\ These functions are then called by amalgam as amalgam parses the amalgam bytecode when `amal_program_run` is called. */ struct amal_executor_impl; typedef struct amal_executor amal_executor; CHECK_RESULT int amal_executor_init(amal_executor **self); void amal_executor_deinit(amal_executor *self); CHECK_RESULT int amal_executor_run(amal_executor *self, u32 offset); u32 amal_exec_get_code_offset(amal_executor *self); /* These functions are called for every file in the program. Every file has its own list of strings, intermediates, functions and external functions */ CHECK_RESULT int amal_executor_instructions_start(amal_executor *self, u16 num_functions); CHECK_RESULT int amal_executor_instructions_end(amal_executor *self); CHECK_RESULT int amal_exec_nop(amal_executor *self); CHECK_RESULT int amal_exec_setz(amal_executor *self, AmalReg dst_reg); CHECK_RESULT int amal_exec_mov(amal_executor *self, AmalReg dst_reg, AmalReg src_reg); CHECK_RESULT int amal_exec_movi(amal_executor *self, AmalReg dst_reg, i64 imm); CHECK_RESULT int amal_exec_movd(amal_executor *self, AmalReg dst_reg, BufferView data); CHECK_RESULT int amal_exec_add(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_sub(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_imul(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_mul(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_idiv(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_div(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_push(amal_executor *self, AmalReg reg); CHECK_RESULT int amal_exec_pushi(amal_executor *self, i64 imm); CHECK_RESULT int amal_exec_pushd(amal_executor *self, BufferView data); CHECK_RESULT int amal_exec_call_start(amal_executor *self, u8 num_args); CHECK_RESULT int amal_exec_call(amal_executor *self, u32 code_offset, AmalReg dst_reg); void amal_exec_call_overwrite(amal_executor *self, u32 call_code_offset, i32 new_target_rel32); CHECK_RESULT int amal_exec_calle(amal_executor *self, void *func, AmalReg dst_reg); CHECK_RESULT int amal_exec_callr(amal_executor *self, AmalReg reg, AmalReg dst_reg); CHECK_RESULT int amal_exec_eq(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_neq(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_ilt(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_ile(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_igt(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_ige(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_lt(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_le(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_gt(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_ge(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_and(amal_executor *self, AmalReg dst_reg, AmalReg src_reg1, AmalReg src_reg2); CHECK_RESULT int amal_exec_jz(amal_executor *self, AmalReg reg, u16 target_label); CHECK_RESULT int amal_exec_jmp(amal_executor *self, u16 target_label); CHECK_RESULT int amal_exec_ret(amal_executor *self, AmalReg reg); CHECK_RESULT int amal_exec_func_start(amal_executor *self, u8 num_params, u16 num_regs); CHECK_RESULT int amal_exec_func_end(amal_executor *self); CHECK_RESULT int amal_exec_label(amal_executor *self); #endif