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]

Patch: IA64 HP-UX struct-layout failures in testsuite.


This patch fixes most of the gcc.dg-struct-layout-1 failures on IA64
HP-UX.  The problem is that while the 128 long double type has 8 byte
alignment in ILP32 mode it should be aligned to 16 bytes when passed as
an argument.  I also found a place in ia64_function_arg_advance where
TFmode values might try to be put into FP registers which is also wrong.

Tested on IA64 HP-UX with no regressions and 25 fewer failures.

Steve Ellcey
sje@cup.hp.com

2004-10-05  Steve Ellcey  <sje@cup.hp.com>

	* config/ia64/ia64.h (FUNCTION_ARG_BOUNDARY): Change macro to
	call ia64_function_arg_boundary.
	* config/ia64/ia64-protos.h (ia64_function_arg_boundary): New.
	* config/ia64/ia64.c (ia64_function_arg_boundary): New.
	(ia64_function_arg_advance): Do not put 128 bit floats into
        FP registers.

*** gcc.orig/gcc/config/ia64/ia64.h	Tue Oct  5 14:05:41 2004
--- gcc/gcc/config/ia64/ia64.h	Tue Oct  5 14:05:15 2004
*************** do {									\
*** 1376,1390 ****
  /* If defined, a C expression that gives the alignment boundary, in bits, of an
     argument with the specified mode and type.  */
  
! /* Arguments with alignment larger than 8 bytes start at the next even
!    boundary.  See ia64_function_arg.  */
  
  #define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
!   (((TYPE) ? (TYPE_ALIGN (TYPE) > 8 * BITS_PER_UNIT)		\
!     : (((((MODE) == BLKmode					\
! 	  ? int_size_in_bytes (TYPE) : GET_MODE_SIZE (MODE))	\
! 	 + UNITS_PER_WORD - 1) / UNITS_PER_WORD) > 1))		\
!     ? 128 : PARM_BOUNDARY)
  
  /* A C expression that is nonzero if REGNO is the number of a hard register in
     which function arguments are sometimes passed.  This does *not* include
--- 1376,1386 ----
  /* If defined, a C expression that gives the alignment boundary, in bits, of an
     argument with the specified mode and type.  */
  
! /* Return the alignment boundary in bits for an argument with a specified
!    mode and type.  */
  
  #define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
!   ia64_function_arg_boundary (MODE, TYPE)
  
  /* A C expression that is nonzero if REGNO is the number of a hard register in
     which function arguments are sometimes passed.  This does *not* include
*** gcc.orig/gcc/config/ia64/ia64-protos.h	Tue Oct  5 14:05:56 2004
--- gcc/gcc/config/ia64/ia64-protos.h	Tue Oct  5 14:05:09 2004
*************** extern int ia64_function_arg_partial_nre
*** 77,82 ****
--- 77,83 ----
  					    enum machine_mode, tree, int);
  extern void ia64_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
  				       tree, int);
+ extern int ia64_function_arg_boundary (enum machine_mode, tree);
  extern void ia64_asm_output_external (FILE *, tree, const char *);
  #endif /* TREE_CODE */
  
*** gcc.orig/gcc/config/ia64/ia64.c	Tue Oct  5 14:05:36 2004
--- gcc/gcc/config/ia64/ia64.c	Tue Oct  5 14:05:17 2004
*************** ia64_function_arg_advance (CUMULATIVE_AR
*** 3328,3334 ****
    /* Integral and aggregates go in general registers.  If we have run out of
       FR registers, then FP values must also go in general registers.  This can
       happen when we have a SFmode HFA.  */
!   else if (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS)
      cum->int_regs = cum->words;
  
    /* If there is a prototype, then FP values go in a FR register when
--- 3328,3335 ----
    /* Integral and aggregates go in general registers.  If we have run out of
       FR registers, then FP values must also go in general registers.  This can
       happen when we have a SFmode HFA.  */
!   else if (mode == TFmode || mode == TCmode
!            || (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS))
      cum->int_regs = cum->words;
  
    /* If there is a prototype, then FP values go in a FR register when
*************** ia64_function_arg_advance (CUMULATIVE_AR
*** 3349,3354 ****
--- 3350,3379 ----
        cum->fp_regs += (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
        cum->int_regs = cum->words;
      }
+ }
+ 
+ /* Arguments with alignment larger than 8 bytes start at the next even
+    boundary.  See ia64_function_arg.  */
+ 
+ int
+ ia64_function_arg_boundary (enum machine_mode mode, tree type)
+ {
+ 
+   if (mode == TFmode && TARGET_HPUX && TARGET_ILP32)
+     return PARM_BOUNDARY * 2;
+ 
+   if (type)
+     {
+       if (TYPE_ALIGN (type) > PARM_BOUNDARY)
+         return PARM_BOUNDARY * 2;
+       else
+         return PARM_BOUNDARY;
+     }
+ 
+   if (GET_MODE_BITSIZE (mode) > PARM_BOUNDARY)
+     return PARM_BOUNDARY * 2;
+   else
+     return PARM_BOUNDARY;
  }
  
  /* Variable sized types are passed by reference.  */


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