diff options
author | amodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-25 00:08:47 +0000 |
---|---|---|
committer | amodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-25 00:08:47 +0000 |
commit | 4b39381b0a1cf6bfe47f6d790e2d65bb8a6c2b13 (patch) | |
tree | 3443d70ab47d0f95befa62099396c38ead325603 | |
parent | 7f54d14c3565845971c9e6923196fa4bce9bd1ff (diff) | |
download | gcc-4b39381b0a1cf6bfe47f6d790e2d65bb8a6c2b13.tar.gz |
* src/powerpc/ffi.c (ffi_prep_args_SYSV): Move var declaration
before statements.
(ffi_prep_args64): Support little-endian.
(ffi_closure_helper_SYSV, ffi_closure_helper_LINUX64): Likewise.
* src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Likewise.
* src/powerpc/ppc_closure.S (ffi_closure_SYSV): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@200383 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | libffi/ChangeLog | 9 | ||||
-rw-r--r-- | libffi/src/powerpc/ffi.c | 24 | ||||
-rw-r--r-- | libffi/src/powerpc/linux64_closure.S | 28 | ||||
-rw-r--r-- | libffi/src/powerpc/ppc_closure.S | 39 |
4 files changed, 93 insertions, 7 deletions
diff --git a/libffi/ChangeLog b/libffi/ChangeLog index 892e87a1560..77a949d13e5 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -1,3 +1,12 @@ +2013-06-25 Alan Modra <amodra@gmail.com> + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Move var declaration + before statements. + (ffi_prep_args64): Support little-endian. + (ffi_closure_helper_SYSV, ffi_closure_helper_LINUX64): Likewise. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Likewise. + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Likewise. + 2013-05-22 Dominique d'Humieres <dominiq@lps.ens.fr> Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> diff --git a/libffi/src/powerpc/ffi.c b/libffi/src/powerpc/ffi.c index 257f02fab3e..26f7cf19b06 100644 --- a/libffi/src/powerpc/ffi.c +++ b/libffi/src/powerpc/ffi.c @@ -127,6 +127,9 @@ ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack) int i; ffi_type **ptr; +#ifndef __NO_FPRS__ + double double_tmp; +#endif union { void **v; char **c; @@ -146,7 +149,6 @@ ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack) gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS; intarg_count = 0; #ifndef __NO_FPRS__ - double double_tmp; fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS; fparg_count = 0; copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c); @@ -542,11 +544,12 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack) { char *where = next_arg.c; +#ifndef __LITTLE_ENDIAN__ /* Structures with size less than eight bytes are passed left-padded. */ if ((*ptr)->size < 8) where += 8 - (*ptr)->size; - +#endif memcpy (where, *p_argv.c, (*ptr)->size); next_arg.ul += words; if (next_arg.ul == gpr_end.ul) @@ -1208,6 +1211,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, case FFI_TYPE_SINT8: case FFI_TYPE_UINT8: +#ifndef __LITTLE_ENDIAN__ /* there are 8 gpr registers used to pass values */ if (ng < 8) { @@ -1221,9 +1225,10 @@ ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, pst++; } break; - +#endif case FFI_TYPE_SINT16: case FFI_TYPE_UINT16: +#ifndef __LITTLE_ENDIAN__ /* there are 8 gpr registers used to pass values */ if (ng < 8) { @@ -1237,7 +1242,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, pst++; } break; - +#endif case FFI_TYPE_SINT32: case FFI_TYPE_UINT32: case FFI_TYPE_POINTER: @@ -1367,22 +1372,25 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, { case FFI_TYPE_SINT8: case FFI_TYPE_UINT8: +#ifndef __LITTLE_ENDIAN__ avalue[i] = (char *) pst + 7; pst++; break; - +#endif case FFI_TYPE_SINT16: case FFI_TYPE_UINT16: +#ifndef __LITTLE_ENDIAN__ avalue[i] = (char *) pst + 6; pst++; break; - +#endif case FFI_TYPE_SINT32: case FFI_TYPE_UINT32: +#ifndef __LITTLE_ENDIAN__ avalue[i] = (char *) pst + 4; pst++; break; - +#endif case FFI_TYPE_SINT64: case FFI_TYPE_UINT64: case FFI_TYPE_POINTER: @@ -1391,11 +1399,13 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, break; case FFI_TYPE_STRUCT: +#ifndef __LITTLE_ENDIAN__ /* Structures with size less than eight bytes are passed left-padded. */ if (arg_types[i]->size < 8) avalue[i] = (char *) pst + 8 - arg_types[i]->size; else +#endif avalue[i] = pst; pst += (arg_types[i]->size + 7) / 8; break; diff --git a/libffi/src/powerpc/linux64_closure.S b/libffi/src/powerpc/linux64_closure.S index b1e12197a2b..ac4a226ac50 100644 --- a/libffi/src/powerpc/linux64_closure.S +++ b/libffi/src/powerpc/linux64_closure.S @@ -132,7 +132,11 @@ ffi_closure_LINUX64: blr nop # case FFI_TYPE_INT +#ifdef __LITTLE_ENDIAN__ + lwa %r3, 112+0(%r1) +#else lwa %r3, 112+4(%r1) +#endif mtlr %r0 addi %r1, %r1, 240 blr @@ -152,33 +156,57 @@ ffi_closure_LINUX64: lfd %f2, 112+8(%r1) b .Lfinish # case FFI_TYPE_UINT8 +#ifdef __LITTLE_ENDIAN__ + lbz %r3, 112+0(%r1) +#else lbz %r3, 112+7(%r1) +#endif mtlr %r0 addi %r1, %r1, 240 blr # case FFI_TYPE_SINT8 +#ifdef __LITTLE_ENDIAN__ + lbz %r3, 112+0(%r1) +#else lbz %r3, 112+7(%r1) +#endif extsb %r3,%r3 mtlr %r0 b .Lfinish # case FFI_TYPE_UINT16 +#ifdef __LITTLE_ENDIAN__ + lhz %r3, 112+0(%r1) +#else lhz %r3, 112+6(%r1) +#endif mtlr %r0 .Lfinish: addi %r1, %r1, 240 blr # case FFI_TYPE_SINT16 +#ifdef __LITTLE_ENDIAN__ + lha %r3, 112+0(%r1) +#else lha %r3, 112+6(%r1) +#endif mtlr %r0 addi %r1, %r1, 240 blr # case FFI_TYPE_UINT32 +#ifdef __LITTLE_ENDIAN__ + lwz %r3, 112+0(%r1) +#else lwz %r3, 112+4(%r1) +#endif mtlr %r0 addi %r1, %r1, 240 blr # case FFI_TYPE_SINT32 +#ifdef __LITTLE_ENDIAN__ + lwa %r3, 112+0(%r1) +#else lwa %r3, 112+4(%r1) +#endif mtlr %r0 addi %r1, %r1, 240 blr diff --git a/libffi/src/powerpc/ppc_closure.S b/libffi/src/powerpc/ppc_closure.S index 41fb8851b62..e160006426e 100644 --- a/libffi/src/powerpc/ppc_closure.S +++ b/libffi/src/powerpc/ppc_closure.S @@ -159,25 +159,41 @@ ENTRY(ffi_closure_SYSV) #endif # case FFI_TYPE_UINT8 +#ifdef __LITTLE_ENDIAN__ + lbz %r3,112+0(%r1) +#else lbz %r3,112+3(%r1) +#endif mtlr %r0 addi %r1,%r1,144 blr # case FFI_TYPE_SINT8 +#ifdef __LITTLE_ENDIAN__ + lbz %r3,112+0(%r1) +#else lbz %r3,112+3(%r1) +#endif extsb %r3,%r3 mtlr %r0 b .Lfinish # case FFI_TYPE_UINT16 +#ifdef __LITTLE_ENDIAN__ + lhz %r3,112+0(%r1) +#else lhz %r3,112+2(%r1) +#endif mtlr %r0 addi %r1,%r1,144 blr # case FFI_TYPE_SINT16 +#ifdef __LITTLE_ENDIAN__ + lha %r3,112+0(%r1) +#else lha %r3,112+2(%r1) +#endif mtlr %r0 addi %r1,%r1,144 blr @@ -239,9 +255,15 @@ ENTRY(ffi_closure_SYSV) # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct. lwz %r3,112+0(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + addi %r1,%r1,144 + blr +#else srwi %r3,%r3,8 mtlr %r0 b .Lfinish +#endif # case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct. lwz %r3,112+0(%r1) @@ -252,20 +274,35 @@ ENTRY(ffi_closure_SYSV) # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct. lwz %r3,112+0(%r1) lwz %r4,112+4(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + b .Lfinish +#else li %r5,24 b .Lstruct567 +#endif # case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct. lwz %r3,112+0(%r1) lwz %r4,112+4(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + b .Lfinish +#else li %r5,16 b .Lstruct567 +#endif # case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct. lwz %r3,112+0(%r1) lwz %r4,112+4(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + b .Lfinish +#else li %r5,8 b .Lstruct567 +#endif # case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct. lwz %r3,112+0(%r1) @@ -273,6 +310,7 @@ ENTRY(ffi_closure_SYSV) mtlr %r0 b .Lfinish +#ifndef __LITTLE_ENDIAN__ .Lstruct567: subfic %r6,%r5,32 srw %r4,%r4,%r5 @@ -282,6 +320,7 @@ ENTRY(ffi_closure_SYSV) mtlr %r0 addi %r1,%r1,144 blr +#endif .Luint128: lwz %r6,112+12(%r1) |