aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2001-04-12 03:41:36 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2001-04-12 03:41:36 +0000
commit691073076ba2bdceb294db095293a0453489ab0f (patch)
tree943b9fe0140e410d24c23703edfa24a7154c671e /gcc
parent001643af8038ea54c0fdf32ce0cc570fafed0c2c (diff)
downloadgcc-691073076ba2bdceb294db095293a0453489ab0f.zip
gcc-691073076ba2bdceb294db095293a0453489ab0f.tar.gz
gcc-691073076ba2bdceb294db095293a0453489ab0f.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/expmed.c20
-rw-r--r--gcc/expr.c10
-rw-r--r--gcc/integrate.c25
-rw-r--r--gcc/optabs.c26
-rw-r--r--gcc/stmt.c136
-rw-r--r--gcc/unroll.c2
-rw-r--r--gcc/varasm.c2
8 files changed, 181 insertions, 60 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a8af9d1..83ec619 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/expmed.c b/gcc/expmed.c
index a768450..b2396ae 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 7d78acd..970c275 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 327e8fa..1955c05 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 0be8d6a..4f30779 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 e9c49dc..9b70606 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 0d39276..52de499 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 8b14dc8..a803fe1 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);