From a3d29ee801a06bb915bec42df226d4a1fc3b5f6a Mon Sep 17 00:00:00 2001 From: d0p1 Date: Thu, 22 Feb 2024 05:10:55 +0100 Subject: [PATCH] Working on JIT (wip) --- configure.ac | 5 ++- disas/main.c | 12 +++++-- lib/op.h | 26 +++++++++++++++ lib/register.h | 15 +++++++++ vm/Makefile.am | 5 +++ vm/jit.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++ vm/jit.h | 19 +++++++++++ vm/main.c | 8 +++++ vm/x64/register.h | 8 +++++ vm/x64/x64.S | 14 ++++++++ 10 files changed, 190 insertions(+), 4 deletions(-) create mode 100644 lib/register.h create mode 100644 vm/jit.c create mode 100644 vm/jit.h create mode 100644 vm/main.c create mode 100644 vm/x64/register.h create mode 100644 vm/x64/x64.S diff --git a/configure.ac b/configure.ac index 7bad3c9..7afb2c2 100644 --- a/configure.ac +++ b/configure.ac @@ -2,11 +2,14 @@ AC_INIT([65oo2], [1.0]) AM_INIT_AUTOMAKE([foreign subdir-objects]) +AC_CANONICAL_HOST + AC_LANG(C) AC_PROG_CC AC_PROG_CPP AC_PROG_INSTALL AC_PROG_RANLIB +AM_PROG_AS AM_PROG_AR AM_PROG_CC_C_O @@ -18,4 +21,4 @@ AC_CONFIG_FILES([ lib/Makefile disas/Makefile vm/Makefile]) -AC_OUTPUT \ No newline at end of file +AC_OUTPUT diff --git a/disas/main.c b/disas/main.c index e161e1c..ebac269 100644 --- a/disas/main.c +++ b/disas/main.c @@ -104,16 +104,21 @@ decode_imm(uint8_t opcode) fprintf(output, "%s.", opcode_str[opcode]); + if (attr & 0x4) + { + fprintf(output, "U"); + } + switch (attr & 0x3) { case 0x0: - fprintf(output, "B #%X\n", readu8()); + fprintf(output, "B #$%X\n", readu8()); break; case 0x1: - fprintf(output, "W #%hX\n", readu16()); + fprintf(output, "W #$%hX\n", readu16()); break; case 0x2: - fprintf(output, "D #%X\n", readu32()); + fprintf(output, "D #$%X\n", readu32()); break; default: break; @@ -146,6 +151,7 @@ decode(void) do { opcode = readu8(); + if (feof(input)) return; switch (opcode_addr[opcode] & OP_ADDR_MODE) { case OP_ADDR_IMPL: diff --git a/lib/op.h b/lib/op.h index 16b551c..48f52b3 100644 --- a/lib/op.h +++ b/lib/op.h @@ -13,6 +13,32 @@ # define OP_ADDR_X 1 << 4 # define OP_ADDR_Y 1 << 5 +# define OP_BRK_impl 0x00 +# define OP_ORA_x_ind 0x01 +# define OP_PHP_impl 0x08 +# define OP_ORA_imm 0x09 +# define OP_ORA_abs 0x0D +# define OP_ASL_abs 0x0E + +# define OP_BPL_rel 0x10 +# define OP_ORA_ind_y 0x11 +# define OP_CLC_impl 0x18 +# define OP_ORA_abs_y 0x19 +# define OP_ORA_abs_x 0x1D +# define OP_ASL_abs_x 0x1E + +# define OP_JSR_abs 0x20 +# define OP_AND_x_ind 0x21 +# define OP_PLP_impl 0x28 +# define OP_AND_imm 0x29 +# define OP_ROL_a 0x2A +# define OP_BIT_abs 0x2C +# define OP_AND_abs 0x2D +# define OP_ROL_abs 0x2E + +# define OP_BMI_rel 0x30 +# define OP_AND_ind_y 0x31 + extern const uint8_t opcode_addr[]; extern const char *opcode_str[]; diff --git a/lib/register.h b/lib/register.h new file mode 100644 index 0000000..7d536a0 --- /dev/null +++ b/lib/register.h @@ -0,0 +1,15 @@ +#ifndef REGISTER_H +# define REGISTER_H + +enum + { + REG_PC, + REG_AC, + REG_X, + REG_Y, + REG_SR, + REG_SP, + REG_MAX + }; + +#endif /* !REGISTER_H */ diff --git a/vm/Makefile.am b/vm/Makefile.am index e69de29..4568631 100644 --- a/vm/Makefile.am +++ b/vm/Makefile.am @@ -0,0 +1,5 @@ +bin_PROGRAMS = vm + +vm_SOURCES = main.c jit.c x64/x64.S +vm_CFLAGS =-I$(top_srcdir) +vm_LDADD = ../lib/lib65oo2.a diff --git a/vm/jit.c b/vm/jit.c new file mode 100644 index 0000000..3c69bc3 --- /dev/null +++ b/vm/jit.c @@ -0,0 +1,82 @@ +#include +#include +#ifdef _WIN32 +# include +# include +#else +# include +# include +#endif + +#include "jit.h" + +static size_t page_size = 0; + + +JitBuffer * +jit_buffer_new(void) +{ +#ifdef _WIN32 + DWORD type; + DWORD prot; + SYSTEM_INFO sysinfo; + + if (page_size == 0) + { + GetSystemInfo(&sysinfo); + page_size = sysinfo.dwPageSize; + } + + type = MEM_RESERVE | MEM_COMMIT; + prot = PAGE_READWRITE; + + return (VirtualAlloc(NULL, page_size, type, prot)); +#else + int prot; + int flags; + + if (page_size == 0) + { + page_size = sysconf(_SC_PAGESIZE); + } + + prot = PROT_READ | PROT_WRITE; + flags = MAP_ANONYMOUS | MAP_PRIVATE; + + return (mmap(NULL, page_size, prot, flags, -1, 0)); +#endif +} + +void +jit_buffer_finalize(JitBuffer *buff) +{ +#ifdef _WIN32 + DWORD old; + + VirtualProtect(buff, page_size, PAGE_EXECUTE_READ, &old); +#else + mprotect(buff, page_size, PROT_READ | PROT_EXEC); +#endif +} + +void +jit_buffer_add(JitBuffer *buff, int size, void *value) +{ + memcpy(buff->code + buff->count, value, size); + buff->count += size; +} + +void +jit_buffer_execute(JitBuffer *buff) +{ +} + +void +jit_buffer_destroy(JitBuffer *buff) +{ +#ifdef _WIN32 + VirtualFree(buff, page_size, MEM_RELEASE); +#else + munmap(buff, page_size); +#endif +} diff --git a/vm/jit.h b/vm/jit.h new file mode 100644 index 0000000..923c989 --- /dev/null +++ b/vm/jit.h @@ -0,0 +1,19 @@ +#ifndef JIT_H +# define JIT_H + +# include "lib/register.h" + +typedef struct +{ + uint32_t registers[REG_MAX]; + size_t count; + uint8_t code[]; +} JitBuffer; + +JitBuffer *jit_buffer_new(void); +void jit_buffer_ins(JitBuffer *buff, int size, uint64_t ins); +void jit_buffer_imm(JitBuffer *buff, int size, void *value); +void jit_buffer_finalize(JitBuffer *buff); +void jit_buffer_destroy(JitBuffer *buff); + +#endif /* !JIT_H */ diff --git a/vm/main.c b/vm/main.c new file mode 100644 index 0000000..abcb908 --- /dev/null +++ b/vm/main.c @@ -0,0 +1,8 @@ +#include +#include + +int +main(int argc, char **argv) +{ + return (EXIT_SUCCESS); +} diff --git a/vm/x64/register.h b/vm/x64/register.h new file mode 100644 index 0000000..6b8b3cc --- /dev/null +++ b/vm/x64/register.h @@ -0,0 +1,8 @@ +#ifndef X64_REGISTER_H +# define X64_REGISTER_H + +# define REG_ACC %eax +# define REG_X %ebx +# define REG_Y %ecx + +#endif /* X64_REGISTER_H */ diff --git a/vm/x64/x64.S b/vm/x64/x64.S new file mode 100644 index 0000000..33e9529 --- /dev/null +++ b/vm/x64/x64.S @@ -0,0 +1,14 @@ + #include "register.h" + + .globl asm_NOP + .globl asm_NOP_end +asm_NOP: + nop +asm_NOP_end: + + .globl asm_DEY + .globl asm_DEY_end +asm_DEY: + dec REG_Y +asm_DEY_end: +