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

A change to MUST_PASS_IN_STACK


I'd like to modify MUST_PASS_IN_STACK to accept another parameter.
Reason: No account is taken of arguments passed partially in registers
and partially on the stack.  In that case you can't put anything in
"the wrong part of the register" on big-endian machines.

The attached testcase illustrates what I'm talking about on
powerpc64-linux.  With a compiler modified to avoid the bug in
http://gcc.gnu.org/ml/gcc-patches/2003-01/msg00508.html, I get:

(sizeof str1 == 60)	(sizeof str1 == 64)	(sizeof str1 == 60, fixed)
.main:			.main:			.main:
	mflr 0			mflr 0			mflr 0
	li 9,5678		li 9,5678		li 11,5678
	std 0,16(1)		std 0,16(1)		std 0,16(1)
	li 5,68			li 0,1234		li 0,1234
	li 0,1234		stdu 1,-208(1)		stdu 1,-208(1)
	stdu 1,-208(1)		stw 9,188(1)		stw 0,120(1)
	addi 4,1,120		stw 0,120(1)		li 0,5678
	addi 3,1,48		lfd 0,184(1)		ld 3,120(1)
	stw 0,120(1)		ld 3,120(1)		ld 4,128(1)
	stw 9,184(1)		ld 4,128(1)		ld 5,136(1)
	bl .memcpy		ld 5,136(1)		ld 6,144(1)
	nop			ld 6,144(1)		ld 7,152(1)
	ld 3,48(1)		ld 7,152(1)		ld 8,160(1)
	ld 4,56(1)		ld 8,160(1)		ld 9,168(1)
	ld 5,64(1)		ld 9,168(1)		ld 10,176(1)
	ld 6,72(1)		ld 10,176(1)		stw 0,184(1)
	ld 7,80(1)		stfd 0,112(1)		stw 11,112(1)
	ld 8,88(1)		bl .subr		bl .subr
	ld 9,96(1)		nop			nop
	ld 10,104(1)		addi 1,1,208		addi 1,1,208
	bl .subr		li 3,0			li 3,0
	nop			ld 0,16(1)		ld 0,16(1)
	addi 1,1,208		mtlr 0			mtlr 0
	li 3,0			blr			blr
	ld 0,16(1)
	mtlr 0
	blr

Note how we unnecessarily copy the entire struct in the lefthand
column when MUST_PASS_IN_STACK triggers due to padding, and avoid
writing to fixed parameter area in the middle column when the
struct bitsize is a multiple of PARM_BOUNDARY.  The rightmost column
shows what I'd like to get for sizeof str1 == 60 (and in fact what I
do get after modifying MUST_PASS_IN_STACK).

Rather than spam the list with a large patch tweaking all occurences
of the macro, I thought I'd first seek approval in principle.  The
changed macro looks like the following.


/* Nonzero if we must pass TYPE on the stack.
   We cannot do so in the following cases:

   - if the type has variable size
   - if the type is marked as addressable (it is required to be constructed
     into the stack)
   - if the padding and mode of the type is such that a copy into a register
     would put it into the wrong part of the register.

   Which padding can't be supported depends on the byte endianness.

   A value in a register is implicitly padded at the most significant end.
   On a big-endian machine, that is the lower end in memory.
   So a value padded in memory at the upper end can't go in a register.
   For a little-endian machine, the reverse is true.

   Padding is irrelevant when big-endian if TYPE will be passed partially
   in registers and partially on the stack as indicated by PART.  This is
   because any padding at the upper end will go on the stack anyway.  */

#ifndef MUST_PASS_IN_STACK
#define MUST_PASS_IN_STACK(MODE, TYPE, PART)			\
  ((TYPE) != 0							\
   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST		\
       || TREE_ADDRESSABLE (TYPE)				\
       || ((MODE) == BLKmode 					\
	   && ((PART) == 0 || !BYTES_BIG_ENDIAN)		\
	   && (int_size_in_bytes (TYPE)				\
	       % (PARM_BOUNDARY / BITS_PER_UNIT)) != 0		\
	   && (FUNCTION_ARG_PADDING (MODE, TYPE)		\
	       == (BYTES_BIG_ENDIAN ? upward : downward)))))
#endif


So, is it worth posting the patch or should I try something different?

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