sparc: Handle more cases of structure return directly

This commit is contained in:
Richard Henderson
2014-10-25 16:24:41 -07:00
parent 0686c2e71c
commit 20da5b4132
5 changed files with 152 additions and 105 deletions

View File

@@ -59,10 +59,10 @@ ffi_prep_cif_machdep(ffi_cif *cif)
flags = SPARC_RET_VOID; flags = SPARC_RET_VOID;
break; break;
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
flags = SPARC_RET_FLOAT; flags = SPARC_RET_F_1;
break; break;
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
flags = SPARC_RET_DOUBLE; flags = SPARC_RET_F_2;
break; break;
case FFI_TYPE_LONGDOUBLE: case FFI_TYPE_LONGDOUBLE:
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:

View File

@@ -66,7 +66,6 @@ ffi_struct_float_mask (ffi_type *struct_type, int size_mask)
{ {
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
size_mask = ffi_struct_float_mask (t, size_mask); size_mask = ffi_struct_float_mask (t, size_mask);
size_mask = ALIGN(size_mask, FFI_SIZEOF_ARG);
continue; continue;
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
@@ -154,13 +153,13 @@ ffi_prep_cif_machdep(ffi_cif *cif)
flags = SPARC_RET_VOID; flags = SPARC_RET_VOID;
break; break;
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
flags = SPARC_RET_FLOAT; flags = SPARC_RET_F_1;
break; break;
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
flags = SPARC_RET_DOUBLE; flags = SPARC_RET_F_2;
break; break;
case FFI_TYPE_LONGDOUBLE: case FFI_TYPE_LONGDOUBLE:
flags = SPARC_RET_LDOUBLE; flags = SPARC_RET_F_4;
break; break;
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
@@ -171,8 +170,37 @@ ffi_prep_cif_machdep(ffi_cif *cif)
} }
else else
{ {
flags = ffi_struct_float_mask (rtype, 0) << SPARC_FLTMASK_SHIFT; int size_mask = ffi_struct_float_mask (rtype, 0);
flags |= SPARC_RET_STRUCT; 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; break;

View File

@@ -1,17 +1,21 @@
#define SPARC_RET_VOID 0 #define SPARC_RET_VOID 0
#define SPARC_RET_STRUCT 1 #define SPARC_RET_STRUCT 1
#define SPARC_RET_FLOAT 2 #define SPARC_RET_UINT8 2
#define SPARC_RET_DOUBLE 3 #define SPARC_RET_SINT8 3
#define SPARC_RET_UINT8 4 #define SPARC_RET_UINT16 4
#define SPARC_RET_SINT8 5 #define SPARC_RET_SINT16 5
#define SPARC_RET_UINT16 6 #define SPARC_RET_UINT32 6
#define SPARC_RET_SINT16 7 #define SPARC_RET_SINT32 7 /* v9 only */
#define SPARC_RET_INT64 8 #define SPARC_RET_INT64 8
#define SPARC_RET_UINT32 9 #define SPARC_RET_INT128 9 /* v9 only */
/* These two are only used for V9. */ /* Note that F_7 is missing, and is handled by SPARC_RET_STRUCT. */
#define SPARC_RET_SINT32 10 #define SPARC_RET_F_8 10
#define SPARC_RET_LDOUBLE 11 #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_MASK 15
#define SPARC_FLAG_RET_IN_MEM 32 #define SPARC_FLAG_RET_IN_MEM 32

View File

@@ -118,15 +118,6 @@ E SPARC_RET_VOID
restore restore
E SPARC_RET_STRUCT E SPARC_RET_STRUCT
unimp unimp
E SPARC_RET_FLOAT
st %f0, [%i2]
ret
restore
E SPARC_RET_DOUBLE
std %f0, [%i2]
ret
restore
nop
E SPARC_RET_UINT8 E SPARC_RET_UINT8
and %o0, 0xff, %o0 and %o0, 0xff, %o0
st %o0, [%i2] st %o0, [%i2]
@@ -144,28 +135,34 @@ E SPARC_RET_SINT16
sll %o0, 16, %o0 sll %o0, 16, %o0
b 7f b 7f
sra %o0, 16, %o0 sra %o0, 16, %o0
E SPARC_RET_INT64
std %o0, [%i2]
ret
restore
E SPARC_RET_UINT32 E SPARC_RET_UINT32
7: st %o0, [%i2] 7: st %o0, [%i2]
ret ret
restore restore
E SPARC_RET_SINT32
! Unused entries. Don't allow bad data to do worse things.
E 10
unimp unimp
E 11 E SPARC_RET_INT64
std %o0, [%i2]
ret
restore
E SPARC_RET_INT128
unimp unimp
E 12 E SPARC_RET_F_8
unimp unimp
E 13 E SPARC_RET_F_6
unimp unimp
E 14 E SPARC_RET_F_4
unimp unimp
E 15 E SPARC_RET_F_2
std %f0, [%i2]
ret
restore
E SPARC_RET_F_3
unimp unimp
E SPARC_RET_F_1
st %f0, [%i2]
ret
restore
! Struct returning functions expect and skip the unimp here. ! Struct returning functions expect and skip the unimp here.
.align 8 .align 8
@@ -234,14 +231,6 @@ E SPARC_RET_VOID
E SPARC_RET_STRUCT E SPARC_RET_STRUCT
jmp %i7+12 jmp %i7+12
restore 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 E SPARC_RET_UINT8
ldub [%fp-8+3], %i0 ldub [%fp-8+3], %i0
ret ret
@@ -258,28 +247,34 @@ E SPARC_RET_SINT16
ldsh [%fp-8+2], %i0 ldsh [%fp-8+2], %i0
ret ret
restore restore
E SPARC_RET_INT64
ldd [%fp-8], %i0
ret
restore
E SPARC_RET_UINT32 E SPARC_RET_UINT32
ld [%fp-8], %i0 ld [%fp-8], %i0
ret ret
restore restore
E SPARC_RET_SINT32
! Unused entries. Don't allow bad data to do worse things.
E 10
unimp unimp
E 11 E SPARC_RET_INT64
ldd [%fp-8], %i0
ret
restore
E SPARC_RET_INT128
unimp unimp
E 12 E SPARC_RET_F_8
unimp unimp
E 13 E SPARC_RET_F_6
unimp unimp
E 14 E SPARC_RET_F_4
unimp unimp
E 15 E SPARC_RET_F_2
ldd [%fp-8], %f0
ret
restore
E SPARC_RET_F_3
unimp unimp
E SPARC_RET_F_1
ld [%fp-8], %f0
ret
restore
cfi_endproc cfi_endproc
.size C(ffi_closure_v8), . - C(ffi_closure_v8) .size C(ffi_closure_v8), . - C(ffi_closure_v8)

View File

@@ -114,12 +114,6 @@ E SPARC_RET_STRUCT
sub %sp, 64, %sp sub %sp, 64, %sp
b 8f b 8f
stx %o0, [%l2] 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 E SPARC_RET_UINT8
and %o0, 0xff, %i0 and %o0, 0xff, %i0
return %i7+8 return %i7+8
@@ -139,10 +133,6 @@ E SPARC_RET_SINT16
sra %o0, 16, %i0 sra %o0, 16, %i0
return %i7+8 return %i7+8
stx %o0, [%o2] stx %o0, [%o2]
E SPARC_RET_INT64
stx %o0, [%i2]
return %i7+8
nop
E SPARC_RET_UINT32 E SPARC_RET_UINT32
srl %o0, 0, %i0 srl %o0, 0, %i0
return %i7+8 return %i7+8
@@ -151,20 +141,40 @@ E SPARC_RET_SINT32
sra %o0, 0, %i0 sra %o0, 0, %i0
return %i7+8 return %i7+8
stx %o0, [%o2] stx %o0, [%o2]
E SPARC_RET_LDOUBLE E SPARC_RET_INT64
std %f0, [%i2] stx %o0, [%i2]
return %i7+8 return %i7+8
std %f2, [%o2+8] nop
E SPARC_RET_INT128
! Unused entries. Don't allow bad data to do worse things. stx %o0, [%i2]
E 12 stx %o1, [%i2+8]
unimp return %i7+8
E 13 nop
unimp E SPARC_RET_F_8
E 14 st %f7, [%i2+7*4]
unimp nop
E 15 st %f6, [%i2+6*4]
unimp 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 %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. ! Finish the SPARC_RET_STRUCT sequence.
.align 8 .align 8
@@ -264,14 +274,6 @@ E SPARC_RET_STRUCT
ldd [FP-160], %f0 ldd [FP-160], %f0
b 8f b 8f
ldx [FP-152], %i1 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 E SPARC_RET_UINT8
ldub [FP-160+7], %i0 ldub [FP-160+7], %i0
return %i7+8 return %i7+8
@@ -288,10 +290,6 @@ E SPARC_RET_SINT16
ldsh [FP-160+6], %i0 ldsh [FP-160+6], %i0
return %i7+8 return %i7+8
nop nop
E SPARC_RET_INT64
ldx [FP-160], %i0
return %i7+8
nop
E SPARC_RET_UINT32 E SPARC_RET_UINT32
lduw [FP-160+4], %i0 lduw [FP-160+4], %i0
return %i7+8 return %i7+8
@@ -300,21 +298,43 @@ E SPARC_RET_SINT32
ldsw [FP-160+4], %i0 ldsw [FP-160+4], %i0
return %i7+8 return %i7+8
nop 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], %f0
ldd [FP-160+8], %f2 ldd [FP-160+8], %f2
return %i7+8 return %i7+8
nop nop
E SPARC_RET_F_2
! Unused entries. Don't allow bad data to do worse things. ldd [FP-160], %f0
E 12 return %i7+8
unimp nop
E 13 E SPARC_RET_F_3
unimp ld [FP-160+2*4], %f2
E 14 nop
unimp ld [FP-160+1*4], %f1
E 15 nop
unimp E SPARC_RET_F_1
ld [FP-160], %f0
return %i7+8
nop
! Finish the SPARC_RET_STRUCT sequence. ! Finish the SPARC_RET_STRUCT sequence.
.align 8 .align 8