On Wed, 6 Jul 2005, Richard Henderson wrote:
> On Tue, Jul 05, 2005 at 05:14:44PM +0200, Richard Guenther wrote: > > I'm lost in the mysteries of expansion of the indirect call, also > > ix86_value_regno gets called all over the place, so the "interesting" > > call-site is hard to find. > > We'll have to change the FUNCTION_VALUE interface to handle this. > > I suggest doing this as a target hook: > > rtx function_value (tree ret_type, tree fn_decl_or_type, bool outgoing) Ok, the fix (that is only working for i386 ATM, I guess) looks like something along attached below. To make this a clean interface I'd suggest making hard_function_value take an extra argument, the fntype, and also FUNCTION_OUTGOING_VALUE/FUNCTION_VALUE, and possibly making that a target hook like you suggested (though this was a cleaup only? Or did you mean to bail out for TYPE_P func in the default implementation?) Richard. 2005-07-11 Richard Guenther <[EMAIL PROTECTED]> * calls.c (expand_call): Pass fntype to hard_function_value, if decl is not available. * explow.c (hard_function_value): Document we also can get a function type as argument. * config/i386/i386.c (ix86_value_regno): Deal with both type and decl argument. Index: calls.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/calls.c,v retrieving revision 1.392 diff -c -3 -p -r1.392 calls.c *** calls.c 26 Jun 2005 05:27:05 -0000 1.392 --- calls.c 11 Jul 2005 15:00:44 -0000 *************** expand_call (tree exp, rtx target, int i *** 2519,2525 **** valreg = hard_function_value (build_pointer_type (TREE_TYPE (exp)), fndecl, (pass == 0)); else ! valreg = hard_function_value (TREE_TYPE (exp), fndecl, (pass == 0)); } /* Precompute all register parameters. It isn't safe to compute anything --- 2519,2526 ---- valreg = hard_function_value (build_pointer_type (TREE_TYPE (exp)), fndecl, (pass == 0)); else ! valreg = hard_function_value (TREE_TYPE (exp), fndecl ? fndecl : fntype, ! (pass == 0)); } /* Precompute all register parameters. It isn't safe to compute anything Index: explow.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/explow.c,v retrieving revision 1.147 diff -c -3 -p -r1.147 explow.c *** explow.c 25 Jun 2005 01:59:47 -0000 1.147 --- explow.c 11 Jul 2005 15:00:44 -0000 *************** probe_stack_range (HOST_WIDE_INT first, *** 1405,1412 **** /* Return an rtx representing the register or memory location in which a scalar value of data type VALTYPE was returned by a function call to function FUNC. ! FUNC is a FUNCTION_DECL node if the precise function is known, ! otherwise 0. OUTGOING is 1 if on a machine with register windows this function should return the register in which the function will put its result and 0 otherwise. */ --- 1405,1412 ---- /* Return an rtx representing the register or memory location in which a scalar value of data type VALTYPE was returned by a function call to function FUNC. ! FUNC is a FUNCTION_DECL or FUNCTION_TYPE node if the precise function ! is known, otherwise 0. OUTGOING is 1 if on a machine with register windows this function should return the register in which the function will put its result and 0 otherwise. */ Index: config/i386/i386.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v retrieving revision 1.841 diff -c -3 -p -r1.841 i386.c *** config/i386/i386.c 11 Jul 2005 09:35:16 -0000 1.841 --- config/i386/i386.c 11 Jul 2005 15:00:47 -0000 *************** ix86_value_regno (enum machine_mode mode *** 3349,3355 **** SSE math is enabled or for functions with sseregparm attribute. */ if (func && (mode == SFmode || mode == DFmode)) { ! int sse_level = ix86_function_sseregparm (TREE_TYPE (func), func); if ((sse_level >= 1 && mode == SFmode) || (sse_level == 2 && mode == DFmode)) return FIRST_SSE_REG; --- 3349,3356 ---- SSE math is enabled or for functions with sseregparm attribute. */ if (func && (mode == SFmode || mode == DFmode)) { ! int sse_level = ix86_function_sseregparm (DECL_P (func) ? TREE_TYPE (func) : func, ! DECL_P (func) ? func : 0); if ((sse_level >= 1 && mode == SFmode) || (sse_level == 2 && mode == DFmode)) return FIRST_SSE_REG;