diff --git a/libffi/ChangeLog b/libffi/ChangeLog index 7e96f277c72..cf2adc0deb4 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -1,3 +1,13 @@ +2003-08-02 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_args64): Modify for changed gcc + structure passing. + (ffi_closure_helper_LINUX64): Likewise. + * src/powerpc/linux64.S: Remove code writing to parm save area. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Use return + address in lr from ffi_closure_helper_LINUX64 call to calculate + table address. Optimize function tail. + 2003-07-28 Andreas Tobler * src/sparc/ffi.c: Handle all floating point registers. diff --git a/libffi/src/powerpc/ffi.c b/libffi/src/powerpc/ffi.c index 6f0e2a561af..30ab7efb0c6 100644 --- a/libffi/src/powerpc/ffi.c +++ b/libffi/src/powerpc/ffi.c @@ -288,7 +288,7 @@ enum { ASM_NEEDS_REGISTERS64 = 4 }; |--------------------------------------------| | | TOC save area 8 | | |--------------------------------------------| | stack | - | Linker doubleword 8 | | gorws | + | Linker doubleword 8 | | grows | |--------------------------------------------| | down V | Compiler doubleword 8 | | |--------------------------------------------| | lower addresses @@ -384,15 +384,14 @@ void hidden ffi_prep_args64(extended_cif *ecif, unsigned long *const stack) } else { - /* Structures with 1, 2 and 4 byte sizes are passed left-padded - if they are in the first 8 arguments. */ - if (next_arg >= gpr_base - && (*ptr)->size < 8 - && ((*ptr)->size & ~((*ptr)->size - 1)) == (*ptr)->size) - memcpy((char *) next_arg + 8 - (*ptr)->size, - (char *) *p_argv, (*ptr)->size); - else - memcpy((char *) next_arg, (char *) *p_argv, (*ptr)->size); + char *where = (char *) next_arg; + + /* Structures with size less than eight bytes are passed + left-padded. */ + if ((*ptr)->size < 8) + where += 8 - (*ptr)->size; + + memcpy (where, (char *) *p_argv, (*ptr)->size); next_arg += words; if (next_arg == gpr_end) next_arg = rest; @@ -1027,12 +1026,9 @@ ffi_closure_helper_LINUX64 (ffi_closure* closure, void * rvalue, #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: #endif - /* Structures with 1, 2 and 4 byte sizes are passed left-padded - if they are in the first 8 arguments. */ - if (ng < NUM_GPR_ARG_REGISTERS64 - && arg_types[i]->size < 8 - && ((arg_types[i]->size & ~(arg_types[i]->size - 1)) - == arg_types[i]->size)) + /* 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 avalue[i] = pst; diff --git a/libffi/src/powerpc/linux64.S b/libffi/src/powerpc/linux64.S index 28727cd01f8..d8af13b108a 100644 --- a/libffi/src/powerpc/linux64.S +++ b/libffi/src/powerpc/linux64.S @@ -95,17 +95,6 @@ ffi_call_LINUX64: lfd %f12, -32-(10*8)(%r28) lfd %f13, -32-(9*8)(%r28) 2: - /* FIXME: Shouldn't gcc use %r3-%r10 in this case - and not the parm save area? */ - std %r3, 48+(0*8)(%r1) - std %r4, 48+(1*8)(%r1) - std %r5, 48+(2*8)(%r1) - std %r6, 48+(3*8)(%r1) - std %r7, 48+(4*8)(%r1) - std %r8, 48+(5*8)(%r1) - std %r9, 48+(6*8)(%r1) - std %r10, 48+(7*8)(%r1) - /* end of FIXME. */ /* Make the call. */ bctrl diff --git a/libffi/src/powerpc/linux64_closure.S b/libffi/src/powerpc/linux64_closure.S index 1159c1e77a8..6cad16ad77d 100644 --- a/libffi/src/powerpc/linux64_closure.S +++ b/libffi/src/powerpc/linux64_closure.S @@ -64,6 +64,7 @@ ffi_closure_LINUX64: # make the call bl .ffi_closure_helper_LINUX64 +.Lret: # now r3 contains the return type # so use it to look up in a table @@ -71,10 +72,10 @@ ffi_closure_LINUX64: # look up the proper starting point in table # by using return type as offset - addi %r5, %r1, 112 # get pointer to results area - bl .Lget_ret_type0_addr # get pointer to .Lret_type0 into LR - mflr %r4 # move to r4 + mflr %r4 # move address of .Lret to r4 sldi %r3, %r3, 4 # now multiply return type by 16 + addi %r4, %r4, .Lret_type0 - .Lret + ld %r0, 224+16(%r1) add %r3, %r3, %r4 # add contents of table to table address mtctr %r3 bctr # jump to it @@ -84,94 +85,84 @@ ffi_closure_LINUX64: # first. .align 4 - nop - nop - nop -.Lget_ret_type0_addr: - blrl - .Lret_type0: # case FFI_TYPE_VOID - b .Lfinish - nop - nop - nop -# case FFI_TYPE_INT - lwa %r3, 4(%r5) - b .Lfinish - nop - nop -# case FFI_TYPE_FLOAT - lfs %f1, 4(%r5) - b .Lfinish - nop - nop -# case FFI_TYPE_DOUBLE - lfd %f1, 0(%r5) - b .Lfinish - nop - nop -# case FFI_TYPE_LONGDOUBLE - lfd %f1, 0(%r5) - b .Lfinish - nop - nop -# case FFI_TYPE_UINT8 - lbz %r3, 7(%r5) - b .Lfinish - nop - nop -# case FFI_TYPE_SINT8 - lbz %r3, 7(%r5) - extsb %r3,%r3 - b .Lfinish - nop -# case FFI_TYPE_UINT16 - lhz %r3, 6(%r5) - b .Lfinish - nop - nop -# case FFI_TYPE_SINT16 - lha %r3, 6(%r5) - b .Lfinish - nop - nop -# case FFI_TYPE_UINT32 - lwz %r3, 4(%r5) - b .Lfinish - nop - nop -# case FFI_TYPE_SINT32 - lwa %r3, 4(%r5) - b .Lfinish - nop - nop -# case FFI_TYPE_UINT64 - ld %r3, 0(%r5) - b .Lfinish - nop - nop -# case FFI_TYPE_SINT64 - ld %r3, 0(%r5) - b .Lfinish - nop - nop -# case FFI_TYPE_STRUCT - b .Lfinish - nop - nop - nop -# case FFI_TYPE_POINTER - ld %r3, 0(%r5) - b .Lfinish - nop - nop -# esac -.Lfinish: - ld %r0, 224+16(%r1) mtlr %r0 addi %r1, %r1, 224 blr + nop +# case FFI_TYPE_INT + lwa %r3, 112+4(%r1) + mtlr %r0 + addi %r1, %r1, 224 + blr +# case FFI_TYPE_FLOAT + lfs %f1, 112+4(%r1) + mtlr %r0 + addi %r1, %r1, 224 + blr +# case FFI_TYPE_DOUBLE + lfd %f1, 112+0(%r1) + mtlr %r0 + addi %r1, %r1, 224 + blr +# case FFI_TYPE_LONGDOUBLE + lfd %f1, 112+0(%r1) + mtlr %r0 + addi %r1, %r1, 224 + blr +# case FFI_TYPE_UINT8 + lbz %r3, 112+7(%r1) + mtlr %r0 + addi %r1, %r1, 224 + blr +# case FFI_TYPE_SINT8 + lbz %r3, 112+7(%r1) + extsb %r3,%r3 + mtlr %r0 + b .Lfinish +# case FFI_TYPE_UINT16 + lhz %r3, 112+6(%r1) + mtlr %r0 +.Lfinish: + addi %r1, %r1, 224 + blr +# case FFI_TYPE_SINT16 + lha %r3, 112+6(%r1) + mtlr %r0 + addi %r1, %r1, 224 + blr +# case FFI_TYPE_UINT32 + lwz %r3, 112+4(%r1) + mtlr %r0 + addi %r1, %r1, 224 + blr +# case FFI_TYPE_SINT32 + lwa %r3, 112+4(%r1) + mtlr %r0 + addi %r1, %r1, 224 + blr +# case FFI_TYPE_UINT64 + ld %r3, 112+0(%r1) + mtlr %r0 + addi %r1, %r1, 224 + blr +# case FFI_TYPE_SINT64 + ld %r3, 112+0(%r1) + mtlr %r0 + addi %r1, %r1, 224 + blr +# case FFI_TYPE_STRUCT + mtlr %r0 + addi %r1, %r1, 224 + blr + nop +# case FFI_TYPE_POINTER + ld %r3, 112+0(%r1) + mtlr %r0 + addi %r1, %r1, 224 + blr +# esac .LFE1: .long 0 .byte 0,12,0,1,128,0,0,0