diff --git a/libffi/ChangeLog b/libffi/ChangeLog index 307e04b54ef..13c279d3329 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -1,3 +1,12 @@ +2006-01-18 Jakub Jelinek + + * src/powerpc/sysv.S (smst_two_register): Don't call __ashldi3, + instead do the shifting inline. + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't compute %r5 + shift count unconditionally. Simplify load sequences for 1, 2, 3, 4 + and 8 byte structs, for the remaining struct sizes don't call + __lshrdi3, instead do the shifting inline. + 2005-12-07 Thiemo Seufer * src/mips/ffitarget.h: Remove obsolete sgidefs.h include. Add diff --git a/libffi/src/powerpc/ppc_closure.S b/libffi/src/powerpc/ppc_closure.S index 36f8ac08769..370381378f9 100644 --- a/libffi/src/powerpc/ppc_closure.S +++ b/libffi/src/powerpc/ppc_closure.S @@ -63,19 +63,6 @@ ENTRY(ffi_closure_SYSV) # so use it to look up in a table # so we know how to deal with each type - # Extract the size of the return type for small structures. - # Then calculate (4 - size) and multiply the result by 8. - # This gives the value needed for the shift operation below. - # This part is only needed for FFI_SYSV and small structures. - addi %r5,%r3,-(FFI_SYSV_TYPE_SMALL_STRUCT) - cmpwi cr0,%r5,4 - ble cr0,.Lnext - addi %r5,%r5,-4 -.Lnext: - addi %r5,%r5,-4 - neg %r5,%r5 - slwi %r5,%r5,3 - # look up the proper starting point in table # by using return type as offset addi %r6,%r1,112 # get pointer to results area @@ -207,66 +194,66 @@ ENTRY(ffi_closure_SYSV) # case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct. .Lret_type15: # fall through. - nop - nop + lbz %r3,0(%r6) + b .Lfinish nop nop # case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct. .Lret_type16: # fall through. - nop - nop + lhz %r3,0(%r6) + b .Lfinish nop nop # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct. .Lret_type17: # fall through. - nop - nop - nop + lwz %r3,0(%r6) + srwi %r3,%r3,8 + b .Lfinish nop # case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct. .Lret_type18: # this one handles the structs from above too. lwz %r3,0(%r6) - srw %r3,%r3,%r5 b .Lfinish nop + nop # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct. .Lret_type19: # fall through. - nop - nop - nop - nop + lwz %r3,0(%r6) + lwz %r4,4(%r6) + li %r5,24 + b .Lstruct567 # case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct. .Lret_type20: # fall through. - nop - nop - nop - nop + lwz %r3,0(%r6) + lwz %r4,4(%r6) + li %r5,16 + b .Lstruct567 # case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct. .Lret_type21: # fall through. - nop - nop - nop - nop + lwz %r3,0(%r6) + lwz %r4,4(%r6) + li %r5,8 + b .Lstruct567 # case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct. .Lret_type22: # this one handles the above unhandled structs. lwz %r3,0(%r6) lwz %r4,4(%r6) - bl __lshrdi3 # libgcc function to shift r3/r4, shift value in r5. b .Lfinish + nop # case done .Lfinish: @@ -275,6 +262,14 @@ ENTRY(ffi_closure_SYSV) mtlr %r0 addi %r1,%r1,144 blr + +.Lstruct567: + subfic %r0,%r5,32 + srw %r4,%r4,%r5 + slw %r0,%r3,%r0 + srw %r3,%r3,%r5 + or %r4,%r0,%r4 + b .Lfinish END(ffi_closure_SYSV) .section ".eh_frame",EH_FRAME_FLAGS,@progbits diff --git a/libffi/src/powerpc/sysv.S b/libffi/src/powerpc/sysv.S index 235acfad382..6d5a707ec03 100644 --- a/libffi/src/powerpc/sysv.S +++ b/libffi/src/powerpc/sysv.S @@ -140,8 +140,14 @@ L(smst_one_register): b L(done_return_value) L(smst_two_register): rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */ - bl __ashldi3 /* libgcc function to shift r3/r4, - shift value in r5. */ + cmpwi %r5,0 + subfic %r9,%r5,32 + slw %r29,%r3,%r5 + srw %r9,%r4,%r9 + beq- L(smst_8byte) + or %r3,%r9,%r29 + slw %r4,%r4,%r5 +L(smst_8byte): stw %r3,0(%r30) stw %r4,4(%r30) b L(done_return_value)