This is the mail archive of the gcc-bugs@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]

[Bug target/23067] Incorrect struct layout on darwin



------- Comment #20 from pinskia at gcc dot gnu dot org  2005-10-06 18:37 -------
I give up, 3 days no luck at getting this correct.

The current patch follows:
Index: src/powerpc/ffi_darwin.c
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/powerpc/ffi_darwin.c,v
retrieving revision 1.13
diff -u -r1.13 ffi_darwin.c
--- src/powerpc/ffi_darwin.c    2 Sep 2004 21:14:45 -0000       1.13
+++ src/powerpc/ffi_darwin.c    6 Oct 2005 10:33:11 -0000
@@ -195,10 +195,15 @@
             SI 4 bytes) are aligned as if they were those modes.
             Structures with 3 byte in size are padded upwards.  */
          size_al = (*ptr)->size;
-         /* If the first member of the struct is a double, then align
-            the struct to double-word.
-            Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
-         if ((*ptr)->elements[0]->type == 3)
+         /* If the first member of the struct is a double or an [unsigned]
+            long long, then align the struct to double-word.
+            Type 3, 11, and 12 are defined in include/ffi.h.
+            #define FFI_TYPE_DOUBLE     3
+            #define FFI_TYPE_UINT64     11
+            #define FFI_TYPE_SINT64     12  */
+         if ((*ptr)->elements[0]->type == 3
+             || (*ptr)->elements[0]->type == 11
+             || (*ptr)->elements[0]->type == 12)
            size_al = ALIGN((*ptr)->size, 8);
          if (size_al < 3 && ecif->cif->abi == FFI_DARWIN)
            dest_cpy += 4 - size_al;
@@ -337,10 +342,15 @@

        case FFI_TYPE_STRUCT:
          size_al = (*ptr)->size;
-         /* If the first member of the struct is a double, then align
-            the struct to double-word.
-            Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
-         if ((*ptr)->elements[0]->type == 3)
+         /* If the first member of the struct is a double or an [unsigned]
+            long long, then align the struct to double-word.
+            Type 3, 11, and 12 are defined in include/ffi.h.
+            #define FFI_TYPE_DOUBLE     3
+            #define FFI_TYPE_UINT64     11
+            #define FFI_TYPE_SINT64     12  */
+         if ((*ptr)->elements[0]->type == 3
+             || (*ptr)->elements[0]->type == 11
+             || (*ptr)->elements[0]->type == 12)
            size_al = ALIGN((*ptr)->size, 8);
          intarg_count += (size_al + 3) / 4;
          break;
@@ -671,10 +681,15 @@
          /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
             SI 4 bytes) are aligned as if they were those modes.  */
          size_al = arg_types[i]->size;
-         /* If the first member of the struct is a double, then align
-            the struct to double-word.
-            Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
-         if (arg_types[i]->elements[0]->type == 3)
+         /* If the first member of the struct is a double or an [unsigned]
+            long long, then align the struct to double-word.
+            Type 3, 11, and 12 are defined in include/ffi.h.
+            #define FFI_TYPE_DOUBLE     3
+            #define FFI_TYPE_UINT64     11
+            #define FFI_TYPE_SINT64     12  */
+         if (arg_types[i]->elements[0]->type == 3
+             || arg_types[i]->elements[0]->type == 11
+             || arg_types[i]->elements[0]->type == 12)
            size_al = ALIGN(arg_types[i]->size, 8);
          if (size_al < 3 && cif->abi == FFI_DARWIN)
            avalue[i] = (void*) pgr + 4 - size_al;
Index: gcc/config/rs6000/darwin.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/darwin.h,v
retrieving revision 1.93
diff -u -p -r1.93 darwin.h
--- gcc/config/rs6000/darwin.h  28 Sep 2005 23:50:05 -0000      1.93
+++ gcc/config/rs6000/darwin.h  5 Oct 2005 20:13:33 -0000
@@ -347,12 +347,12 @@ do {                                                     
                \
 #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.  */
+/* Darwin word-aligns FP doubles and 64-bit ints.  */
 #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
   (TARGET_ALIGN_NATURAL ? (COMPUTED) : \
-  (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
+   ((1 << (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
              ? get_inner_array_type (FIELD) \
-             : TREE_TYPE (FIELD)) == DFmode \
+             : TREE_TYPE (FIELD))) & ((1 << DFmode)|(1 << DImode))) \
    ? MIN ((COMPUTED), 32) : (COMPUTED)))

 /* Darwin increases natural record alignment to doubleword if the first
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.870
diff -u -p -r1.870 rs6000.c
--- gcc/config/rs6000/rs6000.c  26 Sep 2005 19:12:30 -0000      1.870
+++ gcc/config/rs6000/rs6000.c  5 Oct 2005 20:13:46 -0000
@@ -2438,7 +2438,8 @@ invalid_e500_subreg (rtx op, enum machin
 }

 /* Darwin, AIX increases natural record alignment to doubleword if the first
-   field is an FP double while the FP fields remain word aligned.  */
+   field is an FP double while the FP fields remain word aligned.
+   Darwin also increase it for long long too.  */

 unsigned int
 rs6000_special_round_type_align (tree type, int computed, int specified)
@@ -2449,7 +2450,9 @@ rs6000_special_round_type_align (tree ty
   while (field != NULL && TREE_CODE (field) != FIELD_DECL)
     field = TREE_CHAIN (field);

-  if (field == NULL || field == type || DECL_MODE (field) != DFmode)
+  if (field == NULL || field == type
+      || (DECL_MODE (field) != DFmode
+          && !(DEFAULT_ABI == ABI_DARWIN && DECL_MODE (field) == DImode)))
     return MAX (computed, specified);

   return MAX (MAX (computed, specified), 64);
Index: libobjc/encoding.c
===================================================================
RCS file: /cvs/gcc/gcc/libobjc/encoding.c,v
retrieving revision 1.26
diff -u -p -r1.26 encoding.c
--- libobjc/encoding.c  17 Aug 2005 03:17:54 -0000      1.26
+++ libobjc/encoding.c  5 Oct 2005 20:14:10 -0000
@@ -73,6 +73,7 @@ Boston, MA 02110-1301, USA.  */
 #define TYPE_MODE(TYPE) *(TYPE)

 #define DFmode          _C_DBL
+#define DImode          _C_LNG_LNG

 #define get_inner_array_type(TYPE)      ((TYPE) + 1)



-- 

pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         AssignedTo|pinskia at gcc dot gnu dot  |unassigned at gcc dot gnu
                   |org                         |dot org
             Status|ASSIGNED                    |NEW


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23067


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