This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PowerPC64 (+other arches) libffi fixes


This fixes the remaining PowerPC64 libffi testsuite failures.

FAIL: libffi.call/cls_3byte1.c execution test
FAIL: libffi.call/cls_5byte.c execution test
FAIL: libffi.call/cls_float.c output pattern test
FAIL: libffi.special/unwindtest.cc execution test

	* src/prep_cif.c (initialize_aggregate): Include tail padding in
	structure size.
	* src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Correct
	placement of float result.
	* testsuite/libffi.special/unwindtest.cc (closure_test_fn1): Correct
	cast of "resp" for big-endian 64 bit machines.

I'm reasonably sure that the initialize_aggregate change should be
done on all arches to get nested structure layout correct.  Without
this patch, the example in the comment below would result in the inner
struct size being calculated as sizeof(long)+1, and the total struct
size as sizeof(long)+2.  This is then rounded up to 2*sizeof(long) in
ffi_prep_cif, but that's the wrong answer.

So, with permission, I'd like to commit the following without the
#ifdef POWERPC64 test.

Index: libffi/src/prep_cif.c
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/prep_cif.c,v
retrieving revision 1.5
diff -u -p -r1.5 prep_cif.c
--- libffi/src/prep_cif.c	30 Sep 2002 11:59:42 -0000	1.5
+++ libffi/src/prep_cif.c	11 Sep 2003 07:31:09 -0000
@@ -64,6 +64,17 @@ static ffi_status initialize_aggregate(/
       ptr++;
     }
 
+#if defined POWERPC64
+  /* Structure size includes tail padding.  This is important for
+     structures that fit in one register on ABIs like the PowerPC64
+     Linux ABI that right justify small structs in a register.
+     It's also needed for nested structure layout, for example
+     struct A { long a; char b; }; struct B { struct A x; char y; };
+     should find y at an offset of 2*sizeof(long) and result in a
+     total size of 3*sizeof(long).  */
+  arg->size = ALIGN (arg->size, arg->alignment);
+#endif
+
   if (arg->size == 0)
     return FFI_BAD_TYPEDEF;
   else
Index: libffi/src/powerpc/linux64_closure.S
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/powerpc/linux64_closure.S,v
retrieving revision 1.3
diff -u -p -r1.3 linux64_closure.S
--- libffi/src/powerpc/linux64_closure.S	1 Aug 2003 15:19:01 -0000	1.3
+++ libffi/src/powerpc/linux64_closure.S	11 Sep 2003 07:31:09 -0000
@@ -97,7 +97,7 @@ ffi_closure_LINUX64:
 	addi %r1, %r1, 224
 	blr
 # case FFI_TYPE_FLOAT
-	lfs %f1, 112+4(%r1)
+	lfs %f1, 112+0(%r1)
 	mtlr %r0
 	addi %r1, %r1, 224
 	blr
Index: libffi/testsuite/libffi.special/unwindtest.cc
===================================================================
RCS file: /cvs/gcc/gcc/libffi/testsuite/libffi.special/unwindtest.cc,v
retrieving revision 1.1
diff -u -p -r1.1 unwindtest.cc
--- libffi/testsuite/libffi.special/unwindtest.cc	4 Sep 2003 14:47:48 -0000	1.1
+++ libffi/testsuite/libffi.special/unwindtest.cc	11 Sep 2003 07:31:09 -0000
@@ -37,9 +37,9 @@ void closure_test_fn1(ffi_cif* cif,void*
     	   (int)(*(int *)args[10]), (int)(*(float *)args[11]),
     	   (int)*(int *)args[12], (int)(*(int *)args[13]),
     	   (int)(*(int *)args[14]), *(int *)args[15],
-    	   (int)(long)userdata, *(int*)resp);
+    	   (int)(long)userdata, (int)*(ffi_arg*)resp);
     
-    throw *(int*)resp;
+    throw (int)*(ffi_arg*)resp;
 }
 
 typedef int (*closure_test_type1)(float, float, float, float, signed short, 

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]