X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fexpr.c;h=50a20355d1ca399c2ec645e5d1d33867ad75de9b;hb=dc8948dbb1c662516d86df1a9575194358c1890f;hp=75c17923cd0651d6bb790c6f5777fa7211bb2675;hpb=48e1416a24d50cacbb2a5e06a9ee61dd8cbee313;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/expr.c b/gcc/expr.c index 75c17923cd0..50a20355d1c 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -1,6 +1,6 @@ /* Convert tree expression to rtl instructions, for GNU compiler. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -24,7 +24,6 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "machmode.h" -#include "real.h" #include "rtl.h" #include "tree.h" #include "flags.h" @@ -43,7 +42,6 @@ along with GCC; see the file COPYING3. If not see #include "output.h" #include "typeclass.h" #include "toplev.h" -#include "ggc.h" #include "langhooks.h" #include "intl.h" #include "tm_p.h" @@ -774,18 +772,13 @@ convert_modes (enum machine_mode mode, enum machine_mode oldmode, rtx x, int uns && GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT && CONST_INT_P (x) && INTVAL (x) < 0) { - HOST_WIDE_INT val = INTVAL (x); + double_int val = uhwi_to_double_int (INTVAL (x)); - if (oldmode != VOIDmode - && HOST_BITS_PER_WIDE_INT > GET_MODE_BITSIZE (oldmode)) - { - int width = GET_MODE_BITSIZE (oldmode); + /* We need to zero extend VAL. */ + if (oldmode != VOIDmode) + val = double_int_zext (val, GET_MODE_BITSIZE (oldmode)); - /* We need to zero extend VAL. */ - val &= ((HOST_WIDE_INT) 1 << width) - 1; - } - - return immed_double_const (val, (HOST_WIDE_INT) 0, mode); + return immed_double_int_const (val, mode); } /* We can do this with a gen_lowpart if both desired and current modes @@ -1194,6 +1187,7 @@ emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method, } align = MIN (MEM_ALIGN (x), MEM_ALIGN (y)); + gcc_assert (align >= BITS_PER_UNIT); gcc_assert (MEM_P (x)); gcc_assert (MEM_P (y)); @@ -1261,6 +1255,9 @@ block_move_libcall_safe_for_call_parm (void) an outgoing argument. */ #if defined (REG_PARM_STACK_SPACE) fn = emit_block_move_libcall_fn (false); + /* Avoid set but not used warning if *REG_PARM_STACK_SPACE doesn't + depend on its argument. */ + (void) fn; if (OUTGOING_REG_PARM_STACK_SPACE ((!fn ? NULL_TREE : TREE_TYPE (fn))) && REG_PARM_STACK_SPACE (fn) != 0) return false; @@ -4431,9 +4428,11 @@ expand_assignment (tree to, tree from, bool nontemporal) /* In case we are returning the contents of an object which overlaps the place the value is being stored, use a safe function when copying a value through a pointer into a structure value return block. */ - if (TREE_CODE (to) == RESULT_DECL && TREE_CODE (from) == INDIRECT_REF + if (TREE_CODE (to) == RESULT_DECL + && TREE_CODE (from) == INDIRECT_REF && ADDR_SPACE_GENERIC_P - (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (from, 0))))) + (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (from, 0))))) + && refs_may_alias_p (to, from) && cfun->returns_struct && !cfun->returns_pcc_struct) { @@ -4550,7 +4549,7 @@ store_expr (tree exp, rtx target, int call_param_p, bool nontemporal) do_pending_stack_adjust (); NO_DEFER_POP; - jumpifnot (TREE_OPERAND (exp, 0), lab1); + jumpifnot (TREE_OPERAND (exp, 0), lab1, -1); store_expr (TREE_OPERAND (exp, 1), target, call_param_p, nontemporal); emit_jump_insn (gen_jump (lab2)); @@ -4855,9 +4854,8 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts, FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value) { - HOST_WIDE_INT mult; + HOST_WIDE_INT mult = 1; - mult = 1; if (TREE_CODE (purpose) == RANGE_EXPR) { tree lo_index = TREE_OPERAND (purpose, 0); @@ -4919,12 +4917,17 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts, break; default: - nz_elts += mult; - elt_count += mult; + { + HOST_WIDE_INT tc = count_type_elements (TREE_TYPE (value), true); + if (tc < 1) + tc = 1; + nz_elts += mult * tc; + elt_count += mult * tc; - if (const_from_elts_p && const_p) - const_p = initializer_constant_valid_p (value, TREE_TYPE (value)) - != NULL_TREE; + if (const_from_elts_p && const_p) + const_p = initializer_constant_valid_p (value, TREE_TYPE (value)) + != NULL_TREE; + } break; } } @@ -5546,7 +5549,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size) /* Generate a conditional jump to exit the loop. */ exit_cond = build2 (LT_EXPR, integer_type_node, index, hi_index); - jumpif (exit_cond, loop_end); + jumpif (exit_cond, loop_end, -1); /* Update the loop counter, and jump to the head of the loop. */ @@ -5967,6 +5970,7 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize, /* First get the mode, signedness, and size. We do this from just the outermost expression. */ + *pbitsize = -1; if (TREE_CODE (exp) == COMPONENT_REF) { tree field = TREE_OPERAND (exp, 1); @@ -6840,9 +6844,8 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode, return expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier); case CONST_DECL: - /* Recurse and make the output_constant_def clause above handle this. */ - return expand_expr_addr_expr_1 (DECL_INITIAL (exp), target, - tmode, modifier, as); + /* Expand the initializer like constants above. */ + return XEXP (expand_expr_constant (DECL_INITIAL (exp), 0, modifier), 0); case REALPART_EXPR: /* The real part of the complex number is always first, therefore @@ -7173,6 +7176,8 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode, if (cfun && EXPR_HAS_LOCATION (exp)) { location_t saved_location = input_location; + location_t saved_curr_loc = get_curr_insn_source_location (); + tree saved_block = get_curr_insn_block (); input_location = EXPR_LOCATION (exp); set_curr_insn_source_location (input_location); @@ -7182,6 +7187,8 @@ expand_expr_real (tree exp, rtx target, enum machine_mode tmode, ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl); input_location = saved_location; + set_curr_insn_block (saved_block); + set_curr_insn_source_location (saved_curr_loc); } else { @@ -7203,7 +7210,6 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, optab this_optab; rtx subtarget, original_target; int ignore; - tree subexp0, subexp1; bool reduce_bit_field; gimple subexp0_def, subexp1_def; tree top0, top1; @@ -7658,13 +7664,7 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, goto binop2; - case MULT_EXPR: - /* If this is a fixed-point operation, then we cannot use the code - below because "expand_mult" doesn't support sat/no-sat fixed-point - multiplications. */ - if (ALL_FIXED_POINT_MODE_P (mode)) - goto binop; - + case WIDEN_MULT_EXPR: /* If first operand is constant, swap them. Thus the following special case checks need only check the second operand. */ @@ -7675,96 +7675,35 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, treeop1 = t1; } - /* Attempt to return something suitable for generating an - indexed address, for machines that support that. */ - - if (modifier == EXPAND_SUM && mode == ptr_mode - && host_integerp (treeop1, 0)) - { - tree exp1 = treeop1; - - op0 = expand_expr (treeop0, subtarget, VOIDmode, - EXPAND_SUM); - - if (!REG_P (op0)) - op0 = force_operand (op0, NULL_RTX); - if (!REG_P (op0)) - op0 = copy_to_mode_reg (mode, op0); - - return REDUCE_BIT_FIELD (gen_rtx_MULT (mode, op0, - gen_int_mode (tree_low_cst (exp1, 0), - TYPE_MODE (TREE_TYPE (exp1))))); - } - - if (modifier == EXPAND_STACK_PARM) - target = 0; - - /* Check for multiplying things that have been extended - from a narrower type. If this machine supports multiplying - in that narrower type with a result in the desired type, - do it that way, and avoid the explicit type-conversion. */ - - subexp0 = treeop0; - subexp1 = treeop1; - subexp0_def = get_def_for_expr (subexp0, NOP_EXPR); - subexp1_def = get_def_for_expr (subexp1, NOP_EXPR); - top0 = top1 = NULL_TREE; - /* First, check if we have a multiplication of one signed and one unsigned operand. */ - if (subexp0_def - && (top0 = gimple_assign_rhs1 (subexp0_def)) - && subexp1_def - && (top1 = gimple_assign_rhs1 (subexp1_def)) - && TREE_CODE (type) == INTEGER_TYPE - && (TYPE_PRECISION (TREE_TYPE (top0)) - < TYPE_PRECISION (TREE_TYPE (subexp0))) - && (TYPE_PRECISION (TREE_TYPE (top0)) - == TYPE_PRECISION (TREE_TYPE (top1))) - && (TYPE_UNSIGNED (TREE_TYPE (top0)) - != TYPE_UNSIGNED (TREE_TYPE (top1)))) + if (TREE_CODE (treeop1) != INTEGER_CST + && (TYPE_UNSIGNED (TREE_TYPE (treeop0)) + != TYPE_UNSIGNED (TREE_TYPE (treeop1)))) { - enum machine_mode innermode - = TYPE_MODE (TREE_TYPE (top0)); + enum machine_mode innermode = TYPE_MODE (TREE_TYPE (treeop0)); this_optab = usmul_widen_optab; - if (mode == GET_MODE_WIDER_MODE (innermode)) + if (mode == GET_MODE_2XWIDER_MODE (innermode)) { if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing) { - if (TYPE_UNSIGNED (TREE_TYPE (top0))) - expand_operands (top0, top1, NULL_RTX, &op0, &op1, + if (TYPE_UNSIGNED (TREE_TYPE (treeop0))) + expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL); else - expand_operands (top0, top1, NULL_RTX, &op1, &op0, + expand_operands (treeop0, treeop1, subtarget, &op1, &op0, EXPAND_NORMAL); - goto binop3; } } } - /* Check for a multiplication with matching signedness. If - valid, TOP0 and TOP1 were set in the previous if - condition. */ - else if (top0 - && TREE_CODE (type) == INTEGER_TYPE - && (TYPE_PRECISION (TREE_TYPE (top0)) - < TYPE_PRECISION (TREE_TYPE (subexp0))) - && ((TREE_CODE (subexp1) == INTEGER_CST - && int_fits_type_p (subexp1, TREE_TYPE (top0)) - /* Don't use a widening multiply if a shift will do. */ - && ((GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (subexp1))) - > HOST_BITS_PER_WIDE_INT) - || exact_log2 (TREE_INT_CST_LOW (subexp1)) < 0)) - || - (top1 - && (TYPE_PRECISION (TREE_TYPE (top1)) - == TYPE_PRECISION (TREE_TYPE (top0)) - /* If both operands are extended, they must either both - be zero-extended or both be sign-extended. */ - && (TYPE_UNSIGNED (TREE_TYPE (top1)) - == TYPE_UNSIGNED (TREE_TYPE (top0))))))) + /* Check for a multiplication with matching signedness. */ + else if ((TREE_CODE (treeop1) == INTEGER_CST + && int_fits_type_p (treeop1, TREE_TYPE (treeop0))) + || (TYPE_UNSIGNED (TREE_TYPE (treeop1)) + == TYPE_UNSIGNED (TREE_TYPE (treeop0)))) { - tree op0type = TREE_TYPE (top0); + tree op0type = TREE_TYPE (treeop0); enum machine_mode innermode = TYPE_MODE (op0type); bool zextend_p = TYPE_UNSIGNED (op0type); optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab; @@ -7774,24 +7713,22 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, { if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing) { - if (TREE_CODE (subexp1) == INTEGER_CST) - expand_operands (top0, subexp1, NULL_RTX, &op0, &op1, - EXPAND_NORMAL); - else - expand_operands (top0, top1, NULL_RTX, &op0, &op1, - EXPAND_NORMAL); - goto binop3; + expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, + EXPAND_NORMAL); + temp = expand_widening_mult (mode, op0, op1, target, + unsignedp, this_optab); + return REDUCE_BIT_FIELD (temp); } - else if (optab_handler (other_optab, mode)->insn_code != CODE_FOR_nothing - && innermode == word_mode) + if (optab_handler (other_optab, mode)->insn_code != CODE_FOR_nothing + && innermode == word_mode) { rtx htem, hipart; - op0 = expand_normal (top0); - if (TREE_CODE (subexp1) == INTEGER_CST) + op0 = expand_normal (treeop0); + if (TREE_CODE (treeop1) == INTEGER_CST) op1 = convert_modes (innermode, mode, - expand_normal (subexp1), unsignedp); + expand_normal (treeop1), unsignedp); else - op1 = expand_normal (top1); + op1 = expand_normal (treeop1); temp = expand_binop (mode, other_optab, op0, op1, target, unsignedp, OPTAB_LIB_WIDEN); hipart = gen_highpart (innermode, temp); @@ -7804,7 +7741,53 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, } } } - expand_operands (subexp0, subexp1, subtarget, &op0, &op1, EXPAND_NORMAL); + treeop0 = fold_build1 (CONVERT_EXPR, type, treeop0); + treeop1 = fold_build1 (CONVERT_EXPR, type, treeop1); + expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL); + return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp)); + + case MULT_EXPR: + /* If this is a fixed-point operation, then we cannot use the code + below because "expand_mult" doesn't support sat/no-sat fixed-point + multiplications. */ + if (ALL_FIXED_POINT_MODE_P (mode)) + goto binop; + + /* If first operand is constant, swap them. + Thus the following special case checks need only + check the second operand. */ + if (TREE_CODE (treeop0) == INTEGER_CST) + { + tree t1 = treeop0; + treeop0 = treeop1; + treeop1 = t1; + } + + /* Attempt to return something suitable for generating an + indexed address, for machines that support that. */ + + if (modifier == EXPAND_SUM && mode == ptr_mode + && host_integerp (treeop1, 0)) + { + tree exp1 = treeop1; + + op0 = expand_expr (treeop0, subtarget, VOIDmode, + EXPAND_SUM); + + if (!REG_P (op0)) + op0 = force_operand (op0, NULL_RTX); + if (!REG_P (op0)) + op0 = copy_to_mode_reg (mode, op0); + + return REDUCE_BIT_FIELD (gen_rtx_MULT (mode, op0, + gen_int_mode (tree_low_cst (exp1, 0), + TYPE_MODE (TREE_TYPE (exp1))))); + } + + if (modifier == EXPAND_STACK_PARM) + target = 0; + + expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL); return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp)); case TRUNC_DIV_EXPR: @@ -8012,7 +7995,8 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, temp = gen_label_rtx (); do_compare_rtx_and_jump (target, cmpop1, comparison_code, - unsignedp, mode, NULL_RTX, NULL_RTX, temp); + unsignedp, mode, NULL_RTX, NULL_RTX, temp, + -1); } emit_move_insn (target, op1); emit_label (temp); @@ -8120,7 +8104,7 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode, emit_move_insn (target, const0_rtx); op1 = gen_label_rtx (); - jumpifnot_1 (code, treeop0, treeop1, op1); + jumpifnot_1 (code, treeop0, treeop1, op1, -1); emit_move_insn (target, const1_rtx); @@ -8405,8 +8389,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, { gimple g = get_gimple_for_ssa_name (exp); if (g) - return expand_expr_real_1 (gimple_assign_rhs_to_tree (g), target, - tmode, modifier, NULL); + return expand_expr_real (gimple_assign_rhs_to_tree (g), target, + tmode, modifier, NULL); } decl_rtl = get_rtx_for_ssa_name (exp); exp = SSA_NAME_VAR (exp); @@ -8722,6 +8706,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, { addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp)); struct mem_address addr; + tree base; get_address_description (exp, &addr); op0 = addr_for_mem_ref (&addr, as, true); @@ -8729,6 +8714,16 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, temp = gen_rtx_MEM (mode, op0); set_mem_attributes (temp, TMR_ORIGINAL (exp), 0); set_mem_addr_space (temp, as); + base = get_base_address (TMR_ORIGINAL (exp)); + if (INDIRECT_REF_P (base) + && TMR_BASE (exp) + && TREE_CODE (TMR_BASE (exp)) == SSA_NAME + && POINTER_TYPE_P (TREE_TYPE (TMR_BASE (exp)))) + { + set_mem_expr (temp, build1 (INDIRECT_REF, + TREE_TYPE (exp), TMR_BASE (exp))); + set_mem_offset (temp, NULL_RTX); + } } return temp; @@ -9327,9 +9322,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, op0 = force_reg (GET_MODE (op0), op0); op0 = gen_lowpart (mode, op0); } - /* If both modes are integral, then we can convert from one to the - other. */ - else if (SCALAR_INT_MODE_P (GET_MODE (op0)) && SCALAR_INT_MODE_P (mode)) + /* If both types are integral, convert from one mode to the other. */ + else if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (TREE_TYPE (treeop0))) op0 = convert_modes (mode, GET_MODE (op0), op0, TYPE_UNSIGNED (TREE_TYPE (treeop0))); /* As a last resort, spill op0 to memory, and reload it in a @@ -9417,7 +9411,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, emit_move_insn (target, const0_rtx); op1 = gen_label_rtx (); - jumpifnot_1 (code, treeop0, treeop1, op1); + jumpifnot_1 (code, treeop0, treeop1, op1, -1); if (target) emit_move_insn (target, const1_rtx); @@ -9474,7 +9468,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, NO_DEFER_POP; op0 = gen_label_rtx (); op1 = gen_label_rtx (); - jumpifnot (treeop0, op0); + jumpifnot (treeop0, op0, -1); store_expr (treeop1, temp, modifier == EXPAND_STACK_PARM, false); @@ -9520,7 +9514,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, int value = TREE_CODE (rhs) == BIT_IOR_EXPR; do_jump (TREE_OPERAND (rhs, 1), value ? label : 0, - value ? 0 : label); + value ? 0 : label, -1); expand_assignment (lhs, build_int_cst (TREE_TYPE (rhs), value), MOVE_NONTEMPORAL (exp)); do_pending_stack_adjust (); @@ -9660,15 +9654,8 @@ reduce_to_bit_field_precision (rtx exp, rtx target, tree type) } else if (TYPE_UNSIGNED (type)) { - rtx mask; - if (prec < HOST_BITS_PER_WIDE_INT) - mask = immed_double_const (((unsigned HOST_WIDE_INT) 1 << prec) - 1, 0, - GET_MODE (exp)); - else - mask = immed_double_const ((unsigned HOST_WIDE_INT) -1, - ((unsigned HOST_WIDE_INT) 1 - << (prec - HOST_BITS_PER_WIDE_INT)) - 1, - GET_MODE (exp)); + rtx mask = immed_double_int_const (double_int_mask (prec), + GET_MODE (exp)); return expand_and (GET_MODE (exp), exp, mask, target); } else @@ -10254,9 +10241,8 @@ const_vector_from_tree (tree exp) RTVEC_ELT (v, i) = CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (elt), inner); else - RTVEC_ELT (v, i) = immed_double_const (TREE_INT_CST_LOW (elt), - TREE_INT_CST_HIGH (elt), - inner); + RTVEC_ELT (v, i) = immed_double_int_const (tree_to_double_int (elt), + inner); } /* Initialize remaining elements to 0. */