Fix and improve coroutines for Darwin (macOS) ppc/ppc64. (#5975)

This commit is contained in:
Sergey Fedorov 2022-10-19 18:49:45 +08:00 committed by GitHub
parent fc3137ef54
commit 567725ed30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
Notes: git 2022-10-19 10:50:05 +00:00
Merged-By: ioquatix <samuel@codeotaku.com>
17 changed files with 196 additions and 120 deletions

View File

@ -869,8 +869,11 @@ typedef struct {
int type; int type;
} DebugInfoValue; } DebugInfoValue;
/* TODO: Big Endian */ #if defined(WORDS_BIGENDIAN)
#define MERGE_2INTS(a,b,sz) (((uint64_t)(a)<<sz)|(b))
#else
#define MERGE_2INTS(a,b,sz) (((uint64_t)(b)<<sz)|(a)) #define MERGE_2INTS(a,b,sz) (((uint64_t)(b)<<sz)|(a))
#endif
static uint16_t static uint16_t
get_uint16(const uint8_t *p) get_uint16(const uint8_t *p)

View File

@ -1902,8 +1902,8 @@ AS_CASE(["${target_cpu}-${target_os}:${target_archs}"],
[universal-darwin*:*ppc*], [ [universal-darwin*:*ppc*], [
AC_LIBSOURCES(alloca.c) AC_LIBSOURCES(alloca.c)
AC_SUBST([ALLOCA], [\${LIBOBJDIR}alloca.${ac_objext}]) AC_SUBST([ALLOCA], [\${LIBOBJDIR}alloca.${ac_objext}])
RUBY_DEFINE_IF([defined __powerpc__], C_ALLOCA, 1) RUBY_DEFINE_IF([defined __POWERPC__], C_ALLOCA, 1) # Darwin defines __POWERPC__ for ppc and ppc64 both
RUBY_DEFINE_IF([defined __powerpc__], alloca, alloca) RUBY_DEFINE_IF([defined __POWERPC__], alloca, alloca)
], ],
[ [
AC_FUNC_ALLOCA AC_FUNC_ALLOCA
@ -2573,10 +2573,13 @@ AS_CASE([$coroutine_type], [yes|''], [
[arm64-darwin*], [ [arm64-darwin*], [
coroutine_type=arm64 coroutine_type=arm64
], ],
[powerpc-darwin*], [ # Correct target name is powerpc*-, but Ruby seems to prefer ppc*-.
# Notice that Darwin PPC ABI differs from AIX and ELF.
# Adding PPC targets for AIX, *BSD and *Linux will require separate implementations.
[powerpc-darwin*|ppc-darwin*], [
coroutine_type=ppc coroutine_type=ppc
], ],
[powerpc64-darwin*], [ [powerpc64-darwin*|ppc64-darwin*], [
coroutine_type=ppc64 coroutine_type=ppc64
], ],
[x*64-linux*], [ [x*64-linux*], [

View File

@ -1,73 +1,90 @@
; Based on the code by Samuel Williams. Created by Sergey Fedorov on 04/06/2022.
; Credits to Samuel Williams, Rei Odaira and Iain Sandoe. Errors, if any, are mine.
; Some relevant examples: https://github.com/gcc-mirror/gcc/blob/master/libphobos/libdruntime/config/powerpc/switchcontext.S
; https://github.com/gcc-mirror/gcc/blob/master/libgcc/config/rs6000/darwin-gpsave.S
; https://www.ibm.com/docs/en/aix/7.2?topic=epilogs-saving-gprs-only
; ppc32 version may be re-written compactly with stmw/lwm, but the code wonʼt be faster, see: https://github.com/ruby/ruby/pull/5927#issuecomment-1139730541
; Notice that this code is only for Darwin (macOS). Darwin ABI differs from AIX and ELF.
; To add support for AIX, *BSD or *Linux, please make separate implementations.
#define TOKEN_PASTE(x,y) x##y #define TOKEN_PASTE(x,y) x##y
#define PREFIXED_SYMBOL(prefix,name) TOKEN_PASTE(prefix,name) #define PREFIXED_SYMBOL(prefix,name) TOKEN_PASTE(prefix,name)
.machine ppc7400 ; = G4, Rosetta
.text .text
.align 2
.globl PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer) .globl PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer)
.align 2
PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer): PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer):
# Make space on the stack for caller registers ; Make space on the stack for caller registers
addi r1,r1,-80 ; (Should we rather use red zone? See libphobos example.)
subi r1,r1,80
# Save caller registers ; Get LR
stw r13,0(r1)
stw r14,4(r1)
stw r15,8(r1)
stw r16,12(r1)
stw r17,16(r1)
stw r18,20(r1)
stw r19,24(r1)
stw r20,28(r1)
stw r21,32(r1)
stw r22,36(r1)
stw r23,40(r1)
stw r24,44(r1)
stw r25,48(r1)
stw r26,52(r1)
stw r27,56(r1)
stw r28,60(r1)
stw r29,64(r1)
stw r30,68(r1)
stw r31,72(r1)
# Save return address
mflr r0 mflr r0
; Save caller registers
stw r31,0(r1)
stw r30,4(r1)
stw r29,8(r1)
stw r28,12(r1)
stw r27,16(r1)
stw r26,20(r1)
stw r25,24(r1)
stw r24,28(r1)
stw r23,32(r1)
stw r22,36(r1)
stw r21,40(r1)
stw r20,44(r1)
stw r19,48(r1)
stw r18,52(r1)
stw r17,56(r1)
stw r16,60(r1)
stw r15,64(r1)
stw r14,68(r1)
stw r13,72(r1)
; Save return address
; Possibly should rather be saved into linkage area, see libphobos and IBM docs
stw r0,76(r1) stw r0,76(r1)
# Save stack pointer to first argument ; Save stack pointer to first argument
stw r1,0(r3) stw r1,0(r3)
# Load stack pointer from second argument ; Load stack pointer from second argument
lwz r1,0(r4) lwz r1,0(r4)
# Restore caller registers ; Load return address
lwz r13,0(r1)
lwz r14,4(r1)
lwz r15,8(r1)
lwz r16,12(r1)
lwz r17,16(r1)
lwz r18,20(r1)
lwz r19,24(r1)
lwz r20,28(r1)
lwz r21,32(r1)
lwz r22,36(r1)
lwz r23,40(r1)
lwz r24,44(r1)
lwz r25,48(r1)
lwz r26,52(r1)
lwz r27,56(r1)
lwz r28,60(r1)
lwz r29,64(r1)
lwz r30,68(r1)
lwz r31,72(r1)
# Load return address
lwz r0,76(r1) lwz r0,76(r1)
; Restore caller registers
lwz r13,72(r1)
lwz r14,68(r1)
lwz r15,64(r1)
lwz r16,60(r1)
lwz r17,56(r1)
lwz r18,52(r1)
lwz r19,48(r1)
lwz r20,44(r1)
lwz r21,40(r1)
lwz r22,36(r1)
lwz r23,32(r1)
lwz r24,28(r1)
lwz r25,24(r1)
lwz r26,20(r1)
lwz r27,16(r1)
lwz r28,12(r1)
lwz r29,8(r1)
lwz r30,4(r1)
lwz r31,0(r1)
; Set LR
mtlr r0 mtlr r0
# Pop stack frame ; Pop stack frame
addi r1,r1,80 addi r1,r1,80
# Jump to return address ; Jump to return address
blr blr

View File

@ -9,6 +9,7 @@
#include <string.h> #include <string.h>
#define COROUTINE __attribute__((noreturn)) void #define COROUTINE __attribute__((noreturn)) void
#define COROUTINE_LIMITED_ADDRESS_SPACE
enum { enum {
COROUTINE_REGISTERS = COROUTINE_REGISTERS =

View File

@ -1,70 +1,89 @@
; Based on the code by Samuel Williams. Created by Sergey Fedorov on 04/06/2022.
; Credits to Samuel Williams, Rei Odaira and Iain Sandoe. Errors, if any, are mine.
; Some relevant examples: https://github.com/gcc-mirror/gcc/blob/master/libphobos/libdruntime/config/powerpc/switchcontext.S
; https://github.com/gcc-mirror/gcc/blob/master/libgcc/config/rs6000/darwin-gpsave.S
; https://www.ibm.com/docs/en/aix/7.2?topic=epilogs-saving-gprs-only
; Notice that this code is only for Darwin (macOS). Darwin ABI differs from AIX and ELF.
; To add support for AIX, *BSD or *Linux, please make separate implementations.
#define TOKEN_PASTE(x,y) x##y #define TOKEN_PASTE(x,y) x##y
#define PREFIXED_SYMBOL(prefix,name) TOKEN_PASTE(prefix,name) #define PREFIXED_SYMBOL(prefix,name) TOKEN_PASTE(prefix,name)
.machine ppc64 ; = G5
.text .text
.align 3
.globl PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer) .globl PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer)
.align 2
PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer): PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer):
# Make space on the stack for caller registers ; Make space on the stack for caller registers
addi r1,r1,-152 ; (Should we rather use red zone? See libphobos example.)
subi r1,r1,160
# Save caller registers ; Get LR
std r14,0(r1)
std r15,8(r1)
std r16,16(r1)
std r17,24(r1)
std r18,32(r1)
std r19,40(r1)
std r20,48(r1)
std r21,56(r1)
std r22,64(r1)
std r23,72(r1)
std r24,80(r1)
std r25,88(r1)
std r26,96(r1)
std r27,104(r1)
std r28,112(r1)
std r29,120(r1)
std r30,128(r1)
std r31,136(r1)
# Save return address
mflr r0 mflr r0
std r0,144(r1)
# Save stack pointer to first argument ; Save caller registers
std r31,0(r1)
std r30,8(r1)
std r29,16(r1)
std r28,24(r1)
std r27,32(r1)
std r26,40(r1)
std r25,48(r1)
std r24,56(r1)
std r23,64(r1)
std r22,72(r1)
std r21,80(r1)
std r20,88(r1)
std r19,96(r1)
std r18,104(r1)
std r17,112(r1)
std r16,120(r1)
std r15,128(r1)
std r14,136(r1)
std r13,144(r1)
; Save return address
; Possibly should rather be saved into linkage area, see libphobos and IBM docs
std r0,152(r1)
; Save stack pointer to first argument
std r1,0(r3) std r1,0(r3)
# Load stack pointer from second argument ; Load stack pointer from second argument
ld r1,0(r4) ld r1,0(r4)
# Restore caller registers ; Load return address
ld r14,0(r1) ld r0,152(r1)
ld r15,8(r1)
ld r16,16(r1)
ld r17,24(r1)
ld r18,32(r1)
ld r19,40(r1)
ld r20,48(r1)
ld r21,56(r1)
ld r22,64(r1)
ld r23,72(r1)
ld r24,80(r1)
ld r25,88(r1)
ld r26,96(r1)
ld r27,104(r1)
ld r28,112(r1)
ld r29,120(r1)
ld r30,128(r1)
ld r31,136(r1)
# Load return address ; Restore caller registers
ld r0,144(r1) ld r13,144(r1)
ld r14,136(r1)
ld r15,128(r1)
ld r16,120(r1)
ld r17,112(r1)
ld r18,104(r1)
ld r19,96(r1)
ld r20,88(r1)
ld r21,80(r1)
ld r22,72(r1)
ld r23,64(r1)
ld r24,56(r1)
ld r25,48(r1)
ld r26,40(r1)
ld r27,32(r1)
ld r28,24(r1)
ld r29,16(r1)
ld r30,8(r1)
ld r31,0(r1)
; Set LR
mtlr r0 mtlr r0
# Pop stack frame ; Pop stack frame
addi r1,r1,152 addi r1,r1,160
# Jump to return address ; Jump to return address
blr blr

View File

@ -12,7 +12,7 @@
enum { enum {
COROUTINE_REGISTERS = COROUTINE_REGISTERS =
19 /* 18 general purpose registers (r14r31) and 1 return address */ 20 /* 19 general purpose registers (r13r31) and 1 return address */
+ 4 /* space for fiber_entry() to store the link register */ + 4 /* space for fiber_entry() to store the link register */
}; };
@ -44,7 +44,7 @@ static inline void coroutine_initialize(
memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS); memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
/* Skip a global prologue that sets the TOC register */ /* Skip a global prologue that sets the TOC register */
context->stack_pointer[18] = ((char*)start) + 8; context->stack_pointer[19] = ((char*)start) + 8;
} }
struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target); struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target);

6
dln.c
View File

@ -41,6 +41,10 @@ static void dln_loaderror(const char *format, ...);
# include <strings.h> # include <strings.h>
#endif #endif
#if defined __APPLE__
# include <AvailabilityMacros.h>
#endif
#ifndef xmalloc #ifndef xmalloc
void *xmalloc(); void *xmalloc();
void *xcalloc(); void *xcalloc();
@ -58,7 +62,7 @@ void *xrealloc();
#include <sys/stat.h> #include <sys/stat.h>
#ifndef S_ISDIR #ifndef S_ISDIR
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif #endif
#ifdef HAVE_SYS_PARAM_H #ifdef HAVE_SYS_PARAM_H

View File

@ -668,7 +668,7 @@ bug_important_message(FILE *out, const char *const msg, size_t len)
#undef CRASH_REPORTER_MAY_BE_CREATED #undef CRASH_REPORTER_MAY_BE_CREATED
#if defined(__APPLE__) && \ #if defined(__APPLE__) && \
(!defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6) (!defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6 || defined(__POWERPC__)) /* 10.6 PPC case */
# define CRASH_REPORTER_MAY_BE_CREATED # define CRASH_REPORTER_MAY_BE_CREATED
#endif #endif
static void static void

21
gc.c
View File

@ -1359,6 +1359,27 @@ tick(void)
return val; return val;
} }
/* Implementation for macOS PPC by @nobu
* See: https://github.com/ruby/ruby/pull/5975#discussion_r890045558
*/
#elif defined(__POWERPC__) && defined(__APPLE__)
typedef unsigned long long tick_t;
#define PRItick "llu"
static __inline__ tick_t
tick(void)
{
unsigned long int upper, lower, tmp;
# define mftbu(r) __asm__ volatile("mftbu %0" : "=r"(r))
# define mftb(r) __asm__ volatile("mftb %0" : "=r"(r))
do {
mftbu(upper);
mftb(lower);
mftbu(tmp);
} while (tmp != upper);
return ((tick_t)upper << 32) | lower;
}
#elif defined(__aarch64__) && defined(__GNUC__) #elif defined(__aarch64__) && defined(__GNUC__)
typedef unsigned long tick_t; typedef unsigned long tick_t;
#define PRItick "lu" #define PRItick "lu"

4
gc.h
View File

@ -6,10 +6,12 @@
#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movq\t%%rsp, %0" : "=r" (*(p))) #define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movq\t%%rsp, %0" : "=r" (*(p)))
#elif defined(__i386) && defined(__GNUC__) #elif defined(__i386) && defined(__GNUC__)
#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movl\t%%esp, %0" : "=r" (*(p))) #define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movl\t%%esp, %0" : "=r" (*(p)))
#elif (defined(__powerpc__) || defined(__powerpc64__)) && defined(__GNUC__) && !defined(_AIX) #elif (defined(__powerpc__) || defined(__powerpc64__)) && defined(__GNUC__) && !defined(_AIX) && !defined(__APPLE__) // Not Apple is NEEDED to unbreak ppc64 build on Darwin. Don't ask.
#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mr\t%0, %%r1" : "=r" (*(p))) #define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mr\t%0, %%r1" : "=r" (*(p)))
#elif (defined(__powerpc__) || defined(__powerpc64__)) && defined(__GNUC__) && defined(_AIX) #elif (defined(__powerpc__) || defined(__powerpc64__)) && defined(__GNUC__) && defined(_AIX)
#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mr %0,1" : "=r" (*(p))) #define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mr %0,1" : "=r" (*(p)))
#elif defined(__POWERPC__) && defined(__APPLE__) // Darwin ppc and ppc64
#define SET_MACHINE_STACK_END(p) __asm__ volatile("mr %0, r1" : "=r" (*(p)))
#elif defined(__aarch64__) && defined(__GNUC__) #elif defined(__aarch64__) && defined(__GNUC__)
#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mov\t%0, sp" : "=r" (*(p))) #define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mov\t%0, sp" : "=r" (*(p)))
#else #else

View File

@ -113,6 +113,8 @@
# define UNALIGNED_WORD_ACCESS 1 # define UNALIGNED_WORD_ACCESS 1
#elif defined(__powerpc64__) #elif defined(__powerpc64__)
# define UNALIGNED_WORD_ACCESS 1 # define UNALIGNED_WORD_ACCESS 1
#elif defined(__POWERPC__) // __POWERPC__ is defined for ppc and ppc64 on Darwin
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__aarch64__) #elif defined(__aarch64__)
# define UNALIGNED_WORD_ACCESS 1 # define UNALIGNED_WORD_ACCESS 1
#elif defined(__mc68020__) #elif defined(__mc68020__)

View File

@ -49,10 +49,11 @@
# endif # endif
#endif #endif
/* __POWERPC__ added to accommodate Darwin case. */
#ifndef UNALIGNED_WORD_ACCESS #ifndef UNALIGNED_WORD_ACCESS
# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \ defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \
defined(__powerpc64__) || defined(__aarch64__) || \ defined(__powerpc64__) || defined(__POWERPC__) || defined(__aarch64__) || \
defined(__mc68020__) defined(__mc68020__)
# define UNALIGNED_WORD_ACCESS 1 # define UNALIGNED_WORD_ACCESS 1
# else # else

View File

@ -34,10 +34,11 @@
#error "Only strictly little or big endian supported" #error "Only strictly little or big endian supported"
#endif #endif
/* __POWERPC__ added to accommodate Darwin case. */
#ifndef UNALIGNED_WORD_ACCESS #ifndef UNALIGNED_WORD_ACCESS
# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \ defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \
defined(__powerpc64__) || defined(__aarch64__) || \ defined(__powerpc64__) || defined(__POWERPC__) || defined(__aarch64__) || \
defined(__mc68020__) defined(__mc68020__)
# define UNALIGNED_WORD_ACCESS 1 # define UNALIGNED_WORD_ACCESS 1
# endif # endif

3
st.c
View File

@ -1671,10 +1671,11 @@ st_values_check(st_table *tab, st_data_t *values, st_index_t size,
*/ */
#define FNV_32_PRIME 0x01000193 #define FNV_32_PRIME 0x01000193
/* __POWERPC__ added to accommodate Darwin case. */
#ifndef UNALIGNED_WORD_ACCESS #ifndef UNALIGNED_WORD_ACCESS
# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \ defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \
defined(__powerpc64__) || defined(__aarch64__) || \ defined(__powerpc64__) || defined(__POWERPC__) || defined(__aarch64__) || \
defined(__mc68020__) defined(__mc68020__)
# define UNALIGNED_WORD_ACCESS 1 # define UNALIGNED_WORD_ACCESS 1
# endif # endif

View File

@ -5,6 +5,7 @@ AS_CASE([$1],
[arm64], [], [arm64], [],
[*64], [ARCH_FLAG=-m64], [*64], [ARCH_FLAG=-m64],
[[i[3-6]86]], [ARCH_FLAG=-m32], [[i[3-6]86]], [ARCH_FLAG=-m32],
[ppc], [ARCH_FLAG=-m32],
[AC_MSG_ERROR(unknown target architecture: $target_archs)] [AC_MSG_ERROR(unknown target architecture: $target_archs)]
) )
AC_MSG_RESULT([$ARCH_FLAG]) AC_MSG_RESULT([$ARCH_FLAG])

View File

@ -780,8 +780,8 @@ typedef struct rb_vm_struct {
#define RUBY_VM_FIBER_VM_STACK_SIZE ( 16 * 1024 * sizeof(VALUE)) /* 64 KB or 128 KB */ #define RUBY_VM_FIBER_VM_STACK_SIZE ( 16 * 1024 * sizeof(VALUE)) /* 64 KB or 128 KB */
#define RUBY_VM_FIBER_VM_STACK_SIZE_MIN ( 2 * 1024 * sizeof(VALUE)) /* 8 KB or 16 KB */ #define RUBY_VM_FIBER_VM_STACK_SIZE_MIN ( 2 * 1024 * sizeof(VALUE)) /* 8 KB or 16 KB */
#define RUBY_VM_FIBER_MACHINE_STACK_SIZE ( 64 * 1024 * sizeof(VALUE)) /* 256 KB or 512 KB */ #define RUBY_VM_FIBER_MACHINE_STACK_SIZE ( 64 * 1024 * sizeof(VALUE)) /* 256 KB or 512 KB */
#if defined(__powerpc64__) #if defined(__powerpc64__) || defined(__ppc64__) // macOS has __ppc64__
#define RUBY_VM_FIBER_MACHINE_STACK_SIZE_MIN ( 32 * 1024 * sizeof(VALUE)) /* 128 KB or 256 KB */ #define RUBY_VM_FIBER_MACHINE_STACK_SIZE_MIN ( 32 * 1024 * sizeof(VALUE)) /* 128 KB or 256 KB */
#else #else
#define RUBY_VM_FIBER_MACHINE_STACK_SIZE_MIN ( 16 * 1024 * sizeof(VALUE)) /* 64 KB or 128 KB */ #define RUBY_VM_FIBER_MACHINE_STACK_SIZE_MIN ( 16 * 1024 * sizeof(VALUE)) /* 64 KB or 128 KB */
#endif #endif

View File

@ -55,7 +55,7 @@ static void vm_insns_counter_count_insn(int insn) {}
#elif defined(__GNUC__) && defined(__i386__) #elif defined(__GNUC__) && defined(__i386__)
#define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("e" reg) #define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("e" reg)
#elif defined(__GNUC__) && defined(__powerpc64__) #elif defined(__GNUC__) && (defined(__powerpc64__) || defined(__POWERPC__))
#define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("r" reg) #define DECL_SC_REG(type, r, reg) register type reg_##r __asm__("r" reg)
#elif defined(__GNUC__) && defined(__aarch64__) #elif defined(__GNUC__) && defined(__aarch64__)
@ -92,7 +92,7 @@ vm_exec_core(rb_execution_context_t *ec, VALUE initial)
DECL_SC_REG(rb_control_frame_t *, cfp, "15"); DECL_SC_REG(rb_control_frame_t *, cfp, "15");
#define USE_MACHINE_REGS 1 #define USE_MACHINE_REGS 1
#elif defined(__GNUC__) && defined(__powerpc64__) #elif defined(__GNUC__) && (defined(__powerpc64__) || defined(__POWERPC__))
DECL_SC_REG(const VALUE *, pc, "14"); DECL_SC_REG(const VALUE *, pc, "14");
DECL_SC_REG(rb_control_frame_t *, cfp, "15"); DECL_SC_REG(rb_control_frame_t *, cfp, "15");
#define USE_MACHINE_REGS 1 #define USE_MACHINE_REGS 1