-PLAF_MASTER_HEADERS += \
- cpu-arm.hpp
+PLAF_MASTER_HEADERS += vm/cpu-arm.hpp
--- /dev/null
+PLAF_MASTER_HEADERS += vm/cpu-arm.hpp
--- /dev/null
+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
--- /dev/null
+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
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
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 \
--- /dev/null
+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
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
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
include vm/Config.macosx
include vm/Config.x86.fat
SITE_CFLAGS += -arch i386 -arch x86_64
+SITE_CFLAGS += -mmacosx-version-min=10.9
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
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
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
--- /dev/null
+#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
--- /dev/null
+namespace factor {
+
+#define FACTOR_CPU_STRING "arm.32"
+
+register cell ds asm("r5");
+register cell rs asm("r6");
+
+}
--- /dev/null
+#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
--- /dev/null
+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;
+}
+
+
+
+}
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;
+// }
}