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]

ia64 breakage due to old powerpc64 patch


I'm investigating ia64 compat failures and I find that 

  http://gcc.gnu.org/ml/gcc-patches/2003-11/msg00167.html

is the cause of one of them.  The reduced test case is

	struct S { _Complex long double a, b, c; } s;
	extern void bar(struct S);
	void foo (void) { bar(s); }

What should happen is that the first four long doubles in
this structure should be passed in f8-f11, and the last
two should be passed on the stack.  So we build

(parallel:BLK [
        (expr_list (reg:XF 136 f8) (const_int 0 [0x0]))
        (expr_list (reg:XF 137 f9) (const_int 16 [0x10]))
        (expr_list (reg:XF 138 f10) (const_int 32 [0x20]))
        (expr_list (reg:XF 139 f11) (const_int 48 [0x30]))
    ])

The patch in question changed what this means wrt
FUNCTION_ARG_PARTIAL_NREGS means, and didn't update any target
(or the documentation) to match.

In particular, ia64_function_arg_partial_nregs still returns
the number of 64-bit words passed in registers (8).  From that,
emit_push_insn determines that 8*GET_MODE_SIZE(XFmode) == 128
bytes of the 96 byte structure have been put into registers,
and therefore -32 bytes remain to be copied to the stack.

Needless to say, passing memcpy a negative number is a quick
way to get a segmentation fault.

Thinking further, for a call such as

	struct T { float a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p; }  // 16 floats
	extern void bar(int x, struct T t);

the correct set of registers would be

	r32	x		f8	t.a
	r33	empty		f9	t.b
	r34	empty		f10	t.c
	r35	empty		f11	t.d
	r36	empty		f12	t.e
	r37	t.i : t.j	f13	t.f
	r38	t.k : t.l	f14	t.g
	r39	t.m : t.n	f15	t.h

	stack	t.o : t.p

where ":" should be considered a bitwise concatenation operator.
Note that the PARALLEL for "t" would look like

(parallel:BLK [
	(expr_list (reg:SF f8)	(const_int 0))
	(expr_list (reg:SF f9)	(const_int 4))
	(expr_list (reg:SF f10)	(const_int 8))
	(expr_list (reg:SF f11)	(const_int 12))
	(expr_list (reg:SF f12)	(const_int 16))
	(expr_list (reg:SF f13)	(const_int 20))
	(expr_list (reg:SF f14)	(const_int 24))
	(expr_list (reg:SF f15)	(const_int 28))
	(expr_list (reg:DI r37) (const_int 32))
	(expr_list (reg:DI r38) (const_int 40))
	(expr_list (reg:DI r39) (const_int 48))
    ])

Note the mixture of register modes.  Given that the PARALLELs
don't really have any particular ordering, I don't see how any
solution that examines the modes of the parallel can be correct.


What was the original problem you were trying to solve?  The
original posting makes vague references to ppc64 mixed mode
problems, but isn't terribly enlightening.  I presume you want
word_mode == DImode and have SImode entries in your PARALLEL?
And so need FUNCTION_ARG_PARTIAL_NREGS to return a fractional
number of words?

If so, I think we'll just have to bite the bullet and replace
FUNCTION_ARG_PARTIAL_NREGS with a hook that talks about bytes
instead of words.


r~


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