From c58c1a79e8bb718967d256929ac0ab164d0d3d84 Mon Sep 17 00:00:00 2001 From: Doug Coleman Date: Mon, 23 Nov 2020 19:01:26 -0600 Subject: [PATCH] vm: Add a bunch of half-baked arm files. Also fix some .h issues. --- vm/Config.arm | 3 +- vm/Config.arm64.64 | 1 + vm/Config.linux.arm.32 | 4 ++ vm/Config.linux.arm.64 | 4 ++ vm/Config.macosx | 4 +- vm/Config.macosx.arm64 | 5 ++ vm/Config.macosx.x86.32 | 3 + vm/Config.macosx.x86.64 | 6 ++ vm/Config.macosx.x86.fat | 1 + vm/Config.unix | 4 +- vm/Config.windows.x86.32 | 2 +- vm/Config.windows.x86.64 | 2 +- vm/cpu-arm.32.S | 127 +++++++++++++++++++++++++++++++++++++++ vm/cpu-arm.32.hpp | 8 +++ vm/cpu-arm.64.cpp | 25 ++++++++ vm/cpu-arm.64.hpp | 13 ++++ vm/cpu-arm.hpp | 67 ++++++++++++++++++++- 17 files changed, 269 insertions(+), 10 deletions(-) create mode 100644 vm/Config.arm64.64 create mode 100644 vm/Config.linux.arm.32 create mode 100644 vm/Config.linux.arm.64 create mode 100644 vm/Config.macosx.arm64 create mode 100644 vm/cpu-arm.32.S create mode 100644 vm/cpu-arm.32.hpp create mode 100644 vm/cpu-arm.64.cpp create mode 100644 vm/cpu-arm.64.hpp diff --git a/vm/Config.arm b/vm/Config.arm index 958a9b7c6d..b5a14149b3 100644 --- a/vm/Config.arm +++ b/vm/Config.arm @@ -1,2 +1 @@ -PLAF_MASTER_HEADERS += \ - cpu-arm.hpp +PLAF_MASTER_HEADERS += vm/cpu-arm.hpp diff --git a/vm/Config.arm64.64 b/vm/Config.arm64.64 new file mode 100644 index 0000000000..b5a14149b3 --- /dev/null +++ b/vm/Config.arm64.64 @@ -0,0 +1 @@ +PLAF_MASTER_HEADERS += vm/cpu-arm.hpp diff --git a/vm/Config.linux.arm.32 b/vm/Config.linux.arm.32 new file mode 100644 index 0000000000..1677219341 --- /dev/null +++ b/vm/Config.linux.arm.32 @@ -0,0 +1,4 @@ +include vm/Config.linux +include vm/Config.arm +PLAF_DLL_OBJS += vm/cpu-arm.32.o +PLAF_MASTER_HEADERS += vm/cpu-arm.32.hpp \ No newline at end of file diff --git a/vm/Config.linux.arm.64 b/vm/Config.linux.arm.64 new file mode 100644 index 0000000000..d29c988fee --- /dev/null +++ b/vm/Config.linux.arm.64 @@ -0,0 +1,4 @@ +include vm/Config.linux +include vm/Config.arm +PLAF_DLL_OBJS += vm/cpu-arm.64.o +PLAF_MASTER_HEADERS += vm/cpu-arm.64.hpp \ No newline at end of file diff --git a/vm/Config.macosx b/vm/Config.macosx index 74f4fcacef..67cd585827 100644 --- a/vm/Config.macosx +++ b/vm/Config.macosx @@ -1,6 +1,4 @@ include vm/Config.unix -#SITE_CFLAGS += -SITE_CFLAGS += -mmacosx-version-min=10.9 PLAF_DLL_OBJS += vm/os-macosx.o vm/mach_signal.o vm/mvm-unix.o PLAF_MASTER_HEADERS += vm/os-macosx.hpp vm/mach_signal.hpp @@ -16,7 +14,7 @@ else LIBS = -lm -framework Cocoa -framework AppKit endif -LINKER = $(CXX) $(CFLAGS) -dynamiclib -single_module \ +LINKER = $(CXX) $(TARGET) $(CFLAGS) $(CXXFLAGS) $(SHARED_FLAG) -single_module \ -current_version $(VERSION) \ -compatibility_version $(VERSION) \ -fvisibility=hidden \ diff --git a/vm/Config.macosx.arm64 b/vm/Config.macosx.arm64 new file mode 100644 index 0000000000..95affb370d --- /dev/null +++ b/vm/Config.macosx.arm64 @@ -0,0 +1,5 @@ +include vm/Config.macosx +include vm/Config.arm64.64 + +PLAF_DLL_OBJS += vm/cpu-arm.64.cpp +PLAF_MASTER_HEADERS += vm/os-macosx-arm64.64.hpp diff --git a/vm/Config.macosx.x86.32 b/vm/Config.macosx.x86.32 index 47a9473601..5ed3d2bf85 100644 --- a/vm/Config.macosx.x86.32 +++ b/vm/Config.macosx.x86.32 @@ -1,6 +1,9 @@ include vm/Config.macosx include vm/Config.x86.32 +PLAF_MASTER_HEADERS += vm/os-macosx-x86.32.hpp + # The last SDK to support x86 is 10.13 CFLAGS += --sysroot=$(XCODE_PATH)/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/$(MACOSX_32_SDK) CXXFLAGS += --sysroot=$(XCODE_PATH)/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/$(MACOSX_32_SDK) +SITE_CFLAGS += -mmacosx-version-min=10.9 diff --git a/vm/Config.macosx.x86.64 b/vm/Config.macosx.x86.64 index f987a55694..6726f7f855 100644 --- a/vm/Config.macosx.x86.64 +++ b/vm/Config.macosx.x86.64 @@ -1,2 +1,8 @@ include vm/Config.macosx include vm/Config.x86.64 + +TARGET = -target x86_64-apple-darwin + +PLAF_MASTER_HEADERS += vm/os-macosx-x86.64.hpp + +SITE_CFLAGS += -mmacosx-version-min=10.9 diff --git a/vm/Config.macosx.x86.fat b/vm/Config.macosx.x86.fat index e8a0e10d9f..d899efd4d4 100644 --- a/vm/Config.macosx.x86.fat +++ b/vm/Config.macosx.x86.fat @@ -1,3 +1,4 @@ include vm/Config.macosx include vm/Config.x86.fat SITE_CFLAGS += -arch i386 -arch x86_64 +SITE_CFLAGS += -mmacosx-version-min=10.9 diff --git a/vm/Config.unix b/vm/Config.unix index 79fa467826..e667dc61d8 100644 --- a/vm/Config.unix +++ b/vm/Config.unix @@ -8,9 +8,9 @@ DLL_EXTENSION = .a SHARED_DLL_EXTENSION = .so SHARED_FLAG = -shared -PLAF_DLL_OBJS = vm/os-unix.o +PLAF_DLL_OBJS += vm/os-unix.o PLAF_EXE_OBJS += vm/main-unix.o -PLAF_MASTER_HEADERS += vm/os-unix.hpp +PLAF_MASTER_HEADERS += vm/os-unix.hpp vm/atomic-gcc.hpp vm/atomic.hpp FFI_TEST_CFLAGS = -fPIC diff --git a/vm/Config.windows.x86.32 b/vm/Config.windows.x86.32 index 56b7f7fa48..d4c0a88e26 100644 --- a/vm/Config.windows.x86.32 +++ b/vm/Config.windows.x86.32 @@ -1,5 +1,5 @@ PLAF_DLL_OBJS += vm/os-windows-x86.32.o -PLAF_MASTER_HEADERS += vm/os-windows.32.hpp +PLAF_MASTER_HEADERS += vm/os-windows.32.hpp vm/atomic-cl-32.hpp vm/atomic.hpp DLL_PATH=http://factorcode.org/dlls WINDRES=windres -F pe-i386 include vm/Config.windows diff --git a/vm/Config.windows.x86.64 b/vm/Config.windows.x86.64 index 26a1903f94..ade7071c9e 100644 --- a/vm/Config.windows.x86.64 +++ b/vm/Config.windows.x86.64 @@ -1,5 +1,5 @@ PLAF_DLL_OBJS += vm/os-windows-x86.64.o -PLAF_MASTER_HEADERS += vm/os-windows.64.hpp +PLAF_MASTER_HEADERS += vm/os-windows.64.hpp vm/atomic-cl-64.hpp vm/atomic.hpp DLL_PATH=http://factorcode.org/dlls/64 CC=$(WIN64_PATH)-gcc.exe WINDRES=$(WIN64_PATH)-windres.exe diff --git a/vm/cpu-arm.32.S b/vm/cpu-arm.32.S new file mode 100644 index 0000000000..390cc2bf48 --- /dev/null +++ b/vm/cpu-arm.32.S @@ -0,0 +1,127 @@ +#include "asm.h" + +/* Note that the XT is passed to the quotation in r12 */ +#define CALL_QUOT \ + ldr r12,[r0, #9] /* load quotation-xt slot */ ; \ + mov lr,pc ; \ + mov pc,r12 + +#define JUMP_QUOT \ + ldr r12,[r0, #9] /* load quotation-xt slot */ ; \ + mov pc,r12 + +#define SAVED_REGS_SIZE 32 + +#define FRAME (RESERVED_SIZE + SAVED_REGS_SIZE + 8) + +#define LR_SAVE [sp, #-4] +#define RESERVED_SIZE 8 + +#define SAVE_LR str lr,LR_SAVE + +#define LOAD_LR ldr lr,LR_SAVE + +#define SAVE_AT(offset) (RESERVED_SIZE + 4 * offset) + +#define SAVE(register,offset) str register,[sp, #SAVE_AT(offset)] + +#define RESTORE(register,offset) ldr register,[sp, #SAVE_AT(offset)] + +#define PROLOGUE \ + SAVE_LR ; \ + sub sp,sp,#FRAME + +#define EPILOGUE \ + add sp,sp,#FRAME ; \ + LOAD_LR + +DEF(void,c_to_factor,(CELL quot)): + PROLOGUE + + SAVE(r4,0) /* save GPRs */ + /* don't save ds pointer */ + /* don't save rs pointer */ + SAVE(r7,3) + SAVE(r8,4) + SAVE(r9,5) + SAVE(r10,6) + SAVE(r11,7) + SAVE(r0,8) /* save quotation since we're about to mangle it */ + + sub r0,sp,#4 /* pass call stack pointer as an argument */ + bl MANGLE(save_callstack_bottom) + + RESTORE(r0,8) /* restore quotation */ + CALL_QUOT + + RESTORE(r11,7) /* restore GPRs */ + RESTORE(r10,6) + RESTORE(r9,5) + RESTORE(r8,4) + RESTORE(r7,3) + /* don't restore rs pointer */ + /* don't restore ds pointer */ + RESTORE(r4,0) + + EPILOGUE + mov pc,lr + +/* The JIT compiles an 'mov r1',sp in front of every primitive call, since a +word which was defined as a primitive will not change its definition for the +lifetime of the image -- adding new primitives requires a bootstrap. However, +an undefined word can certainly become defined, + +DEFER: foo +... +: foo ... ; + +And calls to non-primitives do not have this one-instruction prologue, so we +set the XT of undefined words to this symbol. */ +DEF(void,undefined,(CELL word)): + sub r1,sp,#4 + b MANGLE(undefined_error) + +/* Here we have two entry points. The first one is taken when profiling is +enabled */ +DEF(void,docol_profiling,(CELL word)): + ldr r1,[r0, #25] /* load profile-count slot */ + add r1,r1,#8 /* increment count */ + str r1,[r0, #25] /* store profile-count slot */ +DEF(void,docol,(CELL word)): + ldr r0,[r0, #13] /* load word-def slot */ + JUMP_QUOT + +/* We must pass the XT to the quotation in r12. */ +DEF(void,primitive_call,(void)): + ldr r0,[r5], #-4 /* load quotation from data stack */ + JUMP_QUOT + +/* We must preserve r1 here in case we're calling a primitive */ +DEF(void,primitive_execute,(void)): + ldr r0,[r5], #-4 /* load word from data stack */ + ldr pc,[r0, #29] /* jump to word-xt */ + +@ DEF(void,set_callstack,(F_STACK_FRAME *to, F_STACK_FRAME *from, CELL length)): +@ sub sp,r0,r2 /* compute new stack pointer */ +@ mov r0,sp /* start of destination of memcpy() */ +@ sub sp,sp,#12 /* alignment */ +@ bl MANGLE(memcpy) /* go */ +@ add sp,sp,#16 /* point SP at innermost frame */ +@ ldr pc,LR_SAVE /* return */ + +DEF(void,throw_impl,(CELL quot, F_STACK_FRAME *rewind_to)): + add sp,r1,#4 /* compute new stack pointer */ + ldr lr,LR_SAVE /* we have rewound the stack; load return address */ + JUMP_QUOT /* call the quotation */ + +DEF(void,lazy_jit_compile,(CELL quot)): + mov r1,sp /* save stack pointer */ + PROLOGUE + bl MANGLE(lazy_jit_compile_impl) + EPILOGUE + JUMP_QUOT /* call the quotation */ + +#ifdef WINCE + .section .drectve + .ascii " -export:c_to_factor" +#endif diff --git a/vm/cpu-arm.32.hpp b/vm/cpu-arm.32.hpp new file mode 100644 index 0000000000..4748efaf93 --- /dev/null +++ b/vm/cpu-arm.32.hpp @@ -0,0 +1,8 @@ +namespace factor { + +#define FACTOR_CPU_STRING "arm.32" + +register cell ds asm("r5"); +register cell rs asm("r6"); + +} diff --git a/vm/cpu-arm.64.cpp b/vm/cpu-arm.64.cpp new file mode 100644 index 0000000000..6951b3de0e --- /dev/null +++ b/vm/cpu-arm.64.cpp @@ -0,0 +1,25 @@ +#include "master.hpp" + +namespace factor { + +void factor_vm::dispatch_signal_handler(cell* sp, cell* pc, cell newpc) { + + // bool in_code_seg = code->seg->in_segment_p(*pc); + // cell cs_limit = ctx->callstack_seg->start + stack_reserved; + // signal_resumable = in_code_seg && *sp >= cs_limit; + + // if (signal_resumable) { + // dispatch_resumable_signal(sp, pc, handler); + // } else { + // dispatch_non_resumable_signal(sp, pc, handler, cs_limit); + // } + + // Poking with the stack pointer, which the above code does, means + // that pointers to stack-allocated objects will become + // corrupted. Therefore the root vectors needs to be cleared because + // their pointers to stack variables are now garbage. + data_roots.clear(); + code_roots.clear(); +} + +} \ No newline at end of file diff --git a/vm/cpu-arm.64.hpp b/vm/cpu-arm.64.hpp new file mode 100644 index 0000000000..b59abac052 --- /dev/null +++ b/vm/cpu-arm.64.hpp @@ -0,0 +1,13 @@ +namespace factor { + +#define FACTOR_CPU_STRING "arm.64" + +// register cell ds asm("r5"); +// register cell rs asm("r6"); +inline static void flush_icache(cell start, cell len) { + // int result; +} + + + +} diff --git a/vm/cpu-arm.hpp b/vm/cpu-arm.hpp index 4cd5316099..a0d4de56ec 100644 --- a/vm/cpu-arm.hpp +++ b/vm/cpu-arm.hpp @@ -1,5 +1,70 @@ namespace factor { -#define FACTOR_CPU_STRING "arm" +#define CALLSTACK_BOTTOM(ctx) (ctx->callstack_seg->end - sizeof(cell) * 5) // omg + +// void c_to_factor(cell quot); +// void lazy_jit_compile(cell quot); + +static const fixnum xt_tail_pic_offset = 4 + 1; // or 4 or whatever else... + + +static const unsigned char call_opcode = 0xe8; // omg, these are x86 values +static const unsigned char jmp_opcode = 0xe9; // omg + +static const unsigned SIGNAL_HANDLER_STACK_FRAME_SIZE = 64; // omg + + +// omg +inline static unsigned char call_site_opcode(cell return_address) { + return *(unsigned char*)(return_address - 5); +} + +// omg +inline static void check_call_site(cell return_address) { + unsigned char opcode = call_site_opcode(return_address); + FACTOR_ASSERT(opcode == call_opcode || opcode == jmp_opcode); + (void)opcode; // suppress warning when compiling without assertions +} + +// omg +inline static void* get_call_target(cell return_address) { + check_call_site(return_address); + return (void*)(*(int*)(return_address - 4) + return_address); +} + +// omg +inline static void set_call_target(cell return_address, cell target) { + check_call_site(return_address); + *(int*)(return_address - 4) = (uint32_t)(target - return_address); +} + +inline static bool tail_call_site_p(cell return_address) { + switch (call_site_opcode(return_address)) { + case jmp_opcode: + return true; + case call_opcode: + return false; + default: + abort(); + return false; + } +} + +// inline static unsigned int fpu_status(unsigned int status) { +// unsigned int r = 0; + +// if (status & 0x01) +// r |= FP_TRAP_INVALID_OPERATION; +// if (status & 0x04) +// r |= FP_TRAP_ZERO_DIVIDE; +// if (status & 0x08) +// r |= FP_TRAP_OVERFLOW; +// if (status & 0x10) +// r |= FP_TRAP_UNDERFLOW; +// if (status & 0x20) +// r |= FP_TRAP_INEXACT; + +// return r; +// } } -- 2.34.1