Mercurial > hg > CbC > CbC_gcc
comparison 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 |
comparison
equal
deleted
inserted
replaced
56:3c8a44c06a95 | 63:b7f97abdc517 |
---|---|
1 /* Convert tree expression to rtl instructions, for GNU compiler. | 1 /* Convert tree expression to rtl instructions, for GNU compiler. |
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, | 2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, |
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 | 3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 |
4 Free Software Foundation, Inc. | 4 Free Software Foundation, Inc. |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
8 GCC is free software; you can redistribute it and/or modify it under | 8 GCC is free software; you can redistribute it and/or modify it under |
22 #include "config.h" | 22 #include "config.h" |
23 #include "system.h" | 23 #include "system.h" |
24 #include "coretypes.h" | 24 #include "coretypes.h" |
25 #include "tm.h" | 25 #include "tm.h" |
26 #include "machmode.h" | 26 #include "machmode.h" |
27 #include "real.h" | |
28 #include "rtl.h" | 27 #include "rtl.h" |
29 #include "tree.h" | 28 #include "tree.h" |
30 #include "flags.h" | 29 #include "flags.h" |
31 #include "regs.h" | 30 #include "regs.h" |
32 #include "hard-reg-set.h" | 31 #include "hard-reg-set.h" |
41 #include "recog.h" | 40 #include "recog.h" |
42 #include "reload.h" | 41 #include "reload.h" |
43 #include "output.h" | 42 #include "output.h" |
44 #include "typeclass.h" | 43 #include "typeclass.h" |
45 #include "toplev.h" | 44 #include "toplev.h" |
46 #include "ggc.h" | |
47 #include "langhooks.h" | 45 #include "langhooks.h" |
48 #include "intl.h" | 46 #include "intl.h" |
49 #include "tm_p.h" | 47 #include "tm_p.h" |
50 #include "tree-iterator.h" | 48 #include "tree-iterator.h" |
51 #include "tree-pass.h" | 49 #include "tree-pass.h" |
772 | 770 |
773 if (unsignedp && GET_MODE_CLASS (mode) == MODE_INT | 771 if (unsignedp && GET_MODE_CLASS (mode) == MODE_INT |
774 && GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT | 772 && GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT |
775 && CONST_INT_P (x) && INTVAL (x) < 0) | 773 && CONST_INT_P (x) && INTVAL (x) < 0) |
776 { | 774 { |
777 HOST_WIDE_INT val = INTVAL (x); | 775 double_int val = uhwi_to_double_int (INTVAL (x)); |
778 | 776 |
779 if (oldmode != VOIDmode | 777 /* We need to zero extend VAL. */ |
780 && HOST_BITS_PER_WIDE_INT > GET_MODE_BITSIZE (oldmode)) | 778 if (oldmode != VOIDmode) |
781 { | 779 val = double_int_zext (val, GET_MODE_BITSIZE (oldmode)); |
782 int width = GET_MODE_BITSIZE (oldmode); | 780 |
783 | 781 return immed_double_int_const (val, mode); |
784 /* We need to zero extend VAL. */ | |
785 val &= ((HOST_WIDE_INT) 1 << width) - 1; | |
786 } | |
787 | |
788 return immed_double_const (val, (HOST_WIDE_INT) 0, mode); | |
789 } | 782 } |
790 | 783 |
791 /* We can do this with a gen_lowpart if both desired and current modes | 784 /* We can do this with a gen_lowpart if both desired and current modes |
792 are integer, and this is either a constant integer, a register, or a | 785 are integer, and this is either a constant integer, a register, or a |
793 non-volatile MEM. Except for the constant case where MODE is no | 786 non-volatile MEM. Except for the constant case where MODE is no |
1260 | 1253 |
1261 /* If registers go on the stack anyway, any argument is sure to clobber | 1254 /* If registers go on the stack anyway, any argument is sure to clobber |
1262 an outgoing argument. */ | 1255 an outgoing argument. */ |
1263 #if defined (REG_PARM_STACK_SPACE) | 1256 #if defined (REG_PARM_STACK_SPACE) |
1264 fn = emit_block_move_libcall_fn (false); | 1257 fn = emit_block_move_libcall_fn (false); |
1258 /* Avoid set but not used warning if *REG_PARM_STACK_SPACE doesn't | |
1259 depend on its argument. */ | |
1260 (void) fn; | |
1265 if (OUTGOING_REG_PARM_STACK_SPACE ((!fn ? NULL_TREE : TREE_TYPE (fn))) | 1261 if (OUTGOING_REG_PARM_STACK_SPACE ((!fn ? NULL_TREE : TREE_TYPE (fn))) |
1266 && REG_PARM_STACK_SPACE (fn) != 0) | 1262 && REG_PARM_STACK_SPACE (fn) != 0) |
1267 return false; | 1263 return false; |
1268 #endif | 1264 #endif |
1269 | 1265 |
4430 } | 4426 } |
4431 | 4427 |
4432 /* In case we are returning the contents of an object which overlaps | 4428 /* In case we are returning the contents of an object which overlaps |
4433 the place the value is being stored, use a safe function when copying | 4429 the place the value is being stored, use a safe function when copying |
4434 a value through a pointer into a structure value return block. */ | 4430 a value through a pointer into a structure value return block. */ |
4435 if (TREE_CODE (to) == RESULT_DECL && TREE_CODE (from) == INDIRECT_REF | 4431 if (TREE_CODE (to) == RESULT_DECL |
4432 && TREE_CODE (from) == INDIRECT_REF | |
4436 && ADDR_SPACE_GENERIC_P | 4433 && ADDR_SPACE_GENERIC_P |
4437 (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (from, 0))))) | 4434 (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (from, 0))))) |
4435 && refs_may_alias_p (to, from) | |
4438 && cfun->returns_struct | 4436 && cfun->returns_struct |
4439 && !cfun->returns_pcc_struct) | 4437 && !cfun->returns_pcc_struct) |
4440 { | 4438 { |
4441 rtx from_rtx, size; | 4439 rtx from_rtx, size; |
4442 | 4440 |
4549 | 4547 |
4550 rtx lab1 = gen_label_rtx (), lab2 = gen_label_rtx (); | 4548 rtx lab1 = gen_label_rtx (), lab2 = gen_label_rtx (); |
4551 | 4549 |
4552 do_pending_stack_adjust (); | 4550 do_pending_stack_adjust (); |
4553 NO_DEFER_POP; | 4551 NO_DEFER_POP; |
4554 jumpifnot (TREE_OPERAND (exp, 0), lab1); | 4552 jumpifnot (TREE_OPERAND (exp, 0), lab1, -1); |
4555 store_expr (TREE_OPERAND (exp, 1), target, call_param_p, | 4553 store_expr (TREE_OPERAND (exp, 1), target, call_param_p, |
4556 nontemporal); | 4554 nontemporal); |
4557 emit_jump_insn (gen_jump (lab2)); | 4555 emit_jump_insn (gen_jump (lab2)); |
4558 emit_barrier (); | 4556 emit_barrier (); |
4559 emit_label (lab1); | 4557 emit_label (lab1); |
4854 nz_elts = 0; | 4852 nz_elts = 0; |
4855 elt_count = 0; | 4853 elt_count = 0; |
4856 | 4854 |
4857 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value) | 4855 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value) |
4858 { | 4856 { |
4859 HOST_WIDE_INT mult; | 4857 HOST_WIDE_INT mult = 1; |
4860 | 4858 |
4861 mult = 1; | |
4862 if (TREE_CODE (purpose) == RANGE_EXPR) | 4859 if (TREE_CODE (purpose) == RANGE_EXPR) |
4863 { | 4860 { |
4864 tree lo_index = TREE_OPERAND (purpose, 0); | 4861 tree lo_index = TREE_OPERAND (purpose, 0); |
4865 tree hi_index = TREE_OPERAND (purpose, 1); | 4862 tree hi_index = TREE_OPERAND (purpose, 1); |
4866 | 4863 |
4918 } | 4915 } |
4919 } | 4916 } |
4920 break; | 4917 break; |
4921 | 4918 |
4922 default: | 4919 default: |
4923 nz_elts += mult; | 4920 { |
4924 elt_count += mult; | 4921 HOST_WIDE_INT tc = count_type_elements (TREE_TYPE (value), true); |
4925 | 4922 if (tc < 1) |
4926 if (const_from_elts_p && const_p) | 4923 tc = 1; |
4927 const_p = initializer_constant_valid_p (value, TREE_TYPE (value)) | 4924 nz_elts += mult * tc; |
4928 != NULL_TREE; | 4925 elt_count += mult * tc; |
4926 | |
4927 if (const_from_elts_p && const_p) | |
4928 const_p = initializer_constant_valid_p (value, TREE_TYPE (value)) | |
4929 != NULL_TREE; | |
4930 } | |
4929 break; | 4931 break; |
4930 } | 4932 } |
4931 } | 4933 } |
4932 | 4934 |
4933 if (!*p_must_clear | 4935 if (!*p_must_clear |
5545 store_expr (value, xtarget, 0, false); | 5547 store_expr (value, xtarget, 0, false); |
5546 | 5548 |
5547 /* Generate a conditional jump to exit the loop. */ | 5549 /* Generate a conditional jump to exit the loop. */ |
5548 exit_cond = build2 (LT_EXPR, integer_type_node, | 5550 exit_cond = build2 (LT_EXPR, integer_type_node, |
5549 index, hi_index); | 5551 index, hi_index); |
5550 jumpif (exit_cond, loop_end); | 5552 jumpif (exit_cond, loop_end, -1); |
5551 | 5553 |
5552 /* Update the loop counter, and jump to the head of | 5554 /* Update the loop counter, and jump to the head of |
5553 the loop. */ | 5555 the loop. */ |
5554 expand_assignment (index, | 5556 expand_assignment (index, |
5555 build2 (PLUS_EXPR, TREE_TYPE (index), | 5557 build2 (PLUS_EXPR, TREE_TYPE (index), |
5966 tree offset = size_zero_node; | 5968 tree offset = size_zero_node; |
5967 tree bit_offset = bitsize_zero_node; | 5969 tree bit_offset = bitsize_zero_node; |
5968 | 5970 |
5969 /* First get the mode, signedness, and size. We do this from just the | 5971 /* First get the mode, signedness, and size. We do this from just the |
5970 outermost expression. */ | 5972 outermost expression. */ |
5973 *pbitsize = -1; | |
5971 if (TREE_CODE (exp) == COMPONENT_REF) | 5974 if (TREE_CODE (exp) == COMPONENT_REF) |
5972 { | 5975 { |
5973 tree field = TREE_OPERAND (exp, 1); | 5976 tree field = TREE_OPERAND (exp, 1); |
5974 size_tree = DECL_SIZE (field); | 5977 size_tree = DECL_SIZE (field); |
5975 if (!DECL_BIT_FIELD (field)) | 5978 if (!DECL_BIT_FIELD (field)) |
7171 used the file/line information embedded in the tree nodes rather | 7174 used the file/line information embedded in the tree nodes rather |
7172 than globals. */ | 7175 than globals. */ |
7173 if (cfun && EXPR_HAS_LOCATION (exp)) | 7176 if (cfun && EXPR_HAS_LOCATION (exp)) |
7174 { | 7177 { |
7175 location_t saved_location = input_location; | 7178 location_t saved_location = input_location; |
7179 location_t saved_curr_loc = get_curr_insn_source_location (); | |
7180 tree saved_block = get_curr_insn_block (); | |
7176 input_location = EXPR_LOCATION (exp); | 7181 input_location = EXPR_LOCATION (exp); |
7177 set_curr_insn_source_location (input_location); | 7182 set_curr_insn_source_location (input_location); |
7178 | 7183 |
7179 /* Record where the insns produced belong. */ | 7184 /* Record where the insns produced belong. */ |
7180 set_curr_insn_block (TREE_BLOCK (exp)); | 7185 set_curr_insn_block (TREE_BLOCK (exp)); |
7181 | 7186 |
7182 ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl); | 7187 ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl); |
7183 | 7188 |
7184 input_location = saved_location; | 7189 input_location = saved_location; |
7190 set_curr_insn_block (saved_block); | |
7191 set_curr_insn_source_location (saved_curr_loc); | |
7185 } | 7192 } |
7186 else | 7193 else |
7187 { | 7194 { |
7188 ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl); | 7195 ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl); |
7189 } | 7196 } |
7201 enum machine_mode mode; | 7208 enum machine_mode mode; |
7202 enum tree_code code = ops->code; | 7209 enum tree_code code = ops->code; |
7203 optab this_optab; | 7210 optab this_optab; |
7204 rtx subtarget, original_target; | 7211 rtx subtarget, original_target; |
7205 int ignore; | 7212 int ignore; |
7206 tree subexp0, subexp1; | |
7207 bool reduce_bit_field; | 7213 bool reduce_bit_field; |
7208 gimple subexp0_def, subexp1_def; | 7214 gimple subexp0_def, subexp1_def; |
7209 tree top0, top1; | 7215 tree top0, top1; |
7210 location_t loc = ops->location; | 7216 location_t loc = ops->location; |
7211 tree treeop0, treeop1; | 7217 tree treeop0, treeop1; |
7656 return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1)); | 7662 return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1)); |
7657 } | 7663 } |
7658 | 7664 |
7659 goto binop2; | 7665 goto binop2; |
7660 | 7666 |
7661 case MULT_EXPR: | 7667 case WIDEN_MULT_EXPR: |
7662 /* If this is a fixed-point operation, then we cannot use the code | |
7663 below because "expand_mult" doesn't support sat/no-sat fixed-point | |
7664 multiplications. */ | |
7665 if (ALL_FIXED_POINT_MODE_P (mode)) | |
7666 goto binop; | |
7667 | |
7668 /* If first operand is constant, swap them. | 7668 /* If first operand is constant, swap them. |
7669 Thus the following special case checks need only | 7669 Thus the following special case checks need only |
7670 check the second operand. */ | 7670 check the second operand. */ |
7671 if (TREE_CODE (treeop0) == INTEGER_CST) | 7671 if (TREE_CODE (treeop0) == INTEGER_CST) |
7672 { | 7672 { |
7673 tree t1 = treeop0; | 7673 tree t1 = treeop0; |
7674 treeop0 = treeop1; | 7674 treeop0 = treeop1; |
7675 treeop1 = t1; | 7675 treeop1 = t1; |
7676 } | 7676 } |
7677 | 7677 |
7678 /* Attempt to return something suitable for generating an | |
7679 indexed address, for machines that support that. */ | |
7680 | |
7681 if (modifier == EXPAND_SUM && mode == ptr_mode | |
7682 && host_integerp (treeop1, 0)) | |
7683 { | |
7684 tree exp1 = treeop1; | |
7685 | |
7686 op0 = expand_expr (treeop0, subtarget, VOIDmode, | |
7687 EXPAND_SUM); | |
7688 | |
7689 if (!REG_P (op0)) | |
7690 op0 = force_operand (op0, NULL_RTX); | |
7691 if (!REG_P (op0)) | |
7692 op0 = copy_to_mode_reg (mode, op0); | |
7693 | |
7694 return REDUCE_BIT_FIELD (gen_rtx_MULT (mode, op0, | |
7695 gen_int_mode (tree_low_cst (exp1, 0), | |
7696 TYPE_MODE (TREE_TYPE (exp1))))); | |
7697 } | |
7698 | |
7699 if (modifier == EXPAND_STACK_PARM) | |
7700 target = 0; | |
7701 | |
7702 /* Check for multiplying things that have been extended | |
7703 from a narrower type. If this machine supports multiplying | |
7704 in that narrower type with a result in the desired type, | |
7705 do it that way, and avoid the explicit type-conversion. */ | |
7706 | |
7707 subexp0 = treeop0; | |
7708 subexp1 = treeop1; | |
7709 subexp0_def = get_def_for_expr (subexp0, NOP_EXPR); | |
7710 subexp1_def = get_def_for_expr (subexp1, NOP_EXPR); | |
7711 top0 = top1 = NULL_TREE; | |
7712 | |
7713 /* First, check if we have a multiplication of one signed and one | 7678 /* First, check if we have a multiplication of one signed and one |
7714 unsigned operand. */ | 7679 unsigned operand. */ |
7715 if (subexp0_def | 7680 if (TREE_CODE (treeop1) != INTEGER_CST |
7716 && (top0 = gimple_assign_rhs1 (subexp0_def)) | 7681 && (TYPE_UNSIGNED (TREE_TYPE (treeop0)) |
7717 && subexp1_def | 7682 != TYPE_UNSIGNED (TREE_TYPE (treeop1)))) |
7718 && (top1 = gimple_assign_rhs1 (subexp1_def)) | 7683 { |
7719 && TREE_CODE (type) == INTEGER_TYPE | 7684 enum machine_mode innermode = TYPE_MODE (TREE_TYPE (treeop0)); |
7720 && (TYPE_PRECISION (TREE_TYPE (top0)) | |
7721 < TYPE_PRECISION (TREE_TYPE (subexp0))) | |
7722 && (TYPE_PRECISION (TREE_TYPE (top0)) | |
7723 == TYPE_PRECISION (TREE_TYPE (top1))) | |
7724 && (TYPE_UNSIGNED (TREE_TYPE (top0)) | |
7725 != TYPE_UNSIGNED (TREE_TYPE (top1)))) | |
7726 { | |
7727 enum machine_mode innermode | |
7728 = TYPE_MODE (TREE_TYPE (top0)); | |
7729 this_optab = usmul_widen_optab; | 7685 this_optab = usmul_widen_optab; |
7730 if (mode == GET_MODE_WIDER_MODE (innermode)) | 7686 if (mode == GET_MODE_2XWIDER_MODE (innermode)) |
7731 { | 7687 { |
7732 if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing) | 7688 if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing) |
7733 { | 7689 { |
7734 if (TYPE_UNSIGNED (TREE_TYPE (top0))) | 7690 if (TYPE_UNSIGNED (TREE_TYPE (treeop0))) |
7735 expand_operands (top0, top1, NULL_RTX, &op0, &op1, | 7691 expand_operands (treeop0, treeop1, subtarget, &op0, &op1, |
7736 EXPAND_NORMAL); | 7692 EXPAND_NORMAL); |
7737 else | 7693 else |
7738 expand_operands (top0, top1, NULL_RTX, &op1, &op0, | 7694 expand_operands (treeop0, treeop1, subtarget, &op1, &op0, |
7739 EXPAND_NORMAL); | 7695 EXPAND_NORMAL); |
7740 | |
7741 goto binop3; | 7696 goto binop3; |
7742 } | 7697 } |
7743 } | 7698 } |
7744 } | 7699 } |
7745 /* Check for a multiplication with matching signedness. If | 7700 /* Check for a multiplication with matching signedness. */ |
7746 valid, TOP0 and TOP1 were set in the previous if | 7701 else if ((TREE_CODE (treeop1) == INTEGER_CST |
7747 condition. */ | 7702 && int_fits_type_p (treeop1, TREE_TYPE (treeop0))) |
7748 else if (top0 | 7703 || (TYPE_UNSIGNED (TREE_TYPE (treeop1)) |
7749 && TREE_CODE (type) == INTEGER_TYPE | 7704 == TYPE_UNSIGNED (TREE_TYPE (treeop0)))) |
7750 && (TYPE_PRECISION (TREE_TYPE (top0)) | 7705 { |
7751 < TYPE_PRECISION (TREE_TYPE (subexp0))) | 7706 tree op0type = TREE_TYPE (treeop0); |
7752 && ((TREE_CODE (subexp1) == INTEGER_CST | |
7753 && int_fits_type_p (subexp1, TREE_TYPE (top0)) | |
7754 /* Don't use a widening multiply if a shift will do. */ | |
7755 && ((GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (subexp1))) | |
7756 > HOST_BITS_PER_WIDE_INT) | |
7757 || exact_log2 (TREE_INT_CST_LOW (subexp1)) < 0)) | |
7758 || | |
7759 (top1 | |
7760 && (TYPE_PRECISION (TREE_TYPE (top1)) | |
7761 == TYPE_PRECISION (TREE_TYPE (top0)) | |
7762 /* If both operands are extended, they must either both | |
7763 be zero-extended or both be sign-extended. */ | |
7764 && (TYPE_UNSIGNED (TREE_TYPE (top1)) | |
7765 == TYPE_UNSIGNED (TREE_TYPE (top0))))))) | |
7766 { | |
7767 tree op0type = TREE_TYPE (top0); | |
7768 enum machine_mode innermode = TYPE_MODE (op0type); | 7707 enum machine_mode innermode = TYPE_MODE (op0type); |
7769 bool zextend_p = TYPE_UNSIGNED (op0type); | 7708 bool zextend_p = TYPE_UNSIGNED (op0type); |
7770 optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab; | 7709 optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab; |
7771 this_optab = zextend_p ? umul_widen_optab : smul_widen_optab; | 7710 this_optab = zextend_p ? umul_widen_optab : smul_widen_optab; |
7772 | 7711 |
7773 if (mode == GET_MODE_2XWIDER_MODE (innermode)) | 7712 if (mode == GET_MODE_2XWIDER_MODE (innermode)) |
7774 { | 7713 { |
7775 if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing) | 7714 if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing) |
7776 { | 7715 { |
7777 if (TREE_CODE (subexp1) == INTEGER_CST) | 7716 expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, |
7778 expand_operands (top0, subexp1, NULL_RTX, &op0, &op1, | 7717 EXPAND_NORMAL); |
7779 EXPAND_NORMAL); | 7718 temp = expand_widening_mult (mode, op0, op1, target, |
7780 else | 7719 unsignedp, this_optab); |
7781 expand_operands (top0, top1, NULL_RTX, &op0, &op1, | 7720 return REDUCE_BIT_FIELD (temp); |
7782 EXPAND_NORMAL); | |
7783 goto binop3; | |
7784 } | 7721 } |
7785 else if (optab_handler (other_optab, mode)->insn_code != CODE_FOR_nothing | 7722 if (optab_handler (other_optab, mode)->insn_code != CODE_FOR_nothing |
7786 && innermode == word_mode) | 7723 && innermode == word_mode) |
7787 { | 7724 { |
7788 rtx htem, hipart; | 7725 rtx htem, hipart; |
7789 op0 = expand_normal (top0); | 7726 op0 = expand_normal (treeop0); |
7790 if (TREE_CODE (subexp1) == INTEGER_CST) | 7727 if (TREE_CODE (treeop1) == INTEGER_CST) |
7791 op1 = convert_modes (innermode, mode, | 7728 op1 = convert_modes (innermode, mode, |
7792 expand_normal (subexp1), unsignedp); | 7729 expand_normal (treeop1), unsignedp); |
7793 else | 7730 else |
7794 op1 = expand_normal (top1); | 7731 op1 = expand_normal (treeop1); |
7795 temp = expand_binop (mode, other_optab, op0, op1, target, | 7732 temp = expand_binop (mode, other_optab, op0, op1, target, |
7796 unsignedp, OPTAB_LIB_WIDEN); | 7733 unsignedp, OPTAB_LIB_WIDEN); |
7797 hipart = gen_highpart (innermode, temp); | 7734 hipart = gen_highpart (innermode, temp); |
7798 htem = expand_mult_highpart_adjust (innermode, hipart, | 7735 htem = expand_mult_highpart_adjust (innermode, hipart, |
7799 op0, op1, hipart, | 7736 op0, op1, hipart, |
7802 emit_move_insn (hipart, htem); | 7739 emit_move_insn (hipart, htem); |
7803 return REDUCE_BIT_FIELD (temp); | 7740 return REDUCE_BIT_FIELD (temp); |
7804 } | 7741 } |
7805 } | 7742 } |
7806 } | 7743 } |
7807 expand_operands (subexp0, subexp1, subtarget, &op0, &op1, EXPAND_NORMAL); | 7744 treeop0 = fold_build1 (CONVERT_EXPR, type, treeop0); |
7745 treeop1 = fold_build1 (CONVERT_EXPR, type, treeop1); | |
7746 expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL); | |
7747 return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp)); | |
7748 | |
7749 case MULT_EXPR: | |
7750 /* If this is a fixed-point operation, then we cannot use the code | |
7751 below because "expand_mult" doesn't support sat/no-sat fixed-point | |
7752 multiplications. */ | |
7753 if (ALL_FIXED_POINT_MODE_P (mode)) | |
7754 goto binop; | |
7755 | |
7756 /* If first operand is constant, swap them. | |
7757 Thus the following special case checks need only | |
7758 check the second operand. */ | |
7759 if (TREE_CODE (treeop0) == INTEGER_CST) | |
7760 { | |
7761 tree t1 = treeop0; | |
7762 treeop0 = treeop1; | |
7763 treeop1 = t1; | |
7764 } | |
7765 | |
7766 /* Attempt to return something suitable for generating an | |
7767 indexed address, for machines that support that. */ | |
7768 | |
7769 if (modifier == EXPAND_SUM && mode == ptr_mode | |
7770 && host_integerp (treeop1, 0)) | |
7771 { | |
7772 tree exp1 = treeop1; | |
7773 | |
7774 op0 = expand_expr (treeop0, subtarget, VOIDmode, | |
7775 EXPAND_SUM); | |
7776 | |
7777 if (!REG_P (op0)) | |
7778 op0 = force_operand (op0, NULL_RTX); | |
7779 if (!REG_P (op0)) | |
7780 op0 = copy_to_mode_reg (mode, op0); | |
7781 | |
7782 return REDUCE_BIT_FIELD (gen_rtx_MULT (mode, op0, | |
7783 gen_int_mode (tree_low_cst (exp1, 0), | |
7784 TYPE_MODE (TREE_TYPE (exp1))))); | |
7785 } | |
7786 | |
7787 if (modifier == EXPAND_STACK_PARM) | |
7788 target = 0; | |
7789 | |
7790 expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL); | |
7808 return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp)); | 7791 return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp)); |
7809 | 7792 |
7810 case TRUNC_DIV_EXPR: | 7793 case TRUNC_DIV_EXPR: |
7811 case FLOOR_DIV_EXPR: | 7794 case FLOOR_DIV_EXPR: |
7812 case CEIL_DIV_EXPR: | 7795 case CEIL_DIV_EXPR: |
8010 if (target != op0) | 7993 if (target != op0) |
8011 emit_move_insn (target, op0); | 7994 emit_move_insn (target, op0); |
8012 | 7995 |
8013 temp = gen_label_rtx (); | 7996 temp = gen_label_rtx (); |
8014 do_compare_rtx_and_jump (target, cmpop1, comparison_code, | 7997 do_compare_rtx_and_jump (target, cmpop1, comparison_code, |
8015 unsignedp, mode, NULL_RTX, NULL_RTX, temp); | 7998 unsignedp, mode, NULL_RTX, NULL_RTX, temp, |
7999 -1); | |
8016 } | 8000 } |
8017 emit_move_insn (target, op1); | 8001 emit_move_insn (target, op1); |
8018 emit_label (temp); | 8002 emit_label (temp); |
8019 return target; | 8003 return target; |
8020 | 8004 |
8118 target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode); | 8102 target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode); |
8119 | 8103 |
8120 emit_move_insn (target, const0_rtx); | 8104 emit_move_insn (target, const0_rtx); |
8121 | 8105 |
8122 op1 = gen_label_rtx (); | 8106 op1 = gen_label_rtx (); |
8123 jumpifnot_1 (code, treeop0, treeop1, op1); | 8107 jumpifnot_1 (code, treeop0, treeop1, op1, -1); |
8124 | 8108 |
8125 emit_move_insn (target, const1_rtx); | 8109 emit_move_insn (target, const1_rtx); |
8126 | 8110 |
8127 emit_label (op1); | 8111 emit_label (op1); |
8128 return target; | 8112 return target; |
8403 if (!currently_expanding_to_rtl) | 8387 if (!currently_expanding_to_rtl) |
8404 return expand_expr_real_1 (SSA_NAME_VAR (exp), target, tmode, modifier, NULL); | 8388 return expand_expr_real_1 (SSA_NAME_VAR (exp), target, tmode, modifier, NULL); |
8405 { | 8389 { |
8406 gimple g = get_gimple_for_ssa_name (exp); | 8390 gimple g = get_gimple_for_ssa_name (exp); |
8407 if (g) | 8391 if (g) |
8408 return expand_expr_real_1 (gimple_assign_rhs_to_tree (g), target, | 8392 return expand_expr_real (gimple_assign_rhs_to_tree (g), target, |
8409 tmode, modifier, NULL); | 8393 tmode, modifier, NULL); |
8410 } | 8394 } |
8411 decl_rtl = get_rtx_for_ssa_name (exp); | 8395 decl_rtl = get_rtx_for_ssa_name (exp); |
8412 exp = SSA_NAME_VAR (exp); | 8396 exp = SSA_NAME_VAR (exp); |
8413 goto expand_decl_rtl; | 8397 goto expand_decl_rtl; |
8414 | 8398 |
8720 | 8704 |
8721 case TARGET_MEM_REF: | 8705 case TARGET_MEM_REF: |
8722 { | 8706 { |
8723 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp)); | 8707 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp)); |
8724 struct mem_address addr; | 8708 struct mem_address addr; |
8709 tree base; | |
8725 | 8710 |
8726 get_address_description (exp, &addr); | 8711 get_address_description (exp, &addr); |
8727 op0 = addr_for_mem_ref (&addr, as, true); | 8712 op0 = addr_for_mem_ref (&addr, as, true); |
8728 op0 = memory_address_addr_space (mode, op0, as); | 8713 op0 = memory_address_addr_space (mode, op0, as); |
8729 temp = gen_rtx_MEM (mode, op0); | 8714 temp = gen_rtx_MEM (mode, op0); |
8730 set_mem_attributes (temp, TMR_ORIGINAL (exp), 0); | 8715 set_mem_attributes (temp, TMR_ORIGINAL (exp), 0); |
8731 set_mem_addr_space (temp, as); | 8716 set_mem_addr_space (temp, as); |
8717 base = get_base_address (TMR_ORIGINAL (exp)); | |
8718 if (INDIRECT_REF_P (base) | |
8719 && TMR_BASE (exp) | |
8720 && TREE_CODE (TMR_BASE (exp)) == SSA_NAME | |
8721 && POINTER_TYPE_P (TREE_TYPE (TMR_BASE (exp)))) | |
8722 { | |
8723 set_mem_expr (temp, build1 (INDIRECT_REF, | |
8724 TREE_TYPE (exp), TMR_BASE (exp))); | |
8725 set_mem_offset (temp, NULL_RTX); | |
8726 } | |
8732 } | 8727 } |
8733 return temp; | 8728 return temp; |
8734 | 8729 |
8735 case ARRAY_REF: | 8730 case ARRAY_REF: |
8736 | 8731 |
9325 { | 9320 { |
9326 if (GET_CODE (op0) == SUBREG) | 9321 if (GET_CODE (op0) == SUBREG) |
9327 op0 = force_reg (GET_MODE (op0), op0); | 9322 op0 = force_reg (GET_MODE (op0), op0); |
9328 op0 = gen_lowpart (mode, op0); | 9323 op0 = gen_lowpart (mode, op0); |
9329 } | 9324 } |
9330 /* If both modes are integral, then we can convert from one to the | 9325 /* If both types are integral, convert from one mode to the other. */ |
9331 other. */ | 9326 else if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (TREE_TYPE (treeop0))) |
9332 else if (SCALAR_INT_MODE_P (GET_MODE (op0)) && SCALAR_INT_MODE_P (mode)) | |
9333 op0 = convert_modes (mode, GET_MODE (op0), op0, | 9327 op0 = convert_modes (mode, GET_MODE (op0), op0, |
9334 TYPE_UNSIGNED (TREE_TYPE (treeop0))); | 9328 TYPE_UNSIGNED (TREE_TYPE (treeop0))); |
9335 /* As a last resort, spill op0 to memory, and reload it in a | 9329 /* As a last resort, spill op0 to memory, and reload it in a |
9336 different mode. */ | 9330 different mode. */ |
9337 else if (!MEM_P (op0)) | 9331 else if (!MEM_P (op0)) |
9415 | 9409 |
9416 if (target) | 9410 if (target) |
9417 emit_move_insn (target, const0_rtx); | 9411 emit_move_insn (target, const0_rtx); |
9418 | 9412 |
9419 op1 = gen_label_rtx (); | 9413 op1 = gen_label_rtx (); |
9420 jumpifnot_1 (code, treeop0, treeop1, op1); | 9414 jumpifnot_1 (code, treeop0, treeop1, op1, -1); |
9421 | 9415 |
9422 if (target) | 9416 if (target) |
9423 emit_move_insn (target, const1_rtx); | 9417 emit_move_insn (target, const1_rtx); |
9424 | 9418 |
9425 emit_label (op1); | 9419 emit_label (op1); |
9472 | 9466 |
9473 do_pending_stack_adjust (); | 9467 do_pending_stack_adjust (); |
9474 NO_DEFER_POP; | 9468 NO_DEFER_POP; |
9475 op0 = gen_label_rtx (); | 9469 op0 = gen_label_rtx (); |
9476 op1 = gen_label_rtx (); | 9470 op1 = gen_label_rtx (); |
9477 jumpifnot (treeop0, op0); | 9471 jumpifnot (treeop0, op0, -1); |
9478 store_expr (treeop1, temp, | 9472 store_expr (treeop1, temp, |
9479 modifier == EXPAND_STACK_PARM, | 9473 modifier == EXPAND_STACK_PARM, |
9480 false); | 9474 false); |
9481 | 9475 |
9482 emit_jump_insn (gen_jump (op1)); | 9476 emit_jump_insn (gen_jump (op1)); |
9518 { | 9512 { |
9519 rtx label = gen_label_rtx (); | 9513 rtx label = gen_label_rtx (); |
9520 int value = TREE_CODE (rhs) == BIT_IOR_EXPR; | 9514 int value = TREE_CODE (rhs) == BIT_IOR_EXPR; |
9521 do_jump (TREE_OPERAND (rhs, 1), | 9515 do_jump (TREE_OPERAND (rhs, 1), |
9522 value ? label : 0, | 9516 value ? label : 0, |
9523 value ? 0 : label); | 9517 value ? 0 : label, -1); |
9524 expand_assignment (lhs, build_int_cst (TREE_TYPE (rhs), value), | 9518 expand_assignment (lhs, build_int_cst (TREE_TYPE (rhs), value), |
9525 MOVE_NONTEMPORAL (exp)); | 9519 MOVE_NONTEMPORAL (exp)); |
9526 do_pending_stack_adjust (); | 9520 do_pending_stack_adjust (); |
9527 emit_label (label); | 9521 emit_label (label); |
9528 return const0_rtx; | 9522 return const0_rtx; |
9658 tree t = build_int_cst_type (type, value); | 9652 tree t = build_int_cst_type (type, value); |
9659 return expand_expr (t, target, VOIDmode, EXPAND_NORMAL); | 9653 return expand_expr (t, target, VOIDmode, EXPAND_NORMAL); |
9660 } | 9654 } |
9661 else if (TYPE_UNSIGNED (type)) | 9655 else if (TYPE_UNSIGNED (type)) |
9662 { | 9656 { |
9663 rtx mask; | 9657 rtx mask = immed_double_int_const (double_int_mask (prec), |
9664 if (prec < HOST_BITS_PER_WIDE_INT) | 9658 GET_MODE (exp)); |
9665 mask = immed_double_const (((unsigned HOST_WIDE_INT) 1 << prec) - 1, 0, | |
9666 GET_MODE (exp)); | |
9667 else | |
9668 mask = immed_double_const ((unsigned HOST_WIDE_INT) -1, | |
9669 ((unsigned HOST_WIDE_INT) 1 | |
9670 << (prec - HOST_BITS_PER_WIDE_INT)) - 1, | |
9671 GET_MODE (exp)); | |
9672 return expand_and (GET_MODE (exp), exp, mask, target); | 9659 return expand_and (GET_MODE (exp), exp, mask, target); |
9673 } | 9660 } |
9674 else | 9661 else |
9675 { | 9662 { |
9676 tree count = build_int_cst (NULL_TREE, | 9663 tree count = build_int_cst (NULL_TREE, |
10252 inner); | 10239 inner); |
10253 else if (TREE_CODE (elt) == FIXED_CST) | 10240 else if (TREE_CODE (elt) == FIXED_CST) |
10254 RTVEC_ELT (v, i) = CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (elt), | 10241 RTVEC_ELT (v, i) = CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (elt), |
10255 inner); | 10242 inner); |
10256 else | 10243 else |
10257 RTVEC_ELT (v, i) = immed_double_const (TREE_INT_CST_LOW (elt), | 10244 RTVEC_ELT (v, i) = immed_double_int_const (tree_to_double_int (elt), |
10258 TREE_INT_CST_HIGH (elt), | 10245 inner); |
10259 inner); | |
10260 } | 10246 } |
10261 | 10247 |
10262 /* Initialize remaining elements to 0. */ | 10248 /* Initialize remaining elements to 0. */ |
10263 for (; i < units; ++i) | 10249 for (; i < units; ++i) |
10264 RTVEC_ELT (v, i) = CONST0_RTX (inner); | 10250 RTVEC_ELT (v, i) = CONST0_RTX (inner); |