diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1992-09-27 18:18:33 -0400 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1992-09-27 18:18:33 -0400 |
commit | a53e14c093434c3829a60dd450db4741205b10eb (patch) | |
tree | 7b1f12b7c6f5f67a737f33acfacb34f115eb0543 | |
parent | 01def76468d36fe7524eca8b54feef5482eacb3e (diff) | |
download | gcc-a53e14c093434c3829a60dd450db4741205b10eb.zip gcc-a53e14c093434c3829a60dd450db4741205b10eb.tar.gz gcc-a53e14c093434c3829a60dd450db4741205b10eb.tar.bz2 |
(assign_parms): If PROMOTE_FUNCTION_ARGS is defined, see if the incoming register should be used in a wider mode.
(assign_parms): If PROMOTE_FUNCTION_ARGS is defined, see if the incoming
register should be used in a wider mode.
(expand_function_start): Likewise for return value if PROMOTE_FUNCTION_RETURN
is defined.
From-SVN: r2263
-rw-r--r-- | gcc/function.c | 57 |
1 files changed, 47 insertions, 10 deletions
diff --git a/gcc/function.c b/gcc/function.c index 01292cb..6cde316 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2556,7 +2556,7 @@ assign_parms (fndecl, second_time) register rtx entry_parm = 0; register rtx stack_parm = 0; CUMULATIVE_ARGS args_so_far; - enum machine_mode passed_mode, nominal_mode; + enum machine_mode promoted_mode, passed_mode, nominal_mode; int unsignedp; /* Total space needed so far for args on the stack, given as a constant and a tree-expression. */ @@ -2692,16 +2692,36 @@ assign_parms (fndecl, second_time) } #endif + promoted_mode = passed_mode; + +#ifdef PROMOTE_FUNCTION_ARGS + /* Compute the mode in which the arg is actually extended to. */ + if (TREE_CODE (passed_type) == INTEGER_TYPE + || TREE_CODE (passed_type) == ENUMERAL_TYPE + || TREE_CODE (passed_type) == BOOLEAN_TYPE + || TREE_CODE (passed_type) == CHAR_TYPE + || TREE_CODE (passed_type) == REAL_TYPE + || TREE_CODE (passed_type) == POINTER_TYPE + || TREE_CODE (passed_type) == OFFSET_TYPE) + { + unsignedp = TREE_UNSIGNED (passed_type); + PROMOTE_MODE (promoted_mode, unsignedp, passed_type); + } +#endif + /* Let machine desc say which reg (if any) the parm arrives in. 0 means it arrives on the stack. */ #ifdef FUNCTION_INCOMING_ARG - entry_parm = FUNCTION_INCOMING_ARG (args_so_far, passed_mode, + entry_parm = FUNCTION_INCOMING_ARG (args_so_far, promoted_mode, passed_type, ! last_named); #else - entry_parm = FUNCTION_ARG (args_so_far, passed_mode, + entry_parm = FUNCTION_ARG (args_so_far, promoted_mode, passed_type, ! last_named); #endif + if (entry_parm) + passed_mode = promoted_mode; + #ifdef SETUP_INCOMING_VARARGS /* If this is the last named parameter, do any required setup for varargs or stdargs. We need to know about the case of this being an @@ -3069,7 +3089,8 @@ assign_parms (fndecl, second_time) && ! HARD_REGNO_MODE_OK (REGNO (entry_parm), passed_mode)) entry_parm = copy_to_reg (entry_parm); - entry_parm = convert_to_mode (nominal_mode, entry_parm, 0); + entry_parm = convert_to_mode (nominal_mode, entry_parm, + TREE_UNSIGNED (TREE_TYPE (parm))); } if (entry_parm != stack_parm) @@ -4079,12 +4100,28 @@ expand_function_start (subr, parms_have_cleanups) /* If return mode is void, this decl rtl should not be used. */ DECL_RTL (DECL_RESULT (subr)) = 0; else if (parms_have_cleanups) - /* If function will end with cleanup code for parms, - compute the return values into a pseudo reg, - which we will copy into the true return register - after the cleanups are done. */ - DECL_RTL (DECL_RESULT (subr)) - = gen_reg_rtx (DECL_MODE (DECL_RESULT (subr))); + { + /* If function will end with cleanup code for parms, + compute the return values into a pseudo reg, + which we will copy into the true return register + after the cleanups are done. */ + + enum machine_mode mode = DECL_MODE (DECL_RESULT (subr)); +#ifdef PROMOTE_FUNCTION_RETURN + tree type = TREE_TYPE (DECL_RESULT (subr)); + int unsignedp = TREE_UNSIGNED (type); + + if (TREE_CODE (type) == INTEGER_TYPE || TREE_CODE (type) == ENUMERAL_TYPE + || TREE_CODE (type) == BOOLEAN_TYPE || TREE_CODE (type) == CHAR_TYPE + || TREE_CODE (type) == REAL_TYPE || TREE_CODE (type) == POINTER_TYPE + || TREE_CODE (type) == OFFSET_TYPE) + { + PROMOTE_MODE (mode, unsignedp, type); + } +#endif + + DECL_RTL (DECL_RESULT (subr)) = gen_reg_rtx (mode); + } else /* Scalar, returned in a register. */ { |