aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@libertysurf.fr>2004-11-22 19:35:16 +0100
committerEric Botcazou <ebotcazou@gcc.gnu.org>2004-11-22 18:35:16 +0000
commitbf02e7fa52bf2ba2284ef5357e1400c38536c82c (patch)
tree8a9179c24c961aa5bb6b5c1b72b5e41595fbe06c
parent167a1354b34d35c26feb63f511e58cd7698e40ce (diff)
downloadgcc-bf02e7fa52bf2ba2284ef5357e1400c38536c82c.zip
gcc-bf02e7fa52bf2ba2284ef5357e1400c38536c82c.tar.gz
gcc-bf02e7fa52bf2ba2284ef5357e1400c38536c82c.tar.bz2
ffi.c (ffi_prep_closure): Align doubles and 64-bit integers on a 8-byte boundary.
* src/sparc/ffi.c (ffi_prep_closure): Align doubles and 64-bit integers on a 8-byte boundary. * src/sparc/v8.S (ffi_closure_v8): Reserve frame space for arguments. From-SVN: r91022
-rw-r--r--libffi/ChangeLog6
-rw-r--r--libffi/src/sparc/ffi.c15
-rw-r--r--libffi/src/sparc/v8.S14
3 files changed, 32 insertions, 3 deletions
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index 46d41da..4508204 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,3 +1,9 @@
+2004-11-22 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * src/sparc/ffi.c (ffi_prep_closure): Align doubles and 64-bit integers
+ on a 8-byte boundary.
+ * src/sparc/v8.S (ffi_closure_v8): Reserve frame space for arguments.
+
2004-10-27 Richard Earnshaw <rearnsha@arm.com>
* src/arm/ffi.c (ffi_prep_cif_machdep): Handle functions that return
diff --git a/libffi/src/sparc/ffi.c b/libffi/src/sparc/ffi.c
index ad15bee..b83d63d 100644
--- a/libffi/src/sparc/ffi.c
+++ b/libffi/src/sparc/ffi.c
@@ -470,7 +470,7 @@ ffi_prep_closure (ffi_closure* closure,
int
ffi_closure_sparc_inner_v8(ffi_closure *closure,
- void *rvalue, unsigned long *gpr)
+ void *rvalue, unsigned long *gpr, unsigned long *scratch)
{
ffi_cif *cif;
ffi_type **arg_types;
@@ -505,6 +505,19 @@ ffi_closure_sparc_inner_v8(ffi_closure *closure,
/* Straight copy of invisible reference. */
avalue[i] = (void *)gpr[argn++];
}
+ else if ((arg_types[i]->type == FFI_TYPE_DOUBLE
+ || arg_types[i]->type == FFI_TYPE_SINT64
+ || arg_types[i]->type == FFI_TYPE_UINT64)
+ /* gpr is 8-byte aligned. */
+ && (argn % 2) != 0)
+ {
+ /* Align on a 8-byte boundary. */
+ scratch[0] = gpr[argn];
+ scratch[1] = gpr[argn+1];
+ avalue[i] = scratch;
+ scratch -= 2;
+ argn += 2;
+ }
else
{
/* Always right-justify. */
diff --git a/libffi/src/sparc/v8.S b/libffi/src/sparc/v8.S
index aaa7be7..709423c 100644
--- a/libffi/src/sparc/v8.S
+++ b/libffi/src/sparc/v8.S
@@ -115,7 +115,15 @@ ffi_closure_v8:
.register %g2, #scratch
#endif
.LLFB2:
- save %sp, -STACKFRAME, %sp
+ ! Reserve frame space for all arguments in case
+ ! we need to align them on a 8-byte boundary.
+ ld [%g2+FFI_TRAMPOLINE_SIZE], %g1
+ ld [%g1+4], %g1
+ sll %g1, 3, %g1
+ add %g1, STACKFRAME, %g1
+ ! %g1 == STACKFRAME + 8*nargs
+ neg %g1
+ save %sp, %g1, %sp
.LLCFI1:
! Store all of the potential argument registers in va_list format.
@@ -129,8 +137,9 @@ ffi_closure_v8:
! Call ffi_closure_sparc_inner to do the bulk of the work.
mov %g2, %o0
add %fp, -8, %o1
+ add %fp, 64, %o2
call ffi_closure_sparc_inner_v8
- add %fp, 64, %o2
+ add %fp, -16, %o3
! Load up the return value in the proper type.
! See ffi_prep_cif_machdep for the list of cases.
@@ -157,6 +166,7 @@ ffi_closure_v8:
be done2
! FFI_TYPE_SINT64
+ ! FFI_TYPE_UINT64
ld [%fp-4], %i1
integer: