libffi patch: closure fixes for Alpha

Anthony Green green@cygnus.com
Sat Dec 9 16:29:00 GMT 2000


I'm going to check these important fixes in once the tree is available
to changes.


2000-12-09  Richard Henderson  <rth@redhat.com>

	* src/alpha/ffi.c (ffi_call): Simplify struct return test.
	(ffi_closure_osf_inner): Index rather than increment avalue
	and arg_types.  Give ffi_closure_osf the raw return value type.
	* src/alpha/osf.S (ffi_closure_osf): Handle return value type
	promotion.

Index: libffi/src/alpha/ffi.c
===================================================================
RCS file: /cvs/java/libgcj/libffi/src/alpha/ffi.c,v
retrieving revision 1.2
diff -u -p -u -r1.2 ffi.c
--- ffi.c	2000/12/08 19:41:15	1.2
+++ ffi.c	2000/12/10 00:26:53
@@ -70,7 +70,7 @@ ffi_call(ffi_cif *cif, void (*fn)(), voi
 
   /* If the return value is a struct and we don't have a return
      value address then we need to make one.  */
-  if (rvalue == NULL && cif->rtype->type == FFI_TYPE_STRUCT)
+  if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT)
     rvalue = alloca(cif->rtype->size);
 
   /* Allocate the space for the arguments, plus 4 words of temp
@@ -202,7 +202,7 @@ ffi_closure_osf_inner(ffi_closure *closu
   /* Grab the addresses of the arguments from the stack frame.  */
   while (i < avn)
     {
-      switch ((*arg_types)->type)
+      switch (arg_types[i]->type)
 	{
 	case FFI_TYPE_SINT8:
 	case FFI_TYPE_UINT8:
@@ -214,7 +214,7 @@ ffi_closure_osf_inner(ffi_closure *closu
 	case FFI_TYPE_UINT64:
 	case FFI_TYPE_POINTER:
 	case FFI_TYPE_STRUCT:
-	  *avalue = &argp[argn];
+	  avalue[i] = &argp[argn];
 	  break;
 
 	case FFI_TYPE_FLOAT:
@@ -223,27 +223,27 @@ ffi_closure_osf_inner(ffi_closure *closu
 	      /* Floats coming from registers need conversion from double
 	         back to float format.  */
 	      *(float *)&argp[argn - 6] = *(double *)&argp[argn - 6];
-	      *avalue = &argp[argn - 6];
+	      avalue[i] = &argp[argn - 6];
 	    }
 	  else
-	    *avalue = &argp[argn];
+	    avalue[i] = &argp[argn];
 	  break;
 
 	case FFI_TYPE_DOUBLE:
-	  *avalue = &argp[argn - (argn < 6 ? 6 : 0)];
+	  avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)];
 	  break;
 
 	default:
 	  FFI_ASSERT(0);
 	}
 
-      argn += ALIGN((*arg_types)->size, SIZEOF_ARG) / SIZEOF_ARG;
-      i++, arg_types++, avalue++;
+      argn += ALIGN(arg_types[i]->size, SIZEOF_ARG) / SIZEOF_ARG;
+      i++;
     }
 
   /* Invoke the closure.  */
   (closure->fun) (cif, rvalue, avalue, closure->user_data);
 
-  /* Tell ffi_closure_osf what register to put the return value in.  */
-  return cif->flags;
+  /* Tell ffi_closure_osf how to perform return type promotions.  */
+  return cif->rtype->type;
 }
Index: libffi/src/alpha/osf.S
===================================================================
RCS file: /cvs/java/libgcj/libffi/src/alpha/osf.S,v
retrieving revision 1.2
diff -u -p -u -r1.2 osf.S
--- osf.S	2000/12/08 19:41:15	1.2
+++ osf.S	2000/12/10 00:26:53
@@ -28,6 +28,7 @@
 #define LIBFFI_ASM	
 #include <ffi.h>
 
+	.arch ev6
 	.text
 
 /* ffi_call_osf (void *args, unsigned long bytes, unsigned flags,
@@ -121,9 +122,9 @@ $retdouble:
 	.ent	ffi_closure_osf
 ffi_closure_osf:
 	.frame	$30, 16*8, $26, 0
-	.mask	0x4000000, -14*8
+	.mask	0x4000000, -16*8
 	ldgp	$29, 0($27)
-	subq	$30, 14*8, $30
+	subq	$30, 16*8, $30
 	stq	$26, 0($30)
 	.prologue 1
 
@@ -150,33 +151,129 @@ ffi_closure_osf:
 	ldq	$26, 0($30)
 
 	# Load up the return value in the proper type.
-	cmpeq	$0, FFI_TYPE_INT, $1
-	bne	$1, $loadint
-	cmpeq	$0, FFI_TYPE_FLOAT, $2
-	bne	$2, $loadfloat
-	cmpeq	$18, FFI_TYPE_DOUBLE, $3
-	bne	$3, $loaddouble
+	lda	$1, $load_table
+	s4addq	$0, $1, $1
+	ldl	$1, 0($1)
+	addq	$1, $29, $1
+	jmp	$31, ($1), $load_32
+
+	.align 4
+$load_none:
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_float:
+	lds	$f0, 16($30)
+	nop
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_double:
+	ldt	$f0, 16($30)
+	nop
+	addq	$30, 16*8, $30
+	ret
 
+	.align 4
+$load_u8:
+#ifdef __alpha_bwx__
+	ldbu	$0, 16($30)
+	nop
+#else
+	ldq	$0, 16($30)
+	and	$0, 255, $0
+#endif
 	addq	$30, 16*8, $30
 	ret
 
-	.align 3
-$loadint:
+	.align 4
+$load_s8:
+#ifdef __alpha_bwx__
+	ldbu	$0, 16($30)
+	sextb	$0, $0
+#else
 	ldq	$0, 16($30)
+	sll	$0, 56, $0
+	sra	$0, 56, $0
+#endif
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_u16:
+#ifdef __alpha_bwx__
+	ldwu	$0, 16($30)
 	nop
+#else
+	ldq	$0, 16($30)
+	zapnot	$0, 3, $0
+#endif
 	addq	$30, 16*8, $30
 	ret
 
-$loadfloat:
-	lds	$f0, 16($30)
+	.align 4
+$load_s16:
+#ifdef __alpha_bwx__
+	ldwu	$0, 16($30)
+	sextw	$0, $0
+#else
+	ldq	$0, 16($30)
+	sll	$0, 48, $0
+	sra	$0, 48, $0
+#endif
+	addq	$30, 16*8, $30
+	ret
+
+	.align 4
+$load_32:
+	ldl	$0, 16($30)
 	nop
 	addq	$30, 16*8, $30
 	ret
 
-$loaddouble:
-	ldt	$f0, 16($30)
+	.align 4
+$load_64:
+	ldq	$0, 16($30)
 	nop
 	addq	$30, 16*8, $30
 	ret
 
 	.end	ffi_closure_osf
+
+.section .rodata
+$load_table:
+	.gprel32 $load_none	# FFI_TYPE_VOID
+	.gprel32 $load_32	# FFI_TYPE_INT
+	.gprel32 $load_float	# FFI_TYPE_FLOAT
+	.gprel32 $load_double	# FFI_TYPE_DOUBLE
+	.gprel32 $load_double	# FFI_TYPE_LONGDOUBLE
+	.gprel32 $load_u8	# FFI_TYPE_UINT8
+	.gprel32 $load_s8	# FFI_TYPE_SINT8
+	.gprel32 $load_u16	# FFI_TYPE_UINT16
+	.gprel32 $load_s16	# FFI_TYPE_SINT16
+	.gprel32 $load_32	# FFI_TYPE_UINT32
+	.gprel32 $load_32	# FFI_TYPE_SINT32
+	.gprel32 $load_64	# FFI_TYPE_UINT64
+	.gprel32 $load_64	# FFI_TYPE_SINT64
+	.gprel32 $load_none	# FFI_TYPE_STRUCT
+	.gprel32 $load_64	# FFI_TYPE_POINTER
+
+/* Assert that the table above is in sync with ffi.h.  */
+
+#if	   FFI_TYPE_FLOAT != 2		\
+	|| FFI_TYPE_DOUBLE != 3		\
+	|| FFI_TYPE_UINT8 != 5		\
+	|| FFI_TYPE_SINT8 != 6		\
+	|| FFI_TYPE_UINT16 != 7		\
+	|| FFI_TYPE_SINT16 != 8		\
+	|| FFI_TYPE_UINT32 != 9		\
+	|| FFI_TYPE_SINT32 != 10	\
+	|| FFI_TYPE_UINT64 != 11	\
+	|| FFI_TYPE_SINT64 != 12	\
+	|| FFI_TYPE_STRUCT != 13	\
+	|| FFI_TYPE_POINTER != 14	\
+	|| FFI_TYPE_LAST != 14
+#error "osf.S out of sync with ffi.h"
+#endif



More information about the Java-patches mailing list