summaryrefslogtreecommitdiff
path: root/gcc/explow.c
diff options
context:
space:
mode:
authorbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>2009-08-01 22:03:34 +0000
committerbonzini <bonzini@138bc75d-0d04-0410-961f-82ee72b054a4>2009-08-01 22:03:34 +0000
commit3b2411a88d1a0a07e7c93da834ec7719792d351f (patch)
treef0eeae6aa04e1213f78c59803b4a875d6b3602cd /gcc/explow.c
parent1684855694a44db9229a0c991221e727904ca960 (diff)
downloadgcc-3b2411a88d1a0a07e7c93da834ec7719792d351f.tar.gz
2009-04-17 Paolo Bonzini <bonzini@gnu.org>
* expr.c (store_constructor): Use promote_decl_mode. Remove now write-only variable unsignedp. (expand_expr_real_1): Use promote_decl_mode. * expr.h (promote_function_mode, promote_decl_mode): New. (promote_mode): Remove last argument. * function.c (assign_temp): Drop last argument of promote_mode. (assign_parm_find_data_types): Use promote_function_mode. (assign_parm_setup_reg): Likewise. (expand_function_end): Use promote_function_mode. * calls.c (initialize_argument_information): Use promote_function_mode. (precompute_arguments): Use promote_mode instead of checking if only PROMOTE_FUNCTION_MODE is defined. (expand_call): When making sibcall decisions, use promote_function_mode. Below, remove an if for targetm.calls.promote_function_return and and use promote_function_mode. (emit_library_call_value_1): Use promote_function_mode, fix bug where promote_mode was passed FOR_CALL == 0 for a return value in an assertion. * cfgexpand.c (expand_one_register_var): Use promote_decl_mode. * explow.c (promote_function_mode, promote_decl_mode): New. (promote_mode): Keep only the FOR_CALL == 0 case. * combine.c (setup_incoming_promotion): Remove test of promote_function_args. Use promote_function_mode. * stmt.c (expand_value_return): Use promote_decl_mode. (expand_decl): Use promote_decl_mode. * expr.c (store_constructor): Use promote_decl_mode. Remove now write-only variable unsignedp. (expand_expr_real_1): Use promote_decl_mode. * expr.h (promote_function_mode, promote_decl_mode): New. (promote_mode): Remove last argument. * function.c (assign_temp): Drop last argument of promote_mode. (assign_parm_find_data_types): Use promote_function_mode. (assign_parm_setup_reg): Likewise. (expand_function_end): Use promote_function_mode. * calls.c (initialize_argument_information): Use promote_function_mode. (precompute_arguments): Use promote_mode instead of checking if only PROMOTE_FUNCTION_MODE is defined. (expand_call): When making sibcall decisions, use promote_function_mode. Below, remove an if for targetm.calls.promote_function_return and and use promote_function_mode. (emit_library_call_value_1): Use promote_function_mode, fix bug where promote_mode was passed FOR_CALL == 0 for a return value in an assertion. * cfgexpand.c (expand_one_register_var): Use promote_decl_mode. * explow.c (promote_function_mode, promote_decl_mode): New. (promote_mode): Keep only the FOR_CALL == 0 case. * combine.c (setup_incoming_promotion): Remove test of promote_function_args. Use promote_function_mode. * stmt.c (expand_value_return): Use promote_decl_mode. (expand_decl): Use promote_decl_mode. * explow.c (promote_function_mode): Just call the target hook. * targhooks.c (default_promote_function_mode, default_promote_function_mode_always_promote): New. * targhooks.h (default_promote_function_mode, default_promote_function_mode_always_promote): Declare. * target.h (promote_function_args, promote_function_return): Remove. (promote_function_mode): New. * target-def.h (TARGET_PROMOTE_FUNCTION_ARGS, TARGET_PROMOTE_FUNCTION_RETURN): Remove. (TARGET_PROMOTE_FUNCTION_MODE): New. (TARGET_CALLS): Adjust. * system.h (TARGET_PROMOTE_FUNCTION_ARGS, TARGET_PROMOTE_FUNCTION_RETURN, PROMOTE_FUNCTION_MODE): Poison. * config/s390/s390.h (PROMOTE_FUNCTION_MODE): Move... * config/s390/s390.c (s390_promote_function_mode): ... here, with pointer handling. (TARGET_PROMOTE_FUNCTION_MODE): Define. (TARGET_PROMOTE_FUNCTION_ARGS, TARGET_PROMOTE_FUNCTION_RETURN): Remove. * config/sparc/sparc.h (PROMOTE_FUNCTION_MODE): Move... * config/sparc/sparc.c (sparc_promote_function_mode): ... here, with pointer handling. (TARGET_PROMOTE_FUNCTION_MODE): Define. (TARGET_PROMOTE_FUNCTION_ARGS, TARGET_PROMOTE_FUNCTION_RETURN): Remove. * config/sh/sh-protos.h (sh_promote_function_mode): New. * config/sh/sh.c (sh_promote_function_mode): New. (TARGET_PROMOTE_FUNCTION_MODE): Define. (TARGET_PROMOTE_FUNCTION_ARGS, TARGET_PROMOTE_FUNCTION_RETURN): Remove. * config/cris/cris.h (PROMOTE_FUNCTION_MODE): Move... * config/cris/cris.c (cris_promote_function_mode): ... here. (TARGET_PROMOTE_FUNCTION_MODE): Define. (TARGET_PROMOTE_FUNCTION_ARGS): Remove. * config/mmix/mmix.h (PROMOTE_FUNCTION_MODE): Move... * config/mmix/mmix.c (mmix_promote_function_mode): ... here. (TARGET_PROMOTE_FUNCTION_MODE): Define. (TARGET_PROMOTE_FUNCTION_ARGS): Remove. * config/arm/arm.h (PROMOTE_FUNCTION_MODE): Move... * config/arm/arm.c (arm_promote_function_mode): ... here, without complex type handling. (TARGET_PROMOTE_FUNCTION_MODE): Define. (TARGET_PROMOTE_FUNCTION_ARGS, TARGET_PROMOTE_FUNCTION_RETURN): Remove. * config/pa/pa.c (pa_promote_function_mode): New. (TARGET_PROMOTE_FUNCTION_MODE): Define. (TARGET_PROMOTE_FUNCTION_RETURN): Remove. * config/alpha/alpha.c (TARGET_PROMOTE_FUNCTION_ARGS, TARGET_PROMOTE_FUNCTION_RETURN): Remove. (TARGET_PROMOTE_FUNCTION_MODE): Define equivalently. * config/xtensa/xtensa.c: Likewise. * config/stormy16/stormy16.c: Likewise. * config/iq2000/iq2000.c: Likewise. * config/rs6000/rs6000.c: Likewise. * config/picochip/picochip.c: Likewise. * config/arc/arc.c: Likewise. * config/mcore/mcore.c: Likewise. * config/score/score.c: Likewise. * config/mips/mips.c: Likewise. * config/bfin/bfin.c: Likewise. * config/ia64/ia64.c: Likewise (disabled though). * config/frv/frv.h: Remove pointless remark. * doc/tm.texi (PROMOTE_FUNCTION_MODE, TARGET_PROMOTE_FUNCTION_ARGS, TARGET_PROMOTE_FUNCTION_RETURN): Consolidate into... (TARGET_PROMOTE_FUNCTION_MODE): ... this. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@150336 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/explow.c')
-rw-r--r--gcc/explow.c95
1 files changed, 64 insertions, 31 deletions
diff --git a/gcc/explow.c b/gcc/explow.c
index 198df220fbd..0a2616436e3 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -749,63 +749,96 @@ copy_to_suggested_reg (rtx x, rtx target, enum machine_mode mode)
return temp;
}
-/* Return the mode to use to store a scalar of TYPE and MODE.
+/* Return the mode to use to pass or return a scalar of TYPE and MODE.
PUNSIGNEDP points to the signedness of the type and may be adjusted
to show what signedness to use on extension operations.
- FOR_CALL is nonzero if this call is promoting args for a call. */
+ FOR_RETURN is nonzero if the caller is promoting the return value
+ of FNDECL, else it is for promoting args. */
-#if defined(PROMOTE_MODE) && !defined(PROMOTE_FUNCTION_MODE)
-#define PROMOTE_FUNCTION_MODE PROMOTE_MODE
-#endif
+enum machine_mode
+promote_function_mode (const_tree type, enum machine_mode mode, int *punsignedp,
+ const_tree funtype, int for_return)
+{
+ gcc_assert (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT);
+ switch (TREE_CODE (type))
+ {
+ case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
+ case REAL_TYPE: case OFFSET_TYPE: case FIXED_POINT_TYPE:
+ case POINTER_TYPE: case REFERENCE_TYPE:
+ return targetm.calls.promote_function_mode (type, mode, punsignedp, funtype,
+ for_return);
+
+ default:
+ return mode;
+ }
+}
+/* Return the mode to use to store a scalar of TYPE and MODE.
+ PUNSIGNEDP points to the signedness of the type and may be adjusted
+ to show what signedness to use on extension operations. */
enum machine_mode
-promote_mode (const_tree type, enum machine_mode mode, int *punsignedp,
- int for_call ATTRIBUTE_UNUSED)
+promote_mode (const_tree type, enum machine_mode mode, int *punsignedp)
{
+ /* FIXME: this is the same logic that was there until GCC 4.4, but we
+ probably want to test POINTERS_EXTEND_UNSIGNED even if PROMOTE_MODE
+ is not defined. The affected targets are M32C, S390, SPARC. */
+#ifdef PROMOTE_MODE
const enum tree_code code = TREE_CODE (type);
int unsignedp = *punsignedp;
-#ifndef PROMOTE_MODE
- if (! for_call)
- return mode;
-#endif
-
switch (code)
{
-#ifdef PROMOTE_FUNCTION_MODE
case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
case REAL_TYPE: case OFFSET_TYPE: case FIXED_POINT_TYPE:
-#ifdef PROMOTE_MODE
- if (for_call)
- {
-#endif
- PROMOTE_FUNCTION_MODE (mode, unsignedp, type);
-#ifdef PROMOTE_MODE
- }
- else
- {
- PROMOTE_MODE (mode, unsignedp, type);
- }
-#endif
+ PROMOTE_MODE (mode, unsignedp, type);
+ *punsignedp = unsignedp;
+ return mode;
break;
-#endif
#ifdef POINTERS_EXTEND_UNSIGNED
case REFERENCE_TYPE:
case POINTER_TYPE:
- mode = Pmode;
- unsignedp = POINTERS_EXTEND_UNSIGNED;
+ *punsignedp = POINTERS_EXTEND_UNSIGNED;
+ return Pmode;
break;
#endif
default:
- break;
+ return mode;
}
-
- *punsignedp = unsignedp;
+#else
return mode;
+#endif
}
+
+
+/* Use one of promote_mode or promote_function_mode to find the promoted
+ mode of DECL. If PUNSIGNEDP is not NULL, store there the unsignedness
+ of DECL after promotion. */
+
+enum machine_mode
+promote_decl_mode (const_tree decl, int *punsignedp)
+{
+ tree type = TREE_TYPE (decl);
+ int unsignedp = TYPE_UNSIGNED (type);
+ enum machine_mode mode = DECL_MODE (decl);
+ enum machine_mode pmode;
+
+ if (TREE_CODE (decl) == RESULT_DECL)
+ pmode = promote_function_mode (type, mode, &unsignedp,
+ TREE_TYPE (current_function_decl), 1);
+ else if (TREE_CODE (decl) == PARM_DECL)
+ pmode = promote_function_mode (type, mode, &unsignedp,
+ TREE_TYPE (current_function_decl), 0);
+ else
+ pmode = promote_mode (type, mode, &unsignedp);
+
+ if (punsignedp)
+ *punsignedp = unsignedp;
+ return pmode;
+}
+
/* Adjust the stack pointer by ADJUST (an rtx for a number of bytes).
This pops when ADJUST is positive. ADJUST need not be constant. */