From 85d53c1d08fbc4b95ac0f21207b87bffe0349841 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 9 Jul 2004 03:13:16 -0700 Subject: [PATCH] xtensa-protos.h (xtensa_va_arg): Remove. * config/xtensa/xtensa-protos.h (xtensa_va_arg): Remove. * config/xtensa/xtensa.c (TARGET_GIMPLIFY_VA_ARG_EXPR): New. (xtensa_gimplify_va_arg_expr): Rewrite from xtensa_va_arg. * config/xtensa/xtensa.h (EXPAND_BUILTIN_VA_ARG): Remove. From-SVN: r84360 --- gcc/ChangeLog | 5 + gcc/config/xtensa/xtensa-protos.h | 1 - gcc/config/xtensa/xtensa.c | 196 ++++++++++++++---------------- gcc/config/xtensa/xtensa.h | 4 - 4 files changed, 97 insertions(+), 109 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 166277bc92d..120df2955e2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2004-07-09 Richard Henderson + * config/xtensa/xtensa-protos.h (xtensa_va_arg): Remove. + * config/xtensa/xtensa.c (TARGET_GIMPLIFY_VA_ARG_EXPR): New. + (xtensa_gimplify_va_arg_expr): Rewrite from xtensa_va_arg. + * config/xtensa/xtensa.h (EXPAND_BUILTIN_VA_ARG): Remove. + * config/v850/v850-protos.h (v850_va_arg): Remove. * config/v850/v850.c (TARGET_GIMPLIFY_VA_ARG_EXPR): New. (v850_gimplify_va_arg_expr): Rewrite from v850_va_arg. diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h index 38a5dce985e..a300204e8ec 100644 --- a/gcc/config/xtensa/xtensa-protos.h +++ b/gcc/config/xtensa/xtensa-protos.h @@ -77,7 +77,6 @@ extern char *xtensa_emit_call (int, rtx *); #ifdef TREE_CODE extern void init_cumulative_args (CUMULATIVE_ARGS *, int); extern void xtensa_va_start (tree, rtx); -extern rtx xtensa_va_arg (tree, tree); #endif /* TREE_CODE */ extern void print_operand (FILE *, rtx, int); diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c index 4f4334a6dbb..f21930d9667 100644 --- a/gcc/config/xtensa/xtensa.c +++ b/gcc/config/xtensa/xtensa.c @@ -48,6 +48,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "target.h" #include "target-def.h" #include "langhooks.h" +#include "tree-gimple.h" + /* Enumeration for all of the relational tests, so that we can build arrays indexed by the test type, and not worry about the order @@ -211,6 +213,7 @@ static void xtensa_select_rtx_section (enum machine_mode, rtx, static bool xtensa_rtx_costs (rtx, int, int, int *); static tree xtensa_build_builtin_va_list (void); static bool xtensa_return_in_memory (tree, tree); +static tree xtensa_gimplify_va_arg_expr (tree, tree, tree *, tree *); static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER; @@ -255,6 +258,8 @@ static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] = #undef TARGET_EXPAND_BUILTIN_SAVEREGS #define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs +#undef TARGET_GIMPLIFY_VA_ARG_EXPR +#define TARGET_GIMPLIFY_VA_ARG_EXPR xtensa_gimplify_va_arg_expr #undef TARGET_RETURN_IN_MSB #define TARGET_RETURN_IN_MSB xtensa_return_in_msb @@ -2461,33 +2466,30 @@ xtensa_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED) /* Implement `va_arg'. */ -rtx -xtensa_va_arg (tree valist, tree type) +static tree +xtensa_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, + tree *post_p ATTRIBUTE_UNUSED) { tree f_stk, stk; tree f_reg, reg; tree f_ndx, ndx; - tree tmp, addr_tree, type_size; - rtx array, orig_ndx, r, addr, size, va_size; - rtx lab_false, lab_over, lab_false2; + tree type_size, array, orig_ndx, addr, size, va_size, t; + tree lab_false, lab_over, lab_false2; /* Handle complex values as separate real and imaginary parts. */ if (TREE_CODE (type) == COMPLEX_TYPE) { - rtx real_part, imag_part, concat_val, local_copy; + tree real_part, imag_part; - real_part = xtensa_va_arg (valist, TREE_TYPE (type)); - imag_part = xtensa_va_arg (valist, TREE_TYPE (type)); + real_part = xtensa_gimplify_va_arg_expr (valist, TREE_TYPE (type), + pre_p, NULL); + real_part = get_initialized_tmp_var (real_part, pre_p, NULL); - /* Make a copy of the value in case the parts are not contiguous. */ - real_part = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (type)), real_part); - imag_part = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (type)), imag_part); - concat_val = gen_rtx_CONCAT (TYPE_MODE (type), real_part, imag_part); + imag_part = xtensa_gimplify_va_arg_expr (valist, TREE_TYPE (type), + pre_p, NULL); + imag_part = get_initialized_tmp_var (imag_part, pre_p, NULL); - local_copy = assign_temp (type, 0, 1, 0); - emit_move_insn (local_copy, concat_val); - - return XEXP (local_copy, 0); + return build (COMPLEX_EXPR, type, real_part, imag_part); } f_stk = TYPE_FIELDS (va_list_type_node); @@ -2498,55 +2500,41 @@ xtensa_va_arg (tree valist, tree type) reg = build (COMPONENT_REF, TREE_TYPE (f_reg), valist, f_reg, NULL_TREE); ndx = build (COMPONENT_REF, TREE_TYPE (f_ndx), valist, f_ndx, NULL_TREE); - type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type)); - - va_size = gen_reg_rtx (SImode); - tmp = fold (build (MULT_EXPR, sizetype, - fold (build (TRUNC_DIV_EXPR, sizetype, - fold (build (PLUS_EXPR, sizetype, - type_size, - size_int (UNITS_PER_WORD - 1))), - size_int (UNITS_PER_WORD))), - size_int (UNITS_PER_WORD))); - r = expand_expr (tmp, va_size, SImode, EXPAND_NORMAL); - if (r != va_size) - emit_move_insn (va_size, r); + type_size = size_in_bytes (type); + va_size = round_up (type_size, UNITS_PER_WORD); + gimplify_expr (&va_size, pre_p, NULL, is_gimple_val, fb_rvalue); /* First align __va_ndx if necessary for this arg: + orig_ndx = (AP).__va_ndx; if (__alignof__ (TYPE) > 4 ) - (AP).__va_ndx = (((AP).__va_ndx + __alignof__ (TYPE) - 1) + orig_ndx = ((orig_ndx + __alignof__ (TYPE) - 1) & -__alignof__ (TYPE)); */ + orig_ndx = get_initialized_tmp_var (ndx, pre_p, NULL); + if (TYPE_ALIGN (type) > BITS_PER_WORD) { int align = TYPE_ALIGN (type) / BITS_PER_UNIT; - tmp = build (PLUS_EXPR, integer_type_node, ndx, - build_int_2 (align - 1, 0)); - tmp = build (BIT_AND_EXPR, integer_type_node, tmp, - build_int_2 (-align, -1)); - tmp = build (MODIFY_EXPR, integer_type_node, ndx, tmp); - TREE_SIDE_EFFECTS (tmp) = 1; - expand_expr (tmp, const0_rtx, VOIDmode, EXPAND_NORMAL); + + t = build (PLUS_EXPR, integer_type_node, orig_ndx, + build_int_2 (align - 1, 0)); + t = build (BIT_AND_EXPR, integer_type_node, t, + build_int_2 (-align, -1)); + t = build (MODIFY_EXPR, integer_type_node, orig_ndx, t); + gimplify_and_add (t, pre_p); } /* Increment __va_ndx to point past the argument: - orig_ndx = (AP).__va_ndx; - (AP).__va_ndx += __va_size (TYPE); */ - - orig_ndx = gen_reg_rtx (SImode); - r = expand_expr (ndx, orig_ndx, SImode, EXPAND_NORMAL); - if (r != orig_ndx) - emit_move_insn (orig_ndx, r); + (AP).__va_ndx = orig_ndx + __va_size (TYPE); */ - tmp = build (PLUS_EXPR, integer_type_node, ndx, - make_tree (intSI_type_node, va_size)); - tmp = build (MODIFY_EXPR, integer_type_node, ndx, tmp); - TREE_SIDE_EFFECTS (tmp) = 1; - expand_expr (tmp, const0_rtx, VOIDmode, EXPAND_NORMAL); + t = fold_convert (integer_type_node, va_size); + t = build (PLUS_EXPR, integer_type_node, orig_ndx, t); + t = build (MODIFY_EXPR, integer_type_node, ndx, t); + gimplify_and_add (t, pre_p); /* Check if the argument is in registers: @@ -2555,29 +2543,32 @@ xtensa_va_arg (tree valist, tree type) && !MUST_PASS_IN_STACK (type)) __array = (AP).__va_reg; */ - array = gen_reg_rtx (Pmode); + array = create_tmp_var (ptr_type_node, NULL); - lab_over = NULL_RTX; + lab_over = NULL; if (!MUST_PASS_IN_STACK (VOIDmode, type)) { - lab_false = gen_label_rtx (); - lab_over = gen_label_rtx (); - - emit_cmp_and_jump_insns (expand_expr (ndx, NULL_RTX, SImode, - EXPAND_NORMAL), - GEN_INT (MAX_ARGS_IN_REGISTERS - * UNITS_PER_WORD), - GT, const1_rtx, SImode, 0, lab_false); - - r = expand_expr (reg, array, Pmode, EXPAND_NORMAL); - if (r != array) - emit_move_insn (array, r); - - emit_jump_insn (gen_jump (lab_over)); - emit_barrier (); - emit_label (lab_false); + lab_false = create_artificial_label (); + lab_over = create_artificial_label (); + + t = build_int_2 (MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD, 0); + t = build (GT_EXPR, boolean_type_node, ndx, t); + t = build (COND_EXPR, void_type_node, t, + build (GOTO_EXPR, void_type_node, lab_false), + NULL); + gimplify_and_add (t, pre_p); + + t = build (MODIFY_EXPR, void_type_node, array, reg); + gimplify_and_add (t, pre_p); + + t = build (GOTO_EXPR, void_type_node, lab_over); + gimplify_and_add (t, pre_p); + + t = build (LABEL_EXPR, void_type_node, lab_false); + gimplify_and_add (t, pre_p); } + /* ...otherwise, the argument is on the stack (never split between registers and the stack -- change __va_ndx if necessary): @@ -2588,25 +2579,31 @@ xtensa_va_arg (tree valist, tree type) __array = (AP).__va_stk; } */ - lab_false2 = gen_label_rtx (); - emit_cmp_and_jump_insns (orig_ndx, - GEN_INT (MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD), - GT, const1_rtx, SImode, 0, lab_false2); + lab_false2 = create_artificial_label (); - tmp = build (PLUS_EXPR, sizetype, make_tree (intSI_type_node, va_size), - build_int_2 (32, 0)); - tmp = build (MODIFY_EXPR, integer_type_node, ndx, tmp); - TREE_SIDE_EFFECTS (tmp) = 1; - expand_expr (tmp, const0_rtx, VOIDmode, EXPAND_NORMAL); + t = build_int_2 (MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD, 0); + t = build (GT_EXPR, boolean_type_node, orig_ndx, t); + t = build (COND_EXPR, void_type_node, t, + build (GOTO_EXPR, void_type_node, lab_false2), + NULL); + gimplify_and_add (t, pre_p); - emit_label (lab_false2); + t = size_binop (PLUS_EXPR, va_size, size_int (32)); + t = fold_convert (integer_type_node, t); + t = build (MODIFY_EXPR, integer_type_node, ndx, t); + gimplify_and_add (t, pre_p); - r = expand_expr (stk, array, Pmode, EXPAND_NORMAL); - if (r != array) - emit_move_insn (array, r); + t = build (LABEL_EXPR, void_type_node, lab_false2); + gimplify_and_add (t, pre_p); - if (lab_over != NULL_RTX) - emit_label (lab_over); + t = build (MODIFY_EXPR, void_type_node, array, stk); + gimplify_and_add (t, pre_p); + + if (lab_over) + { + t = build (LABEL_EXPR, void_type_node, lab_over); + gimplify_and_add (t, pre_p); + } /* Given the base array pointer (__array) and index to the subsequent @@ -2619,33 +2616,24 @@ xtensa_va_arg (tree valist, tree type) The results are endian-dependent because values smaller than one word are aligned differently. */ - size = gen_reg_rtx (SImode); - emit_move_insn (size, va_size); if (BYTES_BIG_ENDIAN) { - rtx lab_use_va_size = gen_label_rtx (); - - emit_cmp_and_jump_insns (expand_expr (type_size, NULL_RTX, SImode, - EXPAND_NORMAL), - GEN_INT (PARM_BOUNDARY / BITS_PER_UNIT), - GE, const1_rtx, SImode, 0, lab_use_va_size); - - r = expand_expr (type_size, size, SImode, EXPAND_NORMAL); - if (r != size) - emit_move_insn (size, r); - - emit_label (lab_use_va_size); + t = size_int (PARM_BOUNDARY / BITS_PER_UNIT); + t = fold (build (GE_EXPR, boolean_type_node, type_size, t)); + t = fold (build (COND_EXPR, sizetype, t, type_size, va_size)); + size = t; } + else + size = va_size; + + t = fold_convert (ptr_type_node, ndx); + addr = build (PLUS_EXPR, ptr_type_node, array, t); + t = fold_convert (ptr_type_node, size); + addr = build (MINUS_EXPR, ptr_type_node, addr, t); - addr_tree = build (PLUS_EXPR, ptr_type_node, - make_tree (ptr_type_node, array), - ndx); - addr_tree = build (MINUS_EXPR, ptr_type_node, addr_tree, - make_tree (intSI_type_node, size)); - addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL); - addr = copy_to_reg (addr); - return addr; + addr = fold_convert (build_pointer_type (type), addr); + return build_fold_indirect_ref (addr); } diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h index 9eb017507a7..41e64c6278b 100644 --- a/gcc/config/xtensa/xtensa.h +++ b/gcc/config/xtensa/xtensa.h @@ -901,10 +901,6 @@ typedef struct xtensa_args #define EXPAND_BUILTIN_VA_START(valist, nextarg) \ xtensa_va_start (valist, nextarg) -/* Implement `va_arg'. */ -#define EXPAND_BUILTIN_VA_ARG(valist, type) \ - xtensa_va_arg (valist, type) - /* If defined, a C expression that produces the machine-specific code to setup the stack so that arbitrary frames can be accessed. -- 2.30.2