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]

structure ABI fixes for powerpc-darwin


[I found this mail trapped in my mail system.  I don't know if it ever
got sent, so am re-sending it to make sure.]

This patch fixes the many darwin-abi testcases that are XFAILed on
mainline.  It also fixes libffi to match the Darwin ABI, and fixes a
few XFAILed testcases there.

It does, however, break more of the objc.dg-struct-layout-encoding-1
testcases; the existing behaviour of that code is preserved, but now
the testcases can see that they're further away from the real ABI than
they used to be.

I'm running a bootstrap and testrun on powerpc-darwin8, and will queue
for 4.3 if that's successful.

-- 
- Geoffrey Keating <geoffk@apple.com>

===File ~/patches/gcc-rs6000-darwinabi.patch================
Index: gcc/ChangeLog
2006-10-16  Geoffrey Keating  <geoffk@apple.com>

	PR 23067
	* c-decl.c (start_struct): Don't create self-containing
	structures.
	* config/rs6000/rs6000.c (darwin_rs6000_special_round_type_align):
	New.
	* config/rs6000/rs6000-protos.h
	(darwin_rs6000_special_round_type_align): New.
	* config/rs6000/darwin.h (ADJUST_FIELD_ALIGN): Rewrite.
	(ROUND_TYPE_ALIGN): Use darwin_rs6000_special_round_type_align.

Index: gcc/testsuite/ChangeLog
2006-10-16  Geoffrey Keating  <geoffk@apple.com>

	PR 23067
	* gcc.target/powerpc/darwin-abi-3.c: Remove XFAIL.
	* gcc.target/powerpc/darwin-abi-6.c: Remove XFAIL.
	* gcc.target/powerpc/darwin-abi-7.c: Remove XFAIL.
	* gcc.target/powerpc/darwin-abi-8.c: Remove XFAIL.
	* gcc.target/powerpc/darwin-abi-9.c: Remove XFAIL.
	* gcc.target/powerpc/darwin-abi-10.c: Remove XFAIL.
	* gcc.target/powerpc/darwin-abi-11.c: Remove XFAIL.

Index: libobjc/ChangeLog
2006-10-16  Geoffrey Keating  <geoffk@apple.com>

	* encoding.c (darwin_rs6000_special_round_type_align): New.

Index: libffi/ChangeLog
2006-10-16  Geoffrey Keating  <geoffk@apple.com>

	* src/powerpc/ffi_darwin.c (darwin_adjust_aggregate_sizes): New.
	(ffi_prep_cif_machdep): Call darwin_adjust_aggregate_sizes for
	Darwin.
	* testsuite/libffi.call/nested_struct4.c: Remove Darwin XFAIL.
	* testsuite/libffi.call/nested_struct6.c: Remove Darwin XFAIL.

Index: gcc/testsuite/gcc.target/powerpc/darwin-abi-11.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darwin-abi-11.c	(revision 118903)
+++ gcc/testsuite/gcc.target/powerpc/darwin-abi-11.c	(working copy)
@@ -1,6 +1,5 @@
 /* { dg-do compile { target powerpc*-*-darwin* } } */
 /* { dg-require-effective-target ilp32 } */
-/* { dg-xfail-if "" { powerpc*-*-darwin* } } */
 /* { dg-options "-Wno-long-long" } */
 
 struct A
Index: gcc/testsuite/gcc.target/powerpc/darwin-abi-9.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darwin-abi-9.c	(revision 118903)
+++ gcc/testsuite/gcc.target/powerpc/darwin-abi-9.c	(working copy)
@@ -1,6 +1,5 @@
 /* { dg-do compile { target powerpc*-*-darwin* } } */
 /* { dg-require-effective-target ilp32 } */
-/* { dg-xfail-if "" { powerpc*-*-darwin* } } */
 /* { dg-options "-Wno-long-long" } */
 
 struct b
Index: gcc/testsuite/gcc.target/powerpc/darwin-abi-6.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darwin-abi-6.c	(revision 118903)
+++ gcc/testsuite/gcc.target/powerpc/darwin-abi-6.c	(working copy)
@@ -1,6 +1,5 @@
 /* { dg-do compile { target powerpc*-*-darwin* } } */
 /* { dg-require-effective-target ilp32 } */
-/* { dg-xfail-if "" { powerpc*-*-darwin* } } */
 /* { dg-options "-Wno-long-long" } */
 
 struct a
Index: gcc/testsuite/gcc.target/powerpc/darwin-abi-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darwin-abi-3.c	(revision 118903)
+++ gcc/testsuite/gcc.target/powerpc/darwin-abi-3.c	(working copy)
@@ -1,6 +1,5 @@
 /* { dg-do compile { target powerpc*-*-darwin* } } */
 /* { dg-require-effective-target ilp32 } */
-/* { dg-xfail-if "" { powerpc*-*-darwin* } } */
 /* { dg-options "-Wno-long-long" } */
 struct f
 {
Index: gcc/testsuite/gcc.target/powerpc/darwin-abi-7.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darwin-abi-7.c	(revision 118903)
+++ gcc/testsuite/gcc.target/powerpc/darwin-abi-7.c	(working copy)
@@ -1,6 +1,5 @@
 /* { dg-do compile { target powerpc*-*-darwin* } } */
 /* { dg-require-effective-target ilp32 } */
-/* { dg-xfail-if "" { powerpc*-*-darwin* } } */
 /* { dg-options "-Wno-long-long" } */
 
 struct b
Index: gcc/testsuite/gcc.target/powerpc/darwin-abi-10.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darwin-abi-10.c	(revision 118903)
+++ gcc/testsuite/gcc.target/powerpc/darwin-abi-10.c	(working copy)
@@ -1,6 +1,5 @@
 /* { dg-do compile { target powerpc*-*-darwin* } } */
 /* { dg-require-effective-target ilp32 } */
-/* { dg-xfail-if "" { powerpc*-*-darwin* } } */
 /* { dg-options "-Wno-long-long" } */
 
 struct b
Index: gcc/testsuite/gcc.target/powerpc/darwin-abi-8.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darwin-abi-8.c	(revision 118903)
+++ gcc/testsuite/gcc.target/powerpc/darwin-abi-8.c	(working copy)
@@ -1,6 +1,5 @@
 /* { dg-do compile { target powerpc*-*-darwin* } } */
 /* { dg-require-effective-target ilp32 } */
-/* { dg-xfail-if "" { powerpc*-*-darwin* } } */
 
 struct c
 {
Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c	(revision 118903)
+++ gcc/c-decl.c	(working copy)
@@ -5280,12 +5280,15 @@
 	    error ("nested redefinition of %<union %E%>", name);
 	  else
 	    error ("nested redefinition of %<struct %E%>", name);
+	  /* Don't create structures that contain themselves.  */
+	  ref = NULL_TREE;
 	}
     }
-  else
+
+  /* Otherwise create a forward-reference just so the tag is in scope.  */
+
+  if (ref == NULL_TREE || TREE_CODE (ref) != code)
     {
-      /* Otherwise create a forward-reference just so the tag is in scope.  */
-
       ref = make_node (code);
       pushtag (name, ref);
     }
Index: gcc/config/rs6000/darwin.h
===================================================================
--- gcc/config/rs6000/darwin.h	(revision 118903)
+++ gcc/config/rs6000/darwin.h	(working copy)
@@ -367,26 +367,28 @@
 /* Fix for emit_group_load (): force large constants to be pushed via regs.  */
 #define ALWAYS_PUSH_CONSTS_USING_REGS_P		1
 
-/* This now supports a natural alignment mode */
-/* Darwin word-aligns FP doubles but doubleword-aligns 64-bit ints.  */
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
-  (TARGET_ALIGN_NATURAL ? (COMPUTED) : \
-  (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
-	      ? get_inner_array_type (FIELD) \
-	      : TREE_TYPE (FIELD)) == DFmode \
-   ? MIN ((COMPUTED), 32) : (COMPUTED)))
+/* Compute field alignment.  This is similar to the version of the
+   macro in the Apple version of GCC, except that version supports
+   'mac68k' alignment, and that version uses the computed alignment
+   always for the first field of a structure.  The first-field
+   behaviour is dealt with by
+   darwin_rs6000_special_round_type_align.  */
+#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)	\
+  (TARGET_ALIGN_NATURAL ? (COMPUTED)		\
+   : (COMPUTED) == 128 ? 128			\
+   : MIN ((COMPUTED), 32))
 
 /* Darwin increases natural record alignment to doubleword if the first
    field is an FP double while the FP fields remain word aligned.  */
-#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED)			\
-  ((TREE_CODE (STRUCT) == RECORD_TYPE					\
-    || TREE_CODE (STRUCT) == UNION_TYPE					\
-    || TREE_CODE (STRUCT) == QUAL_UNION_TYPE)				\
-   && TARGET_ALIGN_NATURAL == 0                         		\
-   ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED)	\
-   : (TREE_CODE (STRUCT) == VECTOR_TYPE					\
-      && ALTIVEC_VECTOR_MODE (TYPE_MODE (STRUCT))) 			\
-   ? MAX (MAX ((COMPUTED), (SPECIFIED)), 128)          			 \
+#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED)			  \
+  ((TREE_CODE (STRUCT) == RECORD_TYPE					  \
+    || TREE_CODE (STRUCT) == UNION_TYPE					  \
+    || TREE_CODE (STRUCT) == QUAL_UNION_TYPE)				  \
+   && TARGET_ALIGN_NATURAL == 0						  \
+   ? darwin_rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED) \
+   : (TREE_CODE (STRUCT) == VECTOR_TYPE					  \
+      && ALTIVEC_VECTOR_MODE (TYPE_MODE (STRUCT)))			  \
+   ? MAX (MAX ((COMPUTED), (SPECIFIED)), 128)				  \
    : MAX ((COMPUTED), (SPECIFIED)))
 
 /* Specify padding for the last element of a block move between
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 118903)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -2591,7 +2591,7 @@
   return false;
 }
 
-/* Darwin, AIX increases natural record alignment to doubleword if the first
+/* AIX increases natural record alignment to doubleword if the first
    field is an FP double while the FP fields remain word aligned.  */
 
 unsigned int
@@ -2618,6 +2618,37 @@
   return align;
 }
 
+/* Darwin increases record alignment to the natural alignment of
+   the first field.  */
+
+unsigned int
+darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
+					unsigned int specified)
+{
+  unsigned int align = MAX (computed, specified);
+
+  if (TYPE_PACKED (type))
+    return align;
+
+  /* Find the first field, looking down into aggregates.  */
+  do {
+    tree field = TYPE_FIELDS (type);
+    /* Skip all non field decls */
+    while (field != NULL && TREE_CODE (field) != FIELD_DECL)
+      field = TREE_CHAIN (field);
+    if (! field)
+      break;
+    type = TREE_TYPE (field);
+    while (TREE_CODE (type) == ARRAY_TYPE)
+      type = TREE_TYPE (type);
+  } while (AGGREGATE_TYPE_P (type));
+
+  if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
+    align = MAX (align, TYPE_ALIGN (type));
+
+  return align;
+}
+
 /* Return 1 for an operand in small memory on V.4/eabi.  */
 
 int
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
--- gcc/config/rs6000/rs6000-protos.h	(revision 118903)
+++ gcc/config/rs6000/rs6000-protos.h	(working copy)
@@ -114,6 +114,8 @@
 #ifdef TREE_CODE
 extern unsigned int rs6000_special_round_type_align (tree, unsigned int,
 						     unsigned int);
+extern unsigned int darwin_rs6000_special_round_type_align (tree, unsigned int,
+							    unsigned int);
 extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
 				  tree, int, int);
 extern int function_arg_boundary (enum machine_mode, tree);
Index: libobjc/encoding.c
===================================================================
--- libobjc/encoding.c	(revision 118903)
+++ libobjc/encoding.c	(working copy)
@@ -120,6 +120,10 @@
 		    : TREE_TYPE (_fields)) == DFmode)			\
    ? MAX (MAX (COMPUTED, SPECIFIED), 64)				\
    : MAX (COMPUTED, SPECIFIED));})
+/* FIXME: The word 'fixme' is insufficient to explain the wrong-ness
+   of this next macro definition.  */
+#define darwin_rs6000_special_round_type_align(S,C,S2) \
+  rs6000_special_round_type_align(S,C,S2)
 
 /*
   return the size of an object specified by type
Index: libffi/src/powerpc/ffi_darwin.c
===================================================================
--- libffi/src/powerpc/ffi_darwin.c	(revision 118903)
+++ libffi/src/powerpc/ffi_darwin.c	(working copy)
@@ -1,11 +1,12 @@
 /* -----------------------------------------------------------------------
-   ffi.c - Copyright (c) 1998 Geoffrey Keating
+   ffi_darwin.c
 
-   PowerPC Foreign Function Interface
+   Copyright (C) 1998 Geoffrey Keating
+   Copyright (C) 2001 John Hornkvist
+   Copyright (C) 2002, 2006 Free Software Foundation, Inc.
 
-   Darwin ABI support (c) 2001 John Hornkvist
-   AIX ABI support (c) 2002 Free Software Foundation, Inc.
-
+   FFI support for Darwin and AIX.
+   
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
    ``Software''), to deal in the Software without restriction, including
@@ -225,6 +226,48 @@
   //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
 }
 
+/* Adjust the size of S to be correct for Darwin.
+   On Darwin, the first field of a structure has natural alignment.  */
+
+static void
+darwin_adjust_aggregate_sizes (ffi_type *s)
+{
+  int i;
+
+  if (s->type != FFI_TYPE_STRUCT)
+    return;
+
+  s->size = 0;
+  for (i = 0; s->elements[i] != NULL; i++)
+    {
+      ffi_type *p;
+      int align;
+      
+      p = s->elements[i];
+      darwin_adjust_aggregate_sizes (p);
+      if (i == 0
+	  && (p->type == FFI_TYPE_UINT64
+	      || p->type == FFI_TYPE_SINT64
+	      || p->type == FFI_TYPE_DOUBLE
+	      || p->alignment == 8))
+	align = 8;
+      else if (p->alignment == 16 || p->alignment < 4)
+	align = p->alignment;
+      else
+	align = 4;
+      s->size = ALIGN(s->size, align) + p->size;
+    }
+  
+  s->size = ALIGN(s->size, s->alignment);
+  
+  if (s->elements[0]->type == FFI_TYPE_UINT64
+      || s->elements[0]->type == FFI_TYPE_SINT64
+      || s->elements[0]->type == FFI_TYPE_DOUBLE
+      || s->elements[0]->alignment == 8)
+    s->alignment = s->alignment > 8 ? s->alignment : 8;
+  /* Do not add additional tail padding.  */
+}
+
 /* Perform machine dependent cif processing.  */
 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
 {
@@ -237,8 +280,16 @@
   unsigned size_al = 0;
 
   /* All the machine-independent calculation of cif->bytes will be wrong.
+     All the calculation of structure sizes will also be wrong.
      Redo the calculation for DARWIN.  */
 
+  if (cif->abi == FFI_DARWIN)
+    {
+      darwin_adjust_aggregate_sizes (cif->rtype);
+      for (i = 0; i < cif->nargs; i++)
+	darwin_adjust_aggregate_sizes (cif->arg_types[i]);
+    }
+
   /* Space for the frame pointer, callee's LR, CR, etc, and for
      the asm's temp regs.  */
 
Index: libffi/testsuite/libffi.call/nested_struct4.c
===================================================================
--- libffi/testsuite/libffi.call/nested_struct4.c	(revision 118903)
+++ libffi/testsuite/libffi.call/nested_struct4.c	(working copy)
@@ -6,7 +6,7 @@
    PR:		PR 25630.
    Originator:	<andreast@gcc.gnu.org> 20051010	 */
 
-/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* powerpc*-*-darwin* } } */
+/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
 #include "ffitest.h"
 
 typedef struct A {
Index: libffi/testsuite/libffi.call/nested_struct6.c
===================================================================
--- libffi/testsuite/libffi.call/nested_struct6.c	(revision 118903)
+++ libffi/testsuite/libffi.call/nested_struct6.c	(working copy)
@@ -6,7 +6,7 @@
    PR:		PR 25630.
    Originator:	<andreast@gcc.gnu.org> 20051010	 */
 
-/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* powerpc*-*-darwin* } } */
+/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
 #include "ffitest.h"
 
 typedef struct A {
============================================================


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