aboutsummaryrefslogtreecommitdiff
path: root/executor/executor.h
blob: 7f9793e41dd759ac72f4532baf6d29eafa9c77bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#ifndef AMAL_EXECUTOR_H
#define AMAL_EXECUTOR_H

#include "../include/std/misc.h"
#include "../include/std/types.h"
#include "../include/std/buffer_view.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, i8 dst_reg);
CHECK_RESULT int amal_exec_mov(amal_executor *self, i8 dst_reg, i8 src_reg);
CHECK_RESULT int amal_exec_movi(amal_executor *self, i8 dst_reg, i64 imm);
CHECK_RESULT int amal_exec_movd(amal_executor *self, i8 dst_reg, BufferView data);
CHECK_RESULT int amal_exec_add(amal_executor *self, i8 dst_reg, i8 src_reg1, i8 src_reg2);
CHECK_RESULT int amal_exec_sub(amal_executor *self, i8 dst_reg, i8 src_reg1, i8 src_reg2);
CHECK_RESULT int amal_exec_imul(amal_executor *self, i8 dst_reg, i8 src_reg1, i8 src_reg2);
CHECK_RESULT int amal_exec_mul(amal_executor *self, i8 dst_reg, i8 src_reg1, i8 src_reg2);
CHECK_RESULT int amal_exec_idiv(amal_executor *self, i8 dst_reg, i8 src_reg1, i8 src_reg2);
CHECK_RESULT int amal_exec_div(amal_executor *self, i8 dst_reg, i8 src_reg1, i8 src_reg2);
CHECK_RESULT int amal_exec_push(amal_executor *self, i8 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, i8 dst_reg);
void amal_exec_call_overwrite(amal_executor *self, u32 call_code_offset, i32 new_target_rel32);
/*CHECK_RESULT int amal_exec_callr(i8 dst_reg, BufferView data);*/
CHECK_RESULT int amal_exec_calle(amal_executor *self, void *func, i8 dst_reg);
CHECK_RESULT int amal_exec_cmp(amal_executor *self, i8 dst_reg, i8 src_reg1, i8 src_reg2);
CHECK_RESULT int amal_exec_jz(amal_executor *self, i8 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, i8 reg);
CHECK_RESULT int amal_exec_func_start(amal_executor *self, u16 num_regs);
CHECK_RESULT int amal_exec_func_end(amal_executor *self);
CHECK_RESULT int amal_exec_label(amal_executor *self);

#endif