summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/berg/vm.h104
1 files changed, 104 insertions, 0 deletions
diff --git a/include/berg/vm.h b/include/berg/vm.h
new file mode 100644
index 0000000..0f87452
--- /dev/null
+++ b/include/berg/vm.h
@@ -0,0 +1,104 @@
+#ifndef BERG_VM_H
+#define BERG_VM_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <assert.h>
+
+enum berg_envcall {
+ BERG_MALLOC,
+ BERG_FREE,
+ /* temporarily used for debugging, actual printf should probably be done
+ * via open/close/write/read etc */
+ BERG_PUTI32
+};
+
+enum berg_op {
+ BERG_LABEL,
+ BERG_LD32,
+ BERG_ST32,
+ BERG_CALL,
+ BERG_RET,
+ BERG_ECALL,
+ BERG_MOVI,
+ BERG_MOVR,
+};
+
+const char *berg_op_str(enum berg_op op);
+
+struct berg_insn {
+ uint16_t op;
+ uint8_t ra;
+ uint8_t rb;
+ uint8_t rc;
+ uint8_t rd;
+ union {
+ void *p;
+ int64_t imm;
+ };
+};
+
+enum berg_type {
+ BERG_VOID,
+ BERG_POINTER
+};
+
+struct berg_vm;
+struct berg_func;
+
+struct berg_gpr {
+ uint8_t r;
+};
+
+struct berg_operand {
+ enum berg_type type;
+ struct berg_gpr gpr;
+};
+
+static inline struct berg_operand berg_operand_gpr(struct berg_gpr gpr, enum berg_type type)
+{
+ return (struct berg_operand){.type = type, .gpr = gpr};
+}
+
+static inline struct berg_gpr berg_gpr(uint8_t r)
+{
+ return (struct berg_gpr){.r = r};
+}
+
+static inline struct berg_gpr berg_gpr_arg(uint8_t r)
+{
+ assert(r < 64);
+ return berg_gpr(r);
+}
+
+static inline struct berg_gpr berg_gpr_tmp(uint8_t r)
+{
+ assert(r < 128);
+ /* skip arg regs */
+ return berg_gpr(r + 64);
+}
+
+struct berg_vm *create_berg_vm();
+struct berg_func *create_berg_func(struct berg_vm *vm, enum berg_type rtype, size_t argc, const struct berg_operand args[argc]);
+long compile_berg_func(struct berg_func *f);
+long run_berg_func(struct berg_func *f);
+void destroy_berg_vm(struct berg_vm *vm);
+
+long berg_ecall(struct berg_func *f,
+ struct berg_gpr ra,
+ int64_t imm);
+
+long berg_call(struct berg_func *f,
+ struct berg_func *c);
+
+long berg_movi(struct berg_func *f,
+ struct berg_gpr ra,
+ int64_t imm);
+
+long berg_movr(struct berg_func *f,
+ struct berg_gpr ra,
+ struct berg_gpr rb);
+
+long berg_ret(struct berg_func *f);
+
+#endif /* BERG_VM_H */