This is the mail archive of the
libffi-discuss@sourceware.org
mailing list for the libffi project.
[PATCH 5/8] sparc: Handle more cases of structure return directly
- From: Richard Henderson <rth at twiddle dot net>
- To: libffi-discuss at sourceware dot org
- Cc: davem at davemloft dot net
- Date: Tue, 28 Oct 2014 12:45:52 -0700
- Subject: [PATCH 5/8] sparc: Handle more cases of structure return directly
- Authentication-results: sourceware.org; auth=none
- References: <1414525555-21256-1-git-send-email-rth at twiddle dot net>
---
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