[PATCH] Fix powerpc libffi (take 2)

Jakub Jelinek jakub@redhat.com
Tue Jan 17 23:13:00 GMT 2006


Hi!
On Tue, Jan 17, 2006 at 08:38:41AM -0500, Jakub Jelinek wrote:
> I don't have access to powerpc*-*-freebsd*, so I have just briefly tested
> the sysv.S change with powerpc64-*-linux -> powerpc*-*-freebsd* cross
> compiling and writing my own testcase that called the freebsd cross compiler
> compiled routines, but I haven't really tested the ppc_closure.S bits
> (I ran make check on powerpc64-*-linux* -m32, but that doesn't test those
> bits).

Andreas kindly tested it on FreeBSD and a bug has been found for 5 and 7
byte long structs.  Here is an updated patch that passed even on
powerpc*-*-freebsd*.

Ok for trunk/4.1?

2006-01-18  Jakub Jelinek  <jakub@redhat.com>

	* 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.

--- libffi/src/powerpc/sysv.S.jj	2006-01-17 14:03:21.000000000 +0100
+++ libffi/src/powerpc/sysv.S	2006-01-17 14:14:55.000000000 +0100
@@ -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)
--- libffi/src/powerpc/ppc_closure.S.jj	2006-01-17 14:03:21.000000000 +0100
+++ libffi/src/powerpc/ppc_closure.S	2006-01-17 23:36:52.000000000 +0100
@@ -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

	Jakub



More information about the Gcc-patches mailing list