From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9047 invoked by alias); 28 Oct 2014 19:46:40 -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 8974 invoked by uid 89); 28 Oct 2014 19:46:40 -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-qg0-f41.google.com Received: from mail-qg0-f41.google.com (HELO mail-qg0-f41.google.com) (209.85.192.41) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Tue, 28 Oct 2014 19:46:38 +0000 Received: by mail-qg0-f41.google.com with SMTP id q107so1134661qgd.14 for ; Tue, 28 Oct 2014 12:46:35 -0700 (PDT) X-Received: by 10.140.92.2 with SMTP id a2mr2050437qge.51.1414525595614; Tue, 28 Oct 2014 12:46:35 -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 11sm2042715qgj.34.2014.10.28.12.46.34 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Oct 2014 12:46:34 -0700 (PDT) From: Richard Henderson To: libffi-discuss@sourceware.org Cc: davem@davemloft.net Subject: [PATCH 5/8] sparc: Handle more cases of structure return directly Date: Tue, 28 Oct 2014 19:46:00 -0000 Message-Id: <1414525555-21256-6-git-send-email-rth@twiddle.net> In-Reply-To: <1414525555-21256-1-git-send-email-rth@twiddle.net> References: <1414525555-21256-1-git-send-email-rth@twiddle.net> X-SW-Source: 2014/txt/msg00151.txt.bz2 --- src/sparc/ffi.c | 4 +- src/sparc/ffi64.c | 40 +++++++++++++++--- src/sparc/internal.h | 24 ++++++----- src/sparc/v8.S | 77 +++++++++++++++++------------------ src/sparc/v9.S | 112 ++++++++++++++++++++++++++++++--------------------- 5 files changed, 152 insertions(+), 105 deletions(-) diff --git a/src/sparc/ffi.c b/src/sparc/ffi.c index 7542847..1b8f48e 100644 --- a/src/sparc/ffi.c +++ b/src/sparc/ffi.c @@ -59,10 +59,10 @@ ffi_prep_cif_machdep(ffi_cif *cif) flags = SPARC_RET_VOID; break; case FFI_TYPE_FLOAT: - flags = SPARC_RET_FLOAT; + flags = SPARC_RET_F_1; break; case FFI_TYPE_DOUBLE: - flags = SPARC_RET_DOUBLE; + flags = SPARC_RET_F_2; break; case FFI_TYPE_LONGDOUBLE: case FFI_TYPE_STRUCT: diff --git a/src/sparc/ffi64.c b/src/sparc/ffi64.c index 65ae438..ab3ed09 100644 --- a/src/sparc/ffi64.c +++ b/src/sparc/ffi64.c @@ -66,7 +66,6 @@ ffi_struct_float_mask (ffi_type *struct_type, int size_mask) { case FFI_TYPE_STRUCT: size_mask = ffi_struct_float_mask (t, size_mask); - size_mask = ALIGN(size_mask, FFI_SIZEOF_ARG); continue; case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: @@ -154,13 +153,13 @@ ffi_prep_cif_machdep(ffi_cif *cif) flags = SPARC_RET_VOID; break; case FFI_TYPE_FLOAT: - flags = SPARC_RET_FLOAT; + flags = SPARC_RET_F_1; break; case FFI_TYPE_DOUBLE: - flags = SPARC_RET_DOUBLE; + flags = SPARC_RET_F_2; break; case FFI_TYPE_LONGDOUBLE: - flags = SPARC_RET_LDOUBLE; + flags = SPARC_RET_F_4; break; case FFI_TYPE_STRUCT: @@ -171,8 +170,37 @@ ffi_prep_cif_machdep(ffi_cif *cif) } else { - flags = ffi_struct_float_mask (rtype, 0) << SPARC_FLTMASK_SHIFT; - flags |= SPARC_RET_STRUCT; + int size_mask = ffi_struct_float_mask (rtype, 0); + int word_size = (size_mask >> 2) & 0x3f; + int all_mask = (1 << word_size) - 1; + int fp_mask = size_mask >> 8; + + flags = (size_mask << SPARC_FLTMASK_SHIFT) | SPARC_RET_STRUCT; + + /* For special cases of all-int or all-fp, we can return + the value directly without popping through a struct copy. */ + if (fp_mask == 0) + { + if (rtype->alignment >= 8) + { + if (rtype->size == 8) + flags = SPARC_RET_INT64; + else if (rtype->size == 16) + flags = SPARC_RET_INT128; + } + } + else if (fp_mask == all_mask) + switch (word_size) + { + case 1: flags = SPARC_RET_F_1; break; + case 2: flags = SPARC_RET_F_2; break; + case 3: flags = SPARC_RET_F_3; break; + case 4: flags = SPARC_RET_F_4; break; + /* 5 word structures skipped; handled via RET_STRUCT. */ + case 6: flags = SPARC_RET_F_6; break; + /* 7 word structures skipped; handled via RET_STRUCT. */ + case 8: flags = SPARC_RET_F_8; break; + } } break; diff --git a/src/sparc/internal.h b/src/sparc/internal.h index 3018928..b4494d9 100644 --- a/src/sparc/internal.h +++ b/src/sparc/internal.h @@ -1,17 +1,21 @@ #define SPARC_RET_VOID 0 #define SPARC_RET_STRUCT 1 -#define SPARC_RET_FLOAT 2 -#define SPARC_RET_DOUBLE 3 -#define SPARC_RET_UINT8 4 -#define SPARC_RET_SINT8 5 -#define SPARC_RET_UINT16 6 -#define SPARC_RET_SINT16 7 +#define SPARC_RET_UINT8 2 +#define SPARC_RET_SINT8 3 +#define SPARC_RET_UINT16 4 +#define SPARC_RET_SINT16 5 +#define SPARC_RET_UINT32 6 +#define SPARC_RET_SINT32 7 /* v9 only */ #define SPARC_RET_INT64 8 -#define SPARC_RET_UINT32 9 +#define SPARC_RET_INT128 9 /* v9 only */ -/* These two are only used for V9. */ -#define SPARC_RET_SINT32 10 -#define SPARC_RET_LDOUBLE 11 +/* Note that F_7 is missing, and is handled by SPARC_RET_STRUCT. */ +#define SPARC_RET_F_8 10 +#define SPARC_RET_F_6 11 /* v9 only */ +#define SPARC_RET_F_4 12 +#define SPARC_RET_F_2 13 +#define SPARC_RET_F_3 14 /* v9 only */ +#define SPARC_RET_F_1 15 #define SPARC_FLAG_RET_MASK 15 #define SPARC_FLAG_RET_IN_MEM 32 diff --git a/src/sparc/v8.S b/src/sparc/v8.S index b0d50a3..4adcf6d 100644 --- a/src/sparc/v8.S +++ b/src/sparc/v8.S @@ -118,15 +118,6 @@ E SPARC_RET_VOID restore E SPARC_RET_STRUCT unimp -E SPARC_RET_FLOAT - st %f0, [%i2] - ret - restore -E SPARC_RET_DOUBLE - std %f0, [%i2] - ret - restore - nop E SPARC_RET_UINT8 and %o0, 0xff, %o0 st %o0, [%i2] @@ -144,28 +135,34 @@ E SPARC_RET_SINT16 sll %o0, 16, %o0 b 7f sra %o0, 16, %o0 -E SPARC_RET_INT64 - std %o0, [%i2] - ret - restore E SPARC_RET_UINT32 7: st %o0, [%i2] ret restore - - ! Unused entries. Don't allow bad data to do worse things. -E 10 +E SPARC_RET_SINT32 unimp -E 11 +E SPARC_RET_INT64 + std %o0, [%i2] + ret + restore +E SPARC_RET_INT128 unimp -E 12 +E SPARC_RET_F_8 unimp -E 13 +E SPARC_RET_F_6 unimp -E 14 +E SPARC_RET_F_4 unimp -E 15 +E SPARC_RET_F_2 + std %f0, [%i2] + ret + restore +E SPARC_RET_F_3 unimp +E SPARC_RET_F_1 + st %f0, [%i2] + ret + restore ! Struct returning functions expect and skip the unimp here. .align 8 @@ -234,14 +231,6 @@ E SPARC_RET_VOID E SPARC_RET_STRUCT jmp %i7+12 restore -E SPARC_RET_FLOAT - ld [%fp-8], %f0 - ret - restore -E SPARC_RET_DOUBLE - ldd [%fp-8], %f0 - ret - restore E SPARC_RET_UINT8 ldub [%fp-8+3], %i0 ret @@ -258,28 +247,34 @@ E SPARC_RET_SINT16 ldsh [%fp-8+2], %i0 ret restore -E SPARC_RET_INT64 - ldd [%fp-8], %i0 - ret - restore E SPARC_RET_UINT32 ld [%fp-8], %i0 ret restore - - ! Unused entries. Don't allow bad data to do worse things. -E 10 +E SPARC_RET_SINT32 unimp -E 11 +E SPARC_RET_INT64 + ldd [%fp-8], %i0 + ret + restore +E SPARC_RET_INT128 unimp -E 12 +E SPARC_RET_F_8 unimp -E 13 +E SPARC_RET_F_6 unimp -E 14 +E SPARC_RET_F_4 unimp -E 15 +E SPARC_RET_F_2 + ldd [%fp-8], %f0 + ret + restore +E SPARC_RET_F_3 unimp +E SPARC_RET_F_1 + ld [%fp-8], %f0 + ret + restore cfi_endproc .size C(ffi_closure_v8), . - C(ffi_closure_v8) diff --git a/src/sparc/v9.S b/src/sparc/v9.S index 3d91f2d..d893d2f 100644 --- a/src/sparc/v9.S +++ b/src/sparc/v9.S @@ -114,12 +114,6 @@ E SPARC_RET_STRUCT sub %sp, 64, %sp b 8f stx %o0, [%l2] -E SPARC_RET_FLOAT - return %i7+8 - st %f0, [%o2] -E SPARC_RET_DOUBLE - return %i7+8 - std %f0, [%o2] E SPARC_RET_UINT8 and %o0, 0xff, %i0 return %i7+8 @@ -139,10 +133,6 @@ E SPARC_RET_SINT16 sra %o0, 16, %i0 return %i7+8 stx %o0, [%o2] -E SPARC_RET_INT64 - stx %o0, [%i2] - return %i7+8 - nop E SPARC_RET_UINT32 srl %o0, 0, %i0 return %i7+8 @@ -151,20 +141,40 @@ E SPARC_RET_SINT32 sra %o0, 0, %i0 return %i7+8 stx %o0, [%o2] -E SPARC_RET_LDOUBLE - std %f0, [%i2] +E SPARC_RET_INT64 + stx %o0, [%i2] + return %i7+8 + nop +E SPARC_RET_INT128 + stx %o0, [%i2] + stx %o1, [%i2+8] + return %i7+8 + nop +E SPARC_RET_F_8 + st %f7, [%i2+7*4] + nop + st %f6, [%i2+6*4] + nop +E SPARC_RET_F_6 + st %f5, [%i2+5*4] + nop + st %f4, [%i2+4*4] + nop +E SPARC_RET_F_4 + std %f2, [%i2+2*4] + return %i7+8 + std %f0, [%o2] +E SPARC_RET_F_2 return %i7+8 - std %f2, [%o2+8] - - ! Unused entries. Don't allow bad data to do worse things. -E 12 - unimp -E 13 - unimp -E 14 - unimp -E 15 - unimp + std %f0, [%o2] +E SPARC_RET_F_3 + st %f2, [%i2+2*4] + nop + st %f1, [%i2+1*4] + nop +E SPARC_RET_F_1 + return %i7+8 + st %f0, [%o2] ! Finish the SPARC_RET_STRUCT sequence. .align 8 @@ -264,14 +274,6 @@ E SPARC_RET_STRUCT ldd [FP-160], %f0 b 8f ldx [FP-152], %i1 -E SPARC_RET_FLOAT - ld [FP-160], %f0 - return %i7+8 - nop -E SPARC_RET_DOUBLE - ldd [FP-160], %f0 - return %i7+8 - nop E SPARC_RET_UINT8 ldub [FP-160+7], %i0 return %i7+8 @@ -288,10 +290,6 @@ E SPARC_RET_SINT16 ldsh [FP-160+6], %i0 return %i7+8 nop -E SPARC_RET_INT64 - ldx [FP-160], %i0 - return %i7+8 - nop E SPARC_RET_UINT32 lduw [FP-160+4], %i0 return %i7+8 @@ -300,21 +298,43 @@ E SPARC_RET_SINT32 ldsw [FP-160+4], %i0 return %i7+8 nop -E SPARC_RET_LDOUBLE +E SPARC_RET_INT64 + ldx [FP-160], %i0 + return %i7+8 + nop +E SPARC_RET_INT128 + ldx [FP-160], %i0 + ldx [FP-160+8], %i1 + return %i7+8 + nop +E SPARC_RET_F_8 + ld [FP-160+7*4], %f7 + nop + ld [FP-160+6*4], %f6 + nop +E SPARC_RET_F_6 + ld [FP-160+5*4], %f5 + nop + ld [FP-160+4*4], %f4 + nop +E SPARC_RET_F_4 ldd [FP-160], %f0 ldd [FP-160+8], %f2 return %i7+8 nop - - ! Unused entries. Don't allow bad data to do worse things. -E 12 - unimp -E 13 - unimp -E 14 - unimp -E 15 - unimp +E SPARC_RET_F_2 + ldd [FP-160], %f0 + return %i7+8 + nop +E SPARC_RET_F_3 + ld [FP-160+2*4], %f2 + nop + ld [FP-160+1*4], %f1 + nop +E SPARC_RET_F_1 + ld [FP-160], %f0 + return %i7+8 + nop ! Finish the SPARC_RET_STRUCT sequence. .align 8 -- 1.9.3