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]

[PowerPC/23404] gij trashes args of functions


PR 23404 shows powerpc-linux gij trashing the first, ninth, tenth and
subsequent double args.  The reason being an incorrect alignment
adjustment for stack based fp args which results in the 9th and
following fp args all being placed incorrectly, the last one exceeding
its storage space and trashing the first fp arg in a reg.

intarg_count is used for the (obvious) counting of integer args, but
also to count stack slots used for args.  When passing doubles on the
stack, we want the stack to be aligned, but the stack can only be
mis-aligned if integer args have been placed there, ie. when
intarg_count exceeds NUM_GPR_ARG_REGISTERS.

Bootstrapped and regression tested powerpc-linux, on 4.0 branch because
gij is busted on mainline for some reason.  I'd like to apply this to
4.0 and 3.4 too, even though it's not a regression.  OK?

:ADDPATCH target(powerpc):

	PR target/23404
	* src/powerpc/ffi.c (ffi_prep_args_SYSV): Correct placement of stack
	homed fp args.
	(ffi_status ffi_prep_cif_machdep): Correct stack sizing for same.

Index: libffi/src/powerpc/ffi.c
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/powerpc/ffi.c,v
retrieving revision 1.14
diff -u -p -r1.14 ffi.c
--- libffi/src/powerpc/ffi.c	11 Aug 2005 21:18:23 -0000	1.14
+++ libffi/src/powerpc/ffi.c	24 Aug 2005 04:23:56 -0000
@@ -155,7 +155,8 @@ void ffi_prep_args_SYSV(extended_cif *ec
 
 	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
 	    {
-	      if (intarg_count%2 != 0)
+	      if (intarg_count >= NUM_GPR_ARG_REGISTERS
+		  && intarg_count % 2 != 0)
 		{
 		  intarg_count++;
 		  next_arg++;
@@ -575,7 +576,8 @@ ffi_status ffi_prep_cif_machdep(ffi_cif 
 	    /* If this FP arg is going on the stack, it must be
 	       8-byte-aligned.  */
 	    if (fparg_count > NUM_FPR_ARG_REGISTERS
-		&& intarg_count%2 != 0)
+		&& intarg_count >= NUM_GPR_ARG_REGISTERS
+		&& intarg_count % 2 != 0)
 	      intarg_count++;
 	    break;
 

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