313 lines
10 KiB
Diff
313 lines
10 KiB
Diff
--- a/common.mk 2021-04-05 15:39:38.000000000 +0300
|
|
+++ b/common.mk 2021-09-30 15:45:14.692152209 +0300
|
|
@@ -936,6 +936,8 @@
|
|
strlcpy.$(OBJEXT): {$(VPATH)}strlcpy.c
|
|
strstr.$(OBJEXT): {$(VPATH)}strstr.c
|
|
nt.$(OBJEXT): {$(VPATH)}nt.c
|
|
+e2k.$(OBJEXT): {$(VPATH)}e2k.c
|
|
+ $(CC) $(CFLAGS) -c $<
|
|
|
|
.coroutine_obj $(COROUTINE_OBJ): \
|
|
{$(VPATH)}$(COROUTINE_SRC) \
|
|
--- a/configure 2021-04-05 15:39:40.000000000 +0300
|
|
+++ b/configure 2021-09-30 15:45:14.697151380 +0300
|
|
@@ -26343,6 +26343,16 @@
|
|
|
|
fi
|
|
|
|
+if test x"$target_cpu" = xe2k; then :
|
|
+ case " $LIBOBJS " in
|
|
+ *" e2k.$ac_objext "* ) ;;
|
|
+ *) LIBOBJS="$LIBOBJS e2k.$ac_objext"
|
|
+ ;;
|
|
+esac
|
|
+
|
|
+
|
|
+fi
|
|
+
|
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether right shift preserve sign bit" >&5
|
|
$as_echo_n "checking whether right shift preserve sign bit... " >&6; }
|
|
if ${rb_cv_rshift_sign+:} false; then :
|
|
@@ -26451,7 +26461,7 @@
|
|
else
|
|
|
|
case "$archs" in #(
|
|
- m68*|x86*|x64|i?86|ppc*|sparc*|alpha*) :
|
|
+ m68*|x86*|x64|i?86|ppc*|sparc*|alpha*|e2k*) :
|
|
dir=-1 ;; #(
|
|
hppa*) :
|
|
dir=+1 ;; #(
|
|
@@ -26548,7 +26558,7 @@
|
|
else
|
|
|
|
case "$target_cpu" in #(
|
|
- m68*|x86*|x64|i?86|ppc*|sparc*|alpha*) :
|
|
+ m68*|x86*|x64|i?86|ppc*|sparc*|alpha*|e2k*) :
|
|
dir=-1 ;; #(
|
|
hppa*) :
|
|
dir=+1 ;; #(
|
|
--- a/configure.ac 2021-04-05 15:39:38.000000000 +0300
|
|
+++ b/configure.ac 2021-09-30 15:45:14.698151123 +0300
|
|
@@ -2259,6 +2259,10 @@
|
|
])])
|
|
])
|
|
|
|
+AS_IF([test x"$target_cpu" = xe2k], [
|
|
+ AC_LIBOBJ([e2k])
|
|
+])
|
|
+
|
|
AC_CACHE_CHECK(whether right shift preserve sign bit, rb_cv_rshift_sign,
|
|
[AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY([], [(-1==(-1>>1))])],
|
|
rb_cv_rshift_sign=yes,
|
|
--- a/cont.c 2021-04-05 15:39:38.000000000 +0300
|
|
+++ b/cont.c 2021-09-30 15:45:32.552045138 +0300
|
|
@@ -189,6 +189,11 @@
|
|
VALUE *stack;
|
|
VALUE *stack_src;
|
|
size_t stack_size;
|
|
+#ifdef __e2k__
|
|
+ VALUE *register_stack;
|
|
+ VALUE *register_stack_src;
|
|
+ size_t register_stack_size;
|
|
+#endif
|
|
} machine;
|
|
rb_execution_context_t saved_ec;
|
|
rb_jmpbuf_t jmpbuf;
|
|
@@ -895,7 +900,12 @@
|
|
}
|
|
}
|
|
}
|
|
-
|
|
+#ifdef __e2k__
|
|
+ if (cont->machine.register_stack) {
|
|
+ rb_gc_mark_locations(cont->machine.register_stack,
|
|
+ cont->machine.register_stack + cont->machine.register_stack_size);
|
|
+ }
|
|
+#endif
|
|
RUBY_MARK_LEAVE("cont");
|
|
}
|
|
|
|
@@ -924,6 +934,9 @@
|
|
}
|
|
|
|
RUBY_FREE_UNLESS_NULL(cont->saved_vm_stack.ptr);
|
|
+#ifdef __e2k__
|
|
+ RUBY_FREE_UNLESS_NULL(cont->machine.register_stack);
|
|
+#endif
|
|
|
|
if (mjit_enabled && cont->mjit_cont != NULL) {
|
|
mjit_cont_free(cont->mjit_cont);
|
|
@@ -952,7 +965,12 @@
|
|
if (cont->machine.stack) {
|
|
size += cont->machine.stack_size * sizeof(*cont->machine.stack);
|
|
}
|
|
-
|
|
+#ifdef __e2k__
|
|
+ if (cont->machine.register_stack) {
|
|
+ size += cont->machine.register_stack_size *
|
|
+ sizeof(*cont->machine.register_stack);
|
|
+ }
|
|
+#endif
|
|
return size;
|
|
}
|
|
|
|
@@ -1072,6 +1090,24 @@
|
|
|
|
FLUSH_REGISTER_WINDOWS;
|
|
MEMCPY(cont->machine.stack, cont->machine.stack_src, VALUE, size);
|
|
+
|
|
+#ifdef __e2k__
|
|
+ rb_e2k_flushr();
|
|
+ th->ec->machine.register_stack_size =
|
|
+ rb_e2k_get_procedure_stack(&th->ec->machine.register_stack_start);
|
|
+ th->ec->machine.register_stack_end =
|
|
+ (VALUE *)((char *)th->ec->machine.register_stack_start +
|
|
+ th->ec->machine.register_stack_size);
|
|
+ size = cont->machine.register_stack_size =
|
|
+ th->ec->machine.register_stack_end - th->ec->machine.register_stack_start;
|
|
+ cont->machine.register_stack_src = th->ec->machine.register_stack_start;
|
|
+ if (cont->machine.register_stack) {
|
|
+ REALLOC_N(cont->machine.register_stack, VALUE, size);
|
|
+ } else {
|
|
+ cont->machine.register_stack = ALLOC_N(VALUE, size);
|
|
+ }
|
|
+ MEMCPY(cont->machine.register_stack, cont->machine.register_stack_src, VALUE, size);
|
|
+#endif
|
|
}
|
|
|
|
static const rb_data_type_t cont_data_type = {
|
|
@@ -1093,6 +1129,10 @@
|
|
/* saved_ec->machine.stack_end should be NULL */
|
|
/* because it may happen GC afterward */
|
|
sec->machine.stack_end = NULL;
|
|
+#ifdef __e2k__
|
|
+ sec->machine.register_stack_start = 0;
|
|
+ sec->machine.register_stack_end = 0;
|
|
+#endif
|
|
}
|
|
|
|
static void
|
|
@@ -1359,6 +1399,12 @@
|
|
MEMCPY(cont->machine.stack_src, cont->machine.stack,
|
|
VALUE, cont->machine.stack_size);
|
|
}
|
|
+#ifdef __e2k__
|
|
+ if (cont->machine.register_stack_src) {
|
|
+ MEMCPY(cont->machine.register_stack_src, cont->machine.register_stack,
|
|
+ VALUE, cont->machine.register_stack_size);
|
|
+ }
|
|
+#endif
|
|
|
|
ruby_longjmp(cont->jmpbuf, 1);
|
|
}
|
|
@@ -1500,6 +1546,9 @@
|
|
static VALUE
|
|
rb_callcc(VALUE self)
|
|
{
|
|
+#ifdef __e2k__
|
|
+ rb_fatal("continuation not supported for e2k");
|
|
+#endif
|
|
volatile int called;
|
|
volatile VALUE val = cont_capture(&called);
|
|
|
|
--- a/coroutine/ucontext/Context.h 2021-04-05 15:39:38.000000000 +0300
|
|
+++ b/coroutine/ucontext/Context.h 2021-09-30 15:45:14.699150870 +0300
|
|
@@ -47,8 +47,11 @@
|
|
context->state.uc_stack.ss_sp = (char*)stack;
|
|
context->state.uc_stack.ss_flags = 0;
|
|
context->state.uc_link = NULL;
|
|
-
|
|
+#ifdef __e2k__
|
|
+ assert(!makecontext_e2k(&context->state, (void(*)(void))coroutine_trampoline, 2, (void*)start, (void*)context));
|
|
+#else
|
|
makecontext(&context->state, (void(*)(void))coroutine_trampoline, 2, (void*)start, (void*)context);
|
|
+#endif
|
|
}
|
|
|
|
static inline struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target)
|
|
@@ -67,4 +70,7 @@
|
|
context->state.uc_stack.ss_sp = NULL;
|
|
context->state.uc_stack.ss_size = 0;
|
|
context->from = NULL;
|
|
+#ifdef __e2k__
|
|
+ freecontext_e2k(&context->state);
|
|
+#endif
|
|
}
|
|
--- a/gc.c 2021-04-05 15:39:38.000000000 +0300
|
|
+++ b/gc.c 2021-09-30 15:45:32.554044960 +0300
|
|
@@ -4991,6 +4991,16 @@
|
|
mark_locations_array(objspace, save_regs_gc_mark.v, numberof(save_regs_gc_mark.v));
|
|
|
|
mark_stack_locations(objspace, ec, stack_start, stack_end);
|
|
+#ifdef __e2k__
|
|
+ /* Get current stack for current thread and mark */
|
|
+ ec->machine.register_stack_size =
|
|
+ rb_e2k_get_procedure_stack(&ec->machine.register_stack_start);
|
|
+ ec->machine.register_stack_end =
|
|
+ (VALUE *)((char *)ec->machine.register_stack_start +
|
|
+ ec->machine.register_stack_size);
|
|
+ rb_gc_mark_locations(ec->machine.register_stack_start,
|
|
+ ec->machine.register_stack_end);
|
|
+#endif
|
|
}
|
|
|
|
void
|
|
@@ -5001,6 +5011,13 @@
|
|
|
|
GET_STACK_BOUNDS(stack_start, stack_end, 0);
|
|
mark_stack_locations(objspace, ec, stack_start, stack_end);
|
|
+#ifdef __e2k__
|
|
+ /* In thread register stack should be saved to buffer and we mark it.
|
|
+ * We can't just save start of stack and move stackend by stackpointer
|
|
+ */
|
|
+ rb_gc_mark_locations(ec->machine.register_stack_start,
|
|
+ ec->machine.register_stack_end);
|
|
+#endif
|
|
}
|
|
|
|
static void
|
|
--- a/include/ruby/defines.h 2021-04-05 15:39:38.000000000 +0300
|
|
+++ b/include/ruby/defines.h 2021-09-30 15:45:14.701150375 +0300
|
|
@@ -427,6 +427,10 @@
|
|
#if defined(__sparc)
|
|
void rb_sparc_flush_register_windows(void);
|
|
# define FLUSH_REGISTER_WINDOWS rb_sparc_flush_register_windows()
|
|
+#elif defined(__e2k__)
|
|
+size_t rb_e2k_get_procedure_stack(unsigned long long **ps_buf);
|
|
+void rb_e2k_flushr(void);
|
|
+# define FLUSH_REGISTER_WINDOWS rb_e2k_flushr()
|
|
#else
|
|
# define FLUSH_REGISTER_WINDOWS ((void)0)
|
|
#endif
|
|
--- a/thread.c 2021-04-05 15:39:38.000000000 +0300
|
|
+++ b/thread.c 2021-09-30 15:45:32.555044872 +0300
|
|
@@ -160,9 +160,23 @@
|
|
rb_unblock_function_t *ubf, void *arg, int fail_if_interrupted);
|
|
static inline void blocking_region_end(rb_thread_t *th, struct rb_blocking_region_buffer *region);
|
|
|
|
+#ifdef __e2k__
|
|
+#define RB_GC_SAVE_MACHINE_REGISTER_STACK(th) \
|
|
+ do { \
|
|
+ (th)->ec->machine.register_stack_size = \
|
|
+ rb_e2k_get_procedure_stack(&(th)->ec->machine.register_stack_start); \
|
|
+ (th)->ec->machine.register_stack_end = \
|
|
+ (VALUE *)((char *)(th)->ec->machine.register_stack_start + \
|
|
+ (th)->ec->machine.register_stack_size); \
|
|
+ } while (0)
|
|
+#else
|
|
+#define RB_GC_SAVE_MACHINE_REGISTER_STACK(th)
|
|
+#endif
|
|
+
|
|
#define RB_GC_SAVE_MACHINE_CONTEXT(th) \
|
|
do { \
|
|
FLUSH_REGISTER_WINDOWS; \
|
|
+ RB_GC_SAVE_MACHINE_REGISTER_STACK(th); \
|
|
setjmp((th)->ec->machine.regs); \
|
|
SET_MACHINE_STACK_END(&(th)->ec->machine.stack_end); \
|
|
} while (0)
|
|
@@ -607,6 +621,9 @@
|
|
th->status = THREAD_KILLED;
|
|
// The thread stack doesn't exist in the forked process:
|
|
th->ec->machine.stack_start = th->ec->machine.stack_end = NULL;
|
|
+#ifdef __e2k__
|
|
+ th->ec->machine.register_stack_start = th->ec->machine.register_stack_end = 0;
|
|
+#endif
|
|
|
|
rb_threadptr_root_fiber_terminate(th);
|
|
}
|
|
@@ -728,6 +745,9 @@
|
|
rb_ec_initialize_vm_stack(th->ec, vm_stack, size);
|
|
th->ec->machine.stack_start = STACK_DIR_UPPER(vm_stack + size, vm_stack);
|
|
th->ec->machine.stack_maxsize -= size * sizeof(VALUE);
|
|
+#ifdef __e2k__
|
|
+ th->ec->machine.register_stack_start = 0;
|
|
+#endif
|
|
|
|
ruby_thread_set_native(th);
|
|
|
|
--- a/tool/m4/ruby_stack_grow_direction.m4 2021-04-05 15:39:38.000000000 +0300
|
|
+++ b/tool/m4/ruby_stack_grow_direction.m4 2021-09-30 15:45:14.701150375 +0300
|
|
@@ -3,7 +3,7 @@
|
|
AS_VAR_PUSHDEF([stack_grow_dir], [rb_cv_stack_grow_dir_$1])
|
|
AC_CACHE_CHECK(stack growing direction on $1, stack_grow_dir, [
|
|
AS_CASE(["$1"],
|
|
-[m68*|x86*|x64|i?86|ppc*|sparc*|alpha*], [ $2=-1],
|
|
+[m68*|x86*|x64|i?86|ppc*|sparc*|alpha*|e2k*], [ $2=-1],
|
|
[hppa*], [ $2=+1],
|
|
[
|
|
AC_TRY_RUN([
|
|
--- a/vm_core.h 2021-04-05 15:39:38.000000000 +0300
|
|
+++ b/vm_core.h 2021-09-30 15:45:32.555044872 +0300
|
|
@@ -887,6 +887,11 @@
|
|
VALUE *stack_start;
|
|
VALUE *stack_end;
|
|
size_t stack_maxsize;
|
|
+#ifdef __e2k__
|
|
+ VALUE *register_stack_start;
|
|
+ VALUE *register_stack_end;
|
|
+ size_t register_stack_size;
|
|
+#endif
|
|
RUBY_ALIGNAS(SIZEOF_VALUE) jmp_buf regs;
|
|
} machine;
|
|
} rb_execution_context_t;
|