From: Alexandre Oliva Date: Thu, 12 Apr 2001 03:41:36 +0000 (+0000) Subject: expmed.c (store_bit_field): Truncate CONST_INTs. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=691073076ba2bdceb294db095293a0453489ab0f;p=gcc.git expmed.c (store_bit_field): Truncate CONST_INTs. * expmed.c (store_bit_field): Truncate CONST_INTs. (expand_mult_highpart, expand_divmod): Likewise. * expr.c (convert_modes, store_field): Likewise. * integrate.c (expand_inline_function): Use promote_mode() to determine whether to convert_modes() an argument as signed or unsigned. * optabs.c (expand_binop): Get CONST_INT operands sign-extended for their appropriate modes. * stmt.c (emit_case_nodes): Convert node values to the appropriate mode. (expand_end_case): Convert minval and range to the appropriate mode. * unroll.c (loop_iterations): Truncate abs_diff to the mode of the iteration variable. * varasm.c (immed_double_const): Don't require words to be narrower than host wide ints to properly sign-extend CONST_INTs. From-SVN: r41285 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a8af9d1b6a3..83ec61933ce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2001-04-12 Alexandre Oliva + + * expmed.c (store_bit_field): Truncate CONST_INTs. + (expand_mult_highpart, expand_divmod): Likewise. + * expr.c (convert_modes, store_field): Likewise. + * integrate.c (expand_inline_function): Use promote_mode() to + determine whether to convert_modes() an argument as signed + or unsigned. + * optabs.c (expand_binop): Get CONST_INT operands + sign-extended for their appropriate modes. + * stmt.c (emit_case_nodes): Convert node values to the + appropriate mode. + (expand_end_case): Convert minval and range to the appropriate + mode. + * unroll.c (loop_iterations): Truncate abs_diff to the mode of + the iteration variable. + * varasm.c (immed_double_const): Don't require words to be + narrower than host wide ints to properly sign-extend + CONST_INTs. + 2001-04-12 kaz Kojima * sh.md (builtin_setjmp_receiver): New expander. diff --git a/gcc/expmed.c b/gcc/expmed.c index a7684508b5b..b2396ae9bd9 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -592,6 +592,8 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size) else value1 = gen_lowpart (maxmode, value1); } + else if (GET_CODE (value) == CONST_INT) + value1 = GEN_INT (trunc_int_for_mode (INTVAL (value), maxmode)); else if (!CONSTANT_P (value)) /* Parse phase is supposed to make VALUE's data type match that of the component reference, which is a type @@ -2787,7 +2789,7 @@ expand_mult_highpart (mode, op0, cnst1, target, unsignedp, max_cost) if (size > HOST_BITS_PER_WIDE_INT) abort (); - op1 = GEN_INT (cnst1); + op1 = GEN_INT (trunc_int_for_mode (cnst1, mode)); if (GET_MODE_BITSIZE (wider_mode) <= HOST_BITS_PER_INT) wide_op1 = op1; @@ -3274,7 +3276,7 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp) if (rem_flag && d < 0) { d = abs_d; - op1 = GEN_INT (abs_d); + op1 = GEN_INT (trunc_int_for_mode (abs_d, compute_mode)); } if (d == 1) @@ -3304,7 +3306,8 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp) t1 = copy_to_mode_reg (compute_mode, op0); do_cmp_and_jump (t1, const0_rtx, GE, compute_mode, label); - expand_inc (t1, GEN_INT (abs_d - 1)); + expand_inc (t1, GEN_INT (trunc_int_for_mode + (abs_d - 1, compute_mode))); emit_label (label); quotient = expand_shift (RSHIFT_EXPR, compute_mode, t1, build_int_2 (lgup, 0), @@ -3341,7 +3344,10 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp) REG_EQUAL, gen_rtx_DIV (compute_mode, op0, - GEN_INT (abs_d))); + GEN_INT + (trunc_int_for_mode + (abs_d, + compute_mode)))); quotient = expand_unop (compute_mode, neg_optab, quotient, quotient, 0); @@ -3840,8 +3846,10 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp) ml = invert_mod2n (d >> pre_shift, size); t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0, build_int_2 (pre_shift, 0), NULL_RTX, unsignedp); - quotient = expand_mult (compute_mode, t1, GEN_INT (ml), NULL_RTX, - 0); + quotient = expand_mult (compute_mode, t1, + GEN_INT (trunc_int_for_mode + (ml, compute_mode)), + NULL_RTX, 0); insn = get_last_insn (); set_unique_reg_note (insn, diff --git a/gcc/expr.c b/gcc/expr.c index 7d78acd33ae..970c275cde5 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -1360,7 +1360,7 @@ convert_modes (mode, oldmode, x, unsignedp) && (val & ((HOST_WIDE_INT) 1 << (width - 1)))) val |= (HOST_WIDE_INT) (-1) << width; - return GEN_INT (val); + return GEN_INT (trunc_int_for_mode (val, mode)); } return gen_lowpart (mode, x); @@ -5268,7 +5268,13 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, enum machine_mode tmode; if (unsignedp) - return expand_and (temp, GEN_INT (width_mask), NULL_RTX); + return expand_and (temp, + GEN_INT + (trunc_int_for_mode + (width_mask, + GET_MODE (temp) == VOIDmode + ? value_mode + : GET_MODE (temp))), NULL_RTX); tmode = GET_MODE (temp); if (tmode == VOIDmode) tmode = value_mode; diff --git a/gcc/integrate.c b/gcc/integrate.c index 327e8fa5f25..1955c0511bd 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -702,13 +702,24 @@ expand_inline_function (fndecl, parms, target, ignore, type, else if (GET_CODE (loc) != MEM) { if (GET_MODE (loc) != TYPE_MODE (TREE_TYPE (arg))) - /* The mode if LOC and ARG can differ if LOC was a variable - that had its mode promoted via PROMOTED_MODE. */ - arg_vals[i] = convert_modes (GET_MODE (loc), - TYPE_MODE (TREE_TYPE (arg)), - expand_expr (arg, NULL_RTX, mode, - EXPAND_SUM), - TREE_UNSIGNED (TREE_TYPE (formal))); + { + int unsignedp = TREE_UNSIGNED (TREE_TYPE (formal)); + enum machine_mode pmode = TYPE_MODE (TREE_TYPE (formal)); + + pmode = promote_mode (TREE_TYPE (formal), pmode, + &unsignedp, 0); + + if (GET_MODE (loc) != pmode) + abort (); + + /* The mode if LOC and ARG can differ if LOC was a variable + that had its mode promoted via PROMOTED_MODE. */ + arg_vals[i] = convert_modes (pmode, + TYPE_MODE (TREE_TYPE (arg)), + expand_expr (arg, NULL_RTX, mode, + EXPAND_SUM), + unsignedp); + } else arg_vals[i] = expand_expr (arg, NULL_RTX, mode, EXPAND_SUM); } diff --git a/gcc/optabs.c b/gcc/optabs.c index 0be8d6a6bce..4f30779ec43 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -723,17 +723,25 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods) } /* In case the insn wants input operands in modes different from - the result, convert the operands. */ + the result, convert the operands. It would seem that we + don't need to convert CONST_INTs, but we do, so that they're + a properly sign-extended for their modes. */ - if (GET_MODE (op0) != VOIDmode - && GET_MODE (op0) != mode0 + if (GET_MODE (op0) != mode0 && mode0 != VOIDmode) - xop0 = convert_to_mode (mode0, xop0, unsignedp); + xop0 = convert_modes (mode0, + GET_MODE (op0) != VOIDmode + ? GET_MODE (op0) + : mode0, + xop0, unsignedp); - if (GET_MODE (xop1) != VOIDmode - && GET_MODE (xop1) != mode1 + if (GET_MODE (xop1) != mode1 && mode1 != VOIDmode) - xop1 = convert_to_mode (mode1, xop1, unsignedp); + xop1 = convert_modes (mode1, + GET_MODE (op1) != VOIDmode + ? GET_MODE (op1) + : mode1, + xop1, unsignedp); /* Now, if insn's predicates don't allow our operands, put them into pseudo regs. */ @@ -4295,7 +4303,9 @@ expand_fix (to, from, unsignedp) NULL_RTX, 0, OPTAB_LIB_WIDEN); expand_fix (to, target, 0); target = expand_binop (GET_MODE (to), xor_optab, to, - GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)), + GEN_INT (trunc_int_for_mode + ((HOST_WIDE_INT) 1 << (bitsize - 1), + GET_MODE (to))), to, 1, OPTAB_LIB_WIDEN); if (target != to) diff --git a/gcc/stmt.c b/gcc/stmt.c index e9c49dcffd4..9b706061217 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -1,6 +1,6 @@ /* Expands front end tree to back end RTL for GNU C-Compiler Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000 Free Software Foundation, Inc. + 1998, 1999, 2000, 2001 Free Software Foundation, Inc. This file is part of GNU CC. @@ -5474,6 +5474,8 @@ expand_end_case (orig_index) op1 = expand_expr (minval, NULL_RTX, VOIDmode, 0); op_mode = insn_data[(int) CODE_FOR_casesi].operand[1].mode; + op1 = convert_modes (op_mode, TYPE_MODE (TREE_TYPE (minval)), + op1, TREE_UNSIGNED (TREE_TYPE (minval))); if (! (*insn_data[(int) CODE_FOR_casesi].operand[1].predicate) (op1, op_mode)) op1 = copy_to_mode_reg (op_mode, op1); @@ -5481,6 +5483,8 @@ expand_end_case (orig_index) op2 = expand_expr (range, NULL_RTX, VOIDmode, 0); op_mode = insn_data[(int) CODE_FOR_casesi].operand[2].mode; + op2 = convert_modes (op_mode, TYPE_MODE (TREE_TYPE (range)), + op2, TREE_UNSIGNED (TREE_TYPE (range))); if (! (*insn_data[(int) CODE_FOR_casesi].operand[2].predicate) (op2, op_mode)) op2 = copy_to_mode_reg (op_mode, op2); @@ -5503,7 +5507,11 @@ expand_end_case (orig_index) do_pending_stack_adjust (); do_tablejump (index, TYPE_MODE (index_type), - expand_expr (range, NULL_RTX, VOIDmode, 0), + convert_modes (TYPE_MODE (index_type), + TYPE_MODE (TREE_TYPE (range)), + expand_expr (range, NULL_RTX, + VOIDmode, 0), + TREE_UNSIGNED (TREE_TYPE (range))), table_label, default_label); win = 1; } @@ -6027,6 +6035,7 @@ emit_case_nodes (index, node, default_label, index_type) /* If INDEX has an unsigned type, we must make unsigned branches. */ int unsignedp = TREE_UNSIGNED (index_type); enum machine_mode mode = GET_MODE (index); + enum machine_mode imode = TYPE_MODE (index_type); /* See if our parents have already tested everything for us. If they have, emit an unconditional jump for this node. */ @@ -6038,7 +6047,11 @@ emit_case_nodes (index, node, default_label, index_type) /* Node is single valued. First see if the index expression matches this node and then check our children, if any. */ - do_jump_if_equal (index, expand_expr (node->low, NULL_RTX, VOIDmode, 0), + do_jump_if_equal (index, + convert_modes (mode, imode, + expand_expr (node->low, NULL_RTX, + VOIDmode, 0), + unsignedp), label_rtx (node->code_label), unsignedp); if (node->right != 0 && node->left != 0) @@ -6052,8 +6065,11 @@ emit_case_nodes (index, node, default_label, index_type) if (node_is_bounded (node->right, index_type)) { emit_cmp_and_jump_insns (index, - expand_expr (node->high, NULL_RTX, - VOIDmode, 0), + convert_modes + (mode, imode, + expand_expr (node->high, NULL_RTX, + VOIDmode, 0), + unsignedp), GT, NULL_RTX, mode, unsignedp, 0, label_rtx (node->right->code_label)); emit_case_nodes (index, node->left, default_label, index_type); @@ -6062,8 +6078,11 @@ emit_case_nodes (index, node, default_label, index_type) else if (node_is_bounded (node->left, index_type)) { emit_cmp_and_jump_insns (index, - expand_expr (node->high, NULL_RTX, - VOIDmode, 0), + convert_modes + (mode, imode, + expand_expr (node->high, NULL_RTX, + VOIDmode, 0), + unsignedp), LT, NULL_RTX, mode, unsignedp, 0, label_rtx (node->left->code_label)); emit_case_nodes (index, node->right, default_label, index_type); @@ -6078,8 +6097,11 @@ emit_case_nodes (index, node, default_label, index_type) /* See if the value is on the right. */ emit_cmp_and_jump_insns (index, - expand_expr (node->high, NULL_RTX, - VOIDmode, 0), + convert_modes + (mode, imode, + expand_expr (node->high, NULL_RTX, + VOIDmode, 0), + unsignedp), GT, NULL_RTX, mode, unsignedp, 0, label_rtx (test_label)); @@ -6110,8 +6132,11 @@ emit_case_nodes (index, node, default_label, index_type) if (!node_has_low_bound (node, index_type)) { emit_cmp_and_jump_insns (index, - expand_expr (node->high, NULL_RTX, - VOIDmode, 0), + convert_modes + (mode, imode, + expand_expr (node->high, NULL_RTX, + VOIDmode, 0), + unsignedp), LT, NULL_RTX, mode, unsignedp, 0, default_label); } @@ -6123,8 +6148,11 @@ emit_case_nodes (index, node, default_label, index_type) since we haven't ruled out the numbers less than this node's value. So handle node->right explicitly. */ do_jump_if_equal (index, - expand_expr (node->right->low, NULL_RTX, - VOIDmode, 0), + convert_modes + (mode, imode, + expand_expr (node->right->low, NULL_RTX, + VOIDmode, 0), + unsignedp), label_rtx (node->right->code_label), unsignedp); } @@ -6150,9 +6178,12 @@ emit_case_nodes (index, node, default_label, index_type) { if (!node_has_high_bound (node, index_type)) { - emit_cmp_and_jump_insns (index, expand_expr (node->high, - NULL_RTX, - VOIDmode, 0), + emit_cmp_and_jump_insns (index, + convert_modes + (mode, imode, + expand_expr (node->high, NULL_RTX, + VOIDmode, 0), + unsignedp), GT, NULL_RTX, mode, unsignedp, 0, default_label); } @@ -6164,8 +6195,11 @@ emit_case_nodes (index, node, default_label, index_type) since we haven't ruled out the numbers less than this node's value. So handle node->left explicitly. */ do_jump_if_equal (index, - expand_expr (node->left->low, NULL_RTX, - VOIDmode, 0), + convert_modes + (mode, imode, + expand_expr (node->left->low, NULL_RTX, + VOIDmode, 0), + unsignedp), label_rtx (node->left->code_label), unsignedp); } } @@ -6187,8 +6221,12 @@ emit_case_nodes (index, node, default_label, index_type) if (node_is_bounded (node->right, index_type)) /* Right hand node is fully bounded so we can eliminate any testing and branch directly to the target code. */ - emit_cmp_and_jump_insns (index, expand_expr (node->high, NULL_RTX, - VOIDmode, 0), + emit_cmp_and_jump_insns (index, + convert_modes + (mode, imode, + expand_expr (node->high, NULL_RTX, + VOIDmode, 0), + unsignedp), GT, NULL_RTX, mode, unsignedp, 0, label_rtx (node->right->code_label)); else @@ -6198,16 +6236,23 @@ emit_case_nodes (index, node, default_label, index_type) test_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); emit_cmp_and_jump_insns (index, - expand_expr (node->high, NULL_RTX, - VOIDmode, 0), + convert_modes + (mode, imode, + expand_expr (node->high, NULL_RTX, + VOIDmode, 0), + unsignedp), GT, NULL_RTX, mode, unsignedp, 0, label_rtx (test_label)); } /* Value belongs to this node or to the left-hand subtree. */ - emit_cmp_and_jump_insns (index, expand_expr (node->low, NULL_RTX, - VOIDmode, 0), + emit_cmp_and_jump_insns (index, + convert_modes + (mode, imode, + expand_expr (node->low, NULL_RTX, + VOIDmode, 0), + unsignedp), GE, NULL_RTX, mode, unsignedp, 0, label_rtx (node->code_label)); @@ -6234,16 +6279,23 @@ emit_case_nodes (index, node, default_label, index_type) if (!node_has_low_bound (node, index_type)) { emit_cmp_and_jump_insns (index, - expand_expr (node->low, NULL_RTX, - VOIDmode, 0), + convert_modes + (mode, imode, + expand_expr (node->low, NULL_RTX, + VOIDmode, 0), + unsignedp), LT, NULL_RTX, mode, unsignedp, 0, default_label); } /* Value belongs to this node or to the right-hand subtree. */ - emit_cmp_and_jump_insns (index, expand_expr (node->high, NULL_RTX, - VOIDmode, 0), + emit_cmp_and_jump_insns (index, + convert_modes + (mode, imode, + expand_expr (node->high, NULL_RTX, + VOIDmode, 0), + unsignedp), LE, NULL_RTX, mode, unsignedp, 0, label_rtx (node->code_label)); @@ -6257,8 +6309,11 @@ emit_case_nodes (index, node, default_label, index_type) if (!node_has_high_bound (node, index_type)) { emit_cmp_and_jump_insns (index, - expand_expr (node->high, NULL_RTX, - VOIDmode, 0), + convert_modes + (mode, imode, + expand_expr (node->high, NULL_RTX, + VOIDmode, 0), + unsignedp), GT, NULL_RTX, mode, unsignedp, 0, default_label); } @@ -6266,8 +6321,11 @@ emit_case_nodes (index, node, default_label, index_type) /* Value belongs to this node or to the left-hand subtree. */ emit_cmp_and_jump_insns (index, - expand_expr (node->low, NULL_RTX, - VOIDmode, 0), + convert_modes + (mode, imode, + expand_expr (node->low, NULL_RTX, + VOIDmode, 0), + unsignedp), GE, NULL_RTX, mode, unsignedp, 0, label_rtx (node->code_label)); @@ -6283,8 +6341,11 @@ emit_case_nodes (index, node, default_label, index_type) if (!node_has_high_bound (node, index_type)) { emit_cmp_and_jump_insns (index, - expand_expr (node->high, NULL_RTX, - VOIDmode, 0), + convert_modes + (mode, imode, + expand_expr (node->high, NULL_RTX, + VOIDmode, 0), + unsignedp), GT, NULL_RTX, mode, unsignedp, 0, default_label); } @@ -6292,8 +6353,11 @@ emit_case_nodes (index, node, default_label, index_type) if (!node_has_low_bound (node, index_type)) { emit_cmp_and_jump_insns (index, - expand_expr (node->low, NULL_RTX, - VOIDmode, 0), + convert_modes + (mode, imode, + expand_expr (node->low, NULL_RTX, + VOIDmode, 0), + unsignedp), LT, NULL_RTX, mode, unsignedp, 0, default_label); } diff --git a/gcc/unroll.c b/gcc/unroll.c index 0d3927632b1..52de4996bd4 100644 --- a/gcc/unroll.c +++ b/gcc/unroll.c @@ -3962,6 +3962,8 @@ loop_iterations (loop) else abort (); + abs_diff = trunc_int_for_mode (abs_diff, GET_MODE (iteration_var)); + /* For NE tests, make sure that the iteration variable won't miss the final value. If abs_diff mod abs_incr is not zero, then the iteration variable will overflow before the loop exits, and we diff --git a/gcc/varasm.c b/gcc/varasm.c index 8b14dc88e39..a803fe174ad 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -1984,7 +1984,7 @@ immed_double_const (i0, i1, mode) represented as a 64 bit value -1, and not as 0x00000000ffffffff. The later confuses the sparc backend. */ - if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT && BITS_PER_WORD == width + if (width < HOST_BITS_PER_WIDE_INT && (i0 & ((HOST_WIDE_INT) 1 << (width - 1)))) i0 |= ((HOST_WIDE_INT) (-1) << width);