From 3f620b5f2ba5930bf574d0b005078f1f7e8497ae Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 17 Apr 2005 12:29:01 -0700 Subject: [PATCH] alpha.c (va_list_skip_additions): Only define if TARGET_ABI_OSF. * config/alpha/alpha.c (va_list_skip_additions): Only define if TARGET_ABI_OSF. (TARGET_STDARG_OPTIMIZE_HOOK): Likewise. (alpha_stdarg_optimize_hook): Likewise. Allow for one more round of indirection through ssa names while looking for the gpr counter field. (alpha_setup_incoming_varargs) : Make use of the saved va_list_gpr_size and va_list_fpr_size. From-SVN: r98286 --- gcc/ChangeLog | 11 ++++++++ gcc/config/alpha/alpha.c | 68 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 56 insertions(+), 23 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 97a1c53..4b409de 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2005-04-17 Richard Henderson + + * config/alpha/alpha.c (va_list_skip_additions): Only define if + TARGET_ABI_OSF. + (TARGET_STDARG_OPTIMIZE_HOOK): Likewise. + (alpha_stdarg_optimize_hook): Likewise. Allow for one more round + of indirection through ssa names while looking for the gpr counter + field. + (alpha_setup_incoming_varargs) : Make use of the + saved va_list_gpr_size and va_list_fpr_size. + 2005-04-17 Kazu Hirata * tree-vrp.c (compare_values): Check that VAL1 and VAL2 are diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index fdcbf1b..71ba449 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -5582,6 +5582,7 @@ alpha_build_builtin_va_list (void) return record; } +#if TARGET_ABI_OSF /* Helper function for alpha_stdarg_optimize_hook. Skip over casts and constant additions. */ @@ -5685,17 +5686,16 @@ alpha_stdarg_optimize_hook (struct stdarg_info *si, tree lhs, tree rhs) arg1 = va_list_skip_additions (PHI_ARG_DEF (offset, 0)); arg2 = va_list_skip_additions (PHI_ARG_DEF (offset, 1)); - if (TREE_CODE (arg1) != COMPONENT_REF) + if (TREE_CODE (arg2) != MINUS_EXPR && TREE_CODE (arg2) != PLUS_EXPR) { tree tem = arg1; - arg1 = arg2; arg2 = tem; - } - if ((TREE_CODE (arg2) != MINUS_EXPR - && TREE_CODE (arg2) != PLUS_EXPR) - || !host_integerp (TREE_OPERAND (arg2, 1), 0)) + if (TREE_CODE (arg2) != MINUS_EXPR && TREE_CODE (arg2) != PLUS_EXPR) + goto escapes; + } + if (!host_integerp (TREE_OPERAND (arg2, 1), 0)) goto escapes; sub = tree_low_cst (TREE_OPERAND (arg2, 1), 0); @@ -5705,8 +5705,13 @@ alpha_stdarg_optimize_hook (struct stdarg_info *si, tree lhs, tree rhs) goto escapes; arg2 = va_list_skip_additions (TREE_OPERAND (arg2, 0)); - if (arg1 != arg2 - || TREE_CODE (arg1) != COMPONENT_REF + if (arg1 != arg2) + goto escapes; + + if (TREE_CODE (arg1) == SSA_NAME) + arg1 = va_list_skip_additions (arg1); + + if (TREE_CODE (arg1) != COMPONENT_REF || TREE_OPERAND (arg1, 1) != va_list_gpr_counter_field || get_base_address (arg1) != base) goto escapes; @@ -5727,6 +5732,7 @@ escapes: si->va_list_escapes = true; return false; } +#endif /* Perform any needed actions needed for a function that is receiving a variable number of arguments. */ @@ -5787,21 +5793,38 @@ alpha_setup_incoming_varargs (CUMULATIVE_ARGS *pcum, enum machine_mode mode, if (!no_rtl) { - int set = get_varargs_alias_set (); + int count, set = get_varargs_alias_set (); rtx tmp; - tmp = gen_rtx_MEM (BLKmode, - plus_constant (virtual_incoming_args_rtx, - (cum + 6) * UNITS_PER_WORD)); - set_mem_alias_set (tmp, set); - move_block_from_reg (16 + cum, tmp, 6 - cum); + count = cfun->va_list_gpr_size / UNITS_PER_WORD; + if (count > 6 - cum) + count = 6 - cum; - tmp = gen_rtx_MEM (BLKmode, - plus_constant (virtual_incoming_args_rtx, - cum * UNITS_PER_WORD)); - set_mem_alias_set (tmp, set); - move_block_from_reg (16 + cum + TARGET_FPREGS*32, tmp, 6 - cum); - } + /* Detect whether integer registers or floating-point registers + are needed by the detected va_arg statements. See above for + how these values are computed. Note that the "escape" value + is VA_LIST_MAX_FPR_SIZE, which is 255, which has both of + these bits set. */ + gcc_assert ((VA_LIST_MAX_FPR_SIZE & 3) == 3); + + if (cfun->va_list_fpr_size & 1) + { + tmp = gen_rtx_MEM (BLKmode, + plus_constant (virtual_incoming_args_rtx, + (cum + 6) * UNITS_PER_WORD)); + set_mem_alias_set (tmp, set); + move_block_from_reg (16 + cum, tmp, count); + } + + if (cfun->va_list_fpr_size & 2) + { + tmp = gen_rtx_MEM (BLKmode, + plus_constant (virtual_incoming_args_rtx, + cum * UNITS_PER_WORD)); + set_mem_alias_set (tmp, set); + move_block_from_reg (16 + cum + TARGET_FPREGS*32, tmp, count); + } + } *pretend_size = 12 * UNITS_PER_WORD; #endif } @@ -10300,6 +10323,8 @@ alpha_init_libfuncs (void) #define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true +#undef TARGET_STDARG_OPTIMIZE_HOOK +#define TARGET_STDARG_OPTIMIZE_HOOK alpha_stdarg_optimize_hook #endif #undef TARGET_RTX_COSTS @@ -10353,9 +10378,6 @@ alpha_init_libfuncs (void) #undef TARGET_HANDLE_OPTION #define TARGET_HANDLE_OPTION alpha_handle_option -#undef TARGET_STDARG_OPTIMIZE_HOOK -#define TARGET_STDARG_OPTIMIZE_HOOK alpha_stdarg_optimize_hook - struct gcc_target targetm = TARGET_INITIALIZER; -- 2.7.4