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