From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 677 invoked by alias); 28 Oct 2014 18:54:16 -0000 Mailing-List: contact libffi-discuss-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libffi-discuss-owner@sourceware.org Received: (qmail 623 invoked by uid 89); 28 Oct 2014 18:54:15 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL,BAYES_00,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-qa0-f53.google.com Received: from mail-qa0-f53.google.com (HELO mail-qa0-f53.google.com) (209.85.216.53) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Tue, 28 Oct 2014 18:54:13 +0000 Received: by mail-qa0-f53.google.com with SMTP id n8so969126qaq.12 for ; Tue, 28 Oct 2014 11:54:11 -0700 (PDT) X-Received: by 10.224.171.194 with SMTP id i2mr7925391qaz.59.1414522451271; Tue, 28 Oct 2014 11:54:11 -0700 (PDT) Received: from anchor.com (50-194-63-110-static.hfc.comcastbusiness.net. [50.194.63.110]) by mx.google.com with ESMTPSA id 69sm1717430qgy.19.2014.10.28.11.54.09 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Oct 2014 11:54:10 -0700 (PDT) From: Richard Henderson To: libffi-discuss@sourceware.org Cc: Richard Henderson Subject: [PATCH 16/16] aarch64: Add support for Go closures Date: Tue, 28 Oct 2014 18:54:00 -0000 Message-Id: <1414522393-19169-17-git-send-email-rth@twiddle.net> In-Reply-To: <1414522393-19169-1-git-send-email-rth@twiddle.net> References: <1414522393-19169-1-git-send-email-rth@twiddle.net> X-SW-Source: 2014/txt/msg00145.txt.bz2 From: Richard Henderson --- src/aarch64/ffi.c | 52 +++++++++++++++++++++++++++++++++++++---- src/aarch64/ffitarget.h | 4 ++++ src/aarch64/sysv.S | 62 ++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 112 insertions(+), 6 deletions(-) diff --git a/src/aarch64/ffi.c b/src/aarch64/ffi.c index f546ab2..0cace9d 100644 --- a/src/aarch64/ffi.c +++ b/src/aarch64/ffi.c @@ -539,13 +539,14 @@ ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, #endif /* __APPLE__ */ extern void ffi_call_SYSV (struct call_context *context, void *frame, - void (*fn)(void), void *rvalue, int flags) - FFI_HIDDEN; + void (*fn)(void), void *rvalue, int flags, + void *closure) FFI_HIDDEN; /* Call a function with the provided arguments and capture the return value. */ -void -ffi_call (ffi_cif *cif, void (*fn)(void), void *orig_rvalue, void **avalue) +static void +ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue, + void **avalue, void *closure) { struct call_context *context; void *stack, *frame, *rvalue; @@ -698,12 +699,27 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *orig_rvalue, void **avalue) #endif } - ffi_call_SYSV (context, frame, fn, rvalue, flags); + ffi_call_SYSV (context, frame, fn, rvalue, flags, closure); if (flags & AARCH64_RET_NEED_COPY) memcpy (orig_rvalue, rvalue, rtype_size); } +void +ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue) +{ + ffi_call_int (cif, fn, rvalue, avalue, NULL); +} + +#ifdef FFI_GO_CLOSURES +void +ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, + void **avalue, void *closure) +{ + ffi_call_int (cif, fn, rvalue, avalue, closure); +} +#endif /* FFI_GO_CLOSURES */ + /* Build a trampoline. */ extern void ffi_closure_SYSV (void) FFI_HIDDEN; @@ -744,6 +760,32 @@ ffi_prep_closure_loc (ffi_closure *closure, return FFI_OK; } +#ifdef FFI_GO_CLOSURES +extern void ffi_go_closure_SYSV (void) FFI_HIDDEN; +extern void ffi_go_closure_SYSV_V (void) FFI_HIDDEN; + +ffi_status +ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*)) +{ + void (*start)(void); + + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + if (cif->flags & AARCH64_FLAG_ARG_V) + start = ffi_go_closure_SYSV_V; + else + start = ffi_go_closure_SYSV; + + closure->tramp = start; + closure->cif = cif; + closure->fun = fun; + + return FFI_OK; +} +#endif /* FFI_GO_CLOSURES */ + /* Primary handler to setup and invoke a function within a closure. A closure when invoked enters via the assembler wrapper diff --git a/src/aarch64/ffitarget.h b/src/aarch64/ffitarget.h index 7461386..80d09af 100644 --- a/src/aarch64/ffitarget.h +++ b/src/aarch64/ffitarget.h @@ -50,6 +50,10 @@ typedef enum ffi_abi #if defined (__APPLE__) #define FFI_TARGET_SPECIFIC_VARIADIC #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs +#else +/* iOS reserves x18 for the system. Disable Go closures until + a new static chain is chosen. */ +#define FFI_GO_CLOSURES 1 #endif #define FFI_TARGET_HAS_COMPLEX_TYPE diff --git a/src/aarch64/sysv.S b/src/aarch64/sysv.S index 7f00a3f..1fb68f2 100644 --- a/src/aarch64/sysv.S +++ b/src/aarch64/sysv.S @@ -50,7 +50,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* ffi_call_SYSV extern void ffi_call_SYSV (void *stack, void *frame, - void (*fn)(void), void *rvalue, int flags); + void (*fn)(void), void *rvalue, + int flags, void *closure); Therefore on entry we have: @@ -59,6 +60,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ x2 fn x3 rvalue x4 flags + x5 closure */ cfi_startproc @@ -74,6 +76,9 @@ CNAME(ffi_call_SYSV): mov x9, x2 /* save fn */ mov x8, x3 /* install structure return */ +#ifdef FFI_GO_CLOSURES + mov x18, x5 /* install static chain */ +#endif stp x3, x4, [x29, #16] /* save rvalue and flags */ /* Load the vector argument passing registers, if necessary. */ @@ -245,6 +250,7 @@ CNAME(ffi_closure_SYSV): /* Load ffi_closure_inner arguments. */ ldp x0, x1, [x17, #FFI_TRAMPOLINE_SIZE] /* load cif, fn */ ldr x2, [x17, #FFI_TRAMPOLINE_SIZE+16] /* load user_data */ +.Ldo_closure: add x3, sp, #16 /* load context */ add x4, sp, #ffi_closure_SYSV_FS /* load stack */ add x5, sp, #16+CALL_CONTEXT_SIZE /* load rvalue */ @@ -336,3 +342,57 @@ CNAME(ffi_closure_SYSV): .hidden CNAME(ffi_closure_SYSV) .size CNAME(ffi_closure_SYSV), . - CNAME(ffi_closure_SYSV) #endif + +#ifdef FFI_GO_CLOSURES + .align 4 +CNAME(ffi_go_closure_SYSV_V): + cfi_startproc + stp x29, x30, [sp, #-ffi_closure_SYSV_FS]! + cfi_adjust_cfa_offset (ffi_closure_SYSV_FS) + cfi_rel_offset (x29, 0) + cfi_rel_offset (x30, 8) + + /* Save the argument passing vector registers. */ + stp q0, q1, [sp, #16 + 0] + stp q2, q3, [sp, #16 + 32] + stp q4, q5, [sp, #16 + 64] + stp q6, q7, [sp, #16 + 96] + b 0f + cfi_endproc + + .globl CNAME(ffi_go_closure_SYSV_V) +#ifdef __ELF__ + .type CNAME(ffi_go_closure_SYSV_V), #function + .hidden CNAME(ffi_go_closure_SYSV_V) + .size CNAME(ffi_go_closure_SYSV_V), . - CNAME(ffi_go_closure_SYSV_V) +#endif + + .align 4 + cfi_startproc +CNAME(ffi_go_closure_SYSV): + stp x29, x30, [sp, #-ffi_closure_SYSV_FS]! + cfi_adjust_cfa_offset (ffi_closure_SYSV_FS) + cfi_rel_offset (x29, 0) + cfi_rel_offset (x30, 8) +0: + mov x29, sp + + /* Save the argument passing core registers. */ + stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0] + stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16] + stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32] + stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48] + + /* Load ffi_closure_inner arguments. */ + ldp x0, x1, [x18, #8] /* load cif, fn */ + mov x2, x18 /* load user_data */ + b .Ldo_closure + cfi_endproc + + .globl CNAME(ffi_go_closure_SYSV) +#ifdef __ELF__ + .type CNAME(ffi_go_closure_SYSV), #function + .hidden CNAME(ffi_go_closure_SYSV) + .size CNAME(ffi_go_closure_SYSV), . - CNAME(ffi_go_closure_SYSV) +#endif +#endif /* FFI_GO_CLOSURES */ -- 1.9.3