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] Fix PR 14262 breakage on Darwin


Hello,

unfortunately my patch to fix PR 14262 broke Darwin, as pointed out
by Andreas Tobler (in the PR record).

I had reasoned that the patch couldn't possibly break any other
target, because it only changes the status quo in situations where
it is currently self-inconsistent: the caller would pass an argument
left-aligned in a register, while the callee would retrieve that
argument right-aligned.

However, this was not completely true: when the ABI specifies that 
a value is to be passed *both* on the stack and in a register, then 
the callee-side currently uses always the copy on the stack.  This
happens on Darwin, where 3-byte structs are supposed to be passed
left-aligned on the stack *and* left-aligned in a register, and
the callee reads them left-aligned from the stack.

With my patch this is changed to passing the argument still left-
aligned on the stack, but right-aligned in the register.  This
normally doesn't matter (as the callee ignores the register),
but breaks with libffi (which does use the register value).

To fix this, I propose the following patch, which restores the
old behaviour in all cases where the argument is passed both
in a register and on the stack.  Andreas has verified that this
fixes libffi on Darwin.

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux.
OK?

PS: Alan, I'm not sure what to do if BLOCK_REG_PADDING is defined.
Should this also be applied for arguments passed both in registers
and on the stack?  It doesn't matter for Darwin right now, which
doesn't currently define BLOCK_REG_PADDING ...

ChangeLog:

	* calls.c (load_registers_parameters): If BLOCK_REG_PADDING is
	not defined, pass small BLKmode values in the high part of a 
	register on big-endian targets if they are also passed on the stack.

Index: gcc/calls.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/calls.c,v
retrieving revision 1.326
diff -c -p -r1.326 calls.c
*** gcc/calls.c	14 Mar 2004 22:26:00 -0000	1.326
--- gcc/calls.c	21 Mar 2004 19:34:24 -0000
*************** load_register_parameters (struct arg_dat
*** 1680,1686 ****
  #ifdef BLOCK_REG_PADDING
  		  && args[i].locate.where_pad == downward
  #else
! 		  && BYTES_BIG_ENDIAN
  #endif
  		 )
  		{
--- 1680,1686 ----
  #ifdef BLOCK_REG_PADDING
  		  && args[i].locate.where_pad == downward
  #else
! 		  && BYTES_BIG_ENDIAN && !args[i].pass_on_stack
  #endif
  		 )
  		{
-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de


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