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
This commit is contained in:
Alexandre Oliva 2001-04-12 03:41:36 +00:00 committed by Alexandre Oliva
parent 001643af80
commit 691073076b
8 changed files with 181 additions and 60 deletions

View File

@ -1,3 +1,23 @@
2001-04-12 Alexandre Oliva <aoliva@redhat.com>
* 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 <kkojima@rr.iij4u.or.jp>
* sh.md (builtin_setjmp_receiver): New expander.

View File

@ -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,

View File

@ -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;

View File

@ -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);
}

View File

@ -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)

View File

@ -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);
}

View File

@ -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

View File

@ -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);