Mercurial > hg > CbC > CbC_gcc
diff gcc/expr.c @ 63:b7f97abdc517 gcc-4.6-20100522
update gcc from gcc-4.5.0 to gcc-4.6
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 24 May 2010 12:47:05 +0900 |
parents | 77e2b8dfacca |
children | f6334be47118 |
line wrap: on
line diff
--- a/gcc/expr.c Fri Feb 12 23:41:23 2010 +0900 +++ b/gcc/expr.c Mon May 24 12:47:05 2010 +0900 @@ -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 @@ #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 @@ #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 @@ && GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT && CONST_INT_P (x) && INTVAL (x) < 0) { - HOST_WIDE_INT val = 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. */ - val &= ((HOST_WIDE_INT) 1 << width) - 1; - } - - return immed_double_const (val, (HOST_WIDE_INT) 0, mode); + double_int val = uhwi_to_double_int (INTVAL (x)); + + /* We need to zero extend VAL. */ + if (oldmode != VOIDmode) + val = double_int_zext (val, GET_MODE_BITSIZE (oldmode)); + + return immed_double_int_const (val, mode); } /* We can do this with a gen_lowpart if both desired and current modes @@ -1262,6 +1255,9 @@ 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; @@ -4432,9 +4428,11 @@ /* 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) { @@ -4551,7 +4549,7 @@ 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)); @@ -4856,9 +4854,8 @@ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value) { - HOST_WIDE_INT mult; - - mult = 1; + HOST_WIDE_INT mult = 1; + if (TREE_CODE (purpose) == RANGE_EXPR) { tree lo_index = TREE_OPERAND (purpose, 0); @@ -4920,12 +4917,17 @@ break; default: - nz_elts += mult; - elt_count += mult; - - if (const_from_elts_p && const_p) - const_p = initializer_constant_valid_p (value, TREE_TYPE (value)) - != NULL_TREE; + { + 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; + } break; } } @@ -5547,7 +5549,7 @@ /* 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. */ @@ -5968,6 +5970,7 @@ /* 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); @@ -7173,6 +7176,8 @@ 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 @@ 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 @@ 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,6 +7664,88 @@ goto binop2; + case WIDEN_MULT_EXPR: + /* 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; + } + + /* First, check if we have a multiplication of one signed and one + unsigned operand. */ + if (TREE_CODE (treeop1) != INTEGER_CST + && (TYPE_UNSIGNED (TREE_TYPE (treeop0)) + != TYPE_UNSIGNED (TREE_TYPE (treeop1)))) + { + enum machine_mode innermode = TYPE_MODE (TREE_TYPE (treeop0)); + this_optab = usmul_widen_optab; + if (mode == GET_MODE_2XWIDER_MODE (innermode)) + { + if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing) + { + if (TYPE_UNSIGNED (TREE_TYPE (treeop0))) + expand_operands (treeop0, treeop1, subtarget, &op0, &op1, + EXPAND_NORMAL); + else + expand_operands (treeop0, treeop1, subtarget, &op1, &op0, + EXPAND_NORMAL); + goto binop3; + } + } + } + /* 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 (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; + this_optab = zextend_p ? umul_widen_optab : smul_widen_optab; + + if (mode == GET_MODE_2XWIDER_MODE (innermode)) + { + if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing) + { + 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); + } + if (optab_handler (other_optab, mode)->insn_code != CODE_FOR_nothing + && innermode == word_mode) + { + rtx htem, hipart; + op0 = expand_normal (treeop0); + if (TREE_CODE (treeop1) == INTEGER_CST) + op1 = convert_modes (innermode, mode, + expand_normal (treeop1), unsignedp); + else + op1 = expand_normal (treeop1); + temp = expand_binop (mode, other_optab, op0, op1, target, + unsignedp, OPTAB_LIB_WIDEN); + hipart = gen_highpart (innermode, temp); + htem = expand_mult_highpart_adjust (innermode, hipart, + op0, op1, hipart, + zextend_p); + if (htem != hipart) + emit_move_insn (hipart, htem); + return REDUCE_BIT_FIELD (temp); + } + } + } + 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 @@ -7699,112 +7787,7 @@ 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)))) - { - enum machine_mode innermode - = TYPE_MODE (TREE_TYPE (top0)); - this_optab = usmul_widen_optab; - if (mode == GET_MODE_WIDER_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, - EXPAND_NORMAL); - else - expand_operands (top0, top1, NULL_RTX, &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))))))) - { - tree op0type = TREE_TYPE (top0); - enum machine_mode innermode = TYPE_MODE (op0type); - bool zextend_p = TYPE_UNSIGNED (op0type); - optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab; - this_optab = zextend_p ? umul_widen_optab : smul_widen_optab; - - if (mode == GET_MODE_2XWIDER_MODE (innermode)) - { - 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; - } - else 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) - op1 = convert_modes (innermode, mode, - expand_normal (subexp1), unsignedp); - else - op1 = expand_normal (top1); - temp = expand_binop (mode, other_optab, op0, op1, target, - unsignedp, OPTAB_LIB_WIDEN); - hipart = gen_highpart (innermode, temp); - htem = expand_mult_highpart_adjust (innermode, hipart, - op0, op1, hipart, - zextend_p); - if (htem != hipart) - emit_move_insn (hipart, htem); - return REDUCE_BIT_FIELD (temp); - } - } - } - expand_operands (subexp0, subexp1, subtarget, &op0, &op1, EXPAND_NORMAL); + 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 @@ 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 @@ 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 @@ { 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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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. */