ruby-changes:54094
From: odaira <ko1@a...>
Date: Tue, 11 Dec 2018 08:23:03 +0900 (JST)
Subject: [ruby-changes:54094] odaira:r66315 (trunk): Native coroutine implementation for ppc64le Linux
odaira 2018-12-11 08:22:56 +0900 (Tue, 11 Dec 2018) New Revision: 66315 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=66315 Log: Native coroutine implementation for ppc64le Linux * configure.ac: enable fiber coroutine for powerpc64le-linux * coroutine/ppc64le/Context.S: coroutine_transfer implementation * coroutine/ppc64le/Context.h: coroutine implementation Added directories: trunk/coroutine/ppc64le/ Added files: trunk/coroutine/ppc64le/Context.S trunk/coroutine/ppc64le/Context.h Modified files: trunk/configure.ac Index: coroutine/ppc64le/Context.h =================================================================== --- coroutine/ppc64le/Context.h (nonexistent) +++ coroutine/ppc64le/Context.h (revision 66315) @@ -0,0 +1,54 @@ https://github.com/ruby/ruby/blob/trunk/coroutine/ppc64le/Context.h#L1 +#pragma once + +#include <assert.h> +#include <string.h> + +#if __cplusplus +extern "C" { +#endif + +#define COROUTINE __attribute__((noreturn)) void + +const size_t COROUTINE_REGISTERS = + 19 /* 18 general purpose registers (r14-r31) and 1 return address */ + + 4; /* space for fiber_entry() to store the link register */ + +typedef struct +{ + void **stack_pointer; +} coroutine_context; + +typedef COROUTINE(* coroutine_start)(coroutine_context *from, coroutine_context *self); + +static inline void coroutine_initialize( + coroutine_context *context, + coroutine_start start, + void *stack_pointer, + size_t stack_size +) { + /* Force 16-byte alignment */ + context->stack_pointer = (void**)((uintptr_t)stack_pointer & ~0xF); + + if (!start) { + assert(!context->stack_pointer); + /* We are main coroutine for this thread */ + return; + } + + context->stack_pointer -= COROUTINE_REGISTERS; + memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS); + + /* Skip a global prologue that sets the TOC register */ + context->stack_pointer[18] = ((char*)start) + 8; +} + +coroutine_context * coroutine_transfer(coroutine_context * current, coroutine_context * target); + +static inline void coroutine_destroy(coroutine_context * context) +{ + context->stack_pointer = NULL; +} + +#if __cplusplus +} +#endif Index: coroutine/ppc64le/Context.S =================================================================== --- coroutine/ppc64le/Context.S (nonexistent) +++ coroutine/ppc64le/Context.S (revision 66315) @@ -0,0 +1,72 @@ https://github.com/ruby/ruby/blob/trunk/coroutine/ppc64le/Context.S#L1 +.text +.align 2 + +.globl coroutine_transfer +.type coroutine_transfer, @function +coroutine_transfer: + # Make space on the stack for caller registers + addi 1,1,-152 + + # Save caller registers + std 14,0(1) + std 15,8(1) + std 16,16(1) + std 17,24(1) + std 18,32(1) + std 19,40(1) + std 20,48(1) + std 21,56(1) + std 22,64(1) + std 23,72(1) + std 24,80(1) + std 25,88(1) + std 26,96(1) + std 27,104(1) + std 28,112(1) + std 29,120(1) + std 30,128(1) + std 31,136(1) + + # Save return address + mflr 0 + std 0,144(1) + + # Save stack pointer to first argument + std 1,0(3) + + # Load stack pointer from second argument + ld 1,0(4) + + # Restore caller registers + ld 14,0(1) + ld 15,8(1) + ld 16,16(1) + ld 17,24(1) + ld 18,32(1) + ld 19,40(1) + ld 20,48(1) + ld 21,56(1) + ld 22,64(1) + ld 23,72(1) + ld 24,80(1) + ld 25,88(1) + ld 26,96(1) + ld 27,104(1) + ld 28,112(1) + ld 29,120(1) + ld 30,128(1) + ld 31,136(1) + + # Load return address + ld 0,144(1) + mtlr 0 + + # Pop stack frame + addi 1,1,152 + + # Jump to return address + blr + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif Index: configure.ac =================================================================== --- configure.ac (revision 66314) +++ configure.ac (revision 66315) @@ -2331,6 +2331,9 @@ AS_CASE(["$rb_cv_fiber_coroutine"], [yes https://github.com/ruby/ruby/blob/trunk/configure.ac#L2331 [x64-mingw32], [ rb_cv_fiber_coroutine=win64 ], + [powerpc64le-linux], [ + rb_cv_fiber_coroutine=ppc64le + ], [*], [ rb_cv_fiber_coroutine= ] -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/