[PATCH] Fix (partly) PR22347
Richard Guenther
rguenther@suse.de
Tue Jul 12 07:54:00 GMT 2005
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.
Here's the patch. Bootstrapped and tested on i686-pc-linux-gnu and
x86_64-unknown-linux-gnu.
Ok for mainline? (I'll run a bootstrap on ppc to make sure I didn't
break any non config/i386 architecture)
Note: this does not fix PR22347 really, because at -O2 tree-tailcall
will happily tailcall the call to mysinfp (if I not cheated and
placed 1.0+ in the testcase). I'll see where to best place a fix
for this, but the patch is large enough as is.
Richard.
2005-07-11 Richard Guenther <rguenther@suse.de>
* Makefile.in (explow.o, reg-stack.o): Depend on target.h.
* calls.c (expand_call): Pass fntype to hard_function_value.
(emit_library_call_value_1): Likewise.
* explow.c: Include target.h.
(hard_function_value): Take extra argument, the fntype.
Use new target hook for function_value.
* expr.h (hard_function_value): Change prototype.
* function.c (aggregate_value_p): Pass 0 as fntype to
hard_function_value.
(assign_parms): Use new target hook for function_value.
Pass 0 as fntype to hard_function_value.
(expand_function_end): Likewise.
* reg-stack.c: Include target.h.
(stack_result): Use new target hook for function_value.
* target-def.h: New target hook function_value.
* target.h: Likewise.
* targhooks.c (default_function_value): New function.
* targhooks.h (default_function_value): Declare.
* config/i386/i386-protos.h (ix86_function_value): Change
prototype to match new target hook.
* config/i386/i386.c (ix86_value_regno): Change prototype
to take extra type argument.
(TARGET_FUNCTION_VALUE): Define.
(ix86_function_ok_for_sibcall): Pass extra argument to
ix86_value_regno.
(ix86_function_value): Take extra parameter. Dispatch to
ix86_value_regno with fndecl/fntype as provided.
(ix86_value_regno): Handle extra type argument.
* config/i386/i386.h (FUNCTION_VALUE): No longer define.
* testsuite/gcc.target/i386/sseregparm-3.c: New testcase.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.1521
diff -c -3 -p -r1.1521 Makefile.in
*** Makefile.in 10 Jul 2005 00:27:44 -0000 1.1521
--- Makefile.in 11 Jul 2005 16:39:57 -0000
*************** expmed.o : expmed.c $(CONFIG_H) $(SYSTEM
*** 2079,2085 ****
toplev.h $(TM_P_H) langhooks.h
explow.o : explow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
$(FLAGS_H) hard-reg-set.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) \
! toplev.h function.h $(GGC_H) $(TM_P_H) langhooks.h gt-explow.h
optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) insn-config.h $(EXPR_H) $(OPTABS_H) libfuncs.h \
$(RECOG_H) reload.h toplev.h $(GGC_H) real.h $(TM_P_H) except.h \
--- 2079,2085 ----
toplev.h $(TM_P_H) langhooks.h
explow.o : explow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
$(FLAGS_H) hard-reg-set.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) \
! toplev.h function.h $(GGC_H) $(TM_P_H) langhooks.h gt-explow.h target.h
optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) insn-config.h $(EXPR_H) $(OPTABS_H) libfuncs.h \
$(RECOG_H) reload.h toplev.h $(GGC_H) real.h $(TM_P_H) except.h \
*************** recog.o : recog.c $(CONFIG_H) $(SYSTEM_H
*** 2391,2397 ****
reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TREE_H) $(RECOG_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
insn-config.h toplev.h reload.h function.h $(TM_P_H) $(GGC_H) \
! gt-reg-stack.h $(BASIC_BLOCK_H) output.h $(VARRAY_H) timevar.h tree-pass.h
sreal.o: sreal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) sreal.h
predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) \
--- 2391,2398 ----
reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TREE_H) $(RECOG_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
insn-config.h toplev.h reload.h function.h $(TM_P_H) $(GGC_H) \
! gt-reg-stack.h $(BASIC_BLOCK_H) output.h $(VARRAY_H) timevar.h tree-pass.h \
! target.h
sreal.o: sreal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) sreal.h
predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) \
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 16:39:58 -0000
*************** expand_call (tree exp, rtx target, int i
*** 2517,2525 ****
{
if (pcc_struct_value)
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
--- 2517,2526 ----
{
if (pcc_struct_value)
valreg = hard_function_value (build_pointer_type (TREE_TYPE (exp)),
! fndecl, NULL, (pass == 0));
else
! valreg = hard_function_value (TREE_TYPE (exp), fndecl, fntype,
! (pass == 0));
}
/* Precompute all register parameters. It isn't safe to compute anything
*************** emit_library_call_value_1 (int retval, r
*** 3266,3272 ****
{
#ifdef PCC_STATIC_STRUCT_RETURN
rtx pointer_reg
! = hard_function_value (build_pointer_type (tfom), 0, 0);
mem_value = gen_rtx_MEM (outmode, pointer_reg);
pcc_struct_value = 1;
if (value == 0)
--- 3267,3273 ----
{
#ifdef PCC_STATIC_STRUCT_RETURN
rtx pointer_reg
! = hard_function_value (build_pointer_type (tfom), 0, 0, 0);
mem_value = gen_rtx_MEM (outmode, pointer_reg);
pcc_struct_value = 1;
if (value == 0)
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 16:39:58 -0000
*************** Software Foundation, 51 Franklin Street,
*** 37,42 ****
--- 37,43 ----
#include "ggc.h"
#include "recog.h"
#include "langhooks.h"
+ #include "target.h"
static rtx break_out_memory_refs (rtx);
static void emit_stack_probe (rtx);
*************** probe_stack_range (HOST_WIDE_INT first,
*** 1405,1428 ****
/* 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. */
rtx
! hard_function_value (tree valtype, tree func ATTRIBUTE_UNUSED,
int outgoing ATTRIBUTE_UNUSED)
{
rtx val;
! #ifdef FUNCTION_OUTGOING_VALUE
! if (outgoing)
! val = FUNCTION_OUTGOING_VALUE (valtype, func);
! else
! #endif
! val = FUNCTION_VALUE (valtype, func);
if (REG_P (val)
&& GET_MODE (val) == BLKmode)
--- 1406,1424 ----
/* 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, FNTYPE a 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. */
rtx
! hard_function_value (tree valtype, tree func, tree fntype,
int outgoing ATTRIBUTE_UNUSED)
{
rtx val;
! val = targetm.calls.function_value (valtype, func ? func : fntype, outgoing);
if (REG_P (val)
&& GET_MODE (val) == BLKmode)
Index: expr.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.h,v
retrieving revision 1.191
diff -c -3 -p -r1.191 expr.h
*** expr.h 28 Jun 2005 19:55:52 -0000 1.191
--- expr.h 11 Jul 2005 16:39:58 -0000
*************** extern HOST_WIDE_INT int_expr_size (tree
*** 550,556 ****
/* Return an rtx that refers to the value returned by a function
in its original home. This becomes invalid if any more code is emitted. */
! extern rtx hard_function_value (tree, tree, int);
extern rtx prepare_call_address (rtx, rtx, rtx *, int, int);
--- 550,556 ----
/* Return an rtx that refers to the value returned by a function
in its original home. This becomes invalid if any more code is emitted. */
! extern rtx hard_function_value (tree, tree, tree, int);
extern rtx prepare_call_address (rtx, rtx, rtx *, int, int);
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.635
diff -c -3 -p -r1.635 function.c
*** function.c 7 Jul 2005 21:04:31 -0000 1.635
--- function.c 11 Jul 2005 16:39:59 -0000
*************** aggregate_value_p (tree exp, tree fntype
*** 1732,1738 ****
return 1;
/* Make sure we have suitable call-clobbered regs to return
the value in; if not, we must return it in memory. */
! reg = hard_function_value (type, 0, 0);
/* If we have something other than a REG (e.g. a PARALLEL), then assume
it is OK. */
--- 1732,1738 ----
return 1;
/* Make sure we have suitable call-clobbered regs to return
the value in; if not, we must return it in memory. */
! reg = hard_function_value (type, 0, 0, 0);
/* If we have something other than a REG (e.g. a PARALLEL), then assume
it is OK. */
*************** assign_parms (tree fndecl)
*** 3055,3067 ****
{
rtx real_decl_rtl;
! #ifdef FUNCTION_OUTGOING_VALUE
! real_decl_rtl = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl_result),
! fndecl);
! #else
! real_decl_rtl = FUNCTION_VALUE (TREE_TYPE (decl_result),
! fndecl);
! #endif
REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
/* The delay slot scheduler assumes that current_function_return_rtx
holds the hard register containing the return value, not a
--- 3055,3062 ----
{
rtx real_decl_rtl;
! real_decl_rtl = targetm.calls.function_value (TREE_TYPE (decl_result),
! fndecl, true);
REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
/* The delay slot scheduler assumes that current_function_return_rtx
holds the hard register containing the return value, not a
*************** expand_function_start (tree subr)
*** 4149,4155 ****
/* In order to figure out what mode to use for the pseudo, we
figure out what the mode of the eventual return register will
actually be, and use that. */
! rtx hard_reg = hard_function_value (return_type, subr, 1);
/* Structures that are returned in registers are not
aggregate_value_p, so we may see a PARALLEL or a REG. */
--- 4144,4150 ----
/* In order to figure out what mode to use for the pseudo, we
figure out what the mode of the eventual return register will
actually be, and use that. */
! rtx hard_reg = hard_function_value (return_type, subr, 0, 1);
/* Structures that are returned in registers are not
aggregate_value_p, so we may see a PARALLEL or a REG. */
*************** expand_function_end (void)
*** 4499,4511 ****
else
value_address = XEXP (value_address, 0);
! #ifdef FUNCTION_OUTGOING_VALUE
! outgoing = FUNCTION_OUTGOING_VALUE (build_pointer_type (type),
! current_function_decl);
! #else
! outgoing = FUNCTION_VALUE (build_pointer_type (type),
! current_function_decl);
! #endif
/* Mark this as a function return value so integrate will delete the
assignment and USE below when inlining this function. */
--- 4494,4501 ----
else
value_address = XEXP (value_address, 0);
! outgoing = targetm.calls.function_value (build_pointer_type (type),
! current_function_decl, true);
/* Mark this as a function return value so integrate will delete the
assignment and USE below when inlining this function. */
Index: reg-stack.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reg-stack.c,v
retrieving revision 1.187
diff -c -3 -p -r1.187 reg-stack.c
*** reg-stack.c 5 Jul 2005 16:20:11 -0000 1.187
--- reg-stack.c 11 Jul 2005 16:39:59 -0000
***************
*** 172,177 ****
--- 172,178 ----
#include "ggc.h"
#include "timevar.h"
#include "tree-pass.h"
+ #include "target.h"
/* We use this array to cache info about insns, because otherwise we
spend too much time in stack_regs_mentioned_p.
*************** stack_result (tree decl)
*** 667,680 ****
result = DECL_RTL_IF_SET (DECL_RESULT (decl));
if (result != 0)
! {
! #ifdef FUNCTION_OUTGOING_VALUE
! result
! = FUNCTION_OUTGOING_VALUE (TREE_TYPE (DECL_RESULT (decl)), decl);
! #else
! result = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (decl)), decl);
! #endif
! }
return result != 0 && STACK_REG_P (result) ? result : 0;
}
--- 668,675 ----
result = DECL_RTL_IF_SET (DECL_RESULT (decl));
if (result != 0)
! result = targetm.calls.function_value (TREE_TYPE (DECL_RESULT (decl)),
! decl, true);
return result != 0 && STACK_REG_P (result) ? result : 0;
}
Index: target-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target-def.h,v
retrieving revision 1.131
diff -c -3 -p -r1.131 target-def.h
*** target-def.h 7 Jul 2005 11:48:13 -0000 1.131
--- target-def.h 11 Jul 2005 16:40:00 -0000
*************** Foundation, 51 Franklin Street, Fifth Fl
*** 438,443 ****
--- 438,445 ----
#define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false
#define TARGET_ARG_PARTIAL_BYTES hook_int_CUMULATIVE_ARGS_mode_tree_bool_0
+ #define TARGET_FUNCTION_VALUE default_function_value
+
#define TARGET_CALLS { \
TARGET_PROMOTE_FUNCTION_ARGS, \
TARGET_PROMOTE_FUNCTION_RETURN, \
*************** Foundation, 51 Franklin Street, Fifth Fl
*** 454,460 ****
TARGET_MUST_PASS_IN_STACK, \
TARGET_CALLEE_COPIES, \
TARGET_ARG_PARTIAL_BYTES, \
! TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN \
}
#ifndef TARGET_UNWIND_TABLES_DEFAULT
--- 456,463 ----
TARGET_MUST_PASS_IN_STACK, \
TARGET_CALLEE_COPIES, \
TARGET_ARG_PARTIAL_BYTES, \
! TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN, \
! TARGET_FUNCTION_VALUE \
}
#ifndef TARGET_UNWIND_TABLES_DEFAULT
Index: target.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target.h,v
retrieving revision 1.143
diff -c -3 -p -r1.143 target.h
*** target.h 7 Jul 2005 11:48:13 -0000 1.143
--- target.h 11 Jul 2005 16:40:00 -0000
*************** struct gcc_target
*** 603,608 ****
--- 603,612 ----
is not allowed for this 'val' argument; NULL otherwise. */
const char *(*invalid_arg_for_unprototyped_fn) (tree typelist,
tree funcdecl, tree val);
+
+ /* FUNCTION_VALUE */
+ rtx (*function_value) (tree ret_type, tree fn_decl_or_type,
+ bool outgoing);
} calls;
/* Return the diagnostic message string if conversion from FROMTYPE
Index: targhooks.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/targhooks.c,v
retrieving revision 2.45
diff -c -3 -p -r2.45 targhooks.c
*** targhooks.c 7 Jul 2005 11:48:13 -0000 2.45
--- targhooks.c 11 Jul 2005 16:40:00 -0000
*************** hook_bool_rtx_commutative_p (rtx x, int
*** 417,420 ****
--- 417,440 ----
return COMMUTATIVE_P (x);
}
+ rtx
+ default_function_value (tree ret_type, tree fn_decl_or_type,
+ bool outgoing ATTRIBUTE_UNUSED)
+ {
+ /* The old interface doesn't handle receiving the function type. */
+ if (!DECL_P (fn_decl_or_type))
+ fn_decl_or_type = NULL;
+
+ #ifdef FUNCTION_OUTGOING_VALUE
+ if (outgoing)
+ return FUNCTION_OUTGOING_VALUE (ret_type, fn_decl_or_type);
+ #endif
+
+ #ifdef FUNCTION_VALUE
+ return FUNCTION_VALUE (ret_type, fn_decl_or_type);
+ #else
+ return NULL_RTX;
+ #endif
+ }
+
#include "gt-targhooks.h"
Index: targhooks.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/targhooks.h,v
retrieving revision 2.32
diff -c -3 -p -r2.32 targhooks.h
*** targhooks.h 7 Jul 2005 11:48:13 -0000 2.32
--- targhooks.h 11 Jul 2005 16:40:00 -0000
*************** extern int hook_int_CUMULATIVE_ARGS_mode
*** 67,69 ****
--- 67,71 ----
extern const char *hook_invalid_arg_for_unprototyped_fn
(tree, tree, tree);
extern bool hook_bool_rtx_commutative_p (rtx, int);
+ extern rtx default_function_value (tree, tree, bool);
+
Index: config/i386/i386-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386-protos.h,v
retrieving revision 1.143
diff -c -3 -p -r1.143 i386-protos.h
*** config/i386/i386-protos.h 29 Jun 2005 17:27:16 -0000 1.143
--- config/i386/i386-protos.h 11 Jul 2005 16:40:00 -0000
*************** extern void init_cumulative_args (CUMULA
*** 206,212 ****
extern rtx function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
tree, int);
! extern rtx ix86_function_value (tree, tree);
#endif
#endif
--- 206,212 ----
extern rtx function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
tree, int);
! extern rtx ix86_function_value (tree, tree, bool);
#endif
#endif
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 16:40:01 -0000
*************** static int ix86_function_regparm (tree,
*** 891,897 ****
const struct attribute_spec ix86_attribute_table[];
static bool ix86_function_ok_for_sibcall (tree, tree);
static tree ix86_handle_cconv_attribute (tree *, tree, tree, int, bool *);
! static int ix86_value_regno (enum machine_mode, tree);
static bool contains_128bit_aligned_vector_p (tree);
static rtx ix86_struct_value_rtx (tree, int);
static bool ix86_ms_bitfield_layout_p (tree);
--- 891,897 ----
const struct attribute_spec ix86_attribute_table[];
static bool ix86_function_ok_for_sibcall (tree, tree);
static tree ix86_handle_cconv_attribute (tree *, tree, tree, int, bool *);
! static int ix86_value_regno (enum machine_mode, tree, tree);
static bool contains_128bit_aligned_vector_p (tree);
static rtx ix86_struct_value_rtx (tree, int);
static bool ix86_ms_bitfield_layout_p (tree);
*************** static void init_ext_80387_constants (vo
*** 1085,1090 ****
--- 1085,1093 ----
#undef TARGET_STACK_PROTECT_FAIL
#define TARGET_STACK_PROTECT_FAIL ix86_stack_protect_fail
+ #undef TARGET_FUNCTION_VALUE
+ #define TARGET_FUNCTION_VALUE ix86_function_value
+
struct gcc_target targetm = TARGET_INITIALIZER;
*************** ix86_function_ok_for_sibcall (tree decl,
*** 1722,1730 ****
function that does or, conversely, from a function that does return
a float to a function that doesn't; the necessary stack adjustment
would not be executed. */
! if (STACK_REG_P (ix86_function_value (TREE_TYPE (exp), func))
!= STACK_REG_P (ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
! cfun->decl)))
return false;
/* If this call is indirect, we'll need to be able to use a call-clobbered
--- 1725,1733 ----
function that does or, conversely, from a function that does return
a float to a function that doesn't; the necessary stack adjustment
would not be executed. */
! if (STACK_REG_P (ix86_function_value (TREE_TYPE (exp), func, false))
!= STACK_REG_P (ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
! cfun->decl, false)))
return false;
/* If this call is indirect, we'll need to be able to use a call-clobbered
*************** ix86_function_value_regno_p (int regno)
*** 3189,3195 ****
If the precise function being called is known, FUNC is its FUNCTION_DECL;
otherwise, FUNC is 0. */
rtx
! ix86_function_value (tree valtype, tree func)
{
enum machine_mode natmode = type_natural_mode (valtype);
--- 3192,3199 ----
If the precise function being called is known, FUNC is its FUNCTION_DECL;
otherwise, FUNC is 0. */
rtx
! ix86_function_value (tree valtype, tree fntype_or_decl,
! bool outgoing ATTRIBUTE_UNUSED)
{
enum machine_mode natmode = type_natural_mode (valtype);
*************** ix86_function_value (tree valtype, tree
*** 3205,3211 ****
return ret;
}
else
! return gen_rtx_REG (TYPE_MODE (valtype), ix86_value_regno (natmode, func));
}
/* Return false iff type is returned in memory. */
--- 3209,3223 ----
return ret;
}
else
! {
! tree fn = NULL_TREE, fntype;
! if (fntype_or_decl
! && DECL_P (fntype_or_decl))
! fn = fntype_or_decl;
! fntype = fn ? NULL_TREE : fntype_or_decl;
! return gen_rtx_REG (TYPE_MODE (valtype),
! ix86_value_regno (natmode, fn, fntype));
! }
}
/* Return false iff type is returned in memory. */
*************** ix86_libcall_value (enum machine_mode mo
*** 3321,3333 ****
}
}
else
! return gen_rtx_REG (mode, ix86_value_regno (mode, NULL));
}
/* Given a mode, return the register to use for a return value. */
static int
! ix86_value_regno (enum machine_mode mode, tree func)
{
gcc_assert (!TARGET_64BIT);
--- 3333,3345 ----
}
}
else
! return gen_rtx_REG (mode, ix86_value_regno (mode, NULL, NULL));
}
/* Given a mode, return the register to use for a return value. */
static int
! ix86_value_regno (enum machine_mode mode, tree func, tree fntype)
{
gcc_assert (!TARGET_64BIT);
*************** ix86_value_regno (enum machine_mode mode
*** 3347,3355 ****
/* Floating point return values in %st(0), except for local functions when
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;
--- 3359,3368 ----
/* Floating point return values in %st(0), except for local functions when
SSE math is enabled or for functions with sseregparm attribute. */
! if ((func || fntype)
! && (mode == SFmode || mode == DFmode))
{
! int sse_level = ix86_function_sseregparm (fntype, func);
if ((sse_level >= 1 && mode == SFmode)
|| (sse_level == 2 && mode == DFmode))
return FIRST_SSE_REG;
Index: config/i386/i386.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.h,v
retrieving revision 1.440
diff -c -3 -p -r1.440 i386.h
*** config/i386/i386.h 26 Jun 2005 05:18:34 -0000 1.440
--- config/i386/i386.h 11 Jul 2005 16:40:01 -0000
*************** enum reg_class
*** 1433,1445 ****
#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) \
ix86_return_pops_args ((FUNDECL), (FUNTYPE), (SIZE))
- /* Define how to find the value returned by a function.
- VALTYPE is the data type of the value (as a tree).
- If the precise function being called is known, FUNC is its FUNCTION_DECL;
- otherwise, FUNC is 0. */
- #define FUNCTION_VALUE(VALTYPE, FUNC) \
- ix86_function_value (VALTYPE, FUNC)
-
#define FUNCTION_VALUE_REGNO_P(N) \
ix86_function_value_regno_p (N)
--- 1433,1438 ----
/* { dg-do compile } */
/* { dg-options "-msse2 -O2" } */
/* { dg-require-effective-target ilp32 } */
/* Make sure we know that mysinfp returns in %xmm0. */
double __attribute__((sseregparm)) mysin(double x);
double __attribute__((sseregparm)) (*mysinfp)(double) = mysin;
double bar(double x)
{
return 1.0+mysinfp(x);
}
/* { dg-final { scan-assembler "fldl" } } */
More information about the Gcc-patches
mailing list